Annotation of researchv9/jtools/src/pads/x11/pad.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.