[PATCH 1/2] mciavi32: Implement MCI_BREAK (try 2)

Bruno Jesus 00cpxxx at gmail.com
Wed Mar 1 22:03:43 CST 2017


From: Bruno Jesus <bjesus at codeweavers.com>

try 2:
Test correct HWND to break

Tested with Half-Life and Worms 2. Since it requires watching a video and pressing a key and realizing that the video was skipped I believe it is hard to write a test.

Signed-off-by: Bruno Jesus <bjesus at codeweavers.com>
---
 dlls/mciavi32/mciavi.c         | 54 ++++++++++++++++++++++++++++++++++++------
 dlls/mciavi32/private_mciavi.h |  5 ++++
 2 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/dlls/mciavi32/mciavi.c b/dlls/mciavi32/mciavi.c
index 843fe2c..140b522 100644
--- a/dlls/mciavi32/mciavi.c
+++ b/dlls/mciavi32/mciavi.c
@@ -353,6 +353,7 @@ static	DWORD	MCIAVI_player(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PARMS lpP
     DWORD		numEvents = 1;
     HANDLE		events[2];
     double next_frame_us;
+    BOOL wait_audio = TRUE;
 
     EnterCriticalSection(&wma->cs);
 
@@ -419,19 +420,37 @@ static	DWORD	MCIAVI_player(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PARMS lpP
         else
             delta = 0;
 
+        /* check if the playback was cancelled */
+        if ((wma->mci_break.flags & MCI_BREAK_KEY) &&
+            (GetAsyncKeyState(wma->mci_break.parms.nVirtKey) & 0x8000))
+        {
+            if (!(wma->mci_break.flags & MCI_BREAK_HWND) ||
+                GetForegroundWindow() == wma->mci_break.parms.hwndBreak)
+            {
+                /* we queue audio blocks ahead so ignore them otherwise the audio
+                 * will keep playing until the buffer is empty */
+                wait_audio = FALSE;
+
+                TRACE("playback cancelled using break key\n");
+                break;
+            }
+        }
+
         LeaveCriticalSection(&wma->cs);
         ret = WaitForMultipleObjects(numEvents, events, FALSE, delta / 1000);
         EnterCriticalSection(&wma->cs);
         if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break;
     }
 
-    if (wma->lpWaveFormat) {
-       while (wma->dwEventCount != nHdr - 1)
-        {
-            LeaveCriticalSection(&wma->cs);
-            Sleep(100);
-            EnterCriticalSection(&wma->cs);
-        }
+    if (wma->lpWaveFormat)
+    {
+        if (wait_audio)
+            while (wma->dwEventCount != nHdr - 1)
+            {
+                LeaveCriticalSection(&wma->cs);
+                Sleep(100);
+                EnterCriticalSection(&wma->cs);
+            }
 
 	/* just to get rid of some race conditions between play, stop and pause */
 	LeaveCriticalSection(&wma->cs);
@@ -871,6 +890,26 @@ static	DWORD	MCIAVI_mciCue(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpPar
 }
 
 /******************************************************************************
+ * 				MCIAVI_mciBreak			[internal]
+ */
+static	DWORD	MCIAVI_mciBreak(UINT wDevID, DWORD dwFlags, LPMCI_BREAK_PARMS lpParms)
+{
+    WINE_MCIAVI *wma;
+
+    TRACE("(%04x, %08x, %p)\n", wDevID, dwFlags, lpParms);
+
+    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;
+
+    wma = MCIAVI_mciGetOpenDev(wDevID);
+    if (wma == NULL)		return MCIERR_INVALID_DEVICE_ID;
+
+    wma->mci_break.flags = dwFlags;
+    wma->mci_break.parms = *lpParms;
+
+    return 0;
+}
+
+/******************************************************************************
  * 				MCIAVI_mciSetAudio			[internal]
  */
 static	DWORD	MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSW lpParms)
@@ -988,6 +1027,7 @@ LRESULT CALLBACK MCIAVI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
     case MCI_WHERE:		return MCIAVI_mciWhere	   (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS)      dwParam2);
     case MCI_STEP:		return MCIAVI_mciStep      (dwDevID, dwParam1, (LPMCI_DGV_STEP_PARMS)      dwParam2);
     case MCI_CUE:		return MCIAVI_mciCue       (dwDevID, dwParam1, (LPMCI_DGV_CUE_PARMS)       dwParam2);
+    case MCI_BREAK:		return MCIAVI_mciBreak     (dwDevID, dwParam1, (LPMCI_BREAK_PARMS)         dwParam2);
 	/* Digital Video specific */
     case MCI_SETAUDIO:		return MCIAVI_mciSetAudio  (dwDevID, dwParam1, (LPMCI_DGV_SETAUDIO_PARMSW) dwParam2);
     case MCI_SIGNAL:		return MCIAVI_mciSignal    (dwDevID, dwParam1, (LPMCI_DGV_SIGNAL_PARMS)    dwParam2);
diff --git a/dlls/mciavi32/private_mciavi.h b/dlls/mciavi32/private_mciavi.h
index 4dfcc09..1b53ab8 100644
--- a/dlls/mciavi32/private_mciavi.h
+++ b/dlls/mciavi32/private_mciavi.h
@@ -76,6 +76,11 @@ typedef struct {
     DWORD               dwToVideoFrame; /* play to */
     DWORD		dwCurrAudioBlock;	/* current audio block being played */
     RECT                source, dest;
+    struct
+    {
+        DWORD flags;
+        MCI_BREAK_PARMS parms;
+    } mci_break;
     /* data for the background mechanism */
     CRITICAL_SECTION	cs;
     HANDLE              hStopEvent;
-- 
2.9.3




More information about the wine-patches mailing list