miexpose.c revision 05b261ec
105b261ecSmrg/*********************************************************** 205b261ecSmrg 305b261ecSmrgCopyright 1987, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrg 2605b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 2705b261ecSmrg 2805b261ecSmrg All Rights Reserved 2905b261ecSmrg 3005b261ecSmrgPermission to use, copy, modify, and distribute this software and its 3105b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 3205b261ecSmrgprovided that the above copyright notice appear in all copies and that 3305b261ecSmrgboth that copyright notice and this permission notice appear in 3405b261ecSmrgsupporting documentation, and that the name of Digital not be 3505b261ecSmrgused in advertising or publicity pertaining to distribution of the 3605b261ecSmrgsoftware without specific, written prior permission. 3705b261ecSmrg 3805b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3905b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 4005b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4105b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4205b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4305b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4405b261ecSmrgSOFTWARE. 4505b261ecSmrg 4605b261ecSmrg******************************************************************/ 4705b261ecSmrg/***************************************************************** 4805b261ecSmrg 4905b261ecSmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 5005b261ecSmrg 5105b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a copy 5205b261ecSmrgof this software and associated documentation files (the "Software"), to deal 5305b261ecSmrgin the Software without restriction, including without limitation the rights 5405b261ecSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5505b261ecSmrgcopies of the Software. 5605b261ecSmrg 5705b261ecSmrgThe above copyright notice and this permission notice shall be included in 5805b261ecSmrgall copies or substantial portions of the Software. 5905b261ecSmrg 6005b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6105b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 6205b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 6305b261ecSmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 6405b261ecSmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 6505b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 6605b261ecSmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6705b261ecSmrg 6805b261ecSmrgExcept as contained in this notice, the name of Digital Equipment Corporation 6905b261ecSmrgshall not be used in advertising or otherwise to promote the sale, use or other 7005b261ecSmrgdealings in this Software without prior written authorization from Digital 7105b261ecSmrgEquipment Corporation. 7205b261ecSmrg 7305b261ecSmrg******************************************************************/ 7405b261ecSmrg 7505b261ecSmrg 7605b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 7705b261ecSmrg#include <dix-config.h> 7805b261ecSmrg#endif 7905b261ecSmrg 8005b261ecSmrg#include <X11/X.h> 8105b261ecSmrg#define NEED_EVENTS 8205b261ecSmrg#include <X11/Xproto.h> 8305b261ecSmrg#include <X11/Xprotostr.h> 8405b261ecSmrg 8505b261ecSmrg#include "misc.h" 8605b261ecSmrg#include "regionstr.h" 8705b261ecSmrg#include "scrnintstr.h" 8805b261ecSmrg#include "gcstruct.h" 8905b261ecSmrg#include "windowstr.h" 9005b261ecSmrg#include "pixmap.h" 9105b261ecSmrg#include "input.h" 9205b261ecSmrg 9305b261ecSmrg#include "dixstruct.h" 9405b261ecSmrg#include "mi.h" 9505b261ecSmrg#include <X11/Xmd.h> 9605b261ecSmrg 9705b261ecSmrg#include "globals.h" 9805b261ecSmrg 9905b261ecSmrg#ifdef PANORAMIX 10005b261ecSmrg#include "panoramiX.h" 10105b261ecSmrg#include "panoramiXsrv.h" 10205b261ecSmrg#endif 10305b261ecSmrg 10405b261ecSmrg/* 10505b261ecSmrg machine-independent graphics exposure code. any device that uses 10605b261ecSmrgthe region package can call this. 10705b261ecSmrg*/ 10805b261ecSmrg 10905b261ecSmrg#ifndef RECTLIMIT 11005b261ecSmrg#define RECTLIMIT 25 /* pick a number, any number > 8 */ 11105b261ecSmrg#endif 11205b261ecSmrg 11305b261ecSmrg/* miHandleExposures 11405b261ecSmrg generate a region for exposures for areas that were copied from obscured or 11505b261ecSmrgnon-existent areas to non-obscured areas of the destination. Paint the 11605b261ecSmrgbackground for the region, if the destination is a window. 11705b261ecSmrg 11805b261ecSmrgNOTE: 11905b261ecSmrg this should generally be called, even if graphicsExposures is false, 12005b261ecSmrgbecause this is where bits get recovered from backing store. 12105b261ecSmrg 12205b261ecSmrgNOTE: 12305b261ecSmrg added argument 'plane' is used to indicate how exposures from backing 12405b261ecSmrgstore should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea 12505b261ecSmrgshould be used, else a CopyPlane of the indicated plane will be used. The 12605b261ecSmrgexposing is done by the backing store's GraphicsExpose function, of course. 12705b261ecSmrg 12805b261ecSmrg*/ 12905b261ecSmrg 13005b261ecSmrg_X_EXPORT RegionPtr 13105b261ecSmrgmiHandleExposures(pSrcDrawable, pDstDrawable, 13205b261ecSmrg pGC, srcx, srcy, width, height, dstx, dsty, plane) 13305b261ecSmrg DrawablePtr pSrcDrawable; 13405b261ecSmrg DrawablePtr pDstDrawable; 13505b261ecSmrg GCPtr pGC; 13605b261ecSmrg int srcx, srcy; 13705b261ecSmrg int width, height; 13805b261ecSmrg int dstx, dsty; 13905b261ecSmrg unsigned long plane; 14005b261ecSmrg{ 14105b261ecSmrg ScreenPtr pscr; 14205b261ecSmrg RegionPtr prgnSrcClip; /* drawable-relative source clip */ 14305b261ecSmrg RegionRec rgnSrcRec; 14405b261ecSmrg RegionPtr prgnDstClip; /* drawable-relative dest clip */ 14505b261ecSmrg RegionRec rgnDstRec; 14605b261ecSmrg BoxRec srcBox; /* unclipped source */ 14705b261ecSmrg RegionRec rgnExposed; /* exposed region, calculated source- 14805b261ecSmrg relative, made dst relative to 14905b261ecSmrg intersect with visible parts of 15005b261ecSmrg dest and send events to client, 15105b261ecSmrg and then screen relative to paint 15205b261ecSmrg the window background 15305b261ecSmrg */ 15405b261ecSmrg WindowPtr pSrcWin; 15505b261ecSmrg BoxRec expBox; 15605b261ecSmrg Bool extents; 15705b261ecSmrg 15805b261ecSmrg /* This prevents warning about pscr not being used. */ 15905b261ecSmrg pGC->pScreen = pscr = pGC->pScreen; 16005b261ecSmrg 16105b261ecSmrg /* avoid work if we can */ 16205b261ecSmrg if (!pGC->graphicsExposures && 16305b261ecSmrg (pDstDrawable->type == DRAWABLE_PIXMAP) && 16405b261ecSmrg ((pSrcDrawable->type == DRAWABLE_PIXMAP) || 16505b261ecSmrg (((WindowPtr)pSrcDrawable)->backStorage == NULL))) 16605b261ecSmrg return NULL; 16705b261ecSmrg 16805b261ecSmrg srcBox.x1 = srcx; 16905b261ecSmrg srcBox.y1 = srcy; 17005b261ecSmrg srcBox.x2 = srcx+width; 17105b261ecSmrg srcBox.y2 = srcy+height; 17205b261ecSmrg 17305b261ecSmrg if (pSrcDrawable->type != DRAWABLE_PIXMAP) 17405b261ecSmrg { 17505b261ecSmrg BoxRec TsrcBox; 17605b261ecSmrg 17705b261ecSmrg TsrcBox.x1 = srcx + pSrcDrawable->x; 17805b261ecSmrg TsrcBox.y1 = srcy + pSrcDrawable->y; 17905b261ecSmrg TsrcBox.x2 = TsrcBox.x1 + width; 18005b261ecSmrg TsrcBox.y2 = TsrcBox.y1 + height; 18105b261ecSmrg pSrcWin = (WindowPtr) pSrcDrawable; 18205b261ecSmrg if (pGC->subWindowMode == IncludeInferiors) 18305b261ecSmrg { 18405b261ecSmrg prgnSrcClip = NotClippedByChildren (pSrcWin); 18505b261ecSmrg if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN) 18605b261ecSmrg { 18705b261ecSmrg REGION_DESTROY(pscr, prgnSrcClip); 18805b261ecSmrg return NULL; 18905b261ecSmrg } 19005b261ecSmrg } 19105b261ecSmrg else 19205b261ecSmrg { 19305b261ecSmrg if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN) 19405b261ecSmrg return NULL; 19505b261ecSmrg prgnSrcClip = &rgnSrcRec; 19605b261ecSmrg REGION_NULL(pscr, prgnSrcClip); 19705b261ecSmrg REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList); 19805b261ecSmrg } 19905b261ecSmrg REGION_TRANSLATE(pscr, prgnSrcClip, 20005b261ecSmrg -pSrcDrawable->x, -pSrcDrawable->y); 20105b261ecSmrg } 20205b261ecSmrg else 20305b261ecSmrg { 20405b261ecSmrg BoxRec box; 20505b261ecSmrg 20605b261ecSmrg if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && 20705b261ecSmrg (srcBox.x2 <= pSrcDrawable->width) && 20805b261ecSmrg (srcBox.y2 <= pSrcDrawable->height)) 20905b261ecSmrg return NULL; 21005b261ecSmrg 21105b261ecSmrg box.x1 = 0; 21205b261ecSmrg box.y1 = 0; 21305b261ecSmrg box.x2 = pSrcDrawable->width; 21405b261ecSmrg box.y2 = pSrcDrawable->height; 21505b261ecSmrg prgnSrcClip = &rgnSrcRec; 21605b261ecSmrg REGION_INIT(pscr, prgnSrcClip, &box, 1); 21705b261ecSmrg pSrcWin = (WindowPtr)NULL; 21805b261ecSmrg } 21905b261ecSmrg 22005b261ecSmrg if (pDstDrawable == pSrcDrawable) 22105b261ecSmrg { 22205b261ecSmrg prgnDstClip = prgnSrcClip; 22305b261ecSmrg } 22405b261ecSmrg else if (pDstDrawable->type != DRAWABLE_PIXMAP) 22505b261ecSmrg { 22605b261ecSmrg if (pGC->subWindowMode == IncludeInferiors) 22705b261ecSmrg { 22805b261ecSmrg prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable); 22905b261ecSmrg } 23005b261ecSmrg else 23105b261ecSmrg { 23205b261ecSmrg prgnDstClip = &rgnDstRec; 23305b261ecSmrg REGION_NULL(pscr, prgnDstClip); 23405b261ecSmrg REGION_COPY(pscr, prgnDstClip, 23505b261ecSmrg &((WindowPtr)pDstDrawable)->clipList); 23605b261ecSmrg } 23705b261ecSmrg REGION_TRANSLATE(pscr, prgnDstClip, 23805b261ecSmrg -pDstDrawable->x, -pDstDrawable->y); 23905b261ecSmrg } 24005b261ecSmrg else 24105b261ecSmrg { 24205b261ecSmrg BoxRec box; 24305b261ecSmrg 24405b261ecSmrg box.x1 = 0; 24505b261ecSmrg box.y1 = 0; 24605b261ecSmrg box.x2 = pDstDrawable->width; 24705b261ecSmrg box.y2 = pDstDrawable->height; 24805b261ecSmrg prgnDstClip = &rgnDstRec; 24905b261ecSmrg REGION_INIT(pscr, prgnDstClip, &box, 1); 25005b261ecSmrg } 25105b261ecSmrg 25205b261ecSmrg /* drawable-relative source region */ 25305b261ecSmrg REGION_INIT(pscr, &rgnExposed, &srcBox, 1); 25405b261ecSmrg 25505b261ecSmrg /* now get the hidden parts of the source box*/ 25605b261ecSmrg REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip); 25705b261ecSmrg 25805b261ecSmrg if (pSrcWin && pSrcWin->backStorage) 25905b261ecSmrg { 26005b261ecSmrg /* 26105b261ecSmrg * Copy any areas from the source backing store. Modifies 26205b261ecSmrg * rgnExposed. 26305b261ecSmrg */ 26405b261ecSmrg (* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable, 26505b261ecSmrg pDstDrawable, 26605b261ecSmrg pGC, 26705b261ecSmrg &rgnExposed, 26805b261ecSmrg srcx, srcy, 26905b261ecSmrg dstx, dsty, 27005b261ecSmrg plane); 27105b261ecSmrg } 27205b261ecSmrg 27305b261ecSmrg /* move them over the destination */ 27405b261ecSmrg REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy); 27505b261ecSmrg 27605b261ecSmrg /* intersect with visible areas of dest */ 27705b261ecSmrg REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip); 27805b261ecSmrg 27905b261ecSmrg /* 28005b261ecSmrg * If we have LOTS of rectangles, we decide to take the extents 28105b261ecSmrg * and force an exposure on that. This should require much less 28205b261ecSmrg * work overall, on both client and server. This is cheating, but 28305b261ecSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-) 28405b261ecSmrg * for windows. 28505b261ecSmrg */ 28605b261ecSmrg extents = pGC->graphicsExposures && 28705b261ecSmrg (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) && 28805b261ecSmrg (pDstDrawable->type != DRAWABLE_PIXMAP); 28905b261ecSmrg#ifdef SHAPE 29005b261ecSmrg if (pSrcWin) 29105b261ecSmrg { 29205b261ecSmrg RegionPtr region; 29305b261ecSmrg if (!(region = wClipShape (pSrcWin))) 29405b261ecSmrg region = wBoundingShape (pSrcWin); 29505b261ecSmrg /* 29605b261ecSmrg * If you try to CopyArea the extents of a shaped window, compacting the 29705b261ecSmrg * exposed region will undo all our work! 29805b261ecSmrg */ 29905b261ecSmrg if (extents && pSrcWin && region && 30005b261ecSmrg (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN)) 30105b261ecSmrg extents = FALSE; 30205b261ecSmrg } 30305b261ecSmrg#endif 30405b261ecSmrg if (extents) 30505b261ecSmrg { 30605b261ecSmrg WindowPtr pWin = (WindowPtr)pDstDrawable; 30705b261ecSmrg 30805b261ecSmrg expBox = *REGION_EXTENTS(pscr, &rgnExposed); 30905b261ecSmrg REGION_RESET(pscr, &rgnExposed, &expBox); 31005b261ecSmrg /* need to clear out new areas of backing store */ 31105b261ecSmrg if (pWin->backStorage) 31205b261ecSmrg (void) (* pWin->drawable.pScreen->ClearBackingStore)( 31305b261ecSmrg pWin, 31405b261ecSmrg expBox.x1, 31505b261ecSmrg expBox.y1, 31605b261ecSmrg expBox.x2 - expBox.x1, 31705b261ecSmrg expBox.y2 - expBox.y1, 31805b261ecSmrg FALSE); 31905b261ecSmrg } 32005b261ecSmrg if ((pDstDrawable->type != DRAWABLE_PIXMAP) && 32105b261ecSmrg (((WindowPtr)pDstDrawable)->backgroundState != None)) 32205b261ecSmrg { 32305b261ecSmrg WindowPtr pWin = (WindowPtr)pDstDrawable; 32405b261ecSmrg 32505b261ecSmrg /* make the exposed area screen-relative */ 32605b261ecSmrg REGION_TRANSLATE(pscr, &rgnExposed, 32705b261ecSmrg pDstDrawable->x, pDstDrawable->y); 32805b261ecSmrg 32905b261ecSmrg if (extents) 33005b261ecSmrg { 33105b261ecSmrg /* PaintWindowBackground doesn't clip, so we have to */ 33205b261ecSmrg REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList); 33305b261ecSmrg } 33405b261ecSmrg (*pWin->drawable.pScreen->PaintWindowBackground)( 33505b261ecSmrg (WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND); 33605b261ecSmrg 33705b261ecSmrg if (extents) 33805b261ecSmrg { 33905b261ecSmrg REGION_RESET(pscr, &rgnExposed, &expBox); 34005b261ecSmrg } 34105b261ecSmrg else 34205b261ecSmrg REGION_TRANSLATE(pscr, &rgnExposed, 34305b261ecSmrg -pDstDrawable->x, -pDstDrawable->y); 34405b261ecSmrg } 34505b261ecSmrg if (prgnDstClip == &rgnDstRec) 34605b261ecSmrg { 34705b261ecSmrg REGION_UNINIT(pscr, prgnDstClip); 34805b261ecSmrg } 34905b261ecSmrg else if (prgnDstClip != prgnSrcClip) 35005b261ecSmrg { 35105b261ecSmrg REGION_DESTROY(pscr, prgnDstClip); 35205b261ecSmrg } 35305b261ecSmrg 35405b261ecSmrg if (prgnSrcClip == &rgnSrcRec) 35505b261ecSmrg { 35605b261ecSmrg REGION_UNINIT(pscr, prgnSrcClip); 35705b261ecSmrg } 35805b261ecSmrg else 35905b261ecSmrg { 36005b261ecSmrg REGION_DESTROY(pscr, prgnSrcClip); 36105b261ecSmrg } 36205b261ecSmrg 36305b261ecSmrg if (pGC->graphicsExposures) 36405b261ecSmrg { 36505b261ecSmrg /* don't look */ 36605b261ecSmrg RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0); 36705b261ecSmrg *exposed = rgnExposed; 36805b261ecSmrg return exposed; 36905b261ecSmrg } 37005b261ecSmrg else 37105b261ecSmrg { 37205b261ecSmrg REGION_UNINIT(pscr, &rgnExposed); 37305b261ecSmrg return NULL; 37405b261ecSmrg } 37505b261ecSmrg} 37605b261ecSmrg 37705b261ecSmrg/* send GraphicsExpose events, or a NoExpose event, based on the region */ 37805b261ecSmrg 37905b261ecSmrg_X_EXPORT void 38005b261ecSmrgmiSendGraphicsExpose (client, pRgn, drawable, major, minor) 38105b261ecSmrg ClientPtr client; 38205b261ecSmrg RegionPtr pRgn; 38305b261ecSmrg XID drawable; 38405b261ecSmrg int major; 38505b261ecSmrg int minor; 38605b261ecSmrg{ 38705b261ecSmrg if (pRgn && !REGION_NIL(pRgn)) 38805b261ecSmrg { 38905b261ecSmrg xEvent *pEvent; 39005b261ecSmrg xEvent *pe; 39105b261ecSmrg BoxPtr pBox; 39205b261ecSmrg int i; 39305b261ecSmrg int numRects; 39405b261ecSmrg 39505b261ecSmrg numRects = REGION_NUM_RECTS(pRgn); 39605b261ecSmrg pBox = REGION_RECTS(pRgn); 39705b261ecSmrg if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent)))) 39805b261ecSmrg return; 39905b261ecSmrg pe = pEvent; 40005b261ecSmrg 40105b261ecSmrg for (i=1; i<=numRects; i++, pe++, pBox++) 40205b261ecSmrg { 40305b261ecSmrg pe->u.u.type = GraphicsExpose; 40405b261ecSmrg pe->u.graphicsExposure.drawable = drawable; 40505b261ecSmrg pe->u.graphicsExposure.x = pBox->x1; 40605b261ecSmrg pe->u.graphicsExposure.y = pBox->y1; 40705b261ecSmrg pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; 40805b261ecSmrg pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; 40905b261ecSmrg pe->u.graphicsExposure.count = numRects - i; 41005b261ecSmrg pe->u.graphicsExposure.majorEvent = major; 41105b261ecSmrg pe->u.graphicsExposure.minorEvent = minor; 41205b261ecSmrg } 41305b261ecSmrg TryClientEvents(client, pEvent, numRects, 41405b261ecSmrg (Mask)0, NoEventMask, NullGrab); 41505b261ecSmrg DEALLOCATE_LOCAL(pEvent); 41605b261ecSmrg } 41705b261ecSmrg else 41805b261ecSmrg { 41905b261ecSmrg xEvent event; 42005b261ecSmrg event.u.u.type = NoExpose; 42105b261ecSmrg event.u.noExposure.drawable = drawable; 42205b261ecSmrg event.u.noExposure.majorEvent = major; 42305b261ecSmrg event.u.noExposure.minorEvent = minor; 42405b261ecSmrg TryClientEvents(client, &event, 1, 42505b261ecSmrg (Mask)0, NoEventMask, NullGrab); 42605b261ecSmrg } 42705b261ecSmrg} 42805b261ecSmrg 42905b261ecSmrg 43005b261ecSmrgvoid 43105b261ecSmrgmiSendExposures(pWin, pRgn, dx, dy) 43205b261ecSmrg WindowPtr pWin; 43305b261ecSmrg RegionPtr pRgn; 43405b261ecSmrg int dx, dy; 43505b261ecSmrg{ 43605b261ecSmrg BoxPtr pBox; 43705b261ecSmrg int numRects; 43805b261ecSmrg xEvent *pEvent, *pe; 43905b261ecSmrg int i; 44005b261ecSmrg 44105b261ecSmrg pBox = REGION_RECTS(pRgn); 44205b261ecSmrg numRects = REGION_NUM_RECTS(pRgn); 44305b261ecSmrg if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent)))) 44405b261ecSmrg return; 44505b261ecSmrg 44605b261ecSmrg for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++) 44705b261ecSmrg { 44805b261ecSmrg pe->u.u.type = Expose; 44905b261ecSmrg pe->u.expose.window = pWin->drawable.id; 45005b261ecSmrg pe->u.expose.x = pBox->x1 - dx; 45105b261ecSmrg pe->u.expose.y = pBox->y1 - dy; 45205b261ecSmrg pe->u.expose.width = pBox->x2 - pBox->x1; 45305b261ecSmrg pe->u.expose.height = pBox->y2 - pBox->y1; 45405b261ecSmrg pe->u.expose.count = i; 45505b261ecSmrg } 45605b261ecSmrg 45705b261ecSmrg#ifdef PANORAMIX 45805b261ecSmrg if(!noPanoramiXExtension) { 45905b261ecSmrg int scrnum = pWin->drawable.pScreen->myNum; 46005b261ecSmrg int x = 0, y = 0; 46105b261ecSmrg XID realWin = 0; 46205b261ecSmrg 46305b261ecSmrg if(!pWin->parent) { 46405b261ecSmrg x = panoramiXdataPtr[scrnum].x; 46505b261ecSmrg y = panoramiXdataPtr[scrnum].y; 46605b261ecSmrg pWin = WindowTable[0]; 46705b261ecSmrg realWin = pWin->drawable.id; 46805b261ecSmrg } else if (scrnum) { 46905b261ecSmrg PanoramiXRes *win; 47005b261ecSmrg win = PanoramiXFindIDByScrnum(XRT_WINDOW, 47105b261ecSmrg pWin->drawable.id, scrnum); 47205b261ecSmrg if(!win) { 47305b261ecSmrg DEALLOCATE_LOCAL(pEvent); 47405b261ecSmrg return; 47505b261ecSmrg } 47605b261ecSmrg realWin = win->info[0].id; 47705b261ecSmrg pWin = LookupIDByType(realWin, RT_WINDOW); 47805b261ecSmrg } 47905b261ecSmrg if(x || y || scrnum) 48005b261ecSmrg for (i = 0; i < numRects; i++) { 48105b261ecSmrg pEvent[i].u.expose.window = realWin; 48205b261ecSmrg pEvent[i].u.expose.x += x; 48305b261ecSmrg pEvent[i].u.expose.y += y; 48405b261ecSmrg } 48505b261ecSmrg } 48605b261ecSmrg#endif 48705b261ecSmrg 48805b261ecSmrg DeliverEvents(pWin, pEvent, numRects, NullWindow); 48905b261ecSmrg 49005b261ecSmrg DEALLOCATE_LOCAL(pEvent); 49105b261ecSmrg} 49205b261ecSmrg 49305b261ecSmrg_X_EXPORT void 49405b261ecSmrgmiWindowExposures(pWin, prgn, other_exposed) 49505b261ecSmrg WindowPtr pWin; 49605b261ecSmrg RegionPtr prgn, other_exposed; 49705b261ecSmrg{ 49805b261ecSmrg RegionPtr exposures = prgn; 49905b261ecSmrg if (pWin->backStorage && prgn) 50005b261ecSmrg /* 50105b261ecSmrg * in some cases, backing store will cause a different 50205b261ecSmrg * region to be exposed than needs to be repainted 50305b261ecSmrg * (like when a window is mapped). RestoreAreas is 50405b261ecSmrg * allowed to return a region other than prgn, 50505b261ecSmrg * in which case this routine will free the resultant 50605b261ecSmrg * region. If exposures is null, then no events will 50705b261ecSmrg * be sent to the client; if prgn is empty 50805b261ecSmrg * no areas will be repainted. 50905b261ecSmrg */ 51005b261ecSmrg exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn); 51105b261ecSmrg if ((prgn && !REGION_NIL(prgn)) || 51205b261ecSmrg (exposures && !REGION_NIL(exposures)) || other_exposed) 51305b261ecSmrg { 51405b261ecSmrg RegionRec expRec; 51505b261ecSmrg int clientInterested; 51605b261ecSmrg 51705b261ecSmrg /* 51805b261ecSmrg * Restore from backing-store FIRST. 51905b261ecSmrg */ 52005b261ecSmrg clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask; 52105b261ecSmrg if (other_exposed) 52205b261ecSmrg { 52305b261ecSmrg if (exposures) 52405b261ecSmrg { 52505b261ecSmrg REGION_UNION(pWin->drawable.pScreen, other_exposed, 52605b261ecSmrg exposures, 52705b261ecSmrg other_exposed); 52805b261ecSmrg if (exposures != prgn) 52905b261ecSmrg REGION_DESTROY(pWin->drawable.pScreen, exposures); 53005b261ecSmrg } 53105b261ecSmrg exposures = other_exposed; 53205b261ecSmrg } 53305b261ecSmrg if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT)) 53405b261ecSmrg { 53505b261ecSmrg /* 53605b261ecSmrg * If we have LOTS of rectangles, we decide to take the extents 53705b261ecSmrg * and force an exposure on that. This should require much less 53805b261ecSmrg * work overall, on both client and server. This is cheating, but 53905b261ecSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-). 54005b261ecSmrg */ 54105b261ecSmrg BoxRec box; 54205b261ecSmrg 54305b261ecSmrg box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures); 54405b261ecSmrg if (exposures == prgn) { 54505b261ecSmrg exposures = &expRec; 54605b261ecSmrg REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1); 54705b261ecSmrg REGION_RESET( pWin->drawable.pScreen, prgn, &box); 54805b261ecSmrg } else { 54905b261ecSmrg REGION_RESET( pWin->drawable.pScreen, exposures, &box); 55005b261ecSmrg REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures); 55105b261ecSmrg } 55205b261ecSmrg /* PaintWindowBackground doesn't clip, so we have to */ 55305b261ecSmrg REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList); 55405b261ecSmrg /* need to clear out new areas of backing store, too */ 55505b261ecSmrg if (pWin->backStorage) 55605b261ecSmrg (void) (* pWin->drawable.pScreen->ClearBackingStore)( 55705b261ecSmrg pWin, 55805b261ecSmrg box.x1 - pWin->drawable.x, 55905b261ecSmrg box.y1 - pWin->drawable.y, 56005b261ecSmrg box.x2 - box.x1, 56105b261ecSmrg box.y2 - box.y1, 56205b261ecSmrg FALSE); 56305b261ecSmrg } 56405b261ecSmrg if (prgn && !REGION_NIL(prgn)) 56505b261ecSmrg (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND); 56605b261ecSmrg if (clientInterested && exposures && !REGION_NIL(exposures)) 56705b261ecSmrg miSendExposures(pWin, exposures, 56805b261ecSmrg pWin->drawable.x, pWin->drawable.y); 56905b261ecSmrg if (exposures == &expRec) 57005b261ecSmrg { 57105b261ecSmrg REGION_UNINIT( pWin->drawable.pScreen, exposures); 57205b261ecSmrg } 57305b261ecSmrg else if (exposures && exposures != prgn && exposures != other_exposed) 57405b261ecSmrg REGION_DESTROY( pWin->drawable.pScreen, exposures); 57505b261ecSmrg if (prgn) 57605b261ecSmrg REGION_EMPTY( pWin->drawable.pScreen, prgn); 57705b261ecSmrg } 57805b261ecSmrg else if (exposures && exposures != prgn) 57905b261ecSmrg REGION_DESTROY( pWin->drawable.pScreen, exposures); 58005b261ecSmrg} 58105b261ecSmrg 58205b261ecSmrg 58305b261ecSmrg/* 58405b261ecSmrg this code is highly unlikely. it is not haile selassie. 58505b261ecSmrg 58605b261ecSmrg there is some hair here. we can't just use the window's 58705b261ecSmrgclip region as it is, because if we are painting the border, 58805b261ecSmrgthe border is not in the client area and so we will be excluded 58905b261ecSmrgwhen we validate the GC, and if we are painting a parent-relative 59005b261ecSmrgbackground, the area we want to paint is in some other window. 59105b261ecSmrgsince we trust the code calling us to tell us to paint only areas 59205b261ecSmrgthat are really ours, we will temporarily give the window a 59305b261ecSmrgclipList the size of the whole screen and an origin at (0,0). 59405b261ecSmrgthis more or less assumes that ddX code will do translation 59505b261ecSmrgbased on the window's absolute position, and that ValidateGC will 59605b261ecSmrglook at clipList, and that no other fields from the 59705b261ecSmrgwindow will be used. it's not possible to just draw 59805b261ecSmrgin the root because it may be a different depth. 59905b261ecSmrg 60005b261ecSmrgto get the tile to align correctly we set the GC's tile origin to 60105b261ecSmrgbe the (x,y) of the window's upper left corner, after which we 60205b261ecSmrgget the right bits when drawing into the root. 60305b261ecSmrg 60405b261ecSmrgbecause the clip_mask is being set to None, we may call DoChangeGC with 60505b261ecSmrgfPointer set true, thus we no longer need to install the background or 60605b261ecSmrgborder tile in the resource table. 60705b261ecSmrg*/ 60805b261ecSmrg 60905b261ecSmrgstatic RESTYPE ResType = 0; 61005b261ecSmrgstatic int numGCs = 0; 61105b261ecSmrgstatic GCPtr screenContext[MAXSCREENS]; 61205b261ecSmrg 61305b261ecSmrg/*ARGSUSED*/ 61405b261ecSmrgstatic int 61505b261ecSmrgtossGC ( 61605b261ecSmrg pointer value, 61705b261ecSmrg XID id) 61805b261ecSmrg{ 61905b261ecSmrg GCPtr pGC = (GCPtr)value; 62005b261ecSmrg screenContext[pGC->pScreen->myNum] = (GCPtr)NULL; 62105b261ecSmrg FreeGC (pGC, id); 62205b261ecSmrg numGCs--; 62305b261ecSmrg if (!numGCs) 62405b261ecSmrg ResType = 0; 62505b261ecSmrg 62605b261ecSmrg return 0; 62705b261ecSmrg} 62805b261ecSmrg 62905b261ecSmrg 63005b261ecSmrg_X_EXPORT void 63105b261ecSmrgmiPaintWindow(pWin, prgn, what) 63205b261ecSmrgWindowPtr pWin; 63305b261ecSmrgRegionPtr prgn; 63405b261ecSmrgint what; 63505b261ecSmrg{ 63605b261ecSmrg int status; 63705b261ecSmrg 63805b261ecSmrg Bool usingScratchGC = FALSE; 63905b261ecSmrg WindowPtr pRoot; 64005b261ecSmrg 64105b261ecSmrg#define FUNCTION 0 64205b261ecSmrg#define FOREGROUND 1 64305b261ecSmrg#define TILE 2 64405b261ecSmrg#define FILLSTYLE 3 64505b261ecSmrg#define ABSX 4 64605b261ecSmrg#define ABSY 5 64705b261ecSmrg#define CLIPMASK 6 64805b261ecSmrg#define SUBWINDOW 7 64905b261ecSmrg#define COUNT_BITS 8 65005b261ecSmrg 65105b261ecSmrg ChangeGCVal gcval[7]; 65205b261ecSmrg ChangeGCVal newValues [COUNT_BITS]; 65305b261ecSmrg 65405b261ecSmrg BITS32 gcmask, index, mask; 65505b261ecSmrg RegionRec prgnWin; 65605b261ecSmrg DDXPointRec oldCorner; 65705b261ecSmrg BoxRec box; 65805b261ecSmrg WindowPtr pBgWin; 65905b261ecSmrg GCPtr pGC; 66005b261ecSmrg int i; 66105b261ecSmrg BoxPtr pbox; 66205b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 66305b261ecSmrg xRectangle *prect; 66405b261ecSmrg int numRects; 66505b261ecSmrg 66605b261ecSmrg gcmask = 0; 66705b261ecSmrg 66805b261ecSmrg if (what == PW_BACKGROUND) 66905b261ecSmrg { 67005b261ecSmrg switch (pWin->backgroundState) { 67105b261ecSmrg case None: 67205b261ecSmrg return; 67305b261ecSmrg case ParentRelative: 67405b261ecSmrg (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what); 67505b261ecSmrg return; 67605b261ecSmrg case BackgroundPixel: 67705b261ecSmrg newValues[FOREGROUND].val = pWin->background.pixel; 67805b261ecSmrg newValues[FILLSTYLE].val = FillSolid; 67905b261ecSmrg gcmask |= GCForeground | GCFillStyle; 68005b261ecSmrg break; 68105b261ecSmrg case BackgroundPixmap: 68205b261ecSmrg newValues[TILE].ptr = (pointer)pWin->background.pixmap; 68305b261ecSmrg newValues[FILLSTYLE].val = FillTiled; 68405b261ecSmrg gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; 68505b261ecSmrg break; 68605b261ecSmrg } 68705b261ecSmrg } 68805b261ecSmrg else 68905b261ecSmrg { 69005b261ecSmrg if (pWin->borderIsPixel) 69105b261ecSmrg { 69205b261ecSmrg newValues[FOREGROUND].val = pWin->border.pixel; 69305b261ecSmrg newValues[FILLSTYLE].val = FillSolid; 69405b261ecSmrg gcmask |= GCForeground | GCFillStyle; 69505b261ecSmrg } 69605b261ecSmrg else 69705b261ecSmrg { 69805b261ecSmrg newValues[TILE].ptr = (pointer)pWin->border.pixmap; 69905b261ecSmrg newValues[FILLSTYLE].val = FillTiled; 70005b261ecSmrg gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; 70105b261ecSmrg } 70205b261ecSmrg } 70305b261ecSmrg 70405b261ecSmrg prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) * 70505b261ecSmrg sizeof(xRectangle)); 70605b261ecSmrg if (!prect) 70705b261ecSmrg return; 70805b261ecSmrg 70905b261ecSmrg newValues[FUNCTION].val = GXcopy; 71005b261ecSmrg gcmask |= GCFunction | GCClipMask; 71105b261ecSmrg 71205b261ecSmrg i = pScreen->myNum; 71305b261ecSmrg pRoot = WindowTable[i]; 71405b261ecSmrg 71505b261ecSmrg pBgWin = pWin; 71605b261ecSmrg if (what == PW_BORDER) 71705b261ecSmrg { 71805b261ecSmrg while (pBgWin->backgroundState == ParentRelative) 71905b261ecSmrg pBgWin = pBgWin->parent; 72005b261ecSmrg } 72105b261ecSmrg 72205b261ecSmrg if ((pWin->drawable.depth != pRoot->drawable.depth) || 72305b261ecSmrg (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel)) 72405b261ecSmrg { 72505b261ecSmrg usingScratchGC = TRUE; 72605b261ecSmrg pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); 72705b261ecSmrg if (!pGC) 72805b261ecSmrg { 72905b261ecSmrg DEALLOCATE_LOCAL(prect); 73005b261ecSmrg return; 73105b261ecSmrg } 73205b261ecSmrg /* 73305b261ecSmrg * mash the clip list so we can paint the border by 73405b261ecSmrg * mangling the window in place, pretending it 73505b261ecSmrg * spans the entire screen 73605b261ecSmrg */ 73705b261ecSmrg if (what == PW_BORDER) 73805b261ecSmrg { 73905b261ecSmrg prgnWin = pWin->clipList; 74005b261ecSmrg oldCorner.x = pWin->drawable.x; 74105b261ecSmrg oldCorner.y = pWin->drawable.y; 74205b261ecSmrg pWin->drawable.x = pWin->drawable.y = 0; 74305b261ecSmrg box.x1 = 0; 74405b261ecSmrg box.y1 = 0; 74505b261ecSmrg box.x2 = pScreen->width; 74605b261ecSmrg box.y2 = pScreen->height; 74705b261ecSmrg REGION_INIT(pScreen, &pWin->clipList, &box, 1); 74805b261ecSmrg pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; 74905b261ecSmrg newValues[ABSX].val = pBgWin->drawable.x; 75005b261ecSmrg newValues[ABSY].val = pBgWin->drawable.y; 75105b261ecSmrg } 75205b261ecSmrg else 75305b261ecSmrg { 75405b261ecSmrg newValues[ABSX].val = 0; 75505b261ecSmrg newValues[ABSY].val = 0; 75605b261ecSmrg } 75705b261ecSmrg } else { 75805b261ecSmrg /* 75905b261ecSmrg * draw the background to the root window 76005b261ecSmrg */ 76105b261ecSmrg if (screenContext[i] == (GCPtr)NULL) 76205b261ecSmrg { 76305b261ecSmrg if (!ResType && !(ResType = CreateNewResourceType(tossGC))) 76405b261ecSmrg return; 76505b261ecSmrg screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0, 76605b261ecSmrg (XID *)NULL, &status); 76705b261ecSmrg if (!screenContext[i]) 76805b261ecSmrg return; 76905b261ecSmrg numGCs++; 77005b261ecSmrg if (!AddResource(FakeClientID(0), ResType, 77105b261ecSmrg (pointer)screenContext[i])) 77205b261ecSmrg return; 77305b261ecSmrg } 77405b261ecSmrg pGC = screenContext[i]; 77505b261ecSmrg newValues[SUBWINDOW].val = IncludeInferiors; 77605b261ecSmrg newValues[ABSX].val = pBgWin->drawable.x; 77705b261ecSmrg newValues[ABSY].val = pBgWin->drawable.y; 77805b261ecSmrg gcmask |= GCSubwindowMode; 77905b261ecSmrg pWin = pRoot; 78005b261ecSmrg } 78105b261ecSmrg 78205b261ecSmrg if (pWin->backStorage) 78305b261ecSmrg (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack); 78405b261ecSmrg 78505b261ecSmrg mask = gcmask; 78605b261ecSmrg gcmask = 0; 78705b261ecSmrg i = 0; 78805b261ecSmrg while (mask) { 78905b261ecSmrg index = lowbit (mask); 79005b261ecSmrg mask &= ~index; 79105b261ecSmrg switch (index) { 79205b261ecSmrg case GCFunction: 79305b261ecSmrg if (pGC->alu != newValues[FUNCTION].val) { 79405b261ecSmrg gcmask |= index; 79505b261ecSmrg gcval[i++].val = newValues[FUNCTION].val; 79605b261ecSmrg } 79705b261ecSmrg break; 79805b261ecSmrg case GCTileStipXOrigin: 79905b261ecSmrg if ( pGC->patOrg.x != newValues[ABSX].val) { 80005b261ecSmrg gcmask |= index; 80105b261ecSmrg gcval[i++].val = newValues[ABSX].val; 80205b261ecSmrg } 80305b261ecSmrg break; 80405b261ecSmrg case GCTileStipYOrigin: 80505b261ecSmrg if ( pGC->patOrg.y != newValues[ABSY].val) { 80605b261ecSmrg gcmask |= index; 80705b261ecSmrg gcval[i++].val = newValues[ABSY].val; 80805b261ecSmrg } 80905b261ecSmrg break; 81005b261ecSmrg case GCClipMask: 81105b261ecSmrg if ( pGC->clientClipType != CT_NONE) { 81205b261ecSmrg gcmask |= index; 81305b261ecSmrg gcval[i++].val = CT_NONE; 81405b261ecSmrg } 81505b261ecSmrg break; 81605b261ecSmrg case GCSubwindowMode: 81705b261ecSmrg if ( pGC->subWindowMode != newValues[SUBWINDOW].val) { 81805b261ecSmrg gcmask |= index; 81905b261ecSmrg gcval[i++].val = newValues[SUBWINDOW].val; 82005b261ecSmrg } 82105b261ecSmrg break; 82205b261ecSmrg case GCTile: 82305b261ecSmrg if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr) 82405b261ecSmrg { 82505b261ecSmrg gcmask |= index; 82605b261ecSmrg gcval[i++].ptr = newValues[TILE].ptr; 82705b261ecSmrg } 82805b261ecSmrg break; 82905b261ecSmrg case GCFillStyle: 83005b261ecSmrg if ( pGC->fillStyle != newValues[FILLSTYLE].val) { 83105b261ecSmrg gcmask |= index; 83205b261ecSmrg gcval[i++].val = newValues[FILLSTYLE].val; 83305b261ecSmrg } 83405b261ecSmrg break; 83505b261ecSmrg case GCForeground: 83605b261ecSmrg if ( pGC->fgPixel != newValues[FOREGROUND].val) { 83705b261ecSmrg gcmask |= index; 83805b261ecSmrg gcval[i++].val = newValues[FOREGROUND].val; 83905b261ecSmrg } 84005b261ecSmrg break; 84105b261ecSmrg } 84205b261ecSmrg } 84305b261ecSmrg 84405b261ecSmrg if (gcmask) 84505b261ecSmrg dixChangeGC(NullClient, pGC, gcmask, NULL, gcval); 84605b261ecSmrg 84705b261ecSmrg if (pWin->drawable.serialNumber != pGC->serialNumber) 84805b261ecSmrg ValidateGC((DrawablePtr)pWin, pGC); 84905b261ecSmrg 85005b261ecSmrg numRects = REGION_NUM_RECTS(prgn); 85105b261ecSmrg pbox = REGION_RECTS(prgn); 85205b261ecSmrg for (i= numRects; --i >= 0; pbox++, prect++) 85305b261ecSmrg { 85405b261ecSmrg prect->x = pbox->x1 - pWin->drawable.x; 85505b261ecSmrg prect->y = pbox->y1 - pWin->drawable.y; 85605b261ecSmrg prect->width = pbox->x2 - pbox->x1; 85705b261ecSmrg prect->height = pbox->y2 - pbox->y1; 85805b261ecSmrg } 85905b261ecSmrg prect -= numRects; 86005b261ecSmrg (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect); 86105b261ecSmrg DEALLOCATE_LOCAL(prect); 86205b261ecSmrg 86305b261ecSmrg if (pWin->backStorage) 86405b261ecSmrg (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing); 86505b261ecSmrg 86605b261ecSmrg if (usingScratchGC) 86705b261ecSmrg { 86805b261ecSmrg if (what == PW_BORDER) 86905b261ecSmrg { 87005b261ecSmrg REGION_UNINIT(pScreen, &pWin->clipList); 87105b261ecSmrg pWin->clipList = prgnWin; 87205b261ecSmrg pWin->drawable.x = oldCorner.x; 87305b261ecSmrg pWin->drawable.y = oldCorner.y; 87405b261ecSmrg pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; 87505b261ecSmrg } 87605b261ecSmrg FreeScratchGC(pGC); 87705b261ecSmrg } 87805b261ecSmrg} 87905b261ecSmrg 88005b261ecSmrg 88105b261ecSmrg/* MICLEARDRAWABLE -- sets the entire drawable to the background color of 88205b261ecSmrg * the GC. Useful when we have a scratch drawable and need to initialize 88305b261ecSmrg * it. */ 88405b261ecSmrg_X_EXPORT void 88505b261ecSmrgmiClearDrawable(pDraw, pGC) 88605b261ecSmrg DrawablePtr pDraw; 88705b261ecSmrg GCPtr pGC; 88805b261ecSmrg{ 88905b261ecSmrg XID fg = pGC->fgPixel; 89005b261ecSmrg XID bg = pGC->bgPixel; 89105b261ecSmrg xRectangle rect; 89205b261ecSmrg 89305b261ecSmrg rect.x = 0; 89405b261ecSmrg rect.y = 0; 89505b261ecSmrg rect.width = pDraw->width; 89605b261ecSmrg rect.height = pDraw->height; 89705b261ecSmrg DoChangeGC(pGC, GCForeground, &bg, 0); 89805b261ecSmrg ValidateGC(pDraw, pGC); 89905b261ecSmrg (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect); 90005b261ecSmrg DoChangeGC(pGC, GCForeground, &fg, 0); 90105b261ecSmrg ValidateGC(pDraw, pGC); 90205b261ecSmrg} 903