From 2043c42cef5a73cc145cad4370b8314fb0bb42c7 Mon Sep 17 00:00:00 2001 From: Ove Kaaven Date: Tue, 17 Apr 2001 17:34:11 +0000 Subject: [PATCH] Implemented gamma control on the DirectDraw primary window. Ensured that the primary window is created before the constructor returns. Flag the primary window as transparent so mouse clicks pass through it. Put the primary window handle into a reserved field for x11drv HAL use. --- dlls/ddraw/dsurface/user.c | 76 +++++++++++++++++++++++++++++++++++--- dlls/ddraw/dsurface/user.h | 9 ++++- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/dlls/ddraw/dsurface/user.c b/dlls/ddraw/dsurface/user.c index b919fb6ff78..9001e739f9c 100644 --- a/dlls/ddraw/dsurface/user.c +++ b/dlls/ddraw/dsurface/user.c @@ -1,6 +1,6 @@ /* User-based primary surface driver * - * Copyright 2000 TransGaming Technologies Inc. + * Copyright 2000-2001 TransGaming Technologies Inc. */ #include "config.h" @@ -21,7 +21,7 @@ DEFAULT_DEBUG_CHANNEL(ddraw); /* if you use OWN_WINDOW, don't use SYNC_UPDATE, or you may get trouble */ /* #define SYNC_UPDATE */ -#define OWN_WINDOW +#define OWN_WINDOW #ifdef OWN_WINDOW static void User_create_own_window(IDirectDrawSurfaceImpl* This); @@ -33,6 +33,8 @@ static DWORD CALLBACK User_update_thread(LPVOID); static void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc); static void User_copy_from_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc); +static HWND get_display_window(IDirectDrawSurfaceImpl* This, LPPOINT pt); + static ICOM_VTABLE(IDirectDrawSurface7) User_IDirectDrawSurface7_VTable; HRESULT @@ -65,18 +67,36 @@ User_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This, This->set_palette = User_DirectDrawSurface_set_palette; This->update_palette = User_DirectDrawSurface_update_palette; + This->get_gamma_ramp = User_DirectDrawSurface_get_gamma_ramp; + This->set_gamma_ramp = User_DirectDrawSurface_set_gamma_ramp; + This->get_display_window = User_DirectDrawSurface_get_display_window; if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { +#ifdef OWN_WINDOW + DirectDrawSurface_RegisterClass(); +#endif #ifndef SYNC_UPDATE priv->user.update_event = CreateEventA(NULL, FALSE, FALSE, NULL); priv->user.update_thread = CreateThread(NULL, 0, User_update_thread, This, 0, NULL); +#ifdef OWN_WINDOW + if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) { + /* wait for window creation (or update thread destruction) */ + while (WaitForMultipleObjects(1, &priv->user.update_thread, FALSE, 10) == WAIT_TIMEOUT) + if (This->more.lpDDRAWReserved) break; + if (!This->more.lpDDRAWReserved) { + ERR("window creation failed\n"); + } + } +#endif #else #ifdef OWN_WINDOW User_create_own_window(This); #endif #endif + if (!This->more.lpDDRAWReserved) + This->more.lpDDRAWReserved = (LPVOID)pDD->window; } return DIB_DirectDrawSurface_alloc_dc(This, &priv->user.cached_dc); @@ -141,6 +161,10 @@ void User_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This) #ifdef OWN_WINDOW User_destroy_own_window(This); #endif +#endif + This->more.lpDDRAWReserved = 0; +#ifdef OWN_WINDOW + DirectDrawSurface_UnregisterClass(); #endif } DIB_DirectDrawSurface_free_dc(This, priv->user.cached_dc); @@ -248,6 +272,44 @@ HRESULT User_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This, return S_OK; } +HRESULT User_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This, + DWORD dwFlags, + LPDDGAMMARAMP lpGammaRamp) +{ + if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { + POINT offset; + HWND hDisplayWnd; + HDC hDisplayDC; + HRESULT hr; + hDisplayWnd = get_display_window(This, &offset); + hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS); + hr = GetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; + ReleaseDC(hDisplayWnd, hDisplayDC); + return hr; + } + return Main_DirectDrawSurface_get_gamma_ramp(This, dwFlags, lpGammaRamp); +} + +HRESULT User_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This, + DWORD dwFlags, + LPDDGAMMARAMP lpGammaRamp) +{ + if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { + POINT offset; + HWND hDisplayWnd; + HDC hDisplayDC; + HRESULT hr; + hDisplayWnd = get_display_window(This, &offset); + hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS); + hr = SetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; + ReleaseDC(hDisplayWnd, hDisplayDC); + return hr; + } + return Main_DirectDrawSurface_set_gamma_ramp(This, dwFlags, lpGammaRamp); +} + /* Returns the window that hosts the display. * *pt is set to the upper left position of the window relative to the * upper left corner of the surface. */ @@ -259,9 +321,11 @@ static HWND get_display_window(IDirectDrawSurfaceImpl* This, LPPOINT pt) { #ifdef OWN_WINDOW USER_PRIV_VAR(priv, This); +#if 1 SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0, SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE| SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE); +#endif return priv->user.window; #else return This->ddraw_owner->window; @@ -310,8 +374,9 @@ static void User_create_own_window(IDirectDrawSurfaceImpl* This) if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) { - DirectDrawSurface_RegisterClass(); - priv->user.window = CreateWindowExA(WS_EX_TOPMOST, + priv->user.window = CreateWindowExA(WS_EX_TOPMOST | + WS_EX_LAYERED | + WS_EX_TRANSPARENT, "WINE_DDRAW", "DirectDraw", WS_POPUP, 0, 0, @@ -319,6 +384,7 @@ static void User_create_own_window(IDirectDrawSurfaceImpl* This) This->surface_desc.dwHeight, GetDesktopWindow(), 0, 0, This); + This->more.lpDDRAWReserved = (LPVOID)priv->user.window; SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0, SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE| SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_SHOWWINDOW); @@ -335,8 +401,8 @@ static void User_destroy_own_window(IDirectDrawSurfaceImpl* This) SetWindowPos(priv->user.window, 0, 0, 0, 0, 0, SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOZORDER| SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_HIDEWINDOW); + This->more.lpDDRAWReserved = NULL; DestroyWindow(priv->user.window); - DirectDrawSurface_UnregisterClass(); priv->user.window = 0; } } diff --git a/dlls/ddraw/dsurface/user.h b/dlls/ddraw/dsurface/user.h index 9f12307ddbd..bdbe88dfa9c 100644 --- a/dlls/ddraw/dsurface/user.h +++ b/dlls/ddraw/dsurface/user.h @@ -1,4 +1,4 @@ -/* Copyright 2000 TransGaming Technologies Inc. */ +/* Copyright 2000-2001 TransGaming Technologies Inc. */ #ifndef DDRAW_DSURFACE_USER_H_INCLUDED #define DDRAW_DSURFACE_USER_H_INCLUDED @@ -57,4 +57,11 @@ HRESULT User_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC); HRESULT User_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This, HDC hDC); +HRESULT User_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This, + DWORD dwFlags, + LPDDGAMMARAMP lpGammaRamp); +HRESULT User_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This, + DWORD dwFlags, + LPDDGAMMARAMP lpGammaRamp); + #endif