1 /* $OpenBSD$ */ 2 3 /* 4 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott (at) 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 21 #include <netinet/in.h> 22 23 #include <ctype.h> 24 #include <resolv.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <time.h> 28 29 #include "tmux.h" 30 31 /* 32 * Based on the description by Paul Williams at: 33 * 34 * https://vt100.net/emu/dec_ansi_parser 35 * 36 * With the following changes: 37 * 38 * - 7-bit only. 39 * 40 * - Support for UTF-8. 41 * 42 * - OSC (but not APC) may be terminated by \007 as well as ST. 43 * 44 * - A state for APC similar to OSC. Some terminals appear to use this to set 45 * the title. 46 * 47 * - A state for the screen \033k...\033\\ sequence to rename a window. This is 48 * pretty stupid but not supporting it is more trouble than it is worth. 49 * 50 * - Special handling for ESC inside a DCS to allow arbitrary byte sequences to 51 * be passed to the underlying terminals. 52 */ 53 54 /* Type of terminator. */ 55 enum input_end_type { 56 INPUT_END_ST, 57 INPUT_END_BEL 58 }; 59 60 /* Request sent by a pane. */ 61 struct input_request { 62 struct client *c; 63 struct input_ctx *ictx; 64 65 enum input_request_type type; 66 time_t t; 67 enum input_end_type end; 68 69 int idx; 70 void *data; 71 72 TAILQ_ENTRY(input_request) entry; 73 TAILQ_ENTRY(input_request) centry; 74 }; 75 #define INPUT_REQUEST_TIMEOUT 2 76 77 /* Input parser cell. */ 78 struct input_cell { 79 struct grid_cell cell; 80 int set; 81 int g0set; /* 1 if ACS */ 82 int g1set; /* 1 if ACS */ 83 }; 84 85 /* Input parser argument. */ 86 struct input_param { 87 enum { 88 INPUT_MISSING, 89 INPUT_NUMBER, 90 INPUT_STRING 91 } type; 92 union { 93 int num; 94 char *str; 95 }; 96 }; 97 98 /* Input parser context. */ 99 struct input_ctx { 100 struct window_pane *wp; 101 struct bufferevent *event; 102 struct screen_write_ctx ctx; 103 struct colour_palette *palette; 104 105 struct input_cell cell; 106 struct input_cell old_cell; 107 u_int old_cx; 108 u_int old_cy; 109 int old_mode; 110 111 u_char interm_buf[4]; 112 size_t interm_len; 113 114 u_char param_buf[64]; 115 size_t param_len; 116 117 #define INPUT_BUF_START 32 118 u_char *input_buf; 119 size_t input_len; 120 size_t input_space; 121 enum input_end_type input_end; 122 123 struct input_param param_list[24]; 124 u_int param_list_len; 125 126 struct utf8_data utf8data; 127 int utf8started; 128 129 int ch; 130 struct utf8_data last; 131 132 const struct input_state *state; 133 int flags; 134 #define INPUT_DISCARD 0x1 135 #define INPUT_LAST 0x2 136 137 struct input_requests requests; 138 u_int request_count; 139 struct event request_timer; 140 141 /* 142 * All input received since we were last in the ground state. Sent to 143 * control clients on connection. 144 */ 145 struct evbuffer *since_ground; 146 struct event ground_timer; 147 }; 148 149 /* Helper functions. */ 150 struct input_transition; 151 static void input_request_timer_callback(int, short, void *); 152 static void input_start_request_timer(struct input_ctx *); 153 static struct input_request *input_make_request(struct input_ctx *, 154 enum input_request_type); 155 static void input_free_request(struct input_request *); 156 static int input_add_request(struct input_ctx *, enum input_request_type, 157 int); 158 static int input_split(struct input_ctx *); 159 static int input_get(struct input_ctx *, u_int, int, int); 160 static void input_set_state(struct input_ctx *, 161 const struct input_transition *); 162 static void input_reset_cell(struct input_ctx *); 163 static void input_report_current_theme(struct input_ctx *); 164 static void input_osc_4(struct input_ctx *, const char *); 165 static void input_osc_8(struct input_ctx *, const char *); 166 static void input_osc_10(struct input_ctx *, const char *); 167 static void input_osc_11(struct input_ctx *, const char *); 168 static void input_osc_12(struct input_ctx *, const char *); 169 static void input_osc_52(struct input_ctx *, const char *); 170 static void input_osc_104(struct input_ctx *, const char *); 171 static void input_osc_110(struct input_ctx *, const char *); 172 static void input_osc_111(struct input_ctx *, const char *); 173 static void input_osc_112(struct input_ctx *, const char *); 174 static void input_osc_133(struct input_ctx *, const char *); 175 176 /* Transition entry/exit handlers. */ 177 static void input_clear(struct input_ctx *); 178 static void input_ground(struct input_ctx *); 179 static void input_enter_dcs(struct input_ctx *); 180 static void input_enter_osc(struct input_ctx *); 181 static void input_exit_osc(struct input_ctx *); 182 static void input_enter_apc(struct input_ctx *); 183 static void input_exit_apc(struct input_ctx *); 184 static void input_enter_rename(struct input_ctx *); 185 static void input_exit_rename(struct input_ctx *); 186 187 /* Input state handlers. */ 188 static int input_print(struct input_ctx *); 189 static int input_intermediate(struct input_ctx *); 190 static int input_parameter(struct input_ctx *); 191 static int input_input(struct input_ctx *); 192 static int input_c0_dispatch(struct input_ctx *); 193 static int input_esc_dispatch(struct input_ctx *); 194 static int input_csi_dispatch(struct input_ctx *); 195 static void input_csi_dispatch_rm(struct input_ctx *); 196 static void input_csi_dispatch_rm_private(struct input_ctx *); 197 static void input_csi_dispatch_sm(struct input_ctx *); 198 static void input_csi_dispatch_sm_private(struct input_ctx *); 199 static void input_csi_dispatch_sm_graphics(struct input_ctx *); 200 static void input_csi_dispatch_winops(struct input_ctx *); 201 static void input_csi_dispatch_sgr_256(struct input_ctx *, int, u_int *); 202 static void input_csi_dispatch_sgr_rgb(struct input_ctx *, int, u_int *); 203 static void input_csi_dispatch_sgr(struct input_ctx *); 204 static int input_dcs_dispatch(struct input_ctx *); 205 static int input_top_bit_set(struct input_ctx *); 206 static int input_end_bel(struct input_ctx *); 207 208 /* Command table comparison function. */ 209 static int input_table_compare(const void *, const void *); 210 211 /* Command table entry. */ 212 struct input_table_entry { 213 int ch; 214 const char *interm; 215 int type; 216 }; 217 218 /* Escape commands. */ 219 enum input_esc_type { 220 INPUT_ESC_DECALN, 221 INPUT_ESC_DECKPAM, 222 INPUT_ESC_DECKPNM, 223 INPUT_ESC_DECRC, 224 INPUT_ESC_DECSC, 225 INPUT_ESC_HTS, 226 INPUT_ESC_IND, 227 INPUT_ESC_NEL, 228 INPUT_ESC_RI, 229 INPUT_ESC_RIS, 230 INPUT_ESC_SCSG0_OFF, 231 INPUT_ESC_SCSG0_ON, 232 INPUT_ESC_SCSG1_OFF, 233 INPUT_ESC_SCSG1_ON, 234 INPUT_ESC_ST 235 }; 236 237 /* Escape command table. */ 238 static const struct input_table_entry input_esc_table[] = { 239 { '0', "(", INPUT_ESC_SCSG0_ON }, 240 { '0', ")", INPUT_ESC_SCSG1_ON }, 241 { '7', "", INPUT_ESC_DECSC }, 242 { '8', "", INPUT_ESC_DECRC }, 243 { '8', "#", INPUT_ESC_DECALN }, 244 { '=', "", INPUT_ESC_DECKPAM }, 245 { '>', "", INPUT_ESC_DECKPNM }, 246 { 'B', "(", INPUT_ESC_SCSG0_OFF }, 247 { 'B', ")", INPUT_ESC_SCSG1_OFF }, 248 { 'D', "", INPUT_ESC_IND }, 249 { 'E', "", INPUT_ESC_NEL }, 250 { 'H', "", INPUT_ESC_HTS }, 251 { 'M', "", INPUT_ESC_RI }, 252 { '\\', "", INPUT_ESC_ST }, 253 { 'c', "", INPUT_ESC_RIS }, 254 }; 255 256 /* Control (CSI) commands. */ 257 enum input_csi_type { 258 INPUT_CSI_CBT, 259 INPUT_CSI_CNL, 260 INPUT_CSI_CPL, 261 INPUT_CSI_CUB, 262 INPUT_CSI_CUD, 263 INPUT_CSI_CUF, 264 INPUT_CSI_CUP, 265 INPUT_CSI_CUU, 266 INPUT_CSI_DA, 267 INPUT_CSI_DA_TWO, 268 INPUT_CSI_DCH, 269 INPUT_CSI_DECSCUSR, 270 INPUT_CSI_DECSTBM, 271 INPUT_CSI_DL, 272 INPUT_CSI_DSR, 273 INPUT_CSI_DSR_PRIVATE, 274 INPUT_CSI_ECH, 275 INPUT_CSI_ED, 276 INPUT_CSI_EL, 277 INPUT_CSI_HPA, 278 INPUT_CSI_ICH, 279 INPUT_CSI_IL, 280 INPUT_CSI_MODOFF, 281 INPUT_CSI_MODSET, 282 INPUT_CSI_QUERY_PRIVATE, 283 INPUT_CSI_RCP, 284 INPUT_CSI_REP, 285 INPUT_CSI_RM, 286 INPUT_CSI_RM_PRIVATE, 287 INPUT_CSI_SCP, 288 INPUT_CSI_SD, 289 INPUT_CSI_SGR, 290 INPUT_CSI_SM, 291 INPUT_CSI_SM_GRAPHICS, 292 INPUT_CSI_SM_PRIVATE, 293 INPUT_CSI_SU, 294 INPUT_CSI_TBC, 295 INPUT_CSI_VPA, 296 INPUT_CSI_WINOPS, 297 INPUT_CSI_XDA 298 }; 299 300 /* Control (CSI) command table. */ 301 static const struct input_table_entry input_csi_table[] = { 302 { '@', "", INPUT_CSI_ICH }, 303 { 'A', "", INPUT_CSI_CUU }, 304 { 'B', "", INPUT_CSI_CUD }, 305 { 'C', "", INPUT_CSI_CUF }, 306 { 'D', "", INPUT_CSI_CUB }, 307 { 'E', "", INPUT_CSI_CNL }, 308 { 'F', "", INPUT_CSI_CPL }, 309 { 'G', "", INPUT_CSI_HPA }, 310 { 'H', "", INPUT_CSI_CUP }, 311 { 'J', "", INPUT_CSI_ED }, 312 { 'K', "", INPUT_CSI_EL }, 313 { 'L', "", INPUT_CSI_IL }, 314 { 'M', "", INPUT_CSI_DL }, 315 { 'P', "", INPUT_CSI_DCH }, 316 { 'S', "", INPUT_CSI_SU }, 317 { 'S', "?", INPUT_CSI_SM_GRAPHICS }, 318 { 'T', "", INPUT_CSI_SD }, 319 { 'X', "", INPUT_CSI_ECH }, 320 { 'Z', "", INPUT_CSI_CBT }, 321 { '`', "", INPUT_CSI_HPA }, 322 { 'b', "", INPUT_CSI_REP }, 323 { 'c', "", INPUT_CSI_DA }, 324 { 'c', ">", INPUT_CSI_DA_TWO }, 325 { 'd', "", INPUT_CSI_VPA }, 326 { 'f', "", INPUT_CSI_CUP }, 327 { 'g', "", INPUT_CSI_TBC }, 328 { 'h', "", INPUT_CSI_SM }, 329 { 'h', "?", INPUT_CSI_SM_PRIVATE }, 330 { 'l', "", INPUT_CSI_RM }, 331 { 'l', "?", INPUT_CSI_RM_PRIVATE }, 332 { 'm', "", INPUT_CSI_SGR }, 333 { 'm', ">", INPUT_CSI_MODSET }, 334 { 'n', "", INPUT_CSI_DSR }, 335 { 'n', ">", INPUT_CSI_MODOFF }, 336 { 'n', "?", INPUT_CSI_DSR_PRIVATE }, 337 { 'p', "?$", INPUT_CSI_QUERY_PRIVATE }, 338 { 'q', " ", INPUT_CSI_DECSCUSR }, 339 { 'q', ">", INPUT_CSI_XDA }, 340 { 'r', "", INPUT_CSI_DECSTBM }, 341 { 's', "", INPUT_CSI_SCP }, 342 { 't', "", INPUT_CSI_WINOPS }, 343 { 'u', "", INPUT_CSI_RCP } 344 }; 345 346 /* Input transition. */ 347 struct input_transition { 348 int first; 349 int last; 350 351 int (*handler)(struct input_ctx *); 352 const struct input_state *state; 353 }; 354 355 /* Input state. */ 356 struct input_state { 357 const char *name; 358 void (*enter)(struct input_ctx *); 359 void (*exit)(struct input_ctx *); 360 const struct input_transition *transitions; 361 }; 362 363 /* State transitions available from all states. */ 364 #define INPUT_STATE_ANYWHERE \ 365 { 0x18, 0x18, input_c0_dispatch, &input_state_ground }, \ 366 { 0x1a, 0x1a, input_c0_dispatch, &input_state_ground }, \ 367 { 0x1b, 0x1b, NULL, &input_state_esc_enter } 368 369 /* Forward declarations of state tables. */ 370 static const struct input_transition input_state_ground_table[]; 371 static const struct input_transition input_state_esc_enter_table[]; 372 static const struct input_transition input_state_esc_intermediate_table[]; 373 static const struct input_transition input_state_csi_enter_table[]; 374 static const struct input_transition input_state_csi_parameter_table[]; 375 static const struct input_transition input_state_csi_intermediate_table[]; 376 static const struct input_transition input_state_csi_ignore_table[]; 377 static const struct input_transition input_state_dcs_enter_table[]; 378 static const struct input_transition input_state_dcs_parameter_table[]; 379 static const struct input_transition input_state_dcs_intermediate_table[]; 380 static const struct input_transition input_state_dcs_handler_table[]; 381 static const struct input_transition input_state_dcs_escape_table[]; 382 static const struct input_transition input_state_dcs_ignore_table[]; 383 static const struct input_transition input_state_osc_string_table[]; 384 static const struct input_transition input_state_apc_string_table[]; 385 static const struct input_transition input_state_rename_string_table[]; 386 static const struct input_transition input_state_consume_st_table[]; 387 388 /* ground state definition. */ 389 static const struct input_state input_state_ground = { 390 "ground", 391 input_ground, NULL, 392 input_state_ground_table 393 }; 394 395 /* esc_enter state definition. */ 396 static const struct input_state input_state_esc_enter = { 397 "esc_enter", 398 input_clear, NULL, 399 input_state_esc_enter_table 400 }; 401 402 /* esc_intermediate state definition. */ 403 static const struct input_state input_state_esc_intermediate = { 404 "esc_intermediate", 405 NULL, NULL, 406 input_state_esc_intermediate_table 407 }; 408 409 /* csi_enter state definition. */ 410 static const struct input_state input_state_csi_enter = { 411 "csi_enter", 412 input_clear, NULL, 413 input_state_csi_enter_table 414 }; 415 416 /* csi_parameter state definition. */ 417 static const struct input_state input_state_csi_parameter = { 418 "csi_parameter", 419 NULL, NULL, 420 input_state_csi_parameter_table 421 }; 422 423 /* csi_intermediate state definition. */ 424 static const struct input_state input_state_csi_intermediate = { 425 "csi_intermediate", 426 NULL, NULL, 427 input_state_csi_intermediate_table 428 }; 429 430 /* csi_ignore state definition. */ 431 static const struct input_state input_state_csi_ignore = { 432 "csi_ignore", 433 NULL, NULL, 434 input_state_csi_ignore_table 435 }; 436 437 /* dcs_enter state definition. */ 438 static const struct input_state input_state_dcs_enter = { 439 "dcs_enter", 440 input_enter_dcs, NULL, 441 input_state_dcs_enter_table 442 }; 443 444 /* dcs_parameter state definition. */ 445 static const struct input_state input_state_dcs_parameter = { 446 "dcs_parameter", 447 NULL, NULL, 448 input_state_dcs_parameter_table 449 }; 450 451 /* dcs_intermediate state definition. */ 452 static const struct input_state input_state_dcs_intermediate = { 453 "dcs_intermediate", 454 NULL, NULL, 455 input_state_dcs_intermediate_table 456 }; 457 458 /* dcs_handler state definition. */ 459 static const struct input_state input_state_dcs_handler = { 460 "dcs_handler", 461 NULL, NULL, 462 input_state_dcs_handler_table 463 }; 464 465 /* dcs_escape state definition. */ 466 static const struct input_state input_state_dcs_escape = { 467 "dcs_escape", 468 NULL, NULL, 469 input_state_dcs_escape_table 470 }; 471 472 /* dcs_ignore state definition. */ 473 static const struct input_state input_state_dcs_ignore = { 474 "dcs_ignore", 475 NULL, NULL, 476 input_state_dcs_ignore_table 477 }; 478 479 /* osc_string state definition. */ 480 static const struct input_state input_state_osc_string = { 481 "osc_string", 482 input_enter_osc, input_exit_osc, 483 input_state_osc_string_table 484 }; 485 486 /* apc_string state definition. */ 487 static const struct input_state input_state_apc_string = { 488 "apc_string", 489 input_enter_apc, input_exit_apc, 490 input_state_apc_string_table 491 }; 492 493 /* rename_string state definition. */ 494 static const struct input_state input_state_rename_string = { 495 "rename_string", 496 input_enter_rename, input_exit_rename, 497 input_state_rename_string_table 498 }; 499 500 /* consume_st state definition. */ 501 static const struct input_state input_state_consume_st = { 502 "consume_st", 503 input_enter_rename, NULL, /* rename also waits for ST */ 504 input_state_consume_st_table 505 }; 506 507 /* ground state table. */ 508 static const struct input_transition input_state_ground_table[] = { 509 INPUT_STATE_ANYWHERE, 510 511 { 0x00, 0x17, input_c0_dispatch, NULL }, 512 { 0x19, 0x19, input_c0_dispatch, NULL }, 513 { 0x1c, 0x1f, input_c0_dispatch, NULL }, 514 { 0x20, 0x7e, input_print, NULL }, 515 { 0x7f, 0x7f, NULL, NULL }, 516 { 0x80, 0xff, input_top_bit_set, NULL }, 517 518 { -1, -1, NULL, NULL } 519 }; 520 521 /* esc_enter state table. */ 522 static const struct input_transition input_state_esc_enter_table[] = { 523 INPUT_STATE_ANYWHERE, 524 525 { 0x00, 0x17, input_c0_dispatch, NULL }, 526 { 0x19, 0x19, input_c0_dispatch, NULL }, 527 { 0x1c, 0x1f, input_c0_dispatch, NULL }, 528 { 0x20, 0x2f, input_intermediate, &input_state_esc_intermediate }, 529 { 0x30, 0x4f, input_esc_dispatch, &input_state_ground }, 530 { 0x50, 0x50, NULL, &input_state_dcs_enter }, 531 { 0x51, 0x57, input_esc_dispatch, &input_state_ground }, 532 { 0x58, 0x58, NULL, &input_state_consume_st }, 533 { 0x59, 0x59, input_esc_dispatch, &input_state_ground }, 534 { 0x5a, 0x5a, input_esc_dispatch, &input_state_ground }, 535 { 0x5b, 0x5b, NULL, &input_state_csi_enter }, 536 { 0x5c, 0x5c, input_esc_dispatch, &input_state_ground }, 537 { 0x5d, 0x5d, NULL, &input_state_osc_string }, 538 { 0x5e, 0x5e, NULL, &input_state_consume_st }, 539 { 0x5f, 0x5f, NULL, &input_state_apc_string }, 540 { 0x60, 0x6a, input_esc_dispatch, &input_state_ground }, 541 { 0x6b, 0x6b, NULL, &input_state_rename_string }, 542 { 0x6c, 0x7e, input_esc_dispatch, &input_state_ground }, 543 { 0x7f, 0xff, NULL, NULL }, 544 545 { -1, -1, NULL, NULL } 546 }; 547 548 /* esc_intermediate state table. */ 549 static const struct input_transition input_state_esc_intermediate_table[] = { 550 INPUT_STATE_ANYWHERE, 551 552 { 0x00, 0x17, input_c0_dispatch, NULL }, 553 { 0x19, 0x19, input_c0_dispatch, NULL }, 554 { 0x1c, 0x1f, input_c0_dispatch, NULL }, 555 { 0x20, 0x2f, input_intermediate, NULL }, 556 { 0x30, 0x7e, input_esc_dispatch, &input_state_ground }, 557 { 0x7f, 0xff, NULL, NULL }, 558 559 { -1, -1, NULL, NULL } 560 }; 561 562 /* csi_enter state table. */ 563 static const struct input_transition input_state_csi_enter_table[] = { 564 INPUT_STATE_ANYWHERE, 565 566 { 0x00, 0x17, input_c0_dispatch, NULL }, 567 { 0x19, 0x19, input_c0_dispatch, NULL }, 568 { 0x1c, 0x1f, input_c0_dispatch, NULL }, 569 { 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate }, 570 { 0x30, 0x39, input_parameter, &input_state_csi_parameter }, 571 { 0x3a, 0x3a, input_parameter, &input_state_csi_parameter }, 572 { 0x3b, 0x3b, input_parameter, &input_state_csi_parameter }, 573 { 0x3c, 0x3f, input_intermediate, &input_state_csi_parameter }, 574 { 0x40, 0x7e, input_csi_dispatch, &input_state_ground }, 575 { 0x7f, 0xff, NULL, NULL }, 576 577 { -1, -1, NULL, NULL } 578 }; 579 580 /* csi_parameter state table. */ 581 static const struct input_transition input_state_csi_parameter_table[] = { 582 INPUT_STATE_ANYWHERE, 583 584 { 0x00, 0x17, input_c0_dispatch, NULL }, 585 { 0x19, 0x19, input_c0_dispatch, NULL }, 586 { 0x1c, 0x1f, input_c0_dispatch, NULL }, 587 { 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate }, 588 { 0x30, 0x39, input_parameter, NULL }, 589 { 0x3a, 0x3a, input_parameter, NULL }, 590 { 0x3b, 0x3b, input_parameter, NULL }, 591 { 0x3c, 0x3f, NULL, &input_state_csi_ignore }, 592 { 0x40, 0x7e, input_csi_dispatch, &input_state_ground }, 593 { 0x7f, 0xff, NULL, NULL }, 594 595 { -1, -1, NULL, NULL } 596 }; 597 598 /* csi_intermediate state table. */ 599 static const struct input_transition input_state_csi_intermediate_table[] = { 600 INPUT_STATE_ANYWHERE, 601 602 { 0x00, 0x17, input_c0_dispatch, NULL }, 603 { 0x19, 0x19, input_c0_dispatch, NULL }, 604 { 0x1c, 0x1f, input_c0_dispatch, NULL }, 605 { 0x20, 0x2f, input_intermediate, NULL }, 606 { 0x30, 0x3f, NULL, &input_state_csi_ignore }, 607 { 0x40, 0x7e, input_csi_dispatch, &input_state_ground }, 608 { 0x7f, 0xff, NULL, NULL }, 609 610 { -1, -1, NULL, NULL } 611 }; 612 613 /* csi_ignore state table. */ 614 static const struct input_transition input_state_csi_ignore_table[] = { 615 INPUT_STATE_ANYWHERE, 616 617 { 0x00, 0x17, input_c0_dispatch, NULL }, 618 { 0x19, 0x19, input_c0_dispatch, NULL }, 619 { 0x1c, 0x1f, input_c0_dispatch, NULL }, 620 { 0x20, 0x3f, NULL, NULL }, 621 { 0x40, 0x7e, NULL, &input_state_ground }, 622 { 0x7f, 0xff, NULL, NULL }, 623 624 { -1, -1, NULL, NULL } 625 }; 626 627 /* dcs_enter state table. */ 628 static const struct input_transition input_state_dcs_enter_table[] = { 629 INPUT_STATE_ANYWHERE, 630 631 { 0x00, 0x17, NULL, NULL }, 632 { 0x19, 0x19, NULL, NULL }, 633 { 0x1c, 0x1f, NULL, NULL }, 634 { 0x20, 0x2f, input_intermediate, &input_state_dcs_intermediate }, 635 { 0x30, 0x39, input_parameter, &input_state_dcs_parameter }, 636 { 0x3a, 0x3a, NULL, &input_state_dcs_ignore }, 637 { 0x3b, 0x3b, input_parameter, &input_state_dcs_parameter }, 638 { 0x3c, 0x3f, input_intermediate, &input_state_dcs_parameter }, 639 { 0x40, 0x7e, input_input, &input_state_dcs_handler }, 640 { 0x7f, 0xff, NULL, NULL }, 641 642 { -1, -1, NULL, NULL } 643 }; 644 645 /* dcs_parameter state table. */ 646 static const struct input_transition input_state_dcs_parameter_table[] = { 647 INPUT_STATE_ANYWHERE, 648 649 { 0x00, 0x17, NULL, NULL }, 650 { 0x19, 0x19, NULL, NULL }, 651 { 0x1c, 0x1f, NULL, NULL }, 652 { 0x20, 0x2f, input_intermediate, &input_state_dcs_intermediate }, 653 { 0x30, 0x39, input_parameter, NULL }, 654 { 0x3a, 0x3a, NULL, &input_state_dcs_ignore }, 655 { 0x3b, 0x3b, input_parameter, NULL }, 656 { 0x3c, 0x3f, NULL, &input_state_dcs_ignore }, 657 { 0x40, 0x7e, input_input, &input_state_dcs_handler }, 658 { 0x7f, 0xff, NULL, NULL }, 659 660 { -1, -1, NULL, NULL } 661 }; 662 663 /* dcs_intermediate state table. */ 664 static const struct input_transition input_state_dcs_intermediate_table[] = { 665 INPUT_STATE_ANYWHERE, 666 667 { 0x00, 0x17, NULL, NULL }, 668 { 0x19, 0x19, NULL, NULL }, 669 { 0x1c, 0x1f, NULL, NULL }, 670 { 0x20, 0x2f, input_intermediate, NULL }, 671 { 0x30, 0x3f, NULL, &input_state_dcs_ignore }, 672 { 0x40, 0x7e, input_input, &input_state_dcs_handler }, 673 { 0x7f, 0xff, NULL, NULL }, 674 675 { -1, -1, NULL, NULL } 676 }; 677 678 /* dcs_handler state table. */ 679 static const struct input_transition input_state_dcs_handler_table[] = { 680 /* No INPUT_STATE_ANYWHERE */ 681 682 { 0x00, 0x1a, input_input, NULL }, 683 { 0x1b, 0x1b, NULL, &input_state_dcs_escape }, 684 { 0x1c, 0xff, input_input, NULL }, 685 686 { -1, -1, NULL, NULL } 687 }; 688 689 /* dcs_escape state table. */ 690 static const struct input_transition input_state_dcs_escape_table[] = { 691 /* No INPUT_STATE_ANYWHERE */ 692 693 { 0x00, 0x5b, input_input, &input_state_dcs_handler }, 694 { 0x5c, 0x5c, input_dcs_dispatch, &input_state_ground }, 695 { 0x5d, 0xff, input_input, &input_state_dcs_handler }, 696 697 { -1, -1, NULL, NULL } 698 }; 699 700 /* dcs_ignore state table. */ 701 static const struct input_transition input_state_dcs_ignore_table[] = { 702 INPUT_STATE_ANYWHERE, 703 704 { 0x00, 0x17, NULL, NULL }, 705 { 0x19, 0x19, NULL, NULL }, 706 { 0x1c, 0x1f, NULL, NULL }, 707 { 0x20, 0xff, NULL, NULL }, 708 709 { -1, -1, NULL, NULL } 710 }; 711 712 /* osc_string state table. */ 713 static const struct input_transition input_state_osc_string_table[] = { 714 INPUT_STATE_ANYWHERE, 715 716 { 0x00, 0x06, NULL, NULL }, 717 { 0x07, 0x07, input_end_bel, &input_state_ground }, 718 { 0x08, 0x17, NULL, NULL }, 719 { 0x19, 0x19, NULL, NULL }, 720 { 0x1c, 0x1f, NULL, NULL }, 721 { 0x20, 0xff, input_input, NULL }, 722 723 { -1, -1, NULL, NULL } 724 }; 725 726 /* apc_string state table. */ 727 static const struct input_transition input_state_apc_string_table[] = { 728 INPUT_STATE_ANYWHERE, 729 730 { 0x00, 0x17, NULL, NULL }, 731 { 0x19, 0x19, NULL, NULL }, 732 { 0x1c, 0x1f, NULL, NULL }, 733 { 0x20, 0xff, input_input, NULL }, 734 735 { -1, -1, NULL, NULL } 736 }; 737 738 /* rename_string state table. */ 739 static const struct input_transition input_state_rename_string_table[] = { 740 INPUT_STATE_ANYWHERE, 741 742 { 0x00, 0x17, NULL, NULL }, 743 { 0x19, 0x19, NULL, NULL }, 744 { 0x1c, 0x1f, NULL, NULL }, 745 { 0x20, 0xff, input_input, NULL }, 746 747 { -1, -1, NULL, NULL } 748 }; 749 750 /* consume_st state table. */ 751 static const struct input_transition input_state_consume_st_table[] = { 752 INPUT_STATE_ANYWHERE, 753 754 { 0x00, 0x17, NULL, NULL }, 755 { 0x19, 0x19, NULL, NULL }, 756 { 0x1c, 0x1f, NULL, NULL }, 757 { 0x20, 0xff, NULL, NULL }, 758 759 { -1, -1, NULL, NULL } 760 }; 761 762 /* Maximum of bytes allowed to read in a single input. */ 763 static size_t input_buffer_size = INPUT_BUF_DEFAULT_SIZE; 764 765 /* Input table compare. */ 766 static int 767 input_table_compare(const void *key, const void *value) 768 { 769 const struct input_ctx *ictx = key; 770 const struct input_table_entry *entry = value; 771 772 if (ictx->ch != entry->ch) 773 return (ictx->ch - entry->ch); 774 return (strcmp((const char *)ictx->interm_buf, entry->interm)); 775 } 776 777 /* Stop UTF-8 and enter an invalid character. */ 778 static void 779 input_stop_utf8(struct input_ctx *ictx) 780 { 781 struct screen_write_ctx *sctx = &ictx->ctx; 782 static struct utf8_data rc = { "\357\277\275", 3, 3, 1 }; 783 784 if (ictx->utf8started) { 785 utf8_copy(&ictx->cell.cell.data, &rc); 786 screen_write_collect_add(sctx, &ictx->cell.cell); 787 } 788 ictx->utf8started = 0; 789 } 790 791 /* 792 * Timer - if this expires then have been waiting for a terminator for too 793 * long, so reset to ground. 794 */ 795 static void 796 input_ground_timer_callback(__unused int fd, __unused short events, void *arg) 797 { 798 struct input_ctx *ictx = arg; 799 800 log_debug("%s: %s expired" , __func__, ictx->state->name); 801 input_reset(ictx, 0); 802 } 803 804 /* Start the timer. */ 805 static void 806 input_start_ground_timer(struct input_ctx *ictx) 807 { 808 struct timeval tv = { .tv_sec = 5, .tv_usec = 0 }; 809 810 event_del(&ictx->ground_timer); 811 event_add(&ictx->ground_timer, &tv); 812 } 813 814 /* Reset cell state to default. */ 815 static void 816 input_reset_cell(struct input_ctx *ictx) 817 { 818 memcpy(&ictx->cell.cell, &grid_default_cell, sizeof ictx->cell.cell); 819 ictx->cell.set = 0; 820 ictx->cell.g0set = ictx->cell.g1set = 0; 821 822 memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); 823 ictx->old_cx = 0; 824 ictx->old_cy = 0; 825 } 826 827 /* Save screen state. */ 828 static void 829 input_save_state(struct input_ctx *ictx) 830 { 831 struct screen_write_ctx *sctx = &ictx->ctx; 832 struct screen *s = sctx->s; 833 834 memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); 835 ictx->old_cx = s->cx; 836 ictx->old_cy = s->cy; 837 ictx->old_mode = s->mode; 838 } 839 840 /* Restore screen state. */ 841 static void 842 input_restore_state(struct input_ctx *ictx) 843 { 844 struct screen_write_ctx *sctx = &ictx->ctx; 845 846 memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell); 847 if (ictx->old_mode & MODE_ORIGIN) 848 screen_write_mode_set(sctx, MODE_ORIGIN); 849 else 850 screen_write_mode_clear(sctx, MODE_ORIGIN); 851 screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy, 0); 852 } 853 854 /* Initialise input parser. */ 855 struct input_ctx * 856 input_init(struct window_pane *wp, struct bufferevent *bev, 857 struct colour_palette *palette) 858 { 859 struct input_ctx *ictx; 860 861 ictx = xcalloc(1, sizeof *ictx); 862 ictx->wp = wp; 863 ictx->event = bev; 864 ictx->palette = palette; 865 866 ictx->input_space = INPUT_BUF_START; 867 ictx->input_buf = xmalloc(INPUT_BUF_START); 868 869 ictx->since_ground = evbuffer_new(); 870 if (ictx->since_ground == NULL) 871 fatalx("out of memory"); 872 evtimer_set(&ictx->ground_timer, input_ground_timer_callback, ictx); 873 874 TAILQ_INIT(&ictx->requests); 875 evtimer_set(&ictx->request_timer, input_request_timer_callback, ictx); 876 877 input_reset(ictx, 0); 878 return (ictx); 879 } 880 881 /* Destroy input parser. */ 882 void 883 input_free(struct input_ctx *ictx) 884 { 885 struct input_request *ir, *ir1; 886 u_int i; 887 888 for (i = 0; i < ictx->param_list_len; i++) { 889 if (ictx->param_list[i].type == INPUT_STRING) 890 free(ictx->param_list[i].str); 891 } 892 893 TAILQ_FOREACH_SAFE(ir, &ictx->requests, entry, ir1) 894 input_free_request(ir); 895 event_del(&ictx->request_timer); 896 897 free(ictx->input_buf); 898 evbuffer_free(ictx->since_ground); 899 event_del(&ictx->ground_timer); 900 901 free(ictx); 902 } 903 904 /* Reset input state and clear screen. */ 905 void 906 input_reset(struct input_ctx *ictx, int clear) 907 { 908 struct screen_write_ctx *sctx = &ictx->ctx; 909 struct window_pane *wp = ictx->wp; 910 911 input_reset_cell(ictx); 912 913 if (clear && wp != NULL) { 914 if (TAILQ_EMPTY(&wp->modes)) 915 screen_write_start_pane(sctx, wp, &wp->base); 916 else 917 screen_write_start(sctx, &wp->base); 918 screen_write_reset(sctx); 919 screen_write_stop(sctx); 920 } 921 922 input_clear(ictx); 923 924 ictx->state = &input_state_ground; 925 ictx->flags = 0; 926 } 927 928 /* Return pending data. */ 929 struct evbuffer * 930 input_pending(struct input_ctx *ictx) 931 { 932 return (ictx->since_ground); 933 } 934 935 /* Change input state. */ 936 static void 937 input_set_state(struct input_ctx *ictx, const struct input_transition *itr) 938 { 939 if (ictx->state->exit != NULL) 940 ictx->state->exit(ictx); 941 ictx->state = itr->state; 942 if (ictx->state->enter != NULL) 943 ictx->state->enter(ictx); 944 } 945 946 /* Parse data. */ 947 static void 948 input_parse(struct input_ctx *ictx, u_char *buf, size_t len) 949 { 950 struct screen_write_ctx *sctx = &ictx->ctx; 951 const struct input_state *state = NULL; 952 const struct input_transition *itr = NULL; 953 size_t off = 0; 954 955 /* Parse the input. */ 956 while (off < len) { 957 ictx->ch = buf[off++]; 958 959 /* Find the transition. */ 960 if (ictx->state != state || 961 itr == NULL || 962 ictx->ch < itr->first || 963 ictx->ch > itr->last) { 964 itr = ictx->state->transitions; 965 while (itr->first != -1 && itr->last != -1) { 966 if (ictx->ch >= itr->first && 967 ictx->ch <= itr->last) 968 break; 969 itr++; 970 } 971 if (itr->first == -1 || itr->last == -1) { 972 /* No transition? Eh? */ 973 fatalx("no transition from state"); 974 } 975 } 976 state = ictx->state; 977 978 /* 979 * Any state except print stops the current collection. This is 980 * an optimization to avoid checking if the attributes have 981 * changed for every character. It will stop unnecessarily for 982 * sequences that don't make a terminal change, but they should 983 * be the minority. 984 */ 985 if (itr->handler != input_print) 986 screen_write_collect_end(sctx); 987 988 /* 989 * Execute the handler, if any. Don't switch state if it 990 * returns non-zero. 991 */ 992 if (itr->handler != NULL && itr->handler(ictx) != 0) 993 continue; 994 995 /* And switch state, if necessary. */ 996 if (itr->state != NULL) 997 input_set_state(ictx, itr); 998 999 /* If not in ground state, save input. */ 1000 if (ictx->state != &input_state_ground) 1001 evbuffer_add(ictx->since_ground, &ictx->ch, 1); 1002 } 1003 } 1004 1005 /* Parse input from pane. */ 1006 void 1007 input_parse_pane(struct window_pane *wp) 1008 { 1009 void *new_data; 1010 size_t new_size; 1011 1012 new_data = window_pane_get_new_data(wp, &wp->offset, &new_size); 1013 input_parse_buffer(wp, new_data, new_size); 1014 window_pane_update_used_data(wp, &wp->offset, new_size); 1015 } 1016 1017 /* Parse given input. */ 1018 void 1019 input_parse_buffer(struct window_pane *wp, u_char *buf, size_t len) 1020 { 1021 struct input_ctx *ictx = wp->ictx; 1022 struct screen_write_ctx *sctx = &ictx->ctx; 1023 1024 if (len == 0) 1025 return; 1026 1027 window_update_activity(wp->window); 1028 wp->flags |= PANE_CHANGED; 1029 1030 /* Flag new input while in a mode. */ 1031 if (!TAILQ_EMPTY(&wp->modes)) 1032 wp->flags |= PANE_UNSEENCHANGES; 1033 1034 /* NULL wp if there is a mode set as don't want to update the tty. */ 1035 if (TAILQ_EMPTY(&wp->modes)) 1036 screen_write_start_pane(sctx, wp, &wp->base); 1037 else 1038 screen_write_start(sctx, &wp->base); 1039 1040 log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id, 1041 ictx->state->name, len, (int)len, buf); 1042 1043 input_parse(ictx, buf, len); 1044 screen_write_stop(sctx); 1045 } 1046 1047 /* Parse given input for screen. */ 1048 void 1049 input_parse_screen(struct input_ctx *ictx, struct screen *s, 1050 screen_write_init_ctx_cb cb, void *arg, u_char *buf, size_t len) 1051 { 1052 struct screen_write_ctx *sctx = &ictx->ctx; 1053 1054 if (len == 0) 1055 return; 1056 1057 screen_write_start_callback(sctx, s, cb, arg); 1058 input_parse(ictx, buf, len); 1059 screen_write_stop(sctx); 1060 } 1061 1062 /* Split the parameter list (if any). */ 1063 static int 1064 input_split(struct input_ctx *ictx) 1065 { 1066 const char *errstr; 1067 char *ptr, *out; 1068 struct input_param *ip; 1069 u_int i; 1070 1071 for (i = 0; i < ictx->param_list_len; i++) { 1072 if (ictx->param_list[i].type == INPUT_STRING) 1073 free(ictx->param_list[i].str); 1074 } 1075 ictx->param_list_len = 0; 1076 1077 if (ictx->param_len == 0) 1078 return (0); 1079 ip = &ictx->param_list[0]; 1080 1081 ptr = (char *)ictx->param_buf; 1082 while ((out = strsep(&ptr, ";")) != NULL) { 1083 if (*out == '\0') 1084 ip->type = INPUT_MISSING; 1085 else { 1086 if (strchr(out, ':') != NULL) { 1087 ip->type = INPUT_STRING; 1088 ip->str = xstrdup(out); 1089 } else { 1090 ip->type = INPUT_NUMBER; 1091 ip->num = strtonum(out, 0, INT_MAX, &errstr); 1092 if (errstr != NULL) 1093 return (-1); 1094 } 1095 } 1096 ip = &ictx->param_list[++ictx->param_list_len]; 1097 if (ictx->param_list_len == nitems(ictx->param_list)) 1098 return (-1); 1099 } 1100 1101 for (i = 0; i < ictx->param_list_len; i++) { 1102 ip = &ictx->param_list[i]; 1103 if (ip->type == INPUT_MISSING) 1104 log_debug("parameter %u: missing", i); 1105 else if (ip->type == INPUT_STRING) 1106 log_debug("parameter %u: string %s", i, ip->str); 1107 else if (ip->type == INPUT_NUMBER) 1108 log_debug("parameter %u: number %d", i, ip->num); 1109 } 1110 1111 return (0); 1112 } 1113 1114 /* Get an argument or return default value. */ 1115 static int 1116 input_get(struct input_ctx *ictx, u_int validx, int minval, int defval) 1117 { 1118 struct input_param *ip; 1119 int retval; 1120 1121 if (validx >= ictx->param_list_len) 1122 return (defval); 1123 ip = &ictx->param_list[validx]; 1124 if (ip->type == INPUT_MISSING) 1125 return (defval); 1126 if (ip->type == INPUT_STRING) 1127 return (-1); 1128 retval = ip->num; 1129 if (retval < minval) 1130 return (minval); 1131 return (retval); 1132 } 1133 1134 /* Send reply. */ 1135 static void 1136 input_send_reply(struct input_ctx *ictx, const char *reply) 1137 { 1138 struct bufferevent *bev = ictx->event; 1139 1140 if (bev != NULL) { 1141 log_debug("%s: %s", __func__, reply); 1142 bufferevent_write(bev, reply, strlen(reply)); 1143 } 1144 } 1145 1146 /* Reply to terminal query. */ 1147 static void printflike(3, 4) 1148 input_reply(struct input_ctx *ictx, int add, const char *fmt, ...) 1149 { 1150 struct input_request *ir; 1151 va_list ap; 1152 char *reply; 1153 1154 va_start(ap, fmt); 1155 xvasprintf(&reply, fmt, ap); 1156 va_end(ap); 1157 1158 if (add && !TAILQ_EMPTY(&ictx->requests)) { 1159 ir = input_make_request(ictx, INPUT_REQUEST_QUEUE); 1160 ir->data = reply; 1161 } else { 1162 input_send_reply(ictx, reply); 1163 free(reply); 1164 } 1165 } 1166 1167 /* Clear saved state. */ 1168 static void 1169 input_clear(struct input_ctx *ictx) 1170 { 1171 event_del(&ictx->ground_timer); 1172 1173 *ictx->interm_buf = '\0'; 1174 ictx->interm_len = 0; 1175 1176 *ictx->param_buf = '\0'; 1177 ictx->param_len = 0; 1178 1179 *ictx->input_buf = '\0'; 1180 ictx->input_len = 0; 1181 1182 ictx->input_end = INPUT_END_ST; 1183 1184 ictx->flags &= ~INPUT_DISCARD; 1185 } 1186 1187 /* Reset for ground state. */ 1188 static void 1189 input_ground(struct input_ctx *ictx) 1190 { 1191 event_del(&ictx->ground_timer); 1192 evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground)); 1193 1194 if (ictx->input_space > INPUT_BUF_START) { 1195 ictx->input_space = INPUT_BUF_START; 1196 ictx->input_buf = xrealloc(ictx->input_buf, INPUT_BUF_START); 1197 } 1198 } 1199 1200 /* Output this character to the screen. */ 1201 static int 1202 input_print(struct input_ctx *ictx) 1203 { 1204 struct screen_write_ctx *sctx = &ictx->ctx; 1205 int set; 1206 1207 input_stop_utf8(ictx); /* can't be valid UTF-8 */ 1208 1209 set = ictx->cell.set == 0 ? ictx->cell.g0set : ictx->cell.g1set; 1210 if (set == 1) 1211 ictx->cell.cell.attr |= GRID_ATTR_CHARSET; 1212 else 1213 ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET; 1214 utf8_set(&ictx->cell.cell.data, ictx->ch); 1215 screen_write_collect_add(sctx, &ictx->cell.cell); 1216 1217 utf8_copy(&ictx->last, &ictx->cell.cell.data); 1218 ictx->flags |= INPUT_LAST; 1219 1220 ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET; 1221 1222 return (0); 1223 } 1224 1225 /* Collect intermediate string. */ 1226 static int 1227 input_intermediate(struct input_ctx *ictx) 1228 { 1229 if (ictx->interm_len == (sizeof ictx->interm_buf) - 1) 1230 ictx->flags |= INPUT_DISCARD; 1231 else { 1232 ictx->interm_buf[ictx->interm_len++] = ictx->ch; 1233 ictx->interm_buf[ictx->interm_len] = '\0'; 1234 } 1235 1236 return (0); 1237 } 1238 1239 /* Collect parameter string. */ 1240 static int 1241 input_parameter(struct input_ctx *ictx) 1242 { 1243 if (ictx->param_len == (sizeof ictx->param_buf) - 1) 1244 ictx->flags |= INPUT_DISCARD; 1245 else { 1246 ictx->param_buf[ictx->param_len++] = ictx->ch; 1247 ictx->param_buf[ictx->param_len] = '\0'; 1248 } 1249 1250 return (0); 1251 } 1252 1253 /* Collect input string. */ 1254 static int 1255 input_input(struct input_ctx *ictx) 1256 { 1257 size_t available; 1258 1259 available = ictx->input_space; 1260 while (ictx->input_len + 1 >= available) { 1261 available *= 2; 1262 if (available > input_buffer_size) { 1263 ictx->flags |= INPUT_DISCARD; 1264 return (0); 1265 } 1266 ictx->input_buf = xrealloc(ictx->input_buf, available); 1267 ictx->input_space = available; 1268 } 1269 ictx->input_buf[ictx->input_len++] = ictx->ch; 1270 ictx->input_buf[ictx->input_len] = '\0'; 1271 1272 return (0); 1273 } 1274 1275 /* Execute C0 control sequence. */ 1276 static int 1277 input_c0_dispatch(struct input_ctx *ictx) 1278 { 1279 struct screen_write_ctx *sctx = &ictx->ctx; 1280 struct window_pane *wp = ictx->wp; 1281 struct screen *s = sctx->s; 1282 struct grid_cell gc, first_gc; 1283 u_int cx, line; 1284 u_int width; 1285 int has_content = 0; 1286 1287 input_stop_utf8(ictx); /* can't be valid UTF-8 */ 1288 1289 log_debug("%s: '%c'", __func__, ictx->ch); 1290 1291 switch (ictx->ch) { 1292 case '\000': /* NUL */ 1293 break; 1294 case '\007': /* BEL */ 1295 if (wp != NULL) 1296 alerts_queue(wp->window, WINDOW_BELL); 1297 break; 1298 case '\010': /* BS */ 1299 screen_write_backspace(sctx); 1300 break; 1301 case '\011': /* HT */ 1302 /* Don't tab beyond the end of the line. */ 1303 cx = s->cx; 1304 if (cx >= screen_size_x(s) - 1) 1305 break; 1306 1307 /* Find the next tab point, or use the last column if none. */ 1308 line = s->cy + s->grid->hsize; 1309 grid_get_cell(s->grid, cx, line, &first_gc); 1310 do { 1311 if (!has_content) { 1312 grid_get_cell(s->grid, cx, line, &gc); 1313 if (gc.data.size != 1 || 1314 *gc.data.data != ' ' || 1315 !grid_cells_look_equal(&gc, &first_gc)) 1316 has_content = 1; 1317 } 1318 cx++; 1319 if (bit_test(s->tabs, cx)) 1320 break; 1321 } while (cx < screen_size_x(s) - 1); 1322 1323 width = cx - s->cx; 1324 if (has_content || width > sizeof gc.data.data) 1325 s->cx = cx; 1326 else { 1327 grid_get_cell(s->grid, s->cx, line, &gc); 1328 grid_set_tab(&gc, width); 1329 screen_write_collect_add(sctx, &gc); 1330 } 1331 break; 1332 case '\012': /* LF */ 1333 case '\013': /* VT */ 1334 case '\014': /* FF */ 1335 screen_write_linefeed(sctx, 0, ictx->cell.cell.bg); 1336 if (s->mode & MODE_CRLF) 1337 screen_write_carriagereturn(sctx); 1338 break; 1339 case '\015': /* CR */ 1340 screen_write_carriagereturn(sctx); 1341 break; 1342 case '\016': /* SO */ 1343 ictx->cell.set = 1; 1344 break; 1345 case '\017': /* SI */ 1346 ictx->cell.set = 0; 1347 break; 1348 default: 1349 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1350 break; 1351 } 1352 1353 ictx->flags &= ~INPUT_LAST; 1354 return (0); 1355 } 1356 1357 /* Execute escape sequence. */ 1358 static int 1359 input_esc_dispatch(struct input_ctx *ictx) 1360 { 1361 struct screen_write_ctx *sctx = &ictx->ctx; 1362 struct screen *s = sctx->s; 1363 struct input_table_entry *entry; 1364 1365 if (ictx->flags & INPUT_DISCARD) 1366 return (0); 1367 log_debug("%s: '%c', %s", __func__, ictx->ch, ictx->interm_buf); 1368 1369 entry = bsearch(ictx, input_esc_table, nitems(input_esc_table), 1370 sizeof input_esc_table[0], input_table_compare); 1371 if (entry == NULL) { 1372 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1373 return (0); 1374 } 1375 1376 switch (entry->type) { 1377 case INPUT_ESC_RIS: 1378 colour_palette_clear(ictx->palette); 1379 input_reset_cell(ictx); 1380 screen_write_reset(sctx); 1381 screen_write_fullredraw(sctx); 1382 break; 1383 case INPUT_ESC_IND: 1384 screen_write_linefeed(sctx, 0, ictx->cell.cell.bg); 1385 break; 1386 case INPUT_ESC_NEL: 1387 screen_write_carriagereturn(sctx); 1388 screen_write_linefeed(sctx, 0, ictx->cell.cell.bg); 1389 break; 1390 case INPUT_ESC_HTS: 1391 if (s->cx < screen_size_x(s)) 1392 bit_set(s->tabs, s->cx); 1393 break; 1394 case INPUT_ESC_RI: 1395 screen_write_reverseindex(sctx, ictx->cell.cell.bg); 1396 break; 1397 case INPUT_ESC_DECKPAM: 1398 screen_write_mode_set(sctx, MODE_KKEYPAD); 1399 break; 1400 case INPUT_ESC_DECKPNM: 1401 screen_write_mode_clear(sctx, MODE_KKEYPAD); 1402 break; 1403 case INPUT_ESC_DECSC: 1404 input_save_state(ictx); 1405 break; 1406 case INPUT_ESC_DECRC: 1407 input_restore_state(ictx); 1408 break; 1409 case INPUT_ESC_DECALN: 1410 screen_write_alignmenttest(sctx); 1411 break; 1412 case INPUT_ESC_SCSG0_ON: 1413 ictx->cell.g0set = 1; 1414 break; 1415 case INPUT_ESC_SCSG0_OFF: 1416 ictx->cell.g0set = 0; 1417 break; 1418 case INPUT_ESC_SCSG1_ON: 1419 ictx->cell.g1set = 1; 1420 break; 1421 case INPUT_ESC_SCSG1_OFF: 1422 ictx->cell.g1set = 0; 1423 break; 1424 case INPUT_ESC_ST: 1425 /* ST terminates OSC but the state transition already did it. */ 1426 break; 1427 } 1428 1429 ictx->flags &= ~INPUT_LAST; 1430 return (0); 1431 } 1432 1433 /* Execute control sequence. */ 1434 static int 1435 input_csi_dispatch(struct input_ctx *ictx) 1436 { 1437 struct screen_write_ctx *sctx = &ictx->ctx; 1438 struct screen *s = sctx->s; 1439 struct input_table_entry *entry; 1440 struct options *oo; 1441 int i, n, m, ek, set, p; 1442 u_int cx, bg = ictx->cell.cell.bg; 1443 1444 if (ictx->flags & INPUT_DISCARD) 1445 return (0); 1446 1447 log_debug("%s: '%c' \"%s\" \"%s\"", __func__, ictx->ch, 1448 ictx->interm_buf, ictx->param_buf); 1449 1450 if (input_split(ictx) != 0) 1451 return (0); 1452 1453 entry = bsearch(ictx, input_csi_table, nitems(input_csi_table), 1454 sizeof input_csi_table[0], input_table_compare); 1455 if (entry == NULL) { 1456 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1457 return (0); 1458 } 1459 1460 switch (entry->type) { 1461 case INPUT_CSI_CBT: 1462 /* Find the previous tab point, n times. */ 1463 cx = s->cx; 1464 if (cx > screen_size_x(s) - 1) 1465 cx = screen_size_x(s) - 1; 1466 n = input_get(ictx, 0, 1, 1); 1467 if (n == -1) 1468 break; 1469 while (cx > 0 && n-- > 0) { 1470 do 1471 cx--; 1472 while (cx > 0 && !bit_test(s->tabs, cx)); 1473 } 1474 s->cx = cx; 1475 break; 1476 case INPUT_CSI_CUB: 1477 n = input_get(ictx, 0, 1, 1); 1478 if (n != -1) 1479 screen_write_cursorleft(sctx, n); 1480 break; 1481 case INPUT_CSI_CUD: 1482 n = input_get(ictx, 0, 1, 1); 1483 if (n != -1) 1484 screen_write_cursordown(sctx, n); 1485 break; 1486 case INPUT_CSI_CUF: 1487 n = input_get(ictx, 0, 1, 1); 1488 if (n != -1) 1489 screen_write_cursorright(sctx, n); 1490 break; 1491 case INPUT_CSI_CUP: 1492 n = input_get(ictx, 0, 1, 1); 1493 m = input_get(ictx, 1, 1, 1); 1494 if (n != -1 && m != -1) 1495 screen_write_cursormove(sctx, m - 1, n - 1, 1); 1496 break; 1497 case INPUT_CSI_MODSET: 1498 n = input_get(ictx, 0, 0, 0); 1499 if (n != 4) 1500 break; 1501 m = input_get(ictx, 1, 0, 0); 1502 1503 /* 1504 * Set the extended key reporting mode as per the client 1505 * request, unless "extended-keys" is set to "off". 1506 */ 1507 ek = options_get_number(global_options, "extended-keys"); 1508 if (ek == 0) 1509 break; 1510 screen_write_mode_clear(sctx, EXTENDED_KEY_MODES); 1511 if (m == 2) 1512 screen_write_mode_set(sctx, MODE_KEYS_EXTENDED_2); 1513 else if (m == 1 || ek == 2) 1514 screen_write_mode_set(sctx, MODE_KEYS_EXTENDED); 1515 break; 1516 case INPUT_CSI_MODOFF: 1517 n = input_get(ictx, 0, 0, 0); 1518 if (n != 4) 1519 break; 1520 1521 /* 1522 * Clear the extended key reporting mode as per the client 1523 * request, unless "extended-keys always" forces into mode 1. 1524 */ 1525 screen_write_mode_clear(sctx, 1526 MODE_KEYS_EXTENDED|MODE_KEYS_EXTENDED_2); 1527 if (options_get_number(global_options, "extended-keys") == 2) 1528 screen_write_mode_set(sctx, MODE_KEYS_EXTENDED); 1529 break; 1530 case INPUT_CSI_WINOPS: 1531 input_csi_dispatch_winops(ictx); 1532 break; 1533 case INPUT_CSI_CUU: 1534 n = input_get(ictx, 0, 1, 1); 1535 if (n != -1) 1536 screen_write_cursorup(sctx, n); 1537 break; 1538 case INPUT_CSI_CNL: 1539 n = input_get(ictx, 0, 1, 1); 1540 if (n != -1) { 1541 screen_write_carriagereturn(sctx); 1542 screen_write_cursordown(sctx, n); 1543 } 1544 break; 1545 case INPUT_CSI_CPL: 1546 n = input_get(ictx, 0, 1, 1); 1547 if (n != -1) { 1548 screen_write_carriagereturn(sctx); 1549 screen_write_cursorup(sctx, n); 1550 } 1551 break; 1552 case INPUT_CSI_DA: 1553 switch (input_get(ictx, 0, 0, 0)) { 1554 case -1: 1555 break; 1556 case 0: 1557 #ifdef ENABLE_SIXEL 1558 input_reply(ictx, 1, "\033[?1;2;4c"); 1559 #else 1560 input_reply(ictx, 1, "\033[?1;2c"); 1561 #endif 1562 break; 1563 default: 1564 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1565 break; 1566 } 1567 break; 1568 case INPUT_CSI_DA_TWO: 1569 switch (input_get(ictx, 0, 0, 0)) { 1570 case -1: 1571 break; 1572 case 0: 1573 input_reply(ictx, 1, "\033[>84;0;0c"); 1574 break; 1575 default: 1576 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1577 break; 1578 } 1579 break; 1580 case INPUT_CSI_ECH: 1581 n = input_get(ictx, 0, 1, 1); 1582 if (n != -1) 1583 screen_write_clearcharacter(sctx, n, bg); 1584 break; 1585 case INPUT_CSI_DCH: 1586 n = input_get(ictx, 0, 1, 1); 1587 if (n != -1) 1588 screen_write_deletecharacter(sctx, n, bg); 1589 break; 1590 case INPUT_CSI_DECSTBM: 1591 n = input_get(ictx, 0, 1, 1); 1592 m = input_get(ictx, 1, 1, screen_size_y(s)); 1593 if (n != -1 && m != -1) 1594 screen_write_scrollregion(sctx, n - 1, m - 1); 1595 break; 1596 case INPUT_CSI_DL: 1597 n = input_get(ictx, 0, 1, 1); 1598 if (n != -1) 1599 screen_write_deleteline(sctx, n, bg); 1600 break; 1601 case INPUT_CSI_DSR_PRIVATE: 1602 switch (input_get(ictx, 0, 0, 0)) { 1603 case 996: 1604 input_report_current_theme(ictx); 1605 break; 1606 } 1607 break; 1608 case INPUT_CSI_QUERY_PRIVATE: 1609 switch (input_get(ictx, 0, 0, 0)) { 1610 case 12: /* cursor blink: 1 = blink, 2 = steady */ 1611 if (s->cstyle != SCREEN_CURSOR_DEFAULT || 1612 s->mode & MODE_CURSOR_BLINKING_SET) 1613 n = (s->mode & MODE_CURSOR_BLINKING) ? 1 : 2; 1614 else { 1615 if (ictx->wp != NULL) 1616 oo = ictx->wp->options; 1617 else 1618 oo = global_options; 1619 p = options_get_number(oo, "cursor-style"); 1620 1621 /* blink for 1,3,5; steady for 0,2,4,6 */ 1622 n = (p == 1 || p == 3 || p == 5) ? 1 : 2; 1623 } 1624 input_reply(ictx, 1, "\033[?12;%d$y", n); 1625 break; 1626 case 2004: /* bracketed paste */ 1627 n = (s->mode & MODE_BRACKETPASTE) ? 1 : 2; 1628 input_reply(ictx, 1, "\033[?2004;%d$y", n); 1629 break; 1630 case 1004: /* focus reporting */ 1631 n = (s->mode & MODE_FOCUSON) ? 1 : 2; 1632 input_reply(ictx, 1, "\033[?1004;%d$y", n); 1633 break; 1634 case 1006: /* SGR mouse */ 1635 n = (s->mode & MODE_MOUSE_SGR) ? 1 : 2; 1636 input_reply(ictx, 1, "\033[?1006;%d$y", n); 1637 break; 1638 case 2031: 1639 input_reply(ictx, 1, "\033[?2031;2$y"); 1640 break; 1641 } 1642 break; 1643 case INPUT_CSI_DSR: 1644 switch (input_get(ictx, 0, 0, 0)) { 1645 case -1: 1646 break; 1647 case 5: 1648 input_reply(ictx, 1, "\033[0n"); 1649 break; 1650 case 6: 1651 input_reply(ictx, 1, "\033[%u;%uR", s->cy + 1, 1652 s->cx + 1); 1653 break; 1654 default: 1655 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1656 break; 1657 } 1658 break; 1659 case INPUT_CSI_ED: 1660 switch (input_get(ictx, 0, 0, 0)) { 1661 case -1: 1662 break; 1663 case 0: 1664 screen_write_clearendofscreen(sctx, bg); 1665 break; 1666 case 1: 1667 screen_write_clearstartofscreen(sctx, bg); 1668 break; 1669 case 2: 1670 screen_write_clearscreen(sctx, bg); 1671 break; 1672 case 3: 1673 if (input_get(ictx, 1, 0, 0) == 0) { 1674 /* 1675 * Linux console extension to clear history 1676 * (for example before locking the screen). 1677 */ 1678 screen_write_clearhistory(sctx); 1679 } 1680 break; 1681 default: 1682 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1683 break; 1684 } 1685 break; 1686 case INPUT_CSI_EL: 1687 switch (input_get(ictx, 0, 0, 0)) { 1688 case -1: 1689 break; 1690 case 0: 1691 screen_write_clearendofline(sctx, bg); 1692 break; 1693 case 1: 1694 screen_write_clearstartofline(sctx, bg); 1695 break; 1696 case 2: 1697 screen_write_clearline(sctx, bg); 1698 break; 1699 default: 1700 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1701 break; 1702 } 1703 break; 1704 case INPUT_CSI_HPA: 1705 n = input_get(ictx, 0, 1, 1); 1706 if (n != -1) 1707 screen_write_cursormove(sctx, n - 1, -1, 1); 1708 break; 1709 case INPUT_CSI_ICH: 1710 n = input_get(ictx, 0, 1, 1); 1711 if (n != -1) 1712 screen_write_insertcharacter(sctx, n, bg); 1713 break; 1714 case INPUT_CSI_IL: 1715 n = input_get(ictx, 0, 1, 1); 1716 if (n != -1) 1717 screen_write_insertline(sctx, n, bg); 1718 break; 1719 case INPUT_CSI_REP: 1720 n = input_get(ictx, 0, 1, 1); 1721 if (n == -1) 1722 break; 1723 1724 m = screen_size_x(s) - s->cx; 1725 if (n > m) 1726 n = m; 1727 1728 if (~ictx->flags & INPUT_LAST) 1729 break; 1730 1731 set = ictx->cell.set == 0 ? ictx->cell.g0set : ictx->cell.g1set; 1732 if (set == 1) 1733 ictx->cell.cell.attr |= GRID_ATTR_CHARSET; 1734 else 1735 ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET; 1736 utf8_copy(&ictx->cell.cell.data, &ictx->last); 1737 for (i = 0; i < n; i++) 1738 screen_write_collect_add(sctx, &ictx->cell.cell); 1739 break; 1740 case INPUT_CSI_RCP: 1741 input_restore_state(ictx); 1742 break; 1743 case INPUT_CSI_RM: 1744 input_csi_dispatch_rm(ictx); 1745 break; 1746 case INPUT_CSI_RM_PRIVATE: 1747 input_csi_dispatch_rm_private(ictx); 1748 break; 1749 case INPUT_CSI_SCP: 1750 input_save_state(ictx); 1751 break; 1752 case INPUT_CSI_SGR: 1753 input_csi_dispatch_sgr(ictx); 1754 break; 1755 case INPUT_CSI_SM: 1756 input_csi_dispatch_sm(ictx); 1757 break; 1758 case INPUT_CSI_SM_PRIVATE: 1759 input_csi_dispatch_sm_private(ictx); 1760 break; 1761 case INPUT_CSI_SM_GRAPHICS: 1762 input_csi_dispatch_sm_graphics(ictx); 1763 break; 1764 case INPUT_CSI_SU: 1765 n = input_get(ictx, 0, 1, 1); 1766 if (n != -1) 1767 screen_write_scrollup(sctx, n, bg); 1768 break; 1769 case INPUT_CSI_SD: 1770 n = input_get(ictx, 0, 1, 1); 1771 if (n != -1) 1772 screen_write_scrolldown(sctx, n, bg); 1773 break; 1774 case INPUT_CSI_TBC: 1775 switch (input_get(ictx, 0, 0, 0)) { 1776 case -1: 1777 break; 1778 case 0: 1779 if (s->cx < screen_size_x(s)) 1780 bit_clear(s->tabs, s->cx); 1781 break; 1782 case 3: 1783 bit_nclear(s->tabs, 0, screen_size_x(s) - 1); 1784 break; 1785 default: 1786 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1787 break; 1788 } 1789 break; 1790 case INPUT_CSI_VPA: 1791 n = input_get(ictx, 0, 1, 1); 1792 if (n != -1) 1793 screen_write_cursormove(sctx, -1, n - 1, 1); 1794 break; 1795 case INPUT_CSI_DECSCUSR: 1796 n = input_get(ictx, 0, 0, 0); 1797 if (n == -1) 1798 break; 1799 screen_set_cursor_style(n, &s->cstyle, &s->mode); 1800 if (n == 0) { 1801 /* Go back to default blinking state. */ 1802 screen_write_mode_clear(sctx, MODE_CURSOR_BLINKING_SET); 1803 } 1804 break; 1805 case INPUT_CSI_XDA: 1806 n = input_get(ictx, 0, 0, 0); 1807 if (n == 0) { 1808 input_reply(ictx, 1, "\033P>|tmux %s\033\\", 1809 getversion()); 1810 } 1811 break; 1812 1813 } 1814 1815 ictx->flags &= ~INPUT_LAST; 1816 return (0); 1817 } 1818 1819 /* Handle CSI RM. */ 1820 static void 1821 input_csi_dispatch_rm(struct input_ctx *ictx) 1822 { 1823 struct screen_write_ctx *sctx = &ictx->ctx; 1824 u_int i; 1825 1826 for (i = 0; i < ictx->param_list_len; i++) { 1827 switch (input_get(ictx, i, 0, -1)) { 1828 case -1: 1829 break; 1830 case 4: /* IRM */ 1831 screen_write_mode_clear(sctx, MODE_INSERT); 1832 break; 1833 case 34: 1834 screen_write_mode_set(sctx, MODE_CURSOR_VERY_VISIBLE); 1835 break; 1836 default: 1837 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1838 break; 1839 } 1840 } 1841 } 1842 1843 /* Handle CSI private RM. */ 1844 static void 1845 input_csi_dispatch_rm_private(struct input_ctx *ictx) 1846 { 1847 struct screen_write_ctx *sctx = &ictx->ctx; 1848 struct grid_cell *gc = &ictx->cell.cell; 1849 u_int i; 1850 1851 for (i = 0; i < ictx->param_list_len; i++) { 1852 switch (input_get(ictx, i, 0, -1)) { 1853 case -1: 1854 break; 1855 case 1: /* DECCKM */ 1856 screen_write_mode_clear(sctx, MODE_KCURSOR); 1857 break; 1858 case 3: /* DECCOLM */ 1859 screen_write_cursormove(sctx, 0, 0, 1); 1860 screen_write_clearscreen(sctx, gc->bg); 1861 break; 1862 case 6: /* DECOM */ 1863 screen_write_mode_clear(sctx, MODE_ORIGIN); 1864 screen_write_cursormove(sctx, 0, 0, 1); 1865 break; 1866 case 7: /* DECAWM */ 1867 screen_write_mode_clear(sctx, MODE_WRAP); 1868 break; 1869 case 12: 1870 screen_write_mode_clear(sctx, MODE_CURSOR_BLINKING); 1871 screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET); 1872 break; 1873 case 25: /* TCEM */ 1874 screen_write_mode_clear(sctx, MODE_CURSOR); 1875 break; 1876 case 1000: 1877 case 1001: 1878 case 1002: 1879 case 1003: 1880 screen_write_mode_clear(sctx, ALL_MOUSE_MODES); 1881 break; 1882 case 1004: 1883 screen_write_mode_clear(sctx, MODE_FOCUSON); 1884 break; 1885 case 1005: 1886 screen_write_mode_clear(sctx, MODE_MOUSE_UTF8); 1887 break; 1888 case 1006: 1889 screen_write_mode_clear(sctx, MODE_MOUSE_SGR); 1890 break; 1891 case 47: 1892 case 1047: 1893 screen_write_alternateoff(sctx, gc, 0); 1894 break; 1895 case 1049: 1896 screen_write_alternateoff(sctx, gc, 1); 1897 break; 1898 case 2004: 1899 screen_write_mode_clear(sctx, MODE_BRACKETPASTE); 1900 break; 1901 case 2031: 1902 screen_write_mode_clear(sctx, MODE_THEME_UPDATES); 1903 break; 1904 default: 1905 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1906 break; 1907 } 1908 } 1909 } 1910 1911 /* Handle CSI SM. */ 1912 static void 1913 input_csi_dispatch_sm(struct input_ctx *ictx) 1914 { 1915 struct screen_write_ctx *sctx = &ictx->ctx; 1916 u_int i; 1917 1918 for (i = 0; i < ictx->param_list_len; i++) { 1919 switch (input_get(ictx, i, 0, -1)) { 1920 case -1: 1921 break; 1922 case 4: /* IRM */ 1923 screen_write_mode_set(sctx, MODE_INSERT); 1924 break; 1925 case 34: 1926 screen_write_mode_clear(sctx, MODE_CURSOR_VERY_VISIBLE); 1927 break; 1928 default: 1929 log_debug("%s: unknown '%c'", __func__, ictx->ch); 1930 break; 1931 } 1932 } 1933 } 1934 1935 /* Handle CSI private SM. */ 1936 static void 1937 input_csi_dispatch_sm_private(struct input_ctx *ictx) 1938 { 1939 struct screen_write_ctx *sctx = &ictx->ctx; 1940 struct grid_cell *gc = &ictx->cell.cell; 1941 u_int i; 1942 1943 for (i = 0; i < ictx->param_list_len; i++) { 1944 switch (input_get(ictx, i, 0, -1)) { 1945 case -1: 1946 break; 1947 case 1: /* DECCKM */ 1948 screen_write_mode_set(sctx, MODE_KCURSOR); 1949 break; 1950 case 3: /* DECCOLM */ 1951 screen_write_cursormove(sctx, 0, 0, 1); 1952 screen_write_clearscreen(sctx, ictx->cell.cell.bg); 1953 break; 1954 case 6: /* DECOM */ 1955 screen_write_mode_set(sctx, MODE_ORIGIN); 1956 screen_write_cursormove(sctx, 0, 0, 1); 1957 break; 1958 case 7: /* DECAWM */ 1959 screen_write_mode_set(sctx, MODE_WRAP); 1960 break; 1961 case 12: 1962 screen_write_mode_set(sctx, MODE_CURSOR_BLINKING); 1963 screen_write_mode_set(sctx, MODE_CURSOR_BLINKING_SET); 1964 break; 1965 case 25: /* TCEM */ 1966 screen_write_mode_set(sctx, MODE_CURSOR); 1967 break; 1968 case 1000: 1969 screen_write_mode_clear(sctx, ALL_MOUSE_MODES); 1970 screen_write_mode_set(sctx, MODE_MOUSE_STANDARD); 1971 break; 1972 case 1002: 1973 screen_write_mode_clear(sctx, ALL_MOUSE_MODES); 1974 screen_write_mode_set(sctx, MODE_MOUSE_BUTTON); 1975 break; 1976 case 1003: 1977 screen_write_mode_clear(sctx, ALL_MOUSE_MODES); 1978 screen_write_mode_set(sctx, MODE_MOUSE_ALL); 1979 break; 1980 case 1004: 1981 screen_write_mode_set(sctx, MODE_FOCUSON); 1982 break; 1983 case 1005: 1984 screen_write_mode_set(sctx, MODE_MOUSE_UTF8); 1985 break; 1986 case 1006: 1987 screen_write_mode_set(sctx, MODE_MOUSE_SGR); 1988 break; 1989 case 47: 1990 case 1047: 1991 screen_write_alternateon(sctx, gc, 0); 1992 break; 1993 case 1049: 1994 screen_write_alternateon(sctx, gc, 1); 1995 break; 1996 case 2004: 1997 screen_write_mode_set(sctx, MODE_BRACKETPASTE); 1998 break; 1999 case 2031: 2000 screen_write_mode_set(sctx, MODE_THEME_UPDATES); 2001 break; 2002 default: 2003 log_debug("%s: unknown '%c'", __func__, ictx->ch); 2004 break; 2005 } 2006 } 2007 } 2008 2009 /* Handle CSI graphics SM. */ 2010 static void 2011 input_csi_dispatch_sm_graphics(__unused struct input_ctx *ictx) 2012 { 2013 #ifdef ENABLE_SIXEL 2014 int n, m, o; 2015 2016 if (ictx->param_list_len > 3) 2017 return; 2018 n = input_get(ictx, 0, 0, 0); 2019 m = input_get(ictx, 1, 0, 0); 2020 o = input_get(ictx, 2, 0, 0); 2021 2022 if (n == 1 && (m == 1 || m == 2 || m == 4)) { 2023 input_reply(ictx, 1, "\033[?%d;0;%uS", n, 2024 SIXEL_COLOUR_REGISTERS); 2025 } else 2026 input_reply(ictx, 1, "\033[?%d;3;%dS", n, o); 2027 #endif 2028 } 2029 2030 /* Handle CSI window operations. */ 2031 static void 2032 input_csi_dispatch_winops(struct input_ctx *ictx) 2033 { 2034 struct screen_write_ctx *sctx = &ictx->ctx; 2035 struct screen *s = sctx->s; 2036 struct window_pane *wp = ictx->wp; 2037 struct window *w = NULL; 2038 u_int x = screen_size_x(s), y = screen_size_y(s); 2039 int n, m; 2040 2041 if (wp != NULL) 2042 w = wp->window; 2043 2044 m = 0; 2045 while ((n = input_get(ictx, m, 0, -1)) != -1) { 2046 switch (n) { 2047 case 1: 2048 case 2: 2049 case 5: 2050 case 6: 2051 case 7: 2052 case 11: 2053 case 13: 2054 case 20: 2055 case 21: 2056 case 24: 2057 break; 2058 case 3: 2059 case 4: 2060 case 8: 2061 m++; 2062 if (input_get(ictx, m, 0, -1) == -1) 2063 return; 2064 /* FALLTHROUGH */ 2065 case 9: 2066 case 10: 2067 m++; 2068 if (input_get(ictx, m, 0, -1) == -1) 2069 return; 2070 break; 2071 case 14: 2072 if (w == NULL) 2073 break; 2074 input_reply(ictx, 1, "\033[4;%u;%ut", y * w->ypixel, 2075 x * w->xpixel); 2076 break; 2077 case 15: 2078 if (w == NULL) 2079 break; 2080 input_reply(ictx, 1, "\033[5;%u;%ut", y * w->ypixel, 2081 x * w->xpixel); 2082 break; 2083 case 16: 2084 if (w == NULL) 2085 break; 2086 input_reply(ictx, 1, "\033[6;%u;%ut", w->ypixel, 2087 w->xpixel); 2088 break; 2089 case 18: 2090 input_reply(ictx, 1, "\033[8;%u;%ut", y, x); 2091 break; 2092 case 19: 2093 input_reply(ictx, 1, "\033[9;%u;%ut", y, x); 2094 break; 2095 case 22: 2096 m++; 2097 switch (input_get(ictx, m, 0, -1)) { 2098 case -1: 2099 return; 2100 case 0: 2101 case 2: 2102 screen_push_title(sctx->s); 2103 break; 2104 } 2105 break; 2106 case 23: 2107 m++; 2108 switch (input_get(ictx, m, 0, -1)) { 2109 case -1: 2110 return; 2111 case 0: 2112 case 2: 2113 screen_pop_title(sctx->s); 2114 if (wp == NULL) 2115 break; 2116 notify_pane("pane-title-changed", wp); 2117 server_redraw_window_borders(w); 2118 server_status_window(w); 2119 break; 2120 } 2121 break; 2122 default: 2123 log_debug("%s: unknown '%c'", __func__, ictx->ch); 2124 break; 2125 } 2126 m++; 2127 } 2128 } 2129 2130 /* Helper for 256 colour SGR. */ 2131 static int 2132 input_csi_dispatch_sgr_256_do(struct input_ctx *ictx, int fgbg, int c) 2133 { 2134 struct grid_cell *gc = &ictx->cell.cell; 2135 2136 if (c == -1 || c > 255) { 2137 if (fgbg == 38) 2138 gc->fg = 8; 2139 else if (fgbg == 48) 2140 gc->bg = 8; 2141 } else { 2142 if (fgbg == 38) 2143 gc->fg = c | COLOUR_FLAG_256; 2144 else if (fgbg == 48) 2145 gc->bg = c | COLOUR_FLAG_256; 2146 else if (fgbg == 58) 2147 gc->us = c | COLOUR_FLAG_256; 2148 } 2149 return (1); 2150 } 2151 2152 /* Handle CSI SGR for 256 colours. */ 2153 static void 2154 input_csi_dispatch_sgr_256(struct input_ctx *ictx, int fgbg, u_int *i) 2155 { 2156 int c; 2157 2158 c = input_get(ictx, (*i) + 1, 0, -1); 2159 if (input_csi_dispatch_sgr_256_do(ictx, fgbg, c)) 2160 (*i)++; 2161 } 2162 2163 /* Helper for RGB colour SGR. */ 2164 static int 2165 input_csi_dispatch_sgr_rgb_do(struct input_ctx *ictx, int fgbg, int r, int g, 2166 int b) 2167 { 2168 struct grid_cell *gc = &ictx->cell.cell; 2169 2170 if (r == -1 || r > 255) 2171 return (0); 2172 if (g == -1 || g > 255) 2173 return (0); 2174 if (b == -1 || b > 255) 2175 return (0); 2176 2177 if (fgbg == 38) 2178 gc->fg = colour_join_rgb(r, g, b); 2179 else if (fgbg == 48) 2180 gc->bg = colour_join_rgb(r, g, b); 2181 else if (fgbg == 58) 2182 gc->us = colour_join_rgb(r, g, b); 2183 return (1); 2184 } 2185 2186 /* Handle CSI SGR for RGB colours. */ 2187 static void 2188 input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i) 2189 { 2190 int r, g, b; 2191 2192 r = input_get(ictx, (*i) + 1, 0, -1); 2193 g = input_get(ictx, (*i) + 2, 0, -1); 2194 b = input_get(ictx, (*i) + 3, 0, -1); 2195 if (input_csi_dispatch_sgr_rgb_do(ictx, fgbg, r, g, b)) 2196 (*i) += 3; 2197 } 2198 2199 /* Handle CSI SGR with a ISO parameter. */ 2200 static void 2201 input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i) 2202 { 2203 struct grid_cell *gc = &ictx->cell.cell; 2204 char *s = ictx->param_list[i].str, *copy, *ptr, *out; 2205 int p[8]; 2206 u_int n; 2207 const char *errstr; 2208 2209 for (n = 0; n < nitems(p); n++) 2210 p[n] = -1; 2211 n = 0; 2212 2213 ptr = copy = xstrdup(s); 2214 while ((out = strsep(&ptr, ":")) != NULL) { 2215 if (*out != '\0') { 2216 p[n++] = strtonum(out, 0, INT_MAX, &errstr); 2217 if (errstr != NULL || n == nitems(p)) { 2218 free(copy); 2219 return; 2220 } 2221 } else { 2222 n++; 2223 if (n == nitems(p)) { 2224 free(copy); 2225 return; 2226 } 2227 } 2228 log_debug("%s: %u = %d", __func__, n - 1, p[n - 1]); 2229 } 2230 free(copy); 2231 2232 if (n == 0) 2233 return; 2234 if (p[0] == 4) { 2235 if (n != 2) 2236 return; 2237 switch (p[1]) { 2238 case 0: 2239 gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; 2240 break; 2241 case 1: 2242 gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; 2243 gc->attr |= GRID_ATTR_UNDERSCORE; 2244 break; 2245 case 2: 2246 gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; 2247 gc->attr |= GRID_ATTR_UNDERSCORE_2; 2248 break; 2249 case 3: 2250 gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; 2251 gc->attr |= GRID_ATTR_UNDERSCORE_3; 2252 break; 2253 case 4: 2254 gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; 2255 gc->attr |= GRID_ATTR_UNDERSCORE_4; 2256 break; 2257 case 5: 2258 gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; 2259 gc->attr |= GRID_ATTR_UNDERSCORE_5; 2260 break; 2261 } 2262 return; 2263 } 2264 if (n < 2 || (p[0] != 38 && p[0] != 48 && p[0] != 58)) 2265 return; 2266 switch (p[1]) { 2267 case 2: 2268 if (n < 3) 2269 break; 2270 if (n == 5) 2271 i = 2; 2272 else 2273 i = 3; 2274 if (n < i + 3) 2275 break; 2276 input_csi_dispatch_sgr_rgb_do(ictx, p[0], p[i], p[i + 1], 2277 p[i + 2]); 2278 break; 2279 case 5: 2280 if (n < 3) 2281 break; 2282 input_csi_dispatch_sgr_256_do(ictx, p[0], p[2]); 2283 break; 2284 } 2285 } 2286 2287 /* Handle CSI SGR. */ 2288 static void 2289 input_csi_dispatch_sgr(struct input_ctx *ictx) 2290 { 2291 struct grid_cell *gc = &ictx->cell.cell; 2292 u_int i, link; 2293 int n; 2294 2295 if (ictx->param_list_len == 0) { 2296 memcpy(gc, &grid_default_cell, sizeof *gc); 2297 return; 2298 } 2299 2300 for (i = 0; i < ictx->param_list_len; i++) { 2301 if (ictx->param_list[i].type == INPUT_STRING) { 2302 input_csi_dispatch_sgr_colon(ictx, i); 2303 continue; 2304 } 2305 n = input_get(ictx, i, 0, 0); 2306 if (n == -1) 2307 continue; 2308 2309 if (n == 38 || n == 48 || n == 58) { 2310 i++; 2311 switch (input_get(ictx, i, 0, -1)) { 2312 case 2: 2313 input_csi_dispatch_sgr_rgb(ictx, n, &i); 2314 break; 2315 case 5: 2316 input_csi_dispatch_sgr_256(ictx, n, &i); 2317 break; 2318 } 2319 continue; 2320 } 2321 2322 switch (n) { 2323 case 0: 2324 link = gc->link; 2325 memcpy(gc, &grid_default_cell, sizeof *gc); 2326 gc->link = link; 2327 break; 2328 case 1: 2329 gc->attr |= GRID_ATTR_BRIGHT; 2330 break; 2331 case 2: 2332 gc->attr |= GRID_ATTR_DIM; 2333 break; 2334 case 3: 2335 gc->attr |= GRID_ATTR_ITALICS; 2336 break; 2337 case 4: 2338 gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; 2339 gc->attr |= GRID_ATTR_UNDERSCORE; 2340 break; 2341 case 5: 2342 case 6: 2343 gc->attr |= GRID_ATTR_BLINK; 2344 break; 2345 case 7: 2346 gc->attr |= GRID_ATTR_REVERSE; 2347 break; 2348 case 8: 2349 gc->attr |= GRID_ATTR_HIDDEN; 2350 break; 2351 case 9: 2352 gc->attr |= GRID_ATTR_STRIKETHROUGH; 2353 break; 2354 case 21: 2355 gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; 2356 gc->attr |= GRID_ATTR_UNDERSCORE_2; 2357 break; 2358 case 22: 2359 gc->attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_DIM); 2360 break; 2361 case 23: 2362 gc->attr &= ~GRID_ATTR_ITALICS; 2363 break; 2364 case 24: 2365 gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; 2366 break; 2367 case 25: 2368 gc->attr &= ~GRID_ATTR_BLINK; 2369 break; 2370 case 27: 2371 gc->attr &= ~GRID_ATTR_REVERSE; 2372 break; 2373 case 28: 2374 gc->attr &= ~GRID_ATTR_HIDDEN; 2375 break; 2376 case 29: 2377 gc->attr &= ~GRID_ATTR_STRIKETHROUGH; 2378 break; 2379 case 30: 2380 case 31: 2381 case 32: 2382 case 33: 2383 case 34: 2384 case 35: 2385 case 36: 2386 case 37: 2387 gc->fg = n - 30; 2388 break; 2389 case 39: 2390 gc->fg = 8; 2391 break; 2392 case 40: 2393 case 41: 2394 case 42: 2395 case 43: 2396 case 44: 2397 case 45: 2398 case 46: 2399 case 47: 2400 gc->bg = n - 40; 2401 break; 2402 case 49: 2403 gc->bg = 8; 2404 break; 2405 case 53: 2406 gc->attr |= GRID_ATTR_OVERLINE; 2407 break; 2408 case 55: 2409 gc->attr &= ~GRID_ATTR_OVERLINE; 2410 break; 2411 case 59: 2412 gc->us = 8; 2413 break; 2414 case 90: 2415 case 91: 2416 case 92: 2417 case 93: 2418 case 94: 2419 case 95: 2420 case 96: 2421 case 97: 2422 gc->fg = n; 2423 break; 2424 case 100: 2425 case 101: 2426 case 102: 2427 case 103: 2428 case 104: 2429 case 105: 2430 case 106: 2431 case 107: 2432 gc->bg = n - 10; 2433 break; 2434 } 2435 } 2436 } 2437 2438 /* End of input with BEL. */ 2439 static int 2440 input_end_bel(struct input_ctx *ictx) 2441 { 2442 log_debug("%s", __func__); 2443 2444 ictx->input_end = INPUT_END_BEL; 2445 2446 return (0); 2447 } 2448 2449 /* DCS string started. */ 2450 static void 2451 input_enter_dcs(struct input_ctx *ictx) 2452 { 2453 log_debug("%s", __func__); 2454 2455 input_clear(ictx); 2456 input_start_ground_timer(ictx); 2457 ictx->flags &= ~INPUT_LAST; 2458 } 2459 2460 /* Handle DECRQSS query. */ 2461 static int 2462 input_handle_decrqss(struct input_ctx *ictx) 2463 { 2464 struct window_pane *wp = ictx->wp; 2465 struct options *oo; 2466 struct screen_write_ctx *sctx = &ictx->ctx; 2467 u_char *buf = ictx->input_buf; 2468 size_t len = ictx->input_len; 2469 struct screen *s = sctx->s; 2470 int ps, opt_ps, blinking; 2471 2472 if (len < 3 || buf[1] != ' ' || buf[2] != 'q') 2473 goto not_recognized; 2474 2475 /* 2476 * Cursor style query: DCS $ q SP q 2477 * Reply: DCS 1 $ r SP q <Ps> SP q ST 2478 */ 2479 if (s->cstyle == SCREEN_CURSOR_BLOCK || 2480 s->cstyle == SCREEN_CURSOR_UNDERLINE || 2481 s->cstyle == SCREEN_CURSOR_BAR) { 2482 blinking = (s->mode & MODE_CURSOR_BLINKING) != 0; 2483 switch (s->cstyle) { 2484 case SCREEN_CURSOR_BLOCK: 2485 ps = blinking ? 1 : 2; 2486 break; 2487 case SCREEN_CURSOR_UNDERLINE: 2488 ps = blinking ? 3 : 4; 2489 break; 2490 case SCREEN_CURSOR_BAR: 2491 ps = blinking ? 5 : 6; 2492 break; 2493 default: 2494 ps = 0; 2495 break; 2496 } 2497 } else { 2498 /* 2499 * No explicit runtime style: fall back to the configured 2500 * cursor-style option (integer Ps 0..6). Pane options inherit. 2501 */ 2502 if (wp != NULL) 2503 oo = wp->options; 2504 else 2505 oo = global_options; 2506 opt_ps = options_get_number(oo, "cursor-style"); 2507 2508 /* Sanity clamp: valid Ps are 0..6 per DECSCUSR. */ 2509 if (opt_ps < 0 || opt_ps > 6) 2510 opt_ps = 0; 2511 ps = opt_ps; 2512 } 2513 2514 log_debug("%s: DECRQSS cursor -> Ps=%d (cstyle=%d mode=%#x)", __func__, 2515 ps, s->cstyle, s->mode); 2516 2517 input_reply(ictx, 1, "\033P1$r q%d q\033\\", ps); 2518 return (0); 2519 2520 not_recognized: 2521 /* Unrecognized DECRQSS: send DCS 0 $ r Pt ST. */ 2522 input_reply(ictx, 1, "\033P0$r\033\\"); 2523 return (0); 2524 } 2525 2526 /* DCS terminator (ST) received. */ 2527 static int 2528 input_dcs_dispatch(struct input_ctx *ictx) 2529 { 2530 struct window_pane *wp = ictx->wp; 2531 struct options *oo; 2532 struct screen_write_ctx *sctx = &ictx->ctx; 2533 char *buf = (char *)ictx->input_buf; 2534 size_t len = ictx->input_len; 2535 const char prefix[] = "tmux;"; 2536 const u_int prefixlen = (sizeof prefix) - 1; 2537 long long allow_passthrough = 0; 2538 #ifdef ENABLE_SIXEL 2539 struct window *w; 2540 struct sixel_image *si; 2541 int p2; 2542 #endif 2543 2544 if (wp == NULL) 2545 return (0); 2546 oo = wp->options; 2547 2548 if (ictx->flags & INPUT_DISCARD) { 2549 log_debug("%s: %zu bytes (discard)", __func__, len); 2550 return (0); 2551 } 2552 2553 #ifdef ENABLE_SIXEL 2554 w = wp->window; 2555 if (buf[0] == 'q' && ictx->interm_len == 0) { 2556 if (input_split(ictx) != 0) 2557 return (0); 2558 p2 = input_get(ictx, 1, 0, 0); 2559 if (p2 == -1) 2560 p2 = 0; 2561 si = sixel_parse(buf, len, p2, w->xpixel, w->ypixel); 2562 if (si != NULL) 2563 screen_write_sixelimage(sctx, si, ictx->cell.cell.bg); 2564 } 2565 #endif 2566 2567 /* DCS sequences with intermediate byte '$' (includes DECRQSS). */ 2568 if (ictx->interm_len == 1 && ictx->interm_buf[0] == '$') { 2569 /* DECRQSS is DCS $ q Pt ST. */ 2570 if (len >= 1 && buf[0] == 'q') 2571 return (input_handle_decrqss(ictx)); 2572 2573 /* 2574 * Not DECRQSS. DCS '$' is currently only used by DECRQSS, but 2575 * leave other '$' DCS (if any appear in future) to existing 2576 * handlers. 2577 */ 2578 } 2579 2580 allow_passthrough = options_get_number(oo, "allow-passthrough"); 2581 if (!allow_passthrough) 2582 return (0); 2583 log_debug("%s: \"%s\"", __func__, buf); 2584 2585 if (len >= prefixlen && strncmp(buf, prefix, prefixlen) == 0) { 2586 screen_write_rawstring(sctx, (u_char *)buf + prefixlen, len - prefixlen, 2587 allow_passthrough == 2); 2588 } 2589 2590 return (0); 2591 } 2592 2593 /* OSC string started. */ 2594 static void 2595 input_enter_osc(struct input_ctx *ictx) 2596 { 2597 log_debug("%s", __func__); 2598 2599 input_clear(ictx); 2600 input_start_ground_timer(ictx); 2601 ictx->flags &= ~INPUT_LAST; 2602 } 2603 2604 /* OSC terminator (ST) received. */ 2605 static void 2606 input_exit_osc(struct input_ctx *ictx) 2607 { 2608 struct screen_write_ctx *sctx = &ictx->ctx; 2609 struct window_pane *wp = ictx->wp; 2610 char *p = (char *)ictx->input_buf; 2611 u_int option; 2612 2613 if (ictx->flags & INPUT_DISCARD) 2614 return; 2615 if (ictx->input_len < 1 || *p < '0' || *p > '9') 2616 return; 2617 2618 log_debug("%s: \"%s\" (end %s)", __func__, p, 2619 ictx->input_end == INPUT_END_ST ? "ST" : "BEL"); 2620 2621 option = 0; 2622 while (*p >= '0' && *p <= '9') 2623 option = option * 10 + *p++ - '0'; 2624 if (*p != ';' && *p != '\0') 2625 return; 2626 if (*p == ';') 2627 p++; 2628 2629 switch (option) { 2630 case 0: 2631 case 2: 2632 if (wp != NULL && 2633 options_get_number(wp->options, "allow-set-title") && 2634 screen_set_title(sctx->s, p)) { 2635 notify_pane("pane-title-changed", wp); 2636 server_redraw_window_borders(wp->window); 2637 server_status_window(wp->window); 2638 } 2639 break; 2640 case 4: 2641 input_osc_4(ictx, p); 2642 break; 2643 case 7: 2644 if (utf8_isvalid(p)) { 2645 screen_set_path(sctx->s, p); 2646 if (wp != NULL) { 2647 server_redraw_window_borders(wp->window); 2648 server_status_window(wp->window); 2649 } 2650 } 2651 break; 2652 case 8: 2653 input_osc_8(ictx, p); 2654 break; 2655 case 10: 2656 input_osc_10(ictx, p); 2657 break; 2658 case 11: 2659 input_osc_11(ictx, p); 2660 break; 2661 case 12: 2662 input_osc_12(ictx, p); 2663 break; 2664 case 52: 2665 input_osc_52(ictx, p); 2666 break; 2667 case 104: 2668 input_osc_104(ictx, p); 2669 break; 2670 case 110: 2671 input_osc_110(ictx, p); 2672 break; 2673 case 111: 2674 input_osc_111(ictx, p); 2675 break; 2676 case 112: 2677 input_osc_112(ictx, p); 2678 break; 2679 case 133: 2680 input_osc_133(ictx, p); 2681 break; 2682 default: 2683 log_debug("%s: unknown '%u'", __func__, option); 2684 break; 2685 } 2686 } 2687 2688 /* APC string started. */ 2689 static void 2690 input_enter_apc(struct input_ctx *ictx) 2691 { 2692 log_debug("%s", __func__); 2693 2694 input_clear(ictx); 2695 input_start_ground_timer(ictx); 2696 ictx->flags &= ~INPUT_LAST; 2697 } 2698 2699 /* APC terminator (ST) received. */ 2700 static void 2701 input_exit_apc(struct input_ctx *ictx) 2702 { 2703 struct screen_write_ctx *sctx = &ictx->ctx; 2704 struct window_pane *wp = ictx->wp; 2705 char *p = (char *)ictx->input_buf; 2706 2707 if (ictx->flags & INPUT_DISCARD) 2708 return; 2709 log_debug("%s: \"%s\"", __func__, p); 2710 2711 if (wp != NULL && 2712 options_get_number(wp->options, "allow-set-title") && 2713 screen_set_title(sctx->s, p)) { 2714 notify_pane("pane-title-changed", wp); 2715 server_redraw_window_borders(wp->window); 2716 server_status_window(wp->window); 2717 } 2718 } 2719 2720 /* Rename string started. */ 2721 static void 2722 input_enter_rename(struct input_ctx *ictx) 2723 { 2724 log_debug("%s", __func__); 2725 2726 input_clear(ictx); 2727 input_start_ground_timer(ictx); 2728 ictx->flags &= ~INPUT_LAST; 2729 } 2730 2731 /* Rename terminator (ST) received. */ 2732 static void 2733 input_exit_rename(struct input_ctx *ictx) 2734 { 2735 struct window_pane *wp = ictx->wp; 2736 struct window *w; 2737 struct options_entry *o; 2738 char *p = (char *)ictx->input_buf; 2739 2740 if (wp == NULL) 2741 return; 2742 if (ictx->flags & INPUT_DISCARD) 2743 return; 2744 if (!options_get_number(ictx->wp->options, "allow-rename")) 2745 return; 2746 log_debug("%s: \"%s\"", __func__, p); 2747 2748 if (!utf8_isvalid(p)) 2749 return; 2750 w = wp->window; 2751 2752 if (ictx->input_len == 0) { 2753 o = options_get_only(w->options, "automatic-rename"); 2754 if (o != NULL) 2755 options_remove_or_default(o, -1, NULL); 2756 if (!options_get_number(w->options, "automatic-rename")) 2757 window_set_name(w, ""); 2758 } else { 2759 options_set_number(w->options, "automatic-rename", 0); 2760 window_set_name(w, ictx->input_buf); 2761 } 2762 server_redraw_window_borders(w); 2763 server_status_window(w); 2764 } 2765 2766 /* Open UTF-8 character. */ 2767 static int 2768 input_top_bit_set(struct input_ctx *ictx) 2769 { 2770 struct screen_write_ctx *sctx = &ictx->ctx; 2771 struct utf8_data *ud = &ictx->utf8data; 2772 2773 ictx->flags &= ~INPUT_LAST; 2774 2775 if (!ictx->utf8started) { 2776 ictx->utf8started = 1; 2777 if (utf8_open(ud, ictx->ch) != UTF8_MORE) 2778 input_stop_utf8(ictx); 2779 return (0); 2780 } 2781 2782 switch (utf8_append(ud, ictx->ch)) { 2783 case UTF8_MORE: 2784 return (0); 2785 case UTF8_ERROR: 2786 input_stop_utf8(ictx); 2787 return (0); 2788 case UTF8_DONE: 2789 break; 2790 } 2791 ictx->utf8started = 0; 2792 2793 log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size, 2794 (int)ud->size, ud->data, ud->width); 2795 2796 utf8_copy(&ictx->cell.cell.data, ud); 2797 screen_write_collect_add(sctx, &ictx->cell.cell); 2798 2799 utf8_copy(&ictx->last, &ictx->cell.cell.data); 2800 ictx->flags |= INPUT_LAST; 2801 2802 return (0); 2803 } 2804 2805 /* Reply to a colour request. */ 2806 static void 2807 input_osc_colour_reply(struct input_ctx *ictx, int add, u_int n, int idx, int c, 2808 enum input_end_type end_type) 2809 { 2810 u_char r, g, b; 2811 const char *end; 2812 2813 if (c != -1) 2814 c = colour_force_rgb(c); 2815 if (c == -1) 2816 return; 2817 colour_split_rgb(c, &r, &g, &b); 2818 2819 if (end_type == INPUT_END_BEL) 2820 end = "\007"; 2821 else 2822 end = "\033\\"; 2823 2824 if (n == 4) { 2825 input_reply(ictx, add, 2826 "\033]%u;%d;rgb:%02hhx%02hhx/%02hhx%02hhx/%02hhx%02hhx%s", 2827 n, idx, r, r, g, g, b, b, end); 2828 } else { 2829 input_reply(ictx, add, 2830 "\033]%u;rgb:%02hhx%02hhx/%02hhx%02hhx/%02hhx%02hhx%s", 2831 n, r, r, g, g, b, b, end); 2832 } 2833 } 2834 2835 /* Handle the OSC 4 sequence for setting (multiple) palette entries. */ 2836 static void 2837 input_osc_4(struct input_ctx *ictx, const char *p) 2838 { 2839 char *copy, *s, *next = NULL; 2840 long idx; 2841 int c, bad = 0, redraw = 0; 2842 struct colour_palette *palette = ictx->palette; 2843 2844 copy = s = xstrdup(p); 2845 while (s != NULL && *s != '\0') { 2846 idx = strtol(s, &next, 10); 2847 if (*next++ != ';') { 2848 bad = 1; 2849 break; 2850 } 2851 if (idx < 0 || idx >= 256) { 2852 bad = 1; 2853 break; 2854 } 2855 2856 s = strsep(&next, ";"); 2857 if (strcmp(s, "?") == 0) { 2858 c = colour_palette_get(palette, idx|COLOUR_FLAG_256); 2859 if (c != -1) { 2860 input_osc_colour_reply(ictx, 1, 4, idx, c, 2861 ictx->input_end); 2862 s = next; 2863 continue; 2864 } 2865 input_add_request(ictx, INPUT_REQUEST_PALETTE, idx); 2866 s = next; 2867 continue; 2868 } 2869 if ((c = colour_parseX11(s)) == -1) { 2870 s = next; 2871 continue; 2872 } 2873 if (colour_palette_set(palette, idx, c)) 2874 redraw = 1; 2875 s = next; 2876 } 2877 if (bad) 2878 log_debug("bad OSC 4: %s", p); 2879 if (redraw) 2880 screen_write_fullredraw(&ictx->ctx); 2881 free(copy); 2882 } 2883 2884 /* Handle the OSC 8 sequence for embedding hyperlinks. */ 2885 static void 2886 input_osc_8(struct input_ctx *ictx, const char *p) 2887 { 2888 struct hyperlinks *hl = ictx->ctx.s->hyperlinks; 2889 struct grid_cell *gc = &ictx->cell.cell; 2890 const char *start, *end, *uri; 2891 char *id = NULL; 2892 2893 for (start = p; (end = strpbrk(start, ":;")) != NULL; start = end + 1) { 2894 if (end - start >= 4 && strncmp(start, "id=", 3) == 0) { 2895 if (id != NULL) 2896 goto bad; 2897 id = xstrndup(start + 3, end - start - 3); 2898 } 2899 2900 /* The first ; is the end of parameters and start of the URI. */ 2901 if (*end == ';') 2902 break; 2903 } 2904 if (end == NULL || *end != ';') 2905 goto bad; 2906 uri = end + 1; 2907 if (*uri == '\0') { 2908 gc->link = 0; 2909 free(id); 2910 return; 2911 } 2912 gc->link = hyperlinks_put(hl, uri, id); 2913 if (id == NULL) 2914 log_debug("hyperlink (anonymous) %s = %u", uri, gc->link); 2915 else 2916 log_debug("hyperlink (id=%s) %s = %u", id, uri, gc->link); 2917 free(id); 2918 return; 2919 2920 bad: 2921 log_debug("bad OSC 8 %s", p); 2922 free(id); 2923 } 2924 2925 2926 /* Handle the OSC 10 sequence for setting and querying foreground colour. */ 2927 static void 2928 input_osc_10(struct input_ctx *ictx, const char *p) 2929 { 2930 struct window_pane *wp = ictx->wp; 2931 struct grid_cell defaults; 2932 int c; 2933 2934 if (strcmp(p, "?") == 0) { 2935 if (wp == NULL) 2936 return; 2937 c = window_pane_get_fg_control_client(wp); 2938 if (c == -1) { 2939 tty_default_colours(&defaults, wp); 2940 if (COLOUR_DEFAULT(defaults.fg)) 2941 c = window_pane_get_fg(wp); 2942 else 2943 c = defaults.fg; 2944 } 2945 input_osc_colour_reply(ictx, 1, 10, 0, c, ictx->input_end); 2946 return; 2947 } 2948 2949 if ((c = colour_parseX11(p)) == -1) { 2950 log_debug("bad OSC 10: %s", p); 2951 return; 2952 } 2953 if (ictx->palette != NULL) { 2954 ictx->palette->fg = c; 2955 if (wp != NULL) 2956 wp->flags |= PANE_STYLECHANGED; 2957 screen_write_fullredraw(&ictx->ctx); 2958 } 2959 } 2960 2961 /* Handle the OSC 110 sequence for resetting foreground colour. */ 2962 static void 2963 input_osc_110(struct input_ctx *ictx, const char *p) 2964 { 2965 struct window_pane *wp = ictx->wp; 2966 2967 if (*p != '\0') 2968 return; 2969 if (ictx->palette != NULL) { 2970 ictx->palette->fg = 8; 2971 if (wp != NULL) 2972 wp->flags |= PANE_STYLECHANGED; 2973 screen_write_fullredraw(&ictx->ctx); 2974 } 2975 } 2976 2977 /* Handle the OSC 11 sequence for setting and querying background colour. */ 2978 static void 2979 input_osc_11(struct input_ctx *ictx, const char *p) 2980 { 2981 struct window_pane *wp = ictx->wp; 2982 int c; 2983 2984 if (strcmp(p, "?") == 0) { 2985 if (wp == NULL) 2986 return; 2987 c = window_pane_get_bg(wp); 2988 input_osc_colour_reply(ictx, 1, 11, 0, c, ictx->input_end); 2989 return; 2990 } 2991 2992 if ((c = colour_parseX11(p)) == -1) { 2993 log_debug("bad OSC 11: %s", p); 2994 return; 2995 } 2996 if (ictx->palette != NULL) { 2997 ictx->palette->bg = c; 2998 if (wp != NULL) 2999 wp->flags |= (PANE_STYLECHANGED|PANE_THEMECHANGED); 3000 screen_write_fullredraw(&ictx->ctx); 3001 } 3002 } 3003 3004 /* Handle the OSC 111 sequence for resetting background colour. */ 3005 static void 3006 input_osc_111(struct input_ctx *ictx, const char *p) 3007 { 3008 struct window_pane *wp = ictx->wp; 3009 3010 if (*p != '\0') 3011 return; 3012 if (ictx->palette != NULL) { 3013 ictx->palette->bg = 8; 3014 if (wp != NULL) 3015 wp->flags |= (PANE_STYLECHANGED|PANE_THEMECHANGED); 3016 screen_write_fullredraw(&ictx->ctx); 3017 } 3018 } 3019 3020 /* Handle the OSC 12 sequence for setting and querying cursor colour. */ 3021 static void 3022 input_osc_12(struct input_ctx *ictx, const char *p) 3023 { 3024 struct window_pane *wp = ictx->wp; 3025 int c; 3026 3027 if (strcmp(p, "?") == 0) { 3028 if (wp != NULL) { 3029 c = ictx->ctx.s->ccolour; 3030 if (c == -1) 3031 c = ictx->ctx.s->default_ccolour; 3032 input_osc_colour_reply(ictx, 1, 12, 0, c, ictx->input_end); 3033 } 3034 return; 3035 } 3036 3037 if ((c = colour_parseX11(p)) == -1) { 3038 log_debug("bad OSC 12: %s", p); 3039 return; 3040 } 3041 screen_set_cursor_colour(ictx->ctx.s, c); 3042 } 3043 3044 /* Handle the OSC 112 sequence for resetting cursor colour. */ 3045 static void 3046 input_osc_112(struct input_ctx *ictx, const char *p) 3047 { 3048 if (*p == '\0') /* no arguments allowed */ 3049 screen_set_cursor_colour(ictx->ctx.s, -1); 3050 } 3051 3052 /* Handle the OSC 133 sequence. */ 3053 static void 3054 input_osc_133(struct input_ctx *ictx, const char *p) 3055 { 3056 struct grid *gd = ictx->ctx.s->grid; 3057 u_int line = ictx->ctx.s->cy + gd->hsize; 3058 struct grid_line *gl; 3059 3060 if (line > gd->hsize + gd->sy - 1) 3061 return; 3062 gl = grid_get_line(gd, line); 3063 3064 switch (*p) { 3065 case 'A': 3066 gl->flags |= GRID_LINE_START_PROMPT; 3067 break; 3068 case 'C': 3069 gl->flags |= GRID_LINE_START_OUTPUT; 3070 break; 3071 } 3072 } 3073 3074 /* Handle the OSC 52 sequence for setting the clipboard. */ 3075 static void 3076 input_osc_52(struct input_ctx *ictx, const char *p) 3077 { 3078 struct window_pane *wp = ictx->wp; 3079 char *end; 3080 const char *buf = NULL; 3081 size_t len = 0; 3082 u_char *out; 3083 int outlen, state; 3084 struct screen_write_ctx ctx; 3085 struct paste_buffer *pb; 3086 const char* allow = "cpqs01234567"; 3087 char flags[sizeof "cpqs01234567"] = ""; 3088 u_int i, j = 0; 3089 3090 if (wp == NULL) 3091 return; 3092 state = options_get_number(global_options, "set-clipboard"); 3093 if (state != 2) 3094 return; 3095 3096 if ((end = strchr(p, ';')) == NULL) 3097 return; 3098 end++; 3099 if (*end == '\0') 3100 return; 3101 log_debug("%s: %s", __func__, end); 3102 3103 for (i = 0; p + i != end; i++) { 3104 if (strchr(allow, p[i]) != NULL && strchr(flags, p[i]) == NULL) 3105 flags[j++] = p[i]; 3106 } 3107 log_debug("%s: %.*s %s", __func__, (int)(end - p - 1), p, flags); 3108 3109 if (strcmp(end, "?") == 0) { 3110 if ((pb = paste_get_top(NULL)) != NULL) 3111 buf = paste_buffer_data(pb, &len); 3112 if (ictx->input_end == INPUT_END_BEL) 3113 input_reply_clipboard(ictx->event, buf, len, "\007"); 3114 else 3115 input_reply_clipboard(ictx->event, buf, len, "\033\\"); 3116 return; 3117 } 3118 3119 len = (strlen(end) / 4) * 3; 3120 if (len == 0) 3121 return; 3122 3123 out = xmalloc(len); 3124 if ((outlen = b64_pton(end, out, len)) == -1) { 3125 free(out); 3126 return; 3127 } 3128 3129 screen_write_start_pane(&ctx, wp, NULL); 3130 screen_write_setselection(&ctx, flags, out, outlen); 3131 screen_write_stop(&ctx); 3132 notify_pane("pane-set-clipboard", wp); 3133 3134 paste_add(NULL, (char *)out, outlen); 3135 } 3136 3137 /* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */ 3138 static void 3139 input_osc_104(struct input_ctx *ictx, const char *p) 3140 { 3141 char *copy, *s; 3142 long idx; 3143 int bad = 0, redraw = 0; 3144 3145 if (*p == '\0') { 3146 colour_palette_clear(ictx->palette); 3147 screen_write_fullredraw(&ictx->ctx); 3148 return; 3149 } 3150 3151 copy = s = xstrdup(p); 3152 while (*s != '\0') { 3153 idx = strtol(s, &s, 10); 3154 if (*s != '\0' && *s != ';') { 3155 bad = 1; 3156 break; 3157 } 3158 if (idx < 0 || idx >= 256) { 3159 bad = 1; 3160 break; 3161 } 3162 if (colour_palette_set(ictx->palette, idx, -1)) 3163 redraw = 1; 3164 if (*s == ';') 3165 s++; 3166 } 3167 if (bad) 3168 log_debug("bad OSC 104: %s", p); 3169 if (redraw) 3170 screen_write_fullredraw(&ictx->ctx); 3171 free(copy); 3172 } 3173 3174 void 3175 input_reply_clipboard(struct bufferevent *bev, const char *buf, size_t len, 3176 const char *end) 3177 { 3178 char *out = NULL; 3179 int outlen = 0; 3180 3181 if (buf != NULL && len != 0) { 3182 if (len >= ((size_t)INT_MAX * 3 / 4) - 1) 3183 return; 3184 outlen = 4 * ((len + 2) / 3) + 1; 3185 out = xmalloc(outlen); 3186 if ((outlen = b64_ntop(buf, len, out, outlen)) == -1) { 3187 free(out); 3188 return; 3189 } 3190 } 3191 3192 bufferevent_write(bev, "\033]52;;", 6); 3193 if (outlen != 0) 3194 bufferevent_write(bev, out, outlen); 3195 bufferevent_write(bev, end, strlen(end)); 3196 free(out); 3197 } 3198 3199 /* Set input buffer size. */ 3200 void 3201 input_set_buffer_size(size_t buffer_size) 3202 { 3203 log_debug("%s: %zu -> %zu", __func__, input_buffer_size, buffer_size); 3204 input_buffer_size = buffer_size; 3205 } 3206 3207 /* Request timer. Remove any requests that are too old. */ 3208 static void 3209 input_request_timer_callback(__unused int fd, __unused short events, void *arg) 3210 { 3211 struct input_ctx *ictx = arg; 3212 struct input_request *ir, *ir1; 3213 time_t t = time(NULL); 3214 3215 TAILQ_FOREACH_SAFE(ir, &ictx->requests, entry, ir1) { 3216 if (ir->t >= t - INPUT_REQUEST_TIMEOUT) 3217 continue; 3218 if (ir->type == INPUT_REQUEST_QUEUE) 3219 input_send_reply(ir->ictx, ir->data); 3220 input_free_request(ir); 3221 } 3222 if (ictx->request_count != 0) 3223 input_start_request_timer(ictx); 3224 } 3225 3226 /* Start the request timer. */ 3227 static void 3228 input_start_request_timer(struct input_ctx *ictx) 3229 { 3230 struct timeval tv = { .tv_sec = 0, .tv_usec = 500000 }; 3231 3232 event_del(&ictx->request_timer); 3233 event_add(&ictx->request_timer, &tv); 3234 } 3235 3236 /* Create a request. */ 3237 static struct input_request * 3238 input_make_request(struct input_ctx *ictx, enum input_request_type type) 3239 { 3240 struct input_request *ir; 3241 3242 ir = xcalloc (1, sizeof *ir); 3243 ir->type = type; 3244 ir->ictx = ictx; 3245 ir->t = time(NULL); 3246 3247 if (++ictx->request_count == 1) 3248 input_start_request_timer(ictx); 3249 TAILQ_INSERT_TAIL(&ictx->requests, ir, entry); 3250 3251 return (ir); 3252 } 3253 3254 /* Free a request. */ 3255 static void 3256 input_free_request(struct input_request *ir) 3257 { 3258 struct input_ctx *ictx = ir->ictx; 3259 3260 if (ir->c != NULL) 3261 TAILQ_REMOVE(&ir->c->input_requests, ir, centry); 3262 3263 ictx->request_count--; 3264 TAILQ_REMOVE(&ictx->requests, ir, entry); 3265 3266 free(ir->data); 3267 free(ir); 3268 } 3269 3270 /* Add a request. */ 3271 static int 3272 input_add_request(struct input_ctx *ictx, enum input_request_type type, int idx) 3273 { 3274 struct window_pane *wp = ictx->wp; 3275 struct window *w; 3276 struct client *c = NULL, *loop; 3277 struct input_request *ir; 3278 char s[64]; 3279 3280 if (wp == NULL) 3281 return (-1); 3282 w = wp->window; 3283 3284 TAILQ_FOREACH(loop, &clients, entry) { 3285 if (loop->flags & CLIENT_UNATTACHEDFLAGS) 3286 continue; 3287 if (loop->session == NULL || !session_has(loop->session, w)) 3288 continue; 3289 if (~loop->tty.flags & TTY_STARTED) 3290 continue; 3291 if (c == NULL) 3292 c = loop; 3293 else if (timercmp(&loop->activity_time, &c->activity_time, >)) 3294 c = loop; 3295 } 3296 if (c == NULL) 3297 return (-1); 3298 3299 ir = input_make_request(ictx, type); 3300 ir->c = c; 3301 ir->idx = idx; 3302 ir->end = ictx->input_end; 3303 TAILQ_INSERT_TAIL(&c->input_requests, ir, centry); 3304 3305 switch (type) { 3306 case INPUT_REQUEST_PALETTE: 3307 xsnprintf(s, sizeof s, "\033]4;%d;?\033\\", idx); 3308 tty_puts(&c->tty, s); 3309 break; 3310 case INPUT_REQUEST_QUEUE: 3311 break; 3312 } 3313 3314 return (0); 3315 } 3316 3317 /* Handle a reply to a request. */ 3318 void 3319 input_request_reply(struct client *c, enum input_request_type type, void *data) 3320 { 3321 struct input_request *ir, *ir1, *found = NULL; 3322 struct input_request_palette_data *pd = data; 3323 int complete = 0; 3324 3325 TAILQ_FOREACH_SAFE(ir, &c->input_requests, centry, ir1) { 3326 if (ir->type == type && pd->idx == ir->idx) { 3327 found = ir; 3328 break; 3329 } 3330 input_free_request(ir); 3331 } 3332 if (found == NULL) 3333 return; 3334 3335 TAILQ_FOREACH_SAFE(ir, &found->ictx->requests, entry, ir1) { 3336 if (complete && ir->type != INPUT_REQUEST_QUEUE) 3337 break; 3338 if (ir->type == INPUT_REQUEST_QUEUE) 3339 input_send_reply(ir->ictx, ir->data); 3340 else if (ir == found && ir->type == INPUT_REQUEST_PALETTE) { 3341 input_osc_colour_reply(ir->ictx, 0, 4, pd->idx, pd->c, ir->end); 3342 complete = 1; 3343 } 3344 input_free_request(ir); 3345 } 3346 } 3347 3348 /* Cancel pending requests for client. */ 3349 void 3350 input_cancel_requests(struct client *c) 3351 { 3352 struct input_request *ir, *ir1; 3353 3354 TAILQ_FOREACH_SAFE(ir, &c->input_requests, entry, ir1) 3355 input_free_request(ir); 3356 } 3357 3358 /* Report current theme. */ 3359 static void 3360 input_report_current_theme(struct input_ctx *ictx) 3361 { 3362 switch (window_pane_get_theme(ictx->wp)) { 3363 case THEME_DARK: 3364 input_reply(ictx, 0, "\033[?997;1n"); 3365 break; 3366 case THEME_LIGHT: 3367 input_reply(ictx, 0, "\033[?997;2n"); 3368 break; 3369 case THEME_UNKNOWN: 3370 break; 3371 } 3372 } 3373