Blame src/keyserv.c

Packit 15a96c
/*
Packit 15a96c
 * Keyserv.c	A process that translates keypresses to
Packit 15a96c
 *		ANSI or VT102 escape sequences.
Packit 15a96c
 *		Communications with this process from minicom
Packit 15a96c
 *		goes through pipes, file descriptors 3 & 4.
Packit 15a96c
 *
Packit 15a96c
 *		This file is part of the minicom communications package,
Packit 15a96c
 *		Copyright 1991-1995 Miquel van Smoorenburg.
Packit 15a96c
 *
Packit 15a96c
 *		This program is free software; you can redistribute it and/or
Packit 15a96c
 *		modify it under the terms of the GNU General Public License
Packit 15a96c
 *		as published by the Free Software Foundation; either version
Packit 15a96c
 *		2 of the License, or (at your option) any later version.
Packit 15a96c
 *  You should have received a copy of the GNU General Public License along
Packit 15a96c
 *  with this program; if not, write to the Free Software Foundation, Inc.,
Packit 15a96c
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit 15a96c
 */
Packit 15a96c
#ifdef HAVE_CONFIG_H
Packit 15a96c
#include <config.h>
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
#include <unistd.h>
Packit 15a96c
#include <stdlib.h>
Packit 15a96c
Packit 15a96c
#include "port.h"
Packit 15a96c
#include "minicom.h"
Packit 15a96c
Packit 15a96c
/* Emulation modes */
Packit 15a96c
#define EVT100	1
Packit 15a96c
#define EANSI	2
Packit 15a96c
Packit 15a96c
/* Pipe file descriptors */
Packit 15a96c
#define from_minicom 3
Packit 15a96c
#define to_minicom   4
Packit 15a96c
Packit 15a96c
/* Set modes to normal */
Packit 15a96c
int keypadmode = NORMAL;
Packit 15a96c
int cursormode = NORMAL;
Packit 15a96c
Packit 15a96c
int mode = EVT100;		/* Emulation mode selector */
Packit 15a96c
int parent;			/* Process ID of minicom */
Packit 15a96c
jmp_buf mainloop;		/* To jump to after a 'HELLO' signal */
Packit 15a96c
char **escseq;			/* Translation table to use */
Packit 15a96c
static int argument;		/* Argument to 'HELLO' command */
Packit 15a96c
static int esc_char = 1;	/* Escape character (initially ^A) */
Packit 15a96c
static int bs_code = 8;		/* Code that backspace key sends */
Packit 15a96c
Packit 15a96c
char *st_vtesc[] = {
Packit 15a96c
  "", "\033OP", "\033OQ", "\033OR", "\033OS", "", "", "", "", "", "",
Packit 15a96c
  "\033[H", "", "\033[A", "\033[D", "\033[C", "\033[B", "\033[K", "",
Packit 15a96c
  "", "\177" };
Packit 15a96c
Packit 15a96c
char *app_vtesc[] = {
Packit 15a96c
  "", "\033OP", "\033OQ", "\033OR", "\033OS", "", "", "", "", "", "",
Packit 15a96c
  "\033[H", "", "\033OA", "\033OD", "\033OC", "\033OB", "\033[K", "",
Packit 15a96c
  "", "\177" };
Packit 15a96c
Packit 15a96c
char *ansiesc[] = {
Packit 15a96c
  "", "\033OP", "\033OQ", "\033OR", "\033OS", "\033OT", "\033OU", "\033OV",
Packit 15a96c
  "\033OW", "\033OX", "\033OY", "\033[H", "\033[V", "\033[A", "\033[D",
Packit 15a96c
  "\033[C", "\033[B", "\033[Y", "\033[U", "0", "\177" };
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * We got a signal. This means that there is some information for us.
Packit 15a96c
 * Read it, and jump to the main loop.
Packit 15a96c
 */
