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

« back to all changes in this revision

Viewing changes to miext/rootless/rootlessValTree.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
/*
 
2
 * Calculate window clip lists for rootless mode
 
3
 *
 
4
 * This file is very closely based on mivaltree.c.
 
5
 */
 
6
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessValTree.c,v 1.1tsi Exp $ */
 
7
 
 
8
/*
 
9
 * mivaltree.c --
 
10
 *      Functions for recalculating window clip lists. Main function
 
11
 *      is miValidateTree.
 
12
 *
 
13
 
 
14
Copyright 1987, 1988, 1989, 1998  The Open Group
 
15
 
 
16
All Rights Reserved.
 
17
 
 
18
The above copyright notice and this permission notice shall be included in
 
19
all copies or substantial portions of the Software.
 
20
 
 
21
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
22
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
23
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
24
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
25
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
26
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
 
 
28
Except as contained in this notice, the name of The Open Group shall not be
 
29
used in advertising or otherwise to promote the sale, use or other dealings
 
30
in this Software without prior written authorization from The Open Group.
 
31
 
 
32
 *
 
33
 * Copyright 1987, 1988, 1989 by 
 
34
 * Digital Equipment Corporation, Maynard, Massachusetts,
 
35
 * 
 
36
 *                         All Rights Reserved
 
37
 * 
 
38
 * Permission to use, copy, modify, and distribute this software and its 
 
39
 * documentation for any purpose and without fee is hereby granted, 
 
40
 * provided that the above copyright notice appear in all copies and that
 
41
 * both that copyright notice and this permission notice appear in 
 
42
 * supporting documentation, and that the name of Digital not be
 
43
 * used in advertising or publicity pertaining to distribution of the
 
44
 * software without specific, written prior permission.  
 
45
 * 
 
46
 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
47
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
48
 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
49
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
50
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
51
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
52
 * SOFTWARE.
 
53
 * 
 
54
 ******************************************************************/
 
55
 
 
56
/* The panoramix components contained the following notice */
 
57
/*****************************************************************
 
58
 
 
59
Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
 
60
 
 
61
Permission is hereby granted, free of charge, to any person obtaining a copy
 
62
of this software and associated documentation files (the "Software"), to deal
 
63
in the Software without restriction, including without limitation the rights
 
64
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
65
copies of the Software.
 
66
 
 
67
The above copyright notice and this permission notice shall be included in
 
68
all copies or substantial portions of the Software.
 
69
 
 
70
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
71
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
72
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
73
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
 
74
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
 
75
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 
76
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
77
 
 
78
Except as contained in this notice, the name of Digital Equipment Corporation
 
79
shall not be used in advertising or otherwise to promote the sale, use or other
 
80
dealings in this Software without prior written authorization from Digital
 
81
Equipment Corporation.
 
82
 
 
83
******************************************************************/
 
84
 /* 
 
85
  * Aug '86: Susan Angebranndt -- original code
 
86
  * July '87: Adam de Boor -- substantially modified and commented
 
87
  * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
 
88
  *             In particular, much improved code for window mapping and
 
89
  *             circulating.
 
90
  *             Bob Scheifler -- avoid miComputeClips for unmapped windows,
 
91
  *                              valdata changes
 
92
  */
 
93
#ifdef HAVE_DIX_CONFIG_H
 
94
#include <dix-config.h>
 
95
#endif
 
96
 
 
97
#include    <X11/X.h>
 
98
#include    "scrnintstr.h"
 
99
#include    "validate.h"
 
100
#include    "windowstr.h"
 
101
#include    "mi.h"
 
102
#include    "regionstr.h"
 
103
#include    "mivalidate.h"
 
104
 
 
105
#include    "globals.h"
 
106
 
 
107
#ifdef SHAPE
 
108
/*
 
109
 * Compute the visibility of a shaped window
 
110
 */
 
111
int
 
112
RootlessShapedWindowIn (pScreen, universe, bounding, rect, x, y)
 
113
    ScreenPtr   pScreen;
 
114
    RegionPtr   universe, bounding;
 
115
    BoxPtr      rect;
 
116
    register int x, y;
 
