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