diff -ru xwin_66/InitOutput.c xwin/InitOutput.c --- xwin_66/InitOutput.c 2002-10-20 11:44:36.000000000 +0900 +++ xwin/InitOutput.c 2002-10-20 12:21:14.000000000 +0900 @@ -44,6 +44,7 @@ int g_iCmapPrivateIndex = -1; int g_iGCPrivateIndex = -1; int g_iPixmapPrivateIndex = -1; +int g_iWindowPrivateIndex = -1; unsigned long g_ulServerGeneration = 0; Bool g_fInitializedDefaultScreens = FALSE; FILE *g_pfLog = NULL; diff -ru xwin_66/win.h xwin/win.h --- xwin_66/win.h 2002-10-20 11:44:36.000000000 +0900 +++ xwin/win.h 2002-10-20 11:58:22.000000000 +0900 @@ -292,6 +292,7 @@ typedef struct { DWORD dwDummy; + HRGN hRgn; } winPrivWinRec, *winPrivWinPtr; @@ -516,6 +517,9 @@ ClearToBackgroundProcPtr ClearToBackground; ClipNotifyProcPtr ClipNotify; RestackWindowProcPtr RestackWindow; +#ifdef SHAPE + SetShapeProcPtr SetShape; +#endif } winPrivScreenRec, *winPrivScreenPtr; @@ -531,6 +535,7 @@ extern int g_iCmapPrivateIndex; extern int g_iGCPrivateIndex; extern int g_iPixmapPrivateIndex; +extern int g_iWindowPrivateIndex; extern unsigned long g_ulServerGeneration; extern CARD32 g_c32LastInputEventTime; extern DWORD g_dwEnginesSupported; @@ -609,8 +614,14 @@ * Window privates macros */ -#define winGetWindowPrivate(_pWin) ((winPrivWin *)\ - (_pWin)->devPrivates[winWindowPrivateIndex].ptr) +#define winGetWindowPriv(pWin) \ + ((winPrivWinPtr) (pWin)->devPrivates[g_iWindowPrivateIndex].ptr) + +#define winSetWindowPriv(pWin,v) \ + ((pWin)->devPrivates[g_iWindowPrivateIndex].ptr = (pointer) v) + +#define winWindowPriv(pWin) \ + winPrivWinPtr pWinPriv = winGetWindowPriv(pWin) /* @@ -1341,6 +1352,10 @@ Bool winMapWindowPRootless (WindowPtr pWindow); +#ifdef SHAPE +void +winSetShapePRootless (WindowPtr pWindow); +#endif /* * winwndproc.c diff -ru xwin_66/winallpriv.c xwin/winallpriv.c --- xwin_66/winallpriv.c 2002-10-20 11:44:36.000000000 +0900 +++ xwin/winallpriv.c 2002-10-20 11:58:40.000000000 +0900 @@ -60,6 +60,7 @@ g_iScreenPrivateIndex = AllocateScreenPrivateIndex (); g_iGCPrivateIndex = AllocateGCPrivateIndex (); g_iPixmapPrivateIndex = AllocatePixmapPrivateIndex (); + g_iWindowPrivateIndex = AllocateWindowPrivateIndex (); g_ulServerGeneration = serverGeneration; } @@ -97,6 +98,14 @@ return FALSE; } + /* Reserve Window memory for our privates */ + if (!AllocateWindowPrivate (pScreen, g_iWindowPrivateIndex, + sizeof (winPrivWinRec))) + { + ErrorF ("winAllocatePrivates () - AllocateWindowPrivates () failed\n"); + return FALSE; + } + return TRUE; } diff -ru xwin_66/winscrinit.c xwin/winscrinit.c --- xwin_66/winscrinit.c 2002-10-20 11:44:36.000000000 +0900 +++ xwin/winscrinit.c 2002-10-20 12:01:24.000000000 +0900 @@ -390,6 +390,9 @@ WRAP(UnrealizeWindow); WRAP(PositionWindow); WRAP(ChangeWindowAttributes); +#ifdef SHAPE + WRAP(SetShape); +#endif /* Assign pseudo-rootless window procedures to be top level procedures */ pScreen->CreateWindow = winCreateWindowPRootless; @@ -398,6 +401,9 @@ pScreen->ChangeWindowAttributes = winChangeWindowAttributesPRootless; pScreen->RealizeWindow = winMapWindowPRootless; pScreen->UnrealizeWindow = winUnmapWindowPRootless; +#ifdef SHAPE + pScreen->SetShape = winSetShapePRootless; +#endif /* Undefine the WRAP macro, as it is not needed elsewhere */ #undef WRAP diff -ru xwin_66/winwindow.c xwin/winwindow.c --- xwin_66/winwindow.c 2002-10-20 11:44:36.000000000 +0900 +++ xwin/winwindow.c 2002-10-20 13:35:38.000000000 +0900 @@ -42,6 +42,10 @@ static void winUpdateRgn (WindowPtr pWindow); +#ifdef SHAPE +static void +winReshape (WindowPtr pWin); +#endif /* See Porting Layer Definition - p. 37 */ @@ -138,6 +142,7 @@ winCreateWindowPRootless (WindowPtr pWin) { Bool fResult = FALSE; + winWindowPriv(pWin); #if CYGDEBUG ErrorF ("winCreateWindowPRootless()\n"); @@ -145,6 +150,7 @@ fResult = winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow(pWin); + pWinPriv->hRgn = NULL; /*winUpdateRgn (pWin);*/ return fResult; @@ -158,6 +164,7 @@ winDestroyWindowPRootless (WindowPtr pWin) { Bool fResult = FALSE; + winWindowPriv(pWin); #if CYGDEBUG ErrorF ("winDestroyWindowPRootless()\n"); @@ -165,6 +172,12 @@ fResult = winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow(pWin); + if (pWinPriv->hRgn != NULL) + { + DeleteObject(pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + winUpdateRgn (pWin); return fResult; @@ -185,6 +198,11 @@ fResult = winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow(pWin, x, y); + if (wBoundingShape(pWin)) + { + winReshape (pWin); + } + winUpdateRgn (pWin); return fResult; @@ -253,39 +271,70 @@ } +#ifdef SHAPE +void +winSetShapePRootless (WindowPtr pWin) +{ +#if CYGDEBUG + ErrorF ("winSetShapePRootless()\n"); +#endif + + winGetScreenPriv(pWin->drawable.pScreen)->SetShape(pWin); + + winReshape (pWin); + winUpdateRgn (pWin); + + return; +} +#endif + + /* * Local function for adding a region to the Windows window region */ static int -winAddRgn (WindowPtr pWindow, pointer data) +winAddRgn (WindowPtr pWin, pointer data) { int iX, iY, iWidth, iHeight, iBorder; HRGN hRgn = *(HRGN*)data; HRGN hRgnWin; + winWindowPriv(pWin); - /* If pWindow is not Root */ - if (pWindow->parent != NULL) + /* If pWin is not Root */ + if (pWin->parent != NULL) { +#if CYGDEBUG ErrorF("winAddRgn()\n"); - if (pWindow->mapped) +#endif + if (pWin->mapped) { - iBorder = wBorderWidth (pWindow); + iBorder = wBorderWidth (pWin); - iX = pWindow->drawable.x - iBorder; - iY = pWindow->drawable.y - iBorder; + iX = pWin->drawable.x - iBorder; + iY = pWin->drawable.y - iBorder; - iWidth = pWindow->drawable.width + iBorder * 2; - iHeight = pWindow->drawable.height + iBorder * 2; + iWidth = pWin->drawable.width + iBorder * 2; + iHeight = pWin->drawable.height + iBorder * 2; - hRgnWin = CreateRectRgn (iX, iY, iX + iWidth, iY + iHeight); + hRgnWin = CreateRectRgn (0, 0, iWidth, iHeight); if (hRgnWin == NULL) { ErrorF ("winAddRgn - CreateRectRgn() failed\n"); ErrorF (" Rect %d %d %d %d\n", iX, iY, iX + iWidth, iY + iHeight); } + + if (pWinPriv->hRgn) + { + if (CombineRgn(hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND) == ERROR) + { + ErrorF("winSetShapePRootless - CombineRgn() failed\n"); + } + } + + OffsetRgn (hRgnWin, iX, iY); if (CombineRgn (hRgn, hRgn, hRgnWin, RGN_OR) == ERROR) { @@ -309,14 +358,14 @@ static void -winUpdateRgn (WindowPtr pWindow) +winUpdateRgn (WindowPtr pWin) { HRGN hRgn = CreateRectRgn (0, 0, 0, 0); if (hRgn != NULL) { - WalkTree (pWindow->drawable.pScreen, winAddRgn, &hRgn); - SetWindowRgn (winGetScreenPriv(pWindow->drawable.pScreen)->hwndScreen, + WalkTree (pWin->drawable.pScreen, winAddRgn, &hRgn); + SetWindowRgn (winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen, hRgn, TRUE); } else @@ -324,3 +373,93 @@ ErrorF ("winUpdateRgn fail to CreateRectRgn\n"); } } + + +#ifdef SHAPE +static +void +winReshape (WindowPtr pWin) +{ + int nRects; + ScreenPtr pScreen = pWin->drawable.pScreen; + RegionRec rrNewShape; + BoxPtr pShape, pRects, pEnd; + HRGN hRgn, hRgnRect; + winWindowPriv(pWin); + +#if CYGDEBUG + ErrorF ("winReshape()\n"); +#endif + + if (pWin->parent == NULL) + { /* If pWin is Root */ + return; + } + else if (pWin->parent->parent != NULL) + { /* If pWin is not top level */ + return; + } + + if (wBoundingShape(pWin)) + { + REGION_INIT(pScreen, &rrNewShape, NullBox, 0); + REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin)); + REGION_TRANSLATE(pScreen, &rrNewShape, pWin->borderWidth, + pWin->borderWidth); + } + else + { + if (pWinPriv->hRgn != NULL) + { + DeleteObject(pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + return; + } + } + + nRects = REGION_NUM_RECTS(&rrNewShape); + pShape = REGION_RECTS(&rrNewShape); + + if (nRects > 0) + { + hRgn = CreateRectRgn (0, 0, 0, 0); + for (pRects = pShape, pEnd = pShape+nRects; pRects < pEnd; pRects++) + { + hRgnRect = CreateRectRgn(pRects->x1, pRects->y1, + pRects->x2, pRects->y2); + if (hRgnRect == NULL) + { + ErrorF("winReshape - CreateRectRgn() failed\n"); + } + + if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF("winReshape - CombineRgn() failed\n"); + } + + DeleteObject(hRgnRect); + } + + if (pWinPriv->hRgn != NULL) + { + DeleteObject(pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + pWinPriv->hRgn = hRgn; + } + else + { + if (pWinPriv->hRgn != NULL) + { + DeleteObject(pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + } + + REGION_UNINIT(pScreen, &rrNewShape); + + return; +} +#endif