[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    [PATCH] Set/GetWindowRgn, take 2
From:       Francois Jacques <francoisj () macadamian ! com>
Date:       2000-06-27 16:32:53
[Download RAW message or body]

(same as previous, but with the patch attached!)

Hello world!

Here's a implementation for Set/GetWindowRgn. Notice that it modifies
configure.in and make_X11wrappers, so a few additional steps are needed
to apply the patch.  Here is the procedure

cd <your_wine_sandbox_here>
patch -p0 < WindowRgn.diff
autoconf configure.in > configure ; chmod u+x configure
cd include
autoheader ../configure.in > config.h.in
cd ..
./configure
./tools/make_X11wrappers
make depend ; make

---

Adds non-rectangular windows support to WINE. Functionality permits
support for skin-enabled applications such as WinAMP, RealJukebox and
any type of non-rectangular window you can think of.

Changelog :
    - implementations of SetWindowsRgn and GetWindowRgn
    - GetDCEx updated with a fixme that shows up when applying a window
region to a non-native window
    - X11DRV and TTYDRV updated with new API SetWindowRgn

Modified file(s):
    - configure.in
    - tools/make_X11wrappers
    - tsx11/Makefile.in
    - tsx11/X11_calls
    - dlls/x11drv/x11drv_main.c
    - include/acconfig.h
    - include/ttydrv.h
    - include/x11drv.h
    - include/win.h
    - windows/winpos.c
    - windows/dce.c
    - windows/x11drv/init.c
    - windows/x11drv/wnd.c
    - windows/ttydrv/init.c
    - windows/ttydrv/wnd.c


    François Jacques
    Macadamian Technologies Inc.



["WindowRgn.diff" (text/plain)]

Index: configure.in
===================================================================
RCS file: /home/wine/wine/configure.in,v
retrieving revision 1.130
diff -u -u -r1.130 configure.in
--- configure.in	2000/06/23 20:15:35	1.130
+++ configure.in	2000/06/27 06:23:20
@@ -1,4 +1,4 @@
-dnl Process this file with autoconf to produce a configure script.
+\dnl Process this file with autoconf to produce a configure script.
 dnl Author: Michael Patra   <micky@marie.physik.tu-berlin.de>
 dnl                         <patra@itp1.physik.tu-berlin.de>
 AC_REVISION([configure.in 1.00])
@@ -169,7 +169,17 @@
             AC_MSG_WARN([Xshm extension not found!!])
         )
 
