From 8ca711f4286343fb4e5a8116722771a1334f60e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Wed, 7 May 2014 15:16:38 +0200 Subject: [PATCH] ddraw/tests: Test palette alpha behavior. What I care about here is that setting peFlags != 0 doesn't cause errors either during ddraw palette creation or DIB section creation. peFlags isn't an alpha channel, but P8 textures abuse it that way, hence the name of the test. It probably has deeper meaning in DDSCL_NORMAL when the X server is running in 8 bit paletteindexed mode, but I don't think we really care about this. --- dlls/ddraw/tests/ddraw1.c | 158 ++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw2.c | 166 ++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw4.c | 154 +++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw7.c | 154 +++++++++++++++++++++++++++++++++++ 4 files changed, 632 insertions(+) diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 7dd34126303..ef07b97e2e5 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -5315,6 +5315,163 @@ static void test_palette_gdi(void) DestroyWindow(window); } +static void test_palette_alpha(void) +{ + IDirectDrawSurface *surface; + DDSURFACEDESC surface_desc; + IDirectDraw *ddraw; + IDirectDrawPalette *palette; + ULONG refcount; + HWND window; + HRESULT hr; + PALETTEENTRY palette_entries[256]; + unsigned int i; + static const struct + { + DWORD caps, flags; + BOOL attach_allowed; + const char *name; + } + test_data[] = + { + {DDSCAPS_OFFSCREENPLAIN, DDSD_WIDTH | DDSD_HEIGHT, FALSE, "offscreenplain"}, + {DDSCAPS_TEXTURE, DDSD_WIDTH | DDSD_HEIGHT, TRUE, "texture"}, + {DDSCAPS_PRIMARYSURFACE, 0, FALSE, "primary"} + }; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (FAILED(hr = IDirectDraw_SetDisplayMode(ddraw, 640, 480, 8))) + { + win_skip("Failed to set 8 bpp display mode, skipping test.\n"); + IDirectDraw_Release(ddraw); + DestroyWindow(window); + return; + } + ok(SUCCEEDED(hr), "Failed to set display mode, hr %#x.\n", hr); + hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); + + memset(palette_entries, 0, sizeof(palette_entries)); + palette_entries[1].peFlags = 0x42; + palette_entries[2].peFlags = 0xff; + palette_entries[3].peFlags = 0x80; + hr = IDirectDraw_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, palette_entries, &palette, NULL); + ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); + + memset(palette_entries, 0x66, sizeof(palette_entries)); + hr = IDirectDrawPalette_GetEntries(palette, 0, 1, 4, palette_entries); + ok(SUCCEEDED(hr), "Failed to get palette entries, hr %#x.\n", hr); + ok(palette_entries[0].peFlags == 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[0].peFlags); + ok(palette_entries[1].peFlags == 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[1].peFlags); + ok(palette_entries[2].peFlags == 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n", + palette_entries[2].peFlags); + ok(palette_entries[3].peFlags == 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n", + palette_entries[3].peFlags); + + IDirectDrawPalette_Release(palette); + + memset(palette_entries, 0, sizeof(palette_entries)); + palette_entries[1].peFlags = 0x42; + palette_entries[1].peRed = 0xff; + palette_entries[2].peFlags = 0xff; + palette_entries[3].peFlags = 0x80; + hr = IDirectDraw_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT | DDPCAPS_ALPHA, + palette_entries, &palette, NULL); + ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); + + memset(palette_entries, 0x66, sizeof(palette_entries)); + hr = IDirectDrawPalette_GetEntries(palette, 0, 1, 4, palette_entries); + ok(SUCCEEDED(hr), "Failed to get palette entries, hr %#x.\n", hr); + ok(palette_entries[0].peFlags == 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[0].peFlags); + ok(palette_entries[1].peFlags == 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[1].peFlags); + ok(palette_entries[2].peFlags == 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n", + palette_entries[2].peFlags); + ok(palette_entries[3].peFlags == 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n", + palette_entries[3].peFlags); + + for (i = 0; i < sizeof(test_data) / sizeof(*test_data); i++) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | test_data[i].flags; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddsCaps.dwCaps = test_data[i].caps; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create %s surface, hr %#x.\n", test_data[i].name, hr); + + hr = IDirectDrawSurface_SetPalette(surface, palette); + if (test_data[i].attach_allowed) + ok(SUCCEEDED(hr), "Failed to attach palette to %s surface, hr %#x.\n", test_data[i].name, hr); + else + ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x, %s surface.\n", hr, test_data[i].name); + + if (SUCCEEDED(hr)) + { + HDC dc; + RGBQUAD rgbquad; + UINT retval; + + hr = IDirectDrawSurface_GetDC(surface, &dc); + ok(SUCCEEDED(hr) || broken(hr == DDERR_CANTCREATEDC) /* Win2k testbot */, + "Failed to get DC, hr %#x, %s surface.\n", hr, test_data[i].name); + if (SUCCEEDED(hr)) + { + retval = GetDIBColorTable(dc, 1, 1, &rgbquad); + ok(retval == 1, "GetDIBColorTable returned unexpected result %u.\n", retval); + ok(rgbquad.rgbRed == 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n", + rgbquad.rgbRed, test_data[i].name); + ok(rgbquad.rgbGreen == 0, "Expected rgbGreen = 0, got %#x, %s surface.\n", + rgbquad.rgbGreen, test_data[i].name); + ok(rgbquad.rgbBlue == 0, "Expected rgbBlue = 0, got %#x, %s surface.\n", + rgbquad.rgbBlue, test_data[i].name); + todo_wine ok(rgbquad.rgbReserved == 0, "Expected rgbReserved = 0, got %u, %s surface.\n", + rgbquad.rgbReserved, test_data[i].name); + hr = IDirectDrawSurface_ReleaseDC(surface, dc); + ok(SUCCEEDED(hr), "Failed to release DC, hr %#x.\n", hr); + } + } + IDirectDrawSurface_Release(surface); + } + + /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */ + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat); + surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32; + U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0x00ff0000; + U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x0000ff00; + U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x000000ff; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); + hr = IDirectDrawSurface_SetPalette(surface, palette); + ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface_Release(surface); + + /* The Windows 8 testbot keeps extra references to the primary + * while in 8 bpp mode. */ + hr = IDirectDraw_RestoreDisplayMode(ddraw); + ok(SUCCEEDED(hr), "Failed to restore display mode, hr %#x.\n", hr); + + refcount = IDirectDrawPalette_Release(palette); + ok(!refcount, "Got unexpected refcount %u.\n", refcount); + refcount = IDirectDraw_Release(ddraw); + ok(!refcount, "Got unexpected refcount %u.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw1) { IDirectDraw *ddraw; @@ -5364,4 +5521,5 @@ START_TEST(ddraw1) test_p8_rgb_blit(); test_material(); test_palette_gdi(); + test_palette_alpha(); } diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index aaef2bc6527..64aa5192240 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -6383,6 +6383,171 @@ static void test_palette_gdi(void) DestroyWindow(window); } +static void test_palette_alpha(void) +{ + IDirectDrawSurface *surface1; + IDirectDrawSurface2 *surface; + DDSURFACEDESC surface_desc; + IDirectDraw2 *ddraw; + IDirectDrawPalette *palette; + ULONG refcount; + HWND window; + HRESULT hr; + PALETTEENTRY palette_entries[256]; + unsigned int i; + static const struct + { + DWORD caps, flags; + BOOL attach_allowed; + const char *name; + } + test_data[] = + { + {DDSCAPS_OFFSCREENPLAIN, DDSD_WIDTH | DDSD_HEIGHT, FALSE, "offscreenplain"}, + {DDSCAPS_TEXTURE, DDSD_WIDTH | DDSD_HEIGHT, TRUE, "texture"}, + {DDSCAPS_PRIMARYSURFACE, 0, FALSE, "primary"} + }; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (FAILED(hr = IDirectDraw2_SetDisplayMode(ddraw, 640, 480, 8, 0, 0))) + { + win_skip("Failed to set 8 bpp display mode, skipping test.\n"); + IDirectDraw2_Release(ddraw); + DestroyWindow(window); + return; + } + ok(SUCCEEDED(hr), "Failed to set display mode, hr %#x.\n", hr); + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); + + memset(palette_entries, 0, sizeof(palette_entries)); + palette_entries[1].peFlags = 0x42; + palette_entries[2].peFlags = 0xff; + palette_entries[3].peFlags = 0x80; + hr = IDirectDraw2_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, palette_entries, &palette, NULL); + ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); + + memset(palette_entries, 0x66, sizeof(palette_entries)); + hr = IDirectDrawPalette_GetEntries(palette, 0, 1, 4, palette_entries); + ok(SUCCEEDED(hr), "Failed to get palette entries, hr %#x.\n", hr); + ok(palette_entries[0].peFlags == 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[0].peFlags); + ok(palette_entries[1].peFlags == 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[1].peFlags); + ok(palette_entries[2].peFlags == 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n", + palette_entries[2].peFlags); + ok(palette_entries[3].peFlags == 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n", + palette_entries[3].peFlags); + + IDirectDrawPalette_Release(palette); + + memset(palette_entries, 0, sizeof(palette_entries)); + palette_entries[1].peFlags = 0x42; + palette_entries[1].peRed = 0xff; + palette_entries[2].peFlags = 0xff; + palette_entries[3].peFlags = 0x80; + hr = IDirectDraw2_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT | DDPCAPS_ALPHA, + palette_entries, &palette, NULL); + ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); + + memset(palette_entries, 0x66, sizeof(palette_entries)); + hr = IDirectDrawPalette_GetEntries(palette, 0, 1, 4, palette_entries); + ok(SUCCEEDED(hr), "Failed to get palette entries, hr %#x.\n", hr); + ok(palette_entries[0].peFlags == 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[0].peFlags); + ok(palette_entries[1].peFlags == 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[1].peFlags); + ok(palette_entries[2].peFlags == 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n", + palette_entries[2].peFlags); + ok(palette_entries[3].peFlags == 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n", + palette_entries[3].peFlags); + + for (i = 0; i < sizeof(test_data) / sizeof(*test_data); i++) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | test_data[i].flags; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddsCaps.dwCaps = test_data[i].caps; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface1, NULL); + ok(SUCCEEDED(hr), "Failed to create %s surface, hr %#x.\n", test_data[i].name, hr); + hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface2, (void **)&surface); + ok(SUCCEEDED(hr), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr); + IDirectDrawSurface_Release(surface1); + + hr = IDirectDrawSurface2_SetPalette(surface, palette); + if (test_data[i].attach_allowed) + ok(SUCCEEDED(hr), "Failed to attach palette to %s surface, hr %#x.\n", test_data[i].name, hr); + else + ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x, %s surface.\n", hr, test_data[i].name); + + if (SUCCEEDED(hr)) + { + HDC dc; + RGBQUAD rgbquad; + UINT retval; + + hr = IDirectDrawSurface2_GetDC(surface, &dc); + ok(SUCCEEDED(hr) || broken(hr == DDERR_CANTCREATEDC) /* Win2k testbot */, + "Failed to get DC, hr %#x, %s surface.\n", hr, test_data[i].name); + if (SUCCEEDED(hr)) + { + retval = GetDIBColorTable(dc, 1, 1, &rgbquad); + ok(retval == 1, "GetDIBColorTable returned unexpected result %u.\n", retval); + ok(rgbquad.rgbRed == 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n", + rgbquad.rgbRed, test_data[i].name); + ok(rgbquad.rgbGreen == 0, "Expected rgbGreen = 0, got %#x, %s surface.\n", + rgbquad.rgbGreen, test_data[i].name); + ok(rgbquad.rgbBlue == 0, "Expected rgbBlue = 0, got %#x, %s surface.\n", + rgbquad.rgbBlue, test_data[i].name); + todo_wine ok(rgbquad.rgbReserved == 0, "Expected rgbReserved = 0, got %u, %s surface.\n", + rgbquad.rgbReserved, test_data[i].name); + hr = IDirectDrawSurface2_ReleaseDC(surface, dc); + ok(SUCCEEDED(hr), "Failed to release DC, hr %#x.\n", hr); + } + } + IDirectDrawSurface2_Release(surface); + } + + /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */ + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat); + surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32; + U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0x00ff0000; + U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x0000ff00; + U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x000000ff; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface1, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); + hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface2, (void **)&surface); + ok(SUCCEEDED(hr), "Failed to get IDirectDrawSurface2 interface, hr %#x.\n", hr); + IDirectDrawSurface_Release(surface1); + + hr = IDirectDrawSurface2_SetPalette(surface, palette); + ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface2_Release(surface); + + /* The Windows 8 testbot keeps extra references to the primary + * while in 8 bpp mode. */ + hr = IDirectDraw2_RestoreDisplayMode(ddraw); + ok(SUCCEEDED(hr), "Failed to restore display mode, hr %#x.\n", hr); + + refcount = IDirectDrawPalette_Release(palette); + ok(!refcount, "Got unexpected refcount %u.\n", refcount); + refcount = IDirectDraw2_Release(ddraw); + ok(!refcount, "Got unexpected refcount %u.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw2) { IDirectDraw2 *ddraw; @@ -6438,4 +6603,5 @@ START_TEST(ddraw2) test_p8_rgb_blit(); test_material(); test_palette_gdi(); + test_palette_alpha(); } diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index cc960455d7b..b760dfb65bc 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -7285,6 +7285,159 @@ static void test_palette_gdi(void) DestroyWindow(window); } +static void test_palette_alpha(void) +{ + IDirectDrawSurface4 *surface; + DDSURFACEDESC2 surface_desc; + IDirectDraw4 *ddraw; + IDirectDrawPalette *palette; + ULONG refcount; + HWND window; + HRESULT hr; + PALETTEENTRY palette_entries[256]; + unsigned int i; + static const struct + { + DWORD caps, flags; + BOOL attach_allowed; + const char *name; + } + test_data[] = + { + {DDSCAPS_OFFSCREENPLAIN, DDSD_WIDTH | DDSD_HEIGHT, FALSE, "offscreenplain"}, + {DDSCAPS_TEXTURE, DDSD_WIDTH | DDSD_HEIGHT, TRUE, "texture"}, + {DDSCAPS_PRIMARYSURFACE, 0, FALSE, "primary"} + }; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (FAILED(hr = IDirectDraw4_SetDisplayMode(ddraw, 640, 480, 8, 0, 0))) + { + win_skip("Failed to set 8 bpp display mode, skipping test.\n"); + IDirectDraw4_Release(ddraw); + DestroyWindow(window); + return; + } + ok(SUCCEEDED(hr), "Failed to set display mode, hr %#x.\n", hr); + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); + + memset(palette_entries, 0, sizeof(palette_entries)); + palette_entries[1].peFlags = 0x42; + palette_entries[2].peFlags = 0xff; + palette_entries[3].peFlags = 0x80; + hr = IDirectDraw4_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, palette_entries, &palette, NULL); + ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); + + memset(palette_entries, 0x66, sizeof(palette_entries)); + hr = IDirectDrawPalette_GetEntries(palette, 0, 1, 4, palette_entries); + ok(SUCCEEDED(hr), "Failed to get palette entries, hr %#x.\n", hr); + ok(palette_entries[0].peFlags == 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[0].peFlags); + ok(palette_entries[1].peFlags == 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[1].peFlags); + ok(palette_entries[2].peFlags == 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n", + palette_entries[2].peFlags); + ok(palette_entries[3].peFlags == 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n", + palette_entries[3].peFlags); + + IDirectDrawPalette_Release(palette); + + memset(palette_entries, 0, sizeof(palette_entries)); + palette_entries[1].peFlags = 0x42; + palette_entries[1].peRed = 0xff; + palette_entries[2].peFlags = 0xff; + palette_entries[3].peFlags = 0x80; + hr = IDirectDraw4_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT | DDPCAPS_ALPHA, + palette_entries, &palette, NULL); + ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); + + memset(palette_entries, 0x66, sizeof(palette_entries)); + hr = IDirectDrawPalette_GetEntries(palette, 0, 1, 4, palette_entries); + ok(SUCCEEDED(hr), "Failed to get palette entries, hr %#x.\n", hr); + ok(palette_entries[0].peFlags == 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[0].peFlags); + ok(palette_entries[1].peFlags == 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[1].peFlags); + ok(palette_entries[2].peFlags == 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n", + palette_entries[2].peFlags); + ok(palette_entries[3].peFlags == 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n", + palette_entries[3].peFlags); + + for (i = 0; i < sizeof(test_data) / sizeof(*test_data); i++) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | test_data[i].flags; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddsCaps.dwCaps = test_data[i].caps; + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create %s surface, hr %#x.\n", test_data[i].name, hr); + + hr = IDirectDrawSurface4_SetPalette(surface, palette); + if (test_data[i].attach_allowed) + ok(SUCCEEDED(hr), "Failed to attach palette to %s surface, hr %#x.\n", test_data[i].name, hr); + else + ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x, %s surface.\n", hr, test_data[i].name); + + if (SUCCEEDED(hr)) + { + HDC dc; + RGBQUAD rgbquad; + UINT retval; + + hr = IDirectDrawSurface4_GetDC(surface, &dc); + ok(SUCCEEDED(hr), "Failed to get DC, hr %#x, %s surface.\n", hr, test_data[i].name); + retval = GetDIBColorTable(dc, 1, 1, &rgbquad); + ok(retval == 1, "GetDIBColorTable returned unexpected result %u.\n", retval); + ok(rgbquad.rgbRed == 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n", + rgbquad.rgbRed, test_data[i].name); + ok(rgbquad.rgbGreen == 0, "Expected rgbGreen = 0, got %#x, %s surface.\n", + rgbquad.rgbGreen, test_data[i].name); + ok(rgbquad.rgbBlue == 0, "Expected rgbBlue = 0, got %#x, %s surface.\n", + rgbquad.rgbBlue, test_data[i].name); + todo_wine ok(rgbquad.rgbReserved == 0, "Expected rgbReserved = 0, got %u, %s surface.\n", + rgbquad.rgbReserved, test_data[i].name); + hr = IDirectDrawSurface4_ReleaseDC(surface, dc); + ok(SUCCEEDED(hr), "Failed to release DC, hr %#x.\n", hr); + } + IDirectDrawSurface4_Release(surface); + } + + /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */ + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); + U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32; + U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000; + U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00; + U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff; + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); + hr = IDirectDrawSurface4_SetPalette(surface, palette); + ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface4_Release(surface); + + /* The Windows 8 testbot keeps extra references to the primary + * while in 8 bpp mode. */ + hr = IDirectDraw4_RestoreDisplayMode(ddraw); + ok(SUCCEEDED(hr), "Failed to restore display mode, hr %#x.\n", hr); + + refcount = IDirectDrawPalette_Release(palette); + ok(!refcount, "Got unexpected refcount %u.\n", refcount); + refcount = IDirectDraw4_Release(ddraw); + ok(!refcount, "Got unexpected refcount %u.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw4) { IDirectDraw4 *ddraw; @@ -7346,4 +7499,5 @@ START_TEST(ddraw4) test_p8_rgb_blit(); test_material(); test_palette_gdi(); + test_palette_alpha(); } diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index fca28929d67..b61172c1dad 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -7007,6 +7007,159 @@ static void test_palette_gdi(void) DestroyWindow(window); } +static void test_palette_alpha(void) +{ + IDirectDrawSurface7 *surface; + DDSURFACEDESC2 surface_desc; + IDirectDraw7 *ddraw; + IDirectDrawPalette *palette; + ULONG refcount; + HWND window; + HRESULT hr; + PALETTEENTRY palette_entries[256]; + unsigned int i; + static const struct + { + DWORD caps, flags; + BOOL attach_allowed; + const char *name; + } + test_data[] = + { + {DDSCAPS_OFFSCREENPLAIN, DDSD_WIDTH | DDSD_HEIGHT, FALSE, "offscreenplain"}, + {DDSCAPS_TEXTURE, DDSD_WIDTH | DDSD_HEIGHT, TRUE, "texture"}, + {DDSCAPS_PRIMARYSURFACE, 0, FALSE, "primary"} + }; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (FAILED(hr = IDirectDraw7_SetDisplayMode(ddraw, 640, 480, 8, 0, 0))) + { + win_skip("Failed to set 8 bpp display mode, skipping test.\n"); + IDirectDraw7_Release(ddraw); + DestroyWindow(window); + return; + } + ok(SUCCEEDED(hr), "Failed to set display mode, hr %#x.\n", hr); + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); + + memset(palette_entries, 0, sizeof(palette_entries)); + palette_entries[1].peFlags = 0x42; + palette_entries[2].peFlags = 0xff; + palette_entries[3].peFlags = 0x80; + hr = IDirectDraw7_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, palette_entries, &palette, NULL); + ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); + + memset(palette_entries, 0x66, sizeof(palette_entries)); + hr = IDirectDrawPalette_GetEntries(palette, 0, 1, 4, palette_entries); + ok(SUCCEEDED(hr), "Failed to get palette entries, hr %#x.\n", hr); + ok(palette_entries[0].peFlags == 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[0].peFlags); + ok(palette_entries[1].peFlags == 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[1].peFlags); + ok(palette_entries[2].peFlags == 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n", + palette_entries[2].peFlags); + ok(palette_entries[3].peFlags == 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n", + palette_entries[3].peFlags); + + IDirectDrawPalette_Release(palette); + + memset(palette_entries, 0, sizeof(palette_entries)); + palette_entries[1].peFlags = 0x42; + palette_entries[1].peRed = 0xff; + palette_entries[2].peFlags = 0xff; + palette_entries[3].peFlags = 0x80; + hr = IDirectDraw7_CreatePalette(ddraw, DDPCAPS_ALLOW256 | DDPCAPS_8BIT | DDPCAPS_ALPHA, + palette_entries, &palette, NULL); + ok(SUCCEEDED(hr), "Failed to create palette, hr %#x.\n", hr); + + memset(palette_entries, 0x66, sizeof(palette_entries)); + hr = IDirectDrawPalette_GetEntries(palette, 0, 1, 4, palette_entries); + ok(SUCCEEDED(hr), "Failed to get palette entries, hr %#x.\n", hr); + ok(palette_entries[0].peFlags == 0x42, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[0].peFlags); + ok(palette_entries[1].peFlags == 0xff, "Got unexpected peFlags 0x%02x, expected 0xff.\n", + palette_entries[1].peFlags); + ok(palette_entries[2].peFlags == 0x80, "Got unexpected peFlags 0x%02x, expected 0x80.\n", + palette_entries[2].peFlags); + ok(palette_entries[3].peFlags == 0x00, "Got unexpected peFlags 0x%02x, expected 0x00.\n", + palette_entries[3].peFlags); + + for (i = 0; i < sizeof(test_data) / sizeof(*test_data); i++) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | test_data[i].flags; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddsCaps.dwCaps = test_data[i].caps; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create %s surface, hr %#x.\n", test_data[i].name, hr); + + hr = IDirectDrawSurface7_SetPalette(surface, palette); + if (test_data[i].attach_allowed) + ok(SUCCEEDED(hr), "Failed to attach palette to %s surface, hr %#x.\n", test_data[i].name, hr); + else + ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x, %s surface.\n", hr, test_data[i].name); + + if (SUCCEEDED(hr)) + { + HDC dc; + RGBQUAD rgbquad; + UINT retval; + + hr = IDirectDrawSurface7_GetDC(surface, &dc); + ok(SUCCEEDED(hr), "Failed to get DC, hr %#x, %s surface.\n", hr, test_data[i].name); + retval = GetDIBColorTable(dc, 1, 1, &rgbquad); + ok(retval == 1, "GetDIBColorTable returned unexpected result %u.\n", retval); + ok(rgbquad.rgbRed == 0xff, "Expected rgbRed = 0xff, got %#x, %s surface.\n", + rgbquad.rgbRed, test_data[i].name); + ok(rgbquad.rgbGreen == 0, "Expected rgbGreen = 0, got %#x, %s surface.\n", + rgbquad.rgbGreen, test_data[i].name); + ok(rgbquad.rgbBlue == 0, "Expected rgbBlue = 0, got %#x, %s surface.\n", + rgbquad.rgbBlue, test_data[i].name); + todo_wine ok(rgbquad.rgbReserved == 0, "Expected rgbReserved = 0, got %u, %s surface.\n", + rgbquad.rgbReserved, test_data[i].name); + hr = IDirectDrawSurface7_ReleaseDC(surface, dc); + ok(SUCCEEDED(hr), "Failed to release DC, hr %#x.\n", hr); + } + IDirectDrawSurface7_Release(surface); + } + + /* Test INVALIDSURFACETYPE vs INVALIDPIXELFORMAT. */ + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.dwWidth = 128; + surface_desc.dwHeight = 128; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat); + U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32; + U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000; + U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00; + U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); + hr = IDirectDrawSurface7_SetPalette(surface, palette); + ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface7_Release(surface); + + /* The Windows 8 testbot keeps extra references to the primary + * while in 8 bpp mode. */ + hr = IDirectDraw7_RestoreDisplayMode(ddraw); + ok(SUCCEEDED(hr), "Failed to restore display mode, hr %#x.\n", hr); + + refcount = IDirectDrawPalette_Release(palette); + ok(!refcount, "Got unexpected refcount %u.\n", refcount); + refcount = IDirectDraw7_Release(ddraw); + ok(!refcount, "Got unexpected refcount %u.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw7) { HMODULE module = GetModuleHandleA("ddraw.dll"); @@ -7075,4 +7228,5 @@ START_TEST(ddraw7) test_p8_rgb_blit(); test_material(); test_palette_gdi(); + test_palette_alpha(); }