First import
[xorg_rtime.git] / xorg-server-1.4 / mi / miexpose.c
blobdf04bd291225ea63de8def2c1e7c622a59da6d9f
1 /***********************************************************
3 Copyright 1987, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
26 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
28 All Rights Reserved
30 Permission to use, copy, modify, and distribute this software and its
31 documentation for any purpose and without fee is hereby granted,
32 provided that the above copyright notice appear in all copies and that
33 both that copyright notice and this permission notice appear in
34 supporting documentation, and that the name of Digital not be
35 used in advertising or publicity pertaining to distribution of the
36 software without specific, written prior permission.
38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44 SOFTWARE.
46 ******************************************************************/
47 /*****************************************************************
49 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
51 Permission is hereby granted, free of charge, to any person obtaining a copy
52 of this software and associated documentation files (the "Software"), to deal
53 in the Software without restriction, including without limitation the rights
54 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55 copies of the Software.
57 The above copyright notice and this permission notice shall be included in
58 all copies or substantial portions of the Software.
60 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
61 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
62 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
63 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
64 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
65 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
66 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
68 Except as contained in this notice, the name of Digital Equipment Corporation
69 shall not be used in advertising or otherwise to promote the sale, use or other
70 dealings in this Software without prior written authorization from Digital
71 Equipment Corporation.
73 ******************************************************************/
76 #ifdef HAVE_DIX_CONFIG_H
77 #include <dix-config.h>
78 #endif
80 #include <X11/X.h>
81 #define NEED_EVENTS
82 #include <X11/Xproto.h>
83 #include <X11/Xprotostr.h>
85 #include "misc.h"
86 #include "regionstr.h"
87 #include "scrnintstr.h"
88 #include "gcstruct.h"
89 #include "windowstr.h"
90 #include "pixmap.h"
91 #include "input.h"
93 #include "dixstruct.h"
94 #include "mi.h"
95 #include <X11/Xmd.h>
97 #include "globals.h"
99 #ifdef PANORAMIX
100 #include "panoramiX.h"
101 #include "panoramiXsrv.h"
102 #endif
105 machine-independent graphics exposure code. any device that uses
106 the region package can call this.
109 #ifndef RECTLIMIT
110 #define RECTLIMIT 25 /* pick a number, any number > 8 */
111 #endif
113 /* miHandleExposures
114 generate a region for exposures for areas that were copied from obscured or
115 non-existent areas to non-obscured areas of the destination. Paint the
116 background for the region, if the destination is a window.
118 NOTE:
119 this should generally be called, even if graphicsExposures is false,
120 because this is where bits get recovered from backing store.
122 NOTE:
123 added argument 'plane' is used to indicate how exposures from backing
124 store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
125 should be used, else a CopyPlane of the indicated plane will be used. The
126 exposing is done by the backing store's GraphicsExpose function, of course.
130 _X_EXPORT RegionPtr
131 miHandleExposures(pSrcDrawable, pDstDrawable,
132 pGC, srcx, srcy, width, height, dstx, dsty, plane)
133 DrawablePtr pSrcDrawable;
134 DrawablePtr pDstDrawable;
135 GCPtr pGC;
136 int srcx, srcy;
137 int width, height;
138 int dstx, dsty;
139 unsigned long plane;
141 ScreenPtr pscr;
142 RegionPtr prgnSrcClip; /* drawable-relative source clip */
143 RegionRec rgnSrcRec;
144 RegionPtr prgnDstClip; /* drawable-relative dest clip */
145 RegionRec rgnDstRec;
146 BoxRec srcBox; /* unclipped source */
147 RegionRec rgnExposed; /* exposed region, calculated source-
148 relative, made dst relative to
149 intersect with visible parts of
150 dest and send events to client,
151 and then screen relative to paint
152 the window background
154 WindowPtr pSrcWin;
155 BoxRec expBox;
156 Bool extents;
158 /* This prevents warning about pscr not being used. */
159 pGC->pScreen = pscr = pGC->pScreen;
161 /* avoid work if we can */
162 if (!pGC->graphicsExposures &&
163 (pDstDrawable->type == DRAWABLE_PIXMAP) &&
164 ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
165 (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
166 return NULL;
168 srcBox.x1 = srcx;
169 srcBox.y1 = srcy;
170 srcBox.x2 = srcx+width;
171 srcBox.y2 = srcy+height;
173 if (pSrcDrawable->type != DRAWABLE_PIXMAP)
175 BoxRec TsrcBox;
177 TsrcBox.x1 = srcx + pSrcDrawable->x;
178 TsrcBox.y1 = srcy + pSrcDrawable->y;
179 TsrcBox.x2 = TsrcBox.x1 + width;
180 TsrcBox.y2 = TsrcBox.y1 + height;
181 pSrcWin = (WindowPtr) pSrcDrawable;
182 if (pGC->subWindowMode == IncludeInferiors)
184 prgnSrcClip = NotClippedByChildren (pSrcWin);
185 if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
187 REGION_DESTROY(pscr, prgnSrcClip);
188 return NULL;
191 else
193 if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
194 return NULL;
195 prgnSrcClip = &rgnSrcRec;
196 REGION_NULL(pscr, prgnSrcClip);
197 REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
199 REGION_TRANSLATE(pscr, prgnSrcClip,
200 -pSrcDrawable->x, -pSrcDrawable->y);
202 else
204 BoxRec box;
206 if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
207 (srcBox.x2 <= pSrcDrawable->width) &&
208 (srcBox.y2 <= pSrcDrawable->height))
209 return NULL;
211 box.x1 = 0;
212 box.y1 = 0;
213 box.x2 = pSrcDrawable->width;
214 box.y2 = pSrcDrawable->height;
215 prgnSrcClip = &rgnSrcRec;
216 REGION_INIT(pscr, prgnSrcClip, &box, 1);
217 pSrcWin = (WindowPtr)NULL;
220 if (pDstDrawable == pSrcDrawable)
222 prgnDstClip = prgnSrcClip;
224 else if (pDstDrawable->type != DRAWABLE_PIXMAP)
226 if (pGC->subWindowMode == IncludeInferiors)
228 prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
230 else
232 prgnDstClip = &rgnDstRec;
233 REGION_NULL(pscr, prgnDstClip);
234 REGION_COPY(pscr, prgnDstClip,
235 &((WindowPtr)pDstDrawable)->clipList);
237 REGION_TRANSLATE(pscr, prgnDstClip,
238 -pDstDrawable->x, -pDstDrawable->y);
240 else
242 BoxRec box;
244 box.x1 = 0;
245 box.y1 = 0;
246 box.x2 = pDstDrawable->width;
247 box.y2 = pDstDrawable->height;
248 prgnDstClip = &rgnDstRec;
249 REGION_INIT(pscr, prgnDstClip, &box, 1);
252 /* drawable-relative source region */
253 REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
255 /* now get the hidden parts of the source box*/
256 REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
258 if (pSrcWin && pSrcWin->backStorage)
261 * Copy any areas from the source backing store. Modifies
262 * rgnExposed.
264 (* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
265 pDstDrawable,
266 pGC,
267 &rgnExposed,
268 srcx, srcy,
269 dstx, dsty,
270 plane);
273 /* move them over the destination */
274 REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
276 /* intersect with visible areas of dest */
277 REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
280 * If we have LOTS of rectangles, we decide to take the extents
281 * and force an exposure on that. This should require much less
282 * work overall, on both client and server. This is cheating, but
283 * isn't prohibited by the protocol ("spontaneous combustion" :-)
284 * for windows.
286 extents = pGC->graphicsExposures &&
287 (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
288 (pDstDrawable->type != DRAWABLE_PIXMAP);
289 #ifdef SHAPE
290 if (pSrcWin)
292 RegionPtr region;
293 if (!(region = wClipShape (pSrcWin)))
294 region = wBoundingShape (pSrcWin);
296 * If you try to CopyArea the extents of a shaped window, compacting the
297 * exposed region will undo all our work!
299 if (extents && pSrcWin && region &&
300 (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
301 extents = FALSE;
303 #endif
304 if (extents)
306 WindowPtr pWin = (WindowPtr)pDstDrawable;
308 expBox = *REGION_EXTENTS(pscr, &rgnExposed);
309 REGION_RESET(pscr, &rgnExposed, &expBox);
310 /* need to clear out new areas of backing store */
311 if (pWin->backStorage)
312 (void) (* pWin->drawable.pScreen->ClearBackingStore)(
313 pWin,
314 expBox.x1,
315 expBox.y1,
316 expBox.x2 - expBox.x1,
317 expBox.y2 - expBox.y1,
318 FALSE);
320 if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
321 (((WindowPtr)pDstDrawable)->backgroundState != None))
323 WindowPtr pWin = (WindowPtr)pDstDrawable;
325 /* make the exposed area screen-relative */
326 REGION_TRANSLATE(pscr, &rgnExposed,
327 pDstDrawable->x, pDstDrawable->y);
329 if (extents)
331 /* PaintWindowBackground doesn't clip, so we have to */
332 REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
334 (*pWin->drawable.pScreen->PaintWindowBackground)(
335 (WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
337 if (extents)
339 REGION_RESET(pscr, &rgnExposed, &expBox);
341 else
342 REGION_TRANSLATE(pscr, &rgnExposed,
343 -pDstDrawable->x, -pDstDrawable->y);
345 if (prgnDstClip == &rgnDstRec)
347 REGION_UNINIT(pscr, prgnDstClip);
349 else if (prgnDstClip != prgnSrcClip)
351 REGION_DESTROY(pscr, prgnDstClip);
354 if (prgnSrcClip == &rgnSrcRec)
356 REGION_UNINIT(pscr, prgnSrcClip);
358 else
360 REGION_DESTROY(pscr, prgnSrcClip);
363 if (pGC->graphicsExposures)
365 /* don't look */
366 RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
367 *exposed = rgnExposed;
368 return exposed;
370 else
372 REGION_UNINIT(pscr, &rgnExposed);
373 return NULL;
377 /* send GraphicsExpose events, or a NoExpose event, based on the region */
379 _X_EXPORT void
380 miSendGraphicsExpose (client, pRgn, drawable, major, minor)
381 ClientPtr client;
382 RegionPtr pRgn;
383 XID drawable;
384 int major;
385 int minor;
387 if (pRgn && !REGION_NIL(pRgn))
389 xEvent *pEvent;
390 xEvent *pe;
391 BoxPtr pBox;
392 int i;
393 int numRects;
395 numRects = REGION_NUM_RECTS(pRgn);
396 pBox = REGION_RECTS(pRgn);
397 if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
398 return;
399 pe = pEvent;
401 for (i=1; i<=numRects; i++, pe++, pBox++)
403 pe->u.u.type = GraphicsExpose;
404 pe->u.graphicsExposure.drawable = drawable;
405 pe->u.graphicsExposure.x = pBox->x1;
406 pe->u.graphicsExposure.y = pBox->y1;
407 pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
408 pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
409 pe->u.graphicsExposure.count = numRects - i;
410 pe->u.graphicsExposure.majorEvent = major;
411 pe->u.graphicsExposure.minorEvent = minor;
413 TryClientEvents(client, pEvent, numRects,
414 (Mask)0, NoEventMask, NullGrab);
415 DEALLOCATE_LOCAL(pEvent);
417 else
419 xEvent event;
420 event.u.u.type = NoExpose;
421 event.u.noExposure.drawable = drawable;
422 event.u.noExposure.majorEvent = major;
423 event.u.noExposure.minorEvent = minor;
424 TryClientEvents(client, &event, 1,
425 (Mask)0, NoEventMask, NullGrab);
430 void
431 miSendExposures(pWin, pRgn, dx, dy)
432 WindowPtr pWin;
433 RegionPtr pRgn;
434 int dx, dy;
436 BoxPtr pBox;
437 int numRects;
438 xEvent *pEvent, *pe;
439 int i;
441 pBox = REGION_RECTS(pRgn);
442 numRects = REGION_NUM_RECTS(pRgn);
443 if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
444 return;
446 for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
448 pe->u.u.type = Expose;
449 pe->u.expose.window = pWin->drawable.id;
450 pe->u.expose.x = pBox->x1 - dx;
451 pe->u.expose.y = pBox->y1 - dy;
452 pe->u.expose.width = pBox->x2 - pBox->x1;
453 pe->u.expose.height = pBox->y2 - pBox->y1;
454 pe->u.expose.count = i;
457 #ifdef PANORAMIX
458 if(!noPanoramiXExtension) {
459 int scrnum = pWin->drawable.pScreen->myNum;
460 int x = 0, y = 0;
461 XID realWin = 0;
463 if(!pWin->parent) {
464 x = panoramiXdataPtr[scrnum].x;
465 y = panoramiXdataPtr[scrnum].y;
466 pWin = WindowTable[0];
467 realWin = pWin->drawable.id;
468 } else if (scrnum) {
469 PanoramiXRes *win;
470 win = PanoramiXFindIDByScrnum(XRT_WINDOW,
471 pWin->drawable.id, scrnum);
472 if(!win) {
473 DEALLOCATE_LOCAL(pEvent);
474 return;
476 realWin = win->info[0].id;
477 pWin = LookupIDByType(realWin, RT_WINDOW);
479 if(x || y || scrnum)
480 for (i = 0; i < numRects; i++) {
481 pEvent[i].u.expose.window = realWin;
482 pEvent[i].u.expose.x += x;
483 pEvent[i].u.expose.y += y;
486 #endif
488 DeliverEvents(pWin, pEvent, numRects, NullWindow);
490 DEALLOCATE_LOCAL(pEvent);
493 _X_EXPORT void
494 miWindowExposures(pWin, prgn, other_exposed)
495 WindowPtr pWin;
496 RegionPtr prgn, other_exposed;
498 RegionPtr exposures = prgn;
499 if (pWin->backStorage && prgn)
501 * in some cases, backing store will cause a different
502 * region to be exposed than needs to be repainted
503 * (like when a window is mapped). RestoreAreas is
504 * allowed to return a region other than prgn,
505 * in which case this routine will free the resultant
506 * region. If exposures is null, then no events will
507 * be sent to the client; if prgn is empty
508 * no areas will be repainted.
510 exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
511 if ((prgn && !REGION_NIL(prgn)) ||
512 (exposures && !REGION_NIL(exposures)) || other_exposed)
514 RegionRec expRec;
515 int clientInterested;
518 * Restore from backing-store FIRST.
520 clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
521 if (other_exposed)
523 if (exposures)
525 REGION_UNION(pWin->drawable.pScreen, other_exposed,
526 exposures,
527 other_exposed);
528 if (exposures != prgn)
529 REGION_DESTROY(pWin->drawable.pScreen, exposures);
531 exposures = other_exposed;
533 if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
536 * If we have LOTS of rectangles, we decide to take the extents
537 * and force an exposure on that. This should require much less
538 * work overall, on both client and server. This is cheating, but
539 * isn't prohibited by the protocol ("spontaneous combustion" :-).
541 BoxRec box;
543 box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
544 if (exposures == prgn) {
545 exposures = &expRec;
546 REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
547 REGION_RESET( pWin->drawable.pScreen, prgn, &box);
548 } else {
549 REGION_RESET( pWin->drawable.pScreen, exposures, &box);
550 REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
552 /* PaintWindowBackground doesn't clip, so we have to */
553 REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
554 /* need to clear out new areas of backing store, too */
555 if (pWin->backStorage)
556 (void) (* pWin->drawable.pScreen->ClearBackingStore)(
557 pWin,
558 box.x1 - pWin->drawable.x,
559 box.y1 - pWin->drawable.y,
560 box.x2 - box.x1,
561 box.y2 - box.y1,
562 FALSE);
564 if (prgn && !REGION_NIL(prgn))
565 (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
566 if (clientInterested && exposures && !REGION_NIL(exposures))
567 miSendExposures(pWin, exposures,
568 pWin->drawable.x, pWin->drawable.y);
569 if (exposures == &expRec)
571 REGION_UNINIT( pWin->drawable.pScreen, exposures);
573 else if (exposures && exposures != prgn && exposures != other_exposed)
574 REGION_DESTROY( pWin->drawable.pScreen, exposures);
575 if (prgn)
576 REGION_EMPTY( pWin->drawable.pScreen, prgn);
578 else if (exposures && exposures != prgn)
579 REGION_DESTROY( pWin->drawable.pScreen, exposures);
584 this code is highly unlikely. it is not haile selassie.
586 there is some hair here. we can't just use the window's
587 clip region as it is, because if we are painting the border,
588 the border is not in the client area and so we will be excluded
589 when we validate the GC, and if we are painting a parent-relative
590 background, the area we want to paint is in some other window.
591 since we trust the code calling us to tell us to paint only areas
592 that are really ours, we will temporarily give the window a
593 clipList the size of the whole screen and an origin at (0,0).
594 this more or less assumes that ddX code will do translation
595 based on the window's absolute position, and that ValidateGC will
596 look at clipList, and that no other fields from the
597 window will be used. it's not possible to just draw
598 in the root because it may be a different depth.
600 to get the tile to align correctly we set the GC's tile origin to
601 be the (x,y) of the window's upper left corner, after which we
602 get the right bits when drawing into the root.
604 because the clip_mask is being set to None, we may call DoChangeGC with
605 fPointer set true, thus we no longer need to install the background or
606 border tile in the resource table.
609 static RESTYPE ResType = 0;
610 static int numGCs = 0;
611 static GCPtr screenContext[MAXSCREENS];
613 /*ARGSUSED*/
614 static int
615 tossGC (
616 pointer value,
617 XID id)
619 GCPtr pGC = (GCPtr)value;
620 screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
621 FreeGC (pGC, id);
622 numGCs--;
623 if (!numGCs)
624 ResType = 0;
626 return 0;
630 _X_EXPORT void
631 miPaintWindow(pWin, prgn, what)
632 WindowPtr pWin;
633 RegionPtr prgn;
634 int what;
636 int status;
638 Bool usingScratchGC = FALSE;
639 WindowPtr pRoot;
641 #define FUNCTION 0
642 #define FOREGROUND 1
643 #define TILE 2
644 #define FILLSTYLE 3
645 #define ABSX 4
646 #define ABSY 5
647 #define CLIPMASK 6
648 #define SUBWINDOW 7
649 #define COUNT_BITS 8
651 ChangeGCVal gcval[7];
652 ChangeGCVal newValues [COUNT_BITS];
654 BITS32 gcmask, index, mask;
655 RegionRec prgnWin;
656 DDXPointRec oldCorner;
657 BoxRec box;
658 WindowPtr pBgWin;
659 GCPtr pGC;
660 int i;
661 BoxPtr pbox;
662 ScreenPtr pScreen = pWin->drawable.pScreen;
663 xRectangle *prect;
664 int numRects;
666 gcmask = 0;
668 if (what == PW_BACKGROUND)
670 switch (pWin->backgroundState) {
671 case None:
672 return;
673 case ParentRelative:
674 (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
675 return;
676 case BackgroundPixel:
677 newValues[FOREGROUND].val = pWin->background.pixel;
678 newValues[FILLSTYLE].val = FillSolid;
679 gcmask |= GCForeground | GCFillStyle;
680 break;
681 case BackgroundPixmap:
682 newValues[TILE].ptr = (pointer)pWin->background.pixmap;
683 newValues[FILLSTYLE].val = FillTiled;
684 gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
685 break;
688 else
690 if (pWin->borderIsPixel)
692 newValues[FOREGROUND].val = pWin->border.pixel;
693 newValues[FILLSTYLE].val = FillSolid;
694 gcmask |= GCForeground | GCFillStyle;
696 else
698 newValues[TILE].ptr = (pointer)pWin->border.pixmap;
699 newValues[FILLSTYLE].val = FillTiled;
700 gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
704 prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
705 sizeof(xRectangle));
706 if (!prect)
707 return;
709 newValues[FUNCTION].val = GXcopy;
710 gcmask |= GCFunction | GCClipMask;
712 i = pScreen->myNum;
713 pRoot = WindowTable[i];
715 pBgWin = pWin;
716 if (what == PW_BORDER)
718 while (pBgWin->backgroundState == ParentRelative)
719 pBgWin = pBgWin->parent;
722 if ((pWin->drawable.depth != pRoot->drawable.depth) ||
723 (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
725 usingScratchGC = TRUE;
726 pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
727 if (!pGC)
729 DEALLOCATE_LOCAL(prect);
730 return;
733 * mash the clip list so we can paint the border by
734 * mangling the window in place, pretending it
735 * spans the entire screen
737 if (what == PW_BORDER)
739 prgnWin = pWin->clipList;
740 oldCorner.x = pWin->drawable.x;
741 oldCorner.y = pWin->drawable.y;
742 pWin->drawable.x = pWin->drawable.y = 0;
743 box.x1 = 0;
744 box.y1 = 0;
745 box.x2 = pScreen->width;
746 box.y2 = pScreen->height;
747 REGION_INIT(pScreen, &pWin->clipList, &box, 1);
748 pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
749 newValues[ABSX].val = pBgWin->drawable.x;
750 newValues[ABSY].val = pBgWin->drawable.y;
752 else
754 newValues[ABSX].val = 0;
755 newValues[ABSY].val = 0;
757 } else {
759 * draw the background to the root window
761 if (screenContext[i] == (GCPtr)NULL)
763 if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
764 return;
765 screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
766 (XID *)NULL, &status);
767 if (!screenContext[i])
768 return;
769 numGCs++;
770 if (!AddResource(FakeClientID(0), ResType,
771 (pointer)screenContext[i]))
772 return;
774 pGC = screenContext[i];
775 newValues[SUBWINDOW].val = IncludeInferiors;
776 newValues[ABSX].val = pBgWin->drawable.x;
777 newValues[ABSY].val = pBgWin->drawable.y;
778 gcmask |= GCSubwindowMode;
779 pWin = pRoot;
782 if (pWin->backStorage)
783 (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
785 mask = gcmask;
786 gcmask = 0;
787 i = 0;
788 while (mask) {
789 index = lowbit (mask);
790 mask &= ~index;
791 switch (index) {
792 case GCFunction:
793 if (pGC->alu != newValues[FUNCTION].val) {
794 gcmask |= index;
795 gcval[i++].val = newValues[FUNCTION].val;
797 break;
798 case GCTileStipXOrigin:
799 if ( pGC->patOrg.x != newValues[ABSX].val) {
800 gcmask |= index;
801 gcval[i++].val = newValues[ABSX].val;
803 break;
804 case GCTileStipYOrigin:
805 if ( pGC->patOrg.y != newValues[ABSY].val) {
806 gcmask |= index;
807 gcval[i++].val = newValues[ABSY].val;
809 break;
810 case GCClipMask:
811 if ( pGC->clientClipType != CT_NONE) {
812 gcmask |= index;
813 gcval[i++].val = CT_NONE;
815 break;
816 case GCSubwindowMode:
817 if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
818 gcmask |= index;
819 gcval[i++].val = newValues[SUBWINDOW].val;
821 break;
822 case GCTile:
823 if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
825 gcmask |= index;
826 gcval[i++].ptr = newValues[TILE].ptr;
828 break;
829 case GCFillStyle:
830 if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
831 gcmask |= index;
832 gcval[i++].val = newValues[FILLSTYLE].val;
834 break;
835 case GCForeground:
836 if ( pGC->fgPixel != newValues[FOREGROUND].val) {
837 gcmask |= index;
838 gcval[i++].val = newValues[FOREGROUND].val;
840 break;
844 if (gcmask)
845 dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
847 if (pWin->drawable.serialNumber != pGC->serialNumber)
848 ValidateGC((DrawablePtr)pWin, pGC);
850 numRects = REGION_NUM_RECTS(prgn);
851 pbox = REGION_RECTS(prgn);
852 for (i= numRects; --i >= 0; pbox++, prect++)
854 prect->x = pbox->x1 - pWin->drawable.x;
855 prect->y = pbox->y1 - pWin->drawable.y;
856 prect->width = pbox->x2 - pbox->x1;
857 prect->height = pbox->y2 - pbox->y1;
859 prect -= numRects;
860 (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
861 DEALLOCATE_LOCAL(prect);
863 if (pWin->backStorage)
864 (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
866 if (usingScratchGC)
868 if (what == PW_BORDER)
870 REGION_UNINIT(pScreen, &pWin->clipList);
871 pWin->clipList = prgnWin;
872 pWin->drawable.x = oldCorner.x;
873 pWin->drawable.y = oldCorner.y;
874 pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
876 FreeScratchGC(pGC);
881 /* MICLEARDRAWABLE -- sets the entire drawable to the background color of
882 * the GC. Useful when we have a scratch drawable and need to initialize
883 * it. */
884 _X_EXPORT void
885 miClearDrawable(pDraw, pGC)
886 DrawablePtr pDraw;
887 GCPtr pGC;
889 XID fg = pGC->fgPixel;
890 XID bg = pGC->bgPixel;
891 xRectangle rect;
893 rect.x = 0;
894 rect.y = 0;
895 rect.width = pDraw->width;
896 rect.height = pDraw->height;
897 DoChangeGC(pGC, GCForeground, &bg, 0);
898 ValidateGC(pDraw, pGC);
899 (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
900 DoChangeGC(pGC, GCForeground, &fg, 0);
901 ValidateGC(pDraw, pGC);