リビジョン | 706cdc50f9b5300ba09c62cd9fa2c75c2b5f5ed2 (tree) |
---|---|
日時 | 2014-08-15 07:32:52 |
作者 | yta <yta@inte...> |
コミッター | TAMUKI Shoichi |
Fix Windows Driver
Add DriverCallback API. The driver must call the DriverCallback API.
After changing, some MIDI sequencers will not freeze: XGWorks, Domino,
etc.
Signed-off-by: yta <yta@inter7.jp>
@@ -381,8 +381,8 @@ typedef JOYDEVMSGPROC *LPJOYDEVMSGPROC; | ||
381 | 381 | #define MAKEMCIRESOURCE(wRet, wRes) MAKELRESULT((wRet), (wRes)) |
382 | 382 | |
383 | 383 | typedef struct { |
384 | - DWORD dwCallback; | |
385 | - DWORD dwInstance; | |
384 | + DWORD_PTR dwCallback; | |
385 | + DWORD_PTR dwInstance; | |
386 | 386 | HMIDIOUT hMidi; |
387 | 387 | DWORD dwFlags; |
388 | 388 | } PORTALLOC, *LPPORTALLOC; |
@@ -390,8 +390,8 @@ typedef struct { | ||
390 | 390 | typedef struct { |
391 | 391 | HWAVE hWave; |
392 | 392 | LPWAVEFORMATEX lpFormat; |
393 | - DWORD dwCallback; | |
394 | - DWORD dwInstance; | |
393 | + DWORD_PTR dwCallback; | |
394 | + DWORD_PTR dwInstance; | |
395 | 395 | UINT uMappedDeviceID; |
396 | 396 | DWORD dnDevNode; |
397 | 397 | } WAVEOPENDESC, *LPWAVEOPENDESC; |
@@ -403,9 +403,9 @@ typedef struct { | ||
403 | 403 | |
404 | 404 | typedef struct { |
405 | 405 | HMIDI hMidi; |
406 | - DWORD dwCallback; | |
407 | - DWORD dwInstance; | |
408 | - DWORD dnDevNode; | |
406 | + DWORD_PTR dwCallback; | |
407 | + DWORD_PTR dwInstance; | |
408 | + DWORD_PTR dnDevNode; | |
409 | 409 | DWORD cIds; |
410 | 410 | MIDIOPENSTRMID rgIds; |
411 | 411 | } MIDIOPENDESC, *LPMIDIOPENDESC; |
@@ -414,8 +414,8 @@ typedef struct tMIXEROPENDESC | ||
414 | 414 | { |
415 | 415 | HMIXEROBJ hmx; |
416 | 416 | LPVOID pReserved0; |
417 | - DWORD dwCallback; | |
418 | - DWORD dwInstance; | |
417 | + DWORD_PTR dwCallback; | |
418 | + DWORD_PTR dwInstance; | |
419 | 419 | } MIXEROPENDESC, *LPMIXEROPENDESC; |
420 | 420 | |
421 | 421 | typedef struct { |
@@ -449,14 +449,14 @@ BOOL WINAPI mciFreeCommandResource(UINT uTable); | ||
449 | 449 | #define DCB_TYPEMASK 0x0007 |
450 | 450 | #define DCB_NOSWITCH 0x0008 /* don't switch stacks for callback */ |
451 | 451 | |
452 | -BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev, | |
453 | - UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2); | |
452 | +BOOL WINAPI DriverCallback(DWORD_PTR dwCallBack, UINT uFlags, HDRVR hDev, | |
453 | + UINT wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2); | |
454 | 454 | |
455 | -typedef void (*LPTASKCALLBACK)(DWORD dwInst); | |
455 | +typedef void (*LPTASKCALLBACK)(DWORD_PTR dwInst); | |
456 | 456 | |
457 | 457 | #define TASKERR_NOTASKSUPPORT 1 |
458 | 458 | #define TASKERR_OUTOFMEMORY 2 |
459 | -MMRESULT WINAPI mmTaskCreate(LPTASKCALLBACK, HANDLE*, DWORD); | |
459 | +MMRESULT WINAPI mmTaskCreate(LPTASKCALLBACK, HANDLE*, DWORD_PTR); | |
460 | 460 | void WINAPI mmTaskBlock(HANDLE); |
461 | 461 | BOOL WINAPI mmTaskSignal(HANDLE); |
462 | 462 | void WINAPI mmTaskYield(void); |
@@ -103,6 +103,10 @@ const GUID CLSID_tim_synth = {0x0FEC4C35,0xA705,0x41d7,{0xA3,0xBB,0xD5,0x87,0xA2 | ||
103 | 103 | static volatile int OpenCount = 0; |
104 | 104 | static volatile int modm_closed = 1; |
105 | 105 | |
106 | +static HDRVR hdrvrInstance; | |
107 | +static MIDIOPENDESC mid_desc; | |
108 | +static DWORD dwOpenFlags; | |
109 | + | |
106 | 110 | static CRITICAL_SECTION mim_section; |
107 | 111 | static volatile int stop_thread = 0; |
108 | 112 | static HANDLE hRtsynThread = NULL; |
@@ -134,8 +138,11 @@ STDAPI DllUnregisterServer(void) | ||
134 | 138 | return S_OK; |
135 | 139 | } |
136 | 140 | |
137 | -STDAPI_(LONG) DriverProc(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, LPARAM lParam1, LPARAM lParam2){ | |
141 | +STDAPI_(LRESULT) DriverProc(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, LPARAM lParam1, LPARAM lParam2){ | |
138 | 142 | switch(msg) { |
143 | + case DRV_OPEN: | |
144 | + hdrvrInstance = hdrvr; | |
145 | + return 1; | |
139 | 146 | case DRV_REMOVE: |
140 | 147 | if (modm_closed == 0){ |
141 | 148 | int maxloop=500; |
@@ -159,7 +166,6 @@ STDAPI_(LONG) DriverProc(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, LPARAM lPa | ||
159 | 166 | case DRV_EXITSESSION: |
160 | 167 | case DRV_FREE: |
161 | 168 | case DRV_INSTALL: |
162 | - case DRV_OPEN: | |
163 | 169 | case DRV_POWER: |
164 | 170 | case DRV_QUERYCONFIGURE: |
165 | 171 | default: |
@@ -260,7 +266,73 @@ unsigned __stdcall threadfunc(LPVOID lpV){ | ||
260 | 266 | return 0; |
261 | 267 | } |
262 | 268 | |
263 | -STDAPI_(LONG) modMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2){ | |
269 | +static void modCallback(UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2) | |
270 | +{ | |
271 | +// DWORD_PTR dwUser, dwSend1, dwSend2; | |
272 | + DWORD_PTR dwCallback = mid_desc.dwCallback; | |
273 | + DWORD_PTR dwInstance = mid_desc.dwInstance; | |
274 | + | |
275 | + if (!dwCallback) { | |
276 | + return; | |
277 | + } | |
278 | +/* | |
279 | + switch (uMsg) { | |
280 | + case MM_MOM_DONE: | |
281 | + dwUser = mid_desc.dwInstance; | |
282 | + dwSend1 = (DWORD_PTR)(mid_desc.hMidi); | |
283 | + dwSend2 = dwParam1; | |
284 | + break; | |
285 | + default: | |
286 | + dwUser = mid_desc.dwInstance; | |
287 | + dwSend1 = (DWORD_PTR)(mid_desc.hMidi); | |
288 | + dwSend2 = 0; | |
289 | + break; | |
290 | + } | |
291 | +*/ | |
292 | + | |
293 | + switch (dwOpenFlags & CALLBACK_TYPEMASK) { | |
294 | + case CALLBACK_NULL: | |
295 | + break; | |
296 | + case CALLBACK_WINDOW: | |
297 | + { | |
298 | +// HWND hWnd = (HWND)(dwCallback); | |
299 | +// PostMessage(hWnd, uMsg, (WPARAM)(dwSend1), (LPARAM)(dwSend2)); | |
300 | + DriverCallback(dwCallback, DCB_WINDOW, hdrvrInstance, uMsg, dwInstance, dwParam1, dwParam2); | |
301 | + } | |
302 | + break; | |
303 | + case CALLBACK_FUNCTION: | |
304 | + { | |
305 | +// typedef void (CALLBACK *MIDIOUTPROC)(HMIDIOUT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR); | |
306 | +// MIDIOUTPROC MidiOutProc = (MIDIOUTPROC)(dwCallback); | |
307 | +// (*MidiOutProc)((HMIDIOUT)mid_desc.hMidi, uMsg, dwUser, dwSend1, dwSend2); | |
308 | + DriverCallback(dwCallback, DCB_FUNCTION, hdrvrInstance, uMsg, dwInstance, dwParam1, dwParam2); | |
309 | + } | |
310 | + break; | |
311 | + case CALLBACK_THREAD: | |
312 | + { | |
313 | +// DWORD dwThread = (DWORD)(dwCallback); | |
314 | +// PostThreadMessage(dwThread, uMsg, (WPARAM)(dwSend1), (LPARAM)(dwSend2)); | |
315 | + DriverCallback(dwCallback, DCB_TASK, hdrvrInstance, uMsg, dwInstance, dwParam1, dwParam2); | |
316 | + } | |
317 | + break; | |
318 | + case CALLBACK_EVENT: | |
319 | + { | |
320 | +// HANDLE hEvent = (HANDLE)(dwCallback); | |
321 | +// SetEvent(hEvent); | |
322 | + DriverCallback(dwCallback, DCB_EVENT, hdrvrInstance, uMsg, dwInstance, dwParam1, dwParam2); | |
323 | + } | |
324 | + break; | |
325 | + default: | |
326 | + { | |
327 | + /* not implemented */ | |
328 | + } | |
329 | + break; | |
330 | + } | |
331 | + | |
332 | + return; | |
333 | +} | |
334 | + | |
335 | +STDAPI_(DWORD) modMessage(UINT uDeviceID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2){ | |
264 | 336 | MIDIHDR *IIMidiHdr; |
265 | 337 | |
266 | 338 | switch (uMsg) { |
@@ -273,6 +345,12 @@ STDAPI_(LONG) modMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1 | ||
273 | 345 | int opend=0; |
274 | 346 | char **argv = (char **)alloca(argc * sizeof(char *)); |
275 | 347 | |
348 | + ZeroMemory(&mid_desc, sizeof(MIDIOPENDESC)); | |
349 | + if (dwParam1) { | |
350 | + CopyMemory(&mid_desc, (LPMIDIOPENDESC)dwParam1, sizeof(MIDIOPENDESC)); | |
351 | + } | |
352 | + dwOpenFlags = (DWORD)dwParam2; | |
353 | + | |
276 | 354 | processPriority = GetPriorityClass(GetCurrentProcess()); |
277 | 355 | SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); |
278 | 356 | //AllocConsole(); |
@@ -291,6 +369,7 @@ STDAPI_(LONG) modMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1 | ||
291 | 369 | hRtsynThread=(HANDLE)_beginthreadex(NULL,0,threadfunc,0,0,&thrdaddr); |
292 | 370 | SetPriorityClass(hRtsynThread, REALTIME_PRIORITY_CLASS); |
293 | 371 | SetThreadPriority(hRtsynThread, THREAD_PRIORITY_TIME_CRITICAL); |
372 | + modCallback(MM_MOM_OPEN, dwParam1, dwParam2); | |
294 | 373 | modm_closed = 0; |
295 | 374 | } |
296 | 375 | SetPriorityClass(GetCurrentProcess(), processPriority); |
@@ -304,13 +383,19 @@ STDAPI_(LONG) modMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1 | ||
304 | 383 | case MODM_LONGDATA: |
305 | 384 | { |
306 | 385 | double event_time = get_current_calender_time(); |
386 | + DWORD dwLength; | |
307 | 387 | IIMidiHdr = (MIDIHDR *)dwParam1; |
308 | 388 | if( !(IIMidiHdr->dwFlags & MHDR_PREPARED) ) return MIDIERR_UNPREPARED; |
309 | 389 | IIMidiHdr->dwFlags &= ~MHDR_INQUEUE; |
310 | 390 | IIMidiHdr->dwFlags |= MHDR_DONE; |
311 | 391 | EnterCriticalSection(&mim_section); |
312 | - rtsyn_play_one_sysex(IIMidiHdr->lpData, IIMidiHdr->dwBufferLength, event_time); | |
392 | + dwLength = IIMidiHdr->dwBufferLength; | |
393 | + if (IIMidiHdr->dwBytesRecorded > 0 && IIMidiHdr->dwBytesRecorded <= IIMidiHdr->dwBufferLength) { | |
394 | + dwLength = IIMidiHdr->dwBytesRecorded; | |
395 | + } | |
396 | + rtsyn_play_one_sysex(IIMidiHdr->lpData, dwLength, event_time); | |
313 | 397 | LeaveCriticalSection(&mim_section); |
398 | + modCallback(MM_MOM_DONE, dwParam1, dwParam2); | |
314 | 399 | return MMSYSERR_NOERROR; |
315 | 400 | } |
316 | 401 | case MODM_DATA: |
@@ -330,6 +415,7 @@ STDAPI_(LONG) modMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1 | ||
330 | 415 | OpenCount = 0; |
331 | 416 | return MMSYSERR_NOTENABLED; |
332 | 417 | } |
418 | + modCallback(MM_MOM_CLOSE, dwParam1, dwParam2); | |
333 | 419 | return MMSYSERR_NOERROR; |
334 | 420 | break; |
335 | 421 | default: |