Home | History | Annotate | Line # | Download | only in dist
      1 /* $OpenBSD$ */
      2 
      3 /*
      4  * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott (at) gmail.com>
      5  *
      6  * Permission to use, copy, modify, and distribute this software for any
      7  * purpose with or without fee is hereby granted, provided that the above
      8  * copyright notice and this permission notice appear in all copies.
      9  *
     10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
     15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17  */
     18 
     19 #include <sys/types.h>
     20 #include <sys/ioctl.h>
     21 #include <sys/uio.h>
     22 
     23 #include <errno.h>
     24 #include <fcntl.h>
     25 #include <stdlib.h>
     26 #include <string.h>
     27 #include <time.h>
     28 #include <unistd.h>
     29 
     30 #include "tmux.h"
     31 
     32 enum mouse_where {
     33 	NOWHERE,
     34 	PANE,
     35 	STATUS,
     36 	STATUS_LEFT,
     37 	STATUS_RIGHT,
     38 	STATUS_DEFAULT,
     39 	BORDER,
     40 	SCROLLBAR_UP,
     41 	SCROLLBAR_SLIDER,
     42 	SCROLLBAR_DOWN
     43 };
     44 
     45 static void	server_client_free(int, short, void *);
     46 static void	server_client_check_pane_resize(struct window_pane *);
     47 static void	server_client_check_pane_buffer(struct window_pane *);
     48 static void	server_client_check_window_resize(struct window *);
     49 static key_code	server_client_check_mouse(struct client *, struct key_event *);
     50 static void	server_client_repeat_timer(int, short, void *);
     51 static void	server_client_click_timer(int, short, void *);
     52 static void	server_client_check_exit(struct client *);
     53 static void	server_client_check_redraw(struct client *);
     54 static void	server_client_check_modes(struct client *);
     55 static void	server_client_set_title(struct client *);
     56 static void	server_client_set_path(struct client *);
     57 static void	server_client_reset_state(struct client *);
     58 static void	server_client_update_latest(struct client *);
     59 static void	server_client_dispatch(struct imsg *, void *);
     60 static int	server_client_dispatch_command(struct client *, struct imsg *);
     61 static int	server_client_dispatch_identify(struct client *, struct imsg *);
     62 static int	server_client_dispatch_shell(struct client *);
     63 static void	server_client_report_theme(struct client *, enum client_theme);
     64 
     65 /* Compare client windows. */
     66 static int
     67 server_client_window_cmp(struct client_window *cw1,
     68     struct client_window *cw2)
     69 {
     70 	if (cw1->window < cw2->window)
     71 		return (-1);
     72 	if (cw1->window > cw2->window)
     73 		return (1);
     74 	return (0);
     75 }
     76 RB_GENERATE(client_windows, client_window, entry, server_client_window_cmp);
     77 
     78 /* Number of attached clients. */
     79 u_int
     80 server_client_how_many(void)
     81 {
     82 	struct client	*c;
     83 	u_int		 n;
     84 
     85 	n = 0;
     86 	TAILQ_FOREACH(c, &clients, entry) {
     87 		if (c->session != NULL && (~c->flags & CLIENT_UNATTACHEDFLAGS))
     88 			n++;
     89 	}
     90 	return (n);
     91 }
     92 
     93 /* Overlay timer callback. */
     94 static void
     95 server_client_overlay_timer(__unused int fd, __unused short events, void *data)
     96 {
     97 	server_client_clear_overlay(data);
     98 }
     99 
    100 /* Set an overlay on client. */
    101 void
    102 server_client_set_overlay(struct client *c, u_int delay,
    103     overlay_check_cb checkcb, overlay_mode_cb modecb,
    104     overlay_draw_cb drawcb, overlay_key_cb keycb, overlay_free_cb freecb,
    105     overlay_resize_cb resizecb, void *data)
    106 {
    107 	struct timeval	tv;
    108 
    109 	if (c->overlay_draw != NULL)
    110 		server_client_clear_overlay(c);
    111 
    112 	tv.tv_sec = delay / 1000;
    113 	tv.tv_usec = (delay % 1000) * 1000L;
    114 
    115 	if (event_initialized(&c->overlay_timer))
    116 		evtimer_del(&c->overlay_timer);
    117 	evtimer_set(&c->overlay_timer, server_client_overlay_timer, c);
    118 	if (delay != 0)
    119 		evtimer_add(&c->overlay_timer, &tv);
    120 
    121 	c->overlay_check = checkcb;
    122 	c->overlay_mode = modecb;
    123 	c->overlay_draw = drawcb;
    124 	c->overlay_key = keycb;
    125 	c->overlay_free = freecb;
    126 	c->overlay_resize = resizecb;
    127 	c->overlay_data = data;
    128 
    129 	if (c->overlay_check == NULL)
    130 		c->tty.flags |= TTY_FREEZE;
    131 	if (c->overlay_mode == NULL)
    132 		c->tty.flags |= TTY_NOCURSOR;
    133 	window_update_focus(c->session->curw->window);
    134 	server_redraw_client(c);
    135 }
    136 
    137 /* Clear overlay mode on client. */
    138 void
    139 server_client_clear_overlay(struct client *c)
    140 {
    141 	if (c->overlay_draw == NULL)
    142 		return;
    143 
    144 	if (event_initialized(&c->overlay_timer))
    145 		evtimer_del(&c->overlay_timer);
    146 
    147 	if (c->overlay_free != NULL)
    148 		c->overlay_free(c, c->overlay_data);
    149 
    150 	c->overlay_check = NULL;
    151 	c->overlay_mode = NULL;
    152 	c->overlay_draw = NULL;
    153 	c->overlay_key = NULL;
    154 	c->overlay_free = NULL;
    155 	c->overlay_resize = NULL;
    156 	c->overlay_data = NULL;
    157 
    158 	c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR);
    159 	if (c->session != NULL)
    160 		window_update_focus(c->session->curw->window);
    161 	server_redraw_client(c);
    162 }
    163 
    164 /*
    165  * Given overlay position and dimensions, return parts of the input range which
    166  * are visible.
    167  */
    168 void
    169 server_client_overlay_range(u_int x, u_int y, u_int sx, u_int sy, u_int px,
    170     u_int py, u_int nx, struct overlay_ranges *r)
    171 {
    172 	u_int	ox, onx;
    173 
    174 	/* Return up to 2 ranges. */
    175 	r->px[2] = 0;
    176 	r->nx[2] = 0;
    177 
    178 	/* Trivial case of no overlap in the y direction. */
    179 	if (py < y || py > y + sy - 1) {
    180 		r->px[0] = px;
    181 		r->nx[0] = nx;
    182 		r->px[1] = 0;
    183 		r->nx[1] = 0;
    184 		return;
    185 	}
    186 
    187 	/* Visible bit to the left of the popup. */
    188 	if (px < x) {
    189 		r->px[0] = px;
    190 		r->nx[0] = x - px;
    191 		if (r->nx[0] > nx)
    192 			r->nx[0] = nx;
    193 	} else {
    194 		r->px[0] = 0;
    195 		r->nx[0] = 0;
    196 	}
    197 
    198 	/* Visible bit to the right of the popup. */
    199 	ox = x + sx;
    200 	if (px > ox)
    201 		ox = px;
    202 	onx = px + nx;
    203 	if (onx > ox) {
    204 		r->px[1] = ox;
    205 		r->nx[1] = onx - ox;
    206 	} else {
    207 		r->px[1] = 0;
    208 		r->nx[1] = 0;
    209 	}
    210 }
    211 
    212 /* Check if this client is inside this server. */
    213 int
    214 server_client_check_nested(struct client *c)
    215 {
    216 	struct environ_entry	*envent;
    217 	struct window_pane	*wp;
    218 
    219 	envent = environ_find(c->environ, "TMUX");
    220 	if (envent == NULL || *envent->value == '\0')
    221 		return (0);
    222 
    223 	RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
    224 		if (strcmp(wp->tty, c->ttyname) == 0)
    225 			return (1);
    226 	}
    227 	return (0);
    228 }
    229 
    230 /* Set client key table. */
    231 void
    232 server_client_set_key_table(struct client *c, const char *name)
    233 {
    234 	if (name == NULL)
    235 		name = server_client_get_key_table(c);
    236 
    237 	key_bindings_unref_table(c->keytable);
    238 	c->keytable = key_bindings_get_table(name, 1);
    239 	c->keytable->references++;
    240 	if (gettimeofday(&c->keytable->activity_time, NULL) != 0)
    241 		fatal("gettimeofday failed");
    242 }
    243 
    244 static uint64_t
    245 server_client_key_table_activity_diff(struct client *c)
    246 {
    247 	struct timeval	diff;
    248 
    249 	timersub(&c->activity_time, &c->keytable->activity_time, &diff);
    250 	return ((diff.tv_sec * 1000ULL) + (diff.tv_usec / 1000ULL));
    251 }
    252 
    253 /* Get default key table. */
    254 const char *
    255 server_client_get_key_table(struct client *c)
    256 {
    257 	struct session	*s = c->session;
    258 	const char	*name;
    259 
    260 	if (s == NULL)
    261 		return ("root");
    262 
    263 	name = options_get_string(s->options, "key-table");
    264 	if (*name == '\0')
    265 		return ("root");
    266 	return (name);
    267 }
    268 
    269 /* Is this table the default key table? */
    270 static int
    271 server_client_is_default_key_table(struct client *c, struct key_table *table)
    272 {
    273 	return (strcmp(table->name, server_client_get_key_table(c)) == 0);
    274 }
    275 
    276 /* Create a new client. */
    277 struct client *
    278 server_client_create(int fd)
    279 {
    280 	struct client	*c;
    281 
    282 	setblocking(fd, 0);
    283 
    284 	c = xcalloc(1, sizeof *c);
    285 	c->references = 1;
    286 	c->peer = proc_add_peer(server_proc, fd, server_client_dispatch, c);
    287 
    288 	if (gettimeofday(&c->creation_time, NULL) != 0)
    289 		fatal("gettimeofday failed");
    290 	memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time);
    291 
    292 	c->environ = environ_create();
    293 
    294 	c->fd = -1;
    295 	c->out_fd = -1;
    296 
    297 	c->queue = cmdq_new();
    298 	RB_INIT(&c->windows);
    299 	RB_INIT(&c->files);
    300 
    301 	c->tty.sx = 80;
    302 	c->tty.sy = 24;
    303 	c->theme = THEME_UNKNOWN;
    304 
    305 	status_init(c);
    306 	c->flags |= CLIENT_FOCUSED;
    307 
    308 	c->keytable = key_bindings_get_table("root", 1);
    309 	c->keytable->references++;
    310 
    311 	evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
    312 	evtimer_set(&c->click_timer, server_client_click_timer, c);
    313 
    314 	TAILQ_INIT(&c->input_requests);
    315 
    316 	TAILQ_INSERT_TAIL(&clients, c, entry);
    317 	log_debug("new client %p", c);
    318 	return (c);
    319 }
    320 
    321 /* Open client terminal if needed. */
    322 int
    323 server_client_open(struct client *c, char **cause)
    324 {
    325 	const char	*ttynam = _PATH_TTY;
    326 
    327 	if (c->flags & CLIENT_CONTROL)
    328 		return (0);
    329 
    330 	if (strcmp(c->ttyname, ttynam) == 0||
    331 	    ((isatty(STDIN_FILENO) &&
    332 	    (ttynam = ttyname(STDIN_FILENO)) != NULL &&
    333 	    strcmp(c->ttyname, ttynam) == 0) ||
    334 	    (isatty(STDOUT_FILENO) &&
    335 	    (ttynam = ttyname(STDOUT_FILENO)) != NULL &&
    336 	    strcmp(c->ttyname, ttynam) == 0) ||
    337 	    (isatty(STDERR_FILENO) &&
    338 	    (ttynam = ttyname(STDERR_FILENO)) != NULL &&
    339 	    strcmp(c->ttyname, ttynam) == 0))) {
    340 		xasprintf(cause, "can't use %s", c->ttyname);
    341 		return (-1);
    342 	}
    343 
    344 	if (!(c->flags & CLIENT_TERMINAL)) {
    345 		*cause = xstrdup("not a terminal");
    346 		return (-1);
    347 	}
    348 
    349 	if (tty_open(&c->tty, cause) != 0)
    350 		return (-1);
    351 
    352 	return (0);
    353 }
    354 
    355 /* Lost an attached client. */
    356 static void
    357 server_client_attached_lost(struct client *c)
    358 {
    359 	struct session	*s;
    360 	struct window	*w;
    361 	struct client	*loop;
    362 	struct client	*found;
    363 
    364 	log_debug("lost attached client %p", c);
    365 
    366 	/*
    367 	 * By this point the session in the client has been cleared so walk all
    368 	 * windows to find any with this client as the latest.
    369 	 */
    370 	RB_FOREACH(w, windows, &windows) {
    371 		if (w->latest != c)
    372 			continue;
    373 
    374 		found = NULL;
    375 		TAILQ_FOREACH(loop, &clients, entry) {
    376 			s = loop->session;
    377 			if (loop == c || s == NULL || s->curw->window != w)
    378 				continue;
    379 			if (found == NULL || timercmp(&loop->activity_time,
    380 			    &found->activity_time, >))
    381 				found = loop;
    382 		}
    383 		if (found != NULL)
    384 			server_client_update_latest(found);
    385 	}
    386 }
    387 
    388 /* Set client session. */
    389 void
    390 server_client_set_session(struct client *c, struct session *s)
    391 {
    392 	struct session	*old = c->session;
    393 
    394 	if (s != NULL && c->session != NULL && c->session != s)
    395 		c->last_session = c->session;
    396 	else if (s == NULL)
    397 		c->last_session = NULL;
    398 	c->session = s;
    399 	c->flags |= CLIENT_FOCUSED;
    400 
    401 	if (old != NULL && old->curw != NULL)
    402 		window_update_focus(old->curw->window);
    403 	if (s != NULL) {
    404 		recalculate_sizes();
    405 		window_update_focus(s->curw->window);
    406 		session_update_activity(s, NULL);
    407 		session_theme_changed(s);
    408 		gettimeofday(&s->last_attached_time, NULL);
    409 		s->curw->flags &= ~WINLINK_ALERTFLAGS;
    410 		s->curw->window->latest = c;
    411 		alerts_check_session(s);
    412 		tty_update_client_offset(c);
    413 		status_timer_start(c);
    414 		notify_client("client-session-changed", c);
    415 		server_redraw_client(c);
    416 	}
    417 
    418 	server_check_unattached();
    419 	server_update_socket();
    420 }
    421 
    422 /* Lost a client. */
    423 void
    424 server_client_lost(struct client *c)
    425 {
    426 	struct client_file	*cf, *cf1;
    427 	struct client_window	*cw, *cw1;
    428 
    429 	c->flags |= CLIENT_DEAD;
    430 
    431 	server_client_clear_overlay(c);
    432 	status_prompt_clear(c);
    433 	status_message_clear(c);
    434 
    435 	RB_FOREACH_SAFE(cf, client_files, &c->files, cf1) {
    436 		cf->error = EINTR;
    437 		file_fire_done(cf);
    438 	}
    439 	RB_FOREACH_SAFE(cw, client_windows, &c->windows, cw1) {
    440 		RB_REMOVE(client_windows, &c->windows, cw);
    441 		free(cw);
    442 	}
    443 
    444 	TAILQ_REMOVE(&clients, c, entry);
    445 	log_debug("lost client %p", c);
    446 
    447 	if (c->flags & CLIENT_ATTACHED) {
    448 		server_client_attached_lost(c);
    449 		notify_client("client-detached", c);
    450 	}
    451 
    452 	if (c->flags & CLIENT_CONTROL)
    453 		control_stop(c);
    454 	if (c->flags & CLIENT_TERMINAL)
    455 		tty_free(&c->tty);
    456 	free(c->ttyname);
    457 	free(c->clipboard_panes);
    458 
    459 	free(c->term_name);
    460 	free(c->term_type);
    461 	tty_term_free_list(c->term_caps, c->term_ncaps);
    462 
    463 	status_free(c);
    464 	input_cancel_requests(c);
    465 
    466 	free(c->title);
    467 	free(__UNCONST(c->cwd));
    468 
    469 	evtimer_del(&c->repeat_timer);
    470 	evtimer_del(&c->click_timer);
    471 
    472 	key_bindings_unref_table(c->keytable);
    473 
    474 	free(c->message_string);
    475 	if (event_initialized(&c->message_timer))
    476 		evtimer_del(&c->message_timer);
    477 
    478 	free(c->prompt_saved);
    479 	free(c->prompt_string);
    480 	free(c->prompt_buffer);
    481 
    482 	format_lost_client(c);
    483 	environ_free(c->environ);
    484 
    485 	proc_remove_peer(c->peer);
    486 	c->peer = NULL;
    487 
    488 	if (c->out_fd != -1)
    489 		close(c->out_fd);
    490 	if (c->fd != -1) {
    491 		close(c->fd);
    492 		c->fd = -1;
    493 	}
    494 	server_client_unref(c);
    495 
    496 	server_add_accept(0); /* may be more file descriptors now */
    497 
    498 	recalculate_sizes();
    499 	server_check_unattached();
    500 	server_update_socket();
    501 }
    502 
    503 /* Remove reference from a client. */
    504 void
    505 server_client_unref(struct client *c)
    506 {
    507 	log_debug("unref client %p (%d references)", c, c->references);
    508 
    509 	c->references--;
    510 	if (c->references == 0)
    511 		event_once(-1, EV_TIMEOUT, server_client_free, c, NULL);
    512 }
    513 
    514 /* Free dead client. */
    515 static void
    516 server_client_free(__unused int fd, __unused short events, void *arg)
    517 {
    518 	struct client	*c = arg;
    519 
    520 	log_debug("free client %p (%d references)", c, c->references);
    521 
    522 	cmdq_free(c->queue);
    523 
    524 	if (c->references == 0) {
    525 		free(__UNCONST(c->name));
    526 		free(c);
    527 	}
    528 }
    529 
    530 /* Suspend a client. */
    531 void
    532 server_client_suspend(struct client *c)
    533 {
    534 	struct session	*s = c->session;
    535 
    536 	if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
    537 		return;
    538 
    539 	tty_stop_tty(&c->tty);
    540 	c->flags |= CLIENT_SUSPENDED;
    541 	proc_send(c->peer, MSG_SUSPEND, -1, NULL, 0);
    542 }
    543 
    544 /* Detach a client. */
    545 void
    546 server_client_detach(struct client *c, enum msgtype msgtype)
    547 {
    548 	struct session	*s = c->session;
    549 
    550 	if (s == NULL || (c->flags & CLIENT_NODETACHFLAGS))
    551 		return;
    552 
    553 	c->flags |= CLIENT_EXIT;
    554 
    555 	c->exit_type = CLIENT_EXIT_DETACH;
    556 	c->exit_msgtype = msgtype;
    557 	c->exit_session = xstrdup(s->name);
    558 }
    559 
    560 /* Execute command to replace a client. */
    561 void
    562 server_client_exec(struct client *c, const char *cmd)
    563 {
    564 	struct session	*s = c->session;
    565 	char		*msg;
    566 	const char	*shell;
    567 	size_t		 cmdsize, shellsize;
    568 
    569 	if (*cmd == '\0')
    570 		return;
    571 	cmdsize = strlen(cmd) + 1;
    572 
    573 	if (s != NULL)
    574 		shell = options_get_string(s->options, "default-shell");
    575 	else
    576 		shell = options_get_string(global_s_options, "default-shell");
    577 	if (!checkshell(shell))
    578 		shell = _PATH_BSHELL;
    579 	shellsize = strlen(shell) + 1;
    580 
    581 	msg = xmalloc(cmdsize + shellsize);
    582 	memcpy(msg, cmd, cmdsize);
    583 	memcpy(msg + cmdsize, shell, shellsize);
    584 
    585 	proc_send(c->peer, MSG_EXEC, -1, msg, cmdsize + shellsize);
    586 	free(msg);
    587 }
    588 
    589 static enum mouse_where
    590 server_client_check_mouse_in_pane(struct window_pane *wp, u_int px, u_int py,
    591     u_int *sl_mpos)
    592 {
    593 	struct window		*w = wp->window;
    594 	struct options		*wo = w->options;
    595 	struct window_pane	*fwp;
    596 	int			 pane_status, sb, sb_pos, sb_w, sb_pad;
    597 	u_int			 line = 0, sl_top, sl_bottom;
    598 
    599 	sb = options_get_number(wo, "pane-scrollbars");
    600 	sb_pos = options_get_number(wo, "pane-scrollbars-position");
    601 	pane_status = options_get_number(wo, "pane-border-status");
    602 
    603 	if (window_pane_show_scrollbar(wp, sb)) {
    604 		sb_w = wp->scrollbar_style.width;
    605 		sb_pad = wp->scrollbar_style.pad;
    606 	} else {
    607 		sb_w = 0;
    608 		sb_pad = 0;
    609 	}
    610 	if (pane_status == PANE_STATUS_TOP)
    611 		line = wp->yoff - 1;
    612 	else if (pane_status == PANE_STATUS_BOTTOM)
    613 		line = wp->yoff + wp->sy;
    614 
    615 	/* Check if point is within the pane or scrollbar. */
    616 	if (((pane_status != PANE_STATUS_OFF &&
    617 	    py != line && py != wp->yoff + wp->sy) ||
    618 	    (wp->yoff == 0 && py < wp->sy) ||
    619 	    (py >= wp->yoff && py < wp->yoff + wp->sy)) &&
    620 	    ((sb_pos == PANE_SCROLLBARS_RIGHT &&
    621 	    px < wp->xoff + wp->sx + sb_pad + sb_w) ||
    622 	    (sb_pos == PANE_SCROLLBARS_LEFT &&
    623 	    px < wp->xoff + wp->sx - sb_pad - sb_w))) {
    624 		/* Check if in the scrollbar. */
    625 		if ((sb_pos == PANE_SCROLLBARS_RIGHT &&
    626 		    (px >= wp->xoff + wp->sx + sb_pad &&
    627 		    px < wp->xoff + wp->sx + sb_pad + sb_w)) ||
    628 		    (sb_pos == PANE_SCROLLBARS_LEFT &&
    629 		    (px >= wp->xoff - sb_pad - sb_w &&
    630 		    px < wp->xoff - sb_pad))) {
    631 			/* Check where inside the scrollbar. */
    632 			sl_top = wp->yoff + wp->sb_slider_y;
    633 			sl_bottom = (wp->yoff + wp->sb_slider_y +
    634 			    wp->sb_slider_h - 1);
    635 			if (py < sl_top)
    636 				return (SCROLLBAR_UP);
    637 			else if (py >= sl_top &&
    638 				 py <= sl_bottom) {
    639 				*sl_mpos = (py - wp->sb_slider_y - wp->yoff);
    640 				return (SCROLLBAR_SLIDER);
    641 			} else /* py > sl_bottom */
    642 				return (SCROLLBAR_DOWN);
    643 		} else {
    644 			/* Must be inside the pane. */
    645 			return (PANE);
    646 		}
    647 	} else if (~w->flags & WINDOW_ZOOMED) {
    648 		/* Try the pane borders if not zoomed. */
    649 		TAILQ_FOREACH(fwp, &w->panes, entry) {
    650 			if ((((sb_pos == PANE_SCROLLBARS_RIGHT &&
    651 			    fwp->xoff + fwp->sx + sb_pad + sb_w == px) ||
    652 			    (sb_pos == PANE_SCROLLBARS_LEFT &&
    653 			    fwp->xoff + fwp->sx == px)) &&
    654 			    fwp->yoff <= 1 + py &&
    655 			    fwp->yoff + fwp->sy >= py) ||
    656 			    (fwp->yoff + fwp->sy == py &&
    657 			    fwp->xoff <= 1 + px &&
    658 			    fwp->xoff + fwp->sx >= px))
    659 				break;
    660 		}
    661 		if (fwp != NULL)
    662 			return (BORDER);
    663 	}
    664 	return (NOWHERE);
    665 }
    666 
    667 /* Check for mouse keys. */
    668 static key_code
    669 server_client_check_mouse(struct client *c, struct key_event *event)
    670 {
    671 	struct mouse_event	*m = &event->m;
    672 	struct session		*s = c->session, *fs;
    673 	struct window		*w = s->curw->window;
    674 	struct winlink		*fwl;
    675 	struct window_pane	*wp, *fwp;
    676 	u_int			 x, y, b, sx, sy, px, py, sl_mpos = 0;
    677 	int			 ignore = 0;
    678 	key_code		 key;
    679 	struct timeval		 tv;
    680 	struct style_range	*sr;
    681 	enum { NOTYPE,
    682 	       MOVE,
    683 	       DOWN,
    684 	       UP,
    685 	       DRAG,
    686 	       WHEEL,
    687 	       SECOND,
    688 	       DOUBLE,
    689 	       TRIPLE } type = NOTYPE;
    690 	enum mouse_where where = NOWHERE;
    691 
    692 	log_debug("%s mouse %02x at %u,%u (last %u,%u) (%d)", c->name, m->b,
    693 	    m->x, m->y, m->lx, m->ly, c->tty.mouse_drag_flag);
    694 
    695 	/* What type of event is this? */
    696 	if (event->key == KEYC_DOUBLECLICK) {
    697 		type = DOUBLE;
    698 		x = m->x, y = m->y, b = m->b;
    699 		ignore = 1;
    700 		log_debug("double-click at %u,%u", x, y);
    701 	} else if ((m->sgr_type != ' ' &&
    702 	    MOUSE_DRAG(m->sgr_b) &&
    703 	    MOUSE_RELEASE(m->sgr_b)) ||
    704 	    (m->sgr_type == ' ' &&
    705 	    MOUSE_DRAG(m->b) &&
    706 	    MOUSE_RELEASE(m->b) &&
    707 	    MOUSE_RELEASE(m->lb))) {
    708 		type = MOVE;
    709 		x = m->x, y = m->y, b = 0;
    710 		log_debug("move at %u,%u", x, y);
    711 	} else if (MOUSE_DRAG(m->b)) {
    712 		type = DRAG;
    713 		if (c->tty.mouse_drag_flag) {
    714 			x = m->x, y = m->y, b = m->b;
    715 			if (x == m->lx && y == m->ly)
    716 				return (KEYC_UNKNOWN);
    717 			log_debug("drag update at %u,%u", x, y);
    718 		} else {
    719 			x = m->lx, y = m->ly, b = m->lb;
    720 			log_debug("drag start at %u,%u", x, y);
    721 		}
    722 	} else if (MOUSE_WHEEL(m->b)) {
    723 		type = WHEEL;
    724 		x = m->x, y = m->y, b = m->b;
    725 		log_debug("wheel at %u,%u", x, y);
    726 	} else if (MOUSE_RELEASE(m->b)) {
    727 		type = UP;
    728 		x = m->x, y = m->y, b = m->lb;
    729 		if (m->sgr_type == 'm')
    730 			b = m->sgr_b;
    731 		log_debug("up at %u,%u", x, y);
    732 	} else {
    733 		if (c->flags & CLIENT_DOUBLECLICK) {
    734 			evtimer_del(&c->click_timer);
    735 			c->flags &= ~CLIENT_DOUBLECLICK;
    736 			if (m->b == c->click_button) {
    737 				type = SECOND;
    738 				x = m->x, y = m->y, b = m->b;
    739 				log_debug("second-click at %u,%u", x, y);
    740 				c->flags |= CLIENT_TRIPLECLICK;
    741 			}
    742 		} else if (c->flags & CLIENT_TRIPLECLICK) {
    743 			evtimer_del(&c->click_timer);
    744 			c->flags &= ~CLIENT_TRIPLECLICK;
    745 			if (m->b == c->click_button) {
    746 				type = TRIPLE;
    747 				x = m->x, y = m->y, b = m->b;
    748 				log_debug("triple-click at %u,%u", x, y);
    749 				goto have_event;
    750 			}
    751 		}
    752 
    753 		/* DOWN is the only remaining event type. */
    754 		if (type == NOTYPE) {
    755 			type = DOWN;
    756 			x = m->x, y = m->y, b = m->b;
    757 			log_debug("down at %u,%u", x, y);
    758 			c->flags |= CLIENT_DOUBLECLICK;
    759 		}
    760 
    761 		if (KEYC_CLICK_TIMEOUT != 0) {
    762 			memcpy(&c->click_event, m, sizeof c->click_event);
    763 			c->click_button = m->b;
    764 
    765 			log_debug("click timer started");
    766 			tv.tv_sec = KEYC_CLICK_TIMEOUT / 1000;
    767 			tv.tv_usec = (KEYC_CLICK_TIMEOUT % 1000) * 1000L;
    768 			evtimer_del(&c->click_timer);
    769 			evtimer_add(&c->click_timer, &tv);
    770 		}
    771 	}
    772 
    773 have_event:
    774 	if (type == NOTYPE)
    775 		return (KEYC_UNKNOWN);
    776 
    777 	/* Save the session. */
    778 	m->s = s->id;
    779 	m->w = -1;
    780 	m->wp = -1;
    781 	m->ignore = ignore;
    782 
    783 	/* Is this on the status line? */
    784 	m->statusat = status_at_line(c);
    785 	m->statuslines = status_line_size(c);
    786 	if (m->statusat != -1 &&
    787 	    y >= (u_int)m->statusat &&
    788 	    y < m->statusat + m->statuslines) {
    789 		sr = status_get_range(c, x, y - m->statusat);
    790 		if (sr == NULL) {
    791 			where = STATUS_DEFAULT;
    792 		} else {
    793 			switch (sr->type) {
    794 			case STYLE_RANGE_NONE:
    795 				return (KEYC_UNKNOWN);
    796 			case STYLE_RANGE_LEFT:
    797 				log_debug("mouse range: left");
    798 				where = STATUS_LEFT;
    799 				break;
    800 			case STYLE_RANGE_RIGHT:
    801 				log_debug("mouse range: right");
    802 				where = STATUS_RIGHT;
    803 				break;
    804 			case STYLE_RANGE_PANE:
    805 				fwp = window_pane_find_by_id(sr->argument);
    806 				if (fwp == NULL)
    807 					return (KEYC_UNKNOWN);
    808 				m->wp = sr->argument;
    809 
    810 				log_debug("mouse range: pane %%%u", m->wp);
    811 				where = STATUS;
    812 				break;
    813 			case STYLE_RANGE_WINDOW:
    814 				fwl = winlink_find_by_index(&s->windows,
    815 				    sr->argument);
    816 				if (fwl == NULL)
    817 					return (KEYC_UNKNOWN);
    818 				m->w = fwl->window->id;
    819 
    820 				log_debug("mouse range: window @%u", m->w);
    821 				where = STATUS;
    822 				break;
    823 			case STYLE_RANGE_SESSION:
    824 				fs = session_find_by_id(sr->argument);
    825 				if (fs == NULL)
    826 					return (KEYC_UNKNOWN);
    827 				m->s = sr->argument;
    828 
    829 				log_debug("mouse range: session $%u", m->s);
    830 				where = STATUS;
    831 				break;
    832 			case STYLE_RANGE_USER:
    833 				where = STATUS;
    834 				break;
    835 			}
    836 		}
    837 	}
    838 
    839 	/*
    840 	 * Not on status line. Adjust position and check for border, pane, or
    841 	 * scrollbar.
    842 	 */
    843 	if (where == NOWHERE) {
    844 		if (c->tty.mouse_scrolling_flag)
    845 			where = SCROLLBAR_SLIDER;
    846 		else {
    847 			px = x;
    848 			if (m->statusat == 0 && y >= m->statuslines)
    849 				py = y - m->statuslines;
    850 			else if (m->statusat > 0 && y >= (u_int)m->statusat)
    851 				py = m->statusat - 1;
    852 			else
    853 				py = y;
    854 
    855 			tty_window_offset(&c->tty, &m->ox, &m->oy, &sx, &sy);
    856 			log_debug("mouse window @%u at %u,%u (%ux%u)",
    857 				  w->id, m->ox, m->oy, sx, sy);
    858 			if (px > sx || py > sy)
    859 				return (KEYC_UNKNOWN);
    860 			px = px + m->ox;
    861 			py = py + m->oy;
    862 
    863 			/* Try inside the pane. */
    864 			wp = window_get_active_at(w, px, py);
    865 			if (wp == NULL)
    866 				return (KEYC_UNKNOWN);
    867 			where = server_client_check_mouse_in_pane(wp, px, py,
    868 			    &sl_mpos);
    869 
    870 			if (where == PANE) {
    871 				log_debug("mouse %u,%u on pane %%%u", x, y,
    872 				    wp->id);
    873 			} else if (where == BORDER)
    874 				log_debug("mouse on pane %%%u border", wp->id);
    875 			else if (where == SCROLLBAR_UP ||
    876 			    where == SCROLLBAR_SLIDER ||
    877 			    where == SCROLLBAR_DOWN) {
    878 				log_debug("mouse on pane %%%u scrollbar",
    879 				    wp->id);
    880 			}
    881 			m->wp = wp->id;
    882 			m->w = wp->window->id;
    883 		}
    884 	}
    885 
    886 	/* Stop dragging if needed. */
    887 	if (type != DRAG &&
    888 	    type != WHEEL &&
    889 	    type != DOUBLE &&
    890 	    type != TRIPLE &&
    891 	    c->tty.mouse_drag_flag != 0) {
    892 		if (c->tty.mouse_drag_release != NULL)
    893 			c->tty.mouse_drag_release(c, m);
    894 
    895 		c->tty.mouse_drag_update = NULL;
    896 		c->tty.mouse_drag_release = NULL;
    897 		c->tty.mouse_scrolling_flag = 0;
    898 
    899 		/*
    900 		 * End a mouse drag by passing a MouseDragEnd key corresponding
    901 		 * to the button that started the drag.
    902 		 */
    903 		switch (c->tty.mouse_drag_flag - 1) {
    904 		case MOUSE_BUTTON_1:
    905 			if (where == PANE)
    906 				key = KEYC_MOUSEDRAGEND1_PANE;
    907 			if (where == STATUS)
    908 				key = KEYC_MOUSEDRAGEND1_STATUS;
    909 			if (where == STATUS_LEFT)
    910 				key = KEYC_MOUSEDRAGEND1_STATUS_LEFT;
    911 			if (where == STATUS_RIGHT)
    912 				key = KEYC_MOUSEDRAGEND1_STATUS_RIGHT;
    913 			if (where == STATUS_DEFAULT)
    914 				key = KEYC_MOUSEDRAGEND1_STATUS_DEFAULT;
    915 			if (where == SCROLLBAR_SLIDER)
    916 				key = KEYC_MOUSEDRAGEND1_SCROLLBAR_SLIDER;
    917 			if (where == BORDER)
    918 				key = KEYC_MOUSEDRAGEND1_BORDER;
    919 			break;
    920 		case MOUSE_BUTTON_2:
    921 			if (where == PANE)
    922 				key = KEYC_MOUSEDRAGEND2_PANE;
    923 			if (where == STATUS)
    924 				key = KEYC_MOUSEDRAGEND2_STATUS;
    925 			if (where == STATUS_LEFT)
    926 				key = KEYC_MOUSEDRAGEND2_STATUS_LEFT;
    927 			if (where == STATUS_RIGHT)
    928 				key = KEYC_MOUSEDRAGEND2_STATUS_RIGHT;
    929 			if (where == STATUS_DEFAULT)
    930 				key = KEYC_MOUSEDRAGEND2_STATUS_DEFAULT;
    931 			if (where == SCROLLBAR_SLIDER)
    932 				key = KEYC_MOUSEDRAGEND2_SCROLLBAR_SLIDER;
    933 			if (where == BORDER)
    934 				key = KEYC_MOUSEDRAGEND2_BORDER;
    935 			break;
    936 		case MOUSE_BUTTON_3:
    937 			if (where == PANE)
    938 				key = KEYC_MOUSEDRAGEND3_PANE;
    939 			if (where == STATUS)
    940 				key = KEYC_MOUSEDRAGEND3_STATUS;
    941 			if (where == STATUS_LEFT)
    942 				key = KEYC_MOUSEDRAGEND3_STATUS_LEFT;
    943 			if (where == STATUS_RIGHT)
    944 				key = KEYC_MOUSEDRAGEND3_STATUS_RIGHT;
    945 			if (where == STATUS_DEFAULT)
    946 				key = KEYC_MOUSEDRAGEND3_STATUS_DEFAULT;
    947 			if (where == SCROLLBAR_SLIDER)
    948 				key = KEYC_MOUSEDRAGEND3_SCROLLBAR_SLIDER;
    949 			if (where == BORDER)
    950 				key = KEYC_MOUSEDRAGEND3_BORDER;
    951 			break;
    952 		case MOUSE_BUTTON_6:
    953 			if (where == PANE)
    954 				key = KEYC_MOUSEDRAGEND6_PANE;
    955 			if (where == STATUS)
    956 				key = KEYC_MOUSEDRAGEND6_STATUS;
    957 			if (where == STATUS_LEFT)
    958 				key = KEYC_MOUSEDRAGEND6_STATUS_LEFT;
    959 			if (where == STATUS_RIGHT)
    960 				key = KEYC_MOUSEDRAGEND6_STATUS_RIGHT;
    961 			if (where == STATUS_DEFAULT)
    962 				key = KEYC_MOUSEDRAGEND6_STATUS_DEFAULT;
    963 			if (where == SCROLLBAR_SLIDER)
    964 				key = KEYC_MOUSEDRAGEND6_SCROLLBAR_SLIDER;
    965 			if (where == BORDER)
    966 				key = KEYC_MOUSEDRAGEND6_BORDER;
    967 			break;
    968 		case MOUSE_BUTTON_7:
    969 			if (where == PANE)
    970 				key = KEYC_MOUSEDRAGEND7_PANE;
    971 			if (where == STATUS)
    972 				key = KEYC_MOUSEDRAGEND7_STATUS;
    973 			if (where == STATUS_LEFT)
    974 				key = KEYC_MOUSEDRAGEND7_STATUS_LEFT;
    975 			if (where == STATUS_RIGHT)
    976 				key = KEYC_MOUSEDRAGEND7_STATUS_RIGHT;
    977 			if (where == STATUS_DEFAULT)
    978 				key = KEYC_MOUSEDRAGEND7_STATUS_DEFAULT;
    979 			if (where == SCROLLBAR_SLIDER)
    980 				key = KEYC_MOUSEDRAGEND7_SCROLLBAR_SLIDER;
    981 			if (where == BORDER)
    982 				key = KEYC_MOUSEDRAGEND7_BORDER;
    983 			break;
    984 		case MOUSE_BUTTON_8:
    985 			if (where == PANE)
    986 				key = KEYC_MOUSEDRAGEND8_PANE;
    987 			if (where == STATUS)
    988 				key = KEYC_MOUSEDRAGEND8_STATUS;
    989 			if (where == STATUS_LEFT)
    990 				key = KEYC_MOUSEDRAGEND8_STATUS_LEFT;
    991 			if (where == STATUS_RIGHT)
    992 				key = KEYC_MOUSEDRAGEND8_STATUS_RIGHT;
    993 			if (where == STATUS_DEFAULT)
    994 				key = KEYC_MOUSEDRAGEND8_STATUS_DEFAULT;
    995 			if (where == SCROLLBAR_SLIDER)
    996 				key = KEYC_MOUSEDRAGEND8_SCROLLBAR_SLIDER;
    997 			if (where == BORDER)
    998 				key = KEYC_MOUSEDRAGEND8_BORDER;
    999 			break;
   1000 		case MOUSE_BUTTON_9:
   1001 			if (where == PANE)
   1002 				key = KEYC_MOUSEDRAGEND9_PANE;
   1003 			if (where == STATUS)
   1004 				key = KEYC_MOUSEDRAGEND9_STATUS;
   1005 			if (where == STATUS_LEFT)
   1006 				key = KEYC_MOUSEDRAGEND9_STATUS_LEFT;
   1007 			if (where == STATUS_RIGHT)
   1008 				key = KEYC_MOUSEDRAGEND9_STATUS_RIGHT;
   1009 			if (where == STATUS_DEFAULT)
   1010 				key = KEYC_MOUSEDRAGEND9_STATUS_DEFAULT;
   1011 			if (where == SCROLLBAR_SLIDER)
   1012 				key = KEYC_MOUSEDRAGEND9_SCROLLBAR_SLIDER;
   1013 			if (where == BORDER)
   1014 				key = KEYC_MOUSEDRAGEND9_BORDER;
   1015 			break;
   1016 		case MOUSE_BUTTON_10:
   1017 			if (where == PANE)
   1018 				key = KEYC_MOUSEDRAGEND10_PANE;
   1019 			if (where == STATUS)
   1020 				key = KEYC_MOUSEDRAGEND10_STATUS;
   1021 			if (where == STATUS_LEFT)
   1022 				key = KEYC_MOUSEDRAGEND10_STATUS_LEFT;
   1023 			if (where == STATUS_RIGHT)
   1024 				key = KEYC_MOUSEDRAGEND10_STATUS_RIGHT;
   1025 			if (where == STATUS_DEFAULT)
   1026 				key = KEYC_MOUSEDRAGEND10_STATUS_DEFAULT;
   1027 			if (where == SCROLLBAR_SLIDER)
   1028 				key = KEYC_MOUSEDRAGEND10_SCROLLBAR_SLIDER;
   1029 			if (where == BORDER)
   1030 				key = KEYC_MOUSEDRAGEND10_BORDER;
   1031 			break;
   1032 		case MOUSE_BUTTON_11:
   1033 			if (where == PANE)
   1034 				key = KEYC_MOUSEDRAGEND11_PANE;
   1035 			if (where == STATUS)
   1036 				key = KEYC_MOUSEDRAGEND11_STATUS;
   1037 			if (where == STATUS_LEFT)
   1038 				key = KEYC_MOUSEDRAGEND11_STATUS_LEFT;
   1039 			if (where == STATUS_RIGHT)
   1040 				key = KEYC_MOUSEDRAGEND11_STATUS_RIGHT;
   1041 			if (where == STATUS_DEFAULT)
   1042 				key = KEYC_MOUSEDRAGEND11_STATUS_DEFAULT;
   1043 			if (where == SCROLLBAR_SLIDER)
   1044 				key = KEYC_MOUSEDRAGEND11_SCROLLBAR_SLIDER;
   1045 			if (where == BORDER)
   1046 				key = KEYC_MOUSEDRAGEND11_BORDER;
   1047 			break;
   1048 		default:
   1049 			key = KEYC_MOUSE;
   1050 			break;
   1051 		}
   1052 		c->tty.mouse_drag_flag = 0;
   1053 		c->tty.mouse_slider_mpos = -1;
   1054 		goto out;
   1055 	}
   1056 
   1057 	/* Convert to a key binding. */
   1058 	key = KEYC_UNKNOWN;
   1059 	switch (type) {
   1060 	case NOTYPE:
   1061 		break;
   1062 	case MOVE:
   1063 		if (where == PANE)
   1064 			key = KEYC_MOUSEMOVE_PANE;
   1065 		if (where == STATUS)
   1066 			key = KEYC_MOUSEMOVE_STATUS;
   1067 		if (where == STATUS_LEFT)
   1068 			key = KEYC_MOUSEMOVE_STATUS_LEFT;
   1069 		if (where == STATUS_RIGHT)
   1070 			key = KEYC_MOUSEMOVE_STATUS_RIGHT;
   1071 		if (where == STATUS_DEFAULT)
   1072 			key = KEYC_MOUSEMOVE_STATUS_DEFAULT;
   1073 		if (where == BORDER)
   1074 			key = KEYC_MOUSEMOVE_BORDER;
   1075 		break;
   1076 	case DRAG:
   1077 		if (c->tty.mouse_drag_update != NULL)
   1078 			key = KEYC_DRAGGING;
   1079 		else {
   1080 			switch (MOUSE_BUTTONS(b)) {
   1081 			case MOUSE_BUTTON_1:
   1082 				if (where == PANE)
   1083 					key = KEYC_MOUSEDRAG1_PANE;
   1084 				if (where == STATUS)
   1085 					key = KEYC_MOUSEDRAG1_STATUS;
   1086 				if (where == STATUS_LEFT)
   1087 					key = KEYC_MOUSEDRAG1_STATUS_LEFT;
   1088 				if (where == STATUS_RIGHT)
   1089 					key = KEYC_MOUSEDRAG1_STATUS_RIGHT;
   1090 				if (where == STATUS_DEFAULT)
   1091 					key = KEYC_MOUSEDRAG1_STATUS_DEFAULT;
   1092 				if (where == SCROLLBAR_UP)
   1093 					key = KEYC_MOUSEDRAG1_SCROLLBAR_UP;
   1094 				if (where == SCROLLBAR_SLIDER)
   1095 					key = KEYC_MOUSEDRAG1_SCROLLBAR_SLIDER;
   1096 				if (where == SCROLLBAR_DOWN)
   1097 					key = KEYC_MOUSEDRAG1_SCROLLBAR_DOWN;
   1098 				if (where == BORDER)
   1099 					key = KEYC_MOUSEDRAG1_BORDER;
   1100 				break;
   1101 			case MOUSE_BUTTON_2:
   1102 				if (where == PANE)
   1103 					key = KEYC_MOUSEDRAG2_PANE;
   1104 				if (where == STATUS)
   1105 					key = KEYC_MOUSEDRAG2_STATUS;
   1106 				if (where == STATUS_LEFT)
   1107 					key = KEYC_MOUSEDRAG2_STATUS_LEFT;
   1108 				if (where == STATUS_RIGHT)
   1109 					key = KEYC_MOUSEDRAG2_STATUS_RIGHT;
   1110 				if (where == STATUS_DEFAULT)
   1111 					key = KEYC_MOUSEDRAG2_STATUS_DEFAULT;
   1112 				if (where == SCROLLBAR_UP)
   1113 					key = KEYC_MOUSEDRAG2_SCROLLBAR_UP;
   1114 				if (where == SCROLLBAR_SLIDER)
   1115 					key = KEYC_MOUSEDRAG2_SCROLLBAR_SLIDER;
   1116 				if (where == SCROLLBAR_DOWN)
   1117 					key = KEYC_MOUSEDRAG2_SCROLLBAR_DOWN;
   1118 				if (where == BORDER)
   1119 					key = KEYC_MOUSEDRAG2_BORDER;
   1120 				break;
   1121 			case MOUSE_BUTTON_3:
   1122 				if (where == PANE)
   1123 					key = KEYC_MOUSEDRAG3_PANE;
   1124 				if (where == STATUS)
   1125 					key = KEYC_MOUSEDRAG3_STATUS;
   1126 				if (where == STATUS_LEFT)
   1127 					key = KEYC_MOUSEDRAG3_STATUS_LEFT;
   1128 				if (where == STATUS_RIGHT)
   1129 					key = KEYC_MOUSEDRAG3_STATUS_RIGHT;
   1130 				if (where == STATUS_DEFAULT)
   1131 					key = KEYC_MOUSEDRAG3_STATUS_DEFAULT;
   1132 				if (where == SCROLLBAR_UP)
   1133 					key = KEYC_MOUSEDRAG3_SCROLLBAR_UP;
   1134 				if (where == SCROLLBAR_SLIDER)
   1135 					key = KEYC_MOUSEDRAG3_SCROLLBAR_SLIDER;
   1136 				if (where == SCROLLBAR_DOWN)
   1137 					key = KEYC_MOUSEDRAG3_SCROLLBAR_DOWN;
   1138 				if (where == BORDER)
   1139 					key = KEYC_MOUSEDRAG3_BORDER;
   1140 				break;
   1141 			case MOUSE_BUTTON_6:
   1142 				if (where == PANE)
   1143 					key = KEYC_MOUSEDRAG6_PANE;
   1144 				if (where == STATUS)
   1145 					key = KEYC_MOUSEDRAG6_STATUS;
   1146 				if (where == STATUS_LEFT)
   1147 					key = KEYC_MOUSEDRAG6_STATUS_LEFT;
   1148 				if (where == STATUS_RIGHT)
   1149 					key = KEYC_MOUSEDRAG6_STATUS_RIGHT;
   1150 				if (where == STATUS_DEFAULT)
   1151 					key = KEYC_MOUSEDRAG6_STATUS_DEFAULT;
   1152 				if (where == SCROLLBAR_UP)
   1153 					key = KEYC_MOUSEDRAG6_SCROLLBAR_UP;
   1154 				if (where == SCROLLBAR_SLIDER)
   1155 					key = KEYC_MOUSEDRAG6_SCROLLBAR_SLIDER;
   1156 				if (where == SCROLLBAR_DOWN)
   1157 					key = KEYC_MOUSEDRAG6_SCROLLBAR_DOWN;
   1158 				if (where == BORDER)
   1159 					key = KEYC_MOUSEDRAG6_BORDER;
   1160 				break;
   1161 			case MOUSE_BUTTON_7:
   1162 				if (where == PANE)
   1163 					key = KEYC_MOUSEDRAG7_PANE;
   1164 				if (where == STATUS)
   1165 					key = KEYC_MOUSEDRAG7_STATUS;
   1166 				if (where == STATUS_LEFT)
   1167 					key = KEYC_MOUSEDRAG7_STATUS_LEFT;
   1168 				if (where == STATUS_RIGHT)
   1169 					key = KEYC_MOUSEDRAG7_STATUS_RIGHT;
   1170 				if (where == STATUS_DEFAULT)
   1171 					key = KEYC_MOUSEDRAG7_STATUS_DEFAULT;
   1172 				if (where == SCROLLBAR_UP)
   1173 					key = KEYC_MOUSEDRAG7_SCROLLBAR_UP;
   1174 				if (where == SCROLLBAR_SLIDER)
   1175 					key = KEYC_MOUSEDRAG7_SCROLLBAR_SLIDER;
   1176 				if (where == SCROLLBAR_DOWN)
   1177 					key = KEYC_MOUSEDRAG7_SCROLLBAR_DOWN;
   1178 				if (where == BORDER)
   1179 					key = KEYC_MOUSEDRAG7_BORDER;
   1180 				break;
   1181 			case MOUSE_BUTTON_8:
   1182 				if (where == PANE)
   1183 					key = KEYC_MOUSEDRAG8_PANE;
   1184 				if (where == STATUS)
   1185 					key = KEYC_MOUSEDRAG8_STATUS;
   1186 				if (where == STATUS_LEFT)
   1187 					key = KEYC_MOUSEDRAG8_STATUS_LEFT;
   1188 				if (where == STATUS_RIGHT)
   1189 					key = KEYC_MOUSEDRAG8_STATUS_RIGHT;
   1190 				if (where == STATUS_DEFAULT)
   1191 					key = KEYC_MOUSEDRAG8_STATUS_DEFAULT;
   1192 				if (where == SCROLLBAR_UP)
   1193 					key = KEYC_MOUSEDRAG8_SCROLLBAR_UP;
   1194 				if (where == SCROLLBAR_SLIDER)
   1195 					key = KEYC_MOUSEDRAG8_SCROLLBAR_SLIDER;
   1196 				if (where == SCROLLBAR_DOWN)
   1197 					key = KEYC_MOUSEDRAG8_SCROLLBAR_DOWN;
   1198 				if (where == BORDER)
   1199 					key = KEYC_MOUSEDRAG8_BORDER;
   1200 				break;
   1201 			case MOUSE_BUTTON_9:
   1202 				if (where == PANE)
   1203 					key = KEYC_MOUSEDRAG9_PANE;
   1204 				if (where == STATUS)
   1205 					key = KEYC_MOUSEDRAG9_STATUS;
   1206 				if (where == STATUS_LEFT)
   1207 					key = KEYC_MOUSEDRAG9_STATUS_LEFT;
   1208 				if (where == STATUS_RIGHT)
   1209 					key = KEYC_MOUSEDRAG9_STATUS_RIGHT;
   1210 				if (where == STATUS_DEFAULT)
   1211 					key = KEYC_MOUSEDRAG9_STATUS_DEFAULT;
   1212 				if (where == SCROLLBAR_UP)
   1213 					key = KEYC_MOUSEDRAG9_SCROLLBAR_UP;
   1214 				if (where == SCROLLBAR_SLIDER)
   1215 					key = KEYC_MOUSEDRAG9_SCROLLBAR_SLIDER;
   1216 				if (where == SCROLLBAR_DOWN)
   1217 					key = KEYC_MOUSEDRAG9_SCROLLBAR_DOWN;
   1218 				if (where == BORDER)
   1219 					key = KEYC_MOUSEDRAG9_BORDER;
   1220 				break;
   1221 			case MOUSE_BUTTON_10:
   1222 				if (where == PANE)
   1223 					key = KEYC_MOUSEDRAG10_PANE;
   1224 				if (where == STATUS)
   1225 					key = KEYC_MOUSEDRAG10_STATUS;
   1226 				if (where == STATUS_LEFT)
   1227 					key = KEYC_MOUSEDRAG10_STATUS_LEFT;
   1228 				if (where == STATUS_RIGHT)
   1229 					key = KEYC_MOUSEDRAG10_STATUS_RIGHT;
   1230 				if (where == STATUS_DEFAULT)
   1231 					key = KEYC_MOUSEDRAG10_STATUS_DEFAULT;
   1232 				if (where == SCROLLBAR_UP)
   1233 					key = KEYC_MOUSEDRAG10_SCROLLBAR_UP;
   1234 				if (where == SCROLLBAR_SLIDER)
   1235 					key = KEYC_MOUSEDRAG10_SCROLLBAR_SLIDER;
   1236 				if (where == SCROLLBAR_DOWN)
   1237 					key = KEYC_MOUSEDRAG10_SCROLLBAR_DOWN;
   1238 				if (where == BORDER)
   1239 					key = KEYC_MOUSEDRAG10_BORDER;
   1240 				break;
   1241 			case MOUSE_BUTTON_11:
   1242 				if (where == PANE)
   1243 					key = KEYC_MOUSEDRAG11_PANE;
   1244 				if (where == STATUS)
   1245 					key = KEYC_MOUSEDRAG11_STATUS;
   1246 				if (where == STATUS_LEFT)
   1247 					key = KEYC_MOUSEDRAG11_STATUS_LEFT;
   1248 				if (where == STATUS_RIGHT)
   1249 					key = KEYC_MOUSEDRAG11_STATUS_RIGHT;
   1250 				if (where == STATUS_DEFAULT)
   1251 					key = KEYC_MOUSEDRAG11_STATUS_DEFAULT;
   1252 				if (where == SCROLLBAR_UP)
   1253 					key = KEYC_MOUSEDRAG11_SCROLLBAR_UP;
   1254 				if (where == SCROLLBAR_SLIDER)
   1255 					key = KEYC_MOUSEDRAG11_SCROLLBAR_SLIDER;
   1256 				if (where == SCROLLBAR_DOWN)
   1257 					key = KEYC_MOUSEDRAG11_SCROLLBAR_DOWN;
   1258 				if (where == BORDER)
   1259 					key = KEYC_MOUSEDRAG11_BORDER;
   1260 				break;
   1261 			}
   1262 		}
   1263 
   1264 		/*
   1265 		 * Begin a drag by setting the flag to a non-zero value that
   1266 		 * corresponds to the mouse button in use. If starting to drag
   1267 		 * the scrollbar, store the relative position in the slider
   1268 		 * where the user grabbed.
   1269 		 */
   1270 		c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1;
   1271 		if (c->tty.mouse_scrolling_flag == 0 &&
   1272 		    where == SCROLLBAR_SLIDER) {
   1273 			c->tty.mouse_scrolling_flag = 1;
   1274 			if (m->statusat == 0) {
   1275 				c->tty.mouse_slider_mpos = sl_mpos +
   1276 				    m->statuslines;
   1277 			} else
   1278 				c->tty.mouse_slider_mpos = sl_mpos;
   1279 		}
   1280 		break;
   1281 	case WHEEL:
   1282 		if (MOUSE_BUTTONS(b) == MOUSE_WHEEL_UP) {
   1283 			if (where == PANE)
   1284 				key = KEYC_WHEELUP_PANE;
   1285 			if (where == STATUS)
   1286 				key = KEYC_WHEELUP_STATUS;
   1287 			if (where == STATUS_LEFT)
   1288 				key = KEYC_WHEELUP_STATUS_LEFT;
   1289 			if (where == STATUS_RIGHT)
   1290 				key = KEYC_WHEELUP_STATUS_RIGHT;
   1291 			if (where == STATUS_DEFAULT)
   1292 				key = KEYC_WHEELUP_STATUS_DEFAULT;
   1293 			if (where == BORDER)
   1294 				key = KEYC_WHEELUP_BORDER;
   1295 		} else {
   1296 			if (where == PANE)
   1297 				key = KEYC_WHEELDOWN_PANE;
   1298 			if (where == STATUS)
   1299 				key = KEYC_WHEELDOWN_STATUS;
   1300 			if (where == STATUS_LEFT)
   1301 				key = KEYC_WHEELDOWN_STATUS_LEFT;
   1302 			if (where == STATUS_RIGHT)
   1303 				key = KEYC_WHEELDOWN_STATUS_RIGHT;
   1304 			if (where == STATUS_DEFAULT)
   1305 				key = KEYC_WHEELDOWN_STATUS_DEFAULT;
   1306 			if (where == BORDER)
   1307 				key = KEYC_WHEELDOWN_BORDER;
   1308 		}
   1309 		break;
   1310 	case UP:
   1311 		switch (MOUSE_BUTTONS(b)) {
   1312 		case MOUSE_BUTTON_1:
   1313 			if (where == PANE)
   1314 				key = KEYC_MOUSEUP1_PANE;
   1315 			if (where == STATUS)
   1316 				key = KEYC_MOUSEUP1_STATUS;
   1317 			if (where == STATUS_LEFT)
   1318 				key = KEYC_MOUSEUP1_STATUS_LEFT;
   1319 			if (where == STATUS_RIGHT)
   1320 				key = KEYC_MOUSEUP1_STATUS_RIGHT;
   1321 			if (where == STATUS_DEFAULT)
   1322 				key = KEYC_MOUSEUP1_STATUS_DEFAULT;
   1323 			if (where == SCROLLBAR_UP)
   1324 				key = KEYC_MOUSEUP1_SCROLLBAR_UP;
   1325 			if (where == SCROLLBAR_SLIDER)
   1326 				key = KEYC_MOUSEUP1_SCROLLBAR_SLIDER;
   1327 			if (where == SCROLLBAR_DOWN)
   1328 				key = KEYC_MOUSEUP1_SCROLLBAR_DOWN;
   1329 			if (where == BORDER)
   1330 				key = KEYC_MOUSEUP1_BORDER;
   1331 			break;
   1332 		case MOUSE_BUTTON_2:
   1333 			if (where == PANE)
   1334 				key = KEYC_MOUSEUP2_PANE;
   1335 			if (where == STATUS)
   1336 				key = KEYC_MOUSEUP2_STATUS;
   1337 			if (where == STATUS_LEFT)
   1338 				key = KEYC_MOUSEUP2_STATUS_LEFT;
   1339 			if (where == STATUS_RIGHT)
   1340 				key = KEYC_MOUSEUP2_STATUS_RIGHT;
   1341 			if (where == STATUS_DEFAULT)
   1342 				key = KEYC_MOUSEUP2_STATUS_DEFAULT;
   1343 			if (where == SCROLLBAR_UP)
   1344 				key = KEYC_MOUSEUP2_SCROLLBAR_UP;
   1345 			if (where == SCROLLBAR_SLIDER)
   1346 				key = KEYC_MOUSEUP2_SCROLLBAR_SLIDER;
   1347 			if (where == SCROLLBAR_DOWN)
   1348 				key = KEYC_MOUSEUP2_SCROLLBAR_DOWN;
   1349 			if (where == BORDER)
   1350 				key = KEYC_MOUSEUP2_BORDER;
   1351 			break;
   1352 		case MOUSE_BUTTON_3:
   1353 			if (where == PANE)
   1354 				key = KEYC_MOUSEUP3_PANE;
   1355 			if (where == STATUS)
   1356 				key = KEYC_MOUSEUP3_STATUS;
   1357 			if (where == STATUS_LEFT)
   1358 				key = KEYC_MOUSEUP3_STATUS_LEFT;
   1359 			if (where == STATUS_RIGHT)
   1360 				key = KEYC_MOUSEUP3_STATUS_RIGHT;
   1361 			if (where == STATUS_DEFAULT)
   1362 				key = KEYC_MOUSEUP3_STATUS_DEFAULT;
   1363 			if (where == SCROLLBAR_UP)
   1364 				key = KEYC_MOUSEUP3_SCROLLBAR_UP;
   1365 			if (where == SCROLLBAR_SLIDER)
   1366 				key = KEYC_MOUSEUP3_SCROLLBAR_SLIDER;
   1367 			if (where == SCROLLBAR_DOWN)
   1368 				key = KEYC_MOUSEUP3_SCROLLBAR_DOWN;
   1369 			if (where == BORDER)
   1370 				key = KEYC_MOUSEUP3_BORDER;
   1371 			break;
   1372 		case MOUSE_BUTTON_6:
   1373 			if (where == PANE)
   1374 				key = KEYC_MOUSEUP6_PANE;
   1375 			if (where == STATUS)
   1376 				key = KEYC_MOUSEUP6_STATUS;
   1377 			if (where == STATUS_LEFT)
   1378 				key = KEYC_MOUSEUP6_STATUS_LEFT;
   1379 			if (where == STATUS_RIGHT)
   1380 				key = KEYC_MOUSEUP6_STATUS_RIGHT;
   1381 			if (where == STATUS_DEFAULT)
   1382 				key = KEYC_MOUSEUP6_STATUS_DEFAULT;
   1383 			if (where == SCROLLBAR_UP)
   1384 				key = KEYC_MOUSEUP6_SCROLLBAR_UP;
   1385 			if (where == SCROLLBAR_SLIDER)
   1386 				key = KEYC_MOUSEUP6_SCROLLBAR_SLIDER;
   1387 			if (where == SCROLLBAR_DOWN)
   1388 				key = KEYC_MOUSEUP6_SCROLLBAR_DOWN;
   1389 			if (where == BORDER)
   1390 				key = KEYC_MOUSEUP6_BORDER;
   1391 			break;
   1392 		case MOUSE_BUTTON_7:
   1393 			if (where == PANE)
   1394 				key = KEYC_MOUSEUP7_PANE;
   1395 			if (where == STATUS)
   1396 				key = KEYC_MOUSEUP7_STATUS;
   1397 			if (where == STATUS_LEFT)
   1398 				key = KEYC_MOUSEUP7_STATUS_LEFT;
   1399 			if (where == STATUS_RIGHT)
   1400 				key = KEYC_MOUSEUP7_STATUS_RIGHT;
   1401 			if (where == STATUS_DEFAULT)
   1402 				key = KEYC_MOUSEUP7_STATUS_DEFAULT;
   1403 			if (where == SCROLLBAR_UP)
   1404 				key = KEYC_MOUSEUP7_SCROLLBAR_UP;
   1405 			if (where == SCROLLBAR_SLIDER)
   1406 				key = KEYC_MOUSEUP7_SCROLLBAR_SLIDER;
   1407 			if (where == SCROLLBAR_DOWN)
   1408 				key = KEYC_MOUSEUP7_SCROLLBAR_DOWN;
   1409 			if (where == BORDER)
   1410 				key = KEYC_MOUSEUP7_BORDER;
   1411 			break;
   1412 		case MOUSE_BUTTON_8:
   1413 			if (where == PANE)
   1414 				key = KEYC_MOUSEUP8_PANE;
   1415 			if (where == STATUS)
   1416 				key = KEYC_MOUSEUP8_STATUS;
   1417 			if (where == STATUS_LEFT)
   1418 				key = KEYC_MOUSEUP8_STATUS_LEFT;
   1419 			if (where == STATUS_RIGHT)
   1420 				key = KEYC_MOUSEUP8_STATUS_RIGHT;
   1421 			if (where == STATUS_DEFAULT)
   1422 				key = KEYC_MOUSEUP8_STATUS_DEFAULT;
   1423 			if (where == SCROLLBAR_UP)
   1424 				key = KEYC_MOUSEUP8_SCROLLBAR_UP;
   1425 			if (where == SCROLLBAR_SLIDER)
   1426 				key = KEYC_MOUSEUP8_SCROLLBAR_SLIDER;
   1427 			if (where == SCROLLBAR_DOWN)
   1428 				key = KEYC_MOUSEUP8_SCROLLBAR_DOWN;
   1429 			if (where == BORDER)
   1430 				key = KEYC_MOUSEUP8_BORDER;
   1431 			break;
   1432 		case MOUSE_BUTTON_9:
   1433 			if (where == PANE)
   1434 				key = KEYC_MOUSEUP9_PANE;
   1435 			if (where == STATUS)
   1436 				key = KEYC_MOUSEUP9_STATUS;
   1437 			if (where == STATUS_LEFT)
   1438 				key = KEYC_MOUSEUP9_STATUS_LEFT;
   1439 			if (where == STATUS_RIGHT)
   1440 				key = KEYC_MOUSEUP9_STATUS_RIGHT;
   1441 			if (where == STATUS_DEFAULT)
   1442 				key = KEYC_MOUSEUP9_STATUS_DEFAULT;
   1443 			if (where == SCROLLBAR_UP)
   1444 				key = KEYC_MOUSEUP9_SCROLLBAR_UP;
   1445 			if (where == SCROLLBAR_SLIDER)
   1446 				key = KEYC_MOUSEUP9_SCROLLBAR_SLIDER;
   1447 			if (where == SCROLLBAR_DOWN)
   1448 				key = KEYC_MOUSEUP9_SCROLLBAR_DOWN;
   1449 			if (where == BORDER)
   1450 				key = KEYC_MOUSEUP9_BORDER;
   1451 			break;
   1452 		case MOUSE_BUTTON_10:
   1453 			if (where == PANE)
   1454 				key = KEYC_MOUSEUP1_PANE;
   1455 			if (where == STATUS)
   1456 				key = KEYC_MOUSEUP1_STATUS;
   1457 			if (where == STATUS_LEFT)
   1458 				key = KEYC_MOUSEUP1_STATUS_LEFT;
   1459 			if (where == STATUS_RIGHT)
   1460 				key = KEYC_MOUSEUP1_STATUS_RIGHT;
   1461 			if (where == STATUS_DEFAULT)
   1462 				key = KEYC_MOUSEUP10_STATUS_DEFAULT;
   1463 			if (where == SCROLLBAR_UP)
   1464 				key = KEYC_MOUSEUP10_SCROLLBAR_UP;
   1465 			if (where == SCROLLBAR_SLIDER)
   1466 				key = KEYC_MOUSEUP10_SCROLLBAR_SLIDER;
   1467 			if (where == SCROLLBAR_DOWN)
   1468 				key = KEYC_MOUSEUP1_SCROLLBAR_DOWN;
   1469 			if (where == BORDER)
   1470 				key = KEYC_MOUSEUP1_BORDER;
   1471 			break;
   1472 		case MOUSE_BUTTON_11:
   1473 			if (where == PANE)
   1474 				key = KEYC_MOUSEUP11_PANE;
   1475 			if (where == STATUS)
   1476 				key = KEYC_MOUSEUP11_STATUS;
   1477 			if (where == STATUS_LEFT)
   1478 				key = KEYC_MOUSEUP11_STATUS_LEFT;
   1479 			if (where == STATUS_RIGHT)
   1480 				key = KEYC_MOUSEUP11_STATUS_RIGHT;
   1481 			if (where == STATUS_DEFAULT)
   1482 				key = KEYC_MOUSEUP11_STATUS_DEFAULT;
   1483 			if (where == SCROLLBAR_UP)
   1484 				key = KEYC_MOUSEUP11_SCROLLBAR_UP;
   1485 			if (where == SCROLLBAR_SLIDER)
   1486 				key = KEYC_MOUSEUP11_SCROLLBAR_SLIDER;
   1487 			if (where == SCROLLBAR_DOWN)
   1488 				key = KEYC_MOUSEUP11_SCROLLBAR_DOWN;
   1489 			if (where == BORDER)
   1490 				key = KEYC_MOUSEUP11_BORDER;
   1491 			break;
   1492 		}
   1493 		break;
   1494 	case DOWN:
   1495 		switch (MOUSE_BUTTONS(b)) {
   1496 		case MOUSE_BUTTON_1:
   1497 			if (where == PANE)
   1498 				key = KEYC_MOUSEDOWN1_PANE;
   1499 			if (where == STATUS)
   1500 				key = KEYC_MOUSEDOWN1_STATUS;
   1501 			if (where == STATUS_LEFT)
   1502 				key = KEYC_MOUSEDOWN1_STATUS_LEFT;
   1503 			if (where == STATUS_RIGHT)
   1504 				key = KEYC_MOUSEDOWN1_STATUS_RIGHT;
   1505 			if (where == STATUS_DEFAULT)
   1506 				key = KEYC_MOUSEDOWN1_STATUS_DEFAULT;
   1507 			if (where == SCROLLBAR_UP)
   1508 				key = KEYC_MOUSEDOWN1_SCROLLBAR_UP;
   1509 			if (where == SCROLLBAR_SLIDER)
   1510 				key = KEYC_MOUSEDOWN1_SCROLLBAR_SLIDER;
   1511 			if (where == SCROLLBAR_DOWN)
   1512 				key = KEYC_MOUSEDOWN1_SCROLLBAR_DOWN;
   1513 			if (where == BORDER)
   1514 				key = KEYC_MOUSEDOWN1_BORDER;
   1515 			break;
   1516 		case MOUSE_BUTTON_2:
   1517 			if (where == PANE)
   1518 				key = KEYC_MOUSEDOWN2_PANE;
   1519 			if (where == STATUS)
   1520 				key = KEYC_MOUSEDOWN2_STATUS;
   1521 			if (where == STATUS_LEFT)
   1522 				key = KEYC_MOUSEDOWN2_STATUS_LEFT;
   1523 			if (where == STATUS_RIGHT)
   1524 				key = KEYC_MOUSEDOWN2_STATUS_RIGHT;
   1525 			if (where == STATUS_DEFAULT)
   1526 				key = KEYC_MOUSEDOWN2_STATUS_DEFAULT;
   1527 			if (where == SCROLLBAR_UP)
   1528 				key = KEYC_MOUSEDOWN2_SCROLLBAR_UP;
   1529 			if (where == SCROLLBAR_SLIDER)
   1530 				key = KEYC_MOUSEDOWN2_SCROLLBAR_SLIDER;
   1531 			if (where == SCROLLBAR_DOWN)
   1532 				key = KEYC_MOUSEDOWN2_SCROLLBAR_DOWN;
   1533 			if (where == BORDER)
   1534 				key = KEYC_MOUSEDOWN2_BORDER;
   1535 			break;
   1536 		case MOUSE_BUTTON_3:
   1537 			if (where == PANE)
   1538 				key = KEYC_MOUSEDOWN3_PANE;
   1539 			if (where == STATUS)
   1540 				key = KEYC_MOUSEDOWN3_STATUS;
   1541 			if (where == STATUS_LEFT)
   1542 				key = KEYC_MOUSEDOWN3_STATUS_LEFT;
   1543 			if (where == STATUS_RIGHT)
   1544 				key = KEYC_MOUSEDOWN3_STATUS_RIGHT;
   1545 			if (where == STATUS_DEFAULT)
   1546 				key = KEYC_MOUSEDOWN3_STATUS_DEFAULT;
   1547 			if (where == SCROLLBAR_UP)
   1548 				key = KEYC_MOUSEDOWN3_SCROLLBAR_UP;
   1549 			if (where == SCROLLBAR_SLIDER)
   1550 				key = KEYC_MOUSEDOWN3_SCROLLBAR_SLIDER;
   1551 			if (where == SCROLLBAR_DOWN)
   1552 				key = KEYC_MOUSEDOWN3_SCROLLBAR_DOWN;
   1553 			if (where == BORDER)
   1554 				key = KEYC_MOUSEDOWN3_BORDER;
   1555 			break;
   1556 		case MOUSE_BUTTON_6:
   1557 			if (where == PANE)
   1558 				key = KEYC_MOUSEDOWN6_PANE;
   1559 			if (where == STATUS)
   1560 				key = KEYC_MOUSEDOWN6_STATUS;
   1561 			if (where == STATUS_LEFT)
   1562 				key = KEYC_MOUSEDOWN6_STATUS_LEFT;
   1563 			if (where == STATUS_RIGHT)
   1564 				key = KEYC_MOUSEDOWN6_STATUS_RIGHT;
   1565 			if (where == STATUS_DEFAULT)
   1566 				key = KEYC_MOUSEDOWN6_STATUS_DEFAULT;
   1567 			if (where == SCROLLBAR_UP)
   1568 				key = KEYC_MOUSEDOWN6_SCROLLBAR_UP;
   1569 			if (where == SCROLLBAR_SLIDER)
   1570 				key = KEYC_MOUSEDOWN6_SCROLLBAR_SLIDER;
   1571 			if (where == SCROLLBAR_DOWN)
   1572 				key = KEYC_MOUSEDOWN6_SCROLLBAR_DOWN;
   1573 			if (where == BORDER)
   1574 				key = KEYC_MOUSEDOWN6_BORDER;
   1575 			break;
   1576 		case MOUSE_BUTTON_7:
   1577 			if (where == PANE)
   1578 				key = KEYC_MOUSEDOWN7_PANE;
   1579 			if (where == STATUS)
   1580 				key = KEYC_MOUSEDOWN7_STATUS;
   1581 			if (where == STATUS_LEFT)
   1582 				key = KEYC_MOUSEDOWN7_STATUS_LEFT;
   1583 			if (where == STATUS_RIGHT)
   1584 				key = KEYC_MOUSEDOWN7_STATUS_RIGHT;
   1585 			if (where == STATUS_DEFAULT)
   1586 				key = KEYC_MOUSEDOWN7_STATUS_DEFAULT;
   1587 			if (where == SCROLLBAR_UP)
   1588 				key = KEYC_MOUSEDOWN7_SCROLLBAR_UP;
   1589 			if (where == SCROLLBAR_SLIDER)
   1590 				key = KEYC_MOUSEDOWN7_SCROLLBAR_SLIDER;
   1591 			if (where == SCROLLBAR_DOWN)
   1592 				key = KEYC_MOUSEDOWN7_SCROLLBAR_DOWN;
   1593 			if (where == BORDER)
   1594 				key = KEYC_MOUSEDOWN7_BORDER;
   1595 			break;
   1596 		case MOUSE_BUTTON_8:
   1597 			if (where == PANE)
   1598 				key = KEYC_MOUSEDOWN8_PANE;
   1599 			if (where == STATUS)
   1600 				key = KEYC_MOUSEDOWN8_STATUS;
   1601 			if (where == STATUS_LEFT)
   1602 				key = KEYC_MOUSEDOWN8_STATUS_LEFT;
   1603 			if (where == STATUS_RIGHT)
   1604 				key = KEYC_MOUSEDOWN8_STATUS_RIGHT;
   1605 			if (where == STATUS_DEFAULT)
   1606 				key = KEYC_MOUSEDOWN8_STATUS_DEFAULT;
   1607 			if (where == SCROLLBAR_UP)
   1608 				key = KEYC_MOUSEDOWN8_SCROLLBAR_UP;
   1609 			if (where == SCROLLBAR_SLIDER)
   1610 				key = KEYC_MOUSEDOWN8_SCROLLBAR_SLIDER;
   1611 			if (where == SCROLLBAR_DOWN)
   1612 				key = KEYC_MOUSEDOWN8_SCROLLBAR_DOWN;
   1613 			if (where == BORDER)
   1614 				key = KEYC_MOUSEDOWN8_BORDER;
   1615 			break;
   1616 		case MOUSE_BUTTON_9:
   1617 			if (where == PANE)
   1618 				key = KEYC_MOUSEDOWN9_PANE;
   1619 			if (where == STATUS)
   1620 				key = KEYC_MOUSEDOWN9_STATUS;
   1621 			if (where == STATUS_LEFT)
   1622 				key = KEYC_MOUSEDOWN9_STATUS_LEFT;
   1623 			if (where == STATUS_RIGHT)
   1624 				key = KEYC_MOUSEDOWN9_STATUS_RIGHT;
   1625 			if (where == STATUS_DEFAULT)
   1626 				key = KEYC_MOUSEDOWN9_STATUS_DEFAULT;
   1627 			if (where == SCROLLBAR_UP)
   1628 				key = KEYC_MOUSEDOWN9_SCROLLBAR_UP;
   1629 			if (where == SCROLLBAR_SLIDER)
   1630 				key = KEYC_MOUSEDOWN9_SCROLLBAR_SLIDER;
   1631 			if (where == SCROLLBAR_DOWN)
   1632 				key = KEYC_MOUSEDOWN9_SCROLLBAR_DOWN;
   1633 			if (where == BORDER)
   1634 				key = KEYC_MOUSEDOWN9_BORDER;
   1635 			break;
   1636 		case MOUSE_BUTTON_10:
   1637 			if (where == PANE)
   1638 				key = KEYC_MOUSEDOWN10_PANE;
   1639 			if (where == STATUS)
   1640 				key = KEYC_MOUSEDOWN10_STATUS;
   1641 			if (where == STATUS_LEFT)
   1642 				key = KEYC_MOUSEDOWN10_STATUS_LEFT;
   1643 			if (where == STATUS_RIGHT)
   1644 				key = KEYC_MOUSEDOWN10_STATUS_RIGHT;
   1645 			if (where == STATUS_DEFAULT)
   1646 				key = KEYC_MOUSEDOWN10_STATUS_DEFAULT;
   1647 			if (where == SCROLLBAR_UP)
   1648 				key = KEYC_MOUSEDOWN10_SCROLLBAR_UP;
   1649 			if (where == SCROLLBAR_SLIDER)
   1650 				key = KEYC_MOUSEDOWN10_SCROLLBAR_SLIDER;
   1651 			if (where == SCROLLBAR_DOWN)
   1652 				key = KEYC_MOUSEDOWN10_SCROLLBAR_DOWN;
   1653 			if (where == BORDER)
   1654 				key = KEYC_MOUSEDOWN10_BORDER;
   1655 			break;
   1656 		case MOUSE_BUTTON_11:
   1657 			if (where == PANE)
   1658 				key = KEYC_MOUSEDOWN11_PANE;
   1659 			if (where == STATUS)
   1660 				key = KEYC_MOUSEDOWN11_STATUS;
   1661 			if (where == STATUS_LEFT)
   1662 				key = KEYC_MOUSEDOWN11_STATUS_LEFT;
   1663 			if (where == STATUS_RIGHT)
   1664 				key = KEYC_MOUSEDOWN11_STATUS_RIGHT;
   1665 			if (where == STATUS_DEFAULT)
   1666 				key = KEYC_MOUSEDOWN11_STATUS_DEFAULT;
   1667 			if (where == SCROLLBAR_UP)
   1668 				key = KEYC_MOUSEDOWN11_SCROLLBAR_UP;
   1669 			if (where == SCROLLBAR_SLIDER)
   1670 				key = KEYC_MOUSEDOWN11_SCROLLBAR_SLIDER;
   1671 			if (where == SCROLLBAR_DOWN)
   1672 				key = KEYC_MOUSEDOWN11_SCROLLBAR_DOWN;
   1673 			if (where == BORDER)
   1674 				key = KEYC_MOUSEDOWN11_BORDER;
   1675 			break;
   1676 		}
   1677 		break;
   1678 	case SECOND:
   1679 		switch (MOUSE_BUTTONS(b)) {
   1680 		case MOUSE_BUTTON_1:
   1681 			if (where == PANE)
   1682 				key = KEYC_SECONDCLICK1_PANE;
   1683 			if (where == STATUS)
   1684 				key = KEYC_SECONDCLICK1_STATUS;
   1685 			if (where == STATUS_LEFT)
   1686 				key = KEYC_SECONDCLICK1_STATUS_LEFT;
   1687 			if (where == STATUS_RIGHT)
   1688 				key = KEYC_SECONDCLICK1_STATUS_RIGHT;
   1689 			if (where == STATUS_DEFAULT)
   1690 				key = KEYC_SECONDCLICK1_STATUS_DEFAULT;
   1691 			if (where == SCROLLBAR_UP)
   1692 				key = KEYC_SECONDCLICK1_SCROLLBAR_UP;
   1693 			if (where == SCROLLBAR_SLIDER)
   1694 				key = KEYC_SECONDCLICK1_SCROLLBAR_SLIDER;
   1695 			if (where == SCROLLBAR_DOWN)
   1696 				key = KEYC_SECONDCLICK1_SCROLLBAR_DOWN;
   1697 			if (where == BORDER)
   1698 				key = KEYC_SECONDCLICK1_BORDER;
   1699 			break;
   1700 		case MOUSE_BUTTON_2:
   1701 			if (where == PANE)
   1702 				key = KEYC_SECONDCLICK2_PANE;
   1703 			if (where == STATUS)
   1704 				key = KEYC_SECONDCLICK2_STATUS;
   1705 			if (where == STATUS_LEFT)
   1706 				key = KEYC_SECONDCLICK2_STATUS_LEFT;
   1707 			if (where == STATUS_RIGHT)
   1708 				key = KEYC_SECONDCLICK2_STATUS_RIGHT;
   1709 			if (where == STATUS_DEFAULT)
   1710 				key = KEYC_SECONDCLICK2_STATUS_DEFAULT;
   1711 			if (where == SCROLLBAR_UP)
   1712 				key = KEYC_SECONDCLICK2_SCROLLBAR_UP;
   1713 			if (where == SCROLLBAR_SLIDER)
   1714 				key = KEYC_SECONDCLICK2_SCROLLBAR_SLIDER;
   1715 			if (where == SCROLLBAR_DOWN)
   1716 				key = KEYC_SECONDCLICK2_SCROLLBAR_DOWN;
   1717 			if (where == BORDER)
   1718 				key = KEYC_SECONDCLICK2_BORDER;
   1719 			break;
   1720 		case MOUSE_BUTTON_3:
   1721 			if (where == PANE)
   1722 				key = KEYC_SECONDCLICK3_PANE;
   1723 			if (where == STATUS)
   1724 				key = KEYC_SECONDCLICK3_STATUS;
   1725 			if (where == STATUS_LEFT)
   1726 				key = KEYC_SECONDCLICK3_STATUS_LEFT;
   1727 			if (where == STATUS_RIGHT)
   1728 				key = KEYC_SECONDCLICK3_STATUS_RIGHT;
   1729 			if (where == STATUS_DEFAULT)
   1730 				key = KEYC_SECONDCLICK3_STATUS_DEFAULT;
   1731 			if (where == SCROLLBAR_UP)
   1732 				key = KEYC_SECONDCLICK3_SCROLLBAR_UP;
   1733 			if (where == SCROLLBAR_SLIDER)
   1734 				key = KEYC_SECONDCLICK3_SCROLLBAR_SLIDER;
   1735 			if (where == SCROLLBAR_DOWN)
   1736 				key = KEYC_SECONDCLICK3_SCROLLBAR_DOWN;
   1737 			if (where == BORDER)
   1738 				key = KEYC_SECONDCLICK3_BORDER;
   1739 			break;
   1740 		case MOUSE_BUTTON_6:
   1741 			if (where == PANE)
   1742 				key = KEYC_SECONDCLICK6_PANE;
   1743 			if (where == STATUS)
   1744 				key = KEYC_SECONDCLICK6_STATUS;
   1745 			if (where == STATUS_LEFT)
   1746 				key = KEYC_SECONDCLICK6_STATUS_LEFT;
   1747 			if (where == STATUS_RIGHT)
   1748 				key = KEYC_SECONDCLICK6_STATUS_RIGHT;
   1749 			if (where == STATUS_DEFAULT)
   1750 				key = KEYC_SECONDCLICK6_STATUS_DEFAULT;
   1751 			if (where == SCROLLBAR_UP)
   1752 				key = KEYC_SECONDCLICK6_SCROLLBAR_UP;
   1753 			if (where == SCROLLBAR_SLIDER)
   1754 				key = KEYC_SECONDCLICK6_SCROLLBAR_SLIDER;
   1755 			if (where == SCROLLBAR_DOWN)
   1756 				key = KEYC_SECONDCLICK6_SCROLLBAR_DOWN;
   1757 			if (where == BORDER)
   1758 				key = KEYC_SECONDCLICK6_BORDER;
   1759 			break;
   1760 		case MOUSE_BUTTON_7:
   1761 			if (where == PANE)
   1762 				key = KEYC_SECONDCLICK7_PANE;
   1763 			if (where == STATUS)
   1764 				key = KEYC_SECONDCLICK7_STATUS;
   1765 			if (where == STATUS_LEFT)
   1766 				key = KEYC_SECONDCLICK7_STATUS_LEFT;
   1767 			if (where == STATUS_RIGHT)
   1768 				key = KEYC_SECONDCLICK7_STATUS_RIGHT;
   1769 			if (where == STATUS_DEFAULT)
   1770 				key = KEYC_SECONDCLICK7_STATUS_DEFAULT;
   1771 			if (where == SCROLLBAR_UP)
   1772 				key = KEYC_SECONDCLICK7_SCROLLBAR_UP;
   1773 			if (where == SCROLLBAR_SLIDER)
   1774 				key = KEYC_SECONDCLICK7_SCROLLBAR_SLIDER;
   1775 			if (where == SCROLLBAR_DOWN)
   1776 				key = KEYC_SECONDCLICK7_SCROLLBAR_DOWN;
   1777 			if (where == BORDER)
   1778 				key = KEYC_SECONDCLICK7_BORDER;
   1779 			break;
   1780 		case MOUSE_BUTTON_8:
   1781 			if (where == PANE)
   1782 				key = KEYC_SECONDCLICK8_PANE;
   1783 			if (where == STATUS)
   1784 				key = KEYC_SECONDCLICK8_STATUS;
   1785 			if (where == STATUS_LEFT)
   1786 				key = KEYC_SECONDCLICK8_STATUS_LEFT;
   1787 			if (where == STATUS_RIGHT)
   1788 				key = KEYC_SECONDCLICK8_STATUS_RIGHT;
   1789 			if (where == STATUS_DEFAULT)
   1790 				key = KEYC_SECONDCLICK8_STATUS_DEFAULT;
   1791 			if (where == SCROLLBAR_UP)
   1792 				key = KEYC_SECONDCLICK8_SCROLLBAR_UP;
   1793 			if (where == SCROLLBAR_SLIDER)
   1794 				key = KEYC_SECONDCLICK8_SCROLLBAR_SLIDER;
   1795 			if (where == SCROLLBAR_DOWN)
   1796 				key = KEYC_SECONDCLICK8_SCROLLBAR_DOWN;
   1797 			if (where == BORDER)
   1798 				key = KEYC_SECONDCLICK8_BORDER;
   1799 			break;
   1800 		case MOUSE_BUTTON_9:
   1801 			if (where == PANE)
   1802 				key = KEYC_SECONDCLICK9_PANE;
   1803 			if (where == STATUS)
   1804 				key = KEYC_SECONDCLICK9_STATUS;
   1805 			if (where == STATUS_LEFT)
   1806 				key = KEYC_SECONDCLICK9_STATUS_LEFT;
   1807 			if (where == STATUS_RIGHT)
   1808 				key = KEYC_SECONDCLICK9_STATUS_RIGHT;
   1809 			if (where == STATUS_DEFAULT)
   1810 				key = KEYC_SECONDCLICK9_STATUS_DEFAULT;
   1811 			if (where == SCROLLBAR_UP)
   1812 				key = KEYC_SECONDCLICK9_SCROLLBAR_UP;
   1813 			if (where == SCROLLBAR_SLIDER)
   1814 				key = KEYC_SECONDCLICK9_SCROLLBAR_SLIDER;
   1815 			if (where == SCROLLBAR_DOWN)
   1816 				key = KEYC_SECONDCLICK9_SCROLLBAR_DOWN;
   1817 			if (where == BORDER)
   1818 				key = KEYC_SECONDCLICK9_BORDER;
   1819 			break;
   1820 		case MOUSE_BUTTON_10:
   1821 			if (where == PANE)
   1822 				key = KEYC_SECONDCLICK10_PANE;
   1823 			if (where == STATUS)
   1824 				key = KEYC_SECONDCLICK10_STATUS;
   1825 			if (where == STATUS_LEFT)
   1826 				key = KEYC_SECONDCLICK10_STATUS_LEFT;
   1827 			if (where == STATUS_RIGHT)
   1828 				key = KEYC_SECONDCLICK10_STATUS_RIGHT;
   1829 			if (where == STATUS_DEFAULT)
   1830 				key = KEYC_SECONDCLICK10_STATUS_DEFAULT;
   1831 			if (where == SCROLLBAR_UP)
   1832 				key = KEYC_SECONDCLICK10_SCROLLBAR_UP;
   1833 			if (where == SCROLLBAR_SLIDER)
   1834 				key = KEYC_SECONDCLICK10_SCROLLBAR_SLIDER;
   1835 			if (where == SCROLLBAR_DOWN)
   1836 				key = KEYC_SECONDCLICK10_SCROLLBAR_DOWN;
   1837 			if (where == BORDER)
   1838 				key = KEYC_SECONDCLICK10_BORDER;
   1839 			break;
   1840 		case MOUSE_BUTTON_11:
   1841 			if (where == PANE)
   1842 				key = KEYC_SECONDCLICK11_PANE;
   1843 			if (where == STATUS)
   1844 				key = KEYC_SECONDCLICK11_STATUS;
   1845 			if (where == STATUS_LEFT)
   1846 				key = KEYC_SECONDCLICK11_STATUS_LEFT;
   1847 			if (where == STATUS_RIGHT)
   1848 				key = KEYC_SECONDCLICK11_STATUS_RIGHT;
   1849 			if (where == STATUS_DEFAULT)
   1850 				key = KEYC_SECONDCLICK11_STATUS_DEFAULT;
   1851 			if (where == SCROLLBAR_UP)
   1852 				key = KEYC_SECONDCLICK11_SCROLLBAR_UP;
   1853 			if (where == SCROLLBAR_SLIDER)
   1854 				key = KEYC_SECONDCLICK11_SCROLLBAR_SLIDER;
   1855 			if (where == SCROLLBAR_DOWN)
   1856 				key = KEYC_SECONDCLICK11_SCROLLBAR_DOWN;
   1857 			if (where == BORDER)
   1858 				key = KEYC_SECONDCLICK11_BORDER;
   1859 			break;
   1860 		}
   1861 		break;
   1862 	case DOUBLE:
   1863 		switch (MOUSE_BUTTONS(b)) {
   1864 		case MOUSE_BUTTON_1:
   1865 			if (where == PANE)
   1866 				key = KEYC_DOUBLECLICK1_PANE;
   1867 			if (where == STATUS)
   1868 				key = KEYC_DOUBLECLICK1_STATUS;
   1869 			if (where == STATUS_LEFT)
   1870 				key = KEYC_DOUBLECLICK1_STATUS_LEFT;
   1871 			if (where == STATUS_RIGHT)
   1872 				key = KEYC_DOUBLECLICK1_STATUS_RIGHT;
   1873 			if (where == STATUS_DEFAULT)
   1874 				key = KEYC_DOUBLECLICK1_STATUS_DEFAULT;
   1875 			if (where == SCROLLBAR_UP)
   1876 				key = KEYC_DOUBLECLICK1_SCROLLBAR_UP;
   1877 			if (where == SCROLLBAR_SLIDER)
   1878 				key = KEYC_DOUBLECLICK1_SCROLLBAR_SLIDER;
   1879 			if (where == SCROLLBAR_DOWN)
   1880 				key = KEYC_DOUBLECLICK1_SCROLLBAR_DOWN;
   1881 			if (where == BORDER)
   1882 				key = KEYC_DOUBLECLICK1_BORDER;
   1883 			break;
   1884 		case MOUSE_BUTTON_2:
   1885 			if (where == PANE)
   1886 				key = KEYC_DOUBLECLICK2_PANE;
   1887 			if (where == STATUS)
   1888 				key = KEYC_DOUBLECLICK2_STATUS;
   1889 			if (where == STATUS_LEFT)
   1890 				key = KEYC_DOUBLECLICK2_STATUS_LEFT;
   1891 			if (where == STATUS_RIGHT)
   1892 				key = KEYC_DOUBLECLICK2_STATUS_RIGHT;
   1893 			if (where == STATUS_DEFAULT)
   1894 				key = KEYC_DOUBLECLICK2_STATUS_DEFAULT;
   1895 			if (where == SCROLLBAR_UP)
   1896 				key = KEYC_DOUBLECLICK2_SCROLLBAR_UP;
   1897 			if (where == SCROLLBAR_SLIDER)
   1898 				key = KEYC_DOUBLECLICK2_SCROLLBAR_SLIDER;
   1899 			if (where == SCROLLBAR_DOWN)
   1900 				key = KEYC_DOUBLECLICK2_SCROLLBAR_DOWN;
   1901 			if (where == BORDER)
   1902 				key = KEYC_DOUBLECLICK2_BORDER;
   1903 			break;
   1904 		case MOUSE_BUTTON_3:
   1905 			if (where == PANE)
   1906 				key = KEYC_DOUBLECLICK3_PANE;
   1907 			if (where == STATUS)
   1908 				key = KEYC_DOUBLECLICK3_STATUS;
   1909 			if (where == STATUS_LEFT)
   1910 				key = KEYC_DOUBLECLICK3_STATUS_LEFT;
   1911 			if (where == STATUS_RIGHT)
   1912 				key = KEYC_DOUBLECLICK3_STATUS_RIGHT;
   1913 			if (where == STATUS_DEFAULT)
   1914 				key = KEYC_DOUBLECLICK3_STATUS_DEFAULT;
   1915 			if (where == SCROLLBAR_UP)
   1916 				key = KEYC_DOUBLECLICK3_SCROLLBAR_UP;
   1917 			if (where == SCROLLBAR_SLIDER)
   1918 				key = KEYC_DOUBLECLICK3_SCROLLBAR_SLIDER;
   1919 			if (where == SCROLLBAR_DOWN)
   1920 				key = KEYC_DOUBLECLICK3_SCROLLBAR_DOWN;
   1921 			if (where == BORDER)
   1922 				key = KEYC_DOUBLECLICK3_BORDER;
   1923 			break;
   1924 		case MOUSE_BUTTON_6:
   1925 			if (where == PANE)
   1926 				key = KEYC_DOUBLECLICK6_PANE;
   1927 			if (where == STATUS)
   1928 				key = KEYC_DOUBLECLICK6_STATUS;
   1929 			if (where == STATUS_LEFT)
   1930 				key = KEYC_DOUBLECLICK6_STATUS_LEFT;
   1931 			if (where == STATUS_RIGHT)
   1932 				key = KEYC_DOUBLECLICK6_STATUS_RIGHT;
   1933 			if (where == STATUS_DEFAULT)
   1934 				key = KEYC_DOUBLECLICK6_STATUS_DEFAULT;
   1935 			if (where == SCROLLBAR_UP)
   1936 				key = KEYC_DOUBLECLICK6_SCROLLBAR_UP;
   1937 			if (where == SCROLLBAR_SLIDER)
   1938 				key = KEYC_DOUBLECLICK6_SCROLLBAR_SLIDER;
   1939 			if (where == SCROLLBAR_DOWN)
   1940 				key = KEYC_DOUBLECLICK6_SCROLLBAR_DOWN;
   1941 			if (where == BORDER)
   1942 				key = KEYC_DOUBLECLICK6_BORDER;
   1943 			break;
   1944 		case MOUSE_BUTTON_7:
   1945 			if (where == PANE)
   1946 				key = KEYC_DOUBLECLICK7_PANE;
   1947 			if (where == STATUS)
   1948 				key = KEYC_DOUBLECLICK7_STATUS;
   1949 			if (where == STATUS_LEFT)
   1950 				key = KEYC_DOUBLECLICK7_STATUS_LEFT;
   1951 			if (where == STATUS_RIGHT)
   1952 				key = KEYC_DOUBLECLICK7_STATUS_RIGHT;
   1953 			if (where == STATUS_DEFAULT)
   1954 				key = KEYC_DOUBLECLICK7_STATUS_DEFAULT;
   1955 			if (where == SCROLLBAR_UP)
   1956 				key = KEYC_DOUBLECLICK7_SCROLLBAR_UP;
   1957 			if (where == SCROLLBAR_SLIDER)
   1958 				key = KEYC_DOUBLECLICK7_SCROLLBAR_SLIDER;
   1959 			if (where == SCROLLBAR_DOWN)
   1960 				key = KEYC_DOUBLECLICK7_SCROLLBAR_DOWN;
   1961 			if (where == BORDER)
   1962 				key = KEYC_DOUBLECLICK7_BORDER;
   1963 			break;
   1964 		case MOUSE_BUTTON_8:
   1965 			if (where == PANE)
   1966 				key = KEYC_DOUBLECLICK8_PANE;
   1967 			if (where == STATUS)
   1968 				key = KEYC_DOUBLECLICK8_STATUS;
   1969 			if (where == STATUS_LEFT)
   1970 				key = KEYC_DOUBLECLICK8_STATUS_LEFT;
   1971 			if (where == STATUS_RIGHT)
   1972 				key = KEYC_DOUBLECLICK8_STATUS_RIGHT;
   1973 			if (where == STATUS_DEFAULT)
   1974 				key = KEYC_DOUBLECLICK8_STATUS_DEFAULT;
   1975 			if (where == SCROLLBAR_UP)
   1976 				key = KEYC_DOUBLECLICK8_SCROLLBAR_UP;
   1977 			if (where == SCROLLBAR_SLIDER)
   1978 				key = KEYC_DOUBLECLICK8_SCROLLBAR_SLIDER;
   1979 			if (where == SCROLLBAR_DOWN)
   1980 				key = KEYC_DOUBLECLICK8_SCROLLBAR_DOWN;
   1981 			if (where == BORDER)
   1982 				key = KEYC_DOUBLECLICK8_BORDER;
   1983 			break;
   1984 		case MOUSE_BUTTON_9:
   1985 			if (where == PANE)
   1986 				key = KEYC_DOUBLECLICK9_PANE;
   1987 			if (where == STATUS)
   1988 				key = KEYC_DOUBLECLICK9_STATUS;
   1989 			if (where == STATUS_LEFT)
   1990 				key = KEYC_DOUBLECLICK9_STATUS_LEFT;
   1991 			if (where == STATUS_RIGHT)
   1992 				key = KEYC_DOUBLECLICK9_STATUS_RIGHT;
   1993 			if (where == STATUS_DEFAULT)
   1994 				key = KEYC_DOUBLECLICK9_STATUS_DEFAULT;
   1995 			if (where == SCROLLBAR_UP)
   1996 				key = KEYC_DOUBLECLICK9_SCROLLBAR_UP;
   1997 			if (where == SCROLLBAR_SLIDER)
   1998 				key = KEYC_DOUBLECLICK9_SCROLLBAR_SLIDER;
   1999 			if (where == SCROLLBAR_DOWN)
   2000 				key = KEYC_DOUBLECLICK9_SCROLLBAR_DOWN;
   2001 			if (where == BORDER)
   2002 				key = KEYC_DOUBLECLICK9_BORDER;
   2003 			break;
   2004 		case MOUSE_BUTTON_10:
   2005 			if (where == PANE)
   2006 				key = KEYC_DOUBLECLICK10_PANE;
   2007 			if (where == STATUS)
   2008 				key = KEYC_DOUBLECLICK10_STATUS;
   2009 			if (where == STATUS_LEFT)
   2010 				key = KEYC_DOUBLECLICK10_STATUS_LEFT;
   2011 			if (where == STATUS_RIGHT)
   2012 				key = KEYC_DOUBLECLICK10_STATUS_RIGHT;
   2013 			if (where == STATUS_DEFAULT)
   2014 				key = KEYC_DOUBLECLICK10_STATUS_DEFAULT;
   2015 			if (where == SCROLLBAR_UP)
   2016 				key = KEYC_DOUBLECLICK10_SCROLLBAR_UP;
   2017 			if (where == SCROLLBAR_SLIDER)
   2018 				key = KEYC_DOUBLECLICK10_SCROLLBAR_SLIDER;
   2019 			if (where == SCROLLBAR_DOWN)
   2020 				key = KEYC_DOUBLECLICK10_SCROLLBAR_DOWN;
   2021 			if (where == BORDER)
   2022 				key = KEYC_DOUBLECLICK10_BORDER;
   2023 			break;
   2024 		case MOUSE_BUTTON_11:
   2025 			if (where == PANE)
   2026 				key = KEYC_DOUBLECLICK11_PANE;
   2027 			if (where == STATUS)
   2028 				key = KEYC_DOUBLECLICK11_STATUS;
   2029 			if (where == STATUS_LEFT)
   2030 				key = KEYC_DOUBLECLICK11_STATUS_LEFT;
   2031 			if (where == STATUS_RIGHT)
   2032 				key = KEYC_DOUBLECLICK11_STATUS_RIGHT;
   2033 			if (where == STATUS_DEFAULT)
   2034 				key = KEYC_DOUBLECLICK11_STATUS_DEFAULT;
   2035 			if (where == SCROLLBAR_UP)
   2036 				key = KEYC_DOUBLECLICK11_SCROLLBAR_UP;
   2037 			if (where == SCROLLBAR_SLIDER)
   2038 				key = KEYC_DOUBLECLICK11_SCROLLBAR_SLIDER;
   2039 			if (where == SCROLLBAR_DOWN)
   2040 				key = KEYC_DOUBLECLICK11_SCROLLBAR_DOWN;
   2041 			if (where == BORDER)
   2042 				key = KEYC_DOUBLECLICK11_BORDER;
   2043 			break;
   2044 		}
   2045 		break;
   2046 	case TRIPLE:
   2047 		switch (MOUSE_BUTTONS(b)) {
   2048 		case MOUSE_BUTTON_1:
   2049 			if (where == PANE)
   2050 				key = KEYC_TRIPLECLICK1_PANE;
   2051 			if (where == STATUS)
   2052 				key = KEYC_TRIPLECLICK1_STATUS;
   2053 			if (where == STATUS_LEFT)
   2054 				key = KEYC_TRIPLECLICK1_STATUS_LEFT;
   2055 			if (where == STATUS_RIGHT)
   2056 				key = KEYC_TRIPLECLICK1_STATUS_RIGHT;
   2057 			if (where == STATUS_DEFAULT)
   2058 				key = KEYC_TRIPLECLICK1_STATUS_DEFAULT;
   2059 			if (where == SCROLLBAR_UP)
   2060 				key = KEYC_TRIPLECLICK1_SCROLLBAR_UP;
   2061 			if (where == SCROLLBAR_SLIDER)
   2062 				key = KEYC_TRIPLECLICK1_SCROLLBAR_SLIDER;
   2063 			if (where == SCROLLBAR_DOWN)
   2064 				key = KEYC_TRIPLECLICK1_SCROLLBAR_DOWN;
   2065 			if (where == BORDER)
   2066 				key = KEYC_TRIPLECLICK1_BORDER;
   2067 			break;
   2068 		case MOUSE_BUTTON_2:
   2069 			if (where == PANE)
   2070 				key = KEYC_TRIPLECLICK2_PANE;
   2071 			if (where == STATUS)
   2072 				key = KEYC_TRIPLECLICK2_STATUS;
   2073 			if (where == STATUS_LEFT)
   2074 				key = KEYC_TRIPLECLICK2_STATUS_LEFT;
   2075 			if (where == STATUS_RIGHT)
   2076 				key = KEYC_TRIPLECLICK2_STATUS_RIGHT;
   2077 			if (where == STATUS_DEFAULT)
   2078 				key = KEYC_TRIPLECLICK2_STATUS_DEFAULT;
   2079 			if (where == SCROLLBAR_UP)
   2080 				key = KEYC_TRIPLECLICK2_SCROLLBAR_UP;
   2081 			if (where == SCROLLBAR_SLIDER)
   2082 				key = KEYC_TRIPLECLICK2_SCROLLBAR_SLIDER;
   2083 			if (where == SCROLLBAR_DOWN)
   2084 				key = KEYC_TRIPLECLICK2_SCROLLBAR_DOWN;
   2085 			if (where == BORDER)
   2086 				key = KEYC_TRIPLECLICK2_BORDER;
   2087 			break;
   2088 		case MOUSE_BUTTON_3:
   2089 			if (where == PANE)
   2090 				key = KEYC_TRIPLECLICK3_PANE;
   2091 			if (where == STATUS)
   2092 				key = KEYC_TRIPLECLICK3_STATUS;
   2093 			if (where == STATUS_LEFT)
   2094 				key = KEYC_TRIPLECLICK3_STATUS_LEFT;
   2095 			if (where == STATUS_RIGHT)
   2096 				key = KEYC_TRIPLECLICK3_STATUS_RIGHT;
   2097 			if (where == STATUS_DEFAULT)
   2098 				key = KEYC_TRIPLECLICK3_STATUS_DEFAULT;
   2099 			if (where == SCROLLBAR_UP)
   2100 				key = KEYC_TRIPLECLICK3_SCROLLBAR_UP;
   2101 			if (where == SCROLLBAR_SLIDER)
   2102 				key = KEYC_TRIPLECLICK3_SCROLLBAR_SLIDER;
   2103 			if (where == SCROLLBAR_DOWN)
   2104 				key = KEYC_TRIPLECLICK3_SCROLLBAR_DOWN;
   2105 			if (where == BORDER)
   2106 				key = KEYC_TRIPLECLICK3_BORDER;
   2107 			break;
   2108 		case MOUSE_BUTTON_6:
   2109 			if (where == PANE)
   2110 				key = KEYC_TRIPLECLICK6_PANE;
   2111 			if (where == STATUS)
   2112 				key = KEYC_TRIPLECLICK6_STATUS;
   2113 			if (where == STATUS_LEFT)
   2114 				key = KEYC_TRIPLECLICK6_STATUS_LEFT;
   2115 			if (where == STATUS_RIGHT)
   2116 				key = KEYC_TRIPLECLICK6_STATUS_RIGHT;
   2117 			if (where == STATUS_DEFAULT)
   2118 				key = KEYC_TRIPLECLICK6_STATUS_DEFAULT;
   2119 			if (where == SCROLLBAR_UP)
   2120 				key = KEYC_TRIPLECLICK6_SCROLLBAR_UP;
   2121 			if (where == SCROLLBAR_SLIDER)
   2122 				key = KEYC_TRIPLECLICK6_SCROLLBAR_SLIDER;
   2123 			if (where == SCROLLBAR_DOWN)
   2124 				key = KEYC_TRIPLECLICK6_SCROLLBAR_DOWN;
   2125 			if (where == BORDER)
   2126 				key = KEYC_TRIPLECLICK6_BORDER;
   2127 			break;
   2128 		case MOUSE_BUTTON_7:
   2129 			if (where == PANE)
   2130 				key = KEYC_TRIPLECLICK7_PANE;
   2131 			if (where == STATUS)
   2132 				key = KEYC_TRIPLECLICK7_STATUS;
   2133 			if (where == STATUS_LEFT)
   2134 				key = KEYC_TRIPLECLICK7_STATUS_LEFT;
   2135 			if (where == STATUS_RIGHT)
   2136 				key = KEYC_TRIPLECLICK7_STATUS_RIGHT;
   2137 			if (where == STATUS_DEFAULT)
   2138 				key = KEYC_TRIPLECLICK7_STATUS_DEFAULT;
   2139 			if (where == SCROLLBAR_UP)
   2140 				key = KEYC_TRIPLECLICK7_SCROLLBAR_UP;
   2141 			if (where == SCROLLBAR_SLIDER)
   2142 				key = KEYC_TRIPLECLICK7_SCROLLBAR_SLIDER;
   2143 			if (where == SCROLLBAR_DOWN)
   2144 				key = KEYC_TRIPLECLICK7_SCROLLBAR_DOWN;
   2145 			if (where == BORDER)
   2146 				key = KEYC_TRIPLECLICK7_BORDER;
   2147 			break;
   2148 		case MOUSE_BUTTON_8:
   2149 			if (where == PANE)
   2150 				key = KEYC_TRIPLECLICK8_PANE;
   2151 			if (where == STATUS)
   2152 				key = KEYC_TRIPLECLICK8_STATUS;
   2153 			if (where == STATUS_LEFT)
   2154 				key = KEYC_TRIPLECLICK8_STATUS_LEFT;
   2155 			if (where == STATUS_RIGHT)
   2156 				key = KEYC_TRIPLECLICK8_STATUS_RIGHT;
   2157 			if (where == STATUS_DEFAULT)
   2158 				key = KEYC_TRIPLECLICK8_STATUS_DEFAULT;
   2159 			if (where == SCROLLBAR_UP)
   2160 				key = KEYC_TRIPLECLICK8_SCROLLBAR_UP;
   2161 			if (where == SCROLLBAR_SLIDER)
   2162 				key = KEYC_TRIPLECLICK8_SCROLLBAR_SLIDER;
   2163 			if (where == SCROLLBAR_DOWN)
   2164 				key = KEYC_TRIPLECLICK8_SCROLLBAR_DOWN;
   2165 			if (where == BORDER)
   2166 				key = KEYC_TRIPLECLICK8_BORDER;
   2167 			break;
   2168 		case MOUSE_BUTTON_9:
   2169 			if (where == PANE)
   2170 				key = KEYC_TRIPLECLICK9_PANE;
   2171 			if (where == STATUS)
   2172 				key = KEYC_TRIPLECLICK9_STATUS;
   2173 			if (where == STATUS_LEFT)
   2174 				key = KEYC_TRIPLECLICK9_STATUS_LEFT;
   2175 			if (where == STATUS_RIGHT)
   2176 				key = KEYC_TRIPLECLICK9_STATUS_RIGHT;
   2177 			if (where == STATUS_DEFAULT)
   2178 				key = KEYC_TRIPLECLICK9_STATUS_DEFAULT;
   2179 			if (where == SCROLLBAR_UP)
   2180 				key = KEYC_TRIPLECLICK9_SCROLLBAR_UP;
   2181 			if (where == SCROLLBAR_SLIDER)
   2182 				key = KEYC_TRIPLECLICK9_SCROLLBAR_SLIDER;
   2183 			if (where == SCROLLBAR_DOWN)
   2184 				key = KEYC_TRIPLECLICK9_SCROLLBAR_DOWN;
   2185 			if (where == BORDER)
   2186 				key = KEYC_TRIPLECLICK9_BORDER;
   2187 			break;
   2188 		case MOUSE_BUTTON_10:
   2189 			if (where == PANE)
   2190 				key = KEYC_TRIPLECLICK10_PANE;
   2191 			if (where == STATUS)
   2192 				key = KEYC_TRIPLECLICK10_STATUS;
   2193 			if (where == STATUS_LEFT)
   2194 				key = KEYC_TRIPLECLICK10_STATUS_LEFT;
   2195 			if (where == STATUS_RIGHT)
   2196 				key = KEYC_TRIPLECLICK10_STATUS_RIGHT;
   2197 			if (where == STATUS_DEFAULT)
   2198 				key = KEYC_TRIPLECLICK10_STATUS_DEFAULT;
   2199 			if (where == SCROLLBAR_UP)
   2200 				key = KEYC_TRIPLECLICK10_SCROLLBAR_UP;
   2201 			if (where == SCROLLBAR_SLIDER)
   2202 				key = KEYC_TRIPLECLICK10_SCROLLBAR_SLIDER;
   2203 			if (where == SCROLLBAR_DOWN)
   2204 				key = KEYC_TRIPLECLICK10_SCROLLBAR_DOWN;
   2205 			if (where == BORDER)
   2206 				key = KEYC_TRIPLECLICK10_BORDER;
   2207 			break;
   2208 		case MOUSE_BUTTON_11:
   2209 			if (where == PANE)
   2210 				key = KEYC_TRIPLECLICK11_PANE;
   2211 			if (where == STATUS)
   2212 				key = KEYC_TRIPLECLICK11_STATUS;
   2213 			if (where == STATUS_LEFT)
   2214 				key = KEYC_TRIPLECLICK11_STATUS_LEFT;
   2215 			if (where == STATUS_RIGHT)
   2216 				key = KEYC_TRIPLECLICK11_STATUS_RIGHT;
   2217 			if (where == STATUS_DEFAULT)
   2218 				key = KEYC_TRIPLECLICK11_STATUS_DEFAULT;
   2219 			if (where == SCROLLBAR_UP)
   2220 				key = KEYC_TRIPLECLICK11_SCROLLBAR_UP;
   2221 			if (where == SCROLLBAR_SLIDER)
   2222 				key = KEYC_TRIPLECLICK11_SCROLLBAR_SLIDER;
   2223 			if (where == SCROLLBAR_DOWN)
   2224 				key = KEYC_TRIPLECLICK11_SCROLLBAR_DOWN;
   2225 			if (where == BORDER)
   2226 				key = KEYC_TRIPLECLICK11_BORDER;
   2227 			break;
   2228 		}
   2229 		break;
   2230 	}
   2231 	if (key == KEYC_UNKNOWN)
   2232 		return (KEYC_UNKNOWN);
   2233 
   2234 out:
   2235 	/* Apply modifiers if any. */
   2236 	if (b & MOUSE_MASK_META)
   2237 		key |= KEYC_META;
   2238 	if (b & MOUSE_MASK_CTRL)
   2239 		key |= KEYC_CTRL;
   2240 	if (b & MOUSE_MASK_SHIFT)
   2241 		key |= KEYC_SHIFT;
   2242 
   2243 	if (log_get_level() != 0)
   2244 		log_debug("mouse key is %s", key_string_lookup_key (key, 1));
   2245 	return (key);
   2246 }
   2247 
   2248 /* Is this a bracket paste key? */
   2249 static int
   2250 server_client_is_bracket_paste(struct client *c, key_code key)
   2251 {
   2252 	if ((key & KEYC_MASK_KEY) == KEYC_PASTE_START) {
   2253 		c->flags |= CLIENT_BRACKETPASTING;
   2254 		log_debug("%s: bracket paste on", c->name);
   2255 		return (0);
   2256 	}
   2257 
   2258 	if ((key & KEYC_MASK_KEY) == KEYC_PASTE_END) {
   2259 		c->flags &= ~CLIENT_BRACKETPASTING;
   2260 		log_debug("%s: bracket paste off", c->name);
   2261 		return (0);
   2262 	}
   2263 
   2264 	return !!(c->flags & CLIENT_BRACKETPASTING);
   2265 }
   2266 
   2267 /* Is this fast enough to probably be a paste? */
   2268 static int
   2269 server_client_is_assume_paste(struct client *c)
   2270 {
   2271 	struct session	*s = c->session;
   2272 	struct timeval	 tv;
   2273 	int		 t;
   2274 
   2275 	if (c->flags & CLIENT_BRACKETPASTING)
   2276 		return (0);
   2277 	if ((t = options_get_number(s->options, "assume-paste-time")) == 0)
   2278 		return (0);
   2279 
   2280 	timersub(&c->activity_time, &c->last_activity_time, &tv);
   2281 	if (tv.tv_sec == 0 && tv.tv_usec < t * 1000) {
   2282 		if (c->flags & CLIENT_ASSUMEPASTING)
   2283 			return (1);
   2284 		c->flags |= CLIENT_ASSUMEPASTING;
   2285 		log_debug("%s: assume paste on", c->name);
   2286 		return (0);
   2287 	}
   2288 	if (c->flags & CLIENT_ASSUMEPASTING) {
   2289 		c->flags &= ~CLIENT_ASSUMEPASTING;
   2290 		log_debug("%s: assume paste off", c->name);
   2291 	}
   2292 	return (0);
   2293 }
   2294 
   2295 /* Has the latest client changed? */
   2296 static void
   2297 server_client_update_latest(struct client *c)
   2298 {
   2299 	struct window	*w;
   2300 
   2301 	if (c->session == NULL)
   2302 		return;
   2303 	w = c->session->curw->window;
   2304 
   2305 	if (w->latest == c)
   2306 		return;
   2307 	w->latest = c;
   2308 
   2309 	if (options_get_number(w->options, "window-size") == WINDOW_SIZE_LATEST)
   2310 		recalculate_size(w, 0);
   2311 
   2312 	notify_client("client-active", c);
   2313 }
   2314 
   2315 /* Get repeat time. */
   2316 static u_int
   2317 server_client_repeat_time(struct client *c, struct key_binding *bd)
   2318 {
   2319 	struct session	*s = c->session;
   2320 	u_int		 repeat, initial;
   2321 
   2322 	if (~bd->flags & KEY_BINDING_REPEAT)
   2323 		return (0);
   2324 	repeat = options_get_number(s->options, "repeat-time");
   2325 	if (repeat == 0)
   2326 		return (0);
   2327 	if ((~c->flags & CLIENT_REPEAT) || bd->key != c->last_key) {
   2328 		initial = options_get_number(s->options, "initial-repeat-time");
   2329 		if (initial != 0)
   2330 			repeat = initial;
   2331 	}
   2332 	return (repeat);
   2333 }
   2334 
   2335 /*
   2336  * Handle data key input from client. This owns and can modify the key event it
   2337  * is given and is responsible for freeing it.
   2338  */
   2339 static enum cmd_retval
   2340 server_client_key_callback(struct cmdq_item *item, void *data)
   2341 {
   2342 	struct client			*c = cmdq_get_client(item);
   2343 	struct key_event		*event = data;
   2344 	key_code			 key = event->key;
   2345 	struct mouse_event		*m = &event->m;
   2346 	struct session			*s = c->session;
   2347 	struct winlink			*wl;
   2348 	struct window_pane		*wp;
   2349 	struct window_mode_entry	*wme;
   2350 	struct timeval			 tv;
   2351 	struct key_table		*table, *first;
   2352 	struct key_binding		*bd;
   2353 	u_int				 repeat;
   2354 	uint64_t			 flags, prefix_delay;
   2355 	struct cmd_find_state		 fs;
   2356 	key_code			 key0, prefix, prefix2;
   2357 
   2358 	/* Check the client is good to accept input. */
   2359 	if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
   2360 		goto out;
   2361 	wl = s->curw;
   2362 
   2363 	/* Update the activity timer. */
   2364 	memcpy(&c->last_activity_time, &c->activity_time,
   2365 	    sizeof c->last_activity_time);
   2366 	if (gettimeofday(&c->activity_time, NULL) != 0)
   2367 		fatal("gettimeofday failed");
   2368 	session_update_activity(s, &c->activity_time);
   2369 
   2370 	/* Check for mouse keys. */
   2371 	m->valid = 0;
   2372 	if (key == KEYC_MOUSE || key == KEYC_DOUBLECLICK) {
   2373 		if (c->flags & CLIENT_READONLY)
   2374 			goto out;
   2375 		key = server_client_check_mouse(c, event);
   2376 		if (key == KEYC_UNKNOWN)
   2377 			goto out;
   2378 
   2379 		m->valid = 1;
   2380 		m->key = key;
   2381 
   2382 		/*
   2383 		 * Mouse drag is in progress, so fire the callback (now that
   2384 		 * the mouse event is valid).
   2385 		 */
   2386 		if ((key & KEYC_MASK_KEY) == KEYC_DRAGGING) {
   2387 			c->tty.mouse_drag_update(c, m);
   2388 			goto out;
   2389 		}
   2390 		event->key = key;
   2391 	}
   2392 
   2393 	/* Handle theme reporting keys. */
   2394 	if (key == KEYC_REPORT_LIGHT_THEME) {
   2395 		server_client_report_theme(c, THEME_LIGHT);
   2396 		goto out;
   2397 	}
   2398 	if (key == KEYC_REPORT_DARK_THEME) {
   2399 		server_client_report_theme(c, THEME_DARK);
   2400 		goto out;
   2401 	}
   2402 
   2403 	/* Find affected pane. */
   2404 	if (!KEYC_IS_MOUSE(key) || cmd_find_from_mouse(&fs, m, 0) != 0)
   2405 		cmd_find_from_client(&fs, c, 0);
   2406 	wp = fs.wp;
   2407 
   2408 	/* Forward mouse keys if disabled. */
   2409 	if (KEYC_IS_MOUSE(key) && !options_get_number(s->options, "mouse"))
   2410 		goto forward_key;
   2411 
   2412 	/* Forward if bracket pasting. */
   2413 	if (server_client_is_bracket_paste (c, key))
   2414 		goto paste_key;
   2415 
   2416 	/* Treat everything as a regular key when pasting is detected. */
   2417 	if (!KEYC_IS_MOUSE(key) &&
   2418 	    key != KEYC_FOCUS_IN &&
   2419 	    key != KEYC_FOCUS_OUT &&
   2420 	    (~key & KEYC_SENT) &&
   2421 	    server_client_is_assume_paste(c))
   2422 		goto paste_key;
   2423 
   2424 	/*
   2425 	 * Work out the current key table. If the pane is in a mode, use
   2426 	 * the mode table instead of the default key table.
   2427 	 */
   2428 	if (server_client_is_default_key_table(c, c->keytable) &&
   2429 	    wp != NULL &&
   2430 	    (wme = TAILQ_FIRST(&wp->modes)) != NULL &&
   2431 	    wme->mode->key_table != NULL)
   2432 		table = key_bindings_get_table(wme->mode->key_table(wme), 1);
   2433 	else
   2434 		table = c->keytable;
   2435 	first = table;
   2436 
   2437 table_changed:
   2438 	/*
   2439 	 * The prefix always takes precedence and forces a switch to the prefix
   2440 	 * table, unless we are already there.
   2441 	 */
   2442 	prefix = (key_code)options_get_number(s->options, "prefix");
   2443 	prefix2 = (key_code)options_get_number(s->options, "prefix2");
   2444 	key0 = (key & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS));
   2445 	if ((key0 == (prefix & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS)) ||
   2446 	    key0 == (prefix2 & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS))) &&
   2447 	    strcmp(table->name, "prefix") != 0) {
   2448 		server_client_set_key_table(c, "prefix");
   2449 		server_status_client(c);
   2450 		goto out;
   2451 	}
   2452 	flags = c->flags;
   2453 
   2454 try_again:
   2455 	/* Log key table. */
   2456 	if (wp == NULL)
   2457 		log_debug("key table %s (no pane)", table->name);
   2458 	else
   2459 		log_debug("key table %s (pane %%%u)", table->name, wp->id);
   2460 	if (c->flags & CLIENT_REPEAT)
   2461 		log_debug("currently repeating");
   2462 
   2463 	bd = key_bindings_get(table, key0);
   2464 
   2465 	/*
   2466 	 * If prefix-timeout is enabled and we're in the prefix table, see if
   2467 	 * the timeout has been exceeded. Revert to the root table if so.
   2468 	 */
   2469 	prefix_delay = options_get_number(global_options, "prefix-timeout");
   2470 	if (prefix_delay > 0 &&
   2471 	    strcmp(table->name, "prefix") == 0 &&
   2472 	    server_client_key_table_activity_diff(c) > prefix_delay) {
   2473 		/*
   2474 		 * If repeating is active and this is a repeating binding,
   2475 		 * ignore the timeout.
   2476 		 */
   2477 		if (bd != NULL &&
   2478 		    (c->flags & CLIENT_REPEAT) &&
   2479 		    (bd->flags & KEY_BINDING_REPEAT)) {
   2480 			log_debug("prefix timeout ignored, repeat is active");
   2481 		} else {
   2482 			log_debug("prefix timeout exceeded");
   2483 			server_client_set_key_table(c, NULL);
   2484 			first = table = c->keytable;
   2485 			server_status_client(c);
   2486 			goto table_changed;
   2487 		}
   2488 	}
   2489 
   2490 	/* Try to see if there is a key binding in the current table. */
   2491 	if (bd != NULL) {
   2492 		/*
   2493 		 * Key was matched in this table. If currently repeating but a
   2494 		 * non-repeating binding was found, stop repeating and try
   2495 		 * again in the root table.
   2496 		 */
   2497 		if ((c->flags & CLIENT_REPEAT) &&
   2498 		    (~bd->flags & KEY_BINDING_REPEAT)) {
   2499 			log_debug("found in key table %s (not repeating)",
   2500 			    table->name);
   2501 			server_client_set_key_table(c, NULL);
   2502 			first = table = c->keytable;
   2503 			c->flags &= ~CLIENT_REPEAT;
   2504 			server_status_client(c);
   2505 			goto table_changed;
   2506 		}
   2507 		log_debug("found in key table %s", table->name);
   2508 
   2509 		/*
   2510 		 * Take a reference to this table to make sure the key binding
   2511 		 * doesn't disappear.
   2512 		 */
   2513 		table->references++;
   2514 
   2515 		/*
   2516 		 * If this is a repeating key, start the timer. Otherwise reset
   2517 		 * the client back to the root table.
   2518 		 */
   2519 		repeat = server_client_repeat_time(c, bd);
   2520 		if (repeat != 0) {
   2521 			c->flags |= CLIENT_REPEAT;
   2522 			c->last_key = bd->key;
   2523 
   2524 			tv.tv_sec = repeat / 1000;
   2525 			tv.tv_usec = (repeat % 1000) * 1000L;
   2526 			evtimer_del(&c->repeat_timer);
   2527 			evtimer_add(&c->repeat_timer, &tv);
   2528 		} else {
   2529 			c->flags &= ~CLIENT_REPEAT;
   2530 			server_client_set_key_table(c, NULL);
   2531 		}
   2532 		server_status_client(c);
   2533 
   2534 		/* Execute the key binding. */
   2535 		key_bindings_dispatch(bd, item, c, event, &fs);
   2536 		key_bindings_unref_table(table);
   2537 		goto out;
   2538 	}
   2539 
   2540 	/*
   2541 	 * No match, try the ANY key.
   2542 	 */
   2543 	if (key0 != KEYC_ANY) {
   2544 		key0 = KEYC_ANY;
   2545 		goto try_again;
   2546 	}
   2547 
   2548 	/*
   2549 	 * Binding movement keys is useless since we only turn them on when the
   2550 	 * application requests, so don't let them exit the prefix table.
   2551 	 */
   2552 	if (key == KEYC_MOUSEMOVE_PANE ||
   2553 	    key == KEYC_MOUSEMOVE_STATUS ||
   2554 	    key == KEYC_MOUSEMOVE_STATUS_LEFT ||
   2555 	    key == KEYC_MOUSEMOVE_STATUS_RIGHT ||
   2556 	    key == KEYC_MOUSEMOVE_STATUS_DEFAULT ||
   2557 	    key == KEYC_MOUSEMOVE_BORDER)
   2558 		goto forward_key;
   2559 
   2560 	/*
   2561 	 * No match in this table. If not in the root table or if repeating
   2562 	 * switch the client back to the root table and try again.
   2563 	 */
   2564 	log_debug("not found in key table %s", table->name);
   2565 	if (!server_client_is_default_key_table(c, table) ||
   2566 	    (c->flags & CLIENT_REPEAT)) {
   2567 		log_debug("trying in root table");
   2568 		server_client_set_key_table(c, NULL);
   2569 		table = c->keytable;
   2570 		if (c->flags & CLIENT_REPEAT)
   2571 			first = table;
   2572 		c->flags &= ~CLIENT_REPEAT;
   2573 		server_status_client(c);
   2574 		goto table_changed;
   2575 	}
   2576 
   2577 	/*
   2578 	 * No match in the root table either. If this wasn't the first table
   2579 	 * tried, don't pass the key to the pane.
   2580 	 */
   2581 	if (first != table && (~flags & CLIENT_REPEAT)) {
   2582 		server_client_set_key_table(c, NULL);
   2583 		server_status_client(c);
   2584 		goto out;
   2585 	}
   2586 
   2587 forward_key:
   2588 	if (c->flags & CLIENT_READONLY)
   2589 		goto out;
   2590 	if (wp != NULL)
   2591 		window_pane_key(wp, c, s, wl, key, m);
   2592 	goto out;
   2593 
   2594 paste_key:
   2595 	if (c->flags & CLIENT_READONLY)
   2596 		goto out;
   2597 	if (event->buf != NULL)
   2598 		window_pane_paste(wp, key, event->buf, event->len);
   2599 	key = KEYC_NONE;
   2600 	goto out;
   2601 
   2602 out:
   2603 	if (s != NULL && key != KEYC_FOCUS_OUT)
   2604 		server_client_update_latest(c);
   2605 	free(event->buf);
   2606 	free(event);
   2607 	return (CMD_RETURN_NORMAL);
   2608 }
   2609 
   2610 /* Handle a key event. */
   2611 int
   2612 server_client_handle_key(struct client *c, struct key_event *event)
   2613 {
   2614 	struct session		*s = c->session;
   2615 	struct cmdq_item	*item;
   2616 
   2617 	/* Check the client is good to accept input. */
   2618 	if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
   2619 		return (0);
   2620 
   2621 	/*
   2622 	 * Key presses in overlay mode and the command prompt are a special
   2623 	 * case. The queue might be blocked so they need to be processed
   2624 	 * immediately rather than queued.
   2625 	 */
   2626 	if (~c->flags & CLIENT_READONLY) {
   2627 		if (c->message_string != NULL) {
   2628 			if (c->message_ignore_keys)
   2629 				return (0);
   2630 			status_message_clear(c);
   2631 		}
   2632 		if (c->overlay_key != NULL) {
   2633 			switch (c->overlay_key(c, c->overlay_data, event)) {
   2634 			case 0:
   2635 				return (0);
   2636 			case 1:
   2637 				server_client_clear_overlay(c);
   2638 				return (0);
   2639 			}
   2640 		}
   2641 		server_client_clear_overlay(c);
   2642 		if (c->prompt_string != NULL) {
   2643 			if (status_prompt_key(c, event->key) == 0)
   2644 				return (0);
   2645 		}
   2646 	}
   2647 
   2648 	/*
   2649 	 * Add the key to the queue so it happens after any commands queued by
   2650 	 * previous keys.
   2651 	 */
   2652 	item = cmdq_get_callback(server_client_key_callback, event);
   2653 	cmdq_append(c, item);
   2654 	return (1);
   2655 }
   2656 
   2657 /* Client functions that need to happen every loop. */
   2658 void
   2659 server_client_loop(void)
   2660 {
   2661 	struct client		*c;
   2662 	struct window		*w;
   2663 	struct window_pane	*wp;
   2664 
   2665 	/* Check for window resize. This is done before redrawing. */
   2666 	RB_FOREACH(w, windows, &windows)
   2667 		server_client_check_window_resize(w);
   2668 
   2669 	/* Check clients. */
   2670 	TAILQ_FOREACH(c, &clients, entry) {
   2671 		server_client_check_exit(c);
   2672 		if (c->session != NULL) {
   2673 			server_client_check_modes(c);
   2674 			server_client_check_redraw(c);
   2675 			server_client_reset_state(c);
   2676 		}
   2677 	}
   2678 
   2679 	/*
   2680 	 * Any windows will have been redrawn as part of clients, so clear
   2681 	 * their flags now.
   2682 	 */
   2683 	RB_FOREACH(w, windows, &windows) {
   2684 		TAILQ_FOREACH(wp, &w->panes, entry) {
   2685 			if (wp->fd != -1) {
   2686 				server_client_check_pane_resize(wp);
   2687 				server_client_check_pane_buffer(wp);
   2688 			}
   2689 			wp->flags &= ~(PANE_REDRAW|PANE_REDRAWSCROLLBAR);
   2690 		}
   2691 		check_window_name(w);
   2692 	}
   2693 
   2694 	/* Send theme updates. */
   2695 	RB_FOREACH(w, windows, &windows) {
   2696 		TAILQ_FOREACH(wp, &w->panes, entry)
   2697 			window_pane_send_theme_update(wp);
   2698 	}
   2699 }
   2700 
   2701 /* Check if window needs to be resized. */
   2702 static void
   2703 server_client_check_window_resize(struct window *w)
   2704 {
   2705 	struct winlink	*wl;
   2706 
   2707 	if (~w->flags & WINDOW_RESIZE)
   2708 		return;
   2709 
   2710 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
   2711 		if (wl->session->attached != 0 && wl->session->curw == wl)
   2712 			break;
   2713 	}
   2714 	if (wl == NULL)
   2715 		return;
   2716 
   2717 	log_debug("%s: resizing window @%u", __func__, w->id);
   2718 	resize_window(w, w->new_sx, w->new_sy, w->new_xpixel, w->new_ypixel);
   2719 }
   2720 
   2721 /* Resize timer event. */
   2722 static void
   2723 server_client_resize_timer(__unused int fd, __unused short events, void *data)
   2724 {
   2725 	struct window_pane	*wp = data;
   2726 
   2727 	log_debug("%s: %%%u resize timer expired", __func__, wp->id);
   2728 	evtimer_del(&wp->resize_timer);
   2729 }
   2730 
   2731 /* Check if pane should be resized. */
   2732 static void
   2733 server_client_check_pane_resize(struct window_pane *wp)
   2734 {
   2735 	struct window_pane_resize	*r;
   2736 	struct window_pane_resize	*r1;
   2737 	struct window_pane_resize	*first;
   2738 	struct window_pane_resize	*last;
   2739 	struct timeval			 tv = { .tv_usec = 250000 };
   2740 
   2741 	if (TAILQ_EMPTY(&wp->resize_queue))
   2742 		return;
   2743 
   2744 	if (!event_initialized(&wp->resize_timer))
   2745 		evtimer_set(&wp->resize_timer, server_client_resize_timer, wp);
   2746 	if (evtimer_pending(&wp->resize_timer, NULL))
   2747 		return;
   2748 
   2749 	log_debug("%s: %%%u needs to be resized", __func__, wp->id);
   2750 	TAILQ_FOREACH(r, &wp->resize_queue, entry) {
   2751 		log_debug("queued resize: %ux%u -> %ux%u", r->osx, r->osy,
   2752 		    r->sx, r->sy);
   2753 	}
   2754 
   2755 	/*
   2756 	 * There are three cases that matter:
   2757 	 *
   2758 	 * - Only one resize. It can just be applied.
   2759 	 *
   2760 	 * - Multiple resizes and the ending size is different from the
   2761 	 *   starting size. We can discard all resizes except the most recent.
   2762 	 *
   2763 	 * - Multiple resizes and the ending size is the same as the starting
   2764 	 *   size. We must resize at least twice to force the application to
   2765 	 *   redraw. So apply the first and leave the last on the queue for
   2766 	 *   next time.
   2767 	 */
   2768 	first = TAILQ_FIRST(&wp->resize_queue);
   2769 	last = TAILQ_LAST(&wp->resize_queue, window_pane_resizes);
   2770 	if (first == last) {
   2771 		/* Only one resize. */
   2772 		window_pane_send_resize(wp, first->sx, first->sy);
   2773 		TAILQ_REMOVE(&wp->resize_queue, first, entry);
   2774 		free(first);
   2775 	} else if (last->sx != first->osx || last->sy != first->osy) {
   2776 		/* Multiple resizes ending up with a different size. */
   2777 		window_pane_send_resize(wp, last->sx, last->sy);
   2778 		TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1) {
   2779 			TAILQ_REMOVE(&wp->resize_queue, r, entry);
   2780 			free(r);
   2781 		}
   2782 	} else {
   2783 		/*
   2784 		 * Multiple resizes ending up with the same size. There will
   2785 		 * not be more than one to the same size in succession so we
   2786 		 * can just use the last-but-one on the list and leave the last
   2787 		 * for later. We reduce the time until the next check to avoid
   2788 		 * a long delay between the resizes.
   2789 		 */
   2790 		r = TAILQ_PREV(last, window_pane_resizes, entry);
   2791 		window_pane_send_resize(wp, r->sx, r->sy);
   2792 		TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1) {
   2793 			if (r == last)
   2794 				break;
   2795 			TAILQ_REMOVE(&wp->resize_queue, r, entry);
   2796 			free(r);
   2797 		}
   2798 		tv.tv_usec = 10000;
   2799 	}
   2800 	evtimer_add(&wp->resize_timer, &tv);
   2801 }
   2802 
   2803 /* Check pane buffer size. */
   2804 static void
   2805 server_client_check_pane_buffer(struct window_pane *wp)
   2806 {
   2807 	struct evbuffer			*evb = wp->event->input;
   2808 	size_t				 minimum;
   2809 	struct client			*c;
   2810 	struct window_pane_offset	*wpo;
   2811 	int				 off = 1, flag;
   2812 	u_int				 attached_clients = 0;
   2813 	size_t				 new_size;
   2814 
   2815 	/*
   2816 	 * Work out the minimum used size. This is the most that can be removed
   2817 	 * from the buffer.
   2818 	 */
   2819 	minimum = wp->offset.used;
   2820 	if (wp->pipe_fd != -1 && wp->pipe_offset.used < minimum)
   2821 		minimum = wp->pipe_offset.used;
   2822 	TAILQ_FOREACH(c, &clients, entry) {
   2823 		if (c->session == NULL)
   2824 			continue;
   2825 		attached_clients++;
   2826 
   2827 		if (~c->flags & CLIENT_CONTROL) {
   2828 			off = 0;
   2829 			continue;
   2830 		}
   2831 		wpo = control_pane_offset(c, wp, &flag);
   2832 		if (wpo == NULL) {
   2833 			if (!flag)
   2834 				off = 0;
   2835 			continue;
   2836 		}
   2837 		if (!flag)
   2838 			off = 0;
   2839 
   2840 		window_pane_get_new_data(wp, wpo, &new_size);
   2841 		log_debug("%s: %s has %zu bytes used and %zu left for %%%u",
   2842 		    __func__, c->name, wpo->used - wp->base_offset, new_size,
   2843 		    wp->id);
   2844 		if (wpo->used < minimum)
   2845 			minimum = wpo->used;
   2846 	}
   2847 	if (attached_clients == 0)
   2848 		off = 0;
   2849 	minimum -= wp->base_offset;
   2850 	if (minimum == 0)
   2851 		goto out;
   2852 
   2853 	/* Drain the buffer. */
   2854 	log_debug("%s: %%%u has %zu minimum (of %zu) bytes used", __func__,
   2855 	    wp->id, minimum, EVBUFFER_LENGTH(evb));
   2856 	evbuffer_drain(evb, minimum);
   2857 
   2858 	/*
   2859 	 * Adjust the base offset. If it would roll over, all the offsets into
   2860 	 * the buffer need to be adjusted.
   2861 	 */
   2862 	if (wp->base_offset > SIZE_MAX - minimum) {
   2863 		log_debug("%s: %%%u base offset has wrapped", __func__, wp->id);
   2864 		wp->offset.used -= wp->base_offset;
   2865 		if (wp->pipe_fd != -1)
   2866 			wp->pipe_offset.used -= wp->base_offset;
   2867 		TAILQ_FOREACH(c, &clients, entry) {
   2868 			if (c->session == NULL || (~c->flags & CLIENT_CONTROL))
   2869 				continue;
   2870 			wpo = control_pane_offset(c, wp, &flag);
   2871 			if (wpo != NULL && !flag)
   2872 				wpo->used -= wp->base_offset;
   2873 		}
   2874 		wp->base_offset = minimum;
   2875 	} else
   2876 		wp->base_offset += minimum;
   2877 
   2878 out:
   2879 	/*
   2880 	 * If there is data remaining, and there are no clients able to consume
   2881 	 * it, do not read any more. This is true when there are attached
   2882 	 * clients, all of which are control clients which are not able to
   2883 	 * accept any more data.
   2884 	 */
   2885 	log_debug("%s: pane %%%u is %s", __func__, wp->id, off ? "off" : "on");
   2886 	if (off)
   2887 		bufferevent_disable(wp->event, EV_READ);
   2888 	else
   2889 		bufferevent_enable(wp->event, EV_READ);
   2890 }
   2891 
   2892 /*
   2893  * Update cursor position and mode settings. The scroll region and attributes
   2894  * are cleared when idle (waiting for an event) as this is the most likely time
   2895  * a user may interrupt tmux, for example with ~^Z in ssh(1). This is a
   2896  * compromise between excessive resets and likelihood of an interrupt.
   2897  *
   2898  * tty_region/tty_reset/tty_update_mode already take care of not resetting
   2899  * things that are already in their default state.
   2900  */
   2901 static void
   2902 server_client_reset_state(struct client *c)
   2903 {
   2904 	struct tty		*tty = &c->tty;
   2905 	struct window		*w = c->session->curw->window;
   2906 	struct window_pane	*wp = server_client_get_pane(c), *loop;
   2907 	struct screen		*s = NULL;
   2908 	struct options		*oo = c->session->options;
   2909 	int			 mode = 0, cursor, flags;
   2910 	u_int			 cx = 0, cy = 0, ox, oy, sx, sy, n;
   2911 
   2912 	if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
   2913 		return;
   2914 
   2915 	/* Disable the block flag. */
   2916 	flags = (tty->flags & TTY_BLOCK);
   2917 	tty->flags &= ~TTY_BLOCK;
   2918 
   2919 	/* Get mode from overlay if any, else from screen. */
   2920 	if (c->overlay_draw != NULL) {
   2921 		if (c->overlay_mode != NULL)
   2922 			s = c->overlay_mode(c, c->overlay_data, &cx, &cy);
   2923 	} else if (c->prompt_string == NULL)
   2924 		s = wp->screen;
   2925 	else
   2926 		s = c->status.active;
   2927 	if (s != NULL)
   2928 		mode = s->mode;
   2929 	if (log_get_level() != 0) {
   2930 		log_debug("%s: client %s mode %s", __func__, c->name,
   2931 		    screen_mode_to_string(mode));
   2932 	}
   2933 
   2934 	/* Reset region and margin. */
   2935 	tty_region_off(tty);
   2936 	tty_margin_off(tty);
   2937 
   2938 	/* Move cursor to pane cursor and offset. */
   2939 	if (c->prompt_string != NULL) {
   2940 		n = options_get_number(oo, "status-position");
   2941 		if (n == 0)
   2942 			cy = status_prompt_line_at(c);
   2943 		else {
   2944 			n = status_line_size(c) - status_prompt_line_at(c);
   2945 			if (n <= tty->sy)
   2946 				cy = tty->sy - n;
   2947 			else
   2948 				cy = tty->sy - 1;
   2949 		}
   2950 		cx = c->prompt_cursor;
   2951 	} else if (c->overlay_draw == NULL) {
   2952 		cursor = 0;
   2953 		tty_window_offset(tty, &ox, &oy, &sx, &sy);
   2954 		if (wp->xoff + s->cx >= ox && wp->xoff + s->cx <= ox + sx &&
   2955 		    wp->yoff + s->cy >= oy && wp->yoff + s->cy <= oy + sy) {
   2956 			cursor = 1;
   2957 
   2958 			cx = wp->xoff + s->cx - ox;
   2959 			cy = wp->yoff + s->cy - oy;
   2960 
   2961 			if (status_at_line(c) == 0)
   2962 				cy += status_line_size(c);
   2963 		}
   2964 		if (!cursor)
   2965 			mode &= ~MODE_CURSOR;
   2966 	}
   2967 	log_debug("%s: cursor to %u,%u", __func__, cx, cy);
   2968 	tty_cursor(tty, cx, cy);
   2969 
   2970 	/*
   2971 	 * Set mouse mode if requested. To support dragging, always use button
   2972 	 * mode.
   2973 	 */
   2974 	if (options_get_number(oo, "mouse")) {
   2975 		if (c->overlay_draw == NULL) {
   2976 			mode &= ~ALL_MOUSE_MODES;
   2977 			TAILQ_FOREACH(loop, &w->panes, entry) {
   2978 				if (loop->screen->mode & MODE_MOUSE_ALL)
   2979 					mode |= MODE_MOUSE_ALL;
   2980 			}
   2981 		}
   2982 		if (~mode & MODE_MOUSE_ALL)
   2983 			mode |= MODE_MOUSE_BUTTON;
   2984 	}
   2985 
   2986 	/* Clear bracketed paste mode if at the prompt. */
   2987 	if (c->overlay_draw == NULL && c->prompt_string != NULL)
   2988 		mode &= ~MODE_BRACKETPASTE;
   2989 
   2990 	/* Set the terminal mode and reset attributes. */
   2991 	tty_update_mode(tty, mode, s);
   2992 	tty_reset(tty);
   2993 
   2994 	/* All writing must be done, send a sync end (if it was started). */
   2995 	tty_sync_end(tty);
   2996 	tty->flags |= flags;
   2997 }
   2998 
   2999 /* Repeat time callback. */
   3000 static void
   3001 server_client_repeat_timer(__unused int fd, __unused short events, void *data)
   3002 {
   3003 	struct client	*c = data;
   3004 
   3005 	if (c->flags & CLIENT_REPEAT) {
   3006 		server_client_set_key_table(c, NULL);
   3007 		c->flags &= ~CLIENT_REPEAT;
   3008 		server_status_client(c);
   3009 	}
   3010 }
   3011 
   3012 /* Double-click callback. */
   3013 static void
   3014 server_client_click_timer(__unused int fd, __unused short events, void *data)
   3015 {
   3016 	struct client		*c = data;
   3017 	struct key_event	*event;
   3018 
   3019 	log_debug("click timer expired");
   3020 
   3021 	if (c->flags & CLIENT_TRIPLECLICK) {
   3022 		/*
   3023 		 * Waiting for a third click that hasn't happened, so this must
   3024 		 * have been a double click.
   3025 		 */
   3026 		event = xcalloc(1, sizeof *event);
   3027 		event->key = KEYC_DOUBLECLICK;
   3028 		memcpy(&event->m, &c->click_event, sizeof event->m);
   3029 		if (!server_client_handle_key(c, event)) {
   3030 			free(event->buf);
   3031 			free(event);
   3032 		}
   3033 	}
   3034 	c->flags &= ~(CLIENT_DOUBLECLICK|CLIENT_TRIPLECLICK);
   3035 }
   3036 
   3037 /* Check if client should be exited. */
   3038 static void
   3039 server_client_check_exit(struct client *c)
   3040 {
   3041 	struct client_file	*cf;
   3042 	const char		*name = c->exit_session;
   3043 	char			*data;
   3044 	size_t			 size, msize;
   3045 
   3046 	if (c->flags & (CLIENT_DEAD|CLIENT_EXITED))
   3047 		return;
   3048 	if (~c->flags & CLIENT_EXIT)
   3049 		return;
   3050 
   3051 	if (c->flags & CLIENT_CONTROL) {
   3052 		control_discard(c);
   3053 		if (!control_all_done(c))
   3054 			return;
   3055 	}
   3056 	RB_FOREACH(cf, client_files, &c->files) {
   3057 		if (EVBUFFER_LENGTH(cf->buffer) != 0)
   3058 			return;
   3059 	}
   3060 	c->flags |= CLIENT_EXITED;
   3061 
   3062 	switch (c->exit_type) {
   3063 	case CLIENT_EXIT_RETURN:
   3064 		if (c->exit_message != NULL)
   3065 			msize = strlen(c->exit_message) + 1;
   3066 		else
   3067 			msize = 0;
   3068 		size = (sizeof c->retval) + msize;
   3069 		data = xmalloc(size);
   3070 		memcpy(data, &c->retval, sizeof c->retval);
   3071 		if (c->exit_message != NULL)
   3072 			memcpy(data + sizeof c->retval, c->exit_message, msize);
   3073 		proc_send(c->peer, MSG_EXIT, -1, data, size);
   3074 		free(data);
   3075 		break;
   3076 	case CLIENT_EXIT_SHUTDOWN:
   3077 		proc_send(c->peer, MSG_SHUTDOWN, -1, NULL, 0);
   3078 		break;
   3079 	case CLIENT_EXIT_DETACH:
   3080 		proc_send(c->peer, c->exit_msgtype, -1, name, strlen(name) + 1);
   3081 		break;
   3082 	}
   3083 	free(c->exit_session);
   3084 	free(c->exit_message);
   3085 }
   3086 
   3087 /* Redraw timer callback. */
   3088 static void
   3089 server_client_redraw_timer(__unused int fd, __unused short events,
   3090     __unused void *data)
   3091 {
   3092 	log_debug("redraw timer fired");
   3093 }
   3094 
   3095 /*
   3096  * Check if modes need to be updated. Only modes in the current window are
   3097  * updated and it is done when the status line is redrawn.
   3098  */
   3099 static void
   3100 server_client_check_modes(struct client *c)
   3101 {
   3102 	struct window			*w = c->session->curw->window;
   3103 	struct window_pane		*wp;
   3104 	struct window_mode_entry	*wme;
   3105 
   3106 	if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
   3107 		return;
   3108 	if (~c->flags & CLIENT_REDRAWSTATUS)
   3109 		return;
   3110 	TAILQ_FOREACH(wp, &w->panes, entry) {
   3111 		wme = TAILQ_FIRST(&wp->modes);
   3112 		if (wme != NULL && wme->mode->update != NULL)
   3113 			wme->mode->update(wme);
   3114 	}
   3115 }
   3116 
   3117 /* Check for client redraws. */
   3118 static void
   3119 server_client_check_redraw(struct client *c)
   3120 {
   3121 	struct session		*s = c->session;
   3122 	struct tty		*tty = &c->tty;
   3123 	struct window		*w = c->session->curw->window;
   3124 	struct window_pane	*wp;
   3125 	int			 needed, tty_flags, mode = tty->mode;
   3126 	uint64_t		 client_flags = 0;
   3127 	int			 redraw_pane, redraw_scrollbar_only;
   3128 	u_int			 bit = 0;
   3129 	struct timeval		 tv = { .tv_usec = 1000 };
   3130 	static struct event	 ev;
   3131 	size_t			 left;
   3132 
   3133 	if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
   3134 		return;
   3135 	if (c->flags & CLIENT_ALLREDRAWFLAGS) {
   3136 		log_debug("%s: redraw%s%s%s%s%s%s", c->name,
   3137 		    (c->flags & CLIENT_REDRAWWINDOW) ? " window" : "",
   3138 		    (c->flags & CLIENT_REDRAWSTATUS) ? " status" : "",
   3139 		    (c->flags & CLIENT_REDRAWBORDERS) ? " borders" : "",
   3140 		    (c->flags & CLIENT_REDRAWOVERLAY) ? " overlay" : "",
   3141 		    (c->flags & CLIENT_REDRAWPANES) ? " panes" : "",
   3142 		    (c->flags & CLIENT_REDRAWSCROLLBARS) ? " scrollbars" : "");
   3143 	}
   3144 
   3145 	/*
   3146 	 * If there is outstanding data, defer the redraw until it has been
   3147 	 * consumed. We can just add a timer to get out of the event loop and
   3148 	 * end up back here.
   3149 	 */
   3150 	needed = 0;
   3151 	if (c->flags & CLIENT_ALLREDRAWFLAGS)
   3152 		needed = 1;
   3153 	else {
   3154 		TAILQ_FOREACH(wp, &w->panes, entry) {
   3155 			if (wp->flags & PANE_REDRAW) {
   3156 				needed = 1;
   3157 				client_flags |= CLIENT_REDRAWPANES;
   3158 				break;
   3159 			}
   3160 			if (wp->flags & PANE_REDRAWSCROLLBAR) {
   3161 				needed = 1;
   3162 				client_flags |= CLIENT_REDRAWSCROLLBARS;
   3163 				/* no break - later panes may need redraw */
   3164 			}
   3165 		}
   3166 	}
   3167 	if (needed && (left = EVBUFFER_LENGTH(tty->out)) != 0) {
   3168 		log_debug("%s: redraw deferred (%zu left)", c->name, left);
   3169 		if (!evtimer_initialized(&ev))
   3170 			evtimer_set(&ev, server_client_redraw_timer, NULL);
   3171 		if (!evtimer_pending(&ev, NULL)) {
   3172 			log_debug("redraw timer started");
   3173 			evtimer_add(&ev, &tv);
   3174 		}
   3175 
   3176 		if (~c->flags & CLIENT_REDRAWWINDOW) {
   3177 			TAILQ_FOREACH(wp, &w->panes, entry) {
   3178 				if (wp->flags & (PANE_REDRAW)) {
   3179 					log_debug("%s: pane %%%u needs redraw",
   3180 					    c->name, wp->id);
   3181 					c->redraw_panes |= (1 << bit);
   3182 				} else if (wp->flags & PANE_REDRAWSCROLLBAR) {
   3183 					log_debug("%s: pane %%%u scrollbar "
   3184 					    "needs redraw", c->name, wp->id);
   3185 					c->redraw_scrollbars |= (1 << bit);
   3186 				}
   3187 				if (++bit == 64) {
   3188 					/*
   3189 					 * If more that 64 panes, give up and
   3190 					 * just redraw the window.
   3191 					 */
   3192 					client_flags &= ~(CLIENT_REDRAWPANES|
   3193 					    CLIENT_REDRAWSCROLLBARS);
   3194 					client_flags |= CLIENT_REDRAWWINDOW;
   3195 					break;
   3196 				}
   3197 			}
   3198 			if (c->redraw_panes != 0)
   3199 				c->flags |= CLIENT_REDRAWPANES;
   3200 			if (c->redraw_scrollbars != 0)
   3201 				c->flags |= CLIENT_REDRAWSCROLLBARS;
   3202 		}
   3203 		c->flags |= client_flags;
   3204 		return;
   3205 	} else if (needed)
   3206 		log_debug("%s: redraw needed", c->name);
   3207 
   3208 	tty_flags = tty->flags & (TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR);
   3209 	tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE))|TTY_NOCURSOR;
   3210 
   3211 	if (~c->flags & CLIENT_REDRAWWINDOW) {
   3212 		/*
   3213 		 * If not redrawing the entire window, check whether each pane
   3214 		 * needs to be redrawn.
   3215 		 */
   3216 		TAILQ_FOREACH(wp, &w->panes, entry) {
   3217 			redraw_pane = 0;
   3218 			redraw_scrollbar_only = 0;
   3219 			if (wp->flags & PANE_REDRAW)
   3220 				redraw_pane = 1;
   3221 			else if (c->flags & CLIENT_REDRAWPANES) {
   3222 				if (c->redraw_panes & (1 << bit))
   3223 					redraw_pane = 1;
   3224 			} else if (c->flags & CLIENT_REDRAWSCROLLBARS) {
   3225 				if (c->redraw_scrollbars & (1 << bit))
   3226 					redraw_scrollbar_only = 1;
   3227 			}
   3228 			bit++;
   3229 			if (!redraw_pane && !redraw_scrollbar_only)
   3230 				continue;
   3231 			if (redraw_scrollbar_only) {
   3232 				log_debug("%s: redrawing (scrollbar only) pane "
   3233 				    "%%%u", __func__, wp->id);
   3234 			} else {
   3235 				log_debug("%s: redrawing pane %%%u", __func__,
   3236 				    wp->id);
   3237 			}
   3238 			screen_redraw_pane(c, wp, redraw_scrollbar_only);
   3239 		}
   3240 		c->redraw_panes = 0;
   3241 		c->redraw_scrollbars = 0;
   3242 		c->flags &= ~(CLIENT_REDRAWPANES|CLIENT_REDRAWSCROLLBARS);
   3243 	}
   3244 
   3245 	if (c->flags & CLIENT_ALLREDRAWFLAGS) {
   3246 		if (options_get_number(s->options, "set-titles")) {
   3247 			server_client_set_title(c);
   3248 			server_client_set_path(c);
   3249 		}
   3250 		screen_redraw_screen(c);
   3251 	}
   3252 
   3253 	tty->flags = (tty->flags & ~TTY_NOCURSOR)|(tty_flags & TTY_NOCURSOR);
   3254 	tty_update_mode(tty, mode, NULL);
   3255 	tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR))|
   3256 	    tty_flags;
   3257 
   3258 	c->flags &= ~(CLIENT_ALLREDRAWFLAGS|CLIENT_STATUSFORCE);
   3259 
   3260 	if (needed) {
   3261 		/*
   3262 		 * We would have deferred the redraw unless the output buffer
   3263 		 * was empty, so we can record how many bytes the redraw
   3264 		 * generated.
   3265 		 */
   3266 		c->redraw = EVBUFFER_LENGTH(tty->out);
   3267 		log_debug("%s: redraw added %zu bytes", c->name, c->redraw);
   3268 	}
   3269 }
   3270 
   3271 /* Set client title. */
   3272 static void
   3273 server_client_set_title(struct client *c)
   3274 {
   3275 	struct session		*s = c->session;
   3276 	const char		*template;
   3277 	char			*title;
   3278 	struct format_tree	*ft;
   3279 
   3280 	template = options_get_string(s->options, "set-titles-string");
   3281 
   3282 	ft = format_create(c, NULL, FORMAT_NONE, 0);
   3283 	format_defaults(ft, c, NULL, NULL, NULL);
   3284 
   3285 	title = format_expand_time(ft, template);
   3286 	if (c->title == NULL || strcmp(title, c->title) != 0) {
   3287 		free(c->title);
   3288 		c->title = xstrdup(title);
   3289 		tty_set_title(&c->tty, c->title);
   3290 	}
   3291 	free(title);
   3292 
   3293 	format_free(ft);
   3294 }
   3295 
   3296 /* Set client path. */
   3297 static void
   3298 server_client_set_path(struct client *c)
   3299 {
   3300 	struct session	*s = c->session;
   3301 	const char	*path;
   3302 
   3303 	if (s->curw == NULL)
   3304 		return;
   3305 	if (s->curw->window->active->base.path == NULL)
   3306 		path = "";
   3307 	else
   3308 		path = s->curw->window->active->base.path;
   3309 	if (c->path == NULL || strcmp(path, c->path) != 0) {
   3310 		free(c->path);
   3311 		c->path = xstrdup(path);
   3312 		tty_set_path(&c->tty, c->path);
   3313 	}
   3314 }
   3315 
   3316 /* Dispatch message from client. */
   3317 static void
   3318 server_client_dispatch(struct imsg *imsg, void *arg)
   3319 {
   3320 	struct client	*c = arg;
   3321 	ssize_t		 datalen;
   3322 	struct session	*s;
   3323 
   3324 	if (c->flags & CLIENT_DEAD)
   3325 		return;
   3326 
   3327 	if (imsg == NULL) {
   3328 		server_client_lost(c);
   3329 		return;
   3330 	}
   3331 
   3332 	datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
   3333 
   3334 	switch (imsg->hdr.type) {
   3335 	case MSG_IDENTIFY_CLIENTPID:
   3336 	case MSG_IDENTIFY_CWD:
   3337 	case MSG_IDENTIFY_ENVIRON:
   3338 	case MSG_IDENTIFY_FEATURES:
   3339 	case MSG_IDENTIFY_FLAGS:
   3340 	case MSG_IDENTIFY_LONGFLAGS:
   3341 	case MSG_IDENTIFY_STDIN:
   3342 	case MSG_IDENTIFY_STDOUT:
   3343 	case MSG_IDENTIFY_TERM:
   3344 	case MSG_IDENTIFY_TERMINFO:
   3345 	case MSG_IDENTIFY_TTYNAME:
   3346 	case MSG_IDENTIFY_DONE:
   3347 		if (server_client_dispatch_identify(c, imsg) != 0)
   3348 			goto bad;
   3349 		break;
   3350 	case MSG_COMMAND:
   3351 		if (server_client_dispatch_command(c, imsg) != 0)
   3352 			goto bad;
   3353 		break;
   3354 	case MSG_RESIZE:
   3355 		if (datalen != 0)
   3356 			goto bad;
   3357 
   3358 		if (c->flags & CLIENT_CONTROL)
   3359 			break;
   3360 		server_client_update_latest(c);
   3361 		tty_resize(&c->tty);
   3362 		tty_repeat_requests(&c->tty, 0);
   3363 		recalculate_sizes();
   3364 		if (c->overlay_resize == NULL)
   3365 			server_client_clear_overlay(c);
   3366 		else
   3367 			c->overlay_resize(c, c->overlay_data);
   3368 		server_redraw_client(c);
   3369 		if (c->session != NULL)
   3370 			notify_client("client-resized", c);
   3371 		break;
   3372 	case MSG_EXITING:
   3373 		if (datalen != 0)
   3374 			goto bad;
   3375 		server_client_set_session(c, NULL);
   3376 		recalculate_sizes();
   3377 		tty_close(&c->tty);
   3378 		proc_send(c->peer, MSG_EXITED, -1, NULL, 0);
   3379 		break;
   3380 	case MSG_WAKEUP:
   3381 	case MSG_UNLOCK:
   3382 		if (datalen != 0)
   3383 			goto bad;
   3384 
   3385 		if (!(c->flags & CLIENT_SUSPENDED))
   3386 			break;
   3387 		c->flags &= ~CLIENT_SUSPENDED;
   3388 
   3389 		if (c->fd == -1 || c->session == NULL) /* exited already */
   3390 			break;
   3391 		s = c->session;
   3392 
   3393 		if (gettimeofday(&c->activity_time, NULL) != 0)
   3394 			fatal("gettimeofday failed");
   3395 
   3396 		tty_start_tty(&c->tty);
   3397 		server_redraw_client(c);
   3398 		recalculate_sizes();
   3399 
   3400 		if (s != NULL)
   3401 			session_update_activity(s, &c->activity_time);
   3402 		break;
   3403 	case MSG_SHELL:
   3404 		if (datalen != 0)
   3405 			goto bad;
   3406 		if (server_client_dispatch_shell(c) != 0)
   3407 			goto bad;
   3408 		break;
   3409 	case MSG_WRITE_READY:
   3410 		file_write_ready(&c->files, imsg);
   3411 		break;
   3412 	case MSG_READ:
   3413 		file_read_data(&c->files, imsg);
   3414 		break;
   3415 	case MSG_READ_DONE:
   3416 		file_read_done(&c->files, imsg);
   3417 		break;
   3418 	}
   3419 
   3420 	return;
   3421 
   3422 bad:
   3423 	log_debug("client %p invalid message type %d", c, imsg->hdr.type);
   3424 	proc_kill_peer(c->peer);
   3425 }
   3426 
   3427 /* Callback when command is not allowed. */
   3428 static enum cmd_retval
   3429 server_client_read_only(struct cmdq_item *item, __unused void *data)
   3430 {
   3431 	cmdq_error(item, "client is read-only");
   3432 	return (CMD_RETURN_ERROR);
   3433 }
   3434 
   3435 /* Callback when command is done. */
   3436 static enum cmd_retval
   3437 server_client_command_done(struct cmdq_item *item, __unused void *data)
   3438 {
   3439 	struct client	*c = cmdq_get_client(item);
   3440 
   3441 	if (~c->flags & CLIENT_ATTACHED)
   3442 		c->flags |= CLIENT_EXIT;
   3443 	else if (~c->flags & CLIENT_EXIT) {
   3444 		if (c->flags & CLIENT_CONTROL)
   3445 			control_ready(c);
   3446 		tty_send_requests(&c->tty);
   3447 	}
   3448 	return (CMD_RETURN_NORMAL);
   3449 }
   3450 
   3451 /* Handle command message. */
   3452 static int
   3453 server_client_dispatch_command(struct client *c, struct imsg *imsg)
   3454 {
   3455 	struct msg_command	  data;
   3456 	char			 *buf;
   3457 	size_t			  len;
   3458 	int			  argc = 0;
   3459 	char			**argv, *cause;
   3460 	struct cmd_parse_result	 *pr;
   3461 	struct args_value	 *values;
   3462 	struct cmdq_item	 *new_item;
   3463 	struct cmd_list		 *cmdlist;
   3464 
   3465 	if (c->flags & CLIENT_EXIT)
   3466 		return (0);
   3467 
   3468 	if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data)
   3469 		return (-1);
   3470 	memcpy(&data, imsg->data, sizeof data);
   3471 
   3472 	buf = (char *)imsg->data + sizeof data;
   3473 	len = imsg->hdr.len - IMSG_HEADER_SIZE - sizeof data;
   3474 	if (len > 0 && buf[len - 1] != '\0')
   3475 		return (-1);
   3476 
   3477 	if (cmd_unpack_argv(buf, len, data.argc, &argv) != 0) {
   3478 		cause = xstrdup("command too long");
   3479 		goto error;
   3480 	}
   3481 
   3482 	argc = data.argc;
   3483 	if (argc == 0) {
   3484 		cmdlist = cmd_list_copy(options_get_command(global_options,
   3485 		    "default-client-command"), 0, NULL);
   3486 	} else {
   3487 		values = args_from_vector(argc, argv);
   3488 		pr = cmd_parse_from_arguments(values, argc, NULL);
   3489 		switch (pr->status) {
   3490 		case CMD_PARSE_ERROR:
   3491 			cause = pr->error;
   3492 			goto error;
   3493 		case CMD_PARSE_SUCCESS:
   3494 			break;
   3495 		}
   3496 		args_free_values(values, argc);
   3497 		free(values);
   3498 		cmd_free_argv(argc, argv);
   3499 		cmdlist = pr->cmdlist;
   3500 	}
   3501 
   3502 	if ((c->flags & CLIENT_READONLY) &&
   3503 	    !cmd_list_all_have(cmdlist, CMD_READONLY))
   3504 		new_item = cmdq_get_callback(server_client_read_only, NULL);
   3505 	else
   3506 		new_item = cmdq_get_command(cmdlist, NULL);
   3507 	cmdq_append(c, new_item);
   3508 	cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL));
   3509 
   3510 	cmd_list_free(cmdlist);
   3511 	return (0);
   3512 
   3513 error:
   3514 	cmd_free_argv(argc, argv);
   3515 
   3516 	cmdq_append(c, cmdq_get_error(cause));
   3517 	free(cause);
   3518 
   3519 	c->flags |= CLIENT_EXIT;
   3520 	return (0);
   3521 }
   3522 
   3523 /* Handle identify message. */
   3524 static int
   3525 server_client_dispatch_identify(struct client *c, struct imsg *imsg)
   3526 {
   3527 	const char	*data, *home;
   3528 	size_t		 datalen;
   3529 	int		 flags, feat;
   3530 	uint64_t	 longflags;
   3531 	char		*name;
   3532 
   3533 	if (c->flags & CLIENT_IDENTIFIED)
   3534 		return (-1);
   3535 
   3536 	data = imsg->data;
   3537 	datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
   3538 
   3539 	switch (imsg->hdr.type)	{
   3540 	case MSG_IDENTIFY_FEATURES:
   3541 		if (datalen != sizeof feat)
   3542 			return (-1);
   3543 		memcpy(&feat, data, sizeof feat);
   3544 		c->term_features |= feat;
   3545 		log_debug("client %p IDENTIFY_FEATURES %s", c,
   3546 		    tty_get_features(feat));
   3547 		break;
   3548 	case MSG_IDENTIFY_FLAGS:
   3549 		if (datalen != sizeof flags)
   3550 			return (-1);
   3551 		memcpy(&flags, data, sizeof flags);
   3552 		c->flags |= flags;
   3553 		log_debug("client %p IDENTIFY_FLAGS %#x", c, flags);
   3554 		break;
   3555 	case MSG_IDENTIFY_LONGFLAGS:
   3556 		if (datalen != sizeof longflags)
   3557 			return (-1);
   3558 		memcpy(&longflags, data, sizeof longflags);
   3559 		c->flags |= longflags;
   3560 		log_debug("client %p IDENTIFY_LONGFLAGS %#llx", c,
   3561 		    (unsigned long long)longflags);
   3562 		break;
   3563 	case MSG_IDENTIFY_TERM:
   3564 		if (datalen == 0 || data[datalen - 1] != '\0')
   3565 			return (-1);
   3566 		c->term_name = xstrdup(data);
   3567 		log_debug("client %p IDENTIFY_TERM %s", c, data);
   3568 		break;
   3569 	case MSG_IDENTIFY_TERMINFO:
   3570 		if (datalen == 0 || data[datalen - 1] != '\0')
   3571 			return (-1);
   3572 		c->term_caps = xreallocarray(c->term_caps, c->term_ncaps + 1,
   3573 		    sizeof *c->term_caps);
   3574 		c->term_caps[c->term_ncaps++] = xstrdup(data);
   3575 		log_debug("client %p IDENTIFY_TERMINFO %s", c, data);
   3576 		break;
   3577 	case MSG_IDENTIFY_TTYNAME:
   3578 		if (datalen == 0 || data[datalen - 1] != '\0')
   3579 			return (-1);
   3580 		c->ttyname = xstrdup(data);
   3581 		log_debug("client %p IDENTIFY_TTYNAME %s", c, data);
   3582 		break;
   3583 	case MSG_IDENTIFY_CWD:
   3584 		if (datalen == 0 || data[datalen - 1] != '\0')
   3585 			return (-1);
   3586 		if (access(data, X_OK) == 0)
   3587 			c->cwd = xstrdup(data);
   3588 		else if ((home = find_home()) != NULL)
   3589 			c->cwd = xstrdup(home);
   3590 		else
   3591 			c->cwd = xstrdup("/");
   3592 		log_debug("client %p IDENTIFY_CWD %s", c, data);
   3593 		break;
   3594 	case MSG_IDENTIFY_STDIN:
   3595 		if (datalen != 0)
   3596 			return (-1);
   3597 		c->fd = imsg_get_fd(imsg);
   3598 		log_debug("client %p IDENTIFY_STDIN %d", c, c->fd);
   3599 		break;
   3600 	case MSG_IDENTIFY_STDOUT:
   3601 		if (datalen != 0)
   3602 			return (-1);
   3603 		c->out_fd = imsg_get_fd(imsg);
   3604 		log_debug("client %p IDENTIFY_STDOUT %d", c, c->out_fd);
   3605 		break;
   3606 	case MSG_IDENTIFY_ENVIRON:
   3607 		if (datalen == 0 || data[datalen - 1] != '\0')
   3608 			return (-1);
   3609 		if (strchr(data, '=') != NULL)
   3610 			environ_put(c->environ, data, 0);
   3611 		log_debug("client %p IDENTIFY_ENVIRON %s", c, data);
   3612 		break;
   3613 	case MSG_IDENTIFY_CLIENTPID:
   3614 		if (datalen != sizeof c->pid)
   3615 			return (-1);
   3616 		memcpy(&c->pid, data, sizeof c->pid);
   3617 		log_debug("client %p IDENTIFY_CLIENTPID %ld", c, (long)c->pid);
   3618 		break;
   3619 	default:
   3620 		break;
   3621 	}
   3622 
   3623 	if (imsg->hdr.type != MSG_IDENTIFY_DONE)
   3624 		return (0);
   3625 	c->flags |= CLIENT_IDENTIFIED;
   3626 
   3627 	if (c->term_name == NULL || *c->term_name == '\0') {
   3628 		free(c->term_name);
   3629 		c->term_name = xstrdup("unknown");
   3630 	}
   3631 
   3632 	if (c->ttyname == NULL || *c->ttyname != '\0')
   3633 		name = xstrdup(c->ttyname);
   3634 	else
   3635 		xasprintf(&name, "client-%ld", (long)c->pid);
   3636 	c->name = name;
   3637 	log_debug("client %p name is %s", c, c->name);
   3638 
   3639 #ifdef __CYGWIN__
   3640 	c->fd = open(c->ttyname, O_RDWR|O_NOCTTY);
   3641 	c->out_fd = dup(c->fd);
   3642 #endif
   3643 
   3644 	if (c->flags & CLIENT_CONTROL)
   3645 		control_start(c);
   3646 	else if (c->fd != -1) {
   3647 		if (tty_init(&c->tty, c) != 0) {
   3648 			close(c->fd);
   3649 			c->fd = -1;
   3650 		} else {
   3651 			tty_resize(&c->tty);
   3652 			c->flags |= CLIENT_TERMINAL;
   3653 		}
   3654 		if (c->out_fd != -1)
   3655 			close(c->out_fd);
   3656 		c->out_fd = -1;
   3657 	}
   3658 
   3659 	/*
   3660 	 * If this is the first client, load configuration files. Any later
   3661 	 * clients are allowed to continue with their command even if the
   3662 	 * config has not been loaded - they might have been run from inside it
   3663 	 */
   3664 	if ((~c->flags & CLIENT_EXIT) &&
   3665 	     !cfg_finished &&
   3666 	     c == TAILQ_FIRST(&clients))
   3667 		start_cfg();
   3668 
   3669 	return (0);
   3670 }
   3671 
   3672 /* Handle shell message. */
   3673 static int
   3674 server_client_dispatch_shell(struct client *c)
   3675 {
   3676 	const char	*shell;
   3677 
   3678 	shell = options_get_string(global_s_options, "default-shell");
   3679 	if (!checkshell(shell))
   3680 		shell = _PATH_BSHELL;
   3681 	proc_send(c->peer, MSG_SHELL, -1, shell, strlen(shell) + 1);
   3682 
   3683 	proc_kill_peer(c->peer);
   3684 	return (0);
   3685 }
   3686 
   3687 /* Get client working directory. */
   3688 const char *
   3689 server_client_get_cwd(struct client *c, struct session *s)
   3690 {
   3691 	const char	*home;
   3692 
   3693 	if (!cfg_finished && cfg_client != NULL)
   3694 		return (cfg_client->cwd);
   3695 	if (c != NULL && c->session == NULL && c->cwd != NULL)
   3696 		return (c->cwd);
   3697 	if (s != NULL && s->cwd != NULL)
   3698 		return (s->cwd);
   3699 	if (c != NULL && (s = c->session) != NULL && s->cwd != NULL)
   3700 		return (s->cwd);
   3701 	if ((home = find_home()) != NULL)
   3702 		return (home);
   3703 	return ("/");
   3704 }
   3705 
   3706 /* Get control client flags. */
   3707 static uint64_t
   3708 server_client_control_flags(struct client *c, const char *next)
   3709 {
   3710 	if (strcmp(next, "pause-after") == 0) {
   3711 		c->pause_age = 0;
   3712 		return (CLIENT_CONTROL_PAUSEAFTER);
   3713 	}
   3714 	if (sscanf(next, "pause-after=%u", &c->pause_age) == 1) {
   3715 		c->pause_age *= 1000;
   3716 		return (CLIENT_CONTROL_PAUSEAFTER);
   3717 	}
   3718 	if (strcmp(next, "no-output") == 0)
   3719 		return (CLIENT_CONTROL_NOOUTPUT);
   3720 	if (strcmp(next, "wait-exit") == 0)
   3721 		return (CLIENT_CONTROL_WAITEXIT);
   3722 	return (0);
   3723 }
   3724 
   3725 /* Set client flags. */
   3726 void
   3727 server_client_set_flags(struct client *c, const char *flags)
   3728 {
   3729 	char	*s, *copy, *next;
   3730 	uint64_t flag;
   3731 	int	 not;
   3732 
   3733 	s = copy = xstrdup(flags);
   3734 	while ((next = strsep(&s, ",")) != NULL) {
   3735 		not = (*next == '!');
   3736 		if (not)
   3737 			next++;
   3738 
   3739 		if (c->flags & CLIENT_CONTROL)
   3740 			flag = server_client_control_flags(c, next);
   3741 		else
   3742 			flag = 0;
   3743 		if (strcmp(next, "read-only") == 0)
   3744 			flag = CLIENT_READONLY;
   3745 		else if (strcmp(next, "ignore-size") == 0)
   3746 			flag = CLIENT_IGNORESIZE;
   3747 		else if (strcmp(next, "active-pane") == 0)
   3748 			flag = CLIENT_ACTIVEPANE;
   3749 		else if (strcmp(next, "no-detach-on-destroy") == 0)
   3750 			flag = CLIENT_NO_DETACH_ON_DESTROY;
   3751 		if (flag == 0)
   3752 			continue;
   3753 
   3754 		log_debug("client %s set flag %s", c->name, next);
   3755 		if (not) {
   3756 			if (c->flags & CLIENT_READONLY)
   3757 				flag &= ~CLIENT_READONLY;
   3758 			c->flags &= ~flag;
   3759 		} else
   3760 			c->flags |= flag;
   3761 		if (flag == CLIENT_CONTROL_NOOUTPUT)
   3762 			control_reset_offsets(c);
   3763 	}
   3764 	free(copy);
   3765 	proc_send(c->peer, MSG_FLAGS, -1, &c->flags, sizeof c->flags);
   3766 }
   3767 
   3768 /* Get client flags. This is only flags useful to show to users. */
   3769 const char *
   3770 server_client_get_flags(struct client *c)
   3771 {
   3772 	static char	s[256];
   3773 	char		tmp[32];
   3774 
   3775 	*s = '\0';
   3776 	if (c->flags & CLIENT_ATTACHED)
   3777 		strlcat(s, "attached,", sizeof s);
   3778 	if (c->flags & CLIENT_FOCUSED)
   3779 		strlcat(s, "focused,", sizeof s);
   3780 	if (c->flags & CLIENT_CONTROL)
   3781 		strlcat(s, "control-mode,", sizeof s);
   3782 	if (c->flags & CLIENT_IGNORESIZE)
   3783 		strlcat(s, "ignore-size,", sizeof s);
   3784 	if (c->flags & CLIENT_NO_DETACH_ON_DESTROY)
   3785 		strlcat(s, "no-detach-on-destroy,", sizeof s);
   3786 	if (c->flags & CLIENT_CONTROL_NOOUTPUT)
   3787 		strlcat(s, "no-output,", sizeof s);
   3788 	if (c->flags & CLIENT_CONTROL_WAITEXIT)
   3789 		strlcat(s, "wait-exit,", sizeof s);
   3790 	if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
   3791 		xsnprintf(tmp, sizeof tmp, "pause-after=%u,",
   3792 		    c->pause_age / 1000);
   3793 		strlcat(s, tmp, sizeof s);
   3794 	}
   3795 	if (c->flags & CLIENT_READONLY)
   3796 		strlcat(s, "read-only,", sizeof s);
   3797 	if (c->flags & CLIENT_ACTIVEPANE)
   3798 		strlcat(s, "active-pane,", sizeof s);
   3799 	if (c->flags & CLIENT_SUSPENDED)
   3800 		strlcat(s, "suspended,", sizeof s);
   3801 	if (c->flags & CLIENT_UTF8)
   3802 		strlcat(s, "UTF-8,", sizeof s);
   3803 	if (*s != '\0')
   3804 		s[strlen(s) - 1] = '\0';
   3805 	return (s);
   3806 }
   3807 
   3808 /* Get client window. */
   3809 struct client_window *
   3810 server_client_get_client_window(struct client *c, u_int id)
   3811 {
   3812 	struct client_window	cw = { .window = id };
   3813 
   3814 	return (RB_FIND(client_windows, &c->windows, &cw));
   3815 }
   3816 
   3817 /* Add client window. */
   3818 struct client_window *
   3819 server_client_add_client_window(struct client *c, u_int id)
   3820 {
   3821 	struct client_window	*cw;
   3822 
   3823 	cw = server_client_get_client_window(c, id);
   3824 	if (cw == NULL) {
   3825 		cw = xcalloc(1, sizeof *cw);
   3826 		cw->window = id;
   3827 		RB_INSERT(client_windows, &c->windows, cw);
   3828 	}
   3829 	return (cw);
   3830 }
   3831 
   3832 /* Get client active pane. */
   3833 struct window_pane *
   3834 server_client_get_pane(struct client *c)
   3835 {
   3836 	struct session		*s = c->session;
   3837 	struct client_window	*cw;
   3838 
   3839 	if (s == NULL)
   3840 		return (NULL);
   3841 
   3842 	if (~c->flags & CLIENT_ACTIVEPANE)
   3843 		return (s->curw->window->active);
   3844 	cw = server_client_get_client_window(c, s->curw->window->id);
   3845 	if (cw == NULL)
   3846 		return (s->curw->window->active);
   3847 	return (cw->pane);
   3848 }
   3849 
   3850 /* Set client active pane. */
   3851 void
   3852 server_client_set_pane(struct client *c, struct window_pane *wp)
   3853 {
   3854 	struct session		*s = c->session;
   3855 	struct client_window	*cw;
   3856 
   3857 	if (s == NULL)
   3858 		return;
   3859 
   3860 	cw = server_client_add_client_window(c, s->curw->window->id);
   3861 	cw->pane = wp;
   3862 	log_debug("%s pane now %%%u", c->name, wp->id);
   3863 }
   3864 
   3865 /* Remove pane from client lists. */
   3866 void
   3867 server_client_remove_pane(struct window_pane *wp)
   3868 {
   3869 	struct client		*c;
   3870 	struct window		*w = wp->window;
   3871 	struct client_window	*cw;
   3872 
   3873 	TAILQ_FOREACH(c, &clients, entry) {
   3874 		cw = server_client_get_client_window(c, w->id);
   3875 		if (cw != NULL && cw->pane == wp) {
   3876 			RB_REMOVE(client_windows, &c->windows, cw);
   3877 			free(cw);
   3878 		}
   3879 	}
   3880 }
   3881 
   3882 /* Print to a client. */
   3883 void
   3884 server_client_print(struct client *c, int parse, struct evbuffer *evb)
   3885 {
   3886 	void				*data = EVBUFFER_DATA(evb);
   3887 	size_t				 size = EVBUFFER_LENGTH(evb);
   3888 	struct window_pane		*wp;
   3889 	struct window_mode_entry	*wme;
   3890 	char				*sanitized, *msg, *line, empty = '\0';
   3891 
   3892 	if (!parse) {
   3893 		utf8_stravisx(&msg, data, size,
   3894 		    VIS_OCTAL|VIS_CSTYLE|VIS_NOSLASH);
   3895 	} else {
   3896 		if (size == 0)
   3897 			msg = &empty;
   3898 		else {
   3899 			msg = (char *)EVBUFFER_DATA(evb);
   3900 			if (msg[size - 1] != '\0')
   3901 				evbuffer_add(evb, "", 1);
   3902 		}
   3903 	}
   3904 	log_debug("%s: %s", __func__, msg);
   3905 
   3906 	if (c == NULL)
   3907 		goto out;
   3908 
   3909 	if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
   3910 		if (~c->flags & CLIENT_UTF8) {
   3911 			sanitized = utf8_sanitize(msg);
   3912 			if (c->flags & CLIENT_CONTROL)
   3913 				control_write(c, "%s", sanitized);
   3914 			else
   3915 				file_print(c, "%s\n", sanitized);
   3916 			free(sanitized);
   3917 		} else {
   3918 			if (c->flags & CLIENT_CONTROL)
   3919 				control_write(c, "%s", msg);
   3920 			else
   3921 				file_print(c, "%s\n", msg);
   3922 		}
   3923 		goto out;
   3924 	}
   3925 
   3926 	wp = server_client_get_pane(c);
   3927 	wme = TAILQ_FIRST(&wp->modes);
   3928 	if (wme == NULL || wme->mode != &window_view_mode)
   3929 		window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL);
   3930 	if (parse) {
   3931 		do {
   3932 			line = evbuffer_readln(evb, NULL, EVBUFFER_EOL_LF);
   3933 			if (line != NULL) {
   3934 				window_copy_add(wp, 1, "%s", line);
   3935 				free(line);
   3936 			}
   3937 		} while (line != NULL);
   3938 
   3939 		size = EVBUFFER_LENGTH(evb);
   3940 		if (size != 0) {
   3941 			line = (char *)EVBUFFER_DATA(evb);
   3942 			window_copy_add(wp, 1, "%.*s", (int)size, line);
   3943 		}
   3944 	} else
   3945 		window_copy_add(wp, 0, "%s", msg);
   3946 
   3947 out:
   3948 	if (!parse)
   3949 		free(msg);
   3950 }
   3951 
   3952 static void
   3953 server_client_report_theme(struct client *c, enum client_theme theme)
   3954 {
   3955 	if (theme == THEME_LIGHT) {
   3956 		c->theme = THEME_LIGHT;
   3957 		notify_client("client-light-theme", c);
   3958 	} else {
   3959 		c->theme = THEME_DARK;
   3960 		notify_client("client-dark-theme", c);
   3961 	}
   3962 
   3963 	/*
   3964 	 * Request foreground and background colour again. Don't forward 2031 to
   3965 	 * panes until a response is received.
   3966 	 */
   3967 	tty_repeat_requests(&c->tty, 1);
   3968 }
   3969