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

This commit is contained in:
Alexandre Julliard 2012-10-10 10:46:16 +02:00
parent 47983d819f
commit c6e0daa200
3 changed files with 86 additions and 17 deletions

View File

@ -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; XSetWindowAttributes attrib;
struct gl_drawable *gl, *prev;
gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) ); gl->drawable = 0;
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 (parent == GetDesktopWindow()) /* top-level window */ 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 ); XFree( gl->visual );
HeapFree( GetProcessHeap(), 0, gl ); HeapFree( GetProcessHeap(), 0, gl );
@ -1343,6 +1355,57 @@ done:
release_gl_drawable( gl ); 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 * 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 ) void destroy_gl_drawable( HWND hwnd )
{ {
} }

View File

@ -2002,6 +2002,7 @@ void CDECL X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent )
} }
done: done:
release_win_data( data ); release_win_data( data );
set_gl_drawable_parent( hwnd, parent );
fetch_icon_data( hwnd, 0, 0 ); fetch_icon_data( hwnd, 0, 0 );
} }

View File

@ -568,6 +568,7 @@ extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern XIC X11DRV_get_ic( 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 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 destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ) DECLSPEC_HIDDEN; extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ) DECLSPEC_HIDDEN;