diff options
Diffstat (limited to 'contrib/less/screen.c')
| -rw-r--r-- | contrib/less/screen.c | 527 |
1 files changed, 374 insertions, 153 deletions
diff --git a/contrib/less/screen.c b/contrib/less/screen.c index 7b91cbb63bbe..4c95f985daf5 100644 --- a/contrib/less/screen.c +++ b/contrib/less/screen.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2025 Mark Nudelman + * Copyright (C) 1984-2026 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -68,6 +68,14 @@ extern int fd0; #endif #endif +#if HAVE_TERMINFO && !USE_TERMCAP +#define USE_TERMINFO 1 +#endif + +#if USE_TERMINFO +#include <curses.h> +#include <term.h> +#else #if HAVE_NCURSESW_TERMCAP_H #include <ncursesw/termcap.h> #else @@ -79,6 +87,7 @@ extern int fd0; #endif #endif #endif +#endif #ifdef _OSK #include <signal.h> #endif @@ -193,10 +202,29 @@ public int vt_enabled = -1; /* Is virtual terminal processing available? */ #else /* + * These two variables are sometimes defined in, + * and needed by, the termcap library. + */ +#if USE_TERMINFO +#undef HAVE_OSPEED +#else +#if MUST_DEFINE_OSPEED +extern short ospeed; /* Terminal output baud rate */ +extern char PC; /* Pad character */ +#endif +#ifdef _OSK +short ospeed; +char PC_, *UP, *BC; +#endif +#endif + +/* * Strings passed to tputs() to do various terminal functions. */ static constant char +#if HAVE_OSPEED *sc_pad, /* Pad string */ +#endif *sc_home, /* Cursor home */ *sc_addline, /* Add line, scroll down following lines */ *sc_lower_left, /* Cursor to last line, first column */ @@ -229,10 +257,12 @@ static constant char static int attrcolor = -1; #endif -static int init_done = 0; +/* term_init has been called; terminal is ready for use by less */ +static lbool term_init_done = FALSE; +public lbool term_init_ever = FALSE; public int auto_wrap; /* Terminal does \r\n when write past margin */ -public int ignaw; /* Terminal ignores \n immediately after wrap */ +public int defer_wrap; /* After printing char in last column, doesn't wrap until next char */ public int erase_char; /* The user's erase char */ public int erase2_char; /* The user's other erase char */ public int kill_char; /* The user's line-kill char */ @@ -247,8 +277,8 @@ public int can_goto_line; /* Can move cursor to any line */ public int clear_bg; /* Clear fills with background color */ public lbool missing_cap = FALSE; /* Some capability is missing */ public constant char *kent = NULL; /* Keypad ENTER sequence */ -public lbool term_init_done = FALSE; -public lbool full_screen = TRUE; +public lbool term_addrs = FALSE; /* "ti" has been sent to terminal */ +public lbool full_screen = TRUE; /* We're using all lines of terminal */ static int attrmode = AT_NORMAL; static int termcap_debug = -1; @@ -259,23 +289,10 @@ extern int shell_lines; #if !MSDOS_COMPILER static constant char *cheaper(constant char *t1, constant char *t2, constant char *def); -static void tmodes(constant char *incap, constant char *outcap, constant char **instr, +static void tmodes(constant char *inti, constant char *outti, constant char *intc, constant char *outtc, constant char **instr, constant char **outstr, constant char *def_instr, constant char *def_outstr, char **spp); #endif -/* - * These two variables are sometimes defined in, - * and needed by, the termcap library. - */ -#if MUST_DEFINE_OSPEED -extern short ospeed; /* Terminal output baud rate */ -extern char PC; /* Pad character */ -#endif -#ifdef _OSK -short ospeed; -char PC_, *UP, *BC; -#endif - extern int quiet; /* If VERY_QUIET, use visual bell for bell */ extern int no_vbell; extern int no_back_scroll; @@ -289,11 +306,11 @@ extern int mousecap; extern int is_tty; extern int use_color; extern int no_paste; +extern int wscroll; #if HILITE_SEARCH extern int hilite_search; #endif #if MSDOS_COMPILER==WIN32C -extern int wscroll; extern HANDLE tty; #else extern int tty; @@ -352,6 +369,15 @@ static void set_termio_flags( | ONLRET #endif ); + + s->c_iflag &= ~(0 +#ifdef ICRNL + | ICRNL +#endif +#ifdef INLCR + | INLCR +#endif + ); } #endif @@ -364,7 +390,7 @@ static void set_termio_flags( * 4. \t is NOT expanded into spaces. * 5. Signal-causing characters such as ctrl-C (interrupt), * etc. are NOT disabled. - * It doesn't matter whether an input \n is mapped to \r, or vice versa. + * 6. Input \r is not mapped to \n, nor vice versa. */ public void raw_mode(int on) { @@ -701,18 +727,21 @@ public void raw_mode(int on) } #if !MSDOS_COMPILER + /* * Some glue to prevent calling termcap functions if tgetent() failed. */ static int hardcopy; -static constant char * ltget_env(constant char *capname) +static constant char * ltget_env(constant char *tiname, constant char *tcname) { - char name[64]; + char envname[64]; + constant char *s; if (termcap_debug) { struct env { struct env *next; char *name; char *value; }; + constant char *capname = tcname != NULL ? tcname : tiname; static struct env *envs = NULL; struct env *p; for (p = envs; p != NULL; p = p->next) @@ -726,48 +755,80 @@ static constant char * ltget_env(constant char *capname) envs = p; return p->value; } - SNPRINTF1(name, sizeof(name), "LESS_TERMCAP_%s", capname); - return (lgetenv(name)); + if (tiname != NULL) + { + SNPRINTF1(envname, sizeof(envname), "LESS_TERMINFO_%s", tiname); + s = lgetenv(envname); + if (!isnullenv(s)) + return s; + } + if (tcname != NULL) + { + SNPRINTF1(envname, sizeof(envname), "LESS_TERMCAP_%s", tcname); + s = lgetenv(envname); + if (!isnullenv(s)) + return s; + } + return NULL; } -static int ltgetflag(constant char *capname) +static int ltgetflag(constant char *tiname, constant char *tcname) { constant char *s; - if ((s = ltget_env(capname)) != NULL) + if ((s = ltget_env(tiname, tcname)) != NULL) return (*s != '\0' && *s != '0'); if (hardcopy) return (0); - return (tgetflag(capname)); +#if USE_TERMINFO + return tiname == NULL ? 0 : tigetflag(tiname); +#else + return tcname == NULL ? 0 : tgetflag(tcname); +#endif } -static int ltgetnum(constant char *capname) +static int ltgetnum(constant char *tiname, constant char *tcname) { constant char *s; - if ((s = ltget_env(capname)) != NULL) + if ((s = ltget_env(tiname, tcname)) != NULL) return (atoi(s)); if (hardcopy) return (-1); - return (tgetnum(capname)); +#if USE_TERMINFO + return tiname == NULL ? -1 : tigetnum(tiname); +#else + return tcname == NULL ? -1 : tgetnum(tcname); +#endif } -static constant char * ltgetstr(constant char *capname, char **pp) +static constant char * ltgetstr(constant char *tiname, constant char *tcname, char **pp) { constant char *s; - if ((s = ltget_env(capname)) != NULL) + if ((s = ltget_env(tiname, tcname)) != NULL) return (s); if (hardcopy) return (NULL); - return (tgetstr(capname, pp)); +#if USE_TERMINFO + if (tiname == NULL) + return (NULL); + s = tigetstr(tiname); + if (s == (constant char *)-1) + s = NULL; + return (s); +#else + if (tcname == NULL) + return (NULL); + return tgetstr(tcname, pp); +#endif } #endif /* MSDOS_COMPILER */ /* * Get size of the output screen. */ -static void scrsize(void) +public void scrsize(void) { constant char *s; int sys_height; @@ -783,7 +844,6 @@ static void scrsize(void) #define DEF_SC_HEIGHT 24 #endif - sys_width = sys_height = 0; #if LESSTEST @@ -846,7 +906,7 @@ static void scrsize(void) #ifdef TIOCGWINSZ { struct winsize w; - if (ioctl(2, TIOCGWINSZ, &w) == 0) + if (ioctl(2, TIOCGWINSZ, &w) == 0 || ioctl(1, TIOCGWINSZ, &w) == 0) { if (w.ws_row > 0) sys_height = w.ws_row; @@ -858,7 +918,7 @@ static void scrsize(void) #ifdef WIOCGETD { struct uwdata w; - if (ioctl(2, WIOCGETD, &w) == 0) + if (ioctl(2, WIOCGETD, &w) == 0 || ioctl(1, WIOCGETD, &w) == 0) { if (w.uw_height > 0) sys_height = w.uw_height / w.uw_vs; @@ -879,7 +939,7 @@ static void scrsize(void) else if ((s = lgetenv("LINES")) != NULL) sc_height = atoi(s); #if !MSDOS_COMPILER - else if ((n = ltgetnum("li")) > 0) + else if ((n = ltgetnum("lines", "li")) > 0) sc_height = n; #endif if ((s = lgetenv("LESS_LINES")) != NULL) @@ -896,7 +956,7 @@ static void scrsize(void) else if ((s = lgetenv("COLUMNS")) != NULL) sc_width = atoi(s); #if !MSDOS_COMPILER - else if ((n = ltgetnum("co")) > 0) + else if ((n = ltgetnum("cols", "co")) > 0) sc_width = n; #endif if ((s = lgetenv("LESS_COLUMNS")) != NULL) @@ -914,6 +974,11 @@ static void scrsize(void) */ public void screen_size_changed(void) { + constant char *env = lgetenv("LESS_SHELL_LINES"); + shell_lines = isnullenv(env) ? 1 : atoi(env); + if (shell_lines >= sc_height) + shell_lines = sc_height - 1; + wscroll = (sc_height + 1) / 2; calc_jump_sline(); calc_shift_count(); calc_match_shift(); @@ -974,6 +1039,8 @@ public constant char * special_key_str(int key) static char k_left[] = { '\340', PCK_LEFT, 0 }; static char k_ctl_right[] = { '\340', PCK_CTL_RIGHT, 0 }; static char k_ctl_left[] = { '\340', PCK_CTL_LEFT, 0 }; + static char k_shift_right[] = { '\340', PCK_SHIFT_RIGHT, 0 }; + static char k_shift_left[] = { '\340', PCK_SHIFT_LEFT, 0 }; static char k_insert[] = { '\340', PCK_INSERT, 0 }; static char k_delete[] = { '\340', PCK_DELETE, 0 }; static char k_ctl_delete[] = { '\340', PCK_CTL_DELETE, 0 }; @@ -986,6 +1053,10 @@ public constant char * special_key_str(int key) static char k_backtab[] = { '\340', PCK_SHIFT_TAB, 0 }; static char k_pagedown[] = { '\340', PCK_PAGEDOWN, 0 }; static char k_pageup[] = { '\340', PCK_PAGEUP, 0 }; + static char k_ctl_home[] = { '\340', PCK_CTL_HOME, 0 }; + static char k_ctl_end[] = { '\340', PCK_CTL_END, 0 }; + static char k_shift_home[] = { '\340', PCK_SHIFT_HOME, 0 }; + static char k_shift_end[] = { '\340', PCK_SHIFT_END, 0 }; static char k_f1[] = { '\340', PCK_F1, 0 }; #endif #if !MSDOS_COMPILER @@ -1000,31 +1071,34 @@ public constant char * special_key_str(int key) * the XFree86 environment. */ case SK_RIGHT_ARROW: - s = windowid ? ltgetstr("kr", &sp) : k_right; + s = windowid ? ltgetstr("kcuf1", "kr", &sp) : k_right; break; case SK_LEFT_ARROW: - s = windowid ? ltgetstr("kl", &sp) : k_left; + s = windowid ? ltgetstr("kcub1", "kl", &sp) : k_left; break; case SK_UP_ARROW: - s = windowid ? ltgetstr("ku", &sp) : k_up; + s = windowid ? ltgetstr("kcuu1", "ku", &sp) : k_up; break; case SK_DOWN_ARROW: - s = windowid ? ltgetstr("kd", &sp) : k_down; + s = windowid ? ltgetstr("kcud1", "kd", &sp) : k_down; break; case SK_PAGE_UP: - s = windowid ? ltgetstr("kP", &sp) : k_pageup; + s = windowid ? ltgetstr("kpp", "kP", &sp) : k_pageup; break; case SK_PAGE_DOWN: - s = windowid ? ltgetstr("kN", &sp) : k_pagedown; + s = windowid ? ltgetstr("knp", "kN", &sp) : k_pagedown; break; case SK_HOME: - s = windowid ? ltgetstr("kh", &sp) : k_home; + s = windowid ? ltgetstr("khome", "kh", &sp) : k_home; break; case SK_END: - s = windowid ? ltgetstr("@7", &sp) : k_end; + s = windowid ? ltgetstr("kend", "@7", &sp) : k_end; + break; + case SK_F1: + s = windowid ? ltgetstr("kf1", "k1", &sp) : k_f1; break; case SK_DELETE: - s = windowid ? ltgetstr("kD", &sp) : k_delete; + s = windowid ? ltgetstr("kdch1", "kD", &sp) : k_delete; if (s == NULL) { tbuf[0] = '\177'; @@ -1072,6 +1146,12 @@ public constant char * special_key_str(int key) case SK_CTL_RIGHT_ARROW: s = k_ctl_right; break; + case SK_SHIFT_LEFT_ARROW: + s = k_shift_left; + break; + case SK_SHIFT_RIGHT_ARROW: + s = k_shift_right; + break; case SK_CTL_BACKSPACE: s = k_ctl_backspace; break; @@ -1087,33 +1167,126 @@ public constant char * special_key_str(int key) case SK_BACKTAB: s = k_backtab; break; + case SK_SHIFT_HOME: + s = k_shift_home; + break; + case SK_CTL_HOME: + s = k_ctl_home; + break; + case SK_SHIFT_END: + s = k_shift_end; + break; + case SK_CTL_END: + s = k_ctl_end; + break; #else case SK_RIGHT_ARROW: - s = ltgetstr("kr", &sp); + s = ltgetstr("kcuf1", "kr", &sp); break; case SK_LEFT_ARROW: - s = ltgetstr("kl", &sp); + s = ltgetstr("kcub1", "kl", &sp); break; case SK_UP_ARROW: - s = ltgetstr("ku", &sp); + s = ltgetstr("kcuu1", "ku", &sp); break; case SK_DOWN_ARROW: - s = ltgetstr("kd", &sp); + s = ltgetstr("kcud1", "kd", &sp); break; case SK_PAGE_UP: - s = ltgetstr("kP", &sp); + s = ltgetstr("kpp", "kP", &sp); break; case SK_PAGE_DOWN: - s = ltgetstr("kN", &sp); + s = ltgetstr("knp", "kN", &sp); break; case SK_HOME: - s = ltgetstr("kh", &sp); + s = ltgetstr("khome", "kh", &sp); + break; + case SK_SHIFT_HOME: + s = ltgetstr("kHOM", "#2", &sp); + break; + case SK_CTL_HOME: + s = ltgetstr("kHOM5", NULL, &sp); break; case SK_END: - s = ltgetstr("@7", &sp); + s = ltgetstr("kend", "@7", &sp); + break; + case SK_SHIFT_END: + s = ltgetstr("kEND", "#7", &sp); + break; + case SK_CTL_END: + s = ltgetstr("kEND5", NULL, &sp); + break; + case SK_INSERT: + s = ltgetstr("kich1", "kI", &sp); + break; + case SK_BACKTAB: + s = ltgetstr("kcbt", "kB", &sp); + break; + case SK_SHIFT_RIGHT_ARROW: + s = ltgetstr("kRIT", NULL, &sp); + break; + case SK_SHIFT_LEFT_ARROW: + s = ltgetstr("kLFT", NULL, &sp); + break; + case SK_CTL_RIGHT_ARROW: + s = ltgetstr("kRIT5", NULL, &sp); + break; + case SK_CTL_LEFT_ARROW: + s = ltgetstr("kLFT5", NULL, &sp); + break; + case SK_F1: + s = ltgetstr("kf1", "k1", &sp); + break; + case SK_PAD_UL: + s = ltgetstr("ka1", "K1", &sp); + break; + case SK_PAD_U: + s = ltgetstr("ka2", NULL, &sp); + break; + case SK_PAD_UR: + s = ltgetstr("ka3", "K3", &sp); + break; + case SK_PAD_L: + s = ltgetstr("kb1", NULL, &sp); + break; + case SK_PAD_CENTER: + s = ltgetstr("kb2", "K2", &sp); + break; + case SK_PAD_R: + s = ltgetstr("kb3", NULL, &sp); + break; + case SK_PAD_DL: + s = ltgetstr("kc1", "K4", &sp); + break; + case SK_PAD_D: + s = ltgetstr("kc2", NULL, &sp); + break; + case SK_PAD_DR: + s = ltgetstr("kc3", "K5", &sp); + break; + case SK_PAD_STAR: + s = ltgetstr("kpMUL", NULL, &sp); + break; + case SK_PAD_SLASH: + s = ltgetstr("kpDIV", NULL, &sp); + break; + case SK_PAD_DASH: + s = ltgetstr("kpSUB", NULL, &sp); + break; + case SK_PAD_PLUS: + s = ltgetstr("kpADD", NULL, &sp); + break; + case SK_PAD_DOT: + s = ltgetstr("kpDOT", NULL, &sp); + break; + case SK_PAD_COMMA: + s = ltgetstr("kpCMA", NULL, &sp); + break; + case SK_PAD_ZERO: + s = ltgetstr("kpZRO", NULL, &sp); break; case SK_DELETE: - s = ltgetstr("kD", &sp); + s = ltgetstr("kdch1", "kD", &sp); if (s == NULL) { tbuf[0] = '\177'; @@ -1122,7 +1295,7 @@ public constant char * special_key_str(int key) } break; case SK_BACKSPACE: - s = ltgetstr("kb", &sp); + s = ltgetstr("kbs", "kb", &sp); if (s == NULL) { tbuf[0] = '\b'; @@ -1139,9 +1312,22 @@ public constant char * special_key_str(int key) default: return (NULL); } + if (s != NULL && *s == '\0') + s = NULL; return (s); } +#if !MSDOS_COMPILER +static constant char *ltgoto(constant char *cap, int col, int line) +{ +#if USE_TERMINFO + return tparm(cap, line, col); +#else + return tgoto(cap, col, line); +#endif +} +#endif /* MSDOS_COMPILER */ + #if MSDOS_COMPILER public void init_win_colors(void) { @@ -1166,12 +1352,12 @@ public void init_win_colors(void) /* * Get terminal capabilities via termcap. */ -public void get_term(void) +public void get_term() { termcap_debug = !isnullenv(lgetenv("LESS_TERMCAP_DEBUG")); #if MSDOS_COMPILER auto_wrap = 1; - ignaw = 0; + defer_wrap = 0; can_goto_line = 1; clear_bg = 1; /* @@ -1220,15 +1406,17 @@ public void get_term(void) #else /* !MSDOS_COMPILER */ { - char *sp; constant char *t1; constant char *t2; constant char *term; + char *sp; /* * Some termcap libraries assume termbuf is static * (accessible after tgetent returns). */ +#if !USE_TERMINFO static char termbuf[TERMBUF_SIZE]; +#endif static char sbuf[TERMSBUF_SIZE]; #if OS2 @@ -1251,13 +1439,19 @@ public void get_term(void) /* * Find out what kind of terminal this is. */ - if ((term = lgetenv("TERM")) == NULL) + if ((term = lgetenv("TERM")) == NULL && (term = getenv("TERM")) == NULL) term = DEFAULT_TERM; hardcopy = 0; - /* {{ Should probably just pass NULL instead of termbuf. }} */ +#if USE_TERMINFO + if (cur_term != NULL) + del_curterm(cur_term); + if (setupterm(term, -1, NULL) != OK) + hardcopy = 1; +#else if (tgetent(termbuf, term) != TGETENT_OK) hardcopy = 1; - if (ltgetflag("hc")) +#endif + if (!hardcopy && ltgetflag("hc", "hc")) hardcopy = 1; /* @@ -1266,12 +1460,12 @@ public void get_term(void) scrsize(); pos_init(); - auto_wrap = ltgetflag("am"); - ignaw = ltgetflag("xn"); - above_mem = ltgetflag("da"); - below_mem = ltgetflag("db"); - clear_bg = ltgetflag("ut"); - no_alt_screen = ltgetflag("NR"); + auto_wrap = ltgetflag("am", "am"); + defer_wrap = ltgetflag("xenl", "xn"); + above_mem = ltgetflag("da", "da"); + below_mem = ltgetflag("db", "db"); + clear_bg = ltgetflag("bce", "ut"); + no_alt_screen = ltgetflag("nrrmc", "NR"); /* * Assumes termcap variable "sg" is the printing width of: @@ -1279,7 +1473,7 @@ public void get_term(void) * the underline sequence, the end underline sequence, * the boldface sequence, and the end boldface sequence. */ - if ((so_s_width = ltgetnum("sg")) < 0) + if ((so_s_width = ltgetnum("xmc", "sg")) < 0) so_s_width = 0; so_e_width = so_s_width; @@ -1305,70 +1499,70 @@ public void get_term(void) sp = sbuf; #if HAVE_OSPEED - sc_pad = ltgetstr("pc", &sp); + sc_pad = ltgetstr("pad", "pc", &sp); if (sc_pad != NULL) PC = *sc_pad; #endif - sc_s_keypad = ltgetstr("ks", &sp); + sc_s_keypad = ltgetstr("smkx", "ks", &sp); if (sc_s_keypad == NULL) sc_s_keypad = ""; - sc_e_keypad = ltgetstr("ke", &sp); + sc_e_keypad = ltgetstr("rmkx", "ke", &sp); if (sc_e_keypad == NULL) sc_e_keypad = ""; - kent = ltgetstr("@8", &sp); + kent = ltgetstr("kent", "@8", &sp); - sc_s_mousecap = ltgetstr("MOUSE_START", &sp); + sc_s_mousecap = ltgetstr("MOUSE_START", "MOUSE_START", &sp); if (sc_s_mousecap == NULL) sc_s_mousecap = ESCS "[?1000h" ESCS "[?1002h" ESCS "[?1006h"; - sc_e_mousecap = ltgetstr("MOUSE_END", &sp); + sc_e_mousecap = ltgetstr("MOUSE_END", "MOUSE_END", &sp); if (sc_e_mousecap == NULL) sc_e_mousecap = ESCS "[?1006l" ESCS "[?1002l" ESCS "[?1000l"; - sc_s_bracketed_paste = ltgetstr("BRACKETED_PASTE_START", &sp); + sc_s_bracketed_paste = ltgetstr("BRACKETED_PASTE_START", "BRACKETED_PASTE_START", &sp); if (sc_s_bracketed_paste == NULL) sc_s_bracketed_paste = ESCS"[?2004h"; - sc_e_bracketed_paste = ltgetstr("BRACKETED_PASTE_END", &sp); + sc_e_bracketed_paste = ltgetstr("BRACKETED_PASTE_END", "BRACKETED_PASTE_END", &sp); if (sc_e_bracketed_paste == NULL) sc_e_bracketed_paste = ESCS"[?2004l"; - sc_suspend = ltgetstr("SUSPEND", &sp); + sc_suspend = ltgetstr("SUSPEND", "SUSPEND", &sp); if (sc_suspend == NULL) sc_suspend = ""; - sc_resume = ltgetstr("RESUME", &sp); + sc_resume = ltgetstr("RESUME", "RESUME", &sp); if (sc_resume == NULL) sc_resume = ""; - sc_init = ltgetstr("ti", &sp); + sc_init = ltgetstr("smcup", "ti", &sp); if (sc_init == NULL) sc_init = ""; - sc_deinit= ltgetstr("te", &sp); + sc_deinit= ltgetstr("rmcup", "te", &sp); if (sc_deinit == NULL) sc_deinit = ""; - sc_eol_clear = ltgetstr("ce", &sp); + sc_eol_clear = ltgetstr("el", "ce", &sp); if (sc_eol_clear == NULL || *sc_eol_clear == '\0') { missing_cap = TRUE; sc_eol_clear = ""; } - sc_eos_clear = ltgetstr("cd", &sp); + sc_eos_clear = ltgetstr("ed", "cd", &sp); if (below_mem && (sc_eos_clear == NULL || *sc_eos_clear == '\0')) { missing_cap = TRUE; sc_eos_clear = ""; } - sc_clear = ltgetstr("cl", &sp); + sc_clear = ltgetstr("clear", "cl", &sp); if (sc_clear == NULL || *sc_clear == '\0') { missing_cap = TRUE; sc_clear = "\n\n"; } - sc_move = ltgetstr("cm", &sp); + sc_move = ltgetstr("cup", "cm", &sp); if (sc_move == NULL || *sc_move == '\0') { /* @@ -1381,20 +1575,20 @@ public void get_term(void) } else can_goto_line = 1; - tmodes("so", "se", &sc_s_in, &sc_s_out, "", "", &sp); - tmodes("us", "ue", &sc_u_in, &sc_u_out, sc_s_in, sc_s_out, &sp); - tmodes("md", "me", &sc_b_in, &sc_b_out, sc_s_in, sc_s_out, &sp); - tmodes("mb", "me", &sc_bl_in, &sc_bl_out, sc_s_in, sc_s_out, &sp); + tmodes("smso", "rmso", "so", "se", &sc_s_in, &sc_s_out, "", "", &sp); + tmodes("smul", "rmul", "us", "ue", &sc_u_in, &sc_u_out, sc_s_in, sc_s_out, &sp); + tmodes("bold", "sgr0", "md", "me", &sc_b_in, &sc_b_out, sc_s_in, sc_s_out, &sp); + tmodes("blink", "sgr0", "mb", "me", &sc_bl_in, &sc_bl_out, sc_s_in, sc_s_out, &sp); - sc_visual_bell = ltgetstr("vb", &sp); + sc_visual_bell = ltgetstr("flash", "vb", &sp); if (sc_visual_bell == NULL) sc_visual_bell = ""; - if (ltgetflag("bs")) + if (ltgetflag(NULL, "bs")) sc_backspace = "\b"; else { - sc_backspace = ltgetstr("bc", &sp); + sc_backspace = ltgetstr("OTbc", "bc", &sp); if (sc_backspace == NULL || *sc_backspace == '\0') sc_backspace = "\b"; } @@ -1403,14 +1597,14 @@ public void get_term(void) * Choose between using "ho" and "cm" ("home" and "cursor move") * to move the cursor to the upper left corner of the screen. */ - t1 = ltgetstr("ho", &sp); + t1 = ltgetstr("home", "ho", &sp); if (t1 == NULL) t1 = ""; if (*sc_move == '\0') t2 = ""; else { - strcpy(sp, tgoto(sc_move, 0, 0)); + strcpy(sp, ltgoto(sc_move, 0, 0)); t2 = sp; sp += strlen(sp) + 1; } @@ -1420,14 +1614,14 @@ public void get_term(void) * Choose between using "ll" and "cm" ("lower left" and "cursor move") * to move the cursor to the lower left corner of the screen. */ - t1 = ltgetstr("ll", &sp); + t1 = ltgetstr("ll", "ll", &sp); if (t1 == NULL || !full_screen) t1 = ""; if (*sc_move == '\0') t2 = ""; else { - strcpy(sp, tgoto(sc_move, 0, sc_height-1)); + strcpy(sp, ltgoto(sc_move, 0, sc_height-1)); t2 = sp; sp += strlen(sp) + 1; } @@ -1436,7 +1630,7 @@ public void get_term(void) /* * Get carriage return string. */ - sc_return = ltgetstr("cr", &sp); + sc_return = ltgetstr("cr", "cr", &sp); if (sc_return == NULL) sc_return = "\r"; @@ -1444,10 +1638,10 @@ public void get_term(void) * Choose between using "al" or "sr" ("add line" or "scroll reverse") * to add a line at the top of the screen. */ - t1 = ltgetstr("al", &sp); + t1 = ltgetstr("ill", "al", &sp); if (t1 == NULL) t1 = ""; - t2 = ltgetstr("sr", &sp); + t2 = ltgetstr("ri", "sr", &sp); if (t2 == NULL) t2 = ""; if (*t1 == '\0' && *t2 == '\0') @@ -1465,12 +1659,6 @@ public void get_term(void) } } #endif /* MSDOS_COMPILER */ - { - const char *env = lgetenv("LESS_SHELL_LINES"); - shell_lines = isnullenv(env) ? 1 : atoi(env); - if (shell_lines >= sc_height) - shell_lines = sc_height - 1; - } } #if !MSDOS_COMPILER @@ -1479,7 +1667,6 @@ public void get_term(void) * We use the trick of calling tputs, but as a char printing function * we give it inc_costcount, which just increments "costcount". * This tells us how many chars would be printed by using this string. - * {{ Couldn't we just use strlen? }} */ static int costcount; @@ -1518,9 +1705,9 @@ static constant char * cheaper(constant char *t1, constant char *t2, constant ch return (t2); } -static void tmodes(constant char *incap, constant char *outcap, constant char **instr, constant char **outstr, constant char *def_instr, constant char *def_outstr, char **spp) +static void tmodes(constant char *inti, constant char *outti, constant char *intc, constant char *outtc, constant char **instr, constant char **outstr, constant char *def_instr, constant char *def_outstr, char **spp) { - *instr = ltgetstr(incap, spp); + *instr = ltgetstr(inti, intc, spp); if (*instr == NULL) { /* Use defaults. */ @@ -1529,10 +1716,10 @@ static void tmodes(constant char *incap, constant char *outcap, constant char ** return; } - *outstr = ltgetstr(outcap, spp); + *outstr = ltgetstr(outti, outtc, spp); if (*outstr == NULL) /* No specific out capability; use "me". */ - *outstr = ltgetstr("me", spp); + *outstr = ltgetstr("sgr0", "me", spp); if (*outstr == NULL) /* Don't even have "me"; use a null string. */ *outstr = ""; @@ -1603,16 +1790,16 @@ static void initcolor(void) static void win32_init_vt_term(void) { if (vt_enabled == 0 || (vt_enabled == 1 && con_out == con_out_ours)) - return; // already initialized + return; /* already initialized */ /* don't care about the initial mode, and win VT hard-enables am+xn */ vt_enabled = SetConsoleMode(con_out, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING | - ENABLE_WRAP_AT_EOL_OUTPUT); + ENABLE_WRAP_AT_EOL_OUTPUT); if (vt_enabled) { auto_wrap = 1; - ignaw = 1; + defer_wrap = 1; } } @@ -1648,9 +1835,11 @@ static void win32_init_term(void) CONSOLE_TEXTMODE_BUFFER, (LPVOID) NULL); - // we don't care about the initial state. we need processed - // output without anything else (no wrap at EOL, no VT, - // no disabled auto-return). + /* + * We don't care about the initial state. We need processed + * output without anything else (no wrap at EOL, no VT, + * no disabled auto-return). + */ if (SetConsoleMode(con_out_ours, ENABLE_PROCESSED_OUTPUT)) auto_wrap = 0; } @@ -1696,7 +1885,6 @@ static void ltputs(constant char *str, int affcnt, int (*f_putc)(int)) { while (str != NULL && *str != '\0') { -#if HAVE_STRSTR constant char *obrac = strstr(str, "$<"); if (obrac != NULL) { @@ -1724,7 +1912,6 @@ static void ltputs(constant char *str, int affcnt, int (*f_putc)(int)) continue; } } -#endif /* Pass the rest of the string to tputs and we're done. */ do_tputs(str, affcnt, f_putc); break; @@ -1787,8 +1974,11 @@ public void resume_screen(void) /* * Initialize terminal */ -public void init(void) +public void term_init(void) { + if (term_init_done) + return; + term_init_done = term_init_ever = TRUE; clear_bot_if_needed(); #if !MSDOS_COMPILER if (!(quit_if_one_screen && one_screen)) @@ -1804,7 +1994,7 @@ public void init(void) */ if (*sc_init != '\0' && *sc_deinit != '\0' && !no_alt_screen) lower_left(); - term_init_done = 1; + term_addrs = TRUE; } if (!no_keypad) ltputs(sc_s_keypad, sc_height, putchr); @@ -1813,7 +2003,6 @@ public void init(void) if (no_paste) init_bracketed_paste(); } - init_done = 1; if (top_scroll) { int i; @@ -1835,7 +2024,7 @@ public void init(void) if (!no_init) { win32_init_term(); - term_init_done = 1; + term_addrs = TRUE; } if (mousecap) init_mouse(); @@ -1843,7 +2032,6 @@ public void init(void) } win32_init_vt_term(); #endif - init_done = 1; initcolor(); flush(); #endif @@ -1852,17 +2040,17 @@ public void init(void) /* * Deinitialize terminal */ -public void deinit(void) +public void term_deinit(void) { - if (!init_done) + if (!term_init_done) return; #if !MSDOS_COMPILER if (!(quit_if_one_screen && one_screen)) { if (mousecap) deinit_mouse(); - if (no_paste) - deinit_bracketed_paste(); + if (no_paste) + deinit_bracketed_paste(); if (!no_keypad) ltputs(sc_e_keypad, sc_height, putchr); if (!no_init) @@ -1885,21 +2073,19 @@ public void deinit(void) clreol(); #endif #endif - init_done = 0; + term_init_done = FALSE; } /* * Are we interactive (ie. writing to an initialized tty)? */ -public int interactive(void) +public lbool interactive(void) { - return (is_tty && init_done); + return (is_tty && term_init_done); } static void assert_interactive(void) { - if (interactive()) return; - /* abort(); */ } /* @@ -1998,7 +2184,7 @@ public void remove_top(int n) if (n >= sc_height - 1) { - clear(); + lclear(); home(); return; } @@ -2202,7 +2388,7 @@ public void check_winch(void) if (!no_init && con_out_ours == con_out) SetConsoleScreenBufferSize(con_out, size); pos_init(); - wscroll = (sc_height + 1) / 2; + screen_size_changed(); screen_trashed(); } #endif @@ -2215,7 +2401,7 @@ public void goto_line(int sindex) { assert_interactive(); #if !MSDOS_COMPILER - ltputs(tgoto(sc_move, 0, sindex), 1, putchr); + ltputs(ltgoto(sc_move, 0, sindex), 1, putchr); #else flush(); _settextposition(sindex+1, 1); @@ -2323,7 +2509,7 @@ public void vbell(void) #else #if MSDOS_COMPILER==WIN32C /* paint screen with an inverse color */ - clear(); + lclear(); /* leave it displayed for 100 msec. */ Sleep(100); @@ -2340,7 +2526,7 @@ public void vbell(void) /* * Make a noise. */ -static void beep(void) +static void lbeep(void) { #if !MSDOS_COMPILER putchr(CONTROL('G')); @@ -2356,18 +2542,18 @@ static void beep(void) /* * Ring the terminal bell. */ -public void bell(void) +public void lbell(void) { if (quiet == VERY_QUIET) vbell(); else - beep(); + lbeep(); } /* * Clear the screen. */ -public void clear(void) +public void lclear(void) { assert_interactive(); suspend_screen(); @@ -2495,14 +2681,14 @@ public void clear_bot(void) public void init_bracketed_paste(void) { #if !MSDOS_COMPILER - ltputs(sc_s_bracketed_paste, 1, putchr); + ltputs(sc_s_bracketed_paste, 1, putchr); #endif } public void deinit_bracketed_paste(void) { #if !MSDOS_COMPILER - ltputs(sc_e_bracketed_paste, 1, putchr); + ltputs(sc_e_bracketed_paste, 1, putchr); #endif } @@ -2952,7 +3138,7 @@ typedef struct XINPUT_RECORD { typedef struct WIN32_CHAR { struct WIN32_CHAR *wc_next; - char wc_ch; + int wc_ch; } WIN32_CHAR; static WIN32_CHAR *win32_queue = NULL; @@ -2960,7 +3146,7 @@ static WIN32_CHAR *win32_queue = NULL; /* * Is the win32_queue nonempty? */ -static int win32_queued_char(void) +static lbool win32_queued_char(void) { return (win32_queue != NULL); } @@ -2968,7 +3154,7 @@ static int win32_queued_char(void) /* * Push a char onto the back of the win32_queue. */ -static void win32_enqueue(char ch) +static void win32_enqueue(int ch) { WIN32_CHAR *wch = (WIN32_CHAR *) ecalloc(1, sizeof(WIN32_CHAR)); wch->wc_ch = ch; @@ -2999,10 +3185,10 @@ public void WIN32ungetch(int ch) /* * Get a char from the front of the win32_queue. */ -static char win32_get_queue(void) +static int win32_get_queue(void) { WIN32_CHAR *wch = win32_queue; - char ch = wch->wc_ch; + int ch = wch->wc_ch; win32_queue = wch->wc_next; free(wch); return ch; @@ -3126,11 +3312,35 @@ static lbool win32_scan_code(XINPUT_RECORD *xip) case PCK_DELETE: /* delete */ scan = PCK_CTL_DELETE; break; + case PCK_HOME: + scan = PCK_CTL_HOME; + break; + case PCK_END: + scan = PCK_CTL_END; + break; } } else if (xip->ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) { if (xip->ichar == '\t') scan = PCK_SHIFT_TAB; + else + { + switch (xip->ir.Event.KeyEvent.wVirtualScanCode) + { + case PCK_RIGHT: + scan = PCK_SHIFT_RIGHT; + break; + case PCK_LEFT: + scan = PCK_SHIFT_LEFT; + break; + case PCK_HOME: + scan = PCK_SHIFT_HOME; + break; + case PCK_END: + scan = PCK_SHIFT_END; + break; + } + } } if (scan < 0 && xip->ichar == 0) scan = xip->ir.Event.KeyEvent.wVirtualScanCode; @@ -3182,12 +3392,23 @@ static lbool win32_key_event(XINPUT_RECORD *xip) { constant char *p; for (p = utf8; p < up; ++p) - win32_enqueue(*p); + win32_enqueue(*p & 0xFF); } return (TRUE); } /* + * Handle a window input event. + */ +static lbool win32_window_event(XINPUT_RECORD *xip) +{ + if (xip->ir.EventType != WINDOW_BUFFER_SIZE_EVENT) + return (FALSE); + win32_enqueue(READ_AGAIN); + return (TRUE); +} + +/* * Determine whether an input character is waiting to be read. */ public lbool win32_kbhit2(lbool no_queued) @@ -3213,7 +3434,7 @@ public lbool win32_kbhit2(lbool no_queued) ReadConsoleInputW(tty, &xip.ir, 1, &nread); if (nread == 0) return (FALSE); - if (win32_mouse_event(&xip) || win32_key_event(&xip)) + if (win32_mouse_event(&xip) || win32_key_event(&xip) || win32_window_event(&xip)) break; } return (TRUE); @@ -3227,7 +3448,7 @@ public lbool win32_kbhit(void) /* * Read a character from the keyboard. */ -public char WIN32getch(void) +public int WIN32getch(void) { while (!win32_kbhit()) { |
