Alexandre Julliard : winex11: Recreate the GL drawable when changing the window parent.

Alexandre Julliard julliard at winehq.org
Wed Oct 10 15:07:52 CDT 2012


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Oct 10 10:46:16 2012 +0200

winex11: Recreate the GL drawable when changing the window parent.

---

 dlls/winex11.drv/opengl.c |  101 +++++++++++++++++++++++++++++++++++++--------
 dlls/winex11.drv/window.c |    1 +
 dlls/winex11.drv/x11drv.h |    1 +
 3 files changed, 86 insertions(+), 17 deletions(-)

diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index ac6f953..5151e20 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -1162,26 +1162,13 @@ static void free_gl_drawable( struct gl_drawable *gl )
 
 
 /***********************************************************************
- *              set_win_format
+ *              create_gl_drawable
  */
-static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
+static BOOL create_gl_drawable( HWND hwnd, HWND parent, struct gl_drawable *gl )
 {
-    HWND parent = GetAncestor( hwnd, GA_PARENT );
     XSetWindowAttributes attrib;
-    struct gl_drawable *gl, *prev;
 
-    gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) );
-    gl->format = format;
-    gl->visual = pglXGetVisualFromFBConfig( gdi_display, format->fbconfig );
-    if (!gl->visual)
-    {
-        HeapFree( GetProcessHeap(), 0, gl );
-        return FALSE;
-    }
-
-    GetClientRect( hwnd, &gl->rect );
-    gl->rect.right  = min( max( 1, gl->rect.right ), 65535 );
-    gl->rect.bottom = min( max( 1, gl->rect.bottom ), 65535 );
+    gl->drawable = 0;
 
     if (parent == GetDesktopWindow())  /* top-level window */
     {
@@ -1261,7 +1248,32 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
         }
     }
 
-    if (!gl->drawable)
+    return gl->drawable != 0;
+}
+
+
+/***********************************************************************
+ *              set_win_format
+ */
+static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
+{
+    HWND parent = GetAncestor( hwnd, GA_PARENT );
+    struct gl_drawable *gl, *prev;
+
+    gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) );
+    gl->format = format;
+    gl->visual = pglXGetVisualFromFBConfig( gdi_display, format->fbconfig );
+    if (!gl->visual)
+    {
+        HeapFree( GetProcessHeap(), 0, gl );
+        return FALSE;
+    }
+
+    GetClientRect( hwnd, &gl->rect );
+    gl->rect.right  = min( max( 1, gl->rect.right ), 65535 );
+    gl->rect.bottom = min( max( 1, gl->rect.bottom ), 65535 );
+
+    if (!create_gl_drawable( hwnd, parent, gl ))
     {
         XFree( gl->visual );
         HeapFree( GetProcessHeap(), 0, gl );
@@ -1343,6 +1355,57 @@ done:
     release_gl_drawable( gl );
 }
 
+
+/***********************************************************************
+ *              set_gl_drawable_parent
+ */
+void set_gl_drawable_parent( HWND hwnd, HWND parent )
+{
+    struct gl_drawable *gl;
+    Drawable old_drawable;
+
+    if (!(gl = get_gl_drawable( hwnd, 0 ))) return;
+
+    TRACE( "setting drawable %lx parent %p\n", gl->drawable, parent );
+
+    old_drawable = gl->drawable;
+    switch (gl->type)
+    {
+    case DC_GL_WINDOW:
+        XDestroyWindow( gdi_display, gl->drawable );
+        XFreeColormap( gdi_display, gl->colormap );
+        break;
+    case DC_GL_CHILD_WIN:
+        if (parent != GetDesktopWindow()) goto done;
+        XDestroyWindow( gdi_display, gl->drawable );
+        XFreeColormap( gdi_display, gl->colormap );
+        break;
+    case DC_GL_PIXMAP_WIN:
+        if (parent != GetDesktopWindow()) goto done;
+        pglXDestroyGLXPixmap( gdi_display, gl->drawable );
+        XFreePixmap( gdi_display, gl->pixmap );
+        break;
+    default:
+        goto done;
+    }
+
+    if (!create_gl_drawable( hwnd, parent, gl ))
+    {
+        XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context );
+        release_gl_drawable( gl );
+        XFree( gl->visual );
+        HeapFree( GetProcessHeap(), 0, gl );
+        __wine_set_pixel_format( hwnd, 0 );
+        return;
+    }
+    mark_drawable_dirty( old_drawable, gl->drawable );
+
+done:
+    release_gl_drawable( gl );
+
+}
+
+
 /***********************************************************************
  *              destroy_gl_drawable
  */
@@ -3076,6 +3139,10 @@ void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_r
 {
 }
 
+void set_gl_drawable_parent( HWND hwnd, HWND parent )
+{
+}
+
 void destroy_gl_drawable( HWND hwnd )
 {
 }
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index b0fc9a0..f5f7af5 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2002,6 +2002,7 @@ void CDECL X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent )
     }
 done:
     release_win_data( data );
+    set_gl_drawable_parent( hwnd, parent );
     fetch_icon_data( hwnd, 0, 0 );
 }
 
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 2f34098..f4ccdd2 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -568,6 +568,7 @@ extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN;
 extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN;
 
 extern void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_rect ) DECLSPEC_HIDDEN;
+extern void set_gl_drawable_parent( HWND hwnd, HWND parent ) DECLSPEC_HIDDEN;
 extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
 
 extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list