winex11: Re-create the client window when setting the pixel format on a top-level window.
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 2d93104..4a41ba5 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -207,6 +207,65 @@
/***********************************************************************
+ * create_client_window
+ */
+static Window create_client_window( Display *display, struct x11drv_win_data *data, XVisualInfo *vis )
+{
+ int cx, cy, mask;
+ XSetWindowAttributes attr;
+ Window client;
+
+ attr.bit_gravity = NorthWestGravity;
+ attr.win_gravity = NorthWestGravity;
+ attr.backing_store = NotUseful;
+ attr.event_mask = (ExposureMask | PointerMotionMask |
+ ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
+ mask = CWEventMask | CWBitGravity | CWWinGravity | CWBackingStore;
+
+ if ((cx = data->client_rect.right - data->client_rect.left) <= 0) cx = 1;
+ if ((cy = data->client_rect.bottom - data->client_rect.top) <= 0) cy = 1;
+
+ wine_tsx11_lock();
+
+ if (vis)
+ {
+ attr.colormap = XCreateColormap( display, root_window, vis->visual,
+ (vis->class == PseudoColor || vis->class == GrayScale ||
+ vis->class == DirectColor) ? AllocAll : AllocNone );
+ mask |= CWColormap;
+ }
+
+ client = XCreateWindow( display, data->whole_window,
+ data->client_rect.left - data->whole_rect.left,
+ data->client_rect.top - data->whole_rect.top,
+ cx, cy, 0, screen_depth, InputOutput,
+ vis ? vis->visual : visual, mask, &attr );
+ if (!client)
+ {
+ wine_tsx11_unlock();
+ return 0;
+ }
+
+ if (data->client_window)
+ {
+ XDeleteContext( display, data->client_window, winContext );
+ XDestroyWindow( display, data->client_window );
+ }
+ data->client_window = client;
+
+ if (data->colormap) XFreeColormap( display, data->colormap );
+ data->colormap = vis ? attr.colormap : 0;
+
+ XMapWindow( display, data->client_window );
+ XSaveContext( display, data->client_window, winContext, (char *)data->hwnd );
+ wine_tsx11_unlock();
+
+ SetPropA( data->hwnd, client_window_prop, (HANDLE)data->client_window );
+ return data->client_window;
+}
+
+
+/***********************************************************************
* X11DRV_sync_window_style
*
* Change the X window attributes when the window style has changed.
@@ -311,41 +370,32 @@
Display *display = thread_display();
struct x11drv_win_data *data;
XVisualInfo *vis;
- Drawable parent;
- HWND next_hwnd;
int w, h;
if (!(data = X11DRV_get_win_data(hwnd)) &&
!(data = X11DRV_create_win_data(hwnd))) return FALSE;
+ if (data->fbconfig_id) return FALSE; /* can't change it twice */
+
wine_tsx11_lock();
-
vis = visual_from_fbconfig_id(fbconfig_id);
- if(!vis)
- {
- wine_tsx11_unlock();
- return FALSE;
- }
-
- if(data->whole_window && vis->visualid == XVisualIDFromVisual(visual))
- {
- TRACE("Whole window available and visual match, rendering onscreen\n");
- goto done;
- }
-
wine_tsx11_unlock();
+ if (!vis) return FALSE;
- parent = data->whole_window;
- next_hwnd = hwnd;
- while(!parent)
+ if (data->whole_window)
{
- next_hwnd = GetAncestor(next_hwnd, GA_PARENT);
- if(!next_hwnd)
+ Window client = data->client_window;
+
+ if (vis->visualid != XVisualIDFromVisual(visual))
{
- ERR("Could not find parent HWND with a drawable!\n");
- return FALSE;
+ client = create_client_window( display, data, vis );
+ TRACE( "re-created client window %lx for %p fbconfig %lx\n", client, data->hwnd, fbconfig_id );
}
- parent = X11DRV_get_whole_window(next_hwnd);
+ wine_tsx11_lock();
+ XFree(vis);
+ wine_tsx11_unlock();
+ if (client) goto done;
+ return FALSE;
}
w = data->client_rect.right - data->client_rect.left;
@@ -354,12 +404,14 @@
if(w <= 0) w = 1;
if(h <= 0) h = 1;
- wine_tsx11_lock();
#ifdef SONAME_LIBXCOMPOSITE
if(usexcomposite)
{
XSetWindowAttributes attrib;
+ Window parent = X11DRV_get_whole_window( GetAncestor( hwnd, GA_ROOT ));
+ if (!parent) parent = root_window;
+ wine_tsx11_lock();
data->colormap = XCreateColormap(display, parent, vis->visual,
(vis->class == PseudoColor ||
vis->class == GrayScale ||
@@ -379,16 +431,18 @@
CompositeRedirectManual);
XMapWindow(display, data->gl_drawable);
}
+ XFree(vis);
+ wine_tsx11_unlock();
}
else
#endif
{
WARN("XComposite is not available, using GLXPixmap hack\n");
- data->pixmap = XCreatePixmap(display, parent, w, h, vis->depth);
+ wine_tsx11_lock();
+ data->pixmap = XCreatePixmap(display, root_window, w, h, vis->depth);
if(!data->pixmap)
{
- ERR("Failed to create pixmap for offscreen rendering\n");
XFree(vis);
wine_tsx11_unlock();
return FALSE;
@@ -400,29 +454,23 @@
XFreePixmap(display, data->pixmap);
data->pixmap = 0;
}
- }
-
- if(!data->gl_drawable)
- {
- ERR("Failed to create drawable for offscreen rendering\n");
XFree(vis);
wine_tsx11_unlock();
- return FALSE;
+ if (data->pixmap) SetPropA(hwnd, pixmap_prop, (HANDLE)data->pixmap);
}
-done:
- XFree(vis);
-
- XFlush(display);
- wine_tsx11_unlock();
+ if (!data->gl_drawable) return FALSE;
TRACE("Created GL drawable 0x%lx, using FBConfigID 0x%lx\n",
data->gl_drawable, fbconfig_id);
+ SetPropA(hwnd, gl_drawable_prop, (HANDLE)data->gl_drawable);
+done:
data->fbconfig_id = fbconfig_id;
SetPropA(hwnd, fbconfig_id_prop, (HANDLE)data->fbconfig_id);
- SetPropA(hwnd, gl_drawable_prop, (HANDLE)data->gl_drawable);
- SetPropA(hwnd, pixmap_prop, (HANDLE)data->pixmap);
+ wine_tsx11_lock();
+ XFlush( display );
+ wine_tsx11_unlock();
invalidate_dce( hwnd, &data->window_rect );
return TRUE;
}
@@ -435,8 +483,6 @@
int w = data->client_rect.right - data->client_rect.left;
int h = data->client_rect.bottom - data->client_rect.top;
XVisualInfo *vis;
- Drawable parent;
- HWND next_hwnd;
Drawable glxp;
Pixmap pix;
@@ -451,19 +497,6 @@
}
#endif
- parent = data->whole_window;
- next_hwnd = data->hwnd;
- while(!parent)
- {
- next_hwnd = GetAncestor(next_hwnd, GA_PARENT);
- if(!next_hwnd)
- {
- ERR("Could not find parent HWND with a drawable!\n");
- return;
- }
- parent = X11DRV_get_whole_window(next_hwnd);
- }
-
wine_tsx11_lock();
vis = visual_from_fbconfig_id(data->fbconfig_id);
@@ -473,7 +506,7 @@
return;
}
- pix = XCreatePixmap(display, parent, w, h, vis->depth);
+ pix = XCreatePixmap(display, root_window, w, h, vis->depth);
if(!pix)
{
ERR("Failed to create pixmap for offscreen rendering\n");
@@ -1161,40 +1194,21 @@
cx, cy, 0, screen_depth, InputOutput,
visual, mask, &attr );
- if (!data->whole_window)
+ if (data->whole_window) XSaveContext( display, data->whole_window, winContext, (char *)data->hwnd );
+ wine_tsx11_unlock();
+
+ if (!data->whole_window) return 0;
+
+ if (!create_client_window( display, data, NULL ))
{
- wine_tsx11_unlock();
- return 0;
- }
-
- attr.bit_gravity = NorthWestGravity;
- attr.win_gravity = NorthWestGravity;
- attr.backing_store = NotUseful;
- attr.event_mask = (ExposureMask | PointerMotionMask |
- ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
- mask = CWEventMask | CWBitGravity | CWWinGravity | CWBackingStore;
-
- if ((cx = data->client_rect.right - data->client_rect.left) <= 0) cx = 1;
- if ((cy = data->client_rect.bottom - data->client_rect.top) <= 0) cy = 1;
-
- data->client_window = XCreateWindow( display, data->whole_window,
- data->client_rect.left - data->window_rect.left,
- data->client_rect.top - data->window_rect.top,
- cx, cy, 0, screen_depth, InputOutput,
- visual, mask, &attr );
- if (!data->client_window)
- {
+ wine_tsx11_lock();
+ XDeleteContext( display, data->whole_window, winContext );
XDestroyWindow( display, data->whole_window );
data->whole_window = 0;
wine_tsx11_unlock();
return 0;
}
- XMapWindow( display, data->client_window );
- XSaveContext( display, data->whole_window, winContext, (char *)data->hwnd );
- XSaveContext( display, data->client_window, winContext, (char *)data->hwnd );
- wine_tsx11_unlock();
-
xim = x11drv_thread_data()->xim;
if (xim) data->xic = X11DRV_CreateIC( xim, display, data->whole_window );
@@ -1202,7 +1216,6 @@
X11DRV_set_wm_hints( display, data );
SetPropA( data->hwnd, whole_window_prop, (HANDLE)data->whole_window );
- SetPropA( data->hwnd, client_window_prop, (HANDLE)data->client_window );
/* set the window text */
if (!InternalGetWindowText( data->hwnd, text, sizeof(text)/sizeof(WCHAR) )) text[0] = 0;