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