[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