diff options
-rw-r--r-- | usr.bin/tmux/Makefile | 3 | ||||
-rw-r--r-- | usr.bin/tmux/client.c | 11 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-show-messages.c | 16 | ||||
-rw-r--r-- | usr.bin/tmux/format.c | 9 | ||||
-rw-r--r-- | usr.bin/tmux/options-table.c | 15 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 26 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 96 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.c | 22 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 32 | ||||
-rw-r--r-- | usr.bin/tmux/tty-acs.c | 4 | ||||
-rw-r--r-- | usr.bin/tmux/tty-features.c | 264 | ||||
-rw-r--r-- | usr.bin/tmux/tty-keys.c | 64 | ||||
-rw-r--r-- | usr.bin/tmux/tty-term.c | 106 | ||||
-rw-r--r-- | usr.bin/tmux/tty.c | 123 |
14 files changed, 554 insertions, 237 deletions
diff --git a/usr.bin/tmux/Makefile b/usr.bin/tmux/Makefile index f03d53c65e5..9c238b3b207 100644 --- a/usr.bin/tmux/Makefile +++ b/usr.bin/tmux/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.103 2020/03/24 08:09:43 nicm Exp $ +# $OpenBSD: Makefile,v 1.104 2020/04/20 13:25:36 nicm Exp $ PROG= tmux SRCS= alerts.c \ @@ -111,6 +111,7 @@ SRCS= alerts.c \ style.c \ tmux.c \ tty-acs.c \ + tty-features.c \ tty-keys.c \ tty-term.c \ tty.c \ diff --git a/usr.bin/tmux/client.c b/usr.bin/tmux/client.c index ccb3ddce812..351002a14d0 100644 --- a/usr.bin/tmux/client.c +++ b/usr.bin/tmux/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.141 2020/04/13 08:26:27 nicm Exp $ */ +/* $OpenBSD: client.c,v 1.142 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -57,7 +57,7 @@ static struct client_files client_files = RB_INITIALIZER(&client_files); static __dead void client_exec(const char *,const char *); static int client_get_lock(char *); static int client_connect(struct event_base *, const char *, int); -static void client_send_identify(const char *, const char *); +static void client_send_identify(const char *, const char *, int); static void client_signal(int); static void client_dispatch(struct imsg *, void *); static void client_dispatch_attached(struct imsg *); @@ -233,7 +233,7 @@ client_exit(void) /* Client main loop. */ int -client_main(struct event_base *base, int argc, char **argv, int flags) +client_main(struct event_base *base, int argc, char **argv, int flags, int feat) { struct cmd_parse_result *pr; struct msg_command *data; @@ -340,7 +340,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags) } /* Send identify messages. */ - client_send_identify(ttynam, cwd); + client_send_identify(ttynam, cwd, feat); /* Send first command. */ if (msg == MSG_COMMAND) { @@ -406,7 +406,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags) /* Send identify messages to server. */ static void -client_send_identify(const char *ttynam, const char *cwd) +client_send_identify(const char *ttynam, const char *cwd, int feat) { const char *s; char **ss; @@ -419,6 +419,7 @@ client_send_identify(const char *ttynam, const char *cwd) if ((s = getenv("TERM")) == NULL) s = ""; proc_send(client_peer, MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1); + proc_send(client_peer, MSG_IDENTIFY_FEATURES, -1, &feat, sizeof feat); proc_send(client_peer, MSG_IDENTIFY_TTYNAME, -1, ttynam, strlen(ttynam) + 1); diff --git a/usr.bin/tmux/cmd-show-messages.c b/usr.bin/tmux/cmd-show-messages.c index daef7aa884a..2d832e6f412 100644 --- a/usr.bin/tmux/cmd-show-messages.c +++ b/usr.bin/tmux/cmd-show-messages.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-show-messages.c,v 1.31 2020/04/13 20:54:15 nicm Exp $ */ +/* $OpenBSD: cmd-show-messages.c,v 1.32 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -43,22 +43,24 @@ const struct cmd_entry cmd_show_messages_entry = { .exec = cmd_show_messages_exec }; -static int cmd_show_messages_terminals(struct cmdq_item *, int); - static int -cmd_show_messages_terminals(struct cmdq_item *item, int blank) +cmd_show_messages_terminals(struct cmd *self, struct cmdq_item *item, int blank) { + struct args *args = cmd_get_args(self); + struct client *tc = cmdq_get_target_client(item); struct tty_term *term; u_int i, n; n = 0; LIST_FOREACH(term, &tty_terms, entry) { + if (args_has(args, 't') && term != tc->tty.term) + continue; if (blank) { cmdq_print(item, "%s", ""); blank = 0; } - cmdq_print(item, "Terminal %u: %s [references=%u, flags=0x%x]:", - n, term->name, term->references, term->flags); + cmdq_print(item, "Terminal %u: %s for %s, flags=0x%x:", n, + term->name, term->tty->client->name, term->flags); n++; for (i = 0; i < tty_term_ncodes(); i++) cmdq_print(item, "%s", tty_term_describe(term, i)); @@ -77,7 +79,7 @@ cmd_show_messages_exec(struct cmd *self, struct cmdq_item *item) done = blank = 0; if (args_has(args, 'T')) { - blank = cmd_show_messages_terminals(item, blank); + blank = cmd_show_messages_terminals(self, item, blank); done = 1; } if (args_has(args, 'J')) { diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c index 7ed4444bfe4..e39f7ef58bd 100644 --- a/usr.bin/tmux/format.c +++ b/usr.bin/tmux/format.c @@ -1,4 +1,4 @@ -/* $OpenBSD: format.c,v 1.245 2020/04/18 14:21:39 nicm Exp $ */ +/* $OpenBSD: format.c,v 1.246 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -2553,8 +2553,9 @@ format_defaults_client(struct format_tree *ft, struct client *c) format_add(ft, "client_control_mode", "%d", !!(c->flags & CLIENT_CONTROL)); - if (tty->term_name != NULL) - format_add(ft, "client_termname", "%s", tty->term_name); + format_add(ft, "client_termname", "%s", c->term_name); + format_add(ft, "client_termfeatures", "%s", + tty_get_features(c->term_features)); format_add_tv(ft, "client_created", &c->creation_time); format_add_tv(ft, "client_activity", &c->activity_time); @@ -2569,7 +2570,7 @@ format_defaults_client(struct format_tree *ft, struct client *c) format_add(ft, "client_prefix", "%d", 1); format_add(ft, "client_key_table", "%s", c->keytable->name); - if (tty_get_flags(tty) & TERM_UTF8) + if (c->flags & CLIENT_UTF8) format_add(ft, "client_utf8", "%d", 1); else format_add(ft, "client_utf8", "%d", 0); diff --git a/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c index b6b48ee128a..2af43f68f35 100644 --- a/usr.bin/tmux/options-table.c +++ b/usr.bin/tmux/options-table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options-table.c,v 1.117 2020/04/17 08:03:22 nicm Exp $ */ +/* $OpenBSD: options-table.c,v 1.118 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -261,9 +261,16 @@ const struct options_table_entry options_table[] = { .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SERVER, .flags = OPTIONS_TABLE_IS_ARRAY, - .default_str = "xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007" - ":Cs=\\E]12;%p1%s\\007:Cr=\\E]112\\007" - ":Ss=\\E[%p1%d q:Se=\\E[2 q,screen*:XT", + .default_str = "tmux*:XT,screen*:XT", + .separator = "," + }, + + { .name = "terminal-features", + .type = OPTIONS_TABLE_STRING, + .scope = OPTIONS_TABLE_SERVER, + .flags = OPTIONS_TABLE_IS_ARRAY, + .default_str = "xterm*:clipboard:ccolour:cstyle:title," + "screen*:title", .separator = "," }, diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index 70e9319e6e6..ad218fecd38 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.328 2020/04/20 09:07:55 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.329 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -296,7 +296,7 @@ server_client_lost(struct client *c) if (c->flags & CLIENT_TERMINAL) tty_free(&c->tty); free(c->ttyname); - free(c->term); + free(c->term_name); status_free(c); @@ -1845,6 +1845,7 @@ server_client_dispatch(struct imsg *imsg, void *arg) datalen = imsg->hdr.len - IMSG_HEADER_SIZE; switch (imsg->hdr.type) { + case MSG_IDENTIFY_FEATURES: case MSG_IDENTIFY_FLAGS: case MSG_IDENTIFY_TERM: case MSG_IDENTIFY_TTYNAME: @@ -2003,7 +2004,7 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg) { const char *data, *home; size_t datalen; - int flags; + int flags, feat; char *name; if (c->flags & CLIENT_IDENTIFIED) @@ -2013,6 +2014,14 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg) datalen = imsg->hdr.len - IMSG_HEADER_SIZE; switch (imsg->hdr.type) { + case MSG_IDENTIFY_FEATURES: + if (datalen != sizeof feat) + fatalx("bad MSG_IDENTIFY_FEATURES size"); + memcpy(&feat, data, sizeof feat); + c->term_features |= feat; + log_debug("client %p IDENTIFY_FEATURES %s", c, + tty_get_features(feat)); + break; case MSG_IDENTIFY_FLAGS: if (datalen != sizeof flags) fatalx("bad MSG_IDENTIFY_FLAGS size"); @@ -2023,7 +2032,10 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg) case MSG_IDENTIFY_TERM: if (datalen == 0 || data[datalen - 1] != '\0') fatalx("bad MSG_IDENTIFY_TERM string"); - c->term = xstrdup(data); + if (*data == '\0') + c->term_name = xstrdup("unknown"); + else + c->term_name = xstrdup(data); log_debug("client %p IDENTIFY_TERM %s", c, data); break; case MSG_IDENTIFY_TTYNAME: @@ -2084,14 +2096,10 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg) control_start(c); c->tty.fd = -1; } else if (c->fd != -1) { - if (tty_init(&c->tty, c, c->fd, c->term) != 0) { + if (tty_init(&c->tty, c, c->fd) != 0) { close(c->fd); c->fd = -1; } else { - if (c->flags & CLIENT_UTF8) - c->tty.term_flags |= TERM_UTF8; - if (c->flags & CLIENT_256COLOURS) - c->tty.term_flags |= TERM_256COLOURS; tty_resize(&c->tty); c->flags |= CLIENT_TERMINAL; } diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 134f25d2a31..40580596df4 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.743 2020/04/18 07:19:29 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.744 2020/04/20 13:25:36 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: April 18 2020 $ +.Dd $Mdocdate: April 20 2020 $ .Dt TMUX 1 .Os .Sh NAME @@ -28,6 +28,7 @@ .Op Fl f Ar file .Op Fl L Ar socket-name .Op Fl S Ar socket-path +.Op Fl T Ar features .Op Ar command Op Ar flags .Ek .Sh DESCRIPTION @@ -98,6 +99,8 @@ The options are as follows: Force .Nm to assume the terminal supports 256 colours. +This is equivalent to +.Fl T Ar 256 . .It Fl C Start in control mode (see the .Sx CONTROL MODE @@ -186,6 +189,14 @@ that is set does not contain .Qq UTF-8 or .Qq UTF8 . +This is equivalent to +.Fl T Ar UTF-8 . +.It Fl T Ar features +Set terminal features for the client. +This is a comma-separated list of features. +See the +.Ic terminal-features +option. .It Fl v Request verbose logging. Log messages will be saved into @@ -3166,6 +3177,63 @@ disallowedWindowOps: 20,21,SetXprop Or changing this property from the .Xr xterm 1 interactive menu when required. +.It Ic terminal-features[] Ar string +Set terminal features for terminal types read from +.Xr terminfo 5 . +.Nm +has a set of named terminal features. +Each will apply appropriate changes to the +.Xr terminfo 5 +entry in use. +.Pp +.Nm +can detect features for a few common terminals; this option can be used to +easily tell tmux about features supported by terminals it cannot detect. +The +.Ic terminal-overrides +option allows individual +.Xr terminfo 5 +capabilities to be set instead, +.Ic terminal-features +is intended for classes of functionality supported in a standard way but not +reported by +.Xr terminfo 5 . +Care must be taken only to configure this with features the terminal actually +support. +.Pp +This is an array option where each entry is a colon-separated string made up +of a terminal type pattern (matched using +.Xr fnmatch 3 ) +followed by a list of terminal features. +The available features are: +.Bl -tag -width Ds +.It 256 +Supports 256 colours with the SGR escape sequences. +.It clipboard +Allows setting the system clipboard. +.It ccolour +Allows setting the cursor colour. +.It cstyle +Allows setting the cursor style. +.It margins +Supports DECSLRM margins. +.It overline +Supports the overline SGR attribute. +.It rectfill +Supports the DECFRA rectangle fill escape sequence. +.It RGB +Supports RGB colour with the SGR escape sequences. +.It sync +Supports synchronized updates. +.It title +Supports +.Xr xterm 1 +title setting. +.It usstyle +Allows underscore style and colour to be set. +.It UTF-8 +Is able to handle UTF-8 output. +.El .It Ic terminal-overrides[] Ar string Allow terminal descriptions read using .Xr terminfo 5 @@ -4383,6 +4451,7 @@ The following variables are available, where appropriate: .It Li "client_readonly" Ta "" Ta "1 if client is readonly" .It Li "client_session" Ta "" Ta "Name of the client's session" .It Li "client_termname" Ta "" Ta "Terminal name of client" +.It Li "client_termfeatures" Ta "" Ta "Terminal features of client" .It Li "client_tty" Ta "" Ta "Pseudo terminal of client" .It Li "client_utf8" Ta "" Ta "1 if client supports UTF-8" .It Li "client_width" Ta "" Ta "Width of client" @@ -5465,7 +5534,10 @@ The server crashed or otherwise exited without telling the client the reason. .Sh TERMINFO EXTENSIONS .Nm understands some unofficial extensions to -.Xr terminfo 5 : +.Xr terminfo 5. +It is not normally necessary to set these manually, instead the +.Ic terminal-features +option should be used. .Bl -tag -width Ds .It Em \&Cs , Cr Set the cursor colour. @@ -5479,33 +5551,15 @@ $ printf '\e033]12;red\e033\e\e' .Ed .It Em \&Smol Enable the overline attribute. -The capability is usually SGR 53 and can be added to -.Ic terminal-overrides -as: -.Bd -literal -offset indent -Smol=\eE[53m -.Ed .It Em \&Smulx Set a styled underscore. The single parameter is one of: 0 for no underscore, 1 for normal underscore, 2 for double underscore, 3 for curly underscore, 4 for dotted underscore and 5 for dashed underscore. -The capability can typically be added to -.Ic terminal-overrides -as: -.Bd -literal -offset indent -Smulx=\eE[4::%p1%dm -.Ed .It Em \&Setulc Set the underscore colour. The argument is (red * 65536) + (green * 256) + blue where each is between 0 and 255. -The capability can typically be added to -.Ic terminal-overrides -as: -.Bd -literal -offset indent -Setulc=\eE[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m -.Ed .It Em \&Ss , Se Set or reset the cursor style. If set, a sequence such as this may be used diff --git a/usr.bin/tmux/tmux.c b/usr.bin/tmux/tmux.c index 52cadfbae66..17b39263f57 100644 --- a/usr.bin/tmux/tmux.c +++ b/usr.bin/tmux/tmux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.c,v 1.197 2020/04/16 07:28:36 nicm Exp $ */ +/* $OpenBSD: tmux.c,v 1.198 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -58,7 +58,7 @@ usage(void) { fprintf(stderr, "usage: %s [-2CluvV] [-c shell-command] [-f file] [-L socket-name]\n" - " [-S socket-path] [command [flags]]\n", + " [-S socket-path] [-T features] [command [flags]]\n", getprogname()); exit(1); } @@ -242,9 +242,11 @@ getversion(void) int main(int argc, char **argv) { - char *path, *label, *cause, **var; + char *path = NULL, *label = NULL; + char *cause, **var; const char *s, *shell, *cwd; - int opt, flags, keys; + int opt, flags = 0, keys; + int feat = 0; const struct options_table_entry *oe; if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL && @@ -261,14 +263,11 @@ main(int argc, char **argv) if (**argv == '-') flags = CLIENT_LOGIN; - else - flags = 0; - label = path = NULL; - while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:uUvV")) != -1) { + while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:T:uUvV")) != -1) { switch (opt) { case '2': - flags |= CLIENT_256COLOURS; + tty_add_features(&feat, "256", ":,"); break; case 'c': shell_command = optarg; @@ -298,6 +297,9 @@ main(int argc, char **argv) free(path); path = xstrdup(optarg); break; + case 'T': + tty_add_features(&feat, optarg, ":,"); + break; case 'u': flags |= CLIENT_UTF8; break; @@ -405,5 +407,5 @@ main(int argc, char **argv) free(label); /* Pass control to the client. */ - exit(client_main(event_init(), argc, argv, flags)); + exit(client_main(event_init(), argc, argv, flags, feat)); } diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 302a7547805..dab2b8db95c 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1010 2020/04/18 21:35:32 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1011 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -474,6 +474,7 @@ enum msgtype { MSG_IDENTIFY_DONE, MSG_IDENTIFY_CLIENTPID, MSG_IDENTIFY_CWD, + MSG_IDENTIFY_FEATURES, MSG_COMMAND = 200, MSG_DETACH, @@ -1176,7 +1177,8 @@ struct tty_key { struct tty_code; struct tty_term { char *name; - u_int references; + struct tty *tty; + int features; char acs[UCHAR_MAX + 1][2]; @@ -1187,8 +1189,6 @@ struct tty_term { #define TERM_DECSLRM 0x4 #define TERM_DECFRA 0x8 #define TERM_RGBCOLOURS 0x10 -#define TERM_SYNC 0x20 -#define TERM_UTF8 0x40 int flags; LIST_ENTRY(tty_term) entry; @@ -1252,8 +1252,6 @@ struct tty { int flags; struct tty_term *term; - char *term_name; - int term_flags; u_int mouse_last_x; u_int mouse_last_y; @@ -1267,7 +1265,6 @@ struct tty { struct event key_timer; struct tty_key *key_tree; }; -#define tty_term_flags(tty) (tty->term->flags|tty->term_flags) /* TTY command context. */ struct tty_ctx { @@ -1498,7 +1495,9 @@ struct client { char *title; const char *cwd; - char *term; + char *term_name; + int term_features; + char *ttyname; struct tty tty; @@ -1531,7 +1530,7 @@ struct client { #define CLIENT_CONTROLCONTROL 0x4000 #define CLIENT_FOCUSED 0x8000 #define CLIENT_UTF8 0x10000 -#define CLIENT_256COLOURS 0x20000 +/* 0x20000 unused */ #define CLIENT_IDENTIFIED 0x40000 #define CLIENT_STATUSFORCE 0x80000 #define CLIENT_DOUBLECLICK 0x100000 @@ -1953,7 +1952,7 @@ void tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, void tty_puts(struct tty *, const char *); void tty_putc(struct tty *, u_char); void tty_putn(struct tty *, const void *, size_t, u_int); -int tty_init(struct tty *, struct client *, int, char *); +int tty_init(struct tty *, struct client *, int); void tty_resize(struct tty *); void tty_set_size(struct tty *, u_int, u_int, u_int, u_int); void tty_start_tty(struct tty *); @@ -1968,8 +1967,7 @@ void tty_sync_end(struct tty *); int tty_open(struct tty *, char **); void tty_close(struct tty *); void tty_free(struct tty *); -void tty_set_flags(struct tty *, int); -int tty_get_flags(struct tty *); +void tty_update_features(struct tty *); void tty_write(void (*)(struct tty *, const struct tty_ctx *), struct tty_ctx *); void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *); @@ -1999,7 +1997,8 @@ void tty_cmd_syncend(struct tty *, const struct tty_ctx *); /* tty-term.c */ extern struct tty_terms tty_terms; u_int tty_term_ncodes(void); -struct tty_term *tty_term_find(char *, int, char **); +void tty_term_apply(struct tty_term *, const char *, int); +struct tty_term *tty_term_create(struct tty *, char *, int *, 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); @@ -2016,6 +2015,11 @@ int tty_term_number(struct tty_term *, enum tty_code_code); int tty_term_flag(struct tty_term *, enum tty_code_code); const char *tty_term_describe(struct tty_term *, enum tty_code_code); +/* tty-features.c */ +void tty_add_features(int *, const char *, const char *); +const char *tty_get_features(int); +void tty_apply_features(struct tty_term *, int); + /* tty-acs.c */ int tty_acs_needed(struct tty *); const char *tty_acs_get(struct tty *, u_char); @@ -2161,7 +2165,7 @@ void printflike(2, 3) cmdq_error(struct cmdq_item *, const char *, ...); void cmd_wait_for_flush(void); /* client.c */ -int client_main(struct event_base *, int, char **, int); +int client_main(struct event_base *, int, char **, int, int); /* key-bindings.c */ struct key_table *key_bindings_get_table(const char *, int); diff --git a/usr.bin/tmux/tty-acs.c b/usr.bin/tmux/tty-acs.c index 6cc369f0fe8..cd6c720b09a 100644 --- a/usr.bin/tmux/tty-acs.c +++ b/usr.bin/tmux/tty-acs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-acs.c,v 1.8 2020/04/16 14:25:35 nicm Exp $ */ +/* $OpenBSD: tty-acs.c,v 1.9 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -99,7 +99,7 @@ tty_acs_needed(struct tty *tty) tty_term_number(tty->term, TTYC_U8) == 0) return (1); - if (tty_get_flags(tty) & TERM_UTF8) + if (tty->client->flags & CLIENT_UTF8) return (0); return (1); } diff --git a/usr.bin/tmux/tty-features.c b/usr.bin/tmux/tty-features.c new file mode 100644 index 00000000000..1ed9a37505f --- /dev/null +++ b/usr.bin/tmux/tty-features.c @@ -0,0 +1,264 @@ +/* $OpenBSD: tty-features.c,v 1.1 2020/04/20 13:25:36 nicm Exp $ */ + +/* + * Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com> + * + * 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 <sys/types.h> + +#include <stdlib.h> +#include <string.h> + +#include "tmux.h" + +/* + * Still hardcoded: + * - bracket paste (sent if application asks for it); + * - mouse (under kmous capability); + * - focus events (under focus-events option); + * - default colours (under AX or op capabilities); + * - AIX colours (under colors >= 16); + * - alternate escape (under XT). + * + * Also: + * - XT is used to decide whether to send DA and DSR, + * - DECSLRM and DECFRA use a flag instead of capabilities. + * - Sync is a flag rather than a string capability. + * - UTF-8 is a separate flag on the client; needed for unattached clients. + */ + +/* A named terminal feature. */ +struct tty_feature { + const char *name; + const char **capabilities; + int flags; +}; + +/* Terminal has xterm(1) title setting. */ +static const char *tty_feature_title_capabilities[] = { + "tsl=\\E]0;", /* should be using TS really */ + "fsl=\\a", + NULL +}; +static struct tty_feature tty_feature_title = { + "title", + tty_feature_title_capabilities, + 0 +}; + +/* Terminal can set the clipboard with OSC 52. */ +static const char *tty_feature_clipboard_capabilities[] = { + "Ms=\\E]52;%p1%s;%p2%s\\a", + NULL +}; +static struct tty_feature tty_feature_clipboard = { + "clipboard", + tty_feature_clipboard_capabilities, + 0 +}; + +/* + * Terminal supports RGB colour. This replaces setab and setaf also since + * terminals with RGB have versions that do not allow setting colours from the + * 256 palette. + */ +static const char *tty_feature_rgb_capabilities[] = { + "setrgbf=\\E[38;2;%p1%d;%p2%d;%p3%dm", + "setrgbb=\\E[48;2;%p1%d;%p2%d;%p3%dm", + "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", + "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", + NULL +}; +static struct tty_feature tty_feature_rgb = { + "RGB", + tty_feature_rgb_capabilities, + (TERM_256COLOURS|TERM_RGBCOLOURS) +}; + +/* Terminal supports 256 colours. */ +static const char *tty_feature_256_capabilities[] = { + "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", + "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", + NULL +}; +static struct tty_feature tty_feature_256 = { + "256", + tty_feature_256_capabilities, + TERM_256COLOURS +}; + +/* Terminal supports overline. */ +static const char *tty_feature_overline_capabilities[] = { + "Smol=\\E[53m", + NULL +}; +static struct tty_feature tty_feature_overline = { + "overline", + tty_feature_overline_capabilities, + 0 +}; + +/* Terminal supports underscore styles. */ +static const char *tty_feature_usstyle_capabilities[] = { + "Smulx=\E[4::%p1%dm", + "Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m", + NULL +}; +static struct tty_feature tty_feature_usstyle = { + "usstyle", + tty_feature_usstyle_capabilities, + 0 +}; + +/* Terminal supports cursor styles. */ +static const char *tty_feature_cstyle_capabilities[] = { + "Ss=\\E[%p1%d q", + "Se=\\E[2 q", + NULL +}; +static struct tty_feature tty_feature_cstyle = { + "cstyle", + tty_feature_cstyle_capabilities, + 0 +}; + +/* Terminal supports cursor colours. */ +static const char *tty_feature_ccolour_capabilities[] = { + "Cs=\\E]12;%p1%s\\a", + "Cr=\\E]112\\a", + NULL +}; +static struct tty_feature tty_feature_ccolour = { + "ccolour", + tty_feature_ccolour_capabilities, + 0 +}; + +/* Terminal supports synchronized updates. */ +static const char *tty_feature_sync_capabilities[] = { + "Sync", + NULL +}; +static struct tty_feature tty_feature_sync = { + "sync", + tty_feature_sync_capabilities, + 0 +}; + +/* Terminal supports DECSLRM margins. */ +static struct tty_feature tty_feature_margins = { + "margins", + NULL, + TERM_DECSLRM +}; + +/* Terminal supports DECFRA rectangle fill. */ +static struct tty_feature tty_feature_rectfill = { + "rectfill", + NULL, + TERM_DECFRA +}; + +/* Available terminal features. */ +static const struct tty_feature *tty_features[] = { + &tty_feature_256, + &tty_feature_clipboard, + &tty_feature_ccolour, + &tty_feature_cstyle, + &tty_feature_margins, + &tty_feature_overline, + &tty_feature_rectfill, + &tty_feature_rgb, + &tty_feature_sync, + &tty_feature_title, + &tty_feature_usstyle +}; + +void +tty_add_features(int *feat, const char *s, const char *separators) +{ + const struct tty_feature *tf; + char *next, *loop, *copy; + u_int i; + + loop = copy = xstrdup(s); + while ((next = strsep(&loop, separators)) != NULL) { + for (i = 0; i < nitems(tty_features); i++) { + tf = tty_features[i]; + if (strcasecmp(tf->name, next) == 0) + break; + } + if (i == nitems(tty_features)) { + log_debug("unknown terminal feature: %s", next); + break; + } + if (~(*feat) & (1 << i)) { + log_debug("adding terminal feature: %s", tf->name); + (*feat) |= (1 << i); + } + } + free(copy); +} + +const char * +tty_get_features(int feat) +{ + const struct tty_feature *tf; + static char s[512]; + u_int i; + + *s = '\0'; + for (i = 0; i < nitems(tty_features); i++) { + if (~feat & (1 << i)) + continue; + tf = tty_features[i]; + + strlcat(s, tf->name, sizeof s); + strlcat(s, ",", sizeof s); + } + if (*s != '\0') + s[strlen(s) - 1] = '\0'; + return (s); +} + +void +tty_apply_features(struct tty_term *term, int feat) +{ + const struct tty_feature *tf; + const char **capability; + u_int i; + + if (feat == 0) + return; + log_debug("applying terminal features: %s", tty_get_features(feat)); + + for (i = 0; i < nitems(tty_features); i++) { + if ((term->features & (1 << i)) || (~feat & (1 << i))) + continue; + tf = tty_features[i]; + + log_debug("applying terminal feature: %s", tf->name); + if (tf->capabilities != NULL) { + capability = tf->capabilities; + while (*capability != NULL) { + log_debug("adding capability: %s", *capability); + tty_term_apply(term, *capability, 1); + capability++; + } + } + term->flags |= tf->flags; + } + term->features |= feat; +} diff --git a/usr.bin/tmux/tty-keys.c b/usr.bin/tmux/tty-keys.c index 01bfad593bd..37747d3ed6a 100644 --- a/usr.bin/tmux/tty-keys.c +++ b/usr.bin/tmux/tty-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-keys.c,v 1.125 2020/04/17 09:06:10 nicm Exp $ */ +/* $OpenBSD: tty-keys.c,v 1.126 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1020,7 +1020,6 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len, struct client *c = tty->client; u_int i, n = 0; char tmp[64], *endptr, p[32] = { 0 }, *cp, *next; - int flags = 0; *size = 0; if (tty->flags & TTY_HAVEDA) @@ -1060,24 +1059,42 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len, n++; } - /* Set terminal flags. */ + /* Add terminal features. */ switch (p[0]) { case 41: /* VT420 */ - flags |= (TERM_DECFRA|TERM_DECSLRM); + tty_add_features(&c->term_features, + "margins," + "rectfill", + ","); break; case 'M': /* mintty */ - flags |= (TERM_256COLOURS|TERM_RGBCOLOURS); + tty_add_features(&c->term_features, + "256," + "RGB," + "title", + ","); break; - case 'T': /* tmux - new versons reply to DSR which will set RGB */ - flags |= (TERM_UTF8|TERM_256COLOURS); + case 'T': /* tmux */ + tty_add_features(&c->term_features, + "256," + "RGB," + "ccolour," + "cstyle," + "overline," + "title," + "usstyle", + ","); break; case 'U': /* rxvt-unicode */ - flags |= (TERM_UTF8); + tty_add_features(&c->term_features, + "256," + "title", + ","); break; } log_debug("%s: received secondary DA %.*s", c->name, (int)*size, buf); - tty_set_flags(tty, flags); + tty_update_features(tty); tty->flags |= TTY_HAVEDA; return (0); @@ -1094,7 +1111,6 @@ tty_keys_device_status_report(struct tty *tty, const char *buf, size_t len, struct client *c = tty->client; u_int i; char tmp[64]; - int flags = 0; *size = 0; if (tty->flags & TTY_HAVEDSR) @@ -1125,15 +1141,31 @@ tty_keys_device_status_report(struct tty *tty, const char *buf, size_t len, tmp[i] = '\0'; *size = 3 + i; - /* Set terminal flags. */ + /* Add terminal features. */ if (strncmp(tmp, "ITERM2 ", 7) == 0) { - flags |= (TERM_UTF8|TERM_DECSLRM|TERM_SYNC|TERM_256COLOURS| - TERM_RGBCOLOURS); - } else if (strncmp(tmp, "TMUX ", 5) == 0) - flags |= (TERM_UTF8|TERM_256COLOURS|TERM_RGBCOLOURS); + tty_add_features(&c->term_features, + "256," + "RGB," + "clipboard," + "cstyle," + "margins," + "sync," + "title,", + ","); + } else if (strncmp(tmp, "TMUX ", 5) == 0) { + tty_add_features(&c->term_features, + "256," + "RGB," + "ccolour," + "cstyle," + "overline," + "title," + "usstyle", + ","); + } log_debug("%s: received DSR %.*s", c->name, (int)*size, buf); - tty_set_flags(tty, flags); + tty_update_features(tty); tty->flags |= TTY_HAVEDSR; return (0); diff --git a/usr.bin/tmux/tty-term.c b/usr.bin/tmux/tty-term.c index ef95f6a1913..b74367eb34e 100644 --- a/usr.bin/tmux/tty-term.c +++ b/usr.bin/tmux/tty-term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty-term.c,v 1.72 2020/04/16 13:35:24 nicm Exp $ */ +/* $OpenBSD: tty-term.c,v 1.73 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -27,7 +27,6 @@ #include "tmux.h" -static void tty_term_override(struct tty_term *, const char *); static char *tty_term_strip(const char *); struct tty_terms tty_terms = LIST_HEAD_INITIALIZER(tty_terms); @@ -335,22 +334,18 @@ tty_term_override_next(const char *s, size_t *offset) return (value); } -static void -tty_term_override(struct tty_term *term, const char *override) +void +tty_term_apply(struct tty_term *term, const char *capabilities, int quiet) { const struct tty_term_code_entry *ent; struct tty_code *code; size_t offset = 0; char *cp, *value, *s; - const char *errstr; + const char *errstr, *name = term->name; u_int i; int n, remove; - s = tty_term_override_next(override, &offset); - if (s == NULL || fnmatch(s, term->name, 0) != 0) - return; - - while ((s = tty_term_override_next(override, &offset)) != NULL) { + while ((s = tty_term_override_next(capabilities, &offset)) != NULL) { if (*s == '\0') continue; value = NULL; @@ -369,12 +364,14 @@ tty_term_override(struct tty_term *term, const char *override) } else value = xstrdup(""); - if (remove) - log_debug("%s override: %s@", term->name, s); - else if (*value == '\0') - log_debug("%s override: %s", term->name, s); - else - log_debug("%s override: %s=%s", term->name, s, value); + if (!quiet) { + if (remove) + log_debug("%s override: %s@", name, s); + else if (*value == '\0') + log_debug("%s override: %s", name, s); + else + log_debug("%s override: %s=%s", name, s, value); + } for (i = 0; i < tty_term_ncodes(); i++) { ent = &tty_term_codes[i]; @@ -414,7 +411,7 @@ tty_term_override(struct tty_term *term, const char *override) } struct tty_term * -tty_term_find(char *name, int fd, char **cause) +tty_term_create(struct tty *tty, char *name, int *feat, int fd, char **cause) { struct tty_term *term; const struct tty_term_code_entry *ent; @@ -425,19 +422,14 @@ tty_term_find(char *name, int fd, char **cause) u_int i; int n, error; const char *s, *acs; + size_t offset; + char *first; - LIST_FOREACH(term, &tty_terms, entry) { - if (strcmp(term->name, name) == 0) { - term->references++; - return (term); - } - } - log_debug("new term: %s", name); + log_debug("adding term %s", name); - term = xmalloc(sizeof *term); + term = xcalloc(1, sizeof *term); + term->tty = tty; term->name = xstrdup(name); - term->references = 1; - term->flags = 0; term->codes = xcalloc(tty_term_ncodes(), sizeof *term->codes); LIST_INSERT_HEAD(&tty_terms, term, entry); @@ -495,12 +487,31 @@ tty_term_find(char *name, int fd, char **cause) } } + /* Apply terminal features. */ + o = options_get_only(global_options, "terminal-features"); + a = options_array_first(o); + while (a != NULL) { + ov = options_array_item_value(a); + s = ov->string; + + offset = 0; + first = tty_term_override_next(s, &offset); + if (first != NULL && fnmatch(first, term->name, 0) == 0) + tty_add_features(feat, s + offset, ":"); + a = options_array_next(a); + } + /* Apply terminal overrides. */ o = options_get_only(global_options, "terminal-overrides"); a = options_array_first(o); while (a != NULL) { ov = options_array_item_value(a); - tty_term_override(term, ov->string); + s = ov->string; + + offset = 0; + first = tty_term_override_next(s, &offset); + if (first != NULL && fnmatch(first, term->name, 0) == 0) + tty_term_apply(term, s + offset, 0); a = options_array_next(a); } @@ -523,19 +534,18 @@ tty_term_find(char *name, int fd, char **cause) goto error; } - /* Set flag if terminal has 256 colours. */ - if (tty_term_number(term, TTYC_COLORS) >= 256) - term->flags |= TERM_256COLOURS; + /* Add RGB feature if terminal has RGB colours. */ + if ((tty_term_flag(term, TTYC_TC) || tty_term_has(term, TTYC_RGB)) && + (!tty_term_has(term, TTYC_SETRGBF) || + !tty_term_has(term, TTYC_SETRGBB))) + tty_add_features(feat, "RGB", ":,"); - /* Set flag if terminal has RGB colours. */ - if ((tty_term_flag(term, TTYC_TC) || tty_term_has(term, TTYC_RGB)) || - (tty_term_has(term, TTYC_SETRGBF) && - tty_term_has(term, TTYC_SETRGBB))) - term->flags |= TERM_RGBCOLOURS; + /* Add feature if terminal has XT. */ + if (tty_term_flag(term, TTYC_XT)) + tty_add_features(feat, "title", ":,"); - /* Set flag if terminal has synchronized updates. */ - if (tty_term_flag(term, TTYC_SYNC)) - term->flags |= TERM_SYNC; + /* Apply the features. */ + tty_apply_features(term, *feat); /* * Terminals without xenl (eat newline glitch) wrap at at $COLUMNS - 1 @@ -559,18 +569,6 @@ tty_term_find(char *name, int fd, char **cause) for (; acs[0] != '\0' && acs[1] != '\0'; acs += 2) term->acs[(u_char) acs[0]][0] = acs[1]; - /* On terminals with xterm titles (XT), fill in tsl and fsl. */ - if (tty_term_flag(term, TTYC_XT) && - !tty_term_has(term, TTYC_TSL) && - !tty_term_has(term, TTYC_FSL)) { - code = &term->codes[TTYC_TSL]; - code->value.string = xstrdup("\033]0;"); - code->type = TTYCODE_STRING; - code = &term->codes[TTYC_FSL]; - code->value.string = xstrdup("\007"); - code->type = TTYCODE_STRING; - } - /* Log the capabilities. */ for (i = 0; i < tty_term_ncodes(); i++) log_debug("%s%s", name, tty_term_describe(term, i)); @@ -587,10 +585,7 @@ tty_term_free(struct tty_term *term) { u_int i; - if (--term->references != 0) - return; - - LIST_REMOVE(term, entry); + log_debug("removing term %s", term->name); for (i = 0; i < tty_term_ncodes(); i++) { if (term->codes[i].type == TTYCODE_STRING) @@ -598,6 +593,7 @@ tty_term_free(struct tty_term *term) } free(term->codes); + LIST_REMOVE(term, entry); free(term->name); free(term); } diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c index 1eb71ac6403..107436ce6c4 100644 --- a/usr.bin/tmux/tty.c +++ b/usr.bin/tmux/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.358 2020/04/18 07:32:54 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.359 2020/04/20 13:25:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -74,7 +74,7 @@ static void tty_default_attributes(struct tty *, struct window_pane *, u_int); #define tty_use_margin(tty) \ - (tty_get_flags(tty) & TERM_DECSLRM) + (tty->term->flags & TERM_DECSLRM) #define tty_pane_full_width(tty, ctx) \ ((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx) @@ -96,27 +96,19 @@ tty_create_log(void) } int -tty_init(struct tty *tty, struct client *c, int fd, char *term) +tty_init(struct tty *tty, struct client *c, int fd) { if (!isatty(fd)) return (-1); memset(tty, 0, sizeof *tty); - if (term == NULL || *term == '\0') - tty->term_name = xstrdup("unknown"); - else - tty->term_name = xstrdup(term); - tty->fd = fd; tty->client = c; tty->cstyle = 0; tty->ccolour = xstrdup(""); - tty->flags = 0; - tty->term_flags = 0; - return (0); } @@ -256,7 +248,10 @@ tty_write_callback(__unused int fd, __unused short events, void *data) int tty_open(struct tty *tty, char **cause) { - tty->term = tty_term_find(tty->term_name, tty->fd, cause); + struct client *c = tty->client; + + tty->term = tty_term_create(tty, c->term_name, &c->term_features, + tty->fd, cause); if (tty->term == NULL) { tty_close(tty); return (-1); @@ -466,28 +461,20 @@ void tty_free(struct tty *tty) { tty_close(tty); - free(tty->ccolour); - free(tty->term_name); } void -tty_set_flags(struct tty *tty, int flags) +tty_update_features(struct tty *tty) { - tty->term_flags |= flags; + struct client *c = tty->client; + + tty_apply_features(tty->term, c->term_features); if (tty_use_margin(tty)) tty_puts(tty, "\033[?69h"); /* DECLRMM */ } -int -tty_get_flags(struct tty *tty) -{ - if (tty->term != NULL) - return (tty->term->flags|tty->term_flags); - return (tty->term_flags); -} - void tty_raw(struct tty *tty, const char *s) { @@ -585,7 +572,7 @@ tty_putc(struct tty *tty, u_char ch) { const char *acs; - if ((tty_get_flags(tty) & TERM_NOXENL) && + if ((tty->term->flags & TERM_NOXENL) && ch >= 0x20 && ch != 0x7f && tty->cy == tty->sy - 1 && tty->cx + 1 >= tty->sx) @@ -611,7 +598,7 @@ tty_putc(struct tty *tty, u_char ch) * where we think it should be after a line wrap - this * means it works on sensible terminals as well. */ - if (tty_get_flags(tty) & TERM_NOXENL) + if (tty->term->flags & TERM_NOXENL) tty_putcode2(tty, TTYC_CUP, tty->cy, tty->cx); } else tty->cx++; @@ -621,7 +608,7 @@ tty_putc(struct tty *tty, u_char ch) void tty_putn(struct tty *tty, const void *buf, size_t len, u_int width) { - if ((tty_get_flags(tty) & TERM_NOXENL) && + if ((tty->term->flags & TERM_NOXENL) && tty->cy == tty->sy - 1 && tty->cx + len >= tty->sx) len = tty->sx - tty->cx - 1; @@ -1179,7 +1166,7 @@ tty_clear_area(struct tty *tty, struct window_pane *wp, u_int py, u_int ny, * background colour isn't default (because it doesn't work * after SGR 0). */ - if ((tty_get_flags(tty) & TERM_DECFRA) && !COLOUR_DEFAULT(bg)) { + if ((tty->term->flags & TERM_DECFRA) && !COLOUR_DEFAULT(bg)) { xsnprintf(tmp, sizeof tmp, "\033[32;%u;%u;%u;%u$x", py + 1, px + 1, py + ny, px + nx); tty_puts(tty, tmp); @@ -1258,7 +1245,7 @@ tty_check_codeset(struct tty *tty, const struct grid_cell *gc) return (gc); /* UTF-8 terminal and a UTF-8 character - fine. */ - if (tty_get_flags(tty) & TERM_UTF8) + if (tty->client->flags & CLIENT_UTF8) return (gc); /* Replace by the right number of underscores. */ @@ -1440,7 +1427,7 @@ tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s, void tty_sync_start(struct tty *tty) { - if ((~tty->flags & TTY_SYNCING) && (tty_get_flags(tty) & TERM_SYNC)) { + if ((~tty->flags & TTY_SYNCING) && tty_term_has(tty->term, TTYC_SYNC)) { tty_puts(tty, "\033P=1s\033\\"); tty->flags |= TTY_SYNCING; } @@ -1449,7 +1436,7 @@ tty_sync_start(struct tty *tty) void tty_sync_end(struct tty *tty) { - if (tty_get_flags(tty) & TERM_SYNC) { + if ((tty->flags & TTY_SYNCING) && tty_term_has(tty->term, TTYC_SYNC)) { tty_puts(tty, "\033P=2s\033\\"); tty->flags &= ~TTY_SYNCING; } @@ -1916,7 +1903,7 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) ctx->xoff + ctx->ocx + ctx->num > ctx->ox + ctx->sx)) { if (!ctx->wrapped || !tty_pane_full_width(tty, ctx) || - (tty_get_flags(tty) & TERM_NOXENL) || + (tty->term->flags & TERM_NOXENL) || ctx->xoff + ctx->ocx != 0 || ctx->yoff + ctx->ocy != tty->cy + 1 || tty->cx < tty->sx || @@ -1977,7 +1964,7 @@ tty_cell(struct tty *tty, const struct grid_cell *gc, struct window_pane *wp) const struct grid_cell *gcp; /* Skip last character if terminal is stupid. */ - if ((tty_get_flags(tty) & TERM_NOXENL) && + if ((tty->term->flags & TERM_NOXENL) && tty->cy == tty->sy - 1 && tty->cx == tty->sx - 1) return; @@ -2140,7 +2127,7 @@ tty_cursor_pane_unless_wrap(struct tty *tty, const struct tty_ctx *ctx, { if (!ctx->wrapped || !tty_pane_full_width(tty, ctx) || - (tty_get_flags(tty) & TERM_NOXENL) || + (tty->term->flags & TERM_NOXENL) || ctx->xoff + cx != 0 || ctx->yoff + cy != tty->cy + 1 || tty->cx < tty->sx || @@ -2480,14 +2467,14 @@ tty_check_fg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc) /* Is this a 24-bit colour? */ if (gc->fg & COLOUR_FLAG_RGB) { /* Not a 24-bit terminal? Translate to 256-colour palette. */ - if (tty_get_flags(tty) & TERM_RGBCOLOURS) + if (tty->term->flags & TERM_RGBCOLOURS) return; colour_split_rgb(gc->fg, &r, &g, &b); gc->fg = colour_find_rgb(r, g, b); } /* How many colours does this terminal have? */ - if (tty_get_flags(tty) & TERM_256COLOURS) + if (tty->term->flags & TERM_256COLOURS) colours = 256; else colours = tty_term_number(tty->term, TTYC_COLORS); @@ -2529,14 +2516,14 @@ tty_check_bg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc) /* Is this a 24-bit colour? */ if (gc->bg & COLOUR_FLAG_RGB) { /* Not a 24-bit terminal? Translate to 256-colour palette. */ - if (tty_get_flags(tty) & TERM_RGBCOLOURS) + if (tty->term->flags & TERM_RGBCOLOURS) return; colour_split_rgb(gc->bg, &r, &g, &b); gc->bg = colour_find_rgb(r, g, b); } /* How many colours does this terminal have? */ - if (tty_get_flags(tty) & TERM_256COLOURS) + if (tty->term->flags & TERM_256COLOURS) colours = 256; else colours = tty_term_number(tty->term, TTYC_COLORS); @@ -2597,7 +2584,7 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc) /* Is this an aixterm bright colour? */ if (gc->fg >= 90 && gc->fg <= 97) { - if (tty_get_flags(tty) & TERM_256COLOURS) { + if (tty->term->flags & TERM_256COLOURS) { xsnprintf(s, sizeof s, "\033[%dm", gc->fg); tty_puts(tty, s); } else @@ -2629,7 +2616,7 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc) /* Is this an aixterm bright colour? */ if (gc->bg >= 90 && gc->bg <= 97) { - if (tty_get_flags(tty) & TERM_256COLOURS) { + if (tty->term->flags & TERM_256COLOURS) { xsnprintf(s, sizeof s, "\033[%dm", gc->bg + 10); tty_puts(tty, s); } else @@ -2674,67 +2661,25 @@ static int tty_try_colour(struct tty *tty, int colour, const char *type) { u_char r, g, b; - char s[32]; if (colour & COLOUR_FLAG_256) { - /* - * If the user has specified -2 to the client (meaning - * TERM_256COLOURS is set), setaf and setab may not work (or - * they may not want to use them), so send the usual sequence. - * - * Also if RGB is set, setaf and setab do not support the 256 - * colour palette so use the sequences directly there too. - */ - if ((tty_get_flags(tty) & TERM_256COLOURS) || - tty_term_has(tty->term, TTYC_RGB)) - goto fallback_256; - - /* - * If the terminfo entry has 256 colours and setaf and setab - * exist, assume that they work correctly. - */ - if (tty_get_flags(tty) & TERM_256COLOURS) { - if (*type == '3') { - if (!tty_term_has(tty->term, TTYC_SETAF)) - goto fallback_256; - tty_putcode1(tty, TTYC_SETAF, colour & 0xff); - } else { - if (!tty_term_has(tty->term, TTYC_SETAB)) - goto fallback_256; - tty_putcode1(tty, TTYC_SETAB, colour & 0xff); - } - return (0); - } - goto fallback_256; + if (*type == '3' && tty_term_has(tty->term, TTYC_SETAF)) + tty_putcode1(tty, TTYC_SETAF, colour & 0xff); + else if (tty_term_has(tty->term, TTYC_SETAB)) + tty_putcode1(tty, TTYC_SETAB, colour & 0xff); + return (0); } if (colour & COLOUR_FLAG_RGB) { colour_split_rgb(colour & 0xffffff, &r, &g, &b); - if (*type == '3') { - if (!tty_term_has(tty->term, TTYC_SETRGBF)) - goto fallback_rgb; + if (*type == '3' && tty_term_has(tty->term, TTYC_SETRGBF)) tty_putcode3(tty, TTYC_SETRGBF, r, g, b); - } else { - if (!tty_term_has(tty->term, TTYC_SETRGBB)) - goto fallback_rgb; + else if (tty_term_has(tty->term, TTYC_SETRGBB)) tty_putcode3(tty, TTYC_SETRGBB, r, g, b); - } return (0); } return (-1); - -fallback_256: - xsnprintf(s, sizeof s, "\033[%s;5;%dm", type, colour & 0xff); - log_debug("%s: 256 colour fallback: %s", tty->client->name, s); - tty_puts(tty, s); - return (0); - -fallback_rgb: - xsnprintf(s, sizeof s, "\033[%s;2;%d;%d;%dm", type, r, g, b); - log_debug("%s: RGB colour fallback: %s", tty->client->name, s); - tty_puts(tty, s); - return (0); } static void |