Annotation of researchv9/cmd/emacs/windows.c, revision 1.1.1.1

1.1       root        1: #include <termio.h>
                      2: #include <fcntl.h>
                      3: #include <stdio.h>
                      4: #include <signal.h>
                      5: 
                      6: /* EMACS_MODES: c,!fill,tabstop=4 */
                      7: 
                      8: #define MWIND 6
                      9: 
                     10: int wproc[MWIND];
                     11: int wx[MWIND];
                     12: int wy[MWIND];
                     13: int wox[MWIND];
                     14: int woy[MWIND];
                     15: int wofrn[MWIND];
                     16: int wifrn[MWIND];
                     17: int wbase[MWIND];
                     18: int wmode[MWIND];
                     19: int wstate[MWIND];
                     20: 
                     21: char wrbuf[MWIND] [BUFSIZ];
                     22: int wcnt[MWIND];
                     23: int wptr[MWIND];
                     24: int wmore[MWIND];
                     25: 
                     26: #define MSNORM 0
                     27: #define MSESC 1
                     28: #define MSXWAIT 2
                     29: #define MSYWAIT 3
                     30: 
                     31: #define MRAW 1
                     32: #define MMORE 2
                     33: #define MMSCROLL 4
                     34: #define MECHO 8
                     35: #define MVSEND 16
                     36: #define WSCROLL 32
                     37: #define MOPENW 64
                     38: #define MWAIT 128
                     39: 
                     40: char *mdname[16] = {"RAW",
                     41:                    "MORE",
                     42:                    "ROLL",
                     43:                    "ECHO",
                     44:                    "VIRTUAL",
                     45:                    "SCROLLING",
                     46:                    "OPEN-WAIT",
                     47:                    "MWAIT",
                     48:                };
                     49: int wlen[MWIND];
                     50: 
                     51: int talkf = 0;                     /* 1 if we are xtalk */
                     52: 
                     53: int cwind,nwind;
                     54: 
                     55: int quote,squig;
                     56: 
                     57: int ic;
                     58: int rx,ry;
                     59: 
                     60: char ibuf[BUFSIZ];
                     61: char tibuf[BUFSIZ];
                     62: 
                     63: extern int SCRNLIN;
                     64: extern int SCRWID;
                     65: extern int mcol;
                     66: extern int mline;
                     67: extern int ttykill;
                     68: extern int ttyerase;
                     69: extern int ttyintr;
                     70: extern int errno;
                     71: extern char *getname();
                     72: extern char *homedir();
                     73: extern char *findtty();
                     74: extern char *getenv();
                     75: 
                     76: tdelay(num)
                     77: 
                     78: int num;
                     79: {
                     80: /*     VMIN = 0  does not seem to work 
                     81:    
                     82: 
                     83:    struct termio td;
                     84:    
                     85:    ioctl(0,TCGETA, &td);
                     86:    td.c_cc[VMIN] = num;
                     87:    td.c_cc[VTIME] = 1;
                     88:    ioctl(0,TCSETA, &td);
                     89: */
                     90: /*     THIS KLUDGE ALSO WORKS POORLY, so now do it with a user level timer 
                     91: 
                     92: 
                     93:    if (num == 0) fcntl(0,F_SETFL,O_RDWR+O_NDELAY);     
                     94:    else fcntl(0,F_SETFL,O_RDWR);
                     95: */
                     96: }
                     97: 
                     98: 
                     99: alarming()
                    100: {
                    101:    return;
                    102: }
                    103: 
                    104: xclose(x)
                    105: int x;
                    106: {
                    107:    int i;
                    108:    
                    109:    for (i = x; i < 20; i++) close(i);
                    110: }
                    111: 
                    112: wput(i,cp,nc)
                    113: int i;
                    114: int nc;
                    115: char *cp;
                    116: {
                    117:    register int x;
                    118:    int maxln;
                    119:    
                    120:    maxln = wbase[i]+wlen[i];
                    121:    xgo(wx[i]+wbase[i],wy[i]);
                    122:    for (x = 0; x < nc; x++) {
                    123:        if (cp[x] == '\n') {
                    124:            clrl();
                    125:            mline++;
                    126:            mcol=0;
                    127:        } else xputc(cp[x]);
                    128:        if (mline>=maxln) {
                    129:            wroll(i);
                    130:        }
                    131:    }
                    132: }
                    133: 
                    134: /* wroll -- roll over window i */
                    135: 
                    136: 
                    137: wroll(i)
                    138: register int i;
                    139: {
                    140:    if ((wmode[i] & WSCROLL) || (vadjust(wbase[i],wbase[i]-1+wlen[i],-1)== 0)) {
                    141:        xgo(wbase[i],0);
                    142:        clrl();
                    143:    } else {
                    144:        mline--;
                    145:    }
                    146: }
                    147: 
                    148: wmfix(c)
                    149: register c;
                    150: {
                    151:    xgo(wx[c]+wbase[c],wy[c]);
                    152:    wroll(c);
                    153:    if (mline == wbase[c]) {
                    154:        wmore[c]  = wlen[c]-1;
                    155:    } else {
                    156:        wmore[c] = 0;
                    157:        wmode[c] |= MMSCROLL;
                    158:    }
                    159:    wmode[c] |= MWAIT;
                    160:    wmode[c] ^= MWAIT;
                    161:    wx[c]=mline-wbase[c];
                    162:    wy[c]=mcol;
                    163: }
                    164: 
                    165: main(argc,argv)
                    166: 
                    167: int argc;
                    168: char **argv;
                    169: {
                    170: 
                    171:    int c;
                    172:    char *cp,*tp;
                    173:    int status;
                    174:    int pipe1[2];
                    175:    int pipe2[2];
                    176:    int i;
                    177:    int x;
                    178:    ttystart();
                    179:    signal(SIGCLD,SIG_IGN);
                    180:    signal(SIGPIPE,SIG_IGN);
                    181:    tdelay(0);
                    182:    nwind = 1;
                    183:    wifrn[0]=0;
                    184:    wofrn[0]=0;
                    185:    wmode[0]=0;
                    186:    wx[0]=0;
                    187:    wy[0]=0;
                    188:    wbase[0]=0;
                    189:    wlen[0]=SCRNLIN-2;
                    190:    wmore[0] = wlen[0]-1;   
                    191:    
                    192:    if (**argv != 'w') {
                    193:        talkf = 1;                  /* We are talk */
                    194:        talk(argv[1]);              /* start talking */
                    195:    }
                    196: 
                    197:    while (1) {     
                    198:        for (i = 0; i < nwind; i++) {
                    199:            
                    200:            if (wmode[i] & MOPENW) {
                    201: 
                    202:                wofrn[i] = open(wrbuf[i],1+O_NDELAY);
                    203:                if (wofrn[i] >= 0) {
                    204:                    wmode[i] ^= MOPENW;
                    205:                    prompt1("TALKING");
                    206:                } else {
                    207:                    prompt1("WAITING");
                    208:                }
                    209:            } else if (wifrn[i]) {
                    210:                if (wcnt[i] == 0) {
                    211:                    wcnt[i] = read(wifrn[i],wrbuf[i],BUFSIZ);
                    212:                    wptr[i] = 0;
                    213:                }
                    214:                if (wcnt[i]) {
                    215:                    x = wprot(i,wrbuf[i]+wptr[i],wcnt[i]);
                    216:                    wptr[i] += wcnt[i]-x;
                    217:                    wcnt[i] = x;
                    218:                    if (i == cwind) {
                    219:                        rx = wx[i]+wbase[i];
                    220:                        ry = wy[i];
                    221:                    }
                    222:                }
                    223:            }
                    224:        }
                    225:        xgo (SCRNLIN-2,0);
                    226:        for (i = 0; i < nwind; i++) {
                    227:            if (wmode[i]&MWAIT) {
                    228:                sputs("  MORE-");
                    229:                xputc(i+'0');
                    230:            }
                    231:        }
                    232:        clrl();
                    233:        if (squig) prompt1("~: ");
                    234:        else if (wmode[cwind] & MRAW) {
                    235:            mgo(wx[cwind]+wbase[cwind],wy[cwind]);
                    236:        } else {
                    237:            mgo (rx,ry);
                    238:        }
                    239:        fflush(stdout);     
                    240:        signal(SIGALRM,alarming);
                    241:        alarm(1);
                    242:        x = read(0,&c,1);
                    243:        alarm(0);
                    244:        if (x > 0) {
                    245:            if (squig) {
                    246:                squig = 0;
                    247:                unprompt();
                    248:                switch(c) {
                    249:                
                    250:                case '':
                    251:                    abort();
                    252:                case '':
                    253:                    rfrsh();
                    254:                    break;
                    255:                case 'w':
                    256:                    cwind++;
                    257:                    if (cwind >= nwind) cwind = 0;
                    258:                    if ((wmode[cwind] &MRAW) == 0) {
                    259:                        rx = wx[cwind]+wbase[cwind];
                    260:                        ry = wy[cwind];
                    261:                        ic = 0;
                    262:                    }
                    263:                    break;
                    264:                
                    265:                    
                    266:                    
                    267:                    
                    268:                case 't':
                    269:                    cp = getname ("Talk to? ");
                    270:                    if (cp) talk(cp);
                    271:                    break;
                    272:                case 's':
                    273:                    wsplit(cwind);
                    274:                    break;
                    275: 
                    276:                case '?':
                    277:                    wmode[cwind] |= MMORE;
                    278:                    newin("/n1/warren/emacs/windows.help");
                    279:                    break;
                    280:                case '<':
                    281:                    cp = getname("Input from? ");
                    282:                    newin(cp);
                    283:                    break;
                    284:                case '>':
                    285:                    if (wofrn[cwind]) close(wofrn[cwind]);
                    286:                    tdelay(1);
                    287:                    cp = getname("Output to? ");
                    288:                    tdelay(0);
                    289:                    wofrn[cwind] = open(cp,1+O_NDELAY);
                    290:                    if (wofrn[cwind] < 0) prompt1("error code %d",errno);
                    291:                    break;
                    292:                case '!':
                    293:                    if (wifrn[cwind]) close(wifrn[cwind]);
                    294:                    if (wofrn[cwind]) close(wofrn[cwind]);
                    295:                    if (wproc[cwind]) {
                    296:                        kill(wproc[cwind],9);
                    297:                    };
                    298:                    tdelay(1);
                    299:                    cp = getname ("Command? ");
                    300:                    tdelay(0);
                    301:                    
                    302:                    pipe(pipe1);
                    303:                    pipe(pipe2);
                    304:                    if ((wproc[cwind] = fork()) == 0) {
                    305:                        close(0);
                    306:                        dup(pipe1[0]);
                    307:                        close(1);
                    308:                        close(2);
                    309:                        dup(pipe2[1]);
                    310:                        dup(pipe2[1]);
                    311:                        xclose(3);
                    312:                        signal(SIGCLD,SIG_DFL);
                    313:                        tp = getenv("TERM");
                    314:                        *tp='v';
                    315:                        tp[1]=0;
                    316:                        execl("/bin/sh", "sh", "-c", cp , 0);
                    317:                        exit(0);
                    318:                    } else {
                    319:                        close(pipe1[0]);
                    320:                        close(pipe2[1]);
                    321:                        wifrn[cwind] = pipe2[0];
                    322:                        fcntl(pipe2[0],F_SETFL,O_RDONLY+O_NDELAY);
                    323:                        wofrn[cwind] = pipe1[1];
                    324:                    }
                    325:                    break;
                    326:                    
                    327:                case 'k':
                    328:                    if (wproc[cwind]) kill(wproc[cwind],9);
                    329:                    if (wofrn[cwind] ){
                    330:                        close(wofrn[cwind]);
                    331:                        wofrn[cwind] = 0;
                    332:                    }
                    333:                    if (wifrn[cwind]) {
                    334:                        close(wifrn[cwind]);
                    335:                        wifrn[cwind] = 0;
                    336:                    }
                    337:                    break;
                    338:                case 'v':
                    339:                    wmode[cwind] ^= MVSEND;
                    340:                    break;
                    341:                case 'd':
                    342:                    xgo(SCRNLIN-1,0);
                    343:                    xprintf("#%d,ifrn:%d,ofrn:%d,base:%d,len:%d,",
                    344:                    cwind,wifrn[cwind],wofrn[cwind],wbase[cwind],wlen[cwind]);
                    345:                    xprintf("pid:%o,mode:%o (",wproc[cwind],wmode[cwind]);
                    346:                    for (x = 0; x < 16; x++) {
                    347:                        if (wmode[cwind] & (1<<x)) {
                    348:                            xprintf ("%s,",mdname[x]);
                    349:                        }
                    350:                    }
                    351:                    xputc(')');
                    352:                    clrl();
                    353:                    break;
                    354:                case '0':
                    355:                case '1':
                    356:                case '2':
                    357:                case '3':
                    358:                    c-='0';
                    359:                    if (wmode[c]&MWAIT) {
                    360:                        wmfix(c);
                    361:                    }
                    362:                    break;
                    363:                case 'm':
                    364:                    wmode[cwind] ^= MMORE;
                    365:                case 'S':
                    366:                    wmode[cwind] ^= WSCROLL;
                    367:                    break;
                    368:                case 'r':
                    369:                    wmode[cwind] ^= MRAW;
                    370:                    break;
                    371:                case '~':
                    372:                    goto defchar;
                    373:                case '.':
                    374:                    for (i = 0; i < nwind; i++) {
                    375:                        if (wproc[i]) kill (wproc[i],9); /* murder */
                    376:                    }
                    377:                    tdelay(1);
                    378:                    die(0);         /* go away */
                    379:                }
                    380:            } else {
                    381:                
                    382:                if (c == '~') {
                    383:                    squig++;
                    384:                } else {
                    385: defchar:                    /* implement modes here */
                    386: 
                    387:                    if (wmode[cwind]&MWAIT) {
                    388:                        wmfix(cwind);
                    389:                    } else {
                    390:                        if (wmode[cwind] & MMSCROLL) {
                    391:                            wmore[cwind] = 0; /* input to this window */
                    392:                        } else {
                    393:                            wmore[cwind] = wlen[cwind]-1;
                    394:                        }
                    395:                    }
                    396:                    if (wmode[cwind]&MRAW) {
                    397:                        if (wofrn[cwind]) {
                    398:                            write(wofrn[cwind],&c,1);
                    399:                        }
                    400:                    } else {
                    401:                        if (quote)  goto deflt;
                    402:                        if (c == ttyerase) {
                    403:                            if (ic) ic--;
                    404:                            if (wmode[cwind] & MVSEND) {
                    405:                                wput(cwind,tibuf,ic);
                    406:                                x = ry-mcol;
                    407:                                if (x < 0) x=1;
                    408:                                if (wofrn[cwind]) {
                    409:                                    write(wofrn[cwind],"",x);
                    410:                                    write(wofrn[cwind],"T",2);
                    411:                                }
                    412:                            }
                    413:                        } else if (c == ttykill) {
                    414:                            ic = 0;
                    415:                            if (wofrn[cwind] && (wmode[cwind] & MVSEND)) {
                    416:                                write(wofrn[cwind],"
T",3);
                    417:                            }
                    418:                        } else if ((c == 015) ||(c == '\n') || (c == 4)) {
                    419:                            if (c == '\r') c = '\n';
                    420:                            tibuf[ic++] = c;
                    421:                            wput(cwind,tibuf,ic);
                    422:                            rx = mline;
                    423:                            wx[cwind] = mline-wbase[cwind];
                    424:                            ry = wy[cwind]=mcol;
                    425:                            if (wofrn[cwind]) {
                    426:                                if (wmode[cwind] & MVSEND) {
                    427:                                    write(wofrn[cwind],&c,1);
                    428:                                } else {
                    429:                                    write(wofrn[cwind],tibuf,ic);
                    430:                                }
                    431:                            }
                    432:                            ic = 0;
                    433:                            if ((c == 4) && talkf) die(0); /* exit */
                    434:                        } else if (c == '\\') {
                    435:                            quote++;
                    436:                        } else if (c == ttyintr) {
                    437:                            if (wproc[cwind]) signal(wproc[cwind],SIGINT);
                    438:                        } else {
                    439: deflt:                     tibuf[ic++] = c;
                    440:                            quote = 0;
                    441:                            if ((wmode[cwind] & MVSEND) && wofrn[cwind]) {
                    442:                                write(wofrn[cwind],&c,1);
                    443:                            }
                    444:                        }
                    445:                        wput(cwind,tibuf,ic);
                    446:                        rx = mline;
                    447:                        ry = mcol;
                    448:                        clrl();
                    449:                    }
                    450:                }
                    451:            }
                    452:        } else {
                    453: /*         sleep(1);*/
                    454:        }
                    455:    }
                    456: }
                    457: wsplit(w)
                    458: 
                    459: int w;
                    460: {  
                    461:    int x;
                    462:    
                    463:    wbase[nwind] = wbase[w]+1+(wlen[w]/2);
                    464:    wlen[nwind] = wlen[w]-wbase[nwind]+wbase[w];
                    465:    wlen[w]=wbase[nwind]-wbase[w]-1;
                    466:    xgo(wbase[w]+wlen[w],0);
                    467:    for (x = 0; x < SCRWID; x++) {
                    468:        xputc('-');
                    469:    }
                    470:    wx[nwind]=wy[nwind]=wifrn[nwind]=wofrn[nwind]=0;
                    471: 
                    472:    if (wx[w] >= wlen[w]) wx[w] = 0;
                    473: 
                    474:    wmore[w] = wlen[w]-1;
                    475:    wmore[nwind]=wlen[nwind]-1;
                    476:    nwind++;
                    477: }
                    478: 
                    479: 
                    480: wprot(w,cp,n)
                    481: int w;
                    482: char *cp;
                    483: int n;
                    484: {
                    485:    char wbuf[10];
                    486:    
                    487:    int i;
                    488: 
                    489:    if (wmode[w] & MWAIT) return(n);
                    490:    
                    491:    for (i = 0; (i < n); i++) {
                    492:        switch(wstate[w]) {
                    493:            
                    494:        case MSNORM:
                    495:            switch(cp[i]) {
                    496:                
                    497:            case '':
                    498:                if (wy[w]) wy[w]--;
                    499:                break;
                    500:            case '':
                    501:                if (wx[w]) wx[w]--;
                    502:                break;
                    503:            case '':
                    504:                wy[w]++;
                    505:                break;
                    506:            case '
':
                    507:                wy[w]=0;
                    508:                break;
                    509:            case '':
                    510:                xgo(wx[w]+wbase[w],wy[w]);
                    511:                sputs("EOF");
                    512:                if (talkf) die(0);
                    513:                break;
                    514:            case '':
                    515:            case '\n':
                    516:                xgo(wx[w]+wbase[w],wy[w]);
                    517:                if (cp[i] == '\n'){
                    518:                    clrl();
                    519:                    mcol=0;
                    520:                }
                    521:                mline++;
                    522:                if ((cp[i] == '\n') && (mline <wlen[w]+wbase[w])) clrl();
                    523:                goto wscroll;
                    524:            case '':
                    525:                beep();
                    526:                break;
                    527:            case '':
                    528:                wx[w]=wy[w]=0;
                    529:                break;
                    530:            case '':
                    531:                wstate[w]=MSESC;
                    532:                break;
                    533:            case '&':
                    534:                break;
                    535:            default:
                    536:                xgo(wx[w]+wbase[w],wy[w]);
                    537:                xputc(cp[i]);
                    538: wscroll:       if (mline>=wbase[w]+wlen[w]) {
                    539:                    if((wmode[w]&MMORE)&& (++wmore[w] >= (wlen[w]))) {
                    540:                        wmode[w] |= MWAIT;
                    541:                        wx[w]=mline-wbase[w];
                    542:                        wy[w]=mcol;
                    543:                        return(n-i);
                    544:                    }
                    545:                    wroll(w);
                    546:                }
                    547:                wx[w]=mline-wbase[w];
                    548:                wy[w]=mcol;
                    549:            }
                    550:            break;
                    551:        case MSESC:
                    552:            switch(cp[i]) {
                    553:            
                    554:            case 'Y':
                    555:                while (wx[w] < wlen[w]) {
                    556:                    xgo(wx[w]+wbase[w],0);
                    557:                    clrl();
                    558:                    wx[w]++;
                    559:                }
                    560:                wx[w]=wy[w]=0;
                    561:                break;
                    562:            case 'T':
                    563:                xgo(wx[w]+wbase[w],wy[w]);
                    564:                clrl();
                    565:                break;
                    566:            case '?':
                    567:                if (wofrn[w]) {
                    568:                    sprintf(wbuf,">%c%c",wlen[w]+' ',SCRWID+' ');
                    569:                    write(wofrn[w],wbuf,4);
                    570:                }
                    571:                break;
                    572:            case '=':
                    573:                wstate[w] = MSXWAIT;
                    574:                break;
                    575:            }
                    576:            if (wstate[w] == MSESC) wstate[w] = MSNORM;
                    577:            break;
                    578:        case MSXWAIT:
                    579:            wx[w] = cp[i]-040;
                    580:            if (wx[w] >= wlen[w]) wx[w]=0;
                    581:            wstate[w]= MSYWAIT;
                    582:            break;
                    583:        case MSYWAIT:
                    584:            wy[w] = cp[i]-040;
                    585:            wstate[w] = MSNORM;
                    586:        }
                    587:    }
                    588:    return(0);
                    589: }
                    590: 
                    591: /* TALK stuff */
                    592: 
                    593: char   desttty[20] = "/dev/";
                    594: 
                    595: alert(tty)
                    596:    char *tty;
                    597: {
                    598:    
                    599:    /* Alerts the destination tty of an incoming "talk" */
                    600:    FILE *ttyfile;
                    601: 
                    602:    strcat(desttty, tty);
                    603:    if ((ttyfile = fopen(desttty, "w")) == NULL) {
                    604:        return(0);
                    605:    }
                    606: 
                    607:    fprintf(ttyfile, "%cTALK2 FROM %s (%s)...\n%c",
                    608:            7, getenv("LOGNAME"), getenv("LOGTTY"), 7);
                    609:    fclose(ttyfile);
                    610:    return(1);
                    611: }
                    612: 
                    613: 
                    614: talk(cp)
                    615: char *cp;
                    616: {
                    617:    char infifo[100];
                    618:    char outfifo[100];
                    619:    char *ttyp;
                    620:    int owind;
                    621: 
                    622:    
                    623:    owind = nwind;
                    624:    wsplit(cwind);          /* two windows */
                    625:    wmode[cwind] = MVSEND;
                    626:    wmode[owind] = MVSEND+MOPENW;
                    627:    
                    628: /* Find other user's terminal */
                    629: 
                    630:    ttyp = findtty(cp);
                    631:    if (*ttyp == NULL) {
                    632:        prompt1("talk: user %s not logged on.\n", cp);
                    633:        return;
                    634:    }
                    635: 
                    636:    /* Check for existence of .talk fifos */
                    637: 
                    638:    sprintf(infifo, "%s/.talk", getenv("HOME"));
                    639:    sprintf(wrbuf[owind], "%s/.talk", homedir(cp));
                    640: 
                    641:    if (access(infifo, 04) != 0) {
                    642:        prompt1("Type mknod $HOME/.talk p and try again");
                    643:        return;
                    644:    }
                    645:    wifrn[cwind] = open(infifo,0+O_NDELAY);
                    646: 
                    647:    /* alert the destination terminal */
                    648: 
                    649:    if (!alert(ttyp)) {
                    650:        prompt1("talk: cant alert tty: /dev/%s.\n", ttyp);
                    651:    }
                    652:    cwind = owind;
                    653:    rx = wbase[cwind];
                    654:    ry = 0;
                    655: }
                    656: newin(cp)
                    657: 
                    658: register char *cp;
                    659: {
                    660:    if (cp) {
                    661:        if (wifrn[cwind]) close(wifrn[cwind]);
                    662:                    
                    663:        wifrn[cwind] = open(cp,0+O_NDELAY);
                    664:        if (wifrn[cwind] < 0) prompt1("error code %d",errno);
                    665:    }
                    666: }

unix.superglobalmegacorp.com

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