Alexandre Julliard : winex11: Support setting the window region on windows belonging to other threads.

Alexandre Julliard julliard at winehq.org
Tue Sep 9 05:50:22 CDT 2008


Module: wine
Branch: master
Commit: 9d45cfde33f49339956167206a10da7229608df6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9d45cfde33f49339956167206a10da7229608df6

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Sep  8 15:51:08 2008 +0200

winex11: Support setting the window region on windows belonging to other threads.

---

 dlls/winex11.drv/window.c |   35 +++++++++++++++++++++++------------
 dlls/winex11.drv/x11drv.h |    1 +
 2 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 4e9c779..e03bbb6 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -336,12 +336,24 @@ static void sync_window_style( Display *display, struct x11drv_win_data *data )
  *
  * Update the X11 window region.
  */
-static void sync_window_region( Display *display, struct x11drv_win_data *data, HRGN hrgn )
+static void sync_window_region( Display *display, struct x11drv_win_data *data, HRGN win_region )
 {
 #ifdef HAVE_LIBXSHAPE
+    HRGN hrgn = win_region;
+
     if (!data->whole_window) return;
     data->shaped = FALSE;
 
+    if (hrgn == (HRGN)1)  /* hack: win_region == 1 means retrieve region from server */
+    {
+        if (!(hrgn = CreateRectRgn( 0, 0, 0, 0 ))) return;
+        if (GetWindowRgn( data->hwnd, hrgn ) == ERROR)
+        {
+            DeleteObject( hrgn );
+            hrgn = 0;
+        }
+    }
+
     if (!hrgn)
     {
         wine_tsx11_lock();
@@ -364,6 +376,7 @@ static void sync_window_region( Display *display, struct x11drv_win_data *data,
             data->shaped = TRUE;
         }
     }
+    if (hrgn && hrgn != win_region) DeleteObject( hrgn );
 #endif  /* HAVE_LIBXSHAPE */
 }
 
@@ -1327,7 +1340,6 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
     int cx, cy, mask;
     XSetWindowAttributes attr;
     WCHAR text[1024];
-    HRGN hrgn;
 
     if (!(cx = data->window_rect.right - data->window_rect.left)) cx = 1;
     if (!(cy = data->window_rect.bottom - data->window_rect.top)) cy = 1;
@@ -1375,11 +1387,8 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat
     sync_window_text( display, data->whole_window, text );
 
     /* set the window region */
-    if ((hrgn = CreateRectRgn( 0, 0, 0, 0 )))
-    {
-        if (GetWindowRgn( data->hwnd, hrgn ) != ERROR) sync_window_region( display, data, hrgn );
-        DeleteObject( hrgn );
-    }
+    sync_window_region( display, data, (HRGN)1 );
+
     wine_tsx11_lock();
     XFlush( display );  /* make sure the window exists before we start painting to it */
     wine_tsx11_unlock();
@@ -2142,13 +2151,10 @@ int X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
     {
         sync_window_region( thread_display(), data, hrgn );
     }
-    else if (GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId())
+    else if (X11DRV_get_whole_window( hwnd ))
     {
-        FIXME( "not supported on other thread window %p\n", hwnd );
-        SetLastError( ERROR_INVALID_WINDOW_HANDLE );
-        return FALSE;
+        SendMessageW( hwnd, WM_X11DRV_SET_WIN_REGION, 0, 0 );
     }
-
     return TRUE;
 }
 
@@ -2158,6 +2164,8 @@ int X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
  */
 LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
 {
+    struct x11drv_win_data *data;
+
     switch(msg)
     {
     case WM_X11DRV_ACQUIRE_SELECTION:
@@ -2166,6 +2174,9 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
         return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
     case WM_X11DRV_SET_WIN_FORMAT:
         return set_win_format( hwnd, (XID)wp );
+    case WM_X11DRV_SET_WIN_REGION:
+        if ((data = X11DRV_get_win_data( hwnd ))) sync_window_region( thread_display(), data, (HRGN)1 );
+        return 0;
     case WM_X11DRV_RESIZE_DESKTOP:
         X11DRV_resize_desktop( LOWORD(lp), HIWORD(lp) );
         return 0;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a9d1abd..7ed91b3 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -668,6 +668,7 @@ enum x11drv_window_messages
     WM_X11DRV_ACQUIRE_SELECTION = 0x80001000,
     WM_X11DRV_DELETE_WINDOW,
     WM_X11DRV_SET_WIN_FORMAT,
+    WM_X11DRV_SET_WIN_REGION,
     WM_X11DRV_RESIZE_DESKTOP
 };
 




More information about the wine-cvs mailing list