Chris Robinson : wgl: Store the fbconfig id with the window when a pixel format is set.

Alexandre Julliard julliard at winehq.org
Tue Sep 18 05:30:57 CDT 2007


Module: wine
Branch: master
Commit: d9571c9e6fa0b8f255815c5128c2859348ea70e6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d9571c9e6fa0b8f255815c5128c2859348ea70e6

Author: Chris Robinson <chris.kcat at 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 );




More information about the wine-cvs mailing list