home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / KA9Q212.ZIP / TTYDRIV.C < prev    next >
C/C++ Source or Header  |  1993-03-07  |  4KB  |  198 lines

  1. /* TTY input line editing
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "session.h"
  8. #include "tty.h"
  9. #include "socket.h"
  10.  
  11. extern FILE *Rawterm;
  12.  
  13. #define    OFF    0
  14. #define    ON    1
  15.  
  16. #define    LINESIZE    256
  17.  
  18. #define    CTLU    21
  19. #define CTLR    18
  20. #define    CTLZ    26
  21. #define LEFT    330
  22. #define RIGHT    332
  23. #define UP        327
  24. #define DOWN    335
  25. #define HOME    326
  26. #define END        334
  27. #define    BS        0x7f
  28. #define DEL        338
  29.  
  30. /* Accept characters from the incoming tty buffer and process them
  31.  * (if in cooked mode) or just pass them directly (if in raw mode).
  32.  *
  33.  * Echoing (if enabled) is direct to the raw terminal. This requires
  34.  * recording (if enabled) of locally typed info to be done by the session
  35.  * itself so that edited output instead of raw input is recorded.
  36.  */
  37. struct mbuf *
  38. ttydriv(sp,c)
  39. struct session *sp;
  40. int c;
  41. {
  42.     struct mbuf *bp;
  43.     char *cp,*rp, cc;
  44.     int dif, i;
  45.     cc = c % 256;
  46.     switch(sp->ttystate.edit){
  47.     case OFF:
  48.         bp = ambufw(1);
  49.         *bp->data = cc;
  50.         bp->cnt = 1;
  51.         if(sp->ttystate.echo)
  52.             putc(c,Rawterm);
  53.  
  54.         return bp;
  55.     case ON:
  56.         if(sp->ttystate.line == NULLBUF)
  57.             sp->ttystate.line = ambufw(LINESIZE);
  58.  
  59.         bp = sp->ttystate.line;
  60.         cp = bp->data + sp->cur_pos;
  61.         dif = bp->cnt - sp->cur_pos;
  62.         /* Perform cooked-mode line editing */
  63.         switch(c){
  64.         case '\r':    /* CR and LF both terminate the line */
  65.         case '\n':
  66.             if(sp->ttystate.crnl)
  67.                 *(cp + dif) = '\n';
  68.             else
  69.                 *(cp + dif) = cc;
  70.             if(sp->ttystate.echo)
  71.                 fputs(Eol,Rawterm);
  72.             bp->cnt += 1;
  73.             sp->ttystate.line = NULLBUF;
  74.             return bp;
  75.         case DEL:
  76.             if (dif == 0)
  77.                 break;
  78.             /* Forward a character */
  79.             sp->cur_pos++;
  80.             dif--;
  81.             cp++;
  82.             putc(' ', Rawterm);
  83.             /* Now drop through to delete backwards */
  84.         case BS:
  85.         case '\b':    /* Character delete */
  86.             if(sp->cur_pos)
  87.                 {
  88.                 bp->cnt--;
  89.                 sp->cur_pos--;
  90.                 if(sp->ttystate.echo)
  91.                     fputs("\b \b",Rawterm);
  92.                 if (dif)
  93.                     {
  94.                     memmove(cp - 1, cp, dif);
  95.                     if(sp->ttystate.echo)
  96.                         {
  97.                         for (i = 0; i < dif; i++)
  98.                             putc(*(cp + i - 1), Rawterm);
  99.                         putc(' ', Rawterm);
  100.                         for (i = 0; i <= dif; i++)
  101.                             fputs("\b", Rawterm);
  102.                         }
  103.                     }
  104.                 }
  105.             break;
  106.         case CTLR:    /* print line buffer */
  107.             if(sp->ttystate.echo)
  108.                 {
  109.                 fprintf(Rawterm,"^R%s",Eol);
  110.                 rp = bp->data;
  111.                 while (rp < cp)
  112.                     putc(*rp++,Rawterm);
  113.                 }
  114.             break ;
  115.         case CTLU:    /* Line kill */
  116.             while (dif--)
  117.                 putc(' ', Rawterm);
  118.             while(bp->cnt != 0)
  119.                 {
  120.                 bp->cnt--;
  121.                 if(sp->ttystate.echo)
  122.                     fputs("\b \b",Rawterm);
  123.                 }
  124.             sp->cur_pos = 0;
  125.             break;
  126.         case LEFT:        /* Cursor left */
  127.             if (sp->cur_pos > 0)
  128.                 {
  129.                 sp->cur_pos--;
  130.                 fputs("\b",Rawterm);
  131.                 }
  132.             break;
  133.         case RIGHT:    /* Cursor right */
  134.             if (sp->cur_pos < bp->cnt)
  135.                 {
  136.                 sp->cur_pos++;
  137.                 if(sp->ttystate.echo)
  138.                     putc(*cp, Rawterm);
  139.                 }
  140.             break;
  141.         case HOME:    /* Back to start of line */
  142.             while (sp->cur_pos)
  143.                 {
  144.                 sp->cur_pos--;
  145.                 if(sp->ttystate.echo)
  146.                     fputs("\b", Rawterm);
  147.                 }
  148.             break;
  149.         case END:    /* Go to end of line */
  150.             for (i = 0; i < dif; i++)
  151.                 {
  152.                 if(sp->ttystate.echo)
  153.                     putc(*(cp + i), Rawterm);
  154.                 sp->cur_pos++;
  155.                 }
  156.             break;
  157.         case UP:    /* Previous line */
  158.             break;
  159.         case DOWN:    /* Next line */
  160.             break;
  161.         default:    /* Ordinary character */
  162.             if (dif)
  163.                 memmove(cp + 1, cp, dif);
  164.             *cp = cc;
  165.             bp->cnt++;
  166.             sp->cur_pos++;
  167.  
  168.             /* ^Z apparently hangs the terminal emulators under
  169.              * DoubleDos and Desqview. I REALLY HATE having to patch
  170.              * around other people's bugs like this!!!
  171.              */
  172.             if(sp->ttystate.echo &&
  173. #ifndef    AMIGA
  174.              c != CTLZ &&
  175. #endif
  176.              bp->cnt < LINESIZE-1)
  177.                 {
  178.                 putc(cc,Rawterm);
  179.                 if (dif)
  180.                     {
  181.                     for (i = 0; i < dif; i++)
  182.                         putc(*(cp + i + 1), Rawterm);
  183.                     for (i = 0; i < dif; i++)
  184.                         fputs("\b", Rawterm);
  185.                     }
  186.                 }
  187.             else if(bp->cnt >= LINESIZE-1)
  188.                 {
  189.                 putc('\007',Rawterm);    /* Beep */
  190.                 bp->cnt--;
  191.                 }
  192.             break;
  193.         }
  194.         break;
  195.     }
  196.     return NULLBUF;
  197. }
  198.