Packit 15a96c
void handler(int dummy)
Packit 15a96c
{
Packit 15a96c
  unsigned char buf[8];
Packit 15a96c
  int n;
Packit 15a96c
Packit 15a96c
  (void)dummy;
Packit 15a96c
  signal(HELLO, handler);
Packit 15a96c
  n = read(from_minicom, buf, 8);
Packit 15a96c
  if (n <= 0) {
Packit 15a96c
    n = 2;
Packit 15a96c
    buf[0] = 0;
Packit 15a96c
  }
Packit 15a96c
  if (n % 2 == 1) {
Packit 15a96c
    n++;
Packit 15a96c
    read(from_minicom, buf + n, 1);
Packit 15a96c
  }
Packit 15a96c
  argument = buf[n-1];
Packit 15a96c
  longjmp(mainloop, (int)buf[n - 2]);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Send a string to the modem
Packit 15a96c
 */
Packit 15a96c
void sendstr(char *s)
Packit 15a96c
{
Packit 15a96c
  write(1, s, strlen(s));
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Main program of keyserv.
Packit 15a96c
 */
Packit 15a96c
int main(int argc, char **argv)
Packit 15a96c
{
Packit 15a96c
  int c;
Packit 15a96c
  char ch;
Packit 15a96c
  int f, fun;
Packit 15a96c
  int stopped = 0;
Packit 15a96c
Packit 15a96c
  if (argc < 2 || (parent = atoi(argv[1])) == 0) {
Packit 15a96c
    printf("Usage: %s <parent>\n", *argv);
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
  
Packit 15a96c
  /* Initialize signal handlers */
Packit 15a96c
  /* signal(SIGHUP, SIG_IGN); */
Packit 15a96c
  signal(SIGQUIT, SIG_IGN);
Packit 15a96c
  signal(SIGINT, SIG_IGN);
Packit 15a96c
#ifdef SIGTSTP
Packit 15a96c
  signal(SIGTSTP, SIG_IGN);
Packit 15a96c
  signal(SIGTTIN, SIG_IGN);
Packit 15a96c
  signal(SIGTTOU, SIG_IGN);
Packit 15a96c
#endif
Packit 15a96c
  signal(HELLO, handler);
Packit 15a96c
Packit 15a96c
  /* Set up escape sequence table */
Packit 15a96c
  escseq = st_vtesc;
Packit 15a96c
Packit 15a96c
  /* Cbreak, no echo (minicom itself sets to raw if needed) */
Packit 15a96c
  setcbreak(1);
Packit 15a96c
Packit 15a96c
  if ((fun = setjmp(mainloop)) != 0) {
Packit 15a96c
    switch (fun) {
Packit 15a96c
Packit 15a96c
      /* We come here after minicom has told us something */
Packit 15a96c
Packit 15a96c
      case KVT100: /* VT100 keyboard */
Packit 15a96c
        mode = EVT100;
Packit 15a96c
        escseq = st_vtesc;
Packit 15a96c
        break;
Packit 15a96c
      case KANSI:  /* ANSI keyboard */
Packit 15a96c
        mode = EANSI;
Packit 15a96c
        escseq = ansiesc;
Packit 15a96c
        break;
Packit 15a96c
      case KKPST: /* Keypad in standard mode, not used */
Packit 15a96c
        keypadmode = NORMAL; 
Packit 15a96c
        break;
Packit 15a96c
      case KKPAPP: /* Keypad in applications mode, not used */
Packit 15a96c
        keypadmode = APPL;
Packit 15a96c
        break;
Packit 15a96c
      case KCURST: /* Standard cursor keys */
Packit 15a96c
        cursormode = NORMAL;
Packit 15a96c
        if (mode == EVT100)
Packit 15a96c
          escseq = st_vtesc;
Packit 15a96c
        break;
Packit 15a96c
      case KCURAPP: /* cursor keys in applications mode */
Packit 15a96c
        cursormode = APPL;
Packit 15a96c
        if (mode == EVT100)
Packit 15a96c
          escseq = app_vtesc;
Packit 15a96c
        break;
Packit 15a96c
      case KSTOP:  /* Sleep until further notice */
Packit 15a96c
        stopped = 1;
Packit 15a96c
        break;
Packit 15a96c
      case KSIGIO: /* Wait for keypress and tell parent */
Packit 15a96c
        kill(parent, ACK);
Packit 15a96c
        f = read(0, &ch, 1);
Packit 15a96c
        if (f == 1) {
Packit 15a96c
          write(to_minicom, &ch, 1);
Packit 15a96c
          kill(parent, HELLO);
Packit 15a96c
        }
Packit 15a96c
        break;
Packit 15a96c
      case KSTART: /* Restart when stopped */
Packit 15a96c
        stopped  = 0;
Packit 15a96c
        break;
Packit 15a96c
      case KSETBS: /* Set code that BS key sends */
Packit 15a96c
        bs_code = argument;
Packit 15a96c
        break;
Packit 15a96c
      case KSETESC: /* Set escape character */
Packit 15a96c
        esc_char = argument;
Packit 15a96c
        break;
Packit 15a96c
      default:
Packit 15a96c
        break;
Packit 15a96c
    }
Packit 15a96c
    if (fun != KSIGIO)
Packit 15a96c
      kill(parent, ACK);
Packit 15a96c
  }
Packit 15a96c
  /* Wait if stopped */
Packit 15a96c
  if (stopped)
Packit 15a96c
    pause();
Packit 15a96c
Packit 15a96c
  /* Main loop: read keyboard, send to modem */
Packit 15a96c
  while (1) {
Packit 15a96c
    c = wxgetch();
Packit 15a96c
    if (c > 256 && c < 256 + NUM_KEYS) {
Packit 15a96c
      sendstr(escseq[c - 256]);
Packit 15a96c
    }
Packit 15a96c
    if (c < 256) {
Packit 15a96c
      if (c == K_ERA)
Packit 15a96c
        c = bs_code;
Packit 15a96c
      ch = c;
Packit 15a96c
      /* Test for escape characters */
Packit 15a96c
      if (c == esc_char || (esc_char == 128 && c > 128)) { 
Packit 15a96c
        /* If we typed too fast, and the escape sequence
Packit 15a96c
         * was not that of a function key, the next key
Packit 15a96c
         * is already in the buffer.
Packit 15a96c
         */
Packit 15a96c
        if (c == esc_char && pendingkeys > 0) {
Packit 15a96c
          ch = wxgetch();
Packit 15a96c
        }
Packit 15a96c
        write(to_minicom, &ch, 1);
Packit 15a96c
        kill(parent, HELLO);
Packit 15a96c
      } else {
Packit 15a96c
        write(1, &ch, 1);
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  return 0;
Packit 15a96c
}