- removed (now obsolete) driver.h file (it's content is now in mmsystem.h)
[wine] / dlls / winmm / midimap / midimap.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2 /*                                 
3  * Wine Midi mapper driver
4  *
5  * Copyright    1999 Eric Pouech
6  */
7
8 #include "windef.h"
9 #include "wingdi.h"
10 #include "winuser.h"
11 #include "mmddk.h"
12 #include "debugtools.h"
13
14 DEFAULT_DEBUG_CHANNEL(msacm)
15
16 typedef struct tagMIDIMAPDATA {
17     struct tagMIDIMAPDATA*      self;
18     HMIDI       hMidi;
19 } MIDIMAPDATA;
20
21 static  BOOL    MIDIMAP_IsData(MIDIMAPDATA* mm)
22 {
23     return (!IsBadReadPtr(mm, sizeof(MIDIMAPDATA)) && mm->self == mm);
24 }
25
26 /*======================================================================*
27  *                  MIDI OUT part                                       *
28  *======================================================================*/
29
30 static  DWORD   modOpen(LPDWORD lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
31 {
32     UINT                nd = midiOutGetNumDevs();
33     UINT                i;
34     MIDIMAPDATA*        mom = HeapAlloc(GetProcessHeap(), 0, sizeof(MIDIMAPDATA));
35
36     TRACE("(%p %p %08lx\n", lpdwUser, lpDesc, dwFlags);
37
38     for (i = 0; i < nd; i++) {
39         if (midiOutOpen(&mom->hMidi, i, lpDesc->dwCallback, 
40                         lpDesc->dwInstance, dwFlags) == MMSYSERR_NOERROR) {
41             lpDesc->hMidi = mom->hMidi;
42             *lpdwUser = (DWORD)mom;
43             return MMSYSERR_NOERROR;
44         }
45     }
46     HeapFree(GetProcessHeap(), 0, mom);
47     return MMSYSERR_ALLOCATED;
48 }
49
50 static  DWORD   modClose(MIDIMAPDATA* mom)
51 {
52     DWORD ret = midiOutClose(mom->hMidi);
53     if (ret == MMSYSERR_NOERROR)
54         HeapFree(GetProcessHeap(), 0, mom);
55     return ret;
56 }
57
58 static  DWORD   modLongData(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
59 {
60     return midiOutLongMsg(mom->hMidi, lpMidiHdr, dwParam2);
61 }
62
63 static  DWORD   modData(MIDIMAPDATA* mom, DWORD dwParam)
64 {
65     return midiOutShortMsg(mom->hMidi, dwParam);
66 }
67
68 static  DWORD   modPrepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
69 {
70     return midiOutPrepareHeader(mom->hMidi, lpMidiHdr, dwParam2);
71 }
72
73 static  DWORD   modUnprepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
74 {
75     return midiOutUnprepareHeader(mom->hMidi, lpMidiHdr, dwParam2);
76 }
77
78 static  DWORD   modGetDevCaps(UINT wDevID, MIDIMAPDATA* mom, LPMIDIOUTCAPSA lpMidiCaps, DWORD dwParam2)
79 {
80     /* if opened low driver, forward message */
81     if (MIDIMAP_IsData(mom))
82         return midiOutGetDevCapsA(mom->hMidi, lpMidiCaps, dwParam2);
83     /* otherwise, return caps of mapper itself */
84     if (wDevID == (UINT)-1 || wDevID == (UINT16)-1) {
85         lpMidiCaps->wMid = 0x00FF;
86         lpMidiCaps->wPid = 0x0001;
87         lpMidiCaps->vDriverVersion = 0x0100;
88         strcpy(lpMidiCaps->szPname, "Wine midi out mapper");
89         lpMidiCaps->wTechnology = MOD_MAPPER;
90         lpMidiCaps->wVoices = 0;
91         lpMidiCaps->wNotes = 0;
92         lpMidiCaps->wChannelMask = 0xFFFF;
93         lpMidiCaps->dwSupport = MIDICAPS_LRVOLUME | MIDICAPS_VOLUME;
94
95         return MMSYSERR_NOERROR;
96     }
97     ERR("This shouldn't happen\n");
98     return MMSYSERR_ERROR; 
99 }
100
101 static  DWORD   modGetVolume(UINT wDevID, MIDIMAPDATA* mom, LPDWORD lpVol)
102 {
103     if (MIDIMAP_IsData(mom))
104         return midiOutGetVolume(mom->hMidi, lpVol);
105     return MMSYSERR_ERROR;
106 }
107
108 static  DWORD   modSetVolume(UINT wDevID, MIDIMAPDATA* mom, DWORD vol)
109 {
110     if (MIDIMAP_IsData(mom))
111         return midiOutSetVolume(mom->hMidi, vol);
112     return MMSYSERR_ERROR;
113 }
114
115 static  DWORD   modReset(MIDIMAPDATA* mom)
116 {
117     return midiOutReset(mom->hMidi);
118 }
119
120 /**************************************************************************
121  *                              MIDIMAP_modMessage      [sample driver]
122  */
123 DWORD WINAPI MIDIMAP_modMessage(UINT wDevID, UINT wMsg, DWORD dwUser, 
124                                 DWORD dwParam1, DWORD dwParam2)
125 {
126     TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
127           wDevID, wMsg, dwUser, dwParam1, dwParam2);
128     
129     switch (wMsg) {
130     case DRVM_INIT:
131     case DRVM_EXIT:
132     case DRVM_ENABLE:
133     case DRVM_DISABLE:
134         /* FIXME: Pretend this is supported */
135         return 0;
136
137     case MODM_OPEN:             return modOpen          ((LPDWORD)dwUser,      (LPMIDIOPENDESC)dwParam1,dwParam2);
138     case MODM_CLOSE:            return modClose         ((MIDIMAPDATA*)dwUser);
139
140     case MODM_DATA:             return modData          ((MIDIMAPDATA*)dwUser, dwParam1);
141     case MODM_LONGDATA:         return modLongData      ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1,     dwParam2);
142     case MODM_PREPARE:          return modPrepare       ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1,     dwParam2);
143     case MODM_UNPREPARE:        return modUnprepare     ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1,     dwParam2);
144
145     case MODM_GETDEVCAPS:       return modGetDevCaps    (wDevID, (MIDIMAPDATA*)dwUser, (LPMIDIOUTCAPSA)dwParam1,dwParam2);
146     case MODM_GETNUMDEVS:       return 1;
147     case MODM_GETVOLUME:        return modGetVolume     (wDevID, (MIDIMAPDATA*)dwUser, (LPDWORD)dwParam1);
148     case MODM_SETVOLUME:        return modSetVolume     (wDevID, (MIDIMAPDATA*)dwUser, dwParam1);
149     case MODM_RESET:            return modReset         ((MIDIMAPDATA*)dwUser);
150     default:
151         FIXME("unknown message %d!\n", wMsg);
152     }
153     return MMSYSERR_NOTSUPPORTED;
154 }
155
156 /*======================================================================*
157  *                  MIDI IN part                                        *
158  *======================================================================*/
159
160 static  DWORD   midOpen(LPDWORD lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
161 {
162     UINT                nd = midiInGetNumDevs();
163     UINT                i;
164     MIDIMAPDATA*        mim = HeapAlloc(GetProcessHeap(), 0, sizeof(MIDIMAPDATA));
165
166     TRACE("(%p %p %08lx\n", lpdwUser, lpDesc, dwFlags);
167
168     for (i = 0; i < nd; i++) {
169         if (midiInOpen(&mim->hMidi, i, lpDesc->dwCallback, 
170                         lpDesc->dwInstance, dwFlags) == MMSYSERR_NOERROR) {
171             lpDesc->hMidi = mim->hMidi;
172             *lpdwUser = (DWORD)mim;
173             return MMSYSERR_NOERROR;
174         }
175     }
176     HeapFree(GetProcessHeap(), 0, mim);
177     return MMSYSERR_ALLOCATED;
178 }
179
180 static  DWORD   midClose(MIDIMAPDATA* mim)
181 {
182     DWORD ret = midiInClose(mim->hMidi);
183     if (ret == MMSYSERR_NOERROR)
184         HeapFree(GetProcessHeap(), 0, mim);
185     return ret;
186 }
187
188 static  DWORD   midAddBuffer(MIDIMAPDATA* mim, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
189 {
190     return midiInAddBuffer(mim->hMidi, lpMidiHdr, dwParam2);
191 }
192
193 static  DWORD   midPrepare(MIDIMAPDATA* mim, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
194 {
195     return midiInPrepareHeader(mim->hMidi, lpMidiHdr, dwParam2);
196 }
197
198 static  DWORD   midUnprepare(MIDIMAPDATA* mim, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
199 {
200     return midiInUnprepareHeader(mim->hMidi, lpMidiHdr, dwParam2);
201 }
202
203 static  DWORD   midGetDevCaps(UINT wDevID, MIDIMAPDATA* mim, LPMIDIINCAPSA lpMidiCaps, DWORD dwParam2)
204 {
205     /* if opened low driver, forward message */
206     if (MIDIMAP_IsData(mim))
207         return midiInGetDevCapsA(mim->hMidi, lpMidiCaps, dwParam2);
208     /* otherwise, return caps of mapper itself */
209     if (wDevID == (UINT)-1 || wDevID == (UINT16)-1) {
210         lpMidiCaps->wMid = 0x00FF;
211         lpMidiCaps->wPid = 0x0001;
212         lpMidiCaps->vDriverVersion = 0x0100;
213         strcpy(lpMidiCaps->szPname, "Wine midi int mapper");
214         lpMidiCaps->dwSupport = 0;
215
216         return MMSYSERR_NOERROR;
217     }
218     ERR("This shouldn't happen\n");
219     return MMSYSERR_ERROR; 
220 }
221
222 static  DWORD   midStop(MIDIMAPDATA* mim)
223 {
224     return midiInStop(mim->hMidi);
225 }
226
227 static  DWORD   midStart(MIDIMAPDATA* mim)
228 {
229     return midiInStart(mim->hMidi);
230 }
231
232 static  DWORD   midReset(MIDIMAPDATA* mim)
233 {
234     return midiInReset(mim->hMidi);
235 }
236
237 /**************************************************************************
238  *                              MIDIMAP_midMessage      [sample driver]
239  */
240 DWORD WINAPI MIDIMAP_midMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
241                                 DWORD dwParam1, DWORD dwParam2)
242 {
243     TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
244           wDevID, wMsg, dwUser, dwParam1, dwParam2);
245
246     switch (wMsg) {
247     case DRVM_INIT:
248     case DRVM_EXIT:
249     case DRVM_ENABLE:
250     case DRVM_DISABLE:
251         /* FIXME: Pretend this is supported */
252         return 0;
253
254     case MIDM_OPEN:             return midOpen          ((LPDWORD)dwUser,     (LPMIDIOPENDESC)dwParam1, dwParam2);
255     case MIDM_CLOSE:            return midClose         ((MIDIMAPDATA*)dwUser);
256
257     case MIDM_ADDBUFFER:        return midAddBuffer     ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
258     case MIDM_PREPARE:          return midPrepare       ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
259     case MIDM_UNPREPARE:        return midUnprepare     ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
260     case MIDM_GETDEVCAPS:       return midGetDevCaps    (wDevID, (MIDIMAPDATA*)dwUser, (LPMIDIINCAPSA)dwParam1, dwParam2);
261     case MIDM_GETNUMDEVS:       return 1;
262     case MIDM_RESET:            return midReset         ((MIDIMAPDATA*)dwUser);
263     case MIDM_START:            return midStart         ((MIDIMAPDATA*)dwUser);
264     case MIDM_STOP:             return midStop          ((MIDIMAPDATA*)dwUser);
265     default:
266         FIXME("unknown message %u!\n", wMsg);
267     }
268     return MMSYSERR_NOTSUPPORTED;
269 }
270
271 /*======================================================================*
272  *                  Driver part                                         *
273  *======================================================================*/
274
275 static  struct WINE_MIDIMAP* oss = NULL;
276
277 /**************************************************************************
278  *                              MIDIMAP_drvOpen                 [internal]      
279  */
280 static  DWORD   MIDIMAP_drvOpen(LPSTR str)
281 {
282     if (oss)
283         return 0;
284     
285     /* I know, this is ugly, but who cares... */
286     oss = (struct WINE_MIDIMAP*)1;
287     return 1;
288 }
289
290 /**************************************************************************
291  *                              MIDIMAP_drvClose                [internal]      
292  */
293 static  DWORD   MIDIMAP_drvClose(DWORD dwDevID)
294 {
295     if (oss) {
296         oss = NULL;
297         return 1;
298     }
299     return 0;
300 }
301
302 /**************************************************************************
303  *                              MIDIMAP_DriverProc              [internal]
304  */
305 LONG CALLBACK   MIDIMAP_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg, 
306                                    DWORD dwParam1, DWORD dwParam2)
307 {
308 /* EPP     TRACE("(%08lX, %04X, %08lX, %08lX, %08lX)\n",  */
309 /* EPP    dwDevID, hDriv, wMsg, dwParam1, dwParam2); */
310     
311     switch(wMsg) {
312     case DRV_LOAD:              return 1;
313     case DRV_FREE:              return 1;
314     case DRV_OPEN:              return MIDIMAP_drvOpen((LPSTR)dwParam1);
315     case DRV_CLOSE:             return MIDIMAP_drvClose(dwDevID);
316     case DRV_ENABLE:            return 1;
317     case DRV_DISABLE:           return 1;
318     case DRV_QUERYCONFIGURE:    return 1;
319     case DRV_CONFIGURE:         MessageBoxA(0, "MIDIMAP MultiMedia Driver !", "OSS Driver", MB_OK);     return 1;
320     case DRV_INSTALL:           return DRVCNF_RESTART;
321     case DRV_REMOVE:            return DRVCNF_RESTART;
322     default:
323         return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
324     }
325 }
326
327