winmm: Synchronize player status and API calls.
Signed-off-by: Akihiro Sagawa <sagawa.aki@gmail.com> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1dd33399db
commit
25f610f96a
dlls/winmm
|
@ -1004,15 +1004,18 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
|
|||
(HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
|
||||
lpwm->mod.dwInstance, (DWORD_PTR)lphdr, 0);
|
||||
}
|
||||
SetEvent((HANDLE)msg->wParam);
|
||||
return TRUE;
|
||||
case WINE_MSM_RESUME:
|
||||
/* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
|
||||
lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
|
||||
lpMidiStrm->status = MSM_STATUS_PLAYING;
|
||||
SetEvent((HANDLE)msg->wParam);
|
||||
return TRUE;
|
||||
case WINE_MSM_PAUSE:
|
||||
/* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
|
||||
lpMidiStrm->status = MSM_STATUS_PAUSED;
|
||||
SetEvent((HANDLE)msg->wParam);
|
||||
break;
|
||||
/* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
|
||||
* by native mcimidi, it doesn't look like a correct one".
|
||||
|
@ -1387,20 +1390,49 @@ MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static MMRESULT midistream_post_message_and_wait(WINE_MIDIStream* lpMidiStrm, UINT msg, LPARAM lParam)
|
||||
{
|
||||
HANDLE hObjects[2];
|
||||
|
||||
hObjects[0] = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!hObjects[0])
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
if (!PostThreadMessageA(lpMidiStrm->dwThreadID, msg, (WPARAM)hObjects[0], lParam)) {
|
||||
WARN("bad PostThreadMessage\n");
|
||||
CloseHandle(hObjects[0]);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
if (GetCurrentThreadId() != lpMidiStrm->dwThreadID) {
|
||||
DWORD ret;
|
||||
hObjects[1] = lpMidiStrm->hThread;
|
||||
ret = WaitForMultipleObjects(sizeof(hObjects)/sizeof(hObjects[0]), hObjects,
|
||||
FALSE, INFINITE);
|
||||
if (ret != WAIT_OBJECT_0) {
|
||||
CloseHandle(hObjects[0]);
|
||||
WARN("bad WaitForSingleObject (%u)\n", ret);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hObjects[0]);
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* midiStreamPause [WINMM.@]
|
||||
*/
|
||||
MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
|
||||
{
|
||||
WINE_MIDIStream* lpMidiStrm;
|
||||
DWORD ret = MMSYSERR_NOERROR;
|
||||
|
||||
TRACE("(%p)!\n", hMidiStrm);
|
||||
|
||||
if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
PostThreadMessageA(lpMidiStrm->dwThreadID, WINE_MSM_PAUSE, 0, 0);
|
||||
return ret;
|
||||
return midistream_post_message_and_wait(lpMidiStrm, WINE_MSM_PAUSE, 0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -1496,14 +1528,12 @@ MMRESULT WINAPI midiStreamProperty(HMIDISTRM hMidiStrm, LPBYTE lpPropData, DWORD
|
|||
MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
|
||||
{
|
||||
WINE_MIDIStream* lpMidiStrm;
|
||||
MMRESULT ret = MMSYSERR_NOERROR;
|
||||
|
||||
TRACE("(%p)!\n", hMidiStrm);
|
||||
|
||||
if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
PostThreadMessageA(lpMidiStrm->dwThreadID, WINE_MSM_RESUME, 0, 0);
|
||||
return ret;
|
||||
return midistream_post_message_and_wait(lpMidiStrm, WINE_MSM_RESUME, 0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -1512,14 +1542,12 @@ MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
|
|||
MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
|
||||
{
|
||||
WINE_MIDIStream* lpMidiStrm;
|
||||
MMRESULT ret = MMSYSERR_NOERROR;
|
||||
|
||||
TRACE("(%p)!\n", hMidiStrm);
|
||||
|
||||
if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
PostThreadMessageA(lpMidiStrm->dwThreadID, WINE_MSM_STOP, 0, 0);
|
||||
return ret;
|
||||
return midistream_post_message_and_wait(lpMidiStrm, WINE_MSM_STOP, 0);
|
||||
}
|
||||
|
||||
struct mm_starter
|
||||
|
|
Loading…
Reference in New Issue