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; }
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); }
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); }