Module: wine Branch: master Commit: a6c543d0e6e2c76f7a357f3d72c242df8fdba78c URL: http://source.winehq.org/git/wine.git/?a=commit;h=a6c543d0e6e2c76f7a357f3d72...
Author: Alexandre Julliard julliard@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)))