Merge branch 'master' into sixel

topcat001 2023-04-29 17:32:07 -07:00
commit 0d71e5853f
20 changed files with 454 additions and 134 deletions

View File

@ -14,6 +14,7 @@ dist_EXTRA_tmux_SOURCES = compat/*.[ch]
AM_CPPFLAGS += @XOPEN_DEFINES@ \ AM_CPPFLAGS += @XOPEN_DEFINES@ \
-DTMUX_VERSION='"@VERSION@"' \ -DTMUX_VERSION='"@VERSION@"' \
-DTMUX_CONF='"$(sysconfdir)/tmux.conf:~/.tmux.conf:$$XDG_CONFIG_HOME/tmux/tmux.conf:~/.config/tmux/tmux.conf"' \ -DTMUX_CONF='"$(sysconfdir)/tmux.conf:~/.tmux.conf:$$XDG_CONFIG_HOME/tmux/tmux.conf:~/.config/tmux/tmux.conf"' \
-DTMUX_LOCK_CMD='"@DEFAULT_LOCK_CMD@"' \
-DTMUX_TERM='"@DEFAULT_TERM@"' -DTMUX_TERM='"@DEFAULT_TERM@"'
# Additional object files. # Additional object files.

View File

@ -41,8 +41,9 @@ const struct cmd_entry cmd_confirm_before_entry = {
.name = "confirm-before", .name = "confirm-before",
.alias = "confirm", .alias = "confirm",
.args = { "bp:t:", 1, 1, cmd_confirm_before_args_parse }, .args = { "bc:p:t:y", 1, 1, cmd_confirm_before_args_parse },
.usage = "[-b] [-p prompt] " CMD_TARGET_CLIENT_USAGE " command", .usage = "[-by] [-c confirm_key] [-p prompt] " CMD_TARGET_CLIENT_USAGE
" command",
.flags = CMD_CLIENT_TFLAG, .flags = CMD_CLIENT_TFLAG,
.exec = cmd_confirm_before_exec .exec = cmd_confirm_before_exec
@ -51,6 +52,8 @@ const struct cmd_entry cmd_confirm_before_entry = {
struct cmd_confirm_before_data { struct cmd_confirm_before_data {
struct cmdq_item *item; struct cmdq_item *item;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
u_char confirm_key;
int default_yes;
}; };
static enum args_parse_type static enum args_parse_type
@ -68,7 +71,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
struct client *tc = cmdq_get_target_client(item); struct client *tc = cmdq_get_target_client(item);
struct cmd_find_state *target = cmdq_get_target(item); struct cmd_find_state *target = cmdq_get_target(item);
char *new_prompt; char *new_prompt;
const char *prompt, *cmd; const char *confirm_key, *prompt, *cmd;
int wait = !args_has(args, 'b'); int wait = !args_has(args, 'b');
cdata = xcalloc(1, sizeof *cdata); cdata = xcalloc(1, sizeof *cdata);
@ -79,11 +82,26 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
if (wait) if (wait)
cdata->item = item; cdata->item = item;
cdata->default_yes = args_has(args, 'y');
if ((confirm_key = args_get(args, 'c')) != NULL) {
if (confirm_key[1] == '\0' &&
confirm_key[0] > 31 &&
confirm_key[0] < 127)
cdata->confirm_key = confirm_key[0];
else {
cmdq_error(item, "invalid confirm key");
return (CMD_RETURN_ERROR);
}
}
else
cdata->confirm_key = 'y';
if ((prompt = args_get(args, 'p')) != NULL) if ((prompt = args_get(args, 'p')) != NULL)
xasprintf(&new_prompt, "%s ", prompt); xasprintf(&new_prompt, "%s ", prompt);
else { else {
cmd = cmd_get_entry(cmd_list_first(cdata->cmdlist))->name; cmd = cmd_get_entry(cmd_list_first(cdata->cmdlist))->name;
xasprintf(&new_prompt, "Confirm '%s'? (y/n) ", cmd); xasprintf(&new_prompt, "Confirm '%s'? (%c/n) ",
cmd, cdata->confirm_key);
} }
status_prompt_set(tc, target, new_prompt, NULL, status_prompt_set(tc, target, new_prompt, NULL,
@ -107,9 +125,9 @@ cmd_confirm_before_callback(struct client *c, void *data, const char *s,
if (c->flags & CLIENT_DEAD) if (c->flags & CLIENT_DEAD)
goto out; goto out;
if (s == NULL || *s == '\0') if (s == NULL)
goto out; goto out;
if (tolower((u_char)s[0]) != 'y' || s[1] != '\0') if (s[0] != cdata->confirm_key && (s[0] != '\0' || !cdata->default_yes))
goto out; goto out;
retcode = 0; retcode = 0;
@ -123,12 +141,12 @@ cmd_confirm_before_callback(struct client *c, void *data, const char *s,
} }
out: out:
if (item != NULL) { if (item != NULL) {
if (cmdq_get_client(item) != NULL && if (cmdq_get_client(item) != NULL &&
cmdq_get_client(item)->session == NULL) cmdq_get_client(item)->session == NULL)
cmdq_get_client(item)->retval = retcode; cmdq_get_client(item)->retval = retcode;
cmdq_continue(item); cmdq_continue(item);
} }
return (0); return (0);
} }

View File

@ -425,6 +425,7 @@ void *recallocarray(void *, size_t, size_t, size_t);
/* systemd.c */ /* systemd.c */
int systemd_activated(void); int systemd_activated(void);
int systemd_create_socket(int, char **); int systemd_create_socket(int, char **);
int systemd_move_pid_to_new_cgroup(pid_t, char **);
#endif #endif
#ifdef HAVE_UTF8PROC #ifdef HAVE_UTF8PROC

View File

