~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to dix/window.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XdotOrg: xserver/xorg/dix/window.c,v 1.13 2006/01/12 22:14:56 sandmann Exp $ */
 
2
/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
 
3
/*
 
4
 
 
5
Copyright 1987, 1998  The Open Group
 
6
 
 
7
Permission to use, copy, modify, distribute, and sell this software and its
 
8
documentation for any purpose is hereby granted without fee, provided that
 
9
the above copyright notice appear in all copies and that both that
 
10
copyright notice and this permission notice appear in supporting
 
11
documentation.
 
12
 
 
13
The above copyright notice and this permission notice shall be included
 
14
in all copies or substantial portions of the Software.
 
15
 
 
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
17
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
18
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
19
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
20
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
21
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
22
OTHER DEALINGS IN THE SOFTWARE.
 
23
 
 
24
Except as contained in this notice, the name of The Open Group shall
 
25
not be used in advertising or otherwise to promote the sale, use or
 
26
other dealings in this Software without prior written authorization
 
27
from The Open Group.
 
28
 
 
29
 
 
30
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
 
31
 
 
32
                        All Rights Reserved
 
33
 
 
34
Permission to use, copy, modify, and distribute this software and its 
 
35
documentation for any purpose and without fee is hereby granted, 
 
36
provided that the above copyright notice appear in all copies and that
 
37
both that copyright notice and this permission notice appear in 
 
38
supporting documentation, and that the name of Digital not be
 
39
used in advertising or publicity pertaining to distribution of the
 
40
software without specific, written prior permission.  
 
41
 
 
42
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
43
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
44
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
45
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
46
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
47
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
48
SOFTWARE.
 
49
 
 
50
*/
 
51
 
 
52
/* The panoramix components contained the following notice */
 
53
/*****************************************************************
 
54
 
 
55
Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
 
56
 
 
57
Permission is hereby granted, free of charge, to any person obtaining a copy
 
58
of this software and associated documentation files (the "Software"), to deal
 
59
in the Software without restriction, including without limitation the rights
 
60
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
61
copies of the Software.
 
62
 
 
63
The above copyright notice and this permission notice shall be included in
 
64
all copies or substantial portions of the Software.
 
65
 
 
66
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
67
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
68
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
69
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
 
70
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
 
71
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 
72
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
73
 
 
74
Except as contained in this notice, the name of Digital Equipment Corporation
 
75
shall not be used in advertising or otherwise to promote the sale, use or other
 
76
dealings in this Software without prior written authorization from Digital
 
77
Equipment Corporation.
 
78
 
 
79
******************************************************************/
 
80
 
 
81
/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.36 2003/11/14 23:52:50 torrey Exp $ */
 
82
 
 
83
#ifdef HAVE_DIX_CONFIG_H
 
84
#include <dix-config.h>
 
85
#endif
 
86
 
 
87
#include "misc.h"
 
88
#include "scrnintstr.h"
 
89
#include "os.h"
 
90
#include "regionstr.h"
 
91
#include "validate.h"
 
92
#include "windowstr.h"
 
93
#include "input.h"
 
94
#include "resource.h"
 
95
#include "colormapst.h"
 
96
#include "cursorstr.h"
 
97
#include "dixstruct.h"
 
98
#include "gcstruct.h"
 
99
#include "servermd.h"
 
100
#ifdef PANORAMIX
 
101
#include "panoramiX.h"
 
102
#include "panoramiXsrv.h"
 
103
#endif
 
104
#include "dixevents.h"
 
105
#include "globals.h"
 
106
 
 
107
#ifdef XAPPGROUP
 
108
#include <X11/extensions/Xagsrv.h>
 
109
#endif
 
110
#ifdef XCSECURITY
 
111
#define _SECURITY_SERVER
 
112
#include <X11/extensions/security.h>
 
113
#endif
 
114
 
 
115
/******
 
116
 * Window stuff for server 
 
117
 *
 
118
 *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
 
119
 *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
 
120
 *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
 
121
 *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
 
122
 *
 
123
 ******/
 
124
 
 
125
static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
 
126
static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
 
127
 
 
128
int screenIsSaved = SCREEN_SAVER_OFF;
 
129
 
 
130
ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
 
131
 
 
132
#if 0
 
133
extern void DeleteWindowFromAnyEvents();
 
134
extern Mask EventMaskForClient();
 
135
extern void WindowHasNewCursor();
 
136
extern void RecalculateDeliverableEvents();
 
137
#endif
 
138
 
 
139
static Bool TileScreenSaver(int i, int kind);
 
140
 
 
141
 
 
142
#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
 
143
                              CWDontPropagate | CWOverrideRedirect | CWCursor )
 
144
 
 
145
#define BOXES_OVERLAP(b1, b2) \
 
146
      (!( ((b1)->x2 <= (b2)->x1)  || \
 
147
        ( ((b1)->x1 >= (b2)->x2)) || \
 
148
        ( ((b1)->y2 <= (b2)->y1)) || \
 
149
        ( ((b1)->y1 >= (b2)->y2)) ) )
 
150
 
 
151
#define RedirectSend(pWin) \
 
152
    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
 
153
 
 
154
#define SubSend(pWin) \
 
155
    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
 
156
 
 
157
#define StrSend(pWin) \
 
158
    ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
 
159
 
 
160
#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
 
161
 
 
162
 
 
163
int numSaveUndersViewable = 0;
 
164
int deltaSaveUndersViewable = 0;
 
165
 
 
166
#ifdef DEBUG
 
167
/******
 
168
 * PrintWindowTree
 
169
 *    For debugging only
 
170
 ******/
 
171
 
 
172
int
 
173
PrintChildren(WindowPtr p1, int indent)
 
174
{
 
175
    WindowPtr p2;
 
176
    int i;
 
177
 
 
178
    while (p1)
 
179
    {
 
180
        p2 = p1->firstChild;
 
181
        for (i=0; i<indent; i++) ErrorF( " ");
 
182
        ErrorF( "%x\n", p1->drawable.id);
 
183
        miPrintRegion(&p1->clipList);
 
184
        PrintChildren(p2, indent+4);
 
185
        p1 = p1->nextSib;
 
186
    }
 
187
}
 
188
 
 
189
PrintWindowTree()
 
190
{
 
191
    int i;
 
192
    WindowPtr pWin, p1;
 
193
 
 
194
    for (i=0; i<screenInfo.numScreens; i++)
 
195
    {
 
196
        ErrorF( "WINDOW %d\n", i);
 
197
        pWin = WindowTable[i];
 
198
        miPrintRegion(&pWin->clipList);
 
199
        p1 = pWin->firstChild;
 
200
        PrintChildren(p1, 4);
 
201
    }
 
202
}
 
203
#endif
 
204
 
 
205
int
 
206
TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
 
207
{
 
208
    register int result;
 
209
    register WindowPtr pChild;
 
210
 
 
211
    if (!(pChild = pWin))
 
212
       return(WT_NOMATCH);
 
213
    while (1)
 
214
    {
 
215
        result = (* func)(pChild, data);
 
216
        if (result == WT_STOPWALKING)
 
217
            return(WT_STOPWALKING);
 
218
        if ((result == WT_WALKCHILDREN) && pChild->firstChild)
 
219
        {
 
220
            pChild = pChild->firstChild;
 
221
            continue;
 
222
        }
 
223
        while (!pChild->nextSib && (pChild != pWin))
 
224
            pChild = pChild->parent;
 
225
        if (pChild == pWin)
 
226
            break;
 
227
        pChild = pChild->nextSib;
 
228
    }
 
229
    return(WT_NOMATCH);
 
230
}
 
231
 
 
232
/*****
 
233
 * WalkTree
 
234
 *   Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
 
235
 *   each window.  If FUNC returns WT_WALKCHILDREN, traverse the children,
 
236
 *   if it returns WT_DONTWALKCHILDREN, dont.  If it returns WT_STOPWALKING
 
237
 *   exit WalkTree.  Does depth-first traverse.
 
238
 *****/
 
239
 
 
240
int
 
241
WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
 
242
{
 
243
    return(TraverseTree(WindowTable[pScreen->myNum], func, data));
 
244
}
 
245
 
 
246
/* hack for forcing backing store on all windows */
 
247
int     defaultBackingStore = NotUseful;
 
248
/* hack to force no backing store */
 
249
Bool    disableBackingStore = FALSE;
 
250
Bool    enableBackingStore = FALSE;
 
251
/* hack to force no save unders */
 
252
Bool    disableSaveUnders = FALSE;
 
253
 
 
254
static void
 
255
SetWindowToDefaults(register WindowPtr pWin)
 
256
{
 
257
    pWin->prevSib = NullWindow;
 
258
    pWin->firstChild = NullWindow;
 
259
    pWin->lastChild = NullWindow;
 
260
 
 
261
    pWin->valdata = (ValidatePtr)NULL;
 
262
    pWin->optional = (WindowOptPtr)NULL;
 
263
    pWin->cursorIsNone = TRUE;
 
264
 
 
265
    pWin->backingStore = NotUseful;
 
266
    pWin->DIXsaveUnder = FALSE;
 
267
    pWin->backStorage = (pointer) NULL;
 
268
 
 
269
    pWin->mapped = FALSE;           /* off */
 
270
    pWin->realized = FALSE;     /* off */
 
271
    pWin->viewable = FALSE;
 
272
    pWin->visibility = VisibilityNotViewable;
 
273
    pWin->overrideRedirect = FALSE;
 
274
    pWin->saveUnder = FALSE;
 
275
 
 
276
    pWin->bitGravity = ForgetGravity;
 
277
    pWin->winGravity = NorthWestGravity;
 
278
 
 
279
    pWin->eventMask = 0;
 
280
    pWin->deliverableEvents = 0;
 
281
    pWin->dontPropagate = 0;
 
282
    pWin->forcedBS = FALSE;
 
283
#ifdef NEED_DBE_BUF_BITS
 
284
    pWin->srcBuffer = DBE_FRONT_BUFFER;
 
285
    pWin->dstBuffer = DBE_FRONT_BUFFER;
 
286
#endif
 
287
#ifdef COMPOSITE
 
288
    pWin->redirectDraw = 0;
 
289
#endif
 
290
}
 
291
 
 
292
static void
 
293
MakeRootTile(WindowPtr pWin)
 
294
{
 
295
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
296
    GCPtr pGC;
 
297
    unsigned char back[128];
 
298
    int len = BitmapBytePad(sizeof(long));
 
299
    register unsigned char *from, *to;
 
300
    register int i, j;
 
301
 
 
302
    pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
 
303
                                                    pScreen->rootDepth);
 
304
 
 
305
    pWin->backgroundState = BackgroundPixmap;
 
306
    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
 
307
    if (!pWin->background.pixmap || !pGC)
 
308
        FatalError("could not create root tile");
 
309
 
 
310
    {
 
311
        CARD32 attributes[2];
 
312
 
 
313
        attributes[0] = pScreen->whitePixel;
 
314
        attributes[1] = pScreen->blackPixel;
 
315
 
 
316
        (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
 
317
    }
 
318
 
 
319
   ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
 
320
 
 
321
   from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
 
322
   to = back;
 
323
 
 
324
   for (i = 4; i > 0; i--, from++)
 
325
        for (j = len; j > 0; j--)
 
326
            *to++ = *from;
 
327
 
 
328
   if (blackRoot)
 
329
       bzero(back, sizeof(back));
 
330
 
 
331
   (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
 
332
                    0, 0, len, 4, 0, XYBitmap, (char *)back);
 
333
 
 
334
   FreeScratchGC(pGC);
 
335
 
 
336
}
 
337
 
 
338
WindowPtr
 
339
AllocateWindow(ScreenPtr pScreen)
 
340
{
 
341
    WindowPtr pWin;
 
342
    register char *ptr;
 
343
    register DevUnion *ppriv;
 
344
    register unsigned *sizes;
 
345
    register unsigned size;
 
346
    register int i;
 
347
 
 
348
    pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
 
349
    if (pWin)
 
350
    {
 
351
        ppriv = (DevUnion *)(pWin + 1);
 
352
        pWin->devPrivates = ppriv;
 
353
        sizes = pScreen->WindowPrivateSizes;
 
354
        ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
 
355
        for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
 
356
        {
 
357
            if ( (size = *sizes) )
 
358
            {
 
359
                ppriv->ptr = (pointer)ptr;
 
360
                ptr += size;
 
361
            }
 
362
            else
 
363
                ppriv->ptr = (pointer)NULL;
 
364
        }
 
365
    }
 
366
    return pWin;
 
367
}
 
368
 
 
369
/*****
 
370
 * CreateRootWindow
 
371
 *    Makes a window at initialization time for specified screen
 
372
 *****/
 
373
 
 
374
Bool
 
375
CreateRootWindow(ScreenPtr pScreen)
 
376
{
 
377
    WindowPtr   pWin;
 
378
    BoxRec      box;
 
379
    PixmapFormatRec *format;
 
380
 
 
381
    pWin = AllocateWindow(pScreen);
 
382
    if (!pWin)
 
383
        return FALSE;
 
384
 
 
385
    savedScreenInfo[pScreen->myNum].pWindow = NULL;
 
386
    savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
 
387
    savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
 
388
    screenIsSaved = SCREEN_SAVER_OFF;
 
389
 
 
390
    WindowTable[pScreen->myNum] = pWin;
 
391
 
 
392
    pWin->drawable.pScreen = pScreen;
 
393
    pWin->drawable.type = DRAWABLE_WINDOW;
 
394
 
 
395
    pWin->drawable.depth = pScreen->rootDepth;
 
396
    for (format = screenInfo.formats;
 
397
         format->depth != pScreen->rootDepth;
 
398
         format++)
 
399
        ;
 
400
    pWin->drawable.bitsPerPixel = format->bitsPerPixel;
 
401
 
 
402
    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
 
403
 
 
404
    pWin->parent = NullWindow;
 
405
    SetWindowToDefaults(pWin);
 
406
 
 
407
    pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
 
408
    if (!pWin->optional)
 
409
        return FALSE;
 
410
 
 
411
    pWin->optional->dontPropagateMask = 0;
 
412
    pWin->optional->otherEventMasks = 0;
 
413
    pWin->optional->otherClients = NULL;
 
414
    pWin->optional->passiveGrabs = NULL;
 
415
    pWin->optional->userProps = NULL;
 
416
    pWin->optional->backingBitPlanes = ~0L;
 
417
    pWin->optional->backingPixel = 0;
 
418
#ifdef SHAPE
 
419
    pWin->optional->boundingShape = NULL;
 
420
    pWin->optional->clipShape = NULL;
 
421
    pWin->optional->inputShape = NULL;
 
422
#endif
 
423
#ifdef XINPUT
 
424
    pWin->optional->inputMasks = NULL;
 
425
#endif
 
426
    pWin->optional->colormap = pScreen->defColormap;
 
427
    pWin->optional->visual = pScreen->rootVisual;
 
428
 
 
429
    pWin->nextSib = NullWindow;
 
430
 
 
431
    pWin->drawable.id = FakeClientID(0);
 
432
 
 
433
    pWin->origin.x = pWin->origin.y = 0;
 
434
    pWin->drawable.height = pScreen->height;
 
435
    pWin->drawable.width = pScreen->width;
 
436
    pWin->drawable.x = pWin->drawable.y = 0;
 
437
 
 
438
    box.x1 = 0;
 
439
    box.y1 = 0;
 
440
    box.x2 = pScreen->width;
 
441
    box.y2 = pScreen->height;
 
442
    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
 
443
    REGION_INIT(pScreen, &pWin->winSize, &box, 1);
 
444
    REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
 
445
    REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
 
446
 
 
447
    pWin->drawable.class = InputOutput;
 
448
    pWin->optional->visual = pScreen->rootVisual;
 
449
 
 
450
    pWin->backgroundState = BackgroundPixel;
 
451
    pWin->background.pixel = pScreen->whitePixel;
 
452
 
 
453
    pWin->borderIsPixel = TRUE;
 
454
    pWin->border.pixel = pScreen->blackPixel;
 
455
    pWin->borderWidth = 0;
 
456
 
 
457
    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
 
458
        return FALSE;
 
459
 
 
460
    if (disableBackingStore)
 
461
        pScreen->backingStoreSupport = NotUseful;
 
462
    if (enableBackingStore)
 
463
        pScreen->backingStoreSupport = Always;
 
464
 
 
465
#ifdef DO_SAVE_UNDERS
 
466
    if ((pScreen->backingStoreSupport != NotUseful) &&
 
467
        (pScreen->saveUnderSupport == NotUseful))
 
468
    {
 
469
        /*
 
470
         * If the screen has backing-store but no save-unders, let the
 
471
         * clients know we can support save-unders using backing-store.
 
472
         */
 
473
        pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
 
474
    }
 
475
#endif /* DO_SAVE_UNDERS */
 
476
                
 
477
    if (disableSaveUnders)
 
478
        pScreen->saveUnderSupport = NotUseful;
 
479
 
 
480
    return TRUE;
 
481
}
 
482
 
 
483
void
 
484
InitRootWindow(WindowPtr pWin)
 
485
{
 
486
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
487
 
 
488
    if (!(*pScreen->CreateWindow)(pWin))
 
489
        return; /* XXX */
 
490
    (*pScreen->PositionWindow)(pWin, 0, 0);
 
491
 
 
492
    pWin->cursorIsNone = FALSE;
 
493
    pWin->optional->cursor = rootCursor;
 
494
    rootCursor->refcnt++;
 
495
    MakeRootTile(pWin);
 
496
    pWin->backingStore = defaultBackingStore;
 
497
    pWin->forcedBS = (defaultBackingStore != NotUseful);
 
498
    /* We SHOULD check for an error value here XXX */
 
499
    (*pScreen->ChangeWindowAttributes)(pWin,
 
500
                       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
 
501
 
 
502
    MapWindow(pWin, serverClient);
 
503
}
 
504
 
 
505
/* Set the region to the intersection of the rectangle and the
 
506
 * window's winSize.  The window is typically the parent of the
 
507
 * window from which the region came.
 
508
 */
 
509
 
 
510
void
 
511
ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
 
512
                     register int x, register int y,
 
513
                     register int w, register int h)
 
514
{
 
515
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
516
    BoxRec box;
 
517
 
 
518
    box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
 
519
    /* we do these calculations to avoid overflows */
 
520
    if (x > box.x1)
 
521
        box.x1 = x;
 
522
    if (y > box.y1)
 
523
        box.y1 = y;
 
524
    x += w;
 
525
    if (x < box.x2)
 
526
        box.x2 = x;
 
527
    y += h;
 
528
    if (y < box.y2)
 
529
        box.y2 = y;
 
530
    if (box.x1 > box.x2)
 
531
        box.x2 = box.x1;
 
532
    if (box.y1 > box.y2)
 
533
        box.y2 = box.y1;
 
534
    REGION_RESET(pScreen, Rgn, &box);
 
535
    REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
 
536
}
 
