Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
0221688c
Commit
0221688c
authored
Mar 18, 2015
by
Akihiro Sagawa
Committed by
Alexandre Julliard
Mar 18, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mciqtz32: Fix notify flag behavior.
parent
e252489a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
103 additions
and
25 deletions
+103
-25
mciqtz.c
dlls/mciqtz32/mciqtz.c
+95
-21
mciqtz_private.h
dlls/mciqtz32/mciqtz_private.h
+5
-1
mci.c
dlls/winmm/tests/mci.c
+3
-3
No files found.
dlls/mciqtz32/mciqtz.c
View file @
0221688c
...
...
@@ -85,6 +85,7 @@ static DWORD MCIQTZ_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
if
(
!
wma
)
return
0
;
wma
->
stop_event
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
modp
->
wType
=
MCI_DEVTYPE_DIGITAL_VIDEO
;
wma
->
wDevID
=
modp
->
wDeviceID
;
modp
->
wCustomCommandTable
=
wma
->
command_table
=
mciLoadCommandResource
(
MCIQTZ_hInstance
,
mciAviWStr
,
0
);
...
...
@@ -110,6 +111,7 @@ static DWORD MCIQTZ_drvClose(DWORD dwDevID)
mciFreeCommandResource
(
wma
->
command_table
);
mciSetDriverData
(
dwDevID
,
0
);
CloseHandle
(
wma
->
stop_event
);
HeapFree
(
GetProcessHeap
(),
0
,
wma
);
return
1
;
}
...
...
@@ -137,6 +139,20 @@ static DWORD MCIQTZ_drvConfigure(DWORD dwDevID)
return
1
;
}
/**************************************************************************
* MCIQTZ_mciNotify [internal]
*
* Notifications in MCI work like a 1-element queue.
* Each new notification request supersedes the previous one.
*/
static
void
MCIQTZ_mciNotify
(
DWORD_PTR
hWndCallBack
,
WINE_MCIQTZ
*
wma
,
UINT
wStatus
)
{
MCIDEVICEID
wDevID
=
wma
->
notify_devid
;
HANDLE
old
=
InterlockedExchangePointer
(
&
wma
->
callback
,
NULL
);
if
(
old
)
mciDriverNotify
(
old
,
wDevID
,
MCI_NOTIFY_SUPERSEDED
);
mciDriverNotify
(
HWND_32
(
LOWORD
(
hWndCallBack
)),
wDevID
,
wStatus
);
}
/***************************************************************************
* MCIQTZ_mciOpen [internal]
*/
...
...
@@ -307,6 +323,63 @@ static DWORD MCIQTZ_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP
}
/***************************************************************************
* MCIQTZ_notifyThread [internal]
*/
static
DWORD
CALLBACK
MCIQTZ_notifyThread
(
LPVOID
parm
)
{
WINE_MCIQTZ
*
wma
=
(
WINE_MCIQTZ
*
)
parm
;
HRESULT
hr
;
HANDLE
handle
[
2
];
DWORD
n
=
0
,
ret
=
0
;
handle
[
n
++
]
=
wma
->
stop_event
;
IMediaEvent_GetEventHandle
(
wma
->
mevent
,
(
OAEVENT
*
)
&
handle
[
n
++
]);
for
(;;)
{
DWORD
r
;
HANDLE
old
;
r
=
WaitForMultipleObjects
(
n
,
handle
,
FALSE
,
INFINITE
);
if
(
r
==
WAIT_OBJECT_0
)
{
TRACE
(
"got stop event
\n
"
);
old
=
InterlockedExchangePointer
(
&
wma
->
callback
,
NULL
);
if
(
old
)
mciDriverNotify
(
old
,
wma
->
notify_devid
,
MCI_NOTIFY_ABORTED
);
break
;
}
else
if
(
r
==
WAIT_OBJECT_0
+
1
)
{
LONG
event_code
;
LONG_PTR
p1
,
p2
;
do
{
hr
=
IMediaEvent_GetEvent
(
wma
->
mevent
,
&
event_code
,
&
p1
,
&
p2
,
0
);
if
(
SUCCEEDED
(
hr
))
{
TRACE
(
"got event_code = 0x%02x
\n
"
,
event_code
);
IMediaEvent_FreeEventParams
(
wma
->
mevent
,
event_code
,
p1
,
p2
);
}
}
while
(
hr
==
S_OK
&&
event_code
!=
EC_COMPLETE
);
if
(
hr
==
S_OK
&&
event_code
==
EC_COMPLETE
)
{
old
=
InterlockedExchangePointer
(
&
wma
->
callback
,
NULL
);
if
(
old
)
mciDriverNotify
(
old
,
wma
->
notify_devid
,
MCI_NOTIFY_SUCCESSFUL
);
break
;
}
}
else
{
TRACE
(
"Unknown error (%d)
\n
"
,
(
int
)
r
);
break
;
}
}
hr
=
IMediaControl_Stop
(
wma
->
pmctrl
);
if
(
FAILED
(
hr
))
{
TRACE
(
"Cannot stop filtergraph (hr = %x)
\n
"
,
hr
);
ret
=
MCIERR_INTERNAL
;
}
return
ret
;
}
/***************************************************************************
* MCIQTZ_mciPlay [internal]
*/
static
DWORD
MCIQTZ_mciPlay
(
UINT
wDevID
,
DWORD
dwFlags
,
LPMCI_PLAY_PARMS
lpParms
)
...
...
@@ -326,6 +399,14 @@ static DWORD MCIQTZ_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
if
(
!
wma
)
return
MCIERR_INVALID_DEVICE_ID
;
ResetEvent
(
wma
->
stop_event
);
if
(
dwFlags
&
MCI_NOTIFY
)
{
HANDLE
old
;
old
=
InterlockedExchangePointer
(
&
wma
->
callback
,
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)));
if
(
old
)
mciDriverNotify
(
old
,
wma
->
notify_devid
,
MCI_NOTIFY_ABORTED
);
}
IMediaSeeking_GetTimeFormat
(
wma
->
seek
,
&
format
);
if
(
dwFlags
&
MCI_FROM
)
{
if
(
IsEqualGUID
(
&
format
,
&
TIME_FORMAT_MEDIA_TIME
))
...
...
@@ -352,8 +433,11 @@ static DWORD MCIQTZ_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
IVideoWindow_put_Visible
(
wma
->
vidwin
,
OATRUE
);
if
(
dwFlags
&
MCI_NOTIFY
)
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wDevID
,
MCI_NOTIFY_SUCCESSFUL
);
wma
->
thread
=
CreateThread
(
NULL
,
0
,
MCIQTZ_notifyThread
,
wma
,
0
,
NULL
);
if
(
!
wma
->
thread
)
{
TRACE
(
"Can't create thread
\n
"
);
return
MCIERR_INTERNAL
;
}
return
0
;
}
...
...
@@ -397,7 +481,7 @@ static DWORD MCIQTZ_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms
}
if
(
dwFlags
&
MCI_NOTIFY
)
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wDevID
,
MCI_NOTIFY_SUCCESSFUL
);
MCIQTZ_mciNotify
(
lpParms
->
dwCallback
,
wma
,
MCI_NOTIFY_SUCCESSFUL
);
return
0
;
}
...
...
@@ -408,7 +492,6 @@ static DWORD MCIQTZ_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms
static
DWORD
MCIQTZ_mciStop
(
UINT
wDevID
,
DWORD
dwFlags
,
LPMCI_GENERIC_PARMS
lpParms
)
{
WINE_MCIQTZ
*
wma
;
HRESULT
hr
;
TRACE
(
"(%04x, %08X, %p)
\n
"
,
wDevID
,
dwFlags
,
lpParms
);
...
...
@@ -419,10 +502,11 @@ static DWORD MCIQTZ_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa
if
(
!
wma
->
opened
)
return
0
;
hr
=
IMediaControl_Stop
(
wma
->
pmctrl
);
if
(
FAILED
(
hr
))
{
TRACE
(
"Cannot stop filtergraph (hr = %x)
\n
"
,
hr
);
return
MCIERR_INTERNAL
;
if
(
wma
->
thread
)
{
SetEvent
(
wma
->
stop_event
);
WaitForSingleObject
(
wma
->
thread
,
INFINITE
);
CloseHandle
(
wma
->
thread
);
wma
->
thread
=
NULL
;
}
if
(
!
wma
->
parent
)
...
...
@@ -676,19 +760,9 @@ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMS
if
(
state
==
State_Stopped
)
lpParms
->
dwReturn
=
MAKEMCIRESOURCE
(
MCI_MODE_STOP
,
MCI_MODE_STOP
);
else
if
(
state
==
State_Running
)
{
LONG
code
;
LONG_PTR
p1
,
p2
;
lpParms
->
dwReturn
=
MAKEMCIRESOURCE
(
MCI_MODE_PLAY
,
MCI_MODE_PLAY
);
do
{
hr
=
IMediaEvent_GetEvent
(
wma
->
mevent
,
&
code
,
&
p1
,
&
p2
,
0
);
if
(
hr
==
S_OK
&&
code
==
EC_COMPLETE
){
lpParms
->
dwReturn
=
MAKEMCIRESOURCE
(
MCI_MODE_STOP
,
MCI_MODE_STOP
);
IMediaControl_Stop
(
wma
->
pmctrl
);
}
}
while
(
hr
==
S_OK
);
if
(
!
wma
->
thread
||
WaitForSingleObject
(
wma
->
thread
,
0
)
==
WAIT_OBJECT_0
)
lpParms
->
dwReturn
=
MAKEMCIRESOURCE
(
MCI_MODE_STOP
,
MCI_MODE_STOP
);
}
else
if
(
state
==
State_Paused
)
lpParms
->
dwReturn
=
MAKEMCIRESOURCE
(
MCI_MODE_PAUSE
,
MCI_MODE_PAUSE
);
ret
=
MCI_RESOURCE_RETURNED
;
...
...
@@ -714,7 +788,7 @@ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMS
}
if
(
dwFlags
&
MCI_NOTIFY
)
mciDriverNotify
(
HWND_32
(
LOWORD
(
lpParms
->
dwCallback
)),
wDevID
,
MCI_NOTIFY_SUCCESSFUL
);
MCIQTZ_mciNotify
(
lpParms
->
dwCallback
,
wma
,
MCI_NOTIFY_SUCCESSFUL
);
return
ret
;
}
...
...
dlls/mciqtz32/mciqtz_private.h
View file @
0221688c
...
...
@@ -38,7 +38,11 @@ typedef struct {
IBasicAudio
*
audio
;
DWORD
time_format
;
UINT
command_table
;
HWND
parent
;
HWND
parent
;
MCIDEVICEID
notify_devid
;
HANDLE
callback
;
HANDLE
thread
;
HANDLE
stop_event
;
}
WINE_MCIQTZ
;
#endif
/* __WINE_PRIVATE_MCIQTZ_H */
dlls/winmm/tests/mci.c
View file @
0221688c
...
...
@@ -1376,7 +1376,7 @@ static void test_asyncWaveTypeMpegvideo(HWND hwnd)
err
=
mciSendStringA
(
"status mysound mode notify"
,
buf
,
sizeof
(
buf
),
hwnd
);
ok
(
!
err
,
"mci status mode returned %s
\n
"
,
dbg_mcierr
(
err
));
if
(
!
err
)
ok
(
!
strcmp
(
buf
,
"paused"
),
"mci status mode: %s
\n
"
,
buf
);
t
odo_wine
t
est_notification
(
hwnd
,
"play (superseded)"
,
MCI_NOTIFY_SUPERSEDED
);
test_notification
(
hwnd
,
"play (superseded)"
,
MCI_NOTIFY_SUPERSEDED
);
test_notification
(
hwnd
,
"status"
,
MCI_NOTIFY_SUCCESSFUL
);
err
=
mciSendStringA
(
"seek mysound to start wait"
,
NULL
,
0
,
NULL
);
...
...
@@ -1388,11 +1388,11 @@ static void test_asyncWaveTypeMpegvideo(HWND hwnd)
err
=
mciSendStringA
(
"play mysound to 1500 notify"
,
NULL
,
0
,
hwnd
);
ok
(
!
err
,
"mci play returned %s
\n
"
,
dbg_mcierr
(
err
));
Sleep
(
200
);
t
odo_wine
t
est_notification
(
hwnd
,
"play"
,
0
);
test_notification
(
hwnd
,
"play"
,
0
);
err
=
mciSendStringA
(
"close mysound wait"
,
NULL
,
0
,
NULL
);
ok
(
!
err
,
"mci close wait returned %s
\n
"
,
dbg_mcierr
(
err
));
t
odo_wine
t
est_notification
(
hwnd
,
"play (aborted by close)"
,
MCI_NOTIFY_ABORTED
);
test_notification
(
hwnd
,
"play (aborted by close)"
,
MCI_NOTIFY_ABORTED
);
}
START_TEST
(
mci
)
...
...
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