[PATCH] Add the ability to recreate the X11 window associated with the client area.

Roderick Colenbrander thunderbird2k at gmx.net
Sun Dec 16 07:26:30 CST 2007


---
 dlls/winex11.drv/window.c |   73 ++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 62 insertions(+), 11 deletions(-)

diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 79f63d0..f6d2c8d 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -54,6 +54,9 @@ XContext winContext = 0;
 /* X context to associate a struct x11drv_win_data to an hwnd */
 static XContext win_data_context;
 
+static Window create_client_window( Display *display, struct x11drv_win_data *data, XVisualInfo *vis);
+static void destroy_client_window( Display *display, struct x11drv_win_data *data );
+
 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";
@@ -245,9 +248,21 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
         return FALSE;
     }
 
-    if(data->whole_window && vis->visualid == XVisualIDFromVisual(visual))
+    if(data->client_window && vis->visualid == XVisualIDFromVisual(visual))
     {
-        TRACE("Whole window available and visual match, rendering onscreen\n");
+        TRACE("Client window available and visual match, rendering onscreen\n");
+        goto done;
+    }
+    else if(data->client_window)
+    {
+        TRACE("Client window available but the visual doesn't match, recreating the client window\n");
+
+        wine_tsx11_unlock();
+        destroy_client_window( display, data );
+        create_client_window( display, data, vis);
+        wine_tsx11_lock();
+
+        TRACE("New client window: %#lx\n", data->client_window);
         goto done;
     }
 
@@ -1091,7 +1106,7 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
  *
  * Create the client window for a given window
  */
-static Window create_client_window( Display *display, struct x11drv_win_data *data)
+static Window create_client_window( Display *display, struct x11drv_win_data *data, XVisualInfo *vis)
 {
     RECT rect = data->whole_rect;
     XSetWindowAttributes attr;
@@ -1104,12 +1119,30 @@ static Window create_client_window( Display *display, struct x11drv_win_data *da
     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 );
+
+    /* Create a client window with a custom visual. This is needed for OpenGL / Direct3D. */
+    if(vis)
+    {
+        attr.colormap = XCreateColormap(display, data->whole_window, vis->visual, AllocNone);
+        XInstallColormap(display, attr.colormap);
+
+        data->client_window = XCreateWindow( display, data->whole_window, 0, 0,
+                                            max( rect.right - rect.left, 1 ),
+                                            max( rect.bottom - rect.top, 1 ),
+                                            0, vis->depth,
+                                            InputOutput, vis->visual,
+                                            CWEventMask | CWBitGravity | CWBackingStore | CWColormap,
+                                            &attr );
+    }
+    else
+    {
+        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 );
@@ -1119,6 +1152,24 @@ static Window create_client_window( Display *display, struct x11drv_win_data *da
     return data->client_window;
 }
 
+/***********************************************************************
+ *              destroy_client_window
+ */
+static void destroy_client_window( Display *display, struct x11drv_win_data *data )
+{
+    if (!data->client_window) return;
+
+    wine_tsx11_lock();
+
+    XDeleteContext( display, data->client_window, winContext );
+    XDestroyWindow( display, data->client_window );
+    data->client_window = 0;
+    XFlush(display);
+
+    wine_tsx11_unlock();
+    RemovePropA( data->hwnd, client_window_prop );
+}
+
 
 /**********************************************************************
  *		destroy_whole_window
@@ -1380,7 +1431,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;
+        if (!create_client_window( display, data, NULL )) goto failed;
     }
     else if (hwnd == GetDesktopWindow())
     {
@@ -1646,7 +1697,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 );
+        create_client_window( display, data, NULL );
     }
 }
 
-- 
1.5.1.3


--========GMX295141197821446473836--



More information about the wine-patches mailing list