boolean Overlay( LPDIRECTDRAWSURFACE7 src_surface, RECT * src_rect,
			 LPDIRECTDRAWSURFACE7 dst_surface, RECT * dst_rect,
			 COLORREF color_key )
{
    DWORD					dw_color_key;
    DDPIXELFORMAT			ddpf;
	DDOVERLAYFX				ddofx;	
	int						flags;
	HRESULT					result;

	// compute the colorkey pixel value from the RGB value we've got/
	// NOTE : based on videolan colorkey code

    memset( &ddpf, 0, sizeof( DDPIXELFORMAT ));
    ddpf.dwSize = sizeof( DDPIXELFORMAT );
    result = IDirectDrawSurface7_GetPixelFormat( dst_surface, &ddpf );
	if( result != DD_OK )
	{
		Error( 0, "IDirectDrawSurface7_GetPixelFormat : could not get surface pixel format" );
		return FALSE;
	}

    dw_color_key = ( DWORD ) color_key;
    dw_color_key = ( DWORD ) ( ( ( dw_color_key * ddpf.dwRBitMask ) / 255 ) & ddpf.dwRBitMask );

    memset( &ddofx, 0, sizeof( DDOVERLAYFX ) );
    ddofx.dwSize = sizeof( DDOVERLAYFX );
    ddofx.dckDestColorkey.dwColorSpaceLowValue = dw_color_key;
    ddofx.dckDestColorkey.dwColorSpaceHighValue = dw_color_key;

	// set our overlay flags

    flags = DDOVER_SHOW | DDOVER_KEYDESTOVERRIDE;

	// attempt to overlay the surface

	result = IDirectDrawSurface7_UpdateOverlay( src_surface, src_rect, dst_surface, dst_rect, flags, &ddofx );
	if( result != DD_OK )
	{
		if( result == DDERR_SURFACELOST )
	    {
			IDirectDrawSurface7_Restore( src_surface );
			IDirectDrawSurface7_Restore( dst_surface );

			IDirectDrawSurface7_UpdateOverlay( src_surface, src_rect, dst_surface, dst_rect, flags, &ddofx );
		}
		else
		{
			Error( 0, "IDirectDrawSurface7_UpdateOverlay : error %i", result );
			return FALSE;
		}
	}

	return TRUE;
}
Exemple #2
0
static void offscreen_test(void) {
    IDirectDrawSurface7 *overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y')), *offscreen = NULL;
    HRESULT hr;
    DDSURFACEDESC2 ddsd;

    /* Try to overlay a NULL surface */
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, NULL, NULL, DDOVER_SHOW, NULL);
    ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, NULL, NULL, DDOVER_HIDE, NULL);
    ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);

    /* Try to overlay an offscreen surface */
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
    ddsd.dwWidth = 64;
    ddsd.dwHeight = 64;
    U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
    U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
    U4(ddsd).ddpfPixelFormat.dwFourCC = 0;
    U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
    U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
    U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07e0;
    U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &offscreen, NULL);
    ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed with hr=0x%08x\n", hr);

    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, offscreen, NULL, DDOVER_SHOW, NULL);
    ok(hr == DD_OK || broken(hr == E_NOTIMPL),
       "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);

    /* Try to overlay the primary with a non-overlay surface */
    hr = IDirectDrawSurface7_UpdateOverlay(offscreen, NULL, primary, NULL, DDOVER_SHOW, NULL);
    ok(hr == DDERR_NOTAOVERLAYSURFACE, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);

    IDirectDrawSurface7_Release(offscreen);
    IDirectDrawSurface7_Release(overlay);
}
Exemple #3
0
static void rectangle_settings(void) {
    IDirectDrawSurface7 *overlay = create_overlay(64, 64, MAKEFOURCC('U','Y','V','Y'));
    HRESULT hr, hr2;
    RECT rect = {0, 0, 64, 64};
    LONG posx, posy;

    /* The dx sdk sort of implies that rect must be set when DDOVER_SHOW is used. This is not true
     * in Windows Vista and earlier, but changed in Win7 */
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_SHOW, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, DDOVER_HIDE, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, DDOVER_SHOW, NULL);
    ok(hr == DD_OK || hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);

    /* Show that the overlay position is the (top, left) coordinate of the dest rectangle */
    rect.top += 16;
    rect.left += 32;
    rect.bottom += 16;
    rect.right += 32;
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_SHOW, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    posx = -1; posy = -1;
    hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
    ok(hr == DD_OK, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
    ok(posx == rect.left && posy == rect.top, "Overlay position is (%d, %d), expected (%d, %d)\n",
       posx, posy, rect.left, rect.top);

    /* Passing a NULL dest rect sets the position to 0/0 . Visually it can be seen that the overlay overlays the whole primary(==screen)*/
    hr2 = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, NULL, 0, NULL);
    ok(hr2 == DD_OK || hr2 == DDERR_INVALIDPARAMS
            || hr2 == DDERR_OUTOFCAPS, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr2);
    hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
    ok(hr == DD_OK, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
    if (SUCCEEDED(hr2))
    {
        ok(posx == 0 && posy == 0, "Overlay position is (%d, %d), expected (%d, %d)\n",
                posx, posy, 0, 0);
    }
    else
    {
        /* Otherwise the position remains untouched */
        ok(posx == 32 && posy == 16, "Overlay position is (%d, %d), expected (%d, %d)\n",
                posx, posy, 32, 16);
    }
    /* The position cannot be retrieved when the overlay is not shown */
    hr = IDirectDrawSurface7_UpdateOverlay(overlay, NULL, primary, &rect, DDOVER_HIDE, NULL);
    ok(hr == DD_OK, "IDirectDrawSurface7_UpdateOverlay failed with hr=0x%08x\n", hr);
    posx = -1; posy = -1;
    hr = IDirectDrawSurface7_GetOverlayPosition(overlay, &posx, &posy);
    ok(hr == DDERR_OVERLAYNOTVISIBLE, "IDirectDrawSurface7_GetOverlayPosition failed with hr=0x%08x\n", hr);
    ok(posx == 0 && posy == 0, "Overlay position is (%d, %d), expected (%d, %d)\n",
       posx, posy, 0, 0);

    IDirectDrawSurface7_Release(overlay);
}