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