home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / TTYDRIV.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  22KB  |  584 lines

  1. /* TTY input line editing
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  * split screen by G. J. van der Grinten, PA0GRI
  4.  * command recall, and status line by Johan. K. Reinalda, WG7J
  5.  */
  6. #ifdef __TURBOC__
  7. #include <conio.h>
  8. #endif
  9. #include <ctype.h>
  10. #include "global.h"
  11. #include "mbuf.h"
  12. #include "session.h"
  13. #include "tty.h"
  14. #include "socket.h"
  15.   
  16. extern FILE *Rawterm;
  17.   
  18. #define OFF 0
  19. #define ON  1
  20.   
  21. #define LINESIZE    256
  22.   
  23. #define CTLR    18      /* reprint current line */
  24. #define CTLU    21      /* delete current line in total */
  25. #define CTLW    23      /* erase last word including preceding space */
  26. #define CTLZ    26      /* EOF char in dos */
  27. #define CTLB    02      /* use as F3 in dos but no editing */
  28. #define DEL 0x7f
  29.   
  30. extern int Numrows,Numcols;
  31.   
  32. #ifdef SPLITSCREEN
  33.   
  34. extern int StatusLines;
  35. static int  Lastsize = 1;
  36. static char Lastline[LINESIZE+1] = "\n";
  37.   
  38. char MainColors;    /* Gets initialized to the startup attribute */
  39. char SplitColors = WHITE+(GREEN<<4);
  40.   
  41. /* Accept characters from the incoming tty buffer and process them
  42.  * (if in cooked mode) or just pass them directly (if in raw mode).
  43.  *
  44.  * Echoing (if enabled) is direct to the raw terminal. This requires
  45.  * recording (if enabled) of locally typed info to be done by the session
  46.  * itself so that edited output instead of raw input is recorded.
  47.  * Control-W added by g1emm again.... for word delete.
  48.  * Control-B/Function key 3 added by g1emm for line repeat.
  49.  */
  50.   
  51. struct mbuf *
  52. ttydriv(sp,c)
  53. struct session *sp;
  54. int c;
  55. {
  56.     struct mbuf *bp;
  57.     char *cp,*rp;
  58.     int cnt;
  59.   
  60.     switch(sp->ttystate.edit){
  61.         case OFF:
  62.             bp = ambufw(1);
  63.             *bp->data = c;
  64.             bp->cnt = 1;
  65.             if(sp->ttystate.echo){
  66.                 if(sp->split){
  67.                 /* Save cursor in top screen */
  68.                     sp->tsavex = wherex();
  69.                     sp->tsavey = wherey();
  70.   
  71.                 /* Access bottom screen */
  72.                     window(1,Numrows-1,Numcols,Numrows);
  73.                     textattr(SplitColors);
  74.                     gotoxy(sp->bsavex,sp->bsavey);
  75.                     highvideo();
  76.                     putch(c);
  77.                     lowvideo();
  78.                     cputs("_\b");
  79.                     sp->bsavex = wherex();
  80.                     sp->bsavey = wherey();
  81.   
  82.                 /* Back to top screen */
  83.                     window(1,1+StatusLines,Numcols,Numrows-2);
  84.                     textattr(MainColors);
  85.                     gotoxy(sp->tsavex,sp->tsavey);
  86.                 } else {
  87. #ifdef UNIX
  88.                     putch(c);
  89. #else
  90.                     if(StatusLines)
  91.                         putch(c);
  92.                     else
  93.                         putc(c,Rawterm);
  94. #endif
  95.                 }
  96.             }
  97.             return bp;
  98.         case ON:
  99.             if(sp->ttystate.line == NULLBUF)
  100.                 sp->ttystate.line = ambufw(LINESIZE);
  101.   
  102.             bp = sp->ttystate.line;
  103.             cp = bp->data + bp->cnt;
  104.         /* Perform cooked-mode line editing */
  105.   
  106.         /* Allow for international character sets - WG7J */
  107. #ifdef notdef
  108.             switch(c & 0x7f){
  109. #endif
  110.                 switch(c){
  111.                     case '\r':  /* CR and LF both terminate the line */
  112.                     case '\n':
  113.                         if(sp->ttystate.crnl)
  114.                             *cp = '\n';
  115.                         else
  116.                             *cp = c;
  117.                         if(sp->ttystate.echo){
  118.                             if(sp->split){
  119.                                 highvideo();
  120.                                 rp = bp->data;
  121.                                 while(rp < cp) {
  122.                                     putch(*rp++);
  123.                                 }
  124.                                 lowvideo();
  125.                                 clreol();
  126.                                 cputs(Eol);
  127.                                 clreol();
  128.                                 sp->tsavex = wherex();
  129.                                 sp->tsavey = wherey();
  130.   
  131.                     /* Access bottom screen */
  132.                                 window(1,Numrows-1,Numcols,Numrows);
  133.                                 textattr(SplitColors);
  134.                                 clrscr();
  135.                                 cputs("_\b");
  136.                                 sp->bsavex = wherex();
  137.                                 sp->bsavey = wherey();
  138.   
  139.                     /* Back to top screen */
  140.                                 window(1,1+StatusLines,Numcols,Numrows-2);
  141.                                 textattr(MainColors);
  142.                                 gotoxy(sp->tsavex,sp->tsavey);
  143.                             } else {
  144. #ifdef UNIX
  145.                                 cputs(Eol);
  146. #else
  147.                                 if(StatusLines)
  148.                                     cputs(Eol);
  149.                                 else
  150.                                     fputs(Eol,Rawterm);
  151. #endif
  152.                             }
  153.                         }
  154.                         bp->cnt += 1;
  155.                         sp->ttystate.line = NULLBUF;
  156.                         Lastsize = bp->cnt;
  157.                         memcpy(Lastline, bp->data, Lastsize);
  158.                         return bp;
  159.                     case DEL:
  160.                     case '\b':  /* Character delete */
  161.                         if(bp->cnt != 0){
  162.                             bp->cnt--;
  163.                             if(sp->ttystate.echo){
  164.                                 if(sp->split){
  165.                         /* Save cursor in top screen */
  166.                                     sp->tsavex = wherex();
  167.                                     sp->tsavey = wherey();
  168.   
  169.                         /* Access bottom screen */
  170.                                     window(1,Numrows-1,Numcols,Numrows);
  171.                                     textattr(SplitColors);
  172.                                     gotoxy(sp->bsavex,sp->bsavey);
  173.                                     cputs(" \b\b_\b");
  174.                                     sp->bsavex = wherex();
  175.                                     sp->bsavey = wherey();
  176.   
  177.                         /* Back to top screen */
  178.                                     window(1,1+StatusLines,Numcols,Numrows-2);
  179.                                     textattr(MainColors);
  180.                                     gotoxy(sp->tsavex,sp->tsavey);
  181.                                 } else {
  182. #ifdef UNIX
  183.                                     cputs("\b \b");
  184. #else
  185.                                     if(StatusLines)
  186.                                         cputs("\b \b");
  187.                                     else
  188.                                         fputs("\b \b",Rawterm);
  189. #endif
  190.                                 }
  191.                             }
  192.                         }
  193.                         break;
  194.                     case CTLR:  /* print line buffer */
  195.                         if(sp->ttystate.echo){
  196.                             if(sp->split) {
  197.                     /* Save cursor in top screen */
  198.                                 sp->tsavex = wherex();
  199.                                 sp->tsavey = wherey();
  200.   
  201.                     /* Access bottom screen */
  202.                                 window(1,Numrows-1,Numcols,Numrows);
  203.                                 textattr(SplitColors);
  204.                                 gotoxy(sp->bsavex,sp->bsavey);
  205.                                 clrscr();
  206.                                 rp = bp->data;
  207.                                 while (rp < cp)
  208.                                     putch(*rp++) ;
  209.                                 cputs("_\b");
  210.                                 sp->bsavex = wherex();
  211.                                 sp->bsavey = wherey();
  212.   
  213.                     /* Back to top screen */
  214.                                 window(1,1+StatusLines,Numcols,Numrows-2);
  215.                                 textattr(MainColors);
  216.                                 gotoxy(sp->tsavex,sp->tsavey);
  217.                             } else {
  218. #ifdef UNIX
  219.                                 cputs("^R");
  220.                                 cputs(Eol);
  221.                                 rp = bp->data;
  222.                                 while (rp < cp)
  223.                                     putch(*rp++);
  224. #else
  225.                                 if(StatusLines)
  226.                                     cprintf("^R%s",Eol);
  227.                                 else
  228.                                     fprintf(Rawterm,"^R%s",Eol) ;
  229.                                 rp = bp->data;
  230.                                 while (rp < cp)
  231.                                     if(StatusLines)
  232.                                         putch(*rp++);
  233.                                     else
  234.                                         putc(*rp++,Rawterm) ;
  235. #endif
  236.                             }
  237.                         }
  238.                         break ;
  239.                     case CTLU:  /* Line kill */
  240.                         if(sp->split) {
  241.                 /* Save cursor in top screen */
  242.                             sp->tsavex = wherex();
  243.                             sp->tsavey = wherey();
  244.   
  245.                 /* Access bottom screen */
  246.                             window(1,Numrows-1,Numcols,Numrows);
  247.                             textattr(SplitColors);
  248.                             gotoxy(sp->bsavex,sp->bsavey);
  249.                             cputs(" \b");
  250.                             while(bp->cnt != 0){
  251.                                 cputs("\b \b");
  252.                                 bp->cnt--;
  253.                             }
  254.                             cputs("_\b");
  255.                             sp->bsavex = wherex();
  256.                             sp->bsavey = wherey();
  257.   
  258.                 /* Back to top screen */
  259.                             window(1,1+StatusLines,Numcols,Numrows-2);
  260.                             textattr(MainColors);
  261.                             gotoxy(sp->tsavex,sp->tsavey);
  262.                         } else {
  263.                             while(bp->cnt != 0){
  264.                                 bp->cnt--;
  265.                                 if(sp->ttystate.echo)
  266. #ifdef UNIX
  267.                                     cputs("\b \b");
  268. #else
  269.                                 if(StatusLines)
  270.                                     cputs("\b \b");
  271.                                 else
  272.                                     fputs("\b \b",Rawterm);
  273. #endif
  274.                             }
  275.                         }
  276.                         break;
  277.                     case CTLB:  /* Use last line to finish current */
  278.                         cnt = bp->cnt;      /* save count so far */
  279.   
  280.                         while(bp->cnt != 0){
  281.                             bp->cnt--;
  282.                             if(sp->ttystate.echo)
  283. #ifdef UNIX
  284.                                 cputs("\b \b");
  285. #else
  286.                             if(StatusLines)
  287.                                 cputs("\b \b");
  288.                             else
  289.                                 fputs("\b \b", Rawterm);
  290. #endif
  291.                         }
  292.                         bp->cnt = cnt;
  293.                         if(bp->cnt < (Lastsize-1)){
  294.                             memcpy(bp->data+bp->cnt, &Lastline[bp->cnt], (Lastsize-1) - bp->cnt);
  295.                             bp->cnt = Lastsize-1;
  296.                         }
  297.                         *(bp->data + bp->cnt) = '\0';   /* make it a string */
  298.                         if(sp->ttystate.echo)
  299. #ifdef UNIX
  300.                             cputs(bp->data);
  301. #else
  302.                         if(StatusLines)
  303.                             cputs(bp->data);
  304.                         else
  305.                             fputs(bp->data, Rawterm);   /* repaint line */
  306. #endif
  307.                         break ;
  308.                     case CTLW:  /* erase word */
  309.                         cnt = 0 ;   /* we haven't seen a printable char yet */
  310.                         while(bp->cnt != 0){
  311.                             *(bp->data + bp->cnt--) = '\n';
  312.                             if(sp->ttystate.echo)
  313. #ifdef UNIX
  314.                                 cputs("\b \b");
  315. #else
  316.                             if(StatusLines)
  317.                                 cputs("\b \b");
  318.                             else
  319.                                 fputs("\b \b", Rawterm);
  320. #endif
  321.                             if (isspace((int)*(bp->data + bp->cnt))) {
  322.                                 if (cnt)
  323.                                     break ;
  324.                             } else {
  325.                                 cnt = 1 ;
  326.                             }
  327.                         }
  328.                         break ;
  329.                     case UPARROW:  /* Recall previous command - WG7J */
  330.                         if(Histry) {
  331.                 /* Blank out what's already there */
  332.                             while(bp->cnt != 0 && sp->ttystate.echo){
  333.                                 bp->cnt--;
  334.                                 cputs("\b \b");
  335.                             }
  336.                 /* Recall last command */
  337.                             strcpy(bp->data,Histry->cmd);
  338.                             bp->cnt = strlen(Histry->cmd);
  339.                 /* Adjust history */
  340.                             Histry = Histry->prev;
  341.                 /* repaint line */
  342.                             if(sp->ttystate.echo)
  343.                                 cputs(bp->data);
  344.                         }
  345.                         break ;
  346.                     case DNARROW:  /* Recall next command - WG7J */
  347.                         if(Histry) {
  348.                 /* Blank out what's already there */
  349.                             while(bp->cnt != 0 && sp->ttystate.echo){
  350.                                 bp->cnt--;
  351.                                 cputs("\b \b");
  352.                             }
  353.                 /* Adjust history */
  354.                             Histry = Histry->next;
  355.                 /* Recall last command */
  356.                             strcpy(bp->data,Histry->cmd);
  357.                             bp->cnt = strlen(Histry->cmd);
  358.                 /* repaint line */
  359.                             if(sp->ttystate.echo)
  360.                                 cputs(bp->data);
  361.                         }
  362.                         break ;
  363.                     default:    /* Ordinary character */
  364.                         *cp = c;
  365.                         bp->cnt++;
  366.   
  367.             /* ^Z apparently hangs the terminal emulators under
  368.              * DoubleDos and Desqview. I REALLY HATE having to patch
  369.              * around other people's bugs like this!!!
  370.              */
  371.                         if(sp->ttystate.echo &&
  372. #ifndef AMIGA
  373.                             c != CTLZ &&
  374. #endif
  375.                         bp->cnt < LINESIZE-1){
  376.                             if(sp->split) {
  377.                     /* Save cursor in top screen */
  378.                                 sp->tsavex = wherex();
  379.                                 sp->tsavey = wherey();
  380.   
  381.                     /* Access bottom screen */
  382.                                 window(1,Numrows-1,Numcols,Numrows);
  383.                                 textattr(SplitColors);
  384.                                 gotoxy(sp->bsavex,sp->bsavey);
  385.                                 putch(c);
  386.                                 cputs("_\b");
  387.                                 sp->bsavex = wherex();
  388.                                 sp->bsavey = wherey();
  389.   
  390.                     /* Back to top screen */
  391.                                 window(1,1+StatusLines,Numcols,Numrows-2);
  392.                                 textattr(MainColors);
  393.                                 gotoxy(sp->tsavex,sp->tsavey);
  394.                             } else {
  395. #ifdef UNIX
  396.                                 putch(c);
  397. #else
  398.                                 if(StatusLines)
  399.                                     putch(c);
  400.                                 else
  401.                                     putc(c,Rawterm);
  402. #endif
  403.                             }
  404.   
  405.                         } else if(bp->cnt >= LINESIZE-1){
  406. #ifdef UNIX
  407.                             write(1, "\007", 1);
  408. #else
  409.                             putc('\007',Rawterm);   /* Beep */
  410. #endif                bp->cnt--;
  411.                         }
  412.                         break;
  413.                 }
  414.                 break;
  415.             }
  416.             return NULLBUF;
  417.     }
  418.   
  419. #else /* SPLITSCREEN */
  420.   
  421.   
  422. /* Accept characters from the incoming tty buffer and process them
  423.  * (if in cooked mode) or just pass them directly (if in raw mode).
  424.  *
  425.  * Echoing (if enabled) is direct to the raw terminal. This requires
  426.  * recording (if enabled) of locally typed info to be done by the session
  427.  * itself so that edited output instead of raw input is recorded.
  428.  */
  429.     struct mbuf *
  430.     ttydriv(sp,c)
  431.     struct session *sp;
  432.     int c;
  433.     {
  434.         struct mbuf *bp;
  435.         char *cp,*rp;
  436.   
  437.         switch(sp->ttystate.edit){
  438.             case OFF:
  439.                 bp = ambufw(1);
  440.                 *bp->data = c;
  441.                 bp->cnt = 1;
  442.                 if(sp->ttystate.echo)
  443. #ifdef UNIX
  444.                     putch(c);
  445. #else
  446.                 putc(c,Rawterm);
  447. #endif
  448.   
  449.                 return bp;
  450.             case ON:
  451.                 if(sp->ttystate.line == NULLBUF)
  452.                     sp->ttystate.line = ambufw(LINESIZE);
  453.   
  454.                 bp = sp->ttystate.line;
  455.                 cp = bp->data + bp->cnt;
  456.         /* Allow for international character sets - WG7J */
  457.         /* Perform cooked-mode line editing */
  458. /*        switch(c & 0x7f){ */
  459.                 switch(c) {
  460.                     case '\r':  /* CR and LF both terminate the line */
  461.                     case '\n':
  462.                         if(sp->ttystate.crnl)
  463.                             *cp = '\n';
  464.                         else
  465.                             *cp = c;
  466.                         if(sp->ttystate.echo)
  467. #ifdef UNIX
  468.                             cputs(Eol);
  469. #else
  470.                         fputs(Eol,Rawterm);
  471. #endif
  472.   
  473.                         bp->cnt += 1;
  474.                         sp->ttystate.line = NULLBUF;
  475.                         return bp;
  476.                     case DEL:
  477.                     case '\b':  /* Character delete */
  478.                         if(bp->cnt != 0){
  479.                             bp->cnt--;
  480.                             if(sp->ttystate.echo)
  481. #ifdef UNIX
  482.                                 cputs("\b \b");
  483. #else
  484.                             fputs("\b \b",Rawterm);
  485. #endif
  486.                         }
  487.                         break;
  488.                     case CTLR:  /* print line buffer */
  489.                         if(sp->ttystate.echo){
  490. #ifdef UNIX
  491.                             cputs("^R");
  492.                             cputs(Eol);
  493.                             rp = bp->data;
  494.                             while (rp < cp)
  495.                                 putch(*rp++);
  496. #else
  497.                             fprintf(Rawterm,"^R%s",Eol) ;
  498.                             rp = bp->data;
  499.                             while (rp < cp)
  500.                                 putc(*rp++,Rawterm) ;
  501. #endif
  502.                         }
  503.                         break ;
  504.                     case CTLU:  /* Line kill */
  505.                         while(bp->cnt != 0){
  506.                             bp->cnt--;
  507.                             if(sp->ttystate.echo){
  508. #ifdef UNIX
  509.                                 cputs("\b \b");
  510. #else
  511.                                 fputs("\b \b",Rawterm);
  512. #endif
  513.                             }
  514.                         }
  515.                         break;
  516.                     case UPARROW:  /* Recall previous command - WG7J */
  517.                         if(Histry) {
  518.                 /* Blank out what's already there */
  519.                             while(bp->cnt != 0 && sp->ttystate.echo){
  520.                                 bp->cnt--;
  521.                                 cputs("\b \b");
  522.                             }
  523.                 /* Recall last command */
  524.                             strcpy(bp->data,Histry->cmd);
  525.                             bp->cnt = strlen(Histry->cmd);
  526.                 /* Adjust history */
  527.                             Histry = Histry->prev;
  528.                 /* repaint line */
  529.                             if(sp->ttystate.echo)
  530.                                 cputs(bp->data);
  531.                         }
  532.                         break ;
  533.                     case DNARROW:  /* Recall next command - WG7J */
  534.                         if(Histry) {
  535.                 /* Blank out what's already there */
  536.                             while(bp->cnt != 0 && sp->ttystate.echo){
  537.                                 bp->cnt--;
  538.                                 cputs("\b \b");
  539.                             }
  540.                 /* Adjust history */
  541.                             Histry = Histry->next;
  542.                 /* Recall last command */
  543.                             strcpy(bp->data,Histry->cmd);
  544.                             bp->cnt = strlen(Histry->cmd);
  545.                 /* repaint line */
  546.                             if(sp->ttystate.echo)
  547.                                 cputs(bp->data);
  548.                         }
  549.                         break ;
  550.                     default:    /* Ordinary character */
  551.                         *cp = c;
  552.                         bp->cnt++;
  553.   
  554.             /* ^Z apparently hangs the terminal emulators under
  555.              * DoubleDos and Desqview. I REALLY HATE having to patch
  556.              * around other people's bugs like this!!!
  557.              */
  558.                         if(sp->ttystate.echo &&
  559. #ifndef AMIGA
  560.                             c != CTLZ &&
  561. #endif
  562.                         bp->cnt < LINESIZE-1){
  563. #ifdef UNIX
  564.                             putch(c);
  565. #else
  566.                             putc(c,Rawterm);
  567. #endif
  568.                         } else if(bp->cnt >= LINESIZE-1){
  569. #ifdef UNIX
  570.                             write(1, "\007", 1);
  571. #else
  572.                             putc('\007',Rawterm);   /* Beep */
  573. #endif
  574.                             bp->cnt--;
  575.                         }
  576.                         break;
  577.                 }
  578.                 break;
  579.         }
  580.         return NULLBUF;
  581.     }
  582.   
  583. #endif /* SPLITSCREEN */
  584.