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