1: #include <X/mit-copyright.h>
   2: 
   3: /* Copyright    Massachusetts Institute of Technology    1985	*/
   4: 
   5: /*	Routines for calculating how windows obscure each other:
   6:  *
   7:  *	Obscure_top, Obscure_bottom, Remove_rectangles
   8:  */
   9: 
  10: #ifndef lint
  11: static char *rcsid_obscure_c = "$Header: obscure.c,v 10.7 86/02/01 15:16:51 tony Rel $";
  12: #endif
  13: 
  14: #include "Xint.h"
  15: 
  16: extern RECTANGLE *free_rectangles;
  17: 
  18: RECTANGLE *Alloc_rectangle(), **Do_overlap();
  19: 
  20: /* Obscure_top allocates the rectangles for a top window, and updates the lists
  21:  * of visible rectangles in other mapped windows to reflect obscuring.
  22:  */
  23: 
  24: Obscure_top (w)
  25:     register WINDOW *w;
  26: {
  27:     register WINDOW *w1;
  28:     register RECTANGLE *pr, *v, *r;
  29:     RECTANGLE crec, brec1, brec2, brec3, brec4;
  30:     int done;
  31: 
  32:     /* Compute visible rectangles from what parent has to offer */
  33: 
  34:     *(RASTER *) &crec = w->vs;
  35:     done = 0;
  36:     for (pr = w->parent->cmvisible; pr; pr = pr->next) {
  37:         if (crec.left >= pr->right || pr->left >= crec.right ||
  38:         crec.top >= pr->bottom || pr->top >= crec.bottom)
  39:         continue;
  40:         NEWRECT(v, max(crec.left, pr->left), min(crec.right, pr->right),
  41:             max(crec.top, pr->top), min(crec.bottom, pr->bottom),
  42:             contents_rec);
  43:         if (v->left == crec.left && v->right == crec.right &&
  44:         v->top == crec.top && v->bottom == crec.bottom)
  45:         done = 1;
  46:         RASTRECT(r, *(RASTER *) v, contents_rec);
  47:         if (w->visible && TRUE(Merge_vertical (v, &w->visible, 1)))
  48:         Merge_vertical (r, &w->cmvisible, 1);
  49:         else {
  50:         v->next = w->visible;
  51:         w->visible = v;
  52:         r->next = w->cmvisible;
  53:         w->cmvisible = r;
  54:         }
  55:         if TRUE(done) break;
  56:     }
  57:     w->unobscured = OB_NOT;
  58:     Windex (w);
  59: 
  60:     if (w->bwidth) {
  61:         /* Compute the visible border */
  62:         brec1.left = w->full.left - w->bwidth;
  63:         brec1.right = w->full.left;
  64:         brec1.top = w->full.top;
  65:         brec1.bottom = w->full.bottom;
  66:         brec1.next = &brec2;
  67:         brec2.left = w->full.right;
  68:         brec2.right = w->full.right + w->bwidth;
  69:         brec2.top = w->full.top;
  70:         brec2.bottom = w->full.bottom;
  71:         brec2.next = &brec3;
  72:         brec3.left = w->full.left - w->bwidth;
  73:         brec3.right = w->full.right + w->bwidth;
  74:         brec3.top = w->full.top - w->bwidth;
  75:         brec3.bottom = w->full.top;
  76:         brec3.next = &brec4;
  77:         brec4.left = w->full.left - w->bwidth;
  78:         brec4.right = w->full.right + w->bwidth;
  79:         brec4.top = w->full.bottom;
  80:         brec4.bottom = w->full.bottom + w->bwidth;
  81:         brec4.type = border_rec;
  82:         brec4.next = NULL;
  83: 
  84:         r = &brec1;
  85:         do {
  86:         done = 0;
  87:         /* again, use what parent has to offer */
  88:         for (pr = w->parent->cmvisible; pr; pr = pr->next) {
  89:             if (r->left >= pr->right || pr->left >= r->right ||
  90:             r->top >= pr->bottom || pr->top >= r->bottom)
  91:             continue;
  92:             NEWRECT(v, max(r->left, pr->left), min(r->right, pr->right),
  93:                 max(r->top, pr->top), min(r->bottom, pr->bottom),
  94:                 border_rec);
  95:             if (v->left == r->left && v->right == r->right &&
  96:             v->top == r->top && v->bottom == r->bottom)
  97:             done = 1;
  98:             if (w->visible == NULL ||
  99:             FALSE(Merge_vertical (v, &w->visible, 1))) {
 100:             v->next = w->visible;
 101:             w->visible = v;
 102:             }
 103:             if TRUE(done) break;
 104:         }
 105:         } while (r = r->next);
 106:     }
 107: 
 108:     if (w->visible == NULL)
 109:         return;
 110: 
 111:     /* Let the window obscure the rest of the list */
 112: 
 113:     w1 = w;
 114:     while (1) {
 115:         w1 = w1->next;
 116: 
 117:         if (w1->kind == IsTransparent ||
 118:         w->ovs.left >= w1->ovs.right || w1->ovs.left >= w->ovs.right ||
 119:         w->ovs.top >= w1->ovs.bottom || w1->ovs.top >= w->ovs.bottom) {
 120:         if (w1 != w->parent)
 121:             continue;
 122:         return;
 123:         }
 124: 
 125:         if (TRUE(Calc_overlaps (&w->ovs, &w1->visible)) && w1->unobscured == OB_YES)
 126:         w1->unobscured = OB_NOT;
 127:         if (w1 == w->parent)
 128:         return;
 129:         Calc_overlaps (&w->ovs, &w1->cmvisible);
 130:     }
 131: }
 132: 
 133: /* Obscure_bottom allocates the rectangles for a bottom window, and updates the
 134:  * lists of visible rectangles in the parent to reflect obscuring.
 135:  */
 136: 
 137: Obscure_bottom (w)
 138:     register WINDOW *w;
 139: {
 140:     register WINDOW *w1;
 141:     register RECTANGLE **prev, *v, *pr, *r;
 142:     RECTANGLE crec, brec1, brec2, brec3, brec4;
 143:     int done;
 144: 
 145:     /* Compute visible rectangles from what parent has left */
 146: 
 147:     *(RASTER *) &crec = w->vs;
 148:     done = 0;
 149:     w1 = w->parent;
 150:     prev = &w1->visible;
 151:     while (pr = *prev) {
 152:         if (pr->type == border_rec ||
 153:         crec.left >= pr->right || pr->left >= crec.right ||
 154:         crec.top >= pr->bottom || pr->top >= crec.bottom) {
 155:         prev = &pr->next;
 156:         continue;
 157:         }
 158:         NEWRECT(v, max(crec.left, pr->left), min(crec.right, pr->right),
 159:             max(crec.top, pr->top), min(crec.bottom, pr->bottom),
 160:             contents_rec);
 161:         if (v->left == crec.left && v->right == crec.right &&
 162:         v->top == crec.top && v->bottom == crec.bottom)
 163:         done = 1;
 164:         /* compute what remains for parent */
 165:         prev = Do_overlap ((RASTER *) v, prev, &w1->visible);
 166:         if (w1->unobscured == OB_YES)
 167:         w1->unobscured = OB_NOT;
 168:         RASTRECT(r, *(RASTER *) v, contents_rec);
 169:         if (w->visible && TRUE(Merge_vertical (v, &w->visible, 1)))
 170:         Merge_vertical (r, &w->cmvisible, 1);
 171:         else {
 172:         v->next = w->visible;
 173:         w->visible = v;
 174:         r->next = w->cmvisible;
 175:         w->cmvisible = r;
 176:         }
 177:         if TRUE(done) break;
 178:     }
 179:     w->unobscured = OB_NOT;
 180:     Windex (w);
 181: 
 182:     if (w->bwidth) {
 183:         /* Compute visible border from what parent has left */
 184:         brec1.left = w->full.left - w->bwidth;
 185:         brec1.right = w->full.left;
 186:         brec1.top = w->full.top;
 187:         brec1.bottom = w->full.bottom;
 188:         brec1.next = &brec2;
 189:         brec2.left = w->full.right;
 190:         brec2.right = w->full.right + w->bwidth;
 191:         brec2.top = w->full.top;
 192:         brec2.bottom = w->full.bottom;
 193:         brec2.next = &brec3;
 194:         brec3.left = w->full.left - w->bwidth;
 195:         brec3.right = w->full.right + w->bwidth;
 196:         brec3.top = w->full.top - w->bwidth;
 197:         brec3.bottom = w->full.top;
 198:         brec3.next = &brec4;
 199:         brec4.left = w->full.left - w->bwidth;
 200:         brec4.right = w->full.right + w->bwidth;
 201:         brec4.top = w->full.bottom;
 202:         brec4.bottom = w->full.bottom + w->bwidth;
 203:         brec4.type = border_rec;
 204:         brec4.next = NULL;
 205: 
 206:         r = &brec1;
 207:         do {
 208:         done = 0;
 209:         prev = &w1->visible;
 210:         while (pr = *prev) {
 211:             if (pr->type == border_rec ||
 212:             r->left >= pr->right || pr->left >= r->right ||
 213:             r->top >= pr->bottom || pr->top >= r->bottom) {
 214:             prev = &pr->next;
 215:             continue;
 216:             }
 217:             NEWRECT(v, max(r->left, pr->left), min(r->right, pr->right),
 218:                 max(r->top, pr->top), min(r->bottom, pr->bottom),
 219:                 border_rec);
 220:             if (v->left == r->left && v->right == r->right &&
 221:             v->top == r->top && v->bottom == r->bottom)
 222:             done = 1;
 223:             /* compute what remains in parent */
 224:             prev = Do_overlap ((RASTER *) v, prev, &w1->visible);
 225:             if (w1->unobscured == OB_YES)
 226:             w1->unobscured = OB_NOT;
 227:             if (w->visible == NULL ||
 228:             FALSE(Merge_vertical (v, &w->visible, 1))) {
 229:             v->next = w->visible;
 230:             w->visible = v;
 231:             }
 232:             if TRUE(done) break;
 233:         }
 234:         } while (r = r->next);
 235:     }
 236: }
 237: 
 238: /* Remove_rectangles removes rectangles from remw and gives the space to
 239:  * the various windows in the chain.  It does this by moving down the list,
 240:  * giving space to each window in turn.  If cleanup = 1, then update and
 241:  * display windows you give space to.  If cleanup < 0, then update the
 242:  * windows without changing the bits on the screen.  If, in the course
 243:  * of following the chain, remw is encountered, we stop.
 244:  */
 245: 
 246: Remove_rectangles (remw, chain, cleanup)
 247:     register WINDOW *remw;
 248:     WINDOW *chain;
 249:     int cleanup;
 250: {
 251:     register RECTANGLE *r, **oldr;
 252:     register WINDOW *w, *ww;
 253:     register RECTANGLE *addrec;
 254:     RECTANGLE *new;
 255: 
 256:     for (w = chain; remw->visible && w != remw; w = w->next) {
 257: 
 258:         if (w->kind == IsTransparent ||
 259:         w->ovs.left >= remw->ovs.right || remw->ovs.left >= w->ovs.right ||
 260:         w->ovs.top >= remw->ovs.bottom || remw->ovs.top >= w->ovs.bottom)
 261:         continue;
 262: 
 263:         new = NULL;
 264: 
 265:         oldr = &remw->visible;
 266:         while (r = *oldr) {
 267:         if (w->ovs.left >= r->right || r->left >= w->ovs.right ||
 268:             w->ovs.top >= r->bottom || r->top >= w->ovs.bottom) {
 269:             oldr = &r->next;
 270:         } else {
 271:             /* compute what remains */
 272:             oldr = Do_overlap (&w->ovs, oldr, &remw->visible);
 273:             remw->unobscured = OB_NOT;
 274:             /* get the piece it wants */
 275:             Clip_rectangle (r, &w->ovs);
 276:             /* remove it */
 277:             if (r->type != border_rec && remw->cmvisible)
 278:             Calc_overlaps ((RASTER *)r, &remw->cmvisible);
 279: 
 280:             /* give it to our elders too */
 281:             if (w->level > remw->level) {
 282:             ww = w;
 283:             while ((ww = ww->parent)->level >= remw->level) {
 284:                 RASTRECT(addrec, *(RASTER *) r, new_rec);
 285:                 addrec->next = ww->cmvisible;
 286:                 ww->cmvisible = addrec;
 287:             }
 288:             }
 289: 
 290:             /* If the rectangle enters the border of w, split it up */
 291: 
 292:             if (w->bwidth) {
 293:             if (r->left < w->vs.left) {
 294:                 if (r->right <= w->vs.left) {
 295:                 r->type = border_rec;
 296:                 r->next = new;
 297:                 new = r;
 298:                 continue;
 299:                 }
 300:                 NEWRECT(addrec, r->left, w->vs.left,
 301:                     r->top, r->bottom, border_rec);
 302:                 addrec->next = new;
 303:                 new = addrec;
 304:                 r->left = w->vs.left;
 305:             }
 306:             if (r->right > w->vs.right) {
 307:                 if (r->left >= w->vs.right) {
 308:                 r->type = border_rec;
 309:                 r->next = new;
 310:                 new = r;
 311:                 continue;
 312:                 }
 313:                 NEWRECT(addrec, w->vs.right, r->right,
 314:                     r->top, r->bottom, border_rec);
 315:                 addrec->next = new;
 316:                 new = addrec;
 317:                 r->right = w->vs.right;
 318:             }
 319:             if (r->top < w->vs.top) {
 320:                 if (r->bottom <= w->vs.top) {
 321:                 r->type = border_rec;
 322:                 r->next = new;
 323:                 new = r;
 324:                 continue;
 325:                 }
 326:                 NEWRECT(addrec, r->left, r->right,
 327:                     r->top, w->vs.top, border_rec);
 328:                 addrec->next = new;
 329:                 new = addrec;
 330:                 r->top = w->vs.top;
 331:             }
 332:             if (r->bottom > w->vs.bottom) {
 333:                 if (r->top >= w->vs.bottom) {
 334:                 r->type = border_rec;
 335:                 r->next = new;
 336:                 new = r;
 337:                 continue;
 338:                 }
 339:                 NEWRECT(addrec, r->left, r->right,
 340:                     w->vs.bottom, r->bottom, border_rec);
 341:                 addrec->next = new;
 342:                 new = addrec;
 343:                 r->bottom = w->vs.bottom;
 344:             }
 345:             }
 346: 
 347:             /* give it to ourselves too */
 348:             if (w->level >= remw->level) {
 349:             RASTRECT(addrec, *(RASTER *) r, new_rec);
 350:             addrec->next = w->cmvisible;
 351:             w->cmvisible = addrec;
 352:             }
 353: 
 354:             if (cleanup >= 0)
 355:             r->type = new_rec;
 356:             else
 357:             r->type = contents_rec;
 358:             r->next = new;
 359:             new = r;
 360:         }
 361:         }
 362: 
 363:         if (new) {
 364:         for (ww = w; ww->level >= remw->level; ww = ww->parent) {
 365:             /* find any new stuff and merge it */
 366:             addrec = NULL;
 367:             while ((r = ww->cmvisible) && r->type == new_rec) {
 368:             r->type = contents_rec;
 369:             ww->cmvisible = r->next;
 370:             r->next = addrec;
 371:             addrec = r;
 372:             }
 373:             if (addrec)
 374:             Merge_rectangles (addrec, &ww->cmvisible);
 375:         }
 376:         Merge_rectangles (new, &w->visible);
 377:         Windex (w);
 378:         if (cleanup > 0)
 379:             Draw_window (w, 0, 0);
 380:         else if (cleanup == 0)
 381:             w->unobscured = OB_TMP;
 382:         }
 383:     }
 384: }

Defined functions

Obscure_bottom defined in line 137; used 1 times
Obscure_top defined in line 24; used 1 times
Remove_rectangles defined in line 246; used 3 times

Defined variables

rcsid_obscure_c defined in line 11; never used
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1564
Valid CSS Valid XHTML 1.0 Strict