[PATCH] Create X11 windows for the client area.
Roderick Colenbrander
thunderbird2k at gmx.net
Sun Dec 16 06:41:09 CST 2007
---
dlls/winex11.drv/dce.c | 11 +++++-
dlls/winex11.drv/window.c | 89 +++++++++++++++++++++++++++++++++++++++------
dlls/winex11.drv/winpos.c | 4 ++-
dlls/winex11.drv/x11drv.h | 2 +
server/window.c | 5 ++-
5 files changed, 96 insertions(+), 15 deletions(-)
diff --git a/dlls/winex11.drv/dce.c b/dlls/winex11.drv/dce.c
index 11d869e..c0a4182 100644
--- a/dlls/winex11.drv/dce.c
+++ b/dlls/winex11.drv/dce.c
@@ -154,9 +154,18 @@ static void update_visible_region( struct dce *dce )
escape.gl_drawable = 0;
escape.pixmap = 0;
}
- else
+ else if(top == dce->hwnd && (flags & DCX_WINDOW))
{
escape.drawable = X11DRV_get_whole_window( top );
+ escape.fbconfig_id = 0;
+ escape.gl_drawable = 0;
+ escape.pixmap = 0;
+ }
+ else
+ {
+ escape.drawable = X11DRV_get_client_window( top );
+ if(!escape.drawable)
+ escape.drawable = X11DRV_get_whole_window( top );
escape.fbconfig_id = X11DRV_get_fbconfig_id( dce->hwnd );
escape.gl_drawable = X11DRV_get_gl_drawable( dce->hwnd );
escape.pixmap = X11DRV_get_gl_pixmap( dce->hwnd );
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 7348f2a..79f63d0 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -54,13 +54,14 @@ XContext winContext = 0;
/* X context to associate a struct x11drv_win_data to an hwnd */
static XContext win_data_context;
-static const char whole_window_prop[] = "__wine_x11_whole_window";
-static const char icon_window_prop[] = "__wine_x11_icon_window";
-static const char fbconfig_id_prop[] = "__wine_x11_fbconfig_id";
-static const char gl_drawable_prop[] = "__wine_x11_gl_drawable";
-static const char pixmap_prop[] = "__wine_x11_pixmap";
-static const char managed_prop[] = "__wine_x11_managed";
-static const char visual_id_prop[] = "__wine_x11_visual_id";
+static const char whole_window_prop[] = "__wine_x11_whole_window";
+static const char client_window_prop[] = "__wine_x11_client_window";
+static const char icon_window_prop[] = "__wine_x11_icon_window";
+static const char fbconfig_id_prop[] = "__wine_x11_fbconfig_id";
+static const char gl_drawable_prop[] = "__wine_x11_gl_drawable";
+static const char pixmap_prop[] = "__wine_x11_pixmap";
+static const char managed_prop[] = "__wine_x11_managed";
+static const char visual_id_prop[] = "__wine_x11_visual_id";
/* for XDG systray icons */
#define SYSTEM_TRAY_REQUEST_DOCK 0
@@ -252,7 +253,7 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
wine_tsx11_unlock();
- parent = data->whole_window;
+ parent = data->client_window;
next_hwnd = hwnd;
while(!parent)
{
@@ -262,7 +263,7 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
ERR("Could not find parent HWND with a drawable!\n");
return FALSE;
}
- parent = X11DRV_get_whole_window(next_hwnd);
+ parent = X11DRV_get_client_window(next_hwnd);
}
w = data->client_rect.right - data->client_rect.left;
@@ -372,7 +373,7 @@ static void update_gl_drawable(Display *display, struct x11drv_win_data *data, c
}
#endif
- parent = data->whole_window;
+ parent = data->client_window;
next_hwnd = data->hwnd;
while(!parent)
{
@@ -382,7 +383,7 @@ static void update_gl_drawable(Display *display, struct x11drv_win_data *data, c
ERR("Could not find parent HWND with a drawable!\n");
return;
}
- parent = X11DRV_get_whole_window(next_hwnd);
+ parent = X11DRV_get_client_window(next_hwnd);
}
wine_tsx11_lock();
@@ -1015,8 +1016,24 @@ void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data
DefaultScreen(display), mask, &changes );
wine_tsx11_unlock();
}
-}
+ if (data->client_window)
+ {
+ int w = data->client_rect.right - data->client_rect.left;
+ int h = data->client_rect.bottom - data->client_rect.top;
+
+ TRACE("Updating client window 0x%lx to %dx%x,%dx%d\n", data->client_window,
+ data->client_rect.left, data->client_rect.top, w, h);
+
+ if(w>0 && h>0)
+ {
+ wine_tsx11_lock();
+ XMoveResizeWindow(display, data->client_window, data->client_rect.left,
+ data->client_rect.top, w, h);
+ wine_tsx11_unlock();
+ }
+ }
+}
/**********************************************************************
* create_whole_window
@@ -1069,6 +1086,39 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
return data->whole_window;
}
+/**********************************************************************
+ * create_client_window
+ *
+ * Create the client window for a given window
+ */
+static Window create_client_window( Display *display, struct x11drv_win_data *data)
+{
+ RECT rect = data->whole_rect;
+ XSetWindowAttributes attr;
+
+ OffsetRect( &rect, -data->whole_rect.left, -data->whole_rect.top );
+ data->client_rect = rect;
+
+ attr.event_mask = ExposureMask;
+ attr.bit_gravity = ForgetGravity;
+ attr.backing_store = NotUseful;
+
+ wine_tsx11_lock();
+ data->client_window = XCreateWindow( display, data->whole_window, 0, 0,
+ max( rect.right - rect.left, 1 ),
+ max( rect.bottom - rect.top, 1 ),
+ 0, screen_depth,
+ InputOutput, visual,
+ CWEventMask | CWBitGravity | CWBackingStore, &attr );
+
+ XSaveContext( display, data->client_window, winContext, (char *)data->hwnd );
+ XMapWindow( display, data->client_window );
+ wine_tsx11_unlock();
+
+ SetPropA( data->hwnd, client_window_prop, (HANDLE)data->client_window );
+ return data->client_window;
+}
+
/**********************************************************************
* destroy_whole_window
@@ -1202,6 +1252,7 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd )
{
data->hwnd = hwnd;
data->whole_window = 0;
+ data->client_window = 0;
data->icon_window = 0;
data->fbconfig_id = 0;
data->gl_drawable = 0;
@@ -1329,6 +1380,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
{
if (!create_whole_window( display, data, cs->style )) goto failed;
+ if (!create_client_window( display, data )) goto failed;
}
else if (hwnd == GetDesktopWindow())
{
@@ -1497,6 +1549,18 @@ Window X11DRV_get_whole_window( HWND hwnd )
return data->whole_window;
}
+/***********************************************************************
+ * X11DRV_get_client_window
+ *
+ * Return the X window associated with the client area of a window
+ */
+Window X11DRV_get_client_window( HWND hwnd )
+{
+ struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+
+ if (!data) return (Window)GetPropA( hwnd, client_window_prop );
+ return data->client_window;
+}
/***********************************************************************
* X11DRV_get_fbconfig_id
@@ -1582,6 +1646,7 @@ void X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
/* FIXME: we ignore errors since we can't really recover anyway */
create_whole_window( display, data, GetWindowLongW( hwnd, GWL_STYLE ) );
+ create_client_window( display, data );
}
}
diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c
index c01f702..0fc79ae 100644
--- a/dlls/winex11.drv/winpos.c
+++ b/dlls/winex11.drv/winpos.c
@@ -121,7 +121,9 @@ void X11DRV_Expose( HWND hwnd, XEvent *xev )
SERVER_END_REQ;
/* make position relative to client area instead of window */
- OffsetRect( &rect, -data->client_rect.left, -data->client_rect.top );
+ if(event->window != data->client_window)
+ OffsetRect( &rect, -data->client_rect.left, -data->client_rect.top );
+
RedrawWindow( hwnd, &rect, 0, flags );
}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index ec03e71..ff80e26 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -661,6 +661,7 @@ struct x11drv_win_data
{
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 of the toplevel window */
Window icon_window; /* X window for the icon */
XID fbconfig_id; /* fbconfig id for the GL drawable this hwnd uses */
Drawable gl_drawable; /* Optional GL drawable for rendering the client area */
@@ -680,6 +681,7 @@ struct x11drv_win_data
extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd );
extern Window X11DRV_get_whole_window( HWND hwnd );
+extern Window X11DRV_get_client_window( HWND hwnd );
extern XID X11DRV_get_fbconfig_id( HWND hwnd );
extern Drawable X11DRV_get_gl_drawable( HWND hwnd );
extern Pixmap X11DRV_get_gl_pixmap( HWND hwnd );
diff --git a/server/window.c b/server/window.c
index 8cf8001..a31a717 100644
--- a/server/window.c
+++ b/server/window.c
@@ -1997,7 +1997,10 @@ DECL_HANDLER(get_visible_region)
if (data) set_reply_data_ptr( data, reply->total_size );
}
reply->top_win = top->handle;
- reply->top_rect = top->visible_rect;
+ if(top == win && (req->flags&DCX_WINDOW))
+ reply->top_rect = top->visible_rect;
+ else
+ reply->top_rect = top->client_rect;
if (!is_desktop_window(win))
{
--
1.5.1.3
--========GMX295121197821309766847--
More information about the wine-patches
mailing list