[PATCH 1/2] winex11: fix destroying of top-level windows v3
Miklós Máté
mtmkls at gmail.com
Wed Jul 20 16:35:55 CDT 2016
Fixes https://bugs.winehq.org/show_bug.cgi?id=40767
v2: move glXDestroyWindow before XDestroyWindow
v3: fix critical section, fix command serialization with xsync
Signed-off-by: Miklós Máté <mtmkls at gmail.com>
---
dlls/winex11.drv/opengl.c | 35 +++++++++++++++++++++++++++++------
dlls/winex11.drv/window.c | 1 -
2 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index d89a193..86b91ec 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -1314,6 +1314,9 @@ static void free_gl_drawable( struct gl_drawable *gl )
{
switch (gl->type)
{
+ case DC_GL_WINDOW:
+ pglXDestroyWindow( gdi_display, gl->drawable );
+ break;
case DC_GL_CHILD_WIN:
pglXDestroyWindow( gdi_display, gl->drawable );
XDestroyWindow( gdi_display, gl->window );
@@ -1334,21 +1337,21 @@ static void free_gl_drawable( struct gl_drawable *gl )
/***********************************************************************
* create_gl_drawable
*/
-static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl )
+static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl, struct x11drv_win_data *data )
{
gl->drawable = 0;
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */
{
- struct x11drv_win_data *data = get_win_data( hwnd );
-
if (data)
{
gl->type = DC_GL_WINDOW;
gl->window = create_client_window( data, gl->visual );
if (gl->window)
+ {
gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL );
- release_win_data( data );
+ XSync( gdi_display, False );
+ }
}
}
#ifdef SONAME_LIBXCOMPOSITE
@@ -1416,6 +1419,8 @@ static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl )
static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
{
struct gl_drawable *gl, *prev;
+ Window old_client_window;
+ struct x11drv_win_data *data;
gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) );
/* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI
@@ -1435,12 +1440,19 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
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, gl ))
+ data = get_win_data( hwnd );
+ if (data) {
+ old_client_window = data->client_window;
+ }
+
+ if (!create_gl_drawable( hwnd, gl, data ))
{
+ release_win_data( data );
XFree( gl->visual );
HeapFree( GetProcessHeap(), 0, gl );
return FALSE;
}
+ release_win_data( data );
TRACE( "created GL drawable %lx for win %p %s\n",
gl->drawable, hwnd, debugstr_fbconfig( format->fbconfig ));
@@ -1452,6 +1464,10 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
{
gl->swap_interval = prev->swap_interval;
free_gl_drawable( prev );
+ XSync( gdi_display, False );
+ if (old_client_window) {
+ XDestroyWindow( data->display, old_client_window );
+ }
}
XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)gl );
LeaveCriticalSection( &context_section );
@@ -1566,6 +1582,7 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent )
{
struct gl_drawable *gl;
GLXDrawable old_drawable;
+ struct x11drv_win_data *data;
if (!(gl = get_gl_drawable( hwnd, 0 ))) return;
@@ -1575,6 +1592,7 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent )
switch (gl->type)
{
case DC_GL_WINDOW:
+ pglXDestroyWindow( gdi_display, gl->drawable );
break;
case DC_GL_CHILD_WIN:
if (parent != GetDesktopWindow()) goto done;
@@ -1590,16 +1608,20 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent )
default:
goto done;
}
+ XSync( gdi_display, False );
- if (!create_gl_drawable( hwnd, gl ))
+ data = get_win_data( hwnd );
+ if (!create_gl_drawable( hwnd, gl, data ))
{
XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context );
+ release_win_data( data );
release_gl_drawable( gl );
XFree( gl->visual );
HeapFree( GetProcessHeap(), 0, gl );
__wine_set_pixel_format( hwnd, 0 );
return;
}
+ release_win_data( data );
mark_drawable_dirty( old_drawable, gl->drawable );
done:
@@ -1620,6 +1642,7 @@ void destroy_gl_drawable( HWND hwnd )
{
XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context );
free_gl_drawable( gl );
+ XSync( gdi_display, False );
}
LeaveCriticalSection( &context_section );
}
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 31ffefe..1dc478c 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1437,7 +1437,6 @@ Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *vi
if (data->client_window)
{
XDeleteContext( data->display, data->client_window, winContext );
- XDestroyWindow( data->display, data->client_window );
}
if (data->colormap) XFreeColormap( data->display, data->colormap );
--
2.8.1
More information about the wine-patches
mailing list