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