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