You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3363 lines
99 KiB
C
3363 lines
99 KiB
C
10 years ago
|
/*
|
||
|
|
||
|
Copyright (c) 2006, Red Hat, Inc.
|
||
|
|
||
|
Permission to use, copy, modify, distribute, and sell this software and its
|
||
|
documentation for any purpose is hereby granted without fee, provided that
|
||
|
the above copyright notice appear in all copies and that both that
|
||
|
copyright notice and this permission notice appear in supporting
|
||
|
documentation.
|
||
|
|
||
|
The above copyright notice and this permission notice shall be included in
|
||
|
all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
|
RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
Except as contained in this notice, the name of Red Hat shall not be
|
||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||
|
in this Software without prior written authorization from Red Hat.
|
||
|
|
||
|
Copyright 1987, 1998 The Open Group
|
||
|
|
||
|
Permission to use, copy, modify, distribute, and sell this software and its
|
||
|
documentation for any purpose is hereby granted without fee, provided that
|
||
|
the above copyright notice appear in all copies and that both that
|
||
|
copyright notice and this permission notice appear in supporting
|
||
|
documentation.
|
||
|
|
||
|
The above copyright notice and this permission notice shall be included
|
||
|
in all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||
|
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
Except as contained in this notice, the name of The Open Group shall
|
||
|
not be used in advertising or otherwise to promote the sale, use or
|
||
|
other dealings in this Software without prior written authorization
|
||
|
from The Open Group.
|
||
|
|
||
|
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
|
||
|
|
||
|
All Rights Reserved
|
||
|
|
||
|
Permission to use, copy, modify, and distribute this software and its
|
||
|
documentation for any purpose and without fee is hereby granted,
|
||
|
provided that the above copyright notice appear in all copies and that
|
||
|
both that copyright notice and this permission notice appear in
|
||
|
supporting documentation, and that the name of Digital not be
|
||
|
used in advertising or publicity pertaining to distribution of the
|
||
|
software without specific, written prior permission.
|
||
|
|
||
|
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||
|
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||
|
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||
|
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||
|
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||
|
SOFTWARE.
|
||
|
|
||
|
*/
|
||
|
|
||
|
#ifdef HAVE_DIX_CONFIG_H
|
||
|
#include <dix-config.h>
|
||
|
#endif
|
||
|
|
||
|
#include "misc.h"
|
||
|
#include "scrnintstr.h"
|
||
|
#include "os.h"
|
||
|
#include "regionstr.h"
|
||
|
#include "validate.h"
|
||
|
#include "windowstr.h"
|
||
|
#include "input.h"
|
||
|
#include "resource.h"
|
||
|
#include "colormapst.h"
|
||
|
#include "cursorstr.h"
|
||
|
#include "dixstruct.h"
|
||
|
#include "gcstruct.h"
|
||
|
#include "servermd.h"
|
||
|
#include "dixevents.h"
|
||
|
#include "globals.h"
|
||
|
|
||
|
|
||
|
/******
|
||
|
* Window stuff for server
|
||
|
*
|
||
|
* CreateRootWindow, CreateWindow, ChangeWindowAttributes,
|
||
|
* GetWindowAttributes, DeleteWindow, DestroySubWindows,
|
||
|
* HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
|
||
|
* UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
|
||
|
*
|
||
|
******/
|
||
|
|
||
|
static const unsigned char _back_lsb[4] = { 0x88, 0x22, 0x44, 0x11 };
|
||
|
static const unsigned char _back_msb[4] = { 0x11, 0x44, 0x22, 0x88 };
|
||
|
|
||
|
_X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF;
|
||
|
|
||
|
_X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
|
||
|
|
||
|
static Bool TileScreenSaver(int i, int kind);
|
||
|
|
||
|
#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
|
||
|
CWDontPropagate | CWOverrideRedirect | CWCursor )
|
||
|
|
||
|
#define BOXES_OVERLAP(b1, b2) \
|
||
|
(!( ((b1)->x2 <= (b2)->x1) || \
|
||
|
( ((b1)->x1 >= (b2)->x2)) || \
|
||
|
( ((b1)->y2 <= (b2)->y1)) || \
|
||
|
( ((b1)->y1 >= (b2)->y2)) ) )
|
||
|
|
||
|
#define RedirectSend(pWin) \
|
||
|
((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
|
||
|
|
||
|
#define SubSend(pWin) \
|
||
|
((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
|
||
|
|
||
|
#define StrSend(pWin) \
|
||
|
((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
|
||
|
|
||
|
#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
/******
|
||
|
* PrintWindowTree
|
||
|
* For debugging only
|
||
|
******/
|
||
|
|
||
|
int
|
||
|
PrintChildren(WindowPtr p1, int indent)
|
||
|
{
|
||
|
WindowPtr p2;
|
||
|
|
||
|
int i;
|
||
|
|
||
|
while (p1) {
|
||
|
p2 = p1->firstChild;
|
||
|
for (i = 0; i < indent; i++)
|
||
|
ErrorF(" ");
|
||
|
ErrorF("%x\n", p1->drawable.id);
|
||
|
miPrintRegion(&p1->clipList);
|
||
|
PrintChildren(p2, indent + 4);
|
||
|
p1 = p1->nextSib;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PrintWindowTree()
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
WindowPtr pWin, p1;
|
||
|
|
||
|
for (i = 0; i < screenInfo.numScreens; i++) {
|
||
|
ErrorF("WINDOW %d\n", i);
|
||
|
pWin = WindowTable[i];
|
||
|
miPrintRegion(&pWin->clipList);
|
||
|
p1 = pWin->firstChild;
|
||
|
PrintChildren(p1, 4);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
_X_EXPORT int
|
||
|
TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
|
||
|
{
|
||
|
int result;
|
||
|
|
||
|
WindowPtr pChild;
|
||
|
|
||
|
if (!(pChild = pWin))
|
||
|
return (WT_NOMATCH);
|
||
|
while (1) {
|
||
|
result = (*func) (pChild, data);
|
||
|
if (result == WT_STOPWALKING)
|
||
|
return (WT_STOPWALKING);
|
||
|
if ((result == WT_WALKCHILDREN) && pChild->firstChild) {
|
||
|
pChild = pChild->firstChild;
|
||
|
continue;
|
||
|
}
|
||
|
while (!pChild->nextSib && (pChild != pWin))
|
||
|
pChild = pChild->parent;
|
||
|
if (pChild == pWin)
|
||
|
break;
|
||
|
pChild = pChild->nextSib;
|
||
|
}
|
||
|
return (WT_NOMATCH);
|
||
|
}
|
||
|
|
||
|
/*****
|
||
|
* WalkTree
|
||
|
* Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
|
||
|
* each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
|
||
|
* if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
|
||
|
* exit WalkTree. Does depth-first traverse.
|
||
|
*****/
|
||
|
|
||
|
_X_EXPORT int
|
||
|
WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
|
||
|
{
|
||
|
return (TraverseTree(WindowTable[pScreen->myNum], func, data));
|
||
|
}
|
||
|
|
||
|
/* hack for forcing backing store on all windows */
|
||
|
static const int defaultBackingStore = NotUseful;
|
||
|
|
||
|
static void
|
||
|
SetWindowToDefaults(register WindowPtr pWin)
|
||
|
{
|
||
|
pWin->prevSib = NullWindow;
|
||
|
pWin->firstChild = NullWindow;
|
||
|
pWin->lastChild = NullWindow;
|
||
|
|
||
|
pWin->valdata = (ValidatePtr) NULL;
|
||
|
pWin->optional = (WindowOptPtr) NULL;
|
||
|
pWin->cursorIsNone = TRUE;
|
||
|
|
||
|
pWin->backingStore = NotUseful;
|
||
|
pWin->DIXsaveUnder = FALSE;
|
||
|
pWin->backStorage = (pointer) NULL;
|
||
|
|
||
|
pWin->mapped = FALSE; /* off */
|
||
|
pWin->realized = FALSE; /* off */
|
||
|
pWin->viewable = FALSE;
|
||
|
pWin->visibility = VisibilityNotViewable;
|
||
|
pWin->overrideRedirect = FALSE;
|
||
|
pWin->saveUnder = FALSE;
|
||
|
|
||
|
pWin->bitGravity = ForgetGravity;
|
||
|
pWin->winGravity = NorthWestGravity;
|
||
|
|
||
|
pWin->eventMask = 0;
|
||
|
pWin->deliverableEvents = 0;
|
||
|
pWin->dontPropagate = 0;
|
||
|
pWin->forcedBS = FALSE;
|
||
|
#ifdef NEED_DBE_BUF_BITS
|
||
|
pWin->srcBuffer = DBE_FRONT_BUFFER;
|
||
|
pWin->dstBuffer = DBE_FRONT_BUFFER;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
MakeRootTile(WindowPtr pWin)
|
||
|
{
|
||
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||
|
|
||
|
GCPtr pGC;
|
||
|
|
||
|
unsigned char back[128];
|
||
|
|
||
|
int len = BitmapBytePad(sizeof(long));
|
||
|
|
||
|
const unsigned char *from;
|
||
|
unsigned char *to;
|
||
|
|
||
|
int i, j;
|
||
|
|
||
|
pWin->background.pixmap = (*pScreen->CreatePixmap) (pScreen, 4, 4,
|
||
|
pScreen->rootDepth);
|
||
|
|
||
|
pWin->backgroundState = BackgroundPixmap;
|
||
|
pGC = GetScratchGC(pScreen->rootDepth, pScreen);
|
||
|
if (!pWin->background.pixmap || !pGC)
|
||
|
FatalError("could not create root tile");
|
||
|
|
||
|
{
|
||
|
CARD32 attributes[2];
|
||
|
|
||
|
attributes[0] = pScreen->whitePixel;
|
||
|
attributes[1] = pScreen->blackPixel;
|
||
|
|
||
|
(void) ChangeGC(pGC, GCForeground | GCBackground, attributes);
|
||
|
}
|
||
|
|
||
|
ValidateGC((DrawablePtr) pWin->background.pixmap, pGC);
|
||
|
|
||
|
from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
|
||
|
to = back;
|
||
|
|
||
|
for (i = 4; i > 0; i--, from++)
|
||
|
for (j = len; j > 0; j--)
|
||
|
*to++ = *from;
|
||
|
|
||
|
(*pGC->ops->PutImage) ((DrawablePtr) pWin->background.pixmap, pGC, 1,
|
||
|
0, 0, len, 4, 0, XYBitmap, (char *) back);
|
||
|
|
||
|
FreeScratchGC(pGC);
|
||
|
|
||
|
}
|
||
|
|
||
|
WindowPtr
|
||
|
AllocateWindow(ScreenPtr pScreen)
|
||
|
{
|
||
|
WindowPtr pWin;
|
||
|
|
||
|
char *ptr;
|
||
|
|
||
|
DevUnion *ppriv;
|
||
|
|
||
|
unsigned *sizes;
|
||
|
|
||
|
unsigned size;
|
||
|
|
||
|
int i;
|
||
|
|
||
|
pWin = malloc(pScreen->totalWindowSize);
|
||
|
if (pWin) {
|
||
|
ppriv = (DevUnion *) (pWin + 1);
|
||
|
pWin->devPrivates = ppriv;
|
||
|
sizes = pScreen->WindowPrivateSizes;
|
||
|
ptr = (char *) (ppriv + pScreen->WindowPrivateLen);
|
||
|
for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++) {
|
||
|
if ((size = *sizes)) {
|
||
|
ppriv->ptr = (pointer) ptr;
|
||
|
ptr += size;
|
||
|
}
|
||
|
else
|
||
|
ppriv->ptr = (pointer) NULL;
|
||
|
}
|
||
|
#if _XSERVER64
|
||
|
pWin->drawable.pad0 = 0;
|
||
|
pWin->drawable.pad1 = 0;
|
||
|
#endif
|
||
|
}
|
||
|
return pWin;
|
||
|
}
|
||
|
|
||
|
/*****
|
||
|
* CreateRootWindow
|
||
|
* Makes a window at initialization time for specified screen
|
||
|
*****/
|
||
|
|
||
|
Bool
|
||
|
CreateRootWindow(ScreenPtr pScreen)
|
||
|
{
|
||
|
WindowPtr pWin;
|
||
|
|
||
|
BoxRec box;
|
||
|
|
||
|
PixmapFormatRec *format;
|
||
|
|
||
|
pWin = AllocateWindow(pScreen);
|
||
|
if (!pWin)
|
||
|
return FALSE;
|
||
|
|
||
|
savedScreenInfo[pScreen->myNum].pWindow = NULL;
|
||
|
savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
|
||
|
savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
|
||
|
screenIsSaved = SCREEN_SAVER_OFF;
|
||
|
|
||
|
WindowTable[pScreen->myNum] = pWin;
|
||
|
|
||
|
pWin->drawable.pScreen = pScreen;
|
||
|
pWin->drawable.type = DRAWABLE_WINDOW;
|
||
|
|
||
|
pWin->drawable.depth = pScreen->rootDepth;
|
||
|
for (format = screenInfo.formats;
|
||
|
format->depth != pScreen->rootDepth; format++);
|
||
|
pWin->drawable.bitsPerPixel = format->bitsPerPixel;
|
||
|
|
||
|
pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||
|
|
||
|
pWin->parent = NullWindow;
|
||
|
SetWindowToDefaults(pWin);
|
||
|
|
||
|
pWin->optional = malloc(sizeof(WindowOptRec));
|
||
|
if (!pWin->optional)
|
||
|
return FALSE;
|
||
|
|
||
|
pWin->optional->dontPropagateMask = 0;
|
||
|
pWin->optional->otherEventMasks = 0;
|
||
|
pWin->optional->otherClients = NULL;
|
||
|
pWin->optional->passiveGrabs = NULL;
|
||
|
pWin->optional->userProps = NULL;
|
||
|
pWin->optional->backingBitPlanes = ~0L;
|
||
|
pWin->optional->backingPixel = 0;
|
||
|
pWin->optional->boundingShape = NULL;
|
||
|
pWin->optional->clipShape = NULL;
|
||
|
pWin->optional->inputShape = NULL;
|
||
|
pWin->optional->colormap = pScreen->defColormap;
|
||
|
pWin->optional->visual = pScreen->rootVisual;
|
||
|
|
||
|
pWin->nextSib = NullWindow;
|
||
|
|
||
|
pWin->drawable.id = FakeClientID(0);
|
||
|
|
||
|
pWin->origin.x = pWin->origin.y = 0;
|
||
|
pWin->drawable.height = pScreen->height;
|
||
|
pWin->drawable.width = pScreen->width;
|
||
|
pWin->drawable.x = pWin->drawable.y = 0;
|
||
|
|
||
|
box.x1 = 0;
|
||
|
box.y1 = 0;
|
||
|
box.x2 = pScreen->width;
|
||
|
box.y2 = pScreen->height;
|
||
|
|
||
|
BoxRec *boxptr = &box;
|
||
|
|
||
|
REGION_INIT(&pWin->clipList, boxptr, 1);
|
||
|
REGION_INIT(&pWin->winSize, boxptr, 1);
|
||
|
REGION_INIT(&pWin->borderSize, boxptr, 1);
|
||
|
REGION_INIT(&pWin->borderClip, boxptr, 1);
|
||
|
|
||
|
pWin->drawable.class = InputOutput;
|
||
|
pWin->optional->visual = pScreen->rootVisual;
|
||
|
|
||
|
pWin->backgroundState = BackgroundPixel;
|
||
|
pWin->background.pixel = pScreen->whitePixel;
|
||
|
|
||
|
pWin->borderIsPixel = TRUE;
|
||
|
pWin->border.pixel = pScreen->blackPixel;
|
||
|
pWin->borderWidth = 0;
|
||
|
|
||
|
if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer) pWin))
|
||
|
return FALSE;
|
||
|
|
||
|
pScreen->saveUnderSupport = NotUseful;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
InitRootWindow(WindowPtr pWin)
|
||
|
{
|
||
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||
|
|
||
|
int backFlag = CWBorderPixel | CWCursor | CWBackingStore;
|
||
|
|
||
|
if (!(*pScreen->CreateWindow) (pWin))
|
||
|
return; /* XXX */
|
||
|
(*pScreen->PositionWindow) (pWin, 0, 0);
|
||
|
|
||
|
pWin->cursorIsNone = FALSE;
|
||
|
pWin->optional->cursor = rootCursor;
|
||
|
rootCursor->refcnt++;
|
||
|
|
||
|
if (!blackRoot && !whiteRoot) {
|
||
|
MakeRootTile(pWin);
|
||
|
backFlag |= CWBackPixmap;
|
||
|
}
|
||
|
else {
|
||
|
if (blackRoot)
|
||
|
pWin->background.pixel = pScreen->blackPixel;
|
||
|
else
|
||
|
pWin->background.pixel = pScreen->whitePixel;
|
||
|
backFlag |= CWBackPixel;
|
||
|
}
|
||
|
|
||
|
pWin->backingStore = defaultBackingStore;
|
||
|
pWin->forcedBS = (defaultBackingStore != NotUseful);
|
||
|
/* We SHOULD check for an error value here XXX */
|
||
|
(*pScreen->ChangeWindowAttributes) (pWin, backFlag);
|
||
|
|
||
|
|
||
|
MapWindow(pWin, serverClient);
|
||
|
}
|
||
|
|
||
|
/* Set the region to the intersection of the rectangle and the
|
||
|
* window's winSize. The window is typically the parent of the
|
||
|
* window from which the region came.
|
||
|
*/
|
||
|
|
||
|
void
|
||
|
ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
|
||
|
register int x, register int y,
|
||
|
register int w, register int h)
|
||
|
{
|
||
|
BoxRec box;
|
||
|
|
||
|
box = *(REGION_EXTENTS(&pWin->winSize));
|
||
|
/* we do these calculations to avoid overflows */
|
||
|
if (x > box.x1)
|
||
|
box.x1 = x;
|
||
|
if (y > box.y1)
|
||
|
box.y1 = y;
|
||
|
x += w;
|
||
|
if (x < box.x2)
|
||
|
box.x2 = x;
|
||
|
y += h;
|
||
|
if (y < box.y2)
|
||
|
box.y2 = y;
|
||
|
if (box.x1 > box.x2)
|
||
|
box.x2 = box.x1;
|
||
|
if (box.y1 > box.y2)
|
||
|
box.y2 = box.y1;
|
||
|
REGION_RESET(Rgn, &box);
|
||
|
REGION_INTERSECT(Rgn, Rgn, &pWin->winSize);
|
||
|
}
|
||
|
|
||
|
static RealChildHeadProc realChildHeadProc = NULL;
|
||
|
|
||
|
void
|
||
|
RegisterRealChildHeadProc(RealChildHeadProc proc)
|
||
|
{
|
||
|
realChildHeadProc = proc;
|
||
|
}
|
||
|
|
||
|
WindowPtr
|
||
|
RealChildHead(register WindowPtr pWin)
|
||
|
{
|
||
|
if (realChildHeadProc) {
|
||
|
return realChildHeadProc(pWin);
|
||
|
}
|
||
|
|
||
|
if (!pWin->parent &&
|
||
|
(screenIsSaved == SCREEN_SAVER_ON) &&
|
||
|
(HasSaverWindow(pWin->drawable.pScreen->myNum)))
|
||
|
return (pWin->firstChild);
|
||
|
else
|
||
|
return (NullWindow);
|
||
|
}
|
||
|
|
||
|
/*****
|
||
|
* CreateWindow
|
||
|
* Makes a window in response to client request
|
||
|
*****/
|
||
|
|
||
|
_X_EXPORT WindowPtr
|
||
|
CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
|
||
|
unsigned h, unsigned bw, unsigned class, register Mask vmask,
|
||
|
XID *vlist, int depth, ClientPtr client, VisualID visual,
|
||
|
int *error)
|
||
|
{
|
||
|
WindowPtr pWin;
|
||
|
|
||
|
WindowPtr pHead;
|
||
|
|
||
|
ScreenPtr pScreen;
|
||
|
|
||
|
xEvent event;
|
||
|
|
||
|
int idepth, ivisual;
|
||
|
|
||
|
Bool fOK;
|
||
|
|
||
|
DepthPtr pDepth;
|
||
|
|
||
|
PixmapFormatRec *format;
|
||
|
|
||
|
WindowOptPtr ancwopt;
|
||
|
|
||
|
if (class == CopyFromParent)
|
||
|
class = pParent->drawable.class;
|
||
|
|
||
|
if ((class != InputOutput) && (class != InputOnly)) {
|
||
|
*error = BadValue;
|
||
|
client->errorValue = class;
|
||
|
return NullWindow;
|
||
|
}
|
||
|
|
||
|
if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) {
|
||
|
*error = BadMatch;
|
||
|
return NullWindow;
|
||
|
}
|
||
|
|
||
|
if ((class == InputOnly) && ((bw != 0) || (depth != 0))) {
|
||
|
*error = BadMatch;
|
||
|
return NullWindow;
|
||
|
}
|
||
|
|
||
|
pScreen = pParent->drawable.pScreen;
|
||
|
if ((class == InputOutput) && (depth == 0))
|
||
|
depth = pParent->drawable.depth;
|
||
|
ancwopt = pParent->optional;
|
||
|
if (!ancwopt)
|
||
|
ancwopt = FindWindowWithOptional(pParent)->optional;
|
||
|
if (visual == CopyFromParent) {
|
||
|
visual = ancwopt->visual;
|
||
|
}
|
||
|
|
||
|
/* Find out if the depth and visual are acceptable for this Screen */
|
||
|
if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) {
|
||
|
fOK = FALSE;
|
||
|
for (idepth = 0; idepth < pScreen->numDepths; idepth++) {
|
||
|
pDepth = (DepthPtr) & pScreen->allowedDepths[idepth];
|
||
|
if ((depth == pDepth->depth) || (depth == 0)) {
|
||
|
for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
|
||
|
if (visual == pDepth->vids[ivisual]) {
|
||
|
fOK = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (fOK == FALSE) {
|
||
|
*error = BadMatch;
|
||
|
return NullWindow;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
|
||
|
(class != InputOnly) && (depth != pParent->drawable.depth)) {
|
||
|
*error = BadMatch;
|
||
|
return NullWindow;
|
||
|
}
|
||
|
|
||
|
if (((vmask & CWColormap) == 0) &&
|
||
|
(class != InputOnly) &&
|
||
|
((visual != ancwopt->visual) || (ancwopt->colormap == None))) {
|
||
|
*error = BadMatch;
|
||
|
return NullWindow;
|
||
|
}
|
||
|
|
||
|
pWin = AllocateWindow(pScreen);
|
||
|
if (!pWin) {
|
||
|
*error = BadAlloc;
|
||
|
return NullWindow;
|
||
|
}
|
||
|
pWin->drawable = pParent->drawable;
|
||
|
pWin->drawable.depth = depth;
|
||
|
if (depth == pParent->drawable.depth)
|
||
|
pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
|
||
|
else {
|
||
|
for (format = screenInfo.formats; format->depth != depth; format++);
|
||
|
pWin->drawable.bitsPerPixel = format->bitsPerPixel;
|
||
|
}
|
||
|
if (class == InputOnly)
|
||
|
pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
|
||
|
pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||
|
|
||
|
pWin->drawable.id = wid;
|
||
|
pWin->drawable.class = class;
|
||
|
|
||
|
pWin->parent = pParent;
|
||
|
SetWindowToDefaults(pWin);
|
||
|
|
||
|
if (visual != ancwopt->visual) {
|
||
|
if (!MakeWindowOptional(pWin)) {
|
||
|
free(pWin);
|
||
|
*error = BadAlloc;
|
||
|
return NullWindow;
|
||
|
}
|
||
|
pWin->optional->visual = visual;
|
||
|
pWin->optional->colormap = None;
|
||
|
}
|
||
|
|
||
|
pWin->borderWidth = bw;
|
||
|
pWin->backgroundState = None;
|
||
|
|
||
|
pWin->borderIsPixel = pParent->borderIsPixel;
|
||
|
pWin->border = pParent->border;
|
||
|
if (pWin->borderIsPixel == FALSE)
|
||
|
pWin->border.pixmap->refcnt++;
|
||
|
|
||
|
pWin->origin.x = x + (int) bw;
|
||
|
pWin->origin.y = y + (int) bw;
|
||
|
pWin->drawable.width = w;
|
||
|
pWin->drawable.height = h;
|
||
|
pWin->drawable.x = pParent->drawable.x + x + (int) bw;
|
||
|
pWin->drawable.y = pParent->drawable.y + y + (int) bw;
|
||
|
|
||
|
/* set up clip list correctly for unobscured WindowPtr */
|
||
|
REGION_NULL(&pWin->clipList);
|
||
|
REGION_NULL(&pWin->borderClip);
|
||
|
REGION_NULL(&pWin->winSize);
|
||
|
REGION_NULL(&pWin->borderSize);
|
||
|
|
||
|
|
||
|
pHead = RealChildHead(pParent);
|
||
|
if (pHead) {
|
||
|
pWin->nextSib = pHead->nextSib;
|
||
|
if (pHead->nextSib)
|
||
|
pHead->nextSib->prevSib = pWin;
|
||
|
else
|
||
|
pParent->lastChild = pWin;
|
||
|
pHead->nextSib = pWin;
|
||
|
pWin->prevSib = pHead;
|
||
|
}
|
||
|
else {
|
||
|
pWin->nextSib = pParent->firstChild;
|
||
|
if (pParent->firstChild)
|
||
|
pParent->firstChild->prevSib = pWin;
|
||
|
else
|
||
|
pParent->lastChild = pWin;
|
||
|
pParent->firstChild = pWin;
|
||
|
}
|
||
|
|
||
|
SetWinSize(pWin);
|
||
|
SetBorderSize(pWin);
|
||
|
|
||
|
/* We SHOULD check for an error value here XXX */
|
||
|
if (!(*pScreen->CreateWindow) (pWin)) {
|
||
|
*error = BadAlloc;
|
||
|
DeleteWindow(pWin, None);
|
||
|
return NullWindow;
|
||
|
}
|
||
|
/* We SHOULD check for an error value here XXX */
|
||
|
(*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y);
|
||
|
|
||
|
if (!(vmask & CWEventMask))
|
||
|
RecalculateDeliverableEvents(pWin);
|
||
|
|
||
|
if (vmask)
|
||
|
*error = ChangeWindowAttributes(pWin, vmask, vlist, wClient(pWin));
|
||
|
else
|
||
|
*error = Success;
|
||
|
|
||
|
if (*error != Success) {
|
||
|
DeleteWindow(pWin, None);
|
||
|
return NullWindow;
|
||
|
}
|
||
|
if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful)) {
|
||
|
XID value = defaultBackingStore;
|
||
|
|
||
|
(void) ChangeWindowAttributes(pWin, CWBackingStore, &value,
|
||
|
wClient(pWin));
|
||
|
pWin->forcedBS = TRUE;
|
||
|
}
|
||
|
|
||
|
if (SubSend(pParent)) {
|
||
|
event.u.u.type = CreateNotify;
|
||
|
event.u.createNotify.window = wid;
|
||
|
event.u.createNotify.parent = pParent->drawable.id;
|
||
|
event.u.createNotify.x = x;
|
||
|
event.u.createNotify.y = y;
|
||
|
event.u.createNotify.width = w;
|
||
|
event.u.createNotify.height = h;
|
||
|
event.u.createNotify.borderWidth = bw;
|
||
|
event.u.createNotify.override = pWin->overrideRedirect;
|
||
|
DeliverEvents(pParent, &event, 1, NullWindow);
|
||
|
}
|
||
|
return pWin;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
FreeWindowResources(register WindowPtr pWin)
|
||
|
{
|
||
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||
|
|
||
|
DeleteWindowFromAnySaveSet(pWin);
|
||
|
DeleteWindowFromAnySelections(pWin);
|
||
|
DeleteWindowFromAnyEvents(pWin, TRUE);
|
||
|
REGION_UNINIT(&pWin->clipList);
|
||
|
REGION_UNINIT(&pWin->winSize);
|
||
|
REGION_UNINIT(&pWin->borderClip);
|
||
|
REGION_UNINIT(&pWin->borderSize);
|
||
|
if (wBoundingShape(pWin))
|
||
|
REGION_DESTROY(wBoundingShape(pWin));
|
||
|
if (wClipShape(pWin))
|
||
|
REGION_DESTROY(wClipShape(pWin));
|
||
|
if (wInputShape(pWin))
|
||
|
REGION_DESTROY(wInputShape(pWin));
|
||
|
if (pWin->borderIsPixel == FALSE)
|
||
|
(*pScreen->DestroyPixmap) (pWin->border.pixmap);
|
||
|
if (pWin->backgroundState == BackgroundPixmap)
|
||
|
(*pScreen->DestroyPixmap) (pWin->background.pixmap);
|
||
|
|
||
|
DeleteAllWindowProperties(pWin);
|
||
|
/* We SHOULD check for an error value here XXX */
|
||
|
(*pScreen->DestroyWindow) (pWin);
|
||
|
DisposeWindowOptional(pWin);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
CrushTree(WindowPtr pWin)
|
||
|
{
|
||
|
WindowPtr pChild, pSib, pParent;
|
||
|
|
||
|
UnrealizeWindowProcPtr UnrealizeWindow;
|
||
|
|
||
|
xEvent event;
|
||
|
|
||
|
if (!(pChild = pWin->firstChild))
|
||
|
return;
|
||
|
UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
|
||
|
while (1) {
|
||
|
if (pChild->firstChild) {
|
||
|
pChild = pChild->firstChild;
|
||
|
continue;
|
||
|
}
|
||
|
while (1) {
|
||
|
pParent = pChild->parent;
|
||
|
if (SubStrSend(pChild, pParent)) {
|
||
|
event.u.u.type = DestroyNotify;
|
||
|
event.u.destroyNotify.window = pChild->drawable.id;
|
||
|
DeliverEvents(pChild, &event, 1, NullWindow);
|
||
|
}
|
||
|
FreeResource(pChild->drawable.id, RT_WINDOW);
|
||
|
pSib = pChild->nextSib;
|
||
|
pChild->viewable = FALSE;
|
||
|
if (pChild->realized) {
|
||
|
pChild->realized = FALSE;
|
||
|
(*UnrealizeWindow) (pChild);
|
||
|
}
|
||
|
FreeWindowResources(pChild);
|
||
|
free(pChild);
|
||
|
if ((pChild = pSib))
|
||
|
break;
|
||
|
pChild = pParent;
|
||
|
pChild->firstChild = NullWindow;
|
||
|
pChild->lastChild = NullWindow;
|
||
|
if (pChild == pWin)
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*****
|
||
|
* DeleteWindow
|
||
|
* Deletes child of window then window itself
|
||
|
* If wid is None, don't send any events
|
||
|
*****/
|
||
|
|
||
|
int
|
||
|
DeleteWindow(pointer value, XID wid)
|
||
|
{
|
||
|
WindowPtr pParent;
|
||
|
|
||
|
WindowPtr pWin = (WindowPtr) value;
|
||
|
|
||
|
xEvent event;
|
||
|
|
||
|
UnmapWindow(pWin, FALSE);
|
||
|
|
||
|
CrushTree(pWin);
|
||
|
|
||
|
pParent = pWin->parent;
|
||
|
if (wid && pParent && SubStrSend(pWin, pParent)) {
|
||
|
event.u.u.type = DestroyNotify;
|
||
|
event.u.destroyNotify.window = pWin->drawable.id;
|
||
|
DeliverEvents(pWin, &event, 1, NullWindow);
|
||
|
}
|
||
|
|
||
|
FreeWindowResources(pWin);
|
||
|
if (pParent) {
|
||
|
if (pParent->firstChild == pWin)
|
||
|
pParent->firstChild = pWin->nextSib;
|
||
|
if (pParent->lastChild == pWin)
|
||
|
pParent->lastChild = pWin->prevSib;
|
||
|
if (pWin->nextSib)
|
||
|
pWin->nextSib->prevSib = pWin->prevSib;
|
||
|
if (pWin->prevSib)
|
||
|
pWin->prevSib->nextSib = pWin->nextSib;
|
||
|
}
|
||
|
free(pWin);
|
||
|
return Success;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
DestroySubwindows(register WindowPtr pWin, ClientPtr client)
|
||
|
{
|
||
|
/* XXX
|
||
|
* The protocol is quite clear that each window should be
|
||
|
* destroyed in turn, however, unmapping all of the first
|
||
|
* eliminates most of the calls to ValidateTree. So,
|
||
|
* this implementation is incorrect in that all of the
|
||
|
* UnmapNotifies occur before all of the DestroyNotifies.
|
||
|
* If you care, simply delete the call to UnmapSubwindows.
|
||
|
*/
|
||
|
UnmapSubwindows(pWin);
|
||
|
while (pWin->lastChild)
|
||
|
FreeResource(pWin->lastChild->drawable.id, RT_NONE);
|
||
|
}
|
||
|
|
||
|
#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
|
||
|
ButtonReleaseMask | PointerMotionMask)
|
||
|
|
||
|
/*****
|
||
|
* ChangeWindowAttributes
|
||
|
*
|
||
|
* The value-mask specifies which attributes are to be changed; the
|
||
|
* value-list contains one value for each one bit in the mask, from least
|
||
|
* to most significant bit in the mask.
|
||
|
*****/
|
||
|
|
||
|
_X_EXPORT int
|
||
|
ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist,
|
||
|
ClientPtr client)
|
||
|
{
|
||
|
Mask index2;
|
||
|
|
||
|
XID *pVlist;
|
||
|
|
||
|
PixmapPtr pPixmap;
|
||
|
|
||
|
Pixmap pixID;
|
||
|
|
||
|
CursorPtr pCursor, pOldCursor;
|
||
|
|
||
|
Cursor cursorID;
|
||
|
|
||
|
WindowPtr pChild;
|
||
|
|
||
|
Colormap cmap;
|
||
|
|
||
|
ColormapPtr pCmap;
|
||
|
|
||
|
xEvent xE;
|
||
|
|
||
|
int result;
|
||
|
|
||
|
ScreenPtr pScreen;
|
||
|
|
||
|
Mask vmaskCopy = 0;
|
||
|
|
||
|
Mask tmask;
|
||
|
|
||
|
unsigned int val;
|
||
|
|
||
|
int error;
|
||
|
|
||
|
Bool checkOptional = FALSE;
|
||
|
|
||
|
Bool borderRelative = FALSE;
|
||
|
|
||
|
if ((pWin->drawable.class == InputOnly) &&
|
||
|
(vmask & (~INPUTONLY_LEGAL_MASK)))
|
||
|
return BadMatch;
|
||
|
|
||
|
error = Success;
|
||
|
pScreen = pWin->drawable.pScreen;
|
||
|
pVlist = vlist;
|
||
|
tmask = vmask;
|
||
|
while (tmask) {
|
||
|
index2 = (Mask) lowbit(tmask);
|
||
|
tmask &= ~index2;
|
||
|
switch (index2) {
|
||
|
case CWBackPixmap:
|
||
|
pixID = (Pixmap) * pVlist;
|
||
|
pVlist++;
|
||
|
if (pWin->backgroundState == ParentRelative)
|
||
|
borderRelative = TRUE;
|
||
|
if (pixID == None) {
|
||
|
if (pWin->backgroundState == BackgroundPixmap)
|
||
|
(*pScreen->DestroyPixmap) (pWin->background.pixmap);
|
||
|
if (!pWin->parent)
|
||
|
MakeRootTile(pWin);
|
||
|
else
|
||
|
pWin->backgroundState = None;
|
||
|
}
|
||
|
else if (pixID == ParentRelative) {
|
||
|
if (pWin->parent &&
|
||
|
pWin->drawable.depth != pWin->parent->drawable.depth) {
|
||
|
error = BadMatch;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
if (pWin->backgroundState == BackgroundPixmap)
|
||
|
(*pScreen->DestroyPixmap) (pWin->background.pixmap);
|
||
|
if (!pWin->parent)
|
||
|
MakeRootTile(pWin);
|
||
|
else
|
||
|
pWin->backgroundState = ParentRelative;
|
||
|
borderRelative = TRUE;
|
||
|
/* Note that the parent's backgroundTile's refcnt is NOT
|
||
|
* incremented. */
|
||
|
}
|
||
|
else {
|
||
|
pPixmap = (PixmapPtr) SecurityLookupIDByType(client, pixID,
|
||
|
RT_PIXMAP,
|
||
|
SecurityReadAccess);
|
||
|
if (pPixmap != (PixmapPtr) NULL) {
|
||
|
if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
|
||
|
(pPixmap->drawable.pScreen != pScreen)) {
|
||
|
error = BadMatch;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
if (pWin->backgroundState == BackgroundPixmap)
|
||
|
(*pScreen->DestroyPixmap) (pWin->background.pixmap);
|
||
|
pWin->backgroundState = BackgroundPixmap;
|
||
|
pWin->background.pixmap = pPixmap;
|
||
|
pPixmap->refcnt++;
|
||
|
}
|
||
|
else {
|
||
|
error = BadPixmap;
|
||
|
client->errorValue = pixID;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case CWBackPixel:
|
||
|
if (pWin->backgroundState == ParentRelative)
|
||
|
borderRelative = TRUE;
|
||
|
if (pWin->backgroundState == BackgroundPixmap)
|
||
|
(*pScreen->DestroyPixmap) (pWin->background.pixmap);
|
||
|
pWin->backgroundState = BackgroundPixel;
|
||
|
pWin->background.pixel = (CARD32) *pVlist;
|
||
|
/* background pixel overrides background pixmap,
|
||
|
so don't let the ddx layer see both bits */
|
||
|
vmaskCopy &= ~CWBackPixmap;
|
||
|
pVlist++;
|
||
|
break;
|
||
|
case CWBorderPixmap:
|
||
|
pixID = (Pixmap) * pVlist;
|
||
|
pVlist++;
|
||
|
if (pixID == CopyFromParent) {
|
||
|
if (!pWin->parent ||
|
||
|
(pWin->drawable.depth != pWin->parent->drawable.depth)) {
|
||
|
error = BadMatch;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
if (pWin->borderIsPixel == FALSE)
|
||
|
(*pScreen->DestroyPixmap) (pWin->border.pixmap);
|
||
|
pWin->border = pWin->parent->border;
|
||
|
if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE) {
|
||
|
index2 = CWBorderPixel;
|
||
|
}
|
||
|
else {
|
||
|
pWin->parent->border.pixmap->refcnt++;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
pPixmap = (PixmapPtr) SecurityLookupIDByType(client, pixID,
|
||
|
RT_PIXMAP,
|
||
|
SecurityReadAccess);
|
||
|
if (pPixmap) {
|
||
|
if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
|
||
|
(pPixmap->drawable.pScreen != pScreen)) {
|
||
|
error = BadMatch;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
if (pWin->borderIsPixel == FALSE)
|
||
|
(*pScreen->DestroyPixmap) (pWin->border.pixmap);
|
||
|
pWin->borderIsPixel = FALSE;
|
||
|
pWin->border.pixmap = pPixmap;
|
||
|
pPixmap->refcnt++;
|
||
|
}
|
||
|
else {
|
||
|
error = BadPixmap;
|
||
|
client->errorValue = pixID;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case CWBorderPixel:
|
||
|
if (pWin->borderIsPixel == FALSE)
|
||
|
(*pScreen->DestroyPixmap) (pWin->border.pixmap);
|
||
|
pWin->borderIsPixel = TRUE;
|
||
|
pWin->border.pixel = (CARD32) *pVlist;
|
||
|
/* border pixel overrides border pixmap,
|
||
|
so don't let the ddx layer see both bits */
|
||
|
vmaskCopy &= ~CWBorderPixmap;
|
||
|
pVlist++;
|
||
|
break;
|
||
|
case CWBitGravity:
|
||
|
val = (CARD8) *pVlist;
|
||
|
pVlist++;
|
||
|
if (val > StaticGravity) {
|
||
|
error = BadValue;
|
||
|
client->errorValue = val;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
pWin->bitGravity = val;
|
||
|
break;
|
||
|
case CWWinGravity:
|
||
|
val = (CARD8) *pVlist;
|
||
|
pVlist++;
|
||
|
if (val > StaticGravity) {
|
||
|
error = BadValue;
|
||
|
client->errorValue = val;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
pWin->winGravity = val;
|
||
|
break;
|
||
|
case CWBackingStore:
|
||
|
val = (CARD8) *pVlist;
|
||
|
pVlist++;
|
||
|
if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) {
|
||
|
error = BadValue;
|
||
|
client->errorValue = val;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
pWin->backingStore = val;
|
||
|
pWin->forcedBS = FALSE;
|
||
|
break;
|
||
|
case CWBackingPlanes:
|
||
|
if (pWin->optional || ((CARD32) *pVlist != (CARD32) ~0L)) {
|
||
|
if (!pWin->optional && !MakeWindowOptional(pWin)) {
|
||
|
error = BadAlloc;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
pWin->optional->backingBitPlanes = (CARD32) *pVlist;
|
||
|
if ((CARD32) *pVlist == (CARD32) ~0L)
|
||
|
checkOptional = TRUE;
|
||
|
}
|
||
|
pVlist++;
|
||
|
break;
|
||
|
case CWBackingPixel:
|
||
|
if (pWin->optional || (CARD32) *pVlist) {
|
||
|
if (!pWin->optional && !MakeWindowOptional(pWin)) {
|
||
|
error = BadAlloc;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
pWin->optional->backingPixel = (CARD32) *pVlist;
|
||
|
if (!*pVlist)
|
||
|
checkOptional = TRUE;
|
||
|
}
|
||
|
pVlist++;
|
||
|
break;
|
||
|
case CWSaveUnder:
|
||
|
val = (BOOL) * pVlist;
|
||
|
pVlist++;
|
||
|
if ((val != xTrue) && (val != xFalse)) {
|
||
|
error = BadValue;
|
||
|
client->errorValue = val;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
pWin->saveUnder = val;
|
||
|
break;
|
||
|
case CWEventMask:
|
||
|
result = EventSelectForWindow(pWin, client, (Mask) *pVlist);
|
||
|
if (result) {
|
||
|
error = result;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
pVlist++;
|
||
|
break;
|
||
|
case CWDontPropagate:
|
||
|
result = EventSuppressForWindow(pWin, client, (Mask) *pVlist,
|
||
|
&checkOptional);
|
||
|
if (result) {
|
||
|
error = result;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
pVlist++;
|
||
|
break;
|
||
|
case CWOverrideRedirect:
|
||
|
val = (BOOL) * pVlist;
|
||
|
pVlist++;
|
||
|
if ((val != xTrue) && (val != xFalse)) {
|
||
|
error = BadValue;
|
||
|
client->errorValue = val;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|
pWin->overrideRedirect = val;
|
||
|
break;
|
||
|
case CWColormap:
|
||
|
cmap = (Colormap) * pVlist;
|
||
|
pVlist++;
|
||
|
if (cmap == CopyFromParent) {
|
||
|
if (pWin->parent &&
|
||
|
(!pWin->optional ||
|
||
|
pWin->optional->visual == wVisual(pWin->parent))) {
|
||
|
cmap = wColormap(pWin->parent);
|
||
|
}
|
||
|
else
|
||
|
cmap = None;
|
||
|
}
|
||
|
if (cmap == None) {
|
||
|
error = BadMatch;
|
||
|
goto PatchUp;
|
||
|
}
|
||
|