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