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