|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* vt100.c ANSI/VT102 emulator code.
|
|
Packit |
15a96c |
* This code was integrated to the Minicom communications
|
|
Packit |
15a96c |
* package, but has been reworked to allow usage as a separate
|
|
Packit |
15a96c |
* module.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* It's not a "real" vt102 emulator - it's more than that:
|
|
Packit |
15a96c |
* somewhere between vt220 and vt420 in commands.
|
|
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 |
*
|
|
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 |
* // jl 04.09.97 character map conversions in and out
|
|
Packit |
15a96c |
* jl 06.07.98 use conversion tables with the capture file
|
|
Packit |
15a96c |
* mark.einon@gmail.com 16/02/11 - Added option to timestamp terminal output
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
#ifdef HAVE_CONFIG_H
|
|
Packit |
15a96c |
#include <config.h>
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#include <time.h>
|
|
Packit |
15a96c |
#include "port.h"
|
|
Packit |
15a96c |
#include "minicom.h"
|
|
Packit |
15a96c |
#include "vt100.h"
|
|
Packit |
15a96c |
#include "config.h"
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* The global variable esc_s holds the escape sequence status:
|
|
Packit |
15a96c |
* 0 - normal
|
|
Packit |
15a96c |
* 1 - ESC
|
|
Packit |
15a96c |
* 2 - ESC [
|
|
Packit |
15a96c |
* 3 - ESC [ ?
|
|
Packit |
15a96c |
* 4 - ESC (
|
|
Packit |
15a96c |
* 5 - ESC )
|
|
Packit |
15a96c |
* 6 - ESC #
|
|
Packit |
15a96c |
* 7 - ESC P
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static int esc_s = 0;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#define ESC 27
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Structure to hold escape sequences. */
|
|
Packit |
15a96c |
struct escseq {
|
|
Packit |
15a96c |
int code;
|
|
Packit |
15a96c |
const char *vt100_st;
|
|
Packit |
15a96c |
const char *vt100_app;
|
|
Packit |
15a96c |
const char *ansi;
|
|
Packit |
15a96c |
};
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Escape sequences for different terminal types. */
|
|
Packit |
15a96c |
static struct escseq vt_keys[] = {
|
|
Packit |
15a96c |
{ K_F1, "OP", "OP", "OP" },
|
|
Packit |
15a96c |
{ K_F2, "OQ", "OQ", "OQ" },
|
|
Packit |
15a96c |
{ K_F3, "OR", "OR", "OR" },
|
|
Packit |
15a96c |
{ K_F4, "OS", "OS", "OS" },
|
|
Packit |
15a96c |
{ K_F5, "[16~", "[16~", "OT" },
|
|
Packit |
15a96c |
{ K_F6, "[17~", "[17~", "OU" },
|
|
Packit |
15a96c |
{ K_F7, "[18~", "[18~", "OV" },
|
|
Packit |
15a96c |
{ K_F8, "[19~", "[19~", "OW" },
|
|
Packit |
15a96c |
{ K_F9, "[20~", "[20~", "OX" },
|
|
Packit |
15a96c |
{ K_F10, "[21~", "[21~", "OY" },
|
|
Packit |
15a96c |
{ K_F11, "[23~", "[23~", "OY" },
|
|
Packit |
15a96c |
{ K_F12, "[24~", "[24~", "OY" },
|
|
Packit |
15a96c |
{ K_HOME, "[1~", "[1~", "[H" },
|
|
Packit |
15a96c |
{ K_PGUP, "[5~", "[5~", "[V" },
|
|
Packit |
15a96c |
{ K_UP, "[A", "OA", "[A" },
|
|
Packit |
15a96c |
{ K_LT, "[D", "OD", "[D" },
|
|
Packit |
15a96c |
{ K_RT, "[C", "OC", "[C" },
|
|
Packit |
15a96c |
{ K_DN, "[B", "OB", "[B" },
|
|
Packit |
15a96c |
{ K_END, "[4~", "[4~", "[Y" },
|
|
Packit |
15a96c |
{ K_PGDN, "[6~", "[6~", "[U" },
|
|
Packit |
15a96c |
{ K_INS, "[2~", "[2~", "[@" },
|
|
Packit |
15a96c |
{ K_DEL, "[3~", "[3~", "\177" },
|
|
Packit |
15a96c |
{ 0, NULL, NULL, NULL }
|
|
Packit |
15a96c |
};
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Two tables for user-defined character map conversions.
|
|
Packit |
15a96c |
* defmap.h should contain all characters 0-255 in ascending order
|
|
Packit |
15a96c |
* to default to no conversion. jl 04.09.1997
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
unsigned char vt_inmap[256] = {
|
|
Packit |
15a96c |
#include "defmap.h"
|
|
Packit |
15a96c |
};
|
|
Packit |
15a96c |
unsigned char vt_outmap[256] = {
|
|
Packit |
15a96c |
#include "defmap.h"
|
|
Packit |
15a96c |
};
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#if TRANSLATE
|
|
Packit |
15a96c |
/* Taken from the Linux kernel source: linux/drivers/char/console.c */
|
|
Packit |
15a96c |
static char * vt_map[] = {
|
|
Packit |
15a96c |
/* 8-bit Latin-1 mapped to the PC character set: '.' means non-printable */
|
|
Packit |
15a96c |
"................"
|
|
Packit |
15a96c |
"................"
|
|
Packit |
15a96c |
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
|
Packit |
15a96c |
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
|
Packit |
15a96c |
"`abcdefghijklmnopqrstuvwxyz{|}~."
|
|
Packit |
15a96c |
"................"
|
|
Packit |
15a96c |
"................"
|
|
Packit |
15a96c |
"\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
|
|
Packit |
15a96c |
"\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
|
|
Packit |
15a96c |
"\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
|
|
Packit |
15a96c |
"\376\245\376\376\376\376\231\376\350\376\376\376\232\376\376\341"
|
|
Packit |
15a96c |
"\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
|
|
Packit |
15a96c |
"\376\244\225\242\223\376\224\366\355\227\243\226\201\376\376\230",
|
|
Packit |
15a96c |
/* vt100 graphics */
|
|
Packit |
15a96c |
"................"
|
|
Packit |
15a96c |
"\0\0\0\0\0\0\0\0\0\0\376\0\0\0\0\0"
|
|
Packit |
15a96c |
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
|
Packit |
15a96c |
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ "
|
|
Packit |
15a96c |
"\004\261\007\007\007\007\370\361\007\007\331\277\332\300\305\304"
|
|
Packit |
15a96c |
"\304\304\137\137\303\264\301\302\263\363\362\343\330\234\007\0"
|
|
Packit |
15a96c |
"................"
|
|
Packit |
15a96c |
"................"
|
|
Packit |
15a96c |
"\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
|
|
Packit |
15a96c |
"\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
|
|
Packit |
15a96c |
"\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
|
|
Packit |
15a96c |
"\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341"
|
|
Packit |
15a96c |
"\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
|
|
Packit |
15a96c |
"\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230"
|
|
Packit |
15a96c |
};
|
|
Packit |
15a96c |
static char *vt_trans[2];
|
|
Packit |
15a96c |
static int vt_charset; /* Character set. */
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
static int vt_echo; /* Local echo on/off. */
|
|
Packit |
15a96c |
int vt_nl_delay; /* Delay after CR key */
|
|
Packit |
15a96c |
int vt_ch_delay; /* Delay between characters */
|
|
Packit |
15a96c |
static int vt_type = ANSI; /* Terminal type. */
|
|
Packit |
15a96c |
static int vt_wrap; /* Line wrap on/off */
|
|
Packit |
15a96c |
static int vt_addlf; /* Add linefeed on/off */
|
|
Packit |
15a96c |
static int vt_addcr; /* Add carriagereturn on/off */
|
|
Packit |
15a96c |
static int vt_fg; /* Standard foreground color. */
|
|
Packit |
15a96c |
static int vt_bg; /* Standard background color. */
|
|
Packit |
15a96c |
static int vt_keypad; /* Keypad mode. */
|
|
Packit |
15a96c |
static int vt_cursor; /* cursor key mode. */
|
|
Packit |
15a96c |
static int vt_asis; /* 8bit clean mode. */
|
|
Packit |
15a96c |
static int vt_line_timestamp; /* Timestamp each line. */
|
|
Packit |
15a96c |
static int vt_bs = 8; /* Code that backspace key sends. */
|
|
Packit |
15a96c |
static int vt_insert; /* Insert mode */
|
|
Packit |
15a96c |
static int vt_crlf; /* Return sends CR/LF */
|
|
Packit |
15a96c |
static int vt_om; /* Origin mode. */
|
|
Packit |
15a96c |
WIN *vt_win; /* Output window. */
|
|
Packit |
15a96c |
static int vt_docap; /* Capture on/off. */
|
|
Packit |
15a96c |
static void (*vt_keyb)(int, int);/* Gets called for NORMAL/APPL switch. */
|
|
Packit |
15a96c |
static void (*termout)(const char *, int);/* Gets called to output a string. */
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
static int escparms[8]; /* Cumulated escape sequence. */
|
|
Packit |
15a96c |
static int ptr; /* Index into escparms array. */
|
|
Packit |
15a96c |
static long vt_tabs[5]; /* Tab stops for max. 32*5 = 160 columns. */
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
static short newy1 = 0; /* Current size of scrolling region. */
|
|
Packit |
15a96c |
static short newy2 = 23;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Saved color and posistions */
|
|
Packit |
15a96c |
static short savex, savey, saveattr = XA_NORMAL, savecol = 112;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#if TRANSLATE
|
|
Packit |
15a96c |
static short savecharset;
|
|
Packit |
15a96c |
static char *savetrans[2];
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Initialize the emulator once.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
void vt_install(void (*fun1)(const char *, int), void (*fun2)(int, int),
|
|
Packit |
15a96c |
WIN *win)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
termout = fun1;
|
|
Packit |
15a96c |
vt_keyb = fun2;
|
|
Packit |
15a96c |
vt_win = win;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Partial init (after screen resize) */
|
|
Packit |
15a96c |
void vt_pinit(WIN *win, int fg, int bg)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
vt_win = win;
|
|
Packit |
15a96c |
newy1 = 0;
|
|
Packit |
15a96c |
newy2 = vt_win->ys - 1;
|
|
Packit |
15a96c |
mc_wresetregion(vt_win);
|
|
Packit |
15a96c |
if (fg > 0)
|
|
Packit |
15a96c |
vt_fg = fg;
|
|
Packit |
15a96c |
if (bg > 0)
|
|
Packit |
15a96c |
vt_bg = bg;
|
|
Packit |
15a96c |
mc_wsetfgcol(vt_win, vt_fg);
|
|
Packit |
15a96c |
mc_wsetbgcol(vt_win, vt_bg);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Set characteristics of emulator. */
|
|
Packit |
15a96c |
void vt_init(int type, int fg, int bg, int wrap, int add_lf, int add_cr)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
vt_type = type;
|
|
Packit |
15a96c |
if (vt_type == ANSI) {
|
|
Packit |
15a96c |
vt_fg = WHITE;
|
|
Packit |
15a96c |
vt_bg = BLACK;
|
|
Packit |
15a96c |
} else {
|
|
Packit |
15a96c |
vt_fg = fg;
|
|
Packit |
15a96c |
vt_bg = bg;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (wrap >= 0)
|
|
Packit |
15a96c |
vt_win->wrap = vt_wrap = wrap;
|
|
Packit |
15a96c |
vt_addlf = add_lf;
|
|
Packit |
15a96c |
vt_addcr = add_cr;
|
|
Packit |
15a96c |
vt_insert = 0;
|
|
Packit |
15a96c |
vt_crlf = 0;
|
|
Packit |
15a96c |
vt_om = 0;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
newy1 = 0;
|
|
Packit |
15a96c |
newy2 = vt_win->ys - 1;
|
|
Packit |
15a96c |
mc_wresetregion(vt_win);
|
|
Packit |
15a96c |
vt_keypad = NORMAL;
|
|
Packit |
15a96c |
vt_cursor = NORMAL;
|
|
Packit |
15a96c |
vt_echo = local_echo;
|
|
Packit |
15a96c |
vt_tabs[0] = 0x01010100;
|
|
Packit |
15a96c |
vt_tabs[1] =
|
|
Packit |
15a96c |
vt_tabs[2] =
|
|
Packit |
15a96c |
vt_tabs[3] =
|
|
Packit |
15a96c |
vt_tabs[4] = 0x01010101;
|
|
Packit |
15a96c |
#if TRANSLATE
|
|
Packit |
15a96c |
vt_charset = 0;
|
|
Packit |
15a96c |
vt_trans[0] = savetrans[0] = vt_map[0];
|
|
Packit |
15a96c |
vt_trans[1] = savetrans[1] = vt_map[1];
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
ptr = 0;
|
|
Packit |
15a96c |
memset(escparms, 0, sizeof(escparms));
|
|
Packit |
15a96c |
esc_s = 0;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (vt_keyb)
|
|
Packit |
15a96c |
(*vt_keyb)(vt_keypad, vt_cursor);
|
|
Packit |
15a96c |
mc_wsetfgcol(vt_win, vt_fg);
|
|
Packit |
15a96c |
mc_wsetbgcol(vt_win, vt_bg);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Change some things on the fly. */
|
|
Packit |
15a96c |
void vt_set(int addlf, int wrap, int docap, int bscode,
|
|
Packit |
15a96c |
int echo, int cursor, int asis, int timestamp,
|
|
Packit |
15a96c |
int addcr)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
if (addlf >= 0)
|
|
Packit |
15a96c |
vt_addlf = addlf;
|
|
Packit |
15a96c |
if (wrap >= 0)
|
|
Packit |
15a96c |
vt_win->wrap = vt_wrap = wrap;
|
|
Packit |
15a96c |
if (docap >= 0)
|
|
Packit |
15a96c |
vt_docap = docap;
|
|
Packit |
15a96c |
if (bscode >= 0)
|
|
Packit |
15a96c |
vt_bs = bscode;
|
|
Packit |
15a96c |
if (echo >= 0)
|
|
Packit |
15a96c |
vt_echo = echo;
|
|
Packit |
15a96c |
if (cursor >= 0)
|
|
Packit |
15a96c |
vt_cursor = cursor;
|
|
Packit |
15a96c |
if (asis >=0)
|
|
Packit |
15a96c |
vt_asis = asis;
|
|
Packit |
15a96c |
if (timestamp >= 0)
|
|
Packit |
15a96c |
vt_line_timestamp = timestamp;
|
|
Packit |
15a96c |
if (addcr >= 0)
|
|
Packit |
15a96c |
vt_addcr = addcr;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Output a string to the modem. */
|
|
Packit |
15a96c |
static void v_termout(const char *s, int len)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
const char *p;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (vt_echo) {
|
|
Packit |
15a96c |
for (p = s; *p; p++) {
|
|
Packit |
15a96c |
vt_out(*p);
|
|
Packit |
15a96c |
if (!vt_addlf && *p == '\r')
|
|
Packit |
15a96c |
vt_out('\n');
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
mc_wflush();
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
(*termout)(s, len);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Escape code handling.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* ESC was seen the last time. Process the next character.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static void state1(int c)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
short x, y, f;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
switch(c) {
|
|
Packit |
15a96c |
case '[': /* ESC [ */
|
|
Packit |
15a96c |
esc_s = 2;
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
case '(': /* ESC ( */
|
|
Packit |
15a96c |
esc_s = 4;
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
case ')': /* ESC ) */
|
|
Packit |
15a96c |
esc_s = 5;
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
case '#': /* ESC # */
|
|
Packit |
15a96c |
esc_s = 6;
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
case 'P': /* ESC P (DCS, Device Control String) */
|
|
Packit |
15a96c |
esc_s = 7;
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
case 'D': /* Cursor down */
|
|
Packit |
15a96c |
case 'M': /* Cursor up */
|
|
Packit |
15a96c |
x = vt_win->curx;
|
|
Packit |
15a96c |
if (c == 'D') { /* Down. */
|
|
Packit |
15a96c |
y = vt_win->cury + 1;
|
|
Packit |
15a96c |
if (y == newy2 + 1)
|
|
Packit |
15a96c |
mc_wscroll(vt_win, S_UP);
|
|
Packit |
15a96c |
else if (vt_win->cury < vt_win->ys)
|
|
Packit |
15a96c |
mc_wlocate(vt_win, x, y);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (c == 'M') { /* Up. */
|
|
Packit |
15a96c |
y = vt_win->cury - 1;
|
|
Packit |
15a96c |
if (y == newy1 - 1)
|
|
Packit |
15a96c |
mc_wscroll(vt_win, S_DOWN);
|
|
Packit |
15a96c |
else if (y >= 0)
|
|
Packit |
15a96c |
mc_wlocate(vt_win, x, y);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'E': /* CR + NL */
|
|
Packit |
15a96c |
mc_wputs(vt_win, "\r\n");
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '7': /* Save attributes and cursor position */
|
|
Packit |
15a96c |
case 's':
|
|
Packit |
15a96c |
savex = vt_win->curx;
|
|
Packit |
15a96c |
savey = vt_win->cury;
|
|
Packit |
15a96c |
saveattr = vt_win->attr;
|
|
Packit |
15a96c |
savecol = vt_win->color;
|
|
Packit |
15a96c |
#if TRANSLATE
|
|
Packit |
15a96c |
savecharset = vt_charset;
|
|
Packit |
15a96c |
savetrans[0] = vt_trans[0];
|
|
Packit |
15a96c |
savetrans[1] = vt_trans[1];
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '8': /* Restore them */
|
|
Packit |
15a96c |
case 'u':
|
|
Packit |
15a96c |
#if TRANSLATE
|
|
Packit |
15a96c |
vt_charset = savecharset;
|
|
Packit |
15a96c |
vt_trans[0] = savetrans[0];
|
|
Packit |
15a96c |
vt_trans[1] = savetrans[1];
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
vt_win->color = savecol; /* HACK should use mc_wsetfgcol etc */
|
|
Packit |
15a96c |
mc_wsetattr(vt_win, saveattr);
|
|
Packit |
15a96c |
mc_wlocate(vt_win, savex, savey);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '=': /* Keypad into applications mode */
|
|
Packit |
15a96c |
vt_keypad = APPL;
|
|
Packit |
15a96c |
if (vt_keyb)
|
|
Packit |
15a96c |
(*vt_keyb)(vt_keypad, vt_cursor);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '>': /* Keypad into numeric mode */
|
|
Packit |
15a96c |
vt_keypad = NORMAL;
|
|
Packit |
15a96c |
if (vt_keyb)
|
|
Packit |
15a96c |
(*vt_keyb)(vt_keypad, vt_cursor);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'Z': /* Report terminal type */
|
|
Packit |
15a96c |
if (vt_type == VT100)
|
|
Packit |
15a96c |
v_termout("\033[?1;0c", 0);
|
|
Packit |
15a96c |
else
|
|
Packit |
15a96c |
v_termout("\033[?c", 0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'c': /* Reset to initial state */
|
|
Packit |
15a96c |
f = XA_NORMAL;
|
|
Packit |
15a96c |
mc_wsetattr(vt_win, f);
|
|
Packit |
15a96c |
vt_win->wrap = (vt_type != VT100);
|
|
Packit |
15a96c |
if (vt_wrap != -1)
|
|
Packit |
15a96c |
vt_win->wrap = vt_wrap;
|
|
Packit |
15a96c |
vt_crlf = vt_insert = 0;
|
|
Packit |
15a96c |
vt_init(vt_type, vt_fg, vt_bg, vt_win->wrap, 0, 0);
|
|
Packit |
15a96c |
mc_wlocate(vt_win, 0, 0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'H': /* Set tab in current position */
|
|
Packit |
15a96c |
x = vt_win->curx;
|
|
Packit |
15a96c |
if (x > 159)
|
|
Packit |
15a96c |
x = 159;
|
|
Packit |
15a96c |
vt_tabs[x / 32] |= 1 << (x % 32);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'N': /* G2 character set for next character only*/
|
|
Packit |
15a96c |
case 'O': /* G3 " " */
|
|
Packit |
15a96c |
case '<': /* Exit vt52 mode */
|
|
Packit |
15a96c |
default:
|
|
Packit |
15a96c |
/* ALL IGNORED */
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
esc_s = 0;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* ESC [ ... [hl] seen. */
|
|
Packit |
15a96c |
static void ansi_mode(int on_off)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
int i;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
for (i = 0; i <= ptr; i++) {
|
|
Packit |
15a96c |
switch (escparms[i]) {
|
|
Packit |
15a96c |
case 4: /* Insert mode */
|
|
Packit |
15a96c |
vt_insert = on_off;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 20: /* Return key mode */
|
|
Packit |
15a96c |
vt_crlf = on_off;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* ESC [ ... was seen the last time. Process next character.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static void state2(int c)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
short x, y, attr, f;
|
|
Packit |
15a96c |
char temp[32];
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* See if a number follows */
|
|
Packit |
15a96c |
if (c >= '0' && c <= '9') {
|
|
Packit |
15a96c |
escparms[ptr] = 10*escparms[ptr] + c - '0';
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
/* Separation between numbers ? */
|
|
Packit |
15a96c |
if (c == ';') {
|
|
Packit |
15a96c |
if (ptr < 7)
|
|
Packit |
15a96c |
ptr++;
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
/* ESC [ ? sequence */
|
|
Packit |
15a96c |
if (escparms[0] == 0 && ptr == 0 && c == '?')
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
esc_s = 3;
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Process functions with zero, one, two or more arguments */
|
|
Packit |
15a96c |
switch (c) {
|
|
Packit |
15a96c |
case 'A':
|
|
Packit |
15a96c |
case 'B':
|
|
Packit |
15a96c |
case 'C':
|
|
Packit |
15a96c |
case 'D': /* Cursor motion */
|
|
Packit |
15a96c |
if ((f = escparms[0]) == 0)
|
|
Packit |
15a96c |
f = 1;
|
|
Packit |
15a96c |
x = vt_win->curx;
|
|
Packit |
15a96c |
y = vt_win->cury;
|
|
Packit |
15a96c |
x += f * ((c == 'C') - (c == 'D'));
|
|
Packit |
15a96c |
if (x < 0)
|
|
Packit |
15a96c |
x = 0;
|
|
Packit |
15a96c |
if (x >= vt_win->xs)
|
|
Packit |
15a96c |
x = vt_win->xs - 1;
|
|
Packit |
15a96c |
if (c == 'B') { /* Down. */
|
|
Packit |
15a96c |
y += f;
|
|
Packit |
15a96c |
if (y >= vt_win->ys)
|
|
Packit |
15a96c |
y = vt_win->ys - 1;
|
|
Packit |
15a96c |
if (y >= newy2 + 1)
|
|
Packit |
15a96c |
y = newy2;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (c == 'A') { /* Up. */
|
|
Packit |
15a96c |
y -= f;
|
|
Packit |
15a96c |
if (y < 0)
|
|
Packit |
15a96c |
y = 0;
|
|
Packit |
15a96c |
if (y <= newy1 - 1)
|
|
Packit |
15a96c |
y = newy1;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
mc_wlocate(vt_win, x, y);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'X': /* Character erasing (ECH) */
|
|
Packit |
15a96c |
if ((f = escparms[0]) == 0)
|
|
Packit |
15a96c |
f = 1;
|
|
Packit |
15a96c |
mc_wclrch(vt_win, f);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'K': /* Line erasing */
|
|
Packit |
15a96c |
switch (escparms[0]) {
|
|
Packit |
15a96c |
case 0:
|
|
Packit |
15a96c |
mc_wclreol(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 1:
|
|
Packit |
15a96c |
mc_wclrbol(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 2:
|
|
Packit |
15a96c |
mc_wclrel(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'J': /* Screen erasing */
|
|
Packit |
15a96c |
x = vt_win->color;
|
|
Packit |
15a96c |
y = vt_win->attr;
|
|
Packit |
15a96c |
if (vt_type == ANSI) {
|
|
Packit |
15a96c |
mc_wsetattr(vt_win, XA_NORMAL);
|
|
Packit |
15a96c |
mc_wsetfgcol(vt_win, WHITE);
|
|
Packit |
15a96c |
mc_wsetbgcol(vt_win, BLACK);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
switch (escparms[0]) {
|
|
Packit |
15a96c |
case 0:
|
|
Packit |
15a96c |
mc_wclreos(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 1:
|
|
Packit |
15a96c |
mc_wclrbos(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 2:
|
|
Packit |
15a96c |
mc_winclr(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (vt_type == ANSI) {
|
|
Packit |
15a96c |
vt_win->color = x;
|
|
Packit |
15a96c |
vt_win->attr = y;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'n': /* Requests / Reports */
|
|
Packit |
15a96c |
switch(escparms[0]) {
|
|
Packit |
15a96c |
case 5: /* Status */
|
|
Packit |
15a96c |
v_termout("\033[0n", 0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 6: /* Cursor Position */
|
|
Packit |
15a96c |
sprintf(temp, "\033[%d;%dR", vt_win->cury + 1, vt_win->curx + 1);
|
|
Packit |
15a96c |
v_termout(temp, 0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'c': /* Identify Terminal Type */
|
|
Packit |
15a96c |
if (vt_type == VT100) {
|
|
Packit |
15a96c |
v_termout("\033[?1;2c", 0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
v_termout("\033[?c", 0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'x': /* Request terminal parameters. */
|
|
Packit |
15a96c |
/* Always answers 19200-8N1 no options. */
|
|
Packit |
15a96c |
sprintf(temp, "\033[%c;1;1;120;120;1;0x", escparms[0] == 1 ? '3' : '2');
|
|
Packit |
15a96c |
v_termout(temp, 0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 's': /* Save attributes and cursor position */
|
|
Packit |
15a96c |
savex = vt_win->curx;
|
|
Packit |
15a96c |
savey = vt_win->cury;
|
|
Packit |
15a96c |
saveattr = vt_win->attr;
|
|
Packit |
15a96c |
savecol = vt_win->color;
|
|
Packit |
15a96c |
#if TRANSLATE
|
|
Packit |
15a96c |
savecharset = vt_charset;
|
|
Packit |
15a96c |
savetrans[0] = vt_trans[0];
|
|
Packit |
15a96c |
savetrans[1] = vt_trans[1];
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'u': /* Restore them */
|
|
Packit |
15a96c |
#if TRANSLATE
|
|
Packit |
15a96c |
vt_charset = savecharset;
|
|
Packit |
15a96c |
vt_trans[0] = savetrans[0];
|
|
Packit |
15a96c |
vt_trans[1] = savetrans[1];
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
vt_win->color = savecol; /* HACK should use mc_wsetfgcol etc */
|
|
Packit |
15a96c |
mc_wsetattr(vt_win, saveattr);
|
|
Packit |
15a96c |
mc_wlocate(vt_win, savex, savey);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'h':
|
|
Packit |
15a96c |
ansi_mode(1);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'l':
|
|
Packit |
15a96c |
ansi_mode(0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'H':
|
|
Packit |
15a96c |
case 'f': /* Set cursor position */
|
|
Packit |
15a96c |
if ((y = escparms[0]) == 0)
|
|
Packit |
15a96c |
y = 1;
|
|
Packit |
15a96c |
if ((x = escparms[1]) == 0)
|
|
Packit |
15a96c |
x = 1;
|
|
Packit |
15a96c |
if (vt_om)
|
|
Packit |
15a96c |
y += newy1;
|
|
Packit |
15a96c |
mc_wlocate(vt_win, x - 1, y - 1);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'g': /* Clear tab stop(s) */
|
|
Packit |
15a96c |
if (escparms[0] == 0) {
|
|
Packit |
15a96c |
x = vt_win->curx;
|
|
Packit |
15a96c |
if (x > 159)
|
|
Packit |
15a96c |
x = 159;
|
|
Packit |
15a96c |
vt_tabs[x / 32] &= ~(1 << x % 32);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (escparms[0] == 3)
|
|
Packit |
15a96c |
for(x = 0; x < 5; x++)
|
|
Packit |
15a96c |
vt_tabs[x] = 0;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'm': /* Set attributes */
|
|
Packit |
15a96c |
attr = mc_wgetattr((vt_win));
|
|
Packit |
15a96c |
for (f = 0; f <= ptr; f++) {
|
|
Packit |
15a96c |
if (escparms[f] >= 30 && escparms[f] <= 37)
|
|
Packit |
15a96c |
mc_wsetfgcol(vt_win, escparms[f] - 30);
|
|
Packit |
15a96c |
if (escparms[f] >= 40 && escparms[f] <= 47)
|
|
Packit |
15a96c |
mc_wsetbgcol(vt_win, escparms[f] - 40);
|
|
Packit |
15a96c |
switch (escparms[f]) {
|
|
Packit |
15a96c |
case 0:
|
|
Packit |
15a96c |
attr = XA_NORMAL;
|
|
Packit |
15a96c |
mc_wsetfgcol(vt_win, vt_fg);
|
|
Packit |
15a96c |
mc_wsetbgcol(vt_win, vt_bg);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 1:
|
|
Packit |
15a96c |
attr |= XA_BOLD;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 4:
|
|
Packit |
15a96c |
attr |= XA_UNDERLINE;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 5:
|
|
Packit |
15a96c |
attr |= XA_BLINK;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 7:
|
|
Packit |
15a96c |
attr |= XA_REVERSE;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 22: /* Bold off */
|
|
Packit |
15a96c |
attr &= ~XA_BOLD;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 24: /* Not underlined */
|
|
Packit |
15a96c |
attr &=~XA_UNDERLINE;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 25: /* Not blinking */
|
|
Packit |
15a96c |
attr &= ~XA_BLINK;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 27: /* Not reverse */
|
|
Packit |
15a96c |
attr &= ~XA_REVERSE;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 39: /* Default fg color */
|
|
Packit |
15a96c |
mc_wsetfgcol(vt_win, vt_fg);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 49: /* Default bg color */
|
|
Packit |
15a96c |
mc_wsetbgcol(vt_win, vt_bg);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
mc_wsetattr(vt_win, attr);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'L': /* Insert lines */
|
|
Packit |
15a96c |
if ((x = escparms[0]) == 0)
|
|
Packit |
15a96c |
x = 1;
|
|
Packit |
15a96c |
for (f = 0; f < x; f++)
|
|
Packit |
15a96c |
mc_winsline(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'M': /* Delete lines */
|
|
Packit |
15a96c |
if ((x = escparms[0]) == 0)
|
|
Packit |
15a96c |
x = 1;
|
|
Packit |
15a96c |
for (f = 0; f < x; f++)
|
|
Packit |
15a96c |
mc_wdelline(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'P': /* Delete Characters */
|
|
Packit |
15a96c |
if ((x = escparms[0]) == 0)
|
|
Packit |
15a96c |
x = 1;
|
|
Packit |
15a96c |
for (f = 0; f < x; f++)
|
|
Packit |
15a96c |
mc_wdelchar(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '@': /* Insert Characters */
|
|
Packit |
15a96c |
if ((x = escparms[0]) == 0)
|
|
Packit |
15a96c |
x = 1;
|
|
Packit |
15a96c |
for (f = 0; f < x; f++)
|
|
Packit |
15a96c |
mc_winschar(vt_win);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'r': /* Set scroll region */
|
|
Packit |
15a96c |
if ((newy1 = escparms[0]) == 0)
|
|
Packit |
15a96c |
newy1 = 1;
|
|
Packit |
15a96c |
if ((newy2 = escparms[1]) == 0)
|
|
Packit |
15a96c |
newy2 = vt_win->ys;
|
|
Packit |
15a96c |
newy1-- ; newy2--;
|
|
Packit |
15a96c |
if (newy1 < 0)
|
|
Packit |
15a96c |
newy1 = 0;
|
|
Packit |
15a96c |
if (newy2 < 0)
|
|
Packit |
15a96c |
newy2 = 0;
|
|
Packit |
15a96c |
if (newy1 >= vt_win->ys)
|
|
Packit |
15a96c |
newy1 = vt_win->ys - 1;
|
|
Packit |
15a96c |
if (newy2 >= vt_win->ys)
|
|
Packit |
15a96c |
newy2 = vt_win->ys - 1;
|
|
Packit |
15a96c |
if (newy1 >= newy2) {
|
|
Packit |
15a96c |
newy1 = 0;
|
|
Packit |
15a96c |
newy2 = vt_win->ys - 1;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
mc_wsetregion(vt_win, newy1, newy2);
|
|
Packit |
15a96c |
mc_wlocate(vt_win, 0, newy1);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'i': /* Printing */
|
|
Packit |
15a96c |
case 'y': /* Self test modes */
|
|
Packit |
15a96c |
default:
|
|
Packit |
15a96c |
/* IGNORED */
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
/* Ok, our escape sequence is all done */
|
|
Packit |
15a96c |
esc_s = 0;
|
|
Packit |
15a96c |
ptr = 0;
|
|
Packit |
15a96c |
memset(escparms, 0, sizeof(escparms));
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* ESC [? ... [hl] seen. */
|
|
Packit |
15a96c |
static void dec_mode(int on_off)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
int i;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
for (i = 0; i <= ptr; i++) {
|
|
Packit |
15a96c |
switch (escparms[i]) {
|
|
Packit |
15a96c |
case 1: /* Cursor keys in cursor/appl mode */
|
|
Packit |
15a96c |
vt_cursor = on_off ? APPL : NORMAL;
|
|
Packit |
15a96c |
if (vt_keyb)
|
|
Packit |
15a96c |
(*vt_keyb)(vt_keypad, vt_cursor);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 6: /* Origin mode. */
|
|
Packit |
15a96c |
vt_om = on_off;
|
|
Packit |
15a96c |
mc_wlocate(vt_win, 0, newy1);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 7: /* Auto wrap */
|
|
Packit |
15a96c |
vt_win->wrap = on_off;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 25: /* Cursor on/off */
|
|
Packit |
15a96c |
mc_wcursor(vt_win, on_off ? CNORMAL : CNONE);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 67: /* Backspace key sends. (FIXME: vt420) */
|
|
Packit |
15a96c |
/* setbackspace(on_off ? 8 : 127); */
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
default: /* Mostly set up functions */
|
|
Packit |
15a96c |
/* IGNORED */
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* ESC [ ? ... seen.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static void state3(int c)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
/* See if a number follows */
|
|
Packit |
15a96c |
if (c >= '0' && c <= '9') {
|
|
Packit |
15a96c |
escparms[ptr] = 10*escparms[ptr] + c - '0';
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
switch (c) {
|
|
Packit |
15a96c |
case 'h':
|
|
Packit |
15a96c |
dec_mode(1);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'l':
|
|
Packit |
15a96c |
dec_mode(0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'i': /* Printing */
|
|
Packit |
15a96c |
case 'n': /* Request printer status */
|
|
Packit |
15a96c |
default:
|
|
Packit |
15a96c |
/* IGNORED */
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
esc_s = 0;
|
|
Packit |
15a96c |
ptr = 0;
|
|
Packit |
15a96c |
memset(escparms, 0, sizeof(escparms));
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* ESC ( Seen.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static void state4(int c)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
/* Switch Character Sets. */
|
|
Packit |
15a96c |
#if !TRANSLATE
|
|
Packit |
15a96c |
/* IGNORED */
|
|
Packit |
15a96c |
(void)c;
|
|
Packit |
15a96c |
#else
|
|
Packit |
15a96c |
switch (c) {
|
|
Packit |
15a96c |
case 'A':
|
|
Packit |
15a96c |
case 'B':
|
|
Packit |
15a96c |
vt_trans[0] = vt_map[0];
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '0':
|
|
Packit |
15a96c |
case 'O':
|
|
Packit |
15a96c |
vt_trans[0] = vt_map[1];
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
esc_s = 0;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* ESC ) Seen.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static void state5(int c)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
/* Switch Character Sets. */
|
|
Packit |
15a96c |
#if !TRANSLATE
|
|
Packit |
15a96c |
/* IGNORED */
|
|
Packit |
15a96c |
(void)c;
|
|
Packit |
15a96c |
#else
|
|
Packit |
15a96c |
switch (c) {
|
|
Packit |
15a96c |
case 'A':
|
|
Packit |
15a96c |
case 'B':
|
|
Packit |
15a96c |
vt_trans[1] = vt_map[0];
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 'O':
|
|
Packit |
15a96c |
case '0':
|
|
Packit |
15a96c |
vt_trans[1] = vt_map[1];
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
esc_s = 0;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* ESC # Seen.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static void state6(int c)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
int x, y;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Double height, double width and selftests. */
|
|
Packit |
15a96c |
switch (c) {
|
|
Packit |
15a96c |
case '8':
|
|
Packit |
15a96c |
/* Selftest: fill screen with E's */
|
|
Packit |
15a96c |
vt_win->doscroll = 0;
|
|
Packit |
15a96c |
vt_win->direct = 0;
|
|
Packit |
15a96c |
mc_wlocate(vt_win, 0, 0);
|
|
Packit |
15a96c |
for (y = 0; y < vt_win->ys; y++) {
|
|
Packit |
15a96c |
mc_wlocate(vt_win, 0, y);
|
|
Packit |
15a96c |
for (x = 0; x < vt_win->xs; x++)
|
|
Packit |
15a96c |
mc_wputc(vt_win, 'E');
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
mc_wlocate(vt_win, 0, 0);
|
|
Packit |
15a96c |
vt_win->doscroll = 1;
|
|
Packit |
15a96c |
mc_wredraw(vt_win, 1);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
default:
|
|
Packit |
15a96c |
/* IGNORED */
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
esc_s = 0;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* ESC P Seen.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static void state7(int c)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Device dependant control strings. The Minix virtual console package
|
|
Packit |
15a96c |
* uses these sequences. We can only turn cursor on or off, because
|
|
Packit |
15a96c |
* that's the only one supported in termcap. The rest is ignored.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static char buf[17];
|
|
Packit |
15a96c |
static int pos = 0;
|
|
Packit |
15a96c |
static int state = 0;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (c == ESC) {
|
|
Packit |
15a96c |
state = 1;
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (state == 1) {
|
|
Packit |
15a96c |
buf[pos] = 0;
|
|
Packit |
15a96c |
pos = 0;
|
|
Packit |
15a96c |
state = 0;
|
|
Packit |
15a96c |
esc_s = 0;
|
|
Packit |
15a96c |
if (c != '\\')
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
/* Process string here! */
|
|
Packit |
15a96c |
if (!strcmp(buf, "cursor.on"))
|
|
Packit |
15a96c |
mc_wcursor(vt_win, CNORMAL);
|
|
Packit |
15a96c |
if (!strcmp(buf, "cursor.off"))
|
|
Packit |
15a96c |
mc_wcursor(vt_win, CNONE);
|
|
Packit |
15a96c |
if (!strcmp(buf, "linewrap.on")) {
|
|
Packit |
15a96c |
vt_wrap = -1;
|
|
Packit |
15a96c |
vt_win->wrap = 1;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (!strcmp(buf, "linewrap.off")) {
|
|
Packit |
15a96c |
vt_wrap = -1;
|
|
Packit |
15a96c |
vt_win->wrap = 0;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (pos > 15)
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
buf[pos++] = c;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
static void output_s(const char *s)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
mc_wputs(vt_win, s);
|
|
Packit |
15a96c |
if (vt_docap == 1)
|
|
Packit |
15a96c |
fputs(s, capfp);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
static void output_c(const char c)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
mc_wputc(vt_win, c);
|
|
Packit |
15a96c |
if (vt_docap == 1)
|
|
Packit |
15a96c |
fputc(c, capfp);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
void vt_out(int ch)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
static unsigned char last_ch;
|
|
Packit |
15a96c |
int f;
|
|
Packit |
15a96c |
unsigned char c;
|
|
Packit |
15a96c |
int go_on = 0;
|
|
Packit |
15a96c |
wchar_t wc;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (!ch)
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (last_ch == '\n'
|
|
Packit |
15a96c |
&& vt_line_timestamp != TIMESTAMP_LINE_OFF)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
struct timeval tmstmp_now;
|
|
Packit |
15a96c |
static time_t tmstmp_last;
|
|
Packit |
15a96c |
char s[36];
|
|
Packit |
15a96c |
struct tm tmstmp_tm;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
gettimeofday(&tmstmp_now, NULL);
|
|
Packit |
15a96c |
if (( vt_line_timestamp == TIMESTAMP_LINE_PER_SECOND
|
|
Packit |
15a96c |
&& tmstmp_now.tv_sec != tmstmp_last)
|
|
Packit |
15a96c |
|| vt_line_timestamp == TIMESTAMP_LINE_SIMPLE
|
|
Packit |
15a96c |
|| vt_line_timestamp == TIMESTAMP_LINE_EXTENDED)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
if ( localtime_r(&tmstmp_now.tv_sec, &tmstmp_tm)
|
|
Packit |
15a96c |
&& strftime(s, sizeof(s), "[%F %T", &tmstmp_tm))
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
output_s(s);
|
|
Packit |
15a96c |
switch (vt_line_timestamp)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
case TIMESTAMP_LINE_SIMPLE:
|
|
Packit |
15a96c |
output_s("] ");
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case TIMESTAMP_LINE_EXTENDED:
|
|
Packit |
15a96c |
snprintf(s, sizeof(s), ".%03ld] ", tmstmp_now.tv_usec / 1000);
|
|
Packit |
15a96c |
output_s(s);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case TIMESTAMP_LINE_PER_SECOND:
|
|
Packit |
15a96c |
output_s("\r\n");
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
};
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
tmstmp_last = tmstmp_now.tv_sec;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
c = (unsigned char)ch;
|
|
Packit |
15a96c |
last_ch = c;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (vt_docap == 2) /* Literal. */
|
|
Packit |
15a96c |
fputc(c, capfp);
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Process <31 chars first, even in an escape sequence. */
|
|
Packit |
15a96c |
switch (c) {
|
|
Packit |
15a96c |
case 5: /* AnswerBack for vt100's */
|
|
Packit |
15a96c |
if (vt_type != VT100) {
|
|
Packit |
15a96c |
go_on = 1;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
v_termout(P_ANSWERBACK, 0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '\r': /* Carriage return */
|
|
Packit |
15a96c |
mc_wputc(vt_win, c);
|
|
Packit |
15a96c |
if (vt_addlf)
|
|
Packit |
15a96c |
output_c('\n');
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '\t': /* Non - destructive TAB */
|
|
Packit |
15a96c |
/* Find next tab stop. */
|
|
Packit |
15a96c |
for (f = vt_win->curx + 1; f < 160; f++)
|
|
Packit |
15a96c |
if (vt_tabs[f / 32] & (1 << f % 32))
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
if (f >= vt_win->xs)
|
|
Packit |
15a96c |
f = vt_win->xs - 1;
|
|
Packit |
15a96c |
mc_wlocate(vt_win, f, vt_win->cury);
|
|
Packit |
15a96c |
if (vt_docap == 1)
|
|
Packit |
15a96c |
fputc(c, capfp);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 013: /* Old Minix: CTRL-K = up */
|
|
Packit |
15a96c |
mc_wlocate(vt_win, vt_win->curx, vt_win->cury - 1);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '\f': /* Form feed: clear screen. */
|
|
Packit |
15a96c |
mc_winclr(vt_win);
|
|
Packit |
15a96c |
mc_wlocate(vt_win, 0, 0);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
#if !TRANSLATE
|
|
Packit |
15a96c |
case 14:
|
|
Packit |
15a96c |
case 15: /* Change character set. Not supported. */
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
#else
|
|
Packit |
15a96c |
case 14:
|
|
Packit |
15a96c |
vt_charset = 1;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 15:
|
|
Packit |
15a96c |
vt_charset = 0;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
case 24:
|
|
Packit |
15a96c |
case 26: /* Cancel escape sequence. */
|
|
Packit |
15a96c |
esc_s = 0;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case ESC: /* Begin escape sequence */
|
|
Packit |
15a96c |
esc_s = 1;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 128+ESC: /* Begin ESC [ sequence. */
|
|
Packit |
15a96c |
esc_s = 2;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '\n':
|
|
Packit |
15a96c |
if(vt_addcr)
|
|
Packit |
15a96c |
mc_wputc(vt_win, '\r');
|
|
Packit |
15a96c |
output_c(c);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '\b':
|
|
Packit |
15a96c |
case 7: /* Bell */
|
|
Packit |
15a96c |
output_c(c);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
default:
|
|
Packit |
15a96c |
go_on = 1;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (!go_on)
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Now see which state we are in. */
|
|
Packit |
15a96c |
switch (esc_s) {
|
|
Packit |
15a96c |
case 0: /* Normal character */
|
|
Packit |
15a96c |
if (vt_docap == 1)
|
|
Packit |
15a96c |
fputc(P_CONVCAP[0] == 'Y' ? vt_inmap[c] : c, capfp);
|
|
Packit |
15a96c |
if (!using_iconv()) {
|
|
Packit |
15a96c |
c = vt_inmap[c]; /* conversion 04.09.97 / jl */
|
|
Packit |
15a96c |
#if TRANSLATE
|
|
Packit |
15a96c |
if (vt_type == VT100 && vt_trans[vt_charset] && vt_asis == 0)
|
|
Packit |
15a96c |
c = vt_trans[vt_charset][c];
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
/* FIXME: This is wrong, but making it right would require
|
|
Packit |
15a96c |
* removing all the 8-bit mapping features. Assuming the locale
|
|
Packit |
15a96c |
* is 8-bit, the character should not be changed by mapping to
|
|
Packit |
15a96c |
* wchar and back; if the locale is multibyte, there is no hope
|
|
Packit |
15a96c |
* of getting it right anyway. */
|
|
Packit |
15a96c |
if (!using_iconv()) {
|
|
Packit |
15a96c |
one_mbtowc (&wc, (char *)&c, 1); /* returns 1 */
|
|
Packit |
15a96c |
if (vt_insert)
|
|
Packit |
15a96c |
mc_winschar2(vt_win, wc, 1);
|
|
Packit |
15a96c |
else
|
|
Packit |
15a96c |
mc_wputc(vt_win, wc);
|
|
Packit |
15a96c |
} else {
|
|
Packit |
15a96c |
mc_wputc(vt_win, c);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 1: /* ESC seen */
|
|
Packit |
15a96c |
state1(c);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 2: /* ESC [ ... seen */
|
|
Packit |
15a96c |
state2(c);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 3:
|
|
Packit |
15a96c |
state3(c);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 4:
|
|
Packit |
15a96c |
state4(c);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 5:
|
|
Packit |
15a96c |
state5(c);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 6:
|
|
Packit |
15a96c |
state6(c);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case 7:
|
|
Packit |
15a96c |
state7(c);
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Flush output to capture file so that all output is visible there
|
|
Packit |
15a96c |
* immediately. Causes a write syscall for every call though. */
|
|
Packit |
15a96c |
if (capfp)
|
|
Packit |
15a96c |
fflush(capfp);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Translate keycode to escape sequence. */
|
|
Packit |
15a96c |
void vt_send(int c)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
char s[3];
|
|
Packit |
15a96c |
int f;
|
|
Packit |
15a96c |
int len = 1;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Special key? */
|
|
Packit |
15a96c |
if (c < 256) {
|
|
Packit |
15a96c |
/* Translate backspace key? */
|
|
Packit |
15a96c |
if (c == K_ERA)
|
|
Packit |
15a96c |
c = vt_bs;
|
|
Packit |
15a96c |
s[0] = vt_outmap[c]; /* conversion 04.09.97 / jl */
|
|
Packit |
15a96c |
s[1] = 0;
|
|
Packit |
15a96c |
/* CR/LF mode? */
|
|
Packit |
15a96c |
if (c == '\r' && vt_crlf) {
|
|
Packit |
15a96c |
s[1] = '\n';
|
|
Packit |
15a96c |
s[2] = 0;
|
|
Packit |
15a96c |
len = 2;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
v_termout(s, len);
|
|
Packit |
15a96c |
if (vt_nl_delay > 0 && c == '\r')
|
|
Packit |
15a96c |
usleep(1000 * vt_nl_delay);
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Look up code in translation table. */
|
|
Packit |
15a96c |
for (f = 0; vt_keys[f].code; f++)
|
|
Packit |
15a96c |
if (vt_keys[f].code == c)
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
if (vt_keys[f].code == 0)
|
|
Packit |
15a96c |
return;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Now send appropriate escape code. */
|
|
Packit |
15a96c |
v_termout("\033", 0);
|
|
Packit |
15a96c |
if (vt_type == VT100) {
|
|
Packit |
15a96c |
if (vt_cursor == NORMAL)
|
|
Packit |
15a96c |
v_termout(vt_keys[f].vt100_st, 0);
|
|
Packit |
15a96c |
else
|
|
Packit |
15a96c |
v_termout(vt_keys[f].vt100_app, 0);
|
|
Packit |
15a96c |
} else
|
|
Packit |
15a96c |
v_termout(vt_keys[f].ansi, 0);
|
|
Packit |
15a96c |
}
|