[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