bitchx/source/term.c

2593 lines
81 KiB
C

/*
* term.c -- termios and termcap handlers
*
* Written By Matthew Green, based on window.c by Michael Sandrof
* Copyright(c) 1993 Matthew Green
* Significant modifications by Jeremy Nelson
* Copyright 1997 EPIC Software Labs,
* Significant additions by J. Kean Johnston
* Copyright 1998 J. Kean Johnston, used with permission
* Modifications Copyright Colten Edwards 1997-1998.
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
*/
#include "irc.h"
static char cvsrevision[] = "$Id$";
CVS_REVISION(term_c)
#include "struct.h"
#include "screen.h"
#include "ircaux.h"
#ifdef __EMX__
static BYTE pair[2];
char default_pair[2];
VIOMODEINFO vmode;
int vio_screen = 0;
#endif
#ifdef WINNT
HANDLE ghstdout;
CONSOLE_SCREEN_BUFFER_INFO gscrbuf;
CONSOLE_CURSOR_INFO gcursbuf;
DWORD gdwPlatform;
#endif
#include "vars.h"
#include "struct.h"
#include "ircterm.h"
#include "window.h"
#include "screen.h"
#include "output.h"
#ifdef TRANSLATE
#include "translat.h"
#endif
#define MAIN_SOURCE
#include "modval.h"
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#else
#include <sys/termios.h>
#endif
#include <sys/ioctl.h>
#if defined(HAVE_NCURSES_TERM_H)
#include <ncurses/term.h>
#elif defined(HAVE_TERM_H)
#include <term.h>
#endif
static int tty_des; /* descriptor for the tty */
static struct termios oldb, newb;
extern int already_detached;
#if !defined(WTERM_C)
/* Systems can't seem to agree where to put these... */
#ifdef HAVE_TERMINFO
#define Tgetstr(x, y) ((void)&(y), tigetstr((x).iname))
#define Tgetnum(x) tigetnum(x.iname);
#define Tgetflag(x) tigetflag(x.iname);
#else
#define Tgetstr(x, y) tgetstr(x.tname, &y)
#define Tgetnum(x) tgetnum(x.tname)
#define Tgetflag(x) tgetflag(x.tname)
#endif
/* Some systems declare tparm() with 9 fixed 'long' arguments */
#define tparm1(str, a1) tparm(str, a1, 0, 0, 0, 0, 0, 0, 0, 0)
#define tparm2(str, a1, a2) tparm(str, a1, a2, 0, 0, 0, 0, 0, 0, 0)
#define tparm4(str, a1, a2, a3, a4) tparm(str, a1, a2, a3, a4, 0, 0, 0, 0, 0)
extern char *getenv();
/*
* The old code assumed termcap. termcap is almost always present, but on
* many systems that have both termcap and terminfo, termcap is deprecated
* and its databases often out of date. Configure will try to use terminfo
* if at all possible. We define here a mapping between the termcap / terminfo
* names, and where we store the information.
* NOTE: The terminfo portions are NOT implemented yet.
*/
#define CAP_TYPE_BOOL 0
#define CAP_TYPE_INT 1
#define CAP_TYPE_STR 2
typedef struct cap2info
{
const char * longname;
/* ncurses can optionally declare tigetstr(), tigetnum() and tigetflags() with
* a const char * argument. */
#ifdef NCURSES_CONST
NCURSES_CONST
#endif
char * iname;
const char * tname;
int type;
void * ptr;
} cap2info;
struct term_struct TIS;
static const cap2info tcaps[] =
{
{ "auto_left_margin", "bw", "bw", CAP_TYPE_BOOL, &TIS.TI_bw },
{ "auto_right_margin", "am", "am", CAP_TYPE_BOOL, &TIS.TI_am },
{ "no_esc_ctlc", "xsb", "xb", CAP_TYPE_BOOL, &TIS.TI_xsb },
{ "ceol_standout_glitch", "xhp", "xs", CAP_TYPE_BOOL, &TIS.TI_xhp },
{ "eat_newline_glitch", "xenl", "xn", CAP_TYPE_BOOL, &TIS.TI_xenl },
{ "erase_overstrike", "eo", "eo", CAP_TYPE_BOOL, &TIS.TI_eo },
{ "generic_type", "gn", "gn", CAP_TYPE_BOOL, &TIS.TI_gn },
{ "hard_copy", "hc", "hc", CAP_TYPE_BOOL, &TIS.TI_hc },
{ "has_meta_key", "km", "km", CAP_TYPE_BOOL, &TIS.TI_km },
{ "has_status_line", "hs", "hs", CAP_TYPE_BOOL, &TIS.TI_hs },
{ "insert_null_glitch", "in", "in", CAP_TYPE_BOOL, &TIS.TI_in },
{ "memory_above", "da", "da", CAP_TYPE_BOOL, &TIS.TI_da },
{ "memory_below", "db", "db", CAP_TYPE_BOOL, &TIS.TI_db },
{ "move_insert_mode", "mir", "mi", CAP_TYPE_BOOL, &TIS.TI_mir },
{ "move_standout_mode", "msgr", "ms", CAP_TYPE_BOOL, &TIS.TI_msgr },
{ "over_strike", "os", "os", CAP_TYPE_BOOL, &TIS.TI_os },
{ "status_line_esc_ok", "eslok", "es", CAP_TYPE_BOOL, &TIS.TI_eslok },
{ "dest_tabs_magic_smso", "xt", "xt", CAP_TYPE_BOOL, &TIS.TI_xt },
{ "tilde_glitch", "hz", "hz", CAP_TYPE_BOOL, &TIS.TI_hz },
{ "transparent_underline", "ul", "ul", CAP_TYPE_BOOL, &TIS.TI_ul },
{ "xon_xoff", "xon", "xo", CAP_TYPE_BOOL, &TIS.TI_xon },
{ "needs_xon_xoff", "nxon", "nx", CAP_TYPE_BOOL, &TIS.TI_nxon },
{ "prtr_silent", "mc5i", "5i", CAP_TYPE_BOOL, &TIS.TI_mc5i },
{ "hard_cursor", "chts", "HC", CAP_TYPE_BOOL, &TIS.TI_chts },
{ "non_rev_rmcup", "nrrmc", "NR", CAP_TYPE_BOOL, &TIS.TI_nrrmc },
{ "no_pad_char", "npc", "NP", CAP_TYPE_BOOL, &TIS.TI_npc },
{ "non_dest_scroll_region", "ndscr", "ND", CAP_TYPE_BOOL, &TIS.TI_ndscr },
{ "can_change", "ccc", "cc", CAP_TYPE_BOOL, &TIS.TI_ccc },
{ "back_color_erase", "bce", "ut", CAP_TYPE_BOOL, &TIS.TI_bce },
{ "hue_lightness_saturation", "hls", "hl", CAP_TYPE_BOOL, &TIS.TI_hls },
{ "col_addr_glitch", "xhpa", "YA", CAP_TYPE_BOOL, &TIS.TI_xhpa },
{ "cr_cancels_micro_mode", "crxm", "YB", CAP_TYPE_BOOL, &TIS.TI_crxm },
{ "has_print_wheel", "daisy", "YC", CAP_TYPE_BOOL, &TIS.TI_daisy },
{ "row_addr_glitch", "xvpa", "YD", CAP_TYPE_BOOL, &TIS.TI_xvpa },
{ "semi_auto_right_margin", "sam", "YE", CAP_TYPE_BOOL, &TIS.TI_sam },
{ "cpi_changes_res", "cpix", "YF", CAP_TYPE_BOOL, &TIS.TI_cpix },
{ "lpi_changes_res", "lpix", "YG", CAP_TYPE_BOOL, &TIS.TI_lpix },
{ "columns", "cols", "co", CAP_TYPE_INT, &TIS.TI_cols },
{ "init_tabs", "it", "it", CAP_TYPE_INT, &TIS.TI_it },
{ "lines", "lines", "li", CAP_TYPE_INT, &TIS.TI_lines },
{ "lines_of_memory", "lm", "lm", CAP_TYPE_INT, &TIS.TI_lm },
{ "magic_cookie_glitch", "xmc", "sg", CAP_TYPE_INT, &TIS.TI_xmc },
{ "padding_baud_rate", "pb", "pb", CAP_TYPE_INT, &TIS.TI_pb },
{ "virtual_terminal", "vt", "vt", CAP_TYPE_INT, &TIS.TI_vt },
{ "width_status_line", "wsl", "ws", CAP_TYPE_INT, &TIS.TI_wsl },
{ "num_labels", "nlab", "Nl", CAP_TYPE_INT, &TIS.TI_nlab },
{ "label_height", "lh", "lh", CAP_TYPE_INT, &TIS.TI_lh },
{ "label_width", "lw", "lw", CAP_TYPE_INT, &TIS.TI_lw },
{ "max_attributes", "ma", "ma", CAP_TYPE_INT, &TIS.TI_ma },
{ "maximum_windows", "wnum", "MW", CAP_TYPE_INT, &TIS.TI_wnum },
{ "max_colors", "colors", "Co", CAP_TYPE_INT, &TIS.TI_colors },
{ "max_pairs", "pairs", "pa", CAP_TYPE_INT, &TIS.TI_pairs },
{ "no_color_video", "ncv", "NC", CAP_TYPE_INT, &TIS.TI_ncv },
{ "buffer_capacity", "bufsz", "Ya", CAP_TYPE_INT, &TIS.TI_bufsz },
{ "dot_vert_spacing", "spinv", "Yb", CAP_TYPE_INT, &TIS.TI_spinv },
{ "dot_horz_spacing", "spinh", "Yc", CAP_TYPE_INT, &TIS.TI_spinh },
{ "max_micro_address", "maddr", "Yd", CAP_TYPE_INT, &TIS.TI_maddr },
{ "max_micro_jump", "mjump", "Ye", CAP_TYPE_INT, &TIS.TI_mjump },
{ "micro_col_size", "mcs", "Yf", CAP_TYPE_INT, &TIS.TI_mcs },
{ "micro_line_size", "mls", "Yg", CAP_TYPE_INT, &TIS.TI_mls },
{ "number_of_pins", "npins", "Yh", CAP_TYPE_INT, &TIS.TI_npins },
{ "output_res_char", "orc", "Yi", CAP_TYPE_INT, &TIS.TI_orc },
{ "output_res_line", "orl", "Yj", CAP_TYPE_INT, &TIS.TI_orl },
{ "output_res_horz_inch", "orhi", "Yk", CAP_TYPE_INT, &TIS.TI_orhi },
{ "output_res_vert_inch", "orvi", "Yl", CAP_TYPE_INT, &TIS.TI_orvi },
{ "print_rate", "cps", "Ym", CAP_TYPE_INT, &TIS.TI_cps },
{ "wide_char_size", "widcs", "Yn", CAP_TYPE_INT, &TIS.TI_widcs },
{ "buttons", "btns", "BT", CAP_TYPE_INT, &TIS.TI_btns },
{ "bit_image_entwining", "bitwin", "Yo", CAP_TYPE_INT, &TIS.TI_bitwin },
{ "bit_image_type", "bitype", "Yp", CAP_TYPE_INT, &TIS.TI_bitype },
{ "back_tab", "cbt", "bt", CAP_TYPE_STR, &TIS.TI_cbt },
{ "bell", "bel", "bl", CAP_TYPE_STR, &TIS.TI_bel },
{ "carriage_return", "cr", "cr", CAP_TYPE_STR, &TIS.TI_cr },
{ "change_scroll_region", "csr", "cs", CAP_TYPE_STR, &TIS.TI_csr },
{ "clear_all_tabs", "tbc", "ct", CAP_TYPE_STR, &TIS.TI_tbc },
{ "clear_screen", "clear", "cl", CAP_TYPE_STR, &TIS.TI_clear },
{ "clr_eol", "el", "ce", CAP_TYPE_STR, &TIS.TI_el },
{ "clr_eos", "ed", "cd", CAP_TYPE_STR, &TIS.TI_ed },
{ "column_address", "hpa", "ch", CAP_TYPE_STR, &TIS.TI_hpa },
{ "command_character", "cmdch", "CC", CAP_TYPE_STR, &TIS.TI_cmdch },
{ "cursor_address", "cup", "cm", CAP_TYPE_STR, &TIS.TI_cup },
{ "cursor_down", "cud1", "do", CAP_TYPE_STR, &TIS.TI_cud1 },
{ "cursor_home", "home", "ho", CAP_TYPE_STR, &TIS.TI_home },
{ "cursor_invisible", "civis", "vi", CAP_TYPE_STR, &TIS.TI_civis },
{ "cursor_left", "cub1", "le", CAP_TYPE_STR, &TIS.TI_cub1 },
{ "cursor_mem_address", "mrcup", "CM", CAP_TYPE_STR, &TIS.TI_mrcup },
{ "cursor_normal", "cnorm", "ve", CAP_TYPE_STR, &TIS.TI_cnorm },
{ "cursor_right", "cuf1", "nd", CAP_TYPE_STR, &TIS.TI_cuf1 },
{ "cursor_to_ll", "ll", "ll", CAP_TYPE_STR, &TIS.TI_ll },
{ "cursor_up", "cuu1", "up", CAP_TYPE_STR, &TIS.TI_cuu1 },
{ "cursor_visible", "cvvis", "vs", CAP_TYPE_STR, &TIS.TI_cvvis },
{ "delete_character", "dch1", "dc", CAP_TYPE_STR, &TIS.TI_dch1 },
{ "delete_line", "dl1", "dl", CAP_TYPE_STR, &TIS.TI_dl1 },
{ "dis_status_line", "dsl", "ds", CAP_TYPE_STR, &TIS.TI_dsl },
{ "down_half_line", "hd", "hd", CAP_TYPE_STR, &TIS.TI_hd },
{ "enter_alt_charset_mode", "smacs", "as", CAP_TYPE_STR, &TIS.TI_smacs },
{ "enter_blink_mode", "blink", "mb", CAP_TYPE_STR, &TIS.TI_blink },
{ "enter_bold_mode", "bold", "md", CAP_TYPE_STR, &TIS.TI_bold },
{ "enter_ca_mode", "smcup", "ti", CAP_TYPE_STR, &TIS.TI_smcup },
{ "enter_delete_mode", "smdc", "dm", CAP_TYPE_STR, &TIS.TI_smdc },
{ "enter_dim_mode", "dim", "mh", CAP_TYPE_STR, &TIS.TI_dim },
{ "enter_insert_mode", "smir", "im", CAP_TYPE_STR, &TIS.TI_smir },
{ "enter_secure_mode", "invis", "mk", CAP_TYPE_STR, &TIS.TI_invis },
{ "enter_protected_mode", "prot", "mp", CAP_TYPE_STR, &TIS.TI_prot },
{ "enter_reverse_mode", "rev", "mr", CAP_TYPE_STR, &TIS.TI_rev },
{ "enter_standout_mode", "smso", "so", CAP_TYPE_STR, &TIS.TI_smso },
{ "enter_underline_mode", "smul", "us", CAP_TYPE_STR, &TIS.TI_smul },
{ "erase_chars", "ech", "ec", CAP_TYPE_STR, &TIS.TI_ech },
{ "exit_alt_charset_mode", "rmacs", "ae", CAP_TYPE_STR, &TIS.TI_rmacs },
{ "exit_attribute_mode", "sgr0", "me", CAP_TYPE_STR, &TIS.TI_sgr0 },
{ "exit_ca_mode", "rmcup", "te", CAP_TYPE_STR, &TIS.TI_rmcup },
{ "exit_delete_mode", "rmdc", "ed", CAP_TYPE_STR, &TIS.TI_rmdc },
{ "exit_insert_mode", "rmir", "ei", CAP_TYPE_STR, &TIS.TI_rmir },
{ "exit_standout_mode", "rmso", "se", CAP_TYPE_STR, &TIS.TI_rmso },
{ "exit_underline_mode", "rmul", "ue", CAP_TYPE_STR, &TIS.TI_rmul },
{ "flash_screen", "flash", "vb", CAP_TYPE_STR, &TIS.TI_flash },
{ "form_feed", "ff", "ff", CAP_TYPE_STR, &TIS.TI_ff },
{ "from_status_line", "fsl", "fs", CAP_TYPE_STR, &TIS.TI_fsl },
{ "init_1string", "is1", "i1", CAP_TYPE_STR, &TIS.TI_is1 },
{ "init_2string", "is2", "is", CAP_TYPE_STR, &TIS.TI_is2 },
{ "init_3string", "is3", "i3", CAP_TYPE_STR, &TIS.TI_is3 },
{ "init_file", "if", "if", CAP_TYPE_STR, &TIS.TI_if },
{ "insert_character", "ich1", "ic", CAP_TYPE_STR, &TIS.TI_ich1 },
{ "insert_line", "il1", "al", CAP_TYPE_STR, &TIS.TI_il1 },
{ "insert_padding", "ip", "ip", CAP_TYPE_STR, &TIS.TI_ip },
{ "key_backspace", "kbs", "kb", CAP_TYPE_STR, &TIS.TI_kbs },
{ "key_catab", "ktbc", "ka", CAP_TYPE_STR, &TIS.TI_ktbc },
{ "key_clear", "kclr", "kC", CAP_TYPE_STR, &TIS.TI_kclr },
{ "key_ctab", "kctab", "kt", CAP_TYPE_STR, &TIS.TI_kctab },
{ "key_dc", "kdch1", "kD", CAP_TYPE_STR, &TIS.TI_kdch1 },
{ "key_dl", "kdl1", "kL", CAP_TYPE_STR, &TIS.TI_kdl1 },
{ "key_down", "kcud1", "kd", CAP_TYPE_STR, &TIS.TI_kcud1 },
{ "key_eic", "krmir", "kM", CAP_TYPE_STR, &TIS.TI_krmir },
{ "key_eol", "kel", "kE", CAP_TYPE_STR, &TIS.TI_kel },
{ "key_eos", "ked", "kS", CAP_TYPE_STR, &TIS.TI_ked },
{ "key_f0", "kf0", "k0", CAP_TYPE_STR, &TIS.TI_kf0 },
{ "key_f1", "kf1", "k1", CAP_TYPE_STR, &TIS.TI_kf1 },
{ "key_f10", "kf10", "k;", CAP_TYPE_STR, &TIS.TI_kf10 },
{ "key_f2", "kf2", "k2", CAP_TYPE_STR, &TIS.TI_kf2 },
{ "key_f3", "kf3", "k3", CAP_TYPE_STR, &TIS.TI_kf3 },
{ "key_f4", "kf4", "k4", CAP_TYPE_STR, &TIS.TI_kf4 },
{ "key_f5", "kf5", "k5", CAP_TYPE_STR, &TIS.TI_kf5 },
{ "key_f6", "kf6", "k6", CAP_TYPE_STR, &TIS.TI_kf6 },
{ "key_f7", "kf7", "k7", CAP_TYPE_STR, &TIS.TI_kf7 },
{ "key_f8", "kf8", "k8", CAP_TYPE_STR, &TIS.TI_kf8 },
{ "key_f9", "kf9", "k9", CAP_TYPE_STR, &TIS.TI_kf9 },
{ "key_home", "khome", "kh", CAP_TYPE_STR, &TIS.TI_khome },
{ "key_ic", "kich1", "kI", CAP_TYPE_STR, &TIS.TI_kich1 },
{ "key_il", "kil1", "kA", CAP_TYPE_STR, &TIS.TI_kil1 },
{ "key_left", "kcub1", "kl", CAP_TYPE_STR, &TIS.TI_kcub1 },
{ "key_ll", "kll", "kH", CAP_TYPE_STR, &TIS.TI_kll },
{ "key_npage", "knp", "kN", CAP_TYPE_STR, &TIS.TI_knp },
{ "key_ppage", "kpp", "kP", CAP_TYPE_STR, &TIS.TI_kpp },
{ "key_right", "kcuf1", "kr", CAP_TYPE_STR, &TIS.TI_kcuf1 },
{ "key_sf", "kind", "kF", CAP_TYPE_STR, &TIS.TI_kind },
{ "key_sr", "kri", "kR", CAP_TYPE_STR, &TIS.TI_kri },
{ "key_stab", "khts", "kT", CAP_TYPE_STR, &TIS.TI_khts },
{ "key_up", "kcuu1", "ku", CAP_TYPE_STR, &TIS.TI_kcuu1 },
{ "keypad_local", "rmkx", "ke", CAP_TYPE_STR, &TIS.TI_rmkx },
{ "keypad_xmit", "smkx", "ks", CAP_TYPE_STR, &TIS.TI_smkx },
{ "lab_f0", "lf0", "l0", CAP_TYPE_STR, &TIS.TI_lf0 },
{ "lab_f1", "lf1", "l1", CAP_TYPE_STR, &TIS.TI_lf1 },
{ "lab_f10", "lf10", "la", CAP_TYPE_STR, &TIS.TI_lf10 },
{ "lab_f2", "lf2", "l2", CAP_TYPE_STR, &TIS.TI_lf2 },
{ "lab_f3", "lf3", "l3", CAP_TYPE_STR, &TIS.TI_lf3 },
{ "lab_f4", "lf4", "l4", CAP_TYPE_STR, &TIS.TI_lf4 },
{ "lab_f5", "lf5", "l5", CAP_TYPE_STR, &TIS.TI_lf5 },
{ "lab_f6", "lf6", "l6", CAP_TYPE_STR, &TIS.TI_lf6 },
{ "lab_f7", "lf7", "l7", CAP_TYPE_STR, &TIS.TI_lf7 },
{ "lab_f8", "lf8", "l8", CAP_TYPE_STR, &TIS.TI_lf8 },
{ "lab_f9", "lf9", "l9", CAP_TYPE_STR, &TIS.TI_lf9 },
{ "meta_off", "rmm", "mo", CAP_TYPE_STR, &TIS.TI_rmm },
{ "meta_on", "smm", "mm", CAP_TYPE_STR, &TIS.TI_smm },
{ "newline", "nel", "nw", CAP_TYPE_STR, &TIS.TI_nel },
{ "pad_char", "pad", "pc", CAP_TYPE_STR, &TIS.TI_pad },
{ "parm_dch", "dch", "DC", CAP_TYPE_STR, &TIS.TI_dch },
{ "parm_delete_line", "dl", "DL", CAP_TYPE_STR, &TIS.TI_dl },
{ "parm_down_cursor", "cud", "DO", CAP_TYPE_STR, &TIS.TI_cud },
{ "parm_ich", "ich", "IC", CAP_TYPE_STR, &TIS.TI_ich },
{ "parm_index", "indn", "SF", CAP_TYPE_STR, &TIS.TI_indn },
{ "parm_insert_line", "il", "AL", CAP_TYPE_STR, &TIS.TI_il },
{ "parm_left_cursor", "cub", "LE", CAP_TYPE_STR, &TIS.TI_cub },
{ "parm_right_cursor", "cuf", "RI", CAP_TYPE_STR, &TIS.TI_cuf },
{ "parm_rindex", "rin", "SR", CAP_TYPE_STR, &TIS.TI_rin },
{ "parm_up_cursor", "cuu", "UP", CAP_TYPE_STR, &TIS.TI_cuu },
{ "pkey_key", "pfkey", "pk", CAP_TYPE_STR, &TIS.TI_pfkey },
{ "pkey_local", "pfloc", "pl", CAP_TYPE_STR, &TIS.TI_pfloc },
{ "pkey_xmit", "pfx", "px", CAP_TYPE_STR, &TIS.TI_pfx },
{ "print_screen", "mc0", "ps", CAP_TYPE_STR, &TIS.TI_mc0 },
{ "prtr_off", "mc4", "pf", CAP_TYPE_STR, &TIS.TI_mc4 },
{ "prtr_on", "mc5", "po", CAP_TYPE_STR, &TIS.TI_mc5 },
{ "repeat_char", "rep", "rp", CAP_TYPE_STR, &TIS.TI_rep },
{ "reset_1string", "rs1", "r1", CAP_TYPE_STR, &TIS.TI_rs1 },
{ "reset_2string", "rs2", "r2", CAP_TYPE_STR, &TIS.TI_rs2 },
{ "reset_3string", "rs3", "r3", CAP_TYPE_STR, &TIS.TI_rs3 },
{ "reset_file", "rf", "rf", CAP_TYPE_STR, &TIS.TI_rf },
{ "restore_cursor", "rc", "rc", CAP_TYPE_STR, &TIS.TI_rc },
{ "row_address", "vpa", "cv", CAP_TYPE_STR, &TIS.TI_vpa },
{ "save_cursor", "sc", "sc", CAP_TYPE_STR, &TIS.TI_sc },
{ "scroll_forward", "ind", "sf", CAP_TYPE_STR, &TIS.TI_ind },
{ "scroll_reverse", "ri", "sr", CAP_TYPE_STR, &TIS.TI_ri },
{ "set_attributes", "sgr", "sa", CAP_TYPE_STR, &TIS.TI_sgr },
{ "set_tab", "hts", "st", CAP_TYPE_STR, &TIS.TI_hts },
{ "set_window", "wind", "wi", CAP_TYPE_STR, &TIS.TI_wind },
{ "tab", "ht", "ta", CAP_TYPE_STR, &TIS.TI_ht },
{ "to_status_line", "tsl", "ts", CAP_TYPE_STR, &TIS.TI_tsl },
{ "underline_char", "uc", "uc", CAP_TYPE_STR, &TIS.TI_uc },
{ "up_half_line", "hu", "hu", CAP_TYPE_STR, &TIS.TI_hu },
{ "init_prog", "iprog", "iP", CAP_TYPE_STR, &TIS.TI_iprog },
{ "key_a1", "ka1", "K1", CAP_TYPE_STR, &TIS.TI_ka1 },
{ "key_a3", "ka3", "K3", CAP_TYPE_STR, &TIS.TI_ka3 },
{ "key_b2", "kb2", "K2", CAP_TYPE_STR, &TIS.TI_kb2 },
{ "key_c1", "kc1", "K4", CAP_TYPE_STR, &TIS.TI_kc1 },
{ "key_c3", "kc3", "K5", CAP_TYPE_STR, &TIS.TI_kc3 },
{ "prtr_non", "mc5p", "pO", CAP_TYPE_STR, &TIS.TI_mc5p },
{ "char_padding", "rmp", "rP", CAP_TYPE_STR, &TIS.TI_rmp },
{ "acs_chars", "acsc", "ac", CAP_TYPE_STR, &TIS.TI_acsc },
{ "plab_norm", "pln", "pn", CAP_TYPE_STR, &TIS.TI_pln },
{ "key_btab", "kcbt", "kB", CAP_TYPE_STR, &TIS.TI_kcbt },
{ "enter_xon_mode", "smxon", "SX", CAP_TYPE_STR, &TIS.TI_smxon },
{ "exit_xon_mode", "rmxon", "RX", CAP_TYPE_STR, &TIS.TI_rmxon },
{ "enter_am_mode", "smam", "SA", CAP_TYPE_STR, &TIS.TI_smam },
{ "exit_am_mode", "rmam", "RA", CAP_TYPE_STR, &TIS.TI_rmam },
{ "xon_character", "xonc", "XN", CAP_TYPE_STR, &TIS.TI_xonc },
{ "xoff_character", "xoffc", "XF", CAP_TYPE_STR, &TIS.TI_xoffc },
{ "ena_acs", "enacs", "eA", CAP_TYPE_STR, &TIS.TI_enacs },
{ "label_on", "smln", "LO", CAP_TYPE_STR, &TIS.TI_smln },
{ "label_off", "rmln", "LF", CAP_TYPE_STR, &TIS.TI_rmln },
{ "key_beg", "kbeg", "@1", CAP_TYPE_STR, &TIS.TI_kbeg },
{ "key_cancel", "kcan", "@2", CAP_TYPE_STR, &TIS.TI_kcan },
{ "key_close", "kclo", "@3", CAP_TYPE_STR, &TIS.TI_kclo },
{ "key_command", "kcmd", "@4", CAP_TYPE_STR, &TIS.TI_kcmd },
{ "key_copy", "kcpy", "@5", CAP_TYPE_STR, &TIS.TI_kcpy },
{ "key_create", "kcrt", "@6", CAP_TYPE_STR, &TIS.TI_kcrt },
{ "key_end", "kend", "@7", CAP_TYPE_STR, &TIS.TI_kend },
{ "key_enter", "kent", "@8", CAP_TYPE_STR, &TIS.TI_kent },
{ "key_exit", "kext", "@9", CAP_TYPE_STR, &TIS.TI_kext },
{ "key_find", "kfnd", "@0", CAP_TYPE_STR, &TIS.TI_kfnd },
{ "key_help", "khlp", "%1", CAP_TYPE_STR, &TIS.TI_khlp },
{ "key_mark", "kmrk", "%2", CAP_TYPE_STR, &TIS.TI_kmrk },
{ "key_message", "kmsg", "%3", CAP_TYPE_STR, &TIS.TI_kmsg },
{ "key_move", "kmov", "%4", CAP_TYPE_STR, &TIS.TI_kmov },
{ "key_next", "knxt", "%5", CAP_TYPE_STR, &TIS.TI_knxt },
{ "key_open", "kopn", "%6", CAP_TYPE_STR, &TIS.TI_kopn },
{ "key_options", "kopt", "%7", CAP_TYPE_STR, &TIS.TI_kopt },
{ "key_previous", "kprv", "%8", CAP_TYPE_STR, &TIS.TI_kprv },
{ "key_print", "kprt", "%9", CAP_TYPE_STR, &TIS.TI_kprt },
{ "key_redo", "krdo", "%0", CAP_TYPE_STR, &TIS.TI_krdo },
{ "key_reference", "kref", "&1", CAP_TYPE_STR, &TIS.TI_kref },
{ "key_refresh", "krfr", "&2", CAP_TYPE_STR, &TIS.TI_krfr },
{ "key_replace", "krpl", "&3", CAP_TYPE_STR, &TIS.TI_krpl },
{ "key_restart", "krst", "&4", CAP_TYPE_STR, &TIS.TI_krst },
{ "key_resume", "kres", "&5", CAP_TYPE_STR, &TIS.TI_kres },
{ "key_save", "ksav", "&6", CAP_TYPE_STR, &TIS.TI_ksav },
{ "key_suspend", "kspd", "&7", CAP_TYPE_STR, &TIS.TI_kspd },
{ "key_undo", "kund", "&8", CAP_TYPE_STR, &TIS.TI_kund },
{ "key_sbeg", "kBEG", "&9", CAP_TYPE_STR, &TIS.TI_kBEG },
{ "key_scancel", "kCAN", "&0", CAP_TYPE_STR, &TIS.TI_kCAN },
{ "key_scommand", "kCMD", "*1", CAP_TYPE_STR, &TIS.TI_kCMD },
{ "key_scopy", "kCPY", "*2", CAP_TYPE_STR, &TIS.TI_kCPY },
{ "key_screate", "kCRT", "*3", CAP_TYPE_STR, &TIS.TI_kCRT },
{ "key_sdc", "kDC", "*4", CAP_TYPE_STR, &TIS.TI_kDC },
{ "key_sdl", "kDL", "*5", CAP_TYPE_STR, &TIS.TI_kDL },
{ "key_select", "kslt", "*6", CAP_TYPE_STR, &TIS.TI_kslt },
{ "key_send", "kEND", "*7", CAP_TYPE_STR, &TIS.TI_kEND },
{ "key_seol", "kEOL", "*8", CAP_TYPE_STR, &TIS.TI_kEOL },
{ "key_sexit", "kEXT", "*9", CAP_TYPE_STR, &TIS.TI_kEXT },
{ "key_sfind", "kFND", "*0", CAP_TYPE_STR, &TIS.TI_kFND },
{ "key_shelp", "kHLP", "#1", CAP_TYPE_STR, &TIS.TI_kHLP },
{ "key_shome", "kHOM", "#2", CAP_TYPE_STR, &TIS.TI_kHOM },
{ "key_sic", "kIC", "#3", CAP_TYPE_STR, &TIS.TI_kIC },
{ "key_sleft", "kLFT", "#4", CAP_TYPE_STR, &TIS.TI_kLFT },
{ "key_smessage", "kMSG", "%a", CAP_TYPE_STR, &TIS.TI_kMSG },
{ "key_smove", "kMOV", "%b", CAP_TYPE_STR, &TIS.TI_kMOV },
{ "key_snext", "kNXT", "%c", CAP_TYPE_STR, &TIS.TI_kNXT },
{ "key_soptions", "kOPT", "%d", CAP_TYPE_STR, &TIS.TI_kOPT },
{ "key_sprevious", "kPRV", "%e", CAP_TYPE_STR, &TIS.TI_kPRV },
{ "key_sprint", "kPRT", "%f", CAP_TYPE_STR, &TIS.TI_kPRT },
{ "key_sredo", "kRDO", "%g", CAP_TYPE_STR, &TIS.TI_kRDO },
{ "key_sreplace", "kRPL", "%h", CAP_TYPE_STR, &TIS.TI_kRPL },
{ "key_sright", "kRIT", "%i", CAP_TYPE_STR, &TIS.TI_kRIT },
{ "key_srsume", "kRES", "%j", CAP_TYPE_STR, &TIS.TI_kRES },
{ "key_ssave", "kSAV", "!1", CAP_TYPE_STR, &TIS.TI_kSAV },
{ "key_ssuspend", "kSPD", "!2", CAP_TYPE_STR, &TIS.TI_kSPD },
{ "key_sundo", "kUND", "!3", CAP_TYPE_STR, &TIS.TI_kUND },
{ "req_for_input", "rfi", "RF", CAP_TYPE_STR, &TIS.TI_rfi },
{ "key_f11", "kf11", "F1", CAP_TYPE_STR, &TIS.TI_kf11 },
{ "key_f12", "kf12", "F2", CAP_TYPE_STR, &TIS.TI_kf12 },
{ "key_f13", "kf13", "F3", CAP_TYPE_STR, &TIS.TI_kf13 },
{ "key_f14", "kf14", "F4", CAP_TYPE_STR, &TIS.TI_kf14 },
{ "key_f15", "kf15", "F5", CAP_TYPE_STR, &TIS.TI_kf15 },
{ "key_f16", "kf16", "F6", CAP_TYPE_STR, &TIS.TI_kf16 },
{ "key_f17", "kf17", "F7", CAP_TYPE_STR, &TIS.TI_kf17 },
{ "key_f18", "kf18", "F8", CAP_TYPE_STR, &TIS.TI_kf18 },
{ "key_f19", "kf19", "F9", CAP_TYPE_STR, &TIS.TI_kf19 },
{ "key_f20", "kf20", "FA", CAP_TYPE_STR, &TIS.TI_kf20 },
{ "key_f21", "kf21", "FB", CAP_TYPE_STR, &TIS.TI_kf21 },
{ "key_f22", "kf22", "FC", CAP_TYPE_STR, &TIS.TI_kf22 },
{ "key_f23", "kf23", "FD", CAP_TYPE_STR, &TIS.TI_kf23 },
{ "key_f24", "kf24", "FE", CAP_TYPE_STR, &TIS.TI_kf24 },
{ "key_f25", "kf25", "FF", CAP_TYPE_STR, &TIS.TI_kf25 },
{ "key_f26", "kf26", "FG", CAP_TYPE_STR, &TIS.TI_kf26 },
{ "key_f27", "kf27", "FH", CAP_TYPE_STR, &TIS.TI_kf27 },
{ "key_f28", "kf28", "FI", CAP_TYPE_STR, &TIS.TI_kf28 },
{ "key_f29", "kf29", "FJ", CAP_TYPE_STR, &TIS.TI_kf29 },
{ "key_f30", "kf30", "FK", CAP_TYPE_STR, &TIS.TI_kf30 },
{ "key_f31", "kf31", "FL", CAP_TYPE_STR, &TIS.TI_kf31 },
{ "key_f32", "kf32", "FM", CAP_TYPE_STR, &TIS.TI_kf32 },
{ "key_f33", "kf33", "FN", CAP_TYPE_STR, &TIS.TI_kf33 },
{ "key_f34", "kf34", "FO", CAP_TYPE_STR, &TIS.TI_kf34 },
{ "key_f35", "kf35", "FP", CAP_TYPE_STR, &TIS.TI_kf35 },
{ "key_f36", "kf36", "FQ", CAP_TYPE_STR, &TIS.TI_kf36 },
{ "key_f37", "kf37", "FR", CAP_TYPE_STR, &TIS.TI_kf37 },
{ "key_f38", "kf38", "FS", CAP_TYPE_STR, &TIS.TI_kf38 },
{ "key_f39", "kf39", "FT", CAP_TYPE_STR, &TIS.TI_kf39 },
{ "key_f40", "kf40", "FU", CAP_TYPE_STR, &TIS.TI_kf40 },
{ "key_f41", "kf41", "FV", CAP_TYPE_STR, &TIS.TI_kf41 },
{ "key_f42", "kf42", "FW", CAP_TYPE_STR, &TIS.TI_kf42 },
{ "key_f43", "kf43", "FX", CAP_TYPE_STR, &TIS.TI_kf43 },
{ "key_f44", "kf44", "FY", CAP_TYPE_STR, &TIS.TI_kf44 },
{ "key_f45", "kf45", "FZ", CAP_TYPE_STR, &TIS.TI_kf45 },
{ "key_f46", "kf46", "Fa", CAP_TYPE_STR, &TIS.TI_kf46 },
{ "key_f47", "kf47", "Fb", CAP_TYPE_STR, &TIS.TI_kf47 },
{ "key_f48", "kf48", "Fc", CAP_TYPE_STR, &TIS.TI_kf48 },
{ "key_f49", "kf49", "Fd", CAP_TYPE_STR, &TIS.TI_kf49 },
{ "key_f50", "kf50", "Fe", CAP_TYPE_STR, &TIS.TI_kf50 },
{ "key_f51", "kf51", "Ff", CAP_TYPE_STR, &TIS.TI_kf51 },
{ "key_f52", "kf52", "Fg", CAP_TYPE_STR, &TIS.TI_kf52 },
{ "key_f53", "kf53", "Fh", CAP_TYPE_STR, &TIS.TI_kf53 },
{ "key_f54", "kf54", "Fi", CAP_TYPE_STR, &TIS.TI_kf54 },
{ "key_f55", "kf55", "Fj", CAP_TYPE_STR, &TIS.TI_kf55 },
{ "key_f56", "kf56", "Fk", CAP_TYPE_STR, &TIS.TI_kf56 },
{ "key_f57", "kf57", "Fl", CAP_TYPE_STR, &TIS.TI_kf57 },
{ "key_f58", "kf58", "Fm", CAP_TYPE_STR, &TIS.TI_kf58 },
{ "key_f59", "kf59", "Fn", CAP_TYPE_STR, &TIS.TI_kf59 },
{ "key_f60", "kf60", "Fo", CAP_TYPE_STR, &TIS.TI_kf60 },
{ "key_f61", "kf61", "Fp", CAP_TYPE_STR, &TIS.TI_kf61 },
{ "key_f62", "kf62", "Fq", CAP_TYPE_STR, &TIS.TI_kf62 },
{ "key_f63", "kf63", "Fr", CAP_TYPE_STR, &TIS.TI_kf63 },
{ "clr_bol", "el1", "cb", CAP_TYPE_STR, &TIS.TI_el1 },
{ "clear_margins", "mgc", "MC", CAP_TYPE_STR, &TIS.TI_mgc },
{ "set_left_margin", "smgl", "ML", CAP_TYPE_STR, &TIS.TI_smgl },
{ "set_right_margin", "smgr", "MR", CAP_TYPE_STR, &TIS.TI_smgr },
{ "label_format", "fln", "Lf", CAP_TYPE_STR, &TIS.TI_fln },
{ "set_clock", "sclk", "SC", CAP_TYPE_STR, &TIS.TI_sclk },
{ "display_clock", "dclk", "DK", CAP_TYPE_STR, &TIS.TI_dclk },
{ "remove_clock", "rmclk", "RC", CAP_TYPE_STR, &TIS.TI_rmclk },
{ "create_window", "cwin", "CW", CAP_TYPE_STR, &TIS.TI_cwin },
{ "goto_window", "wingo", "WG", CAP_TYPE_STR, &TIS.TI_wingo },
{ "hangup", "hup", "HU", CAP_TYPE_STR, &TIS.TI_hup },
{ "dial_phone", "dial", "DI", CAP_TYPE_STR, &TIS.TI_dial },
{ "quick_dial", "qdial", "QD", CAP_TYPE_STR, &TIS.TI_qdial },
{ "tone", "tone", "TO", CAP_TYPE_STR, &TIS.TI_tone },
{ "pulse", "pulse", "PU", CAP_TYPE_STR, &TIS.TI_pulse },
{ "flash_hook", "hook", "fh", CAP_TYPE_STR, &TIS.TI_hook },
{ "fixed_pause", "pause", "PA", CAP_TYPE_STR, &TIS.TI_pause },
{ "wait_tone", "wait", "WA", CAP_TYPE_STR, &TIS.TI_wait },
{ "user0", "u0", "u0", CAP_TYPE_STR, &TIS.TI_u0 },
{ "user1", "u1", "u1", CAP_TYPE_STR, &TIS.TI_u1 },
{ "user2", "u2", "u2", CAP_TYPE_STR, &TIS.TI_u2 },
{ "user3", "u3", "u3", CAP_TYPE_STR, &TIS.TI_u3 },
{ "user4", "u4", "u4", CAP_TYPE_STR, &TIS.TI_u4 },
{ "user5", "u5", "u5", CAP_TYPE_STR, &TIS.TI_u5 },
{ "user6", "u6", "u6", CAP_TYPE_STR, &TIS.TI_u6 },
{ "user7", "u7", "u7", CAP_TYPE_STR, &TIS.TI_u7 },
{ "user8", "u8", "u8", CAP_TYPE_STR, &TIS.TI_u8 },
{ "user9", "u9", "u9", CAP_TYPE_STR, &TIS.TI_u9 },
{ "orig_pair", "op", "op", CAP_TYPE_STR, &TIS.TI_op },
{ "orig_colors", "oc", "oc", CAP_TYPE_STR, &TIS.TI_oc },
{ "initialize_color", "initc", "Ic", CAP_TYPE_STR, &TIS.TI_initc },
{ "initialize_pair", "initp", "Ip", CAP_TYPE_STR, &TIS.TI_initp },
{ "set_color_pair", "scp", "sp", CAP_TYPE_STR, &TIS.TI_scp },
{ "set_foreground", "setf", "Sf", CAP_TYPE_STR, &TIS.TI_setf },
{ "set_background", "setb", "Sb", CAP_TYPE_STR, &TIS.TI_setb },
{ "change_char_pitch", "cpi", "ZA", CAP_TYPE_STR, &TIS.TI_cpi },
{ "change_line_pitch", "lpi", "ZB", CAP_TYPE_STR, &TIS.TI_lpi },
{ "change_res_horz", "chr", "ZC", CAP_TYPE_STR, &TIS.TI_chr },
{ "change_res_vert", "cvr", "ZD", CAP_TYPE_STR, &TIS.TI_cvr },
{ "define_char", "defc", "ZE", CAP_TYPE_STR, &TIS.TI_defc },
{ "enter_doublewide_mode", "swidm", "ZF", CAP_TYPE_STR, &TIS.TI_swidm },
{ "enter_draft_quality", "sdrfq", "ZG", CAP_TYPE_STR, &TIS.TI_sdrfq },
{ "enter_italics_mode", "sitm", "ZH", CAP_TYPE_STR, &TIS.TI_sitm },
{ "enter_leftward_mode", "slm", "ZI", CAP_TYPE_STR, &TIS.TI_slm },
{ "enter_micro_mode", "smicm", "ZJ", CAP_TYPE_STR, &TIS.TI_smicm },
{ "enter_near_letter_quality", "snlq", "ZK", CAP_TYPE_STR, &TIS.TI_snlq },
{ "enter_normal_quality", "snrmq", "ZL", CAP_TYPE_STR, &TIS.TI_snrmq },
{ "enter_shadow_mode", "sshm", "ZM", CAP_TYPE_STR, &TIS.TI_sshm },
{ "enter_subscript_mode", "ssubm", "ZN", CAP_TYPE_STR, &TIS.TI_ssubm },
{ "enter_superscript_mode", "ssupm", "ZO", CAP_TYPE_STR, &TIS.TI_ssupm },
{ "enter_upward_mode", "sum", "ZP", CAP_TYPE_STR, &TIS.TI_sum },
{ "exit_doublewide_mode", "rwidm", "ZQ", CAP_TYPE_STR, &TIS.TI_rwidm },
{ "exit_italics_mode", "ritm", "ZR", CAP_TYPE_STR, &TIS.TI_ritm },
{ "exit_leftward_mode", "rlm", "ZS", CAP_TYPE_STR, &TIS.TI_rlm },
{ "exit_micro_mode", "rmicm", "ZT", CAP_TYPE_STR, &TIS.TI_rmicm },
{ "exit_shadow_mode", "rshm", "ZU", CAP_TYPE_STR, &TIS.TI_rshm },
{ "exit_subscript_mode", "rsubm", "ZV", CAP_TYPE_STR, &TIS.TI_rsubm },
{ "exit_superscript_mode", "rsupm", "ZW", CAP_TYPE_STR, &TIS.TI_rsupm },
{ "exit_upward_mode", "rum", "ZX", CAP_TYPE_STR, &TIS.TI_rum },
{ "micro_column_address", "mhpa", "ZY", CAP_TYPE_STR, &TIS.TI_mhpa },
{ "micro_down", "mcud1", "ZZ", CAP_TYPE_STR, &TIS.TI_mcud1 },
{ "micro_left", "mcub1", "Za", CAP_TYPE_STR, &TIS.TI_mcub1 },
{ "micro_right", "mcuf1", "Zb", CAP_TYPE_STR, &TIS.TI_mcuf1 },
{ "micro_row_address", "mvpa", "Zc", CAP_TYPE_STR, &TIS.TI_mvpa },
{ "micro_up", "mcuu1", "Zd", CAP_TYPE_STR, &TIS.TI_mcuu1 },
{ "order_of_pins", "porder", "Ze", CAP_TYPE_STR, &TIS.TI_porder },
{ "parm_down_micro", "mcud", "Zf", CAP_TYPE_STR, &TIS.TI_mcud },
{ "parm_left_micro", "mcub", "Zg", CAP_TYPE_STR, &TIS.TI_mcub },
{ "parm_right_micro", "mcuf", "Zh", CAP_TYPE_STR, &TIS.TI_mcuf },
{ "parm_up_micro", "mcuu", "Zi", CAP_TYPE_STR, &TIS.TI_mcuu },
{ "select_char_set", "scs", "Zj", CAP_TYPE_STR, &TIS.TI_scs },
{ "set_bottom_margin", "smgb", "Zk", CAP_TYPE_STR, &TIS.TI_smgb },
{ "set_bottom_margin_parm", "smgbp", "Zl", CAP_TYPE_STR, &TIS.TI_smgbp },
{ "set_left_margin_parm", "smglp", "Zm", CAP_TYPE_STR, &TIS.TI_smglp },
{ "set_right_margin_parm", "smgrp", "Zn", CAP_TYPE_STR, &TIS.TI_smgrp },
{ "set_top_margin", "smgt", "Zo", CAP_TYPE_STR, &TIS.TI_smgt },
{ "set_top_margin_parm", "smgtp", "Zp", CAP_TYPE_STR, &TIS.TI_smgtp },
{ "start_bit_image", "sbim", "Zq", CAP_TYPE_STR, &TIS.TI_sbim },
{ "start_char_set_def", "scsd", "Zr", CAP_TYPE_STR, &TIS.TI_scsd },
{ "stop_bit_image", "rbim", "Zs", CAP_TYPE_STR, &TIS.TI_rbim },
{ "stop_char_set_def", "rcsd", "Zt", CAP_TYPE_STR, &TIS.TI_rcsd },
{ "subscript_characters", "subcs", "Zu", CAP_TYPE_STR, &TIS.TI_subcs },
{ "superscript_characters", "supcs", "Zv", CAP_TYPE_STR, &TIS.TI_supcs },
{ "these_cause_cr", "docr", "Zw", CAP_TYPE_STR, &TIS.TI_docr },
{ "zero_motion", "zerom", "Zx", CAP_TYPE_STR, &TIS.TI_zerom },
{ "char_set_names", "csnm", "Zy", CAP_TYPE_STR, &TIS.TI_csnm },
{ "key_mouse", "kmous", "Km", CAP_TYPE_STR, &TIS.TI_kmous },
{ "mouse_info", "minfo", "Mi", CAP_TYPE_STR, &TIS.TI_minfo },
{ "req_mouse_pos", "reqmp", "RQ", CAP_TYPE_STR, &TIS.TI_reqmp },
{ "get_mouse", "getm", "Gm", CAP_TYPE_STR, &TIS.TI_getm },
{ "set_a_foreground", "setaf", "AF", CAP_TYPE_STR, &TIS.TI_setaf },
{ "set_a_background", "setab", "AB", CAP_TYPE_STR, &TIS.TI_setab },
{ "pkey_plab", "pfxl", "xl", CAP_TYPE_STR, &TIS.TI_pfxl },
{ "device_type", "devt", "dv", CAP_TYPE_STR, &TIS.TI_devt },
{ "code_set_init", "csin", "ci", CAP_TYPE_STR, &TIS.TI_csin },
{ "set0_des_seq", "s0ds", "s0", CAP_TYPE_STR, &TIS.TI_s0ds },
{ "set1_des_seq", "s1ds", "s1", CAP_TYPE_STR, &TIS.TI_s1ds },
{ "set2_des_seq", "s2ds", "s2", CAP_TYPE_STR, &TIS.TI_s2ds },
{ "set3_des_seq", "s3ds", "s3", CAP_TYPE_STR, &TIS.TI_s3ds },
{ "set_lr_margin", "smglr", "ML", CAP_TYPE_STR, &TIS.TI_smglr },
{ "set_tb_margin", "smgtb", "MT", CAP_TYPE_STR, &TIS.TI_smgtb },
{ "bit_image_repeat", "birep", "Xy", CAP_TYPE_STR, &TIS.TI_birep },
{ "bit_image_newline", "binel", "Zz", CAP_TYPE_STR, &TIS.TI_binel },
{ "bit_image_carriage_return", "bicr", "Yv", CAP_TYPE_STR, &TIS.TI_bicr },
{ "color_names", "colornm", "Yw", CAP_TYPE_STR, &TIS.TI_colornm },
{ "define_bit_image_region", "defbi", "Yx", CAP_TYPE_STR, &TIS.TI_defbi },
{ "end_bit_image_region", "endbi", "Yy", CAP_TYPE_STR, &TIS.TI_endbi },
{ "set_color_band", "setcolor", "Yz", CAP_TYPE_STR, &TIS.TI_setcolor },
{ "set_page_length", "slines", "YZ", CAP_TYPE_STR, &TIS.TI_slines },
{ "display_pc_char", "dispc", "S1", CAP_TYPE_STR, &TIS.TI_dispc },
{ "enter_pc_charset_mode", "smpch", "S2", CAP_TYPE_STR, &TIS.TI_smpch },
{ "exit_pc_charset_mode", "rmpch", "S3", CAP_TYPE_STR, &TIS.TI_rmpch },
{ "enter_scancode_mode", "smsc", "S4", CAP_TYPE_STR, &TIS.TI_smsc },
{ "exit_scancode_mode", "rmsc", "S5", CAP_TYPE_STR, &TIS.TI_rmsc },
{ "pc_term_options", "pctrm", "S6", CAP_TYPE_STR, &TIS.TI_pctrm },
{ "scancode_escape", "scesc", "S7", CAP_TYPE_STR, &TIS.TI_scesc },
{ "alt_scancode_esc", "scesa", "S8", CAP_TYPE_STR, &TIS.TI_scesa },
{ "enter_horizontal_hl_mode", "ehhlm", "Xh", CAP_TYPE_STR, &TIS.TI_ehhlm },
{ "enter_left_hl_mode", "elhlm", "Xl", CAP_TYPE_STR, &TIS.TI_elhlm },
{ "enter_low_hl_mode", "elohlm", "Xo", CAP_TYPE_STR, &TIS.TI_elohlm },
{ "enter_right_hl_mode", "erhlm", "Xr", CAP_TYPE_STR, &TIS.TI_erhlm },
{ "enter_top_hl_mode", "ethlm", "Xt", CAP_TYPE_STR, &TIS.TI_ethlm },
{ "enter_vertical_hl_mode", "evhlm", "Xv", CAP_TYPE_STR, &TIS.TI_evhlm },
{ "set_a_attributes", "sgr1", "sA", CAP_TYPE_STR, &TIS.TI_sgr1 },
{ "set_pglen_inch", "slength", "sL", CAP_TYPE_STR, &TIS.TI_slength },
{ "termcap_init2", "OTi2", "i2", CAP_TYPE_STR, &TIS.TI_OTi2 },
{ "termcap_reset", "OTrs", "rs", CAP_TYPE_STR, &TIS.TI_OTrs },
{ "magic_cookie_glitch_ul", "OTug", "ug", CAP_TYPE_INT, &TIS.TI_OTug },
{ "backspaces_with_bs", "OTbs", "bs", CAP_TYPE_BOOL, &TIS.TI_OTbs },
{ "crt_no_scrolling", "OTns", "ns", CAP_TYPE_BOOL, &TIS.TI_OTns },
{ "no_correctly_working_cr", "OTnc", "nc", CAP_TYPE_BOOL, &TIS.TI_OTnc },
{ "carriage_return_delay", "OTdC", "dC", CAP_TYPE_INT, &TIS.TI_OTdC },
{ "new_line_delay", "OTdN", "dN", CAP_TYPE_INT, &TIS.TI_OTdN },
{ "linefeed_if_not_lf", "OTnl", "nl", CAP_TYPE_STR, &TIS.TI_OTnl },
{ "backspace_if_not_bs", "OTbc", "bc", CAP_TYPE_STR, &TIS.TI_OTbc },
{ "gnu_has_meta_key", "OTMT", "MT", CAP_TYPE_BOOL, &TIS.TI_OTMT },
{ "linefeed_is_newline", "OTNL", "NL", CAP_TYPE_BOOL, &TIS.TI_OTNL },
{ "backspace_delay", "OTdB", "dB", CAP_TYPE_INT, &TIS.TI_OTdB },
{ "horizontal_tab_delay", "OTdT", "dT", CAP_TYPE_INT, &TIS.TI_OTdT },
{ "number_of_function_keys", "OTkn", "kn", CAP_TYPE_INT, &TIS.TI_OTkn },
{ "other_non_function_keys", "OTko", "ko", CAP_TYPE_STR, &TIS.TI_OTko },
{ "arrow_key_map", "OTma", "ma", CAP_TYPE_STR, &TIS.TI_OTma },
{ "has_hardware_tabs", "OTpt", "pt", CAP_TYPE_BOOL, &TIS.TI_OTpt },
{ "return_does_clr_eol", "OTxr", "xr", CAP_TYPE_BOOL, &TIS.TI_OTxr },
{ "acs_ulcorner", "OTG2", "G2", CAP_TYPE_STR, &TIS.TI_OTG2 },
{ "acs_llcorner", "OTG3", "G3", CAP_TYPE_STR, &TIS.TI_OTG3 },
{ "acs_urcorner", "OTG1", "G1", CAP_TYPE_STR, &TIS.TI_OTG1 },
{ "acs_lrcorner", "OTG4", "G4", CAP_TYPE_STR, &TIS.TI_OTG4 },
{ "acs_ltee", "OTGR", "GR", CAP_TYPE_STR, &TIS.TI_OTGR },
{ "acs_rtee", "OTGL", "GL", CAP_TYPE_STR, &TIS.TI_OTGL },
{ "acs_btee", "OTGU", "GU", CAP_TYPE_STR, &TIS.TI_OTGU },
{ "acs_ttee", "OTGD", "GD", CAP_TYPE_STR, &TIS.TI_OTGD },
{ "acs_hline", "OTGH", "GH", CAP_TYPE_STR, &TIS.TI_OTGH },
{ "acs_vline", "OTGV", "GV", CAP_TYPE_STR, &TIS.TI_OTGV },
{ "acs_plus", "OTGC", "GC", CAP_TYPE_STR, &TIS.TI_OTGC },
{ "memory_lock", "meml", "ml", CAP_TYPE_STR, &TIS.TI_meml },
{ "memory_unlock", "memu", "mu", CAP_TYPE_STR, &TIS.TI_memu },
{ "box_chars_1", "box1", "bx", CAP_TYPE_STR, &TIS.TI_box1 },
};
static const int numcaps = sizeof tcaps / sizeof tcaps[0];
struct term_struct *current_term = &TIS;
int meta_mode = 2;
int can_color = 0;
int need_redraw = 0;
static int term_echo_flag = 1;
#if !defined(__EMX__) && !defined(WINNT) && !defined(GUI)
#ifndef HAVE_TERMINFO
static char termcap[2048]; /* bigger than we need, just in case */
#endif
static char termcap2[2048]; /* bigger than we need, just in case */
#endif
/*
* Any GUI system modules must be included here to make the GUI support
* routines accessible to the rest of BitchX.
*/
#ifndef WTERM_C
#ifdef __EMXPM__
#include "PMBitchX.c"
#elif defined(GTK)
#include "gtkbitchx.c"
#elif defined(WIN32)
#include "winbitchx.c"
#endif
#endif
/*
* term_echo: if 0, echo is turned off (all characters appear as blanks), if
* non-zero, all is normal. The function returns the old value of the
* term_echo_flag
*/
int term_echo (int flag)
{
int echo;
echo = term_echo_flag;
term_echo_flag = flag;
return (echo);
}
/*
* term_putchar: puts a character to the screen, and displays control
* characters as inverse video uppercase letters. NOTE: Don't use this to
* display termcap control sequences! It won't work!
*
* Um... well, it will work if DISPLAY_ANSI_VAR is set to on... (hop)
*/
void term_putchar (unsigned char c)
{
if (!term_echo_flag)
{
putchar_x(' ');
return;
}
/* Sheer, raving paranoia */
#ifndef __EMX__
if (!(newb.c_cflag & CS8) && (c & 0x80))
c &= ~0x80;
#endif
/*
* This mangles all the unprintable control characters
* except for the escape character. This will only support
* escape sequences that use ESC + any normal, printable
* characters (this is an assumption throughout the program).
* While you can use a non-vt100 emulation, the output will
* probably be mangled in several places.
*/
if (c < 0x20 || c == 0x9b) /* all ctl chars except ESC */
{
term_standout_on();
putchar_x((c | 0x40) & 0x7f); /* Convert to printable */
term_standout_off();
}
else if (c == 0x7f) /* delete char */
{
term_standout_on();
putchar_x('?');
term_standout_off();
}
else
putchar_x(c);
}
/*
* term_reset: sets terminal attributed back to what they were before the
* program started
*/
void term_reset (void)
{
if (current_term->TI_csr)
tputs_x(tparm2(current_term->TI_csr, 0, current_term->li - 1));
term_gotoxy(0, current_term->li - 1);
#if use_alt_screen
if (current_term->TI_rmcup)
tputs_x(current_term->TI_rmcup);
#endif
#if use_automargins
if (current_term->TI_am && current_term->TI_smam)
tputs_x(current_term->TI_smam);
#endif
term_flush();
tcsetattr(tty_des, TCSADRAIN, &oldb);
}
void term_reset2 (void)
{
term_flush();
tcsetattr(tty_des, TCSADRAIN, &oldb);
}
/*
* term_cont: sets the terminal back to IRCII stuff when it is restarted
* after a SIGSTOP. Somewhere, this must be used in a signal() call
*/
SIGNAL_HANDLER(term_cont)
{
extern int foreground;
use_input = foreground = (tcgetpgrp(0) == getpgrp());
if (foreground)
{
#if use_alt_screen
if (current_term->TI_smcup)
tputs_x(current_term->TI_smcup);
#endif
#if use_automargins
if (current_term->TI_rmam)
tputs_x(current_term->TI_rmam);
#endif
need_redraw = 1;
tcsetattr(tty_des, TCSADRAIN, &newb);
}
}
#if !defined(STERM_C)
/*
* term_pause: sets terminal back to pre-program days, then SIGSTOPs itself.
*/
extern void term_pause (char unused, char *not_used)
{
#ifndef PUBLIC_ACCESS
#ifdef WINNT
char *shell;
DWORD dwmode;
HANDLE hstdin=GetStdHandle(STD_INPUT_HANDLE);
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si);
if (!(shell = get_string_var(SHELL_VAR)))
{
if (gdwPlatform == VER_PLATFORM_WIN32_WINDOWS)
shell = "command.com";
else
shell = "cmd.exe";
}
if (!(GetConsoleMode(hstdin,&dwmode)))
return;
if (!SetConsoleMode(hstdin, dwmode | ((ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT) & ~ENABLE_WINDOW_INPUT)))
return;
if(!CreateProcess(NULL, shell, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) )
return;
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess,INFINITE);
CloseHandle(pi.hProcess);
if (!SetConsoleMode(hstdin, dwmode ) )
return;
refresh_screen(0,NULL);
#else
term_reset();
#ifndef __EMX__
kill(getpid(), SIGSTOP);
#endif
#endif
#endif /* PUBLIC_ACCESS */
}
#endif /* STERM_C */
#endif /* NOT IN WTERM_C */
/*
* term_init: does all terminal initialization... reads termcap info, sets
* the terminal to CBREAK, no ECHO mode. Chooses the best of the terminal
* attributes to use .. for the version of this function that is called for
* wserv, we set the termial to RAW, no ECHO, so that all the signals are
* ignored.. fixes quite a few problems... -phone, jan 1993..
*/
int termfeatures = 0;
int term_init (char *term)
{
#ifndef WTERM_C
int i;
int desired;
char *termcap2_ptr = termcap2;
#if !defined(__EMX__) && !defined(WINNT) && !defined(GUI)
memset(current_term, 0, sizeof(struct term_struct));
if (dumb_mode)
ircpanic("term_init called in dumb_mode");
*termcap2 = 0;
if (!term && !(term = getenv("TERM")))
{
fprintf(stderr, "\n");
fprintf(stderr, "You do not have a TERM environment variable.\n");
fprintf(stderr, "So we'll be running in dumb mode...\n");
return -1;
}
#ifdef WANT_DETACH
else if (!already_detached)
fprintf(stdout, "Using terminal type [%s]\n", term);
#endif
#ifdef HAVE_TERMINFO
if (setupterm(NULL, 1, &i) == ERR)
{
fprintf(stderr, "setupterm failed: %d\n", i);
fprintf(stderr, "So we'll be running in dumb mode...\n");
return -1;
}
#else
if (tgetent(termcap, term) < 1)
{
fprintf(stderr, "\n");
fprintf(stderr, "Your current TERM setting (%s) does not have a termcap entry.\n", term);
fprintf(stderr, "So we'll be running in dumb mode...\n");
return -1;
}
#endif
for (i = 0; i < numcaps; i++)
{
if (tcaps[i].type == CAP_TYPE_INT)
{
*(int *)tcaps[i].ptr = Tgetnum(tcaps[i]);
}
else if (tcaps[i].type == CAP_TYPE_BOOL)
{
*(int *)tcaps[i].ptr = Tgetflag(tcaps[i]);
}
else
{
char *cval = Tgetstr(tcaps[i], termcap2_ptr);
if (cval == (char *) -1)
cval = NULL;
*(char **)tcaps[i].ptr = cval;
}
}
if (!current_term->TI_cols)
current_term->TI_cols = 79;
if (!current_term->TI_lines)
current_term->TI_lines = 24;
current_term->li = current_term->TI_lines;
current_term->co = current_term->TI_cols;
if (!current_term->TI_nel)
current_term->TI_nel = "\n";
if (!current_term->TI_cr)
current_term->TI_cr = "\r";
current_term->TI_normal[0] = 0;
if (current_term->TI_sgr0)
{
strcat(current_term->TI_normal, current_term->TI_sgr0);
}
if (current_term->TI_rmso)
{
if (current_term->TI_sgr0 && strcmp(current_term->TI_rmso, current_term->TI_sgr0))
strcat(current_term->TI_normal, current_term->TI_rmso);
}
if (current_term->TI_rmul)
{
if (current_term->TI_sgr0 && strcmp(current_term->TI_rmul, current_term->TI_sgr0))
strcat (current_term->TI_normal, current_term->TI_rmul);
}
#else /* !defined(__EMX__) && !defined(WINNT) && !defined(GUI) */
#if defined(WINNT) && !defined(GUI)
CONSOLE_SCREEN_BUFFER_INFO scrbuf;
HANDLE hinput =GetStdHandle(STD_INPUT_HANDLE);
DWORD dwmode;
OSVERSIONINFO osver;
ghstdout = GetStdHandle(STD_OUTPUT_HANDLE);
if(!GetConsoleScreenBufferInfo(ghstdout, &gscrbuf) )
{
fprintf(stderr,"Error from getconsolebufinfo %d\n",GetLastError());
abort();
}
GetConsoleMode(hinput,&dwmode);
SetConsoleMode(hinput,dwmode & (~(ENABLE_LINE_INPUT |ENABLE_ECHO_INPUT
| ENABLE_PROCESSED_INPUT)| ENABLE_WINDOW_INPUT/* | ENABLE_WRAP_AT_EOL_OUTPUT*/)
);
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osver);
gdwPlatform = osver.dwPlatformId;
GetConsoleCursorInfo(hinput, &gcursbuf);
GetConsoleScreenBufferInfo(ghstdout, &scrbuf);
current_term->TI_lines = scrbuf.srWindow.Bottom - scrbuf.srWindow.Top + 1;
current_term->TI_cols = scrbuf.srWindow.Right - scrbuf.srWindow.Left + 1;
memset(current_term, 0, sizeof(struct term_struct));
current_term->li = current_term->TI_lines;
current_term->co = current_term->TI_cols - 1;
#elif defined(GUI)
memset(current_term, 0, sizeof(struct term_struct));
gui_init();
#else
vmode.cb = sizeof(VIOMODEINFO);
VioGetMode(&vmode, 0);
default_pair[0] = ' ';
default_pair[1] = 7;
memset(current_term, 0, sizeof(struct term_struct));
current_term->TI_lines = vmode.row;
current_term->TI_cols = vmode.col;
current_term->li = current_term->TI_lines;
current_term->co = current_term->TI_cols;
#endif
current_term->TI_cup = strdup("\e[%i%d;%dH");
current_term->TI_cub1 = strdup("\e[D");
current_term->TI_clear = strdup("\e[H\e[2J");
current_term->TI_el = strdup("\e[K");
current_term->TI_mrcup = strdup("\e[%i%d;%dH");
current_term->TI_cub = strdup("\e[D");
current_term->TI_cuf = strdup("\e[C");
current_term->TI_cuf1 = strdup("\e[C");
current_term->TI_smso = strdup("\e[7m");
current_term->TI_rmso = strdup("\e[0m");
#ifdef GTK
current_term->TI_smul = strdup("\e[4m");
current_term->TI_rmul = strdup("\e[24m");
#else
current_term->TI_smul = strdup("\e[1;34m");
current_term->TI_rmul = strdup("\e[0;37m");
#endif
current_term->TI_bold = strdup("\e[1;37m");
current_term->TI_sgr0 = strdup("\e[0;37m");
current_term->TI_blink = strdup("\e[5m");
current_term->TI_normal[0]=0;
#ifdef GTK
current_term->TI_csr = strdup("\e[%i%p1%d;%p2%dr");
#endif
current_term->TI_ri = strdup("\eM");
current_term->TI_ind = strdup("\n");
current_term->TI_il = strdup("\e[%p1%dL");
current_term->TI_il1 = strdup("\e[L");
current_term->TI_dl = strdup("\e[%p1%dM");
current_term->TI_dl1 = strdup("\e[M");
strcat(current_term->TI_normal, current_term->TI_sgr0);
strcat(current_term->TI_normal, current_term->TI_rmso);
current_term->TI_cr = strdup("\r");
current_term->TI_nel = strdup("\n");
current_term->TI_bel = strdup("\007");
current_term->TI_cub = strdup("\010");
#ifdef __EMXPM__
current_term->TI_kend = strdup("\eO");
current_term->TI_khome = strdup("\eG");
current_term->TI_knp = strdup("\eQ");
current_term->TI_kpp = strdup("\eI");
current_term->TI_kcuf1 = strdup("\eM");
current_term->TI_kcub1 = strdup("\eK");
current_term->TI_kcuu1 = strdup("\eH");
current_term->TI_kcud1 = strdup("\eP");
#else
current_term->TI_kend = strdup("\e[4~");
current_term->TI_khome = strdup("\e[1~");
current_term->TI_knp = strdup("\e[6~");
current_term->TI_kpp = strdup("\e[5~");
current_term->TI_kcuf1 = strdup("\e[C");
current_term->TI_kcub1 = strdup("\e[D");
current_term->TI_kcuu1 = strdup("\e[A");
current_term->TI_kcud1 = strdup("\e[B");
#endif
#endif
/*
* Finally set up the current_term->TI_sgrstrs array. Clean it out first...
*/
for (i = 0; i < TERM_SGR_MAXVAL; i++)
current_term->TI_sgrstrs[i] = empty_string;
if (current_term->TI_bold)
current_term->TI_sgrstrs[TERM_SGR_BOLD_ON-1] = current_term->TI_bold;
if (current_term->TI_sgr0)
{
current_term->TI_sgrstrs[TERM_SGR_BOLD_OFF - 1] = current_term->TI_sgr0;
current_term->TI_sgrstrs[TERM_SGR_BLINK_OFF - 1] = current_term->TI_sgr0;
}
if (current_term->TI_blink)
current_term->TI_sgrstrs[TERM_SGR_BLINK_ON - 1] = current_term->TI_blink;
if (current_term->TI_smul)
current_term->TI_sgrstrs[TERM_SGR_UNDL_ON - 1] = current_term->TI_smul;
if (current_term->TI_rmul)
current_term->TI_sgrstrs[TERM_SGR_UNDL_OFF - 1] = current_term->TI_rmul;
if (current_term->TI_smso)
current_term->TI_sgrstrs[TERM_SGR_REV_ON - 1] = current_term->TI_smso;
if (current_term->TI_rmso)
current_term->TI_sgrstrs[TERM_SGR_REV_OFF - 1] = current_term->TI_rmso;
if (current_term->TI_smacs)
current_term->TI_sgrstrs[TERM_SGR_ALTCHAR_ON - 1] = current_term->TI_smacs;
if (current_term->TI_rmacs)
current_term->TI_sgrstrs[TERM_SGR_ALTCHAR_OFF - 1] = current_term->TI_rmacs;
if (current_term->TI_normal[0])
{
current_term->TI_sgrstrs[TERM_SGR_NORMAL - 1] = current_term->TI_normal;
current_term->TI_sgrstrs[TERM_SGR_RESET - 1] = current_term->TI_normal;
}
/*
* Now figure out whether or not this terminal is "capable enough"
* for the client. This is a rather complicated set of tests, as
* we have many ways of doing the same thing.
* To keep the set of tests easier, we set up a bitfield integer
* which will have the desired capabilities added to it. If after
* all the checks we don't have the desired mask, we don't have a
* capable enough terminal.
*/
desired = TERM_CAN_CUP | TERM_CAN_CLEAR | TERM_CAN_CLREOL |
TERM_CAN_RIGHT | TERM_CAN_LEFT | TERM_CAN_SCROLL;
termfeatures = 0;
if (current_term->TI_cup)
termfeatures |= TERM_CAN_CUP;
if (current_term->TI_hpa && current_term->TI_vpa)
termfeatures |= TERM_CAN_CUP;
if (current_term->TI_clear)
termfeatures |= TERM_CAN_CLEAR;
if (current_term->TI_ed)
termfeatures |= TERM_CAN_CLEAR;
if (current_term->TI_dl || current_term->TI_dl1)
termfeatures |= TERM_CAN_CLEAR;
if (current_term->TI_il || current_term->TI_il1)
termfeatures |= TERM_CAN_CLEAR;
if (current_term->TI_el)
termfeatures |= TERM_CAN_CLREOL;
if (current_term->TI_cub || current_term->TI_mrcup || current_term->TI_cub1 || current_term->TI_kbs)
termfeatures |= TERM_CAN_LEFT;
if (current_term->TI_cuf || current_term->TI_cuf1 || current_term->TI_mrcup)
termfeatures |= TERM_CAN_RIGHT;
if (current_term->TI_dch || current_term->TI_dch1)
termfeatures |= TERM_CAN_DELETE;
if (current_term->TI_ich || current_term->TI_ich1)
termfeatures |= TERM_CAN_INSERT;
if (current_term->TI_rep)
termfeatures |= TERM_CAN_REPEAT;
if (current_term->TI_csr && (current_term->TI_ri || current_term->TI_rin) && (current_term->TI_ind || current_term->TI_indn))
termfeatures |= TERM_CAN_SCROLL;
if (current_term->TI_wind && (current_term->TI_ri || current_term->TI_rin) && (current_term->TI_ind || current_term->TI_indn))
termfeatures |= TERM_CAN_SCROLL;
if ((current_term->TI_il || current_term->TI_il1) && (current_term->TI_dl || current_term->TI_dl1))
termfeatures |= TERM_CAN_SCROLL;
if (current_term->TI_bold && current_term->TI_sgr0)
termfeatures |= TERM_CAN_BOLD;
if (current_term->TI_blink && current_term->TI_sgr0)
termfeatures |= TERM_CAN_BLINK;
if (current_term->TI_smul && current_term->TI_rmul)
termfeatures |= TERM_CAN_UNDL;
if (current_term->TI_smso && current_term->TI_rmso)
termfeatures |= TERM_CAN_REVERSE;
if (current_term->TI_dispc)
termfeatures |= TERM_CAN_GCHAR;
if ((current_term->TI_setf && current_term->TI_setb) || (current_term->TI_setaf && current_term->TI_setab))
termfeatures |= TERM_CAN_COLOR;
#if !defined(__EMX__) && !defined(WINNT) && !defined(GUI)
if ((termfeatures & desired) != desired)
{
fprintf(stderr, "\nYour terminal (%s) cannot run IRC II in full screen mode.\n", term);
fprintf(stderr, "The following features are missing from your TERM setting.\n");
if (!(termfeatures & TERM_CAN_CUP))
fprintf (stderr, "\tCursor movement\n");
if (!(termfeatures & TERM_CAN_CLEAR))
fprintf(stderr, "\tClear screen\n");
if (!(termfeatures & TERM_CAN_CLREOL))
fprintf(stderr, "\tClear to end-of-line\n");
if (!(termfeatures & TERM_CAN_RIGHT))
fprintf(stderr, "\tCursor right\n");
if (!(termfeatures & TERM_CAN_LEFT))
fprintf(stderr, "\tCursor left\n");
if (!(termfeatures & TERM_CAN_SCROLL))
fprintf(stderr, "\tScrolling\n");
fprintf(stderr, "So we'll be running in dumb mode...\n");
return -1;
}
#endif
if (!current_term->TI_cub1)
{
if (current_term->TI_kbs)
current_term->TI_cub1 = current_term->TI_kbs;
else
current_term->TI_cub1 = "\b";
}
if (!current_term->TI_bel)
current_term->TI_bel = "\007";
/*
* Default to no colors. (ick)
*/
for (i = 0; i < 16; i++)
current_term->TI_forecolors[i] = current_term->TI_backcolors[i] = empty_string;
/*
* Set up colors.
* Absolute fallbacks are for ansi-type colors
*/
for (i = 0; i < 16; i++)
{
char cbuf[128];
cbuf[0] = '\0';
if (i >= 8)
strcpy(cbuf, current_term->TI_sgrstrs[TERM_SGR_BOLD_ON-1]);
if (current_term->TI_setaf)
strcat(cbuf, tparm2(current_term->TI_setaf, i & 0x07, 0));
else if (current_term->TI_setf)
strcat(cbuf, tparm2(current_term->TI_setf, i & 0x07, 0));
else if (i >= 8)
sprintf(cbuf, "\033[1;%dm", (i & 0x07) + 30);
else
sprintf(cbuf, "\033[%dm", (i & 0x07) + 30);
current_term->TI_forecolors[i] = m_strdup(cbuf);
}
for (i = 0; i < 16; i++)
{
char cbuf[128];
cbuf[0] = '\0';
if (i >= 8)
strcpy(cbuf, current_term->TI_sgrstrs[TERM_SGR_BLINK_ON - 1]);
if (current_term->TI_setab)
strcat(cbuf, tparm2(current_term->TI_setab, i & 0x07, 0));
else if (current_term->TI_setb)
strcat(cbuf, tparm2(current_term->TI_setb, i & 0x07, 0));
else if (i >= 8)
sprintf(cbuf, "\033[1;%dm", (i & 0x07) + 40);
else
sprintf(cbuf, "\033[%dm", (i & 0x07) + 40);
current_term->TI_backcolors[i] = m_strdup(cbuf);
}
#endif /* NOT IN WTERM_C */
tty_des = 0;
#ifndef GTK
reinit_term(tty_des);
#endif
return 0;
}
void reinit_term(int tty)
{
/* Set up the terminal discipline */
tcgetattr(tty, &oldb);
newb = oldb;
newb.c_lflag &= ~(ICANON | ECHO); /* set equ. of CBREAK, no ECHO */
newb.c_cc[VMIN] = 1; /* read() satified after 1 char */
newb.c_cc[VTIME] = 0; /* No timer */
# if !defined(_POSIX_VDISABLE)
# if defined(HAVE_FPATHCONF)
# define _POSIX_VDISABLE fpathconf(tty, _PC_VDISABLE)
# else
# define _POSIX_VDISABLE 0
# endif
# endif
newb.c_cc[VQUIT] = _POSIX_VDISABLE;
# ifdef VDSUSP
newb.c_cc[VDSUSP] = _POSIX_VDISABLE;
# endif
# ifdef VSUSP
newb.c_cc[VSUSP] = _POSIX_VDISABLE;
# endif
#ifndef WTERM_C
if (!use_flow_control)
newb.c_iflag &= ~IXON; /* No XON/XOFF */
/* Ugh. =) This is annoying! */
#if use_alt_screen
if (current_term->TI_smcup)
tputs_x(current_term->TI_smcup);
#endif
#if use_automargins
if (current_term->TI_rmam)
tputs_x(current_term->TI_rmam);
#endif
#endif
tcsetattr(tty, TCSADRAIN, &newb);
tty_des = tty;
return;
}
#ifndef WTERM_C
void tty_dup(int tty)
{
close (tty_des);
dup2(tty, tty_des);
}
/* These force the default terminal size, and are used when reattached by scr-bx.
They are then used as the fallback by term_resize(). */
void reset_lines(int nlines)
{
current_term->TI_lines = nlines;
}
void reset_cols(int cols)
{
current_term->TI_cols = cols;
}
/*
* term_resize: gets the terminal height and width. Trys to get the info
* from the tty driver about size, if it can't... uses the termcap values. If
* the terminal size has changed since last time term_resize() has been
* called, 1 is returned. If it is unchanged, 0 is returned.
*/
int term_resize (void)
{
#ifndef GUI
static int old_li = -1,
old_co = -1;
# if defined (TIOCGWINSZ)
{
struct winsize window;
if (ioctl(tty_des, TIOCGWINSZ, &window) < 0)
{
current_term->li = current_term->TI_lines;
current_term->co = current_term->TI_cols;
}
else
{
if ((current_term->li = window.ws_row) == 0)
current_term->li = current_term->TI_lines;
if ((current_term->co = window.ws_col) == 0)
current_term->co = current_term->TI_cols;
}
}
# else
{
current_term->li = current_term->TI_lines;
current_term->co = current_term->TI_cols;
}
# endif
#if use_automargins
if (!current_term->TI_am || !current_term->TI_rmam)
{
current_term->co--;
}
#else
current_term->co--;
#endif
if ((old_li != current_term->li) || (old_co != current_term->co))
{
old_li = current_term->li;
old_co = current_term->co;
if (main_screen)
{
main_screen->li = current_term->li;
main_screen->co = current_term->co;
}
return (1);
}
#endif /* GUI */
return (0);
}
/* term_CE_clear_to_eol(): the clear to eol function, right? */
void term_clreol (void)
{
#ifdef GUI
gui_clreol();
#else
tputs_x(current_term->TI_el);
#endif
return;
}
/* Set the cursor position */
void term_gotoxy (int col, int row)
{
#if defined(__EMX__) && !defined(GUI)
term_flush();
VioSetCurPos(row,col,0);
#elif defined(GUI)
gui_gotoxy(col, row);
#else
if (current_term->TI_cup)
tputs_x(tparm2(current_term->TI_cup, row, col));
else
{
tputs_x(tparm1(current_term->TI_hpa, col));
tputs_x(tparm1(current_term->TI_vpa, row));
}
#endif
}
/* A no-brainer. Clear the screen. */
void term_clear_screen(void)
{
#if defined(__EMX__) && !defined(__EMXX__) && !defined(GUI)
VioScrollUp(0, 0, -1, -1, -1, &default_pair, vio_screen);
#elif defined(GUI)
gui_clrscr();
#else
int i;
/* This is called from scr-bx with output_screen == NULL */
const long li = output_screen ? output_screen->li : current_term->li;
/* We have a specific cap for clearing the screen */
if (current_term->TI_clear)
{
tputs_x(current_term->TI_clear);
term_gotoxy (0, 0);
return;
}
term_gotoxy (0, 0);
/* We can clear by doing an erase-to-end-of-display */
if (current_term->TI_ed)
{
tputs_x (current_term->TI_ed);
return;
}
/* We can also clear by deleteing lines ... */
else if (current_term->TI_dl)
{
tputs_x(tparm1(current_term->TI_dl, li));
return;
}
/* ... in this case one line at a time */
else if (current_term->TI_dl1)
{
for (i = 0; i < li; i++)
tputs_x(current_term->TI_dl1);
return;
}
/* As a last resort we can insert lines ... */
else if (current_term->TI_il)
{
tputs_x(tparm1(current_term->TI_il, li));
term_gotoxy (0, 0);
return;
}
/* ... one line at a time */
else if (current_term->TI_il1)
{
for (i = 0; i < li; i++)
tputs_x(current_term->TI_il1);
term_gotoxy (0, 0);
}
#endif
}
/*
* Move the cursor NUM spaces to the left, non-destruvtively if we can.
*/
void term_left (int num)
{
#ifdef GUI
gui_left(num);
#else
if (current_term->TI_cub)
tputs_x(tparm1(current_term->TI_cub, num));
else if (current_term->TI_mrcup)
tputs_x(tparm2(current_term->TI_mrcup, -num, 0));
else if (current_term->TI_cub1)
while (num--)
tputs_x(current_term->TI_cub1);
else if (current_term->TI_kbs)
while (num--)
tputs_x(current_term->TI_kbs);
#endif
}
/*
* Move the cursor NUM spaces to the right
*/
void term_right (int num)
{
#ifdef GUI
gui_right(num);
#else
if (current_term->TI_cuf)
tputs_x(tparm1(current_term->TI_cuf, num));
else if (current_term->TI_mrcup)
tputs_x(tparm2(current_term->TI_mrcup, num, 0));
else if (current_term->TI_cuf1)
while (num--)
tputs_x(current_term->TI_cuf1);
#endif
}
/*
* term_delete (int num)
* Deletes NUM characters at the current position
*/
void term_delete (int num)
{
if (current_term->TI_smdc)
tputs_x(current_term->TI_smdc);
if (current_term->TI_dch)
tputs_x(tparm1(current_term->TI_dch, num));
else if (current_term->TI_dch1)
while (num--)
tputs_x (current_term->TI_dch1);
if (current_term->TI_rmdc)
tputs_x (current_term->TI_rmdc);
}
/*
* Insert character C at the curent cursor position.
*/
void term_insert (unsigned char c)
{
if (current_term->TI_smir)
tputs_x (current_term->TI_smir);
else if (current_term->TI_ich1)
tputs_x (current_term->TI_ich1);
else if (current_term->TI_ich)
tputs_x(tparm1(current_term->TI_ich, 1));
term_putchar (c);
if (current_term->TI_rmir)
tputs_x(current_term->TI_rmir);
}
/*
* Repeat the character C REP times in the most efficient way.
*/
void term_repeat (unsigned char c, int rep)
{
if (current_term->TI_rep)
tputs_x(tparm2(current_term->TI_rep, (int)c, rep));
else
while (rep--)
putchar_x (c);
}
/*
* Scroll the screen N lines between lines TOP and BOT.
*/
void term_scroll (int top, int bot, int n)
{
#ifdef GUI
gui_scroll(top, bot, n);
#else
int i,oneshot=0,rn,sr,er;
char thing[128], final[128], start[128];
#ifdef __EMX__
pair[0] = ' '; pair[1] = 7;
if (n > 0) VioScrollUp(top, 0, bot, output_screen->co, n, (PBYTE)&pair, (HVIO) vio_screen);
else if (n < 0) { n = -n; VioScrollDn(top, 0, bot, output_screen->co, n, (PBYTE)&pair, (HVIO) vio_screen); }
#ifndef __EMXX__
return;
#endif
#elif defined(WINNT)
/* It seems that Windows 95/98 has a problem with scrolling
when you set the scroll area to something other than the
default, using current_term->TI_csr, so this API call will scroll the
text instead. */
SMALL_RECT src;
COORD dest;
CHAR_INFO chr;
src.Left = gscrbuf.srWindow.Left;
src.Top = top+n;
src.Right = gscrbuf.srWindow.Right;
src.Bottom = bot;
dest.X = 0;
dest.Y = top;
chr.Char.AsciiChar = ' ';
chr.Attributes = 0;
ScrollConsoleScreenBuffer(ghstdout, &src, NULL, dest, &chr);
return;
#endif
/* Some basic sanity checks */
if (n == 0 || top == bot || bot < top)
return;
sr = er = 0;
final[0] = start[0] = thing[0] = 0;
if (n < 0)
rn = -n;
else
rn = n;
/*
* First thing we try to do is set the scrolling region on a
* line granularity. In order to do this, we need to be able
* to have termcap 'cs', and as well, we need to have 'sr' if
* we're scrolling down, and 'sf' if we're scrolling up.
*/
if (current_term->TI_csr && (current_term->TI_ri || current_term->TI_rin) && (current_term->TI_ind || current_term->TI_indn))
{
/*
* Previously there was a test to see if the entire scrolling
* region was the full screen. That test *always* fails,
* because we never scroll the bottom line of the screen.
*/
strcpy(start, tparm2(current_term->TI_csr, top, bot));
strcpy(final, tparm2(current_term->TI_csr, 0, output_screen->li-1));
if (n > 0)
{
sr = bot;
er = top;
if (current_term->TI_indn)
{
oneshot = 1;
strcpy(thing, tparm2(current_term->TI_indn, rn, rn));
}
else
strcpy(thing, current_term->TI_ind);
}
else
{
sr = top;
er = bot;
if (current_term->TI_rin)
{
oneshot = 1;
strcpy(thing, tparm2(current_term->TI_rin, rn, rn));
}
else
strcpy(thing, current_term->TI_ri);
}
}
else if (current_term->TI_wind && (current_term->TI_ri || current_term->TI_rin) && (current_term->TI_ind || current_term->TI_indn))
{
strcpy(start, tparm4(current_term->TI_wind, top, bot, 0, output_screen->co-1));
strcpy(final, tparm4(current_term->TI_wind, 0, output_screen->li-1, 0, output_screen->co-1));
if (n > 0)
{
sr = bot;
er = top;
if (current_term->TI_indn)
{
oneshot = 1;
strcpy(thing, tparm2(current_term->TI_indn, rn, rn));
}
else
strcpy(thing, current_term->TI_ind);
}
else
{
sr = top;
er = bot;
if (current_term->TI_rin)
{
oneshot = 1;
strcpy(thing, tparm2(current_term->TI_rin, rn, rn));
}
else
strcpy (thing, current_term->TI_ri);
}
}
else if ((current_term->TI_il || current_term->TI_il1) && (current_term->TI_dl || current_term->TI_dl1))
{
if (n > 0)
{
sr = top;
er = bot;
if (current_term->TI_dl)
{
oneshot = 1;
strcpy(thing, tparm2(current_term->TI_dl, rn, rn));
}
else
strcpy (thing, current_term->TI_dl1);
if (current_term->TI_il)
{
oneshot = 1;
strcpy(final, tparm2(current_term->TI_il, rn, rn));
}
else
strcpy(final, current_term->TI_il1);
}
else
{
sr = bot;
er = top;
if (current_term->TI_il)
{
oneshot = 1;
strcpy(thing, tparm2(current_term->TI_il, rn, rn));
}
else
strcpy (thing, current_term->TI_il1);
if (current_term->TI_dl)
{
oneshot = 1;
strcpy(final, tparm2(current_term->TI_dl, rn, rn));
}
else
strcpy(final, current_term->TI_dl1);
}
}
if (!thing[0])
return;
/* Do the actual work here */
if (start[0])
tputs_x (start);
term_gotoxy (0, sr);
if (oneshot)
tputs_x (thing);
else
{
for (i = 0; i < rn; i++)
tputs_x(thing);
}
term_gotoxy (0, er);
if (final[0])
tputs_x(final);
#endif
}
/*
* term_getsgr(int opt, int fore, int back)
* Return the string required to set the given mode. OPT defines what
* we really want it to do. It can have these values:
* TERM_SGR_BOLD_ON - turn bold mode on
* TERM_SGR_BOLD_OFF - turn bold mode off
* TERM_SGR_BLINK_ON - turn blink mode on
* TERM_SGR_BLINK_OFF - turn blink mode off
* TERM_SGR_UNDL_ON - turn underline mode on
* TERM_SGR_UNDL_OFF - turn underline mode off
* TERM_SGR_REV_ON - turn reverse video on
* TERM_SGR_REV_OFF - turn reverse video off
* TERM_SGR_NORMAL - turn all attributes off
* TERM_SGR_RESET - all attributes off and back to default colors
* TERM_SGR_FOREGROUND - set foreground color
* TERM_SGR_BACKGROUND - set background color
* TERM_SGR_COLORS - set foreground and background colors
* TERM_SGR_GCHAR - print graphics character
*
* The colors are defined as:
* 0 - black
* 1 - red
* 2 - green
* 3 - brown
* 4 - blue
* 5 - magenta
* 6 - cyan
* 7 - white
* 8 - grey (foreground only)
* 9 - bright red (foreground only)
* 10 - bright green (foreground only)
* 11 - bright yellow (foreground only)
* 12 - bright blue (foreground only)
* 13 - bright magenta (foreground only)
* 14 - bright cyan (foreground only)
* 15 - bright white (foreground only)
*/
char *term_getsgr (int opt, int fore, int back)
{
char *ret = empty_string;
switch (opt)
{
case TERM_SGR_BOLD_ON:
case TERM_SGR_BOLD_OFF:
case TERM_SGR_BLINK_OFF:
case TERM_SGR_BLINK_ON:
case TERM_SGR_UNDL_ON:
case TERM_SGR_UNDL_OFF:
case TERM_SGR_REV_ON:
case TERM_SGR_REV_OFF:
case TERM_SGR_NORMAL:
case TERM_SGR_RESET:
ret = current_term->TI_sgrstrs[opt-1];
break;
case TERM_SGR_FOREGROUND:
ret = current_term->TI_forecolors[fore & 0x0f];
break;
case TERM_SGR_BACKGROUND:
ret = current_term->TI_backcolors[fore & 0x0f];
break;
case TERM_SGR_GCHAR:
if (current_term->TI_dispc)
ret = tparm1(current_term->TI_dispc, fore);
break;
default:
ircpanic ("Unknown option '%d' to term_getsgr", opt);
break;
}
return (ret);
}
extern int term_eight_bit (void)
{
#ifdef GUI
return 1;
#else
if (dumb_mode)
return 1;
return (((newb.c_cflag) & CSIZE) == CS8) ? 1 : 0;
#endif
}
extern void term_beep (void)
{
if (get_int_var(BEEP_VAR))
{
#ifdef __EMX__
DosBeep(1000, 200);
#else
tputs_x(current_term->TI_bel);
term_flush();
#endif
}
}
extern void set_term_eight_bit (int value)
{
if (dumb_mode)
return;
if (value == ON)
{
newb.c_cflag |= CS8;
newb.c_iflag &= ~ISTRIP;
}
else
{
newb.c_cflag &= ~CS8;
newb.c_iflag |= ISTRIP;
}
tcsetattr(tty_des, TCSADRAIN, &newb);
}
void set_meta_8bit (Window *w, char *u, int value)
{
if (dumb_mode)
return;
if (value == 0)
meta_mode = 0;
else if (value == 1)
meta_mode = 1;
else if (value == 2)
meta_mode = (current_term->TI_km == 0 ? 0 : 1);
}
/* control_mangle()
*
* Convert control characters in a string into printable sequences. */
static char *control_mangle(char *text)
{
static char retval[256];
int pos;
if (!text)
{
*retval = 0;
return retval;
}
for (pos = 0; *text && (pos < 254); text++, pos++)
{
if (*text >= 0 && *text < 32)
{
retval[pos++] = '^';
retval[pos] = *text + 64;
}
else if (*text == 127)
{
retval[pos++] = '^';
retval[pos] = '?';
}
else
retval[pos] = *text;
}
retval[pos] = 0;
return retval;
}
/* get_term_capability()
*
* Returns a named terminal capability of the current terminal as a string.
*/
char *get_term_capability(char *name, int querytype, int mangle)
{
static char retval[256];
const char *compare = empty_string;
int x;
const cap2info *t;
for (x = 0; x < numcaps; x++)
{
t = &tcaps[x];
if (querytype == 0)
compare = t->longname;
else if (querytype == 1)
compare = t->iname;
else if (querytype == 2)
compare = t->tname;
if (!strcmp(name, compare))
{
char *control_str;
if (!t->ptr)
return NULL;
switch (t->type)
{
case CAP_TYPE_BOOL:
case CAP_TYPE_INT:
strlcpy(retval, ltoa(*(int *)(t->ptr)), sizeof retval);
return retval;
case CAP_TYPE_STR:
control_str = *(char **)t->ptr;
if (!control_str)
return NULL;
strlcpy(retval,
mangle ? control_mangle(control_str) : control_str,
sizeof retval);
return retval;
}
}
}
return NULL;
}
#endif /* NOT IN WTERM_C */
#if 0
/*
* term.c -- for windows 95/NT
*
* Copyright 1997 Colten Edwards
*
*/
#include "irc.h"
#include "vars.h"
#include "ircterm.h"
#include "window.h"
#include "screen.h"
#include "output.h"
#ifdef TRANSLATE
#include "translat.h"
#endif
#include <windows.h>
char eolbuf[200];
#ifndef WTERM_C
extern char *getenv();
static int term_CE_clear_to_eol (void);
static int term_CS_scroll (int, int, int);
static int term_null_function (void);
/*
* Function variables: each returns 1 if the function is not supported on the
* current term type, otherwise they do their thing and return 0
*/
int (*term_scroll) (int, int, int); /* this is set to the best scroll available */
int (*term_insert) (char); /* this is set to the best insert available */
int (*term_delete) (void); /* this is set to the best delete available */
int (*term_cursor_left) (void); /* this is set to the best left available */
int (*term_cursor_right) (void); /* this is set to the best right available */
int (*term_clear_to_eol) (void); /* this is set... figure it out */
int nt_cursor_right(void);
int nt_cursor_left(void);
int CO = 79,
LI = 24;
HANDLE ghstdout;
CONSOLE_SCREEN_BUFFER_INFO gscrbuf;
CONSOLE_CURSOR_INFO gcursbuf;
DWORD gdwPlatform;
/*
* term_reset_flag: set to true whenever the terminal is reset, thus letter
* the calling program work out what to do
*/
int need_redraw = 0;
static int term_echo_flag = 1;
static int li;
static int co;
static int def_color = 0x07;
int CO, LI;
/*
* term_echo: if 0, echo is turned off (all characters appear as blanks), if
* non-zero, all is normal. The function returns the old value of the
* term_echo_flag
*/
int term_echo (int flag)
{
int echo;
echo = term_echo_flag;
term_echo_flag = flag;
return (echo);
}
void term_flush (void)
{
return;
}
/*
* term_reset: sets terminal attributed back to what they were before the
* program started
*/
void term_reset (void)
{
term_move_cursor(0, LI - 1);
}
/*
* term_cont: sets the terminal back to IRCII stuff when it is restarted
* after a SIGSTOP. Somewhere, this must be used in a signal() call
*/
SIGNAL_HANDLER(term_cont)
{
refresh_screen(0, NULL);
}
/*
* term_pause: sets terminal back to pre-program days, then SIGSTOPs itself.
*/
extern void term_pause (char unused, char *not_used)
{
char *shell;
DWORD dwmode;
HANDLE hstdin=GetStdHandle(STD_INPUT_HANDLE);
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si);
if (!(shell = get_string_var(SHELL_VAR)))
{
if (gdwPlatform == VER_PLATFORM_WIN32_WINDOWS)
shell = "command.com";
else
shell = "cmd.exe";
}
if (!(GetConsoleMode(hstdin,&dwmode)))
return;
if (!SetConsoleMode(hstdin, dwmode | ((ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT) & ~ENABLE_WINDOW_INPUT)))
return;
if(!CreateProcess(NULL, shell, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) )
return;
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess,INFINITE);
CloseHandle(pi.hProcess);
if (!SetConsoleMode(hstdin, dwmode ) )
return;
refresh_screen(0,NULL);
}
#endif /* NOT IN WTERM_C */
/*
* term_init: does all terminal initialization... reads termcap info, sets
* the terminal to CBREAK, no ECHO mode. Chooses the best of the terminal
* attributes to use .. for the version of this function that is called for
* wserv, we set the termial to RAW, no ECHO, so that all the signals are
* ignored.. fixes quite a few problems... -phone, jan 1993..
*/
int term_init (void)
{
#ifndef WTERM_C
CONSOLE_SCREEN_BUFFER_INFO scrbuf;
HANDLE hinput =GetStdHandle(STD_INPUT_HANDLE);
DWORD dwmode;
OSVERSIONINFO osver;
ghstdout = GetStdHandle(STD_OUTPUT_HANDLE);
if(!GetConsoleScreenBufferInfo(ghstdout, &gscrbuf) )
{
fprintf(stderr,"Error from getconsolebufinfo %d\n",GetLastError());
abort();
}
GetConsoleMode(hinput,&dwmode);
SetConsoleMode(hinput,dwmode & (~(ENABLE_LINE_INPUT |ENABLE_ECHO_INPUT
| ENABLE_PROCESSED_INPUT)| ENABLE_WINDOW_INPUT/* | ENABLE_WRAP_AT_EOL_OUTPUT*/)
);
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osver);
gdwPlatform = osver.dwPlatformId;
GetConsoleCursorInfo(hinput, &gcursbuf);
GetConsoleScreenBufferInfo(ghstdout, &scrbuf);
li = scrbuf.srWindow.Bottom - scrbuf.srWindow.Top + 1;
co = scrbuf.srWindow.Right - scrbuf.srWindow.Left + 1;
LI = li;
CO = co - 1;
memset(eolbuf,' ',sizeof(eolbuf)-2);
eolbuf[sizeof(eolbuf)-1] = 0;
def_color = gscrbuf.wAttributes;
term_clear_to_eol = term_CE_clear_to_eol;
term_cursor_right = nt_cursor_right;
term_cursor_left = nt_cursor_left;
term_scroll = term_CS_scroll/* : term_param_ALDL_scroll*/;
term_delete = term_null_function;
term_insert = term_null_function;
#endif /* NOT IN WTERM_C */
return 0;
}
#ifndef WTERM_C
/*
* term_resize: gets the terminal height and width. Trys to get the info
* from the tty driver about size, if it can't... uses the termcap values. If
* the terminal size has changed since last time term_resize() has been
* called, 1 is returned. If it is unchanged, 0 is returned.
*/
int term_resize (void)
{
static int old_li = -1,
old_co = -1;
CONSOLE_SCREEN_BUFFER_INFO scrbuf;
ghstdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(ghstdout, &scrbuf);
li = scrbuf.srWindow.Bottom - scrbuf.srWindow.Top + 1;
co = scrbuf.srWindow.Right - scrbuf.srWindow.Left + 1;
LI = li;
CO = co - 1;
if ((old_li != LI) || (old_co != CO))
{
old_li = LI;
old_co = CO;
return (1);
}
return (0);
}
static int term_null_function _((void))
{
return 1;
}
/* term_CE_clear_to_eol(): the clear to eol function, right? */
static int term_CE_clear_to_eol _((void))
{
CONSOLE_SCREEN_BUFFER_INFO scrbuf;
HANDLE hStdout = ghstdout;
DWORD numwrote;
int num=0;
COORD savepos;
if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) )
return 0 ;
num = scrbuf.srWindow.Right - scrbuf.dwCursorPosition.X;
savepos = scrbuf.dwCursorPosition;
if (!WriteConsole(hStdout,eolbuf,num,&numwrote,NULL))
return 0;
SetConsoleCursorPosition(hStdout, savepos);
return (0);
}
/*
* term_CS_scroll: should be used if the terminal has the CS capability by
* setting term_scroll equal to it
*/
static int term_CS_scroll (int line1, int line2, int n)
{
HANDLE hStdout = ghstdout;
SMALL_RECT src;
SMALL_RECT clip;
COORD dest = {0};
CHAR_INFO chr;
src.Left = gscrbuf.srWindow.Left;
src.Right = gscrbuf.srWindow.Right;
chr.Char.AsciiChar = ' ';
chr.Attributes = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
if (n > 0)
{
src.Bottom = gscrbuf.srWindow.Top + line2;
src.Top = gscrbuf.srWindow.Top + line1 + n;
dest.Y = gscrbuf.srWindow.Top + line1;
ScrollConsoleScreenBuffer(hStdout, &src, NULL, dest, &chr);
}
else
{
clip = src;
src.Bottom = gscrbuf.srWindow.Top + line2 + line1 + n;
src.Top = gscrbuf.srWindow.Top + line1;
dest.Y = gscrbuf.srWindow.Top + line1 - n;
clip.Top = gscrbuf.srWindow.Top + line1;
clip.Bottom = gscrbuf.srWindow.Top + line1 + line2;
ScrollConsoleScreenBuffer(hStdout, &src, &clip, dest, &chr);
}
return 0;
}
extern void copy_window_size (int *lines, int *columns)
{
*lines = LI;
*columns = CO;
}
extern int term_eight_bit (void)
{
return 1;
}
extern void term_beep (void)
{
if (get_int_var(BEEP_VAR))
{
Beep(0x637, 60/8);
}
}
void ScrollBuf(HANDLE hOut, CONSOLE_SCREEN_BUFFER_INFO *scrbuf,int where)
{
SMALL_RECT src;
COORD dest;
CHAR_INFO chr;
src.Left = scrbuf->srWindow.Left;
src.Top = scrbuf->srWindow.Top+where ;
src.Right = scrbuf->srWindow.Right;
src.Bottom = scrbuf->srWindow.Bottom;
dest.X = 0;
dest.Y = 0;
chr.Char.AsciiChar = ' ';
chr.Attributes = 0;
ScrollConsoleScreenBuffer(hOut, &src, NULL, dest, &chr);
}
void NT_MoveToLineOrChar(void *fd, int where,int line)
{
CONSOLE_SCREEN_BUFFER_INFO gscrbuf;
GetConsoleScreenBufferInfo((HANDLE)fd, &gscrbuf);
if (line)
{
if ( ((gscrbuf.dwCursorPosition.Y+where)> (gscrbuf.srWindow.Bottom-1))
&&( where >0))
ScrollBuf((HANDLE)fd,&gscrbuf,where);
else
gscrbuf.dwCursorPosition.Y += where;
}
else
gscrbuf.dwCursorPosition.X += where;
SetConsoleCursorPosition((HANDLE)fd, gscrbuf.dwCursorPosition);
}
void NT_MoveToLineOrCharAbs(void *fd, int where,int line)
{
CONSOLE_SCREEN_BUFFER_INFO scrbuf;
GetConsoleScreenBufferInfo((HANDLE)fd, &scrbuf);
if (line)
scrbuf.dwCursorPosition.Y = where+scrbuf.srWindow.Top;
else
scrbuf.dwCursorPosition.X = where;
SetConsoleCursorPosition((HANDLE)fd, scrbuf.dwCursorPosition);
}
void term_move_cursor(int cursor, int line)
{
HANDLE hStdout =ghstdout;
COORD dest;
dest.X = cursor;
dest.Y = line + gscrbuf.srWindow.Top;
SetConsoleCursorPosition(hStdout, dest);
}
void NT_ClearScreen(void)
{
CONSOLE_SCREEN_BUFFER_INFO scrbuf;
DWORD numwrote;
COORD origin = {0, 0};
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hStdout, &scrbuf);
FillConsoleOutputCharacter(hStdout,' ',scrbuf.dwSize.X*scrbuf.dwSize.Y,
origin,&numwrote);
FillConsoleOutputAttribute(hStdout,scrbuf.wAttributes,
scrbuf.dwSize.X*scrbuf.dwSize.Y,scrbuf.dwCursorPosition,&numwrote);
origin.X = scrbuf.srWindow.Left;
origin.Y = scrbuf.srWindow.Top;
SetConsoleCursorPosition(hStdout, origin);
return;
}
int nt_cursor_right(void)
{
NT_MoveToLineOrChar(GetStdHandle(STD_OUTPUT_HANDLE), 1,0);
return 0;
}
int nt_cursor_left(void)
{
NT_MoveToLineOrChar(GetStdHandle(STD_OUTPUT_HANDLE), -1,0);
return 0;
}
extern void set_term_eight_bit (int value)
{
return;
}
#define NPAR 16
static unsigned int color_table[] = {
0x00, 0x04, 0x02, 0x06, 0x01, 0x05, 0x03, 0x07,
0x00|8, 0x04|8, 0x02|8, 0x06|8, 0x01|8, 0x05|8, 0x03|8, 0x07|8
};
enum VC_STATES { ESnormal = 0, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey };
enum VC_STATES vc_state;
unsigned long par[NPAR+1] = {0};
unsigned long npar = 0;
int intensity = 1;
int blink = 0;
int underline = 0;
int reverse_ch = 0;
void reset_attrib(void *fd, int *fg, int *bg)
{
intensity = 0;
underline = 0;
reverse_ch = 0;
blink = 0;
*fg=FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
*bg=0;
}
void csi_m(void *fd)
{
int i;
static int fg = 7;
static int bg = 0;
CONSOLE_SCREEN_BUFFER_INFO scrbuf;
GetConsoleScreenBufferInfo((HANDLE)fd, &scrbuf);
for (i=0; i <= npar; i++)
{
switch(par[i])
{
case 0:
/* all off */
reset_attrib(fd, &fg, &bg);
break;
case 1: /* bold */
intensity = FOREGROUND_INTENSITY;
break;
case 2: /* all off */
fg = 0;
bg = 0;
intensity = 0;
break;
case 4: /* underline */
fg=FOREGROUND_BLUE | FOREGROUND_RED;
intensity=FOREGROUND_INTENSITY;
bg=0;
break;
case 5: /* blink */
fg=FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
bg=0;
intensity=FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
break;
case 7: /* reverse */
fg=0;
bg=BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
intensity=0;
break;
case 49:
fg = (def_color & 0xf0) | bg;
break;
default:
if (par[i] >=30 && par[i] <= 37)
fg = color_table[par[i]-30];
else if (par[i] >=40 && par[i] <= 47)
bg = color_table[par[i]-40]<<4;
break;
}
}
/* update attribs now */
SetConsoleTextAttribute(fd, fg | bg | intensity);
}
void set_term_intensity(int flag)
{
par[0] = flag ? 1 : 0;
npar = 0;
csi_m(GetStdHandle(STD_OUTPUT_HANDLE));
}
void set_term_inverse(int flag)
{
par[0] = flag ? 7 : 0;
npar = 0;
csi_m(GetStdHandle(STD_OUTPUT_HANDLE));
}
void set_term_underline(int flag)
{
par[0] = flag ? 4 : 0;
npar = 0;
csi_m(GetStdHandle(STD_OUTPUT_HANDLE));
}
void csi_K(void *fd, int parm)
{
COORD save_curs = {0};
CONSOLE_SCREEN_BUFFER_INFO scrbuf;
DWORD bytes_rtn;
int num = 0;
switch(parm)
{
case 2:
NT_MoveToLineOrCharAbs(fd, 0, 0);
case 0:
term_CE_clear_to_eol();
break;
case 1:
GetConsoleScreenBufferInfo((HANDLE)fd, &scrbuf);
save_curs.Y = scrbuf.dwCursorPosition.Y;
SetConsoleCursorPosition((HANDLE)fd, save_curs);
num = scrbuf.dwCursorPosition.X - 1;
if (num > 0)
WriteConsole((HANDLE)fd, eolbuf, num, &bytes_rtn, NULL);
SetConsoleCursorPosition((HANDLE)fd, scrbuf.dwCursorPosition);
break;
}
}
int nt_write(void * fd, unsigned char *buf, register int howmany)
{
DWORD bytes_rtn;
int num = 0;
int len = -1;
register int c;
int ok;
register unsigned char *buf1 = buf;
vc_state = ESnormal;
while (howmany)
{
howmany--;
num++;
ok = 0;
c = *buf1;
buf1++;
len++;
if (!ok && c)
{
switch(c)
{
case 0x1b:
case REV_TOG:
case UND_TOG:
case BOLD_TOG:
case ALL_OFF:
ok = 0;
break;
default:
ok = 1;
}
}
if (vc_state == ESnormal && ok)
{
WriteConsole((HANDLE)fd, buf+len,1, &bytes_rtn, NULL);
continue;
}
switch(c)
{
case REV_TOG:
if (reverse_ch) reverse_ch = 0; else reverse_ch = 1;
set_term_inverse(reverse_ch);
continue;
case BOLD_TOG:
if (intensity) intensity = 0; else intensity = 1;
set_term_intensity(intensity);
continue;
case UND_TOG:
if (underline) underline = 0; else underline = 1;
set_term_underline(underline);
continue;
case ALL_OFF:
set_term_underline(0);
set_term_intensity(0);
set_term_inverse(0); /* This turns it all off */
intensity = 0;
underline = 0;
reverse_ch = 0;
if (!buf1) /* We're the end of line */
term_bold_off();
continue;
case 7:
Beep(0x637, 60/8);
continue;
case 8:
continue;
case 9:
continue;
case 10: case 11: case 12:
NT_MoveToLineOrChar(fd, 1, 1);
case 13:
NT_MoveToLineOrCharAbs(fd, 0, 0);
continue;
case 24: case 26:
vc_state = ESnormal;
continue;
case 27:
vc_state = ESesc;
continue;
case 128+27:
vc_state = ESsquare;
continue;
}
switch(vc_state)
{
case ESesc:
vc_state = ESnormal;
switch(c)
{
case '[':
vc_state = ESsquare;
continue;
}
continue;
case ESsquare:
vc_state = ESgetpars;
for(npar = 0 ; npar < NPAR ; npar++)
par[npar] = 0;
npar = 0;
vc_state = ESgetpars;
if (c == '[') { /* Function key */
vc_state=ESfunckey;
continue;
}
case ESgetpars:
if (c==';' && npar<NPAR-1)
{
npar++;
continue;
} else if (c>='0' && c<='9')
{
par[npar] *= 10;
par[npar] += c-'0';
continue;
} else
vc_state=ESgotpars;
case ESgotpars:
vc_state = ESnormal;
switch(c)
{
case 'C': case 'a':
NT_MoveToLineOrChar(fd, par[0], 0);
continue;
case 'K':
csi_K(fd, par[0]);
continue;
case 'm':
csi_m(fd);
continue;
case 'r':
{
int top, bottom;
if (!par[0]) par[0]++;
if (!par[1]) par[1] = li;
if (par[0] < par[1] && par[1] < li)
{
top = par[0]-1;
bottom = par[1];
term_CS_scroll(top, bottom, 1);
}
continue;
}
}
continue;
default:
vc_state = ESnormal;
}
}
return num;
}
#endif /* NOT IN WTERM_C */
#endif