117
{
 
118
    BoxRec  box;
 
119
    register BoxPtr  boundBox;
 
120
    int     nbox;
 
121
    Bool    someIn, someOut;
 
122
    register int t, x1, y1, x2, y2;
 
123
 
 
124
    nbox = REGION_NUM_RECTS (bounding);
 
125
    boundBox = REGION_RECTS (bounding);
 
126
    someIn = someOut = FALSE;
 
127
    x1 = rect->x1;
 
128
    y1 = rect->y1;
 
129
    x2 = rect->x2;
 
130
    y2 = rect->y2;
 
131
    while (nbox--)
 
132
    {
 
133
        if ((t = boundBox->x1 + x) < x1)
 
134
            t = x1;
 
135
        box.x1 = t;
 
136
        if ((t = boundBox->y1 + y) < y1)
 
137
            t = y1;
 
138
        box.y1 = t;
 
139
        if ((t = boundBox->x2 + x) > x2)
 
140
            t = x2;
 
141
        box.x2 = t;
 
142
        if ((t = boundBox->y2 + y) > y2)
 
143
            t = y2;
 
144
        box.y2 = t;
 
145
        if (box.x1 > box.x2)
 
146
            box.x2 = box.x1;
 
147
        if (box.y1 > box.y2)
 
148
            box.y2 = box.y1;
 
149
        switch (RECT_IN_REGION(pScreen, universe, &box))
 
150
        {
 
151
        case rgnIN:
 
152
            if (someOut)
 
153
                return rgnPART;
 
154
            someIn = TRUE;
 
155
            break;
 
156
        case rgnOUT:
 
157
            if (someIn)
 
158
                return rgnPART;
 
159
            someOut = TRUE;
 
160
            break;
 
161
        default:
 
162
            return rgnPART;
 
163
        }
 
164
        boundBox++;
 
165
    }
 
166
    if (someIn)
 
167
        return rgnIN;
 
168
    return rgnOUT;
 
169
}
 
170
#endif
 
171
 
 
172
#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
 
173
                                    HasBorder(w) && \
 
174
                                    (w)->backgroundState == ParentRelative)
 
175
 
 
176
 
 
177
/*
 
178
 *-----------------------------------------------------------------------
 
179
 * RootlessComputeClips --
 
180
 *      Recompute the clipList, borderClip, exposed and borderExposed
 
181
 *      regions for pParent and its children. Only viewable windows are
 
182
 *      taken into account.
 
183
 *
 
184
 * Results:
 
185
 *      None.
 
186
 *
 
187
 * Side Effects:
 
188
 *      clipList, borderClip, exposed and borderExposed are altered.
 
189
 *      A VisibilityNotify event may be generated on the parent window.
 
190
 *
 
191
 *-----------------------------------------------------------------------
 
192
 */
 
193
static void
 
194
RootlessComputeClips (pParent, pScreen, universe, kind, exposed)
 
195
    register WindowPtr  pParent;
 
196
    register ScreenPtr  pScreen;
 
197
    register RegionPtr  universe;
 
198
    VTKind              kind;
 
199
    RegionPtr           exposed; /* for intermediate calculations */
 
