From c6e0daa200587dda0710ee0dc7135097a4bdce7e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 10 Oct 2012 10:46:16 +0200 Subject: [PATCH] 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 ac6f953b096..5151e200812 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 b0fc9a0ce07..f5f7af5349e 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 2f34098ec5d..f4ccdd2a6a6 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; -- 2.11.4.GIT