Module: wine Branch: master Commit: d9571c9e6fa0b8f255815c5128c2859348ea70e6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d9571c9e6fa0b8f255815c5128...
Author: Chris Robinson chris.kcat@gmail.com Date: Sat Sep 15 13:02:32 2007 -0700
wgl: Store the fbconfig id with the window when a pixel format is set.
---
dlls/opengl32/tests/opengl.c | 25 +++++++++++++++++++++++++ dlls/winex11.drv/dce.c | 7 +++++++ dlls/winex11.drv/event.c | 2 ++ dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/opengl.c | 35 +++++++++++++++++++++++++++++++++++ dlls/winex11.drv/window.c | 32 ++++++++++++++++++++++++++++++++ dlls/winex11.drv/x11drv.h | 9 ++++++++- 7 files changed, 110 insertions(+), 1 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 268bece..2d08cfb 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -294,6 +294,29 @@ static void test_make_current_read(HDC hdc) ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n"); }
+static void test_dc(HWND hwnd, HDC hdc) +{ + int pf1, pf2; + HDC hdc2; + + /* Get another DC and make sure it has the same pixel format */ + hdc2 = GetDC(hwnd); + if(hdc != hdc2) + { + pf1 = GetPixelFormat(hdc); + pf2 = GetPixelFormat(hdc2); + ok(pf1 == pf2, "Second DC does not have the same format (%d != %d)\n", pf1, pf2); + } + else + skip("Could not get a different DC for the window\n"); + + if(hdc2) + { + ReleaseDC(hwnd, hdc2); + hdc2 = NULL; + } +} + START_TEST(opengl) { HWND hwnd; @@ -336,6 +359,8 @@ START_TEST(opengl) res = SetPixelFormat(hdc, iPixelFormat, &pfd); ok(res, "SetPixelformat failed: %x\n", GetLastError());
+ test_dc(hwnd, hdc); + hglrc = wglCreateContext(hdc); res = wglMakeCurrent(hdc, hglrc); ok(res, "wglMakeCurrent failed!\n"); diff --git a/dlls/winex11.drv/dce.c b/dlls/winex11.drv/dce.c index 72c5429..aa37a4a 100644 --- a/dlls/winex11.drv/dce.c +++ b/dlls/winex11.drv/dce.c @@ -148,9 +148,15 @@ static void update_visible_region( struct dce *dce )
if (top == dce->hwnd && ((data = X11DRV_get_win_data( dce->hwnd )) != NULL) && IsIconic( dce->hwnd ) && data->icon_window) + { escape.drawable = data->icon_window; + escape.fbconfig_id = 0; + } else + { escape.drawable = X11DRV_get_whole_window( top ); + escape.fbconfig_id = X11DRV_get_fbconfig_id( dce->hwnd ); + }
escape.code = X11DRV_SET_DRAWABLE; escape.mode = IncludeInferiors; @@ -185,6 +191,7 @@ static void release_dce( struct dce *dce ) escape.drawable_rect = virtual_screen_rect; SetRect( &escape.dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left, virtual_screen_rect.bottom - virtual_screen_rect.top ); + escape.fbconfig_id = 0; ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL ); }
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index f3010de..d06ade8 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -958,6 +958,8 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) return X11DRV_AcquireClipboard( hwnd ); case WM_X11DRV_DELETE_WINDOW: return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 ); + case WM_X11DRV_SET_WIN_FORMAT: + return X11DRV_set_win_format( hwnd, (XID)wp ); default: FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp ); return 0; diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 4bb44f2..0946257 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -340,6 +340,7 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *physDev, INT escape, INT in_count, LPCVOID physDev->dc_rect = data->dc_rect; physDev->drawable = data->drawable; physDev->drawable_rect = data->drawable_rect; + physDev->current_pf = pixelformat_from_fbconfig_id( data->fbconfig_id ); wine_tsx11_lock(); XSetSubwindowMode( gdi_display, physDev->gc, data->mode ); wine_tsx11_unlock(); diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 156a574..fc33143 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -935,6 +935,20 @@ static WineGLPixelFormat* ConvertPixelFormatGLXtoWGL(Display *display, int fmt_i return NULL; }
+int pixelformat_from_fbconfig_id(XID fbconfig_id) +{ + WineGLPixelFormat *fmt; + + if (!fbconfig_id) return 0; + + fmt = ConvertPixelFormatGLXtoWGL(gdi_display, fbconfig_id); + if(fmt) + return fmt->iPixelFormat; + /* This will happen on hwnds without a pixel format set; it's ok */ + return 0; +} + + /** * X11DRV_ChoosePixelFormat * @@ -1349,6 +1363,7 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev, const PIXELFORMATDESCRIPTOR *ppfd) { WineGLPixelFormat *fmt; int value; + HWND hwnd;
TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
@@ -1371,6 +1386,21 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev, return 0; }
+ pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value); + + hwnd = WindowFromDC(physDev->hdc); + if(hwnd) { + if(!(value&GLX_WINDOW_BIT)) { + WARN("Pixel format %d is not compatible for window rendering\n", iPixelFormat); + return 0; + } + + if(!SendMessageW(hwnd, WM_X11DRV_SET_WIN_FORMAT, (WPARAM)fmt->fmt_id, 0)) { + ERR("Couldn't set format of the window, returning failure\n"); + return 0; + } + } + physDev->current_pf = iPixelFormat;
if (TRACE_ON(opengl)) { @@ -3345,6 +3375,11 @@ XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
#else /* no OpenGL includes */
+int pixelformat_from_fbconfig_id(XID fbconfig_id) +{ + return 0; +} + /*********************************************************************** * ChoosePixelFormat (X11DRV.@) */ diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index e55fcfd..b0a7460 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -55,6 +55,7 @@ static XContext win_data_context;
static const char whole_window_prop[] = "__wine_x11_whole_window"; static const char icon_window_prop[] = "__wine_x11_icon_window"; +static const char fbconfig_id_prop[] = "__wine_x11_fbconfig_id"; static const char managed_prop[] = "__wine_x11_managed"; static const char visual_id_prop[] = "__wine_x11_visual_id";
@@ -166,6 +167,21 @@ void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data )
/*********************************************************************** + * X11DRV_set_win_format + */ +BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id ) +{ + struct x11drv_win_data *data; + + if (!(data = X11DRV_get_win_data(hwnd))) return FALSE; + + data->fbconfig_id = fbconfig_id; + SetPropA(hwnd, fbconfig_id_prop, (HANDLE)data->fbconfig_id); + return TRUE; +} + + +/*********************************************************************** * get_window_changes * * fill the window changes structure @@ -937,6 +953,7 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd ) data->hwnd = hwnd; data->whole_window = 0; data->icon_window = 0; + data->fbconfig_id = 0; data->xic = 0; data->managed = FALSE; data->dce = NULL; @@ -1229,6 +1246,21 @@ Window X11DRV_get_whole_window( HWND hwnd )
/*********************************************************************** + * X11DRV_get_fbconfig_id + * + * Return the GLXFBConfig ID of the drawable used by the window for + * OpenGL rendering. This is 0 for windows without a pixel format set. + */ +XID X11DRV_get_fbconfig_id( HWND hwnd ) +{ + struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); + + if (!data) return (XID)GetPropA( hwnd, fbconfig_id_prop ); + return data->fbconfig_id; +} + + +/*********************************************************************** * X11DRV_get_ic * * Return the X input context associated with a window diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 1583411..f61dc98 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -485,6 +485,7 @@ struct x11drv_escape_set_drawable int mode; /* ClipByChildren or IncludeInferiors */ RECT dc_rect; /* DC rectangle relative to drawable */ RECT drawable_rect;/* Drawable rectangle relative to screen */ + XID fbconfig_id; /* fbconfig id used by the GL drawable */ };
struct x11drv_escape_set_dce @@ -633,7 +634,8 @@ extern DWORD EVENT_x11_time_to_win32_time(Time time); enum x11drv_window_messages { WM_X11DRV_ACQUIRE_SELECTION = 0x80001000, - WM_X11DRV_DELETE_WINDOW + WM_X11DRV_DELETE_WINDOW, + WM_X11DRV_SET_WIN_FORMAT };
/* x11drv private window data */ @@ -642,6 +644,7 @@ struct x11drv_win_data HWND hwnd; /* hwnd that this private data belongs to */ Window whole_window; /* X window for the complete window */ Window icon_window; /* X window for the icon */ + XID fbconfig_id; /* fbconfig id for the GL drawable this hwnd uses */ RECT window_rect; /* USER window rectangle relative to parent */ RECT whole_rect; /* X window rectangle for the whole window relative to parent */ RECT client_rect; /* client area relative to whole window */ @@ -656,8 +659,12 @@ struct x11drv_win_data
extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd ); extern Window X11DRV_get_whole_window( HWND hwnd ); +extern XID X11DRV_get_fbconfig_id( HWND hwnd ); extern BOOL X11DRV_is_window_rect_mapped( const RECT *rect ); extern XIC X11DRV_get_ic( HWND hwnd ); +extern BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig ); + +extern int pixelformat_from_fbconfig_id( XID fbconfig_id );
extern void alloc_window_dce( struct x11drv_win_data *data ); extern void free_window_dce( struct x11drv_win_data *data );