Module: wine Branch: master Commit: c6e0daa200587dda0710ee0dc7135097a4bdce7e URL: http://source.winehq.org/git/wine.git/?a=commit;h=c6e0daa200587dda0710ee0dc7...
Author: Alexandre Julliard julliard@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;