1 /* $OpenBSD: server-client.c,v 1.390 2021/11/15 10:58:13 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 33 #include "tmux.h" 34 35 static void server_client_free(int, short, void *); 36 static void server_client_check_pane_resize(struct window_pane *); 37 static void server_client_check_pane_buffer(struct window_pane *); 38 static void server_client_check_window_resize(struct window *); 39 static key_code server_client_check_mouse(struct client *, struct key_event *); 40 static void server_client_repeat_timer(int, short, void *); 41 static void server_client_click_timer(int, short, void *); 42 static void server_client_check_exit(struct client *); 43 static void server_client_check_redraw(struct client *); 44 static void server_client_check_modes(struct client *); 45 static void server_client_set_title(struct client *); 46 static void server_client_reset_state(struct client *); 47 static int server_client_assume_paste(struct session *); 48 static void server_client_update_latest(struct client *); 49 50 static void server_client_dispatch(struct imsg *, void *); 51 static void server_client_dispatch_command(struct client *, struct imsg *); 52 static void server_client_dispatch_identify(struct client *, struct imsg *); 53 static void server_client_dispatch_shell(struct client *); 54 55 /* Compare client windows. */ 56 static int 57 server_client_window_cmp(struct client_window *cw1, 58 struct client_window *cw2) 59 { 60 if (cw1->window < cw2->window) 61 return (-1); 62 if (cw1->window > cw2->window) 63 return (1); 64 return (0); 65 } 66 RB_GENERATE(client_windows, client_window, entry, server_client_window_cmp); 67 68 /* Number of attached clients. */ 69 u_int 70 server_client_how_many(void) 71 { 72 struct client *c; 73 u_int n; 74 75 n = 0; 76 TAILQ_FOREACH(c, &clients, entry) { 77 if (c->session != NULL && (~c->flags & CLIENT_UNATTACHEDFLAGS)) 78 n++; 79 } 80 return (n); 81 } 82 83 /* Overlay timer callback. */ 84 static void 85 server_client_overlay_timer(__unused int fd, __unused short events, void *data) 86 { 87 server_client_clear_overlay(data); 88 } 89 90 /* Set an overlay on client. */ 91 void 92 server_client_set_overlay(struct client *c, u_int delay, 93 overlay_check_cb checkcb, overlay_mode_cb modecb, 94 overlay_draw_cb drawcb, overlay_key_cb keycb, overlay_free_cb freecb, 95 overlay_resize_cb resizecb, void *data) 96 { 97 struct timeval tv; 98 99 if (c->overlay_draw != NULL) 100 server_client_clear_overlay(c); 101 102 tv.tv_sec = delay / 1000; 103 tv.tv_usec = (delay % 1000) * 1000L; 104 105 if (event_initialized(&c->overlay_timer)) 106 evtimer_del(&c->overlay_timer); 107 evtimer_set(&c->overlay_timer, server_client_overlay_timer, c); 108 if (delay != 0) 109 evtimer_add(&c->overlay_timer, &tv); 110 111 c->overlay_check = checkcb; 112 c->overlay_mode = modecb; 113 c->overlay_draw = drawcb; 114 c->overlay_key = keycb; 115 c->overlay_free = freecb; 116 c->overlay_resize = resizecb; 117 c->overlay_data = data; 118 119 if (c->overlay_check == NULL) 120 c->tty.flags |= TTY_FREEZE; 121 if (c->overlay_mode == NULL) 122 c->tty.flags |= TTY_NOCURSOR; 123 server_redraw_client(c); 124 } 125 126 /* Clear overlay mode on client. */ 127 void 128 server_client_clear_overlay(struct client *c) 129 { 130 if (c->overlay_draw == NULL) 131 return; 132 133 if (event_initialized(&c->overlay_timer)) 134 evtimer_del(&c->overlay_timer); 135 136 if (c->overlay_free != NULL) 137 c->overlay_free(c, c->overlay_data); 138 139 c->overlay_check = NULL; 140 c->overlay_mode = NULL; 141 c->overlay_draw = NULL; 142 c->overlay_key = NULL; 143 c->overlay_free = NULL; 144 c->overlay_data = NULL; 145 146 c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR); 147 server_redraw_client(c); 148 } 149 150 /* 151 * Given overlay position and dimensions, return parts of the input range which 152 * are visible. 153 */ 154 void 155 server_client_overlay_range(u_int x, u_int y, u_int sx, u_int sy, u_int px, 156 u_int py, u_int nx, struct overlay_ranges *r) 157 { 158 u_int ox, onx; 159 160 /* Return up to 2 ranges. */ 161 r->px[2] = 0; 162 r->nx[2] = 0; 163 164 /* Trivial case of no overlap in the y direction. */ 165 if (py < y || py > y + sy - 1) { 166 r->px[0] = px; 167 r->nx[0] = nx; 168 r->px[1] = 0; 169 r->nx[1] = 0; 170 return; 171 } 172 173 /* Visible bit to the left of the popup. */ 174 if (px < x) { 175 r->px[0] = px; 176 r->nx[0] = x - px; 177 if (r->nx[0] > nx) 178 r->nx[0] = nx; 179 } else { 180 r->px[0] = 0; 181 r->nx[0] = 0; 182 } 183 184 /* Visible bit to the right of the popup. */ 185 ox = x + sx; 186 if (px > ox) 187 ox = px; 188 onx = px + nx; 189 if (onx > ox) { 190 r->px[1] = ox; 191 r->nx[1] = onx - ox; 192 } else { 193 r->px[1] = 0; 194 r->nx[1] = 0; 195 } 196 } 197 198 /* Check if this client is inside this server. */ 199 int 200 server_client_check_nested(struct client *c) 201 { 202 struct environ_entry *envent; 203 struct window_pane *wp; 204 205 envent = environ_find(c->environ, "TMUX"); 206 if (envent == NULL || *envent->value == '\0') 207 return (0); 208 209 RB_FOREACH(wp, window_pane_tree, &all_window_panes) { 210 if (strcmp(wp->tty, c->ttyname) == 0) 211 return (1); 212 } 213 return (0); 214 } 215 216 /* Set client key table. */ 217 void 218 server_client_set_key_table(struct client *c, const char *name) 219 { 220 if (name == NULL) 221 name = server_client_get_key_table(c); 222 223 key_bindings_unref_table(c->keytable); 224 c->keytable = key_bindings_get_table(name, 1); 225 c->keytable->references++; 226 } 227 228 /* Get default key table. */ 229 const char * 230 server_client_get_key_table(struct client *c) 231 { 232 struct session *s = c->session; 233 const char *name; 234 235 if (s == NULL) 236 return ("root"); 237 238 name = options_get_string(s->options, "key-table"); 239 if (*name == '\0') 240 return ("root"); 241 return (name); 242 } 243 244 /* Is this table the default key table? */ 245 static int 246 server_client_is_default_key_table(struct client *c, struct key_table *table) 247 { 248 return (strcmp(table->name, server_client_get_key_table(c)) == 0); 249 } 250 251 /* Create a new client. */ 252 struct client * 253 server_client_create(int fd) 254 { 255 struct client *c; 256 257 setblocking(fd, 0); 258 259 c = xcalloc(1, sizeof *c); 260 c->references = 1; 261 c->peer = proc_add_peer(server_proc, fd, server_client_dispatch, c); 262 263 if (gettimeofday(&c->creation_time, NULL) != 0) 264 fatal("gettimeofday failed"); 265 memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time); 266 267 c->environ = environ_create(); 268 269 c->fd = -1; 270 c->out_fd = -1; 271 272 c->queue = cmdq_new(); 273 RB_INIT(&c->windows); 274 RB_INIT(&c->files); 275 276 c->tty.sx = 80; 277 c->tty.sy = 24; 278 279 status_init(c); 280 c->flags |= CLIENT_FOCUSED; 281 282 c->keytable = key_bindings_get_table("root", 1); 283 c->keytable->references++; 284 285 evtimer_set(&c->repeat_timer, server_client_repeat_timer, c); 286 evtimer_set(&c->click_timer, server_client_click_timer, c); 287 288 TAILQ_INSERT_TAIL(&clients, c, entry); 289 log_debug("new client %p", c); 290 return (c); 291 } 292 293 /* Open client terminal if needed. */ 294 int 295 server_client_open(struct client *c, char **cause) 296 { 297 const char *ttynam = _PATH_TTY; 298 299 if (c->flags & CLIENT_CONTROL) 300 return (0); 301 302 if (strcmp(c->ttyname, ttynam) == 0|| 303 ((isatty(STDIN_FILENO) && 304 (ttynam = ttyname(STDIN_FILENO)) != NULL && 305 strcmp(c->ttyname, ttynam) == 0) || 306 (isatty(STDOUT_FILENO) && 307 (ttynam = ttyname(STDOUT_FILENO)) != NULL && 308 strcmp(c->ttyname, ttynam) == 0) || 309 (isatty(STDERR_FILENO) && 310 (ttynam = ttyname(STDERR_FILENO)) != NULL && 311 strcmp(c->ttyname, ttynam) == 0))) { 312 xasprintf(cause, "can't use %s", c->ttyname); 313 return (-1); 314 } 315 316 if (!(c->flags & CLIENT_TERMINAL)) { 317 *cause = xstrdup("not a terminal"); 318 return (-1); 319 } 320 321 if (tty_open(&c->tty, cause) != 0) 322 return (-1); 323 324 return (0); 325 } 326 327 /* Lost an attached client. */ 328 static void 329 server_client_attached_lost(struct client *c) 330 { 331 struct session *s; 332 struct window *w; 333 struct client *loop; 334 struct client *found; 335 336 log_debug("lost attached client %p", c); 337 338 /* 339 * By this point the session in the client has been cleared so walk all 340 * windows to find any with this client as the latest. 341 */ 342 RB_FOREACH(w, windows, &windows) { 343 if (w->latest != c) 344 continue; 345 346 found = NULL; 347 TAILQ_FOREACH(loop, &clients, entry) { 348 s = loop->session; 349 if (loop == c || s == NULL || s->curw->window != w) 350 continue; 351 if (found == NULL || timercmp(&loop->activity_time, 352 &found->activity_time, >)) 353 found = loop; 354 } 355 if (found != NULL) 356 server_client_update_latest(found); 357 } 358 } 359 360 /* Set client session. */ 361 void 362 server_client_set_session(struct client *c, struct session *s) 363 { 364 struct session *old = c->session; 365 366 if (s != NULL && c->session != NULL && c->session != s) 367 c->last_session = c->session; 368 else if (s == NULL) 369 c->last_session = NULL; 370 c->session = s; 371 c->flags |= CLIENT_FOCUSED; 372 373 if (old != NULL && old->curw != NULL) 374 window_update_focus(old->curw->window); 375 if (s != NULL) { 376 recalculate_sizes(); 377 window_update_focus(s->curw->window); 378 session_update_activity(s, NULL); 379 gettimeofday(&s->last_attached_time, NULL); 380 s->curw->flags &= ~WINLINK_ALERTFLAGS; 381 s->curw->window->latest = c; 382 alerts_check_session(s); 383 tty_update_client_offset(c); 384 status_timer_start(c); 385 notify_client("client-session-changed", c); 386 server_redraw_client(c); 387 } 388 389 server_check_unattached(); 390 server_update_socket(); 391 } 392 393 /* Lost a client. */ 394 void 395 server_client_lost(struct client *c) 396 { 397 struct client_file *cf, *cf1; 398 struct client_window *cw, *cw1; 399 400 c->flags |= CLIENT_DEAD; 401 402 server_client_clear_overlay(c); 403 status_prompt_clear(c); 404 status_message_clear(c); 405 406 RB_FOREACH_SAFE(cf, client_files, &c->files, cf1) { 407 cf->error = EINTR; 408 file_fire_done(cf); 409 } 410 RB_FOREACH_SAFE(cw, client_windows, &c->windows, cw1) { 411 RB_REMOVE(client_windows, &c->windows, cw); 412 free(cw); 413 } 414 415 TAILQ_REMOVE(&clients, c, entry); 416 log_debug("lost client %p", c); 417 418 if (c->flags & CLIENT_ATTACHED) { 419 server_client_attached_lost(c); 420 notify_client("client-detached", c); 421 } 422 423 if (c->flags & CLIENT_CONTROL) 424 control_stop(c); 425 if (c->flags & CLIENT_TERMINAL) 426 tty_free(&c->tty); 427 free(c->ttyname); 428 429 free(c->term_name); 430 free(c->term_type); 431 tty_term_free_list(c->term_caps, c->term_ncaps); 432 433 status_free(c); 434 435 free(c->title); 436 free((void *)c->cwd); 437 438 evtimer_del(&c->repeat_timer); 439 evtimer_del(&c->click_timer); 440 441 key_bindings_unref_table(c->keytable); 442 443 free(c->message_string); 444 if (event_initialized(&c->message_timer)) 445 evtimer_del(&c->message_timer); 446 447 free(c->prompt_saved); 448 free(c->prompt_string); 449 free(c->prompt_buffer); 450 451 format_lost_client(c); 452 environ_free(c->environ); 453 454 proc_remove_peer(c->peer); 455 c->peer = NULL; 456 457 if (c->out_fd != -1) 458 close(c->out_fd); 459 if (c->fd != -1) { 460 close(c->fd); 461 c->fd = -1; 462 } 463 server_client_unref(c); 464 465 server_add_accept(0); /* may be more file descriptors now */ 466 467 recalculate_sizes(); 468 server_check_unattached(); 469 server_update_socket(); 470 } 471 472 /* Remove reference from a client. */ 473 void 474 server_client_unref(struct client *c) 475 { 476 log_debug("unref client %p (%d references)", c, c->references); 477 478 c->references--; 479 if (c->references == 0) 480 event_once(-1, EV_TIMEOUT, server_client_free, c, NULL); 481 } 482 483 /* Free dead client. */ 484 static void 485 server_client_free(__unused int fd, __unused short events, void *arg) 486 { 487 struct client *c = arg; 488 489 log_debug("free client %p (%d references)", c, c->references); 490 491 cmdq_free(c->queue); 492 493 if (c->references == 0) { 494 free((void *)c->name); 495 free(c); 496 } 497 } 498 499 /* Suspend a client. */ 500 void 501 server_client_suspend(struct client *c) 502 { 503 struct session *s = c->session; 504 505 if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS)) 506 return; 507 508 tty_stop_tty(&c->tty); 509 c->flags |= CLIENT_SUSPENDED; 510 proc_send(c->peer, MSG_SUSPEND, -1, NULL, 0); 511 } 512 513 /* Detach a client. */ 514 void 515 server_client_detach(struct client *c, enum msgtype msgtype) 516 { 517 struct session *s = c->session; 518 519 if (s == NULL || (c->flags & CLIENT_NODETACHFLAGS)) 520 return; 521 522 c->flags |= CLIENT_EXIT; 523 524 c->exit_type = CLIENT_EXIT_DETACH; 525 c->exit_msgtype = msgtype; 526 c->exit_session = xstrdup(s->name); 527 } 528 529 /* Execute command to replace a client. */ 530 void 531 server_client_exec(struct client *c, const char *cmd) 532 { 533 struct session *s = c->session; 534 char *msg; 535 const char *shell; 536 size_t cmdsize, shellsize; 537 538 if (*cmd == '\0') 539 return; 540 cmdsize = strlen(cmd) + 1; 541 542 if (s != NULL) 543 shell = options_get_string(s->options, "default-shell"); 544 else 545 shell = options_get_string(global_s_options, "default-shell"); 546 if (!checkshell(shell)) 547 shell = _PATH_BSHELL; 548 shellsize = strlen(shell) + 1; 549 550 msg = xmalloc(cmdsize + shellsize); 551 memcpy(msg, cmd, cmdsize); 552 memcpy(msg + cmdsize, shell, shellsize); 553 554 proc_send(c->peer, MSG_EXEC, -1, msg, cmdsize + shellsize); 555 free(msg); 556 } 557 558 /* Check for mouse keys. */ 559 static key_code 560 server_client_check_mouse(struct client *c, struct key_event *event) 561 { 562 struct mouse_event *m = &event->m; 563 struct session *s = c->session; 564 struct winlink *wl; 565 struct window_pane *wp; 566 u_int x, y, b, sx, sy, px, py; 567 int ignore = 0; 568 key_code key; 569 struct timeval tv; 570 struct style_range *sr; 571 enum { NOTYPE, 572 MOVE, 573 DOWN, 574 UP, 575 DRAG, 576 WHEEL, 577 SECOND, 578 DOUBLE, 579 TRIPLE } type = NOTYPE; 580 enum { NOWHERE, 581 PANE, 582 STATUS, 583 STATUS_LEFT, 584 STATUS_RIGHT, 585 STATUS_DEFAULT, 586 BORDER } where = NOWHERE; 587 588 log_debug("%s mouse %02x at %u,%u (last %u,%u) (%d)", c->name, m->b, 589 m->x, m->y, m->lx, m->ly, c->tty.mouse_drag_flag); 590 591 /* What type of event is this? */ 592 if (event->key == KEYC_DOUBLECLICK) { 593 type = DOUBLE; 594 x = m->x, y = m->y, b = m->b; 595 ignore = 1; 596 log_debug("double-click at %u,%u", x, y); 597 } else if ((m->sgr_type != ' ' && 598 MOUSE_DRAG(m->sgr_b) && 599 MOUSE_BUTTONS(m->sgr_b) == 3) || 600 (m->sgr_type == ' ' && 601 MOUSE_DRAG(m->b) && 602 MOUSE_BUTTONS(m->b) == 3 && 603 MOUSE_BUTTONS(m->lb) == 3)) { 604 type = MOVE; 605 x = m->x, y = m->y, b = 0; 606 log_debug("move at %u,%u", x, y); 607 } else if (MOUSE_DRAG(m->b)) { 608 type = DRAG; 609 if (c->tty.mouse_drag_flag) { 610 x = m->x, y = m->y, b = m->b; 611 if (x == m->lx && y == m->ly) 612 return (KEYC_UNKNOWN); 613 log_debug("drag update at %u,%u", x, y); 614 } else { 615 x = m->lx, y = m->ly, b = m->lb; 616 log_debug("drag start at %u,%u", x, y); 617 } 618 } else if (MOUSE_WHEEL(m->b)) { 619 type = WHEEL; 620 x = m->x, y = m->y, b = m->b; 621 log_debug("wheel at %u,%u", x, y); 622 } else if (MOUSE_RELEASE(m->b)) { 623 type = UP; 624 x = m->x, y = m->y, b = m->lb; 625 log_debug("up at %u,%u", x, y); 626 } else { 627 if (c->flags & CLIENT_DOUBLECLICK) { 628 evtimer_del(&c->click_timer); 629 c->flags &= ~CLIENT_DOUBLECLICK; 630 if (m->b == c->click_button) { 631 type = SECOND; 632 x = m->x, y = m->y, b = m->b; 633 log_debug("second-click at %u,%u", x, y); 634 c->flags |= CLIENT_TRIPLECLICK; 635 } 636 } else if (c->flags & CLIENT_TRIPLECLICK) { 637 evtimer_del(&c->click_timer); 638 c->flags &= ~CLIENT_TRIPLECLICK; 639 if (m->b == c->click_button) { 640 type = TRIPLE; 641 x = m->x, y = m->y, b = m->b; 642 log_debug("triple-click at %u,%u", x, y); 643 goto have_event; 644 } 645 } else { 646 type = DOWN; 647 x = m->x, y = m->y, b = m->b; 648 log_debug("down at %u,%u", x, y); 649 c->flags |= CLIENT_DOUBLECLICK; 650 } 651 652 if (KEYC_CLICK_TIMEOUT != 0) { 653 memcpy(&c->click_event, m, sizeof c->click_event); 654 c->click_button = m->b; 655 656 log_debug("click timer started"); 657 tv.tv_sec = KEYC_CLICK_TIMEOUT / 1000; 658 tv.tv_usec = (KEYC_CLICK_TIMEOUT % 1000) * 1000L; 659 evtimer_del(&c->click_timer); 660 evtimer_add(&c->click_timer, &tv); 661 } 662 } 663 664 have_event: 665 if (type == NOTYPE) 666 return (KEYC_UNKNOWN); 667 668 /* Save the session. */ 669 m->s = s->id; 670 m->w = -1; 671 m->ignore = ignore; 672 673 /* Is this on the status line? */ 674 m->statusat = status_at_line(c); 675 m->statuslines = status_line_size(c); 676 if (m->statusat != -1 && 677 y >= (u_int)m->statusat && 678 y < m->statusat + m->statuslines) { 679 sr = status_get_range(c, x, y - m->statusat); 680 if (sr == NULL) { 681 where = STATUS_DEFAULT; 682 } else { 683 switch (sr->type) { 684 case STYLE_RANGE_NONE: 685 return (KEYC_UNKNOWN); 686 case STYLE_RANGE_LEFT: 687 where = STATUS_LEFT; 688 break; 689 case STYLE_RANGE_RIGHT: 690 where = STATUS_RIGHT; 691 break; 692 case STYLE_RANGE_WINDOW: 693 wl = winlink_find_by_index(&s->windows, 694 sr->argument); 695 if (wl == NULL) 696 return (KEYC_UNKNOWN); 697 m->w = wl->window->id; 698 699 where = STATUS; 700 break; 701 } 702 } 703 } 704 705 /* Not on status line. Adjust position and check for border or pane. */ 706 if (where == NOWHERE) { 707 px = x; 708 if (m->statusat == 0 && y >= m->statuslines) 709 py = y - m->statuslines; 710 else if (m->statusat > 0 && y >= (u_int)m->statusat) 711 py = m->statusat - 1; 712 else 713 py = y; 714 715 tty_window_offset(&c->tty, &m->ox, &m->oy, &sx, &sy); 716 log_debug("mouse window @%u at %u,%u (%ux%u)", 717 s->curw->window->id, m->ox, m->oy, sx, sy); 718 if (px > sx || py > sy) 719 return (KEYC_UNKNOWN); 720 px = px + m->ox; 721 py = py + m->oy; 722 723 /* Try the pane borders if not zoomed. */ 724 if (~s->curw->window->flags & WINDOW_ZOOMED) { 725 TAILQ_FOREACH(wp, &s->curw->window->panes, entry) { 726 if ((wp->xoff + wp->sx == px && 727 wp->yoff <= 1 + py && 728 wp->yoff + wp->sy >= py) || 729 (wp->yoff + wp->sy == py && 730 wp->xoff <= 1 + px && 731 wp->xoff + wp->sx >= px)) 732 break; 733 } 734 if (wp != NULL) 735 where = BORDER; 736 } 737 738 /* Otherwise try inside the pane. */ 739 if (where == NOWHERE) { 740 wp = window_get_active_at(s->curw->window, px, py); 741 if (wp != NULL) 742 where = PANE; 743 else 744 return (KEYC_UNKNOWN); 745 } 746 if (where == PANE) 747 log_debug("mouse %u,%u on pane %%%u", x, y, wp->id); 748 else if (where == BORDER) 749 log_debug("mouse on pane %%%u border", wp->id); 750 m->wp = wp->id; 751 m->w = wp->window->id; 752 } else 753 m->wp = -1; 754 755 /* Stop dragging if needed. */ 756 if (type != DRAG && type != WHEEL && c->tty.mouse_drag_flag) { 757 if (c->tty.mouse_drag_release != NULL) 758 c->tty.mouse_drag_release(c, m); 759 760 c->tty.mouse_drag_update = NULL; 761 c->tty.mouse_drag_release = NULL; 762 763 /* 764 * End a mouse drag by passing a MouseDragEnd key corresponding 765 * to the button that started the drag. 766 */ 767 switch (c->tty.mouse_drag_flag) { 768 case 1: 769 if (where == PANE) 770 key = KEYC_MOUSEDRAGEND1_PANE; 771 if (where == STATUS) 772 key = KEYC_MOUSEDRAGEND1_STATUS; 773 if (where == STATUS_LEFT) 774 key = KEYC_MOUSEDRAGEND1_STATUS_LEFT; 775 if (where == STATUS_RIGHT) 776 key = KEYC_MOUSEDRAGEND1_STATUS_RIGHT; 777 if (where == STATUS_DEFAULT) 778 key = KEYC_MOUSEDRAGEND1_STATUS_DEFAULT; 779 if (where == BORDER) 780 key = KEYC_MOUSEDRAGEND1_BORDER; 781 break; 782 case 2: 783 if (where == PANE) 784 key = KEYC_MOUSEDRAGEND2_PANE; 785 if (where == STATUS) 786 key = KEYC_MOUSEDRAGEND2_STATUS; 787 if (where == STATUS_LEFT) 788 key = KEYC_MOUSEDRAGEND2_STATUS_LEFT; 789 if (where == STATUS_RIGHT) 790 key = KEYC_MOUSEDRAGEND2_STATUS_RIGHT; 791 if (where == STATUS_DEFAULT) 792 key = KEYC_MOUSEDRAGEND2_STATUS_DEFAULT; 793 if (where == BORDER) 794 key = KEYC_MOUSEDRAGEND2_BORDER; 795 break; 796 case 3: 797 if (where == PANE) 798 key = KEYC_MOUSEDRAGEND3_PANE; 799 if (where == STATUS) 800 key = KEYC_MOUSEDRAGEND3_STATUS; 801 if (where == STATUS_LEFT) 802 key = KEYC_MOUSEDRAGEND3_STATUS_LEFT; 803 if (where == STATUS_RIGHT) 804 key = KEYC_MOUSEDRAGEND3_STATUS_RIGHT; 805 if (where == STATUS_DEFAULT) 806 key = KEYC_MOUSEDRAGEND3_STATUS_DEFAULT; 807 if (where == BORDER) 808 key = KEYC_MOUSEDRAGEND3_BORDER; 809 break; 810 default: 811 key = KEYC_MOUSE; 812 break; 813 } 814 c->tty.mouse_drag_flag = 0; 815 goto out; 816 } 817 818 /* Convert to a key binding. */ 819 key = KEYC_UNKNOWN; 820 switch (type) { 821 case NOTYPE: 822 break; 823 case MOVE: 824 if (where == PANE) 825 key = KEYC_MOUSEMOVE_PANE; 826 if (where == STATUS) 827 key = KEYC_MOUSEMOVE_STATUS; 828 if (where == STATUS_LEFT) 829 key = KEYC_MOUSEMOVE_STATUS_LEFT; 830 if (where == STATUS_RIGHT) 831 key = KEYC_MOUSEMOVE_STATUS_RIGHT; 832 if (where == STATUS_DEFAULT) 833 key = KEYC_MOUSEMOVE_STATUS_DEFAULT; 834 if (where == BORDER) 835 key = KEYC_MOUSEMOVE_BORDER; 836 break; 837 case DRAG: 838 if (c->tty.mouse_drag_update != NULL) 839 key = KEYC_DRAGGING; 840 else { 841 switch (MOUSE_BUTTONS(b)) { 842 case 0: 843 if (where == PANE) 844 key = KEYC_MOUSEDRAG1_PANE; 845 if (where == STATUS) 846 key = KEYC_MOUSEDRAG1_STATUS; 847 if (where == STATUS_LEFT) 848 key = KEYC_MOUSEDRAG1_STATUS_LEFT; 849 if (where == STATUS_RIGHT) 850 key = KEYC_MOUSEDRAG1_STATUS_RIGHT; 851 if (where == STATUS_DEFAULT) 852 key = KEYC_MOUSEDRAG1_STATUS_DEFAULT; 853 if (where == BORDER) 854 key = KEYC_MOUSEDRAG1_BORDER; 855 break; 856 case 1: 857 if (where == PANE) 858 key = KEYC_MOUSEDRAG2_PANE; 859 if (where == STATUS) 860 key = KEYC_MOUSEDRAG2_STATUS; 861 if (where == STATUS_LEFT) 862 key = KEYC_MOUSEDRAG2_STATUS_LEFT; 863 if (where == STATUS_RIGHT) 864 key = KEYC_MOUSEDRAG2_STATUS_RIGHT; 865 if (where == STATUS_DEFAULT) 866 key = KEYC_MOUSEDRAG2_STATUS_DEFAULT; 867 if (where == BORDER) 868 key = KEYC_MOUSEDRAG2_BORDER; 869 break; 870 case 2: 871 if (where == PANE) 872 key = KEYC_MOUSEDRAG3_PANE; 873 if (where == STATUS) 874 key = KEYC_MOUSEDRAG3_STATUS; 875 if (where == STATUS_LEFT) 876 key = KEYC_MOUSEDRAG3_STATUS_LEFT; 877 if (where == STATUS_RIGHT) 878 key = KEYC_MOUSEDRAG3_STATUS_RIGHT; 879 if (where == STATUS_DEFAULT) 880 key = KEYC_MOUSEDRAG3_STATUS_DEFAULT; 881 if (where == BORDER) 882 key = KEYC_MOUSEDRAG3_BORDER; 883 break; 884 } 885 } 886 887 /* 888 * Begin a drag by setting the flag to a non-zero value that 889 * corresponds to the mouse button in use. 890 */ 891 c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1; 892 break; 893 case WHEEL: 894 if (MOUSE_BUTTONS(b) == MOUSE_WHEEL_UP) { 895 if (where == PANE) 896 key = KEYC_WHEELUP_PANE; 897 if (where == STATUS) 898 key = KEYC_WHEELUP_STATUS; 899 if (where == STATUS_LEFT) 900 key = KEYC_WHEELUP_STATUS_LEFT; 901 if (where == STATUS_RIGHT) 902 key = KEYC_WHEELUP_STATUS_RIGHT; 903 if (where == STATUS_DEFAULT) 904 key = KEYC_WHEELUP_STATUS_DEFAULT; 905 if (where == BORDER) 906 key = KEYC_WHEELUP_BORDER; 907 } else { 908 if (where == PANE) 909 key = KEYC_WHEELDOWN_PANE; 910 if (where == STATUS) 911 key = KEYC_WHEELDOWN_STATUS; 912 if (where == STATUS_LEFT) 913 key = KEYC_WHEELDOWN_STATUS_LEFT; 914 if (where == STATUS_RIGHT) 915 key = KEYC_WHEELDOWN_STATUS_RIGHT; 916 if (where == STATUS_DEFAULT) 917 key = KEYC_WHEELDOWN_STATUS_DEFAULT; 918 if (where == BORDER) 919 key = KEYC_WHEELDOWN_BORDER; 920 } 921 break; 922 case UP: 923 switch (MOUSE_BUTTONS(b)) { 924 case 0: 925 if (where == PANE) 926 key = KEYC_MOUSEUP1_PANE; 927 if (where == STATUS) 928 key = KEYC_MOUSEUP1_STATUS; 929 if (where == STATUS_LEFT) 930 key = KEYC_MOUSEUP1_STATUS_LEFT; 931 if (where == STATUS_RIGHT) 932 key = KEYC_MOUSEUP1_STATUS_RIGHT; 933 if (where == STATUS_DEFAULT) 934 key = KEYC_MOUSEUP1_STATUS_DEFAULT; 935 if (where == BORDER) 936 key = KEYC_MOUSEUP1_BORDER; 937 break; 938 case 1: 939 if (where == PANE) 940 key = KEYC_MOUSEUP2_PANE; 941 if (where == STATUS) 942 key = KEYC_MOUSEUP2_STATUS; 943 if (where == STATUS_LEFT) 944 key = KEYC_MOUSEUP2_STATUS_LEFT; 945 if (where == STATUS_RIGHT) 946 key = KEYC_MOUSEUP2_STATUS_RIGHT; 947 if (where == STATUS_DEFAULT) 948 key = KEYC_MOUSEUP2_STATUS_DEFAULT; 949 if (where == BORDER) 950 key = KEYC_MOUSEUP2_BORDER; 951 break; 952 case 2: 953 if (where == PANE) 954 key = KEYC_MOUSEUP3_PANE; 955 if (where == STATUS) 956 key = KEYC_MOUSEUP3_STATUS; 957 if (where == STATUS_LEFT) 958 key = KEYC_MOUSEUP3_STATUS_LEFT; 959 if (where == STATUS_RIGHT) 960 key = KEYC_MOUSEUP3_STATUS_RIGHT; 961 if (where == STATUS_DEFAULT) 962 key = KEYC_MOUSEUP3_STATUS_DEFAULT; 963 if (where == BORDER) 964 key = KEYC_MOUSEUP3_BORDER; 965 break; 966 } 967 break; 968 case DOWN: 969 switch (MOUSE_BUTTONS(b)) { 970 case 0: 971 if (where == PANE) 972 key = KEYC_MOUSEDOWN1_PANE; 973 if (where == STATUS) 974 key = KEYC_MOUSEDOWN1_STATUS; 975 if (where == STATUS_LEFT) 976 key = KEYC_MOUSEDOWN1_STATUS_LEFT; 977 if (where == STATUS_RIGHT) 978 key = KEYC_MOUSEDOWN1_STATUS_RIGHT; 979 if (where == STATUS_DEFAULT) 980 key = KEYC_MOUSEDOWN1_STATUS_DEFAULT; 981 if (where == BORDER) 982 key = KEYC_MOUSEDOWN1_BORDER; 983 break; 984 case 1: 985 if (where == PANE) 986 key = KEYC_MOUSEDOWN2_PANE; 987 if (where == STATUS) 988 key = KEYC_MOUSEDOWN2_STATUS; 989 if (where == STATUS_LEFT) 990 key = KEYC_MOUSEDOWN2_STATUS_LEFT; 991 if (where == STATUS_RIGHT) 992 key = KEYC_MOUSEDOWN2_STATUS_RIGHT; 993 if (where == STATUS_DEFAULT) 994 key = KEYC_MOUSEDOWN2_STATUS_DEFAULT; 995 if (where == BORDER) 996 key = KEYC_MOUSEDOWN2_BORDER; 997 break; 998 case 2: 999 if (where == PANE) 1000 key = KEYC_MOUSEDOWN3_PANE; 1001 if (where == STATUS) 1002 key = KEYC_MOUSEDOWN3_STATUS; 1003 if (where == STATUS_LEFT) 1004 key = KEYC_MOUSEDOWN3_STATUS_LEFT; 1005 if (where == STATUS_RIGHT) 1006 key = KEYC_MOUSEDOWN3_STATUS_RIGHT; 1007 if (where == STATUS_DEFAULT) 1008 key = KEYC_MOUSEDOWN3_STATUS_DEFAULT; 1009 if (where == BORDER) 1010 key = KEYC_MOUSEDOWN3_BORDER; 1011 break; 1012 } 1013 break; 1014 case SECOND: 1015 switch (MOUSE_BUTTONS(b)) { 1016 case 0: 1017 if (where == PANE) 1018 key = KEYC_SECONDCLICK1_PANE; 1019 if (where == STATUS) 1020 key = KEYC_SECONDCLICK1_STATUS; 1021 if (where == STATUS_LEFT) 1022 key = KEYC_SECONDCLICK1_STATUS_LEFT; 1023 if (where == STATUS_RIGHT) 1024 key = KEYC_SECONDCLICK1_STATUS_RIGHT; 1025 if (where == STATUS_DEFAULT) 1026 key = KEYC_SECONDCLICK1_STATUS_DEFAULT; 1027 if (where == BORDER) 1028 key = KEYC_SECONDCLICK1_BORDER; 1029 break; 1030 case 1: 1031 if (where == PANE) 1032 key = KEYC_SECONDCLICK2_PANE; 1033 if (where == STATUS) 1034 key = KEYC_SECONDCLICK2_STATUS; 1035 if (where == STATUS_LEFT) 1036 key = KEYC_SECONDCLICK2_STATUS_LEFT; 1037 if (where == STATUS_RIGHT) 1038 key = KEYC_SECONDCLICK2_STATUS_RIGHT; 1039 if (where == STATUS_DEFAULT) 1040 key = KEYC_SECONDCLICK2_STATUS_DEFAULT; 1041 if (where == BORDER) 1042 key = KEYC_SECONDCLICK2_BORDER; 1043 break; 1044 case 2: 1045 if (where == PANE) 1046 key = KEYC_SECONDCLICK3_PANE; 1047 if (where == STATUS) 1048 key = KEYC_SECONDCLICK3_STATUS; 1049 if (where == STATUS_LEFT) 1050 key = KEYC_SECONDCLICK3_STATUS_LEFT; 1051 if (where == STATUS_RIGHT) 1052 key = KEYC_SECONDCLICK3_STATUS_RIGHT; 1053 if (where == STATUS_DEFAULT) 1054 key = KEYC_SECONDCLICK3_STATUS_DEFAULT; 1055 if (where == BORDER) 1056 key = KEYC_SECONDCLICK3_BORDER; 1057 break; 1058 } 1059 break; 1060 case DOUBLE: 1061 switch (MOUSE_BUTTONS(b)) { 1062 case 0: 1063 if (where == PANE) 1064 key = KEYC_DOUBLECLICK1_PANE; 1065 if (where == STATUS) 1066 key = KEYC_DOUBLECLICK1_STATUS; 1067 if (where == STATUS_LEFT) 1068 key = KEYC_DOUBLECLICK1_STATUS_LEFT; 1069 if (where == STATUS_RIGHT) 1070 key = KEYC_DOUBLECLICK1_STATUS_RIGHT; 1071 if (where == STATUS_DEFAULT) 1072 key = KEYC_DOUBLECLICK1_STATUS_DEFAULT; 1073 if (where == BORDER) 1074 key = KEYC_DOUBLECLICK1_BORDER; 1075 break; 1076 case 1: 1077 if (where == PANE) 1078 key = KEYC_DOUBLECLICK2_PANE; 1079 if (where == STATUS) 1080 key = KEYC_DOUBLECLICK2_STATUS; 1081 if (where == STATUS_LEFT) 1082 key = KEYC_DOUBLECLICK2_STATUS_LEFT; 1083 if (where == STATUS_RIGHT) 1084 key = KEYC_DOUBLECLICK2_STATUS_RIGHT; 1085 if (where == STATUS_DEFAULT) 1086 key = KEYC_DOUBLECLICK2_STATUS_DEFAULT; 1087 if (where == BORDER) 1088 key = KEYC_DOUBLECLICK2_BORDER; 1089 break; 1090 case 2: 1091 if (where == PANE) 1092 key = KEYC_DOUBLECLICK3_PANE; 1093 if (where == STATUS) 1094 key = KEYC_DOUBLECLICK3_STATUS; 1095 if (where == STATUS_LEFT) 1096 key = KEYC_DOUBLECLICK3_STATUS_LEFT; 1097 if (where == STATUS_RIGHT) 1098 key = KEYC_DOUBLECLICK3_STATUS_RIGHT; 1099 if (where == STATUS_DEFAULT) 1100 key = KEYC_DOUBLECLICK3_STATUS_DEFAULT; 1101 if (where == BORDER) 1102 key = KEYC_DOUBLECLICK3_BORDER; 1103 break; 1104 } 1105 break; 1106 case TRIPLE: 1107 switch (MOUSE_BUTTONS(b)) { 1108 case 0: 1109 if (where == PANE) 1110 key = KEYC_TRIPLECLICK1_PANE; 1111 if (where == STATUS) 1112 key = KEYC_TRIPLECLICK1_STATUS; 1113 if (where == STATUS_LEFT) 1114 key = KEYC_TRIPLECLICK1_STATUS_LEFT; 1115 if (where == STATUS_RIGHT) 1116 key = KEYC_TRIPLECLICK1_STATUS_RIGHT; 1117 if (where == STATUS_DEFAULT) 1118 key = KEYC_TRIPLECLICK1_STATUS_DEFAULT; 1119 if (where == BORDER) 1120 key = KEYC_TRIPLECLICK1_BORDER; 1121 break; 1122 case 1: 1123 if (where == PANE) 1124 key = KEYC_TRIPLECLICK2_PANE; 1125 if (where == STATUS) 1126 key = KEYC_TRIPLECLICK2_STATUS; 1127 if (where == STATUS_LEFT) 1128 key = KEYC_TRIPLECLICK2_STATUS_LEFT; 1129 if (where == STATUS_RIGHT) 1130 key = KEYC_TRIPLECLICK2_STATUS_RIGHT; 1131 if (where == STATUS_DEFAULT) 1132 key = KEYC_TRIPLECLICK2_STATUS_DEFAULT; 1133 if (where == BORDER) 1134 key = KEYC_TRIPLECLICK2_BORDER; 1135 break; 1136 case 2: 1137 if (where == PANE) 1138 key = KEYC_TRIPLECLICK3_PANE; 1139 if (where == STATUS) 1140 key = KEYC_TRIPLECLICK3_STATUS; 1141 if (where == STATUS_LEFT) 1142 key = KEYC_TRIPLECLICK3_STATUS_LEFT; 1143 if (where == STATUS_RIGHT) 1144 key = KEYC_TRIPLECLICK3_STATUS_RIGHT; 1145 if (where == STATUS_DEFAULT) 1146 key = KEYC_TRIPLECLICK3_STATUS_DEFAULT; 1147 if (where == BORDER) 1148 key = KEYC_TRIPLECLICK3_BORDER; 1149 break; 1150 } 1151 break; 1152 } 1153 if (key == KEYC_UNKNOWN) 1154 return (KEYC_UNKNOWN); 1155 1156 out: 1157 /* Apply modifiers if any. */ 1158 if (b & MOUSE_MASK_META) 1159 key |= KEYC_META; 1160 if (b & MOUSE_MASK_CTRL) 1161 key |= KEYC_CTRL; 1162 if (b & MOUSE_MASK_SHIFT) 1163 key |= KEYC_SHIFT; 1164 1165 if (log_get_level() != 0) 1166 log_debug("mouse key is %s", key_string_lookup_key (key, 1)); 1167 return (key); 1168 } 1169 1170 /* Is this fast enough to probably be a paste? */ 1171 static int 1172 server_client_assume_paste(struct session *s) 1173 { 1174 struct timeval tv; 1175 int t; 1176 1177 if ((t = options_get_number(s->options, "assume-paste-time")) == 0) 1178 return (0); 1179 1180 timersub(&s->activity_time, &s->last_activity_time, &tv); 1181 if (tv.tv_sec == 0 && tv.tv_usec < t * 1000) { 1182 log_debug("session %s pasting (flag %d)", s->name, 1183 !!(s->flags & SESSION_PASTING)); 1184 if (s->flags & SESSION_PASTING) 1185 return (1); 1186 s->flags |= SESSION_PASTING; 1187 return (0); 1188 } 1189 log_debug("session %s not pasting", s->name); 1190 s->flags &= ~SESSION_PASTING; 1191 return (0); 1192 } 1193 1194 /* Has the latest client changed? */ 1195 static void 1196 server_client_update_latest(struct client *c) 1197 { 1198 struct window *w; 1199 1200 if (c->session == NULL) 1201 return; 1202 w = c->session->curw->window; 1203 1204 if (w->latest == c) 1205 return; 1206 w->latest = c; 1207 1208 if (options_get_number(w->options, "window-size") == WINDOW_SIZE_LATEST) 1209 recalculate_size(w, 0); 1210 1211 notify_client("client-active", c); 1212 } 1213 1214 /* 1215 * Handle data key input from client. This owns and can modify the key event it 1216 * is given and is responsible for freeing it. 1217 */ 1218 static enum cmd_retval 1219 server_client_key_callback(struct cmdq_item *item, void *data) 1220 { 1221 struct client *c = cmdq_get_client(item); 1222 struct key_event *event = data; 1223 key_code key = event->key; 1224 struct mouse_event *m = &event->m; 1225 struct session *s = c->session; 1226 struct winlink *wl; 1227 struct window_pane *wp; 1228 struct window_mode_entry *wme; 1229 struct timeval tv; 1230 struct key_table *table, *first; 1231 struct key_binding *bd; 1232 int xtimeout, flags; 1233 struct cmd_find_state fs; 1234 key_code key0; 1235 1236 /* Check the client is good to accept input. */ 1237 if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS)) 1238 goto out; 1239 wl = s->curw; 1240 1241 /* Update the activity timer. */ 1242 if (gettimeofday(&c->activity_time, NULL) != 0) 1243 fatal("gettimeofday failed"); 1244 session_update_activity(s, &c->activity_time); 1245 1246 /* Check for mouse keys. */ 1247 m->valid = 0; 1248 if (key == KEYC_MOUSE || key == KEYC_DOUBLECLICK) { 1249 if (c->flags & CLIENT_READONLY) 1250 goto out; 1251 key = server_client_check_mouse(c, event); 1252 if (key == KEYC_UNKNOWN) 1253 goto out; 1254 1255 m->valid = 1; 1256 m->key = key; 1257 1258 /* 1259 * Mouse drag is in progress, so fire the callback (now that 1260 * the mouse event is valid). 1261 */ 1262 if ((key & KEYC_MASK_KEY) == KEYC_DRAGGING) { 1263 c->tty.mouse_drag_update(c, m); 1264 goto out; 1265 } 1266 event->key = key; 1267 } 1268 1269 /* Find affected pane. */ 1270 if (!KEYC_IS_MOUSE(key) || cmd_find_from_mouse(&fs, m, 0) != 0) 1271 cmd_find_from_client(&fs, c, 0); 1272 wp = fs.wp; 1273 1274 /* Forward mouse keys if disabled. */ 1275 if (KEYC_IS_MOUSE(key) && !options_get_number(s->options, "mouse")) 1276 goto forward_key; 1277 1278 /* Treat everything as a regular key when pasting is detected. */ 1279 if (!KEYC_IS_MOUSE(key) && server_client_assume_paste(s)) 1280 goto forward_key; 1281 1282 /* 1283 * Work out the current key table. If the pane is in a mode, use 1284 * the mode table instead of the default key table. 1285 */ 1286 if (server_client_is_default_key_table(c, c->keytable) && 1287 wp != NULL && 1288 (wme = TAILQ_FIRST(&wp->modes)) != NULL && 1289 wme->mode->key_table != NULL) 1290 table = key_bindings_get_table(wme->mode->key_table(wme), 1); 1291 else 1292 table = c->keytable; 1293 first = table; 1294 1295 table_changed: 1296 /* 1297 * The prefix always takes precedence and forces a switch to the prefix 1298 * table, unless we are already there. 1299 */ 1300 key0 = (key & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS)); 1301 if ((key0 == (key_code)options_get_number(s->options, "prefix") || 1302 key0 == (key_code)options_get_number(s->options, "prefix2")) && 1303 strcmp(table->name, "prefix") != 0) { 1304 server_client_set_key_table(c, "prefix"); 1305 server_status_client(c); 1306 goto out; 1307 } 1308 flags = c->flags; 1309 1310 try_again: 1311 /* Log key table. */ 1312 if (wp == NULL) 1313 log_debug("key table %s (no pane)", table->name); 1314 else 1315 log_debug("key table %s (pane %%%u)", table->name, wp->id); 1316 if (c->flags & CLIENT_REPEAT) 1317 log_debug("currently repeating"); 1318 1319 /* Try to see if there is a key binding in the current table. */ 1320 bd = key_bindings_get(table, key0); 1321 if (bd != NULL) { 1322 /* 1323 * Key was matched in this table. If currently repeating but a 1324 * non-repeating binding was found, stop repeating and try 1325 * again in the root table. 1326 */ 1327 if ((c->flags & CLIENT_REPEAT) && 1328 (~bd->flags & KEY_BINDING_REPEAT)) { 1329 log_debug("found in key table %s (not repeating)", 1330 table->name); 1331 server_client_set_key_table(c, NULL); 1332 first = table = c->keytable; 1333 c->flags &= ~CLIENT_REPEAT; 1334 server_status_client(c); 1335 goto table_changed; 1336 } 1337 log_debug("found in key table %s", table->name); 1338 1339 /* 1340 * Take a reference to this table to make sure the key binding 1341 * doesn't disappear. 1342 */ 1343 table->references++; 1344 1345 /* 1346 * If this is a repeating key, start the timer. Otherwise reset 1347 * the client back to the root table. 1348 */ 1349 xtimeout = options_get_number(s->options, "repeat-time"); 1350 if (xtimeout != 0 && (bd->flags & KEY_BINDING_REPEAT)) { 1351 c->flags |= CLIENT_REPEAT; 1352 1353 tv.tv_sec = xtimeout / 1000; 1354 tv.tv_usec = (xtimeout % 1000) * 1000L; 1355 evtimer_del(&c->repeat_timer); 1356 evtimer_add(&c->repeat_timer, &tv); 1357 } else { 1358 c->flags &= ~CLIENT_REPEAT; 1359 server_client_set_key_table(c, NULL); 1360 } 1361 server_status_client(c); 1362 1363 /* Execute the key binding. */ 1364 key_bindings_dispatch(bd, item, c, event, &fs); 1365 key_bindings_unref_table(table); 1366 goto out; 1367 } 1368 1369 /* 1370 * No match, try the ANY key. 1371 */ 1372 if (key0 != KEYC_ANY) { 1373 key0 = KEYC_ANY; 1374 goto try_again; 1375 } 1376 1377 /* 1378 * No match in this table. If not in the root table or if repeating, 1379 * switch the client back to the root table and try again. 1380 */ 1381 log_debug("not found in key table %s", table->name); 1382 if (!server_client_is_default_key_table(c, table) || 1383 (c->flags & CLIENT_REPEAT)) { 1384 log_debug("trying in root table"); 1385 server_client_set_key_table(c, NULL); 1386 table = c->keytable; 1387 if (c->flags & CLIENT_REPEAT) 1388 first = table; 1389 c->flags &= ~CLIENT_REPEAT; 1390 server_status_client(c); 1391 goto table_changed; 1392 } 1393 1394 /* 1395 * No match in the root table either. If this wasn't the first table 1396 * tried, don't pass the key to the pane. 1397 */ 1398 if (first != table && (~flags & CLIENT_REPEAT)) { 1399 server_client_set_key_table(c, NULL); 1400 server_status_client(c); 1401 goto out; 1402 } 1403 1404 forward_key: 1405 if (c->flags & CLIENT_READONLY) 1406 goto out; 1407 if (wp != NULL) 1408 window_pane_key(wp, c, s, wl, key, m); 1409 1410 out: 1411 if (s != NULL && key != KEYC_FOCUS_OUT) 1412 server_client_update_latest(c); 1413 free(event); 1414 return (CMD_RETURN_NORMAL); 1415 } 1416 1417 /* Handle a key event. */ 1418 int 1419 server_client_handle_key(struct client *c, struct key_event *event) 1420 { 1421 struct session *s = c->session; 1422 struct cmdq_item *item; 1423 1424 /* Check the client is good to accept input. */ 1425 if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS)) 1426 return (0); 1427 1428 /* 1429 * Key presses in overlay mode and the command prompt are a special 1430 * case. The queue might be blocked so they need to be processed 1431 * immediately rather than queued. 1432 */ 1433 if (~c->flags & CLIENT_READONLY) { 1434 if (c->message_string != NULL) { 1435 if (c->message_ignore_keys) 1436 return (0); 1437 status_message_clear(c); 1438 } 1439 if (c->overlay_key != NULL) { 1440 switch (c->overlay_key(c, c->overlay_data, event)) { 1441 case 0: 1442 return (0); 1443 case 1: 1444 server_client_clear_overlay(c); 1445 return (0); 1446 } 1447 } 1448 server_client_clear_overlay(c); 1449 if (c->prompt_string != NULL) { 1450 if (status_prompt_key(c, event->key) == 0) 1451 return (0); 1452 } 1453 } 1454 1455 /* 1456 * Add the key to the queue so it happens after any commands queued by 1457 * previous keys. 1458 */ 1459 item = cmdq_get_callback(server_client_key_callback, event); 1460 cmdq_append(c, item); 1461 return (1); 1462 } 1463 1464 /* Client functions that need to happen every loop. */ 1465 void 1466 server_client_loop(void) 1467 { 1468 struct client *c; 1469 struct window *w; 1470 struct window_pane *wp; 1471 1472 /* Check for window resize. This is done before redrawing. */ 1473 RB_FOREACH(w, windows, &windows) 1474 server_client_check_window_resize(w); 1475 1476 /* Check clients. */ 1477 TAILQ_FOREACH(c, &clients, entry) { 1478 server_client_check_exit(c); 1479 if (c->session != NULL) { 1480 server_client_check_modes(c); 1481 server_client_check_redraw(c); 1482 server_client_reset_state(c); 1483 } 1484 } 1485 1486 /* 1487 * Any windows will have been redrawn as part of clients, so clear 1488 * their flags now. 1489 */ 1490 RB_FOREACH(w, windows, &windows) { 1491 TAILQ_FOREACH(wp, &w->panes, entry) { 1492 if (wp->fd != -1) { 1493 server_client_check_pane_resize(wp); 1494 server_client_check_pane_buffer(wp); 1495 } 1496 wp->flags &= ~PANE_REDRAW; 1497 } 1498 check_window_name(w); 1499 } 1500 } 1501 1502 /* Check if window needs to be resized. */ 1503 static void 1504 server_client_check_window_resize(struct window *w) 1505 { 1506 struct winlink *wl; 1507 1508 if (~w->flags & WINDOW_RESIZE) 1509 return; 1510 1511 TAILQ_FOREACH(wl, &w->winlinks, wentry) { 1512 if (wl->session->attached != 0 && wl->session->curw == wl) 1513 break; 1514 } 1515 if (wl == NULL) 1516 return; 1517 1518 log_debug("%s: resizing window @%u", __func__, w->id); 1519 resize_window(w, w->new_sx, w->new_sy, w->new_xpixel, w->new_ypixel); 1520 } 1521 1522 /* Resize timer event. */ 1523 static void 1524 server_client_resize_timer(__unused int fd, __unused short events, void *data) 1525 { 1526 struct window_pane *wp = data; 1527 1528 log_debug("%s: %%%u resize timer expired", __func__, wp->id); 1529 evtimer_del(&wp->resize_timer); 1530 } 1531 1532 /* Check if pane should be resized. */ 1533 static void 1534 server_client_check_pane_resize(struct window_pane *wp) 1535 { 1536 struct window_pane_resize *r; 1537 struct window_pane_resize *r1; 1538 struct window_pane_resize *first; 1539 struct window_pane_resize *last; 1540 struct timeval tv = { .tv_usec = 250000 }; 1541 1542 if (TAILQ_EMPTY(&wp->resize_queue)) 1543 return; 1544 1545 if (!event_initialized(&wp->resize_timer)) 1546 evtimer_set(&wp->resize_timer, server_client_resize_timer, wp); 1547 if (evtimer_pending(&wp->resize_timer, NULL)) 1548 return; 1549 1550 log_debug("%s: %%%u needs to be resized", __func__, wp->id); 1551 TAILQ_FOREACH(r, &wp->resize_queue, entry) { 1552 log_debug("queued resize: %ux%u -> %ux%u", r->osx, r->osy, 1553 r->sx, r->sy); 1554 } 1555 1556 /* 1557 * There are three cases that matter: 1558 * 1559 * - Only one resize. It can just be applied. 1560 * 1561 * - Multiple resizes and the ending size is different from the 1562 * starting size. We can discard all resizes except the most recent. 1563 * 1564 * - Multiple resizes and the ending size is the same as the starting 1565 * size. We must resize at least twice to force the application to 1566 * redraw. So apply the first and leave the last on the queue for 1567 * next time. 1568 */ 1569 first = TAILQ_FIRST(&wp->resize_queue); 1570 last = TAILQ_LAST(&wp->resize_queue, window_pane_resizes); 1571 if (first == last) { 1572 /* Only one resize. */ 1573 window_pane_send_resize(wp, first->sx, first->sy); 1574 TAILQ_REMOVE(&wp->resize_queue, first, entry); 1575 free(first); 1576 } else if (last->sx != first->osx || last->sy != first->osy) { 1577 /* Multiple resizes ending up with a different size. */ 1578 window_pane_send_resize(wp, last->sx, last->sy); 1579 TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1) { 1580 TAILQ_REMOVE(&wp->resize_queue, r, entry); 1581 free(r); 1582 } 1583 } else { 1584 /* 1585 * Multiple resizes ending up with the same size. There will 1586 * not be more than one to the same size in succession so we 1587 * can just use the last-but-one on the list and leave the last 1588 * for later. We reduce the time until the next check to avoid 1589 * a long delay between the resizes. 1590 */ 1591 r = TAILQ_PREV(last, window_pane_resizes, entry); 1592 window_pane_send_resize(wp, r->sx, r->sy); 1593 TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1) { 1594 if (r == last) 1595 break; 1596 TAILQ_REMOVE(&wp->resize_queue, r, entry); 1597 free(r); 1598 } 1599 tv.tv_usec = 10000; 1600 } 1601 evtimer_add(&wp->resize_timer, &tv); 1602 } 1603 1604 /* Check pane buffer size. */ 1605 static void 1606 server_client_check_pane_buffer(struct window_pane *wp) 1607 { 1608 struct evbuffer *evb = wp->event->input; 1609 size_t minimum; 1610 struct client *c; 1611 struct window_pane_offset *wpo; 1612 int off = 1, flag; 1613 u_int attached_clients = 0; 1614 size_t new_size; 1615 1616 /* 1617 * Work out the minimum used size. This is the most that can be removed 1618 * from the buffer. 1619 */ 1620 minimum = wp->offset.used; 1621 if (wp->pipe_fd != -1 && wp->pipe_offset.used < minimum) 1622 minimum = wp->pipe_offset.used; 1623 TAILQ_FOREACH(c, &clients, entry) { 1624 if (c->session == NULL) 1625 continue; 1626 attached_clients++; 1627 1628 if (~c->flags & CLIENT_CONTROL) { 1629 off = 0; 1630 continue; 1631 } 1632 wpo = control_pane_offset(c, wp, &flag); 1633 if (wpo == NULL) { 1634 off = 0; 1635 continue; 1636 } 1637 if (!flag) 1638 off = 0; 1639 1640 window_pane_get_new_data(wp, wpo, &new_size); 1641 log_debug("%s: %s has %zu bytes used and %zu left for %%%u", 1642 __func__, c->name, wpo->used - wp->base_offset, new_size, 1643 wp->id); 1644 if (wpo->used < minimum) 1645 minimum = wpo->used; 1646 } 1647 if (attached_clients == 0) 1648 off = 0; 1649 minimum -= wp->base_offset; 1650 if (minimum == 0) 1651 goto out; 1652 1653 /* Drain the buffer. */ 1654 log_debug("%s: %%%u has %zu minimum (of %zu) bytes used", __func__, 1655 wp->id, minimum, EVBUFFER_LENGTH(evb)); 1656 evbuffer_drain(evb, minimum); 1657 1658 /* 1659 * Adjust the base offset. If it would roll over, all the offsets into 1660 * the buffer need to be adjusted. 1661 */ 1662 if (wp->base_offset > SIZE_MAX - minimum) { 1663 log_debug("%s: %%%u base offset has wrapped", __func__, wp->id); 1664 wp->offset.used -= wp->base_offset; 1665 if (wp->pipe_fd != -1) 1666 wp->pipe_offset.used -= wp->base_offset; 1667 TAILQ_FOREACH(c, &clients, entry) { 1668 if (c->session == NULL || (~c->flags & CLIENT_CONTROL)) 1669 continue; 1670 wpo = control_pane_offset(c, wp, &flag); 1671 if (wpo != NULL && !flag) 1672 wpo->used -= wp->base_offset; 1673 } 1674 wp->base_offset = minimum; 1675 } else 1676 wp->base_offset += minimum; 1677 1678 out: 1679 /* 1680 * If there is data remaining, and there are no clients able to consume 1681 * it, do not read any more. This is true when there are attached 1682 * clients, all of which are control clients which are not able to 1683 * accept any more data. 1684 */ 1685 log_debug("%s: pane %%%u is %s", __func__, wp->id, off ? "off" : "on"); 1686 if (off) 1687 bufferevent_disable(wp->event, EV_READ); 1688 else 1689 bufferevent_enable(wp->event, EV_READ); 1690 } 1691 1692 /* 1693 * Update cursor position and mode settings. The scroll region and attributes 1694 * are cleared when idle (waiting for an event) as this is the most likely time 1695 * a user may interrupt tmux, for example with ~^Z in ssh(1). This is a 1696 * compromise between excessive resets and likelihood of an interrupt. 1697 * 1698 * tty_region/tty_reset/tty_update_mode already take care of not resetting 1699 * things that are already in their default state. 1700 */ 1701 static void 1702 server_client_reset_state(struct client *c) 1703 { 1704 struct tty *tty = &c->tty; 1705 struct window *w = c->session->curw->window; 1706 struct window_pane *wp = server_client_get_pane(c), *loop; 1707 struct screen *s = NULL; 1708 struct options *oo = c->session->options; 1709 int mode = 0, cursor, flags, n; 1710 u_int cx = 0, cy = 0, ox, oy, sx, sy; 1711 1712 if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) 1713 return; 1714 1715 /* Disable the block flag. */ 1716 flags = (tty->flags & TTY_BLOCK); 1717 tty->flags &= ~TTY_BLOCK; 1718 1719 /* Get mode from overlay if any, else from screen. */ 1720 if (c->overlay_draw != NULL) { 1721 if (c->overlay_mode != NULL) 1722 s = c->overlay_mode(c, c->overlay_data, &cx, &cy); 1723 } else 1724 s = wp->screen; 1725 if (s != NULL) 1726 mode = s->mode; 1727 if (log_get_level() != 0) { 1728 log_debug("%s: client %s mode %s", __func__, c->name, 1729 screen_mode_to_string(mode)); 1730 } 1731 1732 /* Reset region and margin. */ 1733 tty_region_off(tty); 1734 tty_margin_off(tty); 1735 1736 /* Move cursor to pane cursor and offset. */ 1737 if (c->prompt_string != NULL) { 1738 n = options_get_number(c->session->options, "status-position"); 1739 if (n == 0) 1740 cy = 0; 1741 else { 1742 n = status_line_size(c); 1743 if (n == 0) 1744 cy = tty->sy - 1; 1745 else 1746 cy = tty->sy - n; 1747 } 1748 cx = c->prompt_cursor; 1749 mode &= ~MODE_CURSOR; 1750 } else if (c->overlay_draw == NULL) { 1751 cursor = 0; 1752 tty_window_offset(tty, &ox, &oy, &sx, &sy); 1753 if (wp->xoff + s->cx >= ox && wp->xoff + s->cx <= ox + sx && 1754 wp->yoff + s->cy >= oy && wp->yoff + s->cy <= oy + sy) { 1755 cursor = 1; 1756 1757 cx = wp->xoff + s->cx - ox; 1758 cy = wp->yoff + s->cy - oy; 1759 1760 if (status_at_line(c) == 0) 1761 cy += status_line_size(c); 1762 } 1763 if (!cursor) 1764 mode &= ~MODE_CURSOR; 1765 } 1766 log_debug("%s: cursor to %u,%u", __func__, cx, cy); 1767 tty_cursor(tty, cx, cy); 1768 1769 /* 1770 * Set mouse mode if requested. To support dragging, always use button 1771 * mode. 1772 */ 1773 if (options_get_number(oo, "mouse")) { 1774 if (c->overlay_draw == NULL) { 1775 mode &= ~ALL_MOUSE_MODES; 1776 TAILQ_FOREACH(loop, &w->panes, entry) { 1777 if (loop->screen->mode & MODE_MOUSE_ALL) 1778 mode |= MODE_MOUSE_ALL; 1779 } 1780 } 1781 if (~mode & MODE_MOUSE_ALL) 1782 mode |= MODE_MOUSE_BUTTON; 1783 } 1784 1785 /* Clear bracketed paste mode if at the prompt. */ 1786 if (c->overlay_draw == NULL && c->prompt_string != NULL) 1787 mode &= ~MODE_BRACKETPASTE; 1788 1789 /* Set the terminal mode and reset attributes. */ 1790 tty_update_mode(tty, mode, s); 1791 tty_reset(tty); 1792 1793 /* All writing must be done, send a sync end (if it was started). */ 1794 tty_sync_end(tty); 1795 tty->flags |= flags; 1796 } 1797 1798 /* Repeat time callback. */ 1799 static void 1800 server_client_repeat_timer(__unused int fd, __unused short events, void *data) 1801 { 1802 struct client *c = data; 1803 1804 if (c->flags & CLIENT_REPEAT) { 1805 server_client_set_key_table(c, NULL); 1806 c->flags &= ~CLIENT_REPEAT; 1807 server_status_client(c); 1808 } 1809 } 1810 1811 /* Double-click callback. */ 1812 static void 1813 server_client_click_timer(__unused int fd, __unused short events, void *data) 1814 { 1815 struct client *c = data; 1816 struct key_event *event; 1817 1818 log_debug("click timer expired"); 1819 1820 if (c->flags & CLIENT_TRIPLECLICK) { 1821 /* 1822 * Waiting for a third click that hasn't happened, so this must 1823 * have been a double click. 1824 */ 1825 event = xmalloc(sizeof *event); 1826 event->key = KEYC_DOUBLECLICK; 1827 memcpy(&event->m, &c->click_event, sizeof event->m); 1828 if (!server_client_handle_key(c, event)) 1829 free(event); 1830 } 1831 c->flags &= ~(CLIENT_DOUBLECLICK|CLIENT_TRIPLECLICK); 1832 } 1833 1834 /* Check if client should be exited. */ 1835 static void 1836 server_client_check_exit(struct client *c) 1837 { 1838 struct client_file *cf; 1839 const char *name = c->exit_session; 1840 char *data; 1841 size_t size, msize; 1842 1843 if (c->flags & (CLIENT_DEAD|CLIENT_EXITED)) 1844 return; 1845 if (~c->flags & CLIENT_EXIT) 1846 return; 1847 1848 if (c->flags & CLIENT_CONTROL) { 1849 control_discard(c); 1850 if (!control_all_done(c)) 1851 return; 1852 } 1853 RB_FOREACH(cf, client_files, &c->files) { 1854 if (EVBUFFER_LENGTH(cf->buffer) != 0) 1855 return; 1856 } 1857 c->flags |= CLIENT_EXITED; 1858 1859 switch (c->exit_type) { 1860 case CLIENT_EXIT_RETURN: 1861 if (c->exit_message != NULL) 1862 msize = strlen(c->exit_message) + 1; 1863 else 1864 msize = 0; 1865 size = (sizeof c->retval) + msize; 1866 data = xmalloc(size); 1867 memcpy(data, &c->retval, sizeof c->retval); 1868 if (c->exit_message != NULL) 1869 memcpy(data + sizeof c->retval, c->exit_message, msize); 1870 proc_send(c->peer, MSG_EXIT, -1, data, size); 1871 free(data); 1872 break; 1873 case CLIENT_EXIT_SHUTDOWN: 1874 proc_send(c->peer, MSG_SHUTDOWN, -1, NULL, 0); 1875 break; 1876 case CLIENT_EXIT_DETACH: 1877 proc_send(c->peer, c->exit_msgtype, -1, name, strlen(name) + 1); 1878 break; 1879 } 1880 free(c->exit_session); 1881 free(c->exit_message); 1882 } 1883 1884 /* Redraw timer callback. */ 1885 static void 1886 server_client_redraw_timer(__unused int fd, __unused short events, 1887 __unused void *data) 1888 { 1889 log_debug("redraw timer fired"); 1890 } 1891 1892 /* 1893 * Check if modes need to be updated. Only modes in the current window are 1894 * updated and it is done when the status line is redrawn. 1895 */ 1896 static void 1897 server_client_check_modes(struct client *c) 1898 { 1899 struct window *w = c->session->curw->window; 1900 struct window_pane *wp; 1901 struct window_mode_entry *wme; 1902 1903 if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) 1904 return; 1905 if (~c->flags & CLIENT_REDRAWSTATUS) 1906 return; 1907 TAILQ_FOREACH(wp, &w->panes, entry) { 1908 wme = TAILQ_FIRST(&wp->modes); 1909 if (wme != NULL && wme->mode->update != NULL) 1910 wme->mode->update(wme); 1911 } 1912 } 1913 1914 /* Check for client redraws. */ 1915 static void 1916 server_client_check_redraw(struct client *c) 1917 { 1918 struct session *s = c->session; 1919 struct tty *tty = &c->tty; 1920 struct window *w = c->session->curw->window; 1921 struct window_pane *wp; 1922 int needed, flags, mode = tty->mode, new_flags = 0; 1923 int redraw; 1924 u_int bit = 0; 1925 struct timeval tv = { .tv_usec = 1000 }; 1926 static struct event ev; 1927 size_t left; 1928 1929 if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) 1930 return; 1931 if (c->flags & CLIENT_ALLREDRAWFLAGS) { 1932 log_debug("%s: redraw%s%s%s%s%s", c->name, 1933 (c->flags & CLIENT_REDRAWWINDOW) ? " window" : "", 1934 (c->flags & CLIENT_REDRAWSTATUS) ? " status" : "", 1935 (c->flags & CLIENT_REDRAWBORDERS) ? " borders" : "", 1936 (c->flags & CLIENT_REDRAWOVERLAY) ? " overlay" : "", 1937 (c->flags & CLIENT_REDRAWPANES) ? " panes" : ""); 1938 } 1939 1940 /* 1941 * If there is outstanding data, defer the redraw until it has been 1942 * consumed. We can just add a timer to get out of the event loop and 1943 * end up back here. 1944 */ 1945 needed = 0; 1946 if (c->flags & CLIENT_ALLREDRAWFLAGS) 1947 needed = 1; 1948 else { 1949 TAILQ_FOREACH(wp, &w->panes, entry) { 1950 if (wp->flags & PANE_REDRAW) { 1951 needed = 1; 1952 break; 1953 } 1954 } 1955 if (needed) 1956 new_flags |= CLIENT_REDRAWPANES; 1957 } 1958 if (needed && (left = EVBUFFER_LENGTH(tty->out)) != 0) { 1959 log_debug("%s: redraw deferred (%zu left)", c->name, left); 1960 if (!evtimer_initialized(&ev)) 1961 evtimer_set(&ev, server_client_redraw_timer, NULL); 1962 if (!evtimer_pending(&ev, NULL)) { 1963 log_debug("redraw timer started"); 1964 evtimer_add(&ev, &tv); 1965 } 1966 1967 if (~c->flags & CLIENT_REDRAWWINDOW) { 1968 TAILQ_FOREACH(wp, &w->panes, entry) { 1969 if (wp->flags & PANE_REDRAW) { 1970 log_debug("%s: pane %%%u needs redraw", 1971 c->name, wp->id); 1972 c->redraw_panes |= (1 << bit); 1973 } 1974 if (++bit == 64) { 1975 /* 1976 * If more that 64 panes, give up and 1977 * just redraw the window. 1978 */ 1979 new_flags &= CLIENT_REDRAWPANES; 1980 new_flags |= CLIENT_REDRAWWINDOW; 1981 break; 1982 } 1983 } 1984 if (c->redraw_panes != 0) 1985 c->flags |= CLIENT_REDRAWPANES; 1986 } 1987 c->flags |= new_flags; 1988 return; 1989 } else if (needed) 1990 log_debug("%s: redraw needed", c->name); 1991 1992 flags = tty->flags & (TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR); 1993 tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE))|TTY_NOCURSOR; 1994 1995 if (~c->flags & CLIENT_REDRAWWINDOW) { 1996 /* 1997 * If not redrawing the entire window, check whether each pane 1998 * needs to be redrawn. 1999 */ 2000 TAILQ_FOREACH(wp, &w->panes, entry) { 2001 redraw = 0; 2002 if (wp->flags & PANE_REDRAW) 2003 redraw = 1; 2004 else if (c->flags & CLIENT_REDRAWPANES) 2005 redraw = !!(c->redraw_panes & (1 << bit)); 2006 bit++; 2007 if (!redraw) 2008 continue; 2009 log_debug("%s: redrawing pane %%%u", __func__, wp->id); 2010 screen_redraw_pane(c, wp); 2011 } 2012 c->redraw_panes = 0; 2013 c->flags &= ~CLIENT_REDRAWPANES; 2014 } 2015 2016 if (c->flags & CLIENT_ALLREDRAWFLAGS) { 2017 if (options_get_number(s->options, "set-titles")) 2018 server_client_set_title(c); 2019 screen_redraw_screen(c); 2020 } 2021 2022 tty->flags = (tty->flags & ~TTY_NOCURSOR)|(flags & TTY_NOCURSOR); 2023 tty_update_mode(tty, mode, NULL); 2024 tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR))|flags; 2025 2026 c->flags &= ~(CLIENT_ALLREDRAWFLAGS|CLIENT_STATUSFORCE); 2027 2028 if (needed) { 2029 /* 2030 * We would have deferred the redraw unless the output buffer 2031 * was empty, so we can record how many bytes the redraw 2032 * generated. 2033 */ 2034 c->redraw = EVBUFFER_LENGTH(tty->out); 2035 log_debug("%s: redraw added %zu bytes", c->name, c->redraw); 2036 } 2037 } 2038 2039 /* Set client title. */ 2040 static void 2041 server_client_set_title(struct client *c) 2042 { 2043 struct session *s = c->session; 2044 const char *template; 2045 char *title; 2046 struct format_tree *ft; 2047 2048 template = options_get_string(s->options, "set-titles-string"); 2049 2050 ft = format_create(c, NULL, FORMAT_NONE, 0); 2051 format_defaults(ft, c, NULL, NULL, NULL); 2052 2053 title = format_expand_time(ft, template); 2054 if (c->title == NULL || strcmp(title, c->title) != 0) { 2055 free(c->title); 2056 c->title = xstrdup(title); 2057 tty_set_title(&c->tty, c->title); 2058 } 2059 free(title); 2060 2061 format_free(ft); 2062 } 2063 2064 /* Dispatch message from client. */ 2065 static void 2066 server_client_dispatch(struct imsg *imsg, void *arg) 2067 { 2068 struct client *c = arg; 2069 ssize_t datalen; 2070 struct session *s; 2071 2072 if (c->flags & CLIENT_DEAD) 2073 return; 2074 2075 if (imsg == NULL) { 2076 server_client_lost(c); 2077 return; 2078 } 2079 2080 datalen = imsg->hdr.len - IMSG_HEADER_SIZE; 2081 2082 switch (imsg->hdr.type) { 2083 case MSG_IDENTIFY_CLIENTPID: 2084 case MSG_IDENTIFY_CWD: 2085 case MSG_IDENTIFY_ENVIRON: 2086 case MSG_IDENTIFY_FEATURES: 2087 case MSG_IDENTIFY_FLAGS: 2088 case MSG_IDENTIFY_LONGFLAGS: 2089 case MSG_IDENTIFY_STDIN: 2090 case MSG_IDENTIFY_STDOUT: 2091 case MSG_IDENTIFY_TERM: 2092 case MSG_IDENTIFY_TERMINFO: 2093 case MSG_IDENTIFY_TTYNAME: 2094 case MSG_IDENTIFY_DONE: 2095 server_client_dispatch_identify(c, imsg); 2096 break; 2097 case MSG_COMMAND: 2098 server_client_dispatch_command(c, imsg); 2099 break; 2100 case MSG_RESIZE: 2101 if (datalen != 0) 2102 fatalx("bad MSG_RESIZE size"); 2103 2104 if (c->flags & CLIENT_CONTROL) 2105 break; 2106 server_client_update_latest(c); 2107 tty_resize(&c->tty); 2108 recalculate_sizes(); 2109 if (c->overlay_resize == NULL) 2110 server_client_clear_overlay(c); 2111 else 2112 c->overlay_resize(c, c->overlay_data); 2113 server_redraw_client(c); 2114 if (c->session != NULL) 2115 notify_client("client-resized", c); 2116 break; 2117 case MSG_EXITING: 2118 if (datalen != 0) 2119 fatalx("bad MSG_EXITING size"); 2120 server_client_set_session(c, NULL); 2121 recalculate_sizes(); 2122 tty_close(&c->tty); 2123 proc_send(c->peer, MSG_EXITED, -1, NULL, 0); 2124 break; 2125 case MSG_WAKEUP: 2126 case MSG_UNLOCK: 2127 if (datalen != 0) 2128 fatalx("bad MSG_WAKEUP size"); 2129 2130 if (!(c->flags & CLIENT_SUSPENDED)) 2131 break; 2132 c->flags &= ~CLIENT_SUSPENDED; 2133 2134 if (c->fd == -1 || c->session == NULL) /* exited already */ 2135 break; 2136 s = c->session; 2137 2138 if (gettimeofday(&c->activity_time, NULL) != 0) 2139 fatal("gettimeofday failed"); 2140 2141 tty_start_tty(&c->tty); 2142 server_redraw_client(c); 2143 recalculate_sizes(); 2144 2145 if (s != NULL) 2146 session_update_activity(s, &c->activity_time); 2147 break; 2148 case MSG_SHELL: 2149 if (datalen != 0) 2150 fatalx("bad MSG_SHELL size"); 2151 2152 server_client_dispatch_shell(c); 2153 break; 2154 case MSG_WRITE_READY: 2155 file_write_ready(&c->files, imsg); 2156 break; 2157 case MSG_READ: 2158 file_read_data(&c->files, imsg); 2159 break; 2160 case MSG_READ_DONE: 2161 file_read_done(&c->files, imsg); 2162 break; 2163 } 2164 } 2165 2166 /* Callback when command is done. */ 2167 static enum cmd_retval 2168 server_client_command_done(struct cmdq_item *item, __unused void *data) 2169 { 2170 struct client *c = cmdq_get_client(item); 2171 2172 if (~c->flags & CLIENT_ATTACHED) 2173 c->flags |= CLIENT_EXIT; 2174 else if (~c->flags & CLIENT_EXIT) 2175 tty_send_requests(&c->tty); 2176 return (CMD_RETURN_NORMAL); 2177 } 2178 2179 /* Handle command message. */ 2180 static void 2181 server_client_dispatch_command(struct client *c, struct imsg *imsg) 2182 { 2183 struct msg_command data; 2184 char *buf; 2185 size_t len; 2186 int argc; 2187 char **argv, *cause; 2188 struct cmd_parse_result *pr; 2189 struct args_value *values; 2190 2191 if (c->flags & CLIENT_EXIT) 2192 return; 2193 2194 if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data) 2195 fatalx("bad MSG_COMMAND size"); 2196 memcpy(&data, imsg->data, sizeof data); 2197 2198 buf = (char *)imsg->data + sizeof data; 2199 len = imsg->hdr.len - IMSG_HEADER_SIZE - sizeof data; 2200 if (len > 0 && buf[len - 1] != '\0') 2201 fatalx("bad MSG_COMMAND string"); 2202 2203 argc = data.argc; 2204 if (cmd_unpack_argv(buf, len, argc, &argv) != 0) { 2205 cause = xstrdup("command too long"); 2206 goto error; 2207 } 2208 2209 if (argc == 0) { 2210 argc = 1; 2211 argv = xcalloc(1, sizeof *argv); 2212 *argv = xstrdup("new-session"); 2213 } 2214 2215 values = args_from_vector(argc, argv); 2216 pr = cmd_parse_from_arguments(values, argc, NULL); 2217 switch (pr->status) { 2218 case CMD_PARSE_ERROR: 2219 cause = pr->error; 2220 goto error; 2221 case CMD_PARSE_SUCCESS: 2222 break; 2223 } 2224 args_free_values(values, argc); 2225 free(values); 2226 cmd_free_argv(argc, argv); 2227 2228 cmdq_append(c, cmdq_get_command(pr->cmdlist, NULL)); 2229 cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL)); 2230 2231 cmd_list_free(pr->cmdlist); 2232 return; 2233 2234 error: 2235 cmd_free_argv(argc, argv); 2236 2237 cmdq_append(c, cmdq_get_error(cause)); 2238 free(cause); 2239 2240 c->flags |= CLIENT_EXIT; 2241 } 2242 2243 /* Handle identify message. */ 2244 static void 2245 server_client_dispatch_identify(struct client *c, struct imsg *imsg) 2246 { 2247 const char *data, *home; 2248 size_t datalen; 2249 int flags, feat; 2250 uint64_t longflags; 2251 char *name; 2252 2253 if (c->flags & CLIENT_IDENTIFIED) 2254 fatalx("out-of-order identify message"); 2255 2256 data = imsg->data; 2257 datalen = imsg->hdr.len - IMSG_HEADER_SIZE; 2258 2259 switch (imsg->hdr.type) { 2260 case MSG_IDENTIFY_FEATURES: 2261 if (datalen != sizeof feat) 2262 fatalx("bad MSG_IDENTIFY_FEATURES size"); 2263 memcpy(&feat, data, sizeof feat); 2264 c->term_features |= feat; 2265 log_debug("client %p IDENTIFY_FEATURES %s", c, 2266 tty_get_features(feat)); 2267 break; 2268 case MSG_IDENTIFY_FLAGS: 2269 if (datalen != sizeof flags) 2270 fatalx("bad MSG_IDENTIFY_FLAGS size"); 2271 memcpy(&flags, data, sizeof flags); 2272 c->flags |= flags; 2273 log_debug("client %p IDENTIFY_FLAGS %#x", c, flags); 2274 break; 2275 case MSG_IDENTIFY_LONGFLAGS: 2276 if (datalen != sizeof longflags) 2277 fatalx("bad MSG_IDENTIFY_LONGFLAGS size"); 2278 memcpy(&longflags, data, sizeof longflags); 2279 c->flags |= longflags; 2280 log_debug("client %p IDENTIFY_LONGFLAGS %#llx", c, 2281 (unsigned long long)longflags); 2282 break; 2283 case MSG_IDENTIFY_TERM: 2284 if (datalen == 0 || data[datalen - 1] != '\0') 2285 fatalx("bad MSG_IDENTIFY_TERM string"); 2286 if (*data == '\0') 2287 c->term_name = xstrdup("unknown"); 2288 else 2289 c->term_name = xstrdup(data); 2290 log_debug("client %p IDENTIFY_TERM %s", c, data); 2291 break; 2292 case MSG_IDENTIFY_TERMINFO: 2293 if (datalen == 0 || data[datalen - 1] != '\0') 2294 fatalx("bad MSG_IDENTIFY_TERMINFO string"); 2295 c->term_caps = xreallocarray(c->term_caps, c->term_ncaps + 1, 2296 sizeof *c->term_caps); 2297 c->term_caps[c->term_ncaps++] = xstrdup(data); 2298 log_debug("client %p IDENTIFY_TERMINFO %s", c, data); 2299 break; 2300 case MSG_IDENTIFY_TTYNAME: 2301 if (datalen == 0 || data[datalen - 1] != '\0') 2302 fatalx("bad MSG_IDENTIFY_TTYNAME string"); 2303 c->ttyname = xstrdup(data); 2304 log_debug("client %p IDENTIFY_TTYNAME %s", c, data); 2305 break; 2306 case MSG_IDENTIFY_CWD: 2307 if (datalen == 0 || data[datalen - 1] != '\0') 2308 fatalx("bad MSG_IDENTIFY_CWD string"); 2309 if (access(data, X_OK) == 0) 2310 c->cwd = xstrdup(data); 2311 else if ((home = find_home()) != NULL) 2312 c->cwd = xstrdup(home); 2313 else 2314 c->cwd = xstrdup("/"); 2315 log_debug("client %p IDENTIFY_CWD %s", c, data); 2316 break; 2317 case MSG_IDENTIFY_STDIN: 2318 if (datalen != 0) 2319 fatalx("bad MSG_IDENTIFY_STDIN size"); 2320 c->fd = imsg->fd; 2321 log_debug("client %p IDENTIFY_STDIN %d", c, imsg->fd); 2322 break; 2323 case MSG_IDENTIFY_STDOUT: 2324 if (datalen != 0) 2325 fatalx("bad MSG_IDENTIFY_STDOUT size"); 2326 c->out_fd = imsg->fd; 2327 log_debug("client %p IDENTIFY_STDOUT %d", c, imsg->fd); 2328 break; 2329 case MSG_IDENTIFY_ENVIRON: 2330 if (datalen == 0 || data[datalen - 1] != '\0') 2331 fatalx("bad MSG_IDENTIFY_ENVIRON string"); 2332 if (strchr(data, '=') != NULL) 2333 environ_put(c->environ, data, 0); 2334 log_debug("client %p IDENTIFY_ENVIRON %s", c, data); 2335 break; 2336 case MSG_IDENTIFY_CLIENTPID: 2337 if (datalen != sizeof c->pid) 2338 fatalx("bad MSG_IDENTIFY_CLIENTPID size"); 2339 memcpy(&c->pid, data, sizeof c->pid); 2340 log_debug("client %p IDENTIFY_CLIENTPID %ld", c, (long)c->pid); 2341 break; 2342 default: 2343 break; 2344 } 2345 2346 if (imsg->hdr.type != MSG_IDENTIFY_DONE) 2347 return; 2348 c->flags |= CLIENT_IDENTIFIED; 2349 2350 if (*c->ttyname != '\0') 2351 name = xstrdup(c->ttyname); 2352 else 2353 xasprintf(&name, "client-%ld", (long)c->pid); 2354 c->name = name; 2355 log_debug("client %p name is %s", c, c->name); 2356 2357 if (c->flags & CLIENT_CONTROL) 2358 control_start(c); 2359 else if (c->fd != -1) { 2360 if (tty_init(&c->tty, c) != 0) { 2361 close(c->fd); 2362 c->fd = -1; 2363 } else { 2364 tty_resize(&c->tty); 2365 c->flags |= CLIENT_TERMINAL; 2366 } 2367 close(c->out_fd); 2368 c->out_fd = -1; 2369 } 2370 2371 /* 2372 * If this is the first client, load configuration files. Any later 2373 * clients are allowed to continue with their command even if the 2374 * config has not been loaded - they might have been run from inside it 2375 */ 2376 if ((~c->flags & CLIENT_EXIT) && 2377 !cfg_finished && 2378 c == TAILQ_FIRST(&clients)) 2379 start_cfg(); 2380 } 2381 2382 /* Handle shell message. */ 2383 static void 2384 server_client_dispatch_shell(struct client *c) 2385 { 2386 const char *shell; 2387 2388 shell = options_get_string(global_s_options, "default-shell"); 2389 if (!checkshell(shell)) 2390 shell = _PATH_BSHELL; 2391 proc_send(c->peer, MSG_SHELL, -1, shell, strlen(shell) + 1); 2392 2393 proc_kill_peer(c->peer); 2394 } 2395 2396 /* Get client working directory. */ 2397 const char * 2398 server_client_get_cwd(struct client *c, struct session *s) 2399 { 2400 const char *home; 2401 2402 if (!cfg_finished && cfg_client != NULL) 2403 return (cfg_client->cwd); 2404 if (c != NULL && c->session == NULL && c->cwd != NULL) 2405 return (c->cwd); 2406 if (s != NULL && s->cwd != NULL) 2407 return (s->cwd); 2408 if (c != NULL && (s = c->session) != NULL && s->cwd != NULL) 2409 return (s->cwd); 2410 if ((home = find_home()) != NULL) 2411 return (home); 2412 return ("/"); 2413 } 2414 2415 /* Get control client flags. */ 2416 static uint64_t 2417 server_client_control_flags(struct client *c, const char *next) 2418 { 2419 if (strcmp(next, "pause-after") == 0) { 2420 c->pause_age = 0; 2421 return (CLIENT_CONTROL_PAUSEAFTER); 2422 } 2423 if (sscanf(next, "pause-after=%u", &c->pause_age) == 1) { 2424 c->pause_age *= 1000; 2425 return (CLIENT_CONTROL_PAUSEAFTER); 2426 } 2427 if (strcmp(next, "no-output") == 0) 2428 return (CLIENT_CONTROL_NOOUTPUT); 2429 if (strcmp(next, "wait-exit") == 0) 2430 return (CLIENT_CONTROL_WAITEXIT); 2431 return (0); 2432 } 2433 2434 /* Set client flags. */ 2435 void 2436 server_client_set_flags(struct client *c, const char *flags) 2437 { 2438 char *s, *copy, *next; 2439 uint64_t flag; 2440 int not; 2441 2442 s = copy = xstrdup(flags); 2443 while ((next = strsep(&s, ",")) != NULL) { 2444 not = (*next == '!'); 2445 if (not) 2446 next++; 2447 2448 if (c->flags & CLIENT_CONTROL) 2449 flag = server_client_control_flags(c, next); 2450 else 2451 flag = 0; 2452 if (strcmp(next, "read-only") == 0) 2453 flag = CLIENT_READONLY; 2454 else if (strcmp(next, "ignore-size") == 0) 2455 flag = CLIENT_IGNORESIZE; 2456 else if (strcmp(next, "active-pane") == 0) 2457 flag = CLIENT_ACTIVEPANE; 2458 if (flag == 0) 2459 continue; 2460 2461 log_debug("client %s set flag %s", c->name, next); 2462 if (not) 2463 c->flags &= ~flag; 2464 else 2465 c->flags |= flag; 2466 if (flag == CLIENT_CONTROL_NOOUTPUT) 2467 control_reset_offsets(c); 2468 } 2469 free(copy); 2470 proc_send(c->peer, MSG_FLAGS, -1, &c->flags, sizeof c->flags); 2471 } 2472 2473 /* Get client flags. This is only flags useful to show to users. */ 2474 const char * 2475 server_client_get_flags(struct client *c) 2476 { 2477 static char s[256]; 2478 char tmp[32]; 2479 2480 *s = '\0'; 2481 if (c->flags & CLIENT_ATTACHED) 2482 strlcat(s, "attached,", sizeof s); 2483 if (c->flags & CLIENT_FOCUSED) 2484 strlcat(s, "focused,", sizeof s); 2485 if (c->flags & CLIENT_CONTROL) 2486 strlcat(s, "control-mode,", sizeof s); 2487 if (c->flags & CLIENT_IGNORESIZE) 2488 strlcat(s, "ignore-size,", sizeof s); 2489 if (c->flags & CLIENT_CONTROL_NOOUTPUT) 2490 strlcat(s, "no-output,", sizeof s); 2491 if (c->flags & CLIENT_CONTROL_WAITEXIT) 2492 strlcat(s, "wait-exit,", sizeof s); 2493 if (c->flags & CLIENT_CONTROL_PAUSEAFTER) { 2494 xsnprintf(tmp, sizeof tmp, "pause-after=%u,", 2495 c->pause_age / 1000); 2496 strlcat(s, tmp, sizeof s); 2497 } 2498 if (c->flags & CLIENT_READONLY) 2499 strlcat(s, "read-only,", sizeof s); 2500 if (c->flags & CLIENT_ACTIVEPANE) 2501 strlcat(s, "active-pane,", sizeof s); 2502 if (c->flags & CLIENT_SUSPENDED) 2503 strlcat(s, "suspended,", sizeof s); 2504 if (c->flags & CLIENT_UTF8) 2505 strlcat(s, "UTF-8,", sizeof s); 2506 if (*s != '\0') 2507 s[strlen(s) - 1] = '\0'; 2508 return (s); 2509 } 2510 2511 /* Get client window. */ 2512 struct client_window * 2513 server_client_get_client_window(struct client *c, u_int id) 2514 { 2515 struct client_window cw = { .window = id }; 2516 2517 return (RB_FIND(client_windows, &c->windows, &cw)); 2518 } 2519 2520 /* Add client window. */ 2521 struct client_window * 2522 server_client_add_client_window(struct client *c, u_int id) 2523 { 2524 struct client_window *cw; 2525 2526 cw = server_client_get_client_window(c, id); 2527 if (cw == NULL) { 2528 cw = xcalloc(1, sizeof *cw); 2529 cw->window = id; 2530 RB_INSERT(client_windows, &c->windows, cw); 2531 } 2532 return cw; 2533 } 2534 2535 /* Get client active pane. */ 2536 struct window_pane * 2537 server_client_get_pane(struct client *c) 2538 { 2539 struct session *s = c->session; 2540 struct client_window *cw; 2541 2542 if (s == NULL) 2543 return (NULL); 2544 2545 if (~c->flags & CLIENT_ACTIVEPANE) 2546 return (s->curw->window->active); 2547 cw = server_client_get_client_window(c, s->curw->window->id); 2548 if (cw == NULL) 2549 return (s->curw->window->active); 2550 return (cw->pane); 2551 } 2552 2553 /* Set client active pane. */ 2554 void 2555 server_client_set_pane(struct client *c, struct window_pane *wp) 2556 { 2557 struct session *s = c->session; 2558 struct client_window *cw; 2559 2560 if (s == NULL) 2561 return; 2562 2563 cw = server_client_add_client_window(c, s->curw->window->id); 2564 cw->pane = wp; 2565 log_debug("%s pane now %%%u", c->name, wp->id); 2566 } 2567 2568 /* Remove pane from client lists. */ 2569 void 2570 server_client_remove_pane(struct window_pane *wp) 2571 { 2572 struct client *c; 2573 struct window *w = wp->window; 2574 struct client_window *cw; 2575 2576 TAILQ_FOREACH(c, &clients, entry) { 2577 cw = server_client_get_client_window(c, w->id); 2578 if (cw != NULL && cw->pane == wp) { 2579 RB_REMOVE(client_windows, &c->windows, cw); 2580 free(cw); 2581 } 2582 } 2583 } 2584