-        dnl *** Check for XFree86 DGA / DGA 2.0 extension
+        dnl *** Check for X shape extension
+        AC_CHECK_HEADERS(X11/Xlib.h X11/extensions/shape.h,
+            [ dnl *** If X11/extensions/shape.h exists...
+              AC_CHECK_LIB(Xext,XShapeQueryExtension,
+	      AC_DEFINE(HAVE_LIBXSHAPE),,
+	      $X_LIBS -lXext -lX11 $X_EXTRA_LIBS)
+	    ],
+	    AC_MSG_WARN([XShape extension found!!])
+	)
+        
+	dnl *** Check for XFree86 DGA / DGA 2.0 extension
         AC_CHECK_HEADERS(X11/extensions/xf86dga.h,
             [ dnl *** If X11/extensions/xf86dga.h exists, check 
               dnl *** for XDGAQueryExtension()...
Index: dlls/x11drv/x11drv_main.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv_main.c,v
retrieving revision 1.16
diff -u -u -r1.16 x11drv_main.c
--- dlls/x11drv/x11drv_main.c	2000/06/23 16:49:46	1.16
+++ dlls/x11drv/x11drv_main.c	2000/06/27 06:23:20
@@ -13,6 +13,7 @@
 #include <X11/cursorfont.h>
 #include "ts_xlib.h"
 #include "ts_xutil.h"
+#include "ts_shape.h"
 
 #include "winbase.h"
 #include "wine/winbase16.h"
Index: include/acconfig.h
===================================================================
RCS file: /home/wine/wine/include/acconfig.h,v
retrieving revision 1.22
diff -u -u -r1.22 acconfig.h
--- include/acconfig.h	2000/05/12 20:18:16	1.22
+++ include/acconfig.h	2000/06/27 06:23:20
@@ -24,6 +24,9 @@
 /* Define if you have the X Shm extension */
 #undef HAVE_LIBXXSHM
 
+/* Define if you have the X Shape extension */
+#undef HAVE_LIBXSHAPE                         
+
 /* Define if you have the Xxf86vm library */
 #undef HAVE_LIBXXF86VM
 
Index: include/ttydrv.h
===================================================================
RCS file: /home/wine/wine/include/ttydrv.h,v
retrieving revision 1.30
diff -u -u -r1.30 ttydrv.h
--- include/ttydrv.h	2000/06/08 04:57:23	1.30
+++ include/ttydrv.h	2000/06/27 06:23:20
@@ -201,5 +201,6 @@
 extern void TTYDRV_WND_SetDrawable(struct tagWND *wndPtr, struct tagDC *dc, WORD \
flags, BOOL bSetClipOrigin);  extern BOOL TTYDRV_WND_SetHostAttr(struct tagWND \
*wndPtr, INT haKey, INT value);  extern BOOL TTYDRV_WND_IsSelfClipping(struct tagWND \
*wndPtr); +extern void TTYDRV_WND_SetWindowRgn(struct tagWND *wndPtr, HRGN hrgnWnd);
 
 #endif /* !defined(__WINE_TTYDRV_H) */
Index: include/win.h
===================================================================
RCS file: /home/wine/wine/include/win.h,v
retrieving revision 1.27
diff -u -u -r1.27 win.h
--- include/win.h	2000/05/23 04:12:23	1.27
+++ include/win.h	2000/06/27 06:23:20
@@ -78,6 +78,7 @@
     struct tagDCE *dce;           /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
     HGLOBAL16      hmemTaskQ;     /* Task queue global memory handle */
     HRGN16         hrgnUpdate;    /* Update region */
+    HRGN           hrgnWnd;       /* window's region */
     HWND         hwndLastActive;/* Last active popup hwnd */
     DWORD          dwStyle;       /* Window style (from CreateWindow) */
     DWORD          dwExStyle;     /* Extended style (from CreateWindowEx) */
@@ -131,6 +132,7 @@
     void   (*pSetDrawable)(WND *, struct tagDC *, WORD, BOOL);
     BOOL   (*pSetHostAttr)(WND *, INT haKey, INT value);
     BOOL (*pIsSelfClipping)(WND *);
+    void   (*pSetWindowRgn)(WND *, const HRGN);
 } WND_DRIVER;
 
 extern WND_DRIVER *WND_Driver;
Index: include/x11drv.h
===================================================================
RCS file: /home/wine/wine/include/x11drv.h,v
retrieving revision 1.52
diff -u -u -r1.52 x11drv.h
--- include/x11drv.h	2000/06/08 04:57:23	1.52
+++ include/x11drv.h	2000/06/27 06:23:20
@@ -431,6 +431,7 @@
 extern BOOL X11DRV_WND_SetHostAttr(struct tagWND *wndPtr, INT haKey, INT value);
 extern BOOL X11DRV_WND_IsSelfClipping(struct tagWND *wndPtr);
 extern void X11DRV_WND_DockWindow(struct tagWND *wndPtr);
+extern void X11DRV_WND_SetWindowRgn(struct tagWND *wndPtr, HRGN hrgnWnd); 
 
 extern int X11DRV_EVENT_PrepareShmCompletion( Drawable dw );
 extern void X11DRV_EVENT_WaitShmCompletion( int compl );
Index: tools/make_X11wrappers
===================================================================
RCS file: /home/wine/wine/tools/make_X11wrappers,v
retrieving revision 1.14
diff -u -u -r1.14 make_X11wrappers
--- tools/make_X11wrappers	2000/04/25 19:55:35	1.14
+++ tools/make_X11wrappers	2000/06/27 06:23:21
@@ -17,7 +17,7 @@
 $X11_include_dir = "/usr/X11/include";
 $outdir = "tsx11";
 $wantfile = "$outdir/X11_calls";
-@dolist = ("Xlib", "Xresource", "Xutil", "xpm", "XShm", "xf86dga", "xf86dga2", \
"xf86vmode"); +@dolist = ("Xlib", "Xresource", "Xutil", "xpm", "XShm", "xf86dga", \
"xf86dga2", "xf86vmode", "shape");  
 # First read list of wanted function names.
 
@@ -80,6 +80,14 @@
 	$pre_file = "#include \"windef.h\"\n#ifdef HAVE_LIBXXF86VM\n#define XMD_H\n#include \
\"basetsd.h\"\n";  $post_file = "#endif /* defined(HAVE_LIBXXF86VM) */\n";
     }
