[PATCH 1/2 v2] winex11.drv: Clean up client window pointer when destroying Vulkan surface

Andrew Eikum aeikum at codeweavers.com
Wed Jun 13 10:05:18 CDT 2018


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---

v2: Use gdi_display during XDestroyWindow to mirror the XCreateWindow
in create_client_window. Patch 2/2 is unchanged.

Without this, we destroy the client_window but leave the client_window
pointer dangling in the win_data struct. Later, during
destroy_whole_window, we try to re-parent the destroyed client_window,
causing a BadWindow X error.

We do store the HWND for the client_window with XSaveContext, but it
is saved on the per-thread win_data->display handle. Since we might
not be on that same thread during destroy_client_window, we can't use
it to look up the HWND for the given client_window. So instead we have
to store the HWND in the Vulkan struct, unfortunately. The same goes
for OpenGL in the next patch.

 dlls/winex11.drv/vulkan.c | 15 +++++++++------
 dlls/winex11.drv/window.c | 16 ++++++++++++++++
 dlls/winex11.drv/x11drv.h |  1 +
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index 7e252326b5..d67ad1a564 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -46,7 +46,7 @@ typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
 
 struct wine_vk_surface
 {
-    Window window;
+    HWND hwnd;
     VkSurfaceKHR surface; /* native surface */
 };
 
@@ -179,8 +179,8 @@ static void wine_vk_surface_destroy(VkInstance instance, struct wine_vk_surface
     /* vkDestroySurfaceKHR must handle VK_NULL_HANDLE (0) for surface. */
     pvkDestroySurfaceKHR(instance, surface->surface, NULL /* allocator */);
 
-    if (surface->window)
-        XDestroyWindow(gdi_display, surface->window);
+    if (surface->hwnd)
+        destroy_client_window(surface->hwnd);
 
     heap_free(surface);
 }
@@ -246,6 +246,7 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance,
     VkResult res;
     VkXlibSurfaceCreateInfoKHR create_info_host;
     struct wine_vk_surface *x11_surface;
+    Window window;
 
     TRACE("%p %p %p %p\n", instance, create_info, allocator, surface);
 
@@ -263,8 +264,8 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance,
     if (!x11_surface)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
 
-    x11_surface->window = create_client_window(create_info->hwnd, &default_visual);
-    if (!x11_surface->window)
+    window = create_client_window(create_info->hwnd, &default_visual);
+    if (!window)
     {
         ERR("Failed to allocate client window for hwnd=%p\n", create_info->hwnd);
 
@@ -273,11 +274,13 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance,
         goto err;
     }
 
+    x11_surface->hwnd = create_info->hwnd;
+
     create_info_host.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
     create_info_host.pNext = NULL;
     create_info_host.flags = 0; /* reserved */
     create_info_host.dpy = gdi_display;
-    create_info_host.window = x11_surface->window;
+    create_info_host.window = window;
 
     res = pvkCreateXlibSurfaceKHR(instance, &create_info_host, NULL /* allocator */, &x11_surface->surface);
     if (res != VK_SUCCESS)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 5fecd9a17b..f16964cdac 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1497,6 +1497,22 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual )
 }
 
 
+/**********************************************************************
+ *		destroy_client_window
+ */
+void destroy_client_window( HWND hwnd )
+{
+    struct x11drv_win_data *data = get_win_data( hwnd );
+    if (data)
+    {
+        XDeleteContext( data->display, data->client_window, winContext );
+        XDestroyWindow( gdi_display, data->client_window );
+        data->client_window = 0;
+        release_win_data( data );
+    }
+}
+
+
 /**********************************************************************
  *		create_whole_window
  *
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 85a05a904a..a4df2b2fab 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -594,6 +594,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 ) DECLSPEC_HIDDEN;
 extern void make_window_embedded( struct x11drv_win_data *data ) DECLSPEC_HIDDEN;
 extern Window create_client_window( HWND hwnd, const XVisualInfo *visual ) DECLSPEC_HIDDEN;
+extern void destroy_client_window( HWND hwnd ) DECLSPEC_HIDDEN;
 extern void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis, BOOL use_alpha ) DECLSPEC_HIDDEN;
 extern void change_systray_owner( Display *display, Window systray_window ) DECLSPEC_HIDDEN;
 extern void update_systray_balloon_position(void) DECLSPEC_HIDDEN;
-- 
2.17.1





More information about the wine-devel mailing list