]> code.delx.au - pulseaudio/blob - src/modules/module-detect.c
Updated catalan po
[pulseaudio] / src / modules / module-detect.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6 Copyright 2006 Diego Pettenò
7
8 PulseAudio is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published
10 by the Free Software Foundation; either version 2 of the License,
11 or (at your option) any later version.
12
13 PulseAudio is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with PulseAudio; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 USA.
22 ***/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <stdlib.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36
37 #include <pulse/xmalloc.h>
38
39 #include <pulsecore/core-error.h>
40 #include <pulsecore/module.h>
41 #include <pulsecore/modargs.h>
42 #include <pulsecore/log.h>
43 #include <pulsecore/core-util.h>
44 #include <pulsecore/macro.h>
45
46 #include "module-detect-symdef.h"
47
48 PA_MODULE_AUTHOR("Lennart Poettering");
49 PA_MODULE_DESCRIPTION("Detect available audio hardware and load matching drivers");
50 PA_MODULE_VERSION(PACKAGE_VERSION);
51 PA_MODULE_LOAD_ONCE(TRUE);
52 PA_MODULE_USAGE("just-one=<boolean>");
53
54 static const char* const valid_modargs[] = {
55 "just-one",
56 NULL
57 };
58
59 #ifdef HAVE_ALSA
60
61 static int detect_alsa(pa_core *c, int just_one) {
62 FILE *f;
63 int n = 0, n_sink = 0, n_source = 0;
64
65 if (!(f = fopen("/proc/asound/devices", "r"))) {
66
67 if (errno != ENOENT)
68 pa_log_error("open(\"/proc/asound/devices\") failed: %s", pa_cstrerror(errno));
69
70 return -1;
71 }
72
73 while (!feof(f)) {
74 char line[64], args[64];
75 unsigned device, subdevice;
76 int is_sink;
77
78 if (!fgets(line, sizeof(line), f))
79 break;
80
81 line[strcspn(line, "\r\n")] = 0;
82
83 if (pa_endswith(line, "digital audio playback"))
84 is_sink = 1;
85 else if (pa_endswith(line, "digital audio capture"))
86 is_sink = 0;
87 else
88 continue;
89
90 if (just_one && is_sink && n_sink >= 1)
91 continue;
92
93 if (just_one && !is_sink && n_source >= 1)
94 continue;
95
96 if (sscanf(line, " %*i: [%u- %u]: ", &device, &subdevice) != 2)
97 continue;
98
99 /* Only one sink per device */
100 if (subdevice != 0)
101 continue;
102
103 pa_snprintf(args, sizeof(args), "device_id=%u", device);
104 if (!pa_module_load(c, is_sink ? "module-alsa-sink" : "module-alsa-source", args))
105 continue;
106
107 n++;
108
109 if (is_sink)
110 n_sink++;
111 else
112 n_source++;
113 }
114
115 fclose(f);
116
117 return n;
118 }
119 #endif
120
121 #ifdef HAVE_OSS
122 static int detect_oss(pa_core *c, int just_one) {
123 FILE *f;
124 int n = 0, b = 0;
125
126 if (!(f = fopen("/dev/sndstat", "r")) &&
127 !(f = fopen("/proc/sndstat", "r")) &&
128 !(f = fopen("/proc/asound/oss/sndstat", "r"))) {
129
130 if (errno != ENOENT)
131 pa_log_error("failed to open OSS sndstat device: %s", pa_cstrerror(errno));
132
133 return -1;
134 }
135
136 while (!feof(f)) {
137 char line[64], args[64];
138 unsigned device;
139
140 if (!fgets(line, sizeof(line), f))
141 break;
142
143 line[strcspn(line, "\r\n")] = 0;
144
145 if (!b) {
146 b = strcmp(line, "Audio devices:") == 0 || strcmp(line, "Installed devices:") == 0;
147 continue;
148 }
149
150 if (line[0] == 0)
151 break;
152
153 if (sscanf(line, "%u: ", &device) == 1) {
154 if (device == 0)
155 pa_snprintf(args, sizeof(args), "device=/dev/dsp");
156 else
157 pa_snprintf(args, sizeof(args), "device=/dev/dsp%u", device);
158
159 if (!pa_module_load(c, "module-oss", args))
160 continue;
161
162 } else if (sscanf(line, "pcm%u: ", &device) == 1) {
163 /* FreeBSD support, the devices are named /dev/dsp0.0, dsp0.1 and so on */
164 pa_snprintf(args, sizeof(args), "device=/dev/dsp%u.0", device);
165
166 if (!pa_module_load(c, "module-oss", args))
167 continue;
168 }
169
170 n++;
171
172 if (just_one)
173 break;
174 }
175
176 fclose(f);
177 return n;
178 }
179 #endif
180
181 #ifdef HAVE_SOLARIS
182 static int detect_solaris(pa_core *c, int just_one) {
183 struct stat s;
184 const char *dev;
185 char args[64];
186
187 dev = getenv("AUDIODEV");
188 if (!dev)
189 dev = "/dev/audio";
190
191 if (stat(dev, &s) < 0) {
192 if (errno != ENOENT)
193 pa_log_error("failed to open device %s: %s", dev, pa_cstrerror(errno));
194 return -1;
195 }
196
197 if (!S_ISCHR(s.st_mode))
198 return 0;
199
200 pa_snprintf(args, sizeof(args), "device=%s", dev);
201
202 if (!pa_module_load(c, "module-solaris", args))
203 return 0;
204
205 return 1;
206 }
207 #endif
208
209 #ifdef OS_IS_WIN32
210 static int detect_waveout(pa_core *c, int just_one) {
211 /*
212 * FIXME: No point in enumerating devices until the plugin supports
213 * selecting anything but the first.
214 */
215 if (!pa_module_load(c, "module-waveout", ""))
216 return 0;
217
218 return 1;
219 }
220 #endif
221
222 int pa__init(pa_module*m) {
223 pa_bool_t just_one = FALSE;
224 int n = 0;
225 pa_modargs *ma;
226
227 pa_assert(m);
228
229 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
230 pa_log("Failed to parse module arguments");
231 goto fail;
232 }
233
234 if (pa_modargs_get_value_boolean(ma, "just-one", &just_one) < 0) {
235 pa_log("just_one= expects a boolean argument.");
236 goto fail;
237 }
238
239 #ifdef HAVE_ALSA
240 if ((n = detect_alsa(m->core, just_one)) <= 0)
241 #endif
242 #ifdef HAVE_OSS
243 if ((n = detect_oss(m->core, just_one)) <= 0)
244 #endif
245 #ifdef HAVE_SOLARIS
246 if ((n = detect_solaris(m->core, just_one)) <= 0)
247 #endif
248 #ifdef OS_IS_WIN32
249 if ((n = detect_waveout(m->core, just_one)) <= 0)
250 #endif
251 {
252 pa_log_warn("failed to detect any sound hardware.");
253 goto fail;
254 }
255
256 pa_log_info("loaded %i modules.", n);
257
258 /* We were successful and can unload ourselves now. */
259 pa_module_unload_request(m, TRUE);
260
261 pa_modargs_free(ma);
262
263 return 0;
264
265 fail:
266 if (ma)
267 pa_modargs_free(ma);
268
269 return -1;
270 }