winex11: Store the client window in the window data again, now that it can be accessed from all threads.

This commit is contained in:
Alexandre Julliard 2013-01-23 13:35:30 +01:00
parent 9532de882f
commit 951415b602
3 changed files with 84 additions and 36 deletions

View file

@ -1201,7 +1201,6 @@ static void free_gl_drawable( struct gl_drawable *gl )
{
switch (gl->type)
{
case DC_GL_WINDOW:
case DC_GL_CHILD_WIN:
XDestroyWindow( gdi_display, gl->drawable );
XFreeColormap( gdi_display, gl->colormap );
@ -1229,29 +1228,14 @@ static BOOL create_gl_drawable( HWND hwnd, HWND parent, struct gl_drawable *gl )
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */
{
Window parent = X11DRV_get_whole_window( hwnd );
struct x11drv_win_data *data = get_win_data( hwnd );
gl->type = DC_GL_WINDOW;
gl->colormap = XCreateColormap( gdi_display, root_window, gl->visual->visual,
(gl->visual->class == PseudoColor ||
gl->visual->class == GrayScale ||
gl->visual->class == DirectColor) ? AllocAll : AllocNone );
attrib.colormap = gl->colormap;
attrib.bit_gravity = NorthWestGravity;
attrib.win_gravity = NorthWestGravity;
attrib.backing_store = NotUseful;
/* put the initial rect outside of the window, it will be moved into place by SetWindowPos */
OffsetRect( &gl->rect, gl->rect.right, gl->rect.bottom );
if (parent)
gl->drawable = XCreateWindow( gdi_display, parent, gl->rect.left, gl->rect.top,
gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top,
0, default_visual.depth, InputOutput, gl->visual->visual,
CWBitGravity | CWWinGravity | CWBackingStore | CWColormap,
&attrib );
if (gl->drawable)
XMapWindow( gdi_display, gl->drawable );
else
XFreeColormap( gdi_display, gl->colormap );
if (data)
{
gl->type = DC_GL_WINDOW;
gl->drawable = create_client_window( data, gl->visual );
release_win_data( data );
}
}
#ifdef SONAME_LIBXCOMPOSITE
else if(usexcomposite)
@ -1358,8 +1342,6 @@ void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_r
int mask = 0;
XWindowChanges changes;
changes.x = client_rect->left - visible_rect->left;
changes.y = client_rect->top - visible_rect->top;
changes.width = min( max( 1, client_rect->right - client_rect->left ), 65535 );
changes.height = min( max( 1, client_rect->bottom - client_rect->top ), 65535 );
@ -1373,10 +1355,6 @@ void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_r
switch (gl->type)
{
case DC_GL_WINDOW:
if (changes.x != gl->rect.left) mask |= CWX;
if (changes.y != gl->rect.top) mask |= CWY;
/* fallthrough */
case DC_GL_CHILD_WIN:
if (mask) XConfigureWindow( gdi_display, gl->drawable, mask, &changes );
break;
@ -1425,8 +1403,6 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent )
switch (gl->type)
{
case DC_GL_WINDOW:
XDestroyWindow( gdi_display, gl->drawable );
XFreeColormap( gdi_display, gl->colormap );
break;
case DC_GL_CHILD_WIN:
if (parent != GetDesktopWindow()) goto done;

View file

@ -1263,6 +1263,38 @@ static void sync_window_position( struct x11drv_win_data *data,
}
/***********************************************************************
* sync_client_position
*
* Synchronize the X client window position with the Windows one
*/
static void sync_client_position( struct x11drv_win_data *data,
const RECT *old_client_rect, const RECT *old_whole_rect )
{
int mask = 0;
XWindowChanges changes;
if (!data->client_window) return;
changes.x = data->client_rect.left - data->whole_rect.left;
changes.y = data->client_rect.top - data->whole_rect.top;
changes.width = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
changes.height = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
if (changes.x != old_client_rect->left - old_whole_rect->left) mask |= CWX;
if (changes.y != old_client_rect->top - old_whole_rect->top) mask |= CWY;
if (changes.width != old_client_rect->right - old_client_rect->left) mask |= CWWidth;
if (changes.height != old_client_rect->bottom - old_client_rect->top) mask |= CWHeight;
if (mask)
{
TRACE( "setting client win %lx pos %d,%d,%dx%d changes=%x\n",
data->client_window, changes.x, changes.y, changes.width, changes.height, mask );
XConfigureWindow( data->display, data->client_window, mask, &changes );
}
}
/***********************************************************************
* move_window_bits
*
@ -1332,6 +1364,39 @@ static void move_window_bits( HWND hwnd, Window window, const RECT *old_rect, co
}
/**********************************************************************
* create_client_window
*/
Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *visual )
{
XSetWindowAttributes attr;
int x = data->client_rect.left - data->whole_rect.left;
int y = data->client_rect.top - data->whole_rect.top;
int cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
int cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
data->colormap = XCreateColormap( data->display, root_window, visual->visual,
(visual->class == PseudoColor ||
visual->class == GrayScale ||
visual->class == DirectColor) ? AllocAll : AllocNone );
attr.colormap = data->colormap;
attr.bit_gravity = NorthWestGravity;
attr.win_gravity = NorthWestGravity;
attr.backing_store = NotUseful;
data->client_window = XCreateWindow( data->display, data->whole_window, x, y, cx, cy,
0, default_visual.depth, InputOutput, visual->visual,
CWBitGravity | CWWinGravity | CWBackingStore | CWColormap,
&attr );
if (!data->client_window) return 0;
XSaveContext( data->display, data->client_window, winContext, (char *)data->hwnd );
XMapWindow( data->display, data->client_window );
XFlush( data->display );
return data->client_window;
}
/**********************************************************************
* create_whole_window
*
@ -1430,9 +1495,10 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des
TRACE( "win %p xwin %lx\n", data->hwnd, data->whole_window );
XDeleteContext( data->display, data->whole_window, winContext );
if (data->client_window) XDeleteContext( data->display, data->client_window, winContext );
if (!already_destroyed) XDestroyWindow( data->display, data->whole_window );
if (data->colormap) XFreeColormap( data->display, data->colormap );
data->whole_window = 0;
data->whole_window = data->client_window = 0;
data->colormap = 0;
data->wm_state = WithdrawnState;
data->net_wm_state = 0;
@ -1810,7 +1876,7 @@ HWND create_foreign_window( Display *display, Window xwin )
}
SetRect( &data->window_rect, attr.x, attr.y, attr.x + attr.width, attr.y + attr.height );
data->whole_rect = data->client_rect = data->window_rect;
data->whole_window = 0;
data->whole_window = data->client_window = 0;
data->embedded = TRUE;
data->mapped = TRUE;
@ -2148,9 +2214,14 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
XFlush( gdi_display ); /* make sure painting is done before we move the window */
sync_gl_drawable( data->hwnd, visible_rect, rectClient );
sync_client_position( data, &old_client_rect, &old_whole_rect );
if (!data->whole_window) goto done;
if (!data->whole_window)
{
release_win_data( data );
sync_gl_drawable( hwnd, visible_rect, rectClient );
return;
}
/* check if we are currently processing an event relevant to this window */
event_type = 0;
@ -2219,7 +2290,6 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
if (data->surface && data->vis.visualid != default_visual.visualid)
data->surface->funcs->flush( data->surface );
done:
release_win_data( data );
}

View file

@ -549,6 +549,7 @@ struct x11drv_win_data
Colormap colormap; /* colormap if non-default visual */
HWND hwnd; /* hwnd that this private data belongs to */
Window whole_window; /* X window for the complete window */
Window client_window; /* X window for the client area */
RECT window_rect; /* USER window rectangle relative to parent */
RECT whole_rect; /* X window rectangle for the whole window relative to parent */
RECT client_rect; /* client area relative to parent */
@ -584,6 +585,7 @@ extern Window init_clip_window(void) DECLSPEC_HIDDEN;
extern void update_user_time( Time time ) DECLSPEC_HIDDEN;
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( struct x11drv_win_data *data, const XVisualInfo *visual ) DECLSPEC_HIDDEN;
extern void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis ) DECLSPEC_HIDDEN;
extern void change_systray_owner( Display *display, Window systray_window ) DECLSPEC_HIDDEN;
extern void update_systray_balloon_position(void) DECLSPEC_HIDDEN;