miexpose.c revision 6747b715
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#include <X11/Xproto.h> 8205b261ecSmrg#include <X11/Xprotostr.h> 8305b261ecSmrg 8405b261ecSmrg#include "misc.h" 8505b261ecSmrg#include "regionstr.h" 8605b261ecSmrg#include "scrnintstr.h" 8705b261ecSmrg#include "gcstruct.h" 8805b261ecSmrg#include "windowstr.h" 8905b261ecSmrg#include "pixmap.h" 9005b261ecSmrg#include "input.h" 9105b261ecSmrg 9205b261ecSmrg#include "dixstruct.h" 9305b261ecSmrg#include "mi.h" 9405b261ecSmrg#include <X11/Xmd.h> 9505b261ecSmrg 9605b261ecSmrg#include "globals.h" 9705b261ecSmrg 9805b261ecSmrg#ifdef PANORAMIX 9905b261ecSmrg#include "panoramiX.h" 10005b261ecSmrg#include "panoramiXsrv.h" 10105b261ecSmrg#endif 10205b261ecSmrg 10305b261ecSmrg/* 10405b261ecSmrg machine-independent graphics exposure code. any device that uses 10505b261ecSmrgthe region package can call this. 10605b261ecSmrg*/ 10705b261ecSmrg 10805b261ecSmrg#ifndef RECTLIMIT 10905b261ecSmrg#define RECTLIMIT 25 /* pick a number, any number > 8 */ 11005b261ecSmrg#endif 11105b261ecSmrg 11205b261ecSmrg/* miHandleExposures 11305b261ecSmrg generate a region for exposures for areas that were copied from obscured or 11405b261ecSmrgnon-existent areas to non-obscured areas of the destination. Paint the 11505b261ecSmrgbackground for the region, if the destination is a window. 11605b261ecSmrg 11705b261ecSmrgNOTE: 11805b261ecSmrg this should generally be called, even if graphicsExposures is false, 11905b261ecSmrgbecause this is where bits get recovered from backing store. 12005b261ecSmrg 12105b261ecSmrgNOTE: 12205b261ecSmrg added argument 'plane' is used to indicate how exposures from backing 12305b261ecSmrgstore should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea 12405b261ecSmrgshould be used, else a CopyPlane of the indicated plane will be used. The 12505b261ecSmrgexposing is done by the backing store's GraphicsExpose function, of course. 12605b261ecSmrg 12705b261ecSmrg*/ 12805b261ecSmrg 1296747b715SmrgRegionPtr 1304642e01fSmrgmiHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, 1314642e01fSmrg GCPtr pGC, int srcx, int srcy, int width, int height, 1324642e01fSmrg int dstx, int dsty, unsigned long plane) 13305b261ecSmrg{ 13405b261ecSmrg RegionPtr prgnSrcClip; /* drawable-relative source clip */ 13505b261ecSmrg RegionRec rgnSrcRec; 13605b261ecSmrg RegionPtr prgnDstClip; /* drawable-relative dest clip */ 13705b261ecSmrg RegionRec rgnDstRec; 13805b261ecSmrg BoxRec srcBox; /* unclipped source */ 13905b261ecSmrg RegionRec rgnExposed; /* exposed region, calculated source- 14005b261ecSmrg relative, made dst relative to 14105b261ecSmrg intersect with visible parts of 14205b261ecSmrg dest and send events to client, 14305b261ecSmrg and then screen relative to paint 14405b261ecSmrg the window background 14505b261ecSmrg */ 14605b261ecSmrg WindowPtr pSrcWin; 14705b261ecSmrg BoxRec expBox; 14805b261ecSmrg Bool extents; 14905b261ecSmrg 15005b261ecSmrg /* avoid work if we can */ 15105b261ecSmrg if (!pGC->graphicsExposures && 15205b261ecSmrg (pDstDrawable->type == DRAWABLE_PIXMAP) && 15305b261ecSmrg ((pSrcDrawable->type == DRAWABLE_PIXMAP) || 15405b261ecSmrg (((WindowPtr)pSrcDrawable)->backStorage == NULL))) 15505b261ecSmrg return NULL; 15605b261ecSmrg 15705b261ecSmrg srcBox.x1 = srcx; 15805b261ecSmrg srcBox.y1 = srcy; 15905b261ecSmrg srcBox.x2 = srcx+width; 16005b261ecSmrg srcBox.y2 = srcy+height; 16105b261ecSmrg 16205b261ecSmrg if (pSrcDrawable->type != DRAWABLE_PIXMAP) 16305b261ecSmrg { 16405b261ecSmrg BoxRec TsrcBox; 16505b261ecSmrg 16605b261ecSmrg TsrcBox.x1 = srcx + pSrcDrawable->x; 16705b261ecSmrg TsrcBox.y1 = srcy + pSrcDrawable->y; 16805b261ecSmrg TsrcBox.x2 = TsrcBox.x1 + width; 16905b261ecSmrg TsrcBox.y2 = TsrcBox.y1 + height; 17005b261ecSmrg pSrcWin = (WindowPtr) pSrcDrawable; 17105b261ecSmrg if (pGC->subWindowMode == IncludeInferiors) 17205b261ecSmrg { 17305b261ecSmrg prgnSrcClip = NotClippedByChildren (pSrcWin); 1746747b715Smrg if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) 17505b261ecSmrg { 1766747b715Smrg RegionDestroy(prgnSrcClip); 17705b261ecSmrg return NULL; 17805b261ecSmrg } 17905b261ecSmrg } 18005b261ecSmrg else 18105b261ecSmrg { 1826747b715Smrg if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN) 18305b261ecSmrg return NULL; 18405b261ecSmrg prgnSrcClip = &rgnSrcRec; 1856747b715Smrg RegionNull(prgnSrcClip); 1866747b715Smrg RegionCopy(prgnSrcClip, &pSrcWin->clipList); 18705b261ecSmrg } 1886747b715Smrg RegionTranslate(prgnSrcClip, 18905b261ecSmrg -pSrcDrawable->x, -pSrcDrawable->y); 19005b261ecSmrg } 19105b261ecSmrg else 19205b261ecSmrg { 19305b261ecSmrg BoxRec box; 19405b261ecSmrg 19505b261ecSmrg if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && 19605b261ecSmrg (srcBox.x2 <= pSrcDrawable->width) && 19705b261ecSmrg (srcBox.y2 <= pSrcDrawable->height)) 19805b261ecSmrg return NULL; 19905b261ecSmrg 20005b261ecSmrg box.x1 = 0; 20105b261ecSmrg box.y1 = 0; 20205b261ecSmrg box.x2 = pSrcDrawable->width; 20305b261ecSmrg box.y2 = pSrcDrawable->height; 20405b261ecSmrg prgnSrcClip = &rgnSrcRec; 2056747b715Smrg RegionInit(prgnSrcClip, &box, 1); 2066747b715Smrg pSrcWin = NULL; 20705b261ecSmrg } 20805b261ecSmrg 20905b261ecSmrg if (pDstDrawable == pSrcDrawable) 21005b261ecSmrg { 21105b261ecSmrg prgnDstClip = prgnSrcClip; 21205b261ecSmrg } 21305b261ecSmrg else if (pDstDrawable->type != DRAWABLE_PIXMAP) 21405b261ecSmrg { 21505b261ecSmrg if (pGC->subWindowMode == IncludeInferiors) 21605b261ecSmrg { 21705b261ecSmrg prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable); 21805b261ecSmrg } 21905b261ecSmrg else 22005b261ecSmrg { 22105b261ecSmrg prgnDstClip = &rgnDstRec; 2226747b715Smrg RegionNull(prgnDstClip); 2236747b715Smrg RegionCopy(prgnDstClip, 22405b261ecSmrg &((WindowPtr)pDstDrawable)->clipList); 22505b261ecSmrg } 2266747b715Smrg RegionTranslate(prgnDstClip, 22705b261ecSmrg -pDstDrawable->x, -pDstDrawable->y); 22805b261ecSmrg } 22905b261ecSmrg else 23005b261ecSmrg { 23105b261ecSmrg BoxRec box; 23205b261ecSmrg 23305b261ecSmrg box.x1 = 0; 23405b261ecSmrg box.y1 = 0; 23505b261ecSmrg box.x2 = pDstDrawable->width; 23605b261ecSmrg box.y2 = pDstDrawable->height; 23705b261ecSmrg prgnDstClip = &rgnDstRec; 2386747b715Smrg RegionInit(prgnDstClip, &box, 1); 23905b261ecSmrg } 24005b261ecSmrg 24105b261ecSmrg /* drawable-relative source region */ 2426747b715Smrg RegionInit(&rgnExposed, &srcBox, 1); 24305b261ecSmrg 24405b261ecSmrg /* now get the hidden parts of the source box*/ 2456747b715Smrg RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip); 24605b261ecSmrg 24705b261ecSmrg /* move them over the destination */ 2486747b715Smrg RegionTranslate(&rgnExposed, dstx-srcx, dsty-srcy); 24905b261ecSmrg 25005b261ecSmrg /* intersect with visible areas of dest */ 2516747b715Smrg RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip); 2526747b715Smrg 2536747b715Smrg /* intersect with client clip region. */ 2546747b715Smrg if (pGC->clientClipType == CT_REGION) 2556747b715Smrg RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); 25605b261ecSmrg 25705b261ecSmrg /* 25805b261ecSmrg * If we have LOTS of rectangles, we decide to take the extents 25905b261ecSmrg * and force an exposure on that. This should require much less 26005b261ecSmrg * work overall, on both client and server. This is cheating, but 26105b261ecSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-) 26205b261ecSmrg * for windows. 26305b261ecSmrg */ 26405b261ecSmrg extents = pGC->graphicsExposures && 2656747b715Smrg (RegionNumRects(&rgnExposed) > RECTLIMIT) && 26605b261ecSmrg (pDstDrawable->type != DRAWABLE_PIXMAP); 26705b261ecSmrg if (pSrcWin) 26805b261ecSmrg { 26905b261ecSmrg RegionPtr region; 27005b261ecSmrg if (!(region = wClipShape (pSrcWin))) 27105b261ecSmrg region = wBoundingShape (pSrcWin); 27205b261ecSmrg /* 27305b261ecSmrg * If you try to CopyArea the extents of a shaped window, compacting the 27405b261ecSmrg * exposed region will undo all our work! 27505b261ecSmrg */ 27605b261ecSmrg if (extents && pSrcWin && region && 2776747b715Smrg (RegionContainsRect(region, &srcBox) != rgnIN)) 27805b261ecSmrg extents = FALSE; 27905b261ecSmrg } 28005b261ecSmrg if (extents) 28105b261ecSmrg { 2826747b715Smrg expBox = *RegionExtents(&rgnExposed); 2836747b715Smrg RegionReset(&rgnExposed, &expBox); 28405b261ecSmrg } 28505b261ecSmrg if ((pDstDrawable->type != DRAWABLE_PIXMAP) && 28605b261ecSmrg (((WindowPtr)pDstDrawable)->backgroundState != None)) 28705b261ecSmrg { 28805b261ecSmrg WindowPtr pWin = (WindowPtr)pDstDrawable; 28905b261ecSmrg 29005b261ecSmrg /* make the exposed area screen-relative */ 2916747b715Smrg RegionTranslate(&rgnExposed, 29205b261ecSmrg pDstDrawable->x, pDstDrawable->y); 29305b261ecSmrg 29405b261ecSmrg if (extents) 29505b261ecSmrg { 2966747b715Smrg /* miPaintWindow doesn't clip, so we have to */ 2976747b715Smrg RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); 29805b261ecSmrg } 2994642e01fSmrg miPaintWindow((WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND); 30005b261ecSmrg 30105b261ecSmrg if (extents) 30205b261ecSmrg { 3036747b715Smrg RegionReset(&rgnExposed, &expBox); 30405b261ecSmrg } 30505b261ecSmrg else 3066747b715Smrg RegionTranslate(&rgnExposed, 30705b261ecSmrg -pDstDrawable->x, -pDstDrawable->y); 30805b261ecSmrg } 30905b261ecSmrg if (prgnDstClip == &rgnDstRec) 31005b261ecSmrg { 3116747b715Smrg RegionUninit(prgnDstClip); 31205b261ecSmrg } 31305b261ecSmrg else if (prgnDstClip != prgnSrcClip) 31405b261ecSmrg { 3156747b715Smrg RegionDestroy(prgnDstClip); 31605b261ecSmrg } 31705b261ecSmrg 31805b261ecSmrg if (prgnSrcClip == &rgnSrcRec) 31905b261ecSmrg { 3206747b715Smrg RegionUninit(prgnSrcClip); 32105b261ecSmrg } 32205b261ecSmrg else 32305b261ecSmrg { 3246747b715Smrg RegionDestroy(prgnSrcClip); 32505b261ecSmrg } 32605b261ecSmrg 32705b261ecSmrg if (pGC->graphicsExposures) 32805b261ecSmrg { 32905b261ecSmrg /* don't look */ 3306747b715Smrg RegionPtr exposed = RegionCreate(NullBox, 0); 33105b261ecSmrg *exposed = rgnExposed; 33205b261ecSmrg return exposed; 33305b261ecSmrg } 33405b261ecSmrg else 33505b261ecSmrg { 3366747b715Smrg RegionUninit(&rgnExposed); 33705b261ecSmrg return NULL; 33805b261ecSmrg } 33905b261ecSmrg} 34005b261ecSmrg 34105b261ecSmrg/* send GraphicsExpose events, or a NoExpose event, based on the region */ 34205b261ecSmrg 3434642e01fSmrgvoid 3444642e01fSmrgmiSendGraphicsExpose (ClientPtr client, RegionPtr pRgn, XID drawable, 3454642e01fSmrg int major, int minor) 34605b261ecSmrg{ 3476747b715Smrg if (pRgn && !RegionNil(pRgn)) 34805b261ecSmrg { 34905b261ecSmrg xEvent *pEvent; 35005b261ecSmrg xEvent *pe; 35105b261ecSmrg BoxPtr pBox; 35205b261ecSmrg int i; 35305b261ecSmrg int numRects; 35405b261ecSmrg 3556747b715Smrg numRects = RegionNumRects(pRgn); 3566747b715Smrg pBox = RegionRects(pRgn); 3576747b715Smrg if(!(pEvent = malloc(numRects * sizeof(xEvent)))) 35805b261ecSmrg return; 35905b261ecSmrg pe = pEvent; 36005b261ecSmrg 36105b261ecSmrg for (i=1; i<=numRects; i++, pe++, pBox++) 36205b261ecSmrg { 36305b261ecSmrg pe->u.u.type = GraphicsExpose; 36405b261ecSmrg pe->u.graphicsExposure.drawable = drawable; 36505b261ecSmrg pe->u.graphicsExposure.x = pBox->x1; 36605b261ecSmrg pe->u.graphicsExposure.y = pBox->y1; 36705b261ecSmrg pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; 36805b261ecSmrg pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; 36905b261ecSmrg pe->u.graphicsExposure.count = numRects - i; 37005b261ecSmrg pe->u.graphicsExposure.majorEvent = major; 37105b261ecSmrg pe->u.graphicsExposure.minorEvent = minor; 37205b261ecSmrg } 3736747b715Smrg /* GraphicsExpose is a "critical event", which TryClientEvents 3746747b715Smrg * handles specially. */ 3754642e01fSmrg TryClientEvents(client, NULL, pEvent, numRects, 37605b261ecSmrg (Mask)0, NoEventMask, NullGrab); 3776747b715Smrg free(pEvent); 37805b261ecSmrg } 37905b261ecSmrg else 38005b261ecSmrg { 38105b261ecSmrg xEvent event; 3826747b715Smrg memset(&event, 0, sizeof(xEvent)); 38305b261ecSmrg event.u.u.type = NoExpose; 38405b261ecSmrg event.u.noExposure.drawable = drawable; 38505b261ecSmrg event.u.noExposure.majorEvent = major; 38605b261ecSmrg event.u.noExposure.minorEvent = minor; 3876747b715Smrg WriteEventsToClient(client, 1, &event); 38805b261ecSmrg } 38905b261ecSmrg} 39005b261ecSmrg 39105b261ecSmrg 39205b261ecSmrgvoid 3934642e01fSmrgmiSendExposures( WindowPtr pWin, RegionPtr pRgn, int dx, int dy) 39405b261ecSmrg{ 39505b261ecSmrg BoxPtr pBox; 39605b261ecSmrg int numRects; 39705b261ecSmrg xEvent *pEvent, *pe; 39805b261ecSmrg int i; 39905b261ecSmrg 4006747b715Smrg pBox = RegionRects(pRgn); 4016747b715Smrg numRects = RegionNumRects(pRgn); 4026747b715Smrg if(!(pEvent = calloc(1, numRects * sizeof(xEvent)))) 40305b261ecSmrg return; 40405b261ecSmrg 40505b261ecSmrg for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++) 40605b261ecSmrg { 40705b261ecSmrg pe->u.u.type = Expose; 40805b261ecSmrg pe->u.expose.window = pWin->drawable.id; 40905b261ecSmrg pe->u.expose.x = pBox->x1 - dx; 41005b261ecSmrg pe->u.expose.y = pBox->y1 - dy; 41105b261ecSmrg pe->u.expose.width = pBox->x2 - pBox->x1; 41205b261ecSmrg pe->u.expose.height = pBox->y2 - pBox->y1; 41305b261ecSmrg pe->u.expose.count = i; 41405b261ecSmrg } 41505b261ecSmrg 41605b261ecSmrg#ifdef PANORAMIX 41705b261ecSmrg if(!noPanoramiXExtension) { 41805b261ecSmrg int scrnum = pWin->drawable.pScreen->myNum; 41905b261ecSmrg int x = 0, y = 0; 42005b261ecSmrg XID realWin = 0; 42105b261ecSmrg 42205b261ecSmrg if(!pWin->parent) { 4236747b715Smrg x = screenInfo.screens[scrnum]->x; 4246747b715Smrg y = screenInfo.screens[scrnum]->y; 4256747b715Smrg pWin = screenInfo.screens[0]->root; 42605b261ecSmrg realWin = pWin->drawable.id; 42705b261ecSmrg } else if (scrnum) { 42805b261ecSmrg PanoramiXRes *win; 42905b261ecSmrg win = PanoramiXFindIDByScrnum(XRT_WINDOW, 43005b261ecSmrg pWin->drawable.id, scrnum); 43105b261ecSmrg if(!win) { 4326747b715Smrg free(pEvent); 43305b261ecSmrg return; 43405b261ecSmrg } 43505b261ecSmrg realWin = win->info[0].id; 4366747b715Smrg dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess); 43705b261ecSmrg } 43805b261ecSmrg if(x || y || scrnum) 43905b261ecSmrg for (i = 0; i < numRects; i++) { 44005b261ecSmrg pEvent[i].u.expose.window = realWin; 44105b261ecSmrg pEvent[i].u.expose.x += x; 44205b261ecSmrg pEvent[i].u.expose.y += y; 44305b261ecSmrg } 44405b261ecSmrg } 44505b261ecSmrg#endif 44605b261ecSmrg 44705b261ecSmrg DeliverEvents(pWin, pEvent, numRects, NullWindow); 44805b261ecSmrg 4496747b715Smrg free(pEvent); 45005b261ecSmrg} 45105b261ecSmrg 4526747b715Smrgvoid 4534642e01fSmrgmiWindowExposures( WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed) 45405b261ecSmrg{ 45505b261ecSmrg RegionPtr exposures = prgn; 4566747b715Smrg if ((prgn && !RegionNil(prgn)) || 4576747b715Smrg (exposures && !RegionNil(exposures)) || other_exposed) 45805b261ecSmrg { 45905b261ecSmrg RegionRec expRec; 46005b261ecSmrg int clientInterested; 46105b261ecSmrg 46205b261ecSmrg /* 46305b261ecSmrg * Restore from backing-store FIRST. 46405b261ecSmrg */ 46505b261ecSmrg clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask; 46605b261ecSmrg if (other_exposed) 46705b261ecSmrg { 46805b261ecSmrg if (exposures) 46905b261ecSmrg { 4706747b715Smrg RegionUnion(other_exposed, 47105b261ecSmrg exposures, 47205b261ecSmrg other_exposed); 47305b261ecSmrg if (exposures != prgn) 4746747b715Smrg RegionDestroy(exposures); 47505b261ecSmrg } 47605b261ecSmrg exposures = other_exposed; 47705b261ecSmrg } 4786747b715Smrg if (clientInterested && exposures && (RegionNumRects(exposures) > RECTLIMIT)) 47905b261ecSmrg { 48005b261ecSmrg /* 48105b261ecSmrg * If we have LOTS of rectangles, we decide to take the extents 48205b261ecSmrg * and force an exposure on that. This should require much less 48305b261ecSmrg * work overall, on both client and server. This is cheating, but 48405b261ecSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-). 48505b261ecSmrg */ 48605b261ecSmrg BoxRec box; 48705b261ecSmrg 4886747b715Smrg box = *RegionExtents(exposures); 48905b261ecSmrg if (exposures == prgn) { 49005b261ecSmrg exposures = &expRec; 4916747b715Smrg RegionInit(exposures, &box, 1); 4926747b715Smrg RegionReset(prgn, &box); 49305b261ecSmrg } else { 4946747b715Smrg RegionReset(exposures, &box); 4956747b715Smrg RegionUnion(prgn, prgn, exposures); 49605b261ecSmrg } 4976747b715Smrg /* miPaintWindow doesn't clip, so we have to */ 4986747b715Smrg RegionIntersect(prgn, prgn, &pWin->clipList); 49905b261ecSmrg } 5006747b715Smrg if (prgn && !RegionNil(prgn)) 5014642e01fSmrg miPaintWindow(pWin, prgn, PW_BACKGROUND); 5026747b715Smrg if (clientInterested && exposures && !RegionNil(exposures)) 50305b261ecSmrg miSendExposures(pWin, exposures, 50405b261ecSmrg pWin->drawable.x, pWin->drawable.y); 50505b261ecSmrg if (exposures == &expRec) 50605b261ecSmrg { 5076747b715Smrg RegionUninit(exposures); 50805b261ecSmrg } 50905b261ecSmrg else if (exposures && exposures != prgn && exposures != other_exposed) 5106747b715Smrg RegionDestroy(exposures); 51105b261ecSmrg if (prgn) 5126747b715Smrg RegionEmpty(prgn); 51305b261ecSmrg } 51405b261ecSmrg else if (exposures && exposures != prgn) 5156747b715Smrg RegionDestroy(exposures); 51605b261ecSmrg} 51705b261ecSmrg 5186747b715Smrg#ifdef ROOTLESS 5196747b715Smrg/* Ugly, ugly, but we lost our hooks into miPaintWindow... =/ */ 5206747b715Smrgvoid RootlessSetPixmapOfAncestors(WindowPtr pWin); 5216747b715Smrgvoid RootlessStartDrawing(WindowPtr pWin); 5226747b715Smrgvoid RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn); 5236747b715SmrgBool IsFramedWindow(WindowPtr pWin); 5246747b715Smrg#endif 5256747b715Smrg 5264642e01fSmrgvoid 5274642e01fSmrgmiPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) 52805b261ecSmrg{ 5294642e01fSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 5306747b715Smrg ChangeGCVal gcval[6]; 5314642e01fSmrg BITS32 gcmask; 5324642e01fSmrg GCPtr pGC; 5334642e01fSmrg int i; 5344642e01fSmrg BoxPtr pbox; 5354642e01fSmrg xRectangle *prect; 5364642e01fSmrg int numRects; 5374642e01fSmrg /* 5384642e01fSmrg * Distance from screen to destination drawable, use this 5394642e01fSmrg * to adjust rendering coordinates which come in in screen space 5404642e01fSmrg */ 5414642e01fSmrg int draw_x_off, draw_y_off; 5424642e01fSmrg /* 5434642e01fSmrg * Tile offset for drawing; these need to align the tile 5444642e01fSmrg * to the appropriate window origin 5454642e01fSmrg */ 5464642e01fSmrg int tile_x_off, tile_y_off; 5474642e01fSmrg PixUnion fill; 5484642e01fSmrg Bool solid = TRUE; 5494642e01fSmrg DrawablePtr drawable = &pWin->drawable; 55005b261ecSmrg 5516747b715Smrg#ifdef ROOTLESS 5526747b715Smrg if(!drawable || drawable->type == UNDRAWABLE_WINDOW) 5536747b715Smrg return; 5546747b715Smrg 5556747b715Smrg if(IsFramedWindow(pWin)) { 5566747b715Smrg RootlessStartDrawing(pWin); 5576747b715Smrg RootlessDamageRegion(pWin, prgn); 5586747b715Smrg 5596747b715Smrg if(pWin->backgroundState == ParentRelative) { 5606747b715Smrg if((what == PW_BACKGROUND) || 5616747b715Smrg (what == PW_BORDER && !pWin->borderIsPixel)) 5626747b715Smrg RootlessSetPixmapOfAncestors(pWin); 5636747b715Smrg } 5646747b715Smrg } 5656747b715Smrg#endif 5666747b715Smrg 56705b261ecSmrg if (what == PW_BACKGROUND) 56805b261ecSmrg { 5694642e01fSmrg while (pWin->backgroundState == ParentRelative) 5704642e01fSmrg pWin = pWin->parent; 5714642e01fSmrg 5724642e01fSmrg draw_x_off = drawable->x; 5734642e01fSmrg draw_y_off = drawable->y; 5744642e01fSmrg 5754642e01fSmrg tile_x_off = pWin->drawable.x - draw_x_off; 5764642e01fSmrg tile_y_off = pWin->drawable.y - draw_y_off; 5774642e01fSmrg fill = pWin->background; 57805b261ecSmrg switch (pWin->backgroundState) { 57905b261ecSmrg case None: 58005b261ecSmrg return; 58105b261ecSmrg case BackgroundPixmap: 5824642e01fSmrg solid = FALSE; 58305b261ecSmrg break; 58405b261ecSmrg } 58505b261ecSmrg } 58605b261ecSmrg else 58705b261ecSmrg { 5884642e01fSmrg PixmapPtr pixmap; 5894642e01fSmrg 5904642e01fSmrg tile_x_off = drawable->x; 5914642e01fSmrg tile_y_off = drawable->y; 5924642e01fSmrg 5934642e01fSmrg /* servers without pixmaps draw their own borders */ 5944642e01fSmrg if (!pScreen->GetWindowPixmap) 5954642e01fSmrg return; 5964642e01fSmrg pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); 5974642e01fSmrg drawable = &pixmap->drawable; 5984642e01fSmrg#ifdef COMPOSITE 5994642e01fSmrg draw_x_off = pixmap->screen_x; 6004642e01fSmrg draw_y_off = pixmap->screen_y; 6014642e01fSmrg tile_x_off -= draw_x_off; 6024642e01fSmrg tile_y_off -= draw_y_off; 6034642e01fSmrg#else 6044642e01fSmrg draw_x_off = 0; 6054642e01fSmrg draw_y_off = 0; 6064642e01fSmrg#endif 6074642e01fSmrg fill = pWin->border; 6084642e01fSmrg solid = pWin->borderIsPixel; 60905b261ecSmrg } 6104642e01fSmrg 6114642e01fSmrg gcval[0].val = GXcopy; 6124642e01fSmrg gcmask = GCFunction; 61305b261ecSmrg 6146747b715Smrg#ifdef ROOTLESS_SAFEALPHA 6156747b715Smrg/* Bit mask for alpha channel with a particular number of bits per 6166747b715Smrg * pixel. Note that we only care for 32bpp data. Mac OS X uses planar 6176747b715Smrg * alpha for 16bpp. 6186747b715Smrg */ 6196747b715Smrg#define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0) 6206747b715Smrg#endif 6216747b715Smrg 6224642e01fSmrg if (solid) 6234642e01fSmrg { 6246747b715Smrg#ifdef ROOTLESS_SAFEALPHA 6256747b715Smrg gcval[1].val = fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); 6266747b715Smrg#else 6274642e01fSmrg gcval[1].val = fill.pixel; 6286747b715Smrg#endif 6294642e01fSmrg gcval[2].val = FillSolid; 6304642e01fSmrg gcmask |= GCForeground | GCFillStyle; 6314642e01fSmrg } 6324642e01fSmrg else 6334642e01fSmrg { 6346747b715Smrg int c=1; 6356747b715Smrg#ifdef ROOTLESS_SAFEALPHA 6366747b715Smrg gcval[c++].val = ((CARD32)-1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel); 6376747b715Smrg gcmask |= GCPlaneMask; 6386747b715Smrg#endif 6396747b715Smrg gcval[c++].val = FillTiled; 6406747b715Smrg gcval[c++].ptr = (pointer)fill.pixmap; 6416747b715Smrg gcval[c++].val = tile_x_off; 6426747b715Smrg gcval[c++].val = tile_y_off; 6434642e01fSmrg gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; 6444642e01fSmrg } 6454642e01fSmrg 6466747b715Smrg prect = malloc(RegionNumRects(prgn) * sizeof(xRectangle)); 64705b261ecSmrg if (!prect) 64805b261ecSmrg return; 64905b261ecSmrg 6504642e01fSmrg pGC = GetScratchGC(drawable->depth, drawable->pScreen); 6514642e01fSmrg if (!pGC) 65205b261ecSmrg { 6536747b715Smrg free(prect); 6544642e01fSmrg return; 65505b261ecSmrg } 65605b261ecSmrg 6576747b715Smrg ChangeGC (NullClient, pGC, gcmask, gcval); 6584642e01fSmrg ValidateGC (drawable, pGC); 65905b261ecSmrg 6606747b715Smrg numRects = RegionNumRects(prgn); 6616747b715Smrg pbox = RegionRects(prgn); 66205b261ecSmrg for (i= numRects; --i >= 0; pbox++, prect++) 66305b261ecSmrg { 6644642e01fSmrg prect->x = pbox->x1 - draw_x_off; 6654642e01fSmrg prect->y = pbox->y1 - draw_y_off; 66605b261ecSmrg prect->width = pbox->x2 - pbox->x1; 66705b261ecSmrg prect->height = pbox->y2 - pbox->y1; 66805b261ecSmrg } 66905b261ecSmrg prect -= numRects; 6704642e01fSmrg (*pGC->ops->PolyFillRect)(drawable, pGC, numRects, prect); 6716747b715Smrg free(prect); 67205b261ecSmrg 6734642e01fSmrg FreeScratchGC(pGC); 67405b261ecSmrg} 67505b261ecSmrg 67605b261ecSmrg 67705b261ecSmrg/* MICLEARDRAWABLE -- sets the entire drawable to the background color of 67805b261ecSmrg * the GC. Useful when we have a scratch drawable and need to initialize 67905b261ecSmrg * it. */ 6806747b715Smrgvoid 6814642e01fSmrgmiClearDrawable(DrawablePtr pDraw, GCPtr pGC) 68205b261ecSmrg{ 6836747b715Smrg ChangeGCVal fg, bg; 68405b261ecSmrg xRectangle rect; 68505b261ecSmrg 6866747b715Smrg fg.val = pGC->fgPixel; 6876747b715Smrg bg.val = pGC->bgPixel; 68805b261ecSmrg rect.x = 0; 68905b261ecSmrg rect.y = 0; 69005b261ecSmrg rect.width = pDraw->width; 69105b261ecSmrg rect.height = pDraw->height; 6926747b715Smrg ChangeGC(NullClient, pGC, GCForeground, &bg); 69305b261ecSmrg ValidateGC(pDraw, pGC); 69405b261ecSmrg (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect); 6956747b715Smrg ChangeGC(NullClient, pGC, GCForeground, &fg); 69605b261ecSmrg ValidateGC(pDraw, pGC); 69705b261ecSmrg} 698