home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / pcomm-2.0.2 / part03 / input.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  7.2 KB  |  319 lines

  1. /*
  2.  * The input routines.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include "config.h"
  7. #include "misc.h"
  8. #include "param.h"
  9. #include "status.h"
  10. #include "vcs.h"
  11.  
  12. static int add_lf;
  13. static void vs_scroll();
  14. static FILE *logfp = (FILE *) NULL;
  15. static FILE *lprfp = (FILE *) NULL;
  16.  
  17. /*
  18.  * Read the serial port and write the characters to the screen.  Watch
  19.  * for changes in status structure to toggle the fancy options.
  20.  * Writes the characters received to a virtual screen buffer.
  21.  */
  22.  
  23. void
  24. tty_input()
  25. {
  26.     extern int fd;
  27.     register int in_cnt, out_cnt;
  28.     char c, *bufp, in_buf[INPUT_BUF], out_buf[INPUT_BUF*2];
  29.     void vs_putchar();
  30.  
  31.                     /* here we go... */
  32.     if ((in_cnt = read(fd, in_buf, INPUT_BUF)) <= 0)
  33.         return;
  34.  
  35.     /*
  36.      * If we're doing a script, send a duplicate down the pipe
  37.      */
  38.     if (status->dup_fd != -1)
  39.         write(status->dup_fd, in_buf, in_cnt);
  40.  
  41.                     /* "peel" the buffer one at a time */
  42.     out_cnt = 0;
  43.     bufp = in_buf;
  44.     add_lf = !strcmp(param->cr_in, "CR/LF");
  45.     while (--in_cnt >= 0) {
  46.         c = *bufp++ & 0xff;
  47.                     /* send to logfile? */
  48.         if (status->log_status) {
  49.             if (c == '\r' && add_lf)
  50.                 putc('\n', logfp);
  51.                     /* no carriage returns in logfile */
  52.             if (c != '\r')
  53.                 putc(c, logfp);
  54.         }
  55.                     /* send to printer too? */
  56.         if (status->print_status)
  57.             putc(c, lprfp);
  58.  
  59.                     /* put a char in virtual screen */
  60.         vs_putchar(c);
  61.  
  62.                     /* build the output buffer */
  63.         out_buf[out_cnt++] = c;
  64.         if (c == '\r' && add_lf)
  65.             out_buf[out_cnt++] = '\n';
  66.  
  67.                     /* output in smaller chunks */
  68.         if (out_cnt >= OUTPUT_BUF) {
  69.             write(1, out_buf, out_cnt);
  70.             out_cnt = 0;
  71.         }
  72.     }
  73.     if (out_cnt)
  74.         write(1, out_buf, out_cnt);
  75.     
  76.     return;
  77. }
  78.  
  79. /*
  80.  * Put a character in the virtual screen.  This routine saves incoming
  81.  * characters in a two dimensional buffer designed to mimic the real
  82.  * screen.
  83.  */
  84.  
  85. void
  86. vs_putchar(c)
  87. char c;
  88. {
  89.     register int i;
  90.     extern int vcs_param[NUM_VCS][5], vcs_opt[NUM_VCS][10];
  91.     char *memset();
  92.     int tab_stop;
  93.  
  94.     switch (vcs_filter(c)) {
  95.         case MAYBE:        /* wait and see... */
  96.             break;
  97.         case 256+HOME:        /* home virtual screen "cursor" */
  98.             status->row = 0;
  99.             status->col = 0;
  100.             break;
  101.         case 256+CLR_EOL:    /* clear to end of line */
  102.             memset(&status->vs[status->row][status->col], ' ', status->max_col - status->col);
  103.             status->col = status->max_col -1;
  104.             break;
  105.         case 256+CLR_EOS:    /* clear to end of screen */
  106.             memset(&status->vs[status->row][status->col], ' ', status->max_col - status->col);
  107.             for (i=status->row+1; i<status->max_row; i++)
  108.                 memset(status->vs[i], ' ', status->max_col);
  109.             status->row = status->max_row -1;
  110.             status->col = status->max_col -1;
  111.             break;
  112.         case 256+CLEAR:        /* clear all and home "cursor" */
  113.             for (i=0; i<status->max_row; i++)
  114.                 memset(status->vs[i], ' ', status->max_col);
  115.             status->row = 0;
  116.             status->col = 0;
  117.             break;
  118.         case 256+MV_UP:        /* move "cursor" up */
  119.             status->row--;
  120.             if (status->row < 0)
  121.                 status->row = 0;
  122.             break;
  123.         case 256+MV_DOWN:    /* move "cursor" down */
  124.             status->row++;
  125.             if (status->row >= status->max_row)
  126.                 status->row = status->max_row -1;
  127.             break;
  128.         case 256+MV_RIGHT:    /* move "cursor" right */
  129.             status->col++;
  130.             if (status->col >= status->max_col)
  131.                 status->col = status->max_col -1;
  132.             break;
  133.         case 256+MV_LEFT:    /* move "cursor" left */
  134.         case BS:        /* non destructive back space */
  135.             status->col--;
  136.             if (status->col < 0)
  137.                 status->col = 0;
  138.             break;
  139.         case 256+MV_DIRECT:    /* direct cursor movement */
  140.             status->row = vcs_param[MV_DIRECT][0];
  141.             status->col = vcs_param[MV_DIRECT][1];
  142.  
  143.                     /* if "add one" and "decimal" */
  144.             if (vcs_opt[MV_DIRECT][0] && vcs_opt[MV_DIRECT][1]) {
  145.                 status->row--;
  146.                 status->col--;
  147.             }
  148.                     /* if "character" */
  149.             if (vcs_opt[MV_DIRECT][2]) {
  150.                     /* if "add offset" */
  151.                 if (vcs_opt[MV_DIRECT][3]) {
  152.                     status->row -= vcs_opt[MV_DIRECT][5];
  153.                     status->col -= vcs_opt[MV_DIRECT][5];
  154.                 }
  155.                     /* if "subtract offset" */
  156.                 if (vcs_opt[MV_DIRECT][4]) {
  157.                     status->row += vcs_opt[MV_DIRECT][5];
  158.                     status->col += vcs_opt[MV_DIRECT][5];
  159.                 }
  160.                 status->row--;
  161.                 status->col--;
  162.             }
  163.                     /* sanity check... */
  164.             if (status->row < 0)
  165.                 status->row = 0;
  166.             if (status->col < 0)
  167.                 status->col = 0;
  168.             if (status->row >= status->max_row)
  169.                 status->row = status->max_row -1;
  170.             if (status->col >= status->max_col)
  171.                 status->col = status->max_col -1;
  172.             break;
  173.         case 0:
  174.         case 7:            /* skip NULL and "bell" character */
  175.             break;
  176.         case '\t':        /* tab character */
  177.             tab_stop = status->col + 8 - (status->col % 8);
  178.                     /* if wrap around */
  179.             if (tab_stop >= status->max_col) {
  180.                     /* spaces up to eol */
  181.                 memset(&status->vs[status->row][status->col], ' ', status->max_col - status->col);
  182.                 status->row++;
  183.                 if (status->row >= status->max_row)
  184.                     vs_scroll();
  185.  
  186.                     /* the remainder of the tab */
  187.                 status->col = tab_stop - status->max_col;
  188.             }
  189.             else {
  190.                 memset(&status->vs[status->row][status->col], ' ', tab_stop - status->col);
  191.                 status->col = tab_stop;
  192.             }
  193.             break;
  194.         case '\r':        /* carriage return */
  195.             status->col = 0;
  196.             if (!add_lf)
  197.                 break;
  198.             /* FALLTHRU */
  199.         case '\n':        /* line feed */
  200.             status->row++;
  201.             if (status->row >= status->max_row)
  202.                 vs_scroll();
  203.             break;
  204.         default:        /* a normal character */
  205.             status->vs[status->row][status->col] = c;
  206.             status->col++;
  207.                     /* wrap around */
  208.             if (status->col >= status->max_col) {
  209.                 status->col = 0;
  210.                 status->row++;
  211.                 if (status->row >= status->max_row)
  212.                     vs_scroll();
  213.             }
  214.             break;
  215.     }
  216.     return;
  217. }
  218.  
  219. /*
  220.  * Do a software scroll on the virtual screen.  Does not alter the
  221.  * "col" variable.
  222.  */
  223.  
  224. static void
  225. vs_scroll()
  226. {
  227.     char *memset();
  228.                     /* move 'em up 1 line */
  229. #ifdef MEMMOVE
  230.     MEMMOVE(status->vs[0], status->vs[1], (status->max_row -1) * MAX_COL);
  231. #else /* MEMMOVE */
  232.     register int i;
  233.     char *strcpy();
  234.  
  235.     for (i=0; i<status->max_row-1; i++)
  236.         strcpy(status->vs[i], status->vs[i+1]);
  237. #endif /* MEMMOVE */
  238.                     /* clear the bottom line */
  239.     memset(status->vs[status->max_row-1], ' ', status->max_col);
  240.  
  241.     status->row = status->max_row -1;
  242.     return;
  243. }
  244.  
  245. /*
  246.  * A short-cut for charcters that are "echoed" in the half duplex
  247.  * mode.  Since the TTY driver is putting the characters on the
  248.  * screen (rather than being sent back by the modem), they need
  249.  * to be faked as modem input.
  250.  */
  251.  
  252. void
  253. half_duplex(c)
  254. char c;
  255. {
  256.                     /* send to logfile? */
  257.     if (status->log_status) {
  258.         if (c == '\r' && add_lf)
  259.             putc('\n', logfp);
  260.                     /* no carriage returns in logfile */
  261.         if (c != '\r')
  262.             putc(c, logfp);
  263.     }
  264.                     /* send to printer too? */
  265.     if (status->print_status)
  266.         putc(c, lprfp);
  267.  
  268.                     /* put a char in virtual screen */
  269.     vs_putchar(c);
  270.     return;
  271. }
  272.  
  273. /*
  274.  * Toggle the printer log
  275.  */
  276.  
  277. void
  278. lpr_toggle()
  279. {
  280.     FILE *n_popen();
  281.  
  282.     status->print_status = status->print_status ? 0 : 1;
  283.  
  284.     if (status->print_status && lprfp == NULL) {
  285.         if (!(lprfp = n_popen(LPR, "w")))
  286.             status->print_status = 0;
  287.     }
  288.  
  289.     if (!status->print_status && lprfp != NULL) {
  290.         putc('\f', lprfp);
  291.         n_pclose(lprfp);
  292.         lprfp = (FILE *) NULL;
  293.     }
  294.     return;
  295. }
  296.  
  297. /*
  298.  * Toggle the data log
  299.  */
  300.  
  301. void
  302. log_toggle()
  303. {
  304.     FILE *uid_fopen();
  305.  
  306.     status->log_status = status->log_status ? 0 : 1;
  307.  
  308.     if (status->log_status && logfp == NULL) {
  309.         if (!(logfp = uid_fopen(status->log_path, "a")))
  310.             status->log_status = 0;
  311.     }
  312.  
  313.     if (!status->log_status && logfp != NULL) {
  314.         fclose(logfp);
  315.         logfp = (FILE *) NULL;
  316.     }
  317.     return;
  318. }
  319.