+    if($name eq "shape") {
+        $extensions_dir = "extensions/";
+        $pre_file = "#ifdef HAVE_LIBXSHAPE\n#include <X11/IntrinsicP.h>\n";
+        $post_file = "#endif /* defined(HAVE_LIBXSHAPE) */\n";
+        $inc_name = "shape";
+    }
+
+
 
     print OUTH <<END;
 /*
@@ -154,6 +162,11 @@
 		  "Display *, Drawable, char *, XShmSegmentInfo *, unsigned int, unsigned int, \
                unsigned int",
 		  "Display *a0, Drawable a1, char *a2, XShmSegmentInfo *a3, unsigned int a4, \
unsigned int a5, unsigned int a6",  "a0, a1, a2, a3, a4, a5, a6");
+    } elsif($name eq "shape") {
+	output_fn("XShapeCombineRectangles", "void",
+                  "Display *, Window, int, int, int, XRectangle*, int, int, int",
+                  "Display *a0, Window a1, int a2, int a3, int a4, XRectangle* a5, \
int a6, int a7, int a8", +                  "a0, a1, a2, a3, a4, a5, a6, a7, a8");
     } elsif($name eq "xf86dga") {
     	output_fn("XF86DGAQueryVersion",Bool,
 		"Display*,int*,int*",
Index: tsx11/Makefile.in
===================================================================
RCS file: /home/wine/wine/tsx11/Makefile.in,v
retrieving revision 1.3
diff -u -u -r1.3 Makefile.in
--- tsx11/Makefile.in	1999/09/20 18:42:46	1.3
+++ tsx11/Makefile.in	2000/06/27 06:23:21
@@ -13,6 +13,7 @@
 	ts_xlib.c \
 	ts_xresource.c \
 	ts_xutil.c \
+	ts_shape.c \
 	ts_xpm.c
 
 all: $(MODULE).o
Index: tsx11/X11_calls
===================================================================
RCS file: /home/wine/wine/tsx11/X11_calls,v
retrieving revision 1.15
diff -u -u -r1.15 X11_calls
--- tsx11/X11_calls	2000/06/02 20:36:29	1.15
+++ tsx11/X11_calls	2000/06/27 06:23:21
@@ -143,6 +143,7 @@
 XSetWMProperties
 XSetWMProtocols
 XSetWMSizeHints
+XShapeCombineRectangles
 XShmAttach
 XShmCreateImage
 XShmCreatePixmap
Index: windows/dce.c
===================================================================
RCS file: /home/wine/wine/windows/dce.c,v
retrieving revision 1.36
diff -u -u -r1.36 dce.c
--- windows/dce.c	2000/06/15 00:12:12	1.36
+++ windows/dce.c	2000/06/27 06:23:21
@@ -854,6 +854,10 @@
 	TRACE("no visrgn update %08x dce, hwnd [%04x]\n", (unsigned)dce, hwnd);
 
     /* apply additional region operation (if any) */
