Alexandre Julliard : winex11: Add window data structure locking to the map/ unmap functions.

Alexandre Julliard julliard at winehq.org
Fri Sep 21 14:22:40 CDT 2012


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Sep 21 16:50:17 2012 +0200

winex11: Add window data structure locking to the map/unmap functions.

---

 dlls/winex11.drv/event.c  |   60 +++++++++++++++++++++++------------
 dlls/winex11.drv/window.c |   76 ++++++++++++++++++++++++++-------------------
 2 files changed, 84 insertions(+), 52 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 1f49c3c..4e4b816 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -1163,7 +1163,7 @@ static int get_window_wm_state( Display *display, Window window )
  */
 static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL update_window )
 {
-    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+    struct x11drv_win_data *data = get_win_data( hwnd );
     DWORD style;
 
     if (!data) return;
@@ -1185,13 +1185,13 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
                 data->wm_state = new_state;
                 /* ignore the initial state transition out of withdrawn state */
                 /* metacity does Withdrawn->NormalState->IconicState when mapping an iconic window */
-                if (!old_state) return;
+                if (!old_state) goto done;
             }
         }
         break;
     }
 
-    if (!update_window || !data->managed || !data->mapped) return;
+    if (!update_window || !data->managed || !data->mapped) goto done;
 
     style = GetWindowLongW( data->hwnd, GWL_STYLE );
 
