miexpose.c revision 35c4bbdf
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 2505b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 2605b261ecSmrg 2705b261ecSmrg All Rights Reserved 2805b261ecSmrg 2935c4bbdfSmrgPermission to use, copy, modify, and distribute this software and its 3035c4bbdfSmrgdocumentation for any purpose and without fee is hereby granted, 3105b261ecSmrgprovided that the above copyright notice appear in all copies and that 3235c4bbdfSmrgboth that copyright notice and this permission notice appear in 3305b261ecSmrgsupporting documentation, and that the name of Digital not be 3405b261ecSmrgused in advertising or publicity pertaining to distribution of the 3535c4bbdfSmrgsoftware without specific, written prior permission. 3605b261ecSmrg 3705b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3805b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 3905b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4005b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4205b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4305b261ecSmrgSOFTWARE. 4405b261ecSmrg 4505b261ecSmrg******************************************************************/ 4605b261ecSmrg/***************************************************************** 4705b261ecSmrg 4805b261ecSmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 4905b261ecSmrg 5005b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a copy 5105b261ecSmrgof this software and associated documentation files (the "Software"), to deal 5205b261ecSmrgin the Software without restriction, including without limitation the rights 5305b261ecSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5405b261ecSmrgcopies of the Software. 5505b261ecSmrg 5605b261ecSmrgThe above copyright notice and this permission notice shall be included in 5705b261ecSmrgall copies or substantial portions of the Software. 5805b261ecSmrg 5905b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6005b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 6105b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 6205b261ecSmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 6305b261ecSmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 6405b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 6505b261ecSmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6605b261ecSmrg 6705b261ecSmrgExcept as contained in this notice, the name of Digital Equipment Corporation 6805b261ecSmrgshall not be used in advertising or otherwise to promote the sale, use or other 6905b261ecSmrgdealings in this Software without prior written authorization from Digital 7005b261ecSmrgEquipment Corporation. 7105b261ecSmrg 7205b261ecSmrg******************************************************************/ 7305b261ecSmrg 7405b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 7505b261ecSmrg#include <dix-config.h> 7605b261ecSmrg#endif 7705b261ecSmrg 7805b261ecSmrg#include <X11/X.h> 7905b261ecSmrg#include <X11/Xproto.h> 8005b261ecSmrg#include <X11/Xprotostr.h> 8105b261ecSmrg 8205b261ecSmrg#include "misc.h" 8305b261ecSmrg#include "regionstr.h" 8405b261ecSmrg#include "scrnintstr.h" 8505b261ecSmrg#include "gcstruct.h" 8605b261ecSmrg#include "windowstr.h" 8705b261ecSmrg#include "pixmap.h" 8805b261ecSmrg#include "input.h" 8905b261ecSmrg 9005b261ecSmrg#include "dixstruct.h" 9105b261ecSmrg#include "mi.h" 9205b261ecSmrg#include <X11/Xmd.h> 9305b261ecSmrg 9405b261ecSmrg#include "globals.h" 9505b261ecSmrg 9605b261ecSmrg#ifdef PANORAMIX 9705b261ecSmrg#include "panoramiX.h" 9805b261ecSmrg#include "panoramiXsrv.h" 9905b261ecSmrg#endif 10005b261ecSmrg 10105b261ecSmrg/* 10205b261ecSmrg machine-independent graphics exposure code. any device that uses 10305b261ecSmrgthe region package can call this. 10405b261ecSmrg*/ 10505b261ecSmrg 10605b261ecSmrg#ifndef RECTLIMIT 10735c4bbdfSmrg#define RECTLIMIT 25 /* pick a number, any number > 8 */ 10805b261ecSmrg#endif 10905b261ecSmrg 11035c4bbdfSmrg/* miHandleExposures 11105b261ecSmrg generate a region for exposures for areas that were copied from obscured or 11205b261ecSmrgnon-existent areas to non-obscured areas of the destination. Paint the 11305b261ecSmrgbackground for the region, if the destination is a window. 11405b261ecSmrg 11505b261ecSmrgNOTE: 11605b261ecSmrg this should generally be called, even if graphicsExposures is false, 11705b261ecSmrgbecause this is where bits get recovered from backing store. 11805b261ecSmrg 11905b261ecSmrg*/ 12005b261ecSmrg 1216747b715SmrgRegionPtr 1224642e01fSmrgmiHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, 12335c4bbdfSmrg GCPtr pGC, int srcx, int srcy, int width, int height, 12435c4bbdfSmrg int dstx, int dsty) 12505b261ecSmrg{ 12635c4bbdfSmrg RegionPtr prgnSrcClip; /* drawable-relative source clip */ 12705b261ecSmrg RegionRec rgnSrcRec; 12835c4bbdfSmrg RegionPtr prgnDstClip; /* drawable-relative dest clip */ 12905b261ecSmrg RegionRec rgnDstRec; 13035c4bbdfSmrg BoxRec srcBox; /* unclipped source */ 13135c4bbdfSmrg RegionRec rgnExposed; /* exposed region, calculated source- 13235c4bbdfSmrg relative, made dst relative to 13335c4bbdfSmrg intersect with visible parts of 13435c4bbdfSmrg dest and send events to client, 13535c4bbdfSmrg and then screen relative to paint 13635c4bbdfSmrg the window background 13735c4bbdfSmrg */ 13805b261ecSmrg WindowPtr pSrcWin; 13905b261ecSmrg BoxRec expBox; 14005b261ecSmrg Bool extents; 14105b261ecSmrg 14205b261ecSmrg /* avoid work if we can */ 14305b261ecSmrg if (!pGC->graphicsExposures && 14435c4bbdfSmrg (pDstDrawable->type == DRAWABLE_PIXMAP) && 14535c4bbdfSmrg ((pSrcDrawable->type == DRAWABLE_PIXMAP) || 14635c4bbdfSmrg (((WindowPtr) pSrcDrawable)->backStorage == 0))) 14735c4bbdfSmrg return NULL; 14835c4bbdfSmrg 14905b261ecSmrg srcBox.x1 = srcx; 15005b261ecSmrg srcBox.y1 = srcy; 15135c4bbdfSmrg srcBox.x2 = srcx + width; 15235c4bbdfSmrg srcBox.y2 = srcy + height; 15335c4bbdfSmrg 15435c4bbdfSmrg if (pSrcDrawable->type != DRAWABLE_PIXMAP) { 15535c4bbdfSmrg BoxRec TsrcBox; 15635c4bbdfSmrg 15735c4bbdfSmrg TsrcBox.x1 = srcx + pSrcDrawable->x; 15835c4bbdfSmrg TsrcBox.y1 = srcy + pSrcDrawable->y; 15935c4bbdfSmrg TsrcBox.x2 = TsrcBox.x1 + width; 16035c4bbdfSmrg TsrcBox.y2 = TsrcBox.y1 + height; 16135c4bbdfSmrg pSrcWin = (WindowPtr) pSrcDrawable; 16235c4bbdfSmrg if (pGC->subWindowMode == IncludeInferiors) { 16335c4bbdfSmrg prgnSrcClip = NotClippedByChildren(pSrcWin); 16435c4bbdfSmrg if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) { 16535c4bbdfSmrg RegionDestroy(prgnSrcClip); 16635c4bbdfSmrg return NULL; 16735c4bbdfSmrg } 16835c4bbdfSmrg } 16935c4bbdfSmrg else { 17035c4bbdfSmrg if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN) 17135c4bbdfSmrg return NULL; 17235c4bbdfSmrg prgnSrcClip = &rgnSrcRec; 17335c4bbdfSmrg RegionNull(prgnSrcClip); 17435c4bbdfSmrg RegionCopy(prgnSrcClip, &pSrcWin->clipList); 17535c4bbdfSmrg } 17635c4bbdfSmrg RegionTranslate(prgnSrcClip, -pSrcDrawable->x, -pSrcDrawable->y); 17705b261ecSmrg } 17835c4bbdfSmrg else { 17935c4bbdfSmrg BoxRec box; 18035c4bbdfSmrg 18135c4bbdfSmrg if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && 18235c4bbdfSmrg (srcBox.x2 <= pSrcDrawable->width) && 18335c4bbdfSmrg (srcBox.y2 <= pSrcDrawable->height)) 18435c4bbdfSmrg return NULL; 18535c4bbdfSmrg 18635c4bbdfSmrg box.x1 = 0; 18735c4bbdfSmrg box.y1 = 0; 18835c4bbdfSmrg box.x2 = pSrcDrawable->width; 18935c4bbdfSmrg box.y2 = pSrcDrawable->height; 19035c4bbdfSmrg prgnSrcClip = &rgnSrcRec; 19135c4bbdfSmrg RegionInit(prgnSrcClip, &box, 1); 19235c4bbdfSmrg pSrcWin = NULL; 19305b261ecSmrg } 19405b261ecSmrg 19535c4bbdfSmrg if (pDstDrawable == pSrcDrawable) { 19635c4bbdfSmrg prgnDstClip = prgnSrcClip; 19705b261ecSmrg } 19835c4bbdfSmrg else if (pDstDrawable->type != DRAWABLE_PIXMAP) { 19935c4bbdfSmrg if (pGC->subWindowMode == IncludeInferiors) { 20035c4bbdfSmrg prgnDstClip = NotClippedByChildren((WindowPtr) pDstDrawable); 20135c4bbdfSmrg } 20235c4bbdfSmrg else { 20335c4bbdfSmrg prgnDstClip = &rgnDstRec; 20435c4bbdfSmrg RegionNull(prgnDstClip); 20535c4bbdfSmrg RegionCopy(prgnDstClip, &((WindowPtr) pDstDrawable)->clipList); 20635c4bbdfSmrg } 20735c4bbdfSmrg RegionTranslate(prgnDstClip, -pDstDrawable->x, -pDstDrawable->y); 20805b261ecSmrg } 20935c4bbdfSmrg else { 21035c4bbdfSmrg BoxRec box; 21135c4bbdfSmrg 21235c4bbdfSmrg box.x1 = 0; 21335c4bbdfSmrg box.y1 = 0; 21435c4bbdfSmrg box.x2 = pDstDrawable->width; 21535c4bbdfSmrg box.y2 = pDstDrawable->height; 21635c4bbdfSmrg prgnDstClip = &rgnDstRec; 21735c4bbdfSmrg RegionInit(prgnDstClip, &box, 1); 21805b261ecSmrg } 21905b261ecSmrg 22005b261ecSmrg /* drawable-relative source region */ 2216747b715Smrg RegionInit(&rgnExposed, &srcBox, 1); 22205b261ecSmrg 22335c4bbdfSmrg /* now get the hidden parts of the source box */ 2246747b715Smrg RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip); 22505b261ecSmrg 22605b261ecSmrg /* move them over the destination */ 22735c4bbdfSmrg RegionTranslate(&rgnExposed, dstx - srcx, dsty - srcy); 22805b261ecSmrg 22905b261ecSmrg /* intersect with visible areas of dest */ 2306747b715Smrg RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip); 2316747b715Smrg 2326747b715Smrg /* intersect with client clip region. */ 23335c4bbdfSmrg if (pGC->clientClip) 23435c4bbdfSmrg RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); 23505b261ecSmrg 23605b261ecSmrg /* 23705b261ecSmrg * If we have LOTS of rectangles, we decide to take the extents 23805b261ecSmrg * and force an exposure on that. This should require much less 23905b261ecSmrg * work overall, on both client and server. This is cheating, but 24005b261ecSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-) 24105b261ecSmrg * for windows. 24205b261ecSmrg */ 24305b261ecSmrg extents = pGC->graphicsExposures && 24435c4bbdfSmrg (RegionNumRects(&rgnExposed) > RECTLIMIT) && 24535c4bbdfSmrg (pDstDrawable->type != DRAWABLE_PIXMAP); 24635c4bbdfSmrg if (pSrcWin) { 24735c4bbdfSmrg RegionPtr region; 24835c4bbdfSmrg 24935c4bbdfSmrg if (!(region = wClipShape(pSrcWin))) 25035c4bbdfSmrg region = wBoundingShape(pSrcWin); 25135c4bbdfSmrg /* 25235c4bbdfSmrg * If you try to CopyArea the extents of a shaped window, compacting the 25335c4bbdfSmrg * exposed region will undo all our work! 25435c4bbdfSmrg */ 25535c4bbdfSmrg if (extents && pSrcWin && region && 25635c4bbdfSmrg (RegionContainsRect(region, &srcBox) != rgnIN)) 25735c4bbdfSmrg extents = FALSE; 25805b261ecSmrg } 25935c4bbdfSmrg if (extents) { 26035c4bbdfSmrg expBox = *RegionExtents(&rgnExposed); 26135c4bbdfSmrg RegionReset(&rgnExposed, &expBox); 26205b261ecSmrg } 26305b261ecSmrg if ((pDstDrawable->type != DRAWABLE_PIXMAP) && 26435c4bbdfSmrg (((WindowPtr) pDstDrawable)->backgroundState != None)) { 26535c4bbdfSmrg WindowPtr pWin = (WindowPtr) pDstDrawable; 26605b261ecSmrg 26735c4bbdfSmrg /* make the exposed area screen-relative */ 26835c4bbdfSmrg RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y); 26935c4bbdfSmrg 27035c4bbdfSmrg if (extents) { 27135c4bbdfSmrg /* PaintWindow doesn't clip, so we have to */ 27235c4bbdfSmrg RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); 27335c4bbdfSmrg } 27435c4bbdfSmrg pDstDrawable->pScreen->PaintWindow((WindowPtr) pDstDrawable, 27535c4bbdfSmrg &rgnExposed, PW_BACKGROUND); 27635c4bbdfSmrg 27735c4bbdfSmrg if (extents) { 27835c4bbdfSmrg RegionReset(&rgnExposed, &expBox); 27935c4bbdfSmrg } 28035c4bbdfSmrg else 28135c4bbdfSmrg RegionTranslate(&rgnExposed, -pDstDrawable->x, -pDstDrawable->y); 28235c4bbdfSmrg } 28335c4bbdfSmrg if (prgnDstClip == &rgnDstRec) { 28435c4bbdfSmrg RegionUninit(prgnDstClip); 28505b261ecSmrg } 28635c4bbdfSmrg else if (prgnDstClip != prgnSrcClip) { 28735c4bbdfSmrg RegionDestroy(prgnDstClip); 28805b261ecSmrg } 28905b261ecSmrg 29035c4bbdfSmrg if (prgnSrcClip == &rgnSrcRec) { 29135c4bbdfSmrg RegionUninit(prgnSrcClip); 29205b261ecSmrg } 29335c4bbdfSmrg else { 29435c4bbdfSmrg RegionDestroy(prgnSrcClip); 29505b261ecSmrg } 29605b261ecSmrg 29735c4bbdfSmrg if (pGC->graphicsExposures) { 29835c4bbdfSmrg /* don't look */ 29935c4bbdfSmrg RegionPtr exposed = RegionCreate(NullBox, 0); 30005b261ecSmrg 30135c4bbdfSmrg *exposed = rgnExposed; 30235c4bbdfSmrg return exposed; 30305b261ecSmrg } 30435c4bbdfSmrg else { 30535c4bbdfSmrg RegionUninit(&rgnExposed); 30635c4bbdfSmrg return NULL; 30705b261ecSmrg } 30805b261ecSmrg} 30905b261ecSmrg 31005b261ecSmrgvoid 31135c4bbdfSmrgmiSendExposures(WindowPtr pWin, RegionPtr pRgn, int dx, int dy) 31205b261ecSmrg{ 31305b261ecSmrg BoxPtr pBox; 31405b261ecSmrg int numRects; 31505b261ecSmrg xEvent *pEvent, *pe; 31605b261ecSmrg int i; 31705b261ecSmrg 3186747b715Smrg pBox = RegionRects(pRgn); 3196747b715Smrg numRects = RegionNumRects(pRgn); 32035c4bbdfSmrg if (!(pEvent = calloc(1, numRects * sizeof(xEvent)))) 32135c4bbdfSmrg return; 32235c4bbdfSmrg 32335c4bbdfSmrg for (i = numRects, pe = pEvent; --i >= 0; pe++, pBox++) { 32435c4bbdfSmrg pe->u.u.type = Expose; 32535c4bbdfSmrg pe->u.expose.window = pWin->drawable.id; 32635c4bbdfSmrg pe->u.expose.x = pBox->x1 - dx; 32735c4bbdfSmrg pe->u.expose.y = pBox->y1 - dy; 32835c4bbdfSmrg pe->u.expose.width = pBox->x2 - pBox->x1; 32935c4bbdfSmrg pe->u.expose.height = pBox->y2 - pBox->y1; 33035c4bbdfSmrg pe->u.expose.count = i; 33105b261ecSmrg } 33205b261ecSmrg 33305b261ecSmrg#ifdef PANORAMIX 33435c4bbdfSmrg if (!noPanoramiXExtension) { 33535c4bbdfSmrg int scrnum = pWin->drawable.pScreen->myNum; 33635c4bbdfSmrg int x = 0, y = 0; 33735c4bbdfSmrg XID realWin = 0; 33835c4bbdfSmrg 33935c4bbdfSmrg if (!pWin->parent) { 34035c4bbdfSmrg x = screenInfo.screens[scrnum]->x; 34135c4bbdfSmrg y = screenInfo.screens[scrnum]->y; 34235c4bbdfSmrg pWin = screenInfo.screens[0]->root; 34335c4bbdfSmrg realWin = pWin->drawable.id; 34435c4bbdfSmrg } 34535c4bbdfSmrg else if (scrnum) { 34635c4bbdfSmrg PanoramiXRes *win; 34735c4bbdfSmrg 34835c4bbdfSmrg win = PanoramiXFindIDByScrnum(XRT_WINDOW, 34935c4bbdfSmrg pWin->drawable.id, scrnum); 35035c4bbdfSmrg if (!win) { 35135c4bbdfSmrg free(pEvent); 35235c4bbdfSmrg return; 35335c4bbdfSmrg } 35435c4bbdfSmrg realWin = win->info[0].id; 35535c4bbdfSmrg dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess); 35635c4bbdfSmrg } 35735c4bbdfSmrg if (x || y || scrnum) 35835c4bbdfSmrg for (i = 0; i < numRects; i++) { 35935c4bbdfSmrg pEvent[i].u.expose.window = realWin; 36035c4bbdfSmrg pEvent[i].u.expose.x += x; 36135c4bbdfSmrg pEvent[i].u.expose.y += y; 36235c4bbdfSmrg } 36305b261ecSmrg } 36405b261ecSmrg#endif 36505b261ecSmrg 36605b261ecSmrg DeliverEvents(pWin, pEvent, numRects, NullWindow); 36705b261ecSmrg 3686747b715Smrg free(pEvent); 36905b261ecSmrg} 37005b261ecSmrg 3716747b715Smrgvoid 37235c4bbdfSmrgmiWindowExposures(WindowPtr pWin, RegionPtr prgn) 37305b261ecSmrg{ 37435c4bbdfSmrg RegionPtr exposures = prgn; 37535c4bbdfSmrg 37635c4bbdfSmrg if (prgn && !RegionNil(prgn)) { 37735c4bbdfSmrg RegionRec expRec; 37835c4bbdfSmrg int clientInterested = 37935c4bbdfSmrg (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask; 38035c4bbdfSmrg if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT)) { 38135c4bbdfSmrg /* 38235c4bbdfSmrg * If we have LOTS of rectangles, we decide to take the extents 38335c4bbdfSmrg * and force an exposure on that. This should require much less 38435c4bbdfSmrg * work overall, on both client and server. This is cheating, but 38535c4bbdfSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-). 38635c4bbdfSmrg */ 38735c4bbdfSmrg BoxRec box = *RegionExtents(prgn); 38835c4bbdfSmrg exposures = &expRec; 38935c4bbdfSmrg RegionInit(exposures, &box, 1); 39035c4bbdfSmrg RegionReset(prgn, &box); 39135c4bbdfSmrg /* miPaintWindow doesn't clip, so we have to */ 39235c4bbdfSmrg RegionIntersect(prgn, prgn, &pWin->clipList); 39335c4bbdfSmrg } 39435c4bbdfSmrg pWin->drawable.pScreen->PaintWindow(pWin, prgn, PW_BACKGROUND); 39535c4bbdfSmrg if (clientInterested) 39635c4bbdfSmrg miSendExposures(pWin, exposures, 39735c4bbdfSmrg pWin->drawable.x, pWin->drawable.y); 39835c4bbdfSmrg if (exposures == &expRec) 39935c4bbdfSmrg RegionUninit(exposures); 40035c4bbdfSmrg RegionEmpty(prgn); 40105b261ecSmrg } 40205b261ecSmrg} 40305b261ecSmrg 4044642e01fSmrgvoid 4054642e01fSmrgmiPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) 40605b261ecSmrg{ 40735c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 4086747b715Smrg ChangeGCVal gcval[6]; 40935c4bbdfSmrg BITS32 gcmask; 41035c4bbdfSmrg GCPtr pGC; 41135c4bbdfSmrg int i; 41235c4bbdfSmrg BoxPtr pbox; 41335c4bbdfSmrg xRectangle *prect; 41435c4bbdfSmrg int numRects; 41535c4bbdfSmrg 4164642e01fSmrg /* 4174642e01fSmrg * Distance from screen to destination drawable, use this 4184642e01fSmrg * to adjust rendering coordinates which come in in screen space 4194642e01fSmrg */ 42035c4bbdfSmrg int draw_x_off, draw_y_off; 42135c4bbdfSmrg 4224642e01fSmrg /* 4234642e01fSmrg * Tile offset for drawing; these need to align the tile 4244642e01fSmrg * to the appropriate window origin 4254642e01fSmrg */ 42635c4bbdfSmrg int tile_x_off, tile_y_off; 42735c4bbdfSmrg PixUnion fill; 42835c4bbdfSmrg Bool solid = TRUE; 42935c4bbdfSmrg DrawablePtr drawable = &pWin->drawable; 43035c4bbdfSmrg 43135c4bbdfSmrg if (what == PW_BACKGROUND) { 43235c4bbdfSmrg while (pWin->backgroundState == ParentRelative) 43335c4bbdfSmrg pWin = pWin->parent; 43435c4bbdfSmrg 43535c4bbdfSmrg draw_x_off = drawable->x; 43635c4bbdfSmrg draw_y_off = drawable->y; 43735c4bbdfSmrg 43835c4bbdfSmrg tile_x_off = pWin->drawable.x - draw_x_off; 43935c4bbdfSmrg tile_y_off = pWin->drawable.y - draw_y_off; 44035c4bbdfSmrg fill = pWin->background; 44135c4bbdfSmrg#ifdef COMPOSITE 44235c4bbdfSmrg if (pWin->inhibitBGPaint) 44335c4bbdfSmrg return; 4446747b715Smrg#endif 44535c4bbdfSmrg switch (pWin->backgroundState) { 44635c4bbdfSmrg case None: 44735c4bbdfSmrg return; 44835c4bbdfSmrg case BackgroundPixmap: 44935c4bbdfSmrg solid = FALSE; 45035c4bbdfSmrg break; 45135c4bbdfSmrg } 45205b261ecSmrg } 45335c4bbdfSmrg else { 45435c4bbdfSmrg PixmapPtr pixmap; 45535c4bbdfSmrg 45635c4bbdfSmrg fill = pWin->border; 45735c4bbdfSmrg solid = pWin->borderIsPixel; 45835c4bbdfSmrg 45935c4bbdfSmrg /* servers without pixmaps draw their own borders */ 46035c4bbdfSmrg if (!pScreen->GetWindowPixmap) 46135c4bbdfSmrg return; 46235c4bbdfSmrg pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); 46335c4bbdfSmrg drawable = &pixmap->drawable; 46435c4bbdfSmrg 46535c4bbdfSmrg while (pWin->backgroundState == ParentRelative) 46635c4bbdfSmrg pWin = pWin->parent; 46735c4bbdfSmrg 46835c4bbdfSmrg tile_x_off = pWin->drawable.x; 46935c4bbdfSmrg tile_y_off = pWin->drawable.y; 47035c4bbdfSmrg 4714642e01fSmrg#ifdef COMPOSITE 47235c4bbdfSmrg draw_x_off = pixmap->screen_x; 47335c4bbdfSmrg draw_y_off = pixmap->screen_y; 47435c4bbdfSmrg tile_x_off -= draw_x_off; 47535c4bbdfSmrg tile_y_off -= draw_y_off; 4764642e01fSmrg#else 47735c4bbdfSmrg draw_x_off = 0; 47835c4bbdfSmrg draw_y_off = 0; 4794642e01fSmrg#endif 48005b261ecSmrg } 48135c4bbdfSmrg 4824642e01fSmrg gcval[0].val = GXcopy; 4834642e01fSmrg gcmask = GCFunction; 48405b261ecSmrg 4856747b715Smrg#ifdef ROOTLESS_SAFEALPHA 4866747b715Smrg/* Bit mask for alpha channel with a particular number of bits per 4876747b715Smrg * pixel. Note that we only care for 32bpp data. Mac OS X uses planar 4886747b715Smrg * alpha for 16bpp. 4896747b715Smrg */ 4906747b715Smrg#define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0) 4916747b715Smrg#endif 49235c4bbdfSmrg 49335c4bbdfSmrg if (solid) { 4946747b715Smrg#ifdef ROOTLESS_SAFEALPHA 49535c4bbdfSmrg gcval[1].val = 49635c4bbdfSmrg fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); 4976747b715Smrg#else 49835c4bbdfSmrg gcval[1].val = fill.pixel; 4996747b715Smrg#endif 50035c4bbdfSmrg gcval[2].val = FillSolid; 50135c4bbdfSmrg gcmask |= GCForeground | GCFillStyle; 5024642e01fSmrg } 50335c4bbdfSmrg else { 50435c4bbdfSmrg int c = 1; 50535c4bbdfSmrg 5066747b715Smrg#ifdef ROOTLESS_SAFEALPHA 50735c4bbdfSmrg gcval[c++].val = 50835c4bbdfSmrg ((CARD32) -1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel); 50935c4bbdfSmrg gcmask |= GCPlaneMask; 5106747b715Smrg#endif 51135c4bbdfSmrg gcval[c++].val = FillTiled; 51235c4bbdfSmrg gcval[c++].ptr = (void *) fill.pixmap; 51335c4bbdfSmrg gcval[c++].val = tile_x_off; 51435c4bbdfSmrg gcval[c++].val = tile_y_off; 51535c4bbdfSmrg gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; 5164642e01fSmrg } 5174642e01fSmrg 51835c4bbdfSmrg prect = xallocarray(RegionNumRects(prgn), sizeof(xRectangle)); 51905b261ecSmrg if (!prect) 52035c4bbdfSmrg return; 52105b261ecSmrg 5224642e01fSmrg pGC = GetScratchGC(drawable->depth, drawable->pScreen); 52335c4bbdfSmrg if (!pGC) { 52435c4bbdfSmrg free(prect); 52535c4bbdfSmrg return; 52605b261ecSmrg } 52735c4bbdfSmrg 52835c4bbdfSmrg ChangeGC(NullClient, pGC, gcmask, gcval); 52935c4bbdfSmrg ValidateGC(drawable, pGC); 53005b261ecSmrg 5316747b715Smrg numRects = RegionNumRects(prgn); 5326747b715Smrg pbox = RegionRects(prgn); 53335c4bbdfSmrg for (i = numRects; --i >= 0; pbox++, prect++) { 53435c4bbdfSmrg prect->x = pbox->x1 - draw_x_off; 53535c4bbdfSmrg prect->y = pbox->y1 - draw_y_off; 53635c4bbdfSmrg prect->width = pbox->x2 - pbox->x1; 53735c4bbdfSmrg prect->height = pbox->y2 - pbox->y1; 53805b261ecSmrg } 53905b261ecSmrg prect -= numRects; 54035c4bbdfSmrg (*pGC->ops->PolyFillRect) (drawable, pGC, numRects, prect); 5416747b715Smrg free(prect); 54205b261ecSmrg 5434642e01fSmrg FreeScratchGC(pGC); 54405b261ecSmrg} 54505b261ecSmrg 54605b261ecSmrg/* MICLEARDRAWABLE -- sets the entire drawable to the background color of 54735c4bbdfSmrg * the GC. Useful when we have a scratch drawable and need to initialize 54805b261ecSmrg * it. */ 5496747b715Smrgvoid 5504642e01fSmrgmiClearDrawable(DrawablePtr pDraw, GCPtr pGC) 55105b261ecSmrg{ 5526747b715Smrg ChangeGCVal fg, bg; 55305b261ecSmrg xRectangle rect; 55405b261ecSmrg 5556747b715Smrg fg.val = pGC->fgPixel; 5566747b715Smrg bg.val = pGC->bgPixel; 55705b261ecSmrg rect.x = 0; 55805b261ecSmrg rect.y = 0; 55905b261ecSmrg rect.width = pDraw->width; 56005b261ecSmrg rect.height = pDraw->height; 5616747b715Smrg ChangeGC(NullClient, pGC, GCForeground, &bg); 56205b261ecSmrg ValidateGC(pDraw, pGC); 56335c4bbdfSmrg (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect); 5646747b715Smrg ChangeGC(NullClient, pGC, GCForeground, &fg); 56505b261ecSmrg ValidateGC(pDraw, pGC); 56605b261ecSmrg} 567