|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 4: ! 5: All Rights Reserved ! 6: ! 7: Permission to use, copy, modify, and distribute this software and its ! 8: documentation for any purpose and without fee is hereby granted, ! 9: provided that the above copyright notice appear in all copies and that ! 10: both that copyright notice and this permission notice appear in ! 11: supporting documentation, and that the names of Digital or MIT not be ! 12: used in advertising or publicity pertaining to distribution of the ! 13: software without specific, written prior permission. ! 14: ! 15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 21: SOFTWARE. ! 22: ! 23: ******************************************************************/ ! 24: ! 25: /* $Header: miexpose.c,v 1.25 87/09/11 07:19:01 toddb Exp $ */ ! 26: ! 27: #include "X.h" ! 28: #define NEED_EVENTS ! 29: #include "Xproto.h" ! 30: #include "Xprotostr.h" ! 31: ! 32: #include "misc.h" ! 33: #include "regionstr.h" ! 34: #include "scrnintstr.h" ! 35: #include "gcstruct.h" ! 36: #include "windowstr.h" ! 37: #include "pixmap.h" ! 38: ! 39: #include "dixstruct.h" ! 40: #include "mi.h" ! 41: #include "Xmd.h" ! 42: ! 43: extern WindowRec WindowTable[]; ! 44: ! 45: /* ! 46: machine-independent graphics exposure code. any device that uses ! 47: the region package can call this. ! 48: */ ! 49: ! 50: ! 51: /* miHandleExposures ! 52: generate exposures for areas that were copied from obscured or ! 53: non-existent areas to non-obscured areas of the destination. ! 54: ! 55: NOTE: ! 56: this code sends the exposure events, then paints the background. ! 57: this will NOT work unless this routine is allowed to complete before ! 58: the dispatcher looks at this client again. ! 59: ! 60: NOTE: ! 61: this does not deal with backing store. ! 62: */ ! 63: ! 64: void ! 65: miHandleExposures(pSrcDrawable, pDstDrawable, ! 66: pGC, srcx, srcy, width, height, dstx, dsty) ! 67: register DrawablePtr pSrcDrawable; ! 68: register DrawablePtr pDstDrawable; ! 69: GCPtr pGC; ! 70: int srcx, srcy; ! 71: int width, height; ! 72: int dstx, dsty; ! 73: { ! 74: register ScreenPtr pscr = pGC->pScreen; ! 75: RegionPtr prgnSrcClip; /* drawable-relative source clip */ ! 76: RegionPtr prgnDstClip; /* drawable-relative dest clip */ ! 77: BoxRec srcBox; /* unclipped source */ ! 78: RegionPtr prgnSrc; /* clipped source */ ! 79: RegionPtr prgnExposed; /* exposed region, calculated source- ! 80: relative, made dst relative to ! 81: intersect with visible parts of ! 82: dest and send events to client, ! 83: and then screen relative to paint ! 84: the window background ! 85: */ ! 86: ! 87: if (pSrcDrawable->type == DRAWABLE_WINDOW) ! 88: { ! 89: prgnSrcClip = (*pscr->RegionCreate)(NullBox, 1); ! 90: (*pscr->RegionCopy)(prgnSrcClip, ! 91: ((WindowPtr)pSrcDrawable)->clipList); ! 92: (*pscr->TranslateRegion)(prgnSrcClip, ! 93: -((WindowPtr)pSrcDrawable)->absCorner.x, ! 94: -((WindowPtr)pSrcDrawable)->absCorner.y); ! 95: } ! 96: else ! 97: { ! 98: BoxRec box; ! 99: ! 100: box.x1 = 0; ! 101: box.y1 = 0; ! 102: box.x2 = ((PixmapPtr)pSrcDrawable)->width; ! 103: box.y2 = ((PixmapPtr)pSrcDrawable)->height; ! 104: prgnSrcClip = (*pscr->RegionCreate)(&box, 1); ! 105: } ! 106: ! 107: if (pDstDrawable->type == DRAWABLE_WINDOW) ! 108: { ! 109: prgnDstClip = (*pscr->RegionCreate)(NullBox, 1); ! 110: (*pscr->RegionCopy)(prgnDstClip, ! 111: ((WindowPtr)pDstDrawable)->clipList); ! 112: (*pscr->TranslateRegion)(prgnDstClip, ! 113: -((WindowPtr)pDstDrawable)->absCorner.x, ! 114: -((WindowPtr)pDstDrawable)->absCorner.y); ! 115: } ! 116: else ! 117: { ! 118: BoxRec box; ! 119: ! 120: box.x1 = 0; ! 121: box.y1 = 0; ! 122: box.x2 = ((PixmapPtr)pDstDrawable)->width; ! 123: box.y2 = ((PixmapPtr)pDstDrawable)->height; ! 124: prgnDstClip = (*pscr->RegionCreate)(&box, 1); ! 125: } ! 126: ! 127: /* drawable-relative source region */ ! 128: srcBox.x1 = srcx; ! 129: srcBox.y1 = srcy; ! 130: srcBox.x2 = srcx+width; ! 131: srcBox.y2 = srcy+height; ! 132: prgnSrc = (*pscr->RegionCreate)(&srcBox, 1); ! 133: ! 134: /* get the visible parts of the source box */ ! 135: (*pscr->Intersect)(prgnSrc, prgnSrc, prgnSrcClip); ! 136: ! 137: /* now get the hidden parts */ ! 138: prgnExposed = (*pscr->RegionCreate)(NullBox, 1); ! 139: (*pscr->Inverse)(prgnExposed, prgnSrc, &srcBox); ! 140: ! 141: /* move them over the destination */ ! 142: (*pscr->TranslateRegion)(prgnExposed, dstx-srcx, dsty-srcy); ! 143: ! 144: /* intersect with visible areas of dest */ ! 145: (*pscr->Intersect)(prgnExposed, prgnExposed, prgnDstClip); ! 146: ! 147: /* send them to the client */ ! 148: if (pGC->graphicsExposures) ! 149: { ! 150: if (REGION_NOT_EMPTY(prgnExposed)) ! 151: { ! 152: xEvent *pEvent; ! 153: register xEvent *pe; ! 154: register BoxPtr pBox = prgnExposed->rects; ! 155: register int i; ! 156: ! 157: if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(prgnExposed->numRects * ! 158: sizeof(xEvent)))) ! 159: return; ! 160: pe = pEvent; ! 161: ! 162: for (i=1; i<=prgnExposed->numRects; i++, pe++, pBox++) ! 163: { ! 164: pe->u.u.type = GraphicsExpose; ! 165: pe->u.graphicsExposure.drawable = ! 166: requestingClient->lastDrawableID; ! 167: pe->u.graphicsExposure.x = pBox->x1; ! 168: pe->u.graphicsExposure.y = pBox->y1; ! 169: pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; ! 170: pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; ! 171: pe->u.graphicsExposure.count = prgnExposed->numRects - i; ! 172: ! 173: } ! 174: TryClientEvents(requestingClient, pEvent, prgnExposed->numRects, ! 175: 0, NoEventMask, 0); ! 176: DEALLOCATE_LOCAL(pEvent); ! 177: } ! 178: else ! 179: { ! 180: xEvent event; ! 181: event.u.u.type = NoExpose; ! 182: event.u.noExposure.drawable = requestingClient->lastDrawableID; ! 183: TryClientEvents(requestingClient, &event, 1, ! 184: 0, NoEventMask, 0); ! 185: } ! 186: } ! 187: ! 188: ! 189: if ((pDstDrawable->type == DRAWABLE_WINDOW) && ! 190: (((WindowPtr)pDstDrawable)->backgroundTile != None)) ! 191: { ! 192: WindowPtr pWin = (WindowPtr)pDstDrawable; ! 193: ! 194: /* make the exposed area screen-relative */ ! 195: (*pscr->TranslateRegion)(prgnExposed, ! 196: pWin->absCorner.x, pWin->absCorner.y); ! 197: ! 198: (*pWin->PaintWindowBackground)(pDstDrawable, prgnExposed, ! 199: PW_BACKGROUND); ! 200: } ! 201: (*pscr->RegionDestroy)(prgnDstClip); ! 202: (*pscr->RegionDestroy)(prgnSrcClip); ! 203: (*pscr->RegionDestroy)(prgnSrc); ! 204: (*pscr->RegionDestroy)(prgnExposed); ! 205: } ! 206: ! 207: void ! 208: miSendNoExpose(pGC) ! 209: GCPtr pGC; ! 210: { ! 211: if (pGC->graphicsExposures) ! 212: { ! 213: xEvent event; ! 214: event.u.u.type = NoExpose; ! 215: event.u.noExposure.drawable = ! 216: requestingClient->lastDrawableID; ! 217: TryClientEvents(requestingClient, &event, 1, ! 218: 0, NoEventMask, 0); ! 219: } ! 220: } ! 221: ! 222: ! 223: void ! 224: miWindowExposures(pWin) ! 225: WindowPtr pWin; ! 226: { ! 227: register RegionPtr prgn; ! 228: ! 229: prgn = pWin->exposed; ! 230: if (prgn->numRects) ! 231: { ! 232: xEvent *pEvent; ! 233: register xEvent *pe; ! 234: register BoxPtr pBox; ! 235: register int i; ! 236: ! 237: (*pWin->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND); ! 238: (* pWin->drawable.pScreen->TranslateRegion)(prgn, ! 239: -pWin->absCorner.x, -pWin->absCorner.y); ! 240: if (pWin->backingStore != NotUseful && pWin->backStorage) ! 241: { ! 242: /* modifies pWin->exposed */ ! 243: (*pWin->backStorage->RestoreAreas)(pWin); ! 244: } ! 245: pBox = prgn->rects; ! 246: ! 247: if(!(pEvent = (xEvent *) ! 248: ALLOCATE_LOCAL(prgn->numRects * sizeof(xEvent)))) ! 249: return; ! 250: pe = pEvent; ! 251: ! 252: for (i=1; i<=prgn->numRects; i++, pe++, pBox++) ! 253: { ! 254: pe->u.u.type = Expose; ! 255: pe->u.expose.window = pWin->wid; ! 256: pe->u.expose.x = pBox->x1; ! 257: pe->u.expose.y = pBox->y1; ! 258: pe->u.expose.width = pBox->x2 - pBox->x1; ! 259: pe->u.expose.height = pBox->y2 - pBox->y1; ! 260: pe->u.expose.count = (prgn->numRects - i); ! 261: } ! 262: DeliverEvents(pWin, pEvent, prgn->numRects, NullWindow); ! 263: prgn->numRects = 0; ! 264: DEALLOCATE_LOCAL(pEvent); ! 265: } ! 266: } ! 267: ! 268: ! 269: /* ! 270: this code is highly unlikely. it is not haile selassie. ! 271: ! 272: there is some hair here. we can't just use the window's ! 273: clip region as it is, because if we are painting the border, ! 274: the border is not in the client area and so we will be excluded ! 275: when we validate the GC, and if we are painting a parent-relative ! 276: background, the area we want to paint is in some other window. ! 277: since we trust the code calling us to tell us to paint only areas ! 278: that are really ours, we will temporarily give the window a ! 279: clipList the size of the whole screen and an origin at (0,0). ! 280: this more or less assumes that ddX code will do translation ! 281: based on the window's absCorner, and that ValidateGC will ! 282: look at clipList, and that no other fields from the ! 283: window will be used. it's not possible to just draw ! 284: in the root because it may be a different depth. ! 285: ! 286: to get the tile to align correctly we set the GC's tile origin to ! 287: be the (x,y) of the window's upper left corner, after which we ! 288: get the right bits when drawing into the root. ! 289: ! 290: in order to call ChangeGC, we need to get an id for the pixmap, and ! 291: enter it in the resource table. ! 292: */ ! 293: void ! 294: miPaintWindow(pWin, prgn, what) ! 295: WindowPtr pWin; ! 296: RegionPtr prgn; ! 297: int what; ! 298: { ! 299: int gcval[6]; ! 300: int gcmask; ! 301: RegionPtr prgnWin; ! 302: DDXPointRec oldCorner; ! 303: BoxRec box; ! 304: GCPtr pGC; ! 305: int pid = 0; ! 306: register int i; ! 307: register BoxPtr pbox; ! 308: register ScreenPtr pScreen = pWin->drawable.pScreen; ! 309: register xRectangle *prect; ! 310: ! 311: gcval[0] = GXcopy; ! 312: gcval[3] = pWin->absCorner.x; ! 313: gcval[4] = pWin->absCorner.y; ! 314: gcval[5] = None; ! 315: gcmask = GCFunction | GCFillStyle | ! 316: GCTileStipXOrigin | GCTileStipYOrigin | GCClipMask; ! 317: if (what == PW_BACKGROUND) ! 318: { ! 319: if (pWin->backgroundTile == None) ! 320: return; ! 321: else if ((int)pWin->backgroundTile == ParentRelative) ! 322: { ! 323: (*pWin->parent->PaintWindowBorder)(pWin->parent, prgn, what); ! 324: return; ! 325: } ! 326: else if ((int)pWin->backgroundTile == USE_BACKGROUND_PIXEL) ! 327: { ! 328: gcval[1] = pWin->backgroundPixel; ! 329: gcval[2] = FillSolid; ! 330: gcmask |= GCForeground; ! 331: } ! 332: else ! 333: { ! 334: gcval[1] = FillTiled; ! 335: pid = FakeClientID(0); ! 336: AddResource(pid, RT_PIXMAP, pWin->backgroundTile, ! 337: NoopDDA, RC_CORE); ! 338: gcval[2] = pid; ! 339: gcmask |= GCTile; ! 340: } ! 341: } ! 342: else ! 343: { ! 344: if (pWin->borderTile == None) ! 345: return; ! 346: else if ((int)pWin->borderTile == USE_BORDER_PIXEL) ! 347: { ! 348: gcval[1] = pWin->borderPixel; ! 349: gcval[2] = FillSolid; ! 350: gcmask |= GCForeground; ! 351: } ! 352: else ! 353: { ! 354: gcval[1] = FillTiled; ! 355: pid = FakeClientID(0); ! 356: AddResource(pid, RT_PIXMAP, pWin->borderTile, ! 357: NoopDDA, RC_CORE); ! 358: gcval[2] = pid; ! 359: gcmask |= GCTile; ! 360: } ! 361: } ! 362: pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); ! 363: DoChangeGC(pGC, gcmask, gcval, 0); ! 364: ! 365: box.x1 = 0; ! 366: box.y1 = 0; ! 367: box.x2 = pScreen->width; ! 368: box.y2 = pScreen->height; ! 369: ! 370: prgnWin = pWin->clipList; ! 371: oldCorner = pWin->absCorner; ! 372: pWin->absCorner.x = pWin->absCorner.y = 0; ! 373: pWin->clipList = (*pScreen->RegionCreate)(&box, 1); ! 374: pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; ! 375: ValidateGC(pWin, pGC); ! 376: ! 377: prect = (xRectangle *)ALLOCATE_LOCAL(prgn->numRects * sizeof(xRectangle)); ! 378: pbox = prgn->rects; ! 379: for (i= 0; i < prgn->numRects; i++, pbox++, prect++) ! 380: { ! 381: prect->x = pbox->x1; ! 382: prect->y = pbox->y1; ! 383: prect->width = pbox->x2 - pbox->x1; ! 384: prect->height = pbox->y2 - pbox->y1; ! 385: } ! 386: prect -= prgn->numRects; ! 387: (*pGC->PolyFillRect)(pWin, pGC, prgn->numRects, prect); ! 388: DEALLOCATE_LOCAL(prect); ! 389: ! 390: if (pid) ! 391: FreeResource(pid, RC_CORE); ! 392: (*pScreen->RegionDestroy)(pWin->clipList); ! 393: pWin->clipList = prgnWin; ! 394: pWin->absCorner = oldCorner; ! 395: pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; ! 396: FreeScratchGC(pGC); ! 397: } ! 398:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.