#include "win.h" /* Copyright (c) 1983 University of Maryland Computer Science Department */ /* Routines dealing with cover information */ /* Compute all windows that w covers or that cover w; place them on the appropriate list. */ WComputeCover (w) register Win *w; { register Win *wp; register after = 0; /* Initial windows cover w */ for (wp = WinList; wp; wp = wp -> w_next) { if (wp == w) after++;/* w covers remaining windows */ if (wp == w || (wp -> w_status & WHIDDEN)) continue; /* Do they overlap? */ if (w -> OXO + w -> OXE <= wp -> OXO) continue; if (w -> OYO + w -> OYE <= wp -> OYO) continue; if (w -> OXO >= wp -> OXO + wp -> OXE) continue; if (w -> OYO >= wp -> OYO + wp -> OYE) continue; /* Yes, they overlap */ if (after) /* w covers wp */ WDoCover (w, wp); else /* wp covers w */ WDoCover (wp, w); } } /* Window t covers window b. Update cover list and WINVIS bits. */ static WDoCover (t, b) register Win *t, *b; { register i, j; int i2, j2; register Cov *c; register Ch *cp; t -> w_status |= WCOVERING;/* This window is covering others */ b -> w_status |= WCOVERED;/* This window is covered by others */ for (c = WCovList; c; c = c -> c_next) { if (c -> c_top == t && c -> c_bot == b) { i = c -> c_area.xorigin; j = c -> c_area.yorigin; i2 = c -> c_area.xextent; j2 = c -> c_area.yextent; goto mark;/* ASSUMPTION: SAME INTERSECTION */ } } /* They didnt intersect before, but now they do */ c = (Cov *) malloc (sizeof (Cov)); c -> c_top = t; c -> c_bot = b; c -> c_next = WCovList; WCovList = c; /* Mark the chars in b that are covered by t */ i = Max (t -> OXO, b -> OXO); j = Max (t -> OYO, b -> OYO); i2 = Min (t -> OXO + t -> OXE, b -> OXO + b -> OXE) - i; j2 = Min (t -> OYO + t -> OYE, b -> OYO + b -> OYE) - j; i -= b -> OXO; j -= b -> OYO; /* (i,j),(i+i2,j+j2) are the upper left and lower right corners of the intersection of the two windows. Values are relative to b */ c -> c_area.xorigin = i; c -> c_area.yorigin = j; c -> c_area.xextent = i2; c -> c_area.yextent = j2; mark: cp = b -> w_winbuf + j * b -> OXE + i; for (j = 0; j < j2; j++) { for (i = 0; i < i2; i++) cp++ -> Mode |= WINVIS; cp += b -> OXE - i; } } /* Remove all information about window w from the cover list. This also un-invisbles all chars in w and all chars that w covered (which means that cover info is recomputed for windows that w covered). */ WRemoveCoverList (w) register Win *w; { register Cov *c, *cc, *nextc; char ostatus; if ((w -> w_status & (WCOVERED|WCOVERING)) == 0) return; /* Nothing needs to be done */ w -> w_status &= ~(WCOVERING|WCOVERED); ostatus = w -> w_status; w -> w_status |= WHIDDEN;/* Don't consider w in recomputations */ for (c = WCovList; c; c = nextc) { nextc = c -> c_next; if (c -> c_top == w) { if (c == WCovList) WCovList = nextc; else cc -> c_next = nextc; c -> c_bot -> w_status &= ~WCOVERED; WUnMarkCoverArea (c); WComputeCover (c -> c_bot);/* Recompute excl. w */ free (c); } else if (c -> c_bot == w) { if (c == WCovList) WCovList = nextc; else cc -> c_next = nextc; /* c -> c_top -> w_status &= ~WCOVERING; */ WUnMarkCoverArea (c); free (c); } else cc = c; } w -> w_status = ostatus; } /* Unmark chars in c->c_bot which used to be covered by c->c_top */ /* NOTE: CALL WComputeCover ON c->c_bot AFTERWARDS IF IT IS STILL AROUND */ static WUnMarkCoverArea (c) register Cov *c; { register i, j; int i2, j2; register Ch *cp; register Win *b = c -> c_bot; i2 = c -> c_area.yextent; j2 = c -> c_area.xextent; cp = b -> w_winbuf + c -> c_area.yorigin * b -> OXE + c -> c_area.xorigin; for (i = 0; i < i2; i++) { for (j = 0; j < j2; j++) cp++ -> Mode &= ~WINVIS; cp += b -> OXE - j; } b -> w_status |= WDUMP; }