200
{
 
201
    int                 dx,
 
202
                        dy;
 
203
    RegionRec           childUniverse;
 
204
    register WindowPtr  pChild;
 
205
    int                 oldVis, newVis;
 
206
    BoxRec              borderSize;
 
207
    RegionRec           childUnion;
 
208
    Bool                overlap;
 
209
    RegionPtr           borderVisible;
 
210
    Bool                resized;
 
211
    /*
 
212
     * Figure out the new visibility of this window.
 
213
     * The extent of the universe should be the same as the extent of
 
214
     * the borderSize region. If the window is unobscured, this rectangle
 
215
     * will be completely inside the universe (the universe will cover it
 
216
     * completely). If the window is completely obscured, none of the
 
217
     * universe will cover the rectangle.
 
218
     */
 
219
    borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
 
220
    borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
 
221
    dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
 
222
    if (dx > 32767)
 
223
        dx = 32767;
 
224
    borderSize.x2 = dx;
 
225
    dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
 
226
    if (dy > 32767)
 
227
        dy = 32767;
 
228
    borderSize.y2 = dy;
 
229
 
 
230
    oldVis = pParent->visibility;
 
231
    switch (RECT_IN_REGION( pScreen, universe, &borderSize)) 
 
232
    {
 
233
    case rgnIN:
 
234
            newVis = VisibilityUnobscured;
 
235
            break;
 
236
        case rgnPART:
 
237
            newVis = VisibilityPartiallyObscured;
 
238
#ifdef SHAPE
 
239
            {
 
240
                RegionPtr   pBounding;
 
241
 
 
242
                if ((pBounding = wBoundingShape (pParent)))
 
243
                {
 
244
                    switch (RootlessShapedWindowIn (pScreen, universe, 
 
245
                                                    pBounding, &borderSize,
 
246
                                                    pParent->drawable.x,
 
247
                                                    pParent->drawable.y))
 
248
                    {
 
249
                    case rgnIN:
 
250
                        newVis = VisibilityUnobscured;
 
251
                        break;
 
252
                    case rgnOUT:
 
253
                        newVis = VisibilityFullyObscured;
 
254
                        break;
 
255
                    }
 
256
                }
 
257
            }
 
258
#endif
 
259
            break;
 
260
        default:
 
261
            newVis = VisibilityFullyObscured;
 
262
            break;
 
263
    }
 
264
 
 
265
    pParent->visibility = newVis;
 
266
    if (oldVis != newVis &&
 
267
        ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
 
268
        SendVisibilityNotify(pParent);
 
269
 
 
270
    dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
 
271
    dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
 
272
 
 
273
    /*
 
274
     * avoid computations when dealing with simple operations
 
275
     */
 
276
 
 
277
    switch (kind) {
 
278
    case VTMap:
 
279
    case VTStack:
 
280
    case VTUnmap:
 
281
        break;
 
282
    case VTMove:
 
283
        if ((oldVis == newVis) &&
 
284
            ((oldVis == VisibilityFullyObscured) ||
 
285
             (oldVis == VisibilityUnobscured)))
 
286
        {
 
287
            pChild = pParent;
 
288
            while (1)
 
289
            {
 
290
                if (pChild->viewable)
 
291
                {
 
292
                    if (pChild->visibility != VisibilityFullyObscured)
 
293
                    {
 
294
                        REGION_TRANSLATE( pScreen, &pChild->borderClip,
 
295
                                                      dx, dy);
 
296
                        REGION_TRANSLATE( pScreen, &pChild->clipList,
 
297
                                                      dx, dy);
 
298
                        pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
 
299
                        if (pScreen->ClipNotify)
 
300
                            (* pScreen->ClipNotify) (pChild, dx, dy);
 
301
 
 
302
                    }
 
303
                    if (pChild->valdata)
 
304
                    {
 
305
                        REGION_NULL(pScreen,
 
306
                                    &pChild->valdata->after.borderExposed);
 
307
                        if (HasParentRelativeBorder(pChild))
 
308
                          {
 
309
                            REGION_SUBTRACT(pScreen,
 
310
                                         &pChild->valdata->after.borderExposed,
 
311
                                         &pChild->borderClip,
 
312
                                         &pChild->winSize);
 
313
                        }
 
314
                        REGION_NULL(pScreen, &pChild->valdata->after.exposed);
 
315
                    }
 
316
                    if (pChild->firstChild)
 
317
                    {
 
318
                        pChild = pChild->firstChild;
 
319
                        continue;
 
320
                    }
 
321
                }
 
322
                while (!pChild->nextSib && (pChild != pParent))
 
323
                    pChild = pChild->parent;
 
324
                if (pChild == pParent)
 
325
                    break;
 
326
                pChild = pChild->nextSib;
 
327
            }
 
328
            return;
 
329
        }
 
330
        /* fall through */
 
331
    default:
 
332
        /*
 
333
         * To calculate exposures correctly, we have to translate the old
 
334
         * borderClip and clipList regions to the window's new location so there
 
335
         * is a correspondence between pieces of the new and old clipping regions.
 
336
         */
 
337
        if (dx || dy) 
 
338
        {
 
339
            /*
 
340
             * We translate the old clipList because that will be exposed or copied
 
341
             * if gravity is right.
 
342
             */
 
343
            REGION_TRANSLATE( pScreen, &pParent->borderClip, dx, dy);
 
344
            REGION_TRANSLATE( pScreen, &pParent->clipList, dx, dy);
 
345
        } 
 
346
        break;
 
347
    case VTBroken:
 
348
        REGION_EMPTY (pScreen, &pParent->borderClip);
 
349
        REGION_EMPTY (pScreen, &pParent->clipList);
 
350
        break;
 
351
    }
 
352
 
 
353
    borderVisible = pParent->valdata->before.borderVisible;
 
354
    resized = pParent->valdata->before.resized;
 
355
    REGION_NULL(pScreen, &pParent->valdata->after.borderExposed);
 
356
    REGION_NULL(pScreen, &pParent->valdata->after.exposed);
 
357
 
 
358
    /*
 
359
     * Since the borderClip must not be clipped by the children, we do
 
360
     * the border exposure first...
 
361
     *
 
362
     * 'universe' is the window's borderClip. To figure the exposures, remove
 
363
     * the area that used to be exposed from the new.
 
364
     * This leaves a region of pieces that weren't exposed before.
 
365
     */
 
366
 
 
367
    if (HasBorder (pParent))
 
368
    {
 
369
        if (borderVisible)
 
370
        {
 
371
            /*
 
372
             * when the border changes shape, the old visible portions
 
373
             * of the border will be saved by DIX in borderVisible --
 
374
             * use that region and destroy it
 
375
             */
 
376
            REGION_SUBTRACT( pScreen, exposed, universe, borderVisible);
 
377
            REGION_DESTROY( pScreen, borderVisible);
 
378
        }
 
379
        else
 
380
        {
 
381
            REGION_SUBTRACT( pScreen, exposed, universe, &pParent->borderClip);
 
382
        }
 
383
        if (HasParentRelativeBorder(pParent) && (dx || dy)) {
 
384
            REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
 
385
                                  universe,
 
386
                                  &pParent->winSize);
 
387
        } else {
 
388
            REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
 
389
                               exposed, &pParent->winSize);
 
390
        }
 
391
 
 
392
        REGION_COPY( pScreen, &pParent->borderClip, universe);
 
393
    
 
394
        /*
 
395
         * To get the right clipList for the parent, and to make doubly sure
 
396
         * that no child overlaps the parent's border, we remove the parent's
 
397
         * border from the universe before proceeding.
 
398
         */
 
399
    
 
400
        REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize);
 
