1 /*
2  * term.c -- termios and termcap handlers
3  *
4  * Written By Matthew Green, based on window.c by Michael Sandrof
5  * Copyright(c) 1993 Matthew Green
6  * Significant modifications by Jeremy Nelson
7  * Copyright 1997 EPIC Software Labs,
8  * Significant additions by J. Kean Johnston
9  * Copyright 1998 J. Kean Johnston, used with permission
10  * Modifications Copyright Colten Edwards 1997-1998.
11  * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
12  */
13 
14 #include "irc.h"
15 static char cvsrevision[] = "$Id: term.c 530 2014-11-06 10:25:37Z keaston $";
16 CVS_REVISION(term_c)
17 #include "struct.h"
18 #include "screen.h"
19 #include "ircaux.h"
20 
21 #ifdef __EMX__
22 static BYTE pair[2];
23 char default_pair[2];
24 VIOMODEINFO vmode;
25 int	vio_screen = 0;
26 #endif
27 
28 
29 #ifdef WINNT
30 HANDLE ghstdout;
31 CONSOLE_SCREEN_BUFFER_INFO gscrbuf;
32 CONSOLE_CURSOR_INFO gcursbuf;
33 DWORD gdwPlatform;
34 #endif
35 
36 #include "vars.h"
37 #include "struct.h"
38 #include "ircterm.h"
39 #include "window.h"
40 #include "screen.h"
41 #include "output.h"
42 #ifdef TRANSLATE
43 #include "translat.h"
44 #endif
45 
46 #define MAIN_SOURCE
47 #include "modval.h"
48 
49 #ifdef HAVE_TERMIOS_H
50 #include <termios.h>
51 #else
52 #include <sys/termios.h>
53 #endif
54 
55 #include <sys/ioctl.h>
56 
57 #if defined(HAVE_NCURSES_TERM_H)
58 #include <ncurses/term.h>
59 #elif defined(HAVE_TERM_H)
60 #include <term.h>
61 #endif
62 
63 static	int		tty_des;		/* descriptor for the tty */
64 
65 static	struct	termios	oldb, newb;
66 
67 	char		my_PC, *BC, *UP;
68 	int		BClen, UPlen;
69 extern	int		already_detached;
70 
71 #if !defined(WTERM_C)
72 
73 /* Systems cant seem to agree where to put these... */
74 #ifdef HAVE_TERMINFO
75 #define Tgetstr(x, y) 	((void)&(y), tigetstr((x).iname))
76 #define Tgetnum(x) 	tigetnum(x.iname);
77 #define Tgetflag(x) 	tigetflag(x.iname);
78 #else
79 #define Tgetstr(x, y) 	tgetstr(x.tname, &y)
80 #define Tgetnum(x) 	tgetnum(x.tname)
81 #define Tgetflag(x) 	tgetflag(x.tname)
82 #endif
83 
84 /* Some systems declare tparm() with 9 fixed 'long' arguments */
85 #define tparm1(str, a1) tparm(str, a1, 0, 0, 0, 0, 0, 0, 0, 0)
86 #define tparm2(str, a1, a2) tparm(str, a1, a2, 0, 0, 0, 0, 0, 0, 0)
87 #define tparm4(str, a1, a2, a3, a4) tparm(str, a1, a2, a3, a4, 0, 0, 0, 0, 0)
88 
89 extern  char    *getenv();
90 
91 /*
92  * The old code assumed termcap. termcap is almost always present, but on
93  * many systems that have both termcap and terminfo, termcap is deprecated
94  * and its databases often out of date. Configure will try to use terminfo
95  * if at all possible. We define here a mapping between the termcap / terminfo
96  * names, and where we store the information.
97  * NOTE: The terminfo portions are NOT implemented yet.
98  */
99 #define CAP_TYPE_BOOL   0
100 #define CAP_TYPE_INT    1
101 #define CAP_TYPE_STR    2
102 
103 typedef struct cap2info
104 {
105 	const char *	longname;
106 /* ncurses can optionally declare tigetstr(), tigetnum() and tigetflags() with
107  * a const char * argument. */
108 #ifdef NCURSES_CONST
109 NCURSES_CONST
110 #endif
111 	char *	iname;
112 	const char *	tname;
113 	int 		type;
114 	void *		ptr;
115 } cap2info;
116 
117 struct	term_struct TIS;
118 
119 cap2info tcaps[] =
120 {
121 	{ "auto_left_margin",		"bw",		"bw",	CAP_TYPE_BOOL,	(void *)&TIS.TI_bw },
122 	{ "auto_right_margin",		"am",		"am",	CAP_TYPE_BOOL,	(void *)&TIS.TI_am },
123 	{ "no_esc_ctlc",		"xsb",		"xb",	CAP_TYPE_BOOL,	(void *)&TIS.TI_xsb },
124 	{ "ceol_standout_glitch",	"xhp",		"xs",	CAP_TYPE_BOOL,	(void *)&TIS.TI_xhp },
125 	{ "eat_newline_glitch",		"xenl",		"xn",	CAP_TYPE_BOOL,	(void *)&TIS.TI_xenl },
126 	{ "erase_overstrike",		"eo",		"eo",	CAP_TYPE_BOOL,	(void *)&TIS.TI_eo },
127 	{ "generic_type",		"gn",		"gn",	CAP_TYPE_BOOL,	(void *)&TIS.TI_gn },
128 	{ "hard_copy",			"hc",		"hc",	CAP_TYPE_BOOL,	(void *)&TIS.TI_hc },
129 	{ "has_meta_key",		"km",		"km",	CAP_TYPE_BOOL,	(void *)&TIS.TI_km },
130 	{ "has_status_line",		"hs",		"hs",	CAP_TYPE_BOOL,	(void *)&TIS.TI_hs },
131 	{ "insert_null_glitch",		"in",		"in",	CAP_TYPE_BOOL,	(void *)&TIS.TI_in },
132 	{ "memory_above",		"da",		"da",	CAP_TYPE_BOOL,	(void *)&TIS.TI_da },
133 	{ "memory_below",		"db",		"db",	CAP_TYPE_BOOL,	(void *)&TIS.TI_db },
134 	{ "move_insert_mode",		"mir",		"mi",	CAP_TYPE_BOOL,	(void *)&TIS.TI_mir },
135 	{ "move_standout_mode",		"msgr",		"ms",	CAP_TYPE_BOOL,	(void *)&TIS.TI_msgr },
136 	{ "over_strike",		"os",		"os",	CAP_TYPE_BOOL,	(void *)&TIS.TI_os },
137 	{ "status_line_esc_ok",		"eslok",	"es",	CAP_TYPE_BOOL,	(void *)&TIS.TI_eslok },
138 	{ "dest_tabs_magic_smso",	"xt",		"xt",	CAP_TYPE_BOOL,	(void *)&TIS.TI_xt },
139 	{ "tilde_glitch",		"hz",		"hz",	CAP_TYPE_BOOL,	(void *)&TIS.TI_hz },
140 	{ "transparent_underline",	"ul",		"ul",	CAP_TYPE_BOOL,	(void *)&TIS.TI_ul },
141 	{ "xon_xoff",			"xon",		"xo",	CAP_TYPE_BOOL,	(void *)&TIS.TI_xon },
142 	{ "needs_xon_xoff",		"nxon",		"nx",	CAP_TYPE_BOOL,	(void *)&TIS.TI_nxon },
143 	{ "prtr_silent",		"mc5i",		"5i",	CAP_TYPE_BOOL,	(void *)&TIS.TI_mc5i },
144 	{ "hard_cursor",		"chts",		"HC",	CAP_TYPE_BOOL,	(void *)&TIS.TI_chts },
145 	{ "non_rev_rmcup",		"nrrmc",	"NR",	CAP_TYPE_BOOL,	(void *)&TIS.TI_nrrmc },
146 	{ "no_pad_char",		"npc",		"NP",	CAP_TYPE_BOOL,	(void *)&TIS.TI_npc },
147 	{ "non_dest_scroll_region",	"ndscr",	"ND",	CAP_TYPE_BOOL,	(void *)&TIS.TI_ndscr },
148 	{ "can_change",			"ccc",		"cc",	CAP_TYPE_BOOL,	(void *)&TIS.TI_ccc },
149 	{ "back_color_erase",		"bce",		"ut",	CAP_TYPE_BOOL,	(void *)&TIS.TI_bce },
150 	{ "hue_lightness_saturation",	"hls",		"hl",	CAP_TYPE_BOOL,	(void *)&TIS.TI_hls },
151 	{ "col_addr_glitch",		"xhpa",		"YA",	CAP_TYPE_BOOL,	(void *)&TIS.TI_xhpa },
152 	{ "cr_cancels_micro_mode",	"crxm",		"YB",	CAP_TYPE_BOOL,	(void *)&TIS.TI_crxm },
153 	{ "has_print_wheel",		"daisy",	"YC",	CAP_TYPE_BOOL,	(void *)&TIS.TI_daisy },
154 	{ "row_addr_glitch",		"xvpa",		"YD",	CAP_TYPE_BOOL,	(void *)&TIS.TI_xvpa },
155 	{ "semi_auto_right_margin",	"sam",		"YE",	CAP_TYPE_BOOL,	(void *)&TIS.TI_sam },
156 	{ "cpi_changes_res",		"cpix",		"YF",	CAP_TYPE_BOOL,	(void *)&TIS.TI_cpix },
157 	{ "lpi_changes_res",		"lpix",		"YG",	CAP_TYPE_BOOL,	(void *)&TIS.TI_lpix },
158 	{ "columns",			"cols",		"co",	CAP_TYPE_INT,	(void *)&TIS.TI_cols },
159 	{ "init_tabs",			"it",		"it",	CAP_TYPE_INT,	(void *)&TIS.TI_it },
160 	{ "lines",			"lines",	"li",	CAP_TYPE_INT,	(void *)&TIS.TI_lines },
161 	{ "lines_of_memory",		"lm",		"lm",	CAP_TYPE_INT,	(void *)&TIS.TI_lm },
162 	{ "magic_cookie_glitch",	"xmc",		"sg",	CAP_TYPE_INT,	(void *)&TIS.TI_xmc },
163 	{ "padding_baud_rate",		"pb",		"pb",	CAP_TYPE_INT,	(void *)&TIS.TI_pb },
164 	{ "virtual_terminal",		"vt",		"vt",	CAP_TYPE_INT,	(void *)&TIS.TI_vt },
165 	{ "width_status_line",		"wsl",		"ws",	CAP_TYPE_INT,	(void *)&TIS.TI_wsl },
166 	{ "num_labels",			"nlab",		"Nl",	CAP_TYPE_INT,	(void *)&TIS.TI_nlab },
167 	{ "label_height",		"lh",		"lh",	CAP_TYPE_INT,	(void *)&TIS.TI_lh },
168 	{ "label_width",		"lw",		"lw",	CAP_TYPE_INT,	(void *)&TIS.TI_lw },
169 	{ "max_attributes",		"ma",		"ma",	CAP_TYPE_INT,	(void *)&TIS.TI_ma },
170 	{ "maximum_windows",		"wnum",		"MW",	CAP_TYPE_INT,	(void *)&TIS.TI_wnum },
171 	{ "max_colors",			"colors",	"Co",	CAP_TYPE_INT,	(void *)&TIS.TI_colors },
172 	{ "max_pairs",			"pairs",	"pa",	CAP_TYPE_INT,	(void *)&TIS.TI_pairs },
173 	{ "no_color_video",		"ncv",		"NC",	CAP_TYPE_INT,	(void *)&TIS.TI_ncv },
174 	{ "buffer_capacity",		"bufsz",	"Ya",	CAP_TYPE_INT,	(void *)&TIS.TI_bufsz },
175 	{ "dot_vert_spacing",		"spinv",	"Yb",	CAP_TYPE_INT,	(void *)&TIS.TI_spinv },
176 	{ "dot_horz_spacing",		"spinh",	"Yc",	CAP_TYPE_INT,	(void *)&TIS.TI_spinh },
177 	{ "max_micro_address",		"maddr",	"Yd",	CAP_TYPE_INT,	(void *)&TIS.TI_maddr },
178 	{ "max_micro_jump",		"mjump",	"Ye",	CAP_TYPE_INT,	(void *)&TIS.TI_mjump },
179 	{ "micro_col_size",		"mcs",		"Yf",	CAP_TYPE_INT,	(void *)&TIS.TI_mcs },
180 	{ "micro_line_size",		"mls",		"Yg",	CAP_TYPE_INT,	(void *)&TIS.TI_mls },
181 	{ "number_of_pins",		"npins",	"Yh",	CAP_TYPE_INT,	(void *)&TIS.TI_npins },
182 	{ "output_res_char",		"orc",		"Yi",	CAP_TYPE_INT,	(void *)&TIS.TI_orc },
183 	{ "output_res_line",		"orl",		"Yj",	CAP_TYPE_INT,	(void *)&TIS.TI_orl },
184 	{ "output_res_horz_inch",	"orhi",		"Yk",	CAP_TYPE_INT,	(void *)&TIS.TI_orhi },
185 	{ "output_res_vert_inch",	"orvi",		"Yl",	CAP_TYPE_INT,	(void *)&TIS.TI_orvi },
186 	{ "print_rate",			"cps",		"Ym",	CAP_TYPE_INT,	(void *)&TIS.TI_cps },
187 	{ "wide_char_size",		"widcs",	"Yn",	CAP_TYPE_INT,	(void *)&TIS.TI_widcs },
188 	{ "buttons",			"btns",		"BT",	CAP_TYPE_INT,	(void *)&TIS.TI_btns },
189 	{ "bit_image_entwining",	"bitwin",	"Yo",	CAP_TYPE_INT,	(void *)&TIS.TI_bitwin },
190 	{ "bit_image_type",		"bitype",	"Yp",	CAP_TYPE_INT,	(void *)&TIS.TI_bitype },
191 	{ "back_tab",			"cbt",		"bt",	CAP_TYPE_STR,	&TIS.TI_cbt },
192 	{ "bell",			"bel",		"bl",	CAP_TYPE_STR,	&TIS.TI_bel },
193 	{ "carriage_return",		"cr",		"cr",	CAP_TYPE_STR,	&TIS.TI_cr },
194 	{ "change_scroll_region",	"csr",		"cs",	CAP_TYPE_STR,	&TIS.TI_csr },
195 	{ "clear_all_tabs",		"tbc",		"ct",	CAP_TYPE_STR,	&TIS.TI_tbc },
196 	{ "clear_screen",		"clear",	"cl",	CAP_TYPE_STR,	&TIS.TI_clear },
197 	{ "clr_eol",			"el",		"ce",	CAP_TYPE_STR,	&TIS.TI_el },
198 	{ "clr_eos",			"ed",		"cd",	CAP_TYPE_STR,	&TIS.TI_ed },
199 	{ "column_address",		"hpa",		"ch",	CAP_TYPE_STR,	&TIS.TI_hpa },
200 	{ "command_character",		"cmdch",	"CC",	CAP_TYPE_STR,	&TIS.TI_cmdch },
201 	{ "cursor_address",		"cup",		"cm",	CAP_TYPE_STR,	&TIS.TI_cup },
202 	{ "cursor_down",		"cud1",		"do",	CAP_TYPE_STR,	&TIS.TI_cud1 },
203 	{ "cursor_home",		"home",		"ho",	CAP_TYPE_STR,	&TIS.TI_home },
204 	{ "cursor_invisible",		"civis",	"vi",	CAP_TYPE_STR,	&TIS.TI_civis },
205 	{ "cursor_left",		"cub1",		"le",	CAP_TYPE_STR,	&TIS.TI_cub1 },
206 	{ "cursor_mem_address",		"mrcup",	"CM",	CAP_TYPE_STR,	&TIS.TI_mrcup },
207 	{ "cursor_normal",		"cnorm",	"ve",	CAP_TYPE_STR,	&TIS.TI_cnorm },
208 	{ "cursor_right",		"cuf1",		"nd",	CAP_TYPE_STR,	&TIS.TI_cuf1 },
209 	{ "cursor_to_ll",		"ll",		"ll",	CAP_TYPE_STR,	&TIS.TI_ll },
210 	{ "cursor_up",			"cuu1",		"up",	CAP_TYPE_STR,	&TIS.TI_cuu1 },
211 	{ "cursor_visible",		"cvvis",	"vs",	CAP_TYPE_STR,	&TIS.TI_cvvis },
212 	{ "delete_character",		"dch1",		"dc",	CAP_TYPE_STR,	&TIS.TI_dch1 },
213 	{ "delete_line",		"dl1",		"dl",	CAP_TYPE_STR,	&TIS.TI_dl1 },
214 	{ "dis_status_line",		"dsl",		"ds",	CAP_TYPE_STR,	&TIS.TI_dsl },
215 	{ "down_half_line",		"hd",		"hd",	CAP_TYPE_STR,	&TIS.TI_hd },
216 	{ "enter_alt_charset_mode",	"smacs",	"as",	CAP_TYPE_STR,	&TIS.TI_smacs },
217 	{ "enter_blink_mode",		"blink",	"mb",	CAP_TYPE_STR,	&TIS.TI_blink },
218 	{ "enter_bold_mode",		"bold",		"md",	CAP_TYPE_STR,	&TIS.TI_bold },
219 	{ "enter_ca_mode",		"smcup",	"ti",	CAP_TYPE_STR,	&TIS.TI_smcup },
220 	{ "enter_delete_mode",		"smdc",		"dm",	CAP_TYPE_STR,	&TIS.TI_smdc },
221 	{ "enter_dim_mode",		"dim",		"mh",	CAP_TYPE_STR,	&TIS.TI_dim },
222 	{ "enter_insert_mode",		"smir",		"im",	CAP_TYPE_STR,	&TIS.TI_smir },
223 	{ "enter_secure_mode",		"invis",	"mk",	CAP_TYPE_STR,	&TIS.TI_invis },
224 	{ "enter_protected_mode",	"prot",		"mp",	CAP_TYPE_STR,	&TIS.TI_prot },
225 	{ "enter_reverse_mode",		"rev",		"mr",	CAP_TYPE_STR,	&TIS.TI_rev },
226 	{ "enter_standout_mode",	"smso",		"so",	CAP_TYPE_STR,	&TIS.TI_smso },
227 	{ "enter_underline_mode",	"smul",		"us",	CAP_TYPE_STR,	&TIS.TI_smul },
228 	{ "erase_chars",		"ech",		"ec",	CAP_TYPE_STR,	&TIS.TI_ech },
229 	{ "exit_alt_charset_mode",	"rmacs",	"ae",	CAP_TYPE_STR,	&TIS.TI_rmacs },
230 	{ "exit_attribute_mode",	"sgr0",		"me",	CAP_TYPE_STR,	&TIS.TI_sgr0 },
231 	{ "exit_ca_mode",		"rmcup",	"te",	CAP_TYPE_STR,	&TIS.TI_rmcup },
232 	{ "exit_delete_mode",		"rmdc",		"ed",	CAP_TYPE_STR,	&TIS.TI_rmdc },
233 	{ "exit_insert_mode",		"rmir",		"ei",	CAP_TYPE_STR,	&TIS.TI_rmir },
234 	{ "exit_standout_mode",		"rmso",		"se",	CAP_TYPE_STR,	&TIS.TI_rmso },
235 	{ "exit_underline_mode",	"rmul",		"ue",	CAP_TYPE_STR,	&TIS.TI_rmul },
236 	{ "flash_screen",		"flash",	"vb",	CAP_TYPE_STR,	&TIS.TI_flash },
237 	{ "form_feed",			"ff",		"ff",	CAP_TYPE_STR,	&TIS.TI_ff },
238 	{ "from_status_line",		"fsl",		"fs",	CAP_TYPE_STR,	&TIS.TI_fsl },
239 	{ "init_1string",		"is1",		"i1",	CAP_TYPE_STR,	&TIS.TI_is1 },
240 	{ "init_2string",		"is2",		"is",	CAP_TYPE_STR,	&TIS.TI_is2 },
241 	{ "init_3string",		"is3",		"i3",	CAP_TYPE_STR,	&TIS.TI_is3 },
242 	{ "init_file",			"if",		"if",	CAP_TYPE_STR,	&TIS.TI_if },
243 	{ "insert_character",		"ich1",		"ic",	CAP_TYPE_STR,	&TIS.TI_ich1 },
244 	{ "insert_line",		"il1",		"al",	CAP_TYPE_STR,	&TIS.TI_il1 },
245 	{ "insert_padding",		"ip",		"ip",	CAP_TYPE_STR,	&TIS.TI_ip },
246 	{ "key_backspace",		"kbs",		"kb",	CAP_TYPE_STR,	&TIS.TI_kbs },
247 	{ "key_catab",			"ktbc",		"ka",	CAP_TYPE_STR,	&TIS.TI_ktbc },
248 	{ "key_clear",			"kclr",		"kC",	CAP_TYPE_STR,	&TIS.TI_kclr },
249 	{ "key_ctab",			"kctab",	"kt",	CAP_TYPE_STR,	&TIS.TI_kctab },
250 	{ "key_dc",			"kdch1",	"kD",	CAP_TYPE_STR,	&TIS.TI_kdch1 },
251 	{ "key_dl",			"kdl1",		"kL",	CAP_TYPE_STR,	&TIS.TI_kdl1 },
252 	{ "key_down",			"kcud1",	"kd",	CAP_TYPE_STR,	&TIS.TI_kcud1 },
253 	{ "key_eic",			"krmir",	"kM",	CAP_TYPE_STR,	&TIS.TI_krmir },
254 	{ "key_eol",			"kel",		"kE",	CAP_TYPE_STR,	&TIS.TI_kel },
255 	{ "key_eos",			"ked",		"kS",	CAP_TYPE_STR,	&TIS.TI_ked },
256 	{ "key_f0",			"kf0",		"k0",	CAP_TYPE_STR,	&TIS.TI_kf0 },
257 	{ "key_f1",			"kf1",		"k1",	CAP_TYPE_STR,	&TIS.TI_kf1 },
258 	{ "key_f10",			"kf10",		"k;",	CAP_TYPE_STR,	&TIS.TI_kf10 },
259 	{ "key_f2",			"kf2",		"k2",	CAP_TYPE_STR,	&TIS.TI_kf2 },
260 	{ "key_f3",			"kf3",		"k3",	CAP_TYPE_STR,	&TIS.TI_kf3 },
261 	{ "key_f4",			"kf4",		"k4",	CAP_TYPE_STR,	&TIS.TI_kf4 },
262 	{ "key_f5",			"kf5",		"k5",	CAP_TYPE_STR,	&TIS.TI_kf5 },
263 	{ "key_f6",			"kf6",		"k6",	CAP_TYPE_STR,	&TIS.TI_kf6 },
264 	{ "key_f7",			"kf7",		"k7",	CAP_TYPE_STR,	&TIS.TI_kf7 },
265 	{ "key_f8",			"kf8",		"k8",	CAP_TYPE_STR,	&TIS.TI_kf8 },
266 	{ "key_f9",			"kf9",		"k9",	CAP_TYPE_STR,	&TIS.TI_kf9 },
267 	{ "key_home",			"khome",	"kh",	CAP_TYPE_STR,	&TIS.TI_khome },
268 	{ "key_ic",			"kich1",	"kI",	CAP_TYPE_STR,	&TIS.TI_kich1 },
269 	{ "key_il",			"kil1",		"kA",	CAP_TYPE_STR,	&TIS.TI_kil1 },
270 	{ "key_left",			"kcub1",	"kl",	CAP_TYPE_STR,	&TIS.TI_kcub1 },
271 	{ "key_ll",			"kll",		"kH",	CAP_TYPE_STR,	&TIS.TI_kll },
272 	{ "key_npage",			"knp",		"kN",	CAP_TYPE_STR,	&TIS.TI_knp },
273 	{ "key_ppage",			"kpp",		"kP",	CAP_TYPE_STR,	&TIS.TI_kpp },
274 	{ "key_right",			"kcuf1",	"kr",	CAP_TYPE_STR,	&TIS.TI_kcuf1 },
275 	{ "key_sf",			"kind",		"kF",	CAP_TYPE_STR,	&TIS.TI_kind },
276 	{ "key_sr",			"kri",		"kR",	CAP_TYPE_STR,	&TIS.TI_kri },
277 	{ "key_stab",			"khts",		"kT",	CAP_TYPE_STR,	&TIS.TI_khts },
278 	{ "key_up",			"kcuu1",	"ku",	CAP_TYPE_STR,	&TIS.TI_kcuu1 },
279 	{ "keypad_local",		"rmkx",		"ke",	CAP_TYPE_STR,	&TIS.TI_rmkx },
280 	{ "keypad_xmit",		"smkx",		"ks",	CAP_TYPE_STR,	&TIS.TI_smkx },
281 	{ "lab_f0",			"lf0",		"l0",	CAP_TYPE_STR,	&TIS.TI_lf0 },
282 	{ "lab_f1",			"lf1",		"l1",	CAP_TYPE_STR,	&TIS.TI_lf1 },
283 	{ "lab_f10",			"lf10",		"la",	CAP_TYPE_STR,	&TIS.TI_lf10 },
284 	{ "lab_f2",			"lf2",		"l2",	CAP_TYPE_STR,	&TIS.TI_lf2 },
285 	{ "lab_f3",			"lf3",		"l3",	CAP_TYPE_STR,	&TIS.TI_lf3 },
286 	{ "lab_f4",			"lf4",		"l4",	CAP_TYPE_STR,	&TIS.TI_lf4 },
287 	{ "lab_f5",			"lf5",		"l5",	CAP_TYPE_STR,	&TIS.TI_lf5 },
288 	{ "lab_f6",			"lf6",		"l6",	CAP_TYPE_STR,	&TIS.TI_lf6 },
289 	{ "lab_f7",			"lf7",		"l7",	CAP_TYPE_STR,	&TIS.TI_lf7 },
290 	{ "lab_f8",			"lf8",		"l8",	CAP_TYPE_STR,	&TIS.TI_lf8 },
291 	{ "lab_f9",			"lf9",		"l9",	CAP_TYPE_STR,	&TIS.TI_lf9 },
292 	{ "meta_off",			"rmm",		"mo",	CAP_TYPE_STR,	&TIS.TI_rmm },
293 	{ "meta_on",			"smm",		"mm",	CAP_TYPE_STR,	&TIS.TI_smm },
294 	{ "newline",			"nel",		"nw",	CAP_TYPE_STR,	&TIS.TI_nel },
295 	{ "pad_char",			"pad",		"pc",	CAP_TYPE_STR,	&TIS.TI_pad },
296 	{ "parm_dch",			"dch",		"DC",	CAP_TYPE_STR,	&TIS.TI_dch },
297 	{ "parm_delete_line",		"dl",		"DL",	CAP_TYPE_STR,	&TIS.TI_dl },
298 	{ "parm_down_cursor",		"cud",		"DO",	CAP_TYPE_STR,	&TIS.TI_cud },
299 	{ "parm_ich",			"ich",		"IC",	CAP_TYPE_STR,	&TIS.TI_ich },
300 	{ "parm_index",			"indn",		"SF",	CAP_TYPE_STR,	&TIS.TI_indn },
301 	{ "parm_insert_line",		"il",		"AL",	CAP_TYPE_STR,	&TIS.TI_il },
302 	{ "parm_left_cursor",		"cub",		"LE",	CAP_TYPE_STR,	&TIS.TI_cub },
303 	{ "parm_right_cursor",		"cuf",		"RI",	CAP_TYPE_STR,	&TIS.TI_cuf },
304 	{ "parm_rindex",		"rin",		"SR",	CAP_TYPE_STR,	&TIS.TI_rin },
305 	{ "parm_up_cursor",		"cuu",		"UP",	CAP_TYPE_STR,	&TIS.TI_cuu },
306 	{ "pkey_key",			"pfkey",	"pk",	CAP_TYPE_STR,	&TIS.TI_pfkey },
307 	{ "pkey_local",			"pfloc",	"pl",	CAP_TYPE_STR,	&TIS.TI_pfloc },
308 	{ "pkey_xmit",			"pfx",		"px",	CAP_TYPE_STR,	&TIS.TI_pfx },
309 	{ "print_screen",		"mc0",		"ps",	CAP_TYPE_STR,	&TIS.TI_mc0 },
310 	{ "prtr_off",			"mc4",		"pf",	CAP_TYPE_STR,	&TIS.TI_mc4 },
311 	{ "prtr_on",			"mc5",		"po",	CAP_TYPE_STR,	&TIS.TI_mc5 },
312 	{ "repeat_char",		"rep",		"rp",	CAP_TYPE_STR,	&TIS.TI_rep },
313 	{ "reset_1string",		"rs1",		"r1",	CAP_TYPE_STR,	&TIS.TI_rs1 },
314 	{ "reset_2string",		"rs2",		"r2",	CAP_TYPE_STR,	&TIS.TI_rs2 },
315 	{ "reset_3string",		"rs3",		"r3",	CAP_TYPE_STR,	&TIS.TI_rs3 },
316 	{ "reset_file",			"rf",		"rf",	CAP_TYPE_STR,	&TIS.TI_rf },
317 	{ "restore_cursor",		"rc",		"rc",	CAP_TYPE_STR,	&TIS.TI_rc },
318 	{ "row_address",		"vpa",		"cv",	CAP_TYPE_STR,	&TIS.TI_vpa },
319 	{ "save_cursor",		"sc",		"sc",	CAP_TYPE_STR,	&TIS.TI_sc },
320 	{ "scroll_forward",		"ind",		"sf",	CAP_TYPE_STR,	&TIS.TI_ind },
321 	{ "scroll_reverse",		"ri",		"sr",	CAP_TYPE_STR,	&TIS.TI_ri },
322 	{ "set_attributes",		"sgr",		"sa",	CAP_TYPE_STR,	&TIS.TI_sgr },
323 	{ "set_tab",			"hts",		"st",	CAP_TYPE_STR,	&TIS.TI_hts },
324 	{ "set_window",			"wind",		"wi",	CAP_TYPE_STR,	&TIS.TI_wind },
325 	{ "tab",			"ht",		"ta",	CAP_TYPE_STR,	&TIS.TI_ht },
326 	{ "to_status_line",		"tsl",		"ts",	CAP_TYPE_STR,	&TIS.TI_tsl },
327 	{ "underline_char",		"uc",		"uc",	CAP_TYPE_STR,	&TIS.TI_uc },
328 	{ "up_half_line",		"hu",		"hu",	CAP_TYPE_STR,	&TIS.TI_hu },
329 	{ "init_prog",			"iprog",	"iP",	CAP_TYPE_STR,	&TIS.TI_iprog },
330 	{ "key_a1",			"ka1",		"K1",	CAP_TYPE_STR,	&TIS.TI_ka1 },
331 	{ "key_a3",			"ka3",		"K3",	CAP_TYPE_STR,	&TIS.TI_ka3 },
332 	{ "key_b2",			"kb2",		"K2",	CAP_TYPE_STR,	&TIS.TI_kb2 },
333 	{ "key_c1",			"kc1",		"K4",	CAP_TYPE_STR,	&TIS.TI_kc1 },
334 	{ "key_c3",			"kc3",		"K5",	CAP_TYPE_STR,	&TIS.TI_kc3 },
335 	{ "prtr_non",			"mc5p",		"pO",	CAP_TYPE_STR,	&TIS.TI_mc5p },
336 	{ "char_padding",		"rmp",		"rP",	CAP_TYPE_STR,	&TIS.TI_rmp },
337 	{ "acs_chars",			"acsc",		"ac",	CAP_TYPE_STR,	&TIS.TI_acsc },
338 	{ "plab_norm",			"pln",		"pn",	CAP_TYPE_STR,	&TIS.TI_pln },
339 	{ "key_btab",			"kcbt",		"kB",	CAP_TYPE_STR,	&TIS.TI_kcbt },
340 	{ "enter_xon_mode",		"smxon",	"SX",	CAP_TYPE_STR,	&TIS.TI_smxon },
341 	{ "exit_xon_mode",		"rmxon",	"RX",	CAP_TYPE_STR,	&TIS.TI_rmxon },
342 	{ "enter_am_mode",		"smam",		"SA",	CAP_TYPE_STR,	&TIS.TI_smam },
343 	{ "exit_am_mode",		"rmam",		"RA",	CAP_TYPE_STR,	&TIS.TI_rmam },
344 	{ "xon_character",		"xonc",		"XN",	CAP_TYPE_STR,	&TIS.TI_xonc },
345 	{ "xoff_character",		"xoffc",	"XF",	CAP_TYPE_STR,	&TIS.TI_xoffc },
346 	{ "ena_acs",			"enacs",	"eA",	CAP_TYPE_STR,	&TIS.TI_enacs },
347 	{ "label_on",			"smln",		"LO",	CAP_TYPE_STR,	&TIS.TI_smln },
348 	{ "label_off",			"rmln",		"LF",	CAP_TYPE_STR,	&TIS.TI_rmln },
349 	{ "key_beg",			"kbeg",		"@1",	CAP_TYPE_STR,	&TIS.TI_kbeg },
350 	{ "key_cancel",			"kcan",		"@2",	CAP_TYPE_STR,	&TIS.TI_kcan },
351 	{ "key_close",			"kclo",		"@3",	CAP_TYPE_STR,	&TIS.TI_kclo },
352 	{ "key_command",		"kcmd",		"@4",	CAP_TYPE_STR,	&TIS.TI_kcmd },
353 	{ "key_copy",			"kcpy",		"@5",	CAP_TYPE_STR,	&TIS.TI_kcpy },
354 	{ "key_create",			"kcrt",		"@6",	CAP_TYPE_STR,	&TIS.TI_kcrt },
355 	{ "key_end",			"kend",		"@7",	CAP_TYPE_STR,	&TIS.TI_kend },
356 	{ "key_enter",			"kent",		"@8",	CAP_TYPE_STR,	&TIS.TI_kent },
357 	{ "key_exit",			"kext",		"@9",	CAP_TYPE_STR,	&TIS.TI_kext },
358 	{ "key_find",			"kfnd",		"@0",	CAP_TYPE_STR,	&TIS.TI_kfnd },
359 	{ "key_help",			"khlp",		"%1",	CAP_TYPE_STR,	&TIS.TI_khlp },
360 	{ "key_mark",			"kmrk",		"%2",	CAP_TYPE_STR,	&TIS.TI_kmrk },
361 	{ "key_message",		"kmsg",		"%3",	CAP_TYPE_STR,	&TIS.TI_kmsg },
362 	{ "key_move",			"kmov",		"%4",	CAP_TYPE_STR,	&TIS.TI_kmov },
363 	{ "key_next",			"knxt",		"%5",	CAP_TYPE_STR,	&TIS.TI_knxt },
364 	{ "key_open",			"kopn",		"%6",	CAP_TYPE_STR,	&TIS.TI_kopn },
365 	{ "key_options",		"kopt",		"%7",	CAP_TYPE_STR,	&TIS.TI_kopt },
366 	{ "key_previous",		"kprv",		"%8",	CAP_TYPE_STR,	&TIS.TI_kprv },
367 	{ "key_print",			"kprt",		"%9",	CAP_TYPE_STR,	&TIS.TI_kprt },
368 	{ "key_redo",			"krdo",		"%0",	CAP_TYPE_STR,	&TIS.TI_krdo },
369 	{ "key_reference",		"kref",		"&1",	CAP_TYPE_STR,	&TIS.TI_kref },
370 	{ "key_refresh",		"krfr",		"&2",	CAP_TYPE_STR,	&TIS.TI_krfr },
371 	{ "key_replace",		"krpl",		"&3",	CAP_TYPE_STR,	&TIS.TI_krpl },
372 	{ "key_restart",		"krst",		"&4",	CAP_TYPE_STR,	&TIS.TI_krst },
373 	{ "key_resume",			"kres",		"&5",	CAP_TYPE_STR,	&TIS.TI_kres },
374 	{ "key_save",			"ksav",		"&6",	CAP_TYPE_STR,	&TIS.TI_ksav },
375 	{ "key_suspend",		"kspd",		"&7",	CAP_TYPE_STR,	&TIS.TI_kspd },
376 	{ "key_undo",			"kund",		"&8",	CAP_TYPE_STR,	&TIS.TI_kund },
377 	{ "key_sbeg",			"kBEG",		"&9",	CAP_TYPE_STR,	&TIS.TI_kBEG },
378 	{ "key_scancel",		"kCAN",		"&0",	CAP_TYPE_STR,	&TIS.TI_kCAN },
379 	{ "key_scommand",		"kCMD",		"*1",	CAP_TYPE_STR,	&TIS.TI_kCMD },
380 	{ "key_scopy",			"kCPY",		"*2",	CAP_TYPE_STR,	&TIS.TI_kCPY },
381 	{ "key_screate",		"kCRT",		"*3",	CAP_TYPE_STR,	&TIS.TI_kCRT },
382 	{ "key_sdc",			"kDC",		"*4",	CAP_TYPE_STR,	&TIS.TI_kDC },
383 	{ "key_sdl",			"kDL",		"*5",	CAP_TYPE_STR,	&TIS.TI_kDL },
384 	{ "key_select",			"kslt",		"*6",	CAP_TYPE_STR,	&TIS.TI_kslt },
385 	{ "key_send",			"kEND",		"*7",	CAP_TYPE_STR,	&TIS.TI_kEND },
386 	{ "key_seol",			"kEOL",		"*8",	CAP_TYPE_STR,	&TIS.TI_kEOL },
387 	{ "key_sexit",			"kEXT",		"*9",	CAP_TYPE_STR,	&TIS.TI_kEXT },
388 	{ "key_sfind",			"kFND",		"*0",	CAP_TYPE_STR,	&TIS.TI_kFND },
389 	{ "key_shelp",			"kHLP",		"#1",	CAP_TYPE_STR,	&TIS.TI_kHLP },
390 	{ "key_shome",			"kHOM",		"#2",	CAP_TYPE_STR,	&TIS.TI_kHOM },
391 	{ "key_sic",			"kIC",		"#3",	CAP_TYPE_STR,	&TIS.TI_kIC },
392 	{ "key_sleft",			"kLFT",		"#4",	CAP_TYPE_STR,	&TIS.TI_kLFT },
393 	{ "key_smessage",		"kMSG",		"%a",	CAP_TYPE_STR,	&TIS.TI_kMSG },
394 	{ "key_smove",			"kMOV",		"%b",	CAP_TYPE_STR,	&TIS.TI_kMOV },
395 	{ "key_snext",			"kNXT",		"%c",	CAP_TYPE_STR,	&TIS.TI_kNXT },
396 	{ "key_soptions",		"kOPT",		"%d",	CAP_TYPE_STR,	&TIS.TI_kOPT },
397 	{ "key_sprevious",		"kPRV",		"%e",	CAP_TYPE_STR,	&TIS.TI_kPRV },
398 	{ "key_sprint",			"kPRT",		"%f",	CAP_TYPE_STR,	&TIS.TI_kPRT },
399 	{ "key_sredo",			"kRDO",		"%g",	CAP_TYPE_STR,	&TIS.TI_kRDO },
400 	{ "key_sreplace",		"kRPL",		"%h",	CAP_TYPE_STR,	&TIS.TI_kRPL },
401 	{ "key_sright",			"kRIT",		"%i",	CAP_TYPE_STR,	&TIS.TI_kRIT },
402 	{ "key_srsume",			"kRES",		"%j",	CAP_TYPE_STR,	&TIS.TI_kRES },
403 	{ "key_ssave",			"kSAV",		"!1",	CAP_TYPE_STR,	&TIS.TI_kSAV },
404 	{ "key_ssuspend",		"kSPD",		"!2",	CAP_TYPE_STR,	&TIS.TI_kSPD },
405 	{ "key_sundo",			"kUND",		"!3",	CAP_TYPE_STR,	&TIS.TI_kUND },
406 	{ "req_for_input",		"rfi",		"RF",	CAP_TYPE_STR,	&TIS.TI_rfi },
407 	{ "key_f11",			"kf11",		"F1",	CAP_TYPE_STR,	&TIS.TI_kf11 },
408 	{ "key_f12",			"kf12",		"F2",	CAP_TYPE_STR,	&TIS.TI_kf12 },
409 	{ "key_f13",			"kf13",		"F3",	CAP_TYPE_STR,	&TIS.TI_kf13 },
410 	{ "key_f14",			"kf14",		"F4",	CAP_TYPE_STR,	&TIS.TI_kf14 },
411 	{ "key_f15",			"kf15",		"F5",	CAP_TYPE_STR,	&TIS.TI_kf15 },
412 	{ "key_f16",			"kf16",		"F6",	CAP_TYPE_STR,	&TIS.TI_kf16 },
413 	{ "key_f17",			"kf17",		"F7",	CAP_TYPE_STR,	&TIS.TI_kf17 },
414 	{ "key_f18",			"kf18",		"F8",	CAP_TYPE_STR,	&TIS.TI_kf18 },
415 	{ "key_f19",			"kf19",		"F9",	CAP_TYPE_STR,	&TIS.TI_kf19 },
416 	{ "key_f20",			"kf20",		"FA",	CAP_TYPE_STR,	&TIS.TI_kf20 },
417 	{ "key_f21",			"kf21",		"FB",	CAP_TYPE_STR,	&TIS.TI_kf21 },
418 	{ "key_f22",			"kf22",		"FC",	CAP_TYPE_STR,	&TIS.TI_kf22 },
419 	{ "key_f23",			"kf23",		"FD",	CAP_TYPE_STR,	&TIS.TI_kf23 },
420 	{ "key_f24",			"kf24",		"FE",	CAP_TYPE_STR,	&TIS.TI_kf24 },
421 	{ "key_f25",			"kf25",		"FF",	CAP_TYPE_STR,	&TIS.TI_kf25 },
422 	{ "key_f26",			"kf26",		"FG",	CAP_TYPE_STR,	&TIS.TI_kf26 },
423 	{ "key_f27",			"kf27",		"FH",	CAP_TYPE_STR,	&TIS.TI_kf27 },
424 	{ "key_f28",			"kf28",		"FI",	CAP_TYPE_STR,	&TIS.TI_kf28 },
425 	{ "key_f29",			"kf29",		"FJ",	CAP_TYPE_STR,	&TIS.TI_kf29 },
426 	{ "key_f30",			"kf30",		"FK",	CAP_TYPE_STR,	&TIS.TI_kf30 },
427 	{ "key_f31",			"kf31",		"FL",	CAP_TYPE_STR,	&TIS.TI_kf31 },
428 	{ "key_f32",			"kf32",		"FM",	CAP_TYPE_STR,	&TIS.TI_kf32 },
429 	{ "key_f33",			"kf33",		"FN",	CAP_TYPE_STR,	&TIS.TI_kf33 },
430 	{ "key_f34",			"kf34",		"FO",	CAP_TYPE_STR,	&TIS.TI_kf34 },
431 	{ "key_f35",			"kf35",		"FP",	CAP_TYPE_STR,	&TIS.TI_kf35 },
432 	{ "key_f36",			"kf36",		"FQ",	CAP_TYPE_STR,	&TIS.TI_kf36 },
433 	{ "key_f37",			"kf37",		"FR",	CAP_TYPE_STR,	&TIS.TI_kf37 },
434 	{ "key_f38",			"kf38",		"FS",	CAP_TYPE_STR,	&TIS.TI_kf38 },
435 	{ "key_f39",			"kf39",		"FT",	CAP_TYPE_STR,	&TIS.TI_kf39 },
436 	{ "key_f40",			"kf40",		"FU",	CAP_TYPE_STR,	&TIS.TI_kf40 },
437 	{ "key_f41",			"kf41",		"FV",	CAP_TYPE_STR,	&TIS.TI_kf41 },
438 	{ "key_f42",			"kf42",		"FW",	CAP_TYPE_STR,	&TIS.TI_kf42 },
439 	{ "key_f43",			"kf43",		"FX",	CAP_TYPE_STR,	&TIS.TI_kf43 },
440 	{ "key_f44",			"kf44",		"FY",	CAP_TYPE_STR,	&TIS.TI_kf44 },
441 	{ "key_f45",			"kf45",		"FZ",	CAP_TYPE_STR,	&TIS.TI_kf45 },
442 	{ "key_f46",			"kf46",		"Fa",	CAP_TYPE_STR,	&TIS.TI_kf46 },
443 	{ "key_f47",			"kf47",		"Fb",	CAP_TYPE_STR,	&TIS.TI_kf47 },
444 	{ "key_f48",			"kf48",		"Fc",	CAP_TYPE_STR,	&TIS.TI_kf48 },
445 	{ "key_f49",			"kf49",		"Fd",	CAP_TYPE_STR,	&TIS.TI_kf49 },
446 	{ "key_f50",			"kf50",		"Fe",	CAP_TYPE_STR,	&TIS.TI_kf50 },
447 	{ "key_f51",			"kf51",		"Ff",	CAP_TYPE_STR,	&TIS.TI_kf51 },
448 	{ "key_f52",			"kf52",		"Fg",	CAP_TYPE_STR,	&TIS.TI_kf52 },
449 	{ "key_f53",			"kf53",		"Fh",	CAP_TYPE_STR,	&TIS.TI_kf53 },
450 	{ "key_f54",			"kf54",		"Fi",	CAP_TYPE_STR,	&TIS.TI_kf54 },
451 	{ "key_f55",			"kf55",		"Fj",	CAP_TYPE_STR,	&TIS.TI_kf55 },
452 	{ "key_f56",			"kf56",		"Fk",	CAP_TYPE_STR,	&TIS.TI_kf56 },
453 	{ "key_f57",			"kf57",		"Fl",	CAP_TYPE_STR,	&TIS.TI_kf57 },
454 	{ "key_f58",			"kf58",		"Fm",	CAP_TYPE_STR,	&TIS.TI_kf58 },
455 	{ "key_f59",			"kf59",		"Fn",	CAP_TYPE_STR,	&TIS.TI_kf59 },
456 	{ "key_f60",			"kf60",		"Fo",	CAP_TYPE_STR,	&TIS.TI_kf60 },
457 	{ "key_f61",			"kf61",		"Fp",	CAP_TYPE_STR,	&TIS.TI_kf61 },
458 	{ "key_f62",			"kf62",		"Fq",	CAP_TYPE_STR,	&TIS.TI_kf62 },
459 	{ "key_f63",			"kf63",		"Fr",	CAP_TYPE_STR,	&TIS.TI_kf63 },
460 	{ "clr_bol",			"el1",		"cb",	CAP_TYPE_STR,	&TIS.TI_el1 },
461 	{ "clear_margins",		"mgc",		"MC",	CAP_TYPE_STR,	&TIS.TI_mgc },
462 	{ "set_left_margin",		"smgl",		"ML",	CAP_TYPE_STR,	&TIS.TI_smgl },
463 	{ "set_right_margin",		"smgr",		"MR",	CAP_TYPE_STR,	&TIS.TI_smgr },
464 	{ "label_format",		"fln",		"Lf",	CAP_TYPE_STR,	&TIS.TI_fln },
465 	{ "set_clock",			"sclk",		"SC",	CAP_TYPE_STR,	&TIS.TI_sclk },
466 	{ "display_clock",		"dclk",		"DK",	CAP_TYPE_STR,	&TIS.TI_dclk },
467 	{ "remove_clock",		"rmclk",	"RC",	CAP_TYPE_STR,	&TIS.TI_rmclk },
468 	{ "create_window",		"cwin",		"CW",	CAP_TYPE_STR,	&TIS.TI_cwin },
469 	{ "goto_window",		"wingo",	"WG",	CAP_TYPE_STR,	&TIS.TI_wingo },
470 	{ "hangup",			"hup",		"HU",	CAP_TYPE_STR,	&TIS.TI_hup },
471 	{ "dial_phone",			"dial",		"DI",	CAP_TYPE_STR,	&TIS.TI_dial },
472 	{ "quick_dial",			"qdial",	"QD",	CAP_TYPE_STR,	&TIS.TI_qdial },
473 	{ "tone",			"tone",		"TO",	CAP_TYPE_STR,	&TIS.TI_tone },
474 	{ "pulse",			"pulse",	"PU",	CAP_TYPE_STR,	&TIS.TI_pulse },
475 	{ "flash_hook",			"hook",		"fh",	CAP_TYPE_STR,	&TIS.TI_hook },
476 	{ "fixed_pause",		"pause",	"PA",	CAP_TYPE_STR,	&TIS.TI_pause },
477 	{ "wait_tone",			"wait",		"WA",	CAP_TYPE_STR,	&TIS.TI_wait },
478 	{ "user0",			"u0",		"u0",	CAP_TYPE_STR,	&TIS.TI_u0 },
479 	{ "user1",			"u1",		"u1",	CAP_TYPE_STR,	&TIS.TI_u1 },
480 	{ "user2",			"u2",		"u2",	CAP_TYPE_STR,	&TIS.TI_u2 },
481 	{ "user3",			"u3",		"u3",	CAP_TYPE_STR,	&TIS.TI_u3 },
482 	{ "user4",			"u4",		"u4",	CAP_TYPE_STR,	&TIS.TI_u4 },
483 	{ "user5",			"u5",		"u5",	CAP_TYPE_STR,	&TIS.TI_u5 },
484 	{ "user6",			"u6",		"u6",	CAP_TYPE_STR,	&TIS.TI_u6 },
485 	{ "user7",			"u7",		"u7",	CAP_TYPE_STR,	&TIS.TI_u7 },
486 	{ "user8",			"u8",		"u8",	CAP_TYPE_STR,	&TIS.TI_u8 },
487 	{ "user9",			"u9",		"u9",	CAP_TYPE_STR,	&TIS.TI_u9 },
488 	{ "orig_pair",			"op",		"op",	CAP_TYPE_STR,	&TIS.TI_op },
489 	{ "orig_colors",		"oc",		"oc",	CAP_TYPE_STR,	&TIS.TI_oc },
490 	{ "initialize_color",		"initc",	"Ic",	CAP_TYPE_STR,	&TIS.TI_initc },
491 	{ "initialize_pair",		"initp",	"Ip",	CAP_TYPE_STR,	&TIS.TI_initp },
492 	{ "set_color_pair",		"scp",		"sp",	CAP_TYPE_STR,	&TIS.TI_scp },
493 	{ "set_foreground",		"setf",		"Sf",	CAP_TYPE_STR,	&TIS.TI_setf },
494 	{ "set_background",		"setb",		"Sb",	CAP_TYPE_STR,	&TIS.TI_setb },
495 	{ "change_char_pitch",		"cpi",		"ZA",	CAP_TYPE_STR,	&TIS.TI_cpi },
496 	{ "change_line_pitch",		"lpi",		"ZB",	CAP_TYPE_STR,	&TIS.TI_lpi },
497 	{ "change_res_horz",		"chr",		"ZC",	CAP_TYPE_STR,	&TIS.TI_chr },
498 	{ "change_res_vert",		"cvr",		"ZD",	CAP_TYPE_STR,	&TIS.TI_cvr },
499 	{ "define_char",		"defc",		"ZE",	CAP_TYPE_STR,	&TIS.TI_defc },
500 	{ "enter_doublewide_mode",	"swidm",	"ZF",	CAP_TYPE_STR,	&TIS.TI_swidm },
501 	{ "enter_draft_quality",	"sdrfq",	"ZG",	CAP_TYPE_STR,	&TIS.TI_sdrfq },
502 	{ "enter_italics_mode",		"sitm",		"ZH",	CAP_TYPE_STR,	&TIS.TI_sitm },
503 	{ "enter_leftward_mode",	"slm",		"ZI",	CAP_TYPE_STR,	&TIS.TI_slm },
504 	{ "enter_micro_mode",		"smicm",	"ZJ",	CAP_TYPE_STR,	&TIS.TI_smicm },
505 	{ "enter_near_letter_quality",	"snlq",		"ZK",	CAP_TYPE_STR,	&TIS.TI_snlq },
506 	{ "enter_normal_quality",	"snrmq",	"ZL",	CAP_TYPE_STR,	&TIS.TI_snrmq },
507 	{ "enter_shadow_mode",		"sshm",		"ZM",	CAP_TYPE_STR,	&TIS.TI_sshm },
508 	{ "enter_subscript_mode",	"ssubm",	"ZN",	CAP_TYPE_STR,	&TIS.TI_ssubm },
509 	{ "enter_superscript_mode",	"ssupm",	"ZO",	CAP_TYPE_STR,	&TIS.TI_ssupm },
510 	{ "enter_upward_mode",		"sum",		"ZP",	CAP_TYPE_STR,	&TIS.TI_sum },
511 	{ "exit_doublewide_mode",	"rwidm",	"ZQ",	CAP_TYPE_STR,	&TIS.TI_rwidm },
512 	{ "exit_italics_mode",		"ritm",		"ZR",	CAP_TYPE_STR,	&TIS.TI_ritm },
513 	{ "exit_leftward_mode",		"rlm",		"ZS",	CAP_TYPE_STR,	&TIS.TI_rlm },
514 	{ "exit_micro_mode",		"rmicm",	"ZT",	CAP_TYPE_STR,	&TIS.TI_rmicm },
515 	{ "exit_shadow_mode",		"rshm",		"ZU",	CAP_TYPE_STR,	&TIS.TI_rshm },
516 	{ "exit_subscript_mode",	"rsubm",	"ZV",	CAP_TYPE_STR,	&TIS.TI_rsubm },
517 	{ "exit_superscript_mode",	"rsupm",	"ZW",	CAP_TYPE_STR,	&TIS.TI_rsupm },
518 	{ "exit_upward_mode",		"rum",		"ZX",	CAP_TYPE_STR,	&TIS.TI_rum },
519 	{ "micro_column_address",	"mhpa",		"ZY",	CAP_TYPE_STR,	&TIS.TI_mhpa },
520 	{ "micro_down",			"mcud1",	"ZZ",	CAP_TYPE_STR,	&TIS.TI_mcud1 },
521 	{ "micro_left",			"mcub1",	"Za",	CAP_TYPE_STR,	&TIS.TI_mcub1 },
522 	{ "micro_right",		"mcuf1",	"Zb",	CAP_TYPE_STR,	&TIS.TI_mcuf1 },
523 	{ "micro_row_address",		"mvpa",		"Zc",	CAP_TYPE_STR,	&TIS.TI_mvpa },
524 	{ "micro_up",			"mcuu1",	"Zd",	CAP_TYPE_STR,	&TIS.TI_mcuu1 },
525 	{ "order_of_pins",		"porder",	"Ze",	CAP_TYPE_STR,	&TIS.TI_porder },
526 	{ "parm_down_micro",		"mcud",		"Zf",	CAP_TYPE_STR,	&TIS.TI_mcud },
527 	{ "parm_left_micro",		"mcub",		"Zg",	CAP_TYPE_STR,	&TIS.TI_mcub },
528 	{ "parm_right_micro",		"mcuf",		"Zh",	CAP_TYPE_STR,	&TIS.TI_mcuf },
529 	{ "parm_up_micro",		"mcuu",		"Zi",	CAP_TYPE_STR,	&TIS.TI_mcuu },
530 	{ "select_char_set",		"scs",		"Zj",	CAP_TYPE_STR,	&TIS.TI_scs },
531 	{ "set_bottom_margin",		"smgb",		"Zk",	CAP_TYPE_STR,	&TIS.TI_smgb },
532 	{ "set_bottom_margin_parm",	"smgbp",	"Zl",	CAP_TYPE_STR,	&TIS.TI_smgbp },
533 	{ "set_left_margin_parm",	"smglp",	"Zm",	CAP_TYPE_STR,	&TIS.TI_smglp },
534 	{ "set_right_margin_parm",	"smgrp",	"Zn",	CAP_TYPE_STR,	&TIS.TI_smgrp },
535 	{ "set_top_margin",		"smgt",		"Zo",	CAP_TYPE_STR,	&TIS.TI_smgt },
536 	{ "set_top_margin_parm",	"smgtp",	"Zp",	CAP_TYPE_STR,	&TIS.TI_smgtp },
537 	{ "start_bit_image",		"sbim",		"Zq",	CAP_TYPE_STR,	&TIS.TI_sbim },
538 	{ "start_char_set_def",		"scsd",		"Zr",	CAP_TYPE_STR,	&TIS.TI_scsd },
539 	{ "stop_bit_image",		"rbim",		"Zs",	CAP_TYPE_STR,	&TIS.TI_rbim },
540 	{ "stop_char_set_def",		"rcsd",		"Zt",	CAP_TYPE_STR,	&TIS.TI_rcsd },
541 	{ "subscript_characters",	"subcs",	"Zu",	CAP_TYPE_STR,	&TIS.TI_subcs },
542 	{ "superscript_characters",	"supcs",	"Zv",	CAP_TYPE_STR,	&TIS.TI_supcs },
543 	{ "these_cause_cr",		"docr",		"Zw",	CAP_TYPE_STR,	&TIS.TI_docr },
544 	{ "zero_motion",		"zerom",	"Zx",	CAP_TYPE_STR,	&TIS.TI_zerom },
545 	{ "char_set_names",		"csnm",		"Zy",	CAP_TYPE_STR,	&TIS.TI_csnm },
546 	{ "key_mouse",			"kmous",	"Km",	CAP_TYPE_STR,	&TIS.TI_kmous },
547 	{ "mouse_info",			"minfo",	"Mi",	CAP_TYPE_STR,	&TIS.TI_minfo },
548 	{ "req_mouse_pos",		"reqmp",	"RQ",	CAP_TYPE_STR,	&TIS.TI_reqmp },
549 	{ "get_mouse",			"getm",		"Gm",	CAP_TYPE_STR,	&TIS.TI_getm },
550 	{ "set_a_foreground",		"setaf",	"AF",	CAP_TYPE_STR,	&TIS.TI_setaf },
551 	{ "set_a_background",		"setab",	"AB",	CAP_TYPE_STR,	&TIS.TI_setab },
552 	{ "pkey_plab",			"pfxl",		"xl",	CAP_TYPE_STR,	&TIS.TI_pfxl },
553 	{ "device_type",		"devt",		"dv",	CAP_TYPE_STR,	&TIS.TI_devt },
554 	{ "code_set_init",		"csin",		"ci",	CAP_TYPE_STR,	&TIS.TI_csin },
555 	{ "set0_des_seq",		"s0ds",		"s0",	CAP_TYPE_STR,	&TIS.TI_s0ds },
556 	{ "set1_des_seq",		"s1ds",		"s1",	CAP_TYPE_STR,	&TIS.TI_s1ds },
557 	{ "set2_des_seq",		"s2ds",		"s2",	CAP_TYPE_STR,	&TIS.TI_s2ds },
558 	{ "set3_des_seq",		"s3ds",		"s3",	CAP_TYPE_STR,	&TIS.TI_s3ds },
559 	{ "set_lr_margin",		"smglr",	"ML",	CAP_TYPE_STR,	&TIS.TI_smglr },
560 	{ "set_tb_margin",		"smgtb",	"MT",	CAP_TYPE_STR,	&TIS.TI_smgtb },
561 	{ "bit_image_repeat",		"birep",	"Xy",	CAP_TYPE_STR,	&TIS.TI_birep },
562 	{ "bit_image_newline",		"binel",	"Zz",	CAP_TYPE_STR,	&TIS.TI_binel },
563 	{ "bit_image_carriage_return",	"bicr",		"Yv",	CAP_TYPE_STR,	&TIS.TI_bicr },
564 	{ "color_names",		"colornm",	"Yw",	CAP_TYPE_STR,	&TIS.TI_colornm },
565 	{ "define_bit_image_region",	"defbi",	"Yx",	CAP_TYPE_STR,	&TIS.TI_defbi },
566 	{ "end_bit_image_region",	"endbi",	"Yy",	CAP_TYPE_STR,	&TIS.TI_endbi },
567 	{ "set_color_band",		"setcolor",	"Yz",	CAP_TYPE_STR,	&TIS.TI_setcolor },
568 	{ "set_page_length",		"slines",	"YZ",	CAP_TYPE_STR,	&TIS.TI_slines },
569 	{ "display_pc_char",		"dispc",	"S1",	CAP_TYPE_STR,	&TIS.TI_dispc },
570 	{ "enter_pc_charset_mode",	"smpch",	"S2",	CAP_TYPE_STR,	&TIS.TI_smpch },
571 	{ "exit_pc_charset_mode",	"rmpch",	"S3",	CAP_TYPE_STR,	&TIS.TI_rmpch },
572 	{ "enter_scancode_mode",	"smsc",		"S4",	CAP_TYPE_STR,	&TIS.TI_smsc },
573 	{ "exit_scancode_mode",		"rmsc",		"S5",	CAP_TYPE_STR,	&TIS.TI_rmsc },
574 	{ "pc_term_options",		"pctrm",	"S6",	CAP_TYPE_STR,	&TIS.TI_pctrm },
575 	{ "scancode_escape",		"scesc",	"S7",	CAP_TYPE_STR,	&TIS.TI_scesc },
576 	{ "alt_scancode_esc",		"scesa",	"S8",	CAP_TYPE_STR,	&TIS.TI_scesa },
577 	{ "enter_horizontal_hl_mode",	"ehhlm",	"Xh",	CAP_TYPE_STR,	&TIS.TI_ehhlm },
578 	{ "enter_left_hl_mode",		"elhlm",	"Xl",	CAP_TYPE_STR,	&TIS.TI_elhlm },
579 	{ "enter_low_hl_mode",		"elohlm",	"Xo",	CAP_TYPE_STR,	&TIS.TI_elohlm },
580 	{ "enter_right_hl_mode",	"erhlm",	"Xr",	CAP_TYPE_STR,	&TIS.TI_erhlm },
581 	{ "enter_top_hl_mode",		"ethlm",	"Xt",	CAP_TYPE_STR,	&TIS.TI_ethlm },
582 	{ "enter_vertical_hl_mode",	"evhlm",	"Xv",	CAP_TYPE_STR,	&TIS.TI_evhlm },
583 	{ "set_a_attributes",		"sgr1",		"sA",	CAP_TYPE_STR,	&TIS.TI_sgr1 },
584 	{ "set_pglen_inch",		"slength",	"sL",	CAP_TYPE_STR,	&TIS.TI_slength },
585 	{ "termcap_init2",		"OTi2",		"i2",	CAP_TYPE_STR,	&TIS.TI_OTi2 },
586 	{ "termcap_reset",		"OTrs",		"rs",	CAP_TYPE_STR,	&TIS.TI_OTrs },
587 	{ "magic_cookie_glitch_ul",	"OTug",		"ug",	CAP_TYPE_INT,	(char **)&TIS.TI_OTug },
588 	{ "backspaces_with_bs",		"OTbs",		"bs",	CAP_TYPE_BOOL,	(char **)&TIS.TI_OTbs },
589 	{ "crt_no_scrolling",		"OTns",		"ns",	CAP_TYPE_BOOL,	(char **)&TIS.TI_OTns },
590 	{ "no_correctly_working_cr",	"OTnc",		"nc",	CAP_TYPE_BOOL,	(char **)&TIS.TI_OTnc },
591 	{ "carriage_return_delay",	"OTdC",		"dC",	CAP_TYPE_INT,	(char **)&TIS.TI_OTdC },
592 	{ "new_line_delay",		"OTdN",		"dN",	CAP_TYPE_INT,	(char **)&TIS.TI_OTdN },
593 	{ "linefeed_if_not_lf",		"OTnl",		"nl",	CAP_TYPE_STR,	&TIS.TI_OTnl },
594 	{ "backspace_if_not_bs",	"OTbc",		"bc",	CAP_TYPE_STR,	&TIS.TI_OTbc },
595 	{ "gnu_has_meta_key",		"OTMT",		"MT",	CAP_TYPE_BOOL,	(char **)&TIS.TI_OTMT },
596 	{ "linefeed_is_newline",	"OTNL",		"NL",	CAP_TYPE_BOOL,	(char **)&TIS.TI_OTNL },
597 	{ "backspace_delay",		"OTdB",		"dB",	CAP_TYPE_INT,	(char **)&TIS.TI_OTdB },
598 	{ "horizontal_tab_delay",	"OTdT",		"dT",	CAP_TYPE_INT,	(char **)&TIS.TI_OTdT },
599 	{ "number_of_function_keys",	"OTkn",		"kn",	CAP_TYPE_INT,	(char **)&TIS.TI_OTkn },
600 	{ "other_non_function_keys",	"OTko",		"ko",	CAP_TYPE_STR,	&TIS.TI_OTko },
601 	{ "arrow_key_map",		"OTma",		"ma",	CAP_TYPE_STR,	&TIS.TI_OTma },
602 	{ "has_hardware_tabs",		"OTpt",		"pt",	CAP_TYPE_BOOL,	(char **)&TIS.TI_OTpt },
603 	{ "return_does_clr_eol",	"OTxr",		"xr",	CAP_TYPE_BOOL,	(char **)&TIS.TI_OTxr },
604 	{ "acs_ulcorner",		"OTG2",		"G2",	CAP_TYPE_STR,	&TIS.TI_OTG2 },
605 	{ "acs_llcorner",		"OTG3",		"G3",	CAP_TYPE_STR,	&TIS.TI_OTG3 },
606 	{ "acs_urcorner",		"OTG1",		"G1",	CAP_TYPE_STR,	&TIS.TI_OTG1 },
607 	{ "acs_lrcorner",		"OTG4",		"G4",	CAP_TYPE_STR,	&TIS.TI_OTG4 },
608 	{ "acs_ltee",			"OTGR",		"GR",	CAP_TYPE_STR,	&TIS.TI_OTGR },
609 	{ "acs_rtee",			"OTGL",		"GL",	CAP_TYPE_STR,	&TIS.TI_OTGL },
610 	{ "acs_btee",			"OTGU",		"GU",	CAP_TYPE_STR,	&TIS.TI_OTGU },
611 	{ "acs_ttee",			"OTGD",		"GD",	CAP_TYPE_STR,	&TIS.TI_OTGD },
612 	{ "acs_hline",			"OTGH",		"GH",	CAP_TYPE_STR,	&TIS.TI_OTGH },
613 	{ "acs_vline",			"OTGV",		"GV",	CAP_TYPE_STR,	&TIS.TI_OTGV },
614 	{ "acs_plus",			"OTGC",		"GC",	CAP_TYPE_STR,	&TIS.TI_OTGC },
615 	{ "memory_lock",		"meml",		"ml",	CAP_TYPE_STR,	&TIS.TI_meml },
616 	{ "memory_unlock",		"memu",		"mu",	CAP_TYPE_STR,	&TIS.TI_memu },
617 	{ "box_chars_1",		"box1",		"bx",	CAP_TYPE_STR,	&TIS.TI_box1 },
618 };
619 
620 	struct	term_struct *current_term = &TIS;
621 	int 	numcaps = sizeof(tcaps) / sizeof(cap2info);
622 
623 	int	meta_mode = 2;
624 	int	can_color = 0;
625 	int	need_redraw = 0;
626 static	int	term_echo_flag = 1;
627 static	int	li;
628 static	int	co;
629 
630 #if !defined(__EMX__) && !defined(WINNT) && !defined(GUI)
631 #ifndef HAVE_TERMINFO
632 static	char	termcap[2048];	/* bigger than we need, just in case */
633 #endif
634 static	char	termcap2[2048];	/* bigger than we need, just in case */
635 #endif
636 
637 /*
638  * Any GUI system modules must be included here to make the GUI support
639  *  routines accessable to the rest of BitchX.
640  */
641 #ifndef WTERM_C
642 #ifdef __EMXPM__
643 #include "PMBitchX.c"
644 #elif defined(GTK)
645 #include "gtkbitchx.c"
646 #elif defined(WIN32)
647 #include "winbitchx.c"
648 #endif
649 #endif
650 /*
651  * term_echo: if 0, echo is turned off (all characters appear as blanks), if
652  * non-zero, all is normal.  The function returns the old value of the
653  * term_echo_flag
654  */
term_echo(int flag)655 int	term_echo (int flag)
656 {
657 	int	echo;
658 
659 	echo = term_echo_flag;
660 	term_echo_flag = flag;
661 	return (echo);
662 }
663 
664 /*
665  * term_putchar: puts a character to the screen, and displays control
666  * characters as inverse video uppercase letters.  NOTE:  Dont use this to
667  * display termcap control sequences!  It won't work!
668  *
669  * Um... well, it will work if DISPLAY_ANSI_VAR is set to on... (hop)
670  */
term_putchar(unsigned char c)671 void	term_putchar (unsigned char c)
672 {
673 	if (!term_echo_flag)
674 	{
675 		putchar_x(' ');
676 		return;
677 	}
678 	/* Sheer, raving paranoia */
679 #ifndef __EMX__
680 	if (!(newb.c_cflag & CS8) && (c & 0x80))
681 		c &= ~0x80;
682 #endif
683 	/*
684 	 * This mangles all the unprintable control characters
685 	 * except for the escape character.  This will only support
686 	 * escape sequences that use ESC + any normal, printable
687 	 * characters (this is an assumption throughout the program).
688 	 * While you can use a non-vt100 emulation, the output will
689 	 * probably be mangled in several places.
690 	 */
691 	if (c < 0x20 || c == 0x9b) /* all ctl chars except ESC */
692 	{
693 		term_standout_on();
694 		putchar_x((c | 0x40) & 0x7f); /* Convert to printable */
695 		term_standout_off();
696 	}
697 	else if (c == 0x7f) 	/* delete char */
698 	{
699 		term_standout_on();
700 		putchar_x('?');
701 		term_standout_off();
702 	}
703 	else
704 		putchar_x(c);
705 }
706 
707 /*
708  * term_reset: sets terminal attributed back to what they were before the
709  * program started
710  */
term_reset(void)711 void term_reset (void)
712 {
713 	tcsetattr(tty_des, TCSADRAIN, &oldb);
714 
715 	if (current_term->TI_csr)
716 		tputs_x(tparm2(current_term->TI_csr, 0, current_term->TI_lines - 1));
717 	term_gotoxy(0, current_term->TI_lines - 1);
718 #if use_alt_screen
719 	if (current_term->TI_rmcup)
720 		tputs_x(current_term->TI_rmcup);
721 #endif
722 #if use_automargins
723 	if (current_term->TI_am && current_term->TI_smam)
724 		tputs_x(current_term->TI_smam);
725 #endif
726 	term_flush();
727 }
728 
term_reset2(void)729 void term_reset2 (void)
730 {
731 	tcsetattr(tty_des, TCSADRAIN, &oldb);
732 	term_flush();
733 }
734 
735 /*
736  * term_cont: sets the terminal back to IRCII stuff when it is restarted
737  * after a SIGSTOP.  Somewhere, this must be used in a signal() call
738  */
SIGNAL_HANDLER(term_cont)739 SIGNAL_HANDLER(term_cont)
740 {
741 extern int foreground;
742 	use_input = foreground = (tcgetpgrp(0) == getpgrp());
743 	if (foreground)
744 	{
745 #if use_alt_screen
746 		if (current_term->TI_smcup)
747 			tputs_x(current_term->TI_smcup);
748 #endif
749 #if use_automargins
750 		if (current_term->TI_rmam)
751 			tputs_x(current_term->TI_rmam);
752 #endif
753 		need_redraw = 1;
754 		tcsetattr(tty_des, TCSADRAIN, &newb);
755 	}
756 }
757 
758 #if !defined(STERM_C)
759 /*
760  * term_pause: sets terminal back to pre-program days, then SIGSTOPs itself.
761  */
term_pause(char unused,char * not_used)762 extern void term_pause (char unused, char *not_used)
763 {
764 #ifndef PUBLIC_ACCESS
765 #ifdef WINNT
766 char *shell;
767 DWORD dwmode;
768 HANDLE hstdin=GetStdHandle(STD_INPUT_HANDLE);
769 STARTUPINFO si = { 0 };
770 PROCESS_INFORMATION pi = { 0 };
771 
772 	si.cb = sizeof(si);
773 
774 	if (!(shell = get_string_var(SHELL_VAR)))
775 	{
776 		if (gdwPlatform == VER_PLATFORM_WIN32_WINDOWS)
777 			shell = "command.com";
778 		else
779 			shell = "cmd.exe";
780 	}
781 	if (!(GetConsoleMode(hstdin,&dwmode)))
782 		return;
783 
784 	if (!SetConsoleMode(hstdin, dwmode | ((ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT) & ~ENABLE_WINDOW_INPUT)))
785 		return;
786 
787 	if(!CreateProcess(NULL, shell, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) )
788 		return;
789 	CloseHandle(pi.hThread);
790 	WaitForSingleObject(pi.hProcess,INFINITE);
791 	CloseHandle(pi.hProcess);
792 
793 	if (!SetConsoleMode(hstdin, dwmode ) )
794 		return;
795 	refresh_screen(0,NULL);
796 #else
797 
798 	term_reset();
799 #ifndef __EMX__
800 	kill(getpid(), SIGSTOP);
801 #endif
802 #endif
803 #endif /* PUBLIC_ACCESS */
804 }
805 #endif /* STERM_C */
806 #endif /* NOT IN WTERM_C */
807 
808 /*
809  * term_init: does all terminal initialization... reads termcap info, sets
810  * the terminal to CBREAK, no ECHO mode.   Chooses the best of the terminal
811  * attributes to use ..  for the version of this function that is called for
812  * wserv, we set the termial to RAW, no ECHO, so that all the signals are
813  * ignored.. fixes quite a few problems...  -phone, jan 1993..
814  */
815 int termfeatures = 0;
816 
term_init(char * term)817 int term_init (char *term)
818 {
819 #ifndef WTERM_C
820 	int i;
821 	int desired;
822 	char *termcap2_ptr = termcap2;
823 
824 #if !defined(__EMX__) && !defined(WINNT) && !defined(GUI)
825 	memset(current_term, 0, sizeof(struct term_struct));
826 
827 	if (dumb_mode)
828 		ircpanic("term_init called in dumb_mode");
829 	*termcap2 = 0;
830 	if (!term && !(term = getenv("TERM")))
831 	{
832 		fprintf(stderr, "\n");
833 		fprintf(stderr, "You do not have a TERM environment variable.\n");
834 		fprintf(stderr, "So we'll be running in dumb mode...\n");
835 		return -1;
836 	}
837 #ifdef WANT_DETACH
838 	else if (!already_detached)
839 		fprintf(stdout, "Using terminal type [%s]\n", term);
840 #endif
841 #ifdef HAVE_TERMINFO
842 	if (setupterm(NULL, 1, &i) == ERR)
843 	{
844 		fprintf(stderr, "setupterm failed: %d\n", i);
845 		fprintf(stderr, "So we'll be running in dumb mode...\n");
846 		return -1;
847 	}
848 #else
849 	if (tgetent(termcap, term) < 1)
850 	{
851 		fprintf(stderr, "\n");
852 		fprintf(stderr, "Your current TERM setting (%s) does not have a termcap entry.\n", term);
853 		fprintf(stderr, "So we'll be running in dumb mode...\n");
854 		return -1;
855 	}
856 #endif
857 
858 	for (i = 0; i < numcaps; i++)
859 	{
860 		if (tcaps[i].type == CAP_TYPE_INT)
861 		{
862 			*(int *)tcaps[i].ptr = Tgetnum(tcaps[i]);
863 		}
864 		else if (tcaps[i].type == CAP_TYPE_BOOL)
865 		{
866 			*(int *)tcaps[i].ptr = Tgetflag(tcaps[i]);
867 		}
868 		else
869 		{
870 			char *cval = Tgetstr(tcaps[i], termcap2_ptr);
871 			if (cval == (char *) -1)
872 				cval = NULL;
873 			*(char **)tcaps[i].ptr = cval;
874 		}
875 	}
876 
877 	BC = current_term->TI_cub1;
878 	UP = current_term->TI_cuu1;
879 	if (current_term->TI_pad)
880 		my_PC = current_term->TI_pad[0];
881 	else
882 		my_PC = 0;
883 
884 	if (BC)
885 		BClen = strlen(BC);
886 	else
887 		BClen = 0;
888 	if (UP)
889 		UPlen = strlen(UP);
890 	else
891 		UPlen = 0;
892 
893 	li = current_term->TI_lines;
894 	co = current_term->TI_cols;
895 	if (!co)
896 		co = 79;
897 	if (!li)
898 		li = 24;
899 
900 	if (!current_term->TI_nel)
901 		current_term->TI_nel = "\n";
902 	if (!current_term->TI_cr)
903 		current_term->TI_cr = "\r";
904 
905 	current_term->TI_normal[0] = 0;
906 	if (current_term->TI_sgr0)
907 	{
908 		strcat(current_term->TI_normal, current_term->TI_sgr0);
909 	}
910 	if (current_term->TI_rmso)
911 	{
912 		if (current_term->TI_sgr0 && strcmp(current_term->TI_rmso, current_term->TI_sgr0))
913 			strcat(current_term->TI_normal, current_term->TI_rmso);
914 	}
915 	if (current_term->TI_rmul)
916 	{
917 		if (current_term->TI_sgr0 && strcmp(current_term->TI_rmul, current_term->TI_sgr0))
918 			strcat (current_term->TI_normal, current_term->TI_rmul);
919 	}
920 
921 
922 #else
923 
924 #if defined(WINNT) && !defined(GUI)
925 	CONSOLE_SCREEN_BUFFER_INFO scrbuf;
926 	HANDLE hinput =GetStdHandle(STD_INPUT_HANDLE);
927 	DWORD dwmode;
928 	OSVERSIONINFO osver;
929 
930 	ghstdout = GetStdHandle(STD_OUTPUT_HANDLE);
931 
932 	if(!GetConsoleScreenBufferInfo(ghstdout, &gscrbuf) )
933 	{
934 		fprintf(stderr,"Error from getconsolebufinfo %d\n",GetLastError());
935 		abort();
936 	}
937 
938 	GetConsoleMode(hinput,&dwmode);
939 	SetConsoleMode(hinput,dwmode & (~(ENABLE_LINE_INPUT |ENABLE_ECHO_INPUT
940 				| ENABLE_PROCESSED_INPUT)| ENABLE_WINDOW_INPUT/* | ENABLE_WRAP_AT_EOL_OUTPUT*/)
941 				);
942 
943 	osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
944 	GetVersionEx(&osver);
945 	gdwPlatform = osver.dwPlatformId;
946 
947 	GetConsoleCursorInfo(hinput, &gcursbuf);
948 
949 	GetConsoleScreenBufferInfo(ghstdout, &scrbuf);
950 	li = scrbuf.srWindow.Bottom - scrbuf.srWindow.Top + 1;
951 	co = scrbuf.srWindow.Right - scrbuf.srWindow.Left + 1;
952 
953 	memset(current_term, 0, sizeof(struct term_struct));
954 
955 	current_term->TI_lines = li;
956 	current_term->TI_cols = co - 1;
957 #elif defined(GUI)
958 
959 	memset(current_term, 0, sizeof(struct term_struct));
960 	gui_init();
961 #else
962 	vmode.cb = sizeof(VIOMODEINFO);
963 	VioGetMode(&vmode, 0);
964 	default_pair[0] = ' ';
965 	default_pair[1] = 7;
966 
967 	memset(current_term, 0, sizeof(struct term_struct));
968 
969 	current_term->TI_lines = vmode.row;
970 	current_term->TI_cols = vmode.col;
971 	li = current_term->TI_lines;
972 	co = current_term->TI_cols;
973 #endif
974 
975 	current_term->TI_cup = strdup("\e[%i%d;%dH");
976 	current_term->TI_cub1 = strdup("\e[D");
977 	current_term->TI_clear = strdup("\e[H\e[2J");
978 	current_term->TI_el = strdup("\e[K");
979 	current_term->TI_mrcup = strdup("\e[%i%d;%dH");
980 	current_term->TI_cub = strdup("\e[D");
981 	current_term->TI_cuf = strdup("\e[C");
982 	current_term->TI_cuf1 = strdup("\e[C");
983 	current_term->TI_smso = strdup("\e[7m");
984 	current_term->TI_rmso = strdup("\e[0m");
985 #ifdef GTK
986 	current_term->TI_smul = strdup("\e[4m");
987 	current_term->TI_rmul = strdup("\e[24m");
988 #else
989 	current_term->TI_smul = strdup("\e[1;34m");
990 	current_term->TI_rmul = strdup("\e[0;37m");
991 #endif
992 	current_term->TI_bold = strdup("\e[1;37m");
993 	current_term->TI_sgr0 = strdup("\e[0;37m");
994 	current_term->TI_blink = strdup("\e[5m");
995 	current_term->TI_normal[0]=0;
996 
997 #ifdef GTK
998 	current_term->TI_csr = strdup("\e[%i%p1%d;%p2%dr");
999 #endif
1000 	current_term->TI_ri = strdup("\eM");
1001 	current_term->TI_ind = strdup("\n");
1002 	current_term->TI_il = strdup("\e[%p1%dL");
1003 	current_term->TI_il1 = strdup("\e[L");
1004 	current_term->TI_dl = strdup("\e[%p1%dM");
1005 	current_term->TI_dl1 = strdup("\e[M");
1006 
1007 	strcat(current_term->TI_normal, current_term->TI_sgr0);
1008 	strcat(current_term->TI_normal, current_term->TI_rmso);
1009 
1010 	current_term->TI_cr = strdup("\r");
1011 	current_term->TI_nel = strdup("\n");
1012 	current_term->TI_bel = strdup("\007");
1013 	current_term->TI_cub = strdup("\010");
1014 #ifdef __EMXPM__
1015 	current_term->TI_kend = strdup("\eO");
1016 	current_term->TI_khome = strdup("\eG");
1017 	current_term->TI_knp = strdup("\eQ");
1018 	current_term->TI_kpp = strdup("\eI");
1019 	current_term->TI_kcuf1 = strdup("\eM");
1020 	current_term->TI_kcub1 = strdup("\eK");
1021 	current_term->TI_kcuu1 = strdup("\eH");
1022 	current_term->TI_kcud1 = strdup("\eP");
1023 #else
1024 	current_term->TI_kend = strdup("\e[4~");
1025 	current_term->TI_khome = strdup("\e[1~");
1026 	current_term->TI_knp = strdup("\e[6~");
1027 	current_term->TI_kpp = strdup("\e[5~");
1028 	current_term->TI_kcuf1 = strdup("\e[C");
1029 	current_term->TI_kcub1 = strdup("\e[D");
1030 	current_term->TI_kcuu1 = strdup("\e[A");
1031 	current_term->TI_kcud1 = strdup("\e[B");
1032 #endif
1033 #endif
1034 
1035 	/*
1036 	 * Finally set up the current_term->TI_sgrstrs array.  Clean it out first...
1037 	 */
1038 	for (i = 0; i < TERM_SGR_MAXVAL; i++)
1039 		current_term->TI_sgrstrs[i] = empty_string;
1040 
1041 
1042 	if (current_term->TI_bold)
1043 		current_term->TI_sgrstrs[TERM_SGR_BOLD_ON-1] = current_term->TI_bold;
1044 	if (current_term->TI_sgr0)
1045 	{
1046 		current_term->TI_sgrstrs[TERM_SGR_BOLD_OFF - 1] = current_term->TI_sgr0;
1047 		current_term->TI_sgrstrs[TERM_SGR_BLINK_OFF - 1] = current_term->TI_sgr0;
1048 	}
1049 	if (current_term->TI_blink)
1050 		current_term->TI_sgrstrs[TERM_SGR_BLINK_ON - 1] = current_term->TI_blink;
1051 	if (current_term->TI_smul)
1052 		current_term->TI_sgrstrs[TERM_SGR_UNDL_ON - 1] = current_term->TI_smul;
1053 	if (current_term->TI_rmul)
1054 		current_term->TI_sgrstrs[TERM_SGR_UNDL_OFF - 1] = current_term->TI_rmul;
1055 	if (current_term->TI_smso)
1056 		current_term->TI_sgrstrs[TERM_SGR_REV_ON - 1] = current_term->TI_smso;
1057 	if (current_term->TI_rmso)
1058 		current_term->TI_sgrstrs[TERM_SGR_REV_OFF - 1] = current_term->TI_rmso;
1059 	if (current_term->TI_smacs)
1060 		current_term->TI_sgrstrs[TERM_SGR_ALTCHAR_ON - 1] = current_term->TI_smacs;
1061 	if (current_term->TI_rmacs)
1062 		current_term->TI_sgrstrs[TERM_SGR_ALTCHAR_OFF - 1] = current_term->TI_rmacs;
1063 	if (current_term->TI_normal[0])
1064 	{
1065 		current_term->TI_sgrstrs[TERM_SGR_NORMAL - 1] = current_term->TI_normal;
1066 		current_term->TI_sgrstrs[TERM_SGR_RESET - 1] = current_term->TI_normal;
1067 	}
1068 
1069 
1070 	/*
1071 	 * Now figure out whether or not this terminal is "capable enough"
1072 	 * for the client. This is a rather complicated set of tests, as
1073 	 * we have many ways of doing the same thing.
1074 	 * To keep the set of tests easier, we set up a bitfield integer
1075 	 * which will have the desired capabilities added to it. If after
1076 	 * all the checks we dont have the desired mask, we dont have a
1077 	 * capable enough terminal.
1078 	 */
1079 	desired = TERM_CAN_CUP | TERM_CAN_CLEAR | TERM_CAN_CLREOL |
1080 		TERM_CAN_RIGHT | TERM_CAN_LEFT | TERM_CAN_SCROLL;
1081 
1082 	termfeatures = 0;
1083 	if (current_term->TI_cup)
1084 		termfeatures |= TERM_CAN_CUP;
1085 	if (current_term->TI_hpa && current_term->TI_vpa)
1086 		termfeatures |= TERM_CAN_CUP;
1087 	if (current_term->TI_clear)
1088 		termfeatures |= TERM_CAN_CLEAR;
1089 	if (current_term->TI_ed)
1090 		termfeatures |= TERM_CAN_CLEAR;
1091 	if (current_term->TI_dl || current_term->TI_dl1)
1092 		termfeatures |= TERM_CAN_CLEAR;
1093 	if (current_term->TI_il || current_term->TI_il1)
1094 		termfeatures |= TERM_CAN_CLEAR;
1095 	if (current_term->TI_el)
1096 		termfeatures |= TERM_CAN_CLREOL;
1097 	if (current_term->TI_cub || current_term->TI_mrcup || current_term->TI_cub1 || current_term->TI_kbs)
1098 		termfeatures |= TERM_CAN_LEFT;
1099 	if (current_term->TI_cuf  || current_term->TI_cuf1 || current_term->TI_mrcup)
1100 		termfeatures |= TERM_CAN_RIGHT;
1101 	if (current_term->TI_dch || current_term->TI_dch1)
1102 		termfeatures |= TERM_CAN_DELETE;
1103 	if (current_term->TI_ich || current_term->TI_ich1)
1104 		termfeatures |= TERM_CAN_INSERT;
1105 	if (current_term->TI_rep)
1106 		termfeatures |= TERM_CAN_REPEAT;
1107 	if (current_term->TI_csr && (current_term->TI_ri || current_term->TI_rin) && (current_term->TI_ind || current_term->TI_indn))
1108 		termfeatures |= TERM_CAN_SCROLL;
1109 	if (current_term->TI_wind && (current_term->TI_ri || current_term->TI_rin) && (current_term->TI_ind || current_term->TI_indn))
1110 		termfeatures |= TERM_CAN_SCROLL;
1111 	if ((current_term->TI_il || current_term->TI_il1) && (current_term->TI_dl || current_term->TI_dl1))
1112 		termfeatures |= TERM_CAN_SCROLL;
1113 	if (current_term->TI_bold && current_term->TI_sgr0)
1114 		termfeatures |= TERM_CAN_BOLD;
1115 	if (current_term->TI_blink && current_term->TI_sgr0)
1116 		termfeatures |= TERM_CAN_BLINK;
1117 	if (current_term->TI_smul && current_term->TI_rmul)
1118 		termfeatures |= TERM_CAN_UNDL;
1119 	if (current_term->TI_smso && current_term->TI_rmso)
1120 		termfeatures |= TERM_CAN_REVERSE;
1121 	if (current_term->TI_dispc)
1122 		termfeatures |= TERM_CAN_GCHAR;
1123 	if ((current_term->TI_setf && current_term->TI_setb) || (current_term->TI_setaf && current_term->TI_setab))
1124 		termfeatures |= TERM_CAN_COLOR;
1125 
1126 #if !defined(__EMX__) && !defined(WINNT) && !defined(GUI)
1127 	if ((termfeatures & desired) != desired)
1128 	{
1129 		fprintf(stderr, "\nYour terminal (%s) cannot run IRC II in full screen mode.\n", term);
1130 		fprintf(stderr, "The following features are missing from your TERM setting.\n");
1131 		if (!(termfeatures & TERM_CAN_CUP))
1132 			fprintf (stderr, "\tCursor movement\n");
1133 		if (!(termfeatures & TERM_CAN_CLEAR))
1134 			fprintf(stderr, "\tClear screen\n");
1135 		if (!(termfeatures & TERM_CAN_CLREOL))
1136 			fprintf(stderr, "\tClear to end-of-line\n");
1137 		if (!(termfeatures & TERM_CAN_RIGHT))
1138 			fprintf(stderr, "\tCursor right\n");
1139 		if (!(termfeatures & TERM_CAN_LEFT))
1140 			fprintf(stderr, "\tCursor left\n");
1141 		if (!(termfeatures & TERM_CAN_SCROLL))
1142 			fprintf(stderr, "\tScrolling\n");
1143 
1144 		fprintf(stderr, "So we'll be running in dumb mode...\n");
1145 		return -1;
1146 	}
1147 #endif
1148 
1149 	if (!current_term->TI_cub1)
1150 	{
1151 		if (current_term->TI_kbs)
1152 			current_term->TI_cub1 = current_term->TI_kbs;
1153 		else
1154 			current_term->TI_cub1 = "\b";
1155 	}
1156 	if (!current_term->TI_bel)
1157 		current_term->TI_bel = "\007";
1158 
1159 	/*
1160 	 * Default to no colors. (ick)
1161 	 */
1162 	for (i = 0; i < 16; i++)
1163 		current_term->TI_forecolors[i] = current_term->TI_backcolors[i] = empty_string;
1164 
1165 	/*
1166 	 * Set up colors.
1167 	 * Absolute fallbacks are for ansi-type colors
1168 	 */
1169 	for (i = 0; i < 16; i++)
1170 	{
1171 		char cbuf[128];
1172 
1173 		cbuf[0] = '\0';
1174 		if (i >= 8)
1175 			strcpy(cbuf, current_term->TI_sgrstrs[TERM_SGR_BOLD_ON-1]);
1176 		if (current_term->TI_setaf)
1177 			strcat(cbuf, tparm2(current_term->TI_setaf, i & 0x07, 0));
1178 		else if (current_term->TI_setf)
1179 			strcat(cbuf, tparm2(current_term->TI_setf, i & 0x07, 0));
1180 		else if (i >= 8)
1181 			sprintf(cbuf, "\033[1;%dm", (i & 0x07) + 30);
1182 		else
1183 			sprintf(cbuf, "\033[%dm", (i & 0x07) + 30);
1184 
1185 		current_term->TI_forecolors[i] = m_strdup(cbuf);
1186 	}
1187 
1188 	for (i = 0; i < 16; i++)
1189 	{
1190 		char cbuf[128];
1191 
1192 		cbuf[0] = '\0';
1193 		if (i >= 8)
1194 			strcpy(cbuf, current_term->TI_sgrstrs[TERM_SGR_BLINK_ON - 1]);
1195 
1196 		if (current_term->TI_setab)
1197 			strcat(cbuf, tparm2(current_term->TI_setab, i & 0x07, 0));
1198 		else if (current_term->TI_setb)
1199 			strcat(cbuf, tparm2(current_term->TI_setb, i & 0x07, 0));
1200 		else if (i >= 8)
1201 			sprintf(cbuf, "\033[1;%dm", (i & 0x07) + 40);
1202 		else
1203 			sprintf(cbuf, "\033[%dm", (i & 0x07) + 40);
1204 
1205 		current_term->TI_backcolors[i] = m_strdup(cbuf);
1206 	}
1207 #endif /* NOT IN WTERM_C */
1208 	tty_des = 0;
1209 #ifndef GTK
1210 	reinit_term(tty_des);
1211 #endif
1212 	return 0;
1213 }
1214 
reinit_term(int tty)1215 void reinit_term(int tty)
1216 {
1217 	/* Set up the terminal discipline */
1218 	tcgetattr(tty, &oldb);
1219 
1220 	newb = oldb;
1221 	newb.c_lflag &= ~(ICANON | ECHO); /* set equ. of CBREAK, no ECHO */
1222 	newb.c_cc[VMIN] = 1;	          /* read() satified after 1 char */
1223 	newb.c_cc[VTIME] = 0;	         /* No timer */
1224 
1225 #       if !defined(_POSIX_VDISABLE)
1226 #               if defined(HAVE_FPATHCONF)
1227 #                       define _POSIX_VDISABLE fpathconf(tty, _PC_VDISABLE)
1228 #               else
1229 #                       define _POSIX_VDISABLE 0
1230 #               endif
1231 #       endif
1232 
1233 	newb.c_cc[VQUIT] = _POSIX_VDISABLE;
1234 #	ifdef VDSUSP
1235 		newb.c_cc[VDSUSP] = _POSIX_VDISABLE;
1236 # 	endif
1237 #	ifdef VSUSP
1238 		newb.c_cc[VSUSP] = _POSIX_VDISABLE;
1239 #	endif
1240 
1241 #ifndef WTERM_C
1242 	if (!use_flow_control)
1243 		newb.c_iflag &= ~IXON;	/* No XON/XOFF */
1244 	/* Ugh. =) This is annoying! */
1245 #if use_alt_screen
1246 	if (current_term->TI_smcup)
1247 		tputs_x(current_term->TI_smcup);
1248 #endif
1249 #if use_automargins
1250 	if (current_term->TI_rmam)
1251 		tputs_x(current_term->TI_rmam);
1252 #endif
1253 #endif
1254 
1255 	tcsetattr(tty, TCSADRAIN, &newb);
1256 	tty_des = tty;
1257 	return;
1258 }
1259 
1260 
1261 #ifndef WTERM_C
1262 
tty_dup(int tty)1263 void tty_dup(int tty)
1264 {
1265 	close (tty_des);
1266 	dup2(tty, tty_des);
1267 }
1268 
reset_lines(int nlines)1269 void reset_lines(int nlines)
1270 {
1271 	li = nlines;
1272 }
1273 
reset_cols(int cols)1274 void reset_cols(int cols)
1275 {
1276 	co = cols;
1277 }
1278 
1279 /*
1280  * term_resize: gets the terminal height and width.  Trys to get the info
1281  * from the tty driver about size, if it can't... uses the termcap values. If
1282  * the terminal size has changed since last time term_resize() has been
1283  * called, 1 is returned.  If it is unchanged, 0 is returned.
1284  */
term_resize(void)1285 int term_resize (void)
1286 {
1287 #ifndef GUI
1288 	static	int	old_li = -1,
1289 			old_co = -1;
1290 #	if defined (TIOCGWINSZ)
1291 	{
1292 		struct winsize window;
1293 
1294 		if (ioctl(tty_des, TIOCGWINSZ, &window) < 0)
1295 		{
1296 			current_term->TI_lines = li;
1297 			current_term->TI_cols = co;
1298 		}
1299 		else
1300 		{
1301 			if ((current_term->TI_lines = window.ws_row) == 0)
1302 				current_term->TI_lines = li;
1303 			if ((current_term->TI_cols = (window.ws_col)) == 0)
1304 				current_term->TI_cols = co;
1305 		}
1306 	}
1307 #	else
1308 	{
1309 		current_term->TI_lines = li;
1310 		current_term->TI_cols = co;
1311 	}
1312 #	endif
1313 
1314 #if use_automargins
1315 	if (!current_term->TI_am || !current_term->TI_rmam)
1316 	{
1317 		current_term->TI_cols--;
1318 	}
1319 #else
1320 	current_term->TI_cols--;
1321 #endif
1322 	if ((old_li != current_term->TI_lines) || (old_co != current_term->TI_cols))
1323 	{
1324 		old_li = current_term->TI_lines;
1325 		old_co = current_term->TI_cols;
1326 		if (main_screen)
1327 		{
1328 			main_screen->li = current_term->TI_lines;
1329 			main_screen->co = current_term->TI_cols;
1330 		}
1331 		return (1);
1332 	}
1333 
1334 #endif /* GUI */
1335 	return (0);
1336 }
1337 
1338 
1339 /* term_CE_clear_to_eol(): the clear to eol function, right? */
term_clreol(void)1340 void term_clreol (void)
1341 {
1342 #ifdef GUI
1343 	gui_clreol();
1344 #else
1345 	tputs_x(current_term->TI_el);
1346 #endif
1347 	return;
1348 }
1349 
1350 /* Set the cursor position */
term_gotoxy(int col,int row)1351 void term_gotoxy (int col, int row)
1352 {
1353 #if defined(__EMX__) && !defined(GUI)
1354 	term_flush();
1355 	VioSetCurPos(row,col,0);
1356 #elif defined(GUI)
1357 	gui_gotoxy(col, row);
1358 #else
1359 
1360 	if (current_term->TI_cup)
1361 		tputs_x(tparm2(current_term->TI_cup, row, col));
1362 	else
1363 	{
1364 		tputs_x(tparm1(current_term->TI_hpa, col));
1365 		tputs_x(tparm1(current_term->TI_vpa, row));
1366 	}
1367 #endif
1368 }
1369 
1370 /* A no-brainer. Clear the screen. */
term_clrscr(void)1371 void term_clrscr (void)
1372 {
1373 #if defined(__EMX__) && !defined(__EMXX__) && !defined(GUI)
1374 	VioScrollUp(0, 0, -1, -1, -1, &default_pair, vio_screen);
1375 #elif defined(GUI)
1376 	gui_clrscr();
1377 #else
1378 
1379 	int i;
1380 
1381 	/* We have a specific cap for clearing the screen */
1382 	if (current_term->TI_clear)
1383 	{
1384 		tputs_x(current_term->TI_clear);
1385 		term_gotoxy (0, 0);
1386 		return;
1387 	}
1388 
1389 	term_gotoxy (0, 0);
1390 	/* We can clear by doing an erase-to-end-of-display */
1391 	if (current_term->TI_ed)
1392 	{
1393 		tputs_x (current_term->TI_ed);
1394 		return;
1395 	}
1396 	/* We can also clear by deleteing lines ... */
1397 	else if (current_term->TI_dl)
1398 	{
1399 		tputs_x(tparm1(current_term->TI_dl, current_term->TI_lines));
1400 		return;
1401 	}
1402 	/* ... in this case one line at a time */
1403 	else if (current_term->TI_dl1)
1404 	{
1405 		for (i = 0; i < current_term->TI_lines; i++)
1406 			tputs_x(current_term->TI_dl1);
1407 		return;
1408 	}
1409 	/* As a last resort we can insert lines ... */
1410 	else if (current_term->TI_il)
1411 	{
1412 		tputs_x(tparm1(current_term->TI_il, current_term->TI_lines));
1413 		term_gotoxy (0, 0);
1414 		return;
1415 	}
1416 	/* ... one line at a time */
1417 	else if (current_term->TI_il1)
1418 	{
1419 		for (i = 0; i < current_term->TI_lines; i++)
1420 			tputs_x(current_term->TI_il1);
1421 		term_gotoxy (0, 0);
1422 	}
1423 #endif
1424 }
1425 
1426 /*
1427  * Move the cursor NUM spaces to the left, non-destruvtively if we can.
1428  */
term_left(int num)1429 void term_left (int num)
1430 {
1431 #ifdef GUI
1432 	gui_left(num);
1433 #else
1434 	if (current_term->TI_cub)
1435 		tputs_x(tparm1(current_term->TI_cub, num));
1436 	else if (current_term->TI_mrcup)
1437 		tputs_x(tparm2(current_term->TI_mrcup, -num, 0));
1438 	else if (current_term->TI_cub1)
1439 		while (num--)
1440 			tputs_x(current_term->TI_cub1);
1441 	else if (current_term->TI_kbs)
1442 		while (num--)
1443 			tputs_x(current_term->TI_kbs);
1444 #endif
1445 }
1446 
1447 /*
1448  * Move the cursor NUM spaces to the right
1449  */
term_right(int num)1450 void term_right (int num)
1451 {
1452 #ifdef GUI
1453 	gui_right(num);
1454 #else
1455 	if (current_term->TI_cuf)
1456 		tputs_x(tparm1(current_term->TI_cuf, num));
1457 	else if (current_term->TI_mrcup)
1458 		tputs_x(tparm2(current_term->TI_mrcup, num, 0));
1459 	else if (current_term->TI_cuf1)
1460 		while (num--)
1461 			tputs_x(current_term->TI_cuf1);
1462 #endif
1463 }
1464 
1465 /*
1466  * term_delete (int num)
1467  * Deletes NUM characters at the current position
1468  */
term_delete(int num)1469 void term_delete (int num)
1470 {
1471 	if (current_term->TI_smdc)
1472 		tputs_x(current_term->TI_smdc);
1473 
1474 	if (current_term->TI_dch)
1475 		tputs_x(tparm1(current_term->TI_dch, num));
1476 	else if (current_term->TI_dch1)
1477 		while (num--)
1478 			tputs_x (current_term->TI_dch1);
1479 
1480 	if (current_term->TI_rmdc)
1481 		tputs_x (current_term->TI_rmdc);
1482 }
1483 
1484 /*
1485  * Insert character C at the curent cursor position.
1486  */
term_insert(unsigned char c)1487 void term_insert (unsigned char c)
1488 {
1489 	if (current_term->TI_smir)
1490 		tputs_x (current_term->TI_smir);
1491 	else if (current_term->TI_ich1)
1492 		tputs_x (current_term->TI_ich1);
1493 	else if (current_term->TI_ich)
1494 		tputs_x(tparm1(current_term->TI_ich, 1));
1495 
1496 	term_putchar (c);
1497 
1498 	if (current_term->TI_rmir)
1499 		tputs_x(current_term->TI_rmir);
1500 }
1501 
1502 
1503 /*
1504  * Repeat the character C REP times in the most efficient way.
1505  */
term_repeat(unsigned char c,int rep)1506 void term_repeat (unsigned char c, int rep)
1507 {
1508 	if (current_term->TI_rep)
1509 		tputs_x(tparm2(current_term->TI_rep, (int)c, rep));
1510 	else
1511 		while (rep--)
1512 			putchar_x (c);
1513 }
1514 
1515 
1516 
1517 /*
1518  * Scroll the screen N lines between lines TOP and BOT.
1519  */
term_scroll(int top,int bot,int n)1520 void term_scroll (int top, int bot, int n)
1521 {
1522 #ifdef GUI
1523         gui_scroll(top, bot, n);
1524 #else
1525       int i,oneshot=0,rn,sr,er;
1526       char thing[128], final[128], start[128];
1527 #ifdef __EMX__
1528       pair[0] = ' '; pair[1] = 7;
1529       if (n > 0) VioScrollUp(top, 0, bot, current_term->TI_cols, n, (PBYTE)&pair, (HVIO) vio_screen);
1530       else if (n < 0) { n = -n; VioScrollDn(top, 0, bot, current_term->TI_cols, n, (PBYTE)&pair, (HVIO) vio_screen); }
1531 #ifndef __EMXX__
1532       return;
1533 #endif
1534 #elif defined(WINNT)
1535 
1536 	/* It seems that Windows 95/98 has a problem with scrolling
1537 	   when you set the scroll area to something other than the
1538 	   default, using current_term->TI_csr, so this API call will scroll the
1539 	   text instead. */
1540 
1541 	SMALL_RECT src;
1542 	COORD dest;
1543 	CHAR_INFO chr;
1544 
1545 	src.Left = gscrbuf.srWindow.Left;
1546 	src.Top = top+n;
1547 	src.Right = gscrbuf.srWindow.Right;
1548 	src.Bottom = bot;
1549 
1550 	dest.X = 0;
1551 	dest.Y = top;
1552 
1553 	chr.Char.AsciiChar = ' ';
1554 	chr.Attributes = 0;
1555 	ScrollConsoleScreenBuffer(ghstdout, &src, NULL, dest, &chr);
1556         return;
1557 #endif
1558 
1559 	/* Some basic sanity checks */
1560 	if (n == 0 || top == bot || bot < top)
1561 		return;
1562 
1563 	sr = er = 0;
1564 	final[0] = start[0] = thing[0] = 0;
1565 
1566 	if (n < 0)
1567 		rn = -n;
1568 	else
1569 		rn = n;
1570 
1571 	/*
1572 	 * First thing we try to do is set the scrolling region on a
1573 	 * line granularity.  In order to do this, we need to be able
1574 	 * to have termcap 'cs', and as well, we need to have 'sr' if
1575 	 * we're scrolling down, and 'sf' if we're scrolling up.
1576 	 */
1577 	if (current_term->TI_csr && (current_term->TI_ri || current_term->TI_rin) && (current_term->TI_ind || current_term->TI_indn))
1578 	{
1579 		/*
1580 		 * Previously there was a test to see if the entire scrolling
1581 		 * region was the full screen.  That test *always* fails,
1582 		 * because we never scroll the bottom line of the screen.
1583 		 */
1584 		strcpy(start, tparm2(current_term->TI_csr, top, bot));
1585 		strcpy(final, tparm2(current_term->TI_csr, 0, current_term->TI_lines-1));
1586 
1587 		if (n > 0)
1588 		{
1589 			sr = bot;
1590 			er = top;
1591 			if (current_term->TI_indn)
1592 			{
1593 				oneshot = 1;
1594 				strcpy(thing, tparm2(current_term->TI_indn, rn, rn));
1595 			}
1596 			else
1597 				strcpy(thing, current_term->TI_ind);
1598 		}
1599 		else
1600 		{
1601 			sr = top;
1602 			er = bot;
1603 			if (current_term->TI_rin)
1604 			{
1605 				oneshot = 1;
1606 				strcpy(thing, tparm2(current_term->TI_rin, rn, rn));
1607 			}
1608 			else
1609 				strcpy(thing, current_term->TI_ri);
1610 		}
1611 	}
1612 
1613 	else if (current_term->TI_wind && (current_term->TI_ri || current_term->TI_rin) && (current_term->TI_ind || current_term->TI_indn))
1614 	{
1615 		strcpy(start, tparm4(current_term->TI_wind, top, bot, 0, current_term->TI_cols-1));
1616 		strcpy(final, tparm4(current_term->TI_wind, 0, current_term->TI_lines-1, 0, current_term->TI_cols-1));
1617 
1618 		if (n > 0)
1619 		{
1620 			sr = bot;
1621 			er = top;
1622 			if (current_term->TI_indn)
1623 			{
1624 				oneshot = 1;
1625 				strcpy(thing, tparm2(current_term->TI_indn, rn, rn));
1626 			}
1627 			else
1628 				strcpy(thing, current_term->TI_ind);
1629 		}
1630 		else
1631 		{
1632 			sr = top;
1633 			er = bot;
1634 			if (current_term->TI_rin)
1635 			{
1636 				oneshot = 1;
1637 				strcpy(thing, tparm2(current_term->TI_rin, rn, rn));
1638 			}
1639 			else
1640 				strcpy (thing, current_term->TI_ri);
1641 		}
1642 	}
1643 
1644 	else if ((current_term->TI_il || current_term->TI_il1) && (current_term->TI_dl || current_term->TI_dl1))
1645 	{
1646 		if (n > 0)
1647 		{
1648 			sr = top;
1649 			er = bot;
1650 
1651 			if (current_term->TI_dl)
1652 			{
1653 				oneshot = 1;
1654 				strcpy(thing, tparm2(current_term->TI_dl, rn, rn));
1655 			}
1656 			else
1657 				strcpy (thing, current_term->TI_dl1);
1658 
1659 			if (current_term->TI_il)
1660 			{
1661 				oneshot = 1;
1662 				strcpy(final, tparm2(current_term->TI_il, rn, rn));
1663 			}
1664 			else
1665 				strcpy(final, current_term->TI_il1);
1666 		}
1667 		else
1668 		{
1669 			sr = bot;
1670 			er = top;
1671 			if (current_term->TI_il)
1672 			{
1673 				oneshot = 1;
1674 				strcpy(thing, tparm2(current_term->TI_il, rn, rn));
1675 			}
1676 			else
1677 				strcpy (thing, current_term->TI_il1);
1678 
1679 			if (current_term->TI_dl)
1680 			{
1681 				oneshot = 1;
1682 				strcpy(final, tparm2(current_term->TI_dl, rn, rn));
1683 			}
1684 			else
1685 				strcpy(final, current_term->TI_dl1);
1686 		}
1687 	}
1688 
1689 
1690 	if (!thing[0])
1691 		return;
1692 
1693 	/* Do the actual work here */
1694 	if (start[0])
1695 		tputs_x (start);
1696 	term_gotoxy (0, sr);
1697 
1698 	if (oneshot)
1699 		tputs_x (thing);
1700 	else
1701 	{
1702 		for (i = 0; i < rn; i++)
1703 			tputs_x(thing);
1704 	}
1705 	term_gotoxy (0, er);
1706 	if (final[0])
1707 		tputs_x(final);
1708 #endif
1709 }
1710 
1711 /*
1712  * term_getsgr(int opt, int fore, int back)
1713  * Return the string required to set the given mode. OPT defines what
1714  * we really want it to do. It can have these values:
1715  * TERM_SGR_BOLD_ON     - turn bold mode on
1716  * TERM_SGR_BOLD_OFF    - turn bold mode off
1717  * TERM_SGR_BLINK_ON    - turn blink mode on
1718  * TERM_SGR_BLINK_OFF   - turn blink mode off
1719  * TERM_SGR_UNDL_ON     - turn underline mode on
1720  * TERM_SGR_UNDL_OFF    - turn underline mode off
1721  * TERM_SGR_REV_ON      - turn reverse video on
1722  * TERM_SGR_REV_OFF     - turn reverse video off
1723  * TERM_SGR_NORMAL      - turn all attributes off
1724  * TERM_SGR_RESET       - all attributes off and back to default colors
1725  * TERM_SGR_FOREGROUND  - set foreground color
1726  * TERM_SGR_BACKGROUND  - set background color
1727  * TERM_SGR_COLORS      - set foreground and background colors
1728  * TERM_SGR_GCHAR       - print graphics character
1729  *
1730  * The colors are defined as:
1731  * 0    - black
1732  * 1    - red
1733  * 2    - green
1734  * 3    - brown
1735  * 4    - blue
1736  * 5    - magenta
1737  * 6    - cyan
1738  * 7    - white
1739  * 8    - grey (foreground only)
1740  * 9    - bright red (foreground only)
1741  * 10   - bright green (foreground only)
1742  * 11   - bright yellow (foreground only)
1743  * 12   - bright blue (foreground only)
1744  * 13   - bright magenta (foreground only)
1745  * 14   - bright cyan (foreground only)
1746  * 15   - bright white (foreground only)
1747  */
term_getsgr(int opt,int fore,int back)1748 char *term_getsgr (int opt, int fore, int back)
1749 {
1750 	char *ret = empty_string;
1751 
1752 	switch (opt)
1753 	{
1754 		case TERM_SGR_BOLD_ON:
1755 		case TERM_SGR_BOLD_OFF:
1756 		case TERM_SGR_BLINK_OFF:
1757 		case TERM_SGR_BLINK_ON:
1758 		case TERM_SGR_UNDL_ON:
1759 		case TERM_SGR_UNDL_OFF:
1760 		case TERM_SGR_REV_ON:
1761 		case TERM_SGR_REV_OFF:
1762 		case TERM_SGR_NORMAL:
1763 		case TERM_SGR_RESET:
1764 			ret = current_term->TI_sgrstrs[opt-1];
1765 			break;
1766 		case TERM_SGR_FOREGROUND:
1767 			ret = current_term->TI_forecolors[fore & 0x0f];
1768 			break;
1769 		case TERM_SGR_BACKGROUND:
1770 			ret = current_term->TI_backcolors[fore & 0x0f];
1771 			break;
1772 		case TERM_SGR_GCHAR:
1773 			if (current_term->TI_dispc)
1774 				ret = tparm1(current_term->TI_dispc, fore);
1775 			break;
1776 		default:
1777 			ircpanic ("Unknown option '%d' to term_getsgr", opt);
1778 			break;
1779 	}
1780 	return (ret);
1781 }
1782 
1783 
1784 
1785 
term_eight_bit(void)1786 extern	int term_eight_bit (void)
1787 {
1788 #ifdef GUI
1789 	return 1;
1790 #else
1791 	if (dumb_mode)
1792 		return 1;
1793 	return (((newb.c_cflag) & CSIZE) == CS8) ? 1 : 0;
1794 #endif
1795 }
1796 
term_beep(void)1797 extern	void term_beep (void)
1798 {
1799 	if (get_int_var(BEEP_VAR))
1800 	{
1801 #ifdef __EMX__
1802 		DosBeep(1000, 200);
1803 #else
1804 		tputs_x(current_term->TI_bel);
1805 		term_flush();
1806 #endif
1807 	}
1808 }
1809 
set_term_eight_bit(int value)1810 extern	void	set_term_eight_bit (int value)
1811 {
1812 	if (dumb_mode)
1813 		return;
1814 	if (value == ON)
1815 	{
1816 		newb.c_cflag |= CS8;
1817 		newb.c_iflag &= ~ISTRIP;
1818 	}
1819 	else
1820 	{
1821 		newb.c_cflag &= ~CS8;
1822 		newb.c_iflag |= ISTRIP;
1823 	}
1824 	tcsetattr(tty_des, TCSADRAIN, &newb);
1825 }
1826 
set_meta_8bit(Window * w,char * u,int value)1827 void	set_meta_8bit (Window *w, char *u, int value)
1828 {
1829 	if (dumb_mode)
1830 		return;
1831 
1832 	if (value == 0)
1833 		meta_mode = 0;
1834 	else if (value == 1)
1835 		meta_mode = 1;
1836 	else if (value == 2)
1837 		meta_mode = (current_term->TI_km == 0 ? 0 : 1);
1838 }
1839 
1840 /* control_mangle()
1841  *
1842  * Convert control characters in a string into printable sequences. */
control_mangle(char * text)1843 static char *control_mangle(char *text)
1844 {
1845 	static char retval[256];
1846 	int pos;
1847 
1848 	if (!text)
1849 	{
1850 		*retval = 0;
1851 		return retval;
1852 	}
1853 
1854 	for (pos = 0; *text && (pos < 254); text++, pos++)
1855 	{
1856 		if (*text >= 0 && *text < 32)
1857 		{
1858 			retval[pos++] = '^';
1859 			retval[pos] = *text + 64;
1860 		}
1861 		else if (*text == 127)
1862 		{
1863 			retval[pos++] = '^';
1864 			retval[pos] = '?';
1865 		}
1866 		else
1867 			retval[pos] = *text;
1868 	}
1869 
1870 	retval[pos] = 0;
1871 	return retval;
1872 }
1873 
1874 /* get_term_capability()
1875  *
1876  * Returns a named terminal capability of the current terminal as a string.
1877  */
get_term_capability(char * name,int querytype,int mangle)1878 char *get_term_capability(char *name, int querytype, int mangle)
1879 {
1880 	static char retval[256];
1881 	const char *compare = empty_string;
1882 	int x;
1883 	cap2info *t;
1884 
1885 	for (x = 0; x < numcaps; x++)
1886 	{
1887 		t = &tcaps[x];
1888 		if (querytype == 0)
1889 			compare = t->longname;
1890 		else if (querytype == 1)
1891 			compare = t->iname;
1892 		else if (querytype == 2)
1893 			compare = t->tname;
1894 
1895 		if (!strcmp(name, compare))
1896 		{
1897 			char *control_str;
1898 			if (!t->ptr)
1899 				return NULL;
1900 
1901 			switch (t->type)
1902 			{
1903 			case CAP_TYPE_BOOL:
1904 			case CAP_TYPE_INT:
1905 				strlcpy(retval, ltoa(*(int *)(t->ptr)), sizeof retval);
1906 				return retval;
1907 
1908 			case CAP_TYPE_STR:
1909 				control_str = *(char **)t->ptr;
1910 				if (!control_str)
1911 					return NULL;
1912 				strlcpy(retval,
1913 					mangle ? control_mangle(control_str) : control_str,
1914 					sizeof retval);
1915 				return retval;
1916 			}
1917 		}
1918 	}
1919 	return NULL;
1920 }
1921 
1922 #endif /* NOT IN WTERM_C */
1923 
1924 #if 0
1925 /*
1926  * term.c -- for windows 95/NT
1927  *
1928  * Copyright 1997 Colten Edwards
1929  *
1930  */
1931 
1932 #include "irc.h"
1933 #include "vars.h"
1934 #include "ircterm.h"
1935 #include "window.h"
1936 #include "screen.h"
1937 #include "output.h"
1938 #ifdef TRANSLATE
1939 #include "translat.h"
1940 #endif
1941 
1942 #include <windows.h>
1943 
1944 char eolbuf[200];
1945 
1946 #ifndef WTERM_C
1947 extern	char	*getenv();
1948 
1949 static	int	term_CE_clear_to_eol 	(void);
1950 static	int	term_CS_scroll 		(int, int, int);
1951 static 	int	term_null_function 	(void);
1952 
1953 /*
1954  * Function variables: each returns 1 if the function is not supported on the
1955  * current term type, otherwise they do their thing and return 0
1956  */
1957 int	(*term_scroll) (int, int, int);	/* this is set to the best scroll available */
1958 int	(*term_insert) (char);		/* this is set to the best insert available */
1959 int	(*term_delete) (void);		/* this is set to the best delete available */
1960 int	(*term_cursor_left) (void);	/* this is set to the best left available */
1961 int	(*term_cursor_right) (void); 	/* this is set to the best right available */
1962 int	(*term_clear_to_eol) (void); 	/* this is set... figure it out */
1963 
1964 int nt_cursor_right(void);
1965 int nt_cursor_left(void);
1966 
1967 int	CO = 79,
1968 	LI = 24;
1969 HANDLE ghstdout;
1970 CONSOLE_SCREEN_BUFFER_INFO gscrbuf;
1971 CONSOLE_CURSOR_INFO gcursbuf;
1972 DWORD gdwPlatform;
1973 
1974 /*
1975  * term_reset_flag: set to true whenever the terminal is reset, thus letter
1976  * the calling program work out what to do
1977  */
1978 	int	need_redraw = 0;
1979 static	int	term_echo_flag = 1;
1980 static	int	li;
1981 static	int	co;
1982 static	int	def_color = 0x07;
1983 	int	CO, LI;
1984 
1985 
1986 /*
1987  * term_echo: if 0, echo is turned off (all characters appear as blanks), if
1988  * non-zero, all is normal.  The function returns the old value of the
1989  * term_echo_flag
1990  */
1991 int	term_echo (int flag)
1992 {
1993 	int	echo;
1994 
1995 	echo = term_echo_flag;
1996 	term_echo_flag = flag;
1997 	return (echo);
1998 }
1999 
2000 void term_flush (void)
2001 {
2002 	return;
2003 }
2004 
2005 /*
2006  * term_reset: sets terminal attributed back to what they were before the
2007  * program started
2008  */
2009 void term_reset (void)
2010 {
2011 	term_move_cursor(0, LI - 1);
2012 }
2013 
2014 /*
2015  * term_cont: sets the terminal back to IRCII stuff when it is restarted
2016  * after a SIGSTOP.  Somewhere, this must be used in a signal() call
2017  */
2018 
2019 SIGNAL_HANDLER(term_cont)
2020 {
2021 	refresh_screen(0, NULL);
2022 }
2023 
2024 /*
2025  * term_pause: sets terminal back to pre-program days, then SIGSTOPs itself.
2026  */
2027 extern void term_pause (char unused, char *not_used)
2028 {
2029 char *shell;
2030 DWORD dwmode;
2031 HANDLE hstdin=GetStdHandle(STD_INPUT_HANDLE);
2032 STARTUPINFO si = { 0 };
2033 PROCESS_INFORMATION pi = { 0 };
2034 
2035 	si.cb = sizeof(si);
2036 
2037 	if (!(shell = get_string_var(SHELL_VAR)))
2038 	{
2039 		if (gdwPlatform == VER_PLATFORM_WIN32_WINDOWS)
2040 			shell = "command.com";
2041 		else
2042 			shell = "cmd.exe";
2043 	}
2044 	if (!(GetConsoleMode(hstdin,&dwmode)))
2045 		return;
2046 
2047 	if (!SetConsoleMode(hstdin, dwmode | ((ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT) & ~ENABLE_WINDOW_INPUT)))
2048 		return;
2049 
2050 	if(!CreateProcess(NULL, shell, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) )
2051 		return;
2052 	CloseHandle(pi.hThread);
2053 	WaitForSingleObject(pi.hProcess,INFINITE);
2054 	CloseHandle(pi.hProcess);
2055 
2056 	if (!SetConsoleMode(hstdin, dwmode ) )
2057 		return;
2058 	refresh_screen(0,NULL);
2059 }
2060 #endif /* NOT IN WTERM_C */
2061 
2062 
2063 
2064 /*
2065  * term_init: does all terminal initialization... reads termcap info, sets
2066  * the terminal to CBREAK, no ECHO mode.   Chooses the best of the terminal
2067  * attributes to use ..  for the version of this function that is called for
2068  * wserv, we set the termial to RAW, no ECHO, so that all the signals are
2069  * ignored.. fixes quite a few problems...  -phone, jan 1993..
2070  */
2071 int term_init (void)
2072 {
2073 #ifndef WTERM_C
2074 
2075 	CONSOLE_SCREEN_BUFFER_INFO scrbuf;
2076 	HANDLE hinput =GetStdHandle(STD_INPUT_HANDLE);
2077 	DWORD dwmode;
2078 	OSVERSIONINFO osver;
2079 
2080 	ghstdout = GetStdHandle(STD_OUTPUT_HANDLE);
2081 
2082 	if(!GetConsoleScreenBufferInfo(ghstdout, &gscrbuf) )
2083 	{
2084 		fprintf(stderr,"Error from getconsolebufinfo %d\n",GetLastError());
2085 		abort();
2086 	}
2087 
2088 	GetConsoleMode(hinput,&dwmode);
2089 	SetConsoleMode(hinput,dwmode & (~(ENABLE_LINE_INPUT |ENABLE_ECHO_INPUT
2090 				| ENABLE_PROCESSED_INPUT)| ENABLE_WINDOW_INPUT/* | ENABLE_WRAP_AT_EOL_OUTPUT*/)
2091 				);
2092 
2093 	osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
2094 	GetVersionEx(&osver);
2095 	gdwPlatform = osver.dwPlatformId;
2096 
2097 	GetConsoleCursorInfo(hinput, &gcursbuf);
2098 
2099 	GetConsoleScreenBufferInfo(ghstdout, &scrbuf);
2100 	li = scrbuf.srWindow.Bottom - scrbuf.srWindow.Top + 1;
2101 	co = scrbuf.srWindow.Right - scrbuf.srWindow.Left + 1;
2102 	LI = li;
2103 	CO = co - 1;
2104 	memset(eolbuf,' ',sizeof(eolbuf)-2);
2105 	eolbuf[sizeof(eolbuf)-1] = 0;
2106 	def_color = gscrbuf.wAttributes;
2107 
2108 	term_clear_to_eol = term_CE_clear_to_eol;
2109 	term_cursor_right = nt_cursor_right;
2110 	term_cursor_left  = nt_cursor_left;
2111 	term_scroll 	  = term_CS_scroll/* : term_param_ALDL_scroll*/;
2112 	term_delete	  = term_null_function;
2113 	term_insert       = term_null_function;
2114 #endif /* NOT IN WTERM_C */
2115 	return 0;
2116 }
2117 
2118 
2119 #ifndef WTERM_C
2120 /*
2121  * term_resize: gets the terminal height and width.  Trys to get the info
2122  * from the tty driver about size, if it can't... uses the termcap values. If
2123  * the terminal size has changed since last time term_resize() has been
2124  * called, 1 is returned.  If it is unchanged, 0 is returned.
2125  */
2126 int term_resize (void)
2127 {
2128 	static	int	old_li = -1,
2129 			old_co = -1;
2130 
2131 	CONSOLE_SCREEN_BUFFER_INFO scrbuf;
2132 	ghstdout = GetStdHandle(STD_OUTPUT_HANDLE);
2133 
2134 	GetConsoleScreenBufferInfo(ghstdout, &scrbuf);
2135 	li = scrbuf.srWindow.Bottom - scrbuf.srWindow.Top + 1;
2136 	co = scrbuf.srWindow.Right - scrbuf.srWindow.Left + 1;
2137 	LI = li;
2138 	CO = co - 1;
2139 	if ((old_li != LI) || (old_co != CO))
2140 	{
2141 		old_li = LI;
2142 		old_co = CO;
2143 		return (1);
2144 	}
2145 	return (0);
2146 }
2147 
2148 
2149 static 	int	term_null_function _((void))
2150 {
2151 	return 1;
2152 }
2153 
2154 /* term_CE_clear_to_eol(): the clear to eol function, right? */
2155 
2156 static	int term_CE_clear_to_eol _((void))
2157 {
2158 	CONSOLE_SCREEN_BUFFER_INFO scrbuf;
2159 	HANDLE hStdout = ghstdout;
2160 	DWORD numwrote;
2161 	int num=0;
2162 	COORD savepos;
2163 
2164 	if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) )
2165 		return 0 ;
2166 
2167 	num = scrbuf.srWindow.Right - scrbuf.dwCursorPosition.X;
2168 	savepos = scrbuf.dwCursorPosition;
2169 
2170 	if (!WriteConsole(hStdout,eolbuf,num,&numwrote,NULL))
2171 		return 0;
2172 
2173 	SetConsoleCursorPosition(hStdout, savepos);
2174 	return (0);
2175 }
2176 
2177 /*
2178  * term_CS_scroll: should be used if the terminal has the CS capability by
2179  * setting term_scroll equal to it
2180  */
2181 static	int	term_CS_scroll (int line1, int line2, int n)
2182 {
2183 	HANDLE hStdout = ghstdout;
2184 	SMALL_RECT src;
2185 	SMALL_RECT clip;
2186 	COORD dest = {0};
2187 	CHAR_INFO chr;
2188 
2189 	src.Left = gscrbuf.srWindow.Left;
2190 	src.Right = gscrbuf.srWindow.Right;
2191 	chr.Char.AsciiChar = ' ';
2192 	chr.Attributes = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
2193 	if (n > 0)
2194 	{
2195 		src.Bottom = gscrbuf.srWindow.Top + line2;
2196 		src.Top =  gscrbuf.srWindow.Top + line1 + n;
2197 		dest.Y =  gscrbuf.srWindow.Top + line1;
2198 		ScrollConsoleScreenBuffer(hStdout, &src, NULL, dest, &chr);
2199 	}
2200 	else
2201 	{
2202 		clip = src;
2203         	src.Bottom = gscrbuf.srWindow.Top + line2 + line1 + n;
2204 		src.Top = gscrbuf.srWindow.Top + line1;
2205 		dest.Y = gscrbuf.srWindow.Top + line1 - n;
2206 		clip.Top = gscrbuf.srWindow.Top + line1;
2207 		clip.Bottom = gscrbuf.srWindow.Top + line1 + line2;
2208 		ScrollConsoleScreenBuffer(hStdout, &src, &clip, dest, &chr);
2209 	}
2210 	return 0;
2211 }
2212 
2213 extern	void	copy_window_size (int *lines, int *columns)
2214 {
2215 	*lines = LI;
2216 	*columns = CO;
2217 }
2218 
2219 extern	int term_eight_bit (void)
2220 {
2221 	return 1;
2222 }
2223 
2224 extern	void term_beep (void)
2225 {
2226 	if (get_int_var(BEEP_VAR))
2227 	{
2228        		Beep(0x637, 60/8);
2229 	}
2230 }
2231 
2232 void ScrollBuf(HANDLE hOut, CONSOLE_SCREEN_BUFFER_INFO *scrbuf,int where)
2233 {
2234 	SMALL_RECT src;
2235 	COORD dest;
2236 	CHAR_INFO chr;
2237 
2238 	src.Left = scrbuf->srWindow.Left;
2239 	src.Top = scrbuf->srWindow.Top+where ;
2240 	src.Right = scrbuf->srWindow.Right;
2241 	src.Bottom = scrbuf->srWindow.Bottom;
2242 
2243 	dest.X = 0;
2244 	dest.Y = 0;
2245 
2246 	chr.Char.AsciiChar = ' ';
2247 	chr.Attributes = 0;
2248 	ScrollConsoleScreenBuffer(hOut, &src, NULL, dest, &chr);
2249 
2250 }
2251 
2252 void NT_MoveToLineOrChar(void *fd, int where,int line)
2253 {
2254 	CONSOLE_SCREEN_BUFFER_INFO gscrbuf;
2255 	GetConsoleScreenBufferInfo((HANDLE)fd, &gscrbuf);
2256 	if (line)
2257 	{
2258 		if ( ((gscrbuf.dwCursorPosition.Y+where)> (gscrbuf.srWindow.Bottom-1))
2259 			&&( where >0))
2260 			ScrollBuf((HANDLE)fd,&gscrbuf,where);
2261 		else
2262 			gscrbuf.dwCursorPosition.Y += where;
2263 	}
2264 	else
2265 		gscrbuf.dwCursorPosition.X += where;
2266 	SetConsoleCursorPosition((HANDLE)fd, gscrbuf.dwCursorPosition);
2267 }
2268 
2269 void NT_MoveToLineOrCharAbs(void *fd, int where,int line)
2270 {
2271 
2272 	CONSOLE_SCREEN_BUFFER_INFO scrbuf;
2273         GetConsoleScreenBufferInfo((HANDLE)fd, &scrbuf);
2274 
2275 	if (line)
2276 		scrbuf.dwCursorPosition.Y = where+scrbuf.srWindow.Top;
2277 	else
2278 		scrbuf.dwCursorPosition.X = where;
2279 	SetConsoleCursorPosition((HANDLE)fd, scrbuf.dwCursorPosition);
2280 }
2281 
2282 void term_move_cursor(int cursor, int line)
2283 {
2284 	HANDLE hStdout =ghstdout;
2285 	COORD dest;
2286 	dest.X = cursor;
2287 	dest.Y = line + gscrbuf.srWindow.Top;
2288 	SetConsoleCursorPosition(hStdout, dest);
2289 }
2290 
2291 
2292 void NT_ClearScreen(void)
2293 {
2294 	CONSOLE_SCREEN_BUFFER_INFO scrbuf;
2295 	DWORD numwrote;
2296 	COORD origin = {0, 0};
2297 	HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
2298 
2299 	GetConsoleScreenBufferInfo(hStdout, &scrbuf);
2300 	FillConsoleOutputCharacter(hStdout,' ',scrbuf.dwSize.X*scrbuf.dwSize.Y,
2301 		origin,&numwrote);
2302 	FillConsoleOutputAttribute(hStdout,scrbuf.wAttributes,
2303 		scrbuf.dwSize.X*scrbuf.dwSize.Y,scrbuf.dwCursorPosition,&numwrote);
2304 	origin.X = scrbuf.srWindow.Left;
2305 	origin.Y = scrbuf.srWindow.Top;
2306 	SetConsoleCursorPosition(hStdout, origin);
2307 	return;
2308 }
2309 
2310 int nt_cursor_right(void)
2311 {
2312 	NT_MoveToLineOrChar(GetStdHandle(STD_OUTPUT_HANDLE), 1,0);
2313 	return 0;
2314 }
2315 
2316 int nt_cursor_left(void)
2317 {
2318 	NT_MoveToLineOrChar(GetStdHandle(STD_OUTPUT_HANDLE), -1,0);
2319 	return 0;
2320 }
2321 
2322 extern	void	set_term_eight_bit (int value)
2323 {
2324 	return;
2325 }
2326 
2327 #define NPAR 16
2328 
2329 static unsigned int color_table[] = {
2330         0x00,   0x04,   0x02,   0x06,    0x01,   0x05,   0x03,   0x07,
2331         0x00|8, 0x04|8, 0x02|8, 0x06|8,  0x01|8, 0x05|8, 0x03|8, 0x07|8
2332 };
2333 
2334 enum VC_STATES { ESnormal = 0, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey };
2335 enum VC_STATES vc_state;
2336 unsigned long par[NPAR+1] = {0};
2337 unsigned long npar = 0;
2338 int intensity = 1;
2339 int blink = 0;
2340 int underline = 0;
2341 int reverse_ch = 0;
2342 
2343 
2344 void reset_attrib(void *fd, int *fg, int *bg)
2345 {
2346 	intensity = 0;
2347 	underline = 0;
2348 	reverse_ch = 0;
2349 	blink = 0;
2350 	*fg=FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
2351 	*bg=0;
2352 }
2353 
2354 
2355 void csi_m(void *fd)
2356 {
2357 int i;
2358 static int fg = 7;
2359 static int bg = 0;
2360 	CONSOLE_SCREEN_BUFFER_INFO scrbuf;
2361 	GetConsoleScreenBufferInfo((HANDLE)fd, &scrbuf);
2362 	for (i=0; i <= npar; i++)
2363 	{
2364         	switch(par[i])
2365         	{
2366         		case 0:
2367                         	/* all off */
2368 				reset_attrib(fd, &fg, &bg);
2369                         	break;
2370         		case 1: /* bold */
2371         			intensity = FOREGROUND_INTENSITY;
2372         			break;
2373 			case 2: /* all off */
2374 				fg = 0;
2375 				bg = 0;
2376 				intensity = 0;
2377 				break;
2378         		case 4: /* underline */
2379 		               	fg=FOREGROUND_BLUE | FOREGROUND_RED;
2380 		               	intensity=FOREGROUND_INTENSITY;
2381 		               	bg=0;
2382                         	break;
2383         		case 5: /* blink */
2384 				fg=FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
2385 				bg=0;
2386 				intensity=FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
2387         			break;
2388         		case 7: /* reverse */
2389 				fg=0;
2390 				bg=BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
2391 				intensity=0;
2392 				break;
2393         		case 49:
2394         			fg = (def_color & 0xf0) | bg;
2395         			break;
2396         		default:
2397 				if (par[i] >=30 && par[i] <= 37)
2398 					fg = color_table[par[i]-30];
2399 				else if (par[i] >=40 && par[i] <= 47)
2400 					bg = color_table[par[i]-40]<<4;
2401         			break;
2402 
2403         	}
2404 	}
2405 	/* update attribs now */
2406 	SetConsoleTextAttribute(fd, fg | bg | intensity);
2407 }
2408 
2409 void set_term_intensity(int flag)
2410 {
2411 	par[0] = flag ? 1 : 0;
2412 	npar = 0;
2413 	csi_m(GetStdHandle(STD_OUTPUT_HANDLE));
2414 }
2415 void set_term_inverse(int flag)
2416 {
2417 	par[0] = flag ? 7 : 0;
2418 	npar = 0;
2419 	csi_m(GetStdHandle(STD_OUTPUT_HANDLE));
2420 }
2421 void set_term_underline(int flag)
2422 {
2423 	par[0] = flag ? 4 : 0;
2424 	npar = 0;
2425 	csi_m(GetStdHandle(STD_OUTPUT_HANDLE));
2426 }
2427 
2428 void csi_K(void *fd, int parm)
2429 {
2430 COORD save_curs = {0};
2431 CONSOLE_SCREEN_BUFFER_INFO scrbuf;
2432 DWORD bytes_rtn;
2433 int num = 0;
2434 	switch(parm)
2435 	{
2436 		case 2:
2437 			NT_MoveToLineOrCharAbs(fd, 0, 0);
2438 		case 0:
2439 			term_CE_clear_to_eol();
2440 			break;
2441 		case 1:
2442 			GetConsoleScreenBufferInfo((HANDLE)fd, &scrbuf);
2443 			save_curs.Y = scrbuf.dwCursorPosition.Y;
2444 			SetConsoleCursorPosition((HANDLE)fd, save_curs);
2445 			num = scrbuf.dwCursorPosition.X - 1;
2446 			if (num > 0)
2447 	                        WriteConsole((HANDLE)fd, eolbuf, num, &bytes_rtn, NULL);
2448 			SetConsoleCursorPosition((HANDLE)fd, scrbuf.dwCursorPosition);
2449 			break;
2450 	}
2451 }
2452 
2453 int nt_write(void * fd, unsigned char *buf, register int howmany)
2454 {
2455 	DWORD bytes_rtn;
2456 	int num = 0;
2457 	int len = -1;
2458 	register int c;
2459 	int ok;
2460 	register unsigned char *buf1 = buf;
2461 	vc_state = ESnormal;
2462 
2463 	while (howmany)
2464 	{
2465 		howmany--;
2466                 num++;
2467                 ok = 0;
2468 		c = *buf1;
2469 		buf1++;
2470 		len++;
2471 		if (!ok && c)
2472 		{
2473 		        switch(c)
2474 			{
2475 		                case 0x1b:
2476 		                case REV_TOG:
2477 		                case UND_TOG:
2478 		                case BOLD_TOG:
2479 		                case ALL_OFF:
2480 		                	ok = 0;
2481                                 	break;
2482 		                default:
2483 					ok = 1;
2484                 	}
2485 		}
2486 		if (vc_state == ESnormal && ok)
2487 		{
2488                         WriteConsole((HANDLE)fd, buf+len,1, &bytes_rtn, NULL);
2489 			continue;
2490 		}
2491 
2492         	switch(c)
2493         	{
2494 			case REV_TOG:
2495 				if (reverse_ch) reverse_ch = 0; else reverse_ch = 1;
2496 				set_term_inverse(reverse_ch);
2497 				continue;
2498 			case BOLD_TOG:
2499 				if (intensity) intensity = 0; else intensity = 1;
2500 				set_term_intensity(intensity);
2501 				continue;
2502 			case UND_TOG:
2503 				if (underline) underline = 0; else underline = 1;
2504                         	set_term_underline(underline);
2505                         	continue;
2506 			case ALL_OFF:
2507 				set_term_underline(0);
2508 				set_term_intensity(0);
2509 				set_term_inverse(0); /* This turns it all off */
2510 				intensity = 0;
2511 				underline = 0;
2512 				reverse_ch = 0;
2513 				if (!buf1)	/* We're the end of line */
2514 					term_bold_off();
2515 				continue;
2516                 	case 7:
2517                 		Beep(0x637, 60/8);
2518                         	continue;
2519                 	case 8:
2520                         	continue;
2521                 	case 9:
2522                         	continue;
2523                 	case 10: case 11: case 12:
2524 				NT_MoveToLineOrChar(fd, 1, 1);
2525 			case 13:
2526 				NT_MoveToLineOrCharAbs(fd, 0, 0);
2527                         	continue;
2528                 	case 24: case 26:
2529                 		vc_state = ESnormal;
2530                         	continue;
2531 			case 27:
2532 				vc_state = ESesc;
2533                         	continue;
2534                 	case 128+27:
2535                 		vc_state = ESsquare;
2536                         	continue;
2537         	}
2538         	switch(vc_state)
2539         	{
2540         		case ESesc:
2541         			vc_state = ESnormal;
2542                         	switch(c)
2543                         	{
2544                         		case '[':
2545                         			vc_state = ESsquare;
2546                         			continue;
2547                         	}
2548                         	continue;
2549                 	case ESsquare:
2550                 		vc_state = ESgetpars;
2551 				for(npar = 0 ; npar < NPAR ; npar++)
2552 					par[npar] = 0;
2553 				npar = 0;
2554 				vc_state = ESgetpars;
2555 				if (c == '[') { /* Function key */
2556 					vc_state=ESfunckey;
2557 					continue;
2558 				}
2559 			case ESgetpars:
2560 				if (c==';' && npar<NPAR-1)
2561 				{
2562 					npar++;
2563 					continue;
2564 				} else if (c>='0' && c<='9')
2565 				{
2566 					par[npar] *= 10;
2567 					par[npar] += c-'0';
2568 					continue;
2569 				} else
2570 					vc_state=ESgotpars;
2571 			case ESgotpars:
2572 				vc_state = ESnormal;
2573 				switch(c)
2574 				{
2575 					case 'C': case 'a':
2576 						NT_MoveToLineOrChar(fd, par[0], 0);
2577 						continue;
2578 					case 'K':
2579 						csi_K(fd, par[0]);
2580 						continue;
2581                                 	case 'm':
2582                                 		csi_m(fd);
2583 	                               		continue;
2584 					case 'r':
2585 					{
2586 						int top, bottom;
2587 						if (!par[0]) par[0]++;
2588 						if (!par[1]) par[1] = li;
2589 						if (par[0] < par[1] && par[1] < li)
2590 						{
2591 							top = par[0]-1;
2592 							bottom = par[1];
2593                                                 	term_CS_scroll(top, bottom, 1);
2594 						}
2595 						continue;
2596 					}
2597 				}
2598 			        continue;
2599 			default:
2600 				vc_state = ESnormal;
2601 
2602         	}
2603 	}
2604 	return num;
2605 }
2606 
2607 #endif /* NOT IN WTERM_C */
2608 #endif
2609