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 11505b261ecSmrg*/ 11605b261ecSmrg 1176747b715SmrgRegionPtr 1184642e01fSmrgmiHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, 11935c4bbdfSmrg GCPtr pGC, int srcx, int srcy, int width, int height, 12035c4bbdfSmrg int dstx, int dsty) 12105b261ecSmrg{ 12235c4bbdfSmrg RegionPtr prgnSrcClip; /* drawable-relative source clip */ 12305b261ecSmrg RegionRec rgnSrcRec; 12435c4bbdfSmrg RegionPtr prgnDstClip; /* drawable-relative dest clip */ 12505b261ecSmrg RegionRec rgnDstRec; 12635c4bbdfSmrg BoxRec srcBox; /* unclipped source */ 12735c4bbdfSmrg RegionRec rgnExposed; /* exposed region, calculated source- 12835c4bbdfSmrg relative, made dst relative to 12935c4bbdfSmrg intersect with visible parts of 13035c4bbdfSmrg dest and send events to client, 13135c4bbdfSmrg and then screen relative to paint 13235c4bbdfSmrg the window background 13335c4bbdfSmrg */ 13405b261ecSmrg WindowPtr pSrcWin; 1351b5d61b8Smrg BoxRec expBox = { 0, }; 13605b261ecSmrg Bool extents; 13705b261ecSmrg 13805b261ecSmrg /* avoid work if we can */ 139ed6184dfSmrg if (!pGC->graphicsExposures && pDstDrawable->type == DRAWABLE_PIXMAP) 14035c4bbdfSmrg return NULL; 14135c4bbdfSmrg 14205b261ecSmrg srcBox.x1 = srcx; 14305b261ecSmrg srcBox.y1 = srcy; 14435c4bbdfSmrg srcBox.x2 = srcx + width; 14535c4bbdfSmrg srcBox.y2 = srcy + height; 14635c4bbdfSmrg 14735c4bbdfSmrg if (pSrcDrawable->type != DRAWABLE_PIXMAP) { 14835c4bbdfSmrg BoxRec TsrcBox; 14935c4bbdfSmrg 15035c4bbdfSmrg TsrcBox.x1 = srcx + pSrcDrawable->x; 15135c4bbdfSmrg TsrcBox.y1 = srcy + pSrcDrawable->y; 15235c4bbdfSmrg TsrcBox.x2 = TsrcBox.x1 + width; 15335c4bbdfSmrg TsrcBox.y2 = TsrcBox.y1 + height; 15435c4bbdfSmrg pSrcWin = (WindowPtr) pSrcDrawable; 15535c4bbdfSmrg if (pGC->subWindowMode == IncludeInferiors) { 15635c4bbdfSmrg prgnSrcClip = NotClippedByChildren(pSrcWin); 15735c4bbdfSmrg if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) { 15835c4bbdfSmrg RegionDestroy(prgnSrcClip); 15935c4bbdfSmrg return NULL; 16035c4bbdfSmrg } 16135c4bbdfSmrg } 16235c4bbdfSmrg else { 16335c4bbdfSmrg if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN) 16435c4bbdfSmrg return NULL; 16535c4bbdfSmrg prgnSrcClip = &rgnSrcRec; 16635c4bbdfSmrg RegionNull(prgnSrcClip); 16735c4bbdfSmrg RegionCopy(prgnSrcClip, &pSrcWin->clipList); 16835c4bbdfSmrg } 16935c4bbdfSmrg RegionTranslate(prgnSrcClip, -pSrcDrawable->x, -pSrcDrawable->y); 17005b261ecSmrg } 17135c4bbdfSmrg else { 17235c4bbdfSmrg BoxRec box; 17335c4bbdfSmrg 17435c4bbdfSmrg if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && 17535c4bbdfSmrg (srcBox.x2 <= pSrcDrawable->width) && 17635c4bbdfSmrg (srcBox.y2 <= pSrcDrawable->height)) 17735c4bbdfSmrg return NULL; 17835c4bbdfSmrg 17935c4bbdfSmrg box.x1 = 0; 18035c4bbdfSmrg box.y1 = 0; 18135c4bbdfSmrg box.x2 = pSrcDrawable->width; 18235c4bbdfSmrg box.y2 = pSrcDrawable->height; 18335c4bbdfSmrg prgnSrcClip = &rgnSrcRec; 18435c4bbdfSmrg RegionInit(prgnSrcClip, &box, 1); 18535c4bbdfSmrg pSrcWin = NULL; 18605b261ecSmrg } 18705b261ecSmrg 18835c4bbdfSmrg if (pDstDrawable == pSrcDrawable) { 18935c4bbdfSmrg prgnDstClip = prgnSrcClip; 19005b261ecSmrg } 19135c4bbdfSmrg else if (pDstDrawable->type != DRAWABLE_PIXMAP) { 19235c4bbdfSmrg if (pGC->subWindowMode == IncludeInferiors) { 19335c4bbdfSmrg prgnDstClip = NotClippedByChildren((WindowPtr) pDstDrawable); 19435c4bbdfSmrg } 19535c4bbdfSmrg else { 19635c4bbdfSmrg prgnDstClip = &rgnDstRec; 19735c4bbdfSmrg RegionNull(prgnDstClip); 19835c4bbdfSmrg RegionCopy(prgnDstClip, &((WindowPtr) pDstDrawable)->clipList); 19935c4bbdfSmrg } 20035c4bbdfSmrg RegionTranslate(prgnDstClip, -pDstDrawable->x, -pDstDrawable->y); 20105b261ecSmrg } 20235c4bbdfSmrg else { 20335c4bbdfSmrg BoxRec box; 20435c4bbdfSmrg 20535c4bbdfSmrg box.x1 = 0; 20635c4bbdfSmrg box.y1 = 0; 20735c4bbdfSmrg box.x2 = pDstDrawable->width; 20835c4bbdfSmrg box.y2 = pDstDrawable->height; 20935c4bbdfSmrg prgnDstClip = &rgnDstRec; 21035c4bbdfSmrg RegionInit(prgnDstClip, &box, 1); 21105b261ecSmrg } 21205b261ecSmrg 21305b261ecSmrg /* drawable-relative source region */ 2146747b715Smrg RegionInit(&rgnExposed, &srcBox, 1); 21505b261ecSmrg 21635c4bbdfSmrg /* now get the hidden parts of the source box */ 2176747b715Smrg RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip); 21805b261ecSmrg 21905b261ecSmrg /* move them over the destination */ 22035c4bbdfSmrg RegionTranslate(&rgnExposed, dstx - srcx, dsty - srcy); 22105b261ecSmrg 22205b261ecSmrg /* intersect with visible areas of dest */ 2236747b715Smrg RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip); 2246747b715Smrg 2256747b715Smrg /* intersect with client clip region. */ 22635c4bbdfSmrg if (pGC->clientClip) 22735c4bbdfSmrg RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); 22805b261ecSmrg 22905b261ecSmrg /* 23005b261ecSmrg * If we have LOTS of rectangles, we decide to take the extents 23105b261ecSmrg * and force an exposure on that. This should require much less 23205b261ecSmrg * work overall, on both client and server. This is cheating, but 23305b261ecSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-) 23405b261ecSmrg * for windows. 23505b261ecSmrg */ 23605b261ecSmrg extents = pGC->graphicsExposures && 23735c4bbdfSmrg (RegionNumRects(&rgnExposed) > RECTLIMIT) && 23835c4bbdfSmrg (pDstDrawable->type != DRAWABLE_PIXMAP); 23935c4bbdfSmrg if (pSrcWin) { 24035c4bbdfSmrg RegionPtr region; 24135c4bbdfSmrg 24235c4bbdfSmrg if (!(region = wClipShape(pSrcWin))) 24335c4bbdfSmrg region = wBoundingShape(pSrcWin); 24435c4bbdfSmrg /* 24535c4bbdfSmrg * If you try to CopyArea the extents of a shaped window, compacting the 24635c4bbdfSmrg * exposed region will undo all our work! 24735c4bbdfSmrg */ 24835c4bbdfSmrg if (extents && pSrcWin && region && 24935c4bbdfSmrg (RegionContainsRect(region, &srcBox) != rgnIN)) 25035c4bbdfSmrg extents = FALSE; 25105b261ecSmrg } 25235c4bbdfSmrg if (extents) { 25335c4bbdfSmrg expBox = *RegionExtents(&rgnExposed); 25435c4bbdfSmrg RegionReset(&rgnExposed, &expBox); 25505b261ecSmrg } 25605b261ecSmrg if ((pDstDrawable->type != DRAWABLE_PIXMAP) && 25735c4bbdfSmrg (((WindowPtr) pDstDrawable)->backgroundState != None)) { 25835c4bbdfSmrg WindowPtr pWin = (WindowPtr) pDstDrawable; 25905b261ecSmrg 26035c4bbdfSmrg /* make the exposed area screen-relative */ 26135c4bbdfSmrg RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y); 26235c4bbdfSmrg 26335c4bbdfSmrg if (extents) { 26435c4bbdfSmrg /* PaintWindow doesn't clip, so we have to */ 26535c4bbdfSmrg RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); 26635c4bbdfSmrg } 26735c4bbdfSmrg pDstDrawable->pScreen->PaintWindow((WindowPtr) pDstDrawable, 26835c4bbdfSmrg &rgnExposed, PW_BACKGROUND); 26935c4bbdfSmrg 27035c4bbdfSmrg if (extents) { 27135c4bbdfSmrg RegionReset(&rgnExposed, &expBox); 27235c4bbdfSmrg } 27335c4bbdfSmrg else 27435c4bbdfSmrg RegionTranslate(&rgnExposed, -pDstDrawable->x, -pDstDrawable->y); 27535c4bbdfSmrg } 27635c4bbdfSmrg if (prgnDstClip == &rgnDstRec) { 27735c4bbdfSmrg RegionUninit(prgnDstClip); 27805b261ecSmrg } 27935c4bbdfSmrg else if (prgnDstClip != prgnSrcClip) { 28035c4bbdfSmrg RegionDestroy(prgnDstClip); 28105b261ecSmrg } 28205b261ecSmrg 28335c4bbdfSmrg if (prgnSrcClip == &rgnSrcRec) { 28435c4bbdfSmrg RegionUninit(prgnSrcClip); 28505b261ecSmrg } 28635c4bbdfSmrg else { 28735c4bbdfSmrg RegionDestroy(prgnSrcClip); 28805b261ecSmrg } 28905b261ecSmrg 29035c4bbdfSmrg if (pGC->graphicsExposures) { 29135c4bbdfSmrg /* don't look */ 29235c4bbdfSmrg RegionPtr exposed = RegionCreate(NullBox, 0); 29305b261ecSmrg 29435c4bbdfSmrg *exposed = rgnExposed; 29535c4bbdfSmrg return exposed; 29605b261ecSmrg } 29735c4bbdfSmrg else { 29835c4bbdfSmrg RegionUninit(&rgnExposed); 29935c4bbdfSmrg return NULL; 30005b261ecSmrg } 30105b261ecSmrg} 30205b261ecSmrg 30305b261ecSmrgvoid 30435c4bbdfSmrgmiSendExposures(WindowPtr pWin, RegionPtr pRgn, int dx, int dy) 30505b261ecSmrg{ 30605b261ecSmrg BoxPtr pBox; 30705b261ecSmrg int numRects; 30805b261ecSmrg xEvent *pEvent, *pe; 30905b261ecSmrg int i; 31005b261ecSmrg 3116747b715Smrg pBox = RegionRects(pRgn); 3126747b715Smrg numRects = RegionNumRects(pRgn); 31335c4bbdfSmrg if (!(pEvent = calloc(1, numRects * sizeof(xEvent)))) 31435c4bbdfSmrg return; 31535c4bbdfSmrg 31635c4bbdfSmrg for (i = numRects, pe = pEvent; --i >= 0; pe++, pBox++) { 31735c4bbdfSmrg pe->u.u.type = Expose; 31835c4bbdfSmrg pe->u.expose.window = pWin->drawable.id; 31935c4bbdfSmrg pe->u.expose.x = pBox->x1 - dx; 32035c4bbdfSmrg pe->u.expose.y = pBox->y1 - dy; 32135c4bbdfSmrg pe->u.expose.width = pBox->x2 - pBox->x1; 32235c4bbdfSmrg pe->u.expose.height = pBox->y2 - pBox->y1; 32335c4bbdfSmrg pe->u.expose.count = i; 32405b261ecSmrg } 32505b261ecSmrg 32605b261ecSmrg#ifdef PANORAMIX 32735c4bbdfSmrg if (!noPanoramiXExtension) { 32835c4bbdfSmrg int scrnum = pWin->drawable.pScreen->myNum; 32935c4bbdfSmrg int x = 0, y = 0; 33035c4bbdfSmrg XID realWin = 0; 33135c4bbdfSmrg 33235c4bbdfSmrg if (!pWin->parent) { 33335c4bbdfSmrg x = screenInfo.screens[scrnum]->x; 33435c4bbdfSmrg y = screenInfo.screens[scrnum]->y; 33535c4bbdfSmrg pWin = screenInfo.screens[0]->root; 33635c4bbdfSmrg realWin = pWin->drawable.id; 33735c4bbdfSmrg } 33835c4bbdfSmrg else if (scrnum) { 33935c4bbdfSmrg PanoramiXRes *win; 34035c4bbdfSmrg 34135c4bbdfSmrg win = PanoramiXFindIDByScrnum(XRT_WINDOW, 34235c4bbdfSmrg pWin->drawable.id, scrnum); 34335c4bbdfSmrg if (!win) { 34435c4bbdfSmrg free(pEvent); 34535c4bbdfSmrg return; 34635c4bbdfSmrg } 34735c4bbdfSmrg realWin = win->info[0].id; 34835c4bbdfSmrg dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess); 34935c4bbdfSmrg } 35035c4bbdfSmrg if (x || y || scrnum) 35135c4bbdfSmrg for (i = 0; i < numRects; i++) { 35235c4bbdfSmrg pEvent[i].u.expose.window = realWin; 35335c4bbdfSmrg pEvent[i].u.expose.x += x; 35435c4bbdfSmrg pEvent[i].u.expose.y += y; 35535c4bbdfSmrg } 35605b261ecSmrg } 35705b261ecSmrg#endif 35805b261ecSmrg 35905b261ecSmrg DeliverEvents(pWin, pEvent, numRects, NullWindow); 36005b261ecSmrg 3616747b715Smrg free(pEvent); 36205b261ecSmrg} 36305b261ecSmrg 3646747b715Smrgvoid 36535c4bbdfSmrgmiWindowExposures(WindowPtr pWin, RegionPtr prgn) 36605b261ecSmrg{ 36735c4bbdfSmrg RegionPtr exposures = prgn; 36835c4bbdfSmrg 36935c4bbdfSmrg if (prgn && !RegionNil(prgn)) { 37035c4bbdfSmrg RegionRec expRec; 37135c4bbdfSmrg int clientInterested = 37235c4bbdfSmrg (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask; 37335c4bbdfSmrg if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT)) { 37435c4bbdfSmrg /* 37535c4bbdfSmrg * If we have LOTS of rectangles, we decide to take the extents 37635c4bbdfSmrg * and force an exposure on that. This should require much less 37735c4bbdfSmrg * work overall, on both client and server. This is cheating, but 37835c4bbdfSmrg * isn't prohibited by the protocol ("spontaneous combustion" :-). 37935c4bbdfSmrg */ 38035c4bbdfSmrg BoxRec box = *RegionExtents(prgn); 38135c4bbdfSmrg exposures = &expRec; 38235c4bbdfSmrg RegionInit(exposures, &box, 1); 38335c4bbdfSmrg RegionReset(prgn, &box); 38435c4bbdfSmrg /* miPaintWindow doesn't clip, so we have to */ 38535c4bbdfSmrg RegionIntersect(prgn, prgn, &pWin->clipList); 38635c4bbdfSmrg } 38735c4bbdfSmrg pWin->drawable.pScreen->PaintWindow(pWin, prgn, PW_BACKGROUND); 38835c4bbdfSmrg if (clientInterested) 38935c4bbdfSmrg miSendExposures(pWin, exposures, 39035c4bbdfSmrg pWin->drawable.x, pWin->drawable.y); 39135c4bbdfSmrg if (exposures == &expRec) 39235c4bbdfSmrg RegionUninit(exposures); 39335c4bbdfSmrg RegionEmpty(prgn); 39405b261ecSmrg } 39505b261ecSmrg} 39605b261ecSmrg 3974642e01fSmrgvoid 3984642e01fSmrgmiPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) 39905b261ecSmrg{ 40035c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 4016747b715Smrg ChangeGCVal gcval[6]; 40235c4bbdfSmrg BITS32 gcmask; 40335c4bbdfSmrg GCPtr pGC; 40435c4bbdfSmrg int i; 40535c4bbdfSmrg BoxPtr pbox; 40635c4bbdfSmrg xRectangle *prect; 407ed6184dfSmrg int numRects, regionnumrects; 40835c4bbdfSmrg 4094642e01fSmrg /* 4104642e01fSmrg * Distance from screen to destination drawable, use this 4114642e01fSmrg * to adjust rendering coordinates which come in in screen space 4124642e01fSmrg */ 41335c4bbdfSmrg int draw_x_off, draw_y_off; 41435c4bbdfSmrg 4154642e01fSmrg /* 4164642e01fSmrg * Tile offset for drawing; these need to align the tile 4174642e01fSmrg * to the appropriate window origin 4184642e01fSmrg */ 41935c4bbdfSmrg int tile_x_off, tile_y_off; 42035c4bbdfSmrg PixUnion fill; 42135c4bbdfSmrg Bool solid = TRUE; 42235c4bbdfSmrg DrawablePtr drawable = &pWin->drawable; 42335c4bbdfSmrg 42435c4bbdfSmrg if (what == PW_BACKGROUND) { 42535c4bbdfSmrg while (pWin->backgroundState == ParentRelative) 42635c4bbdfSmrg pWin = pWin->parent; 42735c4bbdfSmrg 42835c4bbdfSmrg draw_x_off = drawable->x; 42935c4bbdfSmrg draw_y_off = drawable->y; 43035c4bbdfSmrg 43135c4bbdfSmrg tile_x_off = pWin->drawable.x - draw_x_off; 43235c4bbdfSmrg tile_y_off = pWin->drawable.y - draw_y_off; 43335c4bbdfSmrg fill = pWin->background; 43435c4bbdfSmrg#ifdef COMPOSITE 43535c4bbdfSmrg if (pWin->inhibitBGPaint) 43635c4bbdfSmrg return; 4376747b715Smrg#endif 43835c4bbdfSmrg switch (pWin->backgroundState) { 43935c4bbdfSmrg case None: 44035c4bbdfSmrg return; 44135c4bbdfSmrg case BackgroundPixmap: 44235c4bbdfSmrg solid = FALSE; 44335c4bbdfSmrg break; 44435c4bbdfSmrg } 44505b261ecSmrg } 44635c4bbdfSmrg else { 44735c4bbdfSmrg PixmapPtr pixmap; 44835c4bbdfSmrg 44935c4bbdfSmrg fill = pWin->border; 45035c4bbdfSmrg solid = pWin->borderIsPixel; 45135c4bbdfSmrg 45235c4bbdfSmrg /* servers without pixmaps draw their own borders */ 45335c4bbdfSmrg if (!pScreen->GetWindowPixmap) 45435c4bbdfSmrg return; 45535c4bbdfSmrg pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); 45635c4bbdfSmrg drawable = &pixmap->drawable; 45735c4bbdfSmrg 45835c4bbdfSmrg while (pWin->backgroundState == ParentRelative) 45935c4bbdfSmrg pWin = pWin->parent; 46035c4bbdfSmrg 46135c4bbdfSmrg tile_x_off = pWin->drawable.x; 46235c4bbdfSmrg tile_y_off = pWin->drawable.y; 46335c4bbdfSmrg 4644642e01fSmrg#ifdef COMPOSITE 46535c4bbdfSmrg draw_x_off = pixmap->screen_x; 46635c4bbdfSmrg draw_y_off = pixmap->screen_y; 46735c4bbdfSmrg tile_x_off -= draw_x_off; 46835c4bbdfSmrg tile_y_off -= draw_y_off; 4694642e01fSmrg#else 47035c4bbdfSmrg draw_x_off = 0; 47135c4bbdfSmrg draw_y_off = 0; 4724642e01fSmrg#endif 47305b261ecSmrg } 47435c4bbdfSmrg 4754642e01fSmrg gcval[0].val = GXcopy; 4764642e01fSmrg gcmask = GCFunction; 47705b261ecSmrg 4786747b715Smrg#ifdef ROOTLESS_SAFEALPHA 4796747b715Smrg/* Bit mask for alpha channel with a particular number of bits per 4806747b715Smrg * pixel. Note that we only care for 32bpp data. Mac OS X uses planar 4816747b715Smrg * alpha for 16bpp. 4826747b715Smrg */ 4836747b715Smrg#define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0) 4846747b715Smrg#endif 48535c4bbdfSmrg 48635c4bbdfSmrg if (solid) { 4876747b715Smrg#ifdef ROOTLESS_SAFEALPHA 48835c4bbdfSmrg gcval[1].val = 48935c4bbdfSmrg fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); 4906747b715Smrg#else 49135c4bbdfSmrg gcval[1].val = fill.pixel; 4926747b715Smrg#endif 49335c4bbdfSmrg gcval[2].val = FillSolid; 49435c4bbdfSmrg gcmask |= GCForeground | GCFillStyle; 4954642e01fSmrg } 49635c4bbdfSmrg else { 49735c4bbdfSmrg int c = 1; 49835c4bbdfSmrg 4996747b715Smrg#ifdef ROOTLESS_SAFEALPHA 50035c4bbdfSmrg gcval[c++].val = 50135c4bbdfSmrg ((CARD32) -1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel); 50235c4bbdfSmrg gcmask |= GCPlaneMask; 5036747b715Smrg#endif 50435c4bbdfSmrg gcval[c++].val = FillTiled; 50535c4bbdfSmrg gcval[c++].ptr = (void *) fill.pixmap; 50635c4bbdfSmrg gcval[c++].val = tile_x_off; 50735c4bbdfSmrg gcval[c++].val = tile_y_off; 50835c4bbdfSmrg gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; 5094642e01fSmrg } 5104642e01fSmrg 511ed6184dfSmrg regionnumrects = RegionNumRects(prgn); 512ed6184dfSmrg if (regionnumrects == 0) 513ed6184dfSmrg return; 514ed6184dfSmrg prect = xallocarray(regionnumrects, sizeof(xRectangle)); 51505b261ecSmrg if (!prect) 51635c4bbdfSmrg return; 51705b261ecSmrg 5184642e01fSmrg pGC = GetScratchGC(drawable->depth, drawable->pScreen); 51935c4bbdfSmrg if (!pGC) { 52035c4bbdfSmrg free(prect); 52135c4bbdfSmrg return; 52205b261ecSmrg } 52335c4bbdfSmrg 52435c4bbdfSmrg ChangeGC(NullClient, pGC, gcmask, gcval); 52535c4bbdfSmrg ValidateGC(drawable, pGC); 52605b261ecSmrg 5276747b715Smrg numRects = RegionNumRects(prgn); 5286747b715Smrg pbox = RegionRects(prgn); 52935c4bbdfSmrg for (i = numRects; --i >= 0; pbox++, prect++) { 53035c4bbdfSmrg prect->x = pbox->x1 - draw_x_off; 53135c4bbdfSmrg prect->y = pbox->y1 - draw_y_off; 53235c4bbdfSmrg prect->width = pbox->x2 - pbox->x1; 53335c4bbdfSmrg prect->height = pbox->y2 - pbox->y1; 53405b261ecSmrg } 53505b261ecSmrg prect -= numRects; 53635c4bbdfSmrg (*pGC->ops->PolyFillRect) (drawable, pGC, numRects, prect); 5376747b715Smrg free(prect); 53805b261ecSmrg 5394642e01fSmrg FreeScratchGC(pGC); 54005b261ecSmrg} 54105b261ecSmrg 54205b261ecSmrg/* MICLEARDRAWABLE -- sets the entire drawable to the background color of 54335c4bbdfSmrg * the GC. Useful when we have a scratch drawable and need to initialize 54405b261ecSmrg * it. */ 5456747b715Smrgvoid 5464642e01fSmrgmiClearDrawable(DrawablePtr pDraw, GCPtr pGC) 54705b261ecSmrg{ 5486747b715Smrg ChangeGCVal fg, bg; 54905b261ecSmrg xRectangle rect; 55005b261ecSmrg 5516747b715Smrg fg.val = pGC->fgPixel; 5526747b715Smrg bg.val = pGC->bgPixel; 55305b261ecSmrg rect.x = 0; 55405b261ecSmrg rect.y = 0; 55505b261ecSmrg rect.width = pDraw->width; 55605b261ecSmrg rect.height = pDraw->height; 5576747b715Smrg ChangeGC(NullClient, pGC, GCForeground, &bg); 55805b261ecSmrg ValidateGC(pDraw, pGC); 55935c4bbdfSmrg (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect); 5606747b715Smrg ChangeGC(NullClient, pGC, GCForeground, &fg); 56105b261ecSmrg ValidateGC(pDraw, pGC); 56205b261ecSmrg} 563