401
    }
 
402
    else
 
403
        REGION_COPY( pScreen, &pParent->borderClip, universe);
 
404
    
 
405
    if ((pChild = pParent->firstChild) && pParent->mapped)
 
406
    {
 
407
        REGION_NULL(pScreen, &childUniverse);
 
408
        REGION_NULL(pScreen, &childUnion);
 
409
        if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
 
410
            ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
 
411
             (pChild->drawable.x < pParent->lastChild->drawable.x)))
 
412
        {
 
413
            for (; pChild; pChild = pChild->nextSib)
 
414
            {
 
415
                if (pChild->viewable)
 
416
                    REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
 
417
            }
 
418
        }
 
419
        else
 
420
        {
 
421
            for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
 
422
            {
 
423
                if (pChild->viewable)
 
424
                    REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
 
425
            }
 
426
        }
 
427
        REGION_VALIDATE( pScreen, &childUnion, &overlap);
 
428
 
 
429
        for (pChild = pParent->firstChild;
 
430
             pChild;
 
431
             pChild = pChild->nextSib)
 
432
        {
 
433
            if (pChild->viewable) {
 
434
                /*
 
435
                 * If the child is viewable, we want to remove its extents
 
436
                 * from the current universe, but we only re-clip it if
 
437
                 * it's been marked.
 
438
                 */
 
439
                if (pChild->valdata) {
 
440
                    /*
 
441
                     * Figure out the new universe from the child's
 
442
                     * perspective and recurse.
 
443
                     */
 
444
                    REGION_INTERSECT( pScreen, &childUniverse,
 
445
                                            universe,
 
446
                                            &pChild->borderSize);
 
447
                    RootlessComputeClips (pChild, pScreen, &childUniverse, 
 
448
                                          kind, exposed);
 
449
                }
 
450
                /*
 
451
                 * Once the child has been processed, we remove its extents
 
452
                 * from the current universe, thus denying its space to any
 
453
                 * other sibling.
 
454
                 */
 
455
                if (overlap)
 
456
                    REGION_SUBTRACT( pScreen, universe, universe,
 
457
                                          &pChild->borderSize);
 
458
            }
 
459
        }
 
