1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 * Wine Midi mapper driver
5 * Copyright 1999 Eric Pouech
14 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(msacm);
18 typedef struct tagMIDIMAPDATA {
19 struct tagMIDIMAPDATA* self;
23 static BOOL MIDIMAP_IsData(MIDIMAPDATA* mm)
25 return (!IsBadReadPtr(mm, sizeof(MIDIMAPDATA)) && mm->self == mm);
28 /*======================================================================*
30 *======================================================================*/
32 static DWORD modOpen(LPDWORD lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
34 UINT nd = midiOutGetNumDevs();
36 MIDIMAPDATA* mom = HeapAlloc(GetProcessHeap(), 0, sizeof(MIDIMAPDATA));
38 TRACE("(%p %p %08lx\n", lpdwUser, lpDesc, dwFlags);
40 for (i = 0; i < nd; i++) {
41 if (midiOutOpen(&mom->hMidi, i, lpDesc->dwCallback,
42 lpDesc->dwInstance, dwFlags) == MMSYSERR_NOERROR) {
43 lpDesc->hMidi = mom->hMidi;
44 *lpdwUser = (DWORD)mom;
45 return MMSYSERR_NOERROR;
48 HeapFree(GetProcessHeap(), 0, mom);
49 return MMSYSERR_ALLOCATED;
52 static DWORD modClose(MIDIMAPDATA* mom)
54 DWORD ret = midiOutClose(mom->hMidi);
55 if (ret == MMSYSERR_NOERROR)
56 HeapFree(GetProcessHeap(), 0, mom);
60 static DWORD modLongData(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
62 return midiOutLongMsg(mom->hMidi, lpMidiHdr, dwParam2);
65 static DWORD modData(MIDIMAPDATA* mom, DWORD dwParam)
67 return midiOutShortMsg(mom->hMidi, dwParam);
70 static DWORD modPrepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
72 return midiOutPrepareHeader(mom->hMidi, lpMidiHdr, dwParam2);
75 static DWORD modUnprepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
77 return midiOutUnprepareHeader(mom->hMidi, lpMidiHdr, dwParam2);
80 static DWORD modGetDevCaps(UINT wDevID, MIDIMAPDATA* mom, LPMIDIOUTCAPSA lpMidiCaps, DWORD dwParam2)
82 /* if opened low driver, forward message */
83 if (MIDIMAP_IsData(mom))
84 return midiOutGetDevCapsA(mom->hMidi, lpMidiCaps, dwParam2);
85 /* otherwise, return caps of mapper itself */
86 if (wDevID == (UINT)-1 || wDevID == (UINT16)-1) {
87 lpMidiCaps->wMid = 0x00FF;
88 lpMidiCaps->wPid = 0x0001;
89 lpMidiCaps->vDriverVersion = 0x0100;
90 strcpy(lpMidiCaps->szPname, "Wine midi out mapper");
91 lpMidiCaps->wTechnology = MOD_MAPPER;
92 lpMidiCaps->wVoices = 0;
93 lpMidiCaps->wNotes = 0;
94 lpMidiCaps->wChannelMask = 0xFFFF;
95 lpMidiCaps->dwSupport = MIDICAPS_LRVOLUME | MIDICAPS_VOLUME;
97 return MMSYSERR_NOERROR;
99 ERR("This shouldn't happen\n");
100 return MMSYSERR_ERROR;
103 static DWORD modGetVolume(UINT wDevID, MIDIMAPDATA* mom, LPDWORD lpVol)
105 if (MIDIMAP_IsData(mom))
106 return midiOutGetVolume(mom->hMidi, lpVol);
107 return MMSYSERR_ERROR;
110 static DWORD modSetVolume(UINT wDevID, MIDIMAPDATA* mom, DWORD vol)
112 if (MIDIMAP_IsData(mom))
113 return midiOutSetVolume(mom->hMidi, vol);
114 return MMSYSERR_ERROR;
117 static DWORD modReset(MIDIMAPDATA* mom)
119 return midiOutReset(mom->hMidi);
122 /**************************************************************************
123 * MIDIMAP_modMessage [sample driver]
125 DWORD WINAPI MIDIMAP_modMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
126 DWORD dwParam1, DWORD dwParam2)
128 TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
129 wDevID, wMsg, dwUser, dwParam1, dwParam2);
136 /* FIXME: Pretend this is supported */
139 case MODM_OPEN: return modOpen ((LPDWORD)dwUser, (LPMIDIOPENDESC)dwParam1,dwParam2);
140 case MODM_CLOSE: return modClose ((MIDIMAPDATA*)dwUser);
142 case MODM_DATA: return modData ((MIDIMAPDATA*)dwUser, dwParam1);
143 case MODM_LONGDATA: return modLongData ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
144 case MODM_PREPARE: return modPrepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
145 case MODM_UNPREPARE: return modUnprepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
147 case MODM_GETDEVCAPS: return modGetDevCaps (wDevID, (MIDIMAPDATA*)dwUser, (LPMIDIOUTCAPSA)dwParam1,dwParam2);
148 case MODM_GETNUMDEVS: return 1;
149 case MODM_GETVOLUME: return modGetVolume (wDevID, (MIDIMAPDATA*)dwUser, (LPDWORD)dwParam1);
150 case MODM_SETVOLUME: return modSetVolume (wDevID, (MIDIMAPDATA*)dwUser, dwParam1);
151 case MODM_RESET: return modReset ((MIDIMAPDATA*)dwUser);
153 FIXME("unknown message %d!\n", wMsg);
155 return MMSYSERR_NOTSUPPORTED;
158 /*======================================================================*
160 *======================================================================*/
162 static DWORD midOpen(LPDWORD lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
164 UINT nd = midiInGetNumDevs();
166 MIDIMAPDATA* mim = HeapAlloc(GetProcessHeap(), 0, sizeof(MIDIMAPDATA));
168 TRACE("(%p %p %08lx\n", lpdwUser, lpDesc, dwFlags);
170 for (i = 0; i < nd; i++) {
171 if (midiInOpen(&mim->hMidi, i, lpDesc->dwCallback,
172 lpDesc->dwInstance, dwFlags) == MMSYSERR_NOERROR) {
173 lpDesc->hMidi = mim->hMidi;
174 *lpdwUser = (DWORD)mim;
175 return MMSYSERR_NOERROR;
178 HeapFree(GetProcessHeap(), 0, mim);
179 return MMSYSERR_ALLOCATED;
182 static DWORD midClose(MIDIMAPDATA* mim)
184 DWORD ret = midiInClose(mim->hMidi);
185 if (ret == MMSYSERR_NOERROR)
186 HeapFree(GetProcessHeap(), 0, mim);
190 static DWORD midAddBuffer(MIDIMAPDATA* mim, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
192 return midiInAddBuffer(mim->hMidi, lpMidiHdr, dwParam2);
195 static DWORD midPrepare(MIDIMAPDATA* mim, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
197 return midiInPrepareHeader(mim->hMidi, lpMidiHdr, dwParam2);
200 static DWORD midUnprepare(MIDIMAPDATA* mim, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
202 return midiInUnprepareHeader(mim->hMidi, lpMidiHdr, dwParam2);
205 static DWORD midGetDevCaps(UINT wDevID, MIDIMAPDATA* mim, LPMIDIINCAPSA lpMidiCaps, DWORD dwParam2)
207 /* if opened low driver, forward message */
208 if (MIDIMAP_IsData(mim))
209 return midiInGetDevCapsA(mim->hMidi, lpMidiCaps, dwParam2);
210 /* otherwise, return caps of mapper itself */
211 if (wDevID == (UINT)-1 || wDevID == (UINT16)-1) {
212 lpMidiCaps->wMid = 0x00FF;
213 lpMidiCaps->wPid = 0x0001;
214 lpMidiCaps->vDriverVersion = 0x0100;
215 strcpy(lpMidiCaps->szPname, "Wine midi int mapper");
216 lpMidiCaps->dwSupport = 0;
218 return MMSYSERR_NOERROR;
220 ERR("This shouldn't happen\n");
221 return MMSYSERR_ERROR;
224 static DWORD midStop(MIDIMAPDATA* mim)
226 return midiInStop(mim->hMidi);
229 static DWORD midStart(MIDIMAPDATA* mim)
231 return midiInStart(mim->hMidi);
234 static DWORD midReset(MIDIMAPDATA* mim)
236 return midiInReset(mim->hMidi);
239 /**************************************************************************
240 * MIDIMAP_midMessage [sample driver]
242 DWORD WINAPI MIDIMAP_midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
243 DWORD dwParam1, DWORD dwParam2)
245 TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
246 wDevID, wMsg, dwUser, dwParam1, dwParam2);
253 /* FIXME: Pretend this is supported */
256 case MIDM_OPEN: return midOpen ((LPDWORD)dwUser, (LPMIDIOPENDESC)dwParam1, dwParam2);
257 case MIDM_CLOSE: return midClose ((MIDIMAPDATA*)dwUser);
259 case MIDM_ADDBUFFER: return midAddBuffer ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
260 case MIDM_PREPARE: return midPrepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
261 case MIDM_UNPREPARE: return midUnprepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
262 case MIDM_GETDEVCAPS: return midGetDevCaps (wDevID, (MIDIMAPDATA*)dwUser, (LPMIDIINCAPSA)dwParam1, dwParam2);
263 case MIDM_GETNUMDEVS: return 1;
264 case MIDM_RESET: return midReset ((MIDIMAPDATA*)dwUser);
265 case MIDM_START: return midStart ((MIDIMAPDATA*)dwUser);
266 case MIDM_STOP: return midStop ((MIDIMAPDATA*)dwUser);
268 FIXME("unknown message %u!\n", wMsg);
270 return MMSYSERR_NOTSUPPORTED;
273 /*======================================================================*
275 *======================================================================*/
277 static struct WINE_MIDIMAP* oss = NULL;
279 /**************************************************************************
280 * MIDIMAP_drvOpen [internal]
282 static DWORD MIDIMAP_drvOpen(LPSTR str)
287 /* I know, this is ugly, but who cares... */
288 oss = (struct WINE_MIDIMAP*)1;
292 /**************************************************************************
293 * MIDIMAP_drvClose [internal]
295 static DWORD MIDIMAP_drvClose(DWORD dwDevID)
304 /**************************************************************************
305 * MIDIMAP_DriverProc [internal]
307 LONG CALLBACK MIDIMAP_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
308 DWORD dwParam1, DWORD dwParam2)
310 /* EPP TRACE("(%08lX, %04X, %08lX, %08lX, %08lX)\n", */
311 /* EPP dwDevID, hDriv, wMsg, dwParam1, dwParam2); */
314 case DRV_LOAD: return 1;
315 case DRV_FREE: return 1;
316 case DRV_OPEN: return MIDIMAP_drvOpen((LPSTR)dwParam1);
317 case DRV_CLOSE: return MIDIMAP_drvClose(dwDevID);
318 case DRV_ENABLE: return 1;
319 case DRV_DISABLE: return 1;
320 case DRV_QUERYCONFIGURE: return 1;
321 case DRV_CONFIGURE: MessageBoxA(0, "MIDIMAP MultiMedia Driver !", "OSS Driver", MB_OK); return 1;
322 case DRV_INSTALL: return DRVCNF_RESTART;
323 case DRV_REMOVE: return DRVCNF_RESTART;
325 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);