Commit 22993aff authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

winex11: Track the client colormap separately.

If a window with an OpenGL surface attached is reparented as a child window, and then reparented as a top-level window, so that its whole window is destroyed and then recreated, it will be recreated with the colormap of its child window, which more than likely has a different visual. This violates the X11 specification, which states that a window's colormap must have the same visual as the window itself, and causes the X server to return BadMatch to the CreateWindow request. Signed-off-by: 's avatarZebediah Figura <z.figura12@gmail.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent cfb06ad1
...@@ -314,7 +314,7 @@ static unsigned long get_mwm_decorations( struct x11drv_win_data *data, ...@@ -314,7 +314,7 @@ static unsigned long get_mwm_decorations( struct x11drv_win_data *data,
static int get_window_attributes( struct x11drv_win_data *data, XSetWindowAttributes *attr ) static int get_window_attributes( struct x11drv_win_data *data, XSetWindowAttributes *attr )
{ {
attr->override_redirect = !data->managed; attr->override_redirect = !data->managed;
attr->colormap = data->colormap ? data->colormap : default_colormap; attr->colormap = data->whole_colormap ? data->whole_colormap : default_colormap;
attr->save_under = ((GetClassLongW( data->hwnd, GCL_STYLE ) & CS_SAVEBITS) != 0); attr->save_under = ((GetClassLongW( data->hwnd, GCL_STYLE ) & CS_SAVEBITS) != 0);
attr->bit_gravity = NorthWestGravity; attr->bit_gravity = NorthWestGravity;
attr->backing_store = NotUseful; attr->backing_store = NotUseful;
...@@ -1445,12 +1445,12 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual ) ...@@ -1445,12 +1445,12 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual )
TRACE( "%p reparent xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window ); TRACE( "%p reparent xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window );
} }
if (data->colormap) XFreeColormap( gdi_display, data->colormap ); if (data->client_colormap) XFreeColormap( gdi_display, data->client_colormap );
data->colormap = XCreateColormap( gdi_display, dummy_parent, visual->visual, data->client_colormap = XCreateColormap( gdi_display, dummy_parent, visual->visual,
(visual->class == PseudoColor || (visual->class == PseudoColor ||
visual->class == GrayScale || visual->class == GrayScale ||
visual->class == DirectColor) ? AllocAll : AllocNone ); visual->class == DirectColor) ? AllocAll : AllocNone );
attr.colormap = data->colormap; attr.colormap = data->client_colormap;
attr.bit_gravity = NorthWestGravity; attr.bit_gravity = NorthWestGravity;
attr.win_gravity = NorthWestGravity; attr.win_gravity = NorthWestGravity;
attr.backing_store = NotUseful; attr.backing_store = NotUseful;
...@@ -1509,7 +1509,7 @@ static void create_whole_window( struct x11drv_win_data *data ) ...@@ -1509,7 +1509,7 @@ static void create_whole_window( struct x11drv_win_data *data )
data->shaped = (win_rgn != 0); data->shaped = (win_rgn != 0);
if (data->vis.visualid != default_visual.visualid) if (data->vis.visualid != default_visual.visualid)
data->colormap = XCreateColormap( data->display, root_window, data->vis.visual, AllocNone ); data->whole_colormap = XCreateColormap( data->display, root_window, data->vis.visual, AllocNone );
mask = get_window_attributes( data, &attr ); mask = get_window_attributes( data, &attr );
...@@ -1586,9 +1586,9 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des ...@@ -1586,9 +1586,9 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des
XDeleteContext( data->display, data->whole_window, winContext ); XDeleteContext( data->display, data->whole_window, winContext );
if (!already_destroyed) XDestroyWindow( data->display, data->whole_window ); if (!already_destroyed) XDestroyWindow( data->display, data->whole_window );
} }
if (data->colormap) XFreeColormap( data->display, data->colormap ); if (data->whole_colormap) XFreeColormap( data->display, data->whole_colormap );
data->whole_window = data->client_window = 0; data->whole_window = data->client_window = 0;
data->colormap = 0; data->whole_colormap = 0;
data->wm_state = WithdrawnState; data->wm_state = WithdrawnState;
data->net_wm_state = 0; data->net_wm_state = 0;
data->mapped = FALSE; data->mapped = FALSE;
...@@ -1694,6 +1694,7 @@ void CDECL X11DRV_DestroyWindow( HWND hwnd ) ...@@ -1694,6 +1694,7 @@ void CDECL X11DRV_DestroyWindow( HWND hwnd )
if (thread_data->last_xic_hwnd == hwnd) thread_data->last_xic_hwnd = 0; if (thread_data->last_xic_hwnd == hwnd) thread_data->last_xic_hwnd = 0;
if (data->icon_pixmap) XFreePixmap( gdi_display, data->icon_pixmap ); if (data->icon_pixmap) XFreePixmap( gdi_display, data->icon_pixmap );
if (data->icon_mask) XFreePixmap( gdi_display, data->icon_mask ); if (data->icon_mask) XFreePixmap( gdi_display, data->icon_mask );
if (data->client_colormap) XFreeColormap( data->display, data->client_colormap );
HeapFree( GetProcessHeap(), 0, data->icon_bits ); HeapFree( GetProcessHeap(), 0, data->icon_bits );
XDeleteContext( gdi_display, (XID)hwnd, win_data_context ); XDeleteContext( gdi_display, (XID)hwnd, win_data_context );
release_win_data( data ); release_win_data( data );
......
...@@ -553,7 +553,8 @@ struct x11drv_win_data ...@@ -553,7 +553,8 @@ struct x11drv_win_data
{ {
Display *display; /* display connection for the thread owning the window */ Display *display; /* display connection for the thread owning the window */
XVisualInfo vis; /* X visual used by this window */ XVisualInfo vis; /* X visual used by this window */
Colormap colormap; /* colormap if non-default visual */ Colormap whole_colormap; /* colormap if non-default visual */
Colormap client_colormap; /* colormap for the client window */
HWND hwnd; /* hwnd that this private data belongs to */ HWND hwnd; /* hwnd that this private data belongs to */
Window whole_window; /* X window for the complete window */ Window whole_window; /* X window for the complete window */
Window client_window; /* X window for the client area */ Window client_window; /* X window for the client area */
......
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