105b261ecSmrg/* 205b261ecSmrg 305b261ecSmrgCopyright 1993 by Davor Matic 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software 605b261ecSmrgand its documentation for any purpose is hereby granted without fee, 705b261ecSmrgprovided that the above copyright notice appear in all copies and that 805b261ecSmrgboth that copyright notice and this permission notice appear in 905b261ecSmrgsupporting documentation. Davor Matic makes no representations about 1005b261ecSmrgthe suitability of this software for any purpose. It is provided "as 1105b261ecSmrgis" without express or implied warranty. 1205b261ecSmrg 1305b261ecSmrg*/ 1405b261ecSmrg 1505b261ecSmrg#ifdef HAVE_XNEST_CONFIG_H 1605b261ecSmrg#include <xnest-config.h> 1705b261ecSmrg#endif 1805b261ecSmrg 1905b261ecSmrg#include <X11/X.h> 2005b261ecSmrg#include <X11/Xproto.h> 2105b261ecSmrg#include "gcstruct.h" 2205b261ecSmrg#include "window.h" 2305b261ecSmrg#include "windowstr.h" 2405b261ecSmrg#include "pixmapstr.h" 2505b261ecSmrg#include "colormapst.h" 2605b261ecSmrg#include "scrnintstr.h" 2705b261ecSmrg#include "region.h" 2805b261ecSmrg 2905b261ecSmrg#include "mi.h" 3005b261ecSmrg 3105b261ecSmrg#include "Xnest.h" 3205b261ecSmrg 3305b261ecSmrg#include "Display.h" 3405b261ecSmrg#include "Screen.h" 3505b261ecSmrg#include "XNGC.h" 3605b261ecSmrg#include "Drawable.h" 3705b261ecSmrg#include "Color.h" 3805b261ecSmrg#include "Visual.h" 3905b261ecSmrg#include "Events.h" 4005b261ecSmrg#include "Args.h" 4105b261ecSmrg 426747b715SmrgDevPrivateKeyRec xnestWindowPrivateKeyRec; 4305b261ecSmrg 4405b261ecSmrgstatic int 4535c4bbdfSmrgxnestFindWindowMatch(WindowPtr pWin, void *ptr) 4605b261ecSmrg{ 4735c4bbdfSmrg xnestWindowMatch *wm = (xnestWindowMatch *) ptr; 4835c4bbdfSmrg 4935c4bbdfSmrg if (wm->window == xnestWindow(pWin)) { 5035c4bbdfSmrg wm->pWin = pWin; 5135c4bbdfSmrg return WT_STOPWALKING; 5235c4bbdfSmrg } 5335c4bbdfSmrg else 5435c4bbdfSmrg return WT_WALKCHILDREN; 5505b261ecSmrg} 5605b261ecSmrg 5705b261ecSmrgWindowPtr 5805b261ecSmrgxnestWindowPtr(Window window) 5905b261ecSmrg{ 6035c4bbdfSmrg xnestWindowMatch wm; 6135c4bbdfSmrg int i; 6235c4bbdfSmrg 6335c4bbdfSmrg wm.pWin = NullWindow; 6435c4bbdfSmrg wm.window = window; 6535c4bbdfSmrg 6635c4bbdfSmrg for (i = 0; i < xnestNumScreens; i++) { 6735c4bbdfSmrg WalkTree(screenInfo.screens[i], xnestFindWindowMatch, (void *) &wm); 6835c4bbdfSmrg if (wm.pWin) 6935c4bbdfSmrg break; 7035c4bbdfSmrg } 7135c4bbdfSmrg 7235c4bbdfSmrg return wm.pWin; 7305b261ecSmrg} 7435c4bbdfSmrg 7505b261ecSmrgBool 7605b261ecSmrgxnestCreateWindow(WindowPtr pWin) 7705b261ecSmrg{ 7835c4bbdfSmrg unsigned long mask; 7935c4bbdfSmrg XSetWindowAttributes attributes; 8035c4bbdfSmrg Visual *visual; 8135c4bbdfSmrg ColormapPtr pCmap; 8235c4bbdfSmrg 8335c4bbdfSmrg if (pWin->drawable.class == InputOnly) { 8435c4bbdfSmrg mask = 0L; 8535c4bbdfSmrg visual = CopyFromParent; 8605b261ecSmrg } 8735c4bbdfSmrg else { 8835c4bbdfSmrg mask = CWEventMask | CWBackingStore; 8935c4bbdfSmrg attributes.event_mask = ExposureMask; 9035c4bbdfSmrg attributes.backing_store = NotUseful; 9135c4bbdfSmrg 9235c4bbdfSmrg if (pWin->parent) { 9335c4bbdfSmrg if (pWin->optional && 9435c4bbdfSmrg pWin->optional->visual != wVisual(pWin->parent)) { 9535c4bbdfSmrg visual = 9635c4bbdfSmrg xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin)); 9735c4bbdfSmrg mask |= CWColormap; 9835c4bbdfSmrg if (pWin->optional->colormap) { 9935c4bbdfSmrg dixLookupResourceByType((void **) &pCmap, wColormap(pWin), 10035c4bbdfSmrg RT_COLORMAP, serverClient, 10135c4bbdfSmrg DixUseAccess); 10235c4bbdfSmrg attributes.colormap = xnestColormap(pCmap); 10335c4bbdfSmrg } 10435c4bbdfSmrg else 10535c4bbdfSmrg attributes.colormap = xnestDefaultVisualColormap(visual); 10635c4bbdfSmrg } 10735c4bbdfSmrg else 10835c4bbdfSmrg visual = CopyFromParent; 10935c4bbdfSmrg } 11035c4bbdfSmrg else { /* root windows have their own colormaps at creation time */ 11135c4bbdfSmrg visual = xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin)); 11235c4bbdfSmrg dixLookupResourceByType((void **) &pCmap, wColormap(pWin), 11335c4bbdfSmrg RT_COLORMAP, serverClient, DixUseAccess); 11435c4bbdfSmrg mask |= CWColormap; 11535c4bbdfSmrg attributes.colormap = xnestColormap(pCmap); 11635c4bbdfSmrg } 11705b261ecSmrg } 11835c4bbdfSmrg 11935c4bbdfSmrg xnestWindowPriv(pWin)->window = XCreateWindow(xnestDisplay, 12035c4bbdfSmrg xnestWindowParent(pWin), 12135c4bbdfSmrg pWin->origin.x - 12235c4bbdfSmrg wBorderWidth(pWin), 12335c4bbdfSmrg pWin->origin.y - 12435c4bbdfSmrg wBorderWidth(pWin), 12535c4bbdfSmrg pWin->drawable.width, 12635c4bbdfSmrg pWin->drawable.height, 12735c4bbdfSmrg pWin->borderWidth, 12835c4bbdfSmrg pWin->drawable.depth, 12935c4bbdfSmrg pWin->drawable.class, 13035c4bbdfSmrg visual, mask, &attributes); 13135c4bbdfSmrg xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin); 13235c4bbdfSmrg xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin); 13335c4bbdfSmrg xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin); 13435c4bbdfSmrg xnestWindowPriv(pWin)->width = pWin->drawable.width; 13535c4bbdfSmrg xnestWindowPriv(pWin)->height = pWin->drawable.height; 13635c4bbdfSmrg xnestWindowPriv(pWin)->border_width = pWin->borderWidth; 13735c4bbdfSmrg xnestWindowPriv(pWin)->sibling_above = None; 13835c4bbdfSmrg if (pWin->nextSib) 13935c4bbdfSmrg xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin); 14035c4bbdfSmrg xnestWindowPriv(pWin)->bounding_shape = RegionCreate(NULL, 1); 14135c4bbdfSmrg xnestWindowPriv(pWin)->clip_shape = RegionCreate(NULL, 1); 14235c4bbdfSmrg 14335c4bbdfSmrg if (!pWin->parent) /* only the root window will have the right colormap */ 14435c4bbdfSmrg xnestSetInstalledColormapWindows(pWin->drawable.pScreen); 14535c4bbdfSmrg 14635c4bbdfSmrg return True; 14705b261ecSmrg} 14805b261ecSmrg 14905b261ecSmrgBool 15005b261ecSmrgxnestDestroyWindow(WindowPtr pWin) 15105b261ecSmrg{ 15235c4bbdfSmrg if (pWin->nextSib) 15335c4bbdfSmrg xnestWindowPriv(pWin->nextSib)->sibling_above = 15435c4bbdfSmrg xnestWindowPriv(pWin)->sibling_above; 15535c4bbdfSmrg RegionDestroy(xnestWindowPriv(pWin)->bounding_shape); 15635c4bbdfSmrg RegionDestroy(xnestWindowPriv(pWin)->clip_shape); 15735c4bbdfSmrg XDestroyWindow(xnestDisplay, xnestWindow(pWin)); 15835c4bbdfSmrg xnestWindowPriv(pWin)->window = None; 15935c4bbdfSmrg 16035c4bbdfSmrg if (pWin->optional && pWin->optional->colormap && pWin->parent) 16135c4bbdfSmrg xnestSetInstalledColormapWindows(pWin->drawable.pScreen); 16235c4bbdfSmrg 16335c4bbdfSmrg return True; 16405b261ecSmrg} 16505b261ecSmrg 16605b261ecSmrgBool 16705b261ecSmrgxnestPositionWindow(WindowPtr pWin, int x, int y) 16805b261ecSmrg{ 16935c4bbdfSmrg xnestConfigureWindow(pWin, 17035c4bbdfSmrg CWParent | 17135c4bbdfSmrg CWX | CWY | CWWidth | CWHeight | CWBorderWidth); 17235c4bbdfSmrg 17335c4bbdfSmrg return True; 17405b261ecSmrg} 17505b261ecSmrg 17605b261ecSmrgvoid 17705b261ecSmrgxnestConfigureWindow(WindowPtr pWin, unsigned int mask) 17805b261ecSmrg{ 17935c4bbdfSmrg unsigned int valuemask; 18035c4bbdfSmrg XWindowChanges values; 18135c4bbdfSmrg 18235c4bbdfSmrg if (mask & CWParent && 18335c4bbdfSmrg xnestWindowPriv(pWin)->parent != xnestWindowParent(pWin)) { 18435c4bbdfSmrg XReparentWindow(xnestDisplay, xnestWindow(pWin), 18535c4bbdfSmrg xnestWindowParent(pWin), 18635c4bbdfSmrg pWin->origin.x - wBorderWidth(pWin), 18735c4bbdfSmrg pWin->origin.y - wBorderWidth(pWin)); 18835c4bbdfSmrg xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin); 18935c4bbdfSmrg xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin); 19035c4bbdfSmrg xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin); 19135c4bbdfSmrg xnestWindowPriv(pWin)->sibling_above = None; 19235c4bbdfSmrg if (pWin->nextSib) 19335c4bbdfSmrg xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin); 19435c4bbdfSmrg } 19535c4bbdfSmrg 19635c4bbdfSmrg valuemask = 0; 19735c4bbdfSmrg 19835c4bbdfSmrg if (mask & CWX && 19935c4bbdfSmrg xnestWindowPriv(pWin)->x != pWin->origin.x - wBorderWidth(pWin)) { 20035c4bbdfSmrg valuemask |= CWX; 20135c4bbdfSmrg values.x = 20235c4bbdfSmrg xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin); 20335c4bbdfSmrg } 20435c4bbdfSmrg 20535c4bbdfSmrg if (mask & CWY && 20635c4bbdfSmrg xnestWindowPriv(pWin)->y != pWin->origin.y - wBorderWidth(pWin)) { 20735c4bbdfSmrg valuemask |= CWY; 20835c4bbdfSmrg values.y = 20935c4bbdfSmrg xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin); 21035c4bbdfSmrg } 21135c4bbdfSmrg 21235c4bbdfSmrg if (mask & CWWidth && xnestWindowPriv(pWin)->width != pWin->drawable.width) { 21335c4bbdfSmrg valuemask |= CWWidth; 21435c4bbdfSmrg values.width = xnestWindowPriv(pWin)->width = pWin->drawable.width; 21535c4bbdfSmrg } 21635c4bbdfSmrg 21735c4bbdfSmrg if (mask & CWHeight && 21835c4bbdfSmrg xnestWindowPriv(pWin)->height != pWin->drawable.height) { 21935c4bbdfSmrg valuemask |= CWHeight; 22035c4bbdfSmrg values.height = xnestWindowPriv(pWin)->height = pWin->drawable.height; 22135c4bbdfSmrg } 22235c4bbdfSmrg 22335c4bbdfSmrg if (mask & CWBorderWidth && 22435c4bbdfSmrg xnestWindowPriv(pWin)->border_width != pWin->borderWidth) { 22535c4bbdfSmrg valuemask |= CWBorderWidth; 22635c4bbdfSmrg values.border_width = 22735c4bbdfSmrg xnestWindowPriv(pWin)->border_width = pWin->borderWidth; 22835c4bbdfSmrg } 22935c4bbdfSmrg 23035c4bbdfSmrg if (valuemask) 23135c4bbdfSmrg XConfigureWindow(xnestDisplay, xnestWindow(pWin), valuemask, &values); 23235c4bbdfSmrg 23335c4bbdfSmrg if (mask & CWStackingOrder && 23435c4bbdfSmrg xnestWindowPriv(pWin)->sibling_above != xnestWindowSiblingAbove(pWin)) { 23535c4bbdfSmrg WindowPtr pSib; 23635c4bbdfSmrg 23735c4bbdfSmrg /* find the top sibling */ 23835c4bbdfSmrg for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib); 23935c4bbdfSmrg 24035c4bbdfSmrg /* the top sibling */ 24135c4bbdfSmrg valuemask = CWStackMode; 24235c4bbdfSmrg values.stack_mode = Above; 24335c4bbdfSmrg XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask, &values); 24435c4bbdfSmrg xnestWindowPriv(pSib)->sibling_above = None; 24535c4bbdfSmrg 24635c4bbdfSmrg /* the rest of siblings */ 24735c4bbdfSmrg for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib) { 24835c4bbdfSmrg valuemask = CWSibling | CWStackMode; 24935c4bbdfSmrg values.sibling = xnestWindowSiblingAbove(pSib); 25035c4bbdfSmrg values.stack_mode = Below; 25135c4bbdfSmrg XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask, 25235c4bbdfSmrg &values); 25335c4bbdfSmrg xnestWindowPriv(pSib)->sibling_above = 25435c4bbdfSmrg xnestWindowSiblingAbove(pSib); 25535c4bbdfSmrg } 25605b261ecSmrg } 25705b261ecSmrg} 25805b261ecSmrg 25905b261ecSmrgBool 26005b261ecSmrgxnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask) 26105b261ecSmrg{ 26235c4bbdfSmrg XSetWindowAttributes attributes; 26335c4bbdfSmrg 26435c4bbdfSmrg if (mask & CWBackPixmap) 26535c4bbdfSmrg switch (pWin->backgroundState) { 26635c4bbdfSmrg case None: 26735c4bbdfSmrg attributes.background_pixmap = None; 26835c4bbdfSmrg break; 26935c4bbdfSmrg 27035c4bbdfSmrg case ParentRelative: 27135c4bbdfSmrg attributes.background_pixmap = ParentRelative; 27235c4bbdfSmrg break; 27335c4bbdfSmrg 27435c4bbdfSmrg case BackgroundPixmap: 27535c4bbdfSmrg attributes.background_pixmap = xnestPixmap(pWin->background.pixmap); 27635c4bbdfSmrg break; 27735c4bbdfSmrg 27835c4bbdfSmrg case BackgroundPixel: 27935c4bbdfSmrg mask &= ~CWBackPixmap; 28035c4bbdfSmrg break; 28135c4bbdfSmrg } 28235c4bbdfSmrg 28335c4bbdfSmrg if (mask & CWBackPixel) { 28435c4bbdfSmrg if (pWin->backgroundState == BackgroundPixel) 28535c4bbdfSmrg attributes.background_pixel = xnestPixel(pWin->background.pixel); 28635c4bbdfSmrg else 28735c4bbdfSmrg mask &= ~CWBackPixel; 28805b261ecSmrg } 28905b261ecSmrg 29035c4bbdfSmrg if (mask & CWBorderPixmap) { 29135c4bbdfSmrg if (pWin->borderIsPixel) 29235c4bbdfSmrg mask &= ~CWBorderPixmap; 29335c4bbdfSmrg else 29435c4bbdfSmrg attributes.border_pixmap = xnestPixmap(pWin->border.pixmap); 29535c4bbdfSmrg } 29605b261ecSmrg 29735c4bbdfSmrg if (mask & CWBorderPixel) { 29835c4bbdfSmrg if (pWin->borderIsPixel) 29935c4bbdfSmrg attributes.border_pixel = xnestPixel(pWin->border.pixel); 30035c4bbdfSmrg else 30135c4bbdfSmrg mask &= ~CWBorderPixel; 30235c4bbdfSmrg } 30305b261ecSmrg 30435c4bbdfSmrg if (mask & CWBitGravity) 30535c4bbdfSmrg attributes.bit_gravity = pWin->bitGravity; 30605b261ecSmrg 30735c4bbdfSmrg if (mask & CWWinGravity) /* dix does this for us */ 30835c4bbdfSmrg mask &= ~CWWinGravity; 30905b261ecSmrg 31035c4bbdfSmrg if (mask & CWBackingStore) /* this is really not useful */ 31135c4bbdfSmrg mask &= ~CWBackingStore; 31205b261ecSmrg 31335c4bbdfSmrg if (mask & CWBackingPlanes) /* this is really not useful */ 31435c4bbdfSmrg mask &= ~CWBackingPlanes; 31505b261ecSmrg 31635c4bbdfSmrg if (mask & CWBackingPixel) /* this is really not useful */ 31735c4bbdfSmrg mask &= ~CWBackingPixel; 31805b261ecSmrg 31935c4bbdfSmrg if (mask & CWOverrideRedirect) 32035c4bbdfSmrg attributes.override_redirect = pWin->overrideRedirect; 32105b261ecSmrg 32235c4bbdfSmrg if (mask & CWSaveUnder) /* this is really not useful */ 32335c4bbdfSmrg mask &= ~CWSaveUnder; 32405b261ecSmrg 32535c4bbdfSmrg if (mask & CWEventMask) /* events are handled elsewhere */ 32635c4bbdfSmrg mask &= ~CWEventMask; 32705b261ecSmrg 32835c4bbdfSmrg if (mask & CWDontPropagate) /* events are handled elsewhere */ 32935c4bbdfSmrg mask &= ~CWDontPropagate; 33005b261ecSmrg 33135c4bbdfSmrg if (mask & CWColormap) { 33235c4bbdfSmrg ColormapPtr pCmap; 33335c4bbdfSmrg 33435c4bbdfSmrg dixLookupResourceByType((void **) &pCmap, wColormap(pWin), 33535c4bbdfSmrg RT_COLORMAP, serverClient, DixUseAccess); 33635c4bbdfSmrg 33735c4bbdfSmrg attributes.colormap = xnestColormap(pCmap); 33835c4bbdfSmrg 33935c4bbdfSmrg xnestSetInstalledColormapWindows(pWin->drawable.pScreen); 34035c4bbdfSmrg } 34105b261ecSmrg 342ed6184dfSmrg if (mask & CWCursor) /* this is handled in cursor code */ 34335c4bbdfSmrg mask &= ~CWCursor; 34435c4bbdfSmrg 34535c4bbdfSmrg if (mask) 34635c4bbdfSmrg XChangeWindowAttributes(xnestDisplay, xnestWindow(pWin), 34735c4bbdfSmrg mask, &attributes); 34835c4bbdfSmrg 34935c4bbdfSmrg return True; 35035c4bbdfSmrg} 35105b261ecSmrg 35205b261ecSmrgBool 35305b261ecSmrgxnestRealizeWindow(WindowPtr pWin) 35405b261ecSmrg{ 35535c4bbdfSmrg xnestConfigureWindow(pWin, CWStackingOrder); 35635c4bbdfSmrg xnestShapeWindow(pWin); 35735c4bbdfSmrg XMapWindow(xnestDisplay, xnestWindow(pWin)); 35805b261ecSmrg 35935c4bbdfSmrg return True; 36005b261ecSmrg} 36105b261ecSmrg 36205b261ecSmrgBool 36305b261ecSmrgxnestUnrealizeWindow(WindowPtr pWin) 36405b261ecSmrg{ 36535c4bbdfSmrg XUnmapWindow(xnestDisplay, xnestWindow(pWin)); 36605b261ecSmrg 36735c4bbdfSmrg return True; 36805b261ecSmrg} 36905b261ecSmrg 37005b261ecSmrgvoid 37105b261ecSmrgxnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion) 37205b261ecSmrg{ 37305b261ecSmrg} 37405b261ecSmrg 37505b261ecSmrgvoid 37605b261ecSmrgxnestClipNotify(WindowPtr pWin, int dx, int dy) 37705b261ecSmrg{ 37835c4bbdfSmrg xnestConfigureWindow(pWin, CWStackingOrder); 37935c4bbdfSmrg xnestShapeWindow(pWin); 38005b261ecSmrg} 38105b261ecSmrg 38205b261ecSmrgstatic Bool 38335c4bbdfSmrgxnestWindowExposurePredicate(Display * dpy, XEvent * event, XPointer ptr) 38405b261ecSmrg{ 38535c4bbdfSmrg return (event->type == Expose && event->xexpose.window == *(Window *) ptr); 38605b261ecSmrg} 38705b261ecSmrg 38805b261ecSmrgvoid 38935c4bbdfSmrgxnestWindowExposures(WindowPtr pWin, RegionPtr pRgn) 39005b261ecSmrg{ 39135c4bbdfSmrg XEvent event; 39235c4bbdfSmrg Window window; 39335c4bbdfSmrg BoxRec Box; 39435c4bbdfSmrg 39535c4bbdfSmrg XSync(xnestDisplay, False); 39635c4bbdfSmrg 39735c4bbdfSmrg window = xnestWindow(pWin); 39835c4bbdfSmrg 39935c4bbdfSmrg while (XCheckIfEvent(xnestDisplay, &event, 40035c4bbdfSmrg xnestWindowExposurePredicate, (char *) &window)) { 40135c4bbdfSmrg 40235c4bbdfSmrg Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + event.xexpose.x; 40335c4bbdfSmrg Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + event.xexpose.y; 40435c4bbdfSmrg Box.x2 = Box.x1 + event.xexpose.width; 40535c4bbdfSmrg Box.y2 = Box.y1 + event.xexpose.height; 40635c4bbdfSmrg 40735c4bbdfSmrg event.xexpose.type = ProcessedExpose; 40835c4bbdfSmrg 40935c4bbdfSmrg if (RegionContainsRect(pRgn, &Box) != rgnIN) 41035c4bbdfSmrg XPutBackEvent(xnestDisplay, &event); 41135c4bbdfSmrg } 41235c4bbdfSmrg 41335c4bbdfSmrg miWindowExposures(pWin, pRgn); 41405b261ecSmrg} 41505b261ecSmrg 41605b261ecSmrgvoid 4176747b715SmrgxnestSetShape(WindowPtr pWin, int kind) 41805b261ecSmrg{ 41935c4bbdfSmrg xnestShapeWindow(pWin); 42035c4bbdfSmrg miSetShape(pWin, kind); 42105b261ecSmrg} 42205b261ecSmrg 42305b261ecSmrgstatic Bool 42405b261ecSmrgxnestRegionEqual(RegionPtr pReg1, RegionPtr pReg2) 42505b261ecSmrg{ 42635c4bbdfSmrg BoxPtr pBox1, pBox2; 42735c4bbdfSmrg unsigned int n1, n2; 42805b261ecSmrg 42935c4bbdfSmrg if (pReg1 == pReg2) 43035c4bbdfSmrg return True; 43105b261ecSmrg 43235c4bbdfSmrg if (pReg1 == NullRegion || pReg2 == NullRegion) 43335c4bbdfSmrg return False; 43405b261ecSmrg 43535c4bbdfSmrg pBox1 = RegionRects(pReg1); 43635c4bbdfSmrg n1 = RegionNumRects(pReg1); 43705b261ecSmrg 43835c4bbdfSmrg pBox2 = RegionRects(pReg2); 43935c4bbdfSmrg n2 = RegionNumRects(pReg2); 44005b261ecSmrg 44135c4bbdfSmrg if (n1 != n2) 44235c4bbdfSmrg return False; 44305b261ecSmrg 44435c4bbdfSmrg if (pBox1 == pBox2) 44535c4bbdfSmrg return True; 44605b261ecSmrg 44735c4bbdfSmrg if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec))) 44835c4bbdfSmrg return False; 44905b261ecSmrg 45035c4bbdfSmrg return True; 45105b261ecSmrg} 45205b261ecSmrg 45305b261ecSmrgvoid 45405b261ecSmrgxnestShapeWindow(WindowPtr pWin) 45505b261ecSmrg{ 45635c4bbdfSmrg Region reg; 45735c4bbdfSmrg BoxPtr pBox; 45835c4bbdfSmrg XRectangle rect; 45935c4bbdfSmrg int i; 46035c4bbdfSmrg 46135c4bbdfSmrg if (!xnestRegionEqual(xnestWindowPriv(pWin)->bounding_shape, 46235c4bbdfSmrg wBoundingShape(pWin))) { 46335c4bbdfSmrg 46435c4bbdfSmrg if (wBoundingShape(pWin)) { 46535c4bbdfSmrg RegionCopy(xnestWindowPriv(pWin)->bounding_shape, 46635c4bbdfSmrg wBoundingShape(pWin)); 46735c4bbdfSmrg 46835c4bbdfSmrg reg = XCreateRegion(); 46935c4bbdfSmrg pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape); 47035c4bbdfSmrg for (i = 0; 47135c4bbdfSmrg i < RegionNumRects(xnestWindowPriv(pWin)->bounding_shape); 47235c4bbdfSmrg i++) { 47335c4bbdfSmrg rect.x = pBox[i].x1; 47435c4bbdfSmrg rect.y = pBox[i].y1; 47535c4bbdfSmrg rect.width = pBox[i].x2 - pBox[i].x1; 47635c4bbdfSmrg rect.height = pBox[i].y2 - pBox[i].y1; 47735c4bbdfSmrg XUnionRectWithRegion(&rect, reg, reg); 47835c4bbdfSmrg } 47935c4bbdfSmrg XShapeCombineRegion(xnestDisplay, xnestWindow(pWin), 48035c4bbdfSmrg ShapeBounding, 0, 0, reg, ShapeSet); 48135c4bbdfSmrg XDestroyRegion(reg); 48235c4bbdfSmrg } 48335c4bbdfSmrg else { 48435c4bbdfSmrg RegionEmpty(xnestWindowPriv(pWin)->bounding_shape); 48535c4bbdfSmrg 48635c4bbdfSmrg XShapeCombineMask(xnestDisplay, xnestWindow(pWin), 48735c4bbdfSmrg ShapeBounding, 0, 0, None, ShapeSet); 48835c4bbdfSmrg } 48905b261ecSmrg } 49035c4bbdfSmrg 49135c4bbdfSmrg if (!xnestRegionEqual(xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin))) { 49235c4bbdfSmrg 49335c4bbdfSmrg if (wClipShape(pWin)) { 49435c4bbdfSmrg RegionCopy(xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin)); 49535c4bbdfSmrg 49635c4bbdfSmrg reg = XCreateRegion(); 49735c4bbdfSmrg pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape); 49835c4bbdfSmrg for (i = 0; 49935c4bbdfSmrg i < RegionNumRects(xnestWindowPriv(pWin)->clip_shape); i++) { 50035c4bbdfSmrg rect.x = pBox[i].x1; 50135c4bbdfSmrg rect.y = pBox[i].y1; 50235c4bbdfSmrg rect.width = pBox[i].x2 - pBox[i].x1; 50335c4bbdfSmrg rect.height = pBox[i].y2 - pBox[i].y1; 50435c4bbdfSmrg XUnionRectWithRegion(&rect, reg, reg); 50535c4bbdfSmrg } 50635c4bbdfSmrg XShapeCombineRegion(xnestDisplay, xnestWindow(pWin), 50735c4bbdfSmrg ShapeClip, 0, 0, reg, ShapeSet); 50835c4bbdfSmrg XDestroyRegion(reg); 50935c4bbdfSmrg } 51035c4bbdfSmrg else { 51135c4bbdfSmrg RegionEmpty(xnestWindowPriv(pWin)->clip_shape); 51235c4bbdfSmrg 51335c4bbdfSmrg XShapeCombineMask(xnestDisplay, xnestWindow(pWin), 51435c4bbdfSmrg ShapeClip, 0, 0, None, ShapeSet); 51535c4bbdfSmrg } 51605b261ecSmrg } 51705b261ecSmrg} 518