537
 
 
538
WindowPtr
 
539
RealChildHead(register WindowPtr pWin)
 
540
{
 
541
    if (!pWin->parent &&
 
542
        (screenIsSaved == SCREEN_SAVER_ON) &&
 
543
        (HasSaverWindow (pWin->drawable.pScreen->myNum)))
 
544
        return (pWin->firstChild);
 
545
    else
 
546
        return (NullWindow);
 
547
}
 
548
 
 
549
/*****
 
550
 * CreateWindow
 
551
 *    Makes a window in response to client request 
 
552
 *****/
 
553
 
 
554
WindowPtr
 
555
CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
 
556
             unsigned h, unsigned bw, unsigned class, register Mask vmask, XID *vlist,
 
557
             int depth, ClientPtr client, VisualID visual, int *error)
 
558
{
 
559
    register WindowPtr pWin;
 
560
    WindowPtr pHead;
 
561
    register ScreenPtr pScreen;
 
562
    xEvent event;
 
563
    int idepth, ivisual;
 
564
    Bool fOK;
 
565
    DepthPtr pDepth;
 
566
    PixmapFormatRec *format;
 
567
    register WindowOptPtr ancwopt;
 
568
 
 
569
    if (class == CopyFromParent)
 
570
        class = pParent->drawable.class;
 
571
 
 
572
    if ((class != InputOutput) && (class != InputOnly))
 
573
    {
 
574
        *error = BadValue;
 
575
        client->errorValue = class;
 
576
        return NullWindow;
 
577
    }
 
578
 
 
579
    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
 
580
    {
 
581
        *error = BadMatch;
 
582
        return NullWindow;
 
583
    }
 
584
 
 
585
    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
 
586
    {
 
587
        *error = BadMatch;
 
588
        return NullWindow;
 
589
    }
 
590
 
 
591
    pScreen = pParent->drawable.pScreen;
 
592
    if ((class == InputOutput) && (depth == 0))
 
593
         depth = pParent->drawable.depth;
 
594
    ancwopt = pParent->optional;
 
595
    if (!ancwopt)
 
596
        ancwopt = FindWindowWithOptional(pParent)->optional;
 
597
    if (visual == CopyFromParent) {
 
598
#ifdef XAPPGROUP
 
599
        VisualID ag_visual;
 
600
 
 
601
        if (client->appgroup && !pParent->parent &&
 
602
            (ag_visual = XagRootVisual (client)))
 
603
            visual = ag_visual;
 
604
        else
 
605
#endif
 
606
        visual = ancwopt->visual;
 
607
    }
 
608
 
 
609
    /* Find out if the depth and visual are acceptable for this Screen */
 
610
    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
 
611
    {
 
612
        fOK = FALSE;
 
613
        for(idepth = 0; idepth < pScreen->numDepths; idepth++)
 
614
        {
 
615
            pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
 
616
            if ((depth == pDepth->depth) || (depth == 0))
 
617
            {
 
618
                for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
 
619
                {
 
620
                    if (visual == pDepth->vids[ivisual])
 
621
                    {
 
622
                        fOK = TRUE;
 
623
                        break;
 
624
                    }
 
625
                }
 
626
            }
 
627
        }
 
628
        if (fOK == FALSE)
 
629
        {
 
630
            *error = BadMatch;
 
631
            return NullWindow;
 
632
        }
 
633
    }
 
634
 
 
635
    if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
 
636
        (class != InputOnly) &&
 
637
        (depth != pParent->drawable.depth))
 
638
    {
 
639
        *error = BadMatch;
 
640
        return NullWindow;
 
641
    }
 
642
 
 
643
    if (((vmask & CWColormap) == 0) &&
 
644
        (class != InputOnly) &&
 
645
        ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
 
646
    {
 
647
        *error = BadMatch;
 
648
        return NullWindow;
 
649
    }
 
650
 
 
651
    pWin = AllocateWindow(pScreen);
 
652
    if (!pWin)
 
653
    {
 
654
        *error = BadAlloc;
 
655
        return NullWindow;
 
656
    }
 
657
    pWin->drawable = pParent->drawable;
 
658
    pWin->drawable.depth = depth;
 
659
    if (depth == pParent->drawable.depth)
 
660
        pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
 
661
    else
 
662
    {
 
663
        for (format = screenInfo.formats; format->depth != depth; format++)
 
664
            ;
 
665
        pWin->drawable.bitsPerPixel = format->bitsPerPixel;
 
666
    }
 
667
    if (class == InputOnly)
 
668
        pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
 
669
    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
 
670
 
 
671
    pWin->drawable.id = wid;
 
672
    pWin->drawable.class = class;
 
673
 
 
674
    pWin->parent = pParent;
 
675
    SetWindowToDefaults(pWin);
 
676
 
 
677
    if (visual != ancwopt->visual)
 
678
    {
 
679
        if (!MakeWindowOptional (pWin))
 
680
        {
 
681
            xfree (pWin);
 
682
            *error = BadAlloc;
 
683
            return NullWindow;
 
684
        }
 
685
        pWin->optional->visual = visual;
 
686
        pWin->optional->colormap = None;
 
687
    }
 
688
 
 
689
    pWin->borderWidth = bw;
 
690
#ifdef XCSECURITY
 
691
    /*  can't let untrusted clients have background None windows;
 
692
     *  they make it too easy to steal window contents
 
693
     */
 
694
    if (client->trustLevel != XSecurityClientTrusted)
 
695
    {
 
696
        pWin->backgroundState = BackgroundPixel;
 
697
        pWin->background.pixel = 0;
 
698
    }
 
699
    else
 
700
#endif
 
701
    pWin->backgroundState = None;
 
702
 
 
703
    pWin->borderIsPixel = pParent->borderIsPixel;
 
704
    pWin->border = pParent->border;
 
705
    if (pWin->borderIsPixel == FALSE)
 
706
        pWin->border.pixmap->refcnt++;
 
707
                
 
708
    pWin->origin.x = x + (int)bw;
 
709
    pWin->origin.y = y + (int)bw;
 
710
    pWin->drawable.width = w;
 
711
    pWin->drawable.height = h;
 
712
    pWin->drawable.x = pParent->drawable.x + x + (int)bw;
 
713
    pWin->drawable.y = pParent->drawable.y + y + (int)bw;
 
714
 
 
715
        /* set up clip list correctly for unobscured WindowPtr */
 
716
    REGION_NULL(pScreen, &pWin->clipList);
 
717
    REGION_NULL(pScreen, &pWin->borderClip);
 
718
    REGION_NULL(pScreen, &pWin->winSize);
 
719
    REGION_NULL(pScreen, &pWin->borderSize);
 
720
 
 
721
    pHead = RealChildHead(pParent);
 
722
    if (pHead)
 
723
    {
 
724
        pWin->nextSib = pHead->nextSib;
 
725
        if (pHead->nextSib)
 
726
            pHead->nextSib->prevSib = pWin;
 
727
        else
 
728
            pParent->lastChild = pWin;
 
729
        pHead->nextSib = pWin;
 
730
        pWin->prevSib = pHead;
 
731
    }
 
732
    else
 
733
    {
 
734
        pWin->nextSib = pParent->firstChild;
 
735
        if (pParent->firstChild)
 
736
            pParent->firstChild->prevSib = pWin;
 
737
        else
 
738
            pParent->lastChild = pWin;
 
739
        pParent->firstChild = pWin;
 
740
    }
 
741
 
 
742
    SetWinSize (pWin);
 
743
    SetBorderSize (pWin);
 
744
 
 
745
    /* We SHOULD check for an error value here XXX */
 
746
    if (!(*pScreen->CreateWindow)(pWin))
 
747
    {
 
748
        *error = BadAlloc;
 
749
        DeleteWindow(pWin, None);
 
750
        return NullWindow;
 
751
    }
 
752
    /* We SHOULD check for an error value here XXX */
 
753
    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
 
754
 
 
755
    if (!(vmask & CWEventMask))
 
756
        RecalculateDeliverableEvents(pWin);
 
757
 
 
758
    if (vmask)
 
759
        *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
 
760
    else
 
761
        *error = Success;
 
762
 
 
763
    if (*error != Success)
 
764
    {
 
765
        DeleteWindow(pWin, None);
 
766
        return NullWindow;
 
767
    }
 
768
    if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
 
769
    {
 
770
        XID value = defaultBackingStore;
 
771
        (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
 
772
        pWin->forcedBS = TRUE;
 
773
    }
 
774
 
 
775
    if (SubSend(pParent))
 
776
    {
 
777
        event.u.u.type = CreateNotify;
 
778
        event.u.createNotify.window = wid;
 
779
        event.u.createNotify.parent = pParent->drawable.id;
 
780
        event.u.createNotify.x = x;
 
781
        event.u.createNotify.y = y;
 
782
        event.u.createNotify.width = w;
 
783
        event.u.createNotify.height = h;
 
784
        event.u.createNotify.borderWidth = bw;
 
785
        event.u.createNotify.override = pWin->overrideRedirect;
 
786
        DeliverEvents(pParent, &event, 1, NullWindow);          
 
787
    }
 
788
    return pWin;
 
789
}
 
790
 
 
791
static void
 
792
FreeWindowResources(register WindowPtr pWin)
 
793
{
 
794
    register ScreenPtr pScreen = pWin->drawable.pScreen;
 
795
 
 
796
    DeleteWindowFromAnySaveSet(pWin);
 
797
    DeleteWindowFromAnySelections(pWin);
 
798
    DeleteWindowFromAnyEvents(pWin, TRUE);
 
799
    REGION_UNINIT(pScreen, &pWin->clipList);
 
800
    REGION_UNINIT(pScreen, &pWin->winSize);
 
801
    REGION_UNINIT(pScreen, &pWin->borderClip);
 
802
    REGION_UNINIT(pScreen, &pWin->borderSize);
 
803
#ifdef SHAPE
 
804
    if (wBoundingShape (pWin))
 
805
        REGION_DESTROY(pScreen, wBoundingShape (pWin));
 
806
    if (wClipShape (pWin))
 
807
        REGION_DESTROY(pScreen, wClipShape (pWin));
 
808
    if (wInputShape (pWin))
 
809
        REGION_DESTROY(pScreen, wInputShape (pWin));
 
810
#endif
 
811
    if (pWin->borderIsPixel == FALSE)
 
812
        (*pScreen->DestroyPixmap)(pWin->border.pixmap);
 
813
    if (pWin->backgroundState == BackgroundPixmap)
 
814
        (*pScreen->DestroyPixmap)(pWin->background.pixmap);
 
815
 
 
816
    DeleteAllWindowProperties(pWin);
 
817
    /* We SHOULD check for an error value here XXX */
 
818
    (*pScreen->DestroyWindow)(pWin);
 
819
    DisposeWindowOptional (pWin);
 
820
}
 
821
 
 
822
static void
 
823
CrushTree(WindowPtr pWin)
 
824
{
 
825
    register WindowPtr pChild, pSib, pParent;
 
826
    UnrealizeWindowProcPtr UnrealizeWindow;
 
827
    xEvent event;
 
828
 
 
829
    if (!(pChild = pWin->firstChild))
 
830
        return;
 
831
    UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
 
832
    while (1)
 
833
    {
 
834
        if (pChild->firstChild)
 
835
        {
 
836
            pChild = pChild->firstChild;
 
837
            continue;
 
838
        }
 
839
        while (1)
 
840
        {
 
841
            pParent = pChild->parent;
 
842
            if (SubStrSend(pChild, pParent))
 
843
            {
 
844
                event.u.u.type = DestroyNotify;
 
845
                event.u.destroyNotify.window = pChild->drawable.id;
 
846
                DeliverEvents(pChild, &event, 1, NullWindow);           
 
847
            }
 
848
            FreeResource(pChild->drawable.id, RT_WINDOW);
 
849
            pSib = pChild->nextSib;
 
850
#ifdef DO_SAVE_UNDERS
 
851
            if (pChild->saveUnder && pChild->viewable)
 
852
                deltaSaveUndersViewable--;
 
853
#endif
 
854
            pChild->viewable = FALSE;
 
855
            if (pChild->realized)
 
856
            {
 
857
                pChild->realized = FALSE;
 
858
                (*UnrealizeWindow)(pChild);
 
859
            }
 
860
            FreeWindowResources(pChild);
 
861
            xfree(pChild);
 
862
            if ( (pChild = pSib) )
 
863
                break;
 
864
            pChild = pParent;
 
865
            pChild->firstChild = NullWindow;
 
866
            pChild->lastChild = NullWindow;
 
867
            if (pChild == pWin)
 
868
                return;
 
869
        }
 
870
    }
 
871
}
 
872
        
 
873
/*****
 
874
 *  DeleteWindow
 
875
 *       Deletes child of window then window itself
 
876
 *       If wid is None, don't send any events
 
877
 *****/
 
878
 
 
879
int
 
880
DeleteWindow(pointer value, XID wid)
 
881
 {
 
882
    register WindowPtr pParent;
 
883
    register WindowPtr pWin = (WindowPtr)value;
 
884
    xEvent event;
 
885
 
 
886
    UnmapWindow(pWin, FALSE);
 
887
 
 
888
    CrushTree(pWin);
 
889
 
 
890
    pParent = pWin->parent;
 
891
    if (wid && pParent && SubStrSend(pWin, pParent))
 
892
    {
 
893
        event.u.u.type = DestroyNotify;
 
894
        event.u.destroyNotify.window = pWin->drawable.id;
 
895
        DeliverEvents(pWin, &event, 1, NullWindow);             
 
896
    }
 
897
 
 
898
    FreeWindowResources(pWin);
 
899
    if (pParent)
 
900
    {
 
901
        if (pParent->firstChild == pWin)
 
902
            pParent->firstChild = pWin->nextSib;
 
903
        if (pParent->lastChild == pWin)
 
904
            pParent->lastChild = pWin->prevSib;
 
905
        if (pWin->nextSib)
 
906
            pWin->nextSib->prevSib = pWin->prevSib;
 
907
        if (pWin->prevSib)
 
908
            pWin->prevSib->nextSib = pWin->nextSib;
 
909
    }
 
910
    xfree(pWin);
 
911
    return Success;
 
912
}
 
913
 
 
914
void
 
915
DestroySubwindows(register WindowPtr pWin, ClientPtr client)
 
916
{
 
917
    /* XXX
 
918
     * The protocol is quite clear that each window should be
 
919
     * destroyed in turn, however, unmapping all of the first
 
920
     * eliminates most of the calls to ValidateTree.  So,
 
921
     * this implementation is incorrect in that all of the
 
922
     * UnmapNotifies occur before all of the DestroyNotifies.
 
923
     * If you care, simply delete the call to UnmapSubwindows.
 
924
     */
 
925
    UnmapSubwindows(pWin);
 
926
    while (pWin->lastChild)
 
927
        FreeResource(pWin->lastChild->drawable.id, RT_NONE);
 
928
}
 
929
 
 
930
#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
 
931
    ButtonReleaseMask | PointerMotionMask)
 
932
 
 
933
/*****
 
934
 *  ChangeWindowAttributes
 
935
 *   
 
936
 *  The value-mask specifies which attributes are to be changed; the
 
937
 *  value-list contains one value for each one bit in the mask, from least
 
938
 *  to most significant bit in the mask.  
 
939
 *****/
 
940
 
 
941
int
 
942
ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
 
