summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/tmux/Makefile3
-rw-r--r--usr.bin/tmux/client.c11
-rw-r--r--usr.bin/tmux/cmd-show-messages.c16
-rw-r--r--usr.bin/tmux/format.c9
-rw-r--r--usr.bin/tmux/options-table.c15
-rw-r--r--usr.bin/tmux/server-client.c26
-rw-r--r--usr.bin/tmux/tmux.196
-rw-r--r--usr.bin/tmux/tmux.c22
-rw-r--r--usr.bin/tmux/tmux.h32
-rw-r--r--usr.bin/tmux/tty-acs.c4
-rw-r--r--usr.bin/tmux/tty-features.c264
-rw-r--r--usr.bin/tmux/tty-keys.c64
-rw-r--r--usr.bin/tmux/tty-term.c106
-rw-r--r--usr.bin/tmux/tty.c123
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