|
|
1.1 ! root 1: #include "flayer.h" ! 2: ! 3: #define DELTA 10 ! 4: ! 5: static Flayer **llist; /* front to back */ ! 6: static int nllist; ! 7: static int nlalloc; ! 8: static Rectangle lDrect; ! 9: ! 10: Vis visibility(); ! 11: ! 12: flstart(r) ! 13: Rectangle r; ! 14: { ! 15: lDrect=r; ! 16: } ! 17: flnew(l, fn, u0, u1) ! 18: register Flayer *l; ! 19: uchar **(*fn)(); ! 20: char *u1; ! 21: { ! 22: if(nllist==nlalloc) ! 23: gcrealloc((char **)&llist, nllist*sizeof(Flayer **), ! 24: (nlalloc+=DELTA)*sizeof(Flayer **)); ! 25: l->textfn=fn; ! 26: l->user0=u0; ! 27: l->user1=u1; ! 28: llinsert(l); ! 29: } ! 30: Rectangle ! 31: flrect(l, r) ! 32: register Flayer *l; ! 33: Rectangle r; ! 34: { ! 35: l->entire=r; ! 36: l->scroll=inset(r, FLMARGIN); ! 37: r.origin.x= ! 38: l->scroll.corner.x=r.origin.x+FLMARGIN+FLSCROLLWID+(FLGAP-FLMARGIN); ! 39: return r; ! 40: } ! 41: flinit(l, r, ft) ! 42: register Flayer *l; ! 43: Rectangle r; ! 44: Font *ft; ! 45: { ! 46: lldelete(l); ! 47: llinsert(l); ! 48: l->visible=All; ! 49: l->origin=l->p0=l->p1=0; ! 50: frinit(&l->f, inset(flrect(l, r), FLMARGIN), ft, D); ! 51: newvisibilities(1); ! 52: rectf(D, l->entire, F_CLR); ! 53: scrdraw(l, 0L); ! 54: flborder(l, 0); ! 55: } ! 56: flclose(l) ! 57: register Flayer *l; ! 58: { ! 59: if(l->visible==All) ! 60: rectf(D, l->entire, F_CLR); ! 61: else if(l->visible==Some){ ! 62: if(l->f.b==0) ! 63: l->f.b=balloc(l->entire); ! 64: if(l->f.b){ ! 65: rectf(l->f.b, l->entire, F_CLR); ! 66: flrefresh(l, l->entire, 0); ! 67: } ! 68: } ! 69: frclear(&l->f); ! 70: lldelete(l); ! 71: if(l->f.b && l->visible!=All) ! 72: bfree(l->f.b); ! 73: l->textfn=0; ! 74: newvisibilities(1); ! 75: } ! 76: flborder(l, wide) ! 77: register Flayer *l; ! 78: { ! 79: if(flprepare(l)){ ! 80: border(l->f.b, l->entire, FLMARGIN, F_CLR); ! 81: border(l->f.b, l->entire, wide? FLMARGIN : 1, F_XOR); ! 82: if(l->visible==Some) ! 83: flrefresh(l, l->entire, 0); ! 84: } ! 85: } ! 86: Flayer * ! 87: flwhich(p) ! 88: Point p; ! 89: { ! 90: register i; ! 91: if(p.x==0 && p.y==0) ! 92: return nllist? llist[0] : 0; ! 93: for(i=0; i<nllist; i++) ! 94: if(ptinrect(p, llist[i]->entire)) ! 95: return llist[i]; ! 96: return 0; ! 97: } ! 98: flupfront(l) ! 99: register Flayer *l; ! 100: { ! 101: register v= (int)l->visible; ! 102: lldelete(l); ! 103: llinsert(l); ! 104: if(v!= (int)All) ! 105: newvisibilities(0); ! 106: } ! 107: newvisibilities(redraw) ! 108: int redraw; /* if false, we know it's a flupfront, and needn't ! 109: * redraw anyone becoming partially covered */ ! 110: { ! 111: register i; ! 112: register Vis ov; ! 113: register Flayer *l; ! 114: for(i=0; i<nllist; i++){ ! 115: l=llist[i]; ! 116: ov=l->visible; ! 117: l->visible=visibility(l); ! 118: #define V(a, b) ((((unsigned)a)<<2)|(((unsigned)b))) /* SUN fix */ ! 119: switch(V(ov, l->visible)){ ! 120: case V(Some, None): ! 121: bfree(l->f.b); ! 122: case V(All, None): ! 123: case V(All, Some): ! 124: l->f.b=0; ! 125: frclear(&l->f); ! 126: break; ! 127: case V(Some, Some): ! 128: if(l->f.b==0 && redraw) ! 129: case V(None, Some): ! 130: flprepare(l); ! 131: if(l->f.b && redraw){ ! 132: flrefresh(l, l->entire, 0); ! 133: bfree(l->f.b); ! 134: l->f.b=0; ! 135: frclear(&l->f); ! 136: } ! 137: case V(None, None): ! 138: case V(All, All): ! 139: break; ! 140: case V(Some, All): ! 141: if(l->f.b){ ! 142: bitblt(l->f.b, l->entire, D, l->entire.origin, F_STORE); ! 143: bfree(l->f.b); ! 144: l->f.b=D; ! 145: break; ! 146: } ! 147: case V(None, All): ! 148: flprepare(l); ! 149: break; ! 150: } ! 151: if(ov==None && l->visible!=None) ! 152: flnewlyvisible(l); ! 153: } ! 154: } ! 155: llinsert(l) ! 156: register Flayer *l; ! 157: { ! 158: register i; ! 159: for(i=nllist; i>0; --i) ! 160: llist[i]=llist[i-1]; ! 161: llist[0]=l; ! 162: nllist++; ! 163: } ! 164: lldelete(l) ! 165: register Flayer *l; ! 166: { ! 167: register i; ! 168: for(i=0; i<nllist; i++) ! 169: if(llist[i]==l){ ! 170: --nllist; ! 171: for(; i<nllist; i++) ! 172: llist[i]=llist[i+1]; ! 173: return; ! 174: } ! 175: panic("lldelete"); ! 176: } ! 177: flinsert(l, sp, p0) ! 178: register Flayer *l; ! 179: uchar **sp; ! 180: long p0; ! 181: { ! 182: if(flprepare(l)){ ! 183: frinsert(&l->f, sp, (Posn)(p0-l->origin)); ! 184: scrdraw(l, scrtotal(l)); ! 185: if(l->visible==Some) ! 186: flrefresh(l, l->entire, 0); ! 187: } ! 188: } ! 189: fldelete(l, p0, p1) ! 190: register Flayer *l; ! 191: long p0, p1; ! 192: { ! 193: if(flprepare(l)){ ! 194: frdelete(&l->f, (Posn)(p0-l->origin), (Posn)(p1-l->origin)); ! 195: scrdraw(l, scrtotal(l)); ! 196: if(l->visible==Some) ! 197: flrefresh(l, l->entire, 0); ! 198: } ! 199: } ! 200: flselect(l) ! 201: register Flayer *l; ! 202: { ! 203: register ret=0; ! 204: if(l->visible!=All) ! 205: flupfront(l); ! 206: Sselect(&l->f); ! 207: if(l->f.p0==l->f.p1){ ! 208: if(realtime()-l->click<Clicktime && l->f.p0+l->origin==l->p0){ ! 209: ret=1; ! 210: l->click=0; ! 211: }else ! 212: l->click=realtime(); ! 213: }else ! 214: l->click=0; ! 215: l->p0=l->f.p0+l->origin, l->p1=l->f.p1+l->origin; ! 216: return ret; ! 217: } ! 218: flsetselect(l, p0, p1) ! 219: register Flayer *l; ! 220: long p0, p1; ! 221: { ! 222: Posn fp0, fp1; ! 223: l->click=0; ! 224: if(l->visible==None || !flprepare(l)){ ! 225: l->p0=p0, l->p1=p1; ! 226: return; ! 227: } ! 228: l->p0=p0, l->p1=p1; ! 229: flfp0p1(l, &fp0, &fp1); ! 230: if(fp0==l->f.p0 && fp1==l->f.p1) ! 231: return; ! 232: selectp(&l->f, F_XOR); ! 233: l->f.p0=fp0, l->f.p1=fp1; ! 234: selectp(&l->f, F_XOR); ! 235: if(l->visible==Some) ! 236: flrefresh(l, l->entire, 0); ! 237: } ! 238: flfp0p1(l, pp0, pp1) ! 239: register Flayer *l; ! 240: register Posn *pp0, *pp1; ! 241: { ! 242: register long p0=l->p0-l->origin, p1=l->p1-l->origin; ! 243: if(p0<0) ! 244: p0=0; ! 245: if(p1<0) ! 246: p1=0; ! 247: if(p0>l->f.nchars) ! 248: p0=l->f.nchars; ! 249: if(p1>l->f.nchars) ! 250: p1=l->f.nchars; ! 251: *pp0=p0, *pp1=p1; ! 252: } ! 253: Rectangle ! 254: rscale(r, old, new) ! 255: Rectangle r; ! 256: Point old, new; ! 257: { ! 258: r.origin.x=muldiv(r.origin.x, new.x, old.x); ! 259: r.origin.y=muldiv(r.origin.y, new.y, old.y); ! 260: r.corner.x=muldiv(r.corner.x, new.x, old.x); ! 261: r.corner.y=muldiv(r.corner.y, new.y, old.y); ! 262: return r; ! 263: } ! 264: flreshape(dr) ! 265: Rectangle dr; ! 266: { ! 267: register i; ! 268: register Flayer *l; ! 269: register Frame *f; ! 270: Rectangle r; ! 271: for(i=0; i<nllist; i++){ ! 272: l=llist[i]; ! 273: f= &l->f; ! 274: r=raddp(rscale(rsubp(l->entire, lDrect.origin), ! 275: sub(lDrect.corner, lDrect.origin), ! 276: sub(dr.corner, dr.origin)), dr.origin); ! 277: if(l->visible==Some && f->b){ ! 278: bfree(f->b); ! 279: frclear(f); ! 280: } ! 281: f->b=0; ! 282: if(P->state&RESHAPED){ ! 283: if(l->visible==All) ! 284: f->b=D; ! 285: }else{ ! 286: if(l->visible!=None) ! 287: frclear(f); ! 288: if(!rectclip(&r, dr)) ! 289: panic("flreshape"); ! 290: if(r.corner.x-r.origin.x<100) ! 291: r.origin.x=dr.origin.x; ! 292: if(r.corner.x-r.origin.x<100) ! 293: r.corner.x=dr.corner.x; ! 294: if(r.corner.y-r.origin.y<40) ! 295: r.origin.y=dr.origin.y; ! 296: if(r.corner.y-r.origin.y<40) ! 297: r.corner.x=dr.corner.x; ! 298: l->visible=None; ! 299: } ! 300: frsetrects(f, inset(flrect(l, r), FLMARGIN), f->b); ! 301: } ! 302: lDrect=dr; ! 303: if(!(P->state&RESHAPED)) ! 304: newvisibilities(1); ! 305: } ! 306: flprepare(l) ! 307: register Flayer *l; ! 308: { ! 309: register Frame *f= &l->f; ! 310: register long n; ! 311: if(l->visible==None) ! 312: return 0; ! 313: if(f->b==0){ ! 314: if(l->visible==All){ ! 315: f->b=D; ! 316: rectf(D, l->entire, F_CLR); ! 317: }else if((f->b=balloc(l->entire))==0) ! 318: return 0; ! 319: border(f->b, l->entire, l==llist[0]? FLMARGIN : 1, F_XOR); ! 320: n=f->nchars; ! 321: frinit(f, f->entire, f->font, f->b); ! 322: frinsert(f, (*l->textfn)(l, n), (Posn)0); ! 323: selectp(f, F_XOR); ! 324: flfp0p1(l, &l->f.p0, &l->f.p1); ! 325: selectp(f, F_XOR); ! 326: scrdraw(l, scrtotal(l)); ! 327: } ! 328: return 1; ! 329: } ! 330: static somevis, someinvis, justvis; ! 331: Vis ! 332: visibility(l) ! 333: register Flayer *l; ! 334: { ! 335: somevis=someinvis=0; ! 336: justvis=1; ! 337: flrefresh(l, l->entire, 0); ! 338: justvis=0; ! 339: if(somevis==0) ! 340: return None; ! 341: if(someinvis==0) ! 342: return All; ! 343: return Some; ! 344: } ! 345: flrefresh(l, r, i) ! 346: register Flayer *l; ! 347: Rectangle r; ! 348: { ! 349: register Flayer *t; ! 350: Rectangle s; ! 351: Top: ! 352: if((t=llist[i++])==l){ ! 353: if(!justvis) ! 354: bitblt(l->f.b, r, D, r.origin, F_STORE); ! 355: somevis=1; ! 356: }else{ ! 357: if(!rectXrect(t->entire, r)) ! 358: goto Top; /* avoid stacking unnecessarily */ ! 359: if(t->entire.origin.x>r.origin.x){ ! 360: s=r; ! 361: s.corner.x=t->entire.origin.x; ! 362: flrefresh(l, s, i); ! 363: r.origin.x=t->entire.origin.x; ! 364: } ! 365: if(t->entire.origin.y>r.origin.y){ ! 366: s=r; ! 367: s.corner.y=t->entire.origin.y; ! 368: flrefresh(l, s, i); ! 369: r.origin.y=t->entire.origin.y; ! 370: } ! 371: if(t->entire.corner.x<r.corner.x){ ! 372: s=r; ! 373: s.origin.x=t->entire.corner.x; ! 374: flrefresh(l, s, i); ! 375: r.corner.x=t->entire.corner.x; ! 376: } ! 377: if(t->entire.corner.y<r.corner.y){ ! 378: s=r; ! 379: s.origin.y=t->entire.corner.y; ! 380: flrefresh(l, s, i); ! 381: r.corner.y=t->entire.corner.y; ! 382: } ! 383: /* remaining piece of r is blocked by t; forget about it */ ! 384: someinvis=1; ! 385: } ! 386: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.