Added timeout to critical section waiting.
[wine/multimedia.git] / multimedia / init.c
blobd40443262b73bb04cf1e24e8ebb49c1f95221661
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * Initialization procedures for multimedia
6 * Copyright 1998 Luiz Otavio L. Zorzella
7 */
9 #include <unistd.h>
10 #include <string.h>
11 #include <fcntl.h>
12 #include <sys/ioctl.h>
13 #include "winbase.h"
14 #include "multimedia.h"
15 #include "xmalloc.h"
16 #include "options.h"
17 #include "debug.h"
19 #ifdef HAVE_OSS
21 extern int MODM_NUMDEVS;
22 extern int MODM_NUMFMSYNTHDEVS;
23 extern int MODM_NUMMIDIDEVS;
24 extern LPMIDIOUTCAPS16 midiOutDevices[MAX_MIDIOUTDRV];
26 extern int MIDM_NUMDEVS;
27 extern LPMIDIINCAPS16 midiInDevices [MAX_MIDIINDRV];
29 #endif
31 /**************************************************************************
32 * unixToWindowsDeviceType [internal]
34 * return the Windows equivalent to a Unix Device Type
37 #ifdef HAVE_OSS
38 int unixToWindowsDeviceType(int type)
40 #if !defined(__NetBSD__) && !defined(__OpenBSD__)
41 /* MOD_MIDIPORT output port
42 * MOD_SYNTH generic internal synth
43 * MOD_SQSYNTH square wave internal synth
44 * MOD_FMSYNTH FM internal synth
45 * MOD_MAPPER MIDI mapper
48 /* FIXME Is this really the correct equivalence from UNIX to
49 Windows Sound type */
51 switch (type) {
52 case SYNTH_TYPE_FM: return MOD_FMSYNTH;
53 case SYNTH_TYPE_SAMPLE: return MOD_SYNTH;
54 case SYNTH_TYPE_MIDI: return MOD_MIDIPORT;
55 default:
56 ERR(midi, "Cannot determine the type of this midi device. "
57 "Assuming FM Synth\n");
58 return MOD_FMSYNTH;
60 #else
61 return MOD_FMSYNTH;
62 #endif
64 #endif
66 /**************************************************************************
67 * MULTIMEDIA_MidiInit [internal]
69 * Initializes the MIDI devices information variables
72 BOOL MULTIMEDIA_MidiInit(void)
74 #if defined(HAVE_OSS) && !defined(__NetBSD__) && !defined(__OpenBSD__)
75 int i, status, numsynthdevs = 255, nummididevs = 255;
76 struct synth_info sinfo;
77 struct midi_info minfo;
78 int fd; /* file descriptor for MIDI_SEQ */
80 TRACE(midi, "Initializing the MIDI variables.\n");
82 /* try to open device */
83 /* FIXME: should use function midiOpenSeq() in midi.c */
84 fd = open(MIDI_SEQ, O_WRONLY);
85 if (fd == -1) {
86 TRACE(midi, "No sequencer found: unable to open `%s'.\n", MIDI_SEQ);
87 return TRUE;
90 /* find how many Synth devices are there in the system */
91 status = ioctl(fd, SNDCTL_SEQ_NRSYNTHS, &numsynthdevs);
93 if (status == -1) {
94 ERR(midi, "ioctl for nr synth failed.\n");
95 close(fd);
96 return TRUE;
99 if (numsynthdevs > MAX_MIDIOUTDRV) {
100 ERR(midi, "MAX_MIDIOUTDRV (%d) was enough for the number of devices (%d). "
101 "Some FM devices will not be available.\n",MAX_MIDIOUTDRV,numsynthdevs);
102 numsynthdevs = MAX_MIDIOUTDRV;
105 for (i = 0; i < numsynthdevs; i++) {
106 LPMIDIOUTCAPS16 tmplpCaps;
108 sinfo.device = i;
109 status = ioctl(fd, SNDCTL_SYNTH_INFO, &sinfo);
110 if (status == -1) {
111 ERR(midi, "ioctl for synth info failed.\n");
112 close(fd);
113 return TRUE;
116 tmplpCaps = xmalloc(sizeof(MIDIOUTCAPS16));
117 /* We also have the information sinfo.synth_subtype, not used here
120 /* Manufac ID. We do not have access to this with soundcard.h
121 * Does not seem to be a problem, because in mmsystem.h only
122 * Microsoft's ID is listed.
124 tmplpCaps->wMid = 0x00FF;
125 tmplpCaps->wPid = 0x0001; /* FIXME Product ID */
126 /* Product Version. We simply say "1" */
127 tmplpCaps->vDriverVersion = 0x001;
128 strcpy(tmplpCaps->szPname, sinfo.name);
130 tmplpCaps->wTechnology = unixToWindowsDeviceType(sinfo.synth_type);
131 tmplpCaps->wVoices = sinfo.nr_voices;
133 /* FIXME Is it possible to know the maximum
134 * number of simultaneous notes of a soundcard ?
135 * I believe we don't have this information, but
136 * it's probably equal or more than wVoices
138 tmplpCaps->wNotes = sinfo.nr_voices;
140 /* FIXME Do we have this information?
141 * Assuming the soundcards can handle
142 * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
143 * not MIDICAPS_CACHE.
145 tmplpCaps->dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
147 midiOutDevices[i] = tmplpCaps;
149 if (sinfo.capabilities & SYNTH_CAP_INPUT) {
150 FIXME(midi, "Synthetizer support MIDI in. Not supported yet (please report)\n");
153 TRACE(midi, "name='%s', techn=%d voices=%d notes=%d support=%ld\n",
154 tmplpCaps->szPname, tmplpCaps->wTechnology,
155 tmplpCaps->wVoices, tmplpCaps->wNotes, tmplpCaps->dwSupport);
156 TRACE(midi,"OSS info: synth subtype=%d capa=%Xh\n",
157 sinfo.synth_subtype, sinfo.capabilities);
160 /* find how many MIDI devices are there in the system */
161 status = ioctl(fd, SNDCTL_SEQ_NRMIDIS, &nummididevs);
162 if (status == -1) {
163 ERR(midi, "ioctl on nr midi failed.\n");
164 return TRUE;
167 /* FIXME: the two restrictions below could be loosen in some cases */
168 if (numsynthdevs + nummididevs > MAX_MIDIOUTDRV) {
169 ERR(midi, "MAX_MIDIOUTDRV was not enough for the number of devices. "
170 "Some MIDI devices will not be available.\n");
171 nummididevs = MAX_MIDIOUTDRV - numsynthdevs;
174 if (nummididevs > MAX_MIDIINDRV) {
175 ERR(midi, "MAX_MIDIINDRV (%d) was not enough for the number of devices (%d). "
176 "Some MIDI devices will not be available.\n",MAX_MIDIINDRV,nummididevs);
177 nummididevs = MAX_MIDIINDRV;
180 for (i = 0; i < nummididevs; i++) {
181 LPMIDIOUTCAPS16 tmplpOutCaps;
182 LPMIDIINCAPS16 tmplpInCaps;
184 minfo.device = i;
185 status = ioctl(fd, SNDCTL_MIDI_INFO, &minfo);
186 if (status == -1) {
187 ERR(midi, "ioctl on midi info failed.\n");
188 close(fd);
189 return TRUE;
192 tmplpOutCaps = xmalloc(sizeof(MIDIOUTCAPS16));
193 /* This whole part is somewhat obscure to me. I'll keep trying to dig
194 info about it. If you happen to know, please tell us. The very
195 descritive minfo.dev_type was not used here.
197 /* Manufac ID. We do not have access to this with soundcard.h
198 Does not seem to be a problem, because in mmsystem.h only
199 Microsoft's ID is listed */
200 tmplpOutCaps->wMid = 0x00FF;
201 tmplpOutCaps->wPid = 0x0001; /* FIXME Product ID */
202 /* Product Version. We simply say "1" */
203 tmplpOutCaps->vDriverVersion = 0x001;
204 strcpy(tmplpOutCaps->szPname, minfo.name);
206 tmplpOutCaps->wTechnology = MOD_MIDIPORT; /* FIXME Is this right? */
207 /* Does it make any difference? */
208 tmplpOutCaps->wVoices = 16;
209 /* Does it make any difference? */
210 tmplpOutCaps->wNotes = 16;
211 /* FIXME Does it make any difference? */
212 tmplpOutCaps->dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
214 midiOutDevices[numsynthdevs + i] = tmplpOutCaps;
216 tmplpInCaps = xmalloc(sizeof(MIDIOUTCAPS16));
217 /* This whole part is somewhat obscure to me. I'll keep trying to dig
218 info about it. If you happen to know, please tell us. The very
219 descritive minfo.dev_type was not used here.
221 /* Manufac ID. We do not have access to this with soundcard.h
222 Does not seem to be a problem, because in mmsystem.h only
223 Microsoft's ID is listed */
224 tmplpInCaps->wMid = 0x00FF;
225 tmplpInCaps->wPid = 0x0001; /* FIXME Product ID */
226 /* Product Version. We simply say "1" */
227 tmplpInCaps->vDriverVersion = 0x001;
228 strcpy(tmplpInCaps->szPname, minfo.name);
230 /* FIXME : could we get better information than that ? */
231 tmplpInCaps->dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
233 midiInDevices[i] = tmplpInCaps;
235 TRACE(midi,"name='%s' techn=%d voices=%d notes=%d support=%ld\n",
236 tmplpOutCaps->szPname, tmplpOutCaps->wTechnology, tmplpOutCaps->wVoices,
237 tmplpOutCaps->wNotes, tmplpOutCaps->dwSupport);
238 TRACE(midi,"OSS info: midi dev-type=%d, capa=%d\n",
239 minfo.dev_type, minfo.capabilities);
242 /* windows does not seem to differentiate Synth from MIDI devices */
243 MODM_NUMFMSYNTHDEVS = numsynthdevs;
244 MODM_NUMMIDIDEVS = nummididevs;
245 MODM_NUMDEVS = numsynthdevs + nummididevs;
247 MIDM_NUMDEVS = nummididevs;
249 /* close file and exit */
250 close(fd);
251 #endif /* HAVE_OSS */
253 return TRUE;
256 BOOL MULTIMEDIA_MciInit(void)
258 LPSTR ptr1, ptr2;
259 char buffer[1024];
261 mciInstalledCount = 0;
262 ptr1 = lpmciInstallNames = xmalloc(2048);
264 /* FIXME: should do also some registry diving here */
265 if (PROFILE_GetWineIniString("options", "mci", "", lpmciInstallNames, 2048) > 0) {
266 TRACE(mci, "Wine => '%s' \n", ptr1);
267 while ((ptr2 = strchr(ptr1, ':')) != 0) {
268 *ptr2++ = 0;
269 TRACE(mci, "---> '%s' \n", ptr1);
270 mciInstalledCount++;
271 ptr1 = ptr2;
273 mciInstalledCount++;
274 TRACE(mci, "---> '%s' \n", ptr1);
275 ptr1 += strlen(ptr1) + 1;
276 } else {
277 GetPrivateProfileStringA("mci", NULL, "", lpmciInstallNames, 2048, "SYSTEM.INI");
278 while (strlen(ptr1) > 0) {
279 TRACE(mci, "---> '%s' \n", ptr1);
280 ptr1 += (strlen(ptr1) + 1);
281 mciInstalledCount++;
284 mciInstalledListLen = ptr1 - lpmciInstallNames;
286 if (PROFILE_GetWineIniString("options", "mciExternal", "", buffer, sizeof(buffer)) > 0) {
287 int i;
289 for (i = 0; MCI_InternalDescriptors[i].uDevType != 0xFFFF; i++) {
290 if (strstr(buffer, MCI_InternalDescriptors[i].lpstrName) != NULL) {
291 MCI_InternalDescriptors[i].uDevType = 0; /* disable slot */
295 return TRUE;
298 /**************************************************************************
299 * MULTIMEDIA_Init [internal]
301 * Initializes the multimedia information variables
304 BOOL MULTIMEDIA_Init(void)
306 return MULTIMEDIA_MidiInit() && MULTIMEDIA_MciInit();