460
        if (!overlap)
 
461
            REGION_SUBTRACT( pScreen, universe, universe, &childUnion);
 
462
        REGION_UNINIT( pScreen, &childUnion);
 
463
        REGION_UNINIT( pScreen, &childUniverse);
 
464
    } /* if any children */
 
465
 
 
466
    /*
 
467
     * 'universe' now contains the new clipList for the parent window.
 
468
     *
 
469
     * To figure the exposure of the window we subtract the old clip from the
 
470
     * new, just as for the border.
 
471
     */
 
472
 
 
473
    if (oldVis == VisibilityFullyObscured ||
 
474
        oldVis == VisibilityNotViewable)
 
475
    {
 
476
        REGION_COPY( pScreen, &pParent->valdata->after.exposed, universe);
 
477
    }
 
478
    else if (newVis != VisibilityFullyObscured &&
 
479
             newVis != VisibilityNotViewable)
 
480
    {
 
481
        REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed,
 
482
                               universe, &pParent->clipList);
 
483
    }
 
484
 
 
485
    /*
 
486
     * One last thing: backing storage. We have to try to save what parts of
 
487
     * the window are about to be obscured. We can just subtract the universe
 
488
     * from the old clipList and get the areas that were in the old but aren't
 
489
     * in the new and, hence, are about to be obscured.
 
490
     */
 
491
    if (pParent->backStorage && !resized)
 
492
    {
 
493
        REGION_SUBTRACT( pScreen, exposed, &pParent->clipList, universe);
 
494
        (* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy);
 
495
    }
 
496
    
 
497
    /* HACK ALERT - copying contents of regions, instead of regions */
 
498
    {
 
499
        RegionRec   tmp;
 
500
 
 
501
        tmp = pParent->clipList;
 
502
        pParent->clipList = *universe;
 
503
        *universe = tmp;
 
504
    }
 
505
 
 
506
#ifdef NOTDEF
 
507
    REGION_COPY( pScreen, &pParent->clipList, universe);
 
508
#endif
 
509
 
 
510
    pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
 
511
 
 
512
    if (pScreen->ClipNotify)
 
513
        (* pScreen->ClipNotify) (pParent, dx, dy);
 
514
}
 
515
 
 
516
static void
 
517
RootlessTreeObscured(pParent)
 
518
    register WindowPtr pParent;
 
519
{
 
520
    register WindowPtr pChild;
 
521
    register int    oldVis;
 
522
 
 
523
    pChild = pParent;
 
524
    while (1)
 
525
    {
 
526
        if (pChild->viewable)
 
527
        {
 
528
            oldVis = pChild->visibility;
 
529
            if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
 
530
                ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
 
531
                SendVisibilityNotify(pChild);
 
532
            if (pChild->firstChild)
 
533
            {
 
534
                pChild = pChild->firstChild;
 
535
                continue;
 
536
            }
 
537
        }
 
538
        while (!pChild->nextSib && (pChild != pParent))
 
539
            pChild = pChild->parent;
 
540
        if (pChild == pParent)
 
541
            break;
 
542
        pChild = pChild->nextSib;
 
543
    }
 
544
}
 
