|
|
1.1 ! root 1: #include "univ.h" ! 2: #define PADBORDER 3 ! 3: #define CHARWIDTH fontwidth(&defont) ! 4: ! 5: Line *Lsent; ! 6: Rectangle Trect; ! 7: Attrib Attributes; ! 8: int CharsWide; ! 9: Line FakeLine; ! 10: Bitmap *Osbm; ! 11: char Tilde; ! 12: ! 13: DoubleOutline(b,r) ! 14: register Bitmap *b; ! 15: Rectangle r; ! 16: { ! 17: outline(b,r); ! 18: outline(b,inset(r,1)); ! 19: } ! 20: ! 21: HeavyBorder( p ) ! 22: register Pad *p; ! 23: { ! 24: DoubleOutline( &display, inset(p->rect,PADBORDER+1) ); ! 25: } ! 26: ! 27: Line *Linei(i) ! 28: register i; ! 29: { ! 30: register Line *lsent = Lsent, *l; ! 31: register long ct = 1, k = lsent->key; ! 32: Line fake; ! 33: ! 34: if( !i ) return lsent; ! 35: for( l = lsent->down; l != lsent; l = l->down, ++ct ) ! 36: if( k ? (l->key==i) : (ct==i) ) ! 37: return l; ! 38: if( k && i<=k ){ ! 39: FakeLine.key = i; ! 40: *(FakeLine.text = itoa((int)i)) = Tilde; ! 41: return &FakeLine; ! 42: } ! 43: return 0; ! 44: } ! 45: ! 46: Trunc(l) ! 47: Line *l; ! 48: { ! 49: int a; ! 50: return (a=l->attributes)&(FOLD|TRUNCATE) ? a&TRUNCATE : Attributes&TRUNCATE; ! 51: } ! 52: ! 53: int Expanded; ! 54: short Tabs = 8; ! 55: Expand( blanks, tabs ) ! 56: register char *blanks, *tabs; ! 57: { ! 58: register int i, c; ! 59: ! 60: for( i = 0; (c = *tabs++) && i<250; ) ! 61: if( c == '\t' ) ! 62: do ! 63: blanks[i++] = ' '; ! 64: while( i % Tabs ); ! 65: else ! 66: blanks[i++] = c; ! 67: if( i==0 ) blanks[i++] = ' '; ! 68: blanks[i] = '\0'; ! 69: Expanded = i; ! 70: } ! 71: ! 72: Needs(i) ! 73: { ! 74: register Line *l = Linei(i); ! 75: char blanks[256]; ! 76: ! 77: if( Trunc(l) ) return 1; ! 78: Expand( blanks, l->text ); ! 79: return 1 + (Expanded-1)/CharsWide; ! 80: } ! 81: ! 82: #define BARWIDTH 10 ! 83: static Rectangle bar; ! 84: ! 85: int ClipPaint(clip,p) /* nobody said it would be easy */ ! 86: register Pad *p; ! 87: Rectangle clip; ! 88: { ! 89: register middle, lines, lo, hi, capacity; ! 90: int change, i, selpainted; ! 91: register Line *lsent, *l; ! 92: char save, *terminate, blanks[256]; ! 93: Point pt; ! 94: ! 95: Tabs = p->tabs; ! 96: Attributes = p->attributes; ! 97: Tilde = Attributes&NO_TILDE ? 0 : '~'; ! 98: Lsent = lsent = &p->sentinel; ! 99: if( !PadSized(p->rect) ) return 1; ! 100: ! 101: p->srect = Trect = inset( p->rect, PADBORDER+4 ); ! 102: p->srect.corner.x = (Trect.origin.x += BARWIDTH); ! 103: Trect.origin.x += 2; ! 104: p->srect.origin.y -= 1; ! 105: p->srect.corner.y += 1; ! 106: p->srect.origin.x -= 1; ! 107: ! 108: capacity = (Trect.corner.y-Trect.origin.y) / ! 109: fontheight(&defont); ! 110: CharsWide = (Trect.corner.x-Trect.origin.x) / CHARWIDTH - 1; ! 111: ! 112: middle = lines = 0; ! 113: for( l = lsent->down; l != lsent; l = l->down ){ ! 114: ++lines; ! 115: if( l == Selected.line && rectinrect(p->rect,clip) ) ! 116: middle = lsent->key ? Selected.line->key : lines; ! 117: } ! 118: if( lsent->key ) lines = lsent->key; ! 119: if( Scrolly ){ ! 120: Scrolly -= p->srect.origin.y; ! 121: middle = 1 + ! 122: muldiv(Scrolly,lines,p->srect.corner.y-p->srect.origin.y); ! 123: if( middle > lines ) middle = lines; ! 124: } ! 125: if( !middle ){ ! 126: middle = (p->lo+p->hi)/2; ! 127: if( middle<1 || middle>lines ) ! 128: middle = lsent->key ? 1 : lines; ! 129: } ! 130: lo = middle+1; ! 131: hi = middle; ! 132: do { ! 133: change = 0; ! 134: if( lo>0 && capacity>=Needs(lo-1)){ ! 135: capacity -= Needs(--lo); ! 136: change = 1; ! 137: } ! 138: if( hi<lines && capacity>=Needs(hi+1)){ ! 139: capacity -= Needs(++hi); ! 140: change = 1; ! 141: } ! 142: } while( change ); ! 143: if( lo>hi ){ ! 144: Selected.line = 0; ! 145: return 1; ! 146: } ! 147: if( Scrolly && lo==p->lo && hi==p->hi ) return 1; ! 148: p->lo = lo; ! 149: p->hi = hi; ! 150: for( l = lsent->down; l != lsent; l = l->down ) ! 151: l->rect = ZRectangle; ! 152: if( Osbm && !eqrect(Osbm->rect,p->rect) && Osbm!=&display ){ ! 153: bfree(Osbm); ! 154: Osbm = 0; ! 155: } ! 156: if( !Osbm && !(Osbm = balloc(p->rect)) ) Osbm = &display; ! 157: rectf( Osbm, p->rect, F_CLR ); ! 158: DoubleOutline( Osbm, inset(p->rect, PADBORDER-1) ); ! 159: if( p == Current ) DoubleOutline( Osbm, inset(p->rect,PADBORDER+1) ); ! 160: rectf( Osbm, bar = scrollbar(p->srect,lo,hi+1,0,lines+1), F_XOR ); ! 161: pt = Trect.origin; ! 162: selpainted = 0; ! 163: for( ; lo <= hi; ++lo ){ ! 164: l = Linei(lo); ! 165: l->rect.origin = pt; ! 166: Expand( blanks, l->text ); ! 167: for( i = 0; i < Expanded; i += CharsWide ){ ! 168: if( i ){ ! 169: if( Trunc(l) ) break; ! 170: pt.x += CHARWIDTH; ! 171: } ! 172: save = '\0'; ! 173: if( i+CharsWide < Expanded ){ ! 174: save = *(terminate=blanks+i+CharsWide); ! 175: *terminate = '\0'; ! 176: } ! 177: string( &defont, blanks+i, Osbm, pt, F_OR ); ! 178: pt.x = Trect.origin.x; ! 179: l->rect.corner.y = (pt.y += fontheight(&defont)); ! 180: l->rect.corner.x = Trect.corner.x; ! 181: if( save ) *terminate = save; ! 182: } ! 183: if( Selected.line == l ){ ! 184: rectf( Osbm, l->rect, F_XOR ); /* LineXOR(l); */ ! 185: selpainted = 1; ! 186: } ! 187: } ! 188: if( !selpainted && Selected.pad == p ) Selected.line = 0; ! 189: if( !Scrolly ) RequestLines(p); ! 190: if( Osbm != &display ) ! 191: { ! 192: Rectangle clipsrc; ! 193: clipsrc = clip; ! 194: rectclip(&clipsrc,Osbm->rect); ! 195: PadBlt( Osbm, clipsrc, p->front ); ! 196: return 1; ! 197: /* bitblt( Osbm, clipsrc, &display, clipsrc.origin, F_STORE );*/ ! 198: } ! 199: return 0; ! 200: } ! 201: ! 202: #define rc (r.corner) ! 203: #define ro (r.origin) ! 204: #define pc (p->rect.corner) ! 205: #define po (p->rect.origin) ! 206: ! 207: PadBlt(b,r,p) ! 208: register Bitmap *b; ! 209: Rectangle r; ! 210: register Pad *p; ! 211: { ! 212: extern Pad Sentinel; ! 213: ! 214: if( p == &Sentinel ){ ! 215: bitblt( b, r, &display, r.origin, F_STORE ); ! 216: return; ! 217: } ! 218: if( !rectXrect(p->rect, r) ){ ! 219: PadBlt( b, r, p->front ); ! 220: return; ! 221: } ! 222: if(ro.y < po.y){ ! 223: PadBlt( b, Rpt(ro,Pt(rc.x,po.y)), p->front ); ! 224: ro.y = po.y; ! 225: } ! 226: if(rc.y > pc.y){ ! 227: PadBlt( b, Rpt(Pt(ro.x,pc.y),rc), p->front ); ! 228: rc.y = pc.y; ! 229: } ! 230: if(ro.x < po.x){ ! 231: PadBlt( b, Rpt(ro,Pt(po.x,rc.y)), p->front ); ! 232: ro.x = po.x; ! 233: } ! 234: if(rc.x > pc.x){ ! 235: PadBlt( b, Rpt(Pt(pc.x,ro.y),rc), p->front ); ! 236: rc.x = pc.x; ! 237: } ! 238: } ! 239: ! 240: Paint(p) ! 241: Pad *p; ! 242: { ! 243: ClipPaint(p->rect,p); ! 244: } ! 245: ! 246: LineReq(p, lo, hi, fake) ! 247: register Pad *p; ! 248: register long lo, hi; ! 249: { ! 250: Line *InsPos(); ! 251: ! 252: if( lo == 0 ) lo = 1; ! 253: if( !p || !p->object || hi < lo ) return; ! 254: PutRemote( P_LINEREQ ); ! 255: SendLong( p->object ); ! 256: SendLong( p->object ); ! 257: SendLong( lo ); ! 258: SendLong( hi ); ! 259: if( fake ) ! 260: for( FakeLine.key = lo; FakeLine.key <= hi; ++FakeLine.key ){ ! 261: *(FakeLine.text = itoa((int)FakeLine.key)) = Tilde; ! 262: InsAbove(InsPos(p,&FakeLine),&FakeLine); ! 263: } ! 264: } ! 265: ! 266: CRequestLines(p) ! 267: register Pad *p; ! 268: { ! 269: register Line *l; ! 270: register reqhi = -1, reqlo = 0, k, i; ! 271: ! 272: for( i = p->lo; i <= p->hi; ++i ){ ! 273: l = Linei(i); ! 274: k = l->key; ! 275: if( l->attributes&FAKELINE ){ ! 276: l->attributes &= ~FAKELINE; ! 277: if( k == reqhi+1 ) ! 278: reqhi = k; ! 279: else { ! 280: LineReq(p, reqlo, reqhi, 0); ! 281: reqlo = reqhi = k; ! 282: } ! 283: } ! 284: } ! 285: LineReq(p, reqlo, reqhi, 0); ! 286: } ! 287: ! 288: RequestLines(p) ! 289: register Pad *p; ! 290: { ! 291: register Line *lsent = Lsent, *l; ! 292: register reqlo, cutlo, cuthi, k, cushion; ! 293: ! 294: if( !lsent || !p ) return; ! 295: if( !lsent->key ){ ! 296: if( p->attributes&FAKELINE ) ! 297: CRequestLines(p); ! 298: return; ! 299: } ! 300: cushion = Configuration&BIGMEMORY ? 1000 : 10; ! 301: reqlo = p->lo; ! 302: cutlo = p->lo - cushion; ! 303: cuthi = p->hi + cushion; ! 304: for( l = lsent->down; l != lsent; l = l->down ){ ! 305: k = l->key; ! 306: if( k>=reqlo && k<=p->hi ){ ! 307: LineReq(p, reqlo, k-1, 1); ! 308: reqlo = k+1; ! 309: } else if( k<cutlo || k>cuthi ) ! 310: DelLine(l); ! 311: } ! 312: LineReq(p, reqlo, p->hi, 1); ! 313: ! 314: } ! 315: ! 316: Pointing() ! 317: { ! 318: register Pad *p = PickPad(mouse.xy); ! 319: register Line *l, *ll, *lsent = &p->sentinel, *sel; ! 320: register int i, paint = 0; ! 321: Point pt, ppt; ! 322: extern Rectangle KBDrect; ! 323: ! 324: if( ptinrect(mouse.xy, KBDrect) ) return; ! 325: if( !p ){ ! 326: Select( (Line*)0, (Pad*)0 ); ! 327: SetCurrent( (Pad *)0 ); ! 328: return; ! 329: } ! 330: if( p != Current ){ ! 331: MakeCurrent(p); ! 332: while( butts==BUTT1 ) jnap(2); /* for rollover */ ! 333: return; ! 334: } ! 335: pt = mouse.xy; ! 336: for( ; butts==BUTT1; jnap(2)){ ! 337: paint = 0; ! 338: ppt = pt; ! 339: pt = mouse.xy; ! 340: if( ptinrect(pt,p->srect) ){ ! 341: if( !ptinrect(ppt,p->srect) && ptinrect(ppt,p->rect) ){ ! 342: pt.y = (bar.origin.y+bar.corner.y)/2; ! 343: cursset( pt ); ! 344: } ! 345: Scrolly = pt.y; ! 346: Paint(p); ! 347: } else { ! 348: sel = 0; ! 349: for( l = lsent->down, i = 1; l!=lsent ; l = l->down, ++i ){ ! 350: if( ptinrect( mouse.xy, l->rect ) ){ ! 351: sel = l; ! 352: break; ! 353: } ! 354: } ! 355: Select( sel, p); ! 356: if( sel ) ! 357: if( p->sentinel.key ! 358: ? (sel->key == p->lo || sel->key == p->hi ) ! 359: : (i == p->lo || i == p->hi) ){ ! 360: paint = 1; ! 361: Scrolly = 0; ! 362: } ! 363: } ! 364: } ! 365: if( paint ) ! 366: Paint(p); ! 367: if( Scrolly ){ ! 368: Scrolly = 0; ! 369: RequestLines(p); ! 370: } ! 371: } ! 372:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.