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