+    if (wndPtr->hrgnWnd != 0 && !(wndPtr->flags & WIN_NATIVE))
+    {
+        FIXME("Clipping of window region on non-native windows not implemented!");
+    }
 
     if( flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) )
     {
Index: windows/winpos.c
===================================================================
RCS file: /home/wine/wine/windows/winpos.c,v
retrieving revision 1.62
diff -u -u -r1.62 winpos.c
--- windows/winpos.c	2000/06/14 21:16:18	1.62
+++ windows/winpos.c	2000/06/27 06:23:21
@@ -6,6 +6,7 @@
  */
 
 #include <string.h>
+#include "winerror.h"
 #include "windef.h"
 #include "wingdi.h"
 #include "wine/winuser16.h"
@@ -272,35 +273,144 @@
 /***********************************************************************
  *           GetWindowRgn 
  */
-BOOL WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
-
+int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
 {
-  RECT    rect;
-  WND * wndPtr = WIN_FindWndPtr( hwnd ); 
-  if (!wndPtr) return (ERROR);
-
-  FIXME("GetWindowRgn: doesn't really do regions\n"); 
+  int   nRet = ERROR;
+  HRGN  hCurrRgn = 0;                         
+  WND * wndPtr   = WIN_FindWndPtr( hwnd );    
   
-  memset (&rect, 0, sizeof(rect));
-
-  GetWindowRect ( hwnd, &rect );
-
-  FIXME("Check whether a valid region here\n");
-
-  SetRectRgn ( hrgn, rect.left, rect.top, rect.right, rect.bottom );
+  if (!wndPtr) return (ERROR);
 
+  hCurrRgn = wndPtr->hrgnWnd;      
+  if (!hrgn) 
+  {
+    SetLastError(ERROR_ALREADY_EXISTS);
+    nRet = ERROR;
+  }
+  else if (!hCurrRgn) 
+  {
+    SetLastError(ERROR_INVALID_WINDOW_HANDLE); 
+    nRet = ERROR;
+  }
+  else if (hrgn == hCurrRgn) 
+  {
+    SetLastError(ERROR_INVALID_HANDLE);
+    nRet = ERROR;
+  }
+  else
+  {
+    int  nRectCount   = NULLREGION;
+    
+    nRectCount = CombineRgn(hrgn, hCurrRgn, hCurrRgn, RGN_COPY);
+ 
+    switch (nRectCount) 
+    {
+    case 0:
+       nRet = NULLREGION;
+       break;
+
+    case 1:
+       nRet = SIMPLEREGION;
+       break;
+ 
+    default:
+       nRet = COMPLEXREGION;
+    }
+ 
+    SetLastError(ERROR_SUCCESS);
+  }
+    
   WIN_ReleaseWndPtr(wndPtr);
-  return (SIMPLEREGION);
+  return (nRet);
 }
 
 /***********************************************************************
  *           SetWindowRgn 
  */
 INT WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn,BOOL bRedraw)
-
 {
+  HRGN      tempRgn = 0;
+  RECT      tempRect;
+
+  WND *     wndPtr  = WIN_FindWndPtr(hwnd);
+
+  if (!wndPtr) return(0);
+  
+  /* a region exists for this window */
+  if (hrgn != 0 && hrgn == wndPtr->hrgnWnd) 
+  {
+    /* can't replace actual region with same region 
+       since we're now owner of that region 
+    */
+    SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+    return(0);
+  }
+  
+  if (wndPtr->hrgnWnd) 
+  {
+    /* delete previous region */
+    DeleteObject(wndPtr->hrgnWnd);
+    wndPtr->hrgnWnd = 0;
+  }
+
+  /* we'd like to set it back to 0 */
+  if (hrgn == 0) 
+  {
+    GetWindowRect(hwnd, &tempRect);
+    tempRgn = CreateRectRgnIndirect(&tempRect);
+    hrgn = tempRgn;
+  }
+  else
+  {
+    /* verify that region really exists */
+    DWORD dwRet = 0;
+
+    dwRet = GetRgnBox(hrgn, &tempRect);
+    if (dwRet == 0) 
+    {
+      /* invalid region handle */
+      SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+      return(0);
+    }
+    
+    wndPtr->hrgnWnd = hrgn;
+  }
+
+  /* valid region handle */
+  if (FALSE == bRedraw)
+  {
+          SetWindowPos(hwnd, 
+                NULL, 
+                tempRect.left, 
+                tempRect.top, 
+                tempRect.right  - tempRect.left, 
+                tempRect.bottom - tempRect.top,
+                SWP_NOSIZE |  SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOREDRAW | \
SWP_NOZORDER); +  }
+  else
+  {
+          SetWindowPos(hwnd, 
+                NULL, 
+                tempRect.left, 
+                tempRect.top, 
+                tempRect.right  - tempRect.left, 
+                tempRect.bottom - tempRect.top,
+                SWP_NOSIZE |  SWP_FRAMECHANGED |  SWP_NOMOVE | SWP_NOZORDER);
+  }
+  if ( wndPtr->flags & WIN_NATIVE )
+  {
+    wndPtr->pDriver->pSetWindowRgn(wndPtr, hrgn);
+  }
+  if (tempRgn) 
+  {
+    DeleteObject(tempRgn);
+    tempRgn = 0;
+  }
+                       
+  SetLastError(ERROR_SUCCESS);
+  
+  WIN_ReleaseWndPtr(wndPtr);
 
-  FIXME("SetWindowRgn: stub\n"); 
   return TRUE;
 }
 
