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: }

Defined functions

Do_BitmapBitsPut defined in line 208; used 1 times
Do_CopyArea defined in line 256; used 1 times
Do_Draw defined in line 627; used 1 times
Do_DrawFilled defined in line 679; used 1 times
Do_Line defined in line 556; used 1 times
Do_PixFill defined in line 35; used 1 times
Do_PixmapBitsPut defined in line 162; used 1 times
Do_PixmapGet defined in line 754; used 1 times
Do_PixmapPut defined in line 123; used 1 times
Do_PixmapSave defined in line 722; used 2 times
Do_Text defined in line 454; used 1 times
Do_TextMask defined in line 506; used 1 times
Do_TileFill defined in line 75; used 1 times
Do_background defined in line 803; used 4 times
Do_border defined in line 883; used 3 times
Do_refill defined in line 834; used 1 times
Get_clips defined in line 928; used 11 times

Defined variables

rcsid_screen_c defined in line 16; never used

Defined macros

altsrc defined in line 637; used 2 times
back defined in line 463; used 4 times
brushx defined in line 635; used 8 times
brushy defined in line 634; used 8 times
ccount defined in line 515; used 10 times
cpad defined in line 516; used 6 times
dmode defined in line 636; used 5 times
dst defined in line 214; used 93 times
dstx defined in line 512; used 18 times
dsty defined in line 513; used 20 times
fore defined in line 462; used 4 times
format defined in line 169; used 2 times
patlen defined in line 639; used 4 times
patmul defined in line 640; used 3 times
patstr defined in line 638; used 2 times
spad defined in line 517; used 6 times
src defined in line 759; used 67 times
srs defined in line 261; used 20 times
vcount defined in line 685; used 6 times
x1 defined in line 560; used 5 times
x2 defined in line 562; used 5 times
y1 defined in line 561; used 5 times
y2 defined in line 563; used 5 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3002
Valid CSS Valid XHTML 1.0 Strict