Blame src/vt100.c

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
}