xref: /minix3/external/bsd/less/dist/screen.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /*	$NetBSD: screen.c,v 1.4 2013/09/04 19:44:21 tron Exp $	*/
2f7cf2976SLionel Sambuc 
3f7cf2976SLionel Sambuc /*
4*84d9c625SLionel Sambuc  * Copyright (C) 1984-2012  Mark Nudelman
5f7cf2976SLionel Sambuc  *
6f7cf2976SLionel Sambuc  * You may distribute under the terms of either the GNU General Public
7f7cf2976SLionel Sambuc  * License or the Less License, as specified in the README file.
8f7cf2976SLionel Sambuc  *
9*84d9c625SLionel Sambuc  * For more information, see the README file.
10f7cf2976SLionel Sambuc  */
11f7cf2976SLionel Sambuc 
12f7cf2976SLionel Sambuc 
13f7cf2976SLionel Sambuc /*
14f7cf2976SLionel Sambuc  * Routines which deal with the characteristics of the terminal.
15f7cf2976SLionel Sambuc  * Uses termcap to be as terminal-independent as possible.
16f7cf2976SLionel Sambuc  */
17f7cf2976SLionel Sambuc 
18f7cf2976SLionel Sambuc #include "less.h"
19f7cf2976SLionel Sambuc #include "cmd.h"
20f7cf2976SLionel Sambuc 
21f7cf2976SLionel Sambuc #if MSDOS_COMPILER
22f7cf2976SLionel Sambuc #include "pckeys.h"
23f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
24f7cf2976SLionel Sambuc #include <graph.h>
25f7cf2976SLionel Sambuc #else
26f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
27f7cf2976SLionel Sambuc #include <conio.h>
28f7cf2976SLionel Sambuc #if MSDOS_COMPILER==DJGPPC
29f7cf2976SLionel Sambuc #include <pc.h>
30f7cf2976SLionel Sambuc extern int fd0;
31f7cf2976SLionel Sambuc #endif
32f7cf2976SLionel Sambuc #else
33f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
34f7cf2976SLionel Sambuc #include <windows.h>
35f7cf2976SLionel Sambuc #endif
36f7cf2976SLionel Sambuc #endif
37f7cf2976SLionel Sambuc #endif
38f7cf2976SLionel Sambuc #include <time.h>
39f7cf2976SLionel Sambuc 
40f7cf2976SLionel Sambuc #else
41f7cf2976SLionel Sambuc 
42f7cf2976SLionel Sambuc #if HAVE_SYS_IOCTL_H
43f7cf2976SLionel Sambuc #include <sys/ioctl.h>
44f7cf2976SLionel Sambuc #endif
45f7cf2976SLionel Sambuc 
46f7cf2976SLionel Sambuc #if HAVE_TERMIOS_H && HAVE_TERMIOS_FUNCS
47f7cf2976SLionel Sambuc #include <termios.h>
48f7cf2976SLionel Sambuc #else
49f7cf2976SLionel Sambuc #if HAVE_TERMIO_H
50f7cf2976SLionel Sambuc #include <termio.h>
51f7cf2976SLionel Sambuc #else
52f7cf2976SLionel Sambuc #if HAVE_SGSTAT_H
53f7cf2976SLionel Sambuc #include <sgstat.h>
54f7cf2976SLionel Sambuc #else
55f7cf2976SLionel Sambuc #include <sgtty.h>
56f7cf2976SLionel Sambuc #endif
57f7cf2976SLionel Sambuc #endif
58f7cf2976SLionel Sambuc #endif
59f7cf2976SLionel Sambuc 
60f7cf2976SLionel Sambuc #if HAVE_TERMCAP_H
61f7cf2976SLionel Sambuc #include <termcap.h>
62f7cf2976SLionel Sambuc #endif
63f7cf2976SLionel Sambuc #ifdef _OSK
64f7cf2976SLionel Sambuc #include <signal.h>
65f7cf2976SLionel Sambuc #endif
66f7cf2976SLionel Sambuc #if OS2
67f7cf2976SLionel Sambuc #include <sys/signal.h>
68f7cf2976SLionel Sambuc #include "pckeys.h"
69f7cf2976SLionel Sambuc #endif
70f7cf2976SLionel Sambuc #if HAVE_SYS_STREAM_H
71f7cf2976SLionel Sambuc #include <sys/stream.h>
72f7cf2976SLionel Sambuc #endif
73f7cf2976SLionel Sambuc #if HAVE_SYS_PTEM_H
74f7cf2976SLionel Sambuc #include <sys/ptem.h>
75f7cf2976SLionel Sambuc #endif
76f7cf2976SLionel Sambuc 
77f7cf2976SLionel Sambuc #endif /* MSDOS_COMPILER */
78f7cf2976SLionel Sambuc 
79f7cf2976SLionel Sambuc /*
80f7cf2976SLionel Sambuc  * Check for broken termios package that forces you to manually
81f7cf2976SLionel Sambuc  * set the line discipline.
82f7cf2976SLionel Sambuc  */
83f7cf2976SLionel Sambuc #ifdef __ultrix__
84f7cf2976SLionel Sambuc #define MUST_SET_LINE_DISCIPLINE 1
85f7cf2976SLionel Sambuc #else
86f7cf2976SLionel Sambuc #define MUST_SET_LINE_DISCIPLINE 0
87f7cf2976SLionel Sambuc #endif
88f7cf2976SLionel Sambuc 
89f7cf2976SLionel Sambuc #if OS2
90f7cf2976SLionel Sambuc #define	DEFAULT_TERM		"ansi"
91f7cf2976SLionel Sambuc static char *windowid;
92f7cf2976SLionel Sambuc #else
93f7cf2976SLionel Sambuc #define	DEFAULT_TERM		"unknown"
94f7cf2976SLionel Sambuc #endif
95f7cf2976SLionel Sambuc 
96f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
97f7cf2976SLionel Sambuc static int videopages;
98f7cf2976SLionel Sambuc static long msec_loops;
99f7cf2976SLionel Sambuc static int flash_created = 0;
100f7cf2976SLionel Sambuc #define	SETCOLORS(fg,bg)	{ _settextcolor(fg); _setbkcolor(bg); }
101f7cf2976SLionel Sambuc #endif
102f7cf2976SLionel Sambuc 
103f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC
104f7cf2976SLionel Sambuc static unsigned short *whitescreen;
105f7cf2976SLionel Sambuc static int flash_created = 0;
106f7cf2976SLionel Sambuc #endif
107f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
108f7cf2976SLionel Sambuc #define _settextposition(y,x)   gotoxy(x,y)
109f7cf2976SLionel Sambuc #define _clearscreen(m)         clrscr()
110f7cf2976SLionel Sambuc #define _outtext(s)             cputs(s)
111f7cf2976SLionel Sambuc #define	SETCOLORS(fg,bg)	{ textcolor(fg); textbackground(bg); }
112f7cf2976SLionel Sambuc extern int sc_height;
113f7cf2976SLionel Sambuc #endif
114f7cf2976SLionel Sambuc 
115f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
116f7cf2976SLionel Sambuc struct keyRecord
117f7cf2976SLionel Sambuc {
118f7cf2976SLionel Sambuc 	int ascii;
119f7cf2976SLionel Sambuc 	int scan;
120f7cf2976SLionel Sambuc } currentKey;
121f7cf2976SLionel Sambuc 
122f7cf2976SLionel Sambuc static int keyCount = 0;
123f7cf2976SLionel Sambuc static WORD curr_attr;
124f7cf2976SLionel Sambuc static int pending_scancode = 0;
125f7cf2976SLionel Sambuc static WORD *whitescreen;
126f7cf2976SLionel Sambuc 
127f7cf2976SLionel Sambuc static HANDLE con_out_save = INVALID_HANDLE_VALUE; /* previous console */
128f7cf2976SLionel Sambuc static HANDLE con_out_ours = INVALID_HANDLE_VALUE; /* our own */
129f7cf2976SLionel Sambuc HANDLE con_out = INVALID_HANDLE_VALUE;             /* current console */
130f7cf2976SLionel Sambuc 
131f7cf2976SLionel Sambuc extern int quitting;
132f7cf2976SLionel Sambuc static void win32_init_term();
133f7cf2976SLionel Sambuc static void win32_deinit_term();
134f7cf2976SLionel Sambuc 
135f7cf2976SLionel Sambuc #define FG_COLORS       (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY)
136f7cf2976SLionel Sambuc #define BG_COLORS       (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY)
137f7cf2976SLionel Sambuc #define	MAKEATTR(fg,bg)		((WORD)((fg)|((bg)<<4)))
138f7cf2976SLionel Sambuc #define	SETCOLORS(fg,bg)	{ curr_attr = MAKEATTR(fg,bg); \
139f7cf2976SLionel Sambuc 				if (SetConsoleTextAttribute(con_out, curr_attr) == 0) \
140f7cf2976SLionel Sambuc 				error("SETCOLORS failed"); }
141f7cf2976SLionel Sambuc #endif
142f7cf2976SLionel Sambuc 
143f7cf2976SLionel Sambuc #if MSDOS_COMPILER
144f7cf2976SLionel Sambuc public int nm_fg_color;		/* Color of normal text */
145f7cf2976SLionel Sambuc public int nm_bg_color;
146f7cf2976SLionel Sambuc public int bo_fg_color;		/* Color of bold text */
147f7cf2976SLionel Sambuc public int bo_bg_color;
148f7cf2976SLionel Sambuc public int ul_fg_color;		/* Color of underlined text */
149f7cf2976SLionel Sambuc public int ul_bg_color;
150f7cf2976SLionel Sambuc public int so_fg_color;		/* Color of standout text */
151f7cf2976SLionel Sambuc public int so_bg_color;
152f7cf2976SLionel Sambuc public int bl_fg_color;		/* Color of blinking text */
153f7cf2976SLionel Sambuc public int bl_bg_color;
154f7cf2976SLionel Sambuc static int sy_fg_color;		/* Color of system text (before less) */
155f7cf2976SLionel Sambuc static int sy_bg_color;
156f7cf2976SLionel Sambuc 
157f7cf2976SLionel Sambuc #else
158f7cf2976SLionel Sambuc 
159f7cf2976SLionel Sambuc /*
160f7cf2976SLionel Sambuc  * Strings passed to tputs() to do various terminal functions.
161f7cf2976SLionel Sambuc  */
162f7cf2976SLionel Sambuc static char
163f7cf2976SLionel Sambuc 	*sc_pad,		/* Pad string */
164f7cf2976SLionel Sambuc 	*sc_home,		/* Cursor home */
165f7cf2976SLionel Sambuc 	*sc_addline,		/* Add line, scroll down following lines */
166f7cf2976SLionel Sambuc 	*sc_lower_left,		/* Cursor to last line, first column */
167f7cf2976SLionel Sambuc 	*sc_return,		/* Cursor to beginning of current line */
168f7cf2976SLionel Sambuc 	*sc_move,		/* General cursor positioning */
169f7cf2976SLionel Sambuc 	*sc_clear,		/* Clear screen */
170f7cf2976SLionel Sambuc 	*sc_eol_clear,		/* Clear to end of line */
171f7cf2976SLionel Sambuc 	*sc_eos_clear,		/* Clear to end of screen */
172f7cf2976SLionel Sambuc 	*sc_s_in,		/* Enter standout (highlighted) mode */
173f7cf2976SLionel Sambuc 	*sc_s_out,		/* Exit standout mode */
174f7cf2976SLionel Sambuc 	*sc_u_in,		/* Enter underline mode */
175f7cf2976SLionel Sambuc 	*sc_u_out,		/* Exit underline mode */
176f7cf2976SLionel Sambuc 	*sc_b_in,		/* Enter bold mode */
177f7cf2976SLionel Sambuc 	*sc_b_out,		/* Exit bold mode */
178f7cf2976SLionel Sambuc 	*sc_bl_in,		/* Enter blink mode */
179f7cf2976SLionel Sambuc 	*sc_bl_out,		/* Exit blink mode */
180f7cf2976SLionel Sambuc 	*sc_visual_bell,	/* Visual bell (flash screen) sequence */
181f7cf2976SLionel Sambuc 	*sc_backspace,		/* Backspace cursor */
182f7cf2976SLionel Sambuc 	*sc_s_keypad,		/* Start keypad mode */
183f7cf2976SLionel Sambuc 	*sc_e_keypad,		/* End keypad mode */
184f7cf2976SLionel Sambuc 	*sc_init,		/* Startup terminal initialization */
185f7cf2976SLionel Sambuc 	*sc_deinit;		/* Exit terminal de-initialization */
186f7cf2976SLionel Sambuc #endif
187f7cf2976SLionel Sambuc 
188f7cf2976SLionel Sambuc static int init_done = 0;
189f7cf2976SLionel Sambuc 
190f7cf2976SLionel Sambuc public int auto_wrap;		/* Terminal does \r\n when write past margin */
191f7cf2976SLionel Sambuc public int ignaw;		/* Terminal ignores \n immediately after wrap */
192f7cf2976SLionel Sambuc public int erase_char;		/* The user's erase char */
193f7cf2976SLionel Sambuc public int erase2_char;		/* The user's other erase char */
194f7cf2976SLionel Sambuc public int kill_char;		/* The user's line-kill char */
195f7cf2976SLionel Sambuc public int werase_char;		/* The user's word-erase char */
196f7cf2976SLionel Sambuc public int sc_width, sc_height;	/* Height & width of screen */
197f7cf2976SLionel Sambuc public int bo_s_width, bo_e_width;	/* Printing width of boldface seq */
198f7cf2976SLionel Sambuc public int ul_s_width, ul_e_width;	/* Printing width of underline seq */
199f7cf2976SLionel Sambuc public int so_s_width, so_e_width;	/* Printing width of standout seq */
200f7cf2976SLionel Sambuc public int bl_s_width, bl_e_width;	/* Printing width of blink seq */
201f7cf2976SLionel Sambuc public int above_mem, below_mem;	/* Memory retained above/below screen */
202f7cf2976SLionel Sambuc public int can_goto_line;		/* Can move cursor to any line */
203f7cf2976SLionel Sambuc public int clear_bg;		/* Clear fills with background color */
204f7cf2976SLionel Sambuc public int missing_cap = 0;	/* Some capability is missing */
205f7cf2976SLionel Sambuc 
206f7cf2976SLionel Sambuc static int attrmode = AT_NORMAL;
207f7cf2976SLionel Sambuc extern int binattr;
208f7cf2976SLionel Sambuc 
209f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
210f7cf2976SLionel Sambuc static char *cheaper();
211f7cf2976SLionel Sambuc static void tmodes();
212f7cf2976SLionel Sambuc #endif
213f7cf2976SLionel Sambuc 
214f7cf2976SLionel Sambuc /*
215f7cf2976SLionel Sambuc  * These two variables are sometimes defined in,
216f7cf2976SLionel Sambuc  * and needed by, the termcap library.
217f7cf2976SLionel Sambuc  */
218f7cf2976SLionel Sambuc #if MUST_DEFINE_OSPEED
219f7cf2976SLionel Sambuc extern short ospeed;	/* Terminal output baud rate */
220f7cf2976SLionel Sambuc extern char PC;		/* Pad character */
221f7cf2976SLionel Sambuc #endif
222f7cf2976SLionel Sambuc #ifdef _OSK
223f7cf2976SLionel Sambuc short ospeed;
224f7cf2976SLionel Sambuc char PC_, *UP, *BC;
225f7cf2976SLionel Sambuc #endif
226f7cf2976SLionel Sambuc 
227f7cf2976SLionel Sambuc extern int quiet;		/* If VERY_QUIET, use visual bell for bell */
228f7cf2976SLionel Sambuc extern int no_back_scroll;
229f7cf2976SLionel Sambuc extern int swindow;
230f7cf2976SLionel Sambuc extern int no_init;
231f7cf2976SLionel Sambuc extern int quit_at_eof;
232f7cf2976SLionel Sambuc extern int more_mode;
233f7cf2976SLionel Sambuc extern int no_keypad;
234f7cf2976SLionel Sambuc extern int sigs;
235f7cf2976SLionel Sambuc extern int wscroll;
236f7cf2976SLionel Sambuc extern int screen_trashed;
237f7cf2976SLionel Sambuc extern int tty;
238f7cf2976SLionel Sambuc extern int top_scroll;
239f7cf2976SLionel Sambuc extern int oldbot;
240f7cf2976SLionel Sambuc #if HILITE_SEARCH
241f7cf2976SLionel Sambuc extern int hilite_search;
242f7cf2976SLionel Sambuc #endif
243f7cf2976SLionel Sambuc 
244f7cf2976SLionel Sambuc #ifndef HAVE_TERMCAP_H
245f7cf2976SLionel Sambuc extern char *tgetstr();
246f7cf2976SLionel Sambuc extern char *tgoto();
247f7cf2976SLionel Sambuc #endif
248f7cf2976SLionel Sambuc 
249f7cf2976SLionel Sambuc 
250f7cf2976SLionel Sambuc /*
251f7cf2976SLionel Sambuc  * Change terminal to "raw mode", or restore to "normal" mode.
252f7cf2976SLionel Sambuc  * "Raw mode" means
253f7cf2976SLionel Sambuc  *	1. An outstanding read will complete on receipt of a single keystroke.
254f7cf2976SLionel Sambuc  *	2. Input is not echoed.
255f7cf2976SLionel Sambuc  *	3. On output, \n is mapped to \r\n.
256f7cf2976SLionel Sambuc  *	4. \t is NOT expanded into spaces.
257f7cf2976SLionel Sambuc  *	5. Signal-causing characters such as ctrl-C (interrupt),
258f7cf2976SLionel Sambuc  *	   etc. are NOT disabled.
259f7cf2976SLionel Sambuc  * It doesn't matter whether an input \n is mapped to \r, or vice versa.
260f7cf2976SLionel Sambuc  */
261f7cf2976SLionel Sambuc 	public void
raw_mode(on)262f7cf2976SLionel Sambuc raw_mode(on)
263f7cf2976SLionel Sambuc 	int on;
264f7cf2976SLionel Sambuc {
265f7cf2976SLionel Sambuc 	static int curr_on = 0;
266f7cf2976SLionel Sambuc 
267f7cf2976SLionel Sambuc 	if (on == curr_on)
268f7cf2976SLionel Sambuc 		return;
269f7cf2976SLionel Sambuc 	erase2_char = '\b'; /* in case OS doesn't know about erase2 */
270f7cf2976SLionel Sambuc #if HAVE_TERMIOS_H && HAVE_TERMIOS_FUNCS
271f7cf2976SLionel Sambuc     {
272f7cf2976SLionel Sambuc 	struct termios s;
273f7cf2976SLionel Sambuc 	static struct termios save_term;
274f7cf2976SLionel Sambuc 	static int saved_term = 0;
275f7cf2976SLionel Sambuc 
276f7cf2976SLionel Sambuc 	if (on)
277f7cf2976SLionel Sambuc 	{
278f7cf2976SLionel Sambuc 		/*
279f7cf2976SLionel Sambuc 		 * Get terminal modes.
280f7cf2976SLionel Sambuc 		 */
281f7cf2976SLionel Sambuc 		tcgetattr(tty, &s);
282f7cf2976SLionel Sambuc 
283f7cf2976SLionel Sambuc 		/*
284f7cf2976SLionel Sambuc 		 * Save modes and set certain variables dependent on modes.
285f7cf2976SLionel Sambuc 		 */
286f7cf2976SLionel Sambuc 		if (!saved_term)
287f7cf2976SLionel Sambuc 		{
288f7cf2976SLionel Sambuc 			save_term = s;
289f7cf2976SLionel Sambuc 			saved_term = 1;
290f7cf2976SLionel Sambuc 		}
291f7cf2976SLionel Sambuc #if HAVE_OSPEED
292f7cf2976SLionel Sambuc 		switch (cfgetospeed(&s))
293f7cf2976SLionel Sambuc 		{
294f7cf2976SLionel Sambuc #ifdef B0
295f7cf2976SLionel Sambuc 		case B0: ospeed = 0; break;
296f7cf2976SLionel Sambuc #endif
297f7cf2976SLionel Sambuc #ifdef B50
298f7cf2976SLionel Sambuc 		case B50: ospeed = 1; break;
299f7cf2976SLionel Sambuc #endif
300f7cf2976SLionel Sambuc #ifdef B75
301f7cf2976SLionel Sambuc 		case B75: ospeed = 2; break;
302f7cf2976SLionel Sambuc #endif
303f7cf2976SLionel Sambuc #ifdef B110
304f7cf2976SLionel Sambuc 		case B110: ospeed = 3; break;
305f7cf2976SLionel Sambuc #endif
306f7cf2976SLionel Sambuc #ifdef B134
307f7cf2976SLionel Sambuc 		case B134: ospeed = 4; break;
308f7cf2976SLionel Sambuc #endif
309f7cf2976SLionel Sambuc #ifdef B150
310f7cf2976SLionel Sambuc 		case B150: ospeed = 5; break;
311f7cf2976SLionel Sambuc #endif
312f7cf2976SLionel Sambuc #ifdef B200
313f7cf2976SLionel Sambuc 		case B200: ospeed = 6; break;
314f7cf2976SLionel Sambuc #endif
315f7cf2976SLionel Sambuc #ifdef B300
316f7cf2976SLionel Sambuc 		case B300: ospeed = 7; break;
317f7cf2976SLionel Sambuc #endif
318f7cf2976SLionel Sambuc #ifdef B600
319f7cf2976SLionel Sambuc 		case B600: ospeed = 8; break;
320f7cf2976SLionel Sambuc #endif
321f7cf2976SLionel Sambuc #ifdef B1200
322f7cf2976SLionel Sambuc 		case B1200: ospeed = 9; break;
323f7cf2976SLionel Sambuc #endif
324f7cf2976SLionel Sambuc #ifdef B1800
325f7cf2976SLionel Sambuc 		case B1800: ospeed = 10; break;
326f7cf2976SLionel Sambuc #endif
327f7cf2976SLionel Sambuc #ifdef B2400
328f7cf2976SLionel Sambuc 		case B2400: ospeed = 11; break;
329f7cf2976SLionel Sambuc #endif
330f7cf2976SLionel Sambuc #ifdef B4800
331f7cf2976SLionel Sambuc 		case B4800: ospeed = 12; break;
332f7cf2976SLionel Sambuc #endif
333f7cf2976SLionel Sambuc #ifdef B9600
334f7cf2976SLionel Sambuc 		case B9600: ospeed = 13; break;
335f7cf2976SLionel Sambuc #endif
336f7cf2976SLionel Sambuc #ifdef EXTA
337f7cf2976SLionel Sambuc 		case EXTA: ospeed = 14; break;
338f7cf2976SLionel Sambuc #endif
339f7cf2976SLionel Sambuc #ifdef EXTB
340f7cf2976SLionel Sambuc 		case EXTB: ospeed = 15; break;
341f7cf2976SLionel Sambuc #endif
342f7cf2976SLionel Sambuc #ifdef B57600
343f7cf2976SLionel Sambuc 		case B57600: ospeed = 16; break;
344f7cf2976SLionel Sambuc #endif
345f7cf2976SLionel Sambuc #ifdef B115200
346f7cf2976SLionel Sambuc 		case B115200: ospeed = 17; break;
347f7cf2976SLionel Sambuc #endif
348f7cf2976SLionel Sambuc 		default: ;
349f7cf2976SLionel Sambuc 		}
350f7cf2976SLionel Sambuc #endif
351f7cf2976SLionel Sambuc 		erase_char = s.c_cc[VERASE];
352f7cf2976SLionel Sambuc #ifdef VERASE2
353f7cf2976SLionel Sambuc 		erase2_char = s.c_cc[VERASE2];
354f7cf2976SLionel Sambuc #endif
355f7cf2976SLionel Sambuc 		kill_char = s.c_cc[VKILL];
356f7cf2976SLionel Sambuc #ifdef VWERASE
357f7cf2976SLionel Sambuc 		werase_char = s.c_cc[VWERASE];
358f7cf2976SLionel Sambuc #else
359f7cf2976SLionel Sambuc 		werase_char = CONTROL('W');
360f7cf2976SLionel Sambuc #endif
361f7cf2976SLionel Sambuc 
362f7cf2976SLionel Sambuc 		/*
363f7cf2976SLionel Sambuc 		 * Set the modes to the way we want them.
364f7cf2976SLionel Sambuc 		 */
365f7cf2976SLionel Sambuc 		s.c_lflag &= ~(0
366f7cf2976SLionel Sambuc #ifdef ICANON
367f7cf2976SLionel Sambuc 			| ICANON
368f7cf2976SLionel Sambuc #endif
369f7cf2976SLionel Sambuc #ifdef ECHO
370f7cf2976SLionel Sambuc 			| ECHO
371f7cf2976SLionel Sambuc #endif
372f7cf2976SLionel Sambuc #ifdef ECHOE
373f7cf2976SLionel Sambuc 			| ECHOE
374f7cf2976SLionel Sambuc #endif
375f7cf2976SLionel Sambuc #ifdef ECHOK
376f7cf2976SLionel Sambuc 			| ECHOK
377f7cf2976SLionel Sambuc #endif
378f7cf2976SLionel Sambuc #if ECHONL
379f7cf2976SLionel Sambuc 			| ECHONL
380f7cf2976SLionel Sambuc #endif
381f7cf2976SLionel Sambuc 		);
382f7cf2976SLionel Sambuc 
383f7cf2976SLionel Sambuc 		s.c_oflag |= (0
384f7cf2976SLionel Sambuc #ifdef OXTABS
385f7cf2976SLionel Sambuc 			| OXTABS
386f7cf2976SLionel Sambuc #else
387f7cf2976SLionel Sambuc #ifdef TAB3
388f7cf2976SLionel Sambuc 			| TAB3
389f7cf2976SLionel Sambuc #else
390f7cf2976SLionel Sambuc #ifdef XTABS
391f7cf2976SLionel Sambuc 			| XTABS
392f7cf2976SLionel Sambuc #endif
393f7cf2976SLionel Sambuc #endif
394f7cf2976SLionel Sambuc #endif
395f7cf2976SLionel Sambuc #ifdef OPOST
396f7cf2976SLionel Sambuc 			| OPOST
397f7cf2976SLionel Sambuc #endif
398f7cf2976SLionel Sambuc #ifdef ONLCR
399f7cf2976SLionel Sambuc 			| ONLCR
400f7cf2976SLionel Sambuc #endif
401f7cf2976SLionel Sambuc 		);
402f7cf2976SLionel Sambuc 
403f7cf2976SLionel Sambuc 		s.c_oflag &= ~(0
404f7cf2976SLionel Sambuc #ifdef ONOEOT
405f7cf2976SLionel Sambuc 			| ONOEOT
406f7cf2976SLionel Sambuc #endif
407f7cf2976SLionel Sambuc #ifdef OCRNL
408f7cf2976SLionel Sambuc 			| OCRNL
409f7cf2976SLionel Sambuc #endif
410f7cf2976SLionel Sambuc #ifdef ONOCR
411f7cf2976SLionel Sambuc 			| ONOCR
412f7cf2976SLionel Sambuc #endif
413f7cf2976SLionel Sambuc #ifdef ONLRET
414f7cf2976SLionel Sambuc 			| ONLRET
415f7cf2976SLionel Sambuc #endif
416f7cf2976SLionel Sambuc 		);
417f7cf2976SLionel Sambuc 		s.c_cc[VMIN] = 1;
418f7cf2976SLionel Sambuc 		s.c_cc[VTIME] = 0;
419f7cf2976SLionel Sambuc #ifdef VLNEXT
420f7cf2976SLionel Sambuc 		s.c_cc[VLNEXT] = 0;
421f7cf2976SLionel Sambuc #endif
422f7cf2976SLionel Sambuc #ifdef VDSUSP
423f7cf2976SLionel Sambuc 		s.c_cc[VDSUSP] = 0;
424f7cf2976SLionel Sambuc #endif
425f7cf2976SLionel Sambuc #if MUST_SET_LINE_DISCIPLINE
426f7cf2976SLionel Sambuc 		/*
427f7cf2976SLionel Sambuc 		 * System's termios is broken; need to explicitly
428f7cf2976SLionel Sambuc 		 * request TERMIODISC line discipline.
429f7cf2976SLionel Sambuc 		 */
430f7cf2976SLionel Sambuc 		s.c_line = TERMIODISC;
431f7cf2976SLionel Sambuc #endif
432f7cf2976SLionel Sambuc 	} else
433f7cf2976SLionel Sambuc 	{
434f7cf2976SLionel Sambuc 		/*
435f7cf2976SLionel Sambuc 		 * Restore saved modes.
436f7cf2976SLionel Sambuc 		 */
437f7cf2976SLionel Sambuc 		s = save_term;
438f7cf2976SLionel Sambuc 	}
439f7cf2976SLionel Sambuc #if HAVE_FSYNC
440f7cf2976SLionel Sambuc 	fsync(tty);
441f7cf2976SLionel Sambuc #endif
442f7cf2976SLionel Sambuc 	tcsetattr(tty, TCSADRAIN, &s);
443f7cf2976SLionel Sambuc #if MUST_SET_LINE_DISCIPLINE
444f7cf2976SLionel Sambuc 	if (!on)
445f7cf2976SLionel Sambuc 	{
446f7cf2976SLionel Sambuc 		/*
447f7cf2976SLionel Sambuc 		 * Broken termios *ignores* any line discipline
448f7cf2976SLionel Sambuc 		 * except TERMIODISC.  A different old line discipline
449f7cf2976SLionel Sambuc 		 * is therefore not restored, yet.  Restore the old
450f7cf2976SLionel Sambuc 		 * line discipline by hand.
451f7cf2976SLionel Sambuc 		 */
452f7cf2976SLionel Sambuc 		ioctl(tty, TIOCSETD, &save_term.c_line);
453f7cf2976SLionel Sambuc 	}
454f7cf2976SLionel Sambuc #endif
455f7cf2976SLionel Sambuc     }
456f7cf2976SLionel Sambuc #else
457f7cf2976SLionel Sambuc #ifdef TCGETA
458f7cf2976SLionel Sambuc     {
459f7cf2976SLionel Sambuc 	struct termio s;
460f7cf2976SLionel Sambuc 	static struct termio save_term;
461f7cf2976SLionel Sambuc 	static int saved_term = 0;
462f7cf2976SLionel Sambuc 
463f7cf2976SLionel Sambuc 	if (on)
464f7cf2976SLionel Sambuc 	{
465f7cf2976SLionel Sambuc 		/*
466f7cf2976SLionel Sambuc 		 * Get terminal modes.
467f7cf2976SLionel Sambuc 		 */
468f7cf2976SLionel Sambuc 		ioctl(tty, TCGETA, &s);
469f7cf2976SLionel Sambuc 
470f7cf2976SLionel Sambuc 		/*
471f7cf2976SLionel Sambuc 		 * Save modes and set certain variables dependent on modes.
472f7cf2976SLionel Sambuc 		 */
473f7cf2976SLionel Sambuc 		if (!saved_term)
474f7cf2976SLionel Sambuc 		{
475f7cf2976SLionel Sambuc 			save_term = s;
476f7cf2976SLionel Sambuc 			saved_term = 1;
477f7cf2976SLionel Sambuc 		}
478f7cf2976SLionel Sambuc #if HAVE_OSPEED
479f7cf2976SLionel Sambuc 		ospeed = s.c_cflag & CBAUD;
480f7cf2976SLionel Sambuc #endif
481f7cf2976SLionel Sambuc 		erase_char = s.c_cc[VERASE];
482f7cf2976SLionel Sambuc 		kill_char = s.c_cc[VKILL];
483f7cf2976SLionel Sambuc #ifdef VWERASE
484f7cf2976SLionel Sambuc 		werase_char = s.c_cc[VWERASE];
485f7cf2976SLionel Sambuc #else
486f7cf2976SLionel Sambuc 		werase_char = CONTROL('W');
487f7cf2976SLionel Sambuc #endif
488f7cf2976SLionel Sambuc 
489f7cf2976SLionel Sambuc 		/*
490f7cf2976SLionel Sambuc 		 * Set the modes to the way we want them.
491f7cf2976SLionel Sambuc 		 */
492f7cf2976SLionel Sambuc 		s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
493f7cf2976SLionel Sambuc 		s.c_oflag |=  (OPOST|ONLCR|TAB3);
494f7cf2976SLionel Sambuc 		s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
495f7cf2976SLionel Sambuc 		s.c_cc[VMIN] = 1;
496f7cf2976SLionel Sambuc 		s.c_cc[VTIME] = 0;
497f7cf2976SLionel Sambuc 	} else
498f7cf2976SLionel Sambuc 	{
499f7cf2976SLionel Sambuc 		/*
500f7cf2976SLionel Sambuc 		 * Restore saved modes.
501f7cf2976SLionel Sambuc 		 */
502f7cf2976SLionel Sambuc 		s = save_term;
503f7cf2976SLionel Sambuc 	}
504f7cf2976SLionel Sambuc 	ioctl(tty, TCSETAW, &s);
505f7cf2976SLionel Sambuc     }
506f7cf2976SLionel Sambuc #else
507f7cf2976SLionel Sambuc #ifdef TIOCGETP
508f7cf2976SLionel Sambuc     {
509f7cf2976SLionel Sambuc 	struct sgttyb s;
510f7cf2976SLionel Sambuc 	static struct sgttyb save_term;
511f7cf2976SLionel Sambuc 	static int saved_term = 0;
512f7cf2976SLionel Sambuc 
513f7cf2976SLionel Sambuc 	if (on)
514f7cf2976SLionel Sambuc 	{
515f7cf2976SLionel Sambuc 		/*
516f7cf2976SLionel Sambuc 		 * Get terminal modes.
517f7cf2976SLionel Sambuc 		 */
518f7cf2976SLionel Sambuc 		ioctl(tty, TIOCGETP, &s);
519f7cf2976SLionel Sambuc 
520f7cf2976SLionel Sambuc 		/*
521f7cf2976SLionel Sambuc 		 * Save modes and set certain variables dependent on modes.
522f7cf2976SLionel Sambuc 		 */
523f7cf2976SLionel Sambuc 		if (!saved_term)
524f7cf2976SLionel Sambuc 		{
525f7cf2976SLionel Sambuc 			save_term = s;
526f7cf2976SLionel Sambuc 			saved_term = 1;
527f7cf2976SLionel Sambuc 		}
528f7cf2976SLionel Sambuc #if HAVE_OSPEED
529f7cf2976SLionel Sambuc 		ospeed = s.sg_ospeed;
530f7cf2976SLionel Sambuc #endif
531f7cf2976SLionel Sambuc 		erase_char = s.sg_erase;
532f7cf2976SLionel Sambuc 		kill_char = s.sg_kill;
533f7cf2976SLionel Sambuc 		werase_char = CONTROL('W');
534f7cf2976SLionel Sambuc 
535f7cf2976SLionel Sambuc 		/*
536f7cf2976SLionel Sambuc 		 * Set the modes to the way we want them.
537f7cf2976SLionel Sambuc 		 */
538f7cf2976SLionel Sambuc 		s.sg_flags |= CBREAK;
539f7cf2976SLionel Sambuc 		s.sg_flags &= ~(ECHO|XTABS);
540f7cf2976SLionel Sambuc 	} else
541f7cf2976SLionel Sambuc 	{
542f7cf2976SLionel Sambuc 		/*
543f7cf2976SLionel Sambuc 		 * Restore saved modes.
544f7cf2976SLionel Sambuc 		 */
545f7cf2976SLionel Sambuc 		s = save_term;
546f7cf2976SLionel Sambuc 	}
547f7cf2976SLionel Sambuc 	ioctl(tty, TIOCSETN, &s);
548f7cf2976SLionel Sambuc     }
549f7cf2976SLionel Sambuc #else
550f7cf2976SLionel Sambuc #ifdef _OSK
551f7cf2976SLionel Sambuc     {
552f7cf2976SLionel Sambuc 	struct sgbuf s;
553f7cf2976SLionel Sambuc 	static struct sgbuf save_term;
554f7cf2976SLionel Sambuc 	static int saved_term = 0;
555f7cf2976SLionel Sambuc 
556f7cf2976SLionel Sambuc 	if (on)
557f7cf2976SLionel Sambuc 	{
558f7cf2976SLionel Sambuc 		/*
559f7cf2976SLionel Sambuc 		 * Get terminal modes.
560f7cf2976SLionel Sambuc 		 */
561f7cf2976SLionel Sambuc 		_gs_opt(tty, &s);
562f7cf2976SLionel Sambuc 
563f7cf2976SLionel Sambuc 		/*
564f7cf2976SLionel Sambuc 		 * Save modes and set certain variables dependent on modes.
565f7cf2976SLionel Sambuc 		 */
566f7cf2976SLionel Sambuc 		if (!saved_term)
567f7cf2976SLionel Sambuc 		{
568f7cf2976SLionel Sambuc 			save_term = s;
569f7cf2976SLionel Sambuc 			saved_term = 1;
570f7cf2976SLionel Sambuc 		}
571f7cf2976SLionel Sambuc 		erase_char = s.sg_bspch;
572f7cf2976SLionel Sambuc 		kill_char = s.sg_dlnch;
573f7cf2976SLionel Sambuc 		werase_char = CONTROL('W');
574f7cf2976SLionel Sambuc 
575f7cf2976SLionel Sambuc 		/*
576f7cf2976SLionel Sambuc 		 * Set the modes to the way we want them.
577f7cf2976SLionel Sambuc 		 */
578f7cf2976SLionel Sambuc 		s.sg_echo = 0;
579f7cf2976SLionel Sambuc 		s.sg_eofch = 0;
580f7cf2976SLionel Sambuc 		s.sg_pause = 0;
581f7cf2976SLionel Sambuc 		s.sg_psch = 0;
582f7cf2976SLionel Sambuc 	} else
583f7cf2976SLionel Sambuc 	{
584f7cf2976SLionel Sambuc 		/*
585f7cf2976SLionel Sambuc 		 * Restore saved modes.
586f7cf2976SLionel Sambuc 		 */
587f7cf2976SLionel Sambuc 		s = save_term;
588f7cf2976SLionel Sambuc 	}
589f7cf2976SLionel Sambuc 	_ss_opt(tty, &s);
590f7cf2976SLionel Sambuc     }
591f7cf2976SLionel Sambuc #else
592f7cf2976SLionel Sambuc 	/* MS-DOS, Windows, or OS2 */
593f7cf2976SLionel Sambuc #if OS2
594f7cf2976SLionel Sambuc 	/* OS2 */
595f7cf2976SLionel Sambuc 	LSIGNAL(SIGINT, SIG_IGN);
596f7cf2976SLionel Sambuc #endif
597f7cf2976SLionel Sambuc 	erase_char = '\b';
598f7cf2976SLionel Sambuc #if MSDOS_COMPILER==DJGPPC
599f7cf2976SLionel Sambuc 	kill_char = CONTROL('U');
600f7cf2976SLionel Sambuc 	/*
601f7cf2976SLionel Sambuc 	 * So that when we shell out or run another program, its
602f7cf2976SLionel Sambuc 	 * stdin is in cooked mode.  We do not switch stdin to binary
603f7cf2976SLionel Sambuc 	 * mode if fd0 is zero, since that means we were called before
604f7cf2976SLionel Sambuc 	 * tty was reopened in open_getchr, in which case we would be
605f7cf2976SLionel Sambuc 	 * changing the original stdin device outside less.
606f7cf2976SLionel Sambuc 	 */
607f7cf2976SLionel Sambuc 	if (fd0 != 0)
608f7cf2976SLionel Sambuc 		setmode(0, on ? O_BINARY : O_TEXT);
609f7cf2976SLionel Sambuc #else
610f7cf2976SLionel Sambuc 	kill_char = ESC;
611f7cf2976SLionel Sambuc #endif
612f7cf2976SLionel Sambuc 	werase_char = CONTROL('W');
613f7cf2976SLionel Sambuc #endif
614f7cf2976SLionel Sambuc #endif
615f7cf2976SLionel Sambuc #endif
616f7cf2976SLionel Sambuc #endif
617f7cf2976SLionel Sambuc 	curr_on = on;
618f7cf2976SLionel Sambuc }
619f7cf2976SLionel Sambuc 
620f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
621f7cf2976SLionel Sambuc /*
622f7cf2976SLionel Sambuc  * Some glue to prevent calling termcap functions if tgetent() failed.
623f7cf2976SLionel Sambuc  */
624f7cf2976SLionel Sambuc static int hardcopy;
625f7cf2976SLionel Sambuc 
626f7cf2976SLionel Sambuc 	static char *
ltget_env(capname)627f7cf2976SLionel Sambuc ltget_env(capname)
628f7cf2976SLionel Sambuc 	char *capname;
629f7cf2976SLionel Sambuc {
630f7cf2976SLionel Sambuc 	char name[16];
631f7cf2976SLionel Sambuc 	char *s;
632f7cf2976SLionel Sambuc 
633f7cf2976SLionel Sambuc 	s = lgetenv("LESS_TERMCAP_DEBUG");
634f7cf2976SLionel Sambuc 	if (s != NULL && *s != '\0')
635f7cf2976SLionel Sambuc 	{
636f7cf2976SLionel Sambuc 		struct env { struct env *next; char *name; char *value; };
637f7cf2976SLionel Sambuc 		static struct env *envs = NULL;
638f7cf2976SLionel Sambuc 		struct env *p;
639f7cf2976SLionel Sambuc 		for (p = envs;  p != NULL;  p = p->next)
640f7cf2976SLionel Sambuc 			if (strcmp(p->name, capname) == 0)
641f7cf2976SLionel Sambuc 				return p->value;
642f7cf2976SLionel Sambuc 		p = (struct env *) ecalloc(1, sizeof(struct env));
643f7cf2976SLionel Sambuc 		p->name = save(capname);
644f7cf2976SLionel Sambuc 		p->value = (char *) ecalloc(strlen(capname)+3, sizeof(char));
645f7cf2976SLionel Sambuc 		sprintf(p->value, "<%s>", capname);
646f7cf2976SLionel Sambuc 		p->next = envs;
647f7cf2976SLionel Sambuc 		envs = p;
648f7cf2976SLionel Sambuc 		return p->value;
649f7cf2976SLionel Sambuc 	}
650f7cf2976SLionel Sambuc 	strcpy(name, "LESS_TERMCAP_");
651f7cf2976SLionel Sambuc 	strcat(name, capname);
652f7cf2976SLionel Sambuc 	return (lgetenv(name));
653f7cf2976SLionel Sambuc }
654f7cf2976SLionel Sambuc 
655f7cf2976SLionel Sambuc 	static int
ltgetflag(capname)656f7cf2976SLionel Sambuc ltgetflag(capname)
657f7cf2976SLionel Sambuc 	char *capname;
658f7cf2976SLionel Sambuc {
659f7cf2976SLionel Sambuc 	char *s;
660f7cf2976SLionel Sambuc 
661f7cf2976SLionel Sambuc 	if ((s = ltget_env(capname)) != NULL)
662f7cf2976SLionel Sambuc 		return (*s != '\0' && *s != '0');
663f7cf2976SLionel Sambuc 	if (hardcopy)
664f7cf2976SLionel Sambuc 		return (0);
665f7cf2976SLionel Sambuc 	return (tgetflag(capname));
666f7cf2976SLionel Sambuc }
667f7cf2976SLionel Sambuc 
668f7cf2976SLionel Sambuc 	static int
ltgetnum(capname)669f7cf2976SLionel Sambuc ltgetnum(capname)
670f7cf2976SLionel Sambuc 	char *capname;
671f7cf2976SLionel Sambuc {
672f7cf2976SLionel Sambuc 	char *s;
673f7cf2976SLionel Sambuc 
674f7cf2976SLionel Sambuc 	if ((s = ltget_env(capname)) != NULL)
675f7cf2976SLionel Sambuc 		return (atoi(s));
676f7cf2976SLionel Sambuc 	if (hardcopy)
677f7cf2976SLionel Sambuc 		return (-1);
678f7cf2976SLionel Sambuc 	return (tgetnum(capname));
679f7cf2976SLionel Sambuc }
680f7cf2976SLionel Sambuc 
681f7cf2976SLionel Sambuc 	static char *
ltgetstr(capname,pp)682f7cf2976SLionel Sambuc ltgetstr(capname, pp)
683f7cf2976SLionel Sambuc 	char *capname;
684f7cf2976SLionel Sambuc 	char **pp;
685f7cf2976SLionel Sambuc {
686f7cf2976SLionel Sambuc 	char *s;
687f7cf2976SLionel Sambuc 
688f7cf2976SLionel Sambuc 	if ((s = ltget_env(capname)) != NULL)
689f7cf2976SLionel Sambuc 		return (s);
690f7cf2976SLionel Sambuc 	if (hardcopy)
691f7cf2976SLionel Sambuc 		return (NULL);
692f7cf2976SLionel Sambuc 	return (tgetstr(capname, pp));
693f7cf2976SLionel Sambuc }
694f7cf2976SLionel Sambuc #endif /* MSDOS_COMPILER */
695f7cf2976SLionel Sambuc 
696f7cf2976SLionel Sambuc /*
697f7cf2976SLionel Sambuc  * Get size of the output screen.
698f7cf2976SLionel Sambuc  */
699f7cf2976SLionel Sambuc 	public void
scrsize()700f7cf2976SLionel Sambuc scrsize()
701f7cf2976SLionel Sambuc {
702f7cf2976SLionel Sambuc 	register char *s;
703f7cf2976SLionel Sambuc 	int sys_height;
704f7cf2976SLionel Sambuc 	int sys_width;
705f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
706f7cf2976SLionel Sambuc 	int n;
707f7cf2976SLionel Sambuc #endif
708f7cf2976SLionel Sambuc 
709f7cf2976SLionel Sambuc #define	DEF_SC_WIDTH	80
710f7cf2976SLionel Sambuc #if MSDOS_COMPILER
711f7cf2976SLionel Sambuc #define	DEF_SC_HEIGHT	25
712f7cf2976SLionel Sambuc #else
713f7cf2976SLionel Sambuc #define	DEF_SC_HEIGHT	24
714f7cf2976SLionel Sambuc #endif
715f7cf2976SLionel Sambuc 
716f7cf2976SLionel Sambuc 
717f7cf2976SLionel Sambuc 	sys_width = sys_height = 0;
718f7cf2976SLionel Sambuc 
719f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
720f7cf2976SLionel Sambuc 	{
721f7cf2976SLionel Sambuc 		struct videoconfig w;
722f7cf2976SLionel Sambuc 		_getvideoconfig(&w);
723f7cf2976SLionel Sambuc 		sys_height = w.numtextrows;
724f7cf2976SLionel Sambuc 		sys_width = w.numtextcols;
725f7cf2976SLionel Sambuc 	}
726f7cf2976SLionel Sambuc #else
727f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
728f7cf2976SLionel Sambuc 	{
729f7cf2976SLionel Sambuc 		struct text_info w;
730f7cf2976SLionel Sambuc 		gettextinfo(&w);
731f7cf2976SLionel Sambuc 		sys_height = w.screenheight;
732f7cf2976SLionel Sambuc 		sys_width = w.screenwidth;
733f7cf2976SLionel Sambuc 	}
734f7cf2976SLionel Sambuc #else
735f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
736f7cf2976SLionel Sambuc 	{
737f7cf2976SLionel Sambuc 		CONSOLE_SCREEN_BUFFER_INFO scr;
738f7cf2976SLionel Sambuc 		GetConsoleScreenBufferInfo(con_out, &scr);
739f7cf2976SLionel Sambuc 		sys_height = scr.srWindow.Bottom - scr.srWindow.Top + 1;
740f7cf2976SLionel Sambuc 		sys_width = scr.srWindow.Right - scr.srWindow.Left + 1;
741f7cf2976SLionel Sambuc 	}
742f7cf2976SLionel Sambuc #else
743f7cf2976SLionel Sambuc #if OS2
744f7cf2976SLionel Sambuc 	{
745f7cf2976SLionel Sambuc 		int s[2];
746f7cf2976SLionel Sambuc 		_scrsize(s);
747f7cf2976SLionel Sambuc 		sys_width = s[0];
748f7cf2976SLionel Sambuc 		sys_height = s[1];
749f7cf2976SLionel Sambuc 		/*
750f7cf2976SLionel Sambuc 		 * When using terminal emulators for XFree86/OS2, the
751f7cf2976SLionel Sambuc 		 * _scrsize function does not work well.
752f7cf2976SLionel Sambuc 		 * Call the scrsize.exe program to get the window size.
753f7cf2976SLionel Sambuc 		 */
754f7cf2976SLionel Sambuc 		windowid = getenv("WINDOWID");
755f7cf2976SLionel Sambuc 		if (windowid != NULL)
756f7cf2976SLionel Sambuc 		{
757f7cf2976SLionel Sambuc 			FILE *fd = popen("scrsize", "rt");
758f7cf2976SLionel Sambuc 			if (fd != NULL)
759f7cf2976SLionel Sambuc 			{
760f7cf2976SLionel Sambuc 				int w, h;
761f7cf2976SLionel Sambuc 				fscanf(fd, "%i %i", &w, &h);
762f7cf2976SLionel Sambuc 				if (w > 0 && h > 0)
763f7cf2976SLionel Sambuc 				{
764f7cf2976SLionel Sambuc 					sys_width = w;
765f7cf2976SLionel Sambuc 					sys_height = h;
766f7cf2976SLionel Sambuc 				}
767f7cf2976SLionel Sambuc 				pclose(fd);
768f7cf2976SLionel Sambuc 			}
769f7cf2976SLionel Sambuc 		}
770f7cf2976SLionel Sambuc 	}
771f7cf2976SLionel Sambuc #else
772f7cf2976SLionel Sambuc #ifdef TIOCGWINSZ
773f7cf2976SLionel Sambuc 	{
774f7cf2976SLionel Sambuc 		struct winsize w;
775f7cf2976SLionel Sambuc 		if (ioctl(2, TIOCGWINSZ, &w) == 0)
776f7cf2976SLionel Sambuc 		{
777f7cf2976SLionel Sambuc 			if (w.ws_row > 0)
778f7cf2976SLionel Sambuc 				sys_height = w.ws_row;
779f7cf2976SLionel Sambuc 			if (w.ws_col > 0)
780f7cf2976SLionel Sambuc 				sys_width = w.ws_col;
781f7cf2976SLionel Sambuc 		}
782f7cf2976SLionel Sambuc 	}
783f7cf2976SLionel Sambuc #else
784f7cf2976SLionel Sambuc #ifdef WIOCGETD
785f7cf2976SLionel Sambuc 	{
786f7cf2976SLionel Sambuc 		struct uwdata w;
787f7cf2976SLionel Sambuc 		if (ioctl(2, WIOCGETD, &w) == 0)
788f7cf2976SLionel Sambuc 		{
789f7cf2976SLionel Sambuc 			if (w.uw_height > 0)
790f7cf2976SLionel Sambuc 				sys_height = w.uw_height / w.uw_vs;
791f7cf2976SLionel Sambuc 			if (w.uw_width > 0)
792f7cf2976SLionel Sambuc 				sys_width = w.uw_width / w.uw_hs;
793f7cf2976SLionel Sambuc 		}
794f7cf2976SLionel Sambuc 	}
795f7cf2976SLionel Sambuc #endif
796f7cf2976SLionel Sambuc #endif
797f7cf2976SLionel Sambuc #endif
798f7cf2976SLionel Sambuc #endif
799f7cf2976SLionel Sambuc #endif
800f7cf2976SLionel Sambuc #endif
801f7cf2976SLionel Sambuc 
802f7cf2976SLionel Sambuc 	if (sys_height > 0)
803f7cf2976SLionel Sambuc 		sc_height = sys_height;
804f7cf2976SLionel Sambuc 	else if ((s = lgetenv("LINES")) != NULL)
805f7cf2976SLionel Sambuc 		sc_height = atoi(s);
806f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
807f7cf2976SLionel Sambuc 	else if ((n = ltgetnum("li")) > 0)
808f7cf2976SLionel Sambuc  		sc_height = n;
809f7cf2976SLionel Sambuc #endif
810*84d9c625SLionel Sambuc 	if (sc_height <= 0)
811f7cf2976SLionel Sambuc 		sc_height = DEF_SC_HEIGHT;
812f7cf2976SLionel Sambuc 
813f7cf2976SLionel Sambuc 	if (sys_width > 0)
814f7cf2976SLionel Sambuc 		sc_width = sys_width;
815f7cf2976SLionel Sambuc 	else if ((s = lgetenv("COLUMNS")) != NULL)
816f7cf2976SLionel Sambuc 		sc_width = atoi(s);
817f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
818f7cf2976SLionel Sambuc 	else if ((n = ltgetnum("co")) > 0)
819f7cf2976SLionel Sambuc  		sc_width = n;
820f7cf2976SLionel Sambuc #endif
821*84d9c625SLionel Sambuc 	if (sc_width <= 0)
822f7cf2976SLionel Sambuc 		sc_width = DEF_SC_WIDTH;
823f7cf2976SLionel Sambuc }
824f7cf2976SLionel Sambuc 
825f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
826f7cf2976SLionel Sambuc /*
827f7cf2976SLionel Sambuc  * Figure out how many empty loops it takes to delay a millisecond.
828f7cf2976SLionel Sambuc  */
829f7cf2976SLionel Sambuc 	static void
get_clock()830f7cf2976SLionel Sambuc get_clock()
831f7cf2976SLionel Sambuc {
832f7cf2976SLionel Sambuc 	clock_t start;
833f7cf2976SLionel Sambuc 
834f7cf2976SLionel Sambuc 	/*
835f7cf2976SLionel Sambuc 	 * Get synchronized at the start of a tick.
836f7cf2976SLionel Sambuc 	 */
837f7cf2976SLionel Sambuc 	start = clock();
838f7cf2976SLionel Sambuc 	while (clock() == start)
839f7cf2976SLionel Sambuc 		;
840f7cf2976SLionel Sambuc 	/*
841f7cf2976SLionel Sambuc 	 * Now count loops till the next tick.
842f7cf2976SLionel Sambuc 	 */
843f7cf2976SLionel Sambuc 	start = clock();
844f7cf2976SLionel Sambuc 	msec_loops = 0;
845f7cf2976SLionel Sambuc 	while (clock() == start)
846f7cf2976SLionel Sambuc 		msec_loops++;
847f7cf2976SLionel Sambuc 	/*
848f7cf2976SLionel Sambuc 	 * Convert from (loops per clock) to (loops per millisecond).
849f7cf2976SLionel Sambuc 	 */
850f7cf2976SLionel Sambuc 	msec_loops *= CLOCKS_PER_SEC;
851f7cf2976SLionel Sambuc 	msec_loops /= 1000;
852f7cf2976SLionel Sambuc }
853f7cf2976SLionel Sambuc 
854f7cf2976SLionel Sambuc /*
855f7cf2976SLionel Sambuc  * Delay for a specified number of milliseconds.
856f7cf2976SLionel Sambuc  */
857f7cf2976SLionel Sambuc 	static void
dummy_func()858f7cf2976SLionel Sambuc dummy_func()
859f7cf2976SLionel Sambuc {
860f7cf2976SLionel Sambuc 	static long delay_dummy = 0;
861f7cf2976SLionel Sambuc 	delay_dummy++;
862f7cf2976SLionel Sambuc }
863f7cf2976SLionel Sambuc 
864f7cf2976SLionel Sambuc 	static void
delay(msec)865f7cf2976SLionel Sambuc delay(msec)
866f7cf2976SLionel Sambuc 	int msec;
867f7cf2976SLionel Sambuc {
868f7cf2976SLionel Sambuc 	long i;
869f7cf2976SLionel Sambuc 
870f7cf2976SLionel Sambuc 	while (msec-- > 0)
871f7cf2976SLionel Sambuc 	{
872f7cf2976SLionel Sambuc 		for (i = 0;  i < msec_loops;  i++)
873f7cf2976SLionel Sambuc 		{
874f7cf2976SLionel Sambuc 			/*
875f7cf2976SLionel Sambuc 			 * Make it look like we're doing something here,
876f7cf2976SLionel Sambuc 			 * so the optimizer doesn't remove the whole loop.
877f7cf2976SLionel Sambuc 			 */
878f7cf2976SLionel Sambuc 			dummy_func();
879f7cf2976SLionel Sambuc 		}
880f7cf2976SLionel Sambuc 	}
881f7cf2976SLionel Sambuc }
882f7cf2976SLionel Sambuc #endif
883f7cf2976SLionel Sambuc 
884f7cf2976SLionel Sambuc /*
885f7cf2976SLionel Sambuc  * Return the characters actually input by a "special" key.
886f7cf2976SLionel Sambuc  */
887f7cf2976SLionel Sambuc 	public char *
special_key_str(key)888f7cf2976SLionel Sambuc special_key_str(key)
889f7cf2976SLionel Sambuc 	int key;
890f7cf2976SLionel Sambuc {
891f7cf2976SLionel Sambuc 	static char tbuf[40];
892f7cf2976SLionel Sambuc 	char *s;
893f7cf2976SLionel Sambuc #if MSDOS_COMPILER || OS2
894f7cf2976SLionel Sambuc 	static char k_right[]		= { '\340', PCK_RIGHT, 0 };
895f7cf2976SLionel Sambuc 	static char k_left[]		= { '\340', PCK_LEFT, 0  };
896f7cf2976SLionel Sambuc 	static char k_ctl_right[]	= { '\340', PCK_CTL_RIGHT, 0  };
897f7cf2976SLionel Sambuc 	static char k_ctl_left[]	= { '\340', PCK_CTL_LEFT, 0  };
898f7cf2976SLionel Sambuc 	static char k_insert[]		= { '\340', PCK_INSERT, 0  };
899f7cf2976SLionel Sambuc 	static char k_delete[]		= { '\340', PCK_DELETE, 0  };
900f7cf2976SLionel Sambuc 	static char k_ctl_delete[]	= { '\340', PCK_CTL_DELETE, 0  };
901f7cf2976SLionel Sambuc 	static char k_ctl_backspace[]	= { '\177', 0 };
902f7cf2976SLionel Sambuc 	static char k_home[]		= { '\340', PCK_HOME, 0 };
903f7cf2976SLionel Sambuc 	static char k_end[]		= { '\340', PCK_END, 0 };
904f7cf2976SLionel Sambuc 	static char k_up[]		= { '\340', PCK_UP, 0 };
905f7cf2976SLionel Sambuc 	static char k_down[]		= { '\340', PCK_DOWN, 0 };
906f7cf2976SLionel Sambuc 	static char k_backtab[]		= { '\340', PCK_SHIFT_TAB, 0 };
907f7cf2976SLionel Sambuc 	static char k_pagedown[]	= { '\340', PCK_PAGEDOWN, 0 };
908f7cf2976SLionel Sambuc 	static char k_pageup[]		= { '\340', PCK_PAGEUP, 0 };
909f7cf2976SLionel Sambuc 	static char k_f1[]		= { '\340', PCK_F1, 0 };
910f7cf2976SLionel Sambuc #endif
911f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
912f7cf2976SLionel Sambuc 	char *sp = tbuf;
913f7cf2976SLionel Sambuc #endif
914f7cf2976SLionel Sambuc 
915f7cf2976SLionel Sambuc 	switch (key)
916f7cf2976SLionel Sambuc 	{
917f7cf2976SLionel Sambuc #if OS2
918f7cf2976SLionel Sambuc 	/*
919f7cf2976SLionel Sambuc 	 * If windowid is not NULL, assume less is executed in
920f7cf2976SLionel Sambuc 	 * the XFree86 environment.
921f7cf2976SLionel Sambuc 	 */
922f7cf2976SLionel Sambuc 	case SK_RIGHT_ARROW:
923f7cf2976SLionel Sambuc 		s = windowid ? ltgetstr("kr", &sp) : k_right;
924f7cf2976SLionel Sambuc 		break;
925f7cf2976SLionel Sambuc 	case SK_LEFT_ARROW:
926f7cf2976SLionel Sambuc 		s = windowid ? ltgetstr("kl", &sp) : k_left;
927f7cf2976SLionel Sambuc 		break;
928f7cf2976SLionel Sambuc 	case SK_UP_ARROW:
929f7cf2976SLionel Sambuc 		s = windowid ? ltgetstr("ku", &sp) : k_up;
930f7cf2976SLionel Sambuc 		break;
931f7cf2976SLionel Sambuc 	case SK_DOWN_ARROW:
932f7cf2976SLionel Sambuc 		s = windowid ? ltgetstr("kd", &sp) : k_down;
933f7cf2976SLionel Sambuc 		break;
934f7cf2976SLionel Sambuc 	case SK_PAGE_UP:
935f7cf2976SLionel Sambuc 		s = windowid ? ltgetstr("kP", &sp) : k_pageup;
936f7cf2976SLionel Sambuc 		break;
937f7cf2976SLionel Sambuc 	case SK_PAGE_DOWN:
938f7cf2976SLionel Sambuc 		s = windowid ? ltgetstr("kN", &sp) : k_pagedown;
939f7cf2976SLionel Sambuc 		break;
940f7cf2976SLionel Sambuc 	case SK_HOME:
941f7cf2976SLionel Sambuc 		s = windowid ? ltgetstr("kh", &sp) : k_home;
942f7cf2976SLionel Sambuc 		break;
943f7cf2976SLionel Sambuc 	case SK_END:
944f7cf2976SLionel Sambuc 		s = windowid ? ltgetstr("@7", &sp) : k_end;
945f7cf2976SLionel Sambuc 		break;
946f7cf2976SLionel Sambuc 	case SK_DELETE:
947f7cf2976SLionel Sambuc 		if (windowid)
948f7cf2976SLionel Sambuc 		{
949f7cf2976SLionel Sambuc 			s = ltgetstr("kD", &sp);
950f7cf2976SLionel Sambuc 			if (s == NULL)
951f7cf2976SLionel Sambuc 			{
952f7cf2976SLionel Sambuc 				tbuf[0] = '\177';
953f7cf2976SLionel Sambuc 				tbuf[1] = '\0';
954f7cf2976SLionel Sambuc 				s = tbuf;
955f7cf2976SLionel Sambuc 			}
956f7cf2976SLionel Sambuc 		} else
957f7cf2976SLionel Sambuc 			s = k_delete;
958f7cf2976SLionel Sambuc 		break;
959f7cf2976SLionel Sambuc #endif
960f7cf2976SLionel Sambuc #if MSDOS_COMPILER
961f7cf2976SLionel Sambuc 	case SK_RIGHT_ARROW:
962f7cf2976SLionel Sambuc 		s = k_right;
963f7cf2976SLionel Sambuc 		break;
964f7cf2976SLionel Sambuc 	case SK_LEFT_ARROW:
965f7cf2976SLionel Sambuc 		s = k_left;
966f7cf2976SLionel Sambuc 		break;
967f7cf2976SLionel Sambuc 	case SK_UP_ARROW:
968f7cf2976SLionel Sambuc 		s = k_up;
969f7cf2976SLionel Sambuc 		break;
970f7cf2976SLionel Sambuc 	case SK_DOWN_ARROW:
971f7cf2976SLionel Sambuc 		s = k_down;
972f7cf2976SLionel Sambuc 		break;
973f7cf2976SLionel Sambuc 	case SK_PAGE_UP:
974f7cf2976SLionel Sambuc 		s = k_pageup;
975f7cf2976SLionel Sambuc 		break;
976f7cf2976SLionel Sambuc 	case SK_PAGE_DOWN:
977f7cf2976SLionel Sambuc 		s = k_pagedown;
978f7cf2976SLionel Sambuc 		break;
979f7cf2976SLionel Sambuc 	case SK_HOME:
980f7cf2976SLionel Sambuc 		s = k_home;
981f7cf2976SLionel Sambuc 		break;
982f7cf2976SLionel Sambuc 	case SK_END:
983f7cf2976SLionel Sambuc 		s = k_end;
984f7cf2976SLionel Sambuc 		break;
985f7cf2976SLionel Sambuc 	case SK_DELETE:
986f7cf2976SLionel Sambuc 		s = k_delete;
987f7cf2976SLionel Sambuc 		break;
988f7cf2976SLionel Sambuc #endif
989f7cf2976SLionel Sambuc #if MSDOS_COMPILER || OS2
990f7cf2976SLionel Sambuc 	case SK_INSERT:
991f7cf2976SLionel Sambuc 		s = k_insert;
992f7cf2976SLionel Sambuc 		break;
993f7cf2976SLionel Sambuc 	case SK_CTL_LEFT_ARROW:
994f7cf2976SLionel Sambuc 		s = k_ctl_left;
995f7cf2976SLionel Sambuc 		break;
996f7cf2976SLionel Sambuc 	case SK_CTL_RIGHT_ARROW:
997f7cf2976SLionel Sambuc 		s = k_ctl_right;
998f7cf2976SLionel Sambuc 		break;
999f7cf2976SLionel Sambuc 	case SK_CTL_BACKSPACE:
1000f7cf2976SLionel Sambuc 		s = k_ctl_backspace;
1001f7cf2976SLionel Sambuc 		break;
1002f7cf2976SLionel Sambuc 	case SK_CTL_DELETE:
1003f7cf2976SLionel Sambuc 		s = k_ctl_delete;
1004f7cf2976SLionel Sambuc 		break;
1005f7cf2976SLionel Sambuc 	case SK_F1:
1006f7cf2976SLionel Sambuc 		s = k_f1;
1007f7cf2976SLionel Sambuc 		break;
1008f7cf2976SLionel Sambuc 	case SK_BACKTAB:
1009f7cf2976SLionel Sambuc 		s = k_backtab;
1010f7cf2976SLionel Sambuc 		break;
1011f7cf2976SLionel Sambuc #else
1012f7cf2976SLionel Sambuc 	case SK_RIGHT_ARROW:
1013f7cf2976SLionel Sambuc 		s = ltgetstr("kr", &sp);
1014f7cf2976SLionel Sambuc 		break;
1015f7cf2976SLionel Sambuc 	case SK_LEFT_ARROW:
1016f7cf2976SLionel Sambuc 		s = ltgetstr("kl", &sp);
1017f7cf2976SLionel Sambuc 		break;
1018f7cf2976SLionel Sambuc 	case SK_UP_ARROW:
1019f7cf2976SLionel Sambuc 		s = ltgetstr("ku", &sp);
1020f7cf2976SLionel Sambuc 		break;
1021f7cf2976SLionel Sambuc 	case SK_DOWN_ARROW:
1022f7cf2976SLionel Sambuc 		s = ltgetstr("kd", &sp);
1023f7cf2976SLionel Sambuc 		break;
1024f7cf2976SLionel Sambuc 	case SK_PAGE_UP:
1025f7cf2976SLionel Sambuc 		s = ltgetstr("kP", &sp);
1026f7cf2976SLionel Sambuc 		break;
1027f7cf2976SLionel Sambuc 	case SK_PAGE_DOWN:
1028f7cf2976SLionel Sambuc 		s = ltgetstr("kN", &sp);
1029f7cf2976SLionel Sambuc 		break;
1030f7cf2976SLionel Sambuc 	case SK_HOME:
1031f7cf2976SLionel Sambuc 		s = ltgetstr("kh", &sp);
1032f7cf2976SLionel Sambuc 		break;
1033f7cf2976SLionel Sambuc 	case SK_END:
1034f7cf2976SLionel Sambuc 		s = ltgetstr("@7", &sp);
1035f7cf2976SLionel Sambuc 		break;
1036f7cf2976SLionel Sambuc 	case SK_DELETE:
1037f7cf2976SLionel Sambuc 		s = ltgetstr("kD", &sp);
1038f7cf2976SLionel Sambuc 		if (s == NULL)
1039f7cf2976SLionel Sambuc 		{
1040f7cf2976SLionel Sambuc 			tbuf[0] = '\177';
1041f7cf2976SLionel Sambuc 			tbuf[1] = '\0';
1042f7cf2976SLionel Sambuc 			s = tbuf;
1043f7cf2976SLionel Sambuc 		}
1044f7cf2976SLionel Sambuc 		break;
1045f7cf2976SLionel Sambuc #endif
1046f7cf2976SLionel Sambuc 	case SK_CONTROL_K:
1047f7cf2976SLionel Sambuc 		tbuf[0] = CONTROL('K');
1048f7cf2976SLionel Sambuc 		tbuf[1] = '\0';
1049f7cf2976SLionel Sambuc 		s = tbuf;
1050f7cf2976SLionel Sambuc 		break;
1051f7cf2976SLionel Sambuc 	default:
1052f7cf2976SLionel Sambuc 		return (NULL);
1053f7cf2976SLionel Sambuc 	}
1054f7cf2976SLionel Sambuc 	return (s);
1055f7cf2976SLionel Sambuc }
1056f7cf2976SLionel Sambuc 
1057f7cf2976SLionel Sambuc /*
1058f7cf2976SLionel Sambuc  * Get terminal capabilities via termcap.
1059f7cf2976SLionel Sambuc  */
1060f7cf2976SLionel Sambuc 	public void
get_term()1061f7cf2976SLionel Sambuc get_term()
1062f7cf2976SLionel Sambuc {
1063f7cf2976SLionel Sambuc #if MSDOS_COMPILER
1064f7cf2976SLionel Sambuc 	auto_wrap = 1;
1065f7cf2976SLionel Sambuc 	ignaw = 0;
1066f7cf2976SLionel Sambuc 	can_goto_line = 1;
1067f7cf2976SLionel Sambuc 	clear_bg = 1;
1068f7cf2976SLionel Sambuc 	/*
1069f7cf2976SLionel Sambuc 	 * Set up default colors.
1070f7cf2976SLionel Sambuc 	 * The xx_s_width and xx_e_width vars are already initialized to 0.
1071f7cf2976SLionel Sambuc 	 */
1072f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
1073f7cf2976SLionel Sambuc 	sy_bg_color = _getbkcolor();
1074f7cf2976SLionel Sambuc 	sy_fg_color = _gettextcolor();
1075f7cf2976SLionel Sambuc 	get_clock();
1076f7cf2976SLionel Sambuc #else
1077f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
1078f7cf2976SLionel Sambuc     {
1079f7cf2976SLionel Sambuc 	struct text_info w;
1080f7cf2976SLionel Sambuc 	gettextinfo(&w);
1081f7cf2976SLionel Sambuc 	sy_bg_color = (w.attribute >> 4) & 0x0F;
1082f7cf2976SLionel Sambuc 	sy_fg_color = (w.attribute >> 0) & 0x0F;
1083f7cf2976SLionel Sambuc     }
1084f7cf2976SLionel Sambuc #else
1085f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1086f7cf2976SLionel Sambuc     {
1087f7cf2976SLionel Sambuc 	DWORD nread;
1088f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO scr;
1089f7cf2976SLionel Sambuc 
1090f7cf2976SLionel Sambuc 	con_out_save = con_out = GetStdHandle(STD_OUTPUT_HANDLE);
1091f7cf2976SLionel Sambuc 	/*
1092f7cf2976SLionel Sambuc 	 * Always open stdin in binary. Note this *must* be done
1093f7cf2976SLionel Sambuc 	 * before any file operations have been done on fd0.
1094f7cf2976SLionel Sambuc 	 */
1095f7cf2976SLionel Sambuc 	SET_BINARY(0);
1096f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out, &scr);
1097f7cf2976SLionel Sambuc 	ReadConsoleOutputAttribute(con_out, &curr_attr,
1098f7cf2976SLionel Sambuc 					1, scr.dwCursorPosition, &nread);
1099f7cf2976SLionel Sambuc 	sy_bg_color = (curr_attr & BG_COLORS) >> 4; /* normalize */
1100f7cf2976SLionel Sambuc 	sy_fg_color = curr_attr & FG_COLORS;
1101f7cf2976SLionel Sambuc     }
1102f7cf2976SLionel Sambuc #endif
1103f7cf2976SLionel Sambuc #endif
1104f7cf2976SLionel Sambuc #endif
1105f7cf2976SLionel Sambuc 	nm_fg_color = sy_fg_color;
1106f7cf2976SLionel Sambuc 	nm_bg_color = sy_bg_color;
1107f7cf2976SLionel Sambuc 	bo_fg_color = 11;
1108f7cf2976SLionel Sambuc 	bo_bg_color = 0;
1109f7cf2976SLionel Sambuc 	ul_fg_color = 9;
1110f7cf2976SLionel Sambuc 	ul_bg_color = 0;
1111f7cf2976SLionel Sambuc 	so_fg_color = 15;
1112f7cf2976SLionel Sambuc 	so_bg_color = 9;
1113f7cf2976SLionel Sambuc 	bl_fg_color = 15;
1114f7cf2976SLionel Sambuc 	bl_bg_color = 0;
1115f7cf2976SLionel Sambuc 
1116f7cf2976SLionel Sambuc 	/*
1117f7cf2976SLionel Sambuc 	 * Get size of the screen.
1118f7cf2976SLionel Sambuc 	 */
1119f7cf2976SLionel Sambuc 	scrsize();
1120f7cf2976SLionel Sambuc 	pos_init();
1121f7cf2976SLionel Sambuc 
1122f7cf2976SLionel Sambuc 
1123f7cf2976SLionel Sambuc #else /* !MSDOS_COMPILER */
1124f7cf2976SLionel Sambuc 
1125f7cf2976SLionel Sambuc 	char *sp;
1126f7cf2976SLionel Sambuc 	register char *t1, *t2;
1127f7cf2976SLionel Sambuc 	char *term;
1128f7cf2976SLionel Sambuc 	char termbuf[TERMBUF_SIZE];
1129f7cf2976SLionel Sambuc 
1130f7cf2976SLionel Sambuc 	static char sbuf[TERMSBUF_SIZE];
1131f7cf2976SLionel Sambuc 
1132f7cf2976SLionel Sambuc #if OS2
1133f7cf2976SLionel Sambuc 	/*
1134f7cf2976SLionel Sambuc 	 * Make sure the termcap database is available.
1135f7cf2976SLionel Sambuc 	 */
1136f7cf2976SLionel Sambuc 	sp = lgetenv("TERMCAP");
1137f7cf2976SLionel Sambuc 	if (sp == NULL || *sp == '\0')
1138f7cf2976SLionel Sambuc 	{
1139f7cf2976SLionel Sambuc 		char *termcap;
1140f7cf2976SLionel Sambuc 		if ((sp = homefile("termcap.dat")) != NULL)
1141f7cf2976SLionel Sambuc 		{
1142f7cf2976SLionel Sambuc 			termcap = (char *) ecalloc(strlen(sp)+9, sizeof(char));
1143f7cf2976SLionel Sambuc 			sprintf(termcap, "TERMCAP=%s", sp);
1144f7cf2976SLionel Sambuc 			free(sp);
1145f7cf2976SLionel Sambuc 			putenv(termcap);
1146f7cf2976SLionel Sambuc 		}
1147f7cf2976SLionel Sambuc 	}
1148f7cf2976SLionel Sambuc #endif
1149f7cf2976SLionel Sambuc 	/*
1150f7cf2976SLionel Sambuc 	 * Find out what kind of terminal this is.
1151f7cf2976SLionel Sambuc 	 */
1152f7cf2976SLionel Sambuc  	if ((term = lgetenv("TERM")) == NULL)
1153f7cf2976SLionel Sambuc  		term = DEFAULT_TERM;
1154f7cf2976SLionel Sambuc 	hardcopy = 0;
1155f7cf2976SLionel Sambuc  	if (tgetent(termbuf, term) != TGETENT_OK)
1156f7cf2976SLionel Sambuc  		hardcopy = 1;
1157f7cf2976SLionel Sambuc  	if (ltgetflag("hc"))
1158f7cf2976SLionel Sambuc 		hardcopy = 1;
1159f7cf2976SLionel Sambuc 
1160f7cf2976SLionel Sambuc 	/*
1161f7cf2976SLionel Sambuc 	 * Get size of the screen.
1162f7cf2976SLionel Sambuc 	 */
1163f7cf2976SLionel Sambuc 	scrsize();
1164f7cf2976SLionel Sambuc 	pos_init();
1165f7cf2976SLionel Sambuc 
1166f7cf2976SLionel Sambuc 	auto_wrap = ltgetflag("am");
1167f7cf2976SLionel Sambuc 	ignaw = ltgetflag("xn");
1168f7cf2976SLionel Sambuc 	above_mem = ltgetflag("da");
1169f7cf2976SLionel Sambuc 	below_mem = ltgetflag("db");
1170f7cf2976SLionel Sambuc 	clear_bg = ltgetflag("ut");
1171f7cf2976SLionel Sambuc 
1172f7cf2976SLionel Sambuc 	/*
1173f7cf2976SLionel Sambuc 	 * Assumes termcap variable "sg" is the printing width of:
1174f7cf2976SLionel Sambuc 	 * the standout sequence, the end standout sequence,
1175f7cf2976SLionel Sambuc 	 * the underline sequence, the end underline sequence,
1176f7cf2976SLionel Sambuc 	 * the boldface sequence, and the end boldface sequence.
1177f7cf2976SLionel Sambuc 	 */
1178f7cf2976SLionel Sambuc 	if ((so_s_width = ltgetnum("sg")) < 0)
1179f7cf2976SLionel Sambuc 		so_s_width = 0;
1180f7cf2976SLionel Sambuc 	so_e_width = so_s_width;
1181f7cf2976SLionel Sambuc 
1182f7cf2976SLionel Sambuc 	bo_s_width = bo_e_width = so_s_width;
1183f7cf2976SLionel Sambuc 	ul_s_width = ul_e_width = so_s_width;
1184f7cf2976SLionel Sambuc 	bl_s_width = bl_e_width = so_s_width;
1185f7cf2976SLionel Sambuc 
1186f7cf2976SLionel Sambuc #if HILITE_SEARCH
1187f7cf2976SLionel Sambuc 	if (so_s_width > 0 || so_e_width > 0)
1188f7cf2976SLionel Sambuc 		/*
1189f7cf2976SLionel Sambuc 		 * Disable highlighting by default on magic cookie terminals.
1190f7cf2976SLionel Sambuc 		 * Turning on highlighting might change the displayed width
1191f7cf2976SLionel Sambuc 		 * of a line, causing the display to get messed up.
1192f7cf2976SLionel Sambuc 		 * The user can turn it back on with -g,
1193f7cf2976SLionel Sambuc 		 * but she won't like the results.
1194f7cf2976SLionel Sambuc 		 */
1195f7cf2976SLionel Sambuc 		hilite_search = 0;
1196f7cf2976SLionel Sambuc #endif
1197f7cf2976SLionel Sambuc 
1198f7cf2976SLionel Sambuc 	/*
1199f7cf2976SLionel Sambuc 	 * Get various string-valued capabilities.
1200f7cf2976SLionel Sambuc 	 */
1201f7cf2976SLionel Sambuc 	sp = sbuf;
1202f7cf2976SLionel Sambuc 
1203f7cf2976SLionel Sambuc #if HAVE_OSPEED
1204f7cf2976SLionel Sambuc 	sc_pad = ltgetstr("pc", &sp);
1205f7cf2976SLionel Sambuc 	if (sc_pad != NULL)
1206f7cf2976SLionel Sambuc 		PC = *sc_pad;
1207f7cf2976SLionel Sambuc #endif
1208f7cf2976SLionel Sambuc 
1209f7cf2976SLionel Sambuc 	sc_s_keypad = ltgetstr("ks", &sp);
1210f7cf2976SLionel Sambuc 	if (sc_s_keypad == NULL)
1211f7cf2976SLionel Sambuc 		sc_s_keypad = "";
1212f7cf2976SLionel Sambuc 	sc_e_keypad = ltgetstr("ke", &sp);
1213f7cf2976SLionel Sambuc 	if (sc_e_keypad == NULL)
1214f7cf2976SLionel Sambuc 		sc_e_keypad = "";
1215f7cf2976SLionel Sambuc 
1216f7cf2976SLionel Sambuc 	/*
1217f7cf2976SLionel Sambuc 	 * This loses for terminals with termcap entries with ti/te strings
1218f7cf2976SLionel Sambuc 	 * that switch to/from an alternate screen, and we're in quit_at_eof
1219f7cf2976SLionel Sambuc 	 * (eg, more(1)).
1220f7cf2976SLionel Sambuc 	 */
1221f7cf2976SLionel Sambuc 	if (quit_at_eof != OPT_ONPLUS && !more_mode) {
1222f7cf2976SLionel Sambuc 		sc_init = ltgetstr("ti", &sp);
1223f7cf2976SLionel Sambuc 		sc_deinit = ltgetstr("te", &sp);
1224f7cf2976SLionel Sambuc 	} else {
1225f7cf2976SLionel Sambuc 		sc_init = NULL;
1226f7cf2976SLionel Sambuc 		sc_deinit = NULL;
1227f7cf2976SLionel Sambuc 	}
1228f7cf2976SLionel Sambuc 
1229f7cf2976SLionel Sambuc 	if (sc_init == NULL)
1230f7cf2976SLionel Sambuc 		sc_init = "";
1231f7cf2976SLionel Sambuc 	if (sc_deinit == NULL)
1232f7cf2976SLionel Sambuc 		sc_deinit = "";
1233f7cf2976SLionel Sambuc 
1234f7cf2976SLionel Sambuc 	sc_eol_clear = ltgetstr("ce", &sp);
1235f7cf2976SLionel Sambuc 	if (sc_eol_clear == NULL || *sc_eol_clear == '\0')
1236f7cf2976SLionel Sambuc 	{
1237f7cf2976SLionel Sambuc 		missing_cap = 1;
1238f7cf2976SLionel Sambuc 		sc_eol_clear = "";
1239f7cf2976SLionel Sambuc 	}
1240f7cf2976SLionel Sambuc 
1241f7cf2976SLionel Sambuc 	sc_eos_clear = ltgetstr("cd", &sp);
1242f7cf2976SLionel Sambuc 	if (below_mem && (sc_eos_clear == NULL || *sc_eos_clear == '\0'))
1243f7cf2976SLionel Sambuc 	{
1244f7cf2976SLionel Sambuc 		missing_cap = 1;
1245f7cf2976SLionel Sambuc 		sc_eos_clear = "";
1246f7cf2976SLionel Sambuc 	}
1247f7cf2976SLionel Sambuc 
1248f7cf2976SLionel Sambuc 	sc_clear = ltgetstr("cl", &sp);
1249f7cf2976SLionel Sambuc 	if (sc_clear == NULL || *sc_clear == '\0')
1250f7cf2976SLionel Sambuc 	{
1251f7cf2976SLionel Sambuc 		missing_cap = 1;
1252f7cf2976SLionel Sambuc 		sc_clear = "\n\n";
1253f7cf2976SLionel Sambuc 	}
1254f7cf2976SLionel Sambuc 
1255f7cf2976SLionel Sambuc 	sc_move = ltgetstr("cm", &sp);
1256f7cf2976SLionel Sambuc 	if (sc_move == NULL || *sc_move == '\0')
1257f7cf2976SLionel Sambuc 	{
1258f7cf2976SLionel Sambuc 		/*
1259f7cf2976SLionel Sambuc 		 * This is not an error here, because we don't
1260f7cf2976SLionel Sambuc 		 * always need sc_move.
1261f7cf2976SLionel Sambuc 		 * We need it only if we don't have home or lower-left.
1262f7cf2976SLionel Sambuc 		 */
1263f7cf2976SLionel Sambuc 		sc_move = "";
1264f7cf2976SLionel Sambuc 		can_goto_line = 0;
1265f7cf2976SLionel Sambuc 	} else
1266f7cf2976SLionel Sambuc 		can_goto_line = 1;
1267f7cf2976SLionel Sambuc 
1268f7cf2976SLionel Sambuc 	tmodes("so", "se", &sc_s_in, &sc_s_out, "", "", &sp);
1269f7cf2976SLionel Sambuc 	tmodes("us", "ue", &sc_u_in, &sc_u_out, sc_s_in, sc_s_out, &sp);
1270f7cf2976SLionel Sambuc 	tmodes("md", "me", &sc_b_in, &sc_b_out, sc_s_in, sc_s_out, &sp);
1271f7cf2976SLionel Sambuc 	tmodes("mb", "me", &sc_bl_in, &sc_bl_out, sc_s_in, sc_s_out, &sp);
1272f7cf2976SLionel Sambuc 
1273f7cf2976SLionel Sambuc 	sc_visual_bell = ltgetstr("vb", &sp);
1274f7cf2976SLionel Sambuc 	if (sc_visual_bell == NULL)
1275f7cf2976SLionel Sambuc 		sc_visual_bell = "";
1276f7cf2976SLionel Sambuc 
1277f7cf2976SLionel Sambuc 	if (ltgetflag("bs"))
1278f7cf2976SLionel Sambuc 		sc_backspace = "\b";
1279f7cf2976SLionel Sambuc 	else
1280f7cf2976SLionel Sambuc 	{
1281f7cf2976SLionel Sambuc 		sc_backspace = ltgetstr("bc", &sp);
1282f7cf2976SLionel Sambuc 		if (sc_backspace == NULL || *sc_backspace == '\0')
1283f7cf2976SLionel Sambuc 			sc_backspace = "\b";
1284f7cf2976SLionel Sambuc 	}
1285f7cf2976SLionel Sambuc 
1286f7cf2976SLionel Sambuc 	/*
1287f7cf2976SLionel Sambuc 	 * Choose between using "ho" and "cm" ("home" and "cursor move")
1288f7cf2976SLionel Sambuc 	 * to move the cursor to the upper left corner of the screen.
1289f7cf2976SLionel Sambuc 	 */
1290f7cf2976SLionel Sambuc 	t1 = ltgetstr("ho", &sp);
1291f7cf2976SLionel Sambuc 	if (t1 == NULL)
1292f7cf2976SLionel Sambuc 		t1 = "";
1293f7cf2976SLionel Sambuc 	if (*sc_move == '\0')
1294f7cf2976SLionel Sambuc 		t2 = "";
1295f7cf2976SLionel Sambuc 	else
1296f7cf2976SLionel Sambuc 	{
1297f7cf2976SLionel Sambuc 		strcpy(sp, tgoto(sc_move, 0, 0));
1298f7cf2976SLionel Sambuc 		t2 = sp;
1299f7cf2976SLionel Sambuc 		sp += strlen(sp) + 1;
1300f7cf2976SLionel Sambuc 	}
1301f7cf2976SLionel Sambuc 	sc_home = cheaper(t1, t2, "|\b^");
1302f7cf2976SLionel Sambuc 
1303f7cf2976SLionel Sambuc 	/*
1304f7cf2976SLionel Sambuc 	 * Choose between using "ll" and "cm"  ("lower left" and "cursor move")
1305f7cf2976SLionel Sambuc 	 * to move the cursor to the lower left corner of the screen.
1306f7cf2976SLionel Sambuc 	 */
1307f7cf2976SLionel Sambuc 	t1 = ltgetstr("ll", &sp);
1308f7cf2976SLionel Sambuc 	if (t1 == NULL)
1309f7cf2976SLionel Sambuc 		t1 = "";
1310f7cf2976SLionel Sambuc 	if (*sc_move == '\0')
1311f7cf2976SLionel Sambuc 		t2 = "";
1312f7cf2976SLionel Sambuc 	else
1313f7cf2976SLionel Sambuc 	{
1314f7cf2976SLionel Sambuc 		strcpy(sp, tgoto(sc_move, 0, sc_height-1));
1315f7cf2976SLionel Sambuc 		t2 = sp;
1316f7cf2976SLionel Sambuc 		sp += strlen(sp) + 1;
1317f7cf2976SLionel Sambuc 	}
1318f7cf2976SLionel Sambuc 	sc_lower_left = cheaper(t1, t2, "\r");
1319f7cf2976SLionel Sambuc 
1320f7cf2976SLionel Sambuc 	/*
1321f7cf2976SLionel Sambuc 	 * Get carriage return string.
1322f7cf2976SLionel Sambuc 	 */
1323f7cf2976SLionel Sambuc 	sc_return = ltgetstr("cr", &sp);
1324f7cf2976SLionel Sambuc 	if (sc_return == NULL)
1325f7cf2976SLionel Sambuc 		sc_return = "\r";
1326f7cf2976SLionel Sambuc 
1327f7cf2976SLionel Sambuc 	/*
1328f7cf2976SLionel Sambuc 	 * Choose between using "al" or "sr" ("add line" or "scroll reverse")
1329f7cf2976SLionel Sambuc 	 * to add a line at the top of the screen.
1330f7cf2976SLionel Sambuc 	 */
1331f7cf2976SLionel Sambuc 	t1 = ltgetstr("al", &sp);
1332f7cf2976SLionel Sambuc 	if (t1 == NULL)
1333f7cf2976SLionel Sambuc 		t1 = "";
1334f7cf2976SLionel Sambuc 	t2 = ltgetstr("sr", &sp);
1335f7cf2976SLionel Sambuc 	if (t2 == NULL)
1336f7cf2976SLionel Sambuc 		t2 = "";
1337f7cf2976SLionel Sambuc #if OS2
1338f7cf2976SLionel Sambuc 	if (*t1 == '\0' && *t2 == '\0')
1339f7cf2976SLionel Sambuc 		sc_addline = "";
1340f7cf2976SLionel Sambuc 	else
1341f7cf2976SLionel Sambuc #endif
1342f7cf2976SLionel Sambuc 	if (above_mem)
1343f7cf2976SLionel Sambuc 		sc_addline = t1;
1344f7cf2976SLionel Sambuc 	else
1345f7cf2976SLionel Sambuc 		sc_addline = cheaper(t1, t2, "");
1346f7cf2976SLionel Sambuc 	if (*sc_addline == '\0')
1347f7cf2976SLionel Sambuc 	{
1348f7cf2976SLionel Sambuc 		/*
1349f7cf2976SLionel Sambuc 		 * Force repaint on any backward movement.
1350f7cf2976SLionel Sambuc 		 */
1351f7cf2976SLionel Sambuc 		no_back_scroll = 1;
1352f7cf2976SLionel Sambuc 	}
1353f7cf2976SLionel Sambuc #endif /* MSDOS_COMPILER */
1354f7cf2976SLionel Sambuc }
1355f7cf2976SLionel Sambuc 
1356f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
1357f7cf2976SLionel Sambuc /*
1358f7cf2976SLionel Sambuc  * Return the cost of displaying a termcap string.
1359f7cf2976SLionel Sambuc  * We use the trick of calling tputs, but as a char printing function
1360f7cf2976SLionel Sambuc  * we give it inc_costcount, which just increments "costcount".
1361f7cf2976SLionel Sambuc  * This tells us how many chars would be printed by using this string.
1362f7cf2976SLionel Sambuc  * {{ Couldn't we just use strlen? }}
1363f7cf2976SLionel Sambuc  */
1364f7cf2976SLionel Sambuc static int costcount;
1365f7cf2976SLionel Sambuc 
1366f7cf2976SLionel Sambuc /*ARGSUSED*/
1367f7cf2976SLionel Sambuc 	static int
inc_costcount(c)1368f7cf2976SLionel Sambuc inc_costcount(c)
1369f7cf2976SLionel Sambuc 	int c;
1370f7cf2976SLionel Sambuc {
1371f7cf2976SLionel Sambuc 	costcount++;
1372f7cf2976SLionel Sambuc 	return (c);
1373f7cf2976SLionel Sambuc }
1374f7cf2976SLionel Sambuc 
1375f7cf2976SLionel Sambuc 	static int
cost(t)1376f7cf2976SLionel Sambuc cost(t)
1377f7cf2976SLionel Sambuc 	char *t;
1378f7cf2976SLionel Sambuc {
1379f7cf2976SLionel Sambuc 	costcount = 0;
1380f7cf2976SLionel Sambuc 	tputs(t, sc_height, inc_costcount);
1381f7cf2976SLionel Sambuc 	return (costcount);
1382f7cf2976SLionel Sambuc }
1383f7cf2976SLionel Sambuc 
1384f7cf2976SLionel Sambuc /*
1385f7cf2976SLionel Sambuc  * Return the "best" of the two given termcap strings.
1386f7cf2976SLionel Sambuc  * The best, if both exist, is the one with the lower
1387f7cf2976SLionel Sambuc  * cost (see cost() function).
1388f7cf2976SLionel Sambuc  */
1389f7cf2976SLionel Sambuc 	static char *
cheaper(t1,t2,def)1390f7cf2976SLionel Sambuc cheaper(t1, t2, def)
1391f7cf2976SLionel Sambuc 	char *t1, *t2;
1392f7cf2976SLionel Sambuc 	char *def;
1393f7cf2976SLionel Sambuc {
1394f7cf2976SLionel Sambuc 	if (*t1 == '\0' && *t2 == '\0')
1395f7cf2976SLionel Sambuc 	{
1396f7cf2976SLionel Sambuc 		missing_cap = 1;
1397f7cf2976SLionel Sambuc 		return (def);
1398f7cf2976SLionel Sambuc 	}
1399f7cf2976SLionel Sambuc 	if (*t1 == '\0')
1400f7cf2976SLionel Sambuc 		return (t2);
1401f7cf2976SLionel Sambuc 	if (*t2 == '\0')
1402f7cf2976SLionel Sambuc 		return (t1);
1403f7cf2976SLionel Sambuc 	if (cost(t1) < cost(t2))
1404f7cf2976SLionel Sambuc 		return (t1);
1405f7cf2976SLionel Sambuc 	return (t2);
1406f7cf2976SLionel Sambuc }
1407f7cf2976SLionel Sambuc 
1408f7cf2976SLionel Sambuc 	static void
tmodes(incap,outcap,instr,outstr,def_instr,def_outstr,spp)1409f7cf2976SLionel Sambuc tmodes(incap, outcap, instr, outstr, def_instr, def_outstr, spp)
1410f7cf2976SLionel Sambuc 	char *incap;
1411f7cf2976SLionel Sambuc 	char *outcap;
1412f7cf2976SLionel Sambuc 	char **instr;
1413f7cf2976SLionel Sambuc 	char **outstr;
1414f7cf2976SLionel Sambuc 	char *def_instr;
1415f7cf2976SLionel Sambuc 	char *def_outstr;
1416f7cf2976SLionel Sambuc 	char **spp;
1417f7cf2976SLionel Sambuc {
1418f7cf2976SLionel Sambuc 	*instr = ltgetstr(incap, spp);
1419f7cf2976SLionel Sambuc 	if (*instr == NULL)
1420f7cf2976SLionel Sambuc 	{
1421f7cf2976SLionel Sambuc 		/* Use defaults. */
1422f7cf2976SLionel Sambuc 		*instr = def_instr;
1423f7cf2976SLionel Sambuc 		*outstr = def_outstr;
1424f7cf2976SLionel Sambuc 		return;
1425f7cf2976SLionel Sambuc 	}
1426f7cf2976SLionel Sambuc 
1427f7cf2976SLionel Sambuc 	*outstr = ltgetstr(outcap, spp);
1428f7cf2976SLionel Sambuc 	if (*outstr == NULL)
1429f7cf2976SLionel Sambuc 		/* No specific out capability; use "me". */
1430f7cf2976SLionel Sambuc 		*outstr = ltgetstr("me", spp);
1431f7cf2976SLionel Sambuc 	if (*outstr == NULL)
1432f7cf2976SLionel Sambuc 		/* Don't even have "me"; use a null string. */
1433f7cf2976SLionel Sambuc 		*outstr = "";
1434f7cf2976SLionel Sambuc }
1435f7cf2976SLionel Sambuc 
1436f7cf2976SLionel Sambuc #endif /* MSDOS_COMPILER */
1437f7cf2976SLionel Sambuc 
1438f7cf2976SLionel Sambuc 
1439f7cf2976SLionel Sambuc /*
1440f7cf2976SLionel Sambuc  * Below are the functions which perform all the
1441f7cf2976SLionel Sambuc  * terminal-specific screen manipulation.
1442f7cf2976SLionel Sambuc  */
1443f7cf2976SLionel Sambuc 
1444f7cf2976SLionel Sambuc 
1445f7cf2976SLionel Sambuc #if MSDOS_COMPILER
1446f7cf2976SLionel Sambuc 
1447f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1448f7cf2976SLionel Sambuc 	static void
_settextposition(int row,int col)1449f7cf2976SLionel Sambuc _settextposition(int row, int col)
1450f7cf2976SLionel Sambuc {
1451f7cf2976SLionel Sambuc 	COORD cpos;
1452f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO csbi;
1453f7cf2976SLionel Sambuc 
1454f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out, &csbi);
1455f7cf2976SLionel Sambuc 	cpos.X = csbi.srWindow.Left + (col - 1);
1456f7cf2976SLionel Sambuc 	cpos.Y = csbi.srWindow.Top + (row - 1);
1457f7cf2976SLionel Sambuc 	SetConsoleCursorPosition(con_out, cpos);
1458f7cf2976SLionel Sambuc }
1459f7cf2976SLionel Sambuc #endif
1460f7cf2976SLionel Sambuc 
1461f7cf2976SLionel Sambuc /*
1462f7cf2976SLionel Sambuc  * Initialize the screen to the correct color at startup.
1463f7cf2976SLionel Sambuc  */
1464f7cf2976SLionel Sambuc 	static void
initcolor()1465f7cf2976SLionel Sambuc initcolor()
1466f7cf2976SLionel Sambuc {
1467f7cf2976SLionel Sambuc 	SETCOLORS(nm_fg_color, nm_bg_color);
1468f7cf2976SLionel Sambuc #if 0
1469f7cf2976SLionel Sambuc 	/*
1470f7cf2976SLionel Sambuc 	 * This clears the screen at startup.  This is different from
1471f7cf2976SLionel Sambuc 	 * the behavior of other versions of less.  Disable it for now.
1472f7cf2976SLionel Sambuc 	 */
1473f7cf2976SLionel Sambuc 	char *blanks;
1474f7cf2976SLionel Sambuc 	int row;
1475f7cf2976SLionel Sambuc 	int col;
1476f7cf2976SLionel Sambuc 
1477f7cf2976SLionel Sambuc 	/*
1478f7cf2976SLionel Sambuc 	 * Create a complete, blank screen using "normal" colors.
1479f7cf2976SLionel Sambuc 	 */
1480f7cf2976SLionel Sambuc 	SETCOLORS(nm_fg_color, nm_bg_color);
1481f7cf2976SLionel Sambuc 	blanks = (char *) ecalloc(width+1, sizeof(char));
1482f7cf2976SLionel Sambuc 	for (col = 0;  col < sc_width;  col++)
1483f7cf2976SLionel Sambuc 		blanks[col] = ' ';
1484f7cf2976SLionel Sambuc 	blanks[sc_width] = '\0';
1485f7cf2976SLionel Sambuc 	for (row = 0;  row < sc_height;  row++)
1486f7cf2976SLionel Sambuc 		_outtext(blanks);
1487f7cf2976SLionel Sambuc 	free(blanks);
1488f7cf2976SLionel Sambuc #endif
1489f7cf2976SLionel Sambuc }
1490f7cf2976SLionel Sambuc #endif
1491f7cf2976SLionel Sambuc 
1492f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1493f7cf2976SLionel Sambuc 
1494f7cf2976SLionel Sambuc /*
1495f7cf2976SLionel Sambuc  * Termcap-like init with a private win32 console.
1496f7cf2976SLionel Sambuc  */
1497f7cf2976SLionel Sambuc 	static void
win32_init_term()1498f7cf2976SLionel Sambuc win32_init_term()
1499f7cf2976SLionel Sambuc {
1500f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO scr;
1501f7cf2976SLionel Sambuc 	COORD size;
1502f7cf2976SLionel Sambuc 
1503f7cf2976SLionel Sambuc 	if (con_out_save == INVALID_HANDLE_VALUE)
1504f7cf2976SLionel Sambuc 		return;
1505f7cf2976SLionel Sambuc 
1506f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out_save, &scr);
1507f7cf2976SLionel Sambuc 
1508f7cf2976SLionel Sambuc 	if (con_out_ours == INVALID_HANDLE_VALUE)
1509f7cf2976SLionel Sambuc 	{
1510f7cf2976SLionel Sambuc 		/*
1511f7cf2976SLionel Sambuc 		 * Create our own screen buffer, so that we
1512f7cf2976SLionel Sambuc 		 * may restore the original when done.
1513f7cf2976SLionel Sambuc 		 */
1514f7cf2976SLionel Sambuc 		con_out_ours = CreateConsoleScreenBuffer(
1515f7cf2976SLionel Sambuc 			GENERIC_WRITE | GENERIC_READ,
1516f7cf2976SLionel Sambuc 			FILE_SHARE_WRITE | FILE_SHARE_READ,
1517f7cf2976SLionel Sambuc 			(LPSECURITY_ATTRIBUTES) NULL,
1518f7cf2976SLionel Sambuc 			CONSOLE_TEXTMODE_BUFFER,
1519f7cf2976SLionel Sambuc 			(LPVOID) NULL);
1520f7cf2976SLionel Sambuc 	}
1521f7cf2976SLionel Sambuc 
1522f7cf2976SLionel Sambuc 	size.X = scr.srWindow.Right - scr.srWindow.Left + 1;
1523f7cf2976SLionel Sambuc 	size.Y = scr.srWindow.Bottom - scr.srWindow.Top + 1;
1524f7cf2976SLionel Sambuc 	SetConsoleScreenBufferSize(con_out_ours, size);
1525f7cf2976SLionel Sambuc 	SetConsoleActiveScreenBuffer(con_out_ours);
1526f7cf2976SLionel Sambuc 	con_out = con_out_ours;
1527f7cf2976SLionel Sambuc }
1528f7cf2976SLionel Sambuc 
1529f7cf2976SLionel Sambuc /*
1530f7cf2976SLionel Sambuc  * Restore the startup console.
1531f7cf2976SLionel Sambuc  */
1532f7cf2976SLionel Sambuc static void
win32_deinit_term()1533f7cf2976SLionel Sambuc win32_deinit_term()
1534f7cf2976SLionel Sambuc {
1535f7cf2976SLionel Sambuc 	if (con_out_save == INVALID_HANDLE_VALUE)
1536f7cf2976SLionel Sambuc 		return;
1537f7cf2976SLionel Sambuc 	if (quitting)
1538f7cf2976SLionel Sambuc 		(void) CloseHandle(con_out_ours);
1539f7cf2976SLionel Sambuc 	SetConsoleActiveScreenBuffer(con_out_save);
1540f7cf2976SLionel Sambuc 	con_out = con_out_save;
1541f7cf2976SLionel Sambuc }
1542f7cf2976SLionel Sambuc 
1543f7cf2976SLionel Sambuc #endif
1544f7cf2976SLionel Sambuc 
1545f7cf2976SLionel Sambuc /*
1546f7cf2976SLionel Sambuc  * Initialize terminal
1547f7cf2976SLionel Sambuc  */
1548f7cf2976SLionel Sambuc 	public void
init()1549f7cf2976SLionel Sambuc init()
1550f7cf2976SLionel Sambuc {
1551f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
1552f7cf2976SLionel Sambuc 	if (!no_init)
1553f7cf2976SLionel Sambuc 		tputs(sc_init, sc_height, putchr);
1554f7cf2976SLionel Sambuc 	if (!no_keypad)
1555f7cf2976SLionel Sambuc 		tputs(sc_s_keypad, sc_height, putchr);
1556f7cf2976SLionel Sambuc 	if (top_scroll)
1557f7cf2976SLionel Sambuc 	{
1558f7cf2976SLionel Sambuc 		int i;
1559f7cf2976SLionel Sambuc 
1560f7cf2976SLionel Sambuc 		/*
1561f7cf2976SLionel Sambuc 		 * This is nice to terminals with no alternate screen,
1562f7cf2976SLionel Sambuc 		 * but with saved scrolled-off-the-top lines.  This way,
1563f7cf2976SLionel Sambuc 		 * no previous line is lost, but we start with a whole
1564f7cf2976SLionel Sambuc 		 * screen to ourself.
1565f7cf2976SLionel Sambuc 		 */
1566f7cf2976SLionel Sambuc 		for (i = 1; i < sc_height; i++)
1567f7cf2976SLionel Sambuc 			putchr('\n');
1568f7cf2976SLionel Sambuc 	} else
1569f7cf2976SLionel Sambuc 		line_left();
1570f7cf2976SLionel Sambuc #else
1571f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1572f7cf2976SLionel Sambuc 	if (!no_init)
1573f7cf2976SLionel Sambuc 		win32_init_term();
1574f7cf2976SLionel Sambuc #endif
1575f7cf2976SLionel Sambuc 	initcolor();
1576f7cf2976SLionel Sambuc 	flush();
1577f7cf2976SLionel Sambuc #endif
1578f7cf2976SLionel Sambuc 	init_done = 1;
1579f7cf2976SLionel Sambuc }
1580f7cf2976SLionel Sambuc 
1581f7cf2976SLionel Sambuc /*
1582f7cf2976SLionel Sambuc  * Deinitialize terminal
1583f7cf2976SLionel Sambuc  */
1584f7cf2976SLionel Sambuc 	public void
deinit()1585f7cf2976SLionel Sambuc deinit()
1586f7cf2976SLionel Sambuc {
1587f7cf2976SLionel Sambuc 	if (!init_done)
1588f7cf2976SLionel Sambuc 		return;
1589f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
1590f7cf2976SLionel Sambuc 	if (!no_keypad)
1591f7cf2976SLionel Sambuc 		tputs(sc_e_keypad, sc_height, putchr);
1592f7cf2976SLionel Sambuc 	if (!no_init)
1593f7cf2976SLionel Sambuc 		tputs(sc_deinit, sc_height, putchr);
1594f7cf2976SLionel Sambuc #else
1595f7cf2976SLionel Sambuc 	/* Restore system colors. */
1596f7cf2976SLionel Sambuc 	SETCOLORS(sy_fg_color, sy_bg_color);
1597f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1598f7cf2976SLionel Sambuc 	if (!no_init)
1599f7cf2976SLionel Sambuc 		win32_deinit_term();
1600f7cf2976SLionel Sambuc #else
1601f7cf2976SLionel Sambuc 	/* Need clreol to make SETCOLORS take effect. */
1602f7cf2976SLionel Sambuc 	clreol();
1603f7cf2976SLionel Sambuc #endif
1604f7cf2976SLionel Sambuc #endif
1605f7cf2976SLionel Sambuc 	init_done = 0;
1606f7cf2976SLionel Sambuc }
1607f7cf2976SLionel Sambuc 
1608f7cf2976SLionel Sambuc /*
1609f7cf2976SLionel Sambuc  * Home cursor (move to upper left corner of screen).
1610f7cf2976SLionel Sambuc  */
1611f7cf2976SLionel Sambuc 	public void
home()1612f7cf2976SLionel Sambuc home()
1613f7cf2976SLionel Sambuc {
1614f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
1615f7cf2976SLionel Sambuc 	tputs(sc_home, 1, putchr);
1616f7cf2976SLionel Sambuc #else
1617f7cf2976SLionel Sambuc 	flush();
1618f7cf2976SLionel Sambuc 	_settextposition(1,1);
1619f7cf2976SLionel Sambuc #endif
1620f7cf2976SLionel Sambuc }
1621f7cf2976SLionel Sambuc 
1622f7cf2976SLionel Sambuc /*
1623f7cf2976SLionel Sambuc  * Add a blank line (called with cursor at home).
1624f7cf2976SLionel Sambuc  * Should scroll the display down.
1625f7cf2976SLionel Sambuc  */
1626f7cf2976SLionel Sambuc 	public void
add_line()1627f7cf2976SLionel Sambuc add_line()
1628f7cf2976SLionel Sambuc {
1629f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
1630f7cf2976SLionel Sambuc 	tputs(sc_addline, sc_height, putchr);
1631f7cf2976SLionel Sambuc #else
1632f7cf2976SLionel Sambuc 	flush();
1633f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
1634f7cf2976SLionel Sambuc 	_scrolltextwindow(_GSCROLLDOWN);
1635f7cf2976SLionel Sambuc 	_settextposition(1,1);
1636f7cf2976SLionel Sambuc #else
1637f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
1638f7cf2976SLionel Sambuc 	movetext(1,1, sc_width,sc_height-1, 1,2);
1639f7cf2976SLionel Sambuc 	gotoxy(1,1);
1640f7cf2976SLionel Sambuc 	clreol();
1641f7cf2976SLionel Sambuc #else
1642f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1643f7cf2976SLionel Sambuc     {
1644f7cf2976SLionel Sambuc 	CHAR_INFO fillchar;
1645f7cf2976SLionel Sambuc 	SMALL_RECT rcSrc, rcClip;
1646f7cf2976SLionel Sambuc 	COORD new_org;
1647f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO csbi;
1648f7cf2976SLionel Sambuc 
1649f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out,&csbi);
1650f7cf2976SLionel Sambuc 
1651f7cf2976SLionel Sambuc 	/* The clip rectangle is the entire visible screen. */
1652f7cf2976SLionel Sambuc 	rcClip.Left = csbi.srWindow.Left;
1653f7cf2976SLionel Sambuc 	rcClip.Top = csbi.srWindow.Top;
1654f7cf2976SLionel Sambuc 	rcClip.Right = csbi.srWindow.Right;
1655f7cf2976SLionel Sambuc 	rcClip.Bottom = csbi.srWindow.Bottom;
1656f7cf2976SLionel Sambuc 
1657f7cf2976SLionel Sambuc 	/* The source rectangle is the visible screen minus the last line. */
1658f7cf2976SLionel Sambuc 	rcSrc = rcClip;
1659f7cf2976SLionel Sambuc 	rcSrc.Bottom--;
1660f7cf2976SLionel Sambuc 
1661f7cf2976SLionel Sambuc 	/* Move the top left corner of the source window down one row. */
1662f7cf2976SLionel Sambuc 	new_org.X = rcSrc.Left;
1663f7cf2976SLionel Sambuc 	new_org.Y = rcSrc.Top + 1;
1664f7cf2976SLionel Sambuc 
1665f7cf2976SLionel Sambuc 	/* Fill the right character and attributes. */
1666f7cf2976SLionel Sambuc 	fillchar.Char.AsciiChar = ' ';
1667f7cf2976SLionel Sambuc 	curr_attr = MAKEATTR(nm_fg_color, nm_bg_color);
1668f7cf2976SLionel Sambuc 	fillchar.Attributes = curr_attr;
1669f7cf2976SLionel Sambuc 	ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar);
1670f7cf2976SLionel Sambuc 	_settextposition(1,1);
1671f7cf2976SLionel Sambuc     }
1672f7cf2976SLionel Sambuc #endif
1673f7cf2976SLionel Sambuc #endif
1674f7cf2976SLionel Sambuc #endif
1675f7cf2976SLionel Sambuc #endif
1676f7cf2976SLionel Sambuc }
1677f7cf2976SLionel Sambuc 
1678f7cf2976SLionel Sambuc #if 0
1679f7cf2976SLionel Sambuc /*
1680f7cf2976SLionel Sambuc  * Remove the n topmost lines and scroll everything below it in the
1681f7cf2976SLionel Sambuc  * window upward.  This is needed to stop leaking the topmost line
1682f7cf2976SLionel Sambuc  * into the scrollback buffer when we go down-one-line (in WIN32).
1683f7cf2976SLionel Sambuc  */
1684f7cf2976SLionel Sambuc 	public void
1685f7cf2976SLionel Sambuc remove_top(n)
1686f7cf2976SLionel Sambuc 	int n;
1687f7cf2976SLionel Sambuc {
1688f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1689f7cf2976SLionel Sambuc 	SMALL_RECT rcSrc, rcClip;
1690f7cf2976SLionel Sambuc 	CHAR_INFO fillchar;
1691f7cf2976SLionel Sambuc 	COORD new_org;
1692f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
1693f7cf2976SLionel Sambuc 
1694f7cf2976SLionel Sambuc 	if (n >= sc_height - 1)
1695f7cf2976SLionel Sambuc 	{
1696f7cf2976SLionel Sambuc 		clear();
1697f7cf2976SLionel Sambuc 		home();
1698f7cf2976SLionel Sambuc 		return;
1699f7cf2976SLionel Sambuc 	}
1700f7cf2976SLionel Sambuc 
1701f7cf2976SLionel Sambuc 	flush();
1702f7cf2976SLionel Sambuc 
1703f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out, &csbi);
1704f7cf2976SLionel Sambuc 
1705f7cf2976SLionel Sambuc 	/* Get the extent of all-visible-rows-but-the-last. */
1706f7cf2976SLionel Sambuc 	rcSrc.Left    = csbi.srWindow.Left;
1707f7cf2976SLionel Sambuc 	rcSrc.Top     = csbi.srWindow.Top + n;
1708f7cf2976SLionel Sambuc 	rcSrc.Right   = csbi.srWindow.Right;
1709f7cf2976SLionel Sambuc 	rcSrc.Bottom  = csbi.srWindow.Bottom;
1710f7cf2976SLionel Sambuc 
1711f7cf2976SLionel Sambuc 	/* Get the clip rectangle. */
1712f7cf2976SLionel Sambuc 	rcClip.Left   = rcSrc.Left;
1713f7cf2976SLionel Sambuc 	rcClip.Top    = csbi.srWindow.Top;
1714f7cf2976SLionel Sambuc 	rcClip.Right  = rcSrc.Right;
1715f7cf2976SLionel Sambuc 	rcClip.Bottom = rcSrc.Bottom ;
1716f7cf2976SLionel Sambuc 
1717f7cf2976SLionel Sambuc 	/* Move the source window up n rows. */
1718f7cf2976SLionel Sambuc 	new_org.X = rcSrc.Left;
1719f7cf2976SLionel Sambuc 	new_org.Y = rcSrc.Top - n;
1720f7cf2976SLionel Sambuc 
1721f7cf2976SLionel Sambuc 	/* Fill the right character and attributes. */
1722f7cf2976SLionel Sambuc 	fillchar.Char.AsciiChar = ' ';
1723f7cf2976SLionel Sambuc 	curr_attr = MAKEATTR(nm_fg_color, nm_bg_color);
1724f7cf2976SLionel Sambuc 	fillchar.Attributes = curr_attr;
1725f7cf2976SLionel Sambuc 
1726f7cf2976SLionel Sambuc 	ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar);
1727f7cf2976SLionel Sambuc 
1728f7cf2976SLionel Sambuc 	/* Position cursor on first blank line. */
1729f7cf2976SLionel Sambuc 	goto_line(sc_height - n - 1);
1730f7cf2976SLionel Sambuc #endif
1731f7cf2976SLionel Sambuc }
1732f7cf2976SLionel Sambuc #endif
1733f7cf2976SLionel Sambuc 
1734f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1735f7cf2976SLionel Sambuc /*
1736f7cf2976SLionel Sambuc  * Clear the screen.
1737f7cf2976SLionel Sambuc  */
1738f7cf2976SLionel Sambuc 	static void
win32_clear()1739f7cf2976SLionel Sambuc win32_clear()
1740f7cf2976SLionel Sambuc {
1741f7cf2976SLionel Sambuc 	/*
1742f7cf2976SLionel Sambuc 	 * This will clear only the currently visible rows of the NT
1743f7cf2976SLionel Sambuc 	 * console buffer, which means none of the precious scrollback
1744f7cf2976SLionel Sambuc 	 * rows are touched making for faster scrolling.  Note that, if
1745f7cf2976SLionel Sambuc 	 * the window has fewer columns than the console buffer (i.e.
1746f7cf2976SLionel Sambuc 	 * there is a horizontal scrollbar as well), the entire width
1747f7cf2976SLionel Sambuc 	 * of the visible rows will be cleared.
1748f7cf2976SLionel Sambuc 	 */
1749f7cf2976SLionel Sambuc 	COORD topleft;
1750f7cf2976SLionel Sambuc 	DWORD nchars;
1751f7cf2976SLionel Sambuc 	DWORD winsz;
1752f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO csbi;
1753f7cf2976SLionel Sambuc 
1754f7cf2976SLionel Sambuc 	/* get the number of cells in the current buffer */
1755f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out, &csbi);
1756f7cf2976SLionel Sambuc 	winsz = csbi.dwSize.X * (csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
1757f7cf2976SLionel Sambuc 	topleft.X = 0;
1758f7cf2976SLionel Sambuc 	topleft.Y = csbi.srWindow.Top;
1759f7cf2976SLionel Sambuc 
1760f7cf2976SLionel Sambuc 	curr_attr = MAKEATTR(nm_fg_color, nm_bg_color);
1761f7cf2976SLionel Sambuc 	FillConsoleOutputCharacter(con_out, ' ', winsz, topleft, &nchars);
1762f7cf2976SLionel Sambuc 	FillConsoleOutputAttribute(con_out, curr_attr, winsz, topleft, &nchars);
1763f7cf2976SLionel Sambuc }
1764f7cf2976SLionel Sambuc 
1765f7cf2976SLionel Sambuc /*
1766f7cf2976SLionel Sambuc  * Remove the n topmost lines and scroll everything below it in the
1767f7cf2976SLionel Sambuc  * window upward.
1768f7cf2976SLionel Sambuc  */
1769f7cf2976SLionel Sambuc 	public void
win32_scroll_up(n)1770f7cf2976SLionel Sambuc win32_scroll_up(n)
1771f7cf2976SLionel Sambuc 	int n;
1772f7cf2976SLionel Sambuc {
1773f7cf2976SLionel Sambuc 	SMALL_RECT rcSrc, rcClip;
1774f7cf2976SLionel Sambuc 	CHAR_INFO fillchar;
1775f7cf2976SLionel Sambuc 	COORD topleft;
1776f7cf2976SLionel Sambuc 	COORD new_org;
1777f7cf2976SLionel Sambuc 	DWORD nchars;
1778f7cf2976SLionel Sambuc 	DWORD size;
1779f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO csbi;
1780f7cf2976SLionel Sambuc 
1781f7cf2976SLionel Sambuc 	if (n <= 0)
1782f7cf2976SLionel Sambuc 		return;
1783f7cf2976SLionel Sambuc 
1784f7cf2976SLionel Sambuc 	if (n >= sc_height - 1)
1785f7cf2976SLionel Sambuc 	{
1786f7cf2976SLionel Sambuc 		win32_clear();
1787f7cf2976SLionel Sambuc 		_settextposition(1,1);
1788f7cf2976SLionel Sambuc 		return;
1789f7cf2976SLionel Sambuc 	}
1790f7cf2976SLionel Sambuc 
1791f7cf2976SLionel Sambuc 	/* Get the extent of what will remain visible after scrolling. */
1792f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out, &csbi);
1793f7cf2976SLionel Sambuc 	rcSrc.Left    = csbi.srWindow.Left;
1794f7cf2976SLionel Sambuc 	rcSrc.Top     = csbi.srWindow.Top + n;
1795f7cf2976SLionel Sambuc 	rcSrc.Right   = csbi.srWindow.Right;
1796f7cf2976SLionel Sambuc 	rcSrc.Bottom  = csbi.srWindow.Bottom;
1797f7cf2976SLionel Sambuc 
1798f7cf2976SLionel Sambuc 	/* Get the clip rectangle. */
1799f7cf2976SLionel Sambuc 	rcClip.Left   = rcSrc.Left;
1800f7cf2976SLionel Sambuc 	rcClip.Top    = csbi.srWindow.Top;
1801f7cf2976SLionel Sambuc 	rcClip.Right  = rcSrc.Right;
1802f7cf2976SLionel Sambuc 	rcClip.Bottom = rcSrc.Bottom ;
1803f7cf2976SLionel Sambuc 
1804f7cf2976SLionel Sambuc 	/* Move the source text to the top of the screen. */
1805f7cf2976SLionel Sambuc 	new_org.X = rcSrc.Left;
1806f7cf2976SLionel Sambuc 	new_org.Y = rcClip.Top;
1807f7cf2976SLionel Sambuc 
1808f7cf2976SLionel Sambuc 	/* Fill the right character and attributes. */
1809f7cf2976SLionel Sambuc 	fillchar.Char.AsciiChar = ' ';
1810f7cf2976SLionel Sambuc 	fillchar.Attributes = MAKEATTR(nm_fg_color, nm_bg_color);
1811f7cf2976SLionel Sambuc 
1812f7cf2976SLionel Sambuc 	/* Scroll the window. */
1813f7cf2976SLionel Sambuc 	SetConsoleTextAttribute(con_out, fillchar.Attributes);
1814f7cf2976SLionel Sambuc 	ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar);
1815f7cf2976SLionel Sambuc 
1816f7cf2976SLionel Sambuc 	/* Clear remaining lines at bottom. */
1817f7cf2976SLionel Sambuc 	topleft.X = csbi.dwCursorPosition.X;
1818f7cf2976SLionel Sambuc 	topleft.Y = rcSrc.Bottom - n;
1819f7cf2976SLionel Sambuc 	size = (n * csbi.dwSize.X) + (rcSrc.Right - topleft.X);
1820f7cf2976SLionel Sambuc 	FillConsoleOutputCharacter(con_out, ' ', size, topleft,
1821f7cf2976SLionel Sambuc 		&nchars);
1822f7cf2976SLionel Sambuc 	FillConsoleOutputAttribute(con_out, fillchar.Attributes, size, topleft,
1823f7cf2976SLionel Sambuc 		&nchars);
1824f7cf2976SLionel Sambuc 	SetConsoleTextAttribute(con_out, curr_attr);
1825f7cf2976SLionel Sambuc 
1826f7cf2976SLionel Sambuc 	/* Move cursor n lines up from where it was. */
1827f7cf2976SLionel Sambuc 	csbi.dwCursorPosition.Y -= n;
1828f7cf2976SLionel Sambuc 	SetConsoleCursorPosition(con_out, csbi.dwCursorPosition);
1829f7cf2976SLionel Sambuc }
1830f7cf2976SLionel Sambuc #endif
1831f7cf2976SLionel Sambuc 
1832f7cf2976SLionel Sambuc /*
1833f7cf2976SLionel Sambuc  * Move cursor to lower left corner of screen.
1834f7cf2976SLionel Sambuc  */
1835f7cf2976SLionel Sambuc 	public void
lower_left()1836f7cf2976SLionel Sambuc lower_left()
1837f7cf2976SLionel Sambuc {
1838f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
1839f7cf2976SLionel Sambuc 	tputs(sc_lower_left, 1, putchr);
1840f7cf2976SLionel Sambuc #else
1841f7cf2976SLionel Sambuc 	flush();
1842f7cf2976SLionel Sambuc 	_settextposition(sc_height, 1);
1843f7cf2976SLionel Sambuc #endif
1844f7cf2976SLionel Sambuc }
1845f7cf2976SLionel Sambuc 
1846f7cf2976SLionel Sambuc /*
1847f7cf2976SLionel Sambuc  * Move cursor to left position of current line.
1848f7cf2976SLionel Sambuc  */
1849f7cf2976SLionel Sambuc 	public void
line_left()1850f7cf2976SLionel Sambuc line_left()
1851f7cf2976SLionel Sambuc {
1852f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
1853f7cf2976SLionel Sambuc 	tputs(sc_return, 1, putchr);
1854f7cf2976SLionel Sambuc #else
1855f7cf2976SLionel Sambuc 	int row;
1856f7cf2976SLionel Sambuc 	flush();
1857f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1858f7cf2976SLionel Sambuc 	{
1859f7cf2976SLionel Sambuc 		CONSOLE_SCREEN_BUFFER_INFO scr;
1860f7cf2976SLionel Sambuc 		GetConsoleScreenBufferInfo(con_out, &scr);
1861f7cf2976SLionel Sambuc 		row = scr.dwCursorPosition.Y - scr.srWindow.Top + 1;
1862f7cf2976SLionel Sambuc 	}
1863f7cf2976SLionel Sambuc #else
1864f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
1865f7cf2976SLionel Sambuc 		row = wherey();
1866f7cf2976SLionel Sambuc #else
1867f7cf2976SLionel Sambuc 	{
1868f7cf2976SLionel Sambuc 		struct rccoord tpos = _gettextposition();
1869f7cf2976SLionel Sambuc 		row = tpos.row;
1870f7cf2976SLionel Sambuc 	}
1871f7cf2976SLionel Sambuc #endif
1872f7cf2976SLionel Sambuc #endif
1873f7cf2976SLionel Sambuc 	_settextposition(row, 1);
1874f7cf2976SLionel Sambuc #endif
1875f7cf2976SLionel Sambuc }
1876f7cf2976SLionel Sambuc 
1877f7cf2976SLionel Sambuc /*
1878f7cf2976SLionel Sambuc  * Check if the console size has changed and reset internals
1879f7cf2976SLionel Sambuc  * (in lieu of SIGWINCH for WIN32).
1880f7cf2976SLionel Sambuc  */
1881f7cf2976SLionel Sambuc 	public void
check_winch()1882f7cf2976SLionel Sambuc check_winch()
1883f7cf2976SLionel Sambuc {
1884f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1885f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO scr;
1886f7cf2976SLionel Sambuc 	COORD size;
1887f7cf2976SLionel Sambuc 
1888f7cf2976SLionel Sambuc 	if (con_out == INVALID_HANDLE_VALUE)
1889f7cf2976SLionel Sambuc 		return;
1890f7cf2976SLionel Sambuc 
1891f7cf2976SLionel Sambuc 	flush();
1892f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out, &scr);
1893f7cf2976SLionel Sambuc 	size.Y = scr.srWindow.Bottom - scr.srWindow.Top + 1;
1894f7cf2976SLionel Sambuc 	size.X = scr.srWindow.Right - scr.srWindow.Left + 1;
1895f7cf2976SLionel Sambuc 	if (size.Y != sc_height || size.X != sc_width)
1896f7cf2976SLionel Sambuc 	{
1897f7cf2976SLionel Sambuc 		sc_height = size.Y;
1898f7cf2976SLionel Sambuc 		sc_width = size.X;
1899f7cf2976SLionel Sambuc 		if (!no_init && con_out_ours == con_out)
1900f7cf2976SLionel Sambuc 			SetConsoleScreenBufferSize(con_out, size);
1901f7cf2976SLionel Sambuc 		pos_init();
1902f7cf2976SLionel Sambuc 		wscroll = (sc_height + 1) / 2;
1903f7cf2976SLionel Sambuc 		screen_trashed = 1;
1904f7cf2976SLionel Sambuc 	}
1905f7cf2976SLionel Sambuc #endif
1906f7cf2976SLionel Sambuc }
1907f7cf2976SLionel Sambuc 
1908f7cf2976SLionel Sambuc /*
1909f7cf2976SLionel Sambuc  * Goto a specific line on the screen.
1910f7cf2976SLionel Sambuc  */
1911f7cf2976SLionel Sambuc 	public void
goto_line(slinenum)1912f7cf2976SLionel Sambuc goto_line(slinenum)
1913f7cf2976SLionel Sambuc 	int slinenum;
1914f7cf2976SLionel Sambuc {
1915f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
1916f7cf2976SLionel Sambuc 	tputs(tgoto(sc_move, 0, slinenum), 1, putchr);
1917f7cf2976SLionel Sambuc #else
1918f7cf2976SLionel Sambuc 	flush();
1919f7cf2976SLionel Sambuc 	_settextposition(slinenum+1, 1);
1920f7cf2976SLionel Sambuc #endif
1921f7cf2976SLionel Sambuc }
1922f7cf2976SLionel Sambuc 
1923f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==BORLANDC
1924f7cf2976SLionel Sambuc /*
1925f7cf2976SLionel Sambuc  * Create an alternate screen which is all white.
1926f7cf2976SLionel Sambuc  * This screen is used to create a "flash" effect, by displaying it
1927f7cf2976SLionel Sambuc  * briefly and then switching back to the normal screen.
1928f7cf2976SLionel Sambuc  * {{ Yuck!  There must be a better way to get a visual bell. }}
1929f7cf2976SLionel Sambuc  */
1930f7cf2976SLionel Sambuc 	static void
create_flash()1931f7cf2976SLionel Sambuc create_flash()
1932f7cf2976SLionel Sambuc {
1933f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
1934f7cf2976SLionel Sambuc 	struct videoconfig w;
1935f7cf2976SLionel Sambuc 	char *blanks;
1936f7cf2976SLionel Sambuc 	int row, col;
1937f7cf2976SLionel Sambuc 
1938f7cf2976SLionel Sambuc 	_getvideoconfig(&w);
1939f7cf2976SLionel Sambuc 	videopages = w.numvideopages;
1940f7cf2976SLionel Sambuc 	if (videopages < 2)
1941f7cf2976SLionel Sambuc 	{
1942f7cf2976SLionel Sambuc 		at_enter(AT_STANDOUT);
1943f7cf2976SLionel Sambuc 		at_exit();
1944f7cf2976SLionel Sambuc 	} else
1945f7cf2976SLionel Sambuc 	{
1946f7cf2976SLionel Sambuc 		_setactivepage(1);
1947f7cf2976SLionel Sambuc 		at_enter(AT_STANDOUT);
1948f7cf2976SLionel Sambuc 		blanks = (char *) ecalloc(w.numtextcols, sizeof(char));
1949f7cf2976SLionel Sambuc 		for (col = 0;  col < w.numtextcols;  col++)
1950f7cf2976SLionel Sambuc 			blanks[col] = ' ';
1951f7cf2976SLionel Sambuc 		for (row = w.numtextrows;  row > 0;  row--)
1952f7cf2976SLionel Sambuc 			_outmem(blanks, w.numtextcols);
1953f7cf2976SLionel Sambuc 		_setactivepage(0);
1954f7cf2976SLionel Sambuc 		_setvisualpage(0);
1955f7cf2976SLionel Sambuc 		free(blanks);
1956f7cf2976SLionel Sambuc 		at_exit();
1957f7cf2976SLionel Sambuc 	}
1958f7cf2976SLionel Sambuc #else
1959f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC
1960f7cf2976SLionel Sambuc 	register int n;
1961f7cf2976SLionel Sambuc 
1962f7cf2976SLionel Sambuc 	whitescreen = (unsigned short *)
1963f7cf2976SLionel Sambuc 		malloc(sc_width * sc_height * sizeof(short));
1964f7cf2976SLionel Sambuc 	if (whitescreen == NULL)
1965f7cf2976SLionel Sambuc 		return;
1966f7cf2976SLionel Sambuc 	for (n = 0;  n < sc_width * sc_height;  n++)
1967f7cf2976SLionel Sambuc 		whitescreen[n] = 0x7020;
1968f7cf2976SLionel Sambuc #else
1969f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
1970f7cf2976SLionel Sambuc 	register int n;
1971f7cf2976SLionel Sambuc 
1972f7cf2976SLionel Sambuc 	whitescreen = (WORD *)
1973f7cf2976SLionel Sambuc 		malloc(sc_height * sc_width * sizeof(WORD));
1974f7cf2976SLionel Sambuc 	if (whitescreen == NULL)
1975f7cf2976SLionel Sambuc 		return;
1976f7cf2976SLionel Sambuc 	/* Invert the standard colors. */
1977f7cf2976SLionel Sambuc 	for (n = 0;  n < sc_width * sc_height;  n++)
1978f7cf2976SLionel Sambuc 		whitescreen[n] = (WORD)((nm_fg_color << 4) | nm_bg_color);
1979f7cf2976SLionel Sambuc #endif
1980f7cf2976SLionel Sambuc #endif
1981f7cf2976SLionel Sambuc #endif
1982f7cf2976SLionel Sambuc 	flash_created = 1;
1983f7cf2976SLionel Sambuc }
1984f7cf2976SLionel Sambuc #endif /* MSDOS_COMPILER */
1985f7cf2976SLionel Sambuc 
1986f7cf2976SLionel Sambuc /*
1987f7cf2976SLionel Sambuc  * Output the "visual bell", if there is one.
1988f7cf2976SLionel Sambuc  */
1989f7cf2976SLionel Sambuc 	public void
vbell()1990f7cf2976SLionel Sambuc vbell()
1991f7cf2976SLionel Sambuc {
1992f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
1993f7cf2976SLionel Sambuc 	if (*sc_visual_bell == '\0')
1994f7cf2976SLionel Sambuc 		return;
1995f7cf2976SLionel Sambuc 	tputs(sc_visual_bell, sc_height, putchr);
1996f7cf2976SLionel Sambuc #else
1997f7cf2976SLionel Sambuc #if MSDOS_COMPILER==DJGPPC
1998f7cf2976SLionel Sambuc 	ScreenVisualBell();
1999f7cf2976SLionel Sambuc #else
2000f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
2001f7cf2976SLionel Sambuc 	/*
2002f7cf2976SLionel Sambuc 	 * Create a flash screen on the second video page.
2003f7cf2976SLionel Sambuc 	 * Switch to that page, then switch back.
2004f7cf2976SLionel Sambuc 	 */
2005f7cf2976SLionel Sambuc 	if (!flash_created)
2006f7cf2976SLionel Sambuc 		create_flash();
2007f7cf2976SLionel Sambuc 	if (videopages < 2)
2008f7cf2976SLionel Sambuc 		return;
2009f7cf2976SLionel Sambuc 	_setvisualpage(1);
2010f7cf2976SLionel Sambuc 	delay(100);
2011f7cf2976SLionel Sambuc 	_setvisualpage(0);
2012f7cf2976SLionel Sambuc #else
2013f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC
2014f7cf2976SLionel Sambuc 	unsigned short *currscreen;
2015f7cf2976SLionel Sambuc 
2016f7cf2976SLionel Sambuc 	/*
2017f7cf2976SLionel Sambuc 	 * Get a copy of the current screen.
2018f7cf2976SLionel Sambuc 	 * Display the flash screen.
2019f7cf2976SLionel Sambuc 	 * Then restore the old screen.
2020f7cf2976SLionel Sambuc 	 */
2021f7cf2976SLionel Sambuc 	if (!flash_created)
2022f7cf2976SLionel Sambuc 		create_flash();
2023f7cf2976SLionel Sambuc 	if (whitescreen == NULL)
2024f7cf2976SLionel Sambuc 		return;
2025f7cf2976SLionel Sambuc 	currscreen = (unsigned short *)
2026f7cf2976SLionel Sambuc 		malloc(sc_width * sc_height * sizeof(short));
2027f7cf2976SLionel Sambuc 	if (currscreen == NULL) return;
2028f7cf2976SLionel Sambuc 	gettext(1, 1, sc_width, sc_height, currscreen);
2029f7cf2976SLionel Sambuc 	puttext(1, 1, sc_width, sc_height, whitescreen);
2030f7cf2976SLionel Sambuc 	delay(100);
2031f7cf2976SLionel Sambuc 	puttext(1, 1, sc_width, sc_height, currscreen);
2032f7cf2976SLionel Sambuc 	free(currscreen);
2033f7cf2976SLionel Sambuc #else
2034f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
2035f7cf2976SLionel Sambuc 	/* paint screen with an inverse color */
2036f7cf2976SLionel Sambuc 	clear();
2037f7cf2976SLionel Sambuc 
2038f7cf2976SLionel Sambuc 	/* leave it displayed for 100 msec. */
2039f7cf2976SLionel Sambuc 	Sleep(100);
2040f7cf2976SLionel Sambuc 
2041f7cf2976SLionel Sambuc 	/* restore with a redraw */
2042f7cf2976SLionel Sambuc 	repaint();
2043f7cf2976SLionel Sambuc #endif
2044f7cf2976SLionel Sambuc #endif
2045f7cf2976SLionel Sambuc #endif
2046f7cf2976SLionel Sambuc #endif
2047f7cf2976SLionel Sambuc #endif
2048f7cf2976SLionel Sambuc }
2049f7cf2976SLionel Sambuc 
2050f7cf2976SLionel Sambuc /*
2051f7cf2976SLionel Sambuc  * Make a noise.
2052f7cf2976SLionel Sambuc  */
2053f7cf2976SLionel Sambuc 	static void
beep()2054f7cf2976SLionel Sambuc beep()
2055f7cf2976SLionel Sambuc {
2056f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
2057f7cf2976SLionel Sambuc 	putchr(CONTROL('G'));
2058f7cf2976SLionel Sambuc #else
2059f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
2060f7cf2976SLionel Sambuc 	MessageBeep(0);
2061f7cf2976SLionel Sambuc #else
2062f7cf2976SLionel Sambuc 	write(1, "\7", 1);
2063f7cf2976SLionel Sambuc #endif
2064f7cf2976SLionel Sambuc #endif
2065f7cf2976SLionel Sambuc }
2066f7cf2976SLionel Sambuc 
2067f7cf2976SLionel Sambuc /*
2068f7cf2976SLionel Sambuc  * Ring the terminal bell.
2069f7cf2976SLionel Sambuc  */
2070f7cf2976SLionel Sambuc 	public void
bell()2071f7cf2976SLionel Sambuc bell()
2072f7cf2976SLionel Sambuc {
2073f7cf2976SLionel Sambuc 	if (quiet == VERY_QUIET)
2074f7cf2976SLionel Sambuc 		vbell();
2075f7cf2976SLionel Sambuc 	else
2076f7cf2976SLionel Sambuc 		beep();
2077f7cf2976SLionel Sambuc }
2078f7cf2976SLionel Sambuc 
2079f7cf2976SLionel Sambuc /*
2080f7cf2976SLionel Sambuc  * Clear the screen.
2081f7cf2976SLionel Sambuc  */
2082f7cf2976SLionel Sambuc 	public void
clear()2083f7cf2976SLionel Sambuc clear()
2084f7cf2976SLionel Sambuc {
2085f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
2086f7cf2976SLionel Sambuc 	tputs(sc_clear, sc_height, putchr);
2087f7cf2976SLionel Sambuc #else
2088f7cf2976SLionel Sambuc 	flush();
2089f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
2090f7cf2976SLionel Sambuc 	win32_clear();
2091f7cf2976SLionel Sambuc #else
2092f7cf2976SLionel Sambuc 	_clearscreen(_GCLEARSCREEN);
2093f7cf2976SLionel Sambuc #endif
2094f7cf2976SLionel Sambuc #endif
2095f7cf2976SLionel Sambuc }
2096f7cf2976SLionel Sambuc 
2097f7cf2976SLionel Sambuc /*
2098f7cf2976SLionel Sambuc  * Clear from the cursor to the end of the cursor's line.
2099f7cf2976SLionel Sambuc  * {{ This must not move the cursor. }}
2100f7cf2976SLionel Sambuc  */
2101f7cf2976SLionel Sambuc 	public void
clear_eol()2102f7cf2976SLionel Sambuc clear_eol()
2103f7cf2976SLionel Sambuc {
2104f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
2105f7cf2976SLionel Sambuc 	tputs(sc_eol_clear, 1, putchr);
2106f7cf2976SLionel Sambuc #else
2107f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
2108f7cf2976SLionel Sambuc 	short top, left;
2109f7cf2976SLionel Sambuc 	short bot, right;
2110f7cf2976SLionel Sambuc 	struct rccoord tpos;
2111f7cf2976SLionel Sambuc 
2112f7cf2976SLionel Sambuc 	flush();
2113f7cf2976SLionel Sambuc 	/*
2114f7cf2976SLionel Sambuc 	 * Save current state.
2115f7cf2976SLionel Sambuc 	 */
2116f7cf2976SLionel Sambuc 	tpos = _gettextposition();
2117f7cf2976SLionel Sambuc 	_gettextwindow(&top, &left, &bot, &right);
2118f7cf2976SLionel Sambuc 	/*
2119f7cf2976SLionel Sambuc 	 * Set a temporary window to the current line,
2120f7cf2976SLionel Sambuc 	 * from the cursor's position to the right edge of the screen.
2121f7cf2976SLionel Sambuc 	 * Then clear that window.
2122f7cf2976SLionel Sambuc 	 */
2123f7cf2976SLionel Sambuc 	_settextwindow(tpos.row, tpos.col, tpos.row, sc_width);
2124f7cf2976SLionel Sambuc 	_clearscreen(_GWINDOW);
2125f7cf2976SLionel Sambuc 	/*
2126f7cf2976SLionel Sambuc 	 * Restore state.
2127f7cf2976SLionel Sambuc 	 */
2128f7cf2976SLionel Sambuc 	_settextwindow(top, left, bot, right);
2129f7cf2976SLionel Sambuc 	_settextposition(tpos.row, tpos.col);
2130f7cf2976SLionel Sambuc #else
2131f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
2132f7cf2976SLionel Sambuc 	flush();
2133f7cf2976SLionel Sambuc 	clreol();
2134f7cf2976SLionel Sambuc #else
2135f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
2136f7cf2976SLionel Sambuc 	DWORD           nchars;
2137f7cf2976SLionel Sambuc 	COORD           cpos;
2138f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO scr;
2139f7cf2976SLionel Sambuc 
2140f7cf2976SLionel Sambuc 	flush();
2141f7cf2976SLionel Sambuc 	memset(&scr, 0, sizeof(scr));
2142f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out, &scr);
2143f7cf2976SLionel Sambuc 	cpos.X = scr.dwCursorPosition.X;
2144f7cf2976SLionel Sambuc 	cpos.Y = scr.dwCursorPosition.Y;
2145f7cf2976SLionel Sambuc 	curr_attr = MAKEATTR(nm_fg_color, nm_bg_color);
2146f7cf2976SLionel Sambuc 	FillConsoleOutputAttribute(con_out, curr_attr,
2147f7cf2976SLionel Sambuc 		scr.dwSize.X - cpos.X, cpos, &nchars);
2148f7cf2976SLionel Sambuc 	FillConsoleOutputCharacter(con_out, ' ',
2149f7cf2976SLionel Sambuc 		scr.dwSize.X - cpos.X, cpos, &nchars);
2150f7cf2976SLionel Sambuc #endif
2151f7cf2976SLionel Sambuc #endif
2152f7cf2976SLionel Sambuc #endif
2153f7cf2976SLionel Sambuc #endif
2154f7cf2976SLionel Sambuc }
2155f7cf2976SLionel Sambuc 
2156f7cf2976SLionel Sambuc /*
2157f7cf2976SLionel Sambuc  * Clear the current line.
2158f7cf2976SLionel Sambuc  * Clear the screen if there's off-screen memory below the display.
2159f7cf2976SLionel Sambuc  */
2160f7cf2976SLionel Sambuc 	static void
clear_eol_bot()2161f7cf2976SLionel Sambuc clear_eol_bot()
2162f7cf2976SLionel Sambuc {
2163f7cf2976SLionel Sambuc #if MSDOS_COMPILER
2164f7cf2976SLionel Sambuc 	clear_eol();
2165f7cf2976SLionel Sambuc #else
2166f7cf2976SLionel Sambuc 	if (below_mem)
2167f7cf2976SLionel Sambuc 		tputs(sc_eos_clear, 1, putchr);
2168f7cf2976SLionel Sambuc 	else
2169f7cf2976SLionel Sambuc 		tputs(sc_eol_clear, 1, putchr);
2170f7cf2976SLionel Sambuc #endif
2171f7cf2976SLionel Sambuc }
2172f7cf2976SLionel Sambuc 
2173f7cf2976SLionel Sambuc /*
2174f7cf2976SLionel Sambuc  * Clear the bottom line of the display.
2175f7cf2976SLionel Sambuc  * Leave the cursor at the beginning of the bottom line.
2176f7cf2976SLionel Sambuc  */
2177f7cf2976SLionel Sambuc 	public void
clear_bot()2178f7cf2976SLionel Sambuc clear_bot()
2179f7cf2976SLionel Sambuc {
2180f7cf2976SLionel Sambuc 	/*
2181f7cf2976SLionel Sambuc 	 * If we're in a non-normal attribute mode, temporarily exit
2182f7cf2976SLionel Sambuc 	 * the mode while we do the clear.  Some terminals fill the
2183f7cf2976SLionel Sambuc 	 * cleared area with the current attribute.
2184f7cf2976SLionel Sambuc 	 */
2185f7cf2976SLionel Sambuc 	if (oldbot)
2186f7cf2976SLionel Sambuc 		lower_left();
2187f7cf2976SLionel Sambuc 	else
2188f7cf2976SLionel Sambuc 		line_left();
2189f7cf2976SLionel Sambuc 
2190f7cf2976SLionel Sambuc 	if (attrmode == AT_NORMAL)
2191f7cf2976SLionel Sambuc 		clear_eol_bot();
2192f7cf2976SLionel Sambuc 	else
2193f7cf2976SLionel Sambuc 	{
2194f7cf2976SLionel Sambuc 		int saved_attrmode = attrmode;
2195f7cf2976SLionel Sambuc 
2196f7cf2976SLionel Sambuc 		at_exit();
2197f7cf2976SLionel Sambuc 		clear_eol_bot();
2198f7cf2976SLionel Sambuc 		at_enter(saved_attrmode);
2199f7cf2976SLionel Sambuc 	}
2200f7cf2976SLionel Sambuc }
2201f7cf2976SLionel Sambuc 
2202f7cf2976SLionel Sambuc 	public void
at_enter(attr)2203f7cf2976SLionel Sambuc at_enter(attr)
2204f7cf2976SLionel Sambuc 	int attr;
2205f7cf2976SLionel Sambuc {
2206f7cf2976SLionel Sambuc 	attr = apply_at_specials(attr);
2207f7cf2976SLionel Sambuc 
2208f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
2209f7cf2976SLionel Sambuc 	/* The one with the most priority is last.  */
2210f7cf2976SLionel Sambuc 	if (attr & AT_UNDERLINE)
2211f7cf2976SLionel Sambuc 		tputs(sc_u_in, 1, putchr);
2212f7cf2976SLionel Sambuc 	if (attr & AT_BOLD)
2213f7cf2976SLionel Sambuc 		tputs(sc_b_in, 1, putchr);
2214f7cf2976SLionel Sambuc 	if (attr & AT_BLINK)
2215f7cf2976SLionel Sambuc 		tputs(sc_bl_in, 1, putchr);
2216f7cf2976SLionel Sambuc 	if (attr & AT_STANDOUT)
2217f7cf2976SLionel Sambuc 		tputs(sc_s_in, 1, putchr);
2218f7cf2976SLionel Sambuc #else
2219f7cf2976SLionel Sambuc 	flush();
2220f7cf2976SLionel Sambuc 	/* The one with the most priority is first.  */
2221f7cf2976SLionel Sambuc 	if (attr & AT_STANDOUT)
2222f7cf2976SLionel Sambuc 	{
2223f7cf2976SLionel Sambuc 		SETCOLORS(so_fg_color, so_bg_color);
2224f7cf2976SLionel Sambuc 	} else if (attr & AT_BLINK)
2225f7cf2976SLionel Sambuc 	{
2226f7cf2976SLionel Sambuc 		SETCOLORS(bl_fg_color, bl_bg_color);
2227f7cf2976SLionel Sambuc 	}
2228f7cf2976SLionel Sambuc 	else if (attr & AT_BOLD)
2229f7cf2976SLionel Sambuc 	{
2230f7cf2976SLionel Sambuc 		SETCOLORS(bo_fg_color, bo_bg_color);
2231f7cf2976SLionel Sambuc 	}
2232f7cf2976SLionel Sambuc 	else if (attr & AT_UNDERLINE)
2233f7cf2976SLionel Sambuc 	{
2234f7cf2976SLionel Sambuc 		SETCOLORS(ul_fg_color, ul_bg_color);
2235f7cf2976SLionel Sambuc 	}
2236f7cf2976SLionel Sambuc #endif
2237f7cf2976SLionel Sambuc 
2238f7cf2976SLionel Sambuc 	attrmode = attr;
2239f7cf2976SLionel Sambuc }
2240f7cf2976SLionel Sambuc 
2241f7cf2976SLionel Sambuc 	public void
at_exit()2242f7cf2976SLionel Sambuc at_exit()
2243f7cf2976SLionel Sambuc {
2244f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
2245f7cf2976SLionel Sambuc 	/* Undo things in the reverse order we did them.  */
2246f7cf2976SLionel Sambuc 	if (attrmode & AT_STANDOUT)
2247f7cf2976SLionel Sambuc 		tputs(sc_s_out, 1, putchr);
2248f7cf2976SLionel Sambuc 	if (attrmode & AT_BLINK)
2249f7cf2976SLionel Sambuc 		tputs(sc_bl_out, 1, putchr);
2250f7cf2976SLionel Sambuc 	if (attrmode & AT_BOLD)
2251f7cf2976SLionel Sambuc 		tputs(sc_b_out, 1, putchr);
2252f7cf2976SLionel Sambuc 	if (attrmode & AT_UNDERLINE)
2253f7cf2976SLionel Sambuc 		tputs(sc_u_out, 1, putchr);
2254f7cf2976SLionel Sambuc #else
2255f7cf2976SLionel Sambuc 	flush();
2256f7cf2976SLionel Sambuc 	SETCOLORS(nm_fg_color, nm_bg_color);
2257f7cf2976SLionel Sambuc #endif
2258f7cf2976SLionel Sambuc 
2259f7cf2976SLionel Sambuc 	attrmode = AT_NORMAL;
2260f7cf2976SLionel Sambuc }
2261f7cf2976SLionel Sambuc 
2262f7cf2976SLionel Sambuc 	public void
at_switch(attr)2263f7cf2976SLionel Sambuc at_switch(attr)
2264f7cf2976SLionel Sambuc 	int attr;
2265f7cf2976SLionel Sambuc {
2266f7cf2976SLionel Sambuc 	int new_attrmode = apply_at_specials(attr);
2267f7cf2976SLionel Sambuc 	int ignore_modes = AT_ANSI;
2268f7cf2976SLionel Sambuc 
2269f7cf2976SLionel Sambuc 	if ((new_attrmode & ~ignore_modes) != (attrmode & ~ignore_modes))
2270f7cf2976SLionel Sambuc 	{
2271f7cf2976SLionel Sambuc 		at_exit();
2272f7cf2976SLionel Sambuc 		at_enter(attr);
2273f7cf2976SLionel Sambuc 	}
2274f7cf2976SLionel Sambuc }
2275f7cf2976SLionel Sambuc 
2276f7cf2976SLionel Sambuc 	public int
is_at_equiv(attr1,attr2)2277f7cf2976SLionel Sambuc is_at_equiv(attr1, attr2)
2278f7cf2976SLionel Sambuc 	int attr1;
2279f7cf2976SLionel Sambuc 	int attr2;
2280f7cf2976SLionel Sambuc {
2281f7cf2976SLionel Sambuc 	attr1 = apply_at_specials(attr1);
2282f7cf2976SLionel Sambuc 	attr2 = apply_at_specials(attr2);
2283f7cf2976SLionel Sambuc 
2284f7cf2976SLionel Sambuc 	return (attr1 == attr2);
2285f7cf2976SLionel Sambuc }
2286f7cf2976SLionel Sambuc 
2287f7cf2976SLionel Sambuc 	public int
apply_at_specials(attr)2288f7cf2976SLionel Sambuc apply_at_specials(attr)
2289f7cf2976SLionel Sambuc 	int attr;
2290f7cf2976SLionel Sambuc {
2291f7cf2976SLionel Sambuc 	if (attr & AT_BINARY)
2292f7cf2976SLionel Sambuc 		attr |= binattr;
2293f7cf2976SLionel Sambuc 	if (attr & AT_HILITE)
2294f7cf2976SLionel Sambuc 		attr |= AT_STANDOUT;
2295f7cf2976SLionel Sambuc 	attr &= ~(AT_BINARY|AT_HILITE);
2296f7cf2976SLionel Sambuc 
2297f7cf2976SLionel Sambuc 	return attr;
2298f7cf2976SLionel Sambuc }
2299f7cf2976SLionel Sambuc 
2300f7cf2976SLionel Sambuc #if 0 /* No longer used */
2301f7cf2976SLionel Sambuc /*
2302f7cf2976SLionel Sambuc  * Erase the character to the left of the cursor
2303f7cf2976SLionel Sambuc  * and move the cursor left.
2304f7cf2976SLionel Sambuc  */
2305f7cf2976SLionel Sambuc 	public void
2306f7cf2976SLionel Sambuc backspace()
2307f7cf2976SLionel Sambuc {
2308f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
2309f7cf2976SLionel Sambuc 	/*
2310f7cf2976SLionel Sambuc 	 * Erase the previous character by overstriking with a space.
2311f7cf2976SLionel Sambuc 	 */
2312f7cf2976SLionel Sambuc 	tputs(sc_backspace, 1, putchr);
2313f7cf2976SLionel Sambuc 	putchr(' ');
2314f7cf2976SLionel Sambuc 	tputs(sc_backspace, 1, putchr);
2315f7cf2976SLionel Sambuc #else
2316f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
2317f7cf2976SLionel Sambuc 	struct rccoord tpos;
2318f7cf2976SLionel Sambuc 
2319f7cf2976SLionel Sambuc 	flush();
2320f7cf2976SLionel Sambuc 	tpos = _gettextposition();
2321f7cf2976SLionel Sambuc 	if (tpos.col <= 1)
2322f7cf2976SLionel Sambuc 		return;
2323f7cf2976SLionel Sambuc 	_settextposition(tpos.row, tpos.col-1);
2324f7cf2976SLionel Sambuc 	_outtext(" ");
2325f7cf2976SLionel Sambuc 	_settextposition(tpos.row, tpos.col-1);
2326f7cf2976SLionel Sambuc #else
2327f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
2328f7cf2976SLionel Sambuc 	cputs("\b");
2329f7cf2976SLionel Sambuc #else
2330f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
2331f7cf2976SLionel Sambuc 	COORD cpos;
2332f7cf2976SLionel Sambuc 	DWORD cChars;
2333f7cf2976SLionel Sambuc 	CONSOLE_SCREEN_BUFFER_INFO scr;
2334f7cf2976SLionel Sambuc 
2335f7cf2976SLionel Sambuc 	flush();
2336f7cf2976SLionel Sambuc 	GetConsoleScreenBufferInfo(con_out, &scr);
2337f7cf2976SLionel Sambuc 	cpos = scr.dwCursorPosition;
2338f7cf2976SLionel Sambuc 	if (cpos.X <= 0)
2339f7cf2976SLionel Sambuc 		return;
2340f7cf2976SLionel Sambuc 	cpos.X--;
2341f7cf2976SLionel Sambuc 	SetConsoleCursorPosition(con_out, cpos);
2342f7cf2976SLionel Sambuc 	FillConsoleOutputCharacter(con_out, (TCHAR)' ', 1, cpos, &cChars);
2343f7cf2976SLionel Sambuc 	SetConsoleCursorPosition(con_out, cpos);
2344f7cf2976SLionel Sambuc #endif
2345f7cf2976SLionel Sambuc #endif
2346f7cf2976SLionel Sambuc #endif
2347f7cf2976SLionel Sambuc #endif
2348f7cf2976SLionel Sambuc }
2349f7cf2976SLionel Sambuc #endif /* 0 */
2350f7cf2976SLionel Sambuc 
2351f7cf2976SLionel Sambuc /*
2352f7cf2976SLionel Sambuc  * Output a plain backspace, without erasing the previous char.
2353f7cf2976SLionel Sambuc  */
2354f7cf2976SLionel Sambuc 	public void
putbs()2355f7cf2976SLionel Sambuc putbs()
2356f7cf2976SLionel Sambuc {
2357f7cf2976SLionel Sambuc #if !MSDOS_COMPILER
2358f7cf2976SLionel Sambuc 	tputs(sc_backspace, 1, putchr);
2359f7cf2976SLionel Sambuc #else
2360f7cf2976SLionel Sambuc 	int row, col;
2361f7cf2976SLionel Sambuc 
2362f7cf2976SLionel Sambuc 	flush();
2363f7cf2976SLionel Sambuc 	{
2364f7cf2976SLionel Sambuc #if MSDOS_COMPILER==MSOFTC
2365f7cf2976SLionel Sambuc 		struct rccoord tpos;
2366f7cf2976SLionel Sambuc 		tpos = _gettextposition();
2367f7cf2976SLionel Sambuc 		row = tpos.row;
2368f7cf2976SLionel Sambuc 		col = tpos.col;
2369f7cf2976SLionel Sambuc #else
2370f7cf2976SLionel Sambuc #if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
2371f7cf2976SLionel Sambuc 		row = wherey();
2372f7cf2976SLionel Sambuc 		col = wherex();
2373f7cf2976SLionel Sambuc #else
2374f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
2375f7cf2976SLionel Sambuc 		CONSOLE_SCREEN_BUFFER_INFO scr;
2376f7cf2976SLionel Sambuc 		GetConsoleScreenBufferInfo(con_out, &scr);
2377f7cf2976SLionel Sambuc 		row = scr.dwCursorPosition.Y - scr.srWindow.Top + 1;
2378f7cf2976SLionel Sambuc 		col = scr.dwCursorPosition.X - scr.srWindow.Left + 1;
2379f7cf2976SLionel Sambuc #endif
2380f7cf2976SLionel Sambuc #endif
2381f7cf2976SLionel Sambuc #endif
2382f7cf2976SLionel Sambuc 	}
2383f7cf2976SLionel Sambuc 	if (col <= 1)
2384f7cf2976SLionel Sambuc 		return;
2385f7cf2976SLionel Sambuc 	_settextposition(row, col-1);
2386f7cf2976SLionel Sambuc #endif /* MSDOS_COMPILER */
2387f7cf2976SLionel Sambuc }
2388f7cf2976SLionel Sambuc 
2389f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
2390f7cf2976SLionel Sambuc /*
2391f7cf2976SLionel Sambuc  * Determine whether an input character is waiting to be read.
2392f7cf2976SLionel Sambuc  */
2393f7cf2976SLionel Sambuc 	static int
win32_kbhit(tty)2394f7cf2976SLionel Sambuc win32_kbhit(tty)
2395f7cf2976SLionel Sambuc 	HANDLE tty;
2396f7cf2976SLionel Sambuc {
2397f7cf2976SLionel Sambuc 	INPUT_RECORD ip;
2398f7cf2976SLionel Sambuc 	DWORD read;
2399f7cf2976SLionel Sambuc 
2400f7cf2976SLionel Sambuc 	if (keyCount > 0)
2401f7cf2976SLionel Sambuc 		return (TRUE);
2402f7cf2976SLionel Sambuc 
2403f7cf2976SLionel Sambuc 	currentKey.ascii = 0;
2404f7cf2976SLionel Sambuc 	currentKey.scan = 0;
2405f7cf2976SLionel Sambuc 
2406f7cf2976SLionel Sambuc 	/*
2407f7cf2976SLionel Sambuc 	 * Wait for a real key-down event, but
2408f7cf2976SLionel Sambuc 	 * ignore SHIFT and CONTROL key events.
2409f7cf2976SLionel Sambuc 	 */
2410f7cf2976SLionel Sambuc 	do
2411f7cf2976SLionel Sambuc 	{
2412f7cf2976SLionel Sambuc 		PeekConsoleInput(tty, &ip, 1, &read);
2413f7cf2976SLionel Sambuc 		if (read == 0)
2414f7cf2976SLionel Sambuc 			return (FALSE);
2415f7cf2976SLionel Sambuc 		ReadConsoleInput(tty, &ip, 1, &read);
2416f7cf2976SLionel Sambuc 	} while (ip.EventType != KEY_EVENT ||
2417f7cf2976SLionel Sambuc 		ip.Event.KeyEvent.bKeyDown != TRUE ||
2418f7cf2976SLionel Sambuc 		ip.Event.KeyEvent.wVirtualScanCode == 0 ||
2419f7cf2976SLionel Sambuc 		ip.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT ||
2420f7cf2976SLionel Sambuc 		ip.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL ||
2421f7cf2976SLionel Sambuc 		ip.Event.KeyEvent.wVirtualKeyCode == VK_MENU);
2422f7cf2976SLionel Sambuc 
2423f7cf2976SLionel Sambuc 	currentKey.ascii = ip.Event.KeyEvent.uChar.AsciiChar;
2424f7cf2976SLionel Sambuc 	currentKey.scan = ip.Event.KeyEvent.wVirtualScanCode;
2425f7cf2976SLionel Sambuc 	keyCount = ip.Event.KeyEvent.wRepeatCount;
2426f7cf2976SLionel Sambuc 
2427f7cf2976SLionel Sambuc 	if (ip.Event.KeyEvent.dwControlKeyState &
2428f7cf2976SLionel Sambuc 		(LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
2429f7cf2976SLionel Sambuc 	{
2430f7cf2976SLionel Sambuc 		switch (currentKey.scan)
2431f7cf2976SLionel Sambuc 		{
2432f7cf2976SLionel Sambuc 		case PCK_ALT_E:     /* letter 'E' */
2433f7cf2976SLionel Sambuc 			currentKey.ascii = 0;
2434f7cf2976SLionel Sambuc 			break;
2435f7cf2976SLionel Sambuc 		}
2436f7cf2976SLionel Sambuc 	} else if (ip.Event.KeyEvent.dwControlKeyState &
2437f7cf2976SLionel Sambuc 		(LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
2438f7cf2976SLionel Sambuc 	{
2439f7cf2976SLionel Sambuc 		switch (currentKey.scan)
2440f7cf2976SLionel Sambuc 		{
2441f7cf2976SLionel Sambuc 		case PCK_RIGHT: /* right arrow */
2442f7cf2976SLionel Sambuc 			currentKey.scan = PCK_CTL_RIGHT;
2443f7cf2976SLionel Sambuc 			break;
2444f7cf2976SLionel Sambuc 		case PCK_LEFT: /* left arrow */
2445f7cf2976SLionel Sambuc 			currentKey.scan = PCK_CTL_LEFT;
2446f7cf2976SLionel Sambuc 			break;
2447f7cf2976SLionel Sambuc 		case PCK_DELETE: /* delete */
2448f7cf2976SLionel Sambuc 			currentKey.scan = PCK_CTL_DELETE;
2449f7cf2976SLionel Sambuc 			break;
2450f7cf2976SLionel Sambuc 		}
2451f7cf2976SLionel Sambuc 	}
2452f7cf2976SLionel Sambuc 	return (TRUE);
2453f7cf2976SLionel Sambuc }
2454f7cf2976SLionel Sambuc 
2455f7cf2976SLionel Sambuc /*
2456f7cf2976SLionel Sambuc  * Read a character from the keyboard.
2457f7cf2976SLionel Sambuc  */
2458f7cf2976SLionel Sambuc 	public char
WIN32getch(tty)2459f7cf2976SLionel Sambuc WIN32getch(tty)
2460f7cf2976SLionel Sambuc 	int tty;
2461f7cf2976SLionel Sambuc {
2462f7cf2976SLionel Sambuc 	int ascii;
2463f7cf2976SLionel Sambuc 
2464f7cf2976SLionel Sambuc 	if (pending_scancode)
2465f7cf2976SLionel Sambuc 	{
2466f7cf2976SLionel Sambuc 		pending_scancode = 0;
2467f7cf2976SLionel Sambuc 		return ((char)(currentKey.scan & 0x00FF));
2468f7cf2976SLionel Sambuc 	}
2469f7cf2976SLionel Sambuc 
2470f7cf2976SLionel Sambuc 	while (win32_kbhit((HANDLE)tty) == FALSE)
2471f7cf2976SLionel Sambuc 	{
2472f7cf2976SLionel Sambuc 		Sleep(20);
2473f7cf2976SLionel Sambuc 		if (ABORT_SIGS())
2474f7cf2976SLionel Sambuc 			return ('\003');
2475f7cf2976SLionel Sambuc 		continue;
2476f7cf2976SLionel Sambuc 	}
2477f7cf2976SLionel Sambuc 	keyCount --;
2478f7cf2976SLionel Sambuc 	ascii = currentKey.ascii;
2479f7cf2976SLionel Sambuc 	/*
2480f7cf2976SLionel Sambuc 	 * On PC's, the extended keys return a 2 byte sequence beginning
2481f7cf2976SLionel Sambuc 	 * with '00', so if the ascii code is 00, the next byte will be
2482f7cf2976SLionel Sambuc 	 * the lsb of the scan code.
2483f7cf2976SLionel Sambuc 	 */
2484f7cf2976SLionel Sambuc 	pending_scancode = (ascii == 0x00);
2485f7cf2976SLionel Sambuc 	return ((char)ascii);
2486f7cf2976SLionel Sambuc }
2487f7cf2976SLionel Sambuc #endif
2488f7cf2976SLionel Sambuc 
2489f7cf2976SLionel Sambuc #if MSDOS_COMPILER
2490f7cf2976SLionel Sambuc /*
2491f7cf2976SLionel Sambuc  */
2492f7cf2976SLionel Sambuc 	public void
WIN32setcolors(fg,bg)2493f7cf2976SLionel Sambuc WIN32setcolors(fg, bg)
2494f7cf2976SLionel Sambuc 	int fg;
2495f7cf2976SLionel Sambuc 	int bg;
2496f7cf2976SLionel Sambuc {
2497f7cf2976SLionel Sambuc 	SETCOLORS(fg, bg);
2498f7cf2976SLionel Sambuc }
2499f7cf2976SLionel Sambuc 
2500f7cf2976SLionel Sambuc /*
2501f7cf2976SLionel Sambuc  */
2502f7cf2976SLionel Sambuc 	public void
WIN32textout(text,len)2503f7cf2976SLionel Sambuc WIN32textout(text, len)
2504f7cf2976SLionel Sambuc 	char *text;
2505f7cf2976SLionel Sambuc 	int len;
2506f7cf2976SLionel Sambuc {
2507f7cf2976SLionel Sambuc #if MSDOS_COMPILER==WIN32C
2508f7cf2976SLionel Sambuc 	DWORD written;
2509f7cf2976SLionel Sambuc 	WriteConsole(con_out, text, len, &written, NULL);
2510f7cf2976SLionel Sambuc #else
2511f7cf2976SLionel Sambuc 	char c = text[len];
2512f7cf2976SLionel Sambuc 	text[len] = '\0';
2513f7cf2976SLionel Sambuc 	cputs(text);
2514f7cf2976SLionel Sambuc 	text[len] = c;
2515f7cf2976SLionel Sambuc #endif
2516f7cf2976SLionel Sambuc }
2517f7cf2976SLionel Sambuc #endif
2518