Index: windows/ttydrv/init.c
===================================================================
RCS file: /home/wine/wine/windows/ttydrv/init.c,v
retrieving revision 1.16
diff -u -u -r1.16 init.c
--- windows/ttydrv/init.c	2000/03/25 17:30:14	1.16
+++ windows/ttydrv/init.c	2000/06/27 06:23:21
@@ -39,7 +39,8 @@
   TTYDRV_WND_ScrollWindow,
   TTYDRV_WND_SetDrawable,
   TTYDRV_WND_SetHostAttr,
-  TTYDRV_WND_IsSelfClipping
+  TTYDRV_WND_IsSelfClipping,
+  TTYDRV_WND_SetWindowRgn
 };
 
 
Index: windows/x11drv/init.c
===================================================================
RCS file: /home/wine/wine/windows/x11drv/init.c,v
retrieving revision 1.19
diff -u -u -r1.19 init.c
--- windows/x11drv/init.c	2000/04/25 19:55:36	1.19
+++ windows/x11drv/init.c	2000/06/27 06:23:21
@@ -39,7 +39,8 @@
   X11DRV_WND_SurfaceCopy,
   X11DRV_WND_SetDrawable,
   X11DRV_WND_SetHostAttr,
-  X11DRV_WND_IsSelfClipping
+  X11DRV_WND_IsSelfClipping,
+  X11DRV_WND_SetWindowRgn
 };
 
 
Index: windows/x11drv/wnd.c
===================================================================
RCS file: /home/wine/wine/windows/x11drv/wnd.c,v
retrieving revision 1.49
diff -u -u -r1.49 wnd.c
--- windows/x11drv/wnd.c	2000/06/25 12:53:28	1.49
+++ windows/x11drv/wnd.c	2000/06/27 06:23:21
@@ -12,6 +12,7 @@
 
 #include "ts_xlib.h"
 #include "ts_xutil.h"
+#include "ts_shape.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -989,3 +990,74 @@
   );
 }
 
+
+/***********************************************************************
+ *		X11DRV_WND_SetWindowRgn
+ *
+ * Assign specified region to window (for non-rectangular windows)
+ */
+void X11DRV_WND_SetWindowRgn(WND *wndPtr, HRGN hrgnWnd)
+{
+    Window   win  = X11DRV_WND_GetXWindow(wndPtr);
+
+    if (0 != win)
+    {
+        DWORD    dwBufferSize = GetRegionData(hrgnWnd, 0, NULL);
+        PRGNDATA  pRegionData = (PRGNDATA) HeapAlloc(SystemHeap, 0, dwBufferSize);
+        DWORD    dwRegionSize = 0;
+
+        int      op          = ShapeSet; 
+        int      dest_kind   = ShapeBounding;
+
+        /* no x or y offset */
+        int      x_off       = 0; 
+        int      y_off       = 0;
+
+        /* 0 = unsorted */
+        int      ordering    = 0;
+
+        GetRegionData(hrgnWnd, dwBufferSize, pRegionData);
+        dwRegionSize = pRegionData->rdh.nCount;
+
+        {
+            /* convert region's "Windows rectangles" to XRectangles */
+            XRectangle  aXRect[dwRegionSize];
+            XRectangle* pCurrRect = aXRect;
+            RECT*       pRect     = (RECT*) pRegionData->Buffer;
+
+            for (; pRect < ((RECT*) pRegionData->Buffer) + dwRegionSize ; ++pRect, \
++pCurrRect) +            {
+                pCurrRect->x      = pRect->left;
+                pCurrRect->y      = pRect->top;
+                pCurrRect->height = pRect->bottom - pRect->top;
+                pCurrRect->width  = pRect->right  - pRect->left;
+
+                TRACE("Rectangle %04d of %04ld data: X=%04d, Y=%04d, Height=%04d, \
Width=%04d.\n", +                      pRect - (RECT*) pRegionData->Buffer,
+                      dwRegionSize,
+                      pCurrRect->x,
+                      pCurrRect->y,
+                      pCurrRect->height,
+                      pCurrRect->width);
+            }
+
+            /* shape = non-rectangular windows (X11/extensions) */
+            TSXShapeCombineRectangles( display, 
+                                       win, 
+                                       dest_kind, 
+                                       x_off, 
+                                       y_off, 
+                                       aXRect , 
+                                       pCurrRect - aXRect, 
+                                       op, 
+                                       ordering);
+            TSXFlush(display);
+        }
+        HeapFree(SystemHeap, 0, pRegionData);
+    }
+    else
+    {
+        WARN("wndPtr hasn't any associated X window!\n");
+    }
+    return;
+}



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic