mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-14 19:05:40 +00:00
winmm: Allow new sounds to interrupt previous PlaySound invocations.
This commit is contained in:
parent
86de76b9e1
commit
197607db2e
|
@ -44,10 +44,10 @@ typedef struct tagWINE_PLAYSOUND
|
|||
LPCWSTR pszSound;
|
||||
HMODULE hMod;
|
||||
DWORD fdwSound;
|
||||
struct tagWINE_PLAYSOUND* lpNext;
|
||||
HWAVEOUT hWave;
|
||||
} WINE_PLAYSOUND;
|
||||
|
||||
static WINE_PLAYSOUND *PlaySoundList;
|
||||
static WINE_PLAYSOUND *PlaySoundCurrent;
|
||||
static BOOL bPlaySoundStop;
|
||||
|
||||
static HMMIO get_mmioFromFile(LPCWSTR lpszName)
|
||||
|
@ -206,12 +206,9 @@ static BOOL PlaySound_IsString(DWORD fdwSound, const void* psz)
|
|||
|
||||
static void PlaySound_Free(WINE_PLAYSOUND* wps)
|
||||
{
|
||||
WINE_PLAYSOUND** p;
|
||||
|
||||
EnterCriticalSection(&WINMM_cs);
|
||||
for (p = &PlaySoundList; *p && *p != wps; p = &((*p)->lpNext));
|
||||
if (*p) *p = (*p)->lpNext;
|
||||
if (PlaySoundList == NULL) SetEvent(psLastEvent);
|
||||
PlaySoundCurrent = NULL;
|
||||
SetEvent(psLastEvent);
|
||||
LeaveCriticalSection(&WINMM_cs);
|
||||
if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound);
|
||||
HeapFree(GetProcessHeap(), 0, wps);
|
||||
|
@ -399,7 +396,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
|||
(LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);
|
||||
|
||||
s.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!s.hEvent)
|
||||
if (!s.hEvent || bPlaySoundStop)
|
||||
goto errCleanUp;
|
||||
|
||||
if (waveOutOpen(&hWave, WAVE_MAPPER, lpWaveFormat, (DWORD_PTR)PlaySound_Callback,
|
||||
|
@ -423,6 +420,7 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
|||
goto errCleanUp;
|
||||
}
|
||||
|
||||
wps->hWave = hWave;
|
||||
s.dwEventCount = 1L; /* for first buffer */
|
||||
index = 0;
|
||||
|
||||
|
@ -434,7 +432,6 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
|||
{
|
||||
if (bPlaySoundStop)
|
||||
{
|
||||
waveOutReset(hWave);
|
||||
wps->bLoop = FALSE;
|
||||
break;
|
||||
}
|
||||
|
@ -464,7 +461,15 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
|
|||
errCleanUp:
|
||||
TRACE("Done playing=%s => %s!\n", debugstr_w(wps->pszSound), bRet ? "ok" : "ko");
|
||||
HeapFree(GetProcessHeap(), 0, lpWaveFormat);
|
||||
if (hWave) while (waveOutClose(hWave) == WAVERR_STILLPLAYING) Sleep(100);
|
||||
if (hWave)
|
||||
{
|
||||
EnterCriticalSection(&WINMM_cs);
|
||||
/* the CS prevents a concurrent waveOutReset */
|
||||
wps->hWave = 0;
|
||||
LeaveCriticalSection(&WINMM_cs);
|
||||
while (waveOutClose(hWave) == WAVERR_STILLPLAYING)
|
||||
Sleep(100);
|
||||
}
|
||||
CloseHandle(s.hEvent);
|
||||
HeapFree(GetProcessHeap(), 0, waveHdr);
|
||||
if (hmmio) mmioClose(hmmio, 0);
|
||||
|
@ -482,7 +487,7 @@ static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSo
|
|||
pszSound, hmod, fdwSound);
|
||||
|
||||
/* SND_NOWAIT is ignored in w95/2k/xp. */
|
||||
if ((fdwSound & SND_NOSTOP) && PlaySoundList != NULL)
|
||||
if ((fdwSound & SND_NOSTOP) && PlaySoundCurrent != NULL)
|
||||
return FALSE;
|
||||
|
||||
/* alloc internal structure, if we need to play something */
|
||||
|
@ -496,12 +501,14 @@ static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSo
|
|||
/* since several threads can enter PlaySound in parallel, we're not
|
||||
* sure, at this point, that another thread didn't start a new playsound
|
||||
*/
|
||||
while (PlaySoundList != NULL)
|
||||
while (PlaySoundCurrent != NULL)
|
||||
{
|
||||
ResetEvent(psLastEvent);
|
||||
/* FIXME: doc says we have to stop all instances of pszSound if it's non
|
||||
* NULL... as of today, we stop all playing instances */
|
||||
bPlaySoundStop = TRUE;
|
||||
if(PlaySoundCurrent->hWave)
|
||||
waveOutReset(PlaySoundCurrent->hWave);
|
||||
|
||||
LeaveCriticalSection(&WINMM_cs);
|
||||
WaitForSingleObject(psLastEvent, INFINITE);
|
||||
|
@ -510,8 +517,7 @@ static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSo
|
|||
bPlaySoundStop = FALSE;
|
||||
}
|
||||
|
||||
if (wps) wps->lpNext = PlaySoundList;
|
||||
PlaySoundList = wps;
|
||||
PlaySoundCurrent = wps;
|
||||
LeaveCriticalSection(&WINMM_cs);
|
||||
|
||||
if (!wps) return TRUE;
|
||||
|
|
Loading…
Reference in a new issue