943
{
 
944
    register Mask index2;
 
945
    register XID *pVlist;
 
946
    PixmapPtr pPixmap;
 
947
    Pixmap pixID;
 
948
    CursorPtr pCursor, pOldCursor;
 
949
    Cursor cursorID;
 
950
    WindowPtr pChild;
 
951
    Colormap cmap;
 
952
    ColormapPtr pCmap;
 
953
    xEvent xE;
 
954
    int result;
 
955
    register ScreenPtr pScreen;
 
956
    Mask vmaskCopy = 0;
 
957
    register Mask tmask;
 
958
    unsigned int val;
 
959
    int error;
 
960
    Bool checkOptional = FALSE;
 
961
    Bool borderRelative = FALSE;
 
962
    WindowPtr pLayerWin;
 
963
 
 
964
    if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
 
965
        return BadMatch;
 
966
 
 
967
    error = Success;
 
968
    pScreen = pWin->drawable.pScreen;
 
969
    pVlist = vlist;
 
970
    tmask = vmask;
 
971
    while (tmask)
 
972
    {
 
973
        index2 = (Mask) lowbit (tmask);
 
974
        tmask &= ~index2;
 
975
        switch (index2)
 
976
        {
 
977
          case CWBackPixmap:
 
978
            pixID = (Pixmap )*pVlist;
 
979
            pVlist++;
 
980
            if (pWin->backgroundState == ParentRelative)
 
981
                borderRelative = TRUE;
 
982
            if (pixID == None)
 
983
            {
 
984
#ifdef XCSECURITY
 
985
                /*  can't let untrusted clients have background None windows */
 
986
                if (client->trustLevel == XSecurityClientTrusted)
 
987
                {
 
988
#endif
 
989
                if (pWin->backgroundState == BackgroundPixmap)
 
990
                    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
 
991
                if (!pWin->parent)
 
992
                    MakeRootTile(pWin);
 
993
                else
 
994
                    pWin->backgroundState = None;
 
995
#ifdef XCSECURITY
 
996
                }
 
997
                else
 
998
                { /* didn't change the background to None, so don't tell ddx */
 
999
                    index2 = 0; 
 
1000
                }
 
1001
#endif
 
1002
            }
 
1003
            else if (pixID == ParentRelative)
 
1004
            {
 
1005
                if (pWin->parent &&
 
1006
                    pWin->drawable.depth != pWin->parent->drawable.depth)
 
1007
                {
 
1008
                    error = BadMatch;
 
1009
                    goto PatchUp;
 
1010
                }
 
1011
                if (pWin->backgroundState == BackgroundPixmap)
 
1012
                    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
 
1013
                if (!pWin->parent)
 
1014
                    MakeRootTile(pWin);
 
1015
                else
 
1016
                    pWin->backgroundState = ParentRelative;
 
1017
                borderRelative = TRUE;
 
1018
                /* Note that the parent's backgroundTile's refcnt is NOT
 
1019
                 * incremented. */
 
1020
            }
 
1021
            else
 
1022
            {   
 
1023
                pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
 
1024
                                                RT_PIXMAP, SecurityReadAccess);
 
1025
                if (pPixmap != (PixmapPtr) NULL)
 
1026
                {
 
1027
                    if  ((pPixmap->drawable.depth != pWin->drawable.depth) ||
 
1028
                         (pPixmap->drawable.pScreen != pScreen))
 
1029
                    {
 
1030
                        error = BadMatch;
 
1031
                        goto PatchUp;
 
1032
                    }
 
1033
                    if (pWin->backgroundState == BackgroundPixmap)
 
1034
                        (*pScreen->DestroyPixmap)(pWin->background.pixmap);
 
1035
                    pWin->backgroundState = BackgroundPixmap;
 
1036
                    pWin->background.pixmap = pPixmap;
 
1037
                    pPixmap->refcnt++;
 
1038
                }
 
1039
                else
 
1040
                {
 
1041
                    error = BadPixmap;
 
1042
                    client->errorValue = pixID;
 
1043
                    goto PatchUp;
 
1044
                }
 
1045
            }
 
1046
            break;
 
1047
          case CWBackPixel:
 
1048
            if (pWin->backgroundState == ParentRelative)
 
1049
                borderRelative = TRUE;
 
1050
            if (pWin->backgroundState == BackgroundPixmap)
 
1051
                (*pScreen->DestroyPixmap)(pWin->background.pixmap);
 
1052
            pWin->backgroundState = BackgroundPixel;
 
1053
            pWin->background.pixel = (CARD32 ) *pVlist;
 
1054
                   /* background pixel overrides background pixmap,
 
1055
                      so don't let the ddx layer see both bits */
 
1056
            vmaskCopy &= ~CWBackPixmap;
 
1057
            pVlist++;
 
1058
            break;
 
1059
          case CWBorderPixmap:
 
1060
            pixID = (Pixmap ) *pVlist;
 
1061
            pVlist++;
 
1062
            if (pixID == CopyFromParent)
 
1063
            {
 
1064
                if (!pWin->parent ||
 
1065
                    (pWin->drawable.depth != pWin->parent->drawable.depth))
 
1066
                {
 
1067
                    error = BadMatch;
 
1068
                    goto PatchUp;
 
1069
                }
 
1070
                if (pWin->borderIsPixel == FALSE)
 
1071
                    (*pScreen->DestroyPixmap)(pWin->border.pixmap);
 
1072
                pWin->border = pWin->parent->border;
 
1073
                if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
 
1074
                {
 
1075
                    index2 = CWBorderPixel;
 
1076
                }
 
1077
                else
 
1078
                {
 
1079
                    pWin->parent->border.pixmap->refcnt++;
 
1080
                }
 
1081
            }
 
1082
            else
 
1083
            {   
 
1084
                pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
 
1085
                                        RT_PIXMAP, SecurityReadAccess);
 
1086
                if (pPixmap)
 
1087
                {
 
1088
                    if  ((pPixmap->drawable.depth != pWin->drawable.depth) ||
 
1089
                         (pPixmap->drawable.pScreen != pScreen))
 
1090
                    {
 
1091
                        error = BadMatch;
 
1092
                        goto PatchUp;
 
1093
                    }
 
1094
                    if (pWin->borderIsPixel == FALSE)
 
1095
                        (*pScreen->DestroyPixmap)(pWin->border.pixmap);
 
1096
                    pWin->borderIsPixel = FALSE;
 
1097
                    pWin->border.pixmap = pPixmap;
 
1098
                    pPixmap->refcnt++;
 
1099
                }
 
1100
                else
 
1101
                {
 
1102
                    error = BadPixmap;
 
1103
                    client->errorValue = pixID;
 
1104
                    goto PatchUp;
 
1105
                }
 
1106
            }
 
1107
            break;
 
1108
          case CWBorderPixel:
 
1109
            if (pWin->borderIsPixel == FALSE)
 
1110
                (*pScreen->DestroyPixmap)(pWin->border.pixmap);
 
1111
            pWin->borderIsPixel = TRUE;
 
1112
            pWin->border.pixel = (CARD32) *pVlist;
 
1113
                    /* border pixel overrides border pixmap,
 
1114
                       so don't let the ddx layer see both bits */
 
1115
            vmaskCopy &= ~CWBorderPixmap;
 
1116
            pVlist++;
 
1117
            break;
 
1118
          case CWBitGravity:
 
1119
            val = (CARD8 )*pVlist;
 
1120
            pVlist++;
 
1121
            if (val > StaticGravity)
 
1122
            {
 
1123
                error = BadValue;
 
1124
                client->errorValue = val;
 
1125
                goto PatchUp;
 
1126
            }
 
1127
            pWin->bitGravity = val;
 
1128
            break;
 
1129
          case CWWinGravity:
 
1130
            val = (CARD8 )*pVlist;
 
1131
            pVlist++;
 
1132
            if (val > StaticGravity)
 
1133
            {
 
1134
                error = BadValue;
 
1135
                client->errorValue = val;
 
1136
                goto PatchUp;
 
1137
            }
 
1138
            pWin->winGravity = val;
 
1139
            break;
 
1140
          case CWBackingStore:
 
1141
            val = (CARD8 )*pVlist;
 
1142
            pVlist++;
 
1143
            if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
 
1144
            {
 
1145
                error = BadValue;
 
1146
                client->errorValue = val;
 
1147
                goto PatchUp;
 
1148
            }
 
1149
            pWin->backingStore = val;
 
1150
            pWin->forcedBS = FALSE;
 
1151
            break;
 
1152
          case CWBackingPlanes:
 
1153
            if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
 
1154
                if (!pWin->optional && !MakeWindowOptional (pWin))
 
1155
                {
 
1156
                    error = BadAlloc;
 
1157
                    goto PatchUp;
 
1158
                }
 
1159
                pWin->optional->backingBitPlanes = (CARD32) *pVlist;
 
1160
                if ((CARD32)*pVlist == (CARD32)~0L)
 
1161
                    checkOptional = TRUE;
 
1162
            }
 
1163
            pVlist++;
 
1164
            break;
 
1165
          case CWBackingPixel:
 
1166
            if (pWin->optional || (CARD32) *pVlist) {
 
1167
                if (!pWin->optional && !MakeWindowOptional (pWin))
 
1168
                {
 
1169
                    error = BadAlloc;
 
1170
                    goto PatchUp;
 
1171
                }
 
1172
                pWin->optional->backingPixel = (CARD32) *pVlist;
 
1173
                if (!*pVlist)
 
1174
                    checkOptional = TRUE;
 
1175
            }
 
1176
            pVlist++;
 
1177
            break;
 
1178
          case CWSaveUnder:
 
1179
            val = (BOOL) *pVlist;
 
1180
            pVlist++;
 
1181
            if ((val != xTrue) && (val != xFalse))
 
1182
            {
 
1183
                error = BadValue;
 
1184
                client->errorValue = val;
 
1185
                goto PatchUp;
 
1186
            }
 
1187
#ifdef DO_SAVE_UNDERS
 
1188
            if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
 
1189
                DO_SAVE_UNDERS(pWin))
 
1190
            {
 
1191
                /*
 
1192
                 * Re-check all siblings and inferiors for obscurity or
 
1193
                 * exposition (hee hee).
 
1194
                 */
 
1195
                if (pWin->saveUnder)
 
1196
                    deltaSaveUndersViewable--;
 
1197
                else
 
1198
                    deltaSaveUndersViewable++;
 
1199
                pWin->saveUnder = val;
 
1200
 
 
1201
                if (pWin->firstChild)
 
1202
                {
 
1203
                    pLayerWin = (*pScreen->GetLayerWindow)(pWin);
 
1204
                   if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
 
1205
                       (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
 
1206
                                                       pWin->nextSib);
 
1207
               }
 
1208
               else
 
1209
               {
 
1210
                   if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
 
1211
                       (*pScreen->PostChangeSaveUnder)(pWin,
 
1212
                                                       pWin->nextSib);
 
1213
               }                                   
 
1214
            }
 
1215
            else
 
1216
            {
 
1217
                /*  If we're changing the saveUnder attribute of the root 
 
1218
                 *  window, all we do is set pWin->saveUnder so that
 
1219
                 *  GetWindowAttributes returns the right value.  We don't
 
1220
                 *  do the "normal" save-under processing (as above).
 
1221
                 *  Hope that doesn't cause any problems.
 
1222
                 */
 
1223
                pWin->saveUnder = val;
 
1224
            }
 
1225
#else
 
1226
            pWin->saveUnder = val;
 
1227
#endif /* DO_SAVE_UNDERS */
 
1228
            break;
 
1229
          case CWEventMask:
 
1230
            result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
 
1231
            if (result)
 
1232
            {
 
1233
                error = result;
 
1234
                goto PatchUp;
 
1235
            }
 
1236
            pVlist++;
 
1237
            break;
 
1238
          case CWDontPropagate:
 
1239
            result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
 
1240
                                            &checkOptional);
 
1241
            if (result)
 
1242
            {
 
1243
                error = result;
 
1244
                goto PatchUp;
 
1245
            }
 
1246
            pVlist++;
 
1247
            break;
 
1248
          case CWOverrideRedirect:
 
1249
            val = (BOOL ) *pVlist;
 
1250
            pVlist++;
 
1251
            if ((val != xTrue) && (val != xFalse))
 
1252
            {
 
1253
                error = BadValue;
 
1254
                client->errorValue = val;
 
1255
                goto PatchUp;
 
1256
            }
 
1257
            pWin->overrideRedirect = val;
 
1258
            break;
 
1259
          case CWColormap:
 
1260
            cmap = (Colormap) *pVlist;
 
1261
            pVlist++;
 
1262
            if (cmap == CopyFromParent)
 
1263
            {
 
1264
#ifdef XAPPGROUP
 
1265
                Colormap ag_colormap;
 
1266
                ClientPtr win_owner;
 
1267
 
 
1268
                /*
 
1269
                 * win_owner == client for CreateWindow, other clients
 
1270
                 * can ChangeWindowAttributes
 
1271
                 */
 
1272
                win_owner = clients[CLIENT_ID(pWin->drawable.id)];
 
1273
 
 
1274
                if ( win_owner && win_owner->appgroup &&
 
1275
                    !pWin->parent->parent &&
 
1276
                    (ag_colormap = XagDefaultColormap (win_owner)))
 
1277
                    cmap = ag_colormap;
 
1278
                else
 
1279
#endif
 
1280
                if (pWin->parent &&
 
1281
                    (!pWin->optional ||
 
1282
                     pWin->optional->visual == wVisual (pWin->parent)))
 
1283
                {
 
1284
                    cmap = wColormap (pWin->parent);
 
1285
                }
 
1286
                else
 
1287
                    cmap = None;
 
1288
            }
 
1289
            if (cmap == None)
 
1290
            {
 
1291
                error = BadMatch;
 
1292
                goto PatchUp;
 
1293
            }
 
1294
            pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
 
1295
                                              RT_COLORMAP, SecurityReadAccess);
 
1296
            if (!pCmap)
 
1297
            {
 
1298
                error = BadColor;
 
1299
                client->errorValue = cmap;
 
1300
                goto PatchUp;
 
1301
            }
 
1302
            if (pCmap->pVisual->vid != wVisual (pWin) ||
 
1303
                pCmap->pScreen != pScreen)
 
1304
            {
 
1305
                error = BadMatch;
 
1306
                goto PatchUp;
 
1307
            }
 
1308
            if (cmap != wColormap (pWin))
 
1309
            {
 
1310
                if (!pWin->optional)
 
1311
                {
 
1312
                    if (!MakeWindowOptional (pWin))
 
1313
                    {
 
1314
                        error = BadAlloc;
 
1315
                        goto PatchUp;
 
1316
                    }
 
1317
                }
 
1318
                else if (pWin->parent && cmap == wColormap (pWin->parent))
 
1319
                    checkOptional = TRUE;
 
1320
 
 
1321
                /*
 
1322
                 * propagate the original colormap to any children
 
1323
                 * inheriting it
 
1324
                 */
 
1325
 
 
1326
                for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
 
1327
                {
 
1328
                    if (!pChild->optional && !MakeWindowOptional (pChild))
 
1329
                    {
 
1330
                        error = BadAlloc;
 
1331
                        goto PatchUp;
 
1332
                    }
 
1333
                }
 
1334
 
 
1335
                pWin->optional->colormap = cmap;
 
1336
 
 
1337
                /*
 
1338
                 * check on any children now matching the new colormap
 
1339
                 */
 
1340
 
 
1341
                for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
 
1342
                {
 
1343
                    if (pChild->optional->colormap == cmap)
 
1344
                        CheckWindowOptionalNeed (pChild);
 
1345
                }
 
1346
        
 
1347
                xE.u.u.type = ColormapNotify;
 
1348
                xE.u.colormap.window = pWin->drawable.id;
 
1349
                xE.u.colormap.colormap = cmap;
 
1350
                xE.u.colormap.new = xTrue;
 
1351
                xE.u.colormap.state = IsMapInstalled(cmap, pWin);
 
1352
                DeliverEvents(pWin, &xE, 1, NullWindow);
 
1353
            }
 
1354
            break;
 
1355
          case CWCursor:
 
1356
            cursorID = (Cursor ) *pVlist;
 
1357
            pVlist++;
 
1358
            /*
 
1359
             * install the new
 
1360
             */
 
1361
            if ( cursorID == None)
 
1362
            {
 
1363
                if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
 
1364
                    pCursor = rootCursor;
 
1365
                else
 
1366
                    pCursor = (CursorPtr) None;
 
1367
            }
 
1368
            else
 
1369
            {
 
1370
                pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
 
1371
                                                RT_CURSOR, SecurityReadAccess);
 
1372
                if (!pCursor)
 
1373
                {
 
1374
                    error = BadCursor;
 
1375
                    client->errorValue = cursorID;
 
1376
                    goto PatchUp;
 
1377
                }
 
1378
            }
 
1379
 
 
1380
            if (pCursor != wCursor (pWin))
 
1381
            {
 
1382
                /*
 
1383
                 * patch up child windows so they don't lose cursors.
 
1384
                 */
 
1385
 
 
1386
                for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
 
1387
                {
 
1388
                    if (!pChild->optional && !pChild->cursorIsNone &&
 
1389
                        !MakeWindowOptional (pChild))
 
1390
                    {
 
1391
                        error = BadAlloc;
 
1392
                        goto PatchUp;
 
1393
                    }
 
1394
                }
 
1395
 
 
1396
                pOldCursor = 0;
 
1397
                if (pCursor == (CursorPtr) None)
 
1398
                {
 
1399
                    pWin->cursorIsNone = TRUE;
 
1400
                    if (pWin->optional)
 
1401
                    {
 
1402
                        pOldCursor = pWin->optional->cursor;
 
1403
                        pWin->optional->cursor = (CursorPtr) None;
 
1404
                        checkOptional = TRUE;
 
1405
                    }
 
1406
                } else {
 
1407
                    if (!pWin->optional)
 
1408
                    {
 
1409
                        if (!MakeWindowOptional (pWin))
 
1410
                        {
 
1411
                            error = BadAlloc;
 
1412
                            goto PatchUp;
 
1413
                        }
 
1414
                    }
 
1415
                    else if (pWin->parent && pCursor == wCursor (pWin->parent))
 
1416
                        checkOptional = TRUE;
 
1417
                    pOldCursor = pWin->optional->cursor;
 
1418
                    pWin->optional->cursor = pCursor;
 
1419
                    pCursor->refcnt++;
 
1420
                    pWin->cursorIsNone = FALSE;
 
1421
                    /*
 
1422
                     * check on any children now matching the new cursor
 
1423
                     */
 
1424
 
 
1425
                    for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
 
1426
                    {
 
1427
                        if (pChild->optional &&
 
1428
                            (pChild->optional->cursor == pCursor))
 
1429
                            CheckWindowOptionalNeed (pChild);
 
1430
                    }
 
1431
                }
 
1432
 
 
1433
                if (pWin->realized)
 
1434
                    WindowHasNewCursor( pWin);
 
1435
 
 
1436
                /* Can't free cursor until here - old cursor
 
1437
                 * is needed in WindowHasNewCursor
 
1438
                 */
 
1439
                if (pOldCursor)
 
1440
                    FreeCursor (pOldCursor, (Cursor)0);
 
1441
            }
 
1442
            break;
 
1443
         default:
 
1444
            error = BadValue;
 
1445
            client->errorValue = vmask;
 
1446
            goto PatchUp;
 
1447
      }
 
1448
      vmaskCopy |= index2;
 
1449
    }
 
1450
PatchUp:
 
1451
    if (checkOptional)
 
1452
        CheckWindowOptionalNeed (pWin);
 
1453
 
 
1454
        /* We SHOULD check for an error value here XXX */
 
1455
    (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
 
1456
 
 
1457
    /* 
 
1458
        If the border contents have changed, redraw the border. 
 
1459
        Note that this has to be done AFTER pScreen->ChangeWindowAttributes
 
1460
        for the tile to be rotated, and the correct function selected.
 
1461
    */
 
1462
    if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
 
1463
        && pWin->viewable && HasBorder (pWin))
 
1464
    {
 
1465
        RegionRec exposed;
 
1466
 
 
1467
        REGION_NULL(pScreen, &exposed);
 
1468
        REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
 
1469
        (*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
 
1470
        REGION_UNINIT(pScreen, &exposed);
 
1471
    }
 
1472
    return error;
 
1473
}
 
1474
 
 
1475
 
 
1476
/*****
 
1477
 * GetWindowAttributes
 
1478
 *    Notice that this is different than ChangeWindowAttributes
 
1479
 *****/
 
1480
 
 
1481
void
 