@@ -1203,17 +1203,20 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
             if ((style & WS_MAXIMIZEBOX) && !(style & WS_DISABLED))
             {
                 TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
-                SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
+                release_win_data( data );
+                SendMessageW( hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
+                return;
             }
-            else TRACE( "not restoring to max win %p/%lx style %08x\n",
-                        data->hwnd, data->whole_window, style );
+            TRACE( "not restoring to max win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
         }
         else if (style & (WS_MINIMIZE | WS_MAXIMIZE))
         {
             TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
-            SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
+            release_win_data( data );
+            SendMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
+            return;
         }
-        else TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
+        TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
     }
     else if (!data->iconic && data->wm_state == IconicState)
     {
@@ -1221,10 +1224,14 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
         if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED))
         {
             TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
-            SendMessageW( data->hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
+            release_win_data( data );
+            SendMessageW( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
+            return;
         }
-        else TRACE( "not minimizing win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
+        TRACE( "not minimizing win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
     }
+done:
+    release_win_data( data );
 }
 
 
@@ -1254,20 +1261,33 @@ static Bool is_wm_state_notify( Display *display, XEvent *event, XPointer arg )
 void wait_for_withdrawn_state( HWND hwnd, BOOL set )
 {
     Display *display = thread_display();
-    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+    struct x11drv_win_data *data;
     DWORD end = GetTickCount() + 2000;
 
-    if (!data || !data->managed) return;
-
-    TRACE( "waiting for window %p/%lx to become %swithdrawn\n",
-           data->hwnd, data->whole_window, set ? "" : "not " );
+    TRACE( "waiting for window %p to become %swithdrawn\n", hwnd, set ? "" : "not " );
 
-    while (data->whole_window && ((data->wm_state == WithdrawnState) == !set))
+    for (;;)
     {
         XEvent event;
+        Window window;
         int count = 0;
 
-        while (XCheckIfEvent( display, &event, is_wm_state_notify, (char *)data->whole_window ))
+        if (!(data = get_win_data( hwnd ))) break;
+        if (!data->managed || data->embedded || data->display != display) break;
+        if (!(window = data->whole_window)) break;
+        if (!data->mapped == !set)
+        {
+            TRACE( "window %p/%lx now %smapped\n", hwnd, window, data->mapped ? "" : "un" );
+            break;
+        }
+        if ((data->wm_state == WithdrawnState) != !set)
+        {
+            TRACE( "window %p/%lx state now %d\n", hwnd, window, data->wm_state );
+            break;
+        }
+        release_win_data( data );
+
+        while (XCheckIfEvent( display, &event, is_wm_state_notify, (char *)window ))
         {
             count++;
             if (XFilterEvent( &event, None )) continue;  /* filtered, ignore it */
@@ -1284,12 +1304,12 @@ void wait_for_withdrawn_state( HWND hwnd, BOOL set )
             pfd.events = POLLIN;
             if (timeout <= 0 || poll( &pfd, 1, timeout ) != 1)
             {
-                FIXME( "window %p/%lx wait timed out\n", data->hwnd, data->whole_window );
-                break;
+                FIXME( "window %p/%lx wait timed out\n", hwnd, window );
+                return;
             }
         }
     }
-    TRACE( "window %p/%lx state now %d\n", data->hwnd, data->whole_window, data->wm_state );
+    release_win_data( data );
 }
 
 
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 4ccf067..931f60e 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1068,24 +1068,31 @@ static void set_xembed_flags( struct x11drv_win_data *data, unsigned long flags
  */
 static void map_window( HWND hwnd, DWORD new_style )
 {
-    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
-
-    TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
-
-    remove_startup_notification( data->display, data->whole_window );
+    struct x11drv_win_data *data;
 
     wait_for_withdrawn_state( hwnd, TRUE );
 
-    if (!data->embedded)
+    if (!(data = get_win_data( hwnd ))) return;
+
+    if (data->whole_window && !data->mapped)
     {
-        update_net_wm_states( data );
-        sync_window_style( data );
-        XMapWindow( data->display, data->whole_window );
-    }
-    else set_xembed_flags( data, XEMBED_MAPPED );
+        TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
 
-    data->mapped = TRUE;
-    data->iconic = (new_style & WS_MINIMIZE) != 0;
+        remove_startup_notification( data->display, data->whole_window );
+        set_wm_hints( data );
+
+        if (!data->embedded)
+        {
+            update_net_wm_states( data );
+            sync_window_style( data );
+            XMapWindow( data->display, data->whole_window );
+        }
+        else set_xembed_flags( data, XEMBED_MAPPED );
+
+        data->mapped = TRUE;
+        data->iconic = (new_style & WS_MINIMIZE) != 0;
+    }
+    release_win_data( data );
 }
 
 
@@ -1094,20 +1101,24 @@ static void map_window( HWND hwnd, DWORD new_style )
  */
 static void unmap_window( HWND hwnd )
 {
-    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+    struct x11drv_win_data *data;
 
-    TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
+    wait_for_withdrawn_state( hwnd, FALSE );
+
+    if (!(data = get_win_data( hwnd ))) return;
 
-    if (!data->embedded)
+    if (data->mapped)
     {
-        wait_for_withdrawn_state( hwnd, FALSE );
-        if (!data->managed) XUnmapWindow( data->display, data->whole_window );
+        TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
+
+        if (data->embedded) set_xembed_flags( data, 0 );
+        else if (!data->managed) XUnmapWindow( data->display, data->whole_window );
         else XWithdrawWindow( data->display, data->whole_window, DefaultScreen(data->display) );
-    }
-    else set_xembed_flags( data, 0 );
 
-    data->mapped = FALSE;
-    data->net_wm_state = 0;
+        data->mapped = FALSE;
+        data->net_wm_state = 0;
+    }
+    release_win_data( data );
 }
 
 
@@ -1116,21 +1127,23 @@ static void unmap_window( HWND hwnd )
  */
 void make_window_embedded( HWND hwnd )
 {
-    struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
-    BOOL was_mapped = data->mapped;
+    struct x11drv_win_data *data = get_win_data( hwnd );
 
-    /* the window cannot be mapped before being embedded */
-    if (data->mapped) unmap_window( hwnd );
+    if (!data) return;
 
+    /* the window cannot be mapped before being embedded */
+    if (data->mapped)
+    {
+        if (data->managed) XUnmapWindow( data->display, data->whole_window );
+        else XWithdrawWindow( data->display, data->whole_window, DefaultScreen(data->display) );
+        data->net_wm_state = 0;
+    }
     data->embedded = TRUE;
     data->managed = TRUE;
     SetPropA( hwnd, managed_prop, (HANDLE)1 );
     sync_window_style( data );
-
-    if (was_mapped)
-        map_window( hwnd, 0 );
-    else
-        set_xembed_flags( data, 0 );
+    set_xembed_flags( data, data->mapped ? XEMBED_MAPPED : 0 );
+    release_win_data( data );
 }
 
 
@@ -2161,7 +2174,6 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
         {
             make_owner_managed( hwnd );
             if (!data->icon_pixmap) fetch_icon_data( hwnd, 0, 0 );
-            set_wm_hints( data );
             map_window( hwnd, new_style );
         }
         else if ((swp_flags & SWP_STATECHANGED) && (!data->iconic != !(new_style & WS_MINIMIZE)))




More information about the wine-cvs mailing list