545
 
 
546
/*
 
547
 *-----------------------------------------------------------------------
 
548
 * RootlessMiValidateTree --
 
549
 *      Recomputes the clip list for pParent and all its inferiors.
 
550
 *
 
551
 * Results:
 
552
 *      Always returns 1.
 
553
 *
 
554
 * Side Effects:
 
555
 *      The clipList, borderClip, exposed, and borderExposed regions for
 
556
 *      each marked window are altered.
 
557
 *
 
558
 * Notes:
 
559
 *      This routine assumes that all affected windows have been marked
 
560
 *      (valdata created) and their winSize and borderSize regions
 
561
 *      adjusted to correspond to their new positions. The borderClip and
 
562
 *      clipList regions should not have been touched.
 
563
 *
 
564
 *      The top-most level is treated differently from all lower levels
 
565
 *      because pParent is unchanged. For the top level, we merge the
 
566
 *      regions taken up by the marked children back into the clipList
 
567
 *      for pParent, thus forming a region from which the marked children
 
568
 *      can claim their areas. For lower levels, where the old clipList
 
569
 *      and borderClip are invalid, we can't do this and have to do the
 
570
 *      extra operations done in miComputeClips, but this is much faster
 
571
 *      e.g. when only one child has moved...
 
572
 *
 
573
 *-----------------------------------------------------------------------
 
574
 */
 
575
/* 
 
576
   Quartz version: used for validate from root in rootless mode.
 
577
   We need to make sure top-level windows don't clip each other, 
 
578
   and that top-level windows aren't clipped to the root window.
 
579
*/
 
580
/*ARGSUSED*/
 
581
// fixme this is ugly
 
582
// Xprint/ValTree.c doesn't work, but maybe that method can?
 
583
int
 
584
RootlessMiValidateTree (pRoot, pChild, kind)
 
585
    WindowPtr           pRoot;      /* Parent to validate */
 
586
    WindowPtr           pChild;     /* First child of pRoot that was
 
587
                                     * affected */
 
588
    VTKind              kind;       /* What kind of configuration caused call */
 
589
{
 
590
    RegionRec           childClip;  /* The new borderClip for the current
 
591
                                     * child */
 
592
    RegionRec           exposed;    /* For intermediate calculations */
 
593
    register ScreenPtr  pScreen;
 
594
    register WindowPtr  pWin;
 
595
 
 
596
    pScreen = pRoot->drawable.pScreen;
 
597
    if (pChild == NullWindow)
 
598
        pChild = pRoot->firstChild;
 
599
 
 
600
    REGION_NULL(pScreen, &childClip);
 
601
    REGION_NULL(pScreen, &exposed);
 
602
 
 
603
    if (REGION_BROKEN (pScreen, &pRoot->clipList) &&
 
604
        !REGION_BROKEN (pScreen, &pRoot->borderClip))
 
605
    {
 
606
        // fixme this might not work, but hopefully doesn't happen anyway.
 
607
        kind = VTBroken;
 
608
        REGION_EMPTY (pScreen, &pRoot->clipList);
 
609
        ErrorF("ValidateTree: BUSTED!\n");
 
610
    }
 
611
 
 
612
    /* 
 
613
     * Recursively compute the clips for all children of the root. 
 
614
     * They don't clip against each other or the root itself, so 
 
615
     * childClip is always reset to that child's size.
 
616
     */
 
617
 
 
618
    for (pWin = pChild;
 
619
         pWin != NullWindow;
 
620
         pWin = pWin->nextSib)
 
621
    {
 
622
        if (pWin->viewable) {
 
623
            if (pWin->valdata) {
 
624
                REGION_COPY( pScreen, &childClip, &pWin->borderSize);
 
625
                RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed);
 
626
            } else if (pWin->visibility == VisibilityNotViewable) {
 
627
                RootlessTreeObscured(pWin);
 
628
            }
 
629
        } else {
 
630
            if (pWin->valdata) {
 
631
                REGION_EMPTY( pScreen, &pWin->clipList);
 
632
                if (pScreen->ClipNotify)
 
633
                    (* pScreen->ClipNotify) (pWin, 0, 0);
 
634
                REGION_EMPTY( pScreen, &pWin->borderClip);
 
635
                pWin->valdata = (ValidatePtr)NULL;
 
636
            }
 
637
        }
 
638
    }
 
639
 
 
640
    REGION_UNINIT(pScreen, &childClip);
 
641
 
 
642
    /* The root is never clipped by its children, so nothing on the root 
 
643
       is ever exposed by moving or mapping its children. */
 
644
    REGION_NULL(pScreen, &pRoot->valdata->after.exposed);
 
645
    REGION_NULL(pScreen, &pRoot->valdata->after.borderExposed);
 
646
 
 
647
    return 1;
 
648
}