1482
GetWindowAttributes(register WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
 
1483
{
 
1484
    wa->type = X_Reply;
 
1485
    wa->bitGravity = pWin->bitGravity;
 
1486
    wa->winGravity = pWin->winGravity;
 
1487
    if (pWin->forcedBS && pWin->backingStore != Always)
 
1488
        wa->backingStore = NotUseful;
 
1489
    else
 
1490
        wa->backingStore = pWin->backingStore;
 
1491
    wa->length = (sizeof(xGetWindowAttributesReply) -
 
1492
                 sizeof(xGenericReply)) >> 2;
 
1493
    wa->sequenceNumber = client->sequence;
 
1494
    wa->backingBitPlanes =  wBackingBitPlanes (pWin);
 
1495
    wa->backingPixel =  wBackingPixel (pWin);
 
1496
    wa->saveUnder = (BOOL)pWin->saveUnder;
 
1497
    wa->override = pWin->overrideRedirect;
 
1498
    if (!pWin->mapped)
 
1499
        wa->mapState = IsUnmapped;
 
1500
    else if (pWin->realized)
 
1501
        wa->mapState = IsViewable;
 
1502
    else
 
1503
        wa->mapState = IsUnviewable;
 
1504
 
 
1505
    wa->colormap =  wColormap (pWin);
 
1506
    wa->mapInstalled = (wa->colormap == None) ? xFalse
 
1507
                                : IsMapInstalled(wa->colormap, pWin);
 
1508
 
 
1509
    wa->yourEventMask = EventMaskForClient(pWin, client);
 
1510
    wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
 
1511
    wa->doNotPropagateMask = wDontPropagateMask (pWin);
 
1512
    wa->class = pWin->drawable.class;
 
1513
    wa->visualID = wVisual (pWin);
 
1514
}
 
1515
 
 
1516
 
 
1517
WindowPtr
 
1518
MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
 
1519
{
 
1520
    register WindowPtr pParent = pWin->parent;
 
1521
    WindowPtr pFirstChange = pWin; /* highest window where list changes */
 
1522
 
 
1523
    if (pWin->nextSib != pNextSib)
 
1524
    {
 
1525
        WindowPtr pOldNextSib = pWin->nextSib;
 
1526
 
 
1527
        if (!pNextSib)        /* move to bottom */
 
1528
        {
 
1529
            if (pParent->firstChild == pWin)
 
1530
                pParent->firstChild = pWin->nextSib;
 
1531
            /* if (pWin->nextSib) */     /* is always True: pNextSib == NULL
 
1532
                                          * and pWin->nextSib != pNextSib
 
1533
                                          * therefore pWin->nextSib != NULL */
 
1534
            pFirstChange = pWin->nextSib;
 
1535
            pWin->nextSib->prevSib = pWin->prevSib;
 
1536
            if (pWin->prevSib)
 
1537
                pWin->prevSib->nextSib = pWin->nextSib;
 
1538
            pParent->lastChild->nextSib = pWin;
 
1539
            pWin->prevSib = pParent->lastChild;
 
1540
            pWin->nextSib = NullWindow;
 
1541
            pParent->lastChild = pWin;
 
1542
        }
 
1543
        else if (pParent->firstChild == pNextSib) /* move to top */
 
1544
        {
 
1545
            pFirstChange = pWin;
 
1546
            if (pParent->lastChild == pWin)
 
1547
               pParent->lastChild = pWin->prevSib;
 
1548
            if (pWin->nextSib)
 
1549
                pWin->nextSib->prevSib = pWin->prevSib;
 
1550
            if (pWin->prevSib)
 
1551
                pWin->prevSib->nextSib = pWin->nextSib;
 
1552
            pWin->nextSib = pParent->firstChild;
 
1553
            pWin->prevSib = (WindowPtr ) NULL;
 
1554
            pNextSib->prevSib = pWin;
 
1555
            pParent->firstChild = pWin;
 
1556
        }
 
1557
        else                    /* move in middle of list */
 
1558
        {
 
1559
            WindowPtr pOldNext = pWin->nextSib;
 
1560
 
 
1561
            pFirstChange = NullWindow;
 
1562
            if (pParent->firstChild == pWin)
 
1563
                pFirstChange = pParent->firstChild = pWin->nextSib;
 
1564
            if (pParent->lastChild == pWin) {
 
1565
               pFirstChange = pWin;
 
1566
               pParent->lastChild = pWin->prevSib;
 
1567
            }
 
1568
            if (pWin->nextSib)
 
1569
                pWin->nextSib->prevSib = pWin->prevSib;
 
1570
            if (pWin->prevSib)
 
1571
                pWin->prevSib->nextSib = pWin->nextSib;
 
1572
            pWin->nextSib = pNextSib;
 
1573
            pWin->prevSib = pNextSib->prevSib;
 
1574
            if (pNextSib->prevSib)
 
1575
                pNextSib->prevSib->nextSib = pWin;
 
1576
            pNextSib->prevSib = pWin;
 
1577
            if (!pFirstChange) {                     /* do we know it yet? */
 
1578
                pFirstChange = pParent->firstChild;  /* no, search from top */
 
1579
                while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
 
1580
                     pFirstChange = pFirstChange->nextSib;
 
1581
            }
 
1582
        }
 
1583
        if(pWin->drawable.pScreen->RestackWindow)
 
1584
            (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
 
1585
    }
 
1586
 
 
1587
#ifdef ROOTLESS
 
1588
    /*
 
1589
     * In rootless mode we can't optimize away window restacks.
 
1590
     * There may be non-X windows around, so even if the window
 
1591
     * is in the correct position from X's point of view,
 
1592
     * the underlying window system may want to reorder it.
 
1593
     */
 
1594
    else if (pWin->drawable.pScreen->RestackWindow)
 
1595
        (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
 
1596
#endif
 
1597
 
 
1598
    return( pFirstChange );
 
1599
}
 
1600
 
 
1601
RegionPtr
 
1602
CreateUnclippedWinSize (register WindowPtr pWin)
 
1603
{
 
1604
    RegionPtr   pRgn;
 
1605
    BoxRec      box;
 
1606
 
 
1607
    box.x1 = pWin->drawable.x;
 
1608
    box.y1 = pWin->drawable.y;
 
1609
    box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
 
1610
    box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
 
1611
    pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
 
1612
#ifdef SHAPE
 
1613
    if (wBoundingShape (pWin) || wClipShape (pWin)) {
 
1614
        ScreenPtr pScreen = pWin->drawable.pScreen;
 
1615
 
 
1616
        REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
 
1617
                         - pWin->drawable.y);
 
1618
        if (wBoundingShape (pWin))
 
1619
            REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
 
1620
        if (wClipShape (pWin))
 
1621
            REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
 
1622
        REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
 
1623
    }
 
1624
#endif
 
1625
    return pRgn;
 
1626
}
 
1627
 
 
1628
void
 
1629
SetWinSize (register WindowPtr pWin)
 
1630
{
 
1631
#ifdef COMPOSITE
 
1632
    if (pWin->redirectDraw)
 
1633
    {
 
1634
        BoxRec  box;
 
1635
 
 
1636
        box.x1 = pWin->drawable.x;
 
1637
        box.y1 = pWin->drawable.y;
 
1638
        box.x2 = pWin->drawable.x + pWin->drawable.width;
 
1639
        box.y2 = pWin->drawable.y + pWin->drawable.height;
 
1640
        REGION_RESET (pScreen, &pWin->winSize, &box);
 
1641
    }
 
1642
    else
 
1643
#endif
 
1644
    ClippedRegionFromBox(pWin->parent, &pWin->winSize,
 
1645
                         pWin->drawable.x, pWin->drawable.y,
 
1646
                         (int)pWin->drawable.width,
 
1647
                         (int)pWin->drawable.height);
 
1648
#ifdef SHAPE
 
1649
    if (wBoundingShape (pWin) || wClipShape (pWin)) {
 
1650
        ScreenPtr pScreen = pWin->drawable.pScreen;
 
1651
 
 
1652
        REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
 
1653
                         - pWin->drawable.y);
 
1654
        if (wBoundingShape (pWin))
 
1655
            REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
 
1656
                             wBoundingShape (pWin));
 
1657
        if (wClipShape (pWin))
 
1658
            REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
 
1659
                             wClipShape (pWin));
 
1660
        REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
 
1661
                         pWin->drawable.y);
 
1662
    }
 
1663
#endif
 
1664
}
 
1665
 
 
1666
void
 
1667
SetBorderSize (register WindowPtr pWin)
 
1668
{
 
1669
    int bw;
 
1670
 
 
1671
    if (HasBorder (pWin)) {
 
1672
        bw = wBorderWidth (pWin);
 
1673
#ifdef COMPOSITE
 
1674
        if (pWin->redirectDraw)
 
1675
        {
 
1676
            BoxRec      box;
 
1677
 
 
1678
            box.x1 = pWin->drawable.x - bw;
 
1679
            box.y1 = pWin->drawable.y - bw;
 
1680
            box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
 
1681
            box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
 
1682
            REGION_RESET (pScreen, &pWin->borderSize, &box);
 
1683
        }
 
1684
        else
 
1685
#endif
 
1686
        ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
 
1687
                pWin->drawable.x - bw, pWin->drawable.y - bw,
 
1688
                (int)(pWin->drawable.width + (bw<<1)),
 
1689
                (int)(pWin->drawable.height + (bw<<1)));
 
1690
#ifdef SHAPE
 
1691
        if (wBoundingShape (pWin)) {
 
1692
            ScreenPtr pScreen = pWin->drawable.pScreen;
 
1693
 
 
1694
            REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
 
1695
                             - pWin->drawable.y);
 
1696
            REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
 
1697
                             wBoundingShape (pWin));
 
1698
            REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
 
1699
                             pWin->drawable.y);
 
1700
            REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
 
1701
                         &pWin->winSize);
 
1702
        }
 
1703
#endif
 
1704
    } else {
 
1705
        REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
 
1706
                                               &pWin->winSize);
 
1707
    }
 
1708
}
 
1709
 
 
1710
/**
 
1711
 *
 
1712
 *  \param x,y          new window position
 
1713
 *  \param oldx,oldy    old window position
 
1714
 *  \param destx,desty  position relative to gravity
 
1715
 */
 
1716
 
 
1717
void
 
1718
GravityTranslate (register int x, register int y, int oldx, int oldy,
 
1719
                  int dw, int dh, unsigned gravity,
 
1720
                  register int *destx, register int *desty)
 
1721
{
 
1722
    switch (gravity) {
 
1723
    case NorthGravity:
 
1724
        *destx = x + dw / 2;
 
1725
        *desty = y;
 
1726
        break;
 
1727
    case NorthEastGravity:
 
1728
        *destx = x + dw;
 
1729
        *desty = y;
 
1730
        break;
 
1731
    case WestGravity:
 
1732
        *destx = x;
 
1733
        *desty = y + dh / 2;
 
1734
        break;
 
1735
    case CenterGravity:
 
1736
        *destx = x + dw / 2;
 
1737
        *desty = y + dh / 2;
 
1738
        break;
 
1739
    case EastGravity:
 
1740
        *destx = x + dw;
 
1741
        *desty = y + dh / 2;
 
1742
        break;
 
1743
    case SouthWestGravity:
 
1744
        *destx = x;
 
1745
        *desty = y + dh;
 
1746
        break;
 
1747
    case SouthGravity:
 
1748
        *destx = x + dw / 2;
 
1749
        *desty = y + dh;
 
1750
        break;
 
1751
    case SouthEastGravity:
 
1752
        *destx = x + dw;
 
1753
        *desty = y + dh;
 
1754
        break;
 
1755
    case StaticGravity:
 
1756
        *destx = oldx;
 
1757
        *desty = oldy;
 
1758
        break;
 
1759
    default:
 
1760
        *destx = x;
 
1761
        *desty = y;
 
1762
        break;
 
1763
    }
 
1764
}
 
1765
 
 
1766
/* XXX need to retile border on each window with ParentRelative origin */
 
1767
void
 
1768
ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
 
1769
{
 
1770
    register ScreenPtr pScreen;
 
1771
    register WindowPtr pSib, pChild;
 
1772
    Bool resized = (dw || dh);
 
1773
 
 
1774
    pScreen = pWin->drawable.pScreen;
 
1775
 
 
1776
    for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
 
1777
    {
 
1778
        if (resized && (pSib->winGravity > NorthWestGravity))
 
1779
        {
 
1780
            int cwsx, cwsy;
 
1781
 
 
1782
            cwsx = pSib->origin.x;
 
1783
            cwsy = pSib->origin.y;
 
1784
            GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
 
1785
                        pSib->winGravity, &cwsx, &cwsy);
 
1786
            if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
 
1787
            {
 
1788
                xEvent event;
 
1789
 
 
1790
                event.u.u.type = GravityNotify;
 
1791
                event.u.gravity.window = pSib->drawable.id;
 
1792
                event.u.gravity.x = cwsx - wBorderWidth (pSib);
 
1793
                event.u.gravity.y = cwsy - wBorderWidth (pSib);
 
1794
                DeliverEvents (pSib, &event, 1, NullWindow);
 
1795
                pSib->origin.x = cwsx;
 
1796
                pSib->origin.y = cwsy;
 
1797
            }
 
1798
        }
 
1799
        pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
 
1800
        pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
 
1801
        SetWinSize (pSib);
 
1802
        SetBorderSize (pSib);
 
1803
        (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
 
1804
 
 
1805
        if ( (pChild = pSib->firstChild) )
 
1806
        {
 
1807
            while (1)
 
1808
            {
 
1809
                pChild->drawable.x = pChild->parent->drawable.x +
 
1810
                                     pChild->origin.x;
 
1811
                pChild->drawable.y = pChild->parent->drawable.y +
 
1812
                                     pChild->origin.y;
 
1813
                SetWinSize (pChild);
 
1814
                SetBorderSize (pChild);
 
1815
                (*pScreen->PositionWindow)(pChild,
 
1816
                                    pChild->drawable.x, pChild->drawable.y);
 
1817
                if (pChild->firstChild)
 
1818
                {
 
1819
                    pChild = pChild->firstChild;
 
1820
                    continue;
 
1821
                }
 
1822
                while (!pChild->nextSib && (pChild != pSib))
 
1823
                    pChild = pChild->parent;
 
1824
                if (pChild == pSib)
 
1825
                    break;
 
1826
                pChild = pChild->nextSib;
 
1827
            }
 
1828
        }
 
1829
    }
 
1830
}
 
1831
 
 
1832
#define GET_INT16(m, f) \
 
1833
        if (m & mask) \
 
1834
          { \
 
1835
             f = (INT16) *pVlist;\
 
1836
            pVlist++; \
 
1837
         }
 
1838
#define GET_CARD16(m, f) \
 
1839
        if (m & mask) \
 
1840
         { \
 
1841
            f = (CARD16) *pVlist;\
 
1842
            pVlist++;\
 
1843
         }
 
1844
 
 
1845
#define GET_CARD8(m, f) \
 
1846
        if (m & mask) \
 
1847
         { \
 
1848
            f = (CARD8) *pVlist;\
 
1849
            pVlist++;\
 
1850
         }
 
1851
 
 
1852
#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
 
1853
 
 
1854
#define IllegalInputOnlyConfigureMask (CWBorderWidth)
 
1855
 
 
1856
/*
 
1857
 * IsSiblingAboveMe
 
1858
 *     returns Above if pSib above pMe in stack or Below otherwise 
 
1859
 */
 
1860
 
 
1861
static int
 
1862
IsSiblingAboveMe(
 
1863
    register WindowPtr pMe,
 
1864
    register WindowPtr pSib)
 
1865
{
 
1866
    register WindowPtr pWin;
 
1867
 
 
1868
    pWin = pMe->parent->firstChild;
 
1869
    while (pWin)
 
1870
    {
 
1871
        if (pWin == pSib)
 
1872
            return(Above);
 
1873
        else if (pWin == pMe)
 
1874
            return(Below);
 
1875
        pWin = pWin->nextSib;
 
1876
    }
 
1877
    return(Below);
 
1878
}
 
1879
 
 
1880
static BoxPtr
 
1881
WindowExtents(
 
1882
    register WindowPtr pWin,
 
1883
    register BoxPtr pBox)
 
1884
{
 
1885
    pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
 
1886
    pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
 
1887
    pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
 
1888
               + wBorderWidth (pWin);
 
1889
    pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
 
1890
               + wBorderWidth (pWin);
 
1891
    return(pBox);
 
1892
}
 
1893
 
 
1894
#ifdef SHAPE
 
1895
#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
 
1896
 
 
1897
static RegionPtr
 
1898
MakeBoundingRegion (
 
1899
    register WindowPtr  pWin,
 
1900
    BoxPtr      pBox)
 
1901
{
 
1902
    RegionPtr   pRgn;
 
1903
    ScreenPtr   pScreen = pWin->drawable.pScreen;
 
1904
 
 
1905
    pRgn = REGION_CREATE(pScreen, pBox, 1);
 
1906
    if (wBoundingShape (pWin)) {
 
1907
            REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
 
1908
                                                  -pWin->origin.y);
 
1909
            REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
 
1910
            REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
 
1911
                                                  pWin->origin.y);
 
1912
    }
 
1913
    return pRgn;
 
1914
}
 
1915
 
 
1916
static Bool
 
1917
ShapeOverlap (
 
1918
    WindowPtr   pWin,
 
1919
    BoxPtr      pWinBox,
 
1920
    WindowPtr   pSib,
 
1921
    BoxPtr      pSibBox)
 
1922
{
 
1923
    RegionPtr   pWinRgn, pSibRgn;
 
1924
    register ScreenPtr  pScreen;
 
1925
    Bool        ret;
 
1926
 
 
1927
    if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
 
1928
        return TRUE;
 
1929
    pScreen = pWin->drawable.pScreen;
 
1930
    pWinRgn = MakeBoundingRegion (pWin, pWinBox);
 
1931
    pSibRgn = MakeBoundingRegion (pSib, pSibBox);
 
1932
    REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
 
1933
    ret = REGION_NOTEMPTY(pScreen, pWinRgn);
 
1934
    REGION_DESTROY(pScreen, pWinRgn);
 
1935
    REGION_DESTROY(pScreen, pSibRgn);
 
1936
    return ret;
 
1937
}
 
1938
#endif
 
1939
 
 
1940
static Bool
 
1941
AnyWindowOverlapsMe(
 
1942
    WindowPtr pWin,
 
1943
    WindowPtr pHead,
 
1944
    register BoxPtr box)
 
1945
{
 
1946
    register WindowPtr pSib;
 
1947
    BoxRec sboxrec;
 
1948
    register BoxPtr sbox;
 
1949
 
 
1950
    for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
 
1951
    {
 
1952
        if (pSib->mapped)
 
1953
        {
 
1954
            sbox = WindowExtents(pSib, &sboxrec);
 
1955
            if (BOXES_OVERLAP(sbox, box)
 
1956
#ifdef SHAPE
 
1957
            && ShapeOverlap (pWin, box, pSib, sbox)
 
1958
#endif
 
1959
            )
 
1960
                return(TRUE);
 
1961
        }
 
1962
    }
 
1963
    return(FALSE);
 
1964
}
 
1965
 
 
1966
static Bool
 
1967
IOverlapAnyWindow(
 
1968
    WindowPtr pWin,
 
1969
    register BoxPtr box)
 
1970
{
 
1971
    register WindowPtr pSib;
 
1972
    BoxRec sboxrec;
 
1973
    register BoxPtr sbox;
 
1974
 
 
1975
    for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
 
1976
    {
 
1977
        if (pSib->mapped)
 
1978
        {
 
1979
            sbox = WindowExtents(pSib, &sboxrec);
 
1980
            if (BOXES_OVERLAP(sbox, box)
 
1981
#ifdef SHAPE
 
1982
            && ShapeOverlap (pWin, box, pSib, sbox)
 
1983
#endif
 
1984
            )
 
1985
                return(TRUE);
 
1986
        }
 
1987
    }
 
1988
    return(FALSE);
 
1989
}
 
