1: #include <X/mit-copyright.h> 2: 3: /* Copyright Massachusetts Institute of Technology 1985 */ 4: 5: /* Routines dealing with output: 6: * 7: * Do_PixFill, Do_TileFill, Do_PixmapPut, 8: * Do_PixmapBitsPut, Do_BitmapBitsPut, 9: * Do_CopyArea, 10: * Do_Text, Do_TextMask, 11: * Do_Line, Do_Draw, Do_DrawFilled, 12: * Do_PixmapSave, Do_PixmapGet, 13: * Do_background, Do_refill, Do_border 14: */ 15: #ifndef lint 16: static char *rcsid_screen_c = "$Header: screen.c,v 10.6 86/02/01 15:17:20 tony Rel $"; 17: #endif 18: 19: #include "Xint.h" 20: 21: extern DEVICE device; 22: extern u_char Xstatus; 23: extern WINDOW *rootwindow; 24: extern RECTANGLE *free_rectangles; 25: #ifdef DUALTCP 26: extern int swapped[]; 27: #endif DUALTCP 28: 29: RECTANGLE *Rec_intersection(), *Alloc_rectangle(); 30: char *AllocateSpace(); 31: PIXMAP *PixmapSave(); 32: 33: /* Do a PixFill in a window */ 34: 35: Do_PixFill (w, req, mask) 36: register WINDOW *w; 37: register XReq *req; 38: BITMAP *mask; 39: { 40: #define src (int) req->param.u[4] 41: #define dst ((REGION *) req->param.s) 42: register WINDOW *ow; 43: register int i; 44: CLIP *cliplist; 45: 46: if (req->func >= funclim) { 47: Xstatus = BadValue; 48: return; 49: } 50: if FALSE(w->mapped) return; 51: ow = w; 52: while (ow->kind == IsTransparent) ow = ow->parent; 53: 54: dst->left += w->full.left; 55: dst->top += w->full.top; 56: if TRUE(ow->unobscured) { 57: cliplist = &w->clip; 58: i = 1; 59: } else { 60: dst->width += dst->left; 61: dst->height += dst->top; 62: if ((i = Get_clips (dst, w, ow, 1, &cliplist)) == 0) 63: return; 64: dst->width -= dst->left; 65: dst->height -= dst->top; 66: } 67: PixFill (src, mask, dst->left, dst->top, dst->width, dst->height, 68: cliplist, i, (int) req->func, (int) req->mask); 69: #undef src 70: #undef dst 71: } 72: 73: /* Do a TileFill in a window */ 74: 75: Do_TileFill (w, req, tile, mask) 76: register WINDOW *w; 77: register XReq *req; 78: PIXMAP *tile; 79: BITMAP *mask; 80: { 81: #define dst ((REGION *) req->param.s) 82: register WINDOW *ow; 83: register int i; 84: CLIP *cliplist; 85: 86: if (req->func >= funclim) { 87: Xstatus = BadValue; 88: return; 89: } else if FALSE(tile->tile) { 90: Xstatus = BadTile; 91: return; 92: } else if (mask && (mask->height != dst->height || 93: mask->width != dst->width)) { 94: Xstatus = BadMatch; 95: return; 96: } 97: if FALSE(w->mapped) return; 98: ow = w; 99: while (ow->kind == IsTransparent) ow = ow->parent; 100: 101: dst->left += w->full.left; 102: dst->top += w->full.top; 103: if TRUE(ow->unobscured) { 104: cliplist = &w->clip; 105: i = 1; 106: } else { 107: dst->width += dst->left; 108: dst->height += dst->top; 109: if ((i = Get_clips (dst, w, ow, 1, &cliplist)) == 0) 110: return; 111: dst->width -= dst->left; 112: dst->height -= dst->top; 113: } 114: while TRUE(w->tilemode) w = w->parent; 115: TileFill (tile, w->full.left, w->full.top, mask, dst->left, dst->top, 116: dst->width, dst->height, cliplist, i, 117: (int) req->func, (int) req->mask); 118: #undef dst 119: } 120: 121: /* Do a PixmapPut in a window */ 122: 123: Do_PixmapPut (w, req, pix) 124: register WINDOW *w; 125: register XReq *req; 126: PIXMAP *pix; 127: { 128: #define src ((REGION *) req->param.s) 129: #define dst ((RASTER *) &req->param.s[4]) 130: register WINDOW *ow; 131: register int i; 132: CLIP *cliplist; 133: 134: if (req->func >= funclim) { 135: Xstatus = BadValue; 136: return; 137: } 138: if FALSE(w->mapped) return; 139: ow = w; 140: while (ow->kind == IsTransparent) ow = ow->parent; 141: 142: dst->left += w->full.left; 143: dst->top += w->full.top; 144: if TRUE(ow->unobscured) { 145: cliplist = &w->clip; 146: i = 1; 147: } else { 148: dst->right = dst->left + src->width; 149: dst->bottom = dst->top + src->height; 150: if ((i = Get_clips (dst, w, ow, 1, &cliplist)) == 0) 151: return; 152: } 153: PixmapPut (pix, src->left, src->top, src->width, src->height, 154: dst->left, dst->top, cliplist, i, 155: (int) req->func, (int) req->mask); 156: #undef src 157: #undef dst 158: } 159: 160: /* Do a PixmapBitsPut in a window */ 161: 162: Do_PixmapBitsPut (w, req, data, mask) 163: register WINDOW *w; 164: register XReq *req; 165: char *data; 166: BITMAP *mask; 167: { 168: #define dst ((REGION *) req->param.s) 169: #define format req->param.s[4] 170: register WINDOW *ow; 171: register int i; 172: CLIP *cliplist; 173: 174: if (req->func >= funclim) { 175: Xstatus = BadValue; 176: return; 177: } else if (mask && (mask->height != dst->height || 178: mask->width != dst->width)) { 179: Xstatus = BadMatch; 180: return; 181: } 182: if FALSE(w->mapped) return; 183: ow = w; 184: while (ow->kind == IsTransparent) ow = ow->parent; 185: 186: dst->left += w->full.left; 187: dst->top += w->full.top; 188: if TRUE(ow->unobscured) { 189: cliplist = &w->clip; 190: i = 1; 191: } else { 192: dst->width += dst->left; 193: dst->height += dst->top; 194: if ((i = Get_clips (dst, w, ow, 1, &cliplist)) == 0) 195: return; 196: dst->width -= dst->left; 197: dst->height -= dst->top; 198: } 199: PixmapBitsPut (dst->width, dst->height, format, data, mask, 200: dst->left, dst->top, cliplist, i, 201: (int) req->func, (int) req->mask); 202: #undef dst 203: #undef format 204: } 205: 206: /* Do a BitmapBitsPut in a window */ 207: 208: Do_BitmapBitsPut (w, req, data, mask) 209: register WINDOW *w; 210: register XReq *req; 211: char *data; 212: BITMAP *mask; 213: { 214: #define dst ((REGION *) req->param.s) 215: #define fore (int) req->param.u[4] 216: #define back (int) req->param.u[5] 217: register WINDOW *ow; 218: register int i; 219: CLIP *cliplist; 220: 221: if (req->func >= funclim) { 222: Xstatus = BadValue; 223: return; 224: } else if (mask && (mask->height != dst->height || 225: mask->width != dst->width)) { 226: Xstatus = BadMatch; 227: return; 228: } 229: if FALSE(w->mapped) return; 230: ow = w; 231: while (ow->kind == IsTransparent) ow = ow->parent; 232: 233: dst->left += w->full.left; 234: dst->top += w->full.top; 235: if TRUE(ow->unobscured) { 236: cliplist = &w->clip; 237: i = 1; 238: } else { 239: dst->width += dst->left; 240: dst->height += dst->top; 241: if ((i = Get_clips (dst, w, ow, 1, &cliplist)) == 0) 242: return; 243: dst->width -= dst->left; 244: dst->height -= dst->top; 245: } 246: BitmapBitsPut (dst->width, dst->height, data, fore, back, mask, 247: dst->left, dst->top, cliplist, i, 248: (int) req->func, (int) req->mask); 249: #undef dst 250: #undef fore 251: #undef back 252: } 253: 254: /* Does a CopyArea in a window */ 255: 256: Do_CopyArea (w, req) 257: register WINDOW *w; 258: register XReq *req; 259: { 260: #define src ((REGION *) req->param.s) 261: #define srs ((RASTER *) req->param.s) 262: #define dstx req->param.s[6] 263: #define dsty req->param.s[7] 264: register RECTANGLE *v1, *v2; 265: register WINDOW *ow; 266: RECTANGLE rec, *vlist, *vis, *new, *end; 267: RASTER temp; 268: int i; 269: CLIP *cliplist, *clipptr; 270: PIXMAP *tile; 271: 272: if (req->func >= funclim) { 273: Xstatus = BadValue; 274: return; 275: } 276: if FALSE(w->mapped) { 277: Stash_misses (w, (RECTANGLE *) NULL); 278: return; 279: } 280: ow = w; 281: while (ow->kind == IsTransparent) ow = ow->parent; 282: 283: dstx -= src->left; 284: dsty -= src->top; 285: src->left += w->full.left; 286: src->top += w->full.top; 287: if TRUE(ow->unobscured) { 288: /* no hairy stuff */ 289: CopyArea (src->left, src->top, src->width, src->height, 290: src->left + dstx, src->top + dsty, 291: &w->clip, 1, (int) req->func, (int) req->mask); 292: srs->right += srs->left; 293: srs->bottom += srs->top; 294: /* unless part of the source is invisible */ 295: if (srs->left >= w->vs.left && srs->top >= w->vs.top && 296: srs->right <= w->vs.right && srs->bottom <= w->vs.bottom) { 297: Stash_misses (w, (RECTANGLE *) NULL); 298: return; 299: } 300: vlist = ow->visible; 301: /* get destination */ 302: rec.left = srs->left + dstx; 303: rec.top = srs->top + dsty; 304: rec.right = srs->right + dstx; 305: rec.bottom = srs->bottom + dsty; 306: /* get visible source */ 307: Clip_raster (srs, &w->vs); 308: srs->left += dstx; 309: srs->top += dsty; 310: srs->right += dstx; 311: srs->bottom += dsty; 312: /* get updated destination */ 313: Clip_raster (srs, &w->vs); 314: RASTRECT(v1, *srs, contents_rec); 315: rec.next = v1; 316: rec.next->next = NULL; 317: } else { 318: if TRUE(w->clipmode) 319: vlist = ow->cmvisible; 320: else 321: vlist = ow->visible; 322: /* get source */ 323: *(REGION *) &rec = *src; 324: rec.right += src->left; 325: rec.bottom += src->top; 326: rec.next = NULL; 327: i = 0; 328: for (v1 = vlist; v1; v1 = v1->next) { 329: /* get visible source */ 330: if (v1->type != contents_rec || 331: (vis = Rec_intersection (v1, &rec)) == NULL || 332: (w != ow && TRUE(Clip_rectangle (vis, &w->vs)))) 333: continue; 334: /* get destination */ 335: vis->left += dstx; 336: vis->top += dsty; 337: vis->right += dstx; 338: vis->bottom += dsty; 339: for (v2 = vlist; v2; v2 = v2->next) { 340: /* get visible destination */ 341: if (v2->type != contents_rec || 342: (new = Rec_intersection (v2, vis)) == NULL || 343: (w != ow && TRUE(Clip_rectangle (new, &w->vs)))) 344: continue; 345: /* try to merge it in */ 346: for (end = rec.next; end; end = end->next) { 347: if (end->left != new->left || end->right != new->right) 348: continue; 349: if (end->top == new->bottom) { 350: end->top = new->top; 351: } else if (end->bottom == new->top) { 352: end->bottom = new->bottom; 353: } else 354: continue; 355: FREERECT(new); 356: new = NULL; 357: break; 358: } 359: if (new == NULL) 360: continue; 361: new->next = rec.next; 362: rec.next = new; 363: i++; 364: } 365: FREERECT(vis); 366: } 367: /* reorder by direction of motion */ 368: for (v1 = rec.next; v1; v1 = v1->next) { 369: for (v2 = v1->next; v2; v2 = v2->next) { 370: if ((((dsty <= 0 && v1->top == v2->top) || 371: (dsty > 0 && v1->bottom == v2->bottom)) && 372: ((dstx < 0 && v1->left > v2->left) || 373: (dstx > 0 && v1->right < v2->right))) || 374: (dsty < 0 && v1->top > v2->top) || 375: (dsty > 0 && v1->bottom < v2->bottom)) { 376: temp = *(RASTER *) v1; 377: *(RASTER *) v1 = *(RASTER *) v2; 378: *(RASTER *) v2 = temp; 379: } 380: } 381: } 382: if (i) { 383: clipptr = (CLIP *) AllocateSpace (i * sizeof (CLIP)); 384: if (cliplist = clipptr) { 385: for (v1 = rec.next; v1; v1 = v1->next) { 386: clipptr->left = v1->left; 387: clipptr->top = v1->top; 388: clipptr->height = v1->bottom - v1->top; 389: clipptr->width = v1->right - v1->left; 390: clipptr++; 391: } 392: CopyArea (src->left, src->top, src->width, src->height, 393: src->left + dstx, src->top + dsty, 394: cliplist, i, (int) req->func, (int) req->mask); 395: } else 396: DeviceError ("Cliplist too large"); 397: } 398: /* get destination */ 399: rec.left += dstx; 400: rec.top += dsty; 401: rec.right += dstx; 402: rec.bottom += dsty; 403: } 404: vis = NULL; 405: for (v1 = vlist; v1; v1 = v1->next) { 406: /* get updated destination */ 407: if (v1->type != contents_rec || 408: (v2 = Rec_intersection (v1, &rec)) == NULL || 409: (w != ow && TRUE(Clip_rectangle (v2, &w->vs)))) 410: continue; 411: v2->next = vis; 412: vis = v2; 413: } 414: /* get missed but visible destination */ 415: for (v1 = rec.next; v1; v1 = v2) { 416: Calc_overlaps ((RASTER *)v1, &vis); 417: v2 = v1->next; 418: FREERECT(v1); 419: } 420: i = 0; 421: for (v1 = vis; v1; v1 = v1->next) 422: i++; 423: if (i) { 424: clipptr = (CLIP *) AllocateSpace (i * sizeof (CLIP)); 425: if (cliplist = clipptr) { 426: for (v1 = vis; v1; v1 = v1->next) { 427: clipptr->left = v1->left; 428: clipptr->top = v1->top; 429: clipptr->height = v1->bottom - v1->top; 430: clipptr->width = v1->right - v1->left; 431: clipptr++; 432: } 433: } 434: tile = ow->tile; 435: ow = w; 436: while TRUE(ow->tilemode) ow = ow->parent; 437: if (clipptr == NULL) 438: DeviceError ("Cliplist too large"); 439: else 440: TileFill (tile, ow->full.left, ow->full.top, (BITMAP *) NULL, 441: rec.left, rec.top, 442: rec.right - rec.left, rec.bottom - rec.top, 443: cliplist, i, (int) req->func, (int) req->mask); 444: } 445: Stash_misses (w, vis); 446: #undef src 447: #undef srs 448: #undef dstx 449: #undef dsty 450: } 451: 452: /* Writes text with a source font in a window */ 453: 454: Do_Text (w, req, text, font) 455: register WINDOW *w; 456: register XReq *req; 457: char *text; 458: FONT *font; 459: { 460: #define dstx req->param.s[0] 461: #define dsty req->param.s[1] 462: #define fore (int) req->param.u[4] 463: #define back (int) req->param.u[5] 464: #define ccount req->param.s[6] 465: #define cpad req->param.b[14] 466: #define spad req->param.b[15] 467: register WINDOW *ow; 468: RASTER bound; 469: register int i; 470: CLIP *cliplist; 471: 472: if (req->func >= funclim) { 473: Xstatus = BadValue; 474: return; 475: } 476: if (FALSE(w->mapped) || ccount == 0) return; 477: ow = w; 478: while (ow->kind == IsTransparent) ow = ow->parent; 479: 480: bound.left = dstx + w->full.left; 481: bound.top = dsty + w->full.top; 482: if TRUE(ow->unobscured) { 483: cliplist = &w->clip; 484: i = 1; 485: } else { 486: bound.bottom = bound.top + font->height; 487: bound.right = bound.left + ccount * cpad + 488: TextWidth (text, ccount, spad, font); 489: if ((i = Get_clips (&bound, w, ow, 1, &cliplist)) == 0) 490: return; 491: } 492: PrintText (text, ccount, font, fore, back, cpad, spad, 493: bound.left, bound.top, cliplist, i, 494: (int) req->func, (int) req->mask); 495: #undef dstx 496: #undef dsty 497: #undef fore 498: #undef back 499: #undef ccount 500: #undef cpad 501: #undef spad 502: } 503: 504: /* Writes text with a mask font in a window */ 505: 506: Do_TextMask (w, req, text, font) 507: register WINDOW *w; 508: register XReq *req; 509: char *text; 510: FONT *font; 511: { 512: #define dstx req->param.s[0] 513: #define dsty req->param.s[1] 514: #define src (int) req->param.u[4] 515: #define ccount req->param.s[6] 516: #define cpad req->param.b[14] 517: #define spad req->param.b[15] 518: register WINDOW *ow; 519: RASTER bound; 520: register int i; 521: CLIP *cliplist; 522: 523: if (req->func >= funclim) { 524: Xstatus = BadValue; 525: return; 526: } 527: if (FALSE(w->mapped) || ccount == 0) return; 528: ow = w; 529: while (ow->kind == IsTransparent) ow = ow->parent; 530: 531: bound.left = dstx + w->full.left; 532: bound.top = dsty + w->full.top; 533: if TRUE(ow->unobscured) { 534: cliplist = &w->clip; 535: i = 1; 536: } else { 537: bound.bottom = bound.top + font->height; 538: bound.right = bound.left + ccount * cpad + 539: TextWidth (text, ccount, spad, font); 540: if ((i = Get_clips (&bound, w, ow, 1, &cliplist)) == 0) 541: return; 542: } 543: PrintTextMask (text, ccount, font, src, cpad, spad, 544: bound.left, bound.top, cliplist, i, 545: (int) req->func, (int) req->mask); 546: #undef dstx 547: #undef dsty 548: #undef ccount 549: #undef src 550: #undef cpad 551: #undef spad 552: } 553: 554: /* Draws a line in a window */ 555: 556: Do_Line (w, req) 557: register WINDOW *w; 558: register XReq *req; 559: { 560: #define x1 req->param.s[0] 561: #define y1 req->param.s[1] 562: #define x2 req->param.s[2] 563: #define y2 req->param.s[3] 564: #define src (int) req->param.u[4] 565: #define brushy req->param.b[10] 566: #define brushx req->param.b[11] 567: register WINDOW *ow; 568: RASTER bound; 569: register int i; 570: CLIP *cliplist; 571: Vertex vlist[2]; 572: 573: if (req->func >= funclim || brushx <= 0 || brushy <= 0) { 574: Xstatus = BadValue; 575: return; 576: } 577: if FALSE(w->mapped) return; 578: ow = w; 579: while (ow->kind == IsTransparent) ow = ow->parent; 580: 581: if TRUE(ow->unobscured) { 582: cliplist = &w->clip; 583: i = 1; 584: } else { 585: /* we can only approximate a minimal clipping region */ 586: if (x1 <= x2) { 587: bound.left = x1; 588: bound.right = x2; 589: } else { 590: bound.left = x2; 591: bound.right = x1; 592: } 593: bound.left += w->full.left - brushx; 594: bound.right += w->full.left + brushx; 595: if (y1 <= y2) { 596: bound.top = y1; 597: bound.bottom = y2; 598: } else { 599: bound.top = y2; 600: bound.bottom = y1; 601: } 602: bound.top += w->full.top - brushy; 603: bound.bottom += w->full.top + brushy; 604: if ((i = Get_clips (&bound, w, ow, 1, &cliplist)) == 0) 605: return; 606: } 607: vlist[0].x = x1; 608: vlist[0].y = y1; 609: vlist[0].flags = VertexDontDraw; 610: vlist[1].x = x2; 611: vlist[1].y = y2; 612: vlist[1].flags = VertexDrawLastPoint; 613: DrawCurve (vlist, 2, w->full.left, w->full.top, src, 0, DrawSolidLine, 614: brushx, brushy, 0, 0, 0, cliplist, i, (int) req->func, 615: (int) req->mask); 616: #undef x1 617: #undef y1 618: #undef x2 619: #undef y2 620: #undef src 621: #undef brushx 622: #undef brushy 623: } 624: 625: /* Draws a polygon/curve in a window */ 626: 627: Do_Draw (w, req, vlist) 628: register WINDOW *w; 629: register XReq *req; 630: Vertex *vlist; 631: { 632: #define vcount req->param.s[0] 633: #define src (int) req->param.u[1] 634: #define brushy req->param.b[4] 635: #define brushx req->param.b[5] 636: #define dmode req->param.s[3] 637: #define altsrc (int) req->param.u[4] 638: #define patstr req->param.s[5] 639: #define patlen req->param.s[6] 640: #define patmul req->param.s[7] 641: register WINDOW *ow; 642: register int i; 643: CLIP *cliplist; 644: 645: if (req->func >= funclim || brushx <= 0 || brushy <= 0 || 646: dmode < 0 || dmode > 2 || 647: (dmode > 0 && (patlen <= 0 || patlen > 16 || patmul <= 0))) { 648: Xstatus = BadValue; 649: return; 650: } 651: if (FALSE(w->mapped) || vcount == 0) return; 652: ow = w; 653: while (ow->kind == IsTransparent) ow = ow->parent; 654: 655: if TRUE(ow->unobscured) { 656: cliplist = &w->clip; 657: i = 1; 658: /* it is generally impossible for us to compute a minimal clip */ 659: } else if ((i = Get_clips (&w->vs, w, ow, 1, &cliplist)) == 0) 660: return; 661: 662: vlist->flags = (vlist->flags | VertexDontDraw) & ~VertexRelative; 663: DrawCurve (vlist, vcount, w->full.left, w->full.top, src, altsrc, 664: dmode, brushx, brushy, patstr, patlen, patmul, cliplist, i, 665: (int) req->func, (int) req->mask); 666: #undef vcount 667: #undef src 668: #undef brushy 669: #undef brushx 670: #undef dmode 671: #undef altsrc 672: #undef patstr 673: #undef patlen 674: #undef patmul 675: } 676: 677: /* Draws a filled polygon/curve in a window */ 678: 679: Do_DrawFilled (w, req, vlist, tile) 680: register WINDOW *w; 681: register XReq *req; 682: Vertex *vlist; 683: PIXMAP *tile; 684: { 685: #define vcount req->param.s[0] 686: #define src (int) req->param.u[1] 687: register WINDOW *ow; 688: register int i; 689: CLIP *cliplist; 690: 691: if (req->func >= funclim) { 692: Xstatus = BadValue; 693: return; 694: } else if (tile && FALSE(tile->tile)) { 695: Xstatus = BadTile; 696: return; 697: } else if (FALSE(w->mapped) || vcount == 0) 698: return; 699: 700: ow = w; 701: while (ow->kind == IsTransparent) ow = ow->parent; 702: 703: if TRUE(ow->unobscured) { 704: cliplist = &w->clip; 705: i = 1; 706: /* it is generally impossible for us to compute a minimal clip */ 707: } else if ((i = Get_clips (&w->vs, w, ow, 1, &cliplist)) == 0) 708: return; 709: ow = w; 710: while TRUE(ow->tilemode) ow = ow->parent; 711: 712: vlist->flags = (vlist->flags | VertexDontDraw) & ~VertexRelative; 713: DrawFilled (vlist, vcount, w->full.left, w->full.top, src, tile, 714: ow->full.left, ow->full.top, cliplist, i, (int) req->func, 715: (int) req->mask); 716: #undef vcount 717: #undef src 718: } 719: 720: /* Save a region of a window */ 721: 722: PIXMAP *Do_PixmapSave (w, req) 723: register WINDOW *w; 724: register XReq *req; 725: { 726: #define src ((REGION *) req->param.s) 727: PIXMAP *pix; 728: 729: if (src->height <= 0 || src->width <= 0) { 730: Xstatus = BadValue; 731: return (NULL); 732: } 733: 734: src->left += w->full.left; 735: src->top += w->full.top; 736: 737: if (FALSE(w->mapped) || 738: src->left < w->vs.left || src->top < w->vs.top || 739: src->left + src->width > w->vs.right || 740: src->top + src->height > w->vs.bottom) { 741: Xstatus = BadValue; 742: return (NULL); 743: } 744: 745: pix = PixmapSave (src->left, src->top, src->width, src->height); 746: if (pix == NULL) 747: Xstatus = BadAlloc; 748: return (pix); 749: #undef src 750: } 751: 752: /* Read a region of a window */ 753: 754: Do_PixmapGet (w, req, client) 755: register WINDOW *w; 756: register XReq *req; 757: int client; 758: { 759: #define src ((REGION *) req->param.s) 760: XRep rep; 761: #ifdef DUALTCP 762: register swaptype n; 763: #endif 764: 765: if ((rep.param.l[0] = Pix_size ((int) req->func, 766: src->height, src->width)) == 0) 767: return; 768: 769: src->left += w->full.left; 770: src->top += w->full.top; 771: 772: if (FALSE(w->mapped) || 773: src->left < w->vs.left || src->top < w->vs.top || 774: src->left + src->width > w->vs.right || 775: src->top + src->height > w->vs.bottom) { 776: Xstatus = BadValue; 777: return; 778: } 779: 780: rep.code = X_Reply; 781: #ifdef DUALTCP 782: if (swapped[client]) { 783: pswapl(&rep, 0); 784: } 785: #endif 786: Write (client, (caddr_t) &rep, sizeof (XRep)); 787: 788: PixmapGet (src->left, src->top, src->width, src->height, 789: client, (int) req->func, 790: #ifdef DUALTCP 791: swapped[client] 792: #else 793: 0 794: #endif 795: ); 796: #undef src 797: } 798: 799: /* Fills a window with the background. 800: * Fills all the window if not_just_new is set, else just the changes. 801: */ 802: 803: Do_background (w, not_just_new) 804: register WINDOW *w; 805: int not_just_new; 806: { 807: register WINDOW *ow; 808: register int i; 809: CLIP *cliplist; 810: PIXMAP *tile; 811: 812: if FALSE(w->mapped) return; 813: ow = w; 814: while (ow->kind == IsTransparent) ow = ow->parent; 815: if (ow->visible == NULL) return; 816: 817: if (TRUE(not_just_new) && TRUE(ow->unobscured)) { 818: cliplist = &w->clip; 819: i = 1; 820: } else if ((i = Get_clips (&w->vs, (WINDOW *) NULL, ow, not_just_new, 821: &cliplist)) == 0) 822: return; 823: tile = ow->tile; 824: ow = w; 825: while TRUE(ow->tilemode) ow = ow->parent; 826: TileFill (tile, ow->full.left, ow->full.top, (BITMAP *) NULL, 827: w->vs.left, w->vs.top, 828: w->vs.right - w->vs.left, w->vs.bottom - w->vs.top, 829: cliplist, i, GXcopy, 0xffff); 830: } 831: 832: /* Move the contents of a window on the screen and redisplay the border. */ 833: 834: Do_refill (w, dx, dy) 835: register WINDOW *w; 836: int dx, dy; 837: { 838: register RECTANGLE *v1, *v2; 839: register CLIP *clipptr; 840: register int i; 841: CLIP *cliplist; 842: RASTER temp; 843: 844: /* Order rectangles by direction of motion */ 845: i = 0; 846: for (v1 = w->cmvisible; v1; v1 = v1->next) { 847: i++; 848: for (v2 = v1->next; v2; v2 = v2->next) { 849: if ((((dy <= 0 && v1->top == v2->top) || 850: (dy > 0 && v1->bottom == v2->bottom)) && 851: ((dx < 0 && v1->left > v2->left) || 852: (dx > 0 && v1->right < v2->right))) || 853: (dy < 0 && v1->top > v2->top) || 854: (dy > 0 && v1->bottom < v2->bottom)) { 855: temp = *(RASTER *) v1; 856: *(RASTER *) v1 = *(RASTER *) v2; 857: *(RASTER *) v2 = temp; 858: } 859: } 860: } 861: if (i) { 862: clipptr = (CLIP *) AllocateSpace (i * sizeof (CLIP)); 863: if (cliplist = clipptr) { 864: for (v1 = w->cmvisible; v1; v1 = v1->next) { 865: clipptr->left = v1->left; 866: clipptr->top = v1->top; 867: clipptr->height = v1->bottom - v1->top; 868: clipptr->width = v1->right - v1->left; 869: clipptr++; 870: } 871: CopyArea (w->vs.left - dx, w->vs.top - dy, 872: w->vs.right - w->vs.left, w->vs.bottom - w->vs.top, 873: w->vs.left, w->vs.top, cliplist, i, GXcopy, 0xffff); 874: } else 875: DeviceError ("Cliplist too large"); 876: 877: } 878: Do_border (w); 879: } 880: 881: /* Repaint the border of a window */ 882: 883: Do_border (w) 884: register WINDOW *w; 885: { 886: register RECTANGLE *r; 887: register int i = 0; 888: CLIP *cliplist; 889: register CLIP *clipptr; 890: 891: for (r = w->visible; r; r = r->next) { 892: if (r->type == border_rec) i++; 893: } 894: 895: if (i == 0) return; 896: 897: clipptr = (CLIP *) AllocateSpace (i * sizeof (CLIP)); 898: if (clipptr == NULL) { 899: DeviceError ("Cliplist too large"); 900: return; 901: } 902: cliplist = clipptr; 903: for (r = w->visible; r; r = r->next) { 904: if (r->type == border_rec) { 905: clipptr->left = r->left; 906: clipptr->top = r->top; 907: clipptr->height = r->bottom - r->top; 908: clipptr->width = r->right - r->left; 909: clipptr++; 910: } 911: } 912: 913: TileFill (w->border, w->full.left - w->bwidth, w->full.top - w->bwidth, 914: (BITMAP *) NULL, 915: w->full.left - w->bwidth, w->full.top - w->bwidth, 916: w->full.right - w->full.left + (w->bwidth << 1), 917: w->full.bottom - w->full.top + (w->bwidth << 1), 918: cliplist, i, GXcopy, 0xffff); 919: } 920: 921: /* Compute a clip list for a destination, and return clip count. 922: * w is the original window, ow is the actual output window. 923: * If not_just_new, compute for all of the window, else just the changes. 924: * We assume that it is better (cheaper/faster) for us to compute a minimal 925: * clip list than to expect all devices to do the computation. 926: */ 927: 928: Get_clips (dst, w, ow, not_just_new, cliplist) 929: register RASTER *dst; 930: WINDOW *w, *ow; 931: register int not_just_new; 932: CLIP **cliplist; 933: { 934: register RECTANGLE *r; 935: register RECTANGLE **ptr1, **ptr2; 936: RECTANGLE *clips; 937: register CLIP *clipptr; 938: register int i; 939: RASTER rast; 940: 941: if (w && TRUE(w->clipmode)) { 942: if (ow == rootwindow) { 943: *cliplist = &w->clip; 944: return (1); 945: } 946: ptr1 = &ow->cmvisible; 947: } else 948: ptr1 = &ow->visible; 949: if (w && w != ow) { 950: rast = *dst; 951: dst = &rast; 952: Clip_raster (dst, &w->vs); 953: } 954: ptr2 = &clips; 955: i = 0; 956: for (r = *ptr1; r; r = r->next) { 957: if (((r->type == contents_rec && not_just_new) || 958: (r->type == new_rec)) && 959: max(dst->left, r->left) < min(dst->right, r->right) && 960: max(dst->top, r->top) < min(dst->bottom, r->bottom)) { 961: *ptr2 = r; 962: ptr2 = &r->next; 963: i++; 964: } else { 965: *ptr1 = r; 966: ptr1 = &r->next; 967: } 968: } 969: *ptr2 = NULL; 970: *ptr1 = clips; 971: if (i == 0) 972: return (0); 973: 974: clipptr = (CLIP *) AllocateSpace (i * sizeof (CLIP)); 975: if (clipptr == NULL) { 976: DeviceError ("Cliplist too large"); 977: return (0); 978: } 979: *cliplist = clipptr; 980: for (r = clips; r; r = r->next) { 981: clipptr->left = max(r->left, dst->left); 982: clipptr->top = max(r->top, dst->top); 983: clipptr->height = min(r->bottom, dst->bottom) - clipptr->top; 984: clipptr->width = min(r->right, dst->right) - clipptr->left; 985: clipptr++; 986: } 987: return (i); 988: }