Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
4664903d
Commit
4664903d
authored
May 29, 2002
by
Eric Pouech
Committed by
Alexandre Julliard
May 29, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Some other synchronisation issues.
parent
94152d50
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
135 additions
and
105 deletions
+135
-105
mmsystem.c
dlls/winmm/mmsystem.c
+126
-96
winemm.h
dlls/winmm/winemm.h
+9
-9
No files found.
dlls/winmm/mmsystem.c
View file @
4664903d
...
...
@@ -93,6 +93,9 @@ static BOOL MULTIMEDIA_CreateIData(HINSTANCE hInstDLL)
iData
->
lpNextIData
=
lpFirstIData
;
lpFirstIData
=
iData
;
InitializeCriticalSection
(
&
iData
->
cs
);
iData
->
cs
.
DebugInfo
=
(
void
*
)
__FILE__
": WinMM"
;
iData
->
psStopEvent
=
CreateEventA
(
NULL
,
TRUE
,
FALSE
,
NULL
);
iData
->
psLastEvent
=
CreateEventA
(
NULL
,
TRUE
,
FALSE
,
NULL
);
TRACE
(
"Created IData (%p) for pid %08lx
\n
"
,
iData
,
iData
->
dwThisProcess
);
return
TRUE
;
}
...
...
@@ -116,6 +119,9 @@ static void MULTIMEDIA_DeleteIData(void)
}
/* FIXME: should also free content and resources allocated
* inside iData */
CloseHandle
(
iData
->
psStopEvent
);
CloseHandle
(
iData
->
psLastEvent
);
DeleteCriticalSection
(
&
iData
->
cs
);
HeapFree
(
GetProcessHeap
(),
0
,
iData
);
}
}
...
...
@@ -245,17 +251,12 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
static
WCHAR
wszSounds
[]
=
{
'S'
,
'o'
,
'u'
,
'n'
,
'd'
,
's'
,
0
};
static
WCHAR
wszDefault
[]
=
{
'D'
,
'e'
,
'f'
,
'a'
,
'u'
,
'l'
,
't'
,
0
};
static
WCHAR
wszKey
[]
=
{
'A'
,
'p'
,
'p'
,
'E'
,
'v'
,
'e'
,
'n'
,
't'
,
's'
,
'\\'
,
'\\'
,
'S'
,
'c'
,
'h'
,
'e'
,
'm'
,
'e'
,
's'
,
'\\'
,
'\\'
,
static
WCHAR
wszKey
[]
=
{
'A'
,
'p'
,
'p'
,
'E'
,
'v'
,
'e'
,
'n'
,
't'
,
's'
,
'\\'
,
'S'
,
'c'
,
'h'
,
'e'
,
'm'
,
'e'
,
's'
,
'\\'
,
'A'
,
'p'
,
'p'
,
's'
,
0
};
static
WCHAR
wszDotDefault
[]
=
{
'.'
,
'D'
,
'e'
,
'f'
,
'a'
,
'u'
,
'l'
,
't'
,
0
};
static
WCHAR
wszNull
[]
=
{
0
};
/* FIXME: we should also look up the registry under
* HKCU\AppEvents\Schemes\Apps\.Default
* HKCU\AppEvents\Schemes\Apps\<AppName>
*/
TRACE
(
"searching in SystemSound list for %s
\n
"
,
debugstr_w
(
lpszName
));
GetProfileStringW
(
wszSounds
,
(
LPWSTR
)
lpszName
,
wszNull
,
str
,
sizeof
(
str
)
/
sizeof
(
str
[
0
]));
if
(
lstrlenW
(
str
)
==
0
)
...
...
@@ -269,14 +270,16 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
hmmio
=
mmioOpenW
(
str
,
NULL
,
MMIO_ALLOCBUF
|
MMIO_READ
|
MMIO_DENYWRITE
);
if
(
hmmio
!=
0
)
return
hmmio
;
next:
/* we look up the registry under
* HKCU\AppEvents\Schemes\Apps\.Default
* HKCU\AppEvents\Schemes\Apps\<AppName>
*/
if
(
RegOpenKeyW
(
HKEY_CURRENT_USER
,
wszKey
,
&
hRegSnd
)
!=
0
)
goto
none
;
if
(
uFlags
&
SND_APPLICATION
)
{
err
=
1
;
err
=
1
;
/* error */
if
(
GetModuleFileNameW
(
0
,
str
,
sizeof
(
str
)
/
sizeof
(
str
[
0
])))
{
LPWSTR
ptr
;
for
(
ptr
=
str
+
lstrlenW
(
str
)
-
1
;
ptr
>=
str
;
ptr
--
)
{
if
(
*
ptr
==
'.'
)
*
ptr
=
0
;
...
...
@@ -303,7 +306,7 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
count
=
sizeof
(
str
)
/
sizeof
(
str
[
0
]);
err
=
RegQueryValueExW
(
hSnd
,
NULL
,
0
,
&
type
,
(
LPBYTE
)
str
,
&
count
);
RegCloseKey
(
hSnd
);
if
(
err
!=
0
)
goto
none
;
if
(
err
!=
0
||
!*
str
)
goto
none
;
hmmio
=
mmioOpenW
(
str
,
NULL
,
MMIO_ALLOCBUF
|
MMIO_READ
|
MMIO_DENYWRITE
);
if
(
hmmio
)
return
hmmio
;
none:
...
...
@@ -348,6 +351,77 @@ static void PlaySound_WaitDone(struct playsound_data* s)
}
}
static
BOOL
PlaySound_IsString
(
DWORD
fdwSound
,
const
void
*
psz
)
{
/* SND_RESOURCE is 0x40004 while
* SND_MEMORY is 0x00004
*/
switch
(
fdwSound
&
(
SND_RESOURCE
|
SND_ALIAS
|
SND_FILENAME
))
{
case
SND_RESOURCE
:
return
HIWORD
(
psz
)
!=
0
;
/* by name or by ID ? */
case
SND_MEMORY
:
return
FALSE
;
case
SND_ALIAS
:
/* what about ALIAS_ID ??? */
case
SND_FILENAME
:
case
0
:
return
TRUE
;
default:
FIXME
(
"WTF
\n
"
);
return
FALSE
;
}
}
static
void
PlaySound_Free
(
WINE_PLAYSOUND
*
wps
)
{
LPWINE_MM_IDATA
iData
=
MULTIMEDIA_GetIData
();
WINE_PLAYSOUND
**
p
;
EnterCriticalSection
(
&
iData
->
cs
);
for
(
p
=
&
iData
->
lpPlaySound
;
*
p
&&
*
p
!=
wps
;
p
=
&
((
*
p
)
->
lpNext
));
if
(
*
p
)
*
p
=
(
*
p
)
->
lpNext
;
if
(
iData
->
lpPlaySound
==
NULL
)
SetEvent
(
iData
->
psLastEvent
);
LeaveCriticalSection
(
&
iData
->
cs
);
if
(
wps
->
bAlloc
)
HeapFree
(
GetProcessHeap
(),
0
,
(
void
*
)
wps
->
pszSound
);
HeapFree
(
GetProcessHeap
(),
0
,
wps
);
}
static
WINE_PLAYSOUND
*
PlaySound_Alloc
(
const
void
*
pszSound
,
HMODULE
hmod
,
DWORD
fdwSound
,
BOOL
bUnicode
)
{
WINE_PLAYSOUND
*
wps
;
wps
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
wps
));
if
(
!
wps
)
return
NULL
;
wps
->
hMod
=
hmod
;
wps
->
fdwSound
=
fdwSound
;
if
(
PlaySound_IsString
(
fdwSound
,
pszSound
))
{
if
(
bUnicode
)
{
if
(
fdwSound
&
SND_ASYNC
)
{
wps
->
pszSound
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
lstrlenW
(
pszSound
)
+
1
)
*
sizeof
(
WCHAR
));
if
(
!
wps
->
pszSound
)
goto
oom_error
;
lstrcpyW
((
LPWSTR
)
wps
->
pszSound
,
pszSound
);
wps
->
bAlloc
=
TRUE
;
}
else
wps
->
pszSound
=
pszSound
;
}
else
{
wps
->
pszSound
=
HEAP_strdupAtoW
(
GetProcessHeap
(),
0
,
pszSound
);
if
(
!
wps
->
pszSound
)
goto
oom_error
;
wps
->
bAlloc
=
TRUE
;
}
}
else
wps
->
pszSound
=
pszSound
;
return
wps
;
oom_error:
PlaySound_Free
(
wps
);
return
NULL
;
}
static
DWORD
WINAPI
proc_PlaySound
(
LPVOID
arg
)
{
WINE_PLAYSOUND
*
wps
=
(
WINE_PLAYSOUND
*
)
arg
;
...
...
@@ -385,7 +459,6 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
data
=
(
void
*
)
wps
->
pszSound
;
/* construct an MMIO stream (either in memory, or from a file */
/* hmmio = 0; */
/* to catch errors */
if
(
wps
->
fdwSound
&
SND_MEMORY
)
{
/* NOTE: SND_RESOURCE has the SND_MEMORY bit set */
MMIOINFO
mminfo
;
...
...
@@ -482,9 +555,11 @@ static DWORD WINAPI proc_PlaySound(LPVOID arg)
s
.
dwEventCount
=
1L
;
/* for first buffer */
mmioSeek
(
hmmio
,
mmckInfo
.
dwDataOffset
,
SEEK_SET
);
while
(
left
)
{
if
(
wps
->
bStop
)
{
wps
->
bStop
=
wps
->
bLoop
=
FALSE
;
while
(
left
)
{
if
(
WaitForSingleObject
(
iData
->
psStopEvent
,
0
)
==
WAIT_OBJECT_0
)
{
wps
->
bLoop
=
FALSE
;
break
;
}
count
=
mmioRead
(
hmmio
,
waveHdr
[
index
].
lpData
,
min
(
bufsize
,
left
));
...
...
@@ -515,38 +590,15 @@ errCleanUp:
if
(
hWave
)
while
(
waveOutClose
(
hWave
)
==
WAVERR_STILLPLAYING
)
Sleep
(
100
);
if
(
hmmio
)
mmioClose
(
hmmio
,
0
);
SetEvent
(
wps
->
hReadyEvent
);
iData
->
lpPlaySound
=
NULL
;
if
(
wps
->
bAlloc
)
HeapFree
(
GetProcessHeap
(),
0
,
(
void
*
)
wps
->
pszSound
);
CloseHandle
(
wps
->
hReadyEvent
);
HeapFree
(
GetProcessHeap
(),
0
,
wps
);
PlaySound_Free
(
wps
);
return
bRet
;
}
static
BOOL
MULTIMEDIA_IsString
(
DWORD
fdwSound
,
const
void
*
psz
)
{
/* SND_RESOURCE is 0x40004 while
* SND_MEMORY is 0x00004
*/
switch
(
fdwSound
&
(
SND_RESOURCE
|
SND_ALIAS
|
SND_FILENAME
))
{
case
SND_RESOURCE
:
return
HIWORD
(
psz
)
!=
0
;
/* by name or by ID ? */
case
SND_MEMORY
:
return
FALSE
;
case
SND_ALIAS
:
/* what about ALIAS_ID ??? */
case
SND_FILENAME
:
case
0
:
return
TRUE
;
default:
FIXME
(
"WTF
\n
"
);
return
FALSE
;
}
}
static
BOOL
MULTIMEDIA_PlaySound
(
const
void
*
pszSound
,
HMODULE
hmod
,
DWORD
fdwSound
,
BOOL
bUnicode
)
{
WINE_PLAYSOUND
*
wps
=
NULL
;
DWORD
id
;
LPWINE_MM_IDATA
iData
=
MULTIMEDIA_GetIData
();
BOOL
bRet
=
FALSE
;
TRACE
(
"pszSound='%p' hmod=%04X fdwSound=%08lX
\n
"
,
pszSound
,
hmod
,
fdwSound
);
...
...
@@ -554,74 +606,52 @@ static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSo
/* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP !
* there could be one if several sounds can be played at once...
*/
if
((
fdwSound
&
(
SND_NOWAIT
|
SND_NOSTOP
))
&&
iData
->
lpPlaySound
)
if
((
fdwSound
&
(
SND_NOWAIT
|
SND_NOSTOP
))
&&
iData
->
lpPlaySound
!=
NULL
)
return
FALSE
;
/* alloc internal structure, if we need to play something */
if
(
pszSound
&&
!
(
fdwSound
&
SND_PURGE
))
{
if
(
!
(
wps
=
PlaySound_Alloc
(
pszSound
,
hmod
,
fdwSound
,
bUnicode
)))
return
FALSE
;
}
do
{
HANDLE
hEvt
=
0
;
EnterCriticalSection
(
&
iData
->
cs
);
/* 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
(
iData
->
lpPlaySound
!=
NULL
)
{
ResetEvent
(
iData
->
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 */
SetEvent
(
iData
->
psStopEvent
);
/* Trying to stop if playing */
EnterCriticalSection
(
&
iData
->
cs
);
if
(
iData
->
lpPlaySound
)
{
LPWINE_PLAYSOUND
ps2stop
=
iData
->
lpPlaySound
;
hEvt
=
ps2stop
->
hReadyEvent
;
ps2stop
->
bStop
=
TRUE
;
}
LeaveCriticalSection
(
&
iData
->
cs
);
/* Waiting playing thread to get ready. I think 10 secs is ok & if not then leave
* FIXME: race here (if hEvt is destroyed and reallocated - as a handle - to
* another object)... unlikely but possible
*/
if
(
hEvt
)
WaitForSingleObject
(
hEvt
,
1000
*
10
);
WaitForSingleObject
(
iData
->
psLastEvent
,
INFINITE
);
EnterCriticalSection
(
&
iData
->
cs
);
if
(
!
pszSound
||
(
fdwSound
&
SND_PURGE
))
return
TRUE
;
/* We stopped playing so leaving */
ResetEvent
(
iData
->
psStopEvent
);
}
if
(
wps
==
NULL
)
{
wps
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
wps
));
if
(
!
wps
)
return
FALSE
;
wps
->
hMod
=
hmod
;
wps
->
fdwSound
=
fdwSound
;
wps
->
bAlloc
=
FALSE
;
if
(
MULTIMEDIA_IsString
(
fdwSound
,
pszSound
))
{
if
(
bUnicode
)
{
if
(
fdwSound
&
SND_ASYNC
)
{
wps
->
pszSound
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
lstrlenW
(
pszSound
)
+
1
)
*
sizeof
(
WCHAR
));
lstrcpyW
((
LPWSTR
)
wps
->
pszSound
,
pszSound
);
wps
->
bAlloc
=
TRUE
;
}
else
wps
->
pszSound
=
pszSound
;
}
else
{
wps
->
pszSound
=
HEAP_strdupAtoW
(
GetProcessHeap
(),
0
,
pszSound
);
wps
->
bAlloc
=
TRUE
;
}
}
else
wps
->
pszSound
=
pszSound
;
if
((
wps
->
hReadyEvent
=
CreateEventA
(
NULL
,
TRUE
,
FALSE
,
NULL
))
==
0
)
goto
cleanup
;
}
}
while
(
InterlockedCompareExchangePointer
((
void
**
)
&
iData
->
lpPlaySound
,
wps
,
NULL
)
!=
NULL
);
wps
->
lpNext
=
iData
->
lpPlaySound
;
iData
->
lpPlaySound
=
wps
;
LeaveCriticalSection
(
&
iData
->
cs
);
if
(
!
pszSound
||
(
fdwSound
&
SND_PURGE
))
return
TRUE
;
if
(
fdwSound
&
SND_ASYNC
)
{
wps
->
bLoop
=
fdwSound
&
SND_LOOP
;
/* FIXME: memory leak in case of error & cs is still locked */
return
((
wps
->
hThread
=
CreateThread
(
NULL
,
0
,
proc_PlaySound
,
wps
,
0
,
&
id
))
!=
0
);
DWORD
id
;
wps
->
bLoop
=
(
fdwSound
&
SND_LOOP
)
?
TRUE
:
FALSE
;
if
(
CreateThread
(
NULL
,
0
,
proc_PlaySound
,
wps
,
0
,
&
id
)
!=
0
)
return
TRUE
;
}
else
return
proc_PlaySound
(
wps
);
bRet
=
proc_PlaySound
(
wps
);
cleanup:
return
bRet
;
/* error cases */
PlaySound_Free
(
wps
);
return
FALSE
;
}
/**************************************************************************
...
...
dlls/winmm/winemm.h
View file @
4664903d
...
...
@@ -156,14 +156,12 @@ typedef struct tagWINE_MMIO {
}
WINE_MMIO
,
*
LPWINE_MMIO
;
typedef
struct
tagWINE_PLAYSOUND
{
HANDLE
hThread
;
HANDLE
hReadyEvent
;
BOOL
bStop
;
LPCWSTR
pszSound
;
HMODULE
hMod
;
DWORD
fdwSound
;
BOOL
bLoop
;
BOOL
bAlloc
;
BOOL
bLoop
:
1
,
bAlloc
:
1
;
LPCWSTR
pszSound
;
HMODULE
hMod
;
DWORD
fdwSound
;
struct
tagWINE_PLAYSOUND
*
lpNext
;
}
WINE_PLAYSOUND
,
*
LPWINE_PLAYSOUND
;
typedef
struct
tagWINE_MM_IDATA
{
...
...
@@ -190,7 +188,9 @@ typedef struct tagWINE_MM_IDATA {
/* mmio part */
LPWINE_MMIO
lpMMIO
;
/* playsound and sndPlaySound */
LPWINE_PLAYSOUND
lpPlaySound
;
WINE_PLAYSOUND
*
lpPlaySound
;
HANDLE
psLastEvent
;
HANDLE
psStopEvent
;
}
WINE_MM_IDATA
,
*
LPWINE_MM_IDATA
;
/* function prototypes */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment