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

Andrew Eikum aeikum at codeweavers.com
Mon Mar 6 08:21:17 CST 2017


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

On Mon, Mar 06, 2017 at 01:24:27AM -0300, Bruno Jesus wrote:
> From: Bruno Jesus <bjesus at codeweavers.com>
> 
> try 3:
> Protect wma struct changes with critical section as requested by Andrew Eikum
> 
> 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         | 58 +++++++++++++++++++++++++++++++++++++-----
>  dlls/mciavi32/private_mciavi.h |  5 ++++
>  2 files changed, 56 insertions(+), 7 deletions(-)
> 
> diff --git a/dlls/mciavi32/mciavi.c b/dlls/mciavi32/mciavi.c
> index fc50a5e..0b340e8 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,30 @@ 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;
> +
> +    EnterCriticalSection(&wma->cs);
> +
> +    wma->mci_break.flags = dwFlags;
> +    wma->mci_break.parms = *lpParms;
> +
> +    LeaveCriticalSection(&wma->cs);
> +
> +    return 0;
> +}
> +
> +/******************************************************************************
>   * 				MCIAVI_mciSetAudio			[internal]
>   */
>  static	DWORD	MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSW lpParms)
> @@ -988,6 +1031,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