home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 3 Comm
/
03-Comm.zip
/
mincom15.zip
/
keyserv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-04
|
5KB
|
231 lines
/*
* This file is part of the Minicom Communications Program,
* written by Miquel van Smoorenburg 1991/1992/1993.
*
* Keyserv.c - a process that translates keypresses to
* ANSI, VT100 or MINIX escape sequences.
*
* Communications with this process from minicom
* goes through pipes, file descriptors 3 & 4.
*/
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#if defined (_POSIX_SOURCE) || defined(_BSD43)
# include <unistd.h>
#endif
#include <setjmp.h>
#undef NULL
#include <stdio.h>
#include "window.h"
#include "keyboard.h"
#include "minicom.h"
#include "vt100.h"
/* Emulation modes */
#define VT100 1
#define MINIX 2
#define ANSI 3
/* Pipe file descriptors */
#define from_minicom 3
#define to_minicom 4
/* Set modes to normal */
int keypadmode = NORMAL;
int cursormode = NORMAL;
char *_tptr = CNULL; /* Pointer to termcap information */
int mode = VT100; /* Emulation mode selector */
int parent; /* Process ID of minicom */
jmp_buf mainloop; /* To jump to after a 'HELLO' signal */
char **escseq; /* Translation table to use */
static int argument; /* Argument to 'HELLO' command */
static int esc_char = 1; /* Escape character (initially ^A) */
static int bs_code = 8; /* Code that backspace key sends */
extern int pendingkeys; /* From wkeys.c */
char *st_vtesc[] = {
"", "\033OP", "\033OQ", "\033OR", "\033OS", "", "", "", "", "", "",
"\033[H", "", "\033[A", "\033[D", "\033[C", "\033[B", "\033[K", "",
"", "\177" };
char *app_vtesc[] = {
"", "\033OP", "\033OQ", "\033OR", "\033OS", "", "", "", "", "", "",
"\033[H", "", "\033OA", "\033OD", "\033OC", "\033OB", "\033[K", "",
"", "\177" };
char *minixesc[] = {
"", "\033OP", "\033OQ", "\033OR", "\033OS", "\033OT", "\033OU", "\033OV",
"\033OW", "\033OX", "\033OY", "\033[H", "\033[V", "\033[A", "\033[D",
"\033[C", "\033[B", "\033[Y", "\033[U", "0", "\177" };
char *ansiesc[] = {
"", "\033OP", "\033OQ", "\033OR", "\033OS", "\033OT", "\033OU", "\033OV",
"\033OW", "\033OX", "\033OY", "\033[H", "\033[V", "\033[A", "\033[D",
"\033[C", "\033[B", "\033[Y", "\033[U", "0", "\177" };
/*
* We got a signal. This means that there is some information for us.
* Read it, and jump to the main loop.
*/
/*ARGSUSED*/
void handler(dummy)
int dummy;
{
unsigned char buf[8];
int n;
signal(HELLO, handler);
n = read(from_minicom, buf, 8);
if (n <= 0) {
n = 2;
buf[0] = 0;
}
if (n % 2 == 1) {
n++;
read(from_minicom, buf + n, 1);
}
argument = buf[n-1];
longjmp(mainloop, (int)buf[n - 2]);
}
/*
* Send a string to the modem
*/
void sendstr(s)
char *s;
{
write(1, s, strlen(s));
}
/*
* Main program of keyserv.
*/
int main(argc, argv)
int argc;
char **argv;
{
int c;
char ch;
int f, fun;
int stopped = 0;
#ifdef _COH3
parent = atoi(argv[1]);
#else
parent = getppid();
#endif
/* Initialize signal handlers */
signal(SIGHUP, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGINT, SIG_IGN);
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
#endif
signal(HELLO, handler);
/* Set up escape sequence table */
escseq = st_vtesc;
/* Cbreak, no echo (minicom itself sets to raw if needed) */
(void) setcbreak(1);
if ((fun = setjmp(mainloop)) != 0) {
switch(fun) {
/* We come here after minicom has told us something */
case KVT100: /* VT100 keyboard */
mode = VT100;
escseq = st_vtesc;
break;
case KANSI: /* ANSI keyboard */
mode = ANSI;
escseq = ansiesc;
break;
case KMINIX: /* MINIX keyboard */
mode = MINIX;
escseq = minixesc;
break;
case KKPST: /* Keypad in standard mode, not used */
keypadmode = NORMAL;
break;
case KKPAPP: /* Keypad in applications mode, not used */
keypadmode = APPL;
break;
case KCURST: /* Standard cursor keys */
cursormode = NORMAL;
if (mode == VT100)
escseq = st_vtesc;
break;
case KCURAPP: /* cursor keys in applications mode */
cursormode = APPL;
if (mode == VT100)
escseq = app_vtesc;
break;
case KSTOP: /* Sleep until further notice */
stopped = 1;
break;
case KSIGIO: /* Wait for keypress and tell parent */
kill(parent, ACK);
f = read(0, &ch, 1);
if (f == 1) {
write(to_minicom, &ch, 1);
(void) kill(parent, HELLO);
}
break;
case KSTART: /* Restart when stopped */
stopped = 0;
break;
case KSETBS: /* Set code that BS key sends */
bs_code = argument;
break;
case KSETESC: /* Set escape character */
esc_char = argument;
break;
default:
break;
}
if (fun != KSIGIO) {
kill(parent, ACK);
}
}
/* Wait if stopped */
if (stopped) pause();
/* Main loop: read keyboard, send to modem */
while(1) {
c = getch();
if (c > 256 && c < 256 + NUM_KEYS) {
sendstr(escseq[c - 256]);
}
if (c < 256) {
if (c == K_ERA) c = bs_code;
ch = c;
/* Test for escape characters */
if (c == esc_char || (esc_char == 128 && c > 128)) {
/* If we typed too fast, and the escape sequence
* was not that of a function key, the next key
* is already in the buffer.
*/
if (c == esc_char && pendingkeys > 0) {
ch = getch();
}
write(to_minicom, &ch, 1);
(void) kill(parent, HELLO);
} else {
write(1, &ch, 1);
}
}
}
/*NOTREACHED*/
return(0);
}