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