1990
 
 
1991
/*
 
1992
 *   WhereDoIGoInTheStack() 
 
1993
 *        Given pWin and pSib and the relationshipe smode, return
 
1994
 *        the window that pWin should go ABOVE.
 
1995
 *        If a pSib is specified:
 
1996
 *            Above:  pWin is placed just above pSib
 
1997
 *            Below:  pWin is placed just below pSib
 
1998
 *            TopIf:  if pSib occludes pWin, then pWin is placed
 
1999
 *                    at the top of the stack
 
2000
 *            BottomIf:  if pWin occludes pSib, then pWin is 
 
2001
 *                       placed at the bottom of the stack
 
2002
 *            Opposite: if pSib occludes pWin, then pWin is placed at the
 
2003
 *                      top of the stack, else if pWin occludes pSib, then
 
2004
 *                      pWin is placed at the bottom of the stack
 
2005
 *
 
2006
 *        If pSib is NULL:
 
2007
 *            Above:  pWin is placed at the top of the stack
 
2008
 *            Below:  pWin is placed at the bottom of the stack
 
2009
 *            TopIf:  if any sibling occludes pWin, then pWin is placed at
 
2010
 *                    the top of the stack
 
2011
 *            BottomIf: if pWin occludes any sibline, then pWin is placed at
 
2012
 *                      the bottom of the stack
 
2013
 *            Opposite: if any sibling occludes pWin, then pWin is placed at
 
2014
 *                      the top of the stack, else if pWin occludes any
 
2015
 *                      sibling, then pWin is placed at the bottom of the stack
 
2016
 *
 
2017
 */
 
2018
 
 
2019
static WindowPtr
 
2020
WhereDoIGoInTheStack(
 
2021
    register WindowPtr pWin,
 
2022
    register WindowPtr pSib,
 
2023
    short x,
 
2024
    short y,
 
2025
    unsigned short w,
 
2026
    unsigned short h,
 
2027
    int smode)
 
2028
{
 
2029
    BoxRec box;
 
2030
    register ScreenPtr pScreen;
 
2031
    WindowPtr pHead, pFirst;
 
2032
 
 
2033
    if ((pWin == pWin->parent->firstChild) &&
 
2034
        (pWin == pWin->parent->lastChild))
 
2035
        return((WindowPtr ) NULL);
 
2036
    pHead = RealChildHead(pWin->parent);
 
2037
    pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
 
2038
    pScreen = pWin->drawable.pScreen;
 
2039
    box.x1 = x;
 
2040
    box.y1 = y;
 
2041
    box.x2 = x + (int)w;
 
2042
    box.y2 = y + (int)h;
 
2043
    switch (smode)
 
2044
    {
 
2045
      case Above:
 
2046
        if (pSib)
 
2047
           return(pSib);
 
2048
        else if (pWin == pFirst)
 
2049
            return(pWin->nextSib);
 
2050
        else
 
2051
            return(pFirst);
 
2052
      case Below:
 
2053
        if (pSib)
 
2054
            if (pSib->nextSib != pWin)
 
2055
                return(pSib->nextSib);
 
2056
            else
 
2057
                return(pWin->nextSib);
 
2058
        else
 
2059
            return NullWindow;
 
2060
      case TopIf:
 
2061
        if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
 
2062
            return(pWin->nextSib);
 
2063
        else if (pSib)
 
2064
        {
 
2065
            if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
 
2066
                (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
 
2067
                return(pFirst);
 
2068
            else
 
2069
                return(pWin->nextSib);
 
2070
        }
 
2071
        else if (AnyWindowOverlapsMe(pWin, pHead, &box))
 
2072
            return(pFirst);
 
2073
        else
 
2074
            return(pWin->nextSib);
 
2075
      case BottomIf:
 
2076
        if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
 
2077
            return(pWin->nextSib);
 
2078
        else if (pSib)
 
2079
        {
 
2080
            if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
 
2081
                (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
 
2082
                return NullWindow;
 
2083
            else
 
2084
                return(pWin->nextSib);
 
2085
        }
 
2086
        else if (IOverlapAnyWindow(pWin, &box))
 
2087
            return NullWindow;
 
2088
        else
 
2089
            return(pWin->nextSib);
 
2090
      case Opposite:
 
2091
        if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
 
2092
            return(pWin->nextSib);
 
2093
        else if (pSib)
 
2094
        {
 
2095
            if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
 
2096
            {
 
2097
                if (IsSiblingAboveMe(pWin, pSib) == Above)
 
2098
                    return(pFirst);
 
2099
                else
 
2100
                    return NullWindow;
 
2101
            }
 
2102
            else
 
2103
                return(pWin->nextSib);
 
2104
        }
 
2105
        else if (AnyWindowOverlapsMe(pWin, pHead, &box))
 
2106
        {
 
2107
            /* If I'm occluded, I can't possibly be the first child
 
2108
             * if (pWin == pWin->parent->firstChild)
 
2109
             *    return pWin->nextSib;
 
2110
             */
 
2111
            return(pFirst);
 
2112
        }
 
2113
        else if (IOverlapAnyWindow(pWin, &box))
 
2114
            return NullWindow;
 
2115
        else
 
2116
            return pWin->nextSib;
 
2117
      default:
 
2118
      {
 
2119
        ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
 
2120
        return pWin->nextSib;
 
2121
      }
 
2122
    }
 
2123
}
 
2124
 
 
2125
static void
 
2126
ReflectStackChange(
 
2127
    register WindowPtr pWin,
 
2128
    register WindowPtr pSib,
 
2129
    VTKind  kind)
 
2130
{
 
2131
/* Note that pSib might be NULL */
 
2132
 
 
2133
    Bool WasViewable = (Bool)pWin->viewable;
 
2134
    Bool anyMarked;
 
2135
    WindowPtr pFirstChange;
 
2136
#ifdef DO_SAVE_UNDERS
 
2137
    Bool        dosave = FALSE;
 
2138
#endif
 
2139
    WindowPtr  pLayerWin;
 
2140
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
2141
 
 
2142
    /* if this is a root window, can't be restacked */
 
2143
    if (!pWin->parent)
 
2144
        return;
 
2145
 
 
2146
    pFirstChange = MoveWindowInStack(pWin, pSib);
 
2147
 
 
2148
    if (WasViewable)
 
2149
    {
 
2150
        anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
 
2151
                                                      &pLayerWin);
 
2152
        if (pLayerWin != pWin) pFirstChange = pLayerWin;
 
2153
#ifdef DO_SAVE_UNDERS
 
2154
        if (DO_SAVE_UNDERS(pWin))
 
2155
        {
 
2156
            dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
 
2157
        }
 
2158
#endif /* DO_SAVE_UNDERS */
 
2159
        if (anyMarked)
 
2160
        {
 
2161
            (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
 
2162
            (*pScreen->HandleExposures)(pLayerWin->parent);
 
2163
        }
 
2164
#ifdef DO_SAVE_UNDERS
 
2165
        if (dosave)
 
2166
            (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
 
2167
#endif /* DO_SAVE_UNDERS */
 
2168
        if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
 
2169
            (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
 
2170
    }
 
2171
    if (pWin->realized)
 
2172
        WindowsRestructured ();
 
2173
}
 
2174
 
 
2175
/*****
 
2176
 * ConfigureWindow
 
2177
 *****/
 
2178
 
 
2179
int
 
2180
ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
 
2181
{
 
2182
#define RESTACK_WIN    0
 
2183
#define MOVE_WIN       1
 
2184
#define RESIZE_WIN     2
 
2185
#define REBORDER_WIN   3
 
2186
    register WindowPtr pSib = NullWindow;
 
2187
    register WindowPtr pParent = pWin->parent;
 
2188
    Window sibwid = 0;
 
2189
    Mask index2, tmask;
 
2190
    register XID *pVlist;
 
2191
    short x,   y, beforeX, beforeY;
 
2192
    unsigned short w = pWin->drawable.width,
 
2193
                   h = pWin->drawable.height,
 
2194
                   bw = pWin->borderWidth;
 
2195
    int action, smode = Above;
 
2196
#ifdef XAPPGROUP
 
2197
    ClientPtr win_owner;
 
2198
    ClientPtr ag_leader = NULL;
 
2199
#endif
 
2200
    xEvent event;
 
2201
 
 
2202
    if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
 
2203
        return(BadMatch);
 
2204
 
 
2205
    if ((mask & CWSibling) && !(mask & CWStackMode))
 
2206
        return(BadMatch);
 
2207
 
 
2208
    pVlist = vlist;
 
2209
 
 
2210
    if (pParent)
 
2211
    {
 
2212
        x = pWin->drawable.x - pParent->drawable.x - (int)bw;
 
2213
        y = pWin->drawable.y - pParent->drawable.y - (int)bw;
 
2214
    }
 
2215
    else
 
2216
    {
 
2217
        x = pWin->drawable.x;
 
2218
        y = pWin->drawable.y;
 
2219
    }
 
2220
    beforeX = x;
 
2221
    beforeY = y;
 
2222
    action = RESTACK_WIN;       
 
2223
    if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
 
2224
    {
 
2225
        GET_INT16(CWX, x);
 
2226
        GET_INT16(CWY, y);
 
2227
        action = MOVE_WIN;
 
2228
    }
 
2229
        /* or should be resized */
 
2230
    else if (mask & (CWX |  CWY | CWWidth | CWHeight))
 
2231
    {
 
2232
        GET_INT16(CWX, x);
 
2233
        GET_INT16(CWY, y);
 
2234
        GET_CARD16(CWWidth, w);
 
2235
        GET_CARD16 (CWHeight, h);
 
2236
        if (!w || !h)
 
2237
        {
 
2238
            client->errorValue = 0;
 
2239
            return BadValue;
 
2240
        }
 
2241
        action = RESIZE_WIN;
 
2242
    }
 
2243
    tmask = mask & ~ChangeMask;
 
2244
    while (tmask)
 
2245
    {
 
2246
        index2 = (Mask)lowbit (tmask);
 
2247
        tmask &= ~index2;
 
2248
        switch (index2)
 
2249
        {
 
2250
          case CWBorderWidth:
 
2251
            GET_CARD16(CWBorderWidth, bw);
 
2252
            break;
 
2253
          case CWSibling:
 
2254
            sibwid = (Window ) *pVlist;
 
2255
            pVlist++;
 
2256
            pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
 
2257
                                                RT_WINDOW, SecurityReadAccess);
 
2258
            if (!pSib)
 
2259
            {
 
2260
                client->errorValue = sibwid;
 
2261
                return(BadWindow);
 
2262
            }
 
2263
            if (pSib->parent != pParent)
 
2264
                return(BadMatch);
 
2265
            if (pSib == pWin)
 
2266
                return(BadMatch);
 
2267
            break;
 
2268
          case CWStackMode:
 
2269
            GET_CARD8(CWStackMode, smode);
 
2270
            if ((smode != TopIf) && (smode != BottomIf) &&
 
2271
                (smode != Opposite) && (smode != Above) && (smode != Below))
 
2272
            {
 
2273
                client->errorValue = smode;
 
2274
                return(BadValue);
 
2275
            }
 
2276
            break;
 
2277
          default:
 
2278
            client->errorValue = mask;
 
2279
            return(BadValue);
 
2280
        }
 
2281
    }
 
2282
        /* root really can't be reconfigured, so just return */
 
2283
    if (!pParent)
 
2284
        return Success;
 
2285
 
 
2286
        /* Figure out if the window should be moved.  Doesnt
 
2287
           make the changes to the window if event sent */
 
2288
 
 
2289
    if (mask & CWStackMode)
 
2290
        pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
 
2291
                                    pParent->drawable.y + y,
 
2292
                                    w + (bw << 1), h + (bw << 1), smode);
 
2293
    else
 
2294
        pSib = pWin->nextSib;
 
2295
 
 
2296
#ifdef XAPPGROUP
 
2297
    win_owner = clients[CLIENT_ID(pWin->drawable.id)];
 
2298
    ag_leader = XagLeader (win_owner);
 
2299
#endif
 
2300
 
 
2301
    if ((!pWin->overrideRedirect) && 
 
2302
        (RedirectSend(pParent)
 
2303
#ifdef XAPPGROUP
 
2304
        || (win_owner->appgroup && ag_leader && 
 
2305
            XagIsControlledRoot (client, pParent))
 
2306
#endif
 
2307
        ))
 
2308
    {
 
2309
        event.u.u.type = ConfigureRequest;
 
2310
        event.u.configureRequest.window = pWin->drawable.id;
 
2311
        if (mask & CWSibling)
 
2312
           event.u.configureRequest.sibling = sibwid;
 
2313
        else
 
2314
            event.u.configureRequest.sibling = None;
 
2315
        if (mask & CWStackMode)
 
2316
           event.u.u.detail = smode;
 
2317
        else
 
2318
            event.u.u.detail = Above;
 
2319
        event.u.configureRequest.x = x;
 
2320
        event.u.configureRequest.y = y;
 
2321
#ifdef PANORAMIX
 
2322
        if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
 
2323
            event.u.configureRequest.x += panoramiXdataPtr[0].x;
 
2324
            event.u.configureRequest.y += panoramiXdataPtr[0].y;
 
2325
        }
 
2326
#endif
 
2327
        event.u.configureRequest.width = w;
 
2328
        event.u.configureRequest.height = h;
 
2329
        event.u.configureRequest.borderWidth = bw;
 
2330
        event.u.configureRequest.valueMask = mask;
 
2331
#ifdef XAPPGROUP
 
2332
        /* make sure if the ag_leader maps the window it goes to the wm */
 
2333
        if (ag_leader && ag_leader != client && 
 
2334
            XagIsControlledRoot (client, pParent)) {
 
2335
            event.u.configureRequest.parent = XagId (win_owner);
 
2336
            (void) TryClientEvents (ag_leader, &event, 1,
 
2337
                                    NoEventMask, NoEventMask, NullGrab);
 
2338
            return Success;
 
2339
        }
 
2340
#endif
 
2341
        event.u.configureRequest.parent = pParent->drawable.id;
 
2342
        if (MaybeDeliverEventsToClient(pParent, &event, 1,
 
2343
                SubstructureRedirectMask, client) == 1)
 
2344
            return(Success);
 
2345
    }
 
2346
    if (action == RESIZE_WIN)
 
2347
    {
 
2348
        Bool size_change = (w != pWin->drawable.width)
 
2349
                        || (h != pWin->drawable.height);
 
2350
        if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
 
2351
        {
 
2352
            xEvent eventT;
 
2353
            eventT.u.u.type = ResizeRequest;
 
2354
            eventT.u.resizeRequest.window = pWin->drawable.id;
 
2355
            eventT.u.resizeRequest.width = w;
 
2356
            eventT.u.resizeRequest.height = h;
 
2357
            if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
 
2358
                                       ResizeRedirectMask, client) == 1)
 
2359
            {
 
2360
                /* if event is delivered, leave the actual size alone. */
 
2361
                w = pWin->drawable.width;
 
2362
                h = pWin->drawable.height;
 
2363
                size_change = FALSE;
 
2364
            }
 
2365
        }
 
2366
        if (!size_change)
 
2367
        {
 
2368
            if (mask & (CWX | CWY))
 
2369
                action = MOVE_WIN;
 
2370
            else if (mask & (CWStackMode | CWBorderWidth))
 
2371
                action = RESTACK_WIN;
 
2372
            else   /* really nothing to do */
 
2373
                return(Success) ;
 
2374
        }
 
2375
    }
 
2376
 
 
2377
    if (action == RESIZE_WIN)
 
2378
            /* we've already checked whether there's really a size change */
 
2379
            goto ActuallyDoSomething;
 
2380
    if ((mask & CWX) && (x != beforeX))
 
2381
            goto ActuallyDoSomething;
 
2382
    if ((mask & CWY) && (y != beforeY))
 
2383
            goto ActuallyDoSomething;
 
2384
    if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
 
2385
            goto ActuallyDoSomething;
 
2386
    if (mask & CWStackMode)
 
2387
    {
 
2388
#ifndef ROOTLESS
 
2389
        /* See above for why we always reorder in rootless mode. */
 
2390
        if (pWin->nextSib != pSib)
 
2391
#endif
 
2392
            goto ActuallyDoSomething;
 
2393
    }
 
2394
    return(Success);
 
2395
 
 
2396
ActuallyDoSomething:
 
2397
    if (SubStrSend(pWin, pParent))
 
2398
    {
 
2399
        event.u.u.type = ConfigureNotify;
 
2400
        event.u.configureNotify.window = pWin->drawable.id;
 
2401
        if (pSib)
 
2402
            event.u.configureNotify.aboveSibling = pSib->drawable.id;
 
2403
        else
 
2404
            event.u.configureNotify.aboveSibling = None;
 
2405
        event.u.configureNotify.x = x;
 
2406
        event.u.configureNotify.y = y;
 
2407
#ifdef PANORAMIX
 
2408
        if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
 
2409
            event.u.configureNotify.x += panoramiXdataPtr[0].x;
 
2410
            event.u.configureNotify.y += panoramiXdataPtr[0].y;
 
2411
        }
 
2412
#endif
 
2413
        event.u.configureNotify.width = w;
 
2414
        event.u.configureNotify.height = h;
 
2415
        event.u.configureNotify.borderWidth = bw;
 
2416
        event.u.configureNotify.override = pWin->overrideRedirect;
 
2417
        DeliverEvents(pWin, &event, 1, NullWindow);
 
2418
    }
 
2419
    if (mask & CWBorderWidth)
 
