diff --git a/CHANGES b/CHANGES index 9ad3dd95..891e2dcf 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,12 @@ 09 January 2009 +* Stop using ncurses variables and instead build a table of the codes we want + into an array for each terminal type. This makes the code a little more + untidy in places but gets rid of the awful global variables and calling + setterm all the time, and shoves all the ncurses-dependent mess into a single + file, tty-term.c. It also allows overriding single terminal codes, this is + used to fix rxvt on some platforms (where it is missing dch) and in future + may allow user customisation a la vim. * Update key handling code. Simplify, support ctrl properly and add a new window option (xterm-keys) to output xterm key codes including ctrl and, if available, alt and shift. @@ -826,7 +833,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.184 2009-01-09 16:45:58 nicm Exp $ +$Id: CHANGES,v 1.185 2009-01-09 23:57:42 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB diff --git a/Makefile b/Makefile index 96f9f633..9efda487 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.81 2008-12-15 21:21:56 nicm Exp $ +# $Id: Makefile,v 1.82 2009-01-09 23:57:42 nicm Exp $ .SUFFIXES: .c .o .y .h .PHONY: clean update-index.html upload-index.html @@ -37,7 +37,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \ cmd-respawn-window.c cmd-source-file.c \ window-scroll.c window-more.c window-copy.c options.c paste.c \ - tty.c tty-keys.c tty-write.c colour.c utf8.c options-cmd.c + tty.c tty-term.c tty-keys.c tty-write.c colour.c utf8.c options-cmd.c CC?= cc INCDIRS+= -I. -I- -I/usr/local/include diff --git a/TODO b/TODO index 53c7c1ed..2e9ae074 100644 --- a/TODO +++ b/TODO @@ -59,3 +59,5 @@ - input.c is too complicated. simplify? - try change from pass-though model to redraw model (use updated screen data). maybe too slow though? +- use a better termcap internally instead of screen, perhaps xterm +- tty.c is a bit ugly diff --git a/key-string.c b/key-string.c index 56c69e98..9a15144a 100644 --- a/key-string.c +++ b/key-string.c @@ -1,4 +1,4 @@ -/* $Id: key-string.c,v 1.11 2009-01-09 16:45:58 nicm Exp $ */ +/* $Id: key-string.c,v 1.12 2009-01-09 23:57:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -88,7 +88,6 @@ key_string_search_table(const char *string) int key_string_lookup_string(const char *string) { - u_int i; int key; if (string[0] == '\0') diff --git a/screen-redraw.c b/screen-redraw.c index 4f6286f5..7b3a8ec0 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -1,4 +1,4 @@ -/* $Id: screen-redraw.c,v 1.14 2008-12-08 16:19:51 nicm Exp $ */ +/* $Id: screen-redraw.c,v 1.15 2009-01-09 23:57:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -52,7 +52,7 @@ screen_redraw_start_session(struct screen_redraw_ctx *ctx, struct session *s) /* Initialise for redrawing. */ void screen_redraw_start(struct screen_redraw_ctx *ctx, - struct screen *s, void (*write)(void *, int, ...), void *data) + struct screen *s, void (*write)(void *, enum tty_cmd, ...), void *data) { ctx->write = write; ctx->data = data; diff --git a/screen-write.c b/screen-write.c index a84141ec..7c2fda4d 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1,4 +1,4 @@ -/* $Id: screen-write.c,v 1.21 2009-01-08 21:55:12 nicm Exp $ */ +/* $Id: screen-write.c,v 1.22 2009-01-09 23:57:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -52,7 +52,7 @@ screen_write_start_session(struct screen_write_ctx *ctx, struct session *s) /* Initialise writing. */ void screen_write_start(struct screen_write_ctx *ctx, - struct screen *s, void (*write)(void *, int, ...), void *data) + struct screen *s, void (*write)(void *, enum tty_cmd, ...), void *data) { ctx->write = write; ctx->data = data; diff --git a/tmux.c b/tmux.c index f83fdb2f..ac5a5b89 100644 --- a/tmux.c +++ b/tmux.c @@ -1,4 +1,4 @@ -/* $Id: tmux.c,v 1.85 2009-01-09 16:45:58 nicm Exp $ */ +/* $Id: tmux.c,v 1.86 2009-01-09 23:57:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -52,6 +52,7 @@ struct options global_window_options; int debug_level; int be_quiet; +time_t start_time; void sighandler(int); __dead void usage(void); diff --git a/tmux.h b/tmux.h index 6be25ab9..fb6f26ee 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.211 2009-01-09 16:45:58 nicm Exp $ */ +/* $Id: tmux.h,v 1.212 2009-01-09 23:57:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -19,7 +19,7 @@ #ifndef TMUX_H #define TMUX_H -#define PROTOCOL_VERSION -3 +#define PROTOCOL_VERSION -4 /* Shut up gcc warnings about empty if bodies. */ #define RB_AUGMENT(x) do {} while (0) @@ -52,13 +52,12 @@ #include "compat/getopt.h" #endif -#include #include #include #include #include #include -#include +#include #include "array.h" @@ -221,33 +220,133 @@ struct buffer { #define KEYC_KP4_0 (KEYC_OFFSET + 0x10e) #define KEYC_KP4_2 (KEYC_OFFSET + 0x10f) -/* Output codes. */ -#define TTY_CURSORUP 0 -#define TTY_CURSORDOWN 1 -#define TTY_CURSORRIGHT 2 -#define TTY_CURSORLEFT 3 -#define TTY_INSERTCHARACTER 4 -#define TTY_DELETECHARACTER 5 -#define TTY_INSERTLINE 6 -#define TTY_DELETELINE 7 -#define TTY_CLEARLINE 8 -#define TTY_CLEARENDOFLINE 9 -#define TTY_CLEARSTARTOFLINE 10 -#define TTY_CURSORMOVE 11 -#define TTY_CURSORMODE 12 -#define TTY_REVERSEINDEX 13 -#define TTY_SCROLLREGION 14 -#define TTY_INSERTMODE 15 -#define TTY_MOUSEMODE 16 -#define TTY_LINEFEED 17 -#define TTY_CARRIAGERETURN 18 -#define TTY_BELL 19 -#define TTY_KCURSORMODE 20 -#define TTY_KKEYPADMODE 21 -#define TTY_CLEARENDOFSCREEN 22 -#define TTY_CLEARSTARTOFSCREEN 23 -#define TTY_CLEARSCREEN 24 -#define TTY_CELL 25 +/* Termcap codes. */ +enum tty_code_code { + TTYC_AX = 0, + TTYC_ACSC, /* acs_chars, ac */ + TTYC_BEL, /* bell, bl */ + TTYC_BLINK, /* enter_blink_mode, mb */ + TTYC_BOLD, /* enter_bold_mode, md */ + TTYC_CIVIS, /* cursor_invisible, vi */ + TTYC_CLEAR, /* clear_screen, cl */ + TTYC_CNORM, /* cursor_normal, ve */ + TTYC_COLORS, /* max_colors, Co */ + TTYC_CR, /* carriage_return, cr */ + TTYC_CSR, /* change_scroll_region, cs */ + TTYC_CUB, /* parm_left_cursor, LE */ + TTYC_CUB1, /* cursor_left, le */ + TTYC_CUD, /* parm_down_cursor, DO */ + TTYC_CUD1, /* cursor_down, do */ + TTYC_CUF, /* parm_right_cursor, RI */ + TTYC_CUF1, /* cursor_right, nd */ + TTYC_CUP, /* cursor_address, cm */ + TTYC_CUU, /* parm_up_cursor, UP */ + TTYC_CUU1, /* cursor_up, up */ + TTYC_DCH, /* parm_dch, DC */ + TTYC_DCH1, /* delete_character, dc */ + TTYC_DIM, /* enter_dim_mode, mh */ + TTYC_DL, /* parm_delete_line, DL */ + TTYC_DL1, /* delete_line, dl */ + TTYC_ED, /* clr_eos, cd */ + TTYC_EL, /* clr_eol, ce */ + TTYC_EL1, /* clr_bol, cb */ + TTYC_ENACS, /* ena_acs, eA */ + TTYC_ICH, /* parm_ich, IC */ + TTYC_ICH1, /* insert_character, ic */ + TTYC_IL, /* parm_insert_line, IL */ + TTYC_IL1, /* insert_line, il */ + TTYC_INVIS, /* enter_secure_mode, mk */ + TTYC_IS1, /* init_1string, i1 */ + TTYC_IS2, /* init_2string, i2 */ + TTYC_IS3, /* init_3string, i3 */ + TTYC_KCUB1, /* key_left, kl */ + TTYC_KCUD1, /* key_down, kd */ + TTYC_KCUF1, /* key_right, kr */ + TTYC_KCUU1, /* key_up, ku */ + TTYC_KDCH1, /* key_dc, kD */ + TTYC_KEND, /* key_end, ke */ + TTYC_KF1, /* key_f1, k1 */ + TTYC_KF10, /* key_f10, k; */ + TTYC_KF11, /* key_f11, F1 */ + TTYC_KF12, /* key_f12, 21 */ + TTYC_KF2, /* key_f2, k2 */ + TTYC_KF3, /* key_f3, k3 */ + TTYC_KF4, /* key_f4, k4 */ + TTYC_KF5, /* key_f5, k5 */ + TTYC_KF6, /* key_f6, k6 */ + TTYC_KF7, /* key_f7, k7 */ + TTYC_KF8, /* key_f8, k8 */ + TTYC_KF9, /* key_f9, k9 */ + TTYC_KHOME, /* key_home, kh */ + TTYC_KICH1, /* key_ic, kI */ + TTYC_KMOUS, /* key_mouse, Km */ + TTYC_KNP, /* key_npage, kN */ + TTYC_KPP, /* key_ppage, kP */ + TTYC_OP, /* orig_pair, op */ + TTYC_REV, /* enter_reverse_mode, mr */ + TTYC_RI, /* scroll_reverse, sr */ + TTYC_RMACS, /* exit_alt_charset_mode */ + TTYC_RMCUP, /* exit_ca_mode, te */ + TTYC_RMKX, /* keypad_local, ke */ + TTYC_SETAB, /* set_a_background, AB */ + TTYC_SETAF, /* set_a_foreground, AF */ + TTYC_SGR0, /* exit_attribute_mode, me */ + TTYC_SMACS, /* enter_alt_charset_mode, as */ + TTYC_SMCUP, /* enter_ca_mode, ti */ + TTYC_SMKX, /* keypad_xmit, ks */ + TTYC_SMSO, /* enter_standout_mode, so */ + TTYC_SMUL, /* enter_underline_mode, us */ + + NTTYCODE +}; + +/* Termcap types. */ +enum tty_code_type { + TTYCODE_NONE = 0, + TTYCODE_STRING, + TTYCODE_NUMBER, + TTYCODE_FLAG, +}; + +/* Termcap code. */ +struct tty_code { + enum tty_code_type type; + union { + char *string; + int number; + int flag; + } value; +}; + +/* Output commands. */ +enum tty_cmd { + TTY_BELL, + TTY_CARRIAGERETURN, + TTY_CELL, + TTY_CLEARENDOFLINE, + TTY_CLEARENDOFSCREEN, + TTY_CLEARLINE, + TTY_CLEARSCREEN, + TTY_CLEARSTARTOFLINE, + TTY_CLEARSTARTOFSCREEN, + TTY_CURSORDOWN, + TTY_CURSORLEFT, + TTY_CURSORMODE, + TTY_CURSORMOVE, + TTY_CURSORRIGHT, + TTY_CURSORUP, + TTY_DELETECHARACTER, + TTY_DELETELINE, + TTY_INSERTCHARACTER, + TTY_INSERTLINE, + TTY_INSERTMODE, + TTY_KCURSORMODE, + TTY_KKEYPADMODE, + TTY_LINEFEED, + TTY_MOUSEMODE, + TTY_REVERSEINDEX, + TTY_SCROLLREGION, +}; /* Message codes. */ enum hdrtype { @@ -405,7 +504,7 @@ struct screen { /* Screen redraw context. */ struct screen_redraw_ctx { void *data; - void (*write)(void *, int, ...); + void (*write)(void *, enum tty_cmd, ...); u_int saved_cx; u_int saved_cy; @@ -416,7 +515,7 @@ struct screen_redraw_ctx { /* Screen write context. */ struct screen_write_ctx { void *data; - void (*write)(void *, int, ...); + void (*write)(void *, enum tty_cmd, ...); struct screen *s; }; @@ -557,7 +656,7 @@ ARRAY_DECL(sessions, struct session *); /* TTY information. */ struct tty_key { - int code; + int key; char *string; int flags; @@ -569,9 +668,10 @@ struct tty_key { struct tty_term { char *name; - TERMINAL *term; u_int references; + struct tty_code codes[NTTYCODE]; + #define TERM_HASDEFAULTS 0x1 #define TERM_256COLOURS 0x2 int flags; @@ -824,6 +924,7 @@ extern struct options global_window_options; extern char *cfg_file; extern int debug_level; extern int be_quiet; +extern time_t start_time; void logfile(const char *); void siginit(void); void sigreset(void); @@ -854,8 +955,20 @@ void tty_set_title(struct tty *, const char *); int tty_open(struct tty *, char **); void tty_close(struct tty *); void tty_free(struct tty *); -void tty_write(struct tty *, struct screen *, int, ...); -void tty_vwrite(struct tty *, struct screen *s, int, va_list); +void tty_write(struct tty *, struct screen *, enum tty_cmd, ...); +void tty_vwrite( + struct tty *, struct screen *s, enum tty_cmd, va_list); + +/* tty-term.c */ +struct tty_term *tty_term_find(char *, int,char **); +void tty_term_free(struct tty_term *); +int tty_term_has(struct tty_term *, enum tty_code_code); +const char *tty_term_string(struct tty_term *, enum tty_code_code); +const char *tty_term_string1(struct tty_term *, enum tty_code_code, int); +const char *tty_term_string2( + struct tty_term *, enum tty_code_code, int, int); +int tty_term_number(struct tty_term *, enum tty_code_code); +int tty_term_flag(struct tty_term *, enum tty_code_code); /* tty-keys.c */ int tty_keys_cmp(struct tty_key *, struct tty_key *); @@ -865,12 +978,12 @@ void tty_keys_free(struct tty *); int tty_keys_next(struct tty *, int *); /* tty-write.c */ -void tty_write_client(void *, int, ...); -void tty_vwrite_client(void *, int, va_list); -void tty_write_window(void *, int, ...); -void tty_vwrite_window(void *, int, va_list); -void tty_write_session(void *, int, ...); -void tty_vwrite_session(void *, int, va_list); +void tty_write_client(void *, enum tty_cmd, ...); +void tty_vwrite_client(void *, enum tty_cmd, va_list); +void tty_write_window(void *, enum tty_cmd, ...); +void tty_vwrite_window(void *, enum tty_cmd, va_list); +void tty_write_session(void *, enum tty_cmd, ...); +void tty_vwrite_session(void *, enum tty_cmd, va_list); /* options-cmd.c */ void set_option_string(struct cmd_ctx *, @@ -1135,7 +1248,7 @@ void screen_write_start_client(struct screen_write_ctx *, struct client *); void screen_write_start_session( struct screen_write_ctx *, struct session *); void screen_write_start(struct screen_write_ctx *, - struct screen *, void (*)(void *, int, ...), void *); + struct screen *, void (*)(void *, enum tty_cmd, ...), void *); void screen_write_stop(struct screen_write_ctx *); void printflike3 screen_write_puts( struct screen_write_ctx *, struct grid_cell *, const char *, ...); @@ -1175,7 +1288,7 @@ void screen_redraw_start_client(struct screen_redraw_ctx *, struct client *); void screen_redraw_start_session( struct screen_redraw_ctx *, struct session *); void screen_redraw_start(struct screen_redraw_ctx *, - struct screen *, void (*)(void *, int, ...), void *); + struct screen *, void (*)(void *, enum tty_cmd, ...), void *); void screen_redraw_stop(struct screen_redraw_ctx *); void printflike3 screen_redraw_puts( struct screen_redraw_ctx *, struct grid_cell *, const char *, ...); diff --git a/tty-keys.c b/tty-keys.c index b0d85c6e..00d48579 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -1,4 +1,4 @@ -/* $Id: tty-keys.c,v 1.15 2009-01-09 16:47:06 nicm Exp $ */ +/* $Id: tty-keys.c,v 1.16 2009-01-09 23:57:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -26,46 +26,47 @@ void tty_keys_add(struct tty *, const char *, int, int); struct tty_key_ent { - const char *name; - int code; + enum tty_code_code code; + const char *string; - int flags; + int key; + int flags; }; struct tty_key_ent tty_keys[] = { /* Function keys. */ - { "kf1", KEYC_F1, TTYKEY_MODIFIER }, - { "kf2", KEYC_F2, TTYKEY_MODIFIER }, - { "kf3", KEYC_F3, TTYKEY_MODIFIER }, - { "kf4", KEYC_F4, TTYKEY_MODIFIER }, - { "kf5", KEYC_F5, TTYKEY_MODIFIER }, - { "kf6", KEYC_F6, TTYKEY_MODIFIER }, - { "kf7", KEYC_F7, TTYKEY_MODIFIER }, - { "kf8", KEYC_F8, TTYKEY_MODIFIER }, - { "kf9", KEYC_F9, TTYKEY_MODIFIER }, - { "kf10", KEYC_F10, TTYKEY_MODIFIER }, - { "kf11", KEYC_F11, TTYKEY_MODIFIER }, - { "kf12", KEYC_F12, TTYKEY_MODIFIER }, - { "kich1", KEYC_IC, TTYKEY_MODIFIER }, - { "kdch1", KEYC_DC, TTYKEY_MODIFIER }, - { "khome", KEYC_HOME, TTYKEY_MODIFIER }, - { "kend", KEYC_END, TTYKEY_MODIFIER }, - { "knp", KEYC_NPAGE, TTYKEY_MODIFIER }, - { "kpp", KEYC_PPAGE, TTYKEY_MODIFIER }, + { TTYC_KF1, NULL, KEYC_F1, TTYKEY_MODIFIER }, + { TTYC_KF2, NULL, KEYC_F2, TTYKEY_MODIFIER }, + { TTYC_KF3, NULL, KEYC_F3, TTYKEY_MODIFIER }, + { TTYC_KF4, NULL, KEYC_F4, TTYKEY_MODIFIER }, + { TTYC_KF5, NULL, KEYC_F5, TTYKEY_MODIFIER }, + { TTYC_KF6, NULL, KEYC_F6, TTYKEY_MODIFIER }, + { TTYC_KF7, NULL, KEYC_F7, TTYKEY_MODIFIER }, + { TTYC_KF8, NULL, KEYC_F8, TTYKEY_MODIFIER }, + { TTYC_KF9, NULL, KEYC_F9, TTYKEY_MODIFIER }, + { TTYC_KF10, NULL, KEYC_F10, TTYKEY_MODIFIER }, + { TTYC_KF11, NULL, KEYC_F11, TTYKEY_MODIFIER }, + { TTYC_KF12, NULL, KEYC_F12, TTYKEY_MODIFIER }, + { TTYC_KICH1, NULL, KEYC_IC, TTYKEY_MODIFIER }, + { TTYC_KDCH1, NULL, KEYC_DC, TTYKEY_MODIFIER }, + { TTYC_KHOME, NULL, KEYC_HOME, TTYKEY_MODIFIER }, + { TTYC_KEND, NULL, KEYC_END, TTYKEY_MODIFIER }, + { TTYC_KNP, NULL, KEYC_NPAGE, TTYKEY_MODIFIER }, + { TTYC_KPP, NULL, KEYC_PPAGE, TTYKEY_MODIFIER }, - /* Arrow keys. */ - { "kcuu1", KEYC_UP, TTYKEY_MODIFIER }, - { "kcud1", KEYC_DOWN, TTYKEY_MODIFIER }, - { "kcub1", KEYC_LEFT, TTYKEY_MODIFIER }, - { "kcuf1", KEYC_RIGHT, TTYKEY_MODIFIER }, - { "\033OA",KEYC_UP, TTYKEY_RAW|TTYKEY_MODIFIER }, - { "\033OB",KEYC_DOWN, TTYKEY_RAW|TTYKEY_MODIFIER }, - { "\033OD",KEYC_LEFT, TTYKEY_RAW|TTYKEY_MODIFIER }, - { "\033OC",KEYC_RIGHT, TTYKEY_RAW|TTYKEY_MODIFIER }, - { "\033[A",KEYC_UP, TTYKEY_RAW|TTYKEY_MODIFIER }, - { "\033[B",KEYC_DOWN, TTYKEY_RAW|TTYKEY_MODIFIER }, - { "\033[D",KEYC_LEFT, TTYKEY_RAW|TTYKEY_MODIFIER }, - { "\033[C",KEYC_RIGHT, TTYKEY_RAW|TTYKEY_MODIFIER }, + /* Arrow keys. */ + { TTYC_KCUU1, NULL, KEYC_UP, TTYKEY_MODIFIER }, + { TTYC_KCUD1, NULL, KEYC_DOWN, TTYKEY_MODIFIER }, + { TTYC_KCUB1, NULL, KEYC_LEFT, TTYKEY_MODIFIER }, + { TTYC_KCUF1, NULL, KEYC_RIGHT, TTYKEY_MODIFIER }, + { 0, "\033OA", KEYC_UP, TTYKEY_RAW|TTYKEY_MODIFIER }, + { 0, "\033OB", KEYC_DOWN, TTYKEY_RAW|TTYKEY_MODIFIER }, + { 0, "\033OD", KEYC_LEFT, TTYKEY_RAW|TTYKEY_MODIFIER }, + { 0, "\033OC", KEYC_RIGHT, TTYKEY_RAW|TTYKEY_MODIFIER }, + { 0, "\033[A", KEYC_UP, TTYKEY_RAW|TTYKEY_MODIFIER }, + { 0, "\033[B", KEYC_DOWN, TTYKEY_RAW|TTYKEY_MODIFIER }, + { 0, "\033[D", KEYC_LEFT, TTYKEY_RAW|TTYKEY_MODIFIER }, + { 0, "\033[C", KEYC_RIGHT, TTYKEY_RAW|TTYKEY_MODIFIER }, /* * Numeric keypad. termcap and terminfo are totally confusing for this. @@ -77,22 +78,22 @@ struct tty_key_ent tty_keys[] = { * mode. Translation of numbers mode/applications mode is done in * input-keys.c. */ - { "\033Oo", KEYC_KP0_1, TTYKEY_RAW }, - { "\033Oj", KEYC_KP0_2, TTYKEY_RAW }, - { "\033Om", KEYC_KP0_3, TTYKEY_RAW }, - { "\033Ow", KEYC_KP1_0, TTYKEY_RAW }, - { "\033Ox", KEYC_KP1_1, TTYKEY_RAW }, - { "\033Oy", KEYC_KP1_2, TTYKEY_RAW }, - { "\033Ok", KEYC_KP1_3, TTYKEY_RAW }, - { "\033Ot", KEYC_KP2_0, TTYKEY_RAW }, - { "\033Ou", KEYC_KP2_1, TTYKEY_RAW }, - { "\033Ov", KEYC_KP2_2, TTYKEY_RAW }, - { "\033Oq", KEYC_KP3_0, TTYKEY_RAW }, - { "\033Or", KEYC_KP3_1, TTYKEY_RAW }, - { "\033Os", KEYC_KP3_2, TTYKEY_RAW }, - { "\033OM", KEYC_KP3_3, TTYKEY_RAW }, - { "\033Op", KEYC_KP4_0, TTYKEY_RAW }, - { "\033On", KEYC_KP4_2, TTYKEY_RAW }, + { 0, "\033Oo", KEYC_KP0_1, TTYKEY_RAW }, + { 0, "\033Oj", KEYC_KP0_2, TTYKEY_RAW }, + { 0, "\033Om", KEYC_KP0_3, TTYKEY_RAW }, + { 0, "\033Ow", KEYC_KP1_0, TTYKEY_RAW }, + { 0, "\033Ox", KEYC_KP1_1, TTYKEY_RAW }, + { 0, "\033Oy", KEYC_KP1_2, TTYKEY_RAW }, + { 0, "\033Ok", KEYC_KP1_3, TTYKEY_RAW }, + { 0, "\033Ot", KEYC_KP2_0, TTYKEY_RAW }, + { 0, "\033Ou", KEYC_KP2_1, TTYKEY_RAW }, + { 0, "\033Ov", KEYC_KP2_2, TTYKEY_RAW }, + { 0, "\033Oq", KEYC_KP3_0, TTYKEY_RAW }, + { 0, "\033Or", KEYC_KP3_1, TTYKEY_RAW }, + { 0, "\033Os", KEYC_KP3_2, TTYKEY_RAW }, + { 0, "\033OM", KEYC_KP3_3, TTYKEY_RAW }, + { 0, "\033Op", KEYC_KP4_0, TTYKEY_RAW }, + { 0, "\033On", KEYC_KP4_2, TTYKEY_RAW }, }; RB_GENERATE(tty_keys, tty_key, entry, tty_keys_cmp); @@ -106,21 +107,20 @@ tty_keys_cmp(struct tty_key *k1, struct tty_key *k2) } void -tty_keys_add(struct tty *tty, const char *s, int code, int flags) +tty_keys_add(struct tty *tty, const char *s, int key, int flags) { struct tty_key *tk; tk = xmalloc(sizeof *tk); tk->string = xstrdup(s); - tk->code = code; + tk->key = key; tk->flags = flags; if (strlen(tk->string) > tty->ksize) tty->ksize = strlen(tk->string); RB_INSERT(tty_keys, &tty->ktree, tk); - log_debug( - "new key %x: size now %zu (%s)", code, tty->ksize, tk->string); + log_debug("new key %x: size now %zu (%s)", key, tty->ksize, tk->string); } void @@ -138,21 +138,21 @@ tty_keys_init(struct tty *tty) tke = &tty_keys[i]; if (tke->flags & TTYKEY_RAW) - s = tke->name; + s = tke->string; else { - s = tigetstr(tke->name); - if (s == (char *) -1 || s == (char *) 0) + if (!tty_term_has(tty->term, tke->code)) continue; + s = tty_term_string(tty->term, tke->code); if (s[0] != '\033' || s[1] == '\0') continue; } - tty_keys_add(tty, s + 1, tke->code, tke->flags); + tty_keys_add(tty, s + 1, tke->key, tke->flags); if (tke->flags & TTYKEY_MODIFIER) { if (strlcpy(tmp, s, sizeof tmp) >= sizeof tmp) continue; tmp[strlen(tmp) - 1] ^= 0x20; - tty_keys_add(tty, tmp + 1, KEYC_ADDCTL(tke->code), 0); + tty_keys_add(tty, tmp + 1, KEYC_ADDCTL(tke->key), 0); } } } @@ -201,7 +201,7 @@ tty_keys_find(struct tty *tty, char *buf, size_t len, size_t *size) } int -tty_keys_next(struct tty *tty, int *code) +tty_keys_next(struct tty *tty, int *key) { struct tty_key *tk; struct timeval tv; @@ -216,14 +216,14 @@ tty_keys_next(struct tty *tty, int *code) /* If a normal key, return it. */ if (*buf != '\033') { - *code = buffer_read8(tty->in); + *key = buffer_read8(tty->in); return (0); } /* Look for matching key string and return if found. */ tk = tty_keys_find(tty, buf + 1, len - 1, &size); if (tk != NULL) { - *code = tk->code; + *key = tk->key; buffer_remove(tty->in, size + 1); tty->flags &= ~TTY_ESCAPE; @@ -239,35 +239,35 @@ tty_keys_next(struct tty *tty, int *code) tk = tty_keys_find(tty, tmp + 1, len - 3, &size); if (tk != NULL) { - *code = tk->code; + *key = tk->key; buffer_remove(tty->in, size + 3); switch (arg) { case '8': - *code = KEYC_ADDSFT(*code); - *code = KEYC_ADDESC(*code); - *code = KEYC_ADDCTL(*code); + *key = KEYC_ADDSFT(*key); + *key = KEYC_ADDESC(*key); + *key = KEYC_ADDCTL(*key); break; case '7': - *code = KEYC_ADDESC(*code); - *code = KEYC_ADDCTL(*code); + *key = KEYC_ADDESC(*key); + *key = KEYC_ADDCTL(*key); break; case '6': - *code = KEYC_ADDSFT(*code); - *code = KEYC_ADDCTL(*code); + *key = KEYC_ADDSFT(*key); + *key = KEYC_ADDCTL(*key); break; case '5': - *code = KEYC_ADDCTL(*code); + *key = KEYC_ADDCTL(*key); break; case '4': - *code = KEYC_ADDSFT(*code); - *code = KEYC_ADDESC(*code); + *key = KEYC_ADDSFT(*key); + *key = KEYC_ADDESC(*key); break; case '3': - *code = KEYC_ADDESC(*code); + *key = KEYC_ADDESC(*key); break; case '2': - *code = KEYC_ADDSFT(*code); + *key = KEYC_ADDSFT(*key); break; } @@ -302,26 +302,26 @@ tty_keys_next(struct tty *tty, int *code) /* If we have no following data, return escape. */ if (len == 0) { - *code = '\033'; + *key = '\033'; return (0); } /* If a normal key follows, return it. */ if (*buf != '\033') { - *code = KEYC_ADDESC(buffer_read8(tty->in)); + *key = KEYC_ADDESC(buffer_read8(tty->in)); return (0); } /* Try to look up the key. */ tk = tty_keys_find(tty, buf + 1, len - 1, &size); if (tk != NULL) { - *code = KEYC_ADDESC(tk->code); + *key = KEYC_ADDESC(tk->key); buffer_remove(tty->in, size + 1); return (0); } /* If not found, return escape-escape. */ - *code = KEYC_ADDESC('\033'); + *key = KEYC_ADDESC('\033'); buffer_remove(tty->in, 1); return (0); } diff --git a/tty-term.c b/tty-term.c new file mode 100644 index 00000000..1aca9bd9 --- /dev/null +++ b/tty-term.c @@ -0,0 +1,395 @@ +/* $Id: tty-term.c,v 1.1 2009-01-09 23:57:42 nicm Exp $ */ + +/* + * Copyright (c) 2008 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +#include "tmux.h" + +void tty_term_quirks(struct tty_term *); +char *tty_term_strip(const char *); + +SLIST_HEAD(, tty_term) tty_terms = SLIST_HEAD_INITIALIZER(tty_terms); + +struct tty_term_code_entry { + enum tty_code_code code; + enum tty_code_type type; + const char *name; +}; + +struct tty_term_code_entry tty_term_codes[] = { + { TTYC_AX, TTYCODE_FLAG, "AX" }, + { TTYC_ACSC, TTYCODE_STRING, "acsc" }, + { TTYC_BEL, TTYCODE_STRING, "bel" }, + { TTYC_BLINK, TTYCODE_STRING, "blink" }, + { TTYC_BOLD, TTYCODE_STRING, "bold" }, + { TTYC_CIVIS, TTYCODE_STRING, "civis" }, + { TTYC_CLEAR, TTYCODE_STRING, "clear" }, + { TTYC_CNORM, TTYCODE_STRING, "cnorm" }, + { TTYC_COLORS, TTYCODE_NUMBER, "colors" }, + { TTYC_CR, TTYCODE_STRING, "cr" }, + { TTYC_CSR, TTYCODE_STRING, "csr" }, + { TTYC_CUB, TTYCODE_STRING, "cub" }, + { TTYC_CUB1, TTYCODE_STRING, "cub1" }, + { TTYC_CUD, TTYCODE_STRING, "cud" }, + { TTYC_CUD1, TTYCODE_STRING, "cud1" }, + { TTYC_CUF, TTYCODE_STRING, "cuf" }, + { TTYC_CUF1, TTYCODE_STRING, "cuf1" }, + { TTYC_CUP, TTYCODE_STRING, "cup" }, + { TTYC_CUU, TTYCODE_STRING, "cuu" }, + { TTYC_CUU1, TTYCODE_STRING, "cuu1" }, + { TTYC_DCH, TTYCODE_STRING, "dch" }, + { TTYC_DIM, TTYCODE_STRING, "dim" }, + { TTYC_DL, TTYCODE_STRING, "dl" }, + { TTYC_DL1, TTYCODE_STRING, "dl1" }, + { TTYC_ED, TTYCODE_STRING, "ed" }, + { TTYC_EL, TTYCODE_STRING, "el" }, + { TTYC_EL1, TTYCODE_STRING, "el1" }, + { TTYC_ENACS, TTYCODE_STRING, "enacs" }, + { TTYC_ICH, TTYCODE_STRING, "ich" }, + { TTYC_ICH1, TTYCODE_STRING, "ich1" }, + { TTYC_IL, TTYCODE_STRING, "il" }, + { TTYC_IL1, TTYCODE_STRING, "il1" }, + { TTYC_INVIS, TTYCODE_STRING, "invis" }, + { TTYC_IS1, TTYCODE_STRING, "is1" }, + { TTYC_IS2, TTYCODE_STRING, "is2" }, + { TTYC_IS3, TTYCODE_STRING, "is3" }, + { TTYC_KCUB1, TTYCODE_STRING, "kcub1" }, + { TTYC_KCUD1, TTYCODE_STRING, "kcud1" }, + { TTYC_KCUF1, TTYCODE_STRING, "kcuf1" }, + { TTYC_KCUU1, TTYCODE_STRING, "kcuu1" }, + { TTYC_KDCH1, TTYCODE_STRING, "kdch1" }, + { TTYC_KEND, TTYCODE_STRING, "kend" }, + { TTYC_KF1, TTYCODE_STRING, "kf1" }, + { TTYC_KF10, TTYCODE_STRING, "kf10" }, + { TTYC_KF11, TTYCODE_STRING, "kf11" }, + { TTYC_KF12, TTYCODE_STRING, "kf12" }, + { TTYC_KF2, TTYCODE_STRING, "kf2" }, + { TTYC_KF3, TTYCODE_STRING, "kf3" }, + { TTYC_KF4, TTYCODE_STRING, "kf4" }, + { TTYC_KF5, TTYCODE_STRING, "kf5" }, + { TTYC_KF6, TTYCODE_STRING, "kf6" }, + { TTYC_KF7, TTYCODE_STRING, "kf7" }, + { TTYC_KF8, TTYCODE_STRING, "kf8" }, + { TTYC_KF9, TTYCODE_STRING, "kf9" }, + { TTYC_KHOME, TTYCODE_STRING, "khome" }, + { TTYC_KICH1, TTYCODE_STRING, "kich1" }, + { TTYC_KMOUS, TTYCODE_STRING, "kmous" }, + { TTYC_KNP, TTYCODE_STRING, "knp" }, + { TTYC_KPP, TTYCODE_STRING, "kpp" }, + { TTYC_OP, TTYCODE_STRING, "op" }, + { TTYC_REV, TTYCODE_STRING, "rev" }, + { TTYC_RI, TTYCODE_STRING, "ri" }, + { TTYC_RMACS, TTYCODE_STRING, "rmacs" }, + { TTYC_RMCUP, TTYCODE_STRING, "rmcup" }, + { TTYC_RMKX, TTYCODE_STRING, "rmkx" }, + { TTYC_SETAB, TTYCODE_STRING, "setab" }, + { TTYC_SETAF, TTYCODE_STRING, "setaf" }, + { TTYC_SGR0, TTYCODE_STRING, "sgr0" }, + { TTYC_SMACS, TTYCODE_STRING, "smacs" }, + { TTYC_SMCUP, TTYCODE_STRING, "smcup" }, + { TTYC_SMKX, TTYCODE_STRING, "smkx" }, + { TTYC_SMSO, TTYCODE_STRING, "smso" }, + { TTYC_SMUL, TTYCODE_STRING, "smul" }, +}; + +char * +tty_term_strip(const char *s) +{ + const char *ptr; + static char buf[BUFSIZ]; + size_t len; + + /* Ignore strings with no padding. */ + if (strchr(s, '$') == NULL) + return (xstrdup(s)); + + len = 0; + for (ptr = s; *ptr != '\0'; ptr++) { + if (*ptr == '$' && *(ptr + 1) == '<') { + while (*ptr != '\0' && *ptr != '>') + ptr++; + if (*ptr == '>') + ptr++; + } + + buf[len++] = *ptr; + if (len == (sizeof buf) - 1) + break; + } + buf[len] = '\0'; + + return (xstrdup(buf)); +} + +void +tty_term_quirks(struct tty_term *term) +{ + if (strcmp(term->name, "rxvt") == 0) { + /* rxvt supports dch1 but some termcap files do not have it. */ + if (!tty_term_has(term, TTYC_DCH1)) { + term->codes[TTYC_DCH1].type = TTYCODE_STRING; + term->codes[TTYC_DCH1].value.string = xstrdup("\033[P"); + } + } +} + +struct tty_term * +tty_term_find(char *name, int fd, char **cause) +{ + struct tty_term *term; + struct tty_term_code_entry *ent; + struct tty_code *code; + u_int i; + int n, error; + char *s; + + SLIST_FOREACH(term, &tty_terms, entry) { + if (strcmp(term->name, name) == 0) { + term->references++; + return (term); + } + } + + log_debug("new term: %s", name); + term = xmalloc(sizeof *term); + term->name = xstrdup(name); + term->references = 1; + SLIST_INSERT_HEAD(&tty_terms, term, entry); + + /* Set up ncurses terminal. */ + if (setupterm(name, fd, &error) != OK) { + switch (error) { + case 0: + xasprintf(cause, "can't use hardcopy terminal"); + break; + case 1: + xasprintf(cause, "missing or unsuitable terminal"); + break; + case 2: + xasprintf(cause, "can't find terminfo database"); + break; + default: + xasprintf(cause, "unknown error"); + break; + } + goto error; + } + + /* Fill in codes. */ + memset(&term->codes, 0, sizeof term->codes); + for (i = 0; i < nitems(tty_term_codes); i++) { + ent = &tty_term_codes[i]; + + code = &term->codes[ent->code]; + code->type = TTYCODE_NONE; + switch (ent->type) { + case TTYCODE_NONE: + break; + case TTYCODE_STRING: + s = tigetstr(ent->name); + if (s == NULL || s == (char *) -1) + break; + code->type = TTYCODE_STRING; + code->value.string = tty_term_strip(s); + log_debug( + "code %d,%s: (string) %s", ent->code, ent->name, s); + break; + case TTYCODE_NUMBER: + n = tigetnum(ent->name); + if (n == -1 || n == -2) + break; + code->type = TTYCODE_NUMBER; + code->value.number = n; + log_debug( + "code %d,%s: (number) %d", ent->code, ent->name, n); + break; + case TTYCODE_FLAG: + n = tigetflag(ent->name); + if (n == -1) + break; + code->type = TTYCODE_FLAG; + code->value.number = n; + log_debug( + "code %d,%s: (flag) %d", ent->code, ent->name, n); + break; + } + } + tty_term_quirks(term); + + /* Delete ncurses data. */ + del_curterm(cur_term); + + /* These are always required. */ + if (!tty_term_has(term, TTYC_CLEAR)) { + xasprintf(cause, "terminal does not support clear"); + goto error; + } + if (!tty_term_has(term, TTYC_CUD)) { + xasprintf(cause, "terminal does not support cud"); + goto error; + } + if (!tty_term_has(term, TTYC_CR)) { + xasprintf(cause, "terminal does not support cr"); + goto error; + } + if (!tty_term_has(term, TTYC_RI)) { + xasprintf(cause, "terminal does not support ri"); + goto error; + } + if (!tty_term_has(term, TTYC_CSR)) { + xasprintf(cause, "terminal does not support csr"); + goto error; + } + if (!tty_term_has(term, TTYC_CUP)) { + xasprintf(cause, "terminal does not support cup"); + goto error; + } + + /* These can be emulated so one of the two is required. */ + if (!tty_term_has(term, TTYC_CUU1) && !tty_term_has(term, TTYC_CUU)) { + xasprintf(cause, "terminal does not support cuu1 or cuu"); + goto error; + } + if (!tty_term_has(term, TTYC_CUD1) && !tty_term_has(term, TTYC_CUD)) { + xasprintf(cause, "terminal does not support cud1 or cud"); + goto error; + } + if (!tty_term_has(term, TTYC_CUF1) && !tty_term_has(term, TTYC_CUF)) { + xasprintf(cause, "terminal does not support cuf1 or cuf"); + goto error; + } + if (!tty_term_has(term, TTYC_CUB1) && !tty_term_has(term, TTYC_CUB)) { + xasprintf(cause, "terminal does not support cub1 or cub"); + goto error; + } + if (!tty_term_has(term, TTYC_IL1) && !tty_term_has(term, TTYC_IL)) { + xasprintf(cause, "terminal does not support il1 or il"); + goto error; + } + if (!tty_term_has(term, TTYC_DL1) && !tty_term_has(term, TTYC_DL)) { + xasprintf(cause, "terminal does not support dl1 or dl"); + goto error; + } + if (!tty_term_has(term, TTYC_ICH1) && !tty_term_has(term, TTYC_ICH)) { + xasprintf(cause, "terminal does not support ich1 or ich"); + goto error; + } + if (!tty_term_has(term, TTYC_DCH1) && !tty_term_has(term, TTYC_DCH)) { + xasprintf(cause, "terminal does not support dch1 or dch"); + goto error; + } + + /* + * Figure out if terminal support default colours. AX is a screen + * extension which indicates this. Also check if op (orig_pair) uses + * the default colours - if it does, this is a good indication the + * terminal supports them. + */ + if (tty_term_flag(term, TTYC_AX)) + term->flags |= TERM_HASDEFAULTS; + if (strcmp(tty_term_string(term, TTYC_OP), "\033[39;49m") == 0) + term->flags |= TERM_HASDEFAULTS; + + /* + * Try to figure out if we have 256 colours. The standard xterm + * definitions are broken (well, or the way they are parsed is: in any + * case they end up returning 8). So also do a hack. + */ + if (tty_term_number(term, TTYC_COLORS) == 256) + term->flags |= TERM_256COLOURS; + if (strstr(name, "256col") != NULL) /* XXX HACK */ + term->flags |= TERM_256COLOURS; + + return (term); + +error: + tty_term_free(term); + return (NULL); +} + +void +tty_term_free(struct tty_term *term) +{ + u_int i; + + if (--term->references != 0) + return; + + SLIST_REMOVE(&tty_terms, term, tty_term, entry); + + for (i = 0; i < NTTYCODE; i++) { + if (term->codes[i].type == TTYCODE_STRING) + xfree(term->codes[i].value.string); + } + xfree(term->name); + xfree(term); +} + +int +tty_term_has(struct tty_term *term, enum tty_code_code code) +{ + return (term->codes[code].type != TTYCODE_NONE); +} + +const char * +tty_term_string(struct tty_term *term, enum tty_code_code code) +{ + if (!tty_term_has(term, code)) + return (""); + if (term->codes[code].type != TTYCODE_STRING) + log_fatalx("not a string: %d", code); + return (term->codes[code].value.string); +} + +/* No vtparm. Fucking ncurses. */ +const char * +tty_term_string1(struct tty_term *term, enum tty_code_code code, int a) +{ + return (tparm(tty_term_string(term, code), a)); +} + +const char * +tty_term_string2(struct tty_term *term, enum tty_code_code code, int a, int b) +{ + return (tparm(tty_term_string(term, code), a, b)); +} + +int +tty_term_number(struct tty_term *term, enum tty_code_code code) +{ + if (!tty_term_has(term, code)) + return (0); + if (term->codes[code].type != TTYCODE_NUMBER) + log_fatalx("not a number: %d", code); + return (term->codes[code].value.number); +} + +int +tty_term_flag(struct tty_term *term, enum tty_code_code code) +{ + if (!tty_term_has(term, code)) + return (0); + if (term->codes[code].type != TTYCODE_FLAG) + log_fatalx("not a flag: %d", code); + return (term->codes[code].value.flag); +} + diff --git a/tty-write.c b/tty-write.c index a58f1b2e..a8d22c0b 100644 --- a/tty-write.c +++ b/tty-write.c @@ -1,4 +1,4 @@ -/* $Id: tty-write.c,v 1.2 2007-12-06 09:46:23 nicm Exp $ */ +/* $Id: tty-write.c,v 1.3 2009-01-09 23:57:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -21,7 +21,7 @@ #include "tmux.h" void -tty_write_client(void *ptr, int cmd, ...) +tty_write_client(void *ptr, enum tty_cmd cmd, ...) { struct client *c = ptr; va_list ap; @@ -32,7 +32,7 @@ tty_write_client(void *ptr, int cmd, ...) } void -tty_vwrite_client(void *ptr, int cmd, va_list ap) +tty_vwrite_client(void *ptr, enum tty_cmd cmd, va_list ap) { struct client *c = ptr; struct screen *s = c->session->curw->window->screen; @@ -41,7 +41,7 @@ tty_vwrite_client(void *ptr, int cmd, va_list ap) } void -tty_write_window(void *ptr, int cmd, ...) +tty_write_window(void *ptr, enum tty_cmd cmd, ...) { va_list ap; @@ -51,7 +51,7 @@ tty_write_window(void *ptr, int cmd, ...) } void -tty_vwrite_window(void *ptr, int cmd, va_list ap) +tty_vwrite_window(void *ptr, enum tty_cmd cmd, va_list ap) { struct window *w = ptr; struct client *c; @@ -75,7 +75,7 @@ tty_vwrite_window(void *ptr, int cmd, va_list ap) } void -tty_write_session(void *ptr, int cmd, ...) +tty_write_session(void *ptr, enum tty_cmd cmd, ...) { va_list ap; @@ -85,7 +85,7 @@ tty_write_session(void *ptr, int cmd, ...) } void -tty_vwrite_session(void *ptr, int cmd, va_list ap) +tty_vwrite_session(void *ptr, enum tty_cmd cmd, va_list ap) { struct session *s = ptr; struct client *c; diff --git a/tty.c b/tty.c index a82b86ea..edd8e65d 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $Id: tty.c,v 1.54 2008-12-13 17:41:49 nicm Exp $ */ +/* $Id: tty.c,v 1.55 2009-01-09 23:57:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -28,16 +27,16 @@ #include "tmux.h" -struct tty_term *tty_find_term(char *, int,char **); -void tty_free_term(struct tty_term *); - void tty_fill_acs(struct tty *); u_char tty_get_acs(struct tty *, u_char); -void tty_put_line(struct tty *, struct screen *, u_int, u_int, u_int); +void tty_emulate_repeat( + struct tty *, enum tty_code_code, enum tty_code_code, u_int); -const char *tty_strip(const char *); void tty_raw(struct tty *, const char *); +void tty_putcode(struct tty *, enum tty_code_code); +void tty_putcode1(struct tty *, enum tty_code_code, int); +void tty_putcode2(struct tty *, enum tty_code_code, int, int); void tty_puts(struct tty *, const char *); void tty_putc(struct tty *, char); @@ -46,62 +45,62 @@ void tty_attributes(struct tty *, const struct grid_cell *); void tty_attributes_fg(struct tty *, const struct grid_cell *); void tty_attributes_bg(struct tty *, const struct grid_cell *); -void tty_cmd_cursorup(struct tty *, struct screen *, va_list); -void tty_cmd_cursordown(struct tty *, struct screen *, va_list); -void tty_cmd_cursorright(struct tty *, struct screen *, va_list); -void tty_cmd_cursorleft(struct tty *, struct screen *, va_list); -void tty_cmd_insertcharacter(struct tty *, struct screen *, va_list); -void tty_cmd_deletecharacter(struct tty *, struct screen *, va_list); -void tty_cmd_insertline(struct tty *, struct screen *, va_list); -void tty_cmd_deleteline(struct tty *, struct screen *, va_list); -void tty_cmd_clearline(struct tty *, struct screen *, va_list); +void tty_cmd_bell(struct tty *, struct screen *, va_list); +void tty_cmd_carriagereturn(struct tty *, struct screen *, va_list); +void tty_cmd_cell(struct tty *, struct screen *, va_list); void tty_cmd_clearendofline(struct tty *, struct screen *, va_list); +void tty_cmd_clearendofscreen(struct tty *, struct screen *, va_list); +void tty_cmd_clearline(struct tty *, struct screen *, va_list); +void tty_cmd_clearscreen(struct tty *, struct screen *, va_list); void tty_cmd_clearstartofline(struct tty *, struct screen *, va_list); -void tty_cmd_cursormove(struct tty *, struct screen *, va_list); +void tty_cmd_clearstartofscreen(struct tty *, struct screen *, va_list); +void tty_cmd_cursordown(struct tty *, struct screen *, va_list); +void tty_cmd_cursorleft(struct tty *, struct screen *, va_list); void tty_cmd_cursormode(struct tty *, struct screen *, va_list); +void tty_cmd_cursormove(struct tty *, struct screen *, va_list); +void tty_cmd_cursorright(struct tty *, struct screen *, va_list); +void tty_cmd_cursorup(struct tty *, struct screen *, va_list); +void tty_cmd_deletecharacter(struct tty *, struct screen *, va_list); +void tty_cmd_deleteline(struct tty *, struct screen *, va_list); +void tty_cmd_insertcharacter(struct tty *, struct screen *, va_list); +void tty_cmd_insertline(struct tty *, struct screen *, va_list); +void tty_cmd_insertmode(struct tty *, struct screen *, va_list); +void tty_cmd_kcursormode(struct tty *, struct screen *, va_list); +void tty_cmd_kkeypadmode(struct tty *, struct screen *, va_list); +void tty_cmd_linefeed(struct tty *, struct screen *, va_list); +void tty_cmd_mousemode(struct tty *, struct screen *, va_list); void tty_cmd_reverseindex(struct tty *, struct screen *, va_list); void tty_cmd_scrollregion(struct tty *, struct screen *, va_list); -void tty_cmd_insertmode(struct tty *, struct screen *, va_list); -void tty_cmd_mousemode(struct tty *, struct screen *, va_list); -void tty_cmd_linefeed(struct tty *, struct screen *, va_list); -void tty_cmd_carriagereturn(struct tty *, struct screen *, va_list); -void tty_cmd_bell(struct tty *, struct screen *, va_list); -void tty_cmd_clearendofscreen(struct tty *, struct screen *, va_list); -void tty_cmd_clearstartofscreen(struct tty *, struct screen *, va_list); -void tty_cmd_clearscreen(struct tty *, struct screen *, va_list); -void tty_cmd_cell(struct tty *, struct screen *, va_list); void (*tty_cmds[])(struct tty *, struct screen *, va_list) = { - tty_cmd_cursorup, - tty_cmd_cursordown, - tty_cmd_cursorright, - tty_cmd_cursorleft, - tty_cmd_insertcharacter, - tty_cmd_deletecharacter, - tty_cmd_insertline, - tty_cmd_deleteline, - tty_cmd_clearline, + tty_cmd_bell, + tty_cmd_carriagereturn, + tty_cmd_cell, tty_cmd_clearendofline, + tty_cmd_clearendofscreen, + tty_cmd_clearline, + tty_cmd_clearscreen, tty_cmd_clearstartofline, - tty_cmd_cursormove, + tty_cmd_clearstartofscreen, + tty_cmd_cursordown, + tty_cmd_cursorleft, tty_cmd_cursormode, + tty_cmd_cursormove, + tty_cmd_cursorright, + tty_cmd_cursorup, + tty_cmd_deletecharacter, + tty_cmd_deleteline, + tty_cmd_insertcharacter, + tty_cmd_insertline, + tty_cmd_insertmode, + tty_cmd_kcursormode, + tty_cmd_kkeypadmode, + tty_cmd_linefeed, + tty_cmd_mousemode, tty_cmd_reverseindex, tty_cmd_scrollregion, - tty_cmd_insertmode, - tty_cmd_mousemode, - tty_cmd_linefeed, - tty_cmd_carriagereturn, - tty_cmd_bell, - NULL, - NULL, - tty_cmd_clearendofscreen, - tty_cmd_clearstartofscreen, - tty_cmd_clearscreen, - tty_cmd_cell, }; -SLIST_HEAD(, tty_term) tty_terms = SLIST_HEAD_INITIALIZER(tty_terms); - void tty_init(struct tty *tty, char *path, char *term) { @@ -139,7 +138,7 @@ tty_open(struct tty *tty, char **cause) else tty->log_fd = -1; - if ((tty->term = tty_find_term(tty->termname, tty->fd, cause)) == NULL) + if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL) goto error; tty->in = buffer_create(BUFSIZ); @@ -167,20 +166,14 @@ tty_open(struct tty *tty, char **cause) fatal("ioctl(TIOCFLUSH)"); #endif - if (init_1string != NULL) - tty_puts(tty, init_1string); - if (init_2string != NULL) - tty_puts(tty, init_2string); - if (init_3string != NULL) - tty_puts(tty, init_3string); + tty_putcode(tty, TTYC_IS1); + tty_putcode(tty, TTYC_IS2); + tty_putcode(tty, TTYC_IS3); - if (enter_ca_mode != NULL) - tty_puts(tty, enter_ca_mode); - if (keypad_xmit != NULL) - tty_puts(tty, keypad_xmit); - if (ena_acs != NULL) - tty_puts(tty, ena_acs); - tty_puts(tty, clear_screen); + tty_putcode(tty, TTYC_SMCUP); + tty_putcode(tty, TTYC_SMKX); + tty_putcode(tty, TTYC_ENACS); + tty_putcode(tty, TTYC_CLEAR); tty_keys_init(tty); @@ -195,6 +188,30 @@ error: return (-1); } +void +tty_fill_acs(struct tty *tty) +{ + const char *ptr; + + memset(tty->acs, 0, sizeof tty->acs); + if (!tty_term_has(tty->term, TTYC_ACSC)) + return; + + ptr = tty_term_string(tty->term, TTYC_ACSC); + if (strlen(ptr) % 2 != 0) + return; + for (; *ptr != '\0'; ptr += 2) + tty->acs[(u_char) ptr[0]] = ptr[1]; +} + +u_char +tty_get_acs(struct tty *tty, u_char ch) +{ + if (tty->acs[ch] != '\0') + return (tty->acs[ch]); + return (ch); +} + void tty_close(struct tty *tty) { @@ -220,21 +237,17 @@ tty_close(struct tty *tty) if (errno != EBADF && errno != ENXIO && errno != ENOTTY) fatal("tcsetattr failed"); } else { - tty_raw(tty, tparm(change_scroll_region, 0, ws.ws_row - 1)); - if (exit_alt_charset_mode != NULL) - tty_puts(tty, exit_alt_charset_mode); - if (exit_attribute_mode != NULL) - tty_raw(tty, exit_attribute_mode); - tty_raw(tty, clear_screen); - if (keypad_local != NULL) - tty_raw(tty, keypad_local); - if (exit_ca_mode != NULL) - tty_raw(tty, exit_ca_mode); - if (cursor_normal != NULL) - tty_raw(tty, cursor_normal); + tty_raw(tty, + tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1)); + tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS)); + tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0)); + tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR)); + tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX)); + tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); + tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM)); } - tty_free_term(tty->term); + tty_term_free(tty->term); tty_keys_free(tty); close(tty->fd); @@ -255,211 +268,43 @@ tty_free(struct tty *tty) xfree(tty->termname); } -struct tty_term * -tty_find_term(char *name, int fd, char **cause) -{ - struct tty_term *term; - int error; - char *s; - - SLIST_FOREACH(term, &tty_terms, entry) { - if (strcmp(term->name, name) == 0) { - term->references++; - return (term); - } - } - - term = xmalloc(sizeof *term); - term->name = xstrdup(name); - term->term = NULL; - term->references = 1; - SLIST_INSERT_HEAD(&tty_terms, term, entry); - - if (setupterm(name, fd, &error) != OK) { - switch (error) { - case 0: - xasprintf(cause, "can't use hardcopy terminal"); - break; - case 1: - xasprintf(cause, "missing or unsuitable terminal"); - break; - case 2: - xasprintf(cause, "can't find terminfo database"); - break; - default: - xasprintf(cause, "unknown error"); - break; - } - goto error; - } - term->term = cur_term; - - if (clear_screen == NULL) { - xasprintf(cause, "clear_screen missing"); - goto error; - } - if (cursor_down == NULL) { - xasprintf(cause, "cursor_down missing"); - goto error; - } - if (carriage_return == NULL) { - xasprintf(cause, "carriage_return missing"); - goto error; - } - if (parm_up_cursor == NULL && cursor_up == NULL) { - xasprintf(cause, "parm_up_cursor missing"); - goto error; - } - if (parm_down_cursor == NULL && cursor_down == NULL) { - xasprintf(cause, "parm_down_cursor missing"); - goto error; - } - if (parm_right_cursor == NULL && cursor_right == NULL) { - xasprintf(cause, "parm_right_cursor missing"); - goto error; - } - if (parm_left_cursor == NULL && cursor_left == NULL) { - xasprintf(cause, "parm_left_cursor missing"); - goto error; - } - if (cursor_address == NULL) { - xasprintf(cause, "cursor_address missing"); - goto error; - } - if (parm_insert_line == NULL && insert_line == NULL) { - xasprintf(cause, "parm_insert_line missing"); - goto error; - } - if (parm_delete_line == NULL && delete_line == NULL) { - xasprintf(cause, "parm_delete_line missing"); - goto error; - } - if (parm_ich == NULL && insert_character == NULL && - (enter_insert_mode == NULL || exit_insert_mode == NULL)) { - xasprintf(cause, "parm_ich missing"); - goto error; - } - if (scroll_reverse == NULL) { - xasprintf(cause, "scroll_reverse missing"); - goto error; - } - if (change_scroll_region == NULL) { - xasprintf(cause, "change_scroll_region missing"); - goto error; - } - - if (tigetflag("AX") == TRUE) - term->flags |= TERM_HASDEFAULTS; - s = tigetstr("orig_pair"); - if (s != NULL && s != (char *) -1 && strcmp(s, "\033[39;49m") == 0) - term->flags |= TERM_HASDEFAULTS; - - /* - * Try to figure out if we have 256 colours. The standard xterm - * definitions are broken (well, or the way they are parsed is: in - * any case they end up returning 8). So also do a hack. - */ - if (max_colors == 256 || strstr(name, "256col") != NULL) /* XXX HACK */ - term->flags |= TERM_256COLOURS; - - return (term); - -error: - tty_free_term(term); - return (NULL); -} - -void -tty_free_term(struct tty_term *term) -{ - if (--term->references != 0) - return; - - SLIST_REMOVE(&tty_terms, term, tty_term, entry); - -#ifdef __FreeBSD___ -/* - * XXX XXX XXX FIXME FIXME - * FreeBSD 6.2 crashes with a double-free somewhere under here. - */ - if (term->term != NULL) - del_curterm(term->term); -#endif - - xfree(term->name); - xfree(term); -} - -void -tty_fill_acs(struct tty *tty) -{ - char *ptr; - - memset(tty->acs, 0, sizeof tty->acs); - if (acs_chars == NULL || (strlen(acs_chars) % 2) != 0) - return; - for (ptr = acs_chars; *ptr != '\0'; ptr += 2) - tty->acs[(u_char) ptr[0]] = ptr[1]; -} - -u_char -tty_get_acs(struct tty *tty, u_char ch) -{ - if (tty->acs[ch] != '\0') - return (tty->acs[ch]); - return (ch); -} - -const char * -tty_strip(const char *s) -{ - const char *ptr; - static char buf[BUFSIZ]; - size_t len; - - /* Ignore strings with no padding. */ - if (strchr(s, '$') == NULL) - return (s); - - len = 0; - for (ptr = s; *ptr != '\0'; ptr++) { - if (*ptr == '$' && *(ptr + 1) == '<') { - while (*ptr != '\0' && *ptr != '>') - ptr++; - if (*ptr == '>') - ptr++; - } - - buf[len++] = *ptr; - if (len == (sizeof buf) - 1) - break; - } - buf[len] = '\0'; - - return (buf); -} - void tty_raw(struct tty *tty, const char *s) { - const char *t; + write(tty->fd, s, strlen(s)); +} - t = tty_strip(s); - write(tty->fd, t, strlen(t)); +void +tty_putcode(struct tty *tty, enum tty_code_code code) +{ + tty_puts(tty, tty_term_string(tty->term, code)); +} + +void +tty_putcode1(struct tty *tty, enum tty_code_code code, int a) +{ + if (a < 0) + return; + tty_puts(tty, tty_term_string1(tty->term, code, a)); +} + +void +tty_putcode2(struct tty *tty, enum tty_code_code code, int a, int b) +{ + if (a < 0 || b < 0) + return; + tty_puts(tty, tty_term_string2(tty->term, code, a, b)); } void tty_puts(struct tty *tty, const char *s) { - const char *t; - - t = tty_strip(s); - if (*t == '\0') + if (*s == '\0') return; - buffer_write(tty->out, t, strlen(t)); + buffer_write(tty->out, s, strlen(s)); if (tty->log_fd != -1) - write(tty->log_fd, t, strlen(t)); + write(tty->log_fd, s, strlen(s)); } void @@ -487,7 +332,19 @@ tty_set_title(struct tty *tty, const char *title) } void -tty_write(struct tty *tty, struct screen *s, int cmd, ...) +tty_emulate_repeat( + struct tty *tty, enum tty_code_code code, enum tty_code_code code1, u_int n) +{ + if (tty_term_has(tty->term, code)) + tty_putcode1(tty, code, n); + else { + while (n-- > 0) + tty_putcode(tty, code1); + } +} + +void +tty_write(struct tty *tty, struct screen *s, enum tty_cmd cmd, ...) { va_list ap; @@ -497,50 +354,22 @@ tty_write(struct tty *tty, struct screen *s, int cmd, ...) } void -tty_vwrite(struct tty *tty, struct screen *s, int cmd, va_list ap) +tty_vwrite(struct tty *tty, struct screen *s, enum tty_cmd cmd, va_list ap) { - if (tty->flags & TTY_FREEZE) + if (tty->flags & TTY_FREEZE || tty->term == NULL) return; - - if (tty->term == NULL) /* XXX XXX */ - return; - set_curterm(tty->term->term); - if (tty_cmds[cmd] != NULL) tty_cmds[cmd](tty, s, ap); } -void -tty_put_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx) -{ - const struct grid_cell *gc; - struct grid_cell tc; - u_int xx; - - for (xx = px; xx < px + nx; xx++) { - gc = grid_view_peek_cell(s->grid, xx, py); - if (screen_check_selection(s, xx, py)) { - memcpy(&tc, &s->sel.cell, sizeof tc); - tc.data = gc->data; - tty_write(tty, s, TTY_CELL, &tc); - } else - tty_write(tty, s, TTY_CELL, gc); - } -} - void tty_cmd_cursorup(struct tty *tty, unused struct screen *s, va_list ap) { u_int ua; ua = va_arg(ap, u_int); - - if (parm_up_cursor != NULL) - tty_puts(tty, tparm(parm_up_cursor, ua)); - else { - while (ua-- > 0) - tty_puts(tty, cursor_up); - } + + tty_emulate_repeat(tty, TTYC_CUU, TTYC_CUU1, ua); } void @@ -550,12 +379,7 @@ tty_cmd_cursordown(struct tty *tty, unused struct screen *s, va_list ap) ua = va_arg(ap, u_int); - if (parm_down_cursor != NULL) - tty_puts(tty, tparm(parm_down_cursor, ua)); - else { - while (ua-- > 0) - tty_puts(tty, cursor_down); - } + tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, ua); } void @@ -565,12 +389,7 @@ tty_cmd_cursorright(struct tty *tty, unused struct screen *s, va_list ap) ua = va_arg(ap, u_int); - if (parm_right_cursor != NULL) - tty_puts(tty, tparm(parm_right_cursor, ua)); - else { - while (ua-- > 0) - tty_puts(tty, cursor_right); - } + tty_emulate_repeat(tty, TTYC_CUF, TTYC_CUF1, ua); } void @@ -580,16 +399,11 @@ tty_cmd_cursorleft(struct tty *tty, unused struct screen *s, va_list ap) ua = va_arg(ap, u_int); - if (parm_left_cursor != NULL) - tty_puts(tty, tparm(parm_left_cursor, ua)); - else { - while (ua-- > 0) - tty_puts(tty, cursor_left); - } + tty_emulate_repeat(tty, TTYC_CUB, TTYC_CUB1, ua); } void -tty_cmd_insertcharacter(struct tty *tty, struct screen *s, va_list ap) +tty_cmd_insertcharacter(struct tty *tty, unused struct screen *s, va_list ap) { u_int ua; @@ -597,18 +411,7 @@ tty_cmd_insertcharacter(struct tty *tty, struct screen *s, va_list ap) tty_reset(tty); - if (parm_ich != NULL) - tty_puts(tty, tparm(parm_ich, ua)); - else if (insert_character != NULL) { - while (ua-- > 0) - tty_puts(tty, insert_character); - } else if (enter_insert_mode != NULL) { - tty_puts(tty, enter_insert_mode); - while (ua-- > 0) - tty_putc(tty, ' '); - tty_puts(tty, exit_insert_mode); - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); - } + tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ua); } void @@ -620,22 +423,7 @@ tty_cmd_deletecharacter(struct tty *tty, unused struct screen *s, va_list ap) tty_reset(tty); - if (parm_dch != NULL) - tty_puts(tty, tparm(parm_dch, ua)); - else if (delete_character != NULL) { - while (ua-- > 0) - tty_puts(tty, delete_character); - } else { - /* - * XXX assumes screen already updated! I hate this... stupid - * terms without dch... - */ - if (s->cx != screen_size_x(s) - 1) { - tty_put_line(tty, s, - s->cx, s->cy, screen_size_x(s) - s->cx); - } - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); - } + tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ua); } void @@ -647,12 +435,7 @@ tty_cmd_insertline(struct tty *tty, unused struct screen *s, va_list ap) tty_reset(tty); - if (parm_insert_line != NULL) - tty_puts(tty, tparm(parm_insert_line, ua)); - else { - while (ua-- > 0) - tty_puts(tty, insert_line); - } + tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ua); } void @@ -664,12 +447,7 @@ tty_cmd_deleteline(struct tty *tty, unused struct screen *s, va_list ap) tty_reset(tty); - if (parm_delete_line != NULL) - tty_puts(tty, tparm(parm_delete_line, ua)); - else { - while (ua-- > 0) - tty_puts(tty, delete_line); - } + tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ua); } void @@ -679,15 +457,15 @@ tty_cmd_clearline(struct tty *tty, struct screen *s, unused va_list ap) tty_reset(tty); - if (clr_eol != NULL) { - tty_puts(tty, tparm(cursor_address, s->cy, 0)); - tty_puts(tty, clr_eol); - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); + if (tty_term_has(tty->term, TTYC_EL)) { + tty_putcode2(tty, TTYC_CUP, s->cy, 0); + tty_putcode(tty, TTYC_EL); + tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); } else { - tty_puts(tty, tparm(cursor_address, s->cy, 0)); + tty_putcode2(tty, TTYC_CUP, s->cy, 0); for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); + tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); } } @@ -698,13 +476,13 @@ tty_cmd_clearendofline(struct tty *tty, struct screen *s, unused va_list ap) tty_reset(tty); - if (clr_eol != NULL) - tty_puts(tty, clr_eol); - else { - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); + if (tty_term_has(tty->term, TTYC_EL)) + tty_putcode(tty, TTYC_EL); + else { + tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); for (i = s->cx; i < screen_size_x(s); i++) tty_putc(tty, ' '); - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); + tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); } } @@ -715,13 +493,13 @@ tty_cmd_clearstartofline(struct tty *tty, struct screen *s, unused va_list ap) tty_reset(tty); - if (clr_bol != NULL) - tty_puts(tty, clr_bol); - else { - tty_puts(tty, tparm(cursor_address, s->cy, 0)); + if (tty_term_has(tty->term, TTYC_EL1)) + tty_putcode(tty, TTYC_EL1); + else { + tty_putcode2(tty, TTYC_CUP, s->cy, 0); for (i = 0; i < s->cx + 1; i++) tty_putc(tty, ' '); - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); + tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); } } @@ -733,7 +511,7 @@ tty_cmd_cursormove(struct tty *tty, unused struct screen *s, va_list ap) ua = va_arg(ap, u_int); ub = va_arg(ap, u_int); - tty_puts(tty, tparm(cursor_address, ub, ua)); + tty_putcode2(tty, TTYC_CUP, ub, ua); } void @@ -741,15 +519,12 @@ tty_cmd_cursormode(struct tty *tty, unused struct screen *s, va_list ap) { u_int ua; - if (cursor_normal == NULL || cursor_invisible == NULL) - return; - ua = va_arg(ap, int); if (ua && !(tty->flags & TTY_NOCURSOR)) - tty_puts(tty, cursor_normal); + tty_putcode(tty, TTYC_CNORM); else - tty_puts(tty, cursor_invisible); + tty_putcode(tty, TTYC_CIVIS); } void @@ -757,7 +532,8 @@ tty_cmd_reverseindex( struct tty *tty, unused struct screen *s, unused va_list ap) { tty_reset(tty); - tty_puts(tty, scroll_reverse); + + tty_putcode(tty, TTYC_RI); } void @@ -768,7 +544,7 @@ tty_cmd_scrollregion(struct tty *tty, unused struct screen *s, va_list ap) ua = va_arg(ap, u_int); ub = va_arg(ap, u_int); - tty_puts(tty, tparm(change_scroll_region, ua, ub)); + tty_putcode2(tty, TTYC_CSR, ua, ub); } void @@ -776,12 +552,10 @@ tty_cmd_insertmode(unused struct tty *tty, unused struct screen *s, va_list ap) { u_int ua; - if (enter_insert_mode == NULL || exit_insert_mode == NULL) - return; - ua = va_arg(ap, int); #if 0 + /* XXX */ if (ua) tty_puts(tty, enter_insert_mode); else @@ -794,7 +568,7 @@ tty_cmd_mousemode(struct tty *tty, unused struct screen *s, va_list ap) { u_int ua; - if (key_mouse == NULL) + if (!tty_term_has(tty->term, TTYC_KMOUS)) return; ua = va_arg(ap, int); @@ -805,6 +579,18 @@ tty_cmd_mousemode(struct tty *tty, unused struct screen *s, va_list ap) tty_puts(tty, "\033[?1000l"); } +void +tty_cmd_kcursormode( + unused struct tty *tty, unused struct screen *s, unused va_list ap) +{ +} + +void +tty_cmd_kkeypadmode( + unused struct tty *tty, unused struct screen *s, unused va_list ap) +{ +} + void tty_cmd_linefeed(struct tty *tty, unused struct screen *s, unused va_list ap) { @@ -819,8 +605,8 @@ tty_cmd_carriagereturn( { tty_reset(tty); - if (carriage_return) - tty_puts(tty, carriage_return); + if (tty_term_has(tty->term, TTYC_CR)) + tty_putcode(tty, TTYC_CR); else tty_putc(tty, '\r'); } @@ -828,8 +614,7 @@ tty_cmd_carriagereturn( void tty_cmd_bell(struct tty *tty, unused struct screen *s, unused va_list ap) { - if (bell) - tty_puts(tty, bell); + tty_putcode(tty, TTYC_BEL); } void @@ -839,11 +624,11 @@ tty_cmd_clearendofscreen(struct tty *tty, struct screen *s, unused va_list ap) tty_reset(tty); - if (clr_eol != NULL) { + if (tty_term_has(tty->term, TTYC_EL)) { for (i = s->cy; i < screen_size_y(s); i++) { - tty_puts(tty, clr_eol); + tty_putcode(tty, TTYC_EL); if (i != screen_size_y(s) - 1) - tty_puts(tty, cursor_down); + tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); } } else { for (i = s->cx; i < screen_size_y(s); i++) @@ -853,7 +638,7 @@ tty_cmd_clearendofscreen(struct tty *tty, struct screen *s, unused va_list ap) tty_putc(tty, ' '); } } - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); + tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); } void @@ -863,11 +648,13 @@ tty_cmd_clearstartofscreen(struct tty *tty, struct screen *s, unused va_list ap) tty_reset(tty); - tty_puts(tty, tparm(cursor_address, 0, 0)); - if (clr_eol) { - for (i = 0; i < s->cy; i++) - tty_puts(tty, clr_eol); - tty_puts(tty, tparm(cursor_address, s->cy, 0)); + tty_putcode2(tty, TTYC_CUP, 0, 0); + if (tty_term_has(tty->term, TTYC_EL)) { + for (i = 0; i < s->cy; i++) { + tty_putcode(tty, TTYC_EL); + tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); + } + tty_putcode2(tty, TTYC_CUP, s->cy, 0); } else { for (j = 0; j < s->cy; j++) { for (i = 0; i < screen_size_x(s); i++) @@ -876,7 +663,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, struct screen *s, unused va_list ap) } for (i = 0; i < s->cx; i++) tty_putc(tty, ' '); - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); + tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); } void @@ -886,21 +673,20 @@ tty_cmd_clearscreen(struct tty *tty, struct screen *s, unused va_list ap) tty_reset(tty); - if (clr_eol) { - tty_puts(tty, tparm(cursor_address, 0, 0)); + tty_putcode2(tty, TTYC_CUP, 0, 0); + if (tty_term_has(tty->term, TTYC_EL)) { for (i = 0; i < screen_size_y(s); i++) { - tty_puts(tty, clr_eol); + tty_putcode(tty, TTYC_EL); if (i != screen_size_y(s) - 1) - tty_puts(tty, cursor_down); + tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); } } else { - tty_puts(tty, tparm(cursor_address, 0, 0)); for (j = 0; j < screen_size_y(s); j++) { for (i = 0; i < screen_size_x(s); i++) tty_putc(tty, ' '); } } - tty_puts(tty, tparm(cursor_address, s->cy, s->cx)); + tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); } void @@ -955,9 +741,9 @@ tty_reset(struct tty *tty) if (memcmp(tc, &grid_default_cell, sizeof *tc) == 0) return; - if (exit_alt_charset_mode != NULL && tc->attr & GRID_ATTR_CHARSET) - tty_puts(tty, exit_alt_charset_mode); - tty_puts(tty, exit_attribute_mode); + if (tty_term_has(tty->term, TTYC_RMACS) && tc->attr & GRID_ATTR_CHARSET) + tty_putcode(tty, TTYC_RMACS); + tty_putcode(tty, TTYC_SGR0); memcpy(tc, &grid_default_cell, sizeof *tc); } @@ -976,22 +762,22 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) tc->attr = gc->attr; /* Set the attributes. */ - if ((changed & GRID_ATTR_BRIGHT) && enter_bold_mode != NULL) - tty_puts(tty, enter_bold_mode); - if ((changed & GRID_ATTR_DIM) && enter_dim_mode != NULL) - tty_puts(tty, enter_dim_mode); - if ((changed & GRID_ATTR_ITALICS) && enter_standout_mode != NULL) - tty_puts(tty, enter_standout_mode); - if ((changed & GRID_ATTR_UNDERSCORE) && enter_underline_mode != NULL) - tty_puts(tty, enter_underline_mode); - if ((changed & GRID_ATTR_BLINK) && enter_blink_mode != NULL) - tty_puts(tty, enter_blink_mode); - if ((changed & GRID_ATTR_REVERSE) && enter_reverse_mode != NULL) - tty_puts(tty, enter_reverse_mode); - if ((changed & GRID_ATTR_HIDDEN) && enter_secure_mode != NULL) - tty_puts(tty, enter_secure_mode); - if ((changed & GRID_ATTR_CHARSET) && enter_alt_charset_mode != NULL) - tty_puts(tty, enter_alt_charset_mode); + if (changed & GRID_ATTR_BRIGHT) + tty_putcode(tty, TTYC_BOLD); + if (changed & GRID_ATTR_DIM) + tty_putcode(tty, TTYC_DIM); + if (changed & GRID_ATTR_ITALICS) + tty_putcode(tty, TTYC_SMSO); + if (changed & GRID_ATTR_UNDERSCORE) + tty_putcode(tty, TTYC_SMUL); + if (changed & GRID_ATTR_BLINK) + tty_putcode(tty, TTYC_BLINK); + if (changed & GRID_ATTR_REVERSE) + tty_putcode(tty, TTYC_REV); + if (changed & GRID_ATTR_HIDDEN) + tty_putcode(tty, TTYC_INVIS); + if (changed & GRID_ATTR_CHARSET) + tty_putcode(tty, TTYC_SMACS); /* Set foreground colour. */ if (gc->fg != tc->fg || @@ -1024,8 +810,7 @@ tty_attributes_fg(struct tty *tty, const struct grid_cell *gc) fg = colour_translate256(fg); if (fg & 8) { fg &= 7; - if (enter_bold_mode != NULL) - tty_puts(tty, enter_bold_mode); + tty_putcode(tty, TTYC_BOLD); tty->cell.attr |= GRID_ATTR_BRIGHT; } else if (tty->cell.attr & GRID_ATTR_BRIGHT) tty_reset(tty); @@ -1037,8 +822,8 @@ tty_attributes_fg(struct tty *tty, const struct grid_cell *gc) fg = 7; if (fg == 8) tty_puts(tty, "\033[39m"); - else if (set_a_foreground != NULL) - tty_puts(tty, tparm(set_a_foreground, fg)); + else + tty_putcode1(tty, TTYC_SETAF, fg); } void @@ -1075,6 +860,6 @@ tty_attributes_bg(struct tty *tty, const struct grid_cell *gc) bg = 0; if (bg == 8) tty_puts(tty, "\033[49m"); - else if (set_a_background != NULL) - tty_puts(tty, tparm(set_a_background, bg)); + else + tty_putcode1(tty, TTYC_SETAB, bg); }