1706f2543Smrg/*********************************************************** 2706f2543Smrg 3706f2543SmrgCopyright 1987, 1998 The Open Group 4706f2543Smrg 5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its 6706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that 7706f2543Smrgthe above copyright notice appear in all copies and that both that 8706f2543Smrgcopyright notice and this permission notice appear in supporting 9706f2543Smrgdocumentation. 10706f2543Smrg 11706f2543SmrgThe above copyright notice and this permission notice shall be included in 12706f2543Smrgall copies or substantial portions of the Software. 13706f2543Smrg 14706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20706f2543Smrg 21706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be 22706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings 23706f2543Smrgin this Software without prior written authorization from The Open Group. 24706f2543Smrg 25706f2543Smrg 26706f2543SmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 27706f2543Smrg 28706f2543Smrg All Rights Reserved 29706f2543Smrg 30706f2543SmrgPermission to use, copy, modify, and distribute this software and its 31706f2543Smrgdocumentation for any purpose and without fee is hereby granted, 32706f2543Smrgprovided that the above copyright notice appear in all copies and that 33706f2543Smrgboth that copyright notice and this permission notice appear in 34706f2543Smrgsupporting documentation, and that the name of Digital not be 35706f2543Smrgused in advertising or publicity pertaining to distribution of the 36706f2543Smrgsoftware without specific, written prior permission. 37706f2543Smrg 38706f2543SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 39706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 40706f2543SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 41706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 42706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 44706f2543SmrgSOFTWARE. 45706f2543Smrg 46706f2543Smrg******************************************************************/ 47706f2543Smrg/***************************************************************** 48706f2543Smrg 49706f2543SmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 50706f2543Smrg 51706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy 52706f2543Smrgof this software and associated documentation files (the "Software"), to deal 53706f2543Smrgin the Software without restriction, including without limitation the rights 54706f2543Smrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 55706f2543Smrgcopies of the Software. 56706f2543Smrg 57706f2543SmrgThe above copyright notice and this permission notice shall be included in 58706f2543Smrgall copies or substantial portions of the Software. 59706f2543Smrg 60706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 61706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 62706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 63706f2543SmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 64706f2543SmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 65706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 66706f2543SmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 67706f2543Smrg 68706f2543SmrgExcept as contained in this notice, the name of Digital Equipment Corporation 69706f2543Smrgshall not be used in advertising or otherwise to promote the sale, use or other 70706f2543Smrgdealings in this Software without prior written authorization from Digital 71706f2543SmrgEquipment Corporation. 72706f2543Smrg 73706f2543Smrg******************************************************************/ 74706f2543Smrg 75706f2543Smrg 76706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 77706f2543Smrg#include <dix-config.h> 78706f2543Smrg#endif 79706f2543Smrg 80706f2543Smrg#include <X11/X.h> 81706f2543Smrg#include <X11/Xproto.h> 82706f2543Smrg#include <X11/Xprotostr.h> 83706f2543Smrg 84706f2543Smrg#include "misc.h" 85706f2543Smrg#include "regionstr.h" 86706f2543Smrg#include "scrnintstr.h" 87706f2543Smrg#include "gcstruct.h" 88706f2543Smrg#include "windowstr.h" 89706f2543Smrg#include "pixmap.h" 90706f2543Smrg#include "input.h" 91706f2543Smrg 92706f2543Smrg#include "dixstruct.h" 93706f2543Smrg#include "mi.h" 94706f2543Smrg#include <X11/Xmd.h> 95706f2543Smrg 96706f2543Smrg#include "globals.h" 97706f2543Smrg 98706f2543Smrg#ifdef PANORAMIX 99706f2543Smrg#include "panoramiX.h" 100706f2543Smrg#include "panoramiXsrv.h" 101706f2543Smrg#endif 102706f2543Smrg 103706f2543Smrg/* 104706f2543Smrg machine-independent graphics exposure code. any device that uses 105706f2543Smrgthe region package can call this. 106706f2543Smrg*/ 107706f2543Smrg 108706f2543Smrg#ifndef RECTLIMIT 109706f2543Smrg#define RECTLIMIT 25 /* pick a number, any number > 8 */ 110706f2543Smrg#endif 111706f2543Smrg 112706f2543Smrg/* miHandleExposures 113706f2543Smrg generate a region for exposures for areas that were copied from obscured or 114706f2543Smrgnon-existent areas to non-obscured areas of the destination. Paint the 115706f2543Smrgbackground for the region, if the destination is a window. 116706f2543Smrg 117706f2543SmrgNOTE: 118706f2543Smrg this should generally be called, even if graphicsExposures is false, 119706f2543Smrgbecause this is where bits get recovered from backing store. 120706f2543Smrg 121706f2543SmrgNOTE: 122706f2543Smrg added argument 'plane' is used to indicate how exposures from backing 123706f2543Smrgstore should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea 124706f2543Smrgshould be used, else a CopyPlane of the indicated plane will be used. The 125706f2543Smrgexposing is done by the backing store's GraphicsExpose function, of course. 126706f2543Smrg 127706f2543Smrg*/ 128706f2543Smrg 129706f2543SmrgRegionPtr 130706f2543SmrgmiHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, 131706f2543Smrg GCPtr pGC, int srcx, int srcy, int width, int height, 132706f2543Smrg int dstx, int dsty, unsigned long plane) 133706f2543Smrg{ 134706f2543Smrg RegionPtr prgnSrcClip; /* drawable-relative source clip */ 135706f2543Smrg RegionRec rgnSrcRec; 136706f2543Smrg RegionPtr prgnDstClip; /* drawable-relative dest clip */ 137706f2543Smrg RegionRec rgnDstRec; 138706f2543Smrg BoxRec srcBox; /* unclipped source */ 139706f2543Smrg RegionRec rgnExposed; /* exposed region, calculated source- 140706f2543Smrg relative, made dst relative to 141706f2543Smrg intersect with visible parts of 142706f2543Smrg dest and send events to client, 143706f2543Smrg and then screen relative to paint 144706f2543Smrg the window background 145706f2543Smrg */ 146706f2543Smrg WindowPtr pSrcWin; 147706f2543Smrg BoxRec expBox; 148706f2543Smrg Bool extents; 149706f2543Smrg 150706f2543Smrg /* avoid work if we can */ 151706f2543Smrg if (!pGC->graphicsExposures && 152706f2543Smrg (pDstDrawable->type == DRAWABLE_PIXMAP) && 153706f2543Smrg ((pSrcDrawable->type == DRAWABLE_PIXMAP) || 154706f2543Smrg (((WindowPtr)pSrcDrawable)->backStorage == NULL))) 155706f2543Smrg return NULL; 156706f2543Smrg 157706f2543Smrg srcBox.x1 = srcx; 158706f2543Smrg srcBox.y1 = srcy; 159706f2543Smrg srcBox.x2 = srcx+width; 160706f2543Smrg srcBox.y2 = srcy+height; 161706f2543Smrg 162706f2543Smrg if (pSrcDrawable->type != DRAWABLE_PIXMAP) 163706f2543Smrg { 164706f2543Smrg BoxRec TsrcBox; 165706f2543Smrg 166706f2543Smrg TsrcBox.x1 = srcx + pSrcDrawable->x; 167706f2543Smrg TsrcBox.y1 = srcy + pSrcDrawable->y; 168706f2543Smrg TsrcBox.x2 = TsrcBox.x1 + width; 169706f2543Smrg TsrcBox.y2 = TsrcBox.y1 + height; 170706f2543Smrg pSrcWin = (WindowPtr) pSrcDrawable; 171706f2543Smrg if (pGC->subWindowMode == IncludeInferiors) 172706f2543Smrg { 173706f2543Smrg prgnSrcClip = NotClippedByChildren (pSrcWin); 174706f2543Smrg if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) 175706f2543Smrg { 176706f2543Smrg RegionDestroy(prgnSrcClip); 177706f2543Smrg return NULL; 178706f2543Smrg } 179706f2543Smrg } 180706f2543Smrg else 181706f2543Smrg { 182706f2543Smrg if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN) 183706f2543Smrg return NULL; 184706f2543Smrg prgnSrcClip = &rgnSrcRec; 185706f2543Smrg RegionNull(prgnSrcClip); 186706f2543Smrg RegionCopy(prgnSrcClip, &pSrcWin->clipList); 187706f2543Smrg } 188706f2543Smrg RegionTranslate(prgnSrcClip, 189706f2543Smrg -pSrcDrawable->x, -pSrcDrawable->y); 190706f2543Smrg } 191706f2543Smrg else 192706f2543Smrg { 193706f2543Smrg BoxRec box; 194706f2543Smrg 195706f2543Smrg if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && 196706f2543Smrg (srcBox.x2 <= pSrcDrawable->width) && 197706f2543Smrg (srcBox.y2 <= pSrcDrawable->height)) 198706f2543Smrg return NULL; 199706f2543Smrg 200706f2543Smrg box.x1 = 0; 201706f2543Smrg box.y1 = 0; 202706f2543Smrg box.x2 = pSrcDrawable->width; 203706f2543Smrg box.y2 = pSrcDrawable->height; 204706f2543Smrg prgnSrcClip = &rgnSrcRec; 205706f2543Smrg RegionInit(prgnSrcClip, &box, 1); 206706f2543Smrg pSrcWin = NULL; 207706f2543Smrg } 208706f2543Smrg 209706f2543Smrg if (pDstDrawable == pSrcDrawable) 210706f2543Smrg { 211706f2543Smrg prgnDstClip = prgnSrcClip; 212706f2543Smrg } 213706f2543Smrg else if (pDstDrawable->type != DRAWABLE_PIXMAP) 214706f2543Smrg { 215706f2543Smrg if (pGC->subWindowMode == IncludeInferiors) 216706f2543Smrg { 217706f2543Smrg prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable); 218706f2543Smrg } 219706f2543Smrg else 220706f2543Smrg { 221706f2543Smrg prgnDstClip = &rgnDstRec; 222706f2543Smrg RegionNull(prgnDstClip); 223706f2543Smrg RegionCopy(prgnDstClip, 224706f2543Smrg &((WindowPtr)pDstDrawable)->clipList); 225706f2543Smrg } 226706f2543Smrg RegionTranslate(prgnDstClip, 227706f2543Smrg -pDstDrawable->x, -pDstDrawable->y); 228706f2543Smrg } 229706f2543Smrg else 230706f2543Smrg { 231706f2543Smrg BoxRec box; 232706f2543Smrg 233706f2543Smrg box.x1 = 0; 234706f2543Smrg box.y1 = 0; 235706f2543Smrg box.x2 = pDstDrawable->width; 236706f2543Smrg box.y2 = pDstDrawable->height; 237706f2543Smrg prgnDstClip = &rgnDstRec; 238706f2543Smrg RegionInit(prgnDstClip, &box, 1); 239706f2543Smrg } 240706f2543Smrg 241706f2543Smrg /* drawable-relative source region */ 242706f2543Smrg RegionInit(&rgnExposed, &srcBox, 1); 243706f2543Smrg 244706f2543Smrg /* now get the hidden parts of the source box*/ 245706f2543Smrg RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip); 246706f2543Smrg 247706f2543Smrg /* move them over the destination */ 248706f2543Smrg RegionTranslate(&rgnExposed, dstx-srcx, dsty-srcy); 249706f2543Smrg 250706f2543Smrg /* intersect with visible areas of dest */ 251706f2543Smrg RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip); 252706f2543Smrg 253706f2543Smrg /* intersect with client clip region. */ 254706f2543Smrg if (pGC->clientClipType == CT_REGION) 255706f2543Smrg RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); 256706f2543Smrg 257706f2543Smrg /* 258706f2543Smrg * If we have LOTS of rectangles, we decide to take the extents 259706f2543Smrg * and force an exposure on that. This should require much less 260706f2543Smrg * work overall, on both client and server. This is cheating, but 261706f2543Smrg * isn't prohibited by the protocol ("spontaneous combustion" :-) 262706f2543Smrg * for windows. 263706f2543Smrg */ 264706f2543Smrg extents = pGC->graphicsExposures && 265706f2543Smrg (RegionNumRects(&rgnExposed) > RECTLIMIT) && 266706f2543Smrg (pDstDrawable->type != DRAWABLE_PIXMAP); 267706f2543Smrg if (pSrcWin) 268706f2543Smrg { 269706f2543Smrg RegionPtr region; 270706f2543Smrg if (!(region = wClipShape (pSrcWin))) 271706f2543Smrg region = wBoundingShape (pSrcWin); 272706f2543Smrg /* 273706f2543Smrg * If you try to CopyArea the extents of a shaped window, compacting the 274706f2543Smrg * exposed region will undo all our work! 275706f2543Smrg */ 276706f2543Smrg if (extents && pSrcWin && region && 277706f2543Smrg (RegionContainsRect(region, &srcBox) != rgnIN)) 278706f2543Smrg extents = FALSE; 279706f2543Smrg } 280706f2543Smrg if (extents) 281706f2543Smrg { 282706f2543Smrg expBox = *RegionExtents(&rgnExposed); 283706f2543Smrg RegionReset(&rgnExposed, &expBox); 284706f2543Smrg } 285706f2543Smrg if ((pDstDrawable->type != DRAWABLE_PIXMAP) && 286706f2543Smrg (((WindowPtr)pDstDrawable)->backgroundState != None)) 287706f2543Smrg { 288706f2543Smrg WindowPtr pWin = (WindowPtr)pDstDrawable; 289706f2543Smrg 290706f2543Smrg /* make the exposed area screen-relative */ 291706f2543Smrg RegionTranslate(&rgnExposed, 292706f2543Smrg pDstDrawable->x, pDstDrawable->y); 293706f2543Smrg 294706f2543Smrg if (extents) 295706f2543Smrg { 296706f2543Smrg /* miPaintWindow doesn't clip, so we have to */ 297706f2543Smrg RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); 298706f2543Smrg } 299706f2543Smrg miPaintWindow((WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND); 300706f2543Smrg 301706f2543Smrg if (extents) 302706f2543Smrg { 303706f2543Smrg RegionReset(&rgnExposed, &expBox); 304706f2543Smrg } 305706f2543Smrg else 306706f2543Smrg RegionTranslate(&rgnExposed, 307706f2543Smrg -pDstDrawable->x, -pDstDrawable->y); 308706f2543Smrg } 309706f2543Smrg if (prgnDstClip == &rgnDstRec) 310706f2543Smrg { 311706f2543Smrg RegionUninit(prgnDstClip); 312706f2543Smrg } 313706f2543Smrg else if (prgnDstClip != prgnSrcClip) 314706f2543Smrg { 315706f2543Smrg RegionDestroy(prgnDstClip); 316706f2543Smrg } 317706f2543Smrg 318706f2543Smrg if (prgnSrcClip == &rgnSrcRec) 319706f2543Smrg { 320706f2543Smrg RegionUninit(prgnSrcClip); 321706f2543Smrg } 322706f2543Smrg else 323706f2543Smrg { 324706f2543Smrg RegionDestroy(prgnSrcClip); 325706f2543Smrg } 326706f2543Smrg 327706f2543Smrg if (pGC->graphicsExposures) 328706f2543Smrg { 329706f2543Smrg /* don't look */ 330706f2543Smrg RegionPtr exposed = RegionCreate(NullBox, 0); 331706f2543Smrg *exposed = rgnExposed; 332706f2543Smrg return exposed; 333706f2543Smrg } 334706f2543Smrg else 335706f2543Smrg { 336706f2543Smrg RegionUninit(&rgnExposed); 337706f2543Smrg return NULL; 338706f2543Smrg } 339706f2543Smrg} 340706f2543Smrg 341706f2543Smrg/* send GraphicsExpose events, or a NoExpose event, based on the region */ 342706f2543Smrg 343706f2543Smrgvoid 344706f2543SmrgmiSendGraphicsExpose (ClientPtr client, RegionPtr pRgn, XID drawable, 345706f2543Smrg int major, int minor) 346706f2543Smrg{ 347706f2543Smrg if (pRgn && !RegionNil(pRgn)) 348706f2543Smrg { 349706f2543Smrg xEvent *pEvent; 350706f2543Smrg xEvent *pe; 351706f2543Smrg BoxPtr pBox; 352706f2543Smrg int i; 353706f2543Smrg int numRects; 354706f2543Smrg 355706f2543Smrg numRects = RegionNumRects(pRgn); 356706f2543Smrg pBox = RegionRects(pRgn); 357706f2543Smrg if(!(pEvent = malloc(numRects * sizeof(xEvent)))) 358706f2543Smrg return; 359706f2543Smrg pe = pEvent; 360706f2543Smrg 361706f2543Smrg for (i=1; i<=numRects; i++, pe++, pBox++) 362706f2543Smrg { 363706f2543Smrg pe->u.u.type = GraphicsExpose; 364706f2543Smrg pe->u.graphicsExposure.drawable = drawable; 365706f2543Smrg pe->u.graphicsExposure.x = pBox->x1; 366706f2543Smrg pe->u.graphicsExposure.y = pBox->y1; 367706f2543Smrg pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; 368706f2543Smrg pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; 369706f2543Smrg pe->u.graphicsExposure.count = numRects - i; 370706f2543Smrg pe->u.graphicsExposure.majorEvent = major; 371706f2543Smrg pe->u.graphicsExposure.minorEvent = minor; 372706f2543Smrg } 373706f2543Smrg /* GraphicsExpose is a "critical event", which TryClientEvents 374706f2543Smrg * handles specially. */ 375706f2543Smrg TryClientEvents(client, NULL, pEvent, numRects, 376706f2543Smrg (Mask)0, NoEventMask, NullGrab); 377706f2543Smrg free(pEvent); 378706f2543Smrg } 379706f2543Smrg else 380706f2543Smrg { 381706f2543Smrg xEvent event; 382706f2543Smrg memset(&event, 0, sizeof(xEvent)); 383706f2543Smrg event.u.u.type = NoExpose; 384706f2543Smrg event.u.noExposure.drawable = drawable; 385706f2543Smrg event.u.noExposure.majorEvent = major; 386706f2543Smrg event.u.noExposure.minorEvent = minor; 387706f2543Smrg WriteEventsToClient(client, 1, &event); 388706f2543Smrg } 389706f2543Smrg} 390706f2543Smrg 391706f2543Smrg 392706f2543Smrgvoid 393706f2543SmrgmiSendExposures( WindowPtr pWin, RegionPtr pRgn, int dx, int dy) 394706f2543Smrg{ 395706f2543Smrg BoxPtr pBox; 396706f2543Smrg int numRects; 397706f2543Smrg xEvent *pEvent, *pe; 398706f2543Smrg int i; 399706f2543Smrg 400706f2543Smrg pBox = RegionRects(pRgn); 401706f2543Smrg numRects = RegionNumRects(pRgn); 402706f2543Smrg if(!(pEvent = calloc(1, numRects * sizeof(xEvent)))) 403706f2543Smrg return; 404706f2543Smrg 405706f2543Smrg for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++) 406706f2543Smrg { 407706f2543Smrg pe->u.u.type = Expose; 408706f2543Smrg pe->u.expose.window = pWin->drawable.id; 409706f2543Smrg pe->u.expose.x = pBox->x1 - dx; 410706f2543Smrg pe->u.expose.y = pBox->y1 - dy; 411706f2543Smrg pe->u.expose.width = pBox->x2 - pBox->x1; 412706f2543Smrg pe->u.expose.height = pBox->y2 - pBox->y1; 413706f2543Smrg pe->u.expose.count = i; 414706f2543Smrg } 415706f2543Smrg 416706f2543Smrg#ifdef PANORAMIX 417706f2543Smrg if(!noPanoramiXExtension) { 418706f2543Smrg int scrnum = pWin->drawable.pScreen->myNum; 419706f2543Smrg int x = 0, y = 0; 420706f2543Smrg XID realWin = 0; 421706f2543Smrg 422706f2543Smrg if(!pWin->parent) { 423706f2543Smrg x = screenInfo.screens[scrnum]->x; 424706f2543Smrg y = screenInfo.screens[scrnum]->y; 425706f2543Smrg pWin = screenInfo.screens[0]->root; 426706f2543Smrg realWin = pWin->drawable.id; 427706f2543Smrg } else if (scrnum) { 428706f2543Smrg PanoramiXRes *win; 429706f2543Smrg win = PanoramiXFindIDByScrnum(XRT_WINDOW, 430706f2543Smrg pWin->drawable.id, scrnum); 431706f2543Smrg if(!win) { 432706f2543Smrg free(pEvent); 433706f2543Smrg return; 434706f2543Smrg } 435706f2543Smrg realWin = win->info[0].id; 436706f2543Smrg dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess); 437706f2543Smrg } 438706f2543Smrg if(x || y || scrnum) 439706f2543Smrg for (i = 0; i < numRects; i++) { 440706f2543Smrg pEvent[i].u.expose.window = realWin; 441706f2543Smrg pEvent[i].u.expose.x += x; 442706f2543Smrg pEvent[i].u.expose.y += y; 443706f2543Smrg } 444706f2543Smrg } 445706f2543Smrg#endif 446706f2543Smrg 447706f2543Smrg DeliverEvents(pWin, pEvent, numRects, NullWindow); 448706f2543Smrg 449706f2543Smrg free(pEvent); 450706f2543Smrg} 451706f2543Smrg 452706f2543Smrgvoid 453706f2543SmrgmiWindowExposures( WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed) 454706f2543Smrg{ 455706f2543Smrg RegionPtr exposures = prgn; 456706f2543Smrg if ((prgn && !RegionNil(prgn)) || 457706f2543Smrg (exposures && !RegionNil(exposures)) || other_exposed) 458706f2543Smrg { 459706f2543Smrg RegionRec expRec; 460706f2543Smrg int clientInterested; 461706f2543Smrg 462706f2543Smrg /* 463706f2543Smrg * Restore from backing-store FIRST. 464706f2543Smrg */ 465706f2543Smrg clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask; 466706f2543Smrg if (other_exposed) 467706f2543Smrg { 468706f2543Smrg if (exposures) 469706f2543Smrg { 470706f2543Smrg RegionUnion(other_exposed, 471706f2543Smrg exposures, 472706f2543Smrg other_exposed); 473706f2543Smrg if (exposures != prgn) 474706f2543Smrg RegionDestroy(exposures); 475706f2543Smrg } 476706f2543Smrg exposures = other_exposed; 477706f2543Smrg } 478706f2543Smrg if (clientInterested && exposures && (RegionNumRects(exposures) > RECTLIMIT)) 479706f2543Smrg { 480706f2543Smrg /* 481706f2543Smrg * If we have LOTS of rectangles, we decide to take the extents 482706f2543Smrg * and force an exposure on that. This should require much less 483706f2543Smrg * work overall, on both client and server. This is cheating, but 484706f2543Smrg * isn't prohibited by the protocol ("spontaneous combustion" :-). 485706f2543Smrg */ 486706f2543Smrg BoxRec box; 487706f2543Smrg 488706f2543Smrg box = *RegionExtents(exposures); 489706f2543Smrg if (exposures == prgn) { 490706f2543Smrg exposures = &expRec; 491706f2543Smrg RegionInit(exposures, &box, 1); 492706f2543Smrg RegionReset(prgn, &box); 493706f2543Smrg } else { 494706f2543Smrg RegionReset(exposures, &box); 495706f2543Smrg RegionUnion(prgn, prgn, exposures); 496706f2543Smrg } 497706f2543Smrg /* miPaintWindow doesn't clip, so we have to */ 498706f2543Smrg RegionIntersect(prgn, prgn, &pWin->clipList); 499706f2543Smrg } 500706f2543Smrg if (prgn && !RegionNil(prgn)) 501706f2543Smrg miPaintWindow(pWin, prgn, PW_BACKGROUND); 502706f2543Smrg if (clientInterested && exposures && !RegionNil(exposures)) 503706f2543Smrg miSendExposures(pWin, exposures, 504706f2543Smrg pWin->drawable.x, pWin->drawable.y); 505706f2543Smrg if (exposures == &expRec) 506706f2543Smrg { 507706f2543Smrg RegionUninit(exposures); 508706f2543Smrg } 509706f2543Smrg else if (exposures && exposures != prgn && exposures != other_exposed) 510706f2543Smrg RegionDestroy(exposures); 511706f2543Smrg if (prgn) 512706f2543Smrg RegionEmpty(prgn); 513706f2543Smrg } 514706f2543Smrg else if (exposures && exposures != prgn) 515706f2543Smrg RegionDestroy(exposures); 516706f2543Smrg} 517706f2543Smrg 518706f2543Smrg#ifdef ROOTLESS 519706f2543Smrg/* Ugly, ugly, but we lost our hooks into miPaintWindow... =/ */ 520706f2543Smrgvoid RootlessSetPixmapOfAncestors(WindowPtr pWin); 521706f2543Smrgvoid RootlessStartDrawing(WindowPtr pWin); 522706f2543Smrgvoid RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn); 523706f2543SmrgBool IsFramedWindow(WindowPtr pWin); 524706f2543Smrg#endif 525706f2543Smrg 526706f2543Smrgvoid 527706f2543SmrgmiPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) 528706f2543Smrg{ 529706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 530706f2543Smrg ChangeGCVal gcval[6]; 531706f2543Smrg BITS32 gcmask; 532706f2543Smrg GCPtr pGC; 533706f2543Smrg int i; 534706f2543Smrg BoxPtr pbox; 535706f2543Smrg xRectangle *prect; 536706f2543Smrg int numRects; 537706f2543Smrg /* 538706f2543Smrg * Distance from screen to destination drawable, use this 539706f2543Smrg * to adjust rendering coordinates which come in in screen space 540706f2543Smrg */ 541706f2543Smrg int draw_x_off, draw_y_off; 542706f2543Smrg /* 543706f2543Smrg * Tile offset for drawing; these need to align the tile 544706f2543Smrg * to the appropriate window origin 545706f2543Smrg */ 546706f2543Smrg int tile_x_off, tile_y_off; 547706f2543Smrg PixUnion fill; 548706f2543Smrg Bool solid = TRUE; 549706f2543Smrg DrawablePtr drawable = &pWin->drawable; 550706f2543Smrg 551706f2543Smrg#ifdef ROOTLESS 552706f2543Smrg if(!drawable || drawable->type == UNDRAWABLE_WINDOW) 553706f2543Smrg return; 554706f2543Smrg 555706f2543Smrg if(IsFramedWindow(pWin)) { 556706f2543Smrg RootlessStartDrawing(pWin); 557706f2543Smrg RootlessDamageRegion(pWin, prgn); 558706f2543Smrg 559706f2543Smrg if(pWin->backgroundState == ParentRelative) { 560706f2543Smrg if((what == PW_BACKGROUND) || 561706f2543Smrg (what == PW_BORDER && !pWin->borderIsPixel)) 562706f2543Smrg RootlessSetPixmapOfAncestors(pWin); 563706f2543Smrg } 564706f2543Smrg } 565706f2543Smrg#endif 566706f2543Smrg 567706f2543Smrg if (what == PW_BACKGROUND) 568706f2543Smrg { 569706f2543Smrg while (pWin->backgroundState == ParentRelative) 570706f2543Smrg pWin = pWin->parent; 571706f2543Smrg 572706f2543Smrg draw_x_off = drawable->x; 573706f2543Smrg draw_y_off = drawable->y; 574706f2543Smrg 575706f2543Smrg tile_x_off = pWin->drawable.x - draw_x_off; 576706f2543Smrg tile_y_off = pWin->drawable.y - draw_y_off; 577706f2543Smrg fill = pWin->background; 578706f2543Smrg switch (pWin->backgroundState) { 579706f2543Smrg case None: 580706f2543Smrg return; 581706f2543Smrg case BackgroundPixmap: 582706f2543Smrg solid = FALSE; 583706f2543Smrg break; 584706f2543Smrg } 585706f2543Smrg } 586706f2543Smrg else 587706f2543Smrg { 588706f2543Smrg PixmapPtr pixmap; 589706f2543Smrg 590706f2543Smrg tile_x_off = drawable->x; 591706f2543Smrg tile_y_off = drawable->y; 592706f2543Smrg 593706f2543Smrg /* servers without pixmaps draw their own borders */ 594706f2543Smrg if (!pScreen->GetWindowPixmap) 595706f2543Smrg return; 596706f2543Smrg pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); 597706f2543Smrg drawable = &pixmap->drawable; 598706f2543Smrg#ifdef COMPOSITE 599706f2543Smrg draw_x_off = pixmap->screen_x; 600706f2543Smrg draw_y_off = pixmap->screen_y; 601706f2543Smrg tile_x_off -= draw_x_off; 602706f2543Smrg tile_y_off -= draw_y_off; 603706f2543Smrg#else 604706f2543Smrg draw_x_off = 0; 605706f2543Smrg draw_y_off = 0; 606706f2543Smrg#endif 607706f2543Smrg fill = pWin->border; 608706f2543Smrg solid = pWin->borderIsPixel; 609706f2543Smrg } 610706f2543Smrg 611706f2543Smrg gcval[0].val = GXcopy; 612706f2543Smrg gcmask = GCFunction; 613706f2543Smrg 614706f2543Smrg#ifdef ROOTLESS_SAFEALPHA 615706f2543Smrg/* Bit mask for alpha channel with a particular number of bits per 616706f2543Smrg * pixel. Note that we only care for 32bpp data. Mac OS X uses planar 617706f2543Smrg * alpha for 16bpp. 618706f2543Smrg */ 619706f2543Smrg#define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0) 620706f2543Smrg#endif 621706f2543Smrg 622706f2543Smrg if (solid) 623706f2543Smrg { 624706f2543Smrg#ifdef ROOTLESS_SAFEALPHA 625706f2543Smrg gcval[1].val = fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); 626706f2543Smrg#else 627706f2543Smrg gcval[1].val = fill.pixel; 628706f2543Smrg#endif 629706f2543Smrg gcval[2].val = FillSolid; 630706f2543Smrg gcmask |= GCForeground | GCFillStyle; 631706f2543Smrg } 632706f2543Smrg else 633706f2543Smrg { 634706f2543Smrg int c=1; 635706f2543Smrg#ifdef ROOTLESS_SAFEALPHA 636706f2543Smrg gcval[c++].val = ((CARD32)-1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel); 637706f2543Smrg gcmask |= GCPlaneMask; 638706f2543Smrg#endif 639706f2543Smrg gcval[c++].val = FillTiled; 640706f2543Smrg gcval[c++].ptr = (pointer)fill.pixmap; 641706f2543Smrg gcval[c++].val = tile_x_off; 642706f2543Smrg gcval[c++].val = tile_y_off; 643706f2543Smrg gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; 644706f2543Smrg } 645706f2543Smrg 646706f2543Smrg prect = malloc(RegionNumRects(prgn) * sizeof(xRectangle)); 647706f2543Smrg if (!prect) 648706f2543Smrg return; 649706f2543Smrg 650706f2543Smrg pGC = GetScratchGC(drawable->depth, drawable->pScreen); 651706f2543Smrg if (!pGC) 652706f2543Smrg { 653706f2543Smrg free(prect); 654706f2543Smrg return; 655706f2543Smrg } 656706f2543Smrg 657706f2543Smrg ChangeGC (NullClient, pGC, gcmask, gcval); 658706f2543Smrg ValidateGC (drawable, pGC); 659706f2543Smrg 660706f2543Smrg numRects = RegionNumRects(prgn); 661706f2543Smrg pbox = RegionRects(prgn); 662706f2543Smrg for (i= numRects; --i >= 0; pbox++, prect++) 663706f2543Smrg { 664706f2543Smrg prect->x = pbox->x1 - draw_x_off; 665706f2543Smrg prect->y = pbox->y1 - draw_y_off; 666706f2543Smrg prect->width = pbox->x2 - pbox->x1; 667706f2543Smrg prect->height = pbox->y2 - pbox->y1; 668706f2543Smrg } 669706f2543Smrg prect -= numRects; 670706f2543Smrg (*pGC->ops->PolyFillRect)(drawable, pGC, numRects, prect); 671706f2543Smrg free(prect); 672706f2543Smrg 673706f2543Smrg FreeScratchGC(pGC); 674706f2543Smrg} 675706f2543Smrg 676706f2543Smrg 677706f2543Smrg/* MICLEARDRAWABLE -- sets the entire drawable to the background color of 678706f2543Smrg * the GC. Useful when we have a scratch drawable and need to initialize 679706f2543Smrg * it. */ 680706f2543Smrgvoid 681706f2543SmrgmiClearDrawable(DrawablePtr pDraw, GCPtr pGC) 682706f2543Smrg{ 683706f2543Smrg ChangeGCVal fg, bg; 684706f2543Smrg xRectangle rect; 685706f2543Smrg 686706f2543Smrg fg.val = pGC->fgPixel; 687706f2543Smrg bg.val = pGC->bgPixel; 688706f2543Smrg rect.x = 0; 689706f2543Smrg rect.y = 0; 690706f2543Smrg rect.width = pDraw->width; 691706f2543Smrg rect.height = pDraw->height; 692706f2543Smrg ChangeGC(NullClient, pGC, GCForeground, &bg); 693706f2543Smrg ValidateGC(pDraw, pGC); 694706f2543Smrg (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect); 695706f2543Smrg ChangeGC(NullClient, pGC, GCForeground, &fg); 696706f2543Smrg ValidateGC(pDraw, pGC); 697706f2543Smrg} 698