home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / mincom15.zip / keyserv.c < prev    next >
C/C++ Source or Header  |  1993-09-04  |  5KB  |  231 lines

  1. /*
  2.  * This file is part of the Minicom Communications Program,
  3.  * written by Miquel van Smoorenburg 1991/1992/1993.
  4.  *
  5.  * Keyserv.c    - a process that translates keypresses to
  6.  *          ANSI, VT100 or MINIX escape sequences.
  7.  *
  8.  *           Communications with this process from minicom
  9.  *          goes through pipes, file descriptors 3 & 4.
  10.  */
  11.  
  12. #include <sys/types.h>
  13. #include <signal.h>
  14. #include <string.h>
  15. #if defined (_POSIX_SOURCE) || defined(_BSD43)
  16. #  include <unistd.h>
  17. #endif
  18. #include <setjmp.h>
  19. #undef NULL
  20. #include <stdio.h>
  21.  
  22. #include "window.h"
  23. #include "keyboard.h"
  24. #include "minicom.h"
  25. #include "vt100.h"
  26.  
  27. /* Emulation modes */
  28. #define VT100    1
  29. #define MINIX    2
  30. #define ANSI    3
  31.  
  32. /* Pipe file descriptors */
  33. #define from_minicom 3
  34. #define to_minicom   4
  35.  
  36. /* Set modes to normal */
  37. int keypadmode = NORMAL;
  38. int cursormode = NORMAL;
  39.  
  40. char *_tptr = CNULL;        /* Pointer to termcap information */
  41. int mode = VT100;        /* Emulation mode selector */
  42. int parent;            /* Process ID of minicom */
  43. jmp_buf mainloop;        /* To jump to after a 'HELLO' signal */
  44. char **escseq;            /* Translation table to use */
  45. static int argument;        /* Argument to 'HELLO' command */
  46. static int esc_char = 1;    /* Escape character (initially ^A) */
  47. static int bs_code = 8;        /* Code that backspace key sends */
  48. extern int pendingkeys;        /* From wkeys.c */
  49.  
  50. char *st_vtesc[] = {
  51.   "", "\033OP", "\033OQ", "\033OR", "\033OS", "", "", "", "", "", "",
  52.   "\033[H", "", "\033[A", "\033[D", "\033[C", "\033[B", "\033[K", "",
  53.   "", "\177" };
  54.  
  55. char *app_vtesc[] = {
  56.   "", "\033OP", "\033OQ", "\033OR", "\033OS", "", "", "", "", "", "",
  57.   "\033[H", "", "\033OA", "\033OD", "\033OC", "\033OB", "\033[K", "",
  58.   "", "\177" };
  59.  
  60. char *minixesc[] = {
  61.   "", "\033OP", "\033OQ", "\033OR", "\033OS", "\033OT", "\033OU", "\033OV",
  62.   "\033OW", "\033OX", "\033OY", "\033[H", "\033[V", "\033[A", "\033[D",
  63.   "\033[C", "\033[B", "\033[Y", "\033[U", "0", "\177" };
  64.  
  65. char *ansiesc[] = {
  66.   "", "\033OP", "\033OQ", "\033OR", "\033OS", "\033OT", "\033OU", "\033OV",
  67.   "\033OW", "\033OX", "\033OY", "\033[H", "\033[V", "\033[A", "\033[D",
  68.   "\033[C", "\033[B", "\033[Y", "\033[U", "0", "\177" };
  69.  
  70. /*
  71.  * We got a signal. This means that there is some information for us.
  72.  * Read it, and jump to the main loop.
  73.  */
  74. /*ARGSUSED*/
  75. void handler(dummy)
  76. int dummy;
  77. {
  78.   unsigned char buf[8];
  79.   int n;
  80.  
  81.   signal(HELLO, handler);
  82.   n = read(from_minicom, buf, 8);
  83.   if (n <= 0) {
  84.       n = 2;
  85.       buf[0] = 0;
  86.   }
  87.   if (n % 2 == 1) {
  88.     n++;
  89.     read(from_minicom, buf + n, 1);
  90.   }
  91.   argument = buf[n-1];
  92.   longjmp(mainloop, (int)buf[n - 2]);
  93. }
  94.  
  95. /*
  96.  * Send a string to the modem
  97.  */
  98. void sendstr(s)
  99. char *s;
  100. {
  101.   write(1, s, strlen(s));
  102. }
  103.  
  104. /*
  105.  * Main program of keyserv.
  106.  */
  107. int main(argc, argv)
  108. int argc;
  109. char **argv;
  110. {
  111.   int c;
  112.   char ch;
  113.   int f, fun;
  114.   int stopped = 0;
  115.  
  116. #ifdef _COH3
  117.   parent = atoi(argv[1]);
  118. #else
  119.   parent = getppid();
  120. #endif
  121.   
  122.   /* Initialize signal handlers */
  123.   signal(SIGHUP, SIG_IGN);
  124.   signal(SIGQUIT, SIG_IGN);
  125.   signal(SIGINT, SIG_IGN);
  126. #ifdef SIGTSTP
  127.   signal(SIGTSTP, SIG_IGN);
  128.   signal(SIGTTIN, SIG_IGN);
  129.   signal(SIGTTOU, SIG_IGN);
  130. #endif
  131.   signal(HELLO, handler);
  132.  
  133.   /* Set up escape sequence table */
  134.   escseq = st_vtesc;
  135.  
  136.   /* Cbreak, no echo (minicom itself sets to raw if needed) */
  137.   (void) setcbreak(1);
  138.  
  139.   if ((fun = setjmp(mainloop)) != 0) {
  140.  
  141.       switch(fun) {
  142.  
  143.       /* We come here after minicom has told us something */
  144.  
  145.       case KVT100: /* VT100 keyboard */
  146.         mode = VT100;
  147.         escseq = st_vtesc;
  148.         break;
  149.     case KANSI:  /* ANSI keyboard */
  150.         mode = ANSI;
  151.         escseq = ansiesc;
  152.         break;
  153.     case KMINIX: /* MINIX keyboard */
  154.         mode = MINIX;
  155.         escseq = minixesc;
  156.         break;
  157.     case KKPST: /* Keypad in standard mode, not used */
  158.         keypadmode = NORMAL; 
  159.         break;
  160.     case KKPAPP: /* Keypad in applications mode, not used */
  161.         keypadmode = APPL;
  162.         break;
  163.     case KCURST: /* Standard cursor keys */
  164.         cursormode = NORMAL;
  165.         if (mode == VT100)
  166.             escseq = st_vtesc;
  167.         break;
  168.     case KCURAPP: /* cursor keys in applications mode */
  169.         cursormode = APPL;
  170.         if (mode == VT100)
  171.             escseq = app_vtesc;
  172.         break;
  173.     case KSTOP:  /* Sleep until further notice */
  174.         stopped = 1;
  175.         break;
  176.     case KSIGIO: /* Wait for keypress and tell parent */
  177.         kill(parent, ACK);
  178.         f = read(0, &ch, 1);
  179.         if (f == 1) {
  180.             write(to_minicom, &ch, 1);
  181.             (void) kill(parent, HELLO);
  182.         }
  183.         break;
  184.     case KSTART: /* Restart when stopped */
  185.         stopped  = 0;
  186.         break;
  187.     case KSETBS: /* Set code that BS key sends */
  188.         bs_code = argument;
  189.         break;
  190.     case KSETESC: /* Set escape character */
  191.         esc_char = argument;
  192.         break;
  193.     default:
  194.         break;
  195.     }
  196.     if (fun != KSIGIO) {
  197.     kill(parent, ACK);
  198.     }
  199.   }
  200.   /* Wait if stopped */
  201.   if (stopped) pause();
  202.  
  203.   /* Main loop: read keyboard, send to modem */
  204.   while(1) {
  205.       c = getch();
  206.       if (c > 256 && c < 256 + NUM_KEYS) {
  207.           sendstr(escseq[c - 256]);
  208.       }
  209.       if (c < 256) {
  210.           if (c == K_ERA) c = bs_code;
  211.           ch = c;
  212.           /* Test for escape characters */
  213.           if (c == esc_char || (esc_char == 128 && c > 128)) { 
  214.             /* If we typed too fast, and the escape sequence
  215.              * was not that of a function key, the next key
  216.              * is already in the buffer.
  217.              */
  218.             if (c == esc_char && pendingkeys > 0) {
  219.                 ch = getch();
  220.             }
  221.               write(to_minicom, &ch, 1);
  222.               (void) kill(parent, HELLO);
  223.           } else {
  224.               write(1, &ch, 1);
  225.           }
  226.       }
  227.   }
  228.   /*NOTREACHED*/
  229.   return(0);
  230. }
  231.