@ -19,7 +19,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h> #include <sys/un.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-daemon.h> #include <systemd/sd-daemon.h>
#include <systemd/sd-login.h>
#include <systemd/sd-id128.h>
#include <string.h> #include <string.h>
@ -64,3 +67,149 @@ fail:
xasprintf(cause, "systemd socket error (%s)", strerror(errno)); xasprintf(cause, "systemd socket error (%s)", strerror(errno));
return (-1); return (-1);
} }
int
systemd_move_pid_to_new_cgroup(pid_t pid, char **cause)
{
sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus_message *m = NULL, *reply = NULL;
sd_bus *bus = NULL;
char *name, *desc, *slice;
sd_id128_t uuid;
int r;
pid_t parent_pid;
/* Connect to the session bus. */
r = sd_bus_default_user(&bus);
if (r < 0) {
xasprintf(cause, "failed to connect to session bus: %s",
strerror(-r));
goto finish;
}
/* Start building the method call. */
r = sd_bus_message_new_method_call(bus, &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"StartTransientUnit");
if (r < 0) {
xasprintf(cause, "failed to create bus message: %s",
strerror(-r));
goto finish;
}
/* Generate a unique name for the new scope, to avoid collisions. */
r = sd_id128_randomize(&uuid);
if (r < 0) {
xasprintf(cause, "failed to generate uuid: %s", strerror(-r));
goto finish;
}
xasprintf(&name, "tmux-spawn-" SD_ID128_UUID_FORMAT_STR ".scope",
SD_ID128_FORMAT_VAL(uuid));
r = sd_bus_message_append(m, "s", name);
free(name);
if (r < 0) {
xasprintf(cause, "failed to append to bus message: %s",
strerror(-r));
goto finish;
}
/* Mode: fail if there's a queued unit with the same name. */
r = sd_bus_message_append(m, "s", "fail");
if (r < 0) {
xasprintf(cause, "failed to append to bus message: %s",
strerror(-r));
goto finish;
}
/* Start properties array. */
r = sd_bus_message_open_container(m, 'a', "(sv)");
if (r < 0) {
xasprintf(cause, "failed to start properties array: %s",
strerror(-r));
goto finish;
}
parent_pid = getpid();
xasprintf(&desc, "tmux child pane %ld launched by process %ld",
(long)pid, (long)parent_pid);
r = sd_bus_message_append(m, "(sv)", "Description", "s", desc);
free(desc);
if (r < 0) {
xasprintf(cause, "failed to append to properties: %s",
strerror(-r));
goto finish;
}
/*
* Inherit the slice from the parent process, or default to
* "app-tmux.slice" if that fails.
*/
r = sd_pid_get_user_slice(parent_pid, &slice);
if (r < 0) {
slice = xstrdup("app-tmux.slice");
}
r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
free(slice);
if (r < 0) {
xasprintf(cause, "failed to append to properties: %s",
strerror(-r));
goto finish;
}
/* PIDs to add to the scope: length - 1 array of uint32_t. */
r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
if (r < 0) {
xasprintf(cause, "failed to append to properties: %s",
strerror(-r));
goto finish;
}
/* Clean up the scope even if it fails. */
r = sd_bus_message_append(m, "(sv)", "CollectMode", "s",
"inactive-or-failed");
if (r < 0) {
xasprintf(cause, "failed to append to properties: %s",
strerror(-r));
goto finish;
}
/* End properties array. */
r = sd_bus_message_close_container(m);
if (r < 0) {
xasprintf(cause, "failed to end properties array: %s",
strerror(-r));
goto finish;
}
/* aux is currently unused and should be passed an empty array. */
r = sd_bus_message_append(m, "a(sa(sv))", 0);
if (r < 0) {
xasprintf(cause, "failed to append to bus message: %s",
strerror(-r));
goto finish;
}
/* Call the method with a timeout of 1 second = 1e6 us. */
r = sd_bus_call(bus, m, 1000000, &error, &reply);
if (r < 0) {
if (error.message != NULL) {
/* We have a specific error message from sd-bus. */
xasprintf(cause, "StartTransientUnit call failed: %s",
error.message);
} else {
xasprintf(cause, "StartTransientUnit call failed: %s",
strerror(-r));
}
goto finish;
}
finish:
sd_bus_error_free(&error);
sd_bus_message_unref(m);
sd_bus_message_unref(reply);
sd_bus_unref(bus);
return (r);
}

View File

