From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 4 +++- dlls/winex11.drv/vulkan.c | 16 ++++++---------- dlls/winex11.drv/window.c | 23 +++++++++++++++++++++++ dlls/winex11.drv/x11drv.h | 1 + 4 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 97618daef65..68c8214b835 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -221,6 +221,7 @@ struct gl_drawable { LONG ref; /* reference count */ enum dc_gl_type type; /* type of GL surface */ + HWND hwnd; GLXDrawable drawable; /* drawable for rendering with GL */ Window window; /* window if drawable is a GLXWindow */ Colormap colormap; /* colormap for the client window */ @@ -1158,7 +1159,7 @@ static void release_gl_drawable( struct gl_drawable *gl ) case DC_GL_CHILD_WIN: TRACE( "destroying %lx drawable %lx\n", gl->window, gl->drawable ); pglXDestroyWindow( gdi_display, gl->drawable ); - XDestroyWindow( gdi_display, gl->window ); + destroy_client_window( gl->hwnd, gl->window ); XFreeColormap( gdi_display, gl->colormap ); break; case DC_GL_PIXMAP_WIN: @@ -1328,6 +1329,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel gl->refresh_swap_interval = TRUE; gl->format = format; gl->ref = 1; + gl->hwnd = hwnd; gl->mutable_pf = mutable_pf;
if (!known_child && !NtUserGetWindowRelative( hwnd, GW_CHILD ) && diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index 6f43164b074..4ff319c7ae2 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -101,9 +101,7 @@ static void wine_vk_surface_release( struct wine_vk_surface *surface ) pthread_mutex_unlock(&vulkan_mutex); }
- if (surface->window) - XDestroyWindow(gdi_display, surface->window); - + destroy_client_window( surface->hwnd, surface->window ); free(surface); }
@@ -193,8 +191,8 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance, ERR("Failed to allocate client window for hwnd=%p\n", create_info->hwnd);
/* VK_KHR_win32_surface only allows out of host and device memory as errors. */ - res = VK_ERROR_OUT_OF_HOST_MEMORY; - goto err; + free(x11_surface); + return VK_ERROR_OUT_OF_HOST_MEMORY; }
create_info_host.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; @@ -207,7 +205,9 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance, if (res != VK_SUCCESS) { ERR("Failed to create Xlib surface, res=%d\n", res); - goto err; + destroy_client_window( x11_surface->hwnd, x11_surface->window ); + free(x11_surface); + return res; }
pthread_mutex_lock(&vulkan_mutex); @@ -218,10 +218,6 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance,
TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*surface)); return VK_SUCCESS; - -err: - wine_vk_surface_release(x11_surface); - return res; }
static void X11DRV_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 031d754a3ef..23391b069dd 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1613,6 +1613,29 @@ static void detach_client_window( struct x11drv_win_data *data, Window client_wi }
+/********************************************************************** + * destroy_client_window + */ +void destroy_client_window( HWND hwnd, Window client_window ) +{ + struct x11drv_win_data *data; + + TRACE( "%p destroying client window %lx\n", hwnd, client_window ); + + if ((data = get_win_data( hwnd ))) + { + if (data->client_window == client_window) + { + if (data->whole_window) client_window_events_disable( data, client_window ); + data->client_window = 0; + } + release_win_data( data ); + } + + XDestroyWindow( gdi_display, client_window ); +} + + /********************************************************************** * create_client_window */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index ef736c86522..af2fe18fb26 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -650,6 +650,7 @@ extern void read_net_wm_states( Display *display, struct x11drv_win_data *data ) extern void update_net_wm_states( struct x11drv_win_data *data ); extern void make_window_embedded( struct x11drv_win_data *data ); extern Window create_client_window( HWND hwnd, const XVisualInfo *visual, Colormap colormap ); +extern void destroy_client_window( HWND hwnd, Window client_window ); extern void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis, BOOL use_alpha ); extern void change_systray_owner( Display *display, Window systray_window ); extern HWND create_foreign_window( Display *display, Window window );