2420
    {
 
2421
        if (action == RESTACK_WIN)
 
2422
        {
 
2423
            action = MOVE_WIN;
 
2424
            pWin->borderWidth = bw;
 
2425
        }
 
2426
        else if ((action == MOVE_WIN) &&
 
2427
                 (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
 
2428
                 (beforeY + wBorderWidth (pWin) == y + (int)bw))
 
2429
        {
 
2430
            action = REBORDER_WIN;
 
2431
            (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
 
2432
        }
 
2433
        else
 
2434
            pWin->borderWidth = bw;
 
2435
    }
 
2436
    if (action == MOVE_WIN)
 
2437
        (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
 
2438
                   (mask & CWBorderWidth) ? VTOther : VTMove);
 
2439
    else if (action == RESIZE_WIN)
 
2440
        (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
 
2441
    else if (mask & CWStackMode)
 
2442
        ReflectStackChange(pWin, pSib, VTOther);
 
2443
 
 
2444
    if (action != RESTACK_WIN)
 
2445
        CheckCursorConfinement(pWin);
 
2446
    return(Success);
 
2447
#undef RESTACK_WIN
 
2448
#undef MOVE_WIN
 
2449
#undef RESIZE_WIN
 
2450
#undef REBORDER_WIN
 
2451
}
 
2452
 
 
2453
 
 
2454
/******
 
2455
 *
 
2456
 * CirculateWindow
 
2457
 *    For RaiseLowest, raises the lowest mapped child (if any) that is
 
2458
 *    obscured by another child to the top of the stack.  For LowerHighest,
 
2459
 *    lowers the highest mapped child (if any) that is obscuring another
 
2460
 *    child to the bottom of the stack.  Exposure processing is performed 
 
2461
 *
 
2462
 ******/
 
2463
 
 
2464
int
 
2465
CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
 
2466
{
 
2467
    register WindowPtr pWin, pHead, pFirst;
 
2468
    xEvent event;
 
2469
    BoxRec box;
 
2470
 
 
2471
    pHead = RealChildHead(pParent);
 
2472
    pFirst = pHead ? pHead->nextSib : pParent->firstChild;
 
2473
    if (direction == RaiseLowest)
 
2474
    {
 
2475
        for (pWin = pParent->lastChild;
 
2476
             (pWin != pHead) &&
 
2477
             !(pWin->mapped &&
 
2478
               AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
 
2479
             pWin = pWin->prevSib) ;
 
2480
        if (pWin == pHead)
 
2481
            return Success;
 
2482
    }
 
2483
    else
 
2484
    {
 
2485
        for (pWin = pFirst;
 
2486
             pWin &&
 
2487
             !(pWin->mapped &&
 
2488
               IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
 
2489
             pWin = pWin->nextSib) ;
 
2490
        if (!pWin)
 
2491
            return Success;
 
2492
    }
 
2493
 
 
2494
    event.u.circulate.window = pWin->drawable.id;
 
2495
    event.u.circulate.parent = pParent->drawable.id;
 
2496
    event.u.circulate.event = pParent->drawable.id;
 
2497
    if (direction == RaiseLowest)
 
2498
        event.u.circulate.place = PlaceOnTop;
 
2499
    else
 
2500
        event.u.circulate.place = PlaceOnBottom;
 
2501
 
 
2502
    if (RedirectSend(pParent))
 
2503
    {
 
2504
        event.u.u.type = CirculateRequest;
 
2505
        if (MaybeDeliverEventsToClient(pParent, &event, 1,
 
2506
                SubstructureRedirectMask, client) == 1)
 
2507
            return(Success);
 
2508
    }
 
2509
 
 
2510
    event.u.u.type = CirculateNotify;
 
2511
    DeliverEvents(pWin, &event, 1, NullWindow);
 
2512
    ReflectStackChange(pWin,
 
2513
                       (direction == RaiseLowest) ? pFirst : NullWindow,
 
2514
                       VTStack);
 
2515
 
 
2516
    return(Success);
 
2517
}
 
2518
 
 
2519
static int
 
2520
CompareWIDs(
 
2521
    WindowPtr pWin,
 
2522
    pointer   value) /* must conform to VisitWindowProcPtr */
 
2523
{
 
2524
    Window *wid = (Window *)value;
 
2525
 
 
2526
    if (pWin->drawable.id == *wid)
 
2527
       return(WT_STOPWALKING);
 
2528
    else
 
2529
       return(WT_WALKCHILDREN);
 
2530
}
 
2531
 
 
2532
/*****
 
2533
 *  ReparentWindow
 
2534
 *****/
 
2535
 
 
2536
int
 
2537
ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
 
2538
               int x, int y, ClientPtr client)
 
2539
{
 
2540
    WindowPtr pPrev, pPriorParent;
 
2541
    Bool WasMapped = (Bool)(pWin->mapped);
 
2542
    xEvent event;
 
2543
    int bw = wBorderWidth (pWin);
 
2544
    register ScreenPtr pScreen;
 
2545
 
 
2546
    pScreen = pWin->drawable.pScreen;
 
2547
    if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
 
2548
        return(BadMatch);               
 
2549
    if (!MakeWindowOptional(pWin))
 
2550
        return(BadAlloc);
 
2551
 
 
2552
    if (WasMapped)
 
2553
       UnmapWindow(pWin, FALSE);
 
2554
 
 
2555
    event.u.u.type = ReparentNotify;
 
2556
    event.u.reparent.window = pWin->drawable.id;
 
2557
    event.u.reparent.parent = pParent->drawable.id;
 
2558
    event.u.reparent.x = x;
 
2559
    event.u.reparent.y = y;
 
2560
#ifdef PANORAMIX
 
2561
    if(!noPanoramiXExtension && !pParent->parent) {
 
2562
        event.u.reparent.x += panoramiXdataPtr[0].x;
 
2563
        event.u.reparent.y += panoramiXdataPtr[0].y;
 
2564
    }
 
2565
#endif
 
2566
    event.u.reparent.override = pWin->overrideRedirect;
 
2567
    DeliverEvents(pWin, &event, 1, pParent);
 
2568
 
 
2569
    /* take out of sibling chain */
 
2570
 
 
2571
    pPriorParent = pPrev = pWin->parent;
 
2572
    if (pPrev->firstChild == pWin)
 
2573
        pPrev->firstChild = pWin->nextSib;
 
2574
    if (pPrev->lastChild == pWin)
 
2575
        pPrev->lastChild = pWin->prevSib;
 
2576
 
 
2577
    if (pWin->nextSib)
 
2578
        pWin->nextSib->prevSib = pWin->prevSib;
 
2579
    if (pWin->prevSib)
 
2580
        pWin->prevSib->nextSib = pWin->nextSib;
 
2581
 
 
2582
    /* insert at begining of pParent */
 
2583
    pWin->parent = pParent;
 
2584
    pPrev = RealChildHead(pParent);
 
2585
    if (pPrev)
 
2586
    {
 
2587
        pWin->nextSib = pPrev->nextSib;
 
2588
        if (pPrev->nextSib)
 
2589
            pPrev->nextSib->prevSib = pWin;
 
2590
        else
 
2591
            pParent->lastChild = pWin;
 
2592
        pPrev->nextSib = pWin;
 
2593
        pWin->prevSib = pPrev;
 
2594
    }
 
2595
    else
 
2596
    {
 
2597
        pWin->nextSib = pParent->firstChild;
 
2598
        pWin->prevSib = NullWindow;
 
2599
        if (pParent->firstChild)
 
2600
            pParent->firstChild->prevSib = pWin;
 
2601
        else
 
2602
            pParent->lastChild = pWin;
 
2603
        pParent->firstChild = pWin;
 
2604
    }
 
2605
 
 
2606
    pWin->origin.x = x + bw;
 
2607
    pWin->origin.y = y + bw;
 
2608
    pWin->drawable.x = x + bw + pParent->drawable.x;
 
2609
    pWin->drawable.y = y + bw + pParent->drawable.y;
 
2610
 
 
2611
    /* clip to parent */
 
2612
    SetWinSize (pWin);
 
2613
    SetBorderSize (pWin);
 
2614
 
 
2615
    if (pScreen->ReparentWindow)
 
2616
        (*pScreen->ReparentWindow)(pWin, pPriorParent);
 
2617
    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
 
2618
    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
 
2619
 
 
2620
    CheckWindowOptionalNeed(pWin);
 
2621
 
 
2622
    if (WasMapped)
 
2623
        MapWindow(pWin, client);
 
2624
    RecalculateDeliverableEvents(pWin);
 
2625
    return(Success);
 
2626
}
 
2627
 
 
2628
static void
 
2629
RealizeTree(WindowPtr pWin)
 
2630
{
 
2631
    register WindowPtr pChild;
 
2632
    RealizeWindowProcPtr Realize;
 
2633
 
 
2634
    Realize = pWin->drawable.pScreen->RealizeWindow;
 
2635
    pChild = pWin;
 
2636
    while (1)
 
2637
    {
 
2638
        if (pChild->mapped)
 
2639
        {
 
2640
            pChild->realized = TRUE;
 
2641
#ifdef DO_SAVE_UNDERS
 
2642
            if (pChild->saveUnder)
 
2643
                deltaSaveUndersViewable++;
 
2644
#endif
 
2645
            pChild->viewable = (pChild->drawable.class == InputOutput);
 
2646
            (* Realize)(pChild);
 
2647
            if (pChild->firstChild)
 
2648
            {
 
2649
                pChild = pChild->firstChild;
 
2650
                continue;
 
2651
            }
 
2652
        }
 
2653
        while (!pChild->nextSib && (pChild != pWin))
 
2654
            pChild = pChild->parent;
 
2655
        if (pChild == pWin)
 
2656
            return;
 
2657
        pChild = pChild->nextSib;
 
2658
    }
 
2659
}
 
2660
 
 
2661
/*****
 
2662
 * MapWindow
 
2663
 *    If some other client has selected SubStructureReDirect on the parent
 
2664
 *    and override-redirect is xFalse, then a MapRequest event is generated,
 
2665
 *    but the window remains unmapped.  Otherwise, the window is mapped and a
 
2666
 *    MapNotify event is generated.
 
2667
 *****/
 
2668
 
 
2669
int
 
2670
MapWindow(register WindowPtr pWin, ClientPtr client)
 
2671
{
 
2672
    register ScreenPtr pScreen;
 
2673
 
 
2674
    register WindowPtr pParent;
 
2675
#ifdef DO_SAVE_UNDERS
 
2676
    Bool        dosave = FALSE;
 
2677
#endif
 
2678
    WindowPtr  pLayerWin;
 
2679
 
 
2680
    if (pWin->mapped)
 
2681
        return(Success);
 
2682
 
 
2683
#ifdef XCSECURITY
 
2684
    /*  don't let an untrusted client map a child-of-trusted-window, InputOnly
 
2685
     *  window; too easy to steal device input
 
2686
     */
 
2687
    if ( (client->trustLevel != XSecurityClientTrusted) &&
 
2688
         (pWin->drawable.class == InputOnly) &&
 
2689
         (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
 
2690
         return Success;
 
2691
#endif  
 
2692
 
 
2693
    pScreen = pWin->drawable.pScreen;
 
2694
    if ( (pParent = pWin->parent) )
 
2695
    {
 
2696
        xEvent event;
 
2697
        Bool anyMarked;
 
2698
#ifdef XAPPGROUP
 
2699
        ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
 
2700
        ClientPtr ag_leader = XagLeader (win_owner);
 
2701
#endif
 
2702
 
 
2703
        if ((!pWin->overrideRedirect) && 
 
2704
            (RedirectSend(pParent)
 
2705
#ifdef XAPPGROUP
 
2706
            || (win_owner->appgroup && ag_leader &&
 
2707
                XagIsControlledRoot (client, pParent))
 
2708
#endif
 
2709
        ))
 
2710
        {
 
2711
            event.u.u.type = MapRequest;
 
2712
            event.u.mapRequest.window = pWin->drawable.id;
 
2713
#ifdef XAPPGROUP
 
2714
            /* make sure if the ag_leader maps the window it goes to the wm */
 
2715
            if (ag_leader && ag_leader != client &&
 
2716
                XagIsControlledRoot (client, pParent)) {
 
2717
                event.u.mapRequest.parent = XagId (win_owner);
 
2718
                (void) TryClientEvents (ag_leader, &event, 1,
 
2719
                                        NoEventMask, NoEventMask, NullGrab);
 
2720
                return Success;
 
2721
            }
 
2722
#endif
 
2723
            event.u.mapRequest.parent = pParent->drawable.id;
 
2724
 
 
2725
            if (MaybeDeliverEventsToClient(pParent, &event, 1,
 
2726
                SubstructureRedirectMask, client) == 1)
 
2727
                return(Success);
 
2728
        }
 
2729
 
 
2730
        pWin->mapped = TRUE;
 
2731
        if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin))
 
2732
        {
 
2733
            event.u.u.type = MapNotify;
 
2734
            event.u.mapNotify.window = pWin->drawable.id;
 
2735
            event.u.mapNotify.override = pWin->overrideRedirect;
 
2736
            DeliverEvents(pWin, &event, 1, NullWindow);
 
2737
        }
 
2738
 
 
2739
        if (!pParent->realized)
 
2740
            return(Success);
 
2741
        RealizeTree(pWin);
 
2742
        if (pWin->viewable)
 
2743
        {
 
2744
            anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
 
2745
                                                          &pLayerWin);
 
2746
#ifdef DO_SAVE_UNDERS
 
2747
            if (DO_SAVE_UNDERS(pWin))
 
2748
            {
 
2749
                dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
 
2750
            }
 
2751
#endif /* DO_SAVE_UNDERS */
 
2752
            if (anyMarked)
 
2753
            {
 
2754
                (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
 
2755
                (*pScreen->HandleExposures)(pLayerWin->parent);
 
2756
            }
 
2757
#ifdef DO_SAVE_UNDERS
 
2758
            if (dosave)
 
2759
                (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
 
2760
#endif /* DO_SAVE_UNDERS */
 
2761
        if (anyMarked && pScreen->PostValidateTree)
 
2762
            (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
 
2763
        }
 
2764
        WindowsRestructured ();
 
2765
    }
 
2766
    else
 
2767
    {
 
2768
        RegionRec   temp;
 
2769
 
 
2770
        pWin->mapped = TRUE;
 
2771
        pWin->realized = TRUE;     /* for roots */
 
2772
        pWin->viewable = pWin->drawable.class == InputOutput;
 
2773
        /* We SHOULD check for an error value here XXX */
 
2774
        (*pScreen->RealizeWindow)(pWin);
 
2775
        if (pScreen->ClipNotify)
 
2776
            (*pScreen->ClipNotify) (pWin, 0, 0);
 
2777
        if (pScreen->PostValidateTree)
 
2778
            (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
 
2779
        REGION_NULL(pScreen, &temp);
 
2780
        REGION_COPY(pScreen, &temp, &pWin->clipList);
 
2781
        (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
 
2782
        REGION_UNINIT(pScreen, &temp);
 
2783
    }
 
2784
 
 
2785
    return(Success);
 
2786
}
 
2787
 
 
2788
 
 
2789
/*****
 
2790
 * MapSubwindows
 
2791
 *    Performs a MapWindow all unmapped children of the window, in top
 
2792
 *    to bottom stacking order.
 
2793
 *****/
 
2794
 
 
2795
void
 
2796
MapSubwindows(register WindowPtr pParent, ClientPtr client)
 
2797
{
 
2798
    register WindowPtr  pWin;
 
2799
    WindowPtr           pFirstMapped = NullWindow;
 
2800
#ifdef DO_SAVE_UNDERS
 
2801
    WindowPtr           pFirstSaveUndered = NullWindow;
 
2802
#endif
 
2803
    register ScreenPtr  pScreen;
 
2804
    register Mask       parentRedirect;
 
2805
    register Mask       parentNotify;
 
2806
    xEvent              event;
 
2807
    Bool                anyMarked;
 
2808
#ifdef DO_SAVE_UNDERS
 
2809
    Bool        dosave = FALSE;
 
2810
#endif
 
2811
    WindowPtr           pLayerWin;
 
2812
 
 
2813
    pScreen = pParent->drawable.pScreen;
 
2814
    parentRedirect = RedirectSend(pParent);
 
2815
    parentNotify = SubSend(pParent);
 
2816
    anyMarked = FALSE;
 
2817
    for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
 
2818
    {
 
2819
        if (!pWin->mapped)
 
2820
        {
 
2821
            if (parentRedirect && !pWin->overrideRedirect)
 
2822
            {
 
2823
                event.u.u.type = MapRequest;
 
2824
                event.u.mapRequest.window = pWin->drawable.id;
 
2825
                event.u.mapRequest.parent = pParent->drawable.id;
 
2826
    
 
2827
                if (MaybeDeliverEventsToClient(pParent, &event, 1,
 
2828
                    SubstructureRedirectMask, client) == 1)
 
2829
                    continue;
 
2830
            }
 
2831
    
 
2832
            pWin->mapped = TRUE;
 
2833
            if (parentNotify || StrSend(pWin))
 
2834
            {
 
2835
                event.u.u.type = MapNotify;
 
2836
                event.u.mapNotify.window = pWin->drawable.id;
 
2837
                event.u.mapNotify.override = pWin->overrideRedirect;
 
2838
                DeliverEvents(pWin, &event, 1, NullWindow);
 
2839
            }
 
2840
    
 
2841
            if (!pFirstMapped)
 
2842
                pFirstMapped = pWin;
 
2843
            if (pParent->realized)
 
2844
            {
 
2845
                RealizeTree(pWin);
 
2846
                if (pWin->viewable)
 
2847
                {
 
2848
                    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
 
2849
                                                        (WindowPtr *)NULL);
 
2850
#ifdef DO_SAVE_UNDERS
 
2851
                    if (DO_SAVE_UNDERS(pWin))
 
2852
                    {
 
2853
                        dosave = TRUE;
 
2854
                    }
 
2855
#endif /* DO_SAVE_UNDERS */
 
2856
                }
 
2857
            }
 
2858
        }
 
2859
    }
 
2860
 
 
2861
    if (pFirstMapped)
 
2862
    {
 
2863
        pLayerWin = (*pScreen->GetLayerWindow)(pParent);
 
2864
        if (pLayerWin->parent != pParent) {
 
2865
            anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
 
2866
                                                           pLayerWin,
 
2867
                                                           (WindowPtr *)NULL);
 
2868
            pFirstMapped = pLayerWin;
 
2869
        }
 
2870
        if (anyMarked)
 
2871
        {
 
2872
#ifdef DO_SAVE_UNDERS
 
2873
            if (pLayerWin->parent != pParent)
 
2874
            {
 
2875
                if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
 
2876
                {
 
2877
                    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
 
2878
                                                         pLayerWin);
 
2879
                }
 
2880
            }
 
2881
            else if (dosave)
 
2882
            {
 
2883
                dosave = FALSE;
 
2884
                for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
 
2885
                {
 
2886
                    if (DO_SAVE_UNDERS(pWin))
 
2887
                    {
 
2888
                        dosave |= (*pScreen->ChangeSaveUnder)(pWin,
 
2889
                                                              pWin->nextSib);
 
2890
                        if (dosave && !pFirstSaveUndered)
 
2891
                            pFirstSaveUndered = pWin;
 
2892
                    }
 
2893
                }
 
2894
            }
 
2895
#endif /* DO_SAVE_UNDERS */
 
2896
            (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
 
2897
            (*pScreen->HandleExposures)(pLayerWin->parent);
 
2898
        }
 
2899
#ifdef DO_SAVE_UNDERS
 
2900
        if (dosave)
 
2901
            (*pScreen->PostChangeSaveUnder)(pLayerWin,
 
2902
                                            pFirstSaveUndered->nextSib);
 
2903
#endif /* DO_SAVE_UNDERS */
 
2904
        if (anyMarked && pScreen->PostValidateTree)
 
2905
            (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
 
2906
                                         VTMap);
 
2907
        WindowsRestructured ();
 
2908
    }
 
2909
}
 
2910
 
 
2911
static void
 
2912
UnrealizeTree(
 
2913
    WindowPtr pWin,
 
2914
    Bool fromConfigure)
 
2915
{
 
2916
    register WindowPtr pChild;
 
2917
    UnrealizeWindowProcPtr Unrealize;
 
2918
    MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
 
2919
 
 
2920
    Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
 
2921
    MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
 
2922
    pChild = pWin;
 
2923
    while (1)
 
2924
    {
 
2925
        if (pChild->realized)
 
2926
        {
 
2927
            pChild->realized = FALSE;
 
2928
            pChild->visibility = VisibilityNotViewable;
 
2929
#ifdef PANORAMIX
 
2930
            if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
 
2931
                PanoramiXRes *win;
 
2932
                win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
 
2933
                                                        XRT_WINDOW);
 
2934
                if(win)
 
2935
                   win->u.win.visibility = VisibilityNotViewable;
 
2936
            } 
 
2937
#endif
 
2938
            (* Unrealize)(pChild);
 
2939
            DeleteWindowFromAnyEvents(pChild, FALSE);
 
2940
            if (pChild->viewable)
 
2941
            {
 
2942
#ifdef DO_SAVE_UNDERS
 
2943
                if (pChild->saveUnder)
 
2944
                    deltaSaveUndersViewable--;
 
2945
#endif
 
2946
                pChild->viewable = FALSE;
 
2947
                if (pChild->backStorage)
 
2948
                    (*pChild->drawable.pScreen->SaveDoomedAreas)(
 
2949
                                            pChild, &pChild->clipList, 0, 0);
 
2950
                (* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
 
2951
                pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
 
2952
            }
 
2953
            if (pChild->firstChild)
 
2954
            {
 
2955
                pChild = pChild->firstChild;
 
2956
                continue;
 
2957
            }
 
2958
        }
 
2959
        while (!pChild->nextSib && (pChild != pWin))
 
2960
            pChild = pChild->parent;
 
2961
        if (pChild == pWin)
 
2962
            return;
 
2963
        pChild = pChild->nextSib;
 
2964
    }
 
2965
}
 
2966
 
 
2967
/*****
 
2968
 * UnmapWindow
 
2969
 *    If the window is already unmapped, this request has no effect.
 
2970
 *    Otherwise, the window is unmapped and an UnMapNotify event is
 
2971
 *    generated.  Cannot unmap a root window.
 
2972
 *****/
 
2973
 
 
2974
int
 
2975
UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
 
2976
{
 
2977
    register WindowPtr pParent;
 
2978
    xEvent event;
 
2979
    Bool wasRealized = (Bool)pWin->realized;
 
2980
    Bool wasViewable = (Bool)pWin->viewable;
 
2981
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
2982
    WindowPtr pLayerWin = pWin;
 
2983
 
 
2984
    if ((!pWin->mapped) || (!(pParent = pWin->parent)))
 
2985
        return(Success);
 
2986
    if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin))
 
2987
    {
 
2988
        event.u.u.type = UnmapNotify;
 
2989
        event.u.unmapNotify.window = pWin->drawable.id;
 
2990
        event.u.unmapNotify.fromConfigure = fromConfigure;
 
2991
        DeliverEvents(pWin, &event, 1, NullWindow);
 
2992
    }
 
2993
    if (wasViewable && !fromConfigure)
 
2994
    {
 
2995
        pWin->valdata = UnmapValData;
 
2996
        (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
 
2997
        (*pScreen->MarkWindow)(pLayerWin->parent);
 
2998
    }
 
2999
    pWin->mapped = FALSE;
 
3000
    if (wasRealized)
 
3001
        UnrealizeTree(pWin, fromConfigure);
 
3002
    if (wasViewable)
 
3003
    {
 
3004
        if (!fromConfigure)
 
3005
        {
 
3006
            (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
 
3007
            (*pScreen->HandleExposures)(pLayerWin->parent);
 
3008
        }
 
3009
#ifdef DO_SAVE_UNDERS
 
3010
        if (DO_SAVE_UNDERS(pWin))
 
3011
        {
 
3012
            if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
 
3013
            {
 
3014
                (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
 
3015
            }
 
3016
        }
 
3017
        pWin->DIXsaveUnder = FALSE;
 
3018
#endif /* DO_SAVE_UNDERS */
 
3019
        if (!fromConfigure && pScreen->PostValidateTree)
 
3020
            (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
 
3021
    }
 
3022
    if (wasRealized && !fromConfigure)
 
3023
        WindowsRestructured ();
 
3024
    return(Success);
 
3025
}
 
3026
 
 
3027
/*****
 
3028
 * UnmapSubwindows
 
3029
 *    Performs an UnmapWindow request with the specified mode on all mapped
 
3030
 *    children of the window, in bottom to top stacking order.
 
3031
 *****/
 
3032
 
 
3033
void
 
3034
UnmapSubwindows(register WindowPtr pWin)
 
3035
{
 
3036
    register WindowPtr pChild, pHead;
 
3037
    xEvent event;
 
3038
    Bool wasRealized = (Bool)pWin->realized;
 
3039
    Bool wasViewable = (Bool)pWin->viewable;
 
3040
    Bool anyMarked = FALSE;
 
3041
    Mask parentNotify;
 
3042
    WindowPtr pLayerWin = NULL;
 
3043
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
3044
 
 
3045
    if (!pWin->firstChild)
 
3046
        return;
 
3047
    parentNotify = SubSend(pWin);
 
3048
    pHead = RealChildHead(pWin);
 
3049
 
 
3050
    if (wasViewable)
 
3051
        pLayerWin = (*pScreen->GetLayerWindow)(pWin);
 
3052
 
 
3053
    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
 
3054
    {
 
3055
        if (pChild->mapped)
 
3056
        {
 
3057
            if (parentNotify || StrSend(pChild))
 
3058
            {
 
3059
                event.u.u.type = UnmapNotify;
 
3060
                event.u.unmapNotify.window = pChild->drawable.id;
 
3061
                event.u.unmapNotify.fromConfigure = xFalse;
 
3062
                DeliverEvents(pChild, &event, 1, NullWindow);
 
3063
            }
 
3064
            if (pChild->viewable)
 
3065
            {
 
3066
                pChild->valdata = UnmapValData;
 
3067
                anyMarked = TRUE;
 
3068
            }
 
3069
            pChild->mapped = FALSE;
 
3070
            if (pChild->realized)
 
3071
                UnrealizeTree(pChild, FALSE);
 
3072
            if (wasViewable)
 
3073
            {
 
3074
#ifdef DO_SAVE_UNDERS
 
3075
                pChild->DIXsaveUnder = FALSE;
 
3076
#endif /* DO_SAVE_UNDERS */
 
3077
                if (pChild->backStorage)
 
3078
                    (*pScreen->SaveDoomedAreas)(
 
3079
                                            pChild, &pChild->clipList, 0, 0);
 
3080
            }
 
3081
        }
 
3082
    }
 
3083
    if (wasViewable)
 
3084
    {
 
3085
        if (anyMarked)
 
3086
        {
 
3087
            if (pLayerWin->parent == pWin)
 
3088
                (*pScreen->MarkWindow)(pWin);
 
3089
            else
 
3090
            {
 
3091
                WindowPtr ptmp;
 
3092
                (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
 
3093
                                                  (WindowPtr *)NULL);
 
3094
                (*pScreen->MarkWindow)(pLayerWin->parent);
 
3095
                
 
3096
                /* Windows between pWin and pLayerWin may not have been marked */
 
3097
                ptmp = pWin;
 
3098
 
 
3099
                while (ptmp != pLayerWin->parent)
 
3100
                {
 
3101
                    (*pScreen->MarkWindow)(ptmp);
 
3102
                    ptmp = ptmp->parent;
 
3103
                }
 
3104
                pHead = pWin->firstChild;
 
3105
            }
 
3106
            (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
 
3107
            (*pScreen->HandleExposures)(pLayerWin->parent);
 
3108
        }
 
3109
#ifdef DO_SAVE_UNDERS
 
3110
        if (DO_SAVE_UNDERS(pWin))
 
3111
        {
 
3112
            if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
 
3113
                (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
 
3114
        }
 
3115
#endif /* DO_SAVE_UNDERS */
 
3116
        if (anyMarked && pScreen->PostValidateTree)
 
3117
            (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
 
3118
    }
 
3119
    if (wasRealized)
 
3120
        WindowsRestructured ();
 
3121
}
 
3122
 
 
3123
 
 
3124
void
 
3125
HandleSaveSet(register ClientPtr client)
 
3126
{
 
3127
    register WindowPtr pParent, pWin;
 
3128
    register int j;
 
3129
 
 
3130
    for (j=0; j<client->numSaved; j++)
 
3131
    {
 
3132
        pWin = SaveSetWindow(client->saveSet[j]);
 
3133
#ifdef XFIXES
 
3134
        if (SaveSetToRoot(client->saveSet[j]))
 
3135
            pParent = WindowTable[pWin->drawable.pScreen->myNum];
 
3136
        else
 
3137
#endif
 
3138
        {
 
3139
            pParent = pWin->parent;
 
3140
            while (pParent && (wClient (pParent) == client))
 
3141
                pParent = pParent->parent;
 
3142
        }
 
3143
        if (pParent)
 
3144
        {
 
3145
            if (pParent != pWin->parent)
 
3146
            {
 
3147
                ReparentWindow(pWin, pParent,
 
3148
                               pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
 
3149
                               pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
 
3150
                               client);
 
3151
                if(!pWin->realized && pWin->mapped)
 
3152
                    pWin->mapped = FALSE;
 
3153
            }
 
3154
#ifdef XFIXES
 
3155
            if (SaveSetRemap (client->saveSet[j]))
 
3156
#endif
 
3157
                MapWindow(pWin, client);
 
3158
        }
 
3159
    }
 
3160
    xfree(client->saveSet);
 
3161
    client->numSaved = 0;
 
3162
    client->saveSet = (SaveSetElt *)NULL;
 
3163
}
 
3164
 
 
3165
/**
 
3166
 *
 
3167
 *  \param x,y  in root
 
3168
 *  \param box  "return" value
 
3169
 */
 
3170
Bool
 
3171
VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
 
3172
{
 
3173
    if (!pWin->realized)
 
3174
        return (FALSE);
 
3175
    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
 
3176
        return(TRUE);
 
3177
    return(FALSE);
 
3178
}
 
3179
 
 
3180
/**
 
3181
 *
 
3182
 * \param x,y  in root
 
3183
 */
 
3184
Bool
 
3185
PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
 
3186
{
 
3187
    BoxRec box;
 
3188
 
 
3189
    if (!pWin->realized)
 
3190
        return (FALSE);
 
3191
    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
 
3192
                                                  x, y, &box)
 
3193
        && (!wInputShape(pWin) ||
 
3194
            POINT_IN_REGION(pWin->drawable.pScreen,
 
3195
                            wInputShape(pWin),
 
3196
                            x - pWin->drawable.x, 
 
3197
                            y - pWin->drawable.y, &box)))
 
3198
        return(TRUE);
 
3199
    return(FALSE);
 
3200
}
 
3201
 
 
3202
 
 
3203
RegionPtr
 
3204
NotClippedByChildren(register WindowPtr pWin)
 
3205
{
 
3206
    register ScreenPtr pScreen;
 
3207
    RegionPtr pReg;
 
3208
 
 
3209
    pScreen = pWin->drawable.pScreen;
 
3210
    pReg = REGION_CREATE(pScreen, NullBox, 1);
 
3211
    if (pWin->parent ||
 
3212
        screenIsSaved != SCREEN_SAVER_ON ||
 
3213
        !HasSaverWindow (pWin->drawable.pScreen->myNum))
 
3214
    {
 
3215
        REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
 
3216
    }
 
3217
    return(pReg);
 
3218
}
 
3219
 
 
3220
void
 
3221
SendVisibilityNotify(WindowPtr pWin)
 
3222
{
 
3223
    xEvent event;
 
3224
#ifndef NO_XINERAMA_PORT
 
3225
    unsigned int visibility = pWin->visibility;
 
3226
#endif
 
3227
#ifdef PANORAMIX
 
3228
    /* This is not quite correct yet, but it's close */
 
3229
    if(!noPanoramiXExtension) {
 
3230
        PanoramiXRes *win;
 
3231
        WindowPtr pWin2;
 
3232
        int i, Scrnum;
 
3233
 
 
3234
        Scrnum = pWin->drawable.pScreen->myNum;
 
3235
        
 
3236
        win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
 
3237
 
 
3238
        if(!win || (win->u.win.visibility == visibility))
 
3239
            return;
 
3240
 
 
3241
        switch(visibility) {
 
3242
        case VisibilityUnobscured:
 
3243
            for(i = 0; i < PanoramiXNumScreens; i++) {
 
3244
                if(i == Scrnum) continue;
 
3245
 
 
3246
                pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
 
3247
 
 
3248
                if (pWin2) {
 
3249
                    if(pWin2->visibility == VisibilityPartiallyObscured)
 
3250
                        return;
 
3251
 
 
3252
                    if(!i) pWin = pWin2;
 
3253
                }
 
3254
            }
 
3255
            break;
 
3256
        case VisibilityPartiallyObscured:
 
3257
            if(Scrnum) {
 
3258
                pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
 
3259
                if (pWin2) pWin = pWin2;
 
3260
            }
 
3261
            break;
 
3262
        case VisibilityFullyObscured:
 
3263
            for(i = 0; i < PanoramiXNumScreens; i++) {
 
3264
                if(i == Scrnum) continue;
 
3265
 
 
3266
                pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
 
3267
                
 
3268
                if (pWin2) {
 
3269
                    if(pWin2->visibility != VisibilityFullyObscured)
 
3270
                        return;
 
3271
 
 
3272
                    if(!i) pWin = pWin2;
 
3273
                }
 
3274
            }
 
3275
            break;
 
3276
        }
 
3277
        
 
3278
        win->u.win.visibility = visibility;
 
3279
    }
 
3280
#endif
 
3281
 
 
3282
    event.u.u.type = VisibilityNotify;
 
3283
    event.u.visibility.window = pWin->drawable.id;
 
3284
    event.u.visibility.state = visibility;
 
3285
    DeliverEvents(pWin, &event, 1, NullWindow);
 
3286
}
 
3287
 
 
3288
static WindowPtr windowDisableMapUnmapEvents;
 
3289
 
 
3290
void
 
3291
DisableMapUnmapEvents(WindowPtr pWin)
 
3292
{
 
3293
    assert (windowDisableMapUnmapEvents == NULL);
 
3294
    
 
3295
    windowDisableMapUnmapEvents = pWin;
 
3296
}
 
3297
 
 
3298
void
 
3299
EnableMapUnmapEvents(WindowPtr pWin)
 
3300
{
 
3301
    assert (windowDisableMapUnmapEvents != NULL);
 
3302
 
 
3303
    windowDisableMapUnmapEvents = NULL;
 
3304
}
 
3305
 
 
3306
Bool
 
3307
MapUnmapEventsEnabled(WindowPtr pWin)
 
3308
{
 
3309
    return pWin != windowDisableMapUnmapEvents;
 
3310
}
 
3311
 
 
3312
#define RANDOM_WIDTH 32
 
3313
 
 
3314
#ifndef NOLOGOHACK
 
3315
static void DrawLogo(
 
3316
    WindowPtr pWin
 
3317
);
 
3318
#endif
 
3319
 
 
3320
void
 
3321
SaveScreens(int on, int mode)
 
3322
{
 
3323
    int i;
 
3324
    int what;
 
3325
    int type;
 
3326
 
 
3327
    if (on == SCREEN_SAVER_FORCER)
 
3328
    {
 
3329
        UpdateCurrentTimeIf();
 
3330
        lastDeviceEventTime = currentTime;
 
3331
        if (mode == ScreenSaverReset)
 
3332
            what = SCREEN_SAVER_OFF;
 
3333
        else
 
3334
            what = SCREEN_SAVER_ON;
 
3335
        type = what;
 
3336
    }
 
3337
    else
 
3338
    {
 
3339
        what = on;
 
3340
        type = what;
 
3341
        if (what == screenIsSaved)
 
3342
            type = SCREEN_SAVER_CYCLE;
 
3343
    }
 
3344
    for (i = 0; i < screenInfo.numScreens; i++)
 
3345
    {
 
3346
        if (on == SCREEN_SAVER_FORCER)
 
3347
           (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
 
3348
        if (savedScreenInfo[i].ExternalScreenSaver)
 
3349
        {
 
3350
            if ((*savedScreenInfo[i].ExternalScreenSaver)
 
3351
                (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
 
3352
                continue;
 
3353
        }
 
3354
        if (type == screenIsSaved)
 
3355
            continue;
 
3356
        switch (type) {
 
3357
        case SCREEN_SAVER_OFF:
 
3358
            if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
 
3359
            {
 
3360
               (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
 
3361
                                                      what);
 
3362
            }
 
3363
            else if (HasSaverWindow (i))
 
3364
            {
 
3365
                savedScreenInfo[i].pWindow = NullWindow;
 
3366
                FreeResource(savedScreenInfo[i].wid, RT_NONE);
 
3367
            }
 
3368
            break;
 
3369
        case SCREEN_SAVER_CYCLE:
 
3370
            if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
 
3371
            {
 
3372
                WindowPtr pWin = savedScreenInfo[i].pWindow;
 
3373
                /* make it look like screen saver is off, so that
 
3374
                 * NotClippedByChildren will compute a clip list
 
3375
                 * for the root window, so miPaintWindow works
 
3376
                 */
 
3377
                screenIsSaved = SCREEN_SAVER_OFF;
 
3378
#ifndef NOLOGOHACK
 
3379
                if (logoScreenSaver)
 
3380
                    (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
 
3381
#endif
 
3382
                (*pWin->drawable.pScreen->MoveWindow)(pWin,
 
3383
                           (short)(-(rand() % RANDOM_WIDTH)),
 
3384
                           (short)(-(rand() % RANDOM_WIDTH)),
 
3385
                           pWin->nextSib, VTMove);
 
3386
#ifndef NOLOGOHACK
 
3387
                if (logoScreenSaver)
 
3388
                    DrawLogo(pWin);
 
3389
#endif
 
3390
                screenIsSaved = SCREEN_SAVER_ON;
 
3391
            }
 
3392
            /*
 
3393
             * Call the DDX saver in case it wants to do something
 
3394
             * at cycle time
 
3395
             */
 
3396
            else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
 
3397
            {
 
3398
                (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
 
3399
                                                       type);
 
3400
            }
 
3401
            break;
 
3402
        case SCREEN_SAVER_ON:
 
3403
            if (ScreenSaverBlanking != DontPreferBlanking)
 
3404
            {
 
3405
                if ((* screenInfo.screens[i]->SaveScreen)
 
3406
                   (screenInfo.screens[i], what))
 
3407
                {
 
3408
                   savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
 
3409
                   continue;
 
3410
                }
 
3411
                if ((ScreenSaverAllowExposures != DontAllowExposures) &&
 
3412
                    TileScreenSaver(i, SCREEN_IS_BLACK))
 
3413
                {
 
3414
                    savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
 
3415
                    continue;
 
3416
                }
 
3417
            }
 
3418
            if ((ScreenSaverAllowExposures != DontAllowExposures) &&
 
3419
                TileScreenSaver(i, SCREEN_IS_TILED))
 
3420
            {
 
3421
                savedScreenInfo[i].blanked = SCREEN_IS_TILED;
 
3422
            }
 
3423
            else
 
3424
                savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
 
3425
            break;
 
3426
        }
 
3427
    }
 
3428
    screenIsSaved = what;
 
3429
    if (mode == ScreenSaverReset)
 
3430
       SetScreenSaverTimer();
 
3431
}
 
3432
 
 
3433
static Bool
 
3434
TileScreenSaver(int i, int kind)
 
3435
{
 
3436
    int j;
 
3437
    int result;
 
3438
    XID attributes[3];
 
3439
    Mask mask;
 
3440
    WindowPtr pWin;             
 
3441
    CursorMetricRec cm;
 
3442
    unsigned char *srcbits, *mskbits;
 
3443
    CursorPtr cursor;
 
3444
    XID cursorID = 0;
 
3445
    int attri;
 
3446
 
 
3447
    mask = 0;
 
3448
    attri = 0;
 
3449
    switch (kind) {
 
3450
    case SCREEN_IS_TILED:
 
3451
        switch (WindowTable[i]->backgroundState) {
 
3452
        case BackgroundPixel:
 
3453
            attributes[attri++] = WindowTable[i]->background.pixel;
 
3454
            mask |= CWBackPixel;
 
3455
            break;
 
3456
        case BackgroundPixmap:
 
3457
            attributes[attri++] = None;
 
3458
            mask |= CWBackPixmap;
 
3459
            break;
 
3460
        default:
 
3461
            break;
 
3462
        }
 
3463
        break;
 
3464
    case SCREEN_IS_BLACK:
 
3465
        attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
 
3466
        mask |= CWBackPixel;
 
3467
        break;
 
3468
    }
 
3469
    mask |= CWOverrideRedirect;
 
3470
    attributes[attri++] = xTrue;
 
3471
 
 
3472
    /*
 
3473
     * create a blank cursor
 
3474
     */
 
3475
 
 
3476
    cm.width=16;
 
3477
    cm.height=16;
 
3478
    cm.xhot=8;
 
3479
    cm.yhot=8;
 
3480
    srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
 
3481
    mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
 
3482
    if (!srcbits || !mskbits)
 
3483
    {
 
3484
        xfree(srcbits);
 
3485
        xfree(mskbits);
 
3486
        cursor = 0;
 
3487
    }
 
3488
    else
 
3489
    {
 
3490
        for (j=0; j<BitmapBytePad(32)*16; j++)
 
3491
            srcbits[j] = mskbits[j] = 0x0;
 
3492
        cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
 
3493
        if (cursor)
 
3494
        {
 
3495
            cursorID = FakeClientID(0);
 
3496
            if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
 
3497
            {
 
3498
                attributes[attri] = cursorID;
 
3499
                mask |= CWCursor;
 
3500
            }
 
3501
            else
 
3502
                cursor = 0;
 
3503
        }
 
3504
        else
 
3505
        {
 
3506
            xfree (srcbits);
 
3507
            xfree (mskbits);
 
3508
        }
 
3509
    }
 
3510
 
 
3511
    pWin = savedScreenInfo[i].pWindow =
 
3512
         CreateWindow(savedScreenInfo[i].wid,
 
3513
              WindowTable[i],
 
3514
              -RANDOM_WIDTH, -RANDOM_WIDTH,
 
3515
              (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
 
3516
              (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
 
3517
              0, InputOutput, mask, attributes, 0, serverClient,
 
3518
              wVisual (WindowTable[i]), &result);
 
3519
 
 
3520
    if (cursor)
 
3521
        FreeResource (cursorID, RT_NONE);
 
3522
 
 
3523
    if (!pWin)
 
3524
        return FALSE;
 
3525
 
 
3526
    if (!AddResource(pWin->drawable.id, RT_WINDOW,
 
3527
                     (pointer)savedScreenInfo[i].pWindow))
 
3528
        return FALSE;
 
3529
 
 
3530
    if (mask & CWBackPixmap)
 
3531
    {
 
3532
        MakeRootTile (pWin);
 
3533
        (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
 
3534
    }
 
3535
    MapWindow(pWin, serverClient);
 
3536
#ifndef NOLOGOHACK
 
3537
    if (kind == SCREEN_IS_TILED && logoScreenSaver)
 
3538
        DrawLogo(pWin);
 
3539
#endif
 
3540
    return TRUE;
 
3541
}
 
3542
 
 
3543
/*
 
3544
 * FindWindowWithOptional
 
3545
 *
 
3546
 * search ancestors of the given window for an entry containing
 
3547
 * a WindowOpt structure.  Assumptions:  some parent will
 
3548
 * contain the structure.
 
3549
 */
 
3550
 
 
3551
WindowPtr
 
3552
FindWindowWithOptional (register WindowPtr w)
 
3553
{
 
3554
    do
 
3555
        w = w->parent;
 
3556
    while (!w->optional);
 
3557
    return w;
 
3558
}
 
3559
 
 
3560
/*
 
3561
 * CheckWindowOptionalNeed
 
3562
 *
 
3563
 * check each optional entry in the given window to see if
 
3564
 * the value is satisfied by the default rules.  If so,
 
3565
 * release the optional record
 
3566
 */
 
3567
 
 
3568
void
 
3569
CheckWindowOptionalNeed (register WindowPtr w)
 
3570
{
 
3571
    register WindowOptPtr optional;
 
3572
    register WindowOptPtr parentOptional;
 
3573
 
 
3574
    if (!w->parent)
 
3575
        return;
 
3576
    optional = w->optional;
 
3577
    if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
 
3578
        return;
 
3579
    if (optional->otherEventMasks != 0)
 
3580
        return;
 
3581
    if (optional->otherClients != NULL)
 
3582
        return;
 
3583
    if (optional->passiveGrabs != NULL)
 
3584
        return;
 
3585
    if (optional->userProps != NULL)
 
3586
        return;
 
3587
    if (optional->backingBitPlanes != ~0L)
 
3588
        return;
 
3589
    if (optional->backingPixel != 0)
 
3590
        return;
 
3591
#ifdef SHAPE
 
3592
    if (optional->boundingShape != NULL)
 
3593
        return;
 
3594
    if (optional->clipShape != NULL)
 
3595
        return;
 
3596
    if (optional->inputShape != NULL)
 
3597
        return;
 
3598
#endif
 
3599
#ifdef XINPUT
 
3600
    if (optional->inputMasks != NULL)
 
3601
        return;
 
3602
#endif
 
3603
    parentOptional = FindWindowWithOptional(w)->optional;
 
3604
    if (optional->visual != parentOptional->visual)
 
3605
        return;
 
3606
    if (optional->cursor != None &&
 
3607
        (optional->cursor != parentOptional->cursor ||
 
3608
         w->parent->cursorIsNone))
 
3609
        return;
 
3610
    if (optional->colormap != parentOptional->colormap)
 
3611
        return;
 
3612
    DisposeWindowOptional (w);
 
3613
}
 
3614
 
 
3615
/*
 
3616
 * MakeWindowOptional
 
3617
 *
 
3618
 * create an optional record and initialize it with the default
 
3619
 * values.
 
3620
 */
 
3621
 
 
3622
Bool
 
3623
MakeWindowOptional (register WindowPtr pWin)
 
3624
{
 
3625
    register WindowOptPtr optional;
 
3626
    register WindowOptPtr parentOptional;
 
3627
 
 
3628
    if (pWin->optional)
 
3629
        return TRUE;
 
3630
    optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
 
3631
    if (!optional)
 
3632
        return FALSE;
 
3633
    optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
 
3634
    optional->otherEventMasks = 0;
 
3635
    optional->otherClients = NULL;
 
3636
    optional->passiveGrabs = NULL;
 
3637
    optional->userProps = NULL;
 
3638
    optional->backingBitPlanes = ~0L;
 
3639
    optional->backingPixel = 0;
 
3640
#ifdef SHAPE
 
3641
    optional->boundingShape = NULL;
 
3642
    optional->clipShape = NULL;
 
3643
    optional->inputShape = NULL;
 
3644
#endif
 
3645
#ifdef XINPUT
 
3646
    optional->inputMasks = NULL;
 
3647
#endif
 
3648
    parentOptional = FindWindowWithOptional(pWin)->optional;
 
3649
    optional->visual = parentOptional->visual;
 
3650
    if (!pWin->cursorIsNone)
 
3651
    {
 
3652
        optional->cursor = parentOptional->cursor;
 
3653
        optional->cursor->refcnt++;
 
3654
    }
 
3655
    else
 
3656
    {
 
3657
        optional->cursor = None;
 
3658
    }
 
3659
    optional->colormap = parentOptional->colormap;
 
3660
    pWin->optional = optional;
 
3661
    return TRUE;
 
3662
}
 
3663
 
 
3664
void
 
3665
DisposeWindowOptional (register WindowPtr pWin)
 
3666
{
 
3667
    if (!pWin->optional)
 
3668
        return;
 
3669
    /*
 
3670
     * everything is peachy.  Delete the optional record
 
3671
     * and clean up
 
3672
     */
 
3673
    /*
 
3674
     * TOG changed this code to:
 
3675
     *
 
3676
     *      if (pWin->cursorIsNone == FALSE)
 
3677
     *          FreeCursor (pWin->optional->cursor, (Cursor)0);
 
3678
     *      pWin->cursorIsNone = TRUE;
 
3679
     *
 
3680
     * This is blatently wrong; windows without optionals can have
 
3681
     * two different cursor values, either None or sharing their
 
3682
     * parents cursor.  This difference is controlled by the
 
3683
     * cursorIsNone value; when TRUE, the window has no cursor,
 
3684
     * when false, it shares its cursor with its parent; TOG
 
3685
     * made it impossible for a window to have a cursor without
 
3686
     * an optional record.
 
3687
     */
 
3688
    if (pWin->optional->cursor)
 
3689
    {
 
3690
        FreeCursor (pWin->optional->cursor, (Cursor)0);
 
3691
        pWin->cursorIsNone = FALSE;
 
3692
    }
 
3693
    else
 
3694
        pWin->cursorIsNone = TRUE;
 
3695
    xfree (pWin->optional);
 
3696
    pWin->optional = NULL;
 
3697
}
 
3698
 
 
3699
#ifndef NOLOGOHACK
 
3700
static void
 
3701
DrawLogo(WindowPtr pWin)
 
3702
{
 
3703
    DrawablePtr pDraw;
 
3704
    ScreenPtr pScreen;
 
3705
    int x, y;
 
3706
    unsigned int width, height, size;
 
3707
    GC *pGC;
 
3708
    int thin, gap, d31;
 
3709
    DDXPointRec poly[4];
 
3710
    ChangeGCVal fore[2], back[2];
 
3711
    xrgb rgb[2];
 
3712
    BITS32 fmask, bmask;
 
3713
    ColormapPtr cmap;
 
3714
 
 
3715
    pDraw = (DrawablePtr)pWin;
 
3716
    pScreen = pDraw->pScreen;
 
3717
    x = -pWin->origin.x;
 
3718
    y = -pWin->origin.y;
 
3719
    width = pScreen->width;
 
3720
    height = pScreen->height;
 
3721
    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
 
3722
    if (!pGC)
 
3723
        return;
 
3724
 
 
3725
    if ((rand() % 100) <= 17) /* make the probability for white fairly low */
 
3726
        fore[0].val = pScreen->whitePixel;
 
3727
    else
 
3728
        fore[0].val = pScreen->blackPixel;
 
3729
    if ((pWin->backgroundState == BackgroundPixel) &&
 
3730
        (cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
 
3731
        Pixel querypixels[2];
 
3732
 
 
3733
        querypixels[0] = fore[0].val;
 
3734
        querypixels[1] = pWin->background.pixel;
 
3735
        QueryColors(cmap, 2, querypixels, rgb);
 
3736
        if ((rgb[0].red == rgb[1].red) &&
 
3737
            (rgb[0].green == rgb[1].green) &&
 
3738
            (rgb[0].blue == rgb[1].blue)) {
 
3739
            if (fore[0].val == pScreen->blackPixel)
 
3740
                fore[0].val = pScreen->whitePixel;
 
3741
            else
 
3742
                fore[0].val = pScreen->blackPixel;
 
3743
        }
 
3744
    }
 
3745
    fore[1].val = FillSolid;
 
3746
    fmask = GCForeground|GCFillStyle;
 
3747
    if (pWin->backgroundState == BackgroundPixel) {
 
3748
        back[0].val = pWin->background.pixel;
 
3749
        back[1].val = FillSolid;
 
3750
        bmask = GCForeground|GCFillStyle;
 
3751
    } else {
 
3752
        back[0].val = 0;
 
3753
        back[1].val = 0;
 
3754
        dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
 
3755
                    NULL, back);
 
3756
        back[0].val = FillTiled;
 
3757
        back[1].ptr = pWin->background.pixmap;
 
3758
        bmask = GCFillStyle|GCTile;
 
3759
    }
 
3760
 
 
3761
    /* should be the same as the reference function XmuDrawLogo() */
 
3762
 
 
3763
    size = width;
 
3764
    if (height < width)
 
3765
         size = height;
 
3766
    size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
 
3767
    size &= ~1;
 
3768
    x += rand() % (width - size);
 
3769
    y += rand() % (height - size);
 
3770
 
 
3771
/*
 
3772
 * Draw what will be the thin strokes.
 
3773
 *
 
3774
 *           -----
 
3775
 *          /    /
 
3776
 *         /    /
 
3777
 *        /    /
 
3778
 *       /    /
 
3779
 *      /____/
 
3780
 *           d
 
3781
 *
 
3782
 * Point d is 9/44 (~1/5) of the way across.
 
3783
 */
 
3784
 
 
3785
    thin = (size / 11);
 
3786
    if (thin < 1) thin = 1;
 
3787
    gap = (thin+3) / 4;
 
3788
    d31 = thin + thin + gap;
 
3789
    poly[0].x = x + size;              poly[0].y = y;
 
3790
    poly[1].x = x + size-d31;          poly[1].y = y;
 
3791
    poly[2].x = x + 0;                 poly[2].y = y + size;
 
3792
    poly[3].x = x + d31;               poly[3].y = y + size;
 
3793
    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
 
3794
    ValidateGC(pDraw, pGC);
 
3795
    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
 
3796
 
 
3797
/*
 
3798
 * Erase area not needed for lower thin stroke.
 
3799
 *
 
3800
 *           ------
 
3801
 *          /     /
 
3802
 *         /  __ /
 
3803
 *        /  /  /
 
3804
 *       /  /  /
 
3805
 *      /__/__/
 
3806
 */
 
3807
 
 
3808
    poly[0].x = x + d31/2;                       poly[0].y = y + size;
 
3809
    poly[1].x = x + size / 2;                    poly[1].y = y + size/2;
 
3810
    poly[2].x = x + (size/2)+(d31-(d31/2));      poly[2].y = y + size/2;
 
3811
    poly[3].x = x + d31;                         poly[3].y = y + size;
 
3812
    dixChangeGC(NullClient, pGC, bmask, NULL, back);
 
3813
    ValidateGC(pDraw, pGC);
 
3814
    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
 
3815
 
 
3816
/*
 
3817
 * Erase area not needed for upper thin stroke.
 
3818
 *
 
3819
 *           ------
 
3820
 *          /  /  /
 
3821
 *         /--/  /
 
3822
 *        /     /
 
3823
 *       /     /
 
3824
 *      /_____/
 
3825
 */
 
3826
 
 
3827
    poly[0].x = x + size - d31/2;                poly[0].y = y;
 
3828
    poly[1].x = x + size / 2;                    poly[1].y = y + size/2;
 
3829
    poly[2].x = x + (size/2)-(d31-(d31/2));      poly[2].y = y + size/2;
 
3830
    poly[3].x = x + size - d31;                  poly[3].y = y;
 
3831
    ValidateGC(pDraw, pGC);
 
3832
    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
 
3833
 
 
3834
/*
 
3835
 * Draw thick stroke.
 
3836
 * Point b is 1/4 of the way across.
 
3837
 *
 
3838
 *      b
 
3839
 * -----
 
3840
 * \    \
 
3841
 *  \    \
 
3842
 *   \    \
 
3843
 *    \    \
 
3844
 *     \____\
 
3845
 */
 
3846
 
 
3847
    poly[0].x = x;                     poly[0].y = y;
 
3848
    poly[1].x = x + size/4;            poly[1].y = y;
 
3849
    poly[2].x = x + size;              poly[2].y = y + size;
 
3850
    poly[3].x = x + size - size/4;     poly[3].y = y + size;
 
3851
    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
 
3852
    ValidateGC(pDraw, pGC);
 
3853
    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
 
3854
 
 
3855
/*
 
3856
 * Erase to create gap.
 
3857
 *
 
3858
 *          /
 
3859
 *         /
 
3860
 *        /
 
3861
 *       /
 
3862
 *      /
 
3863
 */
 
3864
 
 
3865
    poly[0].x = x + size- thin;       poly[0].y = y;
 
3866
    poly[1].x = x + size-( thin+gap);  poly[1].y = y;
 
3867
    poly[2].x = x + thin;             poly[2].y = y + size;
 
3868
    poly[3].x = x + thin + gap;       poly[3].y = y + size;
 
3869
    dixChangeGC(NullClient, pGC, bmask, NULL, back);
 
3870
    ValidateGC(pDraw, pGC);
 
3871
    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
 
3872
 
 
3873
    FreeScratchGC(pGC);
 
3874
}
 
3875
 
 
3876
#endif