|
|
1.1 ! root 1: #include "univ.h" ! 2: Selection Selected; ! 3: Pad *Current; ! 4: long HostObject; ! 5: long HostParent; ! 6: short Scrolly; ! 7: Point Zpoint; ! 8: Rectangle ZRectangle; ! 9: Pad *DirtyPad; ! 10: ! 11: Pad Sentinel = { 0, 0, 0, 0, 0, &Sentinel, &Sentinel }; ! 12: Rectangle PadSpace; ! 13: Rectangle KBDrect; ! 14: Attrib NewFold; ! 15: ! 16: #define ISPAD(p) ((p) != &Sentinel) ! 17: #define ISLINE(l,p) ((l) != &(p)->sentinel) /* used how much? */ ! 18: ! 19: Point PickPoint(s) ! 20: char *s; ! 21: { ! 22: char *pick = "pick window: "; ! 23: Point p; ! 24: cursswitch(&Bullseye); ! 25: if( s ) InvertKBDrect( pick, s ); ! 26: while( !button123() ) waitMOUSE(); ! 27: p = (butts==BUTT2 || butts==BUTT3) ? mouse.xy: Zpoint; ! 28: cursswitch( Pcursor ); ! 29: PaintKBD(); ! 30: return p; ! 31: } ! 32: ! 33: #define MINWD 50 ! 34: #define MINHT 50 ! 35: PadSized( r ) ! 36: Rectangle r; ! 37: { ! 38: return r.corner.x-r.origin.x > MINWD && r.corner.y-r.origin.y > MINHT; ! 39: } ! 40: ! 41: #define SWEEP 125 ! 42: int SWEEPTIMEOUT = 1000*15; ! 43: Rectangle clipgetrect(s) ! 44: register char *s; ! 45: { ! 46: Rectangle r, r1; ! 47: register long start; ! 48: Point p1, p2; ! 49: ! 50: if( s ) InvertKBDrect( "sweep ", s ); ! 51: for( start = realtime(); ; jnap(2) ){ ! 52: if( ptinrect(mouse.xy, inset(PadSpace,-SWEEP)) ) ! 53: break; ! 54: if( realtime()>start+SWEEPTIMEOUT ){ ! 55: r = Drect; ! 56: while( PadSized(r1= inset(r,1)) ) ! 57: r = r1; ! 58: goto TimedOut; ! 59: } ! 60: } ! 61: r = getrect23(); ! 62: if( r.corner.x && r.corner.x-r.origin.x<=5 && r.corner.y-r.origin.y<=5 ) ! 63: r = Drect; /* from jim */ ! 64: TimedOut: ! 65: PaintKBD(); ! 66: if( !rectclip( &r, PadSpace ) ) return ZRectangle; ! 67: return r; ! 68: } ! 69: ! 70: DelLine( l ) ! 71: register Line *l; ! 72: { ! 73: assert( l && l->down && l->up ); ! 74: ! 75: if( Selected.line == l ) Selected.line = 0; ! 76: l->down->up = l->up; ! 77: l->up->down = l->down; ! 78: gcfree( l->text ); ! 79: free( l ); ! 80: } ! 81: ! 82: Line *InsAbove(l, t) ! 83: register Line *l; ! 84: register Line *t; ! 85: { ! 86: register Line *n; ! 87: ! 88: assert( l && l->down && l->up ); ! 89: if( !t->text ) return 0; /* || !t->text[0] allow */ ! 90: n = salloc(Line); ! 91: *n = *t; ! 92: GCString(&n->text, t->text); ! 93: n->down = l; ! 94: n->up = l->up; ! 95: l->up->down = n; ! 96: l->up = n; ! 97: return n; ! 98: } ! 99: ! 100: Line *InsPos(p, tk) ! 101: register Pad *p; ! 102: register Line *tk; ! 103: { ! 104: register Line *l = &p->sentinel; ! 105: ! 106: assert( p && tk ); ! 107: if( (p->attributes&SORTED) && tk->text ){ ! 108: while( ISLINE(l->up,p) && !dictorder(l->up->text,tk->text) ) ! 109: l = l->up; ! 110: } else { ! 111: while( ISLINE(l->up,p) && l->up->key > tk->key ) ! 112: l = l->up; ! 113: } ! 114: return l; ! 115: } ! 116: ! 117: CreateLine(p) ! 118: register Pad *p; ! 119: { ! 120: register long lo, hi, k; ! 121: register Line *inspos, *l; ! 122: Line fake; ! 123: register char tilde; ! 124: ! 125: lo = RcvLong(); ! 126: hi = RcvLong(); ! 127: if( p->sentinel.key || p->attributes&SORTED ) return; ! 128: tilde = p->attributes&NO_TILDE ? 0 : '~'; ! 129: for( k = lo; k <= hi; ++k ) if( k ){ ! 130: fake.key = k; ! 131: fake.carte = 0; ! 132: fake.attributes = FAKELINE; ! 133: fake.text = itoa(k); ! 134: *fake.text = tilde; ! 135: inspos = InsPos(p, &fake); ! 136: if( inspos->up->key == k ) ! 137: DelLine( inspos->up ); ! 138: InsAbove(inspos, &fake); ! 139: p->attributes |= FAKELINE; ! 140: Dirty(p); ! 141: } ! 142: } ! 143: ! 144: PutLine(p,op) ! 145: register Pad *p; ! 146: Protocol op; ! 147: { ! 148: static Line prevrcvd; ! 149: Line rcvd; ! 150: char text[256]; /* 256 ? */ ! 151: register Line *l, *inspos; ! 152: ! 153: rcvd = prevrcvd; ! 154: rcvd.object = RcvLong(); ! 155: if( op == P_NEXTLINE ) ! 156: rcvd.key = ++prevrcvd.key; ! 157: else { ! 158: rcvd.key = RcvLong(); ! 159: rcvd.carte = RcvShort(); ! 160: rcvd.attributes = RcvShort(); ! 161: prevrcvd = rcvd; ! 162: } ! 163: RcvString(rcvd.text = text); ! 164: if( !p ) return; ! 165: if( p->sentinel.key && rcvd.key>p->sentinel.key ) return; ! 166: inspos = InsPos(p, &rcvd); ! 167: { ! 168: extern Script ObjScript; ! 169: rcvd.phit = ObjScript.prevhit; ! 170: rcvd.ptop = ObjScript.prevtop; ! 171: } ! 172: if( rcvd.attributes&SELECTLINE ) MakeCurrent(p); ! 173: for( l = p->sentinel.up; ISLINE(l,p); l = l->up ){ ! 174: if( l->key == rcvd.key ){ ! 175: if( l == Selected.line ) ! 176: rcvd.attributes |= SELECTLINE; ! 177: if( !strcmp(rcvd.text, l->text) ! 178: && rcvd.object == l->object ! 179: && rcvd.carte == l->carte ! 180: && rcvd.attributes == l->attributes ! 181: && !(rcvd.attributes&SELECTLINE) ) ! 182: return; ! 183: inspos = l->down; ! 184: if( NewFold = l->attributes & (FOLD|TRUNCATE) ) ! 185: FoldToggle( &rcvd.attributes ); ! 186: rcvd.phit = l->phit; ! 187: rcvd.ptop = l->ptop; ! 188: DelLine( l ); ! 189: break; ! 190: } ! 191: } ! 192: l = InsAbove(inspos, &rcvd); ! 193: if( !(rcvd.attributes&DONT_DIRTY) ) Dirty(p); ! 194: if( l && rcvd.attributes&SELECTLINE ){ /* selected <= "" !! */ ! 195: Selected.line = l; ! 196: Selected.pad = p; ! 197: Paint(p); ! 198: } ! 199: } ! 200: ! 201: SetCurrent( p ) ! 202: register Pad *p; ! 203: { ! 204: if( Current ) HeavyBorder(Current); ! 205: if( Current = p ) HeavyBorder( p ); ! 206: } ! 207: ! 208: PaintCurrent() ! 209: { ! 210: if( Current ) Paint(Current); ! 211: } ! 212: ! 213: LineXOR( l ) ! 214: Line *l; ! 215: { ! 216: rectf( &display, l->rect, F_XOR ); ! 217: } ! 218: ! 219: Cover Covered( p ) /* should be smarter */ ! 220: register Pad *p; ! 221: { ! 222: register Pad *f; ! 223: ! 224: for( f = p->front; ISPAD(f); f = f->front ) ! 225: if( rectinrect( p->rect, f->rect ) ) return COMPLETE; ! 226: for( f = p->front; ISPAD(f); f = f->front ) ! 227: if( rectXrect( p->rect, f->rect ) ) return PARTIAL; ! 228: return CLEAR; ! 229: } ! 230: ! 231: Dirty(p) ! 232: Pad *p; ! 233: { ! 234: if( p == DirtyPad ) return; ! 235: if( DirtyPad && Covered(DirtyPad)!=COMPLETE ) ! 236: if( !ClipPaint(DirtyPad->rect, DirtyPad) ) ! 237: PaintForward( DirtyPad->rect, DirtyPad->front ); ! 238: DirtyPad = p; ! 239: } ! 240: ! 241: Linkin(p) ! 242: register Pad *p; ! 243: { ! 244: SetCurrent( (Pad *) 0 ); ! 245: p->back = Sentinel.back; ! 246: p->back->front = p; ! 247: p->front = &Sentinel; ! 248: Sentinel.back = p; ! 249: if( PadSized(p->rect) ) SetCurrent(p); ! 250: } ! 251: ! 252: Unlink(p) ! 253: register Pad *p; ! 254: { ! 255: if( p == Current ) SetCurrent( (Pad *) 0 ); ! 256: p->back->front = p->front; ! 257: p->front->back = p->back; ! 258: p->front = p->back = 0; /* redundant - but caught an mcc bug! */ ! 259: } ! 260: ! 261: FrontLink(p) ! 262: register Pad *p; ! 263: { ! 264: if( !p ) return; ! 265: Unlink(p); ! 266: Linkin(p); ! 267: } ! 268: ! 269: PaintForward( r, p ) ! 270: Rectangle r; ! 271: register Pad *p; ! 272: { ! 273: for( ; p != &Sentinel; p = p->front ){ ! 274: if( rectXrect(r, p->rect) && Covered(p)!=COMPLETE ){ ! 275: if( !ClipPaint( r, p ) ) ! 276: r = boundrect(r,p->rect); ! 277: } ! 278: jerqsync(); ! 279: } ! 280: } ! 281: ! 282: Refresh( r ) ! 283: Rectangle r; ! 284: { ! 285: rectf( &display, r, F_CLR ); ! 286: PaintForward( r, Sentinel.front ); ! 287: } ! 288: ! 289: char NewString[] = "<new>"; ! 290: ! 291: void P_Define( p, o ) ! 292: register Pad *p; ! 293: long o; ! 294: { ! 295: if( !p ){ ! 296: p = salloc(Pad); /* zeros */ ! 297: p->sentinel.up = p->sentinel.down = &p->sentinel; ! 298: p->sentinel.ptop = 255; ! 299: Linkin(p); ! 300: p->object = o; ! 301: p->name = NewString; ! 302: p->sentinel.text = NewString; ! 303: p->tabs = 8; ! 304: p->selkey = 0; ! 305: } ! 306: Dirty(p); ! 307: } ! 308: ! 309: void P_Carte(p) ! 310: register Pad *p; ! 311: { ! 312: register Index i = RcvShort(); ! 313: if( p && p->object ) p->carte = i; ! 314: } ! 315: ! 316: void P_Lines(p) ! 317: register Pad *p; ! 318: { ! 319: register long k = RcvLong(); ! 320: if( p ){ ! 321: if( k < p->sentinel.key ) DelLines(p); ! 322: p->sentinel.key = k; ! 323: Dirty(p); ! 324: } ! 325: } ! 326: ! 327: void P_Banner(p) ! 328: register Pad *p; ! 329: { ! 330: char b[256]; ! 331: ! 332: RcvString(b); ! 333: if( p ){ ! 334: if( p->sentinel.text != NewString ) gcfree( p->sentinel.text ); ! 335: GCString( &p->sentinel.text, b ); ! 336: Dirty(p); ! 337: } ! 338: } ! 339: ! 340: void P_Name(p) ! 341: register Pad *p; ! 342: { ! 343: char n[256]; ! 344: ! 345: RcvString(n); ! 346: if( p ){ ! 347: if( p->name != NewString ) gcfree( p->name ); ! 348: GCString( &p->name, n ); ! 349: } ! 350: } ! 351: ! 352: void P_Attributes(p) ! 353: register Pad *p; ! 354: { ! 355: register Attrib a = RcvShort(); ! 356: if( p ) p->attributes = a; ! 357: } ! 358: ! 359: void P_Tabs(p) ! 360: register Pad *p; ! 361: { ! 362: register short t = RcvShort(); ! 363: if( p && t>0 && t<128 ) p->tabs = t; ! 364: Dirty(p); ! 365: } ! 366: ! 367: void P_RemoveLine(p) ! 368: register Pad *p; ! 369: { ! 370: register long k = RcvLong(); ! 371: register Line *l; ! 372: ! 373: if( !p ) return; ! 374: for( l = p->sentinel.up; ISLINE(l,p); l = l->up ){ ! 375: if( l->key == k ){ ! 376: DelLine( l ); ! 377: Dirty(p); ! 378: return; ! 379: } ! 380: } ! 381: ! 382: } ! 383: ! 384: ! 385: Pad *ObjToPad(o) ! 386: register long o; ! 387: { ! 388: register Pad *p; ! 389: ! 390: for( p = Sentinel.back; ISPAD(p); p = p->back ) ! 391: if( p->object == o ) return p; ! 392: return 0; ! 393: } ! 394: ! 395: Cycle() ! 396: { ! 397: register Pad *p; ! 398: int active = 0; ! 399: ! 400: for( p = Sentinel.back; ISPAD(p); p = p->back ){ ! 401: if( p->ticks>0 ){ ! 402: active++; ! 403: if( --p->ticks == 0 ){ ! 404: active--; ! 405: HostParent = HostObject = p->object; ! 406: ToHost( P_CYCLE /*, garbage */ ); ! 407: } ! 408: } ! 409: } ! 410: return active; ! 411: } ! 412: ! 413: MakeGap(p) ! 414: Pad *p; ! 415: { ! 416: register Line *l, *lsent = &p->sentinel; ! 417: register long k = RcvLong(); ! 418: register long gap = RcvLong(); ! 419: ! 420: for( l = lsent->down; l!=lsent; l = l->down ) ! 421: if( l->key >= k ) l->key += gap; ! 422: } ! 423: ! 424: PadOp(op) ! 425: Protocol op; ! 426: { ! 427: static long LINEobj; ! 428: register long obj; ! 429: register Pad *p; ! 430: register short t; ! 431: ! 432: obj = op == P_NEXTLINE ? LINEobj : RcvLong(); ! 433: p = ObjToPad( obj ); ! 434: switch( (int) op ){ ! 435: case P_PADDEF: ! 436: P_Define(p,obj); ! 437: break; ! 438: case P_ATTRIBUTE: ! 439: P_Attributes(p); ! 440: break; ! 441: case P_REMOVELINE: ! 442: P_RemoveLine(p); ! 443: break; ! 444: case P_TABS: ! 445: P_Tabs(p); ! 446: break; ! 447: case P_BANNER: ! 448: P_Banner(p); ! 449: break; ! 450: case P_CARTE: ! 451: P_Carte(p); ! 452: break; ! 453: case P_LINES: ! 454: P_Lines(p); ! 455: break; ! 456: case P_NAME: ! 457: P_Name(p); ! 458: break; ! 459: case P_CLEAR: ! 460: DelLines(p); ! 461: Dirty(p); ! 462: break; ! 463: case P_MAKECURRENT: ! 464: MakeCurrent(p); ! 465: break; ! 466: case P_LINE: ! 467: LINEobj = obj; ! 468: case P_NEXTLINE: ! 469: PutLine(p,op); ! 470: break; ! 471: case P_CREATELINE: ! 472: CreateLine(p); ! 473: break; ! 474: case P_DELETE: ! 475: if( p ) p->attributes |= USERCLOSE; ! 476: DeletePad(p); ! 477: break; ! 478: case P_MAKEGAP: ! 479: MakeGap(p); ! 480: break; ! 481: case P_ALARM: ! 482: t = RcvShort(); ! 483: if(p){ ! 484: if( !(p->ticks = t) ){ ! 485: HostParent = HostObject = p->object; ! 486: ToHost( P_CYCLE /*, garbage */ ); ! 487: } ! 488: } ! 489: break; ! 490: default: ! 491: ProtoErr( "PadOp(): " ); ! 492: } ! 493: } ! 494: ! 495: PickOp() ! 496: { ! 497: register Pad *p; ! 498: Index i; ! 499: ! 500: i = RcvShort(); ! 501: p = PickPad(PickPoint(IndexToStr(i))); ! 502: MakeCurrent(p); ! 503: while( butts ) waitMOUSE(); ! 504: if( p && (HostParent = HostObject = p->object) ){ ! 505: FlashBorder(p); ! 506: PutRemote(P_PICK); ! 507: HostAction( &i ); ! 508: } ! 509: } ! 510: ! 511: Pad *PickPad(pt) ! 512: Point pt; ! 513: { ! 514: register Pad *p; ! 515: ! 516: for( p = Sentinel.back; ISPAD(p); p = p->back ) ! 517: if( PadSized(p->rect) && ptinrect(pt,p->rect) ) ! 518: return p; ! 519: return 0; ! 520: } ! 521: ! 522: DeletePick() ! 523: { ! 524: DeletePad(PickPad(PickPoint(0L))); ! 525: } ! 526: ! 527: DelLines(p) ! 528: register Pad *p; ! 529: { ! 530: if( !p ) return; ! 531: while( ISLINE(p->sentinel.up,p) ) ! 532: DelLine( p->sentinel.up ); ! 533: } ! 534: ! 535: DeletePad(p) ! 536: register Pad *p; ! 537: { ! 538: Rectangle r; ! 539: register Line *l, *lu; ! 540: ! 541: if( !p ) return; ! 542: if( DirtyPad == p ) Dirty((Pad*) 0); ! 543: if( p->attributes&USERCLOSE ){ ! 544: HostParent = HostObject = p->object; ! 545: ToHost( P_USERCLOSE /*, garbage */ ); ! 546: if( p->attributes&DONT_CLOSE ) return; ! 547: DelLines( p ); ! 548: Unlink( p ); ! 549: if( p->sentinel.text != NewString ) gcfree( p->sentinel.text ); ! 550: if( p->name != NewString ) gcfree( p->name ); ! 551: free(p); ! 552: } else { ! 553: if( p->attributes&DONT_CLOSE ) return; ! 554: for( l = p->sentinel.up; ISLINE(l,p); l = lu ){ ! 555: lu = l->up; ! 556: if( !(l->attributes&DONT_CUT) ) DelLine(l); ! 557: } ! 558: } ! 559: if( Current == p ) SetCurrent((Pad *) 0); ! 560: if( Selected.line && Selected.pad == p ) Selected.line = 0; ! 561: r = p->rect; ! 562: p->rect = ZRectangle; ! 563: Refresh( r ); ! 564: } ! 565: ! 566: Select(l, p) ! 567: register Line *l; ! 568: register Pad *p; ! 569: { ! 570: if( Selected.line == l ) return; ! 571: if( Selected.line ){ ! 572: if( Selected.pad != p ) ! 573: Selected.pad->selkey = Selected.line->key; ! 574: switch( (int) Covered(Selected.pad) ){ ! 575: case COMPLETE: ! 576: break; ! 577: case CLEAR: ! 578: LineXOR(Selected.line); ! 579: break; ! 580: case PARTIAL: ! 581: Selected.line = 0; ! 582: Refresh(Selected.pad->rect); ! 583: } ! 584: } ! 585: if( Selected.pad = p ) ! 586: p->selkey = 0; ! 587: if( Selected.line = l ) ! 588: LineXOR(l); ! 589: } ! 590: ! 591: MakeCurrent(p) ! 592: register Pad *p; ! 593: { ! 594: register paint; ! 595: register Line *l; ! 596: ! 597: if( !p ) return; ! 598: if( Selected.line && Selected.pad!=p ) Select((Line*)0, (Pad*)0); ! 599: paint = Covered(p) != CLEAR; ! 600: if( !PadSized(p->rect) ){ ! 601: if( Selected.line ) Select((Line*)0, (Pad*)0); ! 602: if( !PadSized(p->rect = clipgetrect(p->sentinel.text))) return; ! 603: paint = 1; ! 604: } ! 605: if( p == Current ) return; ! 606: FrontLink(p); ! 607: if( paint ) Paint(p); ! 608: l = &p->sentinel; ! 609: if( p->selkey ) ! 610: while( ISLINE(l->up, p) ){ ! 611: l = l->up; ! 612: if( l->key == p->selkey ){ ! 613: Select(l, p); ! 614: break; ! 615: } ! 616: } ! 617: } ! 618: ! 619: Relocate(p,r) ! 620: Pad *p; ! 621: Rectangle r; ! 622: { ! 623: Rectangle bounding; ! 624: ! 625: if( !PadSized(r) ) return; ! 626: MakeCurrent(p); /* bug - used to be FrontLink(p); */ ! 627: bounding = boundrect( r, p->rect ); ! 628: p->rect = r; ! 629: Refresh( bounding ); ! 630: } ! 631: ! 632: Move(){ ! 633: register Pad *p = PickPad(PickPoint(0L)); ! 634: ! 635: if( !p ) return; ! 636: Relocate( p, moverect(p->rect, PadSpace) ); ! 637: } ! 638: ! 639: Reshape() ! 640: { ! 641: register Pad *p = PickPad(PickPoint(0L)); ! 642: ! 643: if( !p ) return; ! 644: while( button123() ) waitMOUSE(); ! 645: Relocate( p, clipgetrect(0L) ); ! 646: } ! 647: ! 648: Rectangle NewSpace; ! 649: Point Scale( p ) ! 650: Point p; ! 651: { ! 652: #define fo PadSpace.origin ! 653: #define fc PadSpace.corner ! 654: #define to NewSpace.origin ! 655: #define tc NewSpace.corner ! 656: #define SCALE(xy) p.xy = to.xy + muldiv( p.xy-fo.xy, tc.xy-to.xy, fc.xy-fo.xy ); ! 657: ! 658: SCALE(x); ! 659: SCALE(y); ! 660: return p; ! 661: } ! 662: ! 663: #define KBDLEN 90 ! 664: char KBDStr[KBDLEN]= "\1"; ! 665: ! 666: PadClip() ! 667: { ! 668: register Pad *p; ! 669: ! 670: KBDrect = NewSpace = display.rect; ! 671: KBDrect.origin.y = NewSpace.corner.y -= fontheight(&defont); ! 672: KBDrect.origin.x += 2; ! 673: for( p = Sentinel.back; ISPAD(p); p = p->back ){ ! 674: p->rect.origin = Scale( p->rect.origin ); ! 675: p->rect.corner = Scale( p->rect.corner ); ! 676: if( !PadSized(p->rect) ){ ! 677: p->rect = ZRectangle; ! 678: if( p == Selected.pad ){ ! 679: Selected.pad = 0; ! 680: Selected.line = 0; ! 681: } ! 682: } ! 683: } ! 684: Refresh( PadSpace = NewSpace ); ! 685: PaintKBD(); ! 686: } ! 687: ! 688: InvertKBDrect(s1, s2) ! 689: char *s1, *s2; ! 690: { ! 691: char buf[300]; ! 692: ! 693: strcpy( buf, s1 ); ! 694: strcat( buf, s2 ); ! 695: rectf( &display, KBDrect, F_CLR ); ! 696: string(&defont, buf, &display, KBDrect.origin, F_XOR); ! 697: rectf( &display, KBDrect, F_XOR ); ! 698: } ! 699: ! 700: PaintKBD() ! 701: { ! 702: rectf( &display, KBDrect, F_CLR ); ! 703: string(&defont, KBDStr, &display, KBDrect.origin, F_XOR); ! 704: } ! 705: ! 706: #define PAD_TO_SH (1L) ! 707: #define LINE_TO_SH (2L) ! 708: CarriageReturn(obj) ! 709: register long obj; ! 710: { ! 711: register char *kbds = KBDStr; ! 712: register Line *l, *lsent; ! 713: register long ct; ! 714: ! 715: kbds[strlen(kbds)-1] = '\0'; ! 716: if( obj == LINE_TO_SH ){ ! 717: PutRemote(P_SHELL); ! 718: SendLong(0L); /* common protocol */ ! 719: SendLong(0L); ! 720: SendString(kbds+1); ! 721: SendLong(1L); ! 722: SendString(Selected.line->text); ! 723: } else if( obj == PAD_TO_SH ){ ! 724: PutRemote(P_SHELL); ! 725: SendLong(0L); /* common protocol */ ! 726: SendLong(0L); ! 727: SendString(kbds+1); ! 728: lsent = &Current->sentinel; ! 729: ct = 0; ! 730: for(l = lsent->down; l != lsent; l = l->down) ! 731: ++ct; ! 732: SendLong(ct); ! 733: for(l = lsent->down; l != lsent; l = l->down) ! 734: SendString(l->text); ! 735: } else { ! 736: PutRemote(P_KBDSTR); ! 737: SendLong(Current->object); ! 738: SendLong(obj); ! 739: SendString(kbds); ! 740: } ! 741: kbds[0] = 001; ! 742: kbds[1] = 000; ! 743: } ! 744: ! 745: LayerReshaped() ! 746: { ! 747: if( P->state & (RESHAPED) ){ ! 748: P->state &= ~(RESHAPED); ! 749: PadClip(); ! 750: } ! 751: } ! 752: ! 753: long LiveKBD() ! 754: { ! 755: register Line *sel = Selected.line; ! 756: register Pad *cur = Current; ! 757: ! 758: if( KBDStr[0] == '>' && cur ){ ! 759: if( sel ){ ! 760: DoubleOutline(&display, sel->rect); ! 761: return LINE_TO_SH; ! 762: } else { ! 763: HeavyBorder(cur); ! 764: return PAD_TO_SH; ! 765: } ! 766: } ! 767: if( sel && (sel->attributes&ACCEPT_KBD) ){ ! 768: DoubleOutline(&display, sel->rect); ! 769: return sel->object; ! 770: } ! 771: if( cur && (cur->attributes&ACCEPT_KBD) ){ ! 772: HeavyBorder(cur); ! 773: return cur->object; ! 774: } ! 775: return 0L; ! 776: } ! 777: ! 778: #define CNTRL_U 025 ! 779: KBDAppend(c) ! 780: register c; ! 781: { ! 782: register char *t; ! 783: register int len = strlen(t = KBDStr); ! 784: ! 785: if( c < 040 || (c&0200) || len >= KBDLEN ){ ! 786: if( c == CNTRL_U ){ ! 787: t[0] = 001; ! 788: t[1] = 000; ! 789: } ! 790: if( c != '\t' ) /* bug: \t when len >= KBDLEN !! */ ! 791: return; ! 792: } ! 793: t[len-1] = c; ! 794: t[len] = 001; ! 795: t[len+1] = 000; ! 796: } ! 797: ! 798: typedef struct String{ ! 799: char *s; /* pointer to string */ ! 800: short n; /* number used, no terminal null */ ! 801: short size; /* size of allocated area */ ! 802: } String; ! 803: ! 804: MuxSnarf() ! 805: { ! 806: String hold; ! 807: register i, c; ! 808: ! 809: hold.s = 0; ! 810: hold.n = hold.size = 0; ! 811: getmuxbuf(&hold); ! 812: for( i = 0; i < hold.n; ++i ){ ! 813: c = hold.s[i]; ! 814: if( c == '\n' ) break; ! 815: KBDAppend(c); ! 816: } ! 817: } ! 818: ! 819: #define KBD_PAUSE 4 ! 820: #define ESCAPE 033 ! 821: KBDServe() ! 822: { ! 823: register char c, *t; ! 824: register live, lenmake, len; ! 825: ! 826: if( P->state & KBD ){ ! 827: live = LiveKBD(); ! 828: while( P->state & KBD ){ ! 829: c = kbdchar(); ! 830: if( c == ESCAPE ){ ! 831: MuxSnarf(); ! 832: break; ! 833: } ! 834: if( c == '\r' && live ){ ! 835: CarriageReturn(live); ! 836: break; ! 837: } ! 838: len = strlen(t = KBDStr); ! 839: if( c == '\b' && len > 1 ){ ! 840: t[len-2] = 001; ! 841: t[len-1] = 000; ! 842: continue; ! 843: } ! 844: KBDAppend(c); ! 845: } ! 846: PaintKBD(); ! 847: LiveKBD(); ! 848: } ! 849: } ! 850: ! 851: FoldToggle(a) ! 852: Attrib *a; ! 853: { ! 854: *a &= ~(TRUNCATE|FOLD); ! 855: *a |= NewFold; ! 856: Paint(Current); ! 857: } ! 858: ! 859: Entry *FoldEntry(a) ! 860: register Attrib *a; ! 861: { ! 862: static Entry e = { 0, FoldToggle, 0 }; ! 863: ! 864: assert(Current); ! 865: if( ( (*a&(TRUNCATE|FOLD)) ? *a : Current->attributes )&TRUNCATE ) ! 866: e.text = "fold", NewFold = FOLD; ! 867: else ! 868: e.text = "truncate", NewFold = TRUNCATE; ! 869: e.opand = (long) a; ! 870: return &e; ! 871: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.