Alexandre Julliard : winex11: Add a DestroyNotify handler to catch a situation that is not supposed to happen .

Alexandre Julliard julliard at winehq.org
Wed Mar 5 13:41:12 CST 2008


Module: wine
Branch: master
Commit: 3b6f95c663b22f1ab2d3c107764a71dcb48d735c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3b6f95c663b22f1ab2d3c107764a71dcb48d735c

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Mar  5 16:51:09 2008 +0100

winex11: Add a DestroyNotify handler to catch a situation that is not supposed to happen.

---

 dlls/winex11.drv/event.c  |    4 ++--
 dlls/winex11.drv/window.c |   27 +++++++++++++++++++++++----
 dlls/winex11.drv/x11drv.h |    1 +
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 30f0c57..3373cf7 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -103,7 +103,7 @@ static struct event_handler handlers[MAX_EVENT_HANDLERS] =
     /* NoExpose */
     /* VisibilityNotify */
     /* CreateNotify */
-    /* DestroyNotify */
+    { DestroyNotify,    X11DRV_DestroyNotify },
     { UnmapNotify,      X11DRV_UnmapNotify },
     { MapNotify,        X11DRV_MapNotify },
     /* MapRequest */
@@ -123,7 +123,7 @@ static struct event_handler handlers[MAX_EVENT_HANDLERS] =
     { MappingNotify,    X11DRV_MappingNotify },
 };
 
-static int nb_event_handlers = 18;  /* change this if you add handlers above */
+static int nb_event_handlers = 19;  /* change this if you add handlers above */
 
 
 /* return the name of an X event */
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index d454b9b..b98c6d8 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1201,7 +1201,7 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
  *
  * Destroy the whole X window for a given window.
  */
-static void destroy_whole_window( Display *display, struct x11drv_win_data *data )
+static void destroy_whole_window( Display *display, struct x11drv_win_data *data, BOOL already_destroyed )
 {
     struct x11drv_thread_data *thread_data = x11drv_thread_data();
 
@@ -1214,12 +1214,16 @@ static void destroy_whole_window( Display *display, struct x11drv_win_data *data
     wine_tsx11_lock();
     XDeleteContext( display, data->whole_window, winContext );
     XDeleteContext( display, data->client_window, winContext );
-    XDestroyWindow( display, data->whole_window );
+    if (!already_destroyed) XDestroyWindow( display, data->whole_window );
     data->whole_window = data->client_window = 0;
+    data->wm_state = WithdrawnState;
+    data->net_wm_state = 0;
+    data->mapped = FALSE;
     if (data->xic)
     {
         XUnsetICFocus( data->xic );
         XDestroyIC( data->xic );
+        data->xic = 0;
     }
     /* Outlook stops processing messages after destroying a dialog, so we need an explicit flush */
     XFlush( display );
@@ -1269,7 +1273,7 @@ void X11DRV_DestroyWindow( HWND hwnd )
         wine_tsx11_unlock();
     }
 
-    destroy_whole_window( display, data );
+    destroy_whole_window( display, data, FALSE );
     destroy_icon_window( display, data );
 
     if (data->colormap)
@@ -1289,6 +1293,21 @@ void X11DRV_DestroyWindow( HWND hwnd )
 }
 
 
+/***********************************************************************
+ *		X11DRV_DestroyNotify
+ */
+void X11DRV_DestroyNotify( HWND hwnd, XEvent *event )
+{
+    Display *display = event->xdestroywindow.display;
+    struct x11drv_win_data *data;
+
+    if (!(data = X11DRV_get_win_data( hwnd ))) return;
+
+    FIXME( "window %p/%lx destroyed from the outside\n", hwnd, data->whole_window );
+    destroy_whole_window( display, data, TRUE );
+}
+
+
 static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd )
 {
     struct x11drv_win_data *data;
@@ -1562,7 +1581,7 @@ void X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent )
         if (old_parent == GetDesktopWindow())
         {
             /* destroy the old X windows */
-            destroy_whole_window( display, data );
+            destroy_whole_window( display, data, FALSE );
             destroy_icon_window( display, data );
             if (data->managed)
             {
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 7b61d95..59685e9 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -626,6 +626,7 @@ extern void X11DRV_EnterNotify( HWND hwnd, XEvent *event );
 extern void X11DRV_KeyEvent( HWND hwnd, XEvent *event );
 extern void X11DRV_KeymapNotify( HWND hwnd, XEvent *event );
 extern void X11DRV_Expose( HWND hwnd, XEvent *event );
+extern void X11DRV_DestroyNotify( HWND hwnd, XEvent *event );
 extern void X11DRV_MapNotify( HWND hwnd, XEvent *event );
 extern void X11DRV_UnmapNotify( HWND hwnd, XEvent *event );
 extern void X11DRV_ConfigureNotify( HWND hwnd, XEvent *event );




More information about the wine-cvs mailing list