(X11 Series 2/3) Fix handling of non-default visuals
Michael Karcher
wine at mkarcher.dialup.fu-berlin.de
Sun Mar 16 15:08:33 CDT 2008
This patch fixes wine with respect to a non-default visual for Wine
windows. The issue is that for an X11 window depth, colormap and visual
have to match, otherwise a BadMatch error is raised. Furthermore, GCs
are specific to one depth, so a GC created for the root window does not
work with windows of a different depth. This is the reason for the
template window I create on non-default visuals. Of course, the Windows
concept of having one GC that works everywhere on the screen breaks in
the case of non-default visuals. I don't see any way to prevent that.
This patch has not yet been thoroughly tested. But it makes wine
applications start if I force ScreenDepth to 32 (thus using a ARGB
visual instead of the 24 bit RGB visual). Using the ARGB visual, I
encountered another bug, namely invisible text. The next patch in this
series fixes it.
>From d6e88b4e9981b5ae6bb6b2f33530b8bea88745e1 Mon Sep 17 00:00:00 2001
From: Michael Karcher <wine at mkarcher.dialup.fu-berlin.de>
Date: Sun, 16 Mar 2008 20:41:57 +0100
Subject: [PATCH] Fixed handling of non-default visuals, to prevent BadMatch
errors from X. This code is more like patched-to-work-at-least-a-bit
than complete worked through. Be careful!
---
dlls/winex11.drv/clipboard.c | 2 +-
dlls/winex11.drv/init.c | 28 +++++++++++++++++++++++++++-
dlls/winex11.drv/window.c | 12 +++++++++---
dlls/winex11.drv/x11drv.h | 2 ++
4 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 5e85998..6b719a6 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -326,7 +326,7 @@ static Window thread_selection_wnd(void)
ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
wine_tsx11_lock();
- w = XCreateWindow(thread_display(), root_window, 0, 0, 1, 1, 0, screen_depth,
+ w = XCreateWindow(thread_display(), root_window, 0, 0, 1, 1, 0, CopyFromParent,
InputOutput, CopyFromParent, CWEventMask, &attr);
wine_tsx11_unlock();
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index 5e549b9..6c49284 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -33,6 +33,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
+Window template_window;
Display *gdi_display; /* display to use for all GDI functions */
/* a few dynamic device caps */
@@ -77,6 +78,29 @@ static DWORD get_dpi( void )
return dpi;
}
+static void init_template_window(void)
+{
+ if( screen_depth != DefaultDepthOfScreen( screen ))
+ {
+ XSetWindowAttributes att;
+ att.colormap = X11DRV_PALETTE_PaletteXColormap;
+ att.border_pixel = BlackPixel( gdi_display, XScreenNumberOfScreen(screen) );
+ template_window = XCreateWindow( gdi_display, root_window, 0, 0, 1, 1, 0,
+ screen_depth, InputOutput, visual,
+ CWColormap | CWBorderPixel, &att );
+ }
+ else
+ {
+ template_window = root_window;
+ }
+}
+
+static void remove_template_window(void)
+{
+ if(template_window != root_window)
+ XDestroyWindow( gdi_display, template_window );
+}
+
/**********************************************************************
* device_init
*
@@ -94,6 +118,7 @@ static void device_init(void)
palette_size = X11DRV_PALETTE_Init();
+ init_template_window();
X11DRV_BITMAP_Init();
/* Initialize device caps */
@@ -110,6 +135,7 @@ static void device_init(void)
*/
void X11DRV_GDI_Finalize(void)
{
+ remove_template_window();
X11DRV_PALETTE_Cleanup();
/* don't bother to close the display, it often triggers X bugs */
/* XCloseDisplay( gdi_display ); */
@@ -144,7 +170,7 @@ BOOL X11DRV_CreateDC( HDC hdc, X11DRV_PDEVICE **pdev, LPCWSTR driver, LPCWSTR de
else
{
physDev->bitmap = NULL;
- physDev->drawable = root_window;
+ physDev->drawable = template_window;
physDev->depth = screen_depth;
physDev->drawable_rect = virtual_screen_rect;
SetRect( &physDev->dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left,
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 2d94455..ef526e1 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -590,6 +590,7 @@ static Window create_icon_window( Display *display, struct x11drv_win_data *data
attr.bit_gravity = NorthWestGravity;
attr.backing_store = NotUseful/*WhenMapped*/;
attr.colormap = X11DRV_PALETTE_PaletteXColormap; /* Needed due to our visual */
+ attr.border_pixel = BlackPixel ( display, XScreenNumberOfScreen(screen) ); /* Needed due to our visual */
wine_tsx11_lock();
data->icon_window = XCreateWindow( display, root_window, 0, 0,
@@ -597,7 +598,7 @@ static Window create_icon_window( Display *display, struct x11drv_win_data *data
GetSystemMetrics( SM_CYICON ),
0, screen_depth,
InputOutput, visual,
- CWEventMask | CWBitGravity | CWBackingStore | CWColormap, &attr );
+ CWEventMask | CWBitGravity | CWBackingStore | CWColormap | CWBorderPixel, &attr );
XSaveContext( display, data->icon_window, winContext, (char *)data->hwnd );
wine_tsx11_unlock();
@@ -1155,11 +1156,16 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
wine_tsx11_lock();
data->whole_rect = data->window_rect;
+ /* HACK: Set CWBorderPixel to prevent a BadMatch on the BorderPixmap
+ when creating windows in a different visual than the root window.
+
+ As the border width is zero, the border itself is never used */
+ attr.border_pixel = BlackPixel( display, DefaultScreen(display) );
data->whole_window = XCreateWindow( display, root_window,
data->window_rect.left - virtual_screen_rect.left,
data->window_rect.top - virtual_screen_rect.top,
cx, cy, 0, screen_depth, InputOutput,
- visual, mask, &attr );
+ visual, mask | CWBorderPixel, &attr );
if (data->whole_window) XSaveContext( display, data->whole_window, winContext, (char *)data->hwnd );
wine_tsx11_unlock();
@@ -1555,7 +1561,7 @@ void X11DRV_ReleaseDC( HWND hwnd, HDC hdc )
struct x11drv_escape_set_drawable escape;
escape.code = X11DRV_SET_DRAWABLE;
- escape.drawable = root_window;
+ escape.drawable = template_window;
escape.mode = IncludeInferiors;
escape.drawable_rect = virtual_screen_rect;
SetRect( &escape.dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left,
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 52670e8..04da1c9 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -520,8 +520,10 @@ static inline struct x11drv_thread_data *x11drv_thread_data(void)
static inline Display *thread_display(void) { return x11drv_thread_data()->display; }
+extern Screen *screen;
extern Visual *visual;
extern Window root_window;
+extern Window template_window;
extern unsigned int screen_width;
extern unsigned int screen_height;
extern unsigned int screen_bpp;
--
1.5.4.3
More information about the wine-patches
mailing list