Imported Upstream version 1.15.1
[deb_xorg-server.git] / mi / miexpose.c
CommitLineData
a09e091a
JB
1/***********************************************************
2
3Copyright 1987, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
26
27 All Rights Reserved
28
29Permission to use, copy, modify, and distribute this software and its
30documentation for any purpose and without fee is hereby granted,
31provided that the above copyright notice appear in all copies and that
32both that copyright notice and this permission notice appear in
33supporting documentation, and that the name of Digital not be
34used in advertising or publicity pertaining to distribution of the
35software without specific, written prior permission.
36
37DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43SOFTWARE.
44
45******************************************************************/
46/*****************************************************************
47
48Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
49
50Permission is hereby granted, free of charge, to any person obtaining a copy
51of this software and associated documentation files (the "Software"), to deal
52in the Software without restriction, including without limitation the rights
53to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
54copies of the Software.
55
56The above copyright notice and this permission notice shall be included in
57all copies or substantial portions of the Software.
58
59THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
62DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
63BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
64WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
65IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
66
67Except as contained in this notice, the name of Digital Equipment Corporation
68shall not be used in advertising or otherwise to promote the sale, use or other
69dealings in this Software without prior written authorization from Digital
70Equipment Corporation.
71
72******************************************************************/
73
74#ifdef HAVE_DIX_CONFIG_H
75#include <dix-config.h>
76#endif
77
78#include <X11/X.h>
79#include <X11/Xproto.h>
80#include <X11/Xprotostr.h>
81
82#include "misc.h"
83#include "regionstr.h"
84#include "scrnintstr.h"
85#include "gcstruct.h"
86#include "windowstr.h"
87#include "pixmap.h"
88#include "input.h"
89
90#include "dixstruct.h"
91#include "mi.h"
92#include <X11/Xmd.h>
93
94#include "globals.h"
95
96#ifdef PANORAMIX
97#include "panoramiX.h"
98#include "panoramiXsrv.h"
99#endif
100
101/*
102 machine-independent graphics exposure code. any device that uses
103the region package can call this.
104*/
105
106#ifndef RECTLIMIT
107#define RECTLIMIT 25 /* pick a number, any number > 8 */
108#endif
109
110/* miHandleExposures
111 generate a region for exposures for areas that were copied from obscured or
112non-existent areas to non-obscured areas of the destination. Paint the
113background for the region, if the destination is a window.
114
115NOTE:
116 this should generally be called, even if graphicsExposures is false,
117because this is where bits get recovered from backing store.
118
119NOTE:
120 added argument 'plane' is used to indicate how exposures from backing
121store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
122should be used, else a CopyPlane of the indicated plane will be used. The
123exposing is done by the backing store's GraphicsExpose function, of course.
124
125*/
126
127RegionPtr
128miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
129 GCPtr pGC, int srcx, int srcy, int width, int height,
130 int dstx, int dsty, unsigned long plane)
131{
132 RegionPtr prgnSrcClip; /* drawable-relative source clip */
133 RegionRec rgnSrcRec;
134 RegionPtr prgnDstClip; /* drawable-relative dest clip */
135 RegionRec rgnDstRec;
136 BoxRec srcBox; /* unclipped source */
137 RegionRec rgnExposed; /* exposed region, calculated source-
138 relative, made dst relative to
139 intersect with visible parts of
140 dest and send events to client,
141 and then screen relative to paint
142 the window background
143 */
144 WindowPtr pSrcWin;
145 BoxRec expBox;
146 Bool extents;
147
148 /* avoid work if we can */
149 if (!pGC->graphicsExposures &&
150 (pDstDrawable->type == DRAWABLE_PIXMAP) &&
151 ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
152 (((WindowPtr) pSrcDrawable)->backStorage == NULL)))
153 return NULL;
154
155 srcBox.x1 = srcx;
156 srcBox.y1 = srcy;
157 srcBox.x2 = srcx + width;
158 srcBox.y2 = srcy + height;
159
160 if (pSrcDrawable->type != DRAWABLE_PIXMAP) {
161 BoxRec TsrcBox;
162
163 TsrcBox.x1 = srcx + pSrcDrawable->x;
164 TsrcBox.y1 = srcy + pSrcDrawable->y;
165 TsrcBox.x2 = TsrcBox.x1 + width;
166 TsrcBox.y2 = TsrcBox.y1 + height;
167 pSrcWin = (WindowPtr) pSrcDrawable;
168 if (pGC->subWindowMode == IncludeInferiors) {
169 prgnSrcClip = NotClippedByChildren(pSrcWin);
170 if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) {
171 RegionDestroy(prgnSrcClip);
172 return NULL;
173 }
174 }
175 else {
176 if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN)
177 return NULL;
178 prgnSrcClip = &rgnSrcRec;
179 RegionNull(prgnSrcClip);
180 RegionCopy(prgnSrcClip, &pSrcWin->clipList);
181 }
182 RegionTranslate(prgnSrcClip, -pSrcDrawable->x, -pSrcDrawable->y);
183 }
184 else {
185 BoxRec box;
186
187 if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
188 (srcBox.x2 <= pSrcDrawable->width) &&
189 (srcBox.y2 <= pSrcDrawable->height))
190 return NULL;
191
192 box.x1 = 0;
193 box.y1 = 0;
194 box.x2 = pSrcDrawable->width;
195 box.y2 = pSrcDrawable->height;
196 prgnSrcClip = &rgnSrcRec;
197 RegionInit(prgnSrcClip, &box, 1);
198 pSrcWin = NULL;
199 }
200
201 if (pDstDrawable == pSrcDrawable) {
202 prgnDstClip = prgnSrcClip;
203 }
204 else if (pDstDrawable->type != DRAWABLE_PIXMAP) {
205 if (pGC->subWindowMode == IncludeInferiors) {
206 prgnDstClip = NotClippedByChildren((WindowPtr) pDstDrawable);
207 }
208 else {
209 prgnDstClip = &rgnDstRec;
210 RegionNull(prgnDstClip);
211 RegionCopy(prgnDstClip, &((WindowPtr) pDstDrawable)->clipList);
212 }
213 RegionTranslate(prgnDstClip, -pDstDrawable->x, -pDstDrawable->y);
214 }
215 else {
216 BoxRec box;
217
218 box.x1 = 0;
219 box.y1 = 0;
220 box.x2 = pDstDrawable->width;
221 box.y2 = pDstDrawable->height;
222 prgnDstClip = &rgnDstRec;
223 RegionInit(prgnDstClip, &box, 1);
224 }
225
226 /* drawable-relative source region */
227 RegionInit(&rgnExposed, &srcBox, 1);
228
229 /* now get the hidden parts of the source box */
230 RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip);
231
232 /* move them over the destination */
233 RegionTranslate(&rgnExposed, dstx - srcx, dsty - srcy);
234
235 /* intersect with visible areas of dest */
236 RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip);
237
238 /* intersect with client clip region. */
239 if (pGC->clientClipType == CT_REGION)
240 RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip);
241
242 /*
243 * If we have LOTS of rectangles, we decide to take the extents
244 * and force an exposure on that. This should require much less
245 * work overall, on both client and server. This is cheating, but
246 * isn't prohibited by the protocol ("spontaneous combustion" :-)
247 * for windows.
248 */
249 extents = pGC->graphicsExposures &&
250 (RegionNumRects(&rgnExposed) > RECTLIMIT) &&
251 (pDstDrawable->type != DRAWABLE_PIXMAP);
252 if (pSrcWin) {
253 RegionPtr region;
254
255 if (!(region = wClipShape(pSrcWin)))
256 region = wBoundingShape(pSrcWin);
257 /*
258 * If you try to CopyArea the extents of a shaped window, compacting the
259 * exposed region will undo all our work!
260 */
261 if (extents && pSrcWin && region &&
262 (RegionContainsRect(region, &srcBox) != rgnIN))
263 extents = FALSE;
264 }
265 if (extents) {
266 expBox = *RegionExtents(&rgnExposed);
267 RegionReset(&rgnExposed, &expBox);
268 }
269 if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
270 (((WindowPtr) pDstDrawable)->backgroundState != None)) {
271 WindowPtr pWin = (WindowPtr) pDstDrawable;
272
273 /* make the exposed area screen-relative */
274 RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y);
275
276 if (extents) {
277 /* miPaintWindow doesn't clip, so we have to */
278 RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList);
279 }
280 miPaintWindow((WindowPtr) pDstDrawable, &rgnExposed, PW_BACKGROUND);
281
282 if (extents) {
283 RegionReset(&rgnExposed, &expBox);
284 }
285 else
286 RegionTranslate(&rgnExposed, -pDstDrawable->x, -pDstDrawable->y);
287 }
288 if (prgnDstClip == &rgnDstRec) {
289 RegionUninit(prgnDstClip);
290 }
291 else if (prgnDstClip != prgnSrcClip) {
292 RegionDestroy(prgnDstClip);
293 }
294
295 if (prgnSrcClip == &rgnSrcRec) {
296 RegionUninit(prgnSrcClip);
297 }
298 else {
299 RegionDestroy(prgnSrcClip);
300 }
301
302 if (pGC->graphicsExposures) {
303 /* don't look */
304 RegionPtr exposed = RegionCreate(NullBox, 0);
305
306 *exposed = rgnExposed;
307 return exposed;
308 }
309 else {
310 RegionUninit(&rgnExposed);
311 return NULL;
312 }
313}
314
315/* send GraphicsExpose events, or a NoExpose event, based on the region */
316
317void
318miSendGraphicsExpose(ClientPtr client, RegionPtr pRgn, XID drawable,
319 int major, int minor)
320{
321 if (pRgn && !RegionNil(pRgn)) {
322 xEvent *pEvent;
323 xEvent *pe;
324 BoxPtr pBox;
325 int i;
326 int numRects;
327
328 numRects = RegionNumRects(pRgn);
329 pBox = RegionRects(pRgn);
330 if (!(pEvent = calloc(numRects, sizeof(xEvent))))
331 return;
332 pe = pEvent;
333
334 for (i = 1; i <= numRects; i++, pe++, pBox++) {
335 pe->u.u.type = GraphicsExpose;
336 pe->u.graphicsExposure.drawable = drawable;
337 pe->u.graphicsExposure.x = pBox->x1;
338 pe->u.graphicsExposure.y = pBox->y1;
339 pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
340 pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
341 pe->u.graphicsExposure.count = numRects - i;
342 pe->u.graphicsExposure.majorEvent = major;
343 pe->u.graphicsExposure.minorEvent = minor;
344 }
345 /* GraphicsExpose is a "critical event", which TryClientEvents
346 * handles specially. */
347 TryClientEvents(client, NULL, pEvent, numRects,
348 (Mask) 0, NoEventMask, NullGrab);
349 free(pEvent);
350 }
351 else {
352 xEvent event = {
353 .u.noExposure.drawable = drawable,
354 .u.noExposure.majorEvent = major,
355 .u.noExposure.minorEvent = minor
356 };
357 event.u.u.type = NoExpose;
358 WriteEventsToClient(client, 1, &event);
359 }
360}
361
362void
363miSendExposures(WindowPtr pWin, RegionPtr pRgn, int dx, int dy)
364{
365 BoxPtr pBox;
366 int numRects;
367 xEvent *pEvent, *pe;
368 int i;
369
370 pBox = RegionRects(pRgn);
371 numRects = RegionNumRects(pRgn);
372 if (!(pEvent = calloc(1, numRects * sizeof(xEvent))))
373 return;
374
375 for (i = numRects, pe = pEvent; --i >= 0; pe++, pBox++) {
376 pe->u.u.type = Expose;
377 pe->u.expose.window = pWin->drawable.id;
378 pe->u.expose.x = pBox->x1 - dx;
379 pe->u.expose.y = pBox->y1 - dy;
380 pe->u.expose.width = pBox->x2 - pBox->x1;
381 pe->u.expose.height = pBox->y2 - pBox->y1;
382 pe->u.expose.count = i;
383 }
384
385#ifdef PANORAMIX
386 if (!noPanoramiXExtension) {
387 int scrnum = pWin->drawable.pScreen->myNum;
388 int x = 0, y = 0;
389 XID realWin = 0;
390
391 if (!pWin->parent) {
392 x = screenInfo.screens[scrnum]->x;
393 y = screenInfo.screens[scrnum]->y;
394 pWin = screenInfo.screens[0]->root;
395 realWin = pWin->drawable.id;
396 }
397 else if (scrnum) {
398 PanoramiXRes *win;
399
400 win = PanoramiXFindIDByScrnum(XRT_WINDOW,
401 pWin->drawable.id, scrnum);
402 if (!win) {
403 free(pEvent);
404 return;
405 }
406 realWin = win->info[0].id;
407 dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess);
408 }
409 if (x || y || scrnum)
410 for (i = 0; i < numRects; i++) {
411 pEvent[i].u.expose.window = realWin;
412 pEvent[i].u.expose.x += x;
413 pEvent[i].u.expose.y += y;
414 }
415 }
416#endif
417
418 DeliverEvents(pWin, pEvent, numRects, NullWindow);
419
420 free(pEvent);
421}
422
423void
424miWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed)
425{
426 RegionPtr exposures = prgn;
427
428 if ((prgn && !RegionNil(prgn)) ||
429 (exposures && !RegionNil(exposures)) || other_exposed) {
430 RegionRec expRec;
431 int clientInterested;
432
433 /*
434 * Restore from backing-store FIRST.
435 */
436 clientInterested =
437 (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask;
438 if (other_exposed) {
439 if (exposures) {
440 RegionUnion(other_exposed, exposures, other_exposed);
441 if (exposures != prgn)
442 RegionDestroy(exposures);
443 }
444 exposures = other_exposed;
445 }
446 if (clientInterested && exposures &&
447 (RegionNumRects(exposures) > RECTLIMIT)) {
448 /*
449 * If we have LOTS of rectangles, we decide to take the extents
450 * and force an exposure on that. This should require much less
451 * work overall, on both client and server. This is cheating, but
452 * isn't prohibited by the protocol ("spontaneous combustion" :-).
453 */
454 BoxRec box;
455
456 box = *RegionExtents(exposures);
457 if (exposures == prgn) {
458 exposures = &expRec;
459 RegionInit(exposures, &box, 1);
460 RegionReset(prgn, &box);
461 }
462 else {
463 RegionReset(exposures, &box);
464 RegionUnion(prgn, prgn, exposures);
465 }
466 /* miPaintWindow doesn't clip, so we have to */
467 RegionIntersect(prgn, prgn, &pWin->clipList);
468 }
469 if (prgn && !RegionNil(prgn))
470 miPaintWindow(pWin, prgn, PW_BACKGROUND);
471 if (clientInterested && exposures && !RegionNil(exposures))
472 miSendExposures(pWin, exposures,
473 pWin->drawable.x, pWin->drawable.y);
474 if (exposures == &expRec) {
475 RegionUninit(exposures);
476 }
477 else if (exposures && exposures != prgn && exposures != other_exposed)
478 RegionDestroy(exposures);
479 if (prgn)
480 RegionEmpty(prgn);
481 }
482 else if (exposures && exposures != prgn)
483 RegionDestroy(exposures);
484}
485
486#ifdef ROOTLESS
487/* Ugly, ugly, but we lost our hooks into miPaintWindow... =/ */
488void RootlessSetPixmapOfAncestors(WindowPtr pWin);
489void RootlessStartDrawing(WindowPtr pWin);
490void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn);
491Bool IsFramedWindow(WindowPtr pWin);
492#endif
493
494void
495miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
496{
497 ScreenPtr pScreen = pWin->drawable.pScreen;
498 ChangeGCVal gcval[6];
499 BITS32 gcmask;
500 GCPtr pGC;
501 int i;
502 BoxPtr pbox;
503 xRectangle *prect;
504 int numRects;
505
506 /*
507 * Distance from screen to destination drawable, use this
508 * to adjust rendering coordinates which come in in screen space
509 */
510 int draw_x_off, draw_y_off;
511
512 /*
513 * Tile offset for drawing; these need to align the tile
514 * to the appropriate window origin
515 */
516 int tile_x_off, tile_y_off;
517 PixUnion fill;
518 Bool solid = TRUE;
519 DrawablePtr drawable = &pWin->drawable;
520
521#ifdef ROOTLESS
522 if (!drawable || drawable->type == UNDRAWABLE_WINDOW)
523 return;
524
525 if (IsFramedWindow(pWin)) {
526 RootlessStartDrawing(pWin);
527 RootlessDamageRegion(pWin, prgn);
528
529 if (pWin->backgroundState == ParentRelative) {
530 if ((what == PW_BACKGROUND) ||
531 (what == PW_BORDER && !pWin->borderIsPixel))
532 RootlessSetPixmapOfAncestors(pWin);
533 }
534 }
535#endif
536
537 if (what == PW_BACKGROUND) {
538 while (pWin->backgroundState == ParentRelative)
539 pWin = pWin->parent;
540
541 draw_x_off = drawable->x;
542 draw_y_off = drawable->y;
543
544 tile_x_off = pWin->drawable.x - draw_x_off;
545 tile_y_off = pWin->drawable.y - draw_y_off;
546 fill = pWin->background;
547#ifdef COMPOSITE
548 if (pWin->inhibitBGPaint)
549 return;
550#endif
551 switch (pWin->backgroundState) {
552 case None:
553 return;
554 case BackgroundPixmap:
555 solid = FALSE;
556 break;
557 }
558 }
559 else {
560 PixmapPtr pixmap;
561
562 tile_x_off = drawable->x;
563 tile_y_off = drawable->y;
564
565 /* servers without pixmaps draw their own borders */
566 if (!pScreen->GetWindowPixmap)
567 return;
568 pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable);
569 drawable = &pixmap->drawable;
570#ifdef COMPOSITE
571 draw_x_off = pixmap->screen_x;
572 draw_y_off = pixmap->screen_y;
573 tile_x_off -= draw_x_off;
574 tile_y_off -= draw_y_off;
575#else
576 draw_x_off = 0;
577 draw_y_off = 0;
578#endif
579 fill = pWin->border;
580 solid = pWin->borderIsPixel;
581 }
582
583 gcval[0].val = GXcopy;
584 gcmask = GCFunction;
585
586#ifdef ROOTLESS_SAFEALPHA
587/* Bit mask for alpha channel with a particular number of bits per
588 * pixel. Note that we only care for 32bpp data. Mac OS X uses planar
589 * alpha for 16bpp.
590 */
591#define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0)
592#endif
593
594 if (solid) {
595#ifdef ROOTLESS_SAFEALPHA
596 gcval[1].val =
597 fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel);
598#else
599 gcval[1].val = fill.pixel;
600#endif
601 gcval[2].val = FillSolid;
602 gcmask |= GCForeground | GCFillStyle;
603 }
604 else {
605 int c = 1;
606
607#ifdef ROOTLESS_SAFEALPHA
608 gcval[c++].val =
609 ((CARD32) -1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel);
610 gcmask |= GCPlaneMask;
611#endif
612 gcval[c++].val = FillTiled;
613 gcval[c++].ptr = (pointer) fill.pixmap;
614 gcval[c++].val = tile_x_off;
615 gcval[c++].val = tile_y_off;
616 gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
617 }
618
619 prect = malloc(RegionNumRects(prgn) * sizeof(xRectangle));
620 if (!prect)
621 return;
622
623 pGC = GetScratchGC(drawable->depth, drawable->pScreen);
624 if (!pGC) {
625 free(prect);
626 return;
627 }
628
629 ChangeGC(NullClient, pGC, gcmask, gcval);
630 ValidateGC(drawable, pGC);
631
632 numRects = RegionNumRects(prgn);
633 pbox = RegionRects(prgn);
634 for (i = numRects; --i >= 0; pbox++, prect++) {
635 prect->x = pbox->x1 - draw_x_off;
636 prect->y = pbox->y1 - draw_y_off;
637 prect->width = pbox->x2 - pbox->x1;
638 prect->height = pbox->y2 - pbox->y1;
639 }
640 prect -= numRects;
641 (*pGC->ops->PolyFillRect) (drawable, pGC, numRects, prect);
642 free(prect);
643
644 FreeScratchGC(pGC);
645}
646
647/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
648 * the GC. Useful when we have a scratch drawable and need to initialize
649 * it. */
650void
651miClearDrawable(DrawablePtr pDraw, GCPtr pGC)
652{
653 ChangeGCVal fg, bg;
654 xRectangle rect;
655
656 fg.val = pGC->fgPixel;
657 bg.val = pGC->bgPixel;
658 rect.x = 0;
659 rect.y = 0;
660 rect.width = pDraw->width;
661 rect.height = pDraw->height;
662 ChangeGC(NullClient, pGC, GCForeground, &bg);
663 ValidateGC(pDraw, pGC);
664 (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect);
665 ChangeGC(NullClient, pGC, GCForeground, &fg);
666 ValidateGC(pDraw, pGC);
667}