miexpose.c revision 4642e01f
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 1314642e01fSmrgmiHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, 1324642e01fSmrg GCPtr pGC, int srcx, int srcy, int width, int height, 1334642e01fSmrg int dstx, int dsty, unsigned long plane) 13405b261ecSmrg{ 13505b261ecSmrg ScreenPtr pscr; 13605b261ecSmrg RegionPtr prgnSrcClip; /* drawable-relative source clip */ 13705b261ecSmrg RegionRec rgnSrcRec; 13805b261ecSmrg RegionPtr prgnDstClip; /* drawable-relative dest clip */ 13905b261ecSmrg RegionRec rgnDstRec; 14005b261ecSmrg BoxRec srcBox; /* unclipped source */ 14105b261ecSmrg RegionRec rgnExposed; /* exposed region, calculated source- 14205b261ecSmrg relative, made dst relative to 14305b261ecSmrg intersect with visible parts of 14405b261ecSmrg dest and send events to client, 14505b261ecSmrg and then screen relative to paint 14605b261ecSmrg the window background 14705b261ecSmrg */ 14805b261ecSmrg WindowPtr pSrcWin; 14905b261ecSmrg BoxRec expBox; 15005b261ecSmrg Bool extents; 15105b261ecSmrg 15205b261ecSmrg /* This prevents warning about pscr not being used. */ 15305b261ecSmrg pGC->pScreen = pscr = pGC->pScreen; 15405b261ecSmrg 15505b261ecSmrg /* avoid work if we can */ 15605b261ecSmrg if (!pGC->graphicsExposures && 15705b261ecSmrg (pDstDrawable->type == DRAWABLE_PIXMAP) && 15805b261ecSmrg ((pSrcDrawable->type == DRAWABLE_PIXMAP) || 15905b261ecSmrg (((WindowPtr)pSrcDrawable)->backStorage == NULL))) 16005b261ecSmrg return NULL; 16105b261ecSmrg 16205b261ecSmrg srcBox.x1 = srcx; 16305b261ecSmrg srcBox.y1 = srcy; 16405b261ecSmrg srcBox.x2 = srcx+width; 16505b261ecSmrg srcBox.y2 = srcy+height; 16605b261ecSmrg 16705b261ecSmrg if (pSrcDrawable->type != DRAWABLE_PIXMAP) 16805b261ecSmrg { 16905b261ecSmrg BoxRec TsrcBox; 17005b261ecSmrg 17105b261ecSmrg TsrcBox.x1 = srcx + pSrcDrawable->x; 17205b261ecSmrg TsrcBox.y1 = srcy + pSrcDrawable->y; 17305b261ecSmrg TsrcBox.x2 = TsrcBox.x1 + width; 17405b261ecSmrg TsrcBox.y2 = TsrcBox.y1 + height; 17505b261ecSmrg pSrcWin = (WindowPtr) pSrcDrawable; 17605b261ecSmrg if (pGC->subWindowMode == IncludeInferiors) 17705b261ecSmrg { 17805b261ecSmrg prgnSrcClip = NotClippedByChildren (pSrcWin); 17905b261ecSmrg if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN) 18005b261ecSmrg { 18105b261ecSmrg REGION_DESTROY(pscr, prgnSrcClip); 18205b261ecSmrg return NULL; 18305b261ecSmrg } 18405b261ecSmrg } 18505b261ecSmrg else 18605b261ecSmrg { 18705b261ecSmrg if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN) 18805b261ecSmrg return NULL; 18905b261ecSmrg prgnSrcClip = &rgnSrcRec; 19005b261ecSmrg REGION_NULL(pscr, prgnSrcClip); 19105b261ecSmrg REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList); 19205b261ecSmrg } 19305b261ecSmrg REGION_TRANSLATE(pscr, prgnSrcClip, 19405b261ecSmrg -pSrcDrawable->x, -pSrcDrawable->y); 19505b261ecSmrg } 19605b261ecSmrg else 19705b261ecSmrg { 19805b261ecSmrg BoxRec box; 19905b261ecSmrg 20005b261ecSmrg if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && 20105b261ecSmrg (srcBox.x2 <= pSrcDrawable->width) && 20205b261ecSmrg (srcBox.y2 <= pSrcDrawable->height)) 20305b261ecSmrg return NULL; 20405b261ecSmrg 20505b261ecSmrg box.x1 = 0; 20605b261ecSmrg box.y1 = 0; 20705b261ecSmrg box.x2 = pSrcDrawable->width; 20805b261ecSmrg box.y2 = pSrcDrawable->height; 20905b261ecSmrg prgnSrcClip = &rgnSrcRec; 21005b261ecSmrg REGION_INIT(pscr, prgnSrcClip, &box, 1); 21105b261ecSmrg pSrcWin = (WindowPtr)NULL; 21205b261ecSmrg } 21305b261ecSmrg 21405b261ecSmrg if (pDstDrawable == pSrcDrawable) 21505b261ecSmrg { 21605b261ecSmrg prgnDstClip = prgnSrcClip; 21705b261ecSmrg } 21805b261ecSmrg else if (pDstDrawable->type != DRAWABLE_PIXMAP) 21905b261ecSmrg { 22005b261ecSmrg if (pGC->subWindowMode == IncludeInferiors) 22105b261ecSmrg { 22205b261ecSmrg prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable); 22305b261ecSmrg } 22405b261ecSmrg else 22505b261ecSmrg { 22605b261ecSmrg prgnDstClip = &rgnDstRec; 22705b261ecSmrg REGION_NULL(pscr, prgnDstClip); 22805b261ecSmrg REGION_COPY(pscr, prgnDstClip, 22905b261ecSmrg &((WindowPtr)pDstDrawable)->clipList); 23005b261ecSmrg } 23105b261ecSmrg REGION_TRANSLATE(pscr, prgnDstClip, 23205b261ecSmrg -pDstDrawable->x, -pDstDrawable->y); 23305b261ecSmrg } 23405b261ecSmrg else 23505b261ecSmrg { 23605b261ecSmrg BoxRec box; 23705b261ecSmrg 23805b261ecSmrg box.x1 = 0; 23905b261ecSmrg box.y1 = 0; 24005b261ecSmrg box.x2 = pDstDrawable->width; 24105b261ecSmrg box.y2 = pDstDrawable->height; 24205b261ecSmrg prgnDstClip = &rgnDstRec; 24305b261ecSmrg REGION_INIT(pscr, prgnDstClip, &box, 1); 24405b261ecSmrg } 24505b261ecSmrg 24605b261ecSmrg /* drawable-relative source region */ 24705b261ecSmrg REGION_INIT(pscr, &rgnExposed, &srcBox, 1); 24805b261ecSmrg 24905b261ecSmrg /* now get the hidden parts of the source box*/ 25005b261ecSmrg REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip); 25105b261ecSmrg 25205b261ecSmrg /* move them over the destination */ 25305b261ecSmrg REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy); 25405b261ecSmrg 25505b261ecSmrg /* intersect with visible areas of dest */ 25605b261ecSmrg REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip); 25705b261ecSmrg 25805b261ecSmrg /* 25905b261ecSmrg * If we have LOTS of rectangles, we decide to take the extents 26005b261ecSmrg * and force an exposure on that. This should require much less 26105b261ecSmrg * work overall, on both client and server. This is cheating, but 26205b261ecSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-) 26305b261ecSmrg * for windows. 26405b261ecSmrg */ 26505b261ecSmrg extents = pGC->graphicsExposures && 26605b261ecSmrg (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) && 26705b261ecSmrg (pDstDrawable->type != DRAWABLE_PIXMAP); 26805b261ecSmrg if (pSrcWin) 26905b261ecSmrg { 27005b261ecSmrg RegionPtr region; 27105b261ecSmrg if (!(region = wClipShape (pSrcWin))) 27205b261ecSmrg region = wBoundingShape (pSrcWin); 27305b261ecSmrg /* 27405b261ecSmrg * If you try to CopyArea the extents of a shaped window, compacting the 27505b261ecSmrg * exposed region will undo all our work! 27605b261ecSmrg */ 27705b261ecSmrg if (extents && pSrcWin && region && 27805b261ecSmrg (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN)) 27905b261ecSmrg extents = FALSE; 28005b261ecSmrg } 28105b261ecSmrg if (extents) 28205b261ecSmrg { 28305b261ecSmrg expBox = *REGION_EXTENTS(pscr, &rgnExposed); 28405b261ecSmrg REGION_RESET(pscr, &rgnExposed, &expBox); 28505b261ecSmrg } 28605b261ecSmrg if ((pDstDrawable->type != DRAWABLE_PIXMAP) && 28705b261ecSmrg (((WindowPtr)pDstDrawable)->backgroundState != None)) 28805b261ecSmrg { 28905b261ecSmrg WindowPtr pWin = (WindowPtr)pDstDrawable; 29005b261ecSmrg 29105b261ecSmrg /* make the exposed area screen-relative */ 29205b261ecSmrg REGION_TRANSLATE(pscr, &rgnExposed, 29305b261ecSmrg pDstDrawable->x, pDstDrawable->y); 29405b261ecSmrg 29505b261ecSmrg if (extents) 29605b261ecSmrg { 29705b261ecSmrg /* PaintWindowBackground doesn't clip, so we have to */ 29805b261ecSmrg REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList); 29905b261ecSmrg } 3004642e01fSmrg miPaintWindow((WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND); 30105b261ecSmrg 30205b261ecSmrg if (extents) 30305b261ecSmrg { 30405b261ecSmrg REGION_RESET(pscr, &rgnExposed, &expBox); 30505b261ecSmrg } 30605b261ecSmrg else 30705b261ecSmrg REGION_TRANSLATE(pscr, &rgnExposed, 30805b261ecSmrg -pDstDrawable->x, -pDstDrawable->y); 30905b261ecSmrg } 31005b261ecSmrg if (prgnDstClip == &rgnDstRec) 31105b261ecSmrg { 31205b261ecSmrg REGION_UNINIT(pscr, prgnDstClip); 31305b261ecSmrg } 31405b261ecSmrg else if (prgnDstClip != prgnSrcClip) 31505b261ecSmrg { 31605b261ecSmrg REGION_DESTROY(pscr, prgnDstClip); 31705b261ecSmrg } 31805b261ecSmrg 31905b261ecSmrg if (prgnSrcClip == &rgnSrcRec) 32005b261ecSmrg { 32105b261ecSmrg REGION_UNINIT(pscr, prgnSrcClip); 32205b261ecSmrg } 32305b261ecSmrg else 32405b261ecSmrg { 32505b261ecSmrg REGION_DESTROY(pscr, prgnSrcClip); 32605b261ecSmrg } 32705b261ecSmrg 32805b261ecSmrg if (pGC->graphicsExposures) 32905b261ecSmrg { 33005b261ecSmrg /* don't look */ 33105b261ecSmrg RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0); 33205b261ecSmrg *exposed = rgnExposed; 33305b261ecSmrg return exposed; 33405b261ecSmrg } 33505b261ecSmrg else 33605b261ecSmrg { 33705b261ecSmrg REGION_UNINIT(pscr, &rgnExposed); 33805b261ecSmrg return NULL; 33905b261ecSmrg } 34005b261ecSmrg} 34105b261ecSmrg 34205b261ecSmrg/* send GraphicsExpose events, or a NoExpose event, based on the region */ 34305b261ecSmrg 3444642e01fSmrgvoid 3454642e01fSmrgmiSendGraphicsExpose (ClientPtr client, RegionPtr pRgn, XID drawable, 3464642e01fSmrg int major, int minor) 34705b261ecSmrg{ 34805b261ecSmrg if (pRgn && !REGION_NIL(pRgn)) 34905b261ecSmrg { 35005b261ecSmrg xEvent *pEvent; 35105b261ecSmrg xEvent *pe; 35205b261ecSmrg BoxPtr pBox; 35305b261ecSmrg int i; 35405b261ecSmrg int numRects; 35505b261ecSmrg 35605b261ecSmrg numRects = REGION_NUM_RECTS(pRgn); 35705b261ecSmrg pBox = REGION_RECTS(pRgn); 3584642e01fSmrg if(!(pEvent = (xEvent *)xalloc(numRects * sizeof(xEvent)))) 35905b261ecSmrg return; 36005b261ecSmrg pe = pEvent; 36105b261ecSmrg 36205b261ecSmrg for (i=1; i<=numRects; i++, pe++, pBox++) 36305b261ecSmrg { 36405b261ecSmrg pe->u.u.type = GraphicsExpose; 36505b261ecSmrg pe->u.graphicsExposure.drawable = drawable; 36605b261ecSmrg pe->u.graphicsExposure.x = pBox->x1; 36705b261ecSmrg pe->u.graphicsExposure.y = pBox->y1; 36805b261ecSmrg pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; 36905b261ecSmrg pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; 37005b261ecSmrg pe->u.graphicsExposure.count = numRects - i; 37105b261ecSmrg pe->u.graphicsExposure.majorEvent = major; 37205b261ecSmrg pe->u.graphicsExposure.minorEvent = minor; 37305b261ecSmrg } 3744642e01fSmrg TryClientEvents(client, NULL, pEvent, numRects, 37505b261ecSmrg (Mask)0, NoEventMask, NullGrab); 3764642e01fSmrg xfree(pEvent); 37705b261ecSmrg } 37805b261ecSmrg else 37905b261ecSmrg { 38005b261ecSmrg xEvent event; 38105b261ecSmrg event.u.u.type = NoExpose; 38205b261ecSmrg event.u.noExposure.drawable = drawable; 38305b261ecSmrg event.u.noExposure.majorEvent = major; 38405b261ecSmrg event.u.noExposure.minorEvent = minor; 3854642e01fSmrg TryClientEvents(client, NULL, &event, 1, 38605b261ecSmrg (Mask)0, NoEventMask, NullGrab); 38705b261ecSmrg } 38805b261ecSmrg} 38905b261ecSmrg 39005b261ecSmrg 39105b261ecSmrgvoid 3924642e01fSmrgmiSendExposures( WindowPtr pWin, RegionPtr pRgn, int dx, int dy) 39305b261ecSmrg{ 39405b261ecSmrg BoxPtr pBox; 39505b261ecSmrg int numRects; 39605b261ecSmrg xEvent *pEvent, *pe; 39705b261ecSmrg int i; 39805b261ecSmrg 39905b261ecSmrg pBox = REGION_RECTS(pRgn); 40005b261ecSmrg numRects = REGION_NUM_RECTS(pRgn); 4014642e01fSmrg if(!(pEvent = (xEvent *) xalloc(numRects * sizeof(xEvent)))) 40205b261ecSmrg return; 40305b261ecSmrg 40405b261ecSmrg for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++) 40505b261ecSmrg { 40605b261ecSmrg pe->u.u.type = Expose; 40705b261ecSmrg pe->u.expose.window = pWin->drawable.id; 40805b261ecSmrg pe->u.expose.x = pBox->x1 - dx; 40905b261ecSmrg pe->u.expose.y = pBox->y1 - dy; 41005b261ecSmrg pe->u.expose.width = pBox->x2 - pBox->x1; 41105b261ecSmrg pe->u.expose.height = pBox->y2 - pBox->y1; 41205b261ecSmrg pe->u.expose.count = i; 41305b261ecSmrg } 41405b261ecSmrg 41505b261ecSmrg#ifdef PANORAMIX 41605b261ecSmrg if(!noPanoramiXExtension) { 41705b261ecSmrg int scrnum = pWin->drawable.pScreen->myNum; 41805b261ecSmrg int x = 0, y = 0; 41905b261ecSmrg XID realWin = 0; 42005b261ecSmrg 42105b261ecSmrg if(!pWin->parent) { 42205b261ecSmrg x = panoramiXdataPtr[scrnum].x; 42305b261ecSmrg y = panoramiXdataPtr[scrnum].y; 42405b261ecSmrg pWin = WindowTable[0]; 42505b261ecSmrg realWin = pWin->drawable.id; 42605b261ecSmrg } else if (scrnum) { 42705b261ecSmrg PanoramiXRes *win; 42805b261ecSmrg win = PanoramiXFindIDByScrnum(XRT_WINDOW, 42905b261ecSmrg pWin->drawable.id, scrnum); 43005b261ecSmrg if(!win) { 4314642e01fSmrg xfree(pEvent); 43205b261ecSmrg return; 43305b261ecSmrg } 43405b261ecSmrg realWin = win->info[0].id; 43505b261ecSmrg pWin = LookupIDByType(realWin, RT_WINDOW); 43605b261ecSmrg } 43705b261ecSmrg if(x || y || scrnum) 43805b261ecSmrg for (i = 0; i < numRects; i++) { 43905b261ecSmrg pEvent[i].u.expose.window = realWin; 44005b261ecSmrg pEvent[i].u.expose.x += x; 44105b261ecSmrg pEvent[i].u.expose.y += y; 44205b261ecSmrg } 44305b261ecSmrg } 44405b261ecSmrg#endif 44505b261ecSmrg 44605b261ecSmrg DeliverEvents(pWin, pEvent, numRects, NullWindow); 44705b261ecSmrg 4484642e01fSmrg xfree(pEvent); 44905b261ecSmrg} 45005b261ecSmrg 45105b261ecSmrg_X_EXPORT void 4524642e01fSmrgmiWindowExposures( WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed) 45305b261ecSmrg{ 45405b261ecSmrg RegionPtr exposures = prgn; 45505b261ecSmrg if ((prgn && !REGION_NIL(prgn)) || 45605b261ecSmrg (exposures && !REGION_NIL(exposures)) || other_exposed) 45705b261ecSmrg { 45805b261ecSmrg RegionRec expRec; 45905b261ecSmrg int clientInterested; 46005b261ecSmrg 46105b261ecSmrg /* 46205b261ecSmrg * Restore from backing-store FIRST. 46305b261ecSmrg */ 46405b261ecSmrg clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask; 46505b261ecSmrg if (other_exposed) 46605b261ecSmrg { 46705b261ecSmrg if (exposures) 46805b261ecSmrg { 46905b261ecSmrg REGION_UNION(pWin->drawable.pScreen, other_exposed, 47005b261ecSmrg exposures, 47105b261ecSmrg other_exposed); 47205b261ecSmrg if (exposures != prgn) 47305b261ecSmrg REGION_DESTROY(pWin->drawable.pScreen, exposures); 47405b261ecSmrg } 47505b261ecSmrg exposures = other_exposed; 47605b261ecSmrg } 47705b261ecSmrg if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT)) 47805b261ecSmrg { 47905b261ecSmrg /* 48005b261ecSmrg * If we have LOTS of rectangles, we decide to take the extents 48105b261ecSmrg * and force an exposure on that. This should require much less 48205b261ecSmrg * work overall, on both client and server. This is cheating, but 48305b261ecSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-). 48405b261ecSmrg */ 48505b261ecSmrg BoxRec box; 48605b261ecSmrg 48705b261ecSmrg box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures); 48805b261ecSmrg if (exposures == prgn) { 48905b261ecSmrg exposures = &expRec; 49005b261ecSmrg REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1); 49105b261ecSmrg REGION_RESET( pWin->drawable.pScreen, prgn, &box); 49205b261ecSmrg } else { 49305b261ecSmrg REGION_RESET( pWin->drawable.pScreen, exposures, &box); 49405b261ecSmrg REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures); 49505b261ecSmrg } 49605b261ecSmrg /* PaintWindowBackground doesn't clip, so we have to */ 49705b261ecSmrg REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList); 49805b261ecSmrg } 49905b261ecSmrg if (prgn && !REGION_NIL(prgn)) 5004642e01fSmrg miPaintWindow(pWin, prgn, PW_BACKGROUND); 50105b261ecSmrg if (clientInterested && exposures && !REGION_NIL(exposures)) 50205b261ecSmrg miSendExposures(pWin, exposures, 50305b261ecSmrg pWin->drawable.x, pWin->drawable.y); 50405b261ecSmrg if (exposures == &expRec) 50505b261ecSmrg { 50605b261ecSmrg REGION_UNINIT( pWin->drawable.pScreen, exposures); 50705b261ecSmrg } 50805b261ecSmrg else if (exposures && exposures != prgn && exposures != other_exposed) 50905b261ecSmrg REGION_DESTROY( pWin->drawable.pScreen, exposures); 51005b261ecSmrg if (prgn) 51105b261ecSmrg REGION_EMPTY( pWin->drawable.pScreen, prgn); 51205b261ecSmrg } 51305b261ecSmrg else if (exposures && exposures != prgn) 51405b261ecSmrg REGION_DESTROY( pWin->drawable.pScreen, exposures); 51505b261ecSmrg} 51605b261ecSmrg 5174642e01fSmrgvoid 5184642e01fSmrgmiPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) 51905b261ecSmrg{ 5204642e01fSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 5214642e01fSmrg ChangeGCVal gcval[5]; 5224642e01fSmrg BITS32 gcmask; 5234642e01fSmrg GCPtr pGC; 5244642e01fSmrg int i; 5254642e01fSmrg BoxPtr pbox; 5264642e01fSmrg xRectangle *prect; 5274642e01fSmrg int numRects; 5284642e01fSmrg /* 5294642e01fSmrg * Distance from screen to destination drawable, use this 5304642e01fSmrg * to adjust rendering coordinates which come in in screen space 5314642e01fSmrg */ 5324642e01fSmrg int draw_x_off, draw_y_off; 5334642e01fSmrg /* 5344642e01fSmrg * Tile offset for drawing; these need to align the tile 5354642e01fSmrg * to the appropriate window origin 5364642e01fSmrg */ 5374642e01fSmrg int tile_x_off, tile_y_off; 5384642e01fSmrg PixUnion fill; 5394642e01fSmrg Bool solid = TRUE; 5404642e01fSmrg DrawablePtr drawable = &pWin->drawable; 54105b261ecSmrg 54205b261ecSmrg if (what == PW_BACKGROUND) 54305b261ecSmrg { 5444642e01fSmrg while (pWin->backgroundState == ParentRelative) 5454642e01fSmrg pWin = pWin->parent; 5464642e01fSmrg 5474642e01fSmrg draw_x_off = drawable->x; 5484642e01fSmrg draw_y_off = drawable->y; 5494642e01fSmrg 5504642e01fSmrg tile_x_off = pWin->drawable.x - draw_x_off; 5514642e01fSmrg tile_y_off = pWin->drawable.y - draw_y_off; 5524642e01fSmrg fill = pWin->background; 55305b261ecSmrg switch (pWin->backgroundState) { 55405b261ecSmrg case None: 55505b261ecSmrg return; 55605b261ecSmrg case BackgroundPixmap: 5574642e01fSmrg solid = FALSE; 55805b261ecSmrg break; 55905b261ecSmrg } 56005b261ecSmrg } 56105b261ecSmrg else 56205b261ecSmrg { 5634642e01fSmrg PixmapPtr pixmap; 5644642e01fSmrg 5654642e01fSmrg tile_x_off = drawable->x; 5664642e01fSmrg tile_y_off = drawable->y; 5674642e01fSmrg 5684642e01fSmrg /* servers without pixmaps draw their own borders */ 5694642e01fSmrg if (!pScreen->GetWindowPixmap) 5704642e01fSmrg return; 5714642e01fSmrg pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); 5724642e01fSmrg drawable = &pixmap->drawable; 5734642e01fSmrg#ifdef COMPOSITE 5744642e01fSmrg draw_x_off = pixmap->screen_x; 5754642e01fSmrg draw_y_off = pixmap->screen_y; 5764642e01fSmrg tile_x_off -= draw_x_off; 5774642e01fSmrg tile_y_off -= draw_y_off; 5784642e01fSmrg#else 5794642e01fSmrg draw_x_off = 0; 5804642e01fSmrg draw_y_off = 0; 5814642e01fSmrg#endif 5824642e01fSmrg fill = pWin->border; 5834642e01fSmrg solid = pWin->borderIsPixel; 58405b261ecSmrg } 5854642e01fSmrg 5864642e01fSmrg gcval[0].val = GXcopy; 5874642e01fSmrg gcmask = GCFunction; 58805b261ecSmrg 5894642e01fSmrg if (solid) 5904642e01fSmrg { 5914642e01fSmrg gcval[1].val = fill.pixel; 5924642e01fSmrg gcval[2].val = FillSolid; 5934642e01fSmrg gcmask |= GCForeground | GCFillStyle; 5944642e01fSmrg } 5954642e01fSmrg else 5964642e01fSmrg { 5974642e01fSmrg gcval[1].val = FillTiled; 5984642e01fSmrg gcval[2].ptr = (pointer)fill.pixmap; 5994642e01fSmrg gcval[3].val = tile_x_off; 6004642e01fSmrg gcval[4].val = tile_y_off; 6014642e01fSmrg gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; 6024642e01fSmrg } 6034642e01fSmrg 6044642e01fSmrg prect = (xRectangle *)xalloc(REGION_NUM_RECTS(prgn) * 60505b261ecSmrg sizeof(xRectangle)); 60605b261ecSmrg if (!prect) 60705b261ecSmrg return; 60805b261ecSmrg 6094642e01fSmrg pGC = GetScratchGC(drawable->depth, drawable->pScreen); 6104642e01fSmrg if (!pGC) 61105b261ecSmrg { 6124642e01fSmrg xfree(prect); 6134642e01fSmrg return; 61405b261ecSmrg } 61505b261ecSmrg 6164642e01fSmrg dixChangeGC (NullClient, pGC, gcmask, NULL, gcval); 6174642e01fSmrg ValidateGC (drawable, pGC); 61805b261ecSmrg 61905b261ecSmrg numRects = REGION_NUM_RECTS(prgn); 62005b261ecSmrg pbox = REGION_RECTS(prgn); 62105b261ecSmrg for (i= numRects; --i >= 0; pbox++, prect++) 62205b261ecSmrg { 6234642e01fSmrg prect->x = pbox->x1 - draw_x_off; 6244642e01fSmrg prect->y = pbox->y1 - draw_y_off; 62505b261ecSmrg prect->width = pbox->x2 - pbox->x1; 62605b261ecSmrg prect->height = pbox->y2 - pbox->y1; 62705b261ecSmrg } 62805b261ecSmrg prect -= numRects; 6294642e01fSmrg (*pGC->ops->PolyFillRect)(drawable, pGC, numRects, prect); 6304642e01fSmrg xfree(prect); 63105b261ecSmrg 6324642e01fSmrg FreeScratchGC(pGC); 63305b261ecSmrg} 63405b261ecSmrg 63505b261ecSmrg 63605b261ecSmrg/* MICLEARDRAWABLE -- sets the entire drawable to the background color of 63705b261ecSmrg * the GC. Useful when we have a scratch drawable and need to initialize 63805b261ecSmrg * it. */ 63905b261ecSmrg_X_EXPORT void 6404642e01fSmrgmiClearDrawable(DrawablePtr pDraw, GCPtr pGC) 64105b261ecSmrg{ 64205b261ecSmrg XID fg = pGC->fgPixel; 64305b261ecSmrg XID bg = pGC->bgPixel; 64405b261ecSmrg xRectangle rect; 64505b261ecSmrg 64605b261ecSmrg rect.x = 0; 64705b261ecSmrg rect.y = 0; 64805b261ecSmrg rect.width = pDraw->width; 64905b261ecSmrg rect.height = pDraw->height; 65005b261ecSmrg DoChangeGC(pGC, GCForeground, &bg, 0); 65105b261ecSmrg ValidateGC(pDraw, pGC); 65205b261ecSmrg (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect); 65305b261ecSmrg DoChangeGC(pGC, GCForeground, &fg, 0); 65405b261ecSmrg ValidateGC(pDraw, pGC); 65505b261ecSmrg} 656