|
|
1.1 root 1: /***********************************************************
2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
4:
5: All Rights Reserved
6:
7: Permission to use, copy, modify, and distribute this software and its
8: documentation for any purpose and without fee is hereby granted,
9: provided that the above copyright notice appear in all copies and that
10: both that copyright notice and this permission notice appear in
11: supporting documentation, and that the names of Digital or MIT not be
12: used in advertising or publicity pertaining to distribution of the
13: software without specific, written prior permission.
14:
15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21: SOFTWARE.
22:
23: ******************************************************************/
24:
25: /* $Header: window.c,v 1.170 87/09/07 18:56:00 rws Exp $ */
26:
27: #include "X.h"
28: #define NEED_REPLIES
29: #define NEED_EVENTS
30: #include "Xproto.h"
31: #include "misc.h"
32: #include "scrnintstr.h"
33: #include "os.h"
34: #include "regionstr.h"
35: #include "windowstr.h"
36: #include "input.h"
37: #include "resource.h"
38: #include "colormapst.h"
39: #include "cursorstr.h"
40: #include "dixstruct.h"
41: #include "gcstruct.h"
42: #include "servermd.h"
43:
44: /******
45: * Window stuff for server
46: *
47: * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
48: * GetWindowAttributes, DeleteWindow, DestroySubWindows,
49: * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
50: * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
51: *
52: ******/
53:
54: static long _back[16] = {0x88888888, 0x22222222, 0x44444444, 0x11111111,
55: 0x88888888, 0x22222222, 0x44444444, 0x11111111,
56: 0x88888888, 0x22222222, 0x44444444, 0x11111111,
57: 0x88888888, 0x22222222, 0x44444444, 0x11111111};
58:
59: typedef struct _ScreenSaverStuff {
60: WindowPtr pWindow;
61: XID wid;
62: XID cid;
63: BYTE blanked;
64: } ScreenSaverStuffRec;
65:
66: #define SCREEN_IS_BLANKED 0
67: #define SCREEN_IS_TILED 1
68: #define SCREEN_ISNT_SAVED 2
69:
70: #define DONT_USE_GRAVITY 0
71: #define USE_GRAVITY 1
72:
73: extern int ScreenSaverBlanking, ScreenSaverAllowExposures;
74: int screenIsSaved = FALSE;
75:
76: static ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
77:
78: extern WindowRec WindowTable[];
79: extern void (* ReplySwapVector[256]) ();
80:
81: static void ResizeChildrenWinSize();
82:
83: #define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
84: CWDontPropagate | CWOverrideRedirect | CWCursor )
85:
86: /******
87: * PrintWindowTree
88: * For debugging only
89: ******/
90:
91: int
92: PrintChildren(p1, indent)
93: WindowPtr p1;
94: int indent;
95: {
96: WindowPtr p2;
97: int i;
98:
99: while (p1)
100: {
101: p2 = p1->firstChild;
102: for (i=0; i<indent; i++) ErrorF( " ");
103: ErrorF( "%x\n", p1->wid);
104: miprintRects(p1->clipList);
105: PrintChildren(p2, indent+4);
106: p1 = p1->nextSib;
107: }
108: }
109:
110: PrintWindowTree()
111: {
112: int i;
113: WindowPtr pWin, p1;
114:
115: for (i=0; i<screenInfo.numScreens; i++)
116: {
117: ErrorF( "WINDOW %d\n", i);
118: pWin = &WindowTable[i];
119: miprintRects(pWin->clipList);
120: p1 = pWin->firstChild;
121: PrintChildren(p1, 4);
122: }
123: }
124:
125:
126: /*****
127: * WalkTree
128: * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
129: * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
130: * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
131: * exit WalkTree. Does depth-first traverse.
132: *****/
133:
134: int
135: TraverseTree(pWin, func, data)
136: WindowPtr pWin;
137: int (*func)();
138: pointer data;
139: {
140: int result;
141: WindowPtr pChild;
142:
143: if (pWin == 0)
144: return(WT_NOMATCH);
145: result = (* func)(pWin, data);
146:
147: if (result == WT_STOPWALKING)
148: return(WT_STOPWALKING);
149:
150: if (result == WT_WALKCHILDREN)
151: for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
152: if (TraverseTree(pChild, func,data) == WT_STOPWALKING)
153: return(WT_STOPWALKING);
154:
155: return(WT_NOMATCH);
156: }
157:
158: int
159: WalkTree(pScreen, func, data)
160: ScreenPtr pScreen;
161: int (* func)();
162: char *data;
163: {
164: WindowPtr pWin;
165:
166: pWin = &WindowTable[pScreen->myNum];
167: return(TraverseTree(pWin, func, data));
168: }
169:
170: /*****
171: * DoObscures(pWin)
172: *
173: *****/
174:
175: static void
176: DoObscures(pWin)
177: WindowPtr pWin;
178: {
179: WindowPtr pSib;
180:
181: if (pWin->backStorage == 0 || (pWin->backingStore == NotUseful))
182: return ;
183: if ((* pWin->drawable.pScreen->RegionNotEmpty)(pWin->backStorage->obscured))
184: {
185: (*pWin->backStorage->SaveDoomedAreas)( pWin );
186: (* pWin->drawable.pScreen->RegionEmpty)(pWin->backStorage->obscured);
187: }
188: pSib = pWin->firstChild;
189: while (pSib)
190: {
191: DoObscures(pSib);
192: pSib = pSib->nextSib;
193: }
194: }
195:
196: /*****
197: * HandleExposures(pWin)
198: * starting at pWin, draw background in any windows that have exposure
199: * regions, translate the regions, restore any backing store,
200: * and then send any regions stille xposed to the client
201: *****/
202:
203: /* NOTE
204: the order of painting and restoration needs to be different,
205: to avoid an extra repaint of the background. --rgd
206: */
207:
208: void
209: HandleExposures(pWin)
210: WindowPtr pWin;
211: {
212: WindowPtr pSib;
213:
214: if ((* pWin->drawable.pScreen->RegionNotEmpty)(pWin->borderExposed))
215: {
216: (*pWin->PaintWindowBorder)(pWin, pWin->borderExposed, PW_BORDER);
217: (* pWin->drawable.pScreen->RegionEmpty)(pWin->borderExposed);
218: }
219: (* pWin->drawable.pScreen->WindowExposures)(pWin);
220: pSib = pWin->firstChild;
221: while (pSib)
222: {
223: HandleExposures(pSib);
224: pSib = pSib->nextSib;
225: }
226: }
227:
228: extern int NotImplemented();
229:
230: static void
231: InitProcedures(pWin)
232: WindowPtr pWin;
233: {
234: #ifdef DEBUG
235: void (**j) ();
236: for (j = &pWin->PaintWindowBackground;
237: j < &pWin->ClearToBackground; j++ )
238: *j = (void (*) ())NotImplemented;
239: #endif /* DEBUG */
240:
241: }
242:
243: static void
244: SetWindowToDefaults(pWin, pScreen)
245: WindowPtr pWin;
246: ScreenPtr pScreen;
247: {
248: pWin->prevSib = NullWindow;
249: pWin->firstChild = NullWindow;
250: pWin->lastChild = NullWindow;
251:
252: pWin->userProps = (PropertyPtr)NULL;
253:
254: pWin->backingStore = NotUseful;
255: pWin->backStorage = (BackingStorePtr) NULL;
256:
257: pWin->mapped = 0; /* off */
258: pWin->realized = 0; /* off */
259: pWin->viewable = 0;
260: pWin->overrideRedirect = FALSE;
261: pWin->saveUnder = FALSE;
262:
263: pWin->bitGravity = ForgetGravity;
264: pWin->winGravity = NorthWestGravity;
265: pWin->backingBitPlanes = -1;
266: pWin->backingPixel = 0;
267:
268: pWin->eventMask = 0;
269: pWin->dontPropagateMask = 0;
270: pWin->allEventMasks = 0;
271: pWin->deliverableEvents = 0;
272:
273: pWin->otherClients = (pointer)NULL;
274: pWin->passiveGrabs = (pointer)NULL;
275: pWin->colormap = (Colormap)CopyFromParent;
276:
277: pWin->exposed = (* pScreen->RegionCreate)(NULL, 1);
278: pWin->borderExposed = (* pScreen->RegionCreate)(NULL, 1);
279:
280: }
281:
282: static void
283: MakeRootCursor(pWin)
284: WindowPtr pWin;
285: {
286: unsigned char *srcbits, *mskbits;
287: int i;
288: if (rootCursor)
289: {
290: pWin->cursor = rootCursor;
291: rootCursor->refcnt++;
292: }
293: else
294: {
295: CursorMetricRec cm;
296: cm.width=32;
297: cm.height=16;
298: cm.xhot=8;
299: cm.yhot=8;
300:
301: srcbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16);
302: mskbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16);
303: for (i=0; i<PixmapBytePad(32, 1)*16; i++)
304: {
305: srcbits[i] = mskbits[i] = 0xff;
306: }
307: pWin->cursor = AllocCursor( srcbits, mskbits, &cm,
308: ~0, ~0, ~0, 0, 0, 0);
309: }
310: }
311:
312: static void
313: MakeRootTile(pWin)
314: WindowPtr pWin;
315: {
316: ScreenPtr pScreen = pWin->drawable.pScreen;
317: GCPtr pGC;
318:
319: pWin->backgroundTile = (*pScreen->CreatePixmap)(pScreen, 16, 16,
320: pScreen->rootDepth);
321:
322: pGC = GetScratchGC(pScreen->rootDepth, pScreen);
323:
324: {
325: CARD32 attributes[3];
326:
327: attributes[0] = pScreen->whitePixel;
328: attributes[1] = pScreen->blackPixel;
329: attributes[2] = FALSE;
330:
331: ChangeGC(pGC, GCForeground | GCBackground | GCGraphicsExposures,
332: attributes, 3);
333: }
334:
335: ValidateGC(pWin->backgroundTile, pGC);
336:
337: (*pGC->PutImage)(pWin->backgroundTile, pGC, 1,
338: 0, 0, 16, 16, 0, XYBitmap, _back);
339:
340: FreeScratchGC(pGC);
341:
342: }
343:
344: /*****
345: * CreateRootWindow
346: * Makes a window at initialization time for specified screen
347: *****/
348:
349: int
350: CreateRootWindow(screen)
351: int screen;
352: {
353: WindowPtr pWin;
354: BoxRec box;
355: ScreenPtr pScreen;
356:
357: savedScreenInfo[screen].pWindow = NULL;
358: savedScreenInfo[screen].wid = FakeClientID(0);
359: savedScreenInfo[screen].cid = FakeClientID(0);
360: screenIsSaved = SCREEN_SAVER_OFF;
361:
362: pWin = &WindowTable[screen];
363: pScreen = &screenInfo.screen[screen];
364: InitProcedures(pWin);
365:
366: pWin->drawable.pScreen = pScreen;
367: pWin->drawable.type = DRAWABLE_WINDOW;
368:
369: pWin->drawable.depth = pScreen->rootDepth;
370:
371: pWin->parent = NullWindow;
372: SetWindowToDefaults(pWin, pScreen);
373:
374: pWin->colormap = pScreen->defColormap;
375:
376: pWin->nextSib = NullWindow;
377:
378: MakeRootCursor(pWin);
379:
380: pWin->client = serverClient; /* since belongs to server */
381: pWin->wid = FakeClientID(0);
382:
383: pWin->clientWinSize.x = pWin->clientWinSize.y = 0;
384: pWin->clientWinSize.height = screenInfo.screen[screen].height;
385: pWin->clientWinSize.width = screenInfo.screen[screen].width;
386: pWin->absCorner.x = pWin->absCorner.y = 0;
387: pWin->oldAbsCorner.x = pWin->oldAbsCorner.y = 0;
388:
389: box.x1 = 0;
390: box.y1 = 0;
391: box.x2 = screenInfo.screen[screen].width ;
392: box.y2 = screenInfo.screen[screen].height;
393: pWin->clipList = (* pScreen->RegionCreate)(&box, 1);
394: pWin->winSize = (* pScreen->RegionCreate)(&box, 1);
395: pWin->borderSize = (* pScreen->RegionCreate)(&box, 1);
396: pWin->borderClip = (* pScreen->RegionCreate)(&box, 1);
397:
398: pWin->class = InputOutput;
399: pWin->visual = pScreen->rootVisual;
400:
401: pWin->backgroundPixel = pScreen->whitePixel;
402:
403: pWin->borderPixel = pScreen->blackPixel;
404: pWin->borderWidth = 0;
405:
406: AddResource(pWin->wid, RT_WINDOW, pWin, DeleteWindow, RC_CORE);
407:
408: MakeRootTile(pWin);
409: pWin->borderTile = (PixmapPtr)USE_BORDER_PIXEL;
410:
411: /* re-validate GC for use with root Window */
412:
413: (*pScreen->CreateWindow)(pWin);
414: MapWindow(pWin, DONT_HANDLE_EXPOSURES, BITS_DISCARDED,
415: DONT_SEND_NOTIFICATION, serverClient);
416:
417: /* We SHOULD check for an error value here XXX */
418: (*pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap | CWBorderPixel);
419:
420: (*pWin->PaintWindowBackground)(pWin, pWin->clipList, PW_BACKGROUND);
421: EventSelectForWindow(pWin, serverClient, 0);
422: return(Success);
423: }
424:
425: /*****
426: * CreateWindow
427: * Makes a window in response to client request
428: * XXX What about depth of inputonly windows -- should be 0
429: *****/
430:
431: WindowPtr
432: CreateWindow(wid, pParent, x, y, w, h, bw, class, vmask, vlist,
433: depth, client, visual, error)
434: Window wid;
435: WindowPtr pParent; /* already looked up in table to do error checking*/
436: short x,y;
437: unsigned short w, h, bw;
438: int class;
439: int vmask;
440: long *vlist;
441: int depth;
442: ClientPtr client;
443: VisualID visual;
444: int *error;
445: {
446: WindowPtr pWin;
447: ScreenPtr pScreen;
448: BoxRec box;
449: xEvent event;
450: int idepth, ivisual;
451: Bool fOK;
452: DepthPtr pDepth;
453:
454: if ((class != InputOnly) && (pParent->class == InputOnly))
455: {
456: *error = BadMatch;
457: return (WindowPtr)NULL;
458: }
459:
460: if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
461: {
462: *error = BadMatch;
463: return (WindowPtr)NULL;
464: }
465:
466: pScreen = pParent->drawable.pScreen;
467: /* Find out if the depth and visual are acceptable for this Screen */
468: fOK = FALSE;
469: if ((class == InputOutput && depth == 0) ||
470: (class == InputOnly) || (class == CopyFromParent))
471: depth = pParent->drawable.depth;
472:
473: if (visual == CopyFromParent)
474: visual = pParent->visual;
475: else
476: {
477: for(idepth = 0; idepth < pScreen->numDepths; idepth++)
478: {
479: pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
480: if (depth == pDepth->depth)
481: {
482: for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
483: {
484: if (visual == pDepth->vids[ivisual])
485: fOK = TRUE;
486: }
487: }
488: }
489: if (fOK == 0)
490: {
491: *error = BadMatch;
492: return (WindowPtr)NULL;
493: }
494: }
495:
496: pWin = (WindowPtr ) Xalloc( sizeof(WindowRec) );
497: if (pWin == (WindowPtr) NULL)
498: {
499: *error = BadAlloc;
500: return (WindowPtr)NULL;
501: }
502: InitProcedures(pWin);
503: pWin->drawable = pParent->drawable;
504: if (class == InputOutput)
505: pWin->drawable.depth = depth;
506: else if (class == InputOnly)
507: pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
508:
509: pWin->wid = wid;
510: pWin->client = client;
511: pWin->visual = visual;
512:
513: SetWindowToDefaults(pWin, pScreen);
514:
515: pWin->cursor = (CursorPtr)None;
516:
517: if (class == CopyFromParent)
518: pWin->class = pParent->class;
519: else
520: pWin->class = class;
521:
522: pWin->borderWidth = (int) bw;
523: pWin->backgroundTile = (PixmapPtr)None;
524: pWin->backgroundPixel = pScreen->whitePixel;
525:
526: if ((pWin->drawable.depth != pParent->drawable.depth) &&
527: (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0 )))
528: {
529: Xfree(pWin);
530: *error = BadMatch;
531: return (WindowPtr)NULL;
532: }
533: if ((vmask & (CWBorderPixmap | CWBorderPixel)) != 0)
534: /* it will just get fixed in ChangeWindowAttributes */
535: pWin->borderTile = (PixmapPtr)NULL;
536: else
537: { /* this is WRONG!! XXX */
538: /* should be actually copied */
539: pWin->borderTile = pParent->borderTile;
540: if (IS_VALID_PIXMAP(pParent->borderTile))
541: pParent->borderTile->refcnt++;
542: }
543: pWin->borderPixel = pParent->borderPixel;
544: pWin->visibility = VisibilityFullyObscured;
545:
546: pWin->clientWinSize.x = x + bw;
547: pWin->clientWinSize.y = y + bw;
548: pWin->clientWinSize.height = h;
549: pWin->clientWinSize.width = w;
550: pWin->absCorner.x = pWin->oldAbsCorner.x = pParent->absCorner.x + x + bw;
551: pWin->absCorner.y = pWin->oldAbsCorner.y = pParent->absCorner.y + y + bw;
552:
553: /* set up clip list correctly for unobscured WindowPtr */
554: pWin->clipList = (* pScreen->RegionCreate)(NULL, 1);
555: pWin->borderClip = (* pScreen->RegionCreate)(NULL, 1);
556: box.x1 = pWin->absCorner.x;
557: box.y1 = pWin->absCorner.y;
558: box.x2 = box.x1 + w;
559: box.y2 = box.y1 + h;
560: pWin->winSize = (* pScreen->RegionCreate)(&box, 1);
561: (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize);
562: if (bw)
563: {
564: box.x1 -= bw;
565: box.y1 -= bw;
566: box.x2 += bw;
567: box.y2 += bw;
568: pWin->borderSize = (* pScreen->RegionCreate)(&box, 1);
569: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize,
570: pParent->winSize);
571: }
572: else
573: {
574: pWin->borderSize = (* pScreen->RegionCreate)(NULL, 1);
575: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize);
576: }
577:
578: pWin->parent = pParent;
579: if ((screenIsSaved == SCREEN_SAVER_ON)
580: && (pParent == &WindowTable[pScreen->myNum])
581: && (pParent->firstChild)
582: && (savedScreenInfo[pScreen->myNum].blanked == SCREEN_IS_TILED))
583: {
584: WindowPtr pFirst = pParent->firstChild;
585: pWin->nextSib = pFirst->nextSib;
586: if (pFirst->nextSib)
587: pFirst->nextSib->prevSib = pWin;
588: else
589: pParent->lastChild = pWin;
590: pFirst->nextSib = pWin;
591: pWin->prevSib = pFirst;
592: }
593: else
594: {
595: pWin->nextSib = pParent->firstChild;
596: if (pParent->firstChild)
597: pParent->firstChild->prevSib = pWin;
598: else
599: pParent->lastChild = pWin;
600: pParent->firstChild = pWin;
601: }
602:
603: /* We SHOULD check for an error value here XXX */
604: (*pScreen->CreateWindow)(pWin);
605: /* We SHOULD check for an error value here XXX */
606: (*pScreen->PositionWindow)(pWin, pWin->absCorner.x, pWin->absCorner.y);
607: if ((vmask & CWEventMask) == 0)
608: EventSelectForWindow(pWin, client, 0);
609:
610: if (vmask)
611: *error = ChangeWindowAttributes(pWin, vmask, vlist, pWin->client);
612: else
613: *error = Success;
614:
615: WindowHasNewCursor( pWin);
616:
617: event.u.u.type = CreateNotify;
618: event.u.createNotify.window = wid;
619: event.u.createNotify.parent = pParent->wid;
620: event.u.createNotify.x = x;
621: event.u.createNotify.y = y;
622: event.u.createNotify.width = w;
623: event.u.createNotify.height = h;
624: event.u.createNotify.borderWidth = bw;
625: event.u.createNotify.override = pWin->overrideRedirect;
626: DeliverEvents(pWin->parent, &event, 1, NullWindow);
627:
628: return pWin;
629: }
630:
631: static void
632: FreeWindowResources(pWin)
633: WindowPtr pWin;
634: {
635: ScreenPtr pScreen;
636: void (* proc)();
637:
638: pScreen = pWin->drawable.pScreen;
639:
640: DeleteWindowFromAnySaveSet(pWin);
641: DeleteWindowFromAnySelections(pWin);
642: DeleteWindowFromAnyEvents(pWin, TRUE);
643: proc = pScreen->RegionDestroy;
644: (* proc)(pWin->clipList);
645: (* proc)(pWin->winSize);
646: (* proc)(pWin->borderClip);
647: (* proc)(pWin->borderSize);
648: (* proc)(pWin->exposed);
649: (* proc)(pWin->borderExposed);
650: if (pWin->backStorage)
651: {
652: (* proc)(pWin->backStorage->obscured);
653: Xfree(pWin->backStorage);
654: }
655: (* pScreen->DestroyPixmap)(pWin->borderTile);
656: (* pScreen->DestroyPixmap)(pWin->backgroundTile);
657:
658: if (pWin->cursor != (CursorPtr)None)
659: FreeCursor( pWin->cursor, 0);
660:
661: DeleteAllWindowProperties(pWin);
662: /* We SHOULD check for an error value here XXX */
663: (* pScreen->DestroyWindow)(pWin);
664: }
665:
666: static void
667: CrushTree(pWin)
668: WindowPtr pWin;
669: {
670: WindowPtr pSib;
671: xEvent event;
672:
673: if (pWin == (WindowPtr) NULL)
674: return;
675: while (pWin)
676: {
677: CrushTree(pWin->firstChild);
678:
679: event.u.u.type = DestroyNotify;
680: event.u.destroyNotify.window = pWin->wid;
681: DeliverEvents(pWin, &event, 1, NullWindow);
682:
683: FreeResource(pWin->wid, RC_CORE);
684: pSib = pWin->nextSib;
685: pWin->realized = FALSE;
686: pWin->viewable = FALSE;
687: (* pWin->drawable.pScreen->UnrealizeWindow)(pWin);
688: FreeWindowResources(pWin);
689: Xfree(pWin);
690: pWin = pSib;
691: }
692: }
693:
694: /*****
695: * DeleteWindow
696: * Deletes child of window then window itself
697: *****/
698:
699: DeleteWindow(pWin, wid)
700: WindowPtr pWin;
701: int wid;
702: {
703: WindowPtr pParent;
704: xEvent event;
705:
706: UnmapWindow(pWin, HANDLE_EXPOSURES, SEND_NOTIFICATION, FALSE);
707:
708: CrushTree(pWin->firstChild);
709:
710: event.u.u.type = DestroyNotify;
711: event.u.destroyNotify.window = pWin->wid;
712: DeliverEvents(pWin, &event, 1, NullWindow);
713:
714: pParent = pWin->parent;
715: FreeWindowResources(pWin);
716: if (pParent)
717: {
718: if (pParent->firstChild == pWin)
719: pParent->firstChild = pWin->nextSib;
720: if (pParent->lastChild == pWin)
721: pParent->lastChild = pWin->prevSib;
722: if (pWin->nextSib)
723: pWin->nextSib->prevSib = pWin->prevSib;
724: if (pWin->prevSib)
725: pWin->prevSib->nextSib = pWin->nextSib;
726: Xfree(pWin);
727: }
728: }
729:
730: DestroySubwindows(pWin, client)
731: WindowPtr pWin;
732: ClientPtr client;
733: {
734: WindowPtr pChild, pSib;
735: xEvent event;
736:
737: if ((pChild = pWin->lastChild) == (WindowPtr) NULL)
738: return;
739: while (pChild)
740: {
741: pSib = pChild->prevSib;
742: /* a little lazy evaluation, don't send exposes until all deleted */
743: if (pSib != (WindowPtr) NULL)
744: {
745: event.u.u.type = UnmapNotify;
746: event.u.unmapNotify.window = pWin->wid;
747: event.u.unmapNotify.fromConfigure = xFalse;
748: DeliverEvents(pWin, &event, 1, NullWindow);
749: }
750: else
751: {
752: pChild->nextSib = (WindowPtr)NULL;
753: UnmapWindow(pChild, HANDLE_EXPOSURES, SEND_NOTIFICATION, FALSE);
754: }
755: CrushTree(pChild->firstChild);
756:
757: event.u.u.type = DestroyNotify;
758: event.u.destroyNotify.window = pChild->wid;
759: DeliverEvents(pChild, &event, 1, NullWindow);
760:
761: FreeResource(pChild->wid, RC_CORE);
762: FreeWindowResources(pChild);
763: Xfree(pChild);
764: pChild = pSib;
765: }
766: pWin->firstChild = (WindowPtr )NULL;
767: }
768:
769:
770: /*****
771: * ChangeWindowAttributes
772: *
773: * The value-mask specifies which attributes are to be changed; the
774: * value-list contains one value for each one bit in the mask, from least
775: * to most significant bit in the mask.
776: *****/
777:
778: int
779: ChangeWindowAttributes(pWin, vmask, vlist, client)
780: WindowPtr pWin;
781: unsigned int vmask;
782: long *vlist;
783: ClientPtr client;
784: {
785: int index;
786: long *pVlist;
787: PixmapPtr pPixmap;
788: Pixmap pixID;
789: CursorPtr pCursor;
790: Cursor cursorID;
791: int result;
792: ScreenPtr pScreen;
793: unsigned int vmaskCopy = 0;
794: int error;
795:
796: if ((pWin->class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
797: return BadMatch;
798:
799: error = Success;
800: pScreen = pWin->drawable.pScreen;
801: pVlist = vlist;
802: while (vmask)
803: {
804: index = ffs(vmask) - 1;
805: vmask &= ~(index = (1 << index));
806: switch (index)
807: {
808: case CWBackPixmap:
809: pixID = (Pixmap )*pVlist;
810: pVlist++;
811: if (pixID == None)
812: {
813: (* pScreen->DestroyPixmap)(pWin->backgroundTile);
814: if (pWin->parent == (WindowPtr) NULL)
815: MakeRootTile(pWin);
816: else
817: pWin->backgroundTile = (PixmapPtr)NULL;
818: }
819: else if (pixID == ParentRelative)
820: {
821: (* pScreen->DestroyPixmap)(pWin->backgroundTile);
822: if (pWin->parent == (WindowPtr) NULL)
823: MakeRootTile(pWin);
824: else
825: pWin->backgroundTile = (PixmapPtr)ParentRelative;
826: /* Note that the parent's backgroundTile's refcnt is NOT
827: * incremented. */
828: }
829: else
830: {
831: pPixmap = (PixmapPtr)LookupID(pixID, RT_PIXMAP, RC_CORE);
832: if (pPixmap != (PixmapPtr) NULL)
833: {
834: if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
835: (pPixmap->drawable.pScreen != pScreen))
836: {
837: error = BadMatch;
838: goto PatchUp;
839: }
840: (* pScreen->DestroyPixmap)(pWin->backgroundTile);
841: pWin->backgroundTile = pPixmap;
842: pPixmap->refcnt++;
843: }
844: else
845: {
846: error = BadPixmap;
847: goto PatchUp;
848: }
849: }
850: break;
851: case CWBackPixel:
852: pWin->backgroundPixel = (CARD32 ) *pVlist;
853: (* pScreen->DestroyPixmap)(pWin->backgroundTile);
854: pWin->backgroundTile = (PixmapPtr)USE_BACKGROUND_PIXEL;
855: /* background pixel overrides background pixmap,
856: so don't let the ddx layer see both bits */
857: vmaskCopy &= ~CWBackPixmap;
858: pVlist++;
859: break;
860: case CWBorderPixmap:
861: pixID = (Pixmap ) *pVlist;
862: pVlist++;
863: if (pixID == CopyFromParent)
864: {
865: GCPtr pGC;
866: PixmapPtr parentPixmap;
867: if ((pWin->parent == (WindowPtr) NULL) || (pWin->parent &&
868: (pWin->drawable.depth !=
869: pWin->parent->drawable.depth)))
870: {
871: error = BadMatch;
872: goto PatchUp;
873: }
874: (* pScreen->DestroyPixmap)(pWin->borderTile);
875: parentPixmap = pWin->parent->borderTile;
876: if (parentPixmap == (PixmapPtr)USE_BORDER_PIXEL)
877: {
878: pWin->borderTile = (PixmapPtr)USE_BORDER_PIXEL;
879: pWin->borderPixel = pWin->parent->borderPixel;
880: }
881: else
882: {
883: CARD32 attribute;
884:
885: pPixmap = (* pWin->drawable.pScreen->CreatePixmap)
886: (pWin->drawable.pScreen, parentPixmap->width,
887: parentPixmap->height, pWin->drawable.depth);
888: pGC = GetScratchGC(pWin->drawable.depth,
889: pWin->drawable.pScreen);
890:
891: attribute = GXcopy;
892: ChangeGC(pGC, GCFunction, &attribute, 1);
893: ValidateGC(pPixmap, pGC);
894:
895: (* pGC->CopyArea)(parentPixmap, pPixmap, pGC, 0, 0,
896: parentPixmap->width,
897: parentPixmap->height,
898: pWin->drawable.depth,
899: 0, 0);
900: pWin->borderTile = pPixmap;
901: FreeScratchGC(pGC);
902: }
903: }
904: else
905: {
906: pPixmap = (PixmapPtr)LookupID(pixID, RT_PIXMAP, RC_CORE);
907: if (pPixmap)
908: {
909: if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
910: (pPixmap->drawable.pScreen != pScreen))
911: {
912: error = BadMatch;
913: goto PatchUp;
914: }
915: (* pScreen->DestroyPixmap)(pWin->borderTile);
916: pWin->borderTile = pPixmap;
917: pPixmap->refcnt++;
918: }
919: else
920: {
921: error = BadPixmap;
922: goto PatchUp;
923: }
924: }
925: break;
926: case CWBorderPixel:
927: pWin->borderPixel = (CARD32) *pVlist;
928: (* pScreen->DestroyPixmap)(pWin->borderTile);
929: pWin->borderTile = (PixmapPtr)USE_BORDER_PIXEL;
930: /* border pixel overrides border pixmap,
931: so don't let the ddx layer see both bits */
932: vmaskCopy &= ~CWBorderPixmap;
933: pVlist++;
934: break;
935: case CWBitGravity:
936: pWin->bitGravity = (CARD8 )*pVlist;
937: pVlist++;
938: break;
939: case CWWinGravity:
940: pWin->winGravity = (CARD8 )*pVlist;
941: pVlist++;
942: break;
943: case CWBackingStore:
944: pWin->backingStore = (CARD8 )*pVlist;
945: pVlist++;
946: break;
947: case CWBackingPlanes:
948: pWin->backingBitPlanes = (CARD32) *pVlist;
949: pVlist++;
950: break;
951: case CWBackingPixel:
952: pWin->backingPixel = (CARD32)*pVlist;
953: pVlist++;
954: break;
955: case CWSaveUnder:
956: pWin->saveUnder = (Bool) *pVlist;
957: pVlist++;
958: break;
959: case CWEventMask:
960: result = EventSelectForWindow(pWin, client, (long )*pVlist);
961: if (result)
962: {
963: error = result;
964: goto PatchUp;
965: }
966: pVlist++;
967: break;
968: case CWDontPropagate:
969: result = EventSuppressForWindow(pWin, client, (long )*pVlist);
970: if (result)
971: {
972: error = result;
973: goto PatchUp;
974: }
975: pVlist++;
976: break;
977: case CWOverrideRedirect:
978: pWin->overrideRedirect = (Bool ) *pVlist;
979: pVlist++;
980: break;
981: case CWColormap:
982: {
983: Colormap cmap;
984: ColormapPtr pCmap;
985: xEvent xE;
986: WindowPtr pWinT;
987:
988: cmap = (Colormap ) *pVlist;
989: pWinT = pWin;
990: while(cmap == CopyFromParent)
991: {
992: if(pWinT->parent)
993: {
994: if (pWinT->parent->colormap != CopyFromParent)
995: {
996: cmap = pWinT->parent->colormap;
997: }
998: else
999: pWinT = pWinT->parent;
1000: }
1001: else
1002: {
1003: error = BadMatch;
1004: goto PatchUp;
1005: }
1006: }
1007: pCmap = (ColormapPtr)LookupID(cmap, RT_COLORMAP, RC_CORE);
1008: if (pCmap)
1009: {
1010: if (pCmap->pVisual->vid == pWin->visual)
1011: {
1012: pWin->colormap = (Colormap ) cmap;
1013: xE.u.u.type = ColormapNotify;
1014: xE.u.colormap.new = TRUE;
1015: xE.u.colormap.state = IsMapInstalled(cmap, pWin);
1016: TraverseTree(pWin, TellNewMap, &xE);
1017: }
1018: else
1019: {
1020: error = BadMatch;
1021: goto PatchUp;
1022: }
1023: }
1024: else
1025: {
1026: error = BadColor;
1027: goto PatchUp;
1028: }
1029: pVlist++;
1030: break;
1031: }
1032: case CWCursor:
1033: cursorID = (Cursor ) *pVlist;
1034: pVlist++;
1035: /*
1036: * install the new
1037: */
1038: if ( cursorID == None)
1039: {
1040: if ( pWin->cursor != None)
1041: FreeCursor( pWin->cursor);
1042: if (pWin == &WindowTable[pWin->drawable.pScreen->myNum])
1043: MakeRootCursor( pWin);
1044: else
1045: pWin->cursor = (CursorPtr)None;
1046: }
1047: else
1048: {
1049: pCursor = (CursorPtr)LookupID(cursorID, RT_CURSOR, RC_CORE);
1050: if (pCursor)
1051: {
1052: if ( pWin->cursor != None)
1053: FreeCursor( pWin->cursor);
1054: pWin->cursor = pCursor;
1055: pWin->cursor->refcnt++;
1056: }
1057: else
1058: {
1059: error = BadCursor;
1060: goto PatchUp;
1061: }
1062: }
1063: WindowHasNewCursor( pWin);
1064: break;
1065: default: break;
1066: }
1067: vmaskCopy |= index;
1068: }
1069: PatchUp:
1070: /* We SHOULD check for an error value here XXX */
1071: (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
1072:
1073: /*
1074: If the border pixel changed, redraw the border.
1075: Note that this has to be done AFTER pScreen->ChangeWindowAttributes
1076: for the tile to be rotated, and the correct function selected.
1077: */
1078: if ((vmaskCopy & (CWBorderPixel | CWBorderPixmap))
1079: && pWin->viewable && pWin->borderWidth)
1080: {
1081: (* pScreen->Subtract)(pWin->borderExposed, pWin->borderClip,
1082: pWin->winSize);
1083: (*pWin->PaintWindowBorder)(pWin, pWin->borderExposed, PW_BORDER);
1084: (* pScreen->RegionEmpty)(pWin->borderExposed);
1085: }
1086: return error;
1087: }
1088:
1089:
1090: /*****
1091: * GetWindowAttributes
1092: * Notice that this is different than ChangeWindowAttributes
1093: *****/
1094:
1095: GetWindowAttributes(pWin, client)
1096: WindowPtr pWin;
1097: ClientPtr client;
1098: {
1099: xGetWindowAttributesReply wa;
1100: WindowPtr pWinT;
1101:
1102: wa.type = X_Reply;
1103: wa.bitGravity = pWin->bitGravity;
1104: wa.winGravity = pWin->winGravity;
1105: wa.backingStore = pWin->backingStore;
1106: wa.length = (sizeof(xGetWindowAttributesReply) -
1107: sizeof(xGenericReply)) >> 2;
1108: wa.sequenceNumber = client->sequence;
1109: wa.backingBitPlanes = pWin->backingBitPlanes;
1110: wa.backingPixel = pWin->backingPixel;
1111: wa.saveUnder = (BOOL)pWin->saveUnder;
1112: wa.override = pWin->overrideRedirect;
1113: if (!pWin->mapped)
1114: wa.mapState = IsUnmapped;
1115: else if (pWin->realized)
1116: wa.mapState = IsViewable;
1117: else
1118: wa.mapState = IsUnviewable;
1119:
1120: pWinT = pWin;
1121: while (pWinT->colormap == (Colormap)CopyFromParent)
1122: pWinT = pWinT->parent;
1123: wa.colormap = pWinT->colormap;
1124: wa.mapInstalled = IsMapInstalled(wa.colormap, pWin);
1125:
1126: wa.yourEventMask = EventMaskForClient(pWin, client, &wa.allEventMasks);
1127: wa.doNotPropagateMask = pWin->dontPropagateMask ;
1128: wa.class = pWin->class;
1129: wa.visualID = pWin->visual;
1130:
1131: WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
1132: }
1133:
1134:
1135: static WindowPtr
1136: MoveWindowInStack(pWin, pNextSib)
1137: WindowPtr pWin, pNextSib;
1138: {
1139: WindowPtr pParent = pWin->parent;
1140: WindowPtr pFirstChange = pWin; /* highest window where list changes */
1141:
1142: if (pWin->nextSib != pNextSib)
1143: {
1144: if (!pNextSib) /* move to bottom */
1145: {
1146: if (pParent->firstChild == pWin)
1147: pParent->firstChild = pWin->nextSib;
1148: /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL
1149: * and pWin->nextSib != pNextSib
1150: * therefore pWin->nextSib != NULL */
1151: pFirstChange = pWin->nextSib;
1152: pWin->nextSib->prevSib = pWin->prevSib;
1153: /* else pFirstChange = pWin; */
1154: if (pWin->prevSib)
1155: pWin->prevSib->nextSib = pWin->nextSib;
1156: pParent->lastChild->nextSib = pWin;
1157: pWin->prevSib = pParent->lastChild;
1158: pWin->nextSib = (WindowPtr )NULL;
1159: pParent->lastChild = pWin;
1160: }
1161: else if (pParent->firstChild == pNextSib) /* move to top */
1162: {
1163: pFirstChange = pWin;
1164: if (pParent->lastChild == pWin)
1165: pParent->lastChild = pWin->prevSib;
1166: if (pWin->nextSib)
1167: pWin->nextSib->prevSib = pWin->prevSib;
1168: if (pWin->prevSib)
1169: pWin->prevSib->nextSib = pWin->nextSib;
1170: pWin->nextSib = pParent->firstChild;
1171: pWin->prevSib = (WindowPtr ) NULL;
1172: pNextSib->prevSib = pWin;
1173: pParent->firstChild = pWin;
1174: }
1175: else /* move in middle of list */
1176: {
1177: WindowPtr pOldNext = pWin->nextSib;
1178:
1179: pFirstChange = (WindowPtr )NULL;
1180: if (pParent->firstChild == pWin)
1181: pFirstChange = pParent->firstChild = pWin->nextSib;
1182: if (pParent->lastChild == pWin) {
1183: pFirstChange = pWin;
1184: pParent->lastChild = pWin->prevSib;
1185: }
1186: if (pWin->nextSib)
1187: pWin->nextSib->prevSib = pWin->prevSib;
1188: if (pWin->prevSib)
1189: pWin->prevSib->nextSib = pWin->nextSib;
1190: pWin->nextSib = pNextSib;
1191: pWin->prevSib = pNextSib->prevSib;
1192: if (pNextSib->prevSib)
1193: pNextSib->prevSib->nextSib = pWin;
1194: pNextSib->prevSib = pWin;
1195: if (!pFirstChange) { /* do we know it yet? */
1196: pFirstChange = pParent->firstChild; /* no, search from top */
1197: while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
1198: pFirstChange = pFirstChange->nextSib;
1199: }
1200: }
1201: }
1202:
1203: return( pFirstChange );
1204: }
1205:
1206: static void
1207: MoveWindow(pWin, x, y, pNextSib)
1208: WindowPtr pWin;
1209: short x,y;
1210: WindowPtr pNextSib;
1211: {
1212: WindowPtr pParent;
1213: Bool WasMapped = (Bool)(pWin->realized);
1214: BoxRec box;
1215: short oldx, oldy, bw;
1216: RegionPtr oldRegion;
1217: DDXPointRec oldpt;
1218: Bool anyMarked;
1219: register ScreenPtr pScreen;
1220: BoxPtr pBox;
1221: WindowPtr windowToValidate = pWin;
1222:
1223: /* if this is a root window, can't be moved */
1224: if (!(pParent = pWin->parent))
1225: return ;
1226: pScreen = pWin->drawable.pScreen;
1227: bw = pWin->borderWidth;
1228:
1229: oldx = pWin->absCorner.x;
1230: oldy = pWin->absCorner.y;
1231: oldpt.x = oldx;
1232: oldpt.y = oldy;
1233: if (WasMapped)
1234: {
1235: oldRegion = (* pScreen->RegionCreate)(NULL, 1);
1236: (* pScreen->RegionCopy)(oldRegion, pWin->borderClip);
1237: pBox = (* pScreen->RegionExtents)(pWin->borderSize);
1238: anyMarked = MarkSiblingsBelowMe(pWin, pBox);
1239: }
1240: pWin->clientWinSize.x = x + bw;
1241: pWin->clientWinSize.y = y + bw;
1242: pWin->oldAbsCorner.x = oldx;
1243: pWin->oldAbsCorner.y = oldy;
1244: pWin->absCorner.x = pParent->absCorner.x + x +bw;
1245: pWin->absCorner.y = pParent->absCorner.y + y + bw;
1246:
1247: box.x1 = pWin->absCorner.x;
1248: box.y1 = pWin->absCorner.y;
1249: box.x2 = box.x1 + pWin->clientWinSize.width;
1250: box.y2 = box.y1+ pWin->clientWinSize.height;
1251: (* pScreen->RegionReset)(pWin->winSize, &box);
1252: (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize);
1253:
1254: if (bw)
1255: {
1256: box.x1 -= bw;
1257: box.y1 -= bw;
1258: box.x2 += bw;
1259: box.y2 += bw;
1260: (* pScreen->RegionReset)(pWin->borderSize, &box);
1261: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize,
1262: pParent->winSize);
1263: }
1264: else
1265: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize);
1266:
1267: (* pScreen->PositionWindow)(pWin,pWin->absCorner.x, pWin->absCorner.y);
1268:
1269: windowToValidate = MoveWindowInStack(pWin, pNextSib);
1270:
1271: ResizeChildrenWinSize(pWin, FALSE, 0, 0, DONT_USE_GRAVITY);
1272: if (WasMapped)
1273: {
1274:
1275: anyMarked = MarkSiblingsBelowMe(windowToValidate, pBox) || anyMarked;
1276:
1277: (* pScreen->ValidateTree)(pParent, (WindowPtr)NULL, TRUE, anyMarked);
1278:
1279: DoObscures(pParent);
1280: if (pWin->backgroundTile == (PixmapPtr)ParentRelative)
1281: (* pScreen->RegionCopy)(pWin->exposed, pWin->clipList);
1282: else
1283: {
1284: /*
1285: * Why subtract borderSize from parent's exposures? parent
1286: * exposures aren't supposed to extend into children!
1287: */
1288: (* pWin->CopyWindow)(pWin, oldpt, oldRegion);
1289: (* pScreen->Subtract)(pParent->exposed, pParent->exposed,
1290: pWin->borderSize);
1291:
1292: }
1293: (* pScreen->RegionDestroy)(oldRegion);
1294: HandleExposures(pParent);
1295: }
1296: }
1297:
1298: static void
1299: ResizeChildrenWinSize(pWin, XYSame, dw, dh, useGravity)
1300: WindowPtr pWin;
1301: Bool XYSame;
1302: int dw, dh;
1303: Bool useGravity;
1304: {
1305: WindowPtr pSib;
1306: RegionPtr parentReg;
1307: BoxRec box;
1308: register short x, y, cwsx, cwsy;
1309: Bool unmap = FALSE;
1310: register ScreenPtr pScreen;
1311: xEvent event;
1312:
1313: pScreen = pWin->drawable.pScreen;
1314: parentReg = pWin->winSize;
1315: pSib = pWin->firstChild;
1316: x = pWin->absCorner.x;
1317: y = pWin->absCorner.y;
1318:
1319: while (pSib)
1320: {
1321: cwsx = pSib->clientWinSize.x;
1322: cwsy = pSib->clientWinSize.y;
1323: if (useGravity == USE_GRAVITY)
1324: {
1325: switch (pSib->winGravity)
1326: {
1327: case UnmapGravity:
1328: unmap = TRUE;
1329: case NorthWestGravity:
1330: break;
1331: case NorthGravity:
1332: cwsx += dw/2;
1333: break;
1334: case NorthEastGravity:
1335: cwsx += dw;
1336: break;
1337: case WestGravity:
1338: cwsy += dh/2;
1339: break;
1340: case CenterGravity:
1341: cwsx += dw/2;
1342: cwsy += dh/2;
1343: break;
1344: case EastGravity:
1345: cwsx += dw;
1346: cwsy += dh/2;
1347: break;
1348: case SouthWestGravity:
1349: cwsy += dh;
1350: break;
1351: case SouthGravity:
1352: cwsx += dw/2;
1353: cwsy += dh;
1354: break;
1355: case SouthEastGravity:
1356: cwsx += dw;
1357: cwsy += dh;
1358: break;
1359: case StaticGravity: /* XXX */
1360: break;
1361: default:
1362: break;
1363: }
1364: }
1365:
1366: event.u.u.type = GravityNotify;
1367: event.u.gravity.window = pSib->wid;
1368: event.u.gravity.x = cwsx;
1369: event.u.gravity.y = cwsy;
1370: DeliverEvents (pSib, &event, 1, NullWindow);
1371:
1372: box.x1 = x + cwsx;
1373: box.y1 = y + cwsy;
1374: box.x2 = box.x1 + pSib->clientWinSize.width;
1375: box.y2 = box.y1 + pSib->clientWinSize.height;
1376:
1377: pSib->oldAbsCorner.x = pSib->absCorner.x;
1378: pSib->oldAbsCorner.y = pSib->absCorner.y;
1379: pSib->absCorner.x = x + cwsx;
1380: pSib->absCorner.y = y + cwsy;
1381:
1382: (* pScreen->RegionReset)(pSib->winSize, &box);
1383: (* pScreen->Intersect)(pSib->winSize, pSib->winSize,
1384: parentReg);
1385:
1386: if (pSib->borderWidth)
1387: {
1388: box.x1 -= pSib->borderWidth;
1389: box.y1 -= pSib->borderWidth;
1390: box.x2 += pSib->borderWidth;
1391: box.y2 += pSib->borderWidth;
1392: (* pScreen->RegionReset)(pSib->borderSize, &box);
1393: (* pScreen->Intersect)(pSib->borderSize,
1394: pSib->borderSize, parentReg);
1395: }
1396: else
1397: (* pScreen->RegionCopy)(pSib->borderSize, pSib->winSize);
1398: (* pScreen->PositionWindow)(pSib, pSib->absCorner.x, pSib->absCorner.y);
1399: pSib->marked = 1;
1400: if (pSib->firstChild)
1401: ResizeChildrenWinSize(pSib, XYSame, 0, 0, DONT_USE_GRAVITY);
1402: if (unmap)
1403: {
1404: UnmapWindow(pSib, DONT_HANDLE_EXPOSURES, SEND_NOTIFICATION, TRUE);
1405: unmap = FALSE;
1406: }
1407: pSib = pSib->nextSib;
1408: }
1409: }
1410:
1411: static int
1412: ExposeAll(pWin, pScreen)
1413: WindowPtr pWin;
1414: ScreenPtr pScreen;
1415: {
1416: if (!pWin)
1417: return(WT_NOMATCH);
1418: if (pWin->mapped)
1419: {
1420: (* pScreen->RegionCopy)(pWin->exposed, pWin->clipList);
1421: return (WT_WALKCHILDREN);
1422: }
1423: else
1424: return(WT_NOMATCH);
1425: }
1426:
1427:
1428:
1429: static void
1430: SlideAndSizeWindow(pWin, x, y, w, h, pSib)
1431: WindowPtr pWin;
1432: short x,y;
1433: unsigned short w, h;
1434: WindowPtr pSib;
1435: {
1436: WindowPtr pParent;
1437: Bool WasMapped = (Bool)(pWin->realized);
1438: BoxRec box;
1439: unsigned short width = pWin->clientWinSize.width,
1440: height = pWin->clientWinSize.height;
1441: short oldx = pWin->absCorner.x,
1442: oldy = pWin->absCorner.y,
1443: bw = pWin->borderWidth;
1444: short dw, dh;
1445: Bool XYSame = FALSE;
1446: DDXPointRec oldpt;
1447: RegionPtr oldRegion;
1448: Bool anyMarked;
1449: register ScreenPtr pScreen;
1450: BoxPtr pBox;
1451: WindowPtr pFirstChange;
1452:
1453: /* if this is a root window, can't be resized */
1454: if (!(pParent = pWin->parent))
1455: return ;
1456:
1457: pScreen = pWin->drawable.pScreen;
1458: if (WasMapped)
1459: {
1460: if ((pWin->bitGravity != ForgetGravity) ||
1461: (pWin->backgroundTile == (PixmapPtr)ParentRelative))
1462: oldRegion = NotClippedByChildren(pWin);
1463: pBox = (* pScreen->RegionExtents)(pWin->borderSize);
1464: anyMarked = MarkSiblingsBelowMe(pWin, pBox);
1465: }
1466: pWin->clientWinSize.x = x + bw;
1467: pWin->clientWinSize.y = y + bw;
1468: pWin->clientWinSize.height = h;
1469: pWin->clientWinSize.width = w;
1470: XYSame = ((pParent->absCorner.x + x == pWin->absCorner.x)
1471: && (pParent->absCorner.y + y == pWin->absCorner.y));
1472: pWin->oldAbsCorner.x = oldx;
1473: pWin->oldAbsCorner.y = oldy;
1474: oldpt.x = oldx;
1475: oldpt.y = oldy;
1476:
1477: pWin->absCorner.x = pParent->absCorner.x + x + bw;
1478: pWin->absCorner.y = pParent->absCorner.y + y + bw;
1479:
1480: box.x1 = pWin->absCorner.x;
1481: box.y1 = pWin->absCorner.y;
1482: box.x2 = pWin->absCorner.x + w;
1483: box.y2 = pWin->absCorner.y + h;
1484: (* pScreen->RegionReset)(pWin->winSize, &box);
1485: (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize);
1486:
1487: if (pWin->borderWidth)
1488: {
1489: box.x1 -= bw;
1490: box.y1 -= bw;
1491: box.x2 += bw;
1492: box.y2 += bw;
1493: (* pScreen->RegionReset)(pWin->borderSize, &box);
1494: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize,
1495: pParent->winSize);
1496: }
1497: else
1498: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize);
1499:
1500: dw = w - width;
1501: dh = h - height;
1502: ResizeChildrenWinSize(pWin, XYSame, dw, dh, USE_GRAVITY);
1503:
1504: /* let the hardware adjust background and border pixmaps, if any */
1505: (* pScreen->PositionWindow)(pWin, pWin->absCorner.x, pWin->absCorner.y);
1506:
1507: pFirstChange = MoveWindowInStack(pWin, pSib);
1508:
1509: if (WasMapped)
1510: {
1511: RegionPtr pRegion;
1512:
1513: anyMarked = MarkSiblingsBelowMe(pFirstChange, pBox) || anyMarked;
1514:
1515: if ((pWin->bitGravity == ForgetGravity) ||
1516: (pWin->backgroundTile == (PixmapPtr)ParentRelative))
1517: {
1518: (* pScreen->ValidateTree)(pParent, pFirstChange, TRUE, anyMarked);
1519: /* CopyWindow will step on borders, so re-paint them */
1520: (* pScreen->Subtract)(pWin->borderExposed,
1521: pWin->borderClip, pWin->winSize);
1522: TraverseTree(pWin, ExposeAll, pScreen);
1523: DoObscures(pParent);
1524: HandleExposures(pParent);
1525: }
1526: else
1527: {
1528: pRegion = (* pScreen->RegionCreate)(NULL, 1);
1529: (* pScreen->RegionCopy)(pRegion, pWin->clipList);
1530:
1531: x = pWin->absCorner.x;
1532: y = pWin->absCorner.y;
1533: switch (pWin->bitGravity)
1534: {
1535: case NorthWestGravity:
1536: break;
1537: case NorthGravity:
1538: x += dw/2;
1539: break;
1540: case NorthEastGravity:
1541: x += dw;
1542: break;
1543: case WestGravity:
1544: y += dh/2;
1545: break;
1546: case CenterGravity:
1547: x += dw/2;
1548: y += dh/2;
1549: break;
1550: case EastGravity:
1551: x += dw;
1552: y += dh/2;
1553: break;
1554: case SouthWestGravity:
1555: y += dh;
1556: break;
1557: case SouthGravity:
1558: x += dw/2;
1559: y += dh;
1560: break;
1561: case SouthEastGravity:
1562: x += dw;
1563: y += dh;
1564: break;
1565: case StaticGravity:
1566: x = oldx;
1567: y = oldy;
1568: break;
1569: default:
1570: break;
1571: }
1572:
1573: (* pScreen->ValidateTree)(pParent, pFirstChange, TRUE, anyMarked);
1574: DoObscures(pParent);
1575: if (pWin->backStorage && (pWin->backingStore != NotUseful))
1576: {
1577: ErrorF("Going to translate backing store %d %d\n",
1578: oldx - x, oldy - y);
1579: (* pWin->backStorage->TranslateBackingStore) (pWin,
1580: oldx - x, oldy - y);
1581: }
1582: oldpt.x = oldx - x + pWin->absCorner.x;
1583: oldpt.y = oldy - y + pWin->absCorner.y;
1584: (* pWin->CopyWindow)(pWin, oldpt, oldRegion);
1585:
1586:
1587: /* Note that oldRegion is *translated* by CopyWindow */
1588:
1589: /*
1590: * We've taken care of those spots in oldRegion so they needn't
1591: * be re-exposed...
1592: */
1593: (* pScreen->Subtract)(pWin->exposed, pWin->clipList, oldRegion);
1594: (* pScreen->RegionDestroy)(pRegion);
1595:
1596: /* CopyWindow will step on borders, so repaint them */
1597: (* pScreen->Subtract)(pWin->borderExposed,
1598: pWin->borderClip, pWin->winSize);
1599:
1600: HandleExposures(pParent);
1601: (* pScreen->RegionDestroy)(oldRegion);
1602: }
1603: }
1604: }
1605:
1606: static void
1607: ChangeBorderWidth(pWin, width)
1608: WindowPtr pWin;
1609: int width;
1610: {
1611: WindowPtr pParent;
1612: BoxRec box;
1613: BoxPtr pBox;
1614: int oldwidth;
1615: Bool anyMarked;
1616: register ScreenPtr pScreen;
1617: RegionPtr oldRegion;
1618: DDXPointRec oldpt;
1619: Bool WasMapped = (Bool)(pWin->realized);
1620:
1621: oldwidth = pWin->borderWidth;
1622: if (oldwidth == width)
1623: return ;
1624: pScreen = pWin->drawable.pScreen;
1625: pParent = pWin->parent;
1626: pWin->borderWidth = width;
1627:
1628: oldpt.x = pWin->absCorner.x;
1629: oldpt.y = pWin->absCorner.y;
1630: pWin->oldAbsCorner.x = oldpt.x;
1631: pWin->oldAbsCorner.y = oldpt.y;
1632:
1633: pWin->clientWinSize.x += width - oldwidth;
1634: pWin->clientWinSize.y += width - oldwidth;
1635: pWin->absCorner.x += width - oldwidth;
1636: pWin->absCorner.y += width - oldwidth;
1637:
1638: if (WasMapped)
1639: {
1640: oldRegion = (* pScreen->RegionCreate)(NULL, 1);
1641: (* pScreen->RegionCopy)(oldRegion, pWin->borderClip);
1642: }
1643:
1644:
1645: box.x1 = pWin->absCorner.x;
1646: box.y1 = pWin->absCorner.y;
1647: box.x2 = box.x1 + pWin->clientWinSize.width;
1648: box.y2 = box.y1 + pWin->clientWinSize.height;
1649: (* pScreen->RegionReset)(pWin->winSize, &box);
1650: (* pScreen->Intersect)(pWin->winSize, pWin->winSize, pParent->winSize);
1651:
1652: if (width)
1653: {
1654: box.x1 -= width;
1655: box.y1 -= width;
1656: box.x2 += width;
1657: box.y2 += width;
1658: (* pScreen->RegionReset)(pWin->borderSize, &box);
1659: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize,
1660: pParent->winSize);
1661: }
1662: else
1663: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize);
1664:
1665: if (WasMapped)
1666: {
1667: if (width < oldwidth)
1668: pBox = (* pScreen->RegionExtents)(oldRegion);
1669: else
1670: pBox = (* pScreen->RegionExtents)(pWin->borderSize);
1671: anyMarked = MarkSiblingsBelowMe(pWin, pBox);
1672:
1673: (* pScreen->ValidateTree)(pParent,(anyMarked ? pWin : (WindowPtr)NULL),
1674: TRUE, anyMarked );
1675:
1676: (* pWin->CopyWindow)(pWin, oldpt, oldRegion);
1677:
1678: if (width > oldwidth)
1679: {
1680: DoObscures(pParent);
1681: (* pScreen->Subtract)(pWin->borderExposed,
1682: pWin->borderClip, pWin->winSize);
1683: (* pWin->PaintWindowBorder)(pWin, pWin->borderExposed, PW_BORDER);
1684: (* pScreen->RegionEmpty)(pWin->borderExposed);
1685: }
1686: else if (oldwidth > width)
1687: HandleExposures(pParent);
1688:
1689: (* pScreen->RegionDestroy)(oldRegion);
1690:
1691: }
1692: }
1693:
1694:
1695: #define GET_INT16(m, f) \
1696: if (m & mask) \
1697: { \
1698: f = (short) *pVlist;\
1699: pVlist++; \
1700: }
1701: #define GET_CARD16(m, f) \
1702: if (m & mask) \
1703: { \
1704: f = (CARD16) *pVlist;\
1705: pVlist++;\
1706: }
1707:
1708: #define GET_CARD8(m, f) \
1709: if (m & mask) \
1710: { \
1711: f = (CARD8) *pVlist;\
1712: pVlist++;\
1713: }
1714:
1715: #define ChangeMask (CWX | CWY | CWWidth | CWHeight)
1716:
1717: #define IllegalInputOnlyConfigureMask (CWBorderWidth)
1718:
1719: /*
1720: * IsSiblingAboveMe
1721: * returns Above if pSib above pMe in stack or Below otherwise
1722: */
1723:
1724: static int
1725: IsSiblingAboveMe(pMe, pSib)
1726: WindowPtr pMe, pSib;
1727: {
1728: WindowPtr pWin;
1729:
1730: pWin = pMe->parent->firstChild;
1731: while (pWin)
1732: {
1733: if (pWin == pSib)
1734: return(Above);
1735: else if (pWin == pMe)
1736: return(Below);
1737: pWin = pWin->nextSib;
1738: }
1739: return(Below);
1740: }
1741:
1742: static Bool
1743: AnyWindowOverlapsMe(pWin, box)
1744: WindowPtr pWin;
1745: BoxPtr box;
1746: {
1747: WindowPtr pSib;
1748: register ScreenPtr pScreen;
1749:
1750: pSib = pWin->parent->firstChild;
1751: pScreen = pWin->drawable.pScreen;
1752: while (pSib)
1753: {
1754: if (pSib == pWin)
1755: return(FALSE);
1756: else if ((pSib->mapped) &&
1757: ((* pScreen->RectIn)(pSib->borderSize, box) != rgnOUT))
1758: return(TRUE);
1759: pSib = pSib->nextSib;
1760: }
1761: return(FALSE);
1762: }
1763:
1764: static WindowPtr
1765: IOverlapAnyWindow(pWin, box)
1766: WindowPtr pWin;
1767: BoxPtr box;
1768: {
1769: WindowPtr pSib;
1770: register ScreenPtr pScreen;
1771:
1772: pScreen = pWin->drawable.pScreen;
1773: pSib = pWin->nextSib;
1774: while (pSib)
1775: {
1776: if ((pSib->mapped) &&
1777: ((* pScreen->RectIn)(pSib->borderSize, box) != rgnOUT))
1778: return(pSib);
1779: pSib = pSib->nextSib;
1780: }
1781: return((WindowPtr )NULL);
1782: }
1783:
1784: /*
1785: * WhereDoIGoInTheStack()
1786: * Given pWin and pSib and the relationshipe smode, return
1787: * the window that pWin should go ABOVE.
1788: * If a pSib is specified:
1789: * Above: pWin is placed just above pSib
1790: * Below: pWin is placed just below pSib
1791: * TopIf: if pSib occludes pWin, then pWin is placed
1792: * at the top of the stack
1793: * BottomIf: if pWin occludes pSib, then pWin is
1794: * placed at the bottom of the stack
1795: * Opposite: if pSib occludes pWin, then pWin is placed at the
1796: * top of the stack, else if pWin occludes pSib, then
1797: * pWin is placed at the bottom of the stack
1798: *
1799: * If pSib is NULL:
1800: * Above: pWin is placed at the top of the stack
1801: * Below: pWin is placed at the bottom of the stack
1802: * TopIf: if any sibling occludes pWin, then pWin is placed at
1803: * the top of the stack
1804: * BottomIf: if pWin occludes any sibline, then pWin is placed at
1805: * the bottom of the stack
1806: * Opposite: if any sibling occludes pWin, then pWin is placed at
1807: * the top of the stack, else if pWin occludes any
1808: * sibling, then pWin is placed at the bottom of the stack
1809: *
1810: */
1811:
1812: static WindowPtr
1813: WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode)
1814: WindowPtr pWin, pSib;
1815: short x, y, w, h;
1816: int smode;
1817: {
1818: BoxRec box;
1819: register ScreenPtr pScreen;
1820:
1821: if ((pWin == pWin->parent->firstChild) &&
1822: (pWin == pWin->parent->lastChild))
1823: return((WindowPtr ) NULL);
1824: pScreen = pWin->drawable.pScreen;
1825: box.x1 = x;
1826: box.y1 = y;
1827: box.x2= x + w;
1828: box.y2 = y + h;
1829: switch (smode)
1830: {
1831: case Above:
1832: if (pSib)
1833: return(pSib);
1834: else if (pWin == pWin->parent->firstChild)
1835: return(pWin->nextSib);
1836: else
1837: return(pWin->parent->firstChild);
1838: case Below:
1839: if (pSib)
1840: if (pSib->nextSib != pWin)
1841: return(pSib->nextSib);
1842: else
1843: return(pWin->nextSib);
1844: else
1845: return((WindowPtr )NULL);
1846: case TopIf:
1847: if (pSib)
1848: {
1849: if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
1850: ((* pScreen->RectIn)(pSib->borderSize, &box) != rgnOUT))
1851: return(pWin->parent->firstChild);
1852: else
1853: return(pWin->nextSib);
1854: }
1855: else if (AnyWindowOverlapsMe(pWin, &box))
1856: return(pWin->parent->firstChild);
1857: else
1858: return(pWin->nextSib);
1859: case BottomIf:
1860: if (pSib)
1861: {
1862: if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
1863: ((* pScreen->RectIn)(pSib->borderSize, &box) != rgnOUT))
1864: return(WindowPtr)NULL;
1865: else
1866: return(pWin->nextSib);
1867: }
1868: else if (IOverlapAnyWindow(pWin, &box))
1869: return((WindowPtr)NULL);
1870: else
1871: return(pWin->nextSib);
1872: case Opposite:
1873: if (pSib)
1874: {
1875: if ((* pScreen->RectIn)(pSib->borderSize, &box) != rgnOUT)
1876: {
1877: if (IsSiblingAboveMe(pWin, pSib) == Above)
1878: return(pWin->parent->firstChild);
1879: else
1880: return((WindowPtr)NULL);
1881: }
1882: else
1883: return(pWin->nextSib);
1884: }
1885: else if (AnyWindowOverlapsMe(pWin, &box))
1886: {
1887: /* If I'm occluded, I can't possibly be the first child
1888: * if (pWin == pWin->parent->firstChild)
1889: * return pWin->nextSib;
1890: */
1891: return(pWin->parent->firstChild);
1892: }
1893: else if (IOverlapAnyWindow(pWin, &box))
1894: return((WindowPtr)NULL);
1895: else
1896: return pWin->nextSib;
1897: default:
1898: {
1899: ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
1900: return((WindowPtr)pWin->nextSib);
1901: }
1902: }
1903: }
1904:
1905: static void
1906: ReflectStackChange(pWin, pSib)
1907: WindowPtr pWin, pSib;
1908: {
1909: /* Note that pSib might be NULL */
1910:
1911: Bool doValidation = (Bool)pWin->realized;
1912: WindowPtr pParent;
1913: int anyMarked;
1914: BoxPtr box;
1915: WindowPtr pFirstChange;
1916:
1917: /* if this is a root window, can't be restacked */
1918: if (!(pParent = pWin->parent))
1919: return ;
1920:
1921: pFirstChange = MoveWindowInStack(pWin, pSib);
1922:
1923: if (doValidation)
1924: {
1925: box = (* pWin->drawable.pScreen->RegionExtents)(pWin->borderSize);
1926: anyMarked = MarkSiblingsBelowMe(pFirstChange, box);
1927: (* pWin->drawable.pScreen->ValidateTree)(pParent, pFirstChange,
1928: TRUE, anyMarked);
1929: DoObscures(pParent);
1930: HandleExposures(pParent);
1931: }
1932: }
1933:
1934: /*****
1935: * ConfigureWindow
1936: *****/
1937:
1938:
1939: int
1940: ConfigureWindow(pWin, mask, vlist, client)
1941: WindowPtr pWin;
1942: unsigned long mask;
1943: long *vlist;
1944: ClientPtr client;
1945: {
1946: #define RESTACK_WIN 0
1947: #define MOVE_WIN 1
1948: #define RESIZE_WIN 2
1949: WindowPtr pSib = (WindowPtr )NULL;
1950: Window sibwid;
1951: int index, tmask;
1952: long *pVlist;
1953: short x, y, beforeX, beforeY;
1954: unsigned short w = pWin->clientWinSize.width,
1955: h = pWin->clientWinSize.height,
1956: bw = pWin->borderWidth;
1957: int action,
1958: smode = Above;
1959: xEvent event;
1960:
1961: if ((pWin->class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
1962: return(BadMatch);
1963:
1964: if ((mask & CWSibling) && !(mask & CWStackMode))
1965: return(BadMatch);
1966:
1967: pVlist = vlist;
1968:
1969: if (pWin->parent)
1970: {
1971: x = pWin->absCorner.x - pWin->parent->absCorner.x - bw;
1972: y = pWin->absCorner.y - pWin->parent->absCorner.y - bw;
1973: }
1974: else
1975: {
1976: x = pWin->absCorner.x;
1977: y = pWin->absCorner.y;
1978: }
1979: beforeX = x;
1980: beforeY = y;
1981: action = RESTACK_WIN;
1982: if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
1983: {
1984: GET_INT16(CWX, x);
1985: GET_INT16(CWY, y);
1986: action = MOVE_WIN;
1987: }
1988: /* or should be resized */
1989: else if (mask & (CWX | CWY | CWWidth | CWHeight))
1990: {
1991: GET_INT16(CWX, x);
1992: GET_INT16(CWY, y);
1993: GET_CARD16(CWWidth, w);
1994: GET_CARD16 (CWHeight, h);
1995: if (!w || !h)
1996: return BadValue;
1997: action = RESIZE_WIN;
1998: }
1999: tmask = mask & ~ChangeMask;
2000: while (tmask)
2001: {
2002: index = ffs(tmask) - 1;
2003: tmask &= ~(index = (1 << index));
2004: switch (index)
2005: {
2006: case CWBorderWidth:
2007: GET_CARD16(CWBorderWidth, bw);
2008: break;
2009: case CWSibling:
2010: sibwid = (Window ) *pVlist;
2011: pVlist++;
2012: pSib = (WindowPtr )LookupID(sibwid, RT_WINDOW, RC_CORE);
2013: if (!pSib)
2014: return(BadWindow);
2015: if (pSib->parent != pWin->parent)
2016: return(BadMatch);
2017: if (pSib == pWin)
2018: return(BadMatch);
2019: break;
2020: case CWStackMode:
2021: GET_CARD8(CWStackMode, smode);
2022: if ((smode != TopIf) && (smode != BottomIf) &&
2023: (smode != Opposite) && (smode != Above) && (smode != Below))
2024: return(BadMatch);
2025: break;
2026: default:
2027: return(BadMatch);
2028: }
2029: }
2030: /* root really can't be reconfigured, so just return */
2031: if (!pWin->parent)
2032: return Success;
2033:
2034: /* Figure out if the window should be moved. Doesnt
2035: make the changes to the window if event sent */
2036:
2037: if (mask & CWStackMode)
2038: pSib = WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode);
2039: else
2040: pSib = pWin->nextSib;
2041:
2042: if ((!pWin->overrideRedirect) &&
2043: (pWin->parent->allEventMasks & SubstructureRedirectMask))
2044: {
2045: event.u.u.type = ConfigureRequest;
2046: event.u.configureRequest.window = pWin->wid;
2047: event.u.configureRequest.parent = pWin->parent->wid;
2048: if (mask & CWSibling)
2049: event.u.configureRequest.sibling = sibwid;
2050: else
2051: event.u.configureRequest.sibling = None;
2052: if (mask & CWStackMode)
2053: event.u.u.detail = smode;
2054: else
2055: event.u.u.detail = Above;
2056: event.u.configureRequest.x = x;
2057: event.u.configureRequest.y = y;
2058: event.u.configureRequest.width = w;
2059: event.u.configureRequest.height = h;
2060: event.u.configureRequest.borderWidth = bw;
2061: event.u.configureRequest.valueMask = mask;
2062: if (MaybeDeliverEventsToClient(pWin->parent, &event, 1,
2063: SubstructureRedirectMask, client) == 1)
2064: return(Success);
2065: }
2066: if (action == RESIZE_WIN) {
2067: Bool size_change = (w != pWin->clientWinSize.width)
2068: || (h != pWin->clientWinSize.height);
2069: if (size_change && (pWin->allEventMasks & ResizeRedirectMask)) {
2070: xEvent eventT;
2071: eventT.u.u.type = ResizeRequest;
2072: eventT.u.resizeRequest.window = pWin->wid;
2073: eventT.u.resizeRequest.width = w;
2074: eventT.u.resizeRequest.height = h;
2075: if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
2076: ResizeRedirectMask, client) == 1) {
2077: /* if event is delivered, leave the actual size alone. */
2078: w = pWin->clientWinSize.width;
2079: h = pWin->clientWinSize.height;
2080: size_change = FALSE;
2081: }
2082: }
2083: if (!size_change) {
2084: if (mask & (CWX | CWY))
2085: action = MOVE_WIN;
2086: else if (mask & (CWStackMode | CWSibling | CWBorderWidth))
2087: action = RESTACK_WIN;
2088: else /* really nothing to do */
2089: return(Success) ;
2090: }
2091: }
2092:
2093: if (action == RESIZE_WIN)
2094: /* we've already checked whether there's really a size change */
2095: goto ActuallyDoSomething;
2096: if ((mask & CWX) && (x != beforeX))
2097: goto ActuallyDoSomething;
2098: if ((mask & CWY) && (y != beforeY))
2099: goto ActuallyDoSomething;
2100: if ((mask & CWBorderWidth) && (bw != pWin->borderWidth))
2101: goto ActuallyDoSomething;
2102: if (mask & CWStackMode)
2103: {
2104: if (pWin->nextSib != pSib)
2105: goto ActuallyDoSomething;
2106: }
2107: return(Success);
2108:
2109: ActuallyDoSomething:
2110: event.u.u.type = ConfigureNotify;
2111: event.u.configureNotify.window = pWin->wid;
2112: if (pSib)
2113: event.u.configureNotify.aboveSibling = pSib->wid;
2114: else
2115: event.u.configureNotify.aboveSibling = None;
2116: event.u.configureNotify.x = x;
2117: event.u.configureNotify.y = y;
2118: event.u.configureNotify.width = w;
2119: event.u.configureNotify.height = h;
2120: event.u.configureNotify.borderWidth = bw;
2121: event.u.configureNotify.override = pWin->overrideRedirect;
2122: DeliverEvents(pWin, &event, 1, NullWindow);
2123:
2124: if (mask & CWBorderWidth)
2125: {
2126: if (action == RESTACK_WIN)
2127: ChangeBorderWidth(pWin, bw);
2128: else
2129: pWin->borderWidth = bw;
2130: }
2131: if (action == MOVE_WIN)
2132: MoveWindow(pWin, x, y, pSib);
2133: else if (action == RESIZE_WIN)
2134: SlideAndSizeWindow(pWin, x, y, w, h, pSib);
2135: else if (mask & CWStackMode)
2136: ReflectStackChange(pWin, pSib);
2137:
2138: return(Success);
2139: #undef RESTACK_WIN
2140: #undef MOVE_WIN
2141: #undef RESIZE_WIN
2142: }
2143:
2144:
2145: /******
2146: *
2147: * CirculateWindow
2148: * For RaiseLowest, raises the lowest mapped child (if any) that is
2149: * obscured by another child to the top of the stack. For LowerHighest,
2150: * lowers the highest mapped child (if any) that is obscuring another
2151: * child to the bottom of the stack. Exposure processing is performed
2152: *
2153: ******/
2154:
2155: /* XXX shouldn't this be a case for the stack mode stuff?? */
2156:
2157: int
2158: CirculateWindow(pParent, direction, client)
2159: WindowPtr pParent;
2160: int direction;
2161: ClientPtr client;
2162: {
2163: WindowPtr pChild, pSib;
2164: xEvent event;
2165: register ScreenPtr pScreen;
2166:
2167: if (pParent->firstChild == pParent->lastChild)
2168: return(Success) ;
2169:
2170: pScreen = pParent->drawable.pScreen;
2171: if (direction == RaiseLowest)
2172: {
2173: pChild = pParent->lastChild;
2174: while (pChild)
2175: {
2176: if (pChild->mapped && (pChild->visibility != VisibilityUnobscured))
2177: {
2178: if (pParent->firstChild != pChild)
2179: {
2180: if (pParent->lastChild == pChild)
2181: pParent->lastChild = pChild->prevSib;
2182: if (pChild->nextSib)
2183: pChild->nextSib->prevSib = pChild->prevSib;
2184: if (pChild->prevSib)
2185: pChild->prevSib->nextSib = pChild->nextSib;
2186: pChild->nextSib = pParent->firstChild;
2187: pChild->prevSib = (WindowPtr ) NULL;
2188: pParent->firstChild->prevSib = pChild;
2189: pParent->firstChild = pChild;
2190: pChild->mapped = 0; /* to fool MapWindow */
2191: pSib = pChild;
2192: break;
2193: }
2194: return Success;
2195: }
2196: pChild = pChild->prevSib;
2197: }
2198: }
2199: else if (direction == LowerHighest)
2200: {
2201: BoxPtr pBox;
2202:
2203: pChild = pParent->firstChild;
2204: while (pChild)
2205: {
2206: if (pChild->mapped && (pChild->visibility == VisibilityUnobscured))
2207: {
2208: int result;
2209:
2210: /* HACK -- this search is n squared */
2211:
2212: pSib = pChild->nextSib;
2213:
2214: /* find a sibling that pChild overlaps */
2215:
2216: pBox = (* pScreen->RegionExtents)(pChild->borderSize);
2217: while (pSib)
2218: {
2219: if (pSib->realized && (pSib->visibility != VisibilityUnobscured))
2220: {
2221: result = (* pScreen->RectIn)(pSib->borderSize,
2222: &pBox);
2223: if (result != rgnOUT)
2224: break;
2225: }
2226: pSib = pSib->nextSib;
2227: }
2228: if (pSib)
2229: {
2230: WindowPtr pNext;
2231: pNext = pChild->nextSib;
2232: if (pParent->firstChild == pChild)
2233: pParent->firstChild = pNext;
2234: pNext->prevSib = pChild->prevSib;
2235: if (pChild->prevSib)
2236: pChild->prevSib->nextSib = pNext;
2237: pChild->nextSib = (WindowPtr ) NULL;
2238: pChild->prevSib = pParent->lastChild;
2239: pParent->lastChild->nextSib = pChild;
2240: pParent->lastChild = pChild;
2241: pSib->mapped = 0; /* to fool mapWindow */
2242: break;
2243: }
2244: }
2245: pChild = pChild->nextSib;
2246: }
2247: }
2248: if (!pChild)
2249: return(Success) ;
2250: event.u.circulate.window = pChild->wid;
2251: event.u.circulate.parent = pParent->wid;
2252: event.u.circulate.event = pParent->wid;
2253: if (direction == RaiseLowest)
2254: event.u.circulate.place = PlaceOnTop;
2255: else
2256: event.u.circulate.place = PlaceOnBottom;
2257:
2258: if (pParent->allEventMasks & SubstructureRedirectMask)
2259: {
2260: event.u.u.type = CirculateRequest;
2261: if (MaybeDeliverEventsToClient(pParent, &event, 1,
2262: SubstructureRedirectMask, client) == 1)
2263: return(Success);
2264: }
2265: if (pParent->realized)
2266: MapWindow(pSib, HANDLE_EXPOSURES, BITS_DISCARDED,
2267: DONT_SEND_NOTIFICATION, client);
2268: event.u.u.type = CirculateNotify;
2269: DeliverEvents(pParent, &event, 1, NullWindow);
2270: return(Success);
2271: }
2272:
2273: /*****
2274: * ReparentWindow
2275: *****/
2276:
2277: static int
2278: CompareWIDs(pWin, wid)
2279: WindowPtr pWin;
2280: int *wid;
2281: {
2282: if (pWin->wid == *wid)
2283: return(WT_STOPWALKING);
2284: else
2285: return(WT_WALKCHILDREN);
2286: }
2287:
2288: int
2289: ReparentWindow(pWin, pParent, x, y, client)
2290: WindowPtr pWin, pParent;
2291: short x,y;
2292: ClientPtr client;
2293: {
2294: WindowPtr pPrev;
2295: Bool WasMapped = (Bool)(pWin->realized);
2296: BoxRec box;
2297: xEvent event;
2298: short oldx, oldy;
2299: int bw;
2300: register ScreenPtr pScreen;
2301:
2302: if (pWin == pParent)
2303: return(BadWindow);
2304: if (TraverseTree(pWin, CompareWIDs, &pParent->wid) == WT_STOPWALKING)
2305: return(BadWindow);
2306:
2307: pScreen = pWin->drawable.pScreen;
2308: event.u.u.type = ReparentNotify;
2309: event.u.reparent.window = pWin->wid;
2310: event.u.reparent.parent = pParent->wid;
2311: event.u.reparent.x = x;
2312: event.u.reparent.y = y;
2313: event.u.reparent.override = pWin->overrideRedirect;
2314: DeliverEvents(pWin, &event, 1, pParent);
2315:
2316: oldx = pWin->absCorner.x;
2317: oldy = pWin->absCorner.y;
2318: if (WasMapped)
2319: UnmapWindow(pWin, HANDLE_EXPOSURES, SEND_NOTIFICATION, FALSE);
2320:
2321: /* take out of sibling chain */
2322:
2323: pPrev = pWin->parent;
2324: if (pPrev->firstChild == pWin)
2325: pPrev->firstChild = pWin->nextSib;
2326: if (pPrev->lastChild == pWin)
2327: pPrev->lastChild = pWin->prevSib;
2328:
2329: if (pWin->nextSib)
2330: pWin->nextSib->prevSib = pWin->prevSib;
2331: if (pWin->prevSib)
2332: pWin->prevSib->nextSib = pWin->nextSib;
2333:
2334: /* insert at begining of pParent */
2335: pWin->parent = pParent;
2336: pWin->nextSib = pParent->firstChild;
2337: pWin->prevSib = (WindowPtr )NULL;
2338: if (pParent->firstChild)
2339: pParent->firstChild->prevSib = pWin;
2340: else
2341: pParent->lastChild = pWin;
2342: pParent->firstChild = pWin;
2343:
2344: /* clip to parent */
2345: box.x1 = x + pParent->absCorner.x;
2346: box.y1 = y + pParent->absCorner.y;
2347: box.x2 = box.x1 + pWin->clientWinSize.width;
2348: box.y2 = box.y1+ pWin->clientWinSize.height;
2349: (* pScreen->RegionReset)(pWin->winSize, &box);
2350: (* pScreen->Intersect)(pWin->winSize, pWin->winSize,
2351: pParent->winSize);
2352:
2353: pWin->clientWinSize.x = x;
2354: pWin->clientWinSize.y = y;
2355: pWin->oldAbsCorner.x = oldx;
2356: pWin->oldAbsCorner.y = oldy;
2357: pWin->absCorner.x = box.x1;
2358: pWin->absCorner.y = box.y1;
2359:
2360: if (bw = pWin->borderWidth)
2361: {
2362: box.x1 -= bw;
2363: box.y1 -= bw;
2364: box.x2 += bw;
2365: box.y2 += bw;
2366: (* pScreen->RegionReset)(pWin->borderSize, &box);
2367: (* pScreen->Intersect)(pWin->borderSize, pWin->borderSize,
2368: pParent->winSize);
2369: }
2370: else
2371: (* pScreen->RegionCopy)(pWin->borderSize, pWin->winSize);
2372:
2373: (* pScreen->PositionWindow)(pWin, pWin->absCorner.x, pWin->absCorner.y);
2374: ResizeChildrenWinSize(pWin, FALSE, 0, 0, DONT_USE_GRAVITY);
2375:
2376: if (WasMapped)
2377: {
2378: MapWindow(pWin, HANDLE_EXPOSURES, BITS_DISCARDED, SEND_NOTIFICATION,
2379: client);
2380: }
2381: RecalculateDeliverableEvents(pParent);
2382: return(Success);
2383: }
2384:
2385: static int
2386: MarkChildren(pWin, box)
2387: WindowPtr pWin;
2388: BoxPtr box;
2389: {
2390: WindowPtr pChild;
2391: int anyMarked=0;
2392: register ScreenPtr pScreen;
2393:
2394: pScreen = pWin->drawable.pScreen;
2395: pChild = pWin->firstChild;
2396: while (pChild)
2397: {
2398: if (pChild->mapped && ((* pScreen->RectIn)(pChild->borderSize, box)))
2399: {
2400: anyMarked++;
2401: pChild->marked = 1;
2402: anyMarked += MarkChildren(pChild, box);
2403: }
2404: pChild = pChild->nextSib;
2405: }
2406: return(anyMarked);
2407: }
2408:
2409: static int
2410: MarkSiblingsBelowMe(pWin, box)
2411: WindowPtr pWin;
2412: BoxPtr box;
2413: {
2414: WindowPtr pSib;
2415: int anyMarked = 0;
2416: register ScreenPtr pScreen;
2417:
2418: pScreen = pWin->drawable.pScreen;
2419:
2420: pSib = pWin;
2421: while (pSib)
2422: {
2423: if (pSib->mapped && ((* pScreen->RectIn)(pSib->borderSize, box)))
2424: {
2425: pSib->marked = 1;
2426: anyMarked++;
2427: if (pSib->firstChild)
2428: anyMarked += MarkChildren(pSib, box);
2429: }
2430: pSib = pSib->nextSib;
2431: }
2432: return(anyMarked);
2433: }
2434:
2435:
2436: /*****
2437: * MapWindow
2438: * If some other client has selected SubStructureReDirect on the parent
2439: * and override-redirect is xFalse, then a MapRequest event is generated,
2440: * but the window remains unmapped. Otherwise, the window is mapped and a
2441: * MapNotify event is generated.
2442: *****/
2443:
2444: static void
2445: RealizeChildren(pWin, client)
2446: WindowPtr pWin;
2447: ClientPtr client;
2448: {
2449: WindowPtr pSib;
2450: Bool (* Realize)();
2451:
2452: pSib = pWin;
2453: if (pWin)
2454: Realize = pSib->drawable.pScreen->RealizeWindow;
2455: while (pSib)
2456: {
2457: if (pSib->mapped)
2458: {
2459: pSib->realized = TRUE;
2460: pSib->viewable = pSib->class == InputOutput;
2461: (* Realize)(pSib);
2462: FlushClientCaches(pSib->wid);
2463: if (pSib->firstChild)
2464: RealizeChildren(pSib->firstChild, client);
2465: }
2466: pSib = pSib->nextSib;
2467: }
2468: }
2469:
2470: int
2471: MapWindow(pWin, SendExposures, BitsAvailable, SendNotification, client)
2472:
2473: WindowPtr pWin;
2474: Bool SendExposures;
2475: Bool BitsAvailable;
2476: ClientPtr client;
2477: {
2478: register ScreenPtr pScreen;
2479:
2480: WindowPtr pParent;
2481: Bool anyMarked;
2482:
2483: if (pWin->mapped)
2484: return(Success);
2485: pScreen = pWin->drawable.pScreen;
2486: if (pParent = pWin->parent)
2487: {
2488: xEvent event;
2489: BoxPtr box;
2490:
2491: if (SendNotification && (!pWin->overrideRedirect) &&
2492: (pParent->allEventMasks & SubstructureRedirectMask))
2493: {
2494: event.u.u.type = MapRequest;
2495: event.u.mapRequest.window = pWin->wid;
2496: event.u.mapRequest.parent = pParent->wid;
2497:
2498: if (MaybeDeliverEventsToClient(pParent, &event, 1,
2499: SubstructureRedirectMask, client) == 1)
2500: return(Success);
2501: }
2502:
2503: pWin->mapped = 1;
2504: if (SendNotification)
2505: {
2506: event.u.u.type = MapNotify;
2507: event.u.mapNotify.window = pWin->wid;
2508: event.u.mapNotify.override = pWin->overrideRedirect;
2509: DeliverEvents(pWin, &event, 1, NullWindow);
2510: }
2511:
2512: pWin->marked = 0; /* so siblings get mapped correctly */
2513: if (!pParent->realized)
2514: return(Success);
2515: pWin->realized = TRUE;
2516: pWin->viewable = pWin->class == InputOutput;
2517: /* We SHOULD check for an error value here XXX */
2518: (* pScreen->RealizeWindow)(pWin);
2519: if (pWin->firstChild)
2520: RealizeChildren(pWin->firstChild, client);
2521: box = (* pScreen->RegionExtents)(pWin->borderSize);
2522: anyMarked = MarkSiblingsBelowMe(pWin, box);
2523:
2524: /* kludge; remove when miregion works! */
2525: if (!pParent->parent &&
2526: (box->x1 == pParent->winSize->extents.x1) &&
2527: (box->y1 == pParent->winSize->extents.y1) &&
2528: (box->x2 == pParent->winSize->extents.x2) &&
2529: (box->y2 == pParent->winSize->extents.y2) &&
2530: (pParent->firstChild == pWin)) {
2531: (*pWin->drawable.pScreen->RegionCopy)(pParent->clipList,
2532: pParent->winSize);
2533: }
2534: /* end of kludge */
2535:
2536: (* pScreen->ValidateTree)(pParent, pWin, TRUE, anyMarked);
2537: if (SendExposures)
2538: {
2539: if (!BitsAvailable)
2540: {
2541: (* pScreen->RegionCopy)(pWin->exposed, pWin->clipList);
2542: DoObscures(pParent);
2543: HandleExposures(pWin);
2544: }
2545: else
2546: {
2547: /*
2548: * Children shouldn't be in the parent's exposed region...
2549: (* pScreen->Subtract)(pParent->exposed, pParent->exposed,
2550: pWin->borderSize);
2551: */
2552: (* pScreen->RegionEmpty)(pWin->exposed);
2553: DoObscures(pParent);
2554: HandleExposures(pWin);
2555: }
2556: }
2557: }
2558: else
2559: {
2560: pWin->mapped = 1;
2561: pWin->realized = TRUE; /* for roots */
2562: pWin->viewable = pWin->class == InputOutput;
2563: /* We SHOULD check for an error value here XXX */
2564: (* pScreen->RealizeWindow)(pWin);
2565: }
2566:
2567: return(Success);
2568: }
2569:
2570:
2571: /*****
2572: * MapSubwindows
2573: * Performs a MapWindow all unmapped children of the window, in top
2574: * to bottom stacking order.
2575: *****/
2576:
2577: MapSubwindows(pWin, SendExposures, client)
2578: WindowPtr pWin;
2579: Bool SendExposures;
2580: ClientPtr client;
2581: {
2582: WindowPtr pChild;
2583:
2584: pChild = pWin->firstChild;
2585: while (pChild)
2586: {
2587: if (!pChild->mapped)
2588: /* What about backing store? */
2589: MapWindow(pChild, SendExposures, BITS_DISCARDED,
2590: SEND_NOTIFICATION, client);
2591: pChild = pChild->nextSib;
2592: }
2593: }
2594:
2595: /*****
2596: * UnmapWindow
2597: * If the window is already unmapped, this request has no effect.
2598: * Otherwise, the window is unmapped and an UnMapNotify event is
2599: * generated. Cannot unmap a root window.
2600: *****/
2601:
2602: static void
2603: UnrealizeChildren(pWin)
2604: WindowPtr pWin;
2605: {
2606: WindowPtr pSib;
2607: void (*RegionEmpty)();
2608: Bool (*Unrealize)();
2609:
2610: pSib = pWin;
2611: if (pWin)
2612: {
2613: RegionEmpty = pWin->drawable.pScreen->RegionEmpty;
2614: Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
2615: }
2616: while (pSib)
2617: {
2618: pSib->realized = pSib->viewable = FALSE;
2619: (* Unrealize)(pSib);
2620: /* to force exposures later */
2621: (* RegionEmpty)(pSib->clipList);
2622: (* RegionEmpty)(pSib->borderClip);
2623: (* RegionEmpty)(pSib->exposed);
2624: pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
2625: DeleteWindowFromAnyEvents(pSib, FALSE);
2626: if (pSib->firstChild)
2627: UnrealizeChildren(pSib->firstChild);
2628: pSib = pSib->nextSib;
2629: }
2630: }
2631:
2632: UnmapWindow(pWin, SendExposures, SendNotification, fromConfigure)
2633: WindowPtr pWin;
2634: Bool SendExposures, fromConfigure;
2635: {
2636: WindowPtr pParent;
2637: xEvent event;
2638: Bool anyMarked;
2639: Bool wasMapped = (Bool)pWin->realized;
2640: BoxPtr box;
2641:
2642: if ((!pWin->mapped) || (!(pParent = pWin->parent)))
2643: return(Success);
2644: if (SendNotification)
2645: {
2646: event.u.u.type = UnmapNotify;
2647: event.u.unmapNotify.window = pWin->wid;
2648: event.u.unmapNotify.fromConfigure = fromConfigure;
2649: DeliverEvents(pWin, &event, 1, NullWindow);
2650: }
2651: if (wasMapped)
2652: {
2653: box = (* pWin->drawable.pScreen->RegionExtents)(pWin->borderSize);
2654: anyMarked = MarkSiblingsBelowMe(pWin, box);
2655: }
2656: pWin->mapped = 0;
2657: pWin->realized = pWin->viewable = FALSE;
2658: if (wasMapped)
2659: {
2660: /* We SHOULD check for an error value here XXX */
2661: (* pWin->drawable.pScreen->UnrealizeWindow)(pWin);
2662: DeleteWindowFromAnyEvents(pWin, FALSE);
2663: if (pWin->firstChild)
2664: UnrealizeChildren(pWin->firstChild);
2665: (* pWin->drawable.pScreen->ValidateTree)(pParent, pWin,
2666: TRUE, anyMarked);
2667: if (SendExposures)
2668: {
2669: HandleExposures(pParent);
2670: }
2671: }
2672: return(Success);
2673: }
2674:
2675: /*****
2676: * UnmapSubwindows
2677: * Performs an UnMapWindow request with the specified mode on all mapped
2678: * children of the window, in bottom to top stacking order.
2679: *
2680: * XXX: Should use the validation function, not mess with the clip lists
2681: * directly, though this way is faster.
2682: *****/
2683:
2684: UnmapSubwindows(pWin, sendExposures)
2685: WindowPtr pWin;
2686: Bool sendExposures;
2687: {
2688: WindowPtr pChild;
2689: xEvent event;
2690: void (*RegionEmpty)();
2691: Bool (*UnrealizeWindow)();
2692: Bool wasMapped = (Bool)pWin->realized;
2693:
2694: pChild = pWin->lastChild;
2695: event.u.u.type = UnmapNotify;
2696: event.u.unmapNotify.fromConfigure = xFalse;
2697: RegionEmpty = pWin->drawable.pScreen->RegionEmpty;
2698: UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
2699: while (pChild)
2700: {
2701: if (pChild->mapped)
2702: {
2703: event.u.unmapNotify.window = pChild->wid;
2704: event.u.unmapNotify.fromConfigure = xFalse;
2705: DeliverEvents(pWin, &event, 1, NullWindow);
2706: pChild->mapped = 0;
2707: if (wasMapped)
2708: {
2709: pChild->realized = pChild->viewable = FALSE;
2710: /* We SHOULD check for an error value here XXX */
2711: (* UnrealizeWindow)(pChild);
2712: if (pChild->firstChild)
2713: UnrealizeChildren(pChild->firstChild);
2714: DeleteWindowFromAnyEvents(pChild, FALSE);
2715: (* RegionEmpty)(pChild->clipList);/* to force expsoures later*/
2716: (* RegionEmpty)(pChild->borderClip);
2717: (* RegionEmpty)(pChild->borderExposed);
2718: (* RegionEmpty)(pChild->exposed);
2719: pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
2720: }
2721: }
2722: pChild = pChild->prevSib;
2723: }
2724: if ((pWin->lastChild) && wasMapped)
2725: {
2726: (* pWin->drawable.pScreen->Intersect)(pWin->clipList,
2727: pWin->winSize, pWin->borderClip);
2728: (* pWin->drawable.pScreen->RegionCopy)(pWin->exposed, pWin->clipList);
2729: HandleExposures(pWin);
2730: }
2731: }
2732:
2733:
2734: void
2735: HandleSaveSet(client)
2736: ClientPtr client;
2737: {
2738: WindowPtr pParent, pWin;
2739: int j;
2740:
2741: for (j=0; j<client->numSaved; j++)
2742: {
2743: pWin = (WindowPtr)client->saveSet[j];
2744: pParent = pWin->parent;
2745: while (pParent && (pParent->client == client))
2746: pParent = pParent->parent;
2747: if (pParent)
2748: {
2749: ReparentWindow(pWin, pParent, pWin->absCorner.x,
2750: pWin->absCorner.y, client);
2751: if(!pWin->realized && pWin->mapped)
2752: pWin->mapped = FALSE;
2753: MapWindow(pWin, HANDLE_EXPOSURES, BITS_DISCARDED,
2754: SEND_NOTIFICATION, client);
2755: }
2756: }
2757: }
2758:
2759: Bool
2760: VisibleBoundingBoxFromPoint(pWin, x, y, box)
2761: WindowPtr pWin;
2762: int x, y; /* in root */
2763: BoxPtr box; /* "return" value */
2764: {
2765: if (!pWin->realized)
2766: return (FALSE);
2767: if ((* pWin->drawable.pScreen->PointInRegion)(pWin->clipList, x, y, box))
2768: return(TRUE);
2769: return(FALSE);
2770: }
2771:
2772: Bool
2773: PointInWindowIsVisible(pWin, x, y)
2774: WindowPtr pWin;
2775: int x, y; /* in root */
2776: {
2777: BoxRec box;
2778:
2779: if (!pWin->realized)
2780: return (FALSE);
2781: if ((* pWin->drawable.pScreen->PointInRegion)(pWin->clipList, x, y, &box))
2782: return(TRUE);
2783: return(FALSE);
2784: }
2785:
2786:
2787: RegionPtr
2788: NotClippedByChildren(pWin)
2789: WindowPtr pWin;
2790: {
2791: register ScreenPtr pScreen;
2792: RegionPtr pReg;
2793:
2794: pScreen = pWin->drawable.pScreen;
2795: pReg = (* pScreen->RegionCreate)(NULL, 1);
2796: (* pScreen->Intersect) (pReg, pWin->borderClip, pWin->winSize);
2797: return(pReg);
2798: }
2799:
2800:
2801: void
2802: SendVisibilityNotify(pWin)
2803: WindowPtr pWin;
2804: {
2805: xEvent event;
2806: event.u.u.type = VisibilityNotify;
2807: event.u.visibility.window = pWin->wid;
2808: event.u.visibility.state = pWin->visibility;
2809: DeliverEvents(pWin, &event, 1, NullWindow);
2810: }
2811:
2812:
2813: #define RANDOM_WIDTH 32
2814:
2815: void
2816: SaveScreens(on, mode)
2817: int on;
2818: int mode;
2819: {
2820: int i, j;
2821: int what;
2822: unsigned char *srcbits, *mskbits;
2823:
2824: if (on == SCREEN_SAVER_FORCER)
2825: {
2826: if (mode == ScreenSaverReset)
2827: what = SCREEN_SAVER_OFF;
2828: else
2829: what = SCREEN_SAVER_ON;
2830: if (what == screenIsSaved)
2831: return ;
2832: }
2833: else
2834: what = on;
2835: for (i = 0; i < screenInfo.numScreens; i++)
2836: {
2837: if (on == SCREEN_SAVER_FORCER)
2838: {
2839: (* screenInfo.screen[i].SaveScreen) (&screenInfo.screen[i], on);
2840: }
2841: if (what == SCREEN_SAVER_OFF)
2842: {
2843: if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
2844: {
2845: (* screenInfo.screen[i].SaveScreen) (&screenInfo.screen[i], on);
2846: }
2847: else if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
2848: {
2849: FreeResource(savedScreenInfo[i].wid, RC_NONE);
2850: savedScreenInfo[i].pWindow = (WindowPtr)NULL;
2851: FreeResource(savedScreenInfo[i].cid, RC_NONE);
2852: }
2853: continue;
2854: }
2855: else if (what == SCREEN_SAVER_ON)
2856: {
2857: if (screenIsSaved == SCREEN_SAVER_ON) /* rotate pattern */
2858: {
2859: int new_x, new_y;
2860:
2861: if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
2862: {
2863: new_x = random() % RANDOM_WIDTH;
2864: new_y = random() % RANDOM_WIDTH;
2865: MoveWindow(savedScreenInfo[i].pWindow, -new_x, -new_y,
2866: savedScreenInfo[i].pWindow->nextSib);
2867: }
2868: continue;
2869: }
2870: if (ScreenSaverBlanking != DontPreferBlanking)
2871: {
2872: if ((* screenInfo.screen[i].SaveScreen)
2873: (&screenInfo.screen[i], what))
2874: {
2875: savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
2876: continue;
2877: }
2878: }
2879: if (ScreenSaverAllowExposures != DontAllowExposures)
2880: {
2881: int result;
2882: long attributes[1];
2883: int mask = CWBackPixmap;
2884: WindowPtr pWin;
2885: CursorMetricRec cm;
2886:
2887: if (WindowTable[i].backgroundTile ==
2888: (PixmapPtr)USE_BACKGROUND_PIXEL)
2889: {
2890: attributes[0] = WindowTable[i].backgroundPixel;
2891: mask = CWBackPixel;
2892: }
2893: else
2894: attributes[0] = None;
2895:
2896: pWin = savedScreenInfo[i].pWindow =
2897: /* We SHOULD check for an error value here XXX */
2898: CreateWindow(savedScreenInfo[i].wid,
2899: &WindowTable[i],
2900: -RANDOM_WIDTH, -RANDOM_WIDTH,
2901: screenInfo.screen[i].width + RANDOM_WIDTH,
2902: screenInfo.screen[i].height + RANDOM_WIDTH,
2903: 0, InputOutput, mask, attributes, 0, 0,
2904: WindowTable[i].visual, &result);
2905: if (attributes[0] == None)
2906: {
2907:
2908: pWin->backgroundTile = pWin->parent->backgroundTile;
2909: pWin->backgroundTile->refcnt++;
2910: (* screenInfo.screen[i].ChangeWindowAttributes)
2911: (pWin, CWBackPixmap);
2912: }
2913: AddResource(pWin->wid, RT_WINDOW,
2914: savedScreenInfo[i].pWindow,
2915: DeleteWindow, RC_CORE);
2916: cm.width=32;
2917: cm.height=16;
2918: cm.xhot=8;
2919: cm.yhot=8;
2920: srcbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16);
2921: mskbits = (unsigned char *)Xalloc( PixmapBytePad(32, 1)*16);
2922: for (j=0; j<PixmapBytePad(32, 1)*16; j++)
2923: srcbits[j] = mskbits[j] = 0x0;
2924: pWin->cursor = AllocCursor( srcbits, mskbits, &cm,
2925: ~0, ~0, ~0, 0, 0, 0);
2926: AddResource(savedScreenInfo[i].cid, RT_CURSOR,
2927: pWin->cursor,
2928: FreeCursor, RC_CORE);
2929: pWin->cursor->refcnt++;
2930: pWin->overrideRedirect = TRUE;
2931: MapWindow(pWin, TRUE, FALSE, FALSE, 0);
2932: savedScreenInfo[i].blanked = SCREEN_IS_TILED;
2933: }
2934: else
2935: savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
2936: }
2937: }
2938: screenIsSaved = what;
2939: }
2940:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.