@ -350,6 +350,10 @@ else
AC_MSG_ERROR("curses not found") AC_MSG_ERROR("curses not found")
fi fi
fi fi
AC_CHECK_FUNCS([ \
tiparm \
tiparm_s \
])
# Look for utempter. # Look for utempter.
AC_ARG_ENABLE( AC_ARG_ENABLE(
@ -420,6 +424,21 @@ if test x"$enable_systemd" = xyes; then
fi fi
fi fi
AM_CONDITIONAL(HAVE_SYSTEMD, [test "x$found_systemd" = xyes]) AM_CONDITIONAL(HAVE_SYSTEMD, [test "x$found_systemd" = xyes])
AC_ARG_ENABLE(
cgroups,
AS_HELP_STRING(--disable-cgroups, disable adding panes to new cgroups with systemd)
)
if test "x$enable_cgroups" = x; then
# Default to the same as $enable_systemd.
enable_cgroups=$enable_systemd
fi
if test "x$enable_cgroups" = xyes; then
if test "x$found_systemd" = xyes; then
AC_DEFINE(ENABLE_CGROUPS)
else
AC_MSG_ERROR("cgroups requires systemd to be enabled")
fi
fi
# Check for b64_ntop. If we have b64_ntop, we assume b64_pton as well. # Check for b64_ntop. If we have b64_ntop, we assume b64_pton as well.
AC_MSG_CHECKING(for b64_ntop) AC_MSG_CHECKING(for b64_ntop)
@ -921,6 +940,19 @@ AM_CONDITIONAL(IS_HPUX, test "x$PLATFORM" = xhpux)
AM_CONDITIONAL(IS_HAIKU, test "x$PLATFORM" = xhaiku) AM_CONDITIONAL(IS_HAIKU, test "x$PLATFORM" = xhaiku)
AM_CONDITIONAL(IS_UNKNOWN, test "x$PLATFORM" = xunknown) AM_CONDITIONAL(IS_UNKNOWN, test "x$PLATFORM" = xunknown)
# Set the default lock command
DEFAULT_LOCK_CMD="lock -np"
AC_MSG_CHECKING(lock-command)
if test "x$PLATFORM" = xlinux; then
AC_CHECK_PROG(found_vlock, vlock, yes, no)
if test "x$found_vlock" = xyes; then
DEFAULT_LOCK_CMD="vlock"
fi
fi
AC_MSG_RESULT($DEFAULT_LOCK_CMD)
AC_SUBST(DEFAULT_LOCK_CMD)
# Save our CFLAGS/CPPFLAGS/LDFLAGS for the Makefile and restore the old user # Save our CFLAGS/CPPFLAGS/LDFLAGS for the Makefile and restore the old user
# variables. # variables.
AC_SUBST(AM_CPPFLAGS) AC_SUBST(AM_CPPFLAGS)

6
file.c
View File

@ -174,9 +174,9 @@ file_fire_read(struct client_file *cf)
int int
file_can_print(struct client *c) file_can_print(struct client *c)
{ {
if (c == NULL) if (c == NULL ||
return (0); (c->flags & CLIENT_ATTACHED) ||
if (c->session != NULL && (~c->flags & CLIENT_CONTROL)) (c->flags & CLIENT_CONTROL))
return (0); return (0);
return (1); return (1);
} }

View File

@ -1885,6 +1885,18 @@ format_cb_pane_input_off(struct format_tree *ft)
return (NULL); return (NULL);
} }
/* Callback for pane_unseen_changes. */
static void *
format_cb_pane_unseen_changes(struct format_tree *ft)
{
if (ft->wp != NULL) {
if (ft->wp->flags & PANE_UNSEENCHANGES)
return (xstrdup("1"));
return (xstrdup("0"));
}
return (NULL);
}
/* Callback for pane_last. */ /* Callback for pane_last. */
static void * static void *
format_cb_pane_last(struct format_tree *ft) format_cb_pane_last(struct format_tree *ft)
@ -2953,6 +2965,9 @@ static const struct format_table_entry format_table[] = {
{ "pane_tty", FORMAT_TABLE_STRING, { "pane_tty", FORMAT_TABLE_STRING,
format_cb_pane_tty format_cb_pane_tty
}, },
{ "pane_unseen_changes", FORMAT_TABLE_STRING,
format_cb_pane_unseen_changes
},
{ "pane_width", FORMAT_TABLE_STRING, { "pane_width", FORMAT_TABLE_STRING,
format_cb_pane_width format_cb_pane_width
}, },

View File

@ -971,6 +971,10 @@ input_parse_buffer(struct window_pane *wp, u_char *buf, size_t len)
window_update_activity(wp->window); window_update_activity(wp->window);
wp->flags |= PANE_CHANGED; wp->flags |= PANE_CHANGED;
/* Flag new input while in a mode. */
if (!TAILQ_EMPTY(&wp->modes))
wp->flags |= PANE_UNSEENCHANGES;
/* NULL wp if there is a mode set as don't want to update the tty. */ /* NULL wp if there is a mode set as don't want to update the tty. */
if (TAILQ_EMPTY(&wp->modes)) if (TAILQ_EMPTY(&wp->modes))
screen_write_start_pane(sctx, wp, &wp->base); screen_write_start_pane(sctx, wp, &wp->base);

View File

@ -530,7 +530,7 @@ const struct options_table_entry options_table[] = {
{ .name = "lock-command", { .name = "lock-command",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_SESSION, .scope = OPTIONS_TABLE_SESSION,
.default_str = "lock -np", .default_str = TMUX_LOCK_CMD,
.text = "Shell command to run to lock a client." .text = "Shell command to run to lock a client."
}, },

11
proc.c
View File

@ -193,18 +193,13 @@ proc_start(const char *name)
log_debug("%s started (%ld): version %s, socket %s, protocol %d", name, log_debug("%s started (%ld): version %s, socket %s, protocol %d", name,
(long)getpid(), getversion(), socket_path, PROTOCOL_VERSION); (long)getpid(), getversion(), socket_path, PROTOCOL_VERSION);
log_debug("on %s %s %s", u.sysname, u.release, u.version); log_debug("on %s %s %s", u.sysname, u.release, u.version);
log_debug("using libevent %s (%s)" log_debug("using libevent %s %s", event_get_version(), event_get_method());
#ifdef HAVE_UTF8PROC #ifdef HAVE_UTF8PROC
"; utf8proc %s" log_debug("using utf8proc %s", utf8proc_version());
#endif #endif
#ifdef NCURSES_VERSION #ifdef NCURSES_VERSION
"; ncurses " NCURSES_VERSION log_debug("using ncurses %s %06u", NCURSES_VERSION, NCURSES_VERSION_PATCH);
#endif #endif
, event_get_version(), event_get_method()
#ifdef HAVE_UTF8PROC
, utf8proc_version()
#endif
);
tp = xcalloc(1, sizeof *tp); tp = xcalloc(1, sizeof *tp);
tp->name = xstrdup(name); tp->name = xstrdup(name);

View File

@ -132,6 +132,12 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
{ {
struct window_pane *wp = ttyctx->arg; struct window_pane *wp = ttyctx->arg;
if (ttyctx->allow_invisible_panes) {
if (session_has(c->session, wp->window))
return (1);
return (0);
}
if (c->session->curw->window != wp->window) if (c->session->curw->window != wp->window)
return (0); return (0);
if (wp->layout_cell == NULL) if (wp->layout_cell == NULL)

14
spawn.c
View File

@ -380,8 +380,20 @@ spawn_pane(struct spawn_context *sc, char **cause)
} }
/* In the parent process, everything is done now. */ /* In the parent process, everything is done now. */
if (new_wp->pid != 0) if (new_wp->pid != 0) {
#if defined(HAVE_SYSTEMD) && defined(ENABLE_CGROUPS)
/*
* Move the child process into a new cgroup for systemd-oomd
* isolation.
*/
if (systemd_move_pid_to_new_cgroup(new_wp->pid, cause) < 0) {
log_debug("%s: moving pane to new cgroup failed: %s",
__func__, *cause);
free (*cause);
}
#endif
goto complete; goto complete;
}
/* /*
* Child process. Change to the working directory or home if that * Child process. Change to the working directory or home if that

View File

@ -1471,8 +1471,6 @@ process_key:
return (0); return (0);
append_key: append_key:
if (key <= 0x1f || (key >= KEYC_BASE && key < KEYC_BASE_END))
return (0);
if (key <= 0x7f) if (key <= 0x7f)
utf8_set(&tmp, key); utf8_set(&tmp, key);
else if (KEYC_IS_UNICODE(key)) else if (KEYC_IS_UNICODE(key))

17
tmux.1
View File

@ -1281,7 +1281,10 @@ behave like
.Ic attach-session .Ic attach-session
if if
.Ar session-name .Ar session-name
already exists; in this case, already exists;
if
.Fl A
is given,
.Fl D .Fl D
behaves like behaves like
.Fl d .Fl d
@ -5260,6 +5263,7 @@ The following variables are available, where appropriate:
.It Li "pane_title" Ta "#T" Ta "Title of pane (can be set by application)" .It Li "pane_title" Ta "#T" Ta "Title of pane (can be set by application)"
.It Li "pane_top" Ta "" Ta "Top of pane" .It Li "pane_top" Ta "" Ta "Top of pane"
.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane" .It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
.It Li "pane_unseen_changes" Ta "" Ta "1 if there were changes in pane while in mode"
.It Li "pane_width" Ta "" Ta "Width of pane" .It Li "pane_width" Ta "" Ta "Width of pane"
.It Li "pid" Ta "" Ta "Server PID" .It Li "pid" Ta "" Ta "Server PID"
.It Li "rectangle_toggle" Ta "" Ta "1 if rectangle selection is activated" .It Li "rectangle_toggle" Ta "" Ta "1 if rectangle selection is activated"
@ -5806,7 +5810,8 @@ the prompt is shown in the background and the invoking client does not exit
until it is dismissed. until it is dismissed.
.Tg confirm .Tg confirm
.It Xo Ic confirm-before .It Xo Ic confirm-before
.Op Fl b .Op Fl by
.Op Fl c Ar confirm-key
.Op Fl p Ar prompt .Op Fl p Ar prompt
.Op Fl t Ar target-client .Op Fl t Ar target-client
.Ar command .Ar command
@ -5827,6 +5832,14 @@ With
.Fl b , .Fl b ,
the prompt is shown in the background and the invoking client does not exit the prompt is shown in the background and the invoking client does not exit
until it is dismissed. until it is dismissed.
.Fl y
changes the default behaviour (if Enter alone is pressed) of the prompt to
run the command.
.Fl c
changes the confirmation key to
.Ar confirm-key ;
the default is
.Ql y .
.Tg menu .Tg menu
.It Xo Ic display-menu .It Xo Ic display-menu
.Op Fl O .Op Fl O

2
tmux.c
View File

@ -391,7 +391,7 @@ main(int argc, char **argv)
cfg_quiet = 0; cfg_quiet = 0;
break; break;
case 'V': case 'V':
printf("%s %s\n", getprogname(), getversion()); printf("tmux %s\n", getversion());
exit(0); exit(0);
case 'l': case 'l':
flags |= CLIENT_LOGIN; flags |= CLIENT_LOGIN;

34
tmux.h
View File

@ -82,6 +82,9 @@ struct winlink;
#ifndef TMUX_TERM #ifndef TMUX_TERM
#define TMUX_TERM "screen" #define TMUX_TERM "screen"
#endif #endif
#ifndef TMUX_LOCK_CMD
#define TMUX_LOCK_CMD "lock -np"
#endif
/* Minimum layout cell size, NOT including border lines. */ /* Minimum layout cell size, NOT including border lines. */
#define PANE_MINIMUM 1 #define PANE_MINIMUM 1
@ -159,7 +162,9 @@ struct winlink;
#define KEYC_IS_UNICODE(key) \ #define KEYC_IS_UNICODE(key) \
(((key) & KEYC_MASK_KEY) > 0x7f && \ (((key) & KEYC_MASK_KEY) > 0x7f && \
(((key) & KEYC_MASK_KEY) < KEYC_BASE || \ (((key) & KEYC_MASK_KEY) < KEYC_BASE || \
((key) & KEYC_MASK_KEY) >= KEYC_BASE_END)) ((key) & KEYC_MASK_KEY) >= KEYC_BASE_END) && \
(((key) & KEYC_MASK_KEY) < KEYC_USER || \
((key) & KEYC_MASK_KEY) >= KEYC_USER + KEYC_NUSER))
/* Multiple click timeout. */ /* Multiple click timeout. */
#define KEYC_CLICK_TIMEOUT 300 #define KEYC_CLICK_TIMEOUT 300
@ -1063,6 +1068,7 @@ struct window_pane {
#define PANE_STATUSDRAWN 0x400 #define PANE_STATUSDRAWN 0x400
#define PANE_EMPTY 0x800 #define PANE_EMPTY 0x800
#define PANE_STYLECHANGED 0x1000 #define PANE_STYLECHANGED 0x1000
#define PANE_UNSEENCHANGES 0x2000
int argc; int argc;
char **argv; char **argv;
@ -2312,12 +2318,12 @@ void tty_margin_off(struct tty *);
void tty_cursor(struct tty *, u_int, u_int); void tty_cursor(struct tty *, u_int, u_int);
void tty_clipboard_query(struct tty *); void tty_clipboard_query(struct tty *);
void tty_putcode(struct tty *, enum tty_code_code); void tty_putcode(struct tty *, enum tty_code_code);
void tty_putcode1(struct tty *, enum tty_code_code, int); void tty_putcode_i(struct tty *, enum tty_code_code, int);
void tty_putcode2(struct tty *, enum tty_code_code, int, int); void tty_putcode_ii(struct tty *, enum tty_code_code, int, int);
void tty_putcode3(struct tty *, enum tty_code_code, int, int, int); void tty_putcode_iii(struct tty *, enum tty_code_code, int, int, int);
void tty_putcode_ptr1(struct tty *, enum tty_code_code, const void *); void tty_putcode_s(struct tty *, enum tty_code_code, const char *);
void tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, void tty_putcode_ss(struct tty *, enum tty_code_code, const char *,
const void *); const char *);
void tty_puts(struct tty *, const char *); void tty_puts(struct tty *, const char *);
void tty_putc(struct tty *, u_char); void tty_putc(struct tty *, u_char);
void tty_putn(struct tty *, const void *, size_t, u_int); void tty_putn(struct tty *, const void *, size_t, u_int);
@ -2383,15 +2389,15 @@ int tty_term_read_list(const char *, int, char ***, u_int *,
void tty_term_free_list(char **, u_int); void tty_term_free_list(char **, u_int);
int tty_term_has(struct tty_term *, enum tty_code_code); 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_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_string_i(struct tty_term *, enum tty_code_code, int);
const char *tty_term_string2(struct tty_term *, enum tty_code_code, int, const char *tty_term_string_ii(struct tty_term *, enum tty_code_code, int,
int); int);
const char *tty_term_string3(struct tty_term *, enum tty_code_code, int, const char *tty_term_string_iii(struct tty_term *, enum tty_code_code, int,
int, int); int, int);
const char *tty_term_ptr1(struct tty_term *, enum tty_code_code, const char *tty_term_string_s(struct tty_term *, enum tty_code_code,
const void *); const char *);
const char *tty_term_ptr2(struct tty_term *, enum tty_code_code, const char *tty_term_string_ss(struct tty_term *, enum tty_code_code,
const void *, const void *); const char *, const char *);
int tty_term_number(struct tty_term *, enum tty_code_code); int tty_term_number(struct tty_term *, enum tty_code_code);
int tty_term_flag(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); const char *tty_term_describe(struct tty_term *, enum tty_code_code);

View File

@ -1008,7 +1008,8 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
/* /*
* Handle mouse key input. Returns 0 for success, -1 for failure, 1 for partial * Handle mouse key input. Returns 0 for success, -1 for failure, 1 for partial
* (probably a mouse sequence but need more data). * (probably a mouse sequence but need more data), -2 if an invalid mouse
* sequence.
*/ */
static int static int
tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size, tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size,
@ -1069,7 +1070,7 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size,
if (b < MOUSE_PARAM_BTN_OFF || if (b < MOUSE_PARAM_BTN_OFF ||
x < MOUSE_PARAM_POS_OFF || x < MOUSE_PARAM_POS_OFF ||
y < MOUSE_PARAM_POS_OFF) y < MOUSE_PARAM_POS_OFF)
return (-1); return (-2);
b -= MOUSE_PARAM_BTN_OFF; b -= MOUSE_PARAM_BTN_OFF;
x -= MOUSE_PARAM_POS_OFF; x -= MOUSE_PARAM_POS_OFF;
y -= MOUSE_PARAM_POS_OFF; y -= MOUSE_PARAM_POS_OFF;
@ -1111,7 +1112,7 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size,
/* Check and return the mouse input. */ /* Check and return the mouse input. */
if (x < 1 || y < 1) if (x < 1 || y < 1)
return (-1); return (-2);
x--; x--;
y--; y--;
b = sgr_b; b = sgr_b;

View File

@ -766,35 +766,100 @@ tty_term_string(struct tty_term *term, enum tty_code_code code)
} }
const char * const char *
tty_term_string1(struct tty_term *term, enum tty_code_code code, int a) tty_term_string_i(struct tty_term *term, enum tty_code_code code, int a)
{ {
return (tparm((char *) tty_term_string(term, code), a, 0, 0, 0, 0, 0, 0, 0, 0)); const char *x = tty_term_string(term, code), *s;
#if defined(HAVE_TIPARM_S)
s = tiparm_s(1, 0, x, a);
#elif defined(HAVE_TIPARM)
s = tiparm(x, a);
#else
s = tparm((char *)x, a, 0, 0, 0, 0, 0, 0, 0, 0);
#endif
if (s == NULL) {
log_debug("could not expand %s", tty_term_codes[code].name);
return ("");
}
return (s);
} }
const char * const char *
tty_term_string2(struct tty_term *term, enum tty_code_code code, int a, int b) tty_term_string_ii(struct tty_term *term, enum tty_code_code code, int a, int b)
{ {
return (tparm((char *) tty_term_string(term, code), a, b, 0, 0, 0, 0, 0, 0, 0)); const char *x = tty_term_string(term, code), *s;
#if defined(HAVE_TIPARM_S)
s = tiparm_s(2, 0, x, a, b);
#elif defined(HAVE_TIPARM)
s = tiparm(x, a, b);
#else
s = tparm((char *)x, a, b, 0, 0, 0, 0, 0, 0, 0);
#endif
if (s == NULL) {
log_debug("could not expand %s", tty_term_codes[code].name);
return ("");
}
return (s);
} }
const char * const char *
tty_term_string3(struct tty_term *term, enum tty_code_code code, int a, int b, tty_term_string_iii(struct tty_term *term, enum tty_code_code code, int a,
int c) int b, int c)
{ {
return (tparm((char *) tty_term_string(term, code), a, b, c, 0, 0, 0, 0, 0, 0)); const char *x = tty_term_string(term, code), *s;
#if defined(HAVE_TIPARM_S)
s = tiparm_s(3, 0, x, a, b, c);
#elif defined(HAVE_TIPARM)
s = tiparm(x, a, b, c);
#else
s = tparm((char *)x, a, b, c, 0, 0, 0, 0, 0, 0);
#endif
if (s == NULL) {
log_debug("could not expand %s", tty_term_codes[code].name);
return ("");
}
return (s);
} }
const char * const char *
tty_term_ptr1(struct tty_term *term, enum tty_code_code code, const void *a) tty_term_string_s(struct tty_term *term, enum tty_code_code code, const char *a)
{ {
return (tparm((char *) tty_term_string(term, code), (long)a, 0, 0, 0, 0, 0, 0, 0, 0)); const char *x = tty_term_string(term, code), *s;
#if defined(HAVE_TIPARM_S)
s = tiparm_s(1, 1, x, a);
#elif defined(HAVE_TIPARM)
s = tiparm(x, a);
#else
s = tparm((char *)x, (long)a, 0, 0, 0, 0, 0, 0, 0, 0);
#endif
if (s == NULL) {
log_debug("could not expand %s", tty_term_codes[code].name);
return ("");
}
return (s);
} }
const char * const char *
tty_term_ptr2(struct tty_term *term, enum tty_code_code code, const void *a, tty_term_string_ss(struct tty_term *term, enum tty_code_code code,
const void *b) const char *a, const char *b)
{ {
return (tparm((char *) tty_term_string(term, code), (long)a, (long)b, 0, 0, 0, 0, 0, 0, 0)); const char *x = tty_term_string(term, code), *s;
#if defined(HAVE_TIPARM_S)
s = tiparm_s(2, 3, x, a, b);
#elif defined(HAVE_TIPARM)
s = tiparm(x, a, b);
#else
s = tparm((char *)x, (long)a, (long)b, 0, 0, 0, 0, 0, 0, 0);
#endif
if (s == NULL) {
log_debug("could not expand %s", tty_term_codes[code].name);
return ("");
}
return (s);
} }
int int

153
tty.c
View File

@ -34,8 +34,6 @@
static int tty_log_fd = -1; static int tty_log_fd = -1;
static int tty_client_ready(struct client *);
static void tty_set_italics(struct tty *); static void tty_set_italics(struct tty *);
static int tty_try_colour(struct tty *, int, const char *); static int tty_try_colour(struct tty *, int, const char *);
static void tty_force_cursor_colour(struct tty *, int); static void tty_force_cursor_colour(struct tty *, int);
@ -407,7 +405,7 @@ tty_stop_tty(struct tty *tty)
if (tcsetattr(c->fd, TCSANOW, &tty->tio) == -1) if (tcsetattr(c->fd, TCSANOW, &tty->tio) == -1)
return; return;
tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1)); tty_raw(tty, tty_term_string_ii(tty->term, TTYC_CSR, 0, ws.ws_row - 1));
if (tty_acs_needed(tty)) if (tty_acs_needed(tty))
tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS)); 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_SGR0));
@ -417,7 +415,7 @@ tty_stop_tty(struct tty *tty)
if (tty_term_has(tty->term, TTYC_SE)) if (tty_term_has(tty->term, TTYC_SE))
tty_raw(tty, tty_term_string(tty->term, TTYC_SE)); tty_raw(tty, tty_term_string(tty->term, TTYC_SE));
else if (tty_term_has(tty->term, TTYC_SS)) else if (tty_term_has(tty->term, TTYC_SS))
tty_raw(tty, tty_term_string1(tty->term, TTYC_SS, 0)); tty_raw(tty, tty_term_string_i(tty->term, TTYC_SS, 0));
} }
if (tty->ccolour != -1) if (tty->ccolour != -1)
tty_raw(tty, tty_term_string(tty->term, TTYC_CR)); tty_raw(tty, tty_term_string(tty->term, TTYC_CR));
@ -484,6 +482,8 @@ tty_update_features(struct tty *tty)
tty_puts(tty, tty_term_string(tty->term, TTYC_ENFCS)); tty_puts(tty, tty_term_string(tty->term, TTYC_ENFCS));
if (tty->term->flags & TERM_VT100LIKE) if (tty->term->flags & TERM_VT100LIKE)
tty_puts(tty, "\033[?7727h"); tty_puts(tty, "\033[?7727h");
tty_invalidate(tty);
} }
void void
@ -514,42 +514,42 @@ tty_putcode(struct tty *tty, enum tty_code_code code)
} }
void void
tty_putcode1(struct tty *tty, enum tty_code_code code, int a) tty_putcode_i(struct tty *tty, enum tty_code_code code, int a)
{ {
if (a < 0) if (a < 0)
return; return;
tty_puts(tty, tty_term_string1(tty->term, code, a)); tty_puts(tty, tty_term_string_i(tty->term, code, a));
} }
void void
tty_putcode2(struct tty *tty, enum tty_code_code code, int a, int b) tty_putcode_ii(struct tty *tty, enum tty_code_code code, int a, int b)
{ {
if (a < 0 || b < 0) if (a < 0 || b < 0)
return; return;
tty_puts(tty, tty_term_string2(tty->term, code, a, b)); tty_puts(tty, tty_term_string_ii(tty->term, code, a, b));
} }
void void
tty_putcode3(struct tty *tty, enum tty_code_code code, int a, int b, int c) tty_putcode_iii(struct tty *tty, enum tty_code_code code, int a, int b, int c)
{ {
if (a < 0 || b < 0 || c < 0) if (a < 0 || b < 0 || c < 0)
return; return;
tty_puts(tty, tty_term_string3(tty->term, code, a, b, c)); tty_puts(tty, tty_term_string_iii(tty->term, code, a, b, c));
} }
void void
tty_putcode_ptr1(struct tty *tty, enum tty_code_code code, const void *a) tty_putcode_s(struct tty *tty, enum tty_code_code code, const char *a)
{ {
if (a != NULL) if (a != NULL)
tty_puts(tty, tty_term_ptr1(tty->term, code, a)); tty_puts(tty, tty_term_string_s(tty->term, code, a));
} }
void void
tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a, tty_putcode_ss(struct tty *tty, enum tty_code_code code, const char *a,
const void *b) const char *b)
{ {
if (a != NULL && b != NULL) if (a != NULL && b != NULL)
tty_puts(tty, tty_term_ptr2(tty->term, code, a, b)); tty_puts(tty, tty_term_string_ss(tty->term, code, a, b));
} }
static void static void
@ -611,7 +611,7 @@ tty_putc(struct tty *tty, u_char ch)
* it works on sensible terminals as well. * it works on sensible terminals as well.
*/ */
if (tty->term->flags & TERM_NOAM) if (tty->term->flags & TERM_NOAM)
tty_putcode2(tty, TTYC_CUP, tty->cy, tty->cx); tty_putcode_ii(tty, TTYC_CUP, tty->cy, tty->cx);
} else } else
tty->cx++; tty->cx++;
} }
@ -690,7 +690,7 @@ tty_force_cursor_colour(struct tty *tty, int c)
else { else {
colour_split_rgb(c, &r, &g, &b); colour_split_rgb(c, &r, &g, &b);
xsnprintf(s, sizeof s, "rgb:%02hhx/%02hhx/%02hhx", r, g, b); xsnprintf(s, sizeof s, "rgb:%02hhx/%02hhx/%02hhx", r, g, b);
tty_putcode_ptr1(tty, TTYC_CS, s); tty_putcode_s(tty, TTYC_CS, s);
} }
tty->ccolour = c; tty->ccolour = c;
} }
@ -751,7 +751,7 @@ tty_update_cursor(struct tty *tty, int mode, struct screen *s)
if (tty_term_has(tty->term, TTYC_SE)) if (tty_term_has(tty->term, TTYC_SE))
tty_putcode(tty, TTYC_SE); tty_putcode(tty, TTYC_SE);
else else
tty_putcode1(tty, TTYC_SS, 0); tty_putcode_i(tty, TTYC_SS, 0);
} }
if (cmode & (MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE)) if (cmode & (MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE))
tty_putcode(tty, TTYC_CVVIS); tty_putcode(tty, TTYC_CVVIS);
@ -759,27 +759,27 @@ tty_update_cursor(struct tty *tty, int mode, struct screen *s)
case SCREEN_CURSOR_BLOCK: case SCREEN_CURSOR_BLOCK:
if (tty_term_has(tty->term, TTYC_SS)) { if (tty_term_has(tty->term, TTYC_SS)) {
if (cmode & MODE_CURSOR_BLINKING) if (cmode & MODE_CURSOR_BLINKING)
tty_putcode1(tty, TTYC_SS, 1); tty_putcode_i(tty, TTYC_SS, 1);
else else
tty_putcode1(tty, TTYC_SS, 2); tty_putcode_i(tty, TTYC_SS, 2);
} else if (cmode & MODE_CURSOR_BLINKING) } else if (cmode & MODE_CURSOR_BLINKING)
tty_putcode(tty, TTYC_CVVIS); tty_putcode(tty, TTYC_CVVIS);
break; break;
case SCREEN_CURSOR_UNDERLINE: case SCREEN_CURSOR_UNDERLINE:
if (tty_term_has(tty->term, TTYC_SS)) { if (tty_term_has(tty->term, TTYC_SS)) {
if (cmode & MODE_CURSOR_BLINKING) if (cmode & MODE_CURSOR_BLINKING)
tty_putcode1(tty, TTYC_SS, 3); tty_putcode_i(tty, TTYC_SS, 3);
else else
tty_putcode1(tty, TTYC_SS, 4); tty_putcode_i(tty, TTYC_SS, 4);
} else if (cmode & MODE_CURSOR_BLINKING) } else if (cmode & MODE_CURSOR_BLINKING)
tty_putcode(tty, TTYC_CVVIS); tty_putcode(tty, TTYC_CVVIS);
break; break;
case SCREEN_CURSOR_BAR: case SCREEN_CURSOR_BAR:
if (tty_term_has(tty->term, TTYC_SS)) { if (tty_term_has(tty->term, TTYC_SS)) {
if (cmode & MODE_CURSOR_BLINKING) if (cmode & MODE_CURSOR_BLINKING)
tty_putcode1(tty, TTYC_SS, 5); tty_putcode_i(tty, TTYC_SS, 5);
else else
tty_putcode1(tty, TTYC_SS, 6); tty_putcode_i(tty, TTYC_SS, 6);
} else if (cmode & MODE_CURSOR_BLINKING) } else if (cmode & MODE_CURSOR_BLINKING)
tty_putcode(tty, TTYC_CVVIS); tty_putcode(tty, TTYC_CVVIS);
break; break;
@ -835,7 +835,7 @@ tty_emulate_repeat(struct tty *tty, enum tty_code_code code,
enum tty_code_code code1, u_int n) enum tty_code_code code1, u_int n)
{ {
if (tty_term_has(tty->term, code)) if (tty_term_has(tty->term, code))
tty_putcode1(tty, code, n); tty_putcode_i(tty, code, n);
else { else {
while (n-- > 0) while (n-- > 0)
tty_putcode(tty, code1); tty_putcode(tty, code1);
@ -1124,7 +1124,7 @@ tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py,
/* Section of line. Use ECH if possible. */ /* Section of line. Use ECH if possible. */
if (tty_term_has(tty->term, TTYC_ECH)) { if (tty_term_has(tty->term, TTYC_ECH)) {
tty_cursor(tty, px, py); tty_cursor(tty, px, py);
tty_putcode1(tty, TTYC_ECH, nx); tty_putcode_i(tty, TTYC_ECH, nx);
return; return;
} }
} }
@ -1265,7 +1265,7 @@ tty_clear_area(struct tty *tty, const struct grid_cell *defaults, u_int py,
tty_term_has(tty->term, TTYC_INDN)) { tty_term_has(tty->term, TTYC_INDN)) {
tty_region(tty, py, py + ny - 1); tty_region(tty, py, py + ny - 1);
tty_margin_off(tty); tty_margin_off(tty);
tty_putcode1(tty, TTYC_INDN, ny); tty_putcode_i(tty, TTYC_INDN, ny);
return; return;
} }
@ -1280,7 +1280,7 @@ tty_clear_area(struct tty *tty, const struct grid_cell *defaults, u_int py,
tty_term_has(tty->term, TTYC_INDN)) { tty_term_has(tty->term, TTYC_INDN)) {
tty_region(tty, py, py + ny - 1); tty_region(tty, py, py + ny - 1);
tty_margin(tty, px, px + nx - 1); tty_margin(tty, px, px + nx - 1);
tty_putcode1(tty, TTYC_INDN, ny); tty_putcode_i(tty, TTYC_INDN, ny);
return; return;
} }
} }
@ -1619,7 +1619,7 @@ tty_sync_start(struct tty *tty)
if (tty_term_has(tty->term, TTYC_SYNC)) { if (tty_term_has(tty->term, TTYC_SYNC)) {
log_debug("%s sync start", tty->client->name); log_debug("%s sync start", tty->client->name);
tty_putcode1(tty, TTYC_SYNC, 1); tty_putcode_i(tty, TTYC_SYNC, 1);
} }
} }
@ -1634,16 +1634,26 @@ tty_sync_end(struct tty *tty)
if (tty_term_has(tty->term, TTYC_SYNC)) { if (tty_term_has(tty->term, TTYC_SYNC)) {
log_debug("%s sync end", tty->client->name); log_debug("%s sync end", tty->client->name);
tty_putcode1(tty, TTYC_SYNC, 2); tty_putcode_i(tty, TTYC_SYNC, 2);
} }
} }
static int static int
tty_client_ready(struct client *c) tty_client_ready(const struct tty_ctx *ctx, struct client *c)
{ {
if (c->session == NULL || c->tty.term == NULL) if (c->session == NULL || c->tty.term == NULL)
return (0); return (0);
if (c->flags & (CLIENT_REDRAWWINDOW|CLIENT_SUSPENDED)) if (c->flags & CLIENT_SUSPENDED)
return (0);
/*
* If invisible panes are allowed (used for passthrough), don't care if
* redrawing or frozen.
*/
if (ctx->allow_invisible_panes)
return (1);
if (c->flags & CLIENT_REDRAWWINDOW)
return (0); return (0);
if (c->tty.flags & TTY_FREEZE) if (c->tty.flags & TTY_FREEZE)
return (0); return (0);
@ -1660,21 +1670,14 @@ tty_write(void (*cmdfn)(struct tty *, const struct tty_ctx *),
if (ctx->set_client_cb == NULL) if (ctx->set_client_cb == NULL)
return; return;
TAILQ_FOREACH(c, &clients, entry) { TAILQ_FOREACH(c, &clients, entry) {
if (ctx->allow_invisible_panes) { if (tty_client_ready(ctx, c)) {
if (c->session == NULL ||
c->tty.term == NULL ||
c->flags & CLIENT_SUSPENDED)
continue;
} else {
if (!tty_client_ready(c))
continue;
state = ctx->set_client_cb(ctx, c); state = ctx->set_client_cb(ctx, c);
if (state == -1) if (state == -1)
break; break;
if (state == 0) if (state == 0)
continue; continue;
cmdfn(&c->tty, ctx);
} }
cmdfn(&c->tty, ctx);
} }
} }
@ -1849,7 +1852,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
if (tty_term_has(tty->term, TTYC_RI)) if (tty_term_has(tty->term, TTYC_RI))
tty_putcode(tty, TTYC_RI); tty_putcode(tty, TTYC_RI);
else else
tty_putcode1(tty, TTYC_RIN, 1); tty_putcode_i(tty, TTYC_RIN, 1);
} }
void void
@ -1930,7 +1933,7 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor(tty, 0, 0); tty_cursor(tty, 0, 0);
else else
tty_cursor(tty, 0, tty->cy); tty_cursor(tty, 0, tty->cy);
tty_putcode1(tty, TTYC_INDN, ctx->num); tty_putcode_i(tty, TTYC_INDN, ctx->num);
} }
} }
@ -1961,7 +1964,7 @@ tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
if (tty_term_has(tty->term, TTYC_RIN)) if (tty_term_has(tty->term, TTYC_RIN))
tty_putcode1(tty, TTYC_RIN, ctx->num); tty_putcode_i(tty, TTYC_RIN, ctx->num);
else { else {
for (i = 0; i < ctx->num; i++) for (i = 0; i < ctx->num; i++)
tty_putcode(tty, TTYC_RI); tty_putcode(tty, TTYC_RI);
@ -2166,7 +2169,7 @@ tty_set_selection(struct tty *tty, const char *flags, const char *buf,
b64_ntop(buf, len, encoded, size); b64_ntop(buf, len, encoded, size);
tty->flags |= TTY_NOBLOCK; tty->flags |= TTY_NOBLOCK;
tty_putcode_ptr2(tty, TTYC_MS, flags, encoded); tty_putcode_ss(tty, TTYC_MS, flags, encoded);
free(encoded); free(encoded);
} }
@ -2280,7 +2283,7 @@ tty_reset(struct tty *tty)
if (!grid_cells_equal(gc, &grid_default_cell)) { if (!grid_cells_equal(gc, &grid_default_cell)) {
if (gc->link != 0) if (gc->link != 0)
tty_putcode_ptr2(tty, TTYC_HLS, "", ""); tty_putcode_ss(tty, TTYC_HLS, "", "");
if ((gc->attr & GRID_ATTR_CHARSET) && tty_acs_needed(tty)) if ((gc->attr & GRID_ATTR_CHARSET) && tty_acs_needed(tty))
tty_putcode(tty, TTYC_RMACS); tty_putcode(tty, TTYC_RMACS);
tty_putcode(tty, TTYC_SGR0); tty_putcode(tty, TTYC_SGR0);
@ -2355,7 +2358,7 @@ tty_region(struct tty *tty, u_int rupper, u_int rlower)
tty_cursor(tty, 0, tty->cy); tty_cursor(tty, 0, tty->cy);
} }
tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower); tty_putcode_ii(tty, TTYC_CSR, tty->rupper, tty->rlower);
tty->cx = tty->cy = UINT_MAX; tty->cx = tty->cy = UINT_MAX;
} }
@ -2383,7 +2386,7 @@ tty_margin(struct tty *tty, u_int rleft, u_int rright)
if (tty->rleft == rleft && tty->rright == rright) if (tty->rleft == rleft && tty->rright == rright)
return; return;
tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower); tty_putcode_ii(tty, TTYC_CSR, tty->rupper, tty->rlower);
tty->rleft = rleft; tty->rleft = rleft;
tty->rright = rright; tty->rright = rright;
@ -2391,7 +2394,7 @@ tty_margin(struct tty *tty, u_int rleft, u_int rright)
if (rleft == 0 && rright == tty->sx - 1) if (rleft == 0 && rright == tty->sx - 1)
tty_putcode(tty, TTYC_CLMG); tty_putcode(tty, TTYC_CLMG);
else else
tty_putcode2(tty, TTYC_CMG, rleft, rright); tty_putcode_ii(tty, TTYC_CMG, rleft, rright);
tty->cx = tty->cy = UINT_MAX; tty->cx = tty->cy = UINT_MAX;
} }
@ -2501,7 +2504,7 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy)
* the cursor with CUB/CUF. * the cursor with CUB/CUF.
*/ */
if ((u_int) abs(change) > cx && tty_term_has(term, TTYC_HPA)) { if ((u_int) abs(change) > cx && tty_term_has(term, TTYC_HPA)) {
tty_putcode1(tty, TTYC_HPA, cx); tty_putcode_i(tty, TTYC_HPA, cx);
goto out; goto out;
} else if (change > 0 && } else if (change > 0 &&
tty_term_has(term, TTYC_CUB) && tty_term_has(term, TTYC_CUB) &&
@ -2511,12 +2514,12 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy)
tty_putcode(tty, TTYC_CUB1); tty_putcode(tty, TTYC_CUB1);
goto out; goto out;
} }
tty_putcode1(tty, TTYC_CUB, change); tty_putcode_i(tty, TTYC_CUB, change);
goto out; goto out;
} else if (change < 0 && } else if (change < 0 &&
tty_term_has(term, TTYC_CUF) && tty_term_has(term, TTYC_CUF) &&
!tty_use_margin(tty)) { !tty_use_margin(tty)) {
tty_putcode1(tty, TTYC_CUF, -change); tty_putcode_i(tty, TTYC_CUF, -change);
goto out; goto out;
} }
} else if (cx == thisx) { } else if (cx == thisx) {
@ -2549,21 +2552,21 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy)
(change < 0 && cy - change > tty->rlower) || (change < 0 && cy - change > tty->rlower) ||
(change > 0 && cy - change < tty->rupper)) { (change > 0 && cy - change < tty->rupper)) {
if (tty_term_has(term, TTYC_VPA)) { if (tty_term_has(term, TTYC_VPA)) {
tty_putcode1(tty, TTYC_VPA, cy); tty_putcode_i(tty, TTYC_VPA, cy);
goto out; goto out;
} }
} else if (change > 0 && tty_term_has(term, TTYC_CUU)) { } else if (change > 0 && tty_term_has(term, TTYC_CUU)) {
tty_putcode1(tty, TTYC_CUU, change); tty_putcode_i(tty, TTYC_CUU, change);
goto out; goto out;
} else if (change < 0 && tty_term_has(term, TTYC_CUD)) { } else if (change < 0 && tty_term_has(term, TTYC_CUD)) {
tty_putcode1(tty, TTYC_CUD, -change); tty_putcode_i(tty, TTYC_CUD, -change);
goto out; goto out;
} }
} }
absolute: absolute:
/* Absolute movement. */ /* Absolute movement. */
tty_putcode2(tty, TTYC_CUP, cy, cx); tty_putcode_ii(tty, TTYC_CUP, cy, cx);
out: out:
tty->cx = cx; tty->cx = cx;
@ -2584,9 +2587,9 @@ tty_hyperlink(struct tty *tty, const struct grid_cell *gc,
return; return;
if (gc->link == 0 || !hyperlinks_get(hl, gc->link, &uri, NULL, &id)) if (gc->link == 0 || !hyperlinks_get(hl, gc->link, &uri, NULL, &id))
tty_putcode_ptr2(tty, TTYC_HLS, "", ""); tty_putcode_ss(tty, TTYC_HLS, "", "");
else else
tty_putcode_ptr2(tty, TTYC_HLS, id, uri); tty_putcode_ss(tty, TTYC_HLS, id, uri);
} }
void void
@ -2663,13 +2666,13 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
!tty_term_has(tty->term, TTYC_SMULX)) !tty_term_has(tty->term, TTYC_SMULX))
tty_putcode(tty, TTYC_SMUL); tty_putcode(tty, TTYC_SMUL);
else if (changed & GRID_ATTR_UNDERSCORE_2) else if (changed & GRID_ATTR_UNDERSCORE_2)
tty_putcode1(tty, TTYC_SMULX, 2); tty_putcode_i(tty, TTYC_SMULX, 2);
else if (changed & GRID_ATTR_UNDERSCORE_3) else if (changed & GRID_ATTR_UNDERSCORE_3)
tty_putcode1(tty, TTYC_SMULX, 3); tty_putcode_i(tty, TTYC_SMULX, 3);
else if (changed & GRID_ATTR_UNDERSCORE_4) else if (changed & GRID_ATTR_UNDERSCORE_4)
tty_putcode1(tty, TTYC_SMULX, 4); tty_putcode_i(tty, TTYC_SMULX, 4);
else if (changed & GRID_ATTR_UNDERSCORE_5) else if (changed & GRID_ATTR_UNDERSCORE_5)
tty_putcode1(tty, TTYC_SMULX, 5); tty_putcode_i(tty, TTYC_SMULX, 5);
} }
if (changed & GRID_ATTR_BLINK) if (changed & GRID_ATTR_BLINK)
tty_putcode(tty, TTYC_BLINK); tty_putcode(tty, TTYC_BLINK);
@ -2726,14 +2729,14 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
if (have_ax) if (have_ax)
tty_puts(tty, "\033[39m"); tty_puts(tty, "\033[39m");
else if (tc->fg != 7) else if (tc->fg != 7)
tty_putcode1(tty, TTYC_SETAF, 7); tty_putcode_i(tty, TTYC_SETAF, 7);
tc->fg = gc->fg; tc->fg = gc->fg;
} }
if (COLOUR_DEFAULT(gc->bg) && !COLOUR_DEFAULT(tc->bg)) { if (COLOUR_DEFAULT(gc->bg) && !COLOUR_DEFAULT(tc->bg)) {
if (have_ax) if (have_ax)
tty_puts(tty, "\033[49m"); tty_puts(tty, "\033[49m");
else if (tc->bg != 0) else if (tc->bg != 0)
tty_putcode1(tty, TTYC_SETAB, 0); tty_putcode_i(tty, TTYC_SETAB, 0);
tc->bg = gc->bg; tc->bg = gc->bg;
} }
} }
@ -2903,12 +2906,12 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
xsnprintf(s, sizeof s, "\033[%dm", gc->fg); xsnprintf(s, sizeof s, "\033[%dm", gc->fg);
tty_puts(tty, s); tty_puts(tty, s);
} else } else
tty_putcode1(tty, TTYC_SETAF, gc->fg - 90 + 8); tty_putcode_i(tty, TTYC_SETAF, gc->fg - 90 + 8);
goto save; goto save;
} }
/* Otherwise set the foreground colour. */ /* Otherwise set the foreground colour. */
tty_putcode1(tty, TTYC_SETAF, gc->fg); tty_putcode_i(tty, TTYC_SETAF, gc->fg);
save: save:
/* Save the new values in the terminal current cell. */ /* Save the new values in the terminal current cell. */
@ -2935,12 +2938,12 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc)
xsnprintf(s, sizeof s, "\033[%dm", gc->bg + 10); xsnprintf(s, sizeof s, "\033[%dm", gc->bg + 10);
tty_puts(tty, s); tty_puts(tty, s);
} else } else
tty_putcode1(tty, TTYC_SETAB, gc->bg - 90 + 8); tty_putcode_i(tty, TTYC_SETAB, gc->bg - 90 + 8);
goto save; goto save;
} }
/* Otherwise set the background colour. */ /* Otherwise set the background colour. */
tty_putcode1(tty, TTYC_SETAB, gc->bg); tty_putcode_i(tty, TTYC_SETAB, gc->bg);
save: save:
/* Save the new values in the terminal current cell. */ /* Save the new values in the terminal current cell. */
@ -2976,10 +2979,10 @@ tty_colours_us(struct tty *tty, const struct grid_cell *gc)
* non-RGB version may be wrong. * non-RGB version may be wrong.
*/ */
if (tty_term_has(tty->term, TTYC_SETULC)) if (tty_term_has(tty->term, TTYC_SETULC))
tty_putcode1(tty, TTYC_SETULC, c); tty_putcode_i(tty, TTYC_SETULC, c);
else if (tty_term_has(tty->term, TTYC_SETAL) && else if (tty_term_has(tty->term, TTYC_SETAL) &&
tty_term_has(tty->term, TTYC_RGB)) tty_term_has(tty->term, TTYC_RGB))
tty_putcode1(tty, TTYC_SETAL, c); tty_putcode_i(tty, TTYC_SETAL, c);
save: save:
/* Save the new values in the terminal current cell. */ /* Save the new values in the terminal current cell. */
@ -2993,18 +2996,18 @@ tty_try_colour(struct tty *tty, int colour, const char *type)
if (colour & COLOUR_FLAG_256) { if (colour & COLOUR_FLAG_256) {
if (*type == '3' && tty_term_has(tty->term, TTYC_SETAF)) if (*type == '3' && tty_term_has(tty->term, TTYC_SETAF))
tty_putcode1(tty, TTYC_SETAF, colour & 0xff); tty_putcode_i(tty, TTYC_SETAF, colour & 0xff);
else if (tty_term_has(tty->term, TTYC_SETAB)) else if (tty_term_has(tty->term, TTYC_SETAB))
tty_putcode1(tty, TTYC_SETAB, colour & 0xff); tty_putcode_i(tty, TTYC_SETAB, colour & 0xff);
return (0); return (0);
} }
if (colour & COLOUR_FLAG_RGB) { if (colour & COLOUR_FLAG_RGB) {
colour_split_rgb(colour & 0xffffff, &r, &g, &b); colour_split_rgb(colour & 0xffffff, &r, &g, &b);
if (*type == '3' && tty_term_has(tty->term, TTYC_SETRGBF)) if (*type == '3' && tty_term_has(tty->term, TTYC_SETRGBF))
tty_putcode3(tty, TTYC_SETRGBF, r, g, b); tty_putcode_iii(tty, TTYC_SETRGBF, r, g, b);
else if (tty_term_has(tty->term, TTYC_SETRGBB)) else if (tty_term_has(tty->term, TTYC_SETRGBB))
tty_putcode3(tty, TTYC_SETRGBB, r, g, b); tty_putcode_iii(tty, TTYC_SETRGBB, r, g, b);
return (0); return (0);
} }
@ -3088,7 +3091,7 @@ tty_clipboard_query(struct tty *tty)
if ((~tty->flags & TTY_STARTED) || (tty->flags & TTY_OSC52QUERY)) if ((~tty->flags & TTY_STARTED) || (tty->flags & TTY_OSC52QUERY))
return; return;
tty_putcode_ptr2(tty, TTYC_MS, "", "?"); tty_putcode_ss(tty, TTYC_MS, "", "?");
tty->flags |= TTY_OSC52QUERY; tty->flags |= TTY_OSC52QUERY;
evtimer_set(&tty->clipboard_timer, tty_clipboard_query_callback, tty); evtimer_set(&tty->clipboard_timer, tty_clipboard_query_callback, tty);

View File

@ -1130,6 +1130,7 @@ window_pane_reset_mode(struct window_pane *wp)
next = TAILQ_FIRST(&wp->modes); next = TAILQ_FIRST(&wp->modes);
if (next == NULL) { if (next == NULL) {
wp->flags &= ~PANE_UNSEENCHANGES;
log_debug("%s: no next mode", __func__); log_debug("%s: no next mode", __func__);
wp->screen = &wp->base; wp->screen = &wp->base;
} else { } else {