Commit 4c582103 authored by Alexandre Julliard's avatar Alexandre Julliard

winex11: Add window data structure locking to the WindowPosChanging/Changed entry points.

parent 803fc6e2
...@@ -1070,6 +1070,7 @@ static void map_window( HWND hwnd, DWORD new_style ) ...@@ -1070,6 +1070,7 @@ static void map_window( HWND hwnd, DWORD new_style )
{ {
struct x11drv_win_data *data; struct x11drv_win_data *data;
make_owner_managed( hwnd );
wait_for_withdrawn_state( hwnd, TRUE ); wait_for_withdrawn_state( hwnd, TRUE );
if (!(data = get_win_data( hwnd ))) return; if (!(data = get_win_data( hwnd ))) return;
...@@ -1086,6 +1087,7 @@ static void map_window( HWND hwnd, DWORD new_style ) ...@@ -1086,6 +1087,7 @@ static void map_window( HWND hwnd, DWORD new_style )
update_net_wm_states( data ); update_net_wm_states( data );
sync_window_style( data ); sync_window_style( data );
XMapWindow( data->display, data->whole_window ); XMapWindow( data->display, data->whole_window );
XFlush( data->display );
} }
else set_xembed_flags( data, XEMBED_MAPPED ); else set_xembed_flags( data, XEMBED_MAPPED );
...@@ -1277,10 +1279,10 @@ static void sync_window_position( struct x11drv_win_data *data, ...@@ -1277,10 +1279,10 @@ static void sync_window_position( struct x11drv_win_data *data,
* *
* Move the window bits when a window is moved. * Move the window bits when a window is moved.
*/ */
static void move_window_bits( HWND hwnd, const RECT *old_rect, const RECT *new_rect, static void move_window_bits( HWND hwnd, Window window, const RECT *old_rect, const RECT *new_rect,
const RECT *old_client_rect ) const RECT *old_client_rect, const RECT *new_client_rect,
const RECT *new_window_rect )
{ {
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
RECT src_rect = *old_rect; RECT src_rect = *old_rect;
RECT dst_rect = *new_rect; RECT dst_rect = *new_rect;
HDC hdc_src, hdc_dst; HDC hdc_src, hdc_dst;
...@@ -1288,32 +1290,32 @@ static void move_window_bits( HWND hwnd, const RECT *old_rect, const RECT *new_r ...@@ -1288,32 +1290,32 @@ static void move_window_bits( HWND hwnd, const RECT *old_rect, const RECT *new_r
HRGN rgn; HRGN rgn;
HWND parent = 0; HWND parent = 0;
if (!data->whole_window) if (!window)
{ {
OffsetRect( &dst_rect, -data->window_rect.left, -data->window_rect.top ); OffsetRect( &dst_rect, -new_window_rect->left, -new_window_rect->top );
parent = GetAncestor( data->hwnd, GA_PARENT ); parent = GetAncestor( hwnd, GA_PARENT );
hdc_src = GetDCEx( parent, 0, DCX_CACHE ); hdc_src = GetDCEx( parent, 0, DCX_CACHE );
hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE | DCX_WINDOW ); hdc_dst = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW );
} }
else else
{ {
OffsetRect( &dst_rect, -data->client_rect.left, -data->client_rect.top ); OffsetRect( &dst_rect, -new_client_rect->left, -new_client_rect->top );
/* make src rect relative to the old position of the window */ /* make src rect relative to the old position of the window */
OffsetRect( &src_rect, -old_client_rect->left, -old_client_rect->top ); OffsetRect( &src_rect, -old_client_rect->left, -old_client_rect->top );
if (dst_rect.left == src_rect.left && dst_rect.top == src_rect.top) return; if (dst_rect.left == src_rect.left && dst_rect.top == src_rect.top) return;
hdc_src = hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE ); hdc_src = hdc_dst = GetDCEx( hwnd, 0, DCX_CACHE );
} }
rgn = CreateRectRgnIndirect( &dst_rect ); rgn = CreateRectRgnIndirect( &dst_rect );
SelectClipRgn( hdc_dst, rgn ); SelectClipRgn( hdc_dst, rgn );
DeleteObject( rgn ); DeleteObject( rgn );
ExcludeUpdateRgn( hdc_dst, data->hwnd ); ExcludeUpdateRgn( hdc_dst, hwnd );
code = X11DRV_START_EXPOSURES; code = X11DRV_START_EXPOSURES;
ExtEscape( hdc_dst, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL ); ExtEscape( hdc_dst, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL );
TRACE( "copying bits for win %p/%lx %s -> %s\n", TRACE( "copying bits for win %p/%lx %s -> %s\n",
data->hwnd, data->whole_window, wine_dbgstr_rect(&src_rect), wine_dbgstr_rect(&dst_rect) ); hwnd, window, wine_dbgstr_rect(&src_rect), wine_dbgstr_rect(&dst_rect) );
BitBlt( hdc_dst, dst_rect.left, dst_rect.top, BitBlt( hdc_dst, dst_rect.left, dst_rect.top,
dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top, dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top,
hdc_src, src_rect.left, src_rect.top, SRCCOPY ); hdc_src, src_rect.left, src_rect.top, SRCCOPY );
...@@ -1322,20 +1324,20 @@ static void move_window_bits( HWND hwnd, const RECT *old_rect, const RECT *new_r ...@@ -1322,20 +1324,20 @@ static void move_window_bits( HWND hwnd, const RECT *old_rect, const RECT *new_r
code = X11DRV_END_EXPOSURES; code = X11DRV_END_EXPOSURES;
ExtEscape( hdc_dst, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, sizeof(rgn), (LPSTR)&rgn ); ExtEscape( hdc_dst, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, sizeof(rgn), (LPSTR)&rgn );
ReleaseDC( data->hwnd, hdc_dst ); ReleaseDC( hwnd, hdc_dst );
if (hdc_src != hdc_dst) ReleaseDC( parent, hdc_src ); if (hdc_src != hdc_dst) ReleaseDC( parent, hdc_src );
if (rgn) if (rgn)
{ {
if (!data->whole_window) if (!window)
{ {
/* map region to client rect since we are using DCX_WINDOW */ /* map region to client rect since we are using DCX_WINDOW */
OffsetRgn( rgn, data->window_rect.left - data->client_rect.left, OffsetRgn( rgn, new_window_rect->left - new_client_rect->left,
data->window_rect.top - data->client_rect.top ); new_window_rect->top - new_client_rect->top );
RedrawWindow( data->hwnd, NULL, rgn, RedrawWindow( hwnd, NULL, rgn,
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN ); RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN );
} }
else RedrawWindow( data->hwnd, NULL, rgn, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN ); else RedrawWindow( hwnd, NULL, rgn, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN );
DeleteObject( rgn ); DeleteObject( rgn );
} }
} }
...@@ -1718,7 +1720,6 @@ static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const RECT *wi ...@@ -1718,7 +1720,6 @@ static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const RECT *wi
hwnd, data->whole_window, wine_dbgstr_rect( &data->window_rect ), hwnd, data->whole_window, wine_dbgstr_rect( &data->window_rect ),
wine_dbgstr_rect( &data->whole_rect ), wine_dbgstr_rect( &data->client_rect )); wine_dbgstr_rect( &data->whole_rect ), wine_dbgstr_rect( &data->client_rect ));
} }
release_win_data( data );
return data; return data;
} }
...@@ -2026,7 +2027,7 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag ...@@ -2026,7 +2027,7 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
const RECT *window_rect, const RECT *client_rect, RECT *visible_rect, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect,
struct window_surface **surface ) struct window_surface **surface )
{ {
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); struct x11drv_win_data *data = get_win_data( hwnd );
RECT surface_rect; RECT surface_rect;
XVisualInfo vis; XVisualInfo vis;
DWORD flags; DWORD flags;
...@@ -2039,7 +2040,9 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag ...@@ -2039,7 +2040,9 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
if (!data->managed && data->whole_window && is_window_managed( hwnd, swp_flags, window_rect )) if (!data->managed && data->whole_window && is_window_managed( hwnd, swp_flags, window_rect ))
{ {
TRACE( "making win %p/%lx managed\n", hwnd, data->whole_window ); TRACE( "making win %p/%lx managed\n", hwnd, data->whole_window );
if (data->mapped) unmap_window( hwnd ); release_win_data( data );
unmap_window( hwnd );
if (!(data = get_win_data( hwnd ))) return;
data->managed = TRUE; data->managed = TRUE;
SetPropA( hwnd, managed_prop, (HANDLE)1 ); SetPropA( hwnd, managed_prop, (HANDLE)1 );
} }
...@@ -2048,12 +2051,12 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag ...@@ -2048,12 +2051,12 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
X11DRV_window_to_X_rect( data, visible_rect ); X11DRV_window_to_X_rect( data, visible_rect );
/* create the window surface if necessary */ /* create the window surface if necessary */
if (!data->whole_window) return; if (!data->whole_window) goto done;
if (data->embedded) return; if (data->embedded) goto done;
if (swp_flags & SWP_HIDEWINDOW) return; if (swp_flags & SWP_HIDEWINDOW) goto done;
if (data->whole_window == root_window) return; if (data->whole_window == root_window) goto done;
if (has_gl_drawable( hwnd )) return; if (has_gl_drawable( hwnd )) goto done;
if (!client_side_graphics && !layered) return; if (!client_side_graphics && !layered) goto done;
surface_rect = get_surface_rect( visible_rect ); surface_rect = get_surface_rect( visible_rect );
if (data->surface) if (data->surface)
...@@ -2063,10 +2066,10 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag ...@@ -2063,10 +2066,10 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
/* existing surface is good enough */ /* existing surface is good enough */
window_surface_add_ref( data->surface ); window_surface_add_ref( data->surface );
*surface = data->surface; *surface = data->surface;
return; goto done;
} }
} }
else if (!(swp_flags & SWP_SHOWWINDOW) && !(GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) return; else if (!(swp_flags & SWP_SHOWWINDOW) && !(GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) goto done;
memset( &vis, 0, sizeof(vis) ); memset( &vis, 0, sizeof(vis) );
vis.visual = visual; vis.visual = visual;
...@@ -2079,6 +2082,9 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag ...@@ -2079,6 +2082,9 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
key = CLR_INVALID; key = CLR_INVALID;
*surface = create_surface( data->whole_window, &vis, &surface_rect, key ); *surface = create_surface( data->whole_window, &vis, &surface_rect, key );
done:
release_win_data( data );
} }
...@@ -2091,12 +2097,12 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags ...@@ -2091,12 +2097,12 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
struct window_surface *surface ) struct window_surface *surface )
{ {
struct x11drv_thread_data *thread_data; struct x11drv_thread_data *thread_data;
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); struct x11drv_win_data *data;
DWORD new_style = GetWindowLongW( hwnd, GWL_STYLE ); DWORD new_style = GetWindowLongW( hwnd, GWL_STYLE );
RECT old_window_rect, old_whole_rect, old_client_rect; RECT old_window_rect, old_whole_rect, old_client_rect;
int event_type; int event_type;
if (!data) return; if (!(data = get_win_data( hwnd ))) return;
thread_data = x11drv_thread_data(); thread_data = x11drv_thread_data();
...@@ -2115,6 +2121,7 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags ...@@ -2115,6 +2121,7 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
if (!IsRectEmpty( &valid_rects[0] )) if (!IsRectEmpty( &valid_rects[0] ))
{ {
Window window = data->whole_window;
int x_offset = old_whole_rect.left - data->whole_rect.left; int x_offset = old_whole_rect.left - data->whole_rect.left;
int y_offset = old_whole_rect.top - data->whole_rect.top; int y_offset = old_whole_rect.top - data->whole_rect.top;
...@@ -2129,27 +2136,40 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags ...@@ -2129,27 +2136,40 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
!memcmp( &valid_rects[0], &data->client_rect, sizeof(RECT) )) !memcmp( &valid_rects[0], &data->client_rect, sizeof(RECT) ))
{ {
/* if we have an X window the bits will be moved by the X server */ /* if we have an X window the bits will be moved by the X server */
if (!data->whole_window && (x_offset != 0 || y_offset != 0)) if (!window && (x_offset != 0 || y_offset != 0))
move_window_bits( hwnd, &old_whole_rect, &data->whole_rect, &old_client_rect ); {
release_win_data( data );
move_window_bits( hwnd, window, &old_whole_rect, visible_rect,
&old_client_rect, rectClient, rectWindow );
if (!(data = get_win_data( hwnd ))) return;
}
} }
else else
move_window_bits( hwnd, &valid_rects[1], &valid_rects[0], &old_client_rect ); {
release_win_data( data );
move_window_bits( hwnd, window, &valid_rects[1], &valid_rects[0],
&old_client_rect, rectClient, rectWindow );
if (!(data = get_win_data( hwnd ))) return;
}
} }
XFlush( gdi_display ); /* make sure painting is done before we move the window */ XFlush( gdi_display ); /* make sure painting is done before we move the window */
sync_gl_drawable( data->hwnd, visible_rect, rectClient ); sync_gl_drawable( data->hwnd, visible_rect, rectClient );
if (!data->whole_window) return; if (!data->whole_window) goto done;
/* check if we are currently processing an event relevant to this window */ /* check if we are currently processing an event relevant to this window */
event_type = 0; event_type = 0;
if (thread_data->current_event && thread_data->current_event->xany.window == data->whole_window) if (thread_data &&
thread_data->current_event &&
thread_data->current_event->xany.window == data->whole_window)
{
event_type = thread_data->current_event->type; event_type = thread_data->current_event->type;
if (event_type != ConfigureNotify && event_type != PropertyNotify &&
if (event_type != ConfigureNotify && event_type != PropertyNotify && event_type != GravityNotify && event_type != ReparentNotify)
event_type != GravityNotify && event_type != ReparentNotify) event_type = 0; /* ignore other events */
event_type = 0; /* ignore other events */ }
if (data->mapped && event_type != ReparentNotify) if (data->mapped && event_type != ReparentNotify)
{ {
...@@ -2157,8 +2177,10 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags ...@@ -2157,8 +2177,10 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
(!event_type && (!event_type &&
!is_window_rect_mapped( rectWindow ) && is_window_rect_mapped( &old_window_rect ))) !is_window_rect_mapped( rectWindow ) && is_window_rect_mapped( &old_window_rect )))
{ {
release_win_data( data );
unmap_window( hwnd ); unmap_window( hwnd );
if (is_window_rect_fullscreen( &old_window_rect )) reset_clipping_window(); if (is_window_rect_fullscreen( &old_window_rect )) reset_clipping_window();
if (!(data = get_win_data( hwnd ))) return;
} }
} }
...@@ -2172,9 +2194,12 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags ...@@ -2172,9 +2194,12 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
{ {
if (!data->mapped) if (!data->mapped)
{ {
make_owner_managed( hwnd ); BOOL needs_icon = !data->icon_pixmap;
if (!data->icon_pixmap) fetch_icon_data( hwnd, 0, 0 );
release_win_data( data );
if (needs_icon) fetch_icon_data( hwnd, 0, 0 );
map_window( hwnd, new_style ); map_window( hwnd, new_style );
return;
} }
else if ((swp_flags & SWP_STATECHANGED) && (!data->iconic != !(new_style & WS_MINIMIZE))) else if ((swp_flags & SWP_STATECHANGED) && (!data->iconic != !(new_style & WS_MINIMIZE)))
{ {
...@@ -2195,6 +2220,8 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags ...@@ -2195,6 +2220,8 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
} }
XFlush( data->display ); /* make sure changes are done before we start painting again */ XFlush( data->display ); /* make sure changes are done before we start painting again */
done:
release_win_data( data );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment