Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/tests/Makefile.in | 2 +- dlls/user32/tests/win.c | 144 +++++++++++++++++++++++++++++++++- 2 files changed, 143 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index 326c44528ec..e7f9883896f 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = user32.dll -IMPORTS = user32 gdi32 advapi32 hid dwmapi d3d9 +IMPORTS = user32 gdi32 advapi32 hid dwmapi d3d9 opengl32
C_SRCS = \ broadcast.c \ diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 0300b3745a8..20f3e2ede18 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -34,6 +34,7 @@ #include "dwmapi.h" #include "d3d9.h"
+#include "wine/wgl.h" #include "wine/test.h"
#ifndef SPI_GETDESKWALLPAPER @@ -12121,6 +12122,7 @@ static SIZE_T capture_client_surface_(int line, HWND hwnd, DWORD *surface, SIZE_ SIZE_T data_size; RECT rect; HDC hdc; + int i;
GetClientRect(hwnd, &rect); OffsetRect(&rect, -rect.left, -rect.top); @@ -12130,6 +12132,9 @@ static SIZE_T capture_client_surface_(int line, HWND hwnd, DWORD *surface, SIZE_ data_size = capture_surface_(line, hdc, 0, 0, rect.right, rect.bottom, surface, surface_size); ReleaseDC(hwnd, hdc);
+ /* clear inconsistent alpha channel (D3D R5G6B5 clear sets it, other paint ops clear it) */ + for (i = 0; i < data_size / 4; i++) surface[i] &= 0xffffff; + return data_size; }
@@ -12175,7 +12180,7 @@ static struct d3d9_context *create_d3d9_context(HWND hwnd) params.Windowed = TRUE; params.SwapEffect = D3DSWAPEFFECT_DISCARD; params.hDeviceWindow = hwnd; - params.BackBufferFormat = D3DFMT_X8R8G8B8; + params.BackBufferFormat = D3DFMT_R5G6B5; /* something incompatible with GL */ params.BackBufferWidth = rect.right; params.BackBufferHeight = rect.bottom;
@@ -12202,6 +12207,67 @@ static void destroy_d3d9_context(struct d3d9_context *ctx) free(ctx); }
+struct gl_context +{ + HWND hwnd; + HDC hdc; + HGLRC hrc; + IDirect3D9 *d3d; + IDirect3DDevice9 *device; +}; + +static struct gl_context *create_gl_context(HWND hwnd) +{ + PIXELFORMATDESCRIPTOR desc; + struct gl_context *ctx; + RECT rect; + BOOL ret; + INT pixel_format; + + if (!(ctx = malloc(sizeof(struct gl_context)))) return NULL; + + GetClientRect(hwnd, &rect); + OffsetRect(&rect, -rect.left, -rect.top); + + memset(&desc, 0, sizeof(desc)); + desc.nSize = sizeof(PIXELFORMATDESCRIPTOR); + desc.nVersion = 1; + desc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + desc.iPixelType = PFD_TYPE_RGBA; + desc.cColorBits = 32; + + ctx->hwnd = hwnd; + ctx->hdc = GetDC(hwnd); + pixel_format = ChoosePixelFormat(ctx->hdc, &desc); + ok(pixel_format, "ChoosePixelFormat returned 0, last error %u\n", GetLastError()); + ret = SetPixelFormat(ctx->hdc, pixel_format, &desc); + ok(ret, "SetPixelFormat failed, last error %u\n", GetLastError()); + ctx->hrc = wglCreateContext(ctx->hdc); + wglMakeCurrent(ctx->hdc, ctx->hrc); + glViewport(0, 0, (GLint)rect.right, (GLint)rect.bottom); + + return ctx; +} + +static void paint_gl_client_rect(struct gl_context *ctx, DWORD color) +{ + BOOL ret; + ret = wglMakeCurrent(ctx->hdc, ctx->hrc); + ok(ret, "wglMakeCurrent failed\n"); + glClearColor((color >> 16) & 0xff, (color >> 8) & 0xff, (color >> 0) & 0xff, 0); + glClear(GL_COLOR_BUFFER_BIT); + ret = SwapBuffers(ctx->hdc); + ok(ret, "SwapBuffers failed\n"); +} + +static void destroy_gl_context(struct gl_context *ctx) +{ + wglMakeCurrent(NULL, NULL); + wglDeleteContext(ctx->hrc); + ReleaseDC(ctx->hwnd, ctx->hdc); + free(ctx); +} + static void paint_client_rect(HWND hwnd, COLORREF color) { HDC hdc = GetDC(hwnd); @@ -12305,6 +12371,7 @@ static void test_surface_composition(void) DWORD layered_child_alpha_surface[ARRAY_SIZE(painted_child_surface)];
struct d3d9_context *d3d9_ctx1, *d3d9_ctx2; + struct gl_context *gl_ctx1, *gl_ctx2; BLENDFUNCTION blend_cst_alpha = { AC_SRC_OVER, 0, 0x7f, 0 }; BLENDFUNCTION blend_src_alpha = { AC_SRC_OVER, 0, 0xff, AC_SRC_ALPHA }; WNDCLASSEXW wc; @@ -12746,7 +12813,7 @@ static void test_surface_composition(void) DestroyWindow(hwnd);
- /* D3D / GDI interactions */ + /* D3D / GL / GDI interactions */
hwnd = CreateWindowW(L"surface", L"", WS_POPUP | WS_VISIBLE, 0, 0, 4, 4, 0, NULL, NULL, NULL); ok(hwnd != 0, "CreateWindowW failed, last error %u\n", GetLastError()); @@ -12770,6 +12837,44 @@ static void test_surface_composition(void) check_client_surface(hwnd, painted_surface4, sizeof(painted_surface4), TRUE); check_screen_surface(hwnd, painted_surface4, sizeof(painted_surface4), FALSE);
+ gl_ctx1 = create_gl_context(hwnd); + gl_ctx2 = create_gl_context(hwnd); + flush_events( TRUE ); + + paint_client_rect(hwnd, BGRA2RGB(COLOR1)); + check_client_surface(hwnd, painted_surface, sizeof(painted_surface), TRUE); + check_screen_surface(hwnd, painted_surface, sizeof(painted_surface), FALSE); + + paint_gl_client_rect(gl_ctx1, COLOR2); + check_client_surface(hwnd, painted_surface2, sizeof(painted_surface2), TRUE); + check_screen_surface(hwnd, painted_surface2, sizeof(painted_surface2), FALSE); + + paint_gl_client_rect(gl_ctx2, COLOR3); + check_client_surface(hwnd, painted_surface3, sizeof(painted_surface3), TRUE); + check_screen_surface(hwnd, painted_surface3, sizeof(painted_surface3), FALSE); + + paint_d3d9_client_rect(d3d9_ctx1, COLOR4); + check_client_surface(hwnd, painted_surface4, sizeof(painted_surface4), TRUE); + check_screen_surface(hwnd, painted_surface4, sizeof(painted_surface4), TRUE); + + paint_gl_client_rect(gl_ctx2, COLOR2); + check_client_surface(hwnd, painted_surface2, sizeof(painted_surface2), TRUE); + check_screen_surface(hwnd, painted_surface2, sizeof(painted_surface2), FALSE); + + paint_client_rect(hwnd, BGRA2RGB(COLOR1)); + check_client_surface(hwnd, painted_surface, sizeof(painted_surface), TRUE); + check_screen_surface(hwnd, painted_surface, sizeof(painted_surface), FALSE); + + paint_d3d9_client_rect(d3d9_ctx2, COLOR3); + check_client_surface(hwnd, painted_surface3, sizeof(painted_surface3), TRUE); + check_screen_surface(hwnd, painted_surface3, sizeof(painted_surface3), TRUE); + + paint_gl_client_rect(gl_ctx1, COLOR4); + check_client_surface(hwnd, painted_surface4, sizeof(painted_surface4), TRUE); + check_screen_surface(hwnd, painted_surface4, sizeof(painted_surface4), FALSE); + + destroy_gl_context(gl_ctx1); + destroy_gl_context(gl_ctx2); destroy_d3d9_context(d3d9_ctx1); destroy_d3d9_context(d3d9_ctx2); DestroyWindow(hwnd); @@ -12804,6 +12909,35 @@ static void test_surface_composition(void) check_client_surface(hwnd, painted_surface4, sizeof(painted_surface4), FALSE); check_screen_surface(hwnd, layered_const_surface4, sizeof(layered_const_surface4), TRUE);
+ gl_ctx1 = create_gl_context(hwnd); + gl_ctx2 = create_gl_context(hwnd); + flush_events( TRUE ); + paint_client_rect(hwnd, BGRA2RGB(COLOR1)); + check_client_surface(hwnd, painted_surface, sizeof(painted_surface), FALSE); + check_screen_surface(hwnd, layered_const_surface, sizeof(layered_const_surface), TRUE); + + paint_gl_client_rect(gl_ctx1, COLOR2); + check_client_surface(hwnd, painted_surface2, sizeof(painted_surface2), FALSE); + check_screen_surface(hwnd, layered_const_surface2, sizeof(layered_const_surface2), TRUE); + + paint_d3d9_client_rect(d3d9_ctx1, COLOR3); + check_client_surface(hwnd, painted_surface3, sizeof(painted_surface3), TRUE); + check_screen_surface(hwnd, layered_const_surface3, sizeof(layered_const_surface3), TRUE); + + paint_gl_client_rect(gl_ctx2, COLOR4); + check_client_surface(hwnd, painted_surface4, sizeof(painted_surface4), FALSE); + check_screen_surface(hwnd, layered_const_surface4, sizeof(layered_const_surface4), TRUE); + + paint_client_rect(hwnd, BGRA2RGB(COLOR2)); + check_client_surface(hwnd, painted_surface2, sizeof(painted_surface2), FALSE); + check_screen_surface(hwnd, layered_const_surface2, sizeof(layered_const_surface2), TRUE); + + paint_d3d9_client_rect(d3d9_ctx2, COLOR1); + check_client_surface(hwnd, painted_surface, sizeof(painted_surface), TRUE); + check_screen_surface(hwnd, layered_const_surface, sizeof(layered_const_surface), TRUE); + + destroy_gl_context(gl_ctx1); + destroy_gl_context(gl_ctx2); destroy_d3d9_context(d3d9_ctx1); destroy_d3d9_context(d3d9_ctx2); DestroyWindow(hwnd); @@ -12814,6 +12948,7 @@ static void test_surface_composition(void) hwnd = CreateWindowW(L"surface", L"", WS_POPUP, 0, 0, 4, 4, 0, NULL, NULL, NULL); ok(hwnd != 0, "CreateWindowW failed, last error %u\n", GetLastError()); d3d9_ctx1 = create_d3d9_context(hwnd); + gl_ctx1 = create_gl_context(hwnd);
SetWindowLongW(hwnd, GWL_EXSTYLE, GetWindowLongW(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); ret = UpdateLayeredWindow(hwnd, hdc_dst, NULL, (SIZE *)&rect.right, hdc_src, (POINT *)&rect.left, 0, NULL, ULW_OPAQUE); @@ -12825,6 +12960,10 @@ static void test_surface_composition(void) check_client_surface(hwnd, hidden_surface, sizeof(hidden_surface), TRUE); check_screen_surface(hwnd, painted_child_surface, sizeof(painted_child_surface), TRUE);
+ paint_gl_client_rect(gl_ctx1, COLOR1); + check_client_surface(hwnd, hidden_surface, sizeof(hidden_surface), TRUE); + check_screen_surface(hwnd, painted_child_surface, sizeof(painted_child_surface), TRUE); + paint_d3d9_client_rect(d3d9_ctx1, COLOR2); check_client_surface(hwnd, hidden_surface, sizeof(hidden_surface), TRUE); check_screen_surface(hwnd, painted_child_surface, sizeof(painted_child_surface), TRUE); @@ -12833,6 +12972,7 @@ static void test_surface_composition(void) check_client_surface(hwnd, hidden_surface, sizeof(hidden_surface), TRUE); check_screen_surface(hwnd, painted_child_surface, sizeof(painted_child_surface), TRUE);
+ destroy_gl_context(gl_ctx1); destroy_d3d9_context(d3d9_ctx1); DestroyWindow(hwnd);