"Fossies" - the Fresh Open Source Software Archive

Member "tmux-3.2a/input.c" (10 Jun 2021, 63808 Bytes) of package /linux/misc/tmux-3.2a.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "input.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.2_vs_3.2a.

    1 /* $OpenBSD$ */
    2 
    3 /*
    4  * Copyright (c) 2007 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 
   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 /* Input parser cell. */
   55 struct input_cell {
   56     struct grid_cell    cell;
   57     int         set;
   58     int         g0set;  /* 1 if ACS */
   59     int         g1set;  /* 1 if ACS */
   60 };
   61 
   62 /* Input parser argument. */
   63 struct input_param {
   64     enum {
   65         INPUT_MISSING,
   66         INPUT_NUMBER,
   67         INPUT_STRING
   68     }           type;
   69     union {
   70         int     num;
   71         char           *str;
   72     };
   73 };
   74 
   75 /* Input parser context. */
   76 struct input_ctx {
   77     struct window_pane     *wp;
   78     struct bufferevent     *event;
   79     struct screen_write_ctx ctx;
   80 
   81     struct input_cell   cell;
   82 
   83     struct input_cell   old_cell;
   84     u_int           old_cx;
   85     u_int           old_cy;
   86     int         old_mode;
   87 
   88     u_char          interm_buf[4];
   89     size_t          interm_len;
   90 
   91     u_char          param_buf[64];
   92     size_t          param_len;
   93 
   94 #define INPUT_BUF_START 32
   95 #define INPUT_BUF_LIMIT 1048576
   96     u_char             *input_buf;
   97     size_t          input_len;
   98     size_t          input_space;
   99     enum {
  100         INPUT_END_ST,
  101         INPUT_END_BEL
  102     }           input_end;
  103 
  104     struct input_param  param_list[24];
  105     u_int           param_list_len;
  106 
  107     struct utf8_data    utf8data;
  108     int         utf8started;
  109 
  110     int         ch;
  111     int         last;
  112 
  113     int         flags;
  114 #define INPUT_DISCARD 0x1
  115 
  116     const struct input_state *state;
  117 
  118     struct event        timer;
  119 
  120     /*
  121      * All input received since we were last in the ground state. Sent to
  122      * control clients on connection.
  123      */
  124     struct evbuffer     *since_ground;
  125 };
  126 
  127 /* Helper functions. */
  128 struct input_transition;
  129 static int  input_split(struct input_ctx *);
  130 static int  input_get(struct input_ctx *, u_int, int, int);
  131 static void printflike(2, 3) input_reply(struct input_ctx *, const char *, ...);
  132 static void input_set_state(struct input_ctx *,
  133             const struct input_transition *);
  134 static void input_reset_cell(struct input_ctx *);
  135 
  136 static void input_osc_4(struct input_ctx *, const char *);
  137 static void input_osc_10(struct input_ctx *, const char *);
  138 static void input_osc_11(struct input_ctx *, const char *);
  139 static void input_osc_52(struct input_ctx *, const char *);
  140 static void input_osc_104(struct input_ctx *, const char *);
  141 static void input_osc_110(struct input_ctx *, const char *);
  142 static void input_osc_111(struct input_ctx *, const char *);
  143 
  144 /* Transition entry/exit handlers. */
  145 static void input_clear(struct input_ctx *);
  146 static void input_ground(struct input_ctx *);
  147 static void input_enter_dcs(struct input_ctx *);
  148 static void input_enter_osc(struct input_ctx *);
  149 static void input_exit_osc(struct input_ctx *);
  150 static void input_enter_apc(struct input_ctx *);
  151 static void input_exit_apc(struct input_ctx *);
  152 static void input_enter_rename(struct input_ctx *);
  153 static void input_exit_rename(struct input_ctx *);
  154 
  155 /* Input state handlers. */
  156 static int  input_print(struct input_ctx *);
  157 static int  input_intermediate(struct input_ctx *);
  158 static int  input_parameter(struct input_ctx *);
  159 static int  input_input(struct input_ctx *);
  160 static int  input_c0_dispatch(struct input_ctx *);
  161 static int  input_esc_dispatch(struct input_ctx *);
  162 static int  input_csi_dispatch(struct input_ctx *);
  163 static void input_csi_dispatch_rm(struct input_ctx *);
  164 static void input_csi_dispatch_rm_private(struct input_ctx *);
  165 static void input_csi_dispatch_sm(struct input_ctx *);
  166 static void input_csi_dispatch_sm_private(struct input_ctx *);
  167 static void input_csi_dispatch_winops(struct input_ctx *);
  168 static void input_csi_dispatch_sgr_256(struct input_ctx *, int, u_int *);
  169 static void input_csi_dispatch_sgr_rgb(struct input_ctx *, int, u_int *);
  170 static void input_csi_dispatch_sgr(struct input_ctx *);
  171 static int  input_dcs_dispatch(struct input_ctx *);
  172 static int  input_top_bit_set(struct input_ctx *);
  173 static int  input_end_bel(struct input_ctx *);
  174 
  175 /* Command table comparison function. */
  176 static int  input_table_compare(const void *, const void *);
  177 
  178 /* Command table entry. */
  179 struct input_table_entry {
  180     int     ch;
  181     const char     *interm;
  182     int     type;
  183 };
  184 
  185 /* Escape commands. */
  186 enum input_esc_type {
  187     INPUT_ESC_DECALN,
  188     INPUT_ESC_DECKPAM,
  189     INPUT_ESC_DECKPNM,
  190     INPUT_ESC_DECRC,
  191     INPUT_ESC_DECSC,
  192     INPUT_ESC_HTS,
  193     INPUT_ESC_IND,
  194     INPUT_ESC_NEL,
  195     INPUT_ESC_RI,
  196     INPUT_ESC_RIS,
  197     INPUT_ESC_SCSG0_OFF,
  198     INPUT_ESC_SCSG0_ON,
  199     INPUT_ESC_SCSG1_OFF,
  200     INPUT_ESC_SCSG1_ON,
  201     INPUT_ESC_ST,
  202 };
  203 
  204 /* Escape command table. */
  205 static const struct input_table_entry input_esc_table[] = {
  206     { '0', "(", INPUT_ESC_SCSG0_ON },
  207     { '0', ")", INPUT_ESC_SCSG1_ON },
  208     { '7', "",  INPUT_ESC_DECSC },
  209     { '8', "",  INPUT_ESC_DECRC },
  210     { '8', "#", INPUT_ESC_DECALN },
  211     { '=', "",  INPUT_ESC_DECKPAM },
  212     { '>', "",  INPUT_ESC_DECKPNM },
  213     { 'B', "(", INPUT_ESC_SCSG0_OFF },
  214     { 'B', ")", INPUT_ESC_SCSG1_OFF },
  215     { 'D', "",  INPUT_ESC_IND },
  216     { 'E', "",  INPUT_ESC_NEL },
  217     { 'H', "",  INPUT_ESC_HTS },
  218     { 'M', "",  INPUT_ESC_RI },
  219     { '\\', "", INPUT_ESC_ST },
  220     { 'c', "",  INPUT_ESC_RIS },
  221 };
  222 
  223 /* Control (CSI) commands. */
  224 enum input_csi_type {
  225     INPUT_CSI_CBT,
  226     INPUT_CSI_CNL,
  227     INPUT_CSI_CPL,
  228     INPUT_CSI_CUB,
  229     INPUT_CSI_CUD,
  230     INPUT_CSI_CUF,
  231     INPUT_CSI_CUP,
  232     INPUT_CSI_CUU,
  233     INPUT_CSI_DA,
  234     INPUT_CSI_DA_TWO,
  235     INPUT_CSI_DCH,
  236     INPUT_CSI_DECSCUSR,
  237     INPUT_CSI_DECSTBM,
  238     INPUT_CSI_DL,
  239     INPUT_CSI_DSR,
  240     INPUT_CSI_ECH,
  241     INPUT_CSI_ED,
  242     INPUT_CSI_EL,
  243     INPUT_CSI_HPA,
  244     INPUT_CSI_ICH,
  245     INPUT_CSI_IL,
  246     INPUT_CSI_MODOFF,
  247     INPUT_CSI_MODSET,
  248     INPUT_CSI_RCP,
  249     INPUT_CSI_REP,
  250     INPUT_CSI_RM,
  251     INPUT_CSI_RM_PRIVATE,
  252     INPUT_CSI_SCP,
  253     INPUT_CSI_SD,
  254     INPUT_CSI_SGR,
  255     INPUT_CSI_SM,
  256     INPUT_CSI_SM_PRIVATE,
  257     INPUT_CSI_SU,
  258     INPUT_CSI_TBC,
  259     INPUT_CSI_VPA,
  260     INPUT_CSI_WINOPS,
  261     INPUT_CSI_XDA,
  262 };
  263 
  264 /* Control (CSI) command table. */
  265 static const struct input_table_entry input_csi_table[] = {
  266     { '@', "",  INPUT_CSI_ICH },
  267     { 'A', "",  INPUT_CSI_CUU },
  268     { 'B', "",  INPUT_CSI_CUD },
  269     { 'C', "",  INPUT_CSI_CUF },
  270     { 'D', "",  INPUT_CSI_CUB },
  271     { 'E', "",  INPUT_CSI_CNL },
  272     { 'F', "",  INPUT_CSI_CPL },
  273     { 'G', "",  INPUT_CSI_HPA },
  274     { 'H', "",  INPUT_CSI_CUP },
  275     { 'J', "",  INPUT_CSI_ED },
  276     { 'K', "",  INPUT_CSI_EL },
  277     { 'L', "",  INPUT_CSI_IL },
  278     { 'M', "",  INPUT_CSI_DL },
  279     { 'P', "",  INPUT_CSI_DCH },
  280     { 'S', "",  INPUT_CSI_SU },
  281     { 'T', "",  INPUT_CSI_SD },
  282     { 'X', "",  INPUT_CSI_ECH },
  283     { 'Z', "",  INPUT_CSI_CBT },
  284     { '`', "",  INPUT_CSI_HPA },
  285     { 'b', "",  INPUT_CSI_REP },
  286     { 'c', "",  INPUT_CSI_DA },
  287     { 'c', ">", INPUT_CSI_DA_TWO },
  288     { 'd', "",  INPUT_CSI_VPA },
  289     { 'f', "",  INPUT_CSI_CUP },
  290     { 'g', "",  INPUT_CSI_TBC },
  291     { 'h', "",  INPUT_CSI_SM },
  292     { 'h', "?", INPUT_CSI_SM_PRIVATE },
  293     { 'l', "",  INPUT_CSI_RM },
  294     { 'l', "?", INPUT_CSI_RM_PRIVATE },
  295     { 'm', "",  INPUT_CSI_SGR },
  296     { 'm', ">", INPUT_CSI_MODSET },
  297     { 'n', "",  INPUT_CSI_DSR },
  298     { 'n', ">", INPUT_CSI_MODOFF },
  299     { 'q', " ", INPUT_CSI_DECSCUSR },
  300     { 'q', ">", INPUT_CSI_XDA },
  301     { 'r', "",  INPUT_CSI_DECSTBM },
  302     { 's', "",  INPUT_CSI_SCP },
  303     { 't', "",  INPUT_CSI_WINOPS },
  304     { 'u', "",  INPUT_CSI_RCP },
  305 };
  306 
  307 /* Input transition. */
  308 struct input_transition {
  309     int             first;
  310     int             last;
  311 
  312     int             (*handler)(struct input_ctx *);
  313     const struct input_state       *state;
  314 };
  315 
  316 /* Input state. */
  317 struct input_state {
  318     const char          *name;
  319     void                (*enter)(struct input_ctx *);
  320     void                (*exit)(struct input_ctx *);
  321     const struct input_transition   *transitions;
  322 };
  323 
  324 /* State transitions available from all states. */
  325 #define INPUT_STATE_ANYWHERE \
  326     { 0x18, 0x18, input_c0_dispatch, &input_state_ground }, \
  327     { 0x1a, 0x1a, input_c0_dispatch, &input_state_ground }, \
  328     { 0x1b, 0x1b, NULL,      &input_state_esc_enter }
  329 
  330 /* Forward declarations of state tables. */
  331 static const struct input_transition input_state_ground_table[];
  332 static const struct input_transition input_state_esc_enter_table[];
  333 static const struct input_transition input_state_esc_intermediate_table[];
  334 static const struct input_transition input_state_csi_enter_table[];
  335 static const struct input_transition input_state_csi_parameter_table[];
  336 static const struct input_transition input_state_csi_intermediate_table[];
  337 static const struct input_transition input_state_csi_ignore_table[];
  338 static const struct input_transition input_state_dcs_enter_table[];
  339 static const struct input_transition input_state_dcs_parameter_table[];
  340 static const struct input_transition input_state_dcs_intermediate_table[];
  341 static const struct input_transition input_state_dcs_handler_table[];
  342 static const struct input_transition input_state_dcs_escape_table[];
  343 static const struct input_transition input_state_dcs_ignore_table[];
  344 static const struct input_transition input_state_osc_string_table[];
  345 static const struct input_transition input_state_apc_string_table[];
  346 static const struct input_transition input_state_rename_string_table[];
  347 static const struct input_transition input_state_consume_st_table[];
  348 
  349 /* ground state definition. */
  350 static const struct input_state input_state_ground = {
  351     "ground",
  352     input_ground, NULL,
  353     input_state_ground_table
  354 };
  355 
  356 /* esc_enter state definition. */
  357 static const struct input_state input_state_esc_enter = {
  358     "esc_enter",
  359     input_clear, NULL,
  360     input_state_esc_enter_table
  361 };
  362 
  363 /* esc_intermediate state definition. */
  364 static const struct input_state input_state_esc_intermediate = {
  365     "esc_intermediate",
  366     NULL, NULL,
  367     input_state_esc_intermediate_table
  368 };
  369 
  370 /* csi_enter state definition. */
  371 static const struct input_state input_state_csi_enter = {
  372     "csi_enter",
  373     input_clear, NULL,
  374     input_state_csi_enter_table
  375 };
  376 
  377 /* csi_parameter state definition. */
  378 static const struct input_state input_state_csi_parameter = {
  379     "csi_parameter",
  380     NULL, NULL,
  381     input_state_csi_parameter_table
  382 };
  383 
  384 /* csi_intermediate state definition. */
  385 static const struct input_state input_state_csi_intermediate = {
  386     "csi_intermediate",
  387     NULL, NULL,
  388     input_state_csi_intermediate_table
  389 };
  390 
  391 /* csi_ignore state definition. */
  392 static const struct input_state input_state_csi_ignore = {
  393     "csi_ignore",
  394     NULL, NULL,
  395     input_state_csi_ignore_table
  396 };
  397 
  398 /* dcs_enter state definition. */
  399 static const struct input_state input_state_dcs_enter = {
  400     "dcs_enter",
  401     input_enter_dcs, NULL,
  402     input_state_dcs_enter_table
  403 };
  404 
  405 /* dcs_parameter state definition. */
  406 static const struct input_state input_state_dcs_parameter = {
  407     "dcs_parameter",
  408     NULL, NULL,
  409     input_state_dcs_parameter_table
  410 };
  411 
  412 /* dcs_intermediate state definition. */
  413 static const struct input_state input_state_dcs_intermediate = {
  414     "dcs_intermediate",
  415     NULL, NULL,
  416     input_state_dcs_intermediate_table
  417 };
  418 
  419 /* dcs_handler state definition. */
  420 static const struct input_state input_state_dcs_handler = {
  421     "dcs_handler",
  422     NULL, NULL,
  423     input_state_dcs_handler_table
  424 };
  425 
  426 /* dcs_escape state definition. */
  427 static const struct input_state input_state_dcs_escape = {
  428     "dcs_escape",
  429     NULL, NULL,
  430     input_state_dcs_escape_table
  431 };
  432 
  433 /* dcs_ignore state definition. */
  434 static const struct input_state input_state_dcs_ignore = {
  435     "dcs_ignore",
  436     NULL, NULL,
  437     input_state_dcs_ignore_table
  438 };
  439 
  440 /* osc_string state definition. */
  441 static const struct input_state input_state_osc_string = {
  442     "osc_string",
  443     input_enter_osc, input_exit_osc,
  444     input_state_osc_string_table
  445 };
  446 
  447 /* apc_string state definition. */
  448 static const struct input_state input_state_apc_string = {
  449     "apc_string",
  450     input_enter_apc, input_exit_apc,
  451     input_state_apc_string_table
  452 };
  453 
  454 /* rename_string state definition. */
  455 static const struct input_state input_state_rename_string = {
  456     "rename_string",
  457     input_enter_rename, input_exit_rename,
  458     input_state_rename_string_table
  459 };
  460 
  461 /* consume_st state definition. */
  462 static const struct input_state input_state_consume_st = {
  463     "consume_st",
  464     input_enter_rename, NULL, /* rename also waits for ST */
  465     input_state_consume_st_table
  466 };
  467 
  468 /* ground state table. */
  469 static const struct input_transition input_state_ground_table[] = {
  470     INPUT_STATE_ANYWHERE,
  471 
  472     { 0x00, 0x17, input_c0_dispatch, NULL },
  473     { 0x19, 0x19, input_c0_dispatch, NULL },
  474     { 0x1c, 0x1f, input_c0_dispatch, NULL },
  475     { 0x20, 0x7e, input_print,   NULL },
  476     { 0x7f, 0x7f, NULL,      NULL },
  477     { 0x80, 0xff, input_top_bit_set, NULL },
  478 
  479     { -1, -1, NULL, NULL }
  480 };
  481 
  482 /* esc_enter state table. */
  483 static const struct input_transition input_state_esc_enter_table[] = {
  484     INPUT_STATE_ANYWHERE,
  485 
  486     { 0x00, 0x17, input_c0_dispatch,  NULL },
  487     { 0x19, 0x19, input_c0_dispatch,  NULL },
  488     { 0x1c, 0x1f, input_c0_dispatch,  NULL },
  489     { 0x20, 0x2f, input_intermediate, &input_state_esc_intermediate },
  490     { 0x30, 0x4f, input_esc_dispatch, &input_state_ground },
  491     { 0x50, 0x50, NULL,       &input_state_dcs_enter },
  492     { 0x51, 0x57, input_esc_dispatch, &input_state_ground },
  493     { 0x58, 0x58, NULL,       &input_state_consume_st },
  494     { 0x59, 0x59, input_esc_dispatch, &input_state_ground },
  495     { 0x5a, 0x5a, input_esc_dispatch, &input_state_ground },
  496     { 0x5b, 0x5b, NULL,       &input_state_csi_enter },
  497     { 0x5c, 0x5c, input_esc_dispatch, &input_state_ground },
  498     { 0x5d, 0x5d, NULL,       &input_state_osc_string },
  499     { 0x5e, 0x5e, NULL,       &input_state_consume_st },
  500     { 0x5f, 0x5f, NULL,       &input_state_apc_string },
  501     { 0x60, 0x6a, input_esc_dispatch, &input_state_ground },
  502     { 0x6b, 0x6b, NULL,       &input_state_rename_string },
  503     { 0x6c, 0x7e, input_esc_dispatch, &input_state_ground },
  504     { 0x7f, 0xff, NULL,       NULL },
  505 
  506     { -1, -1, NULL, NULL }
  507 };
  508 
  509 /* esc_intermediate state table. */
  510 static const struct input_transition input_state_esc_intermediate_table[] = {
  511     INPUT_STATE_ANYWHERE,
  512 
  513     { 0x00, 0x17, input_c0_dispatch,  NULL },
  514     { 0x19, 0x19, input_c0_dispatch,  NULL },
  515     { 0x1c, 0x1f, input_c0_dispatch,  NULL },
  516     { 0x20, 0x2f, input_intermediate, NULL },
  517     { 0x30, 0x7e, input_esc_dispatch, &input_state_ground },
  518     { 0x7f, 0xff, NULL,       NULL },
  519 
  520     { -1, -1, NULL, NULL }
  521 };
  522 
  523 /* csi_enter state table. */
  524 static const struct input_transition input_state_csi_enter_table[] = {
  525     INPUT_STATE_ANYWHERE,
  526 
  527     { 0x00, 0x17, input_c0_dispatch,  NULL },
  528     { 0x19, 0x19, input_c0_dispatch,  NULL },
  529     { 0x1c, 0x1f, input_c0_dispatch,  NULL },
  530     { 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate },
  531     { 0x30, 0x39, input_parameter,    &input_state_csi_parameter },
  532     { 0x3a, 0x3a, input_parameter,    &input_state_csi_parameter },
  533     { 0x3b, 0x3b, input_parameter,    &input_state_csi_parameter },
  534     { 0x3c, 0x3f, input_intermediate, &input_state_csi_parameter },
  535     { 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
  536     { 0x7f, 0xff, NULL,       NULL },
  537 
  538     { -1, -1, NULL, NULL }
  539 };
  540 
  541 /* csi_parameter state table. */
  542 static const struct input_transition input_state_csi_parameter_table[] = {
  543     INPUT_STATE_ANYWHERE,
  544 
  545     { 0x00, 0x17, input_c0_dispatch,  NULL },
  546     { 0x19, 0x19, input_c0_dispatch,  NULL },
  547     { 0x1c, 0x1f, input_c0_dispatch,  NULL },
  548     { 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate },
  549     { 0x30, 0x39, input_parameter,    NULL },
  550     { 0x3a, 0x3a, input_parameter,    NULL },
  551     { 0x3b, 0x3b, input_parameter,    NULL },
  552     { 0x3c, 0x3f, NULL,       &input_state_csi_ignore },
  553     { 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
  554     { 0x7f, 0xff, NULL,       NULL },
  555 
  556     { -1, -1, NULL, NULL }
  557 };
  558 
  559 /* csi_intermediate state table. */
  560 static const struct input_transition input_state_csi_intermediate_table[] = {
  561     INPUT_STATE_ANYWHERE,
  562 
  563     { 0x00, 0x17, input_c0_dispatch,  NULL },
  564     { 0x19, 0x19, input_c0_dispatch,  NULL },
  565     { 0x1c, 0x1f, input_c0_dispatch,  NULL },
  566     { 0x20, 0x2f, input_intermediate, NULL },
  567     { 0x30, 0x3f, NULL,       &input_state_csi_ignore },
  568     { 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
  569     { 0x7f, 0xff, NULL,       NULL },
  570 
  571     { -1, -1, NULL, NULL }
  572 };
  573 
  574 /* csi_ignore state table. */
  575 static const struct input_transition input_state_csi_ignore_table[] = {
  576     INPUT_STATE_ANYWHERE,
  577 
  578     { 0x00, 0x17, input_c0_dispatch, NULL },
  579     { 0x19, 0x19, input_c0_dispatch, NULL },
  580     { 0x1c, 0x1f, input_c0_dispatch, NULL },
  581     { 0x20, 0x3f, NULL,      NULL },
  582     { 0x40, 0x7e, NULL,      &input_state_ground },
  583     { 0x7f, 0xff, NULL,      NULL },
  584 
  585     { -1, -1, NULL, NULL }
  586 };
  587 
  588 /* dcs_enter state table. */
  589 static const struct input_transition input_state_dcs_enter_table[] = {
  590     INPUT_STATE_ANYWHERE,
  591 
  592     { 0x00, 0x17, NULL,       NULL },
  593     { 0x19, 0x19, NULL,       NULL },
  594     { 0x1c, 0x1f, NULL,       NULL },
  595     { 0x20, 0x2f, input_intermediate, &input_state_dcs_intermediate },
  596     { 0x30, 0x39, input_parameter,    &input_state_dcs_parameter },
  597     { 0x3a, 0x3a, NULL,       &input_state_dcs_ignore },
  598     { 0x3b, 0x3b, input_parameter,    &input_state_dcs_parameter },
  599     { 0x3c, 0x3f, input_intermediate, &input_state_dcs_parameter },
  600     { 0x40, 0x7e, input_input,    &input_state_dcs_handler },
  601     { 0x7f, 0xff, NULL,       NULL },
  602 
  603     { -1, -1, NULL, NULL }
  604 };
  605 
  606 /* dcs_parameter state table. */
  607 static const struct input_transition input_state_dcs_parameter_table[] = {
  608     INPUT_STATE_ANYWHERE,
  609 
  610     { 0x00, 0x17, NULL,       NULL },
  611     { 0x19, 0x19, NULL,       NULL },
  612     { 0x1c, 0x1f, NULL,       NULL },
  613     { 0x20, 0x2f, input_intermediate, &input_state_dcs_intermediate },
  614     { 0x30, 0x39, input_parameter,    NULL },
  615     { 0x3a, 0x3a, NULL,       &input_state_dcs_ignore },
  616     { 0x3b, 0x3b, input_parameter,    NULL },
  617     { 0x3c, 0x3f, NULL,       &input_state_dcs_ignore },
  618     { 0x40, 0x7e, input_input,    &input_state_dcs_handler },
  619     { 0x7f, 0xff, NULL,       NULL },
  620 
  621     { -1, -1, NULL, NULL }
  622 };
  623 
  624 /* dcs_intermediate state table. */
  625 static const struct input_transition input_state_dcs_intermediate_table[] = {
  626     INPUT_STATE_ANYWHERE,
  627 
  628     { 0x00, 0x17, NULL,       NULL },
  629     { 0x19, 0x19, NULL,       NULL },
  630     { 0x1c, 0x1f, NULL,       NULL },
  631     { 0x20, 0x2f, input_intermediate, NULL },
  632     { 0x30, 0x3f, NULL,       &input_state_dcs_ignore },
  633     { 0x40, 0x7e, input_input,    &input_state_dcs_handler },
  634     { 0x7f, 0xff, NULL,       NULL },
  635 
  636     { -1, -1, NULL, NULL }
  637 };
  638 
  639 /* dcs_handler state table. */
  640 static const struct input_transition input_state_dcs_handler_table[] = {
  641     /* No INPUT_STATE_ANYWHERE */
  642 
  643     { 0x00, 0x1a, input_input,  NULL },
  644     { 0x1b, 0x1b, NULL,     &input_state_dcs_escape },
  645     { 0x1c, 0xff, input_input,  NULL },
  646 
  647     { -1, -1, NULL, NULL }
  648 };
  649 
  650 /* dcs_escape state table. */
  651 static const struct input_transition input_state_dcs_escape_table[] = {
  652     /* No INPUT_STATE_ANYWHERE */
  653 
  654     { 0x00, 0x5b, input_input,    &input_state_dcs_handler },
  655     { 0x5c, 0x5c, input_dcs_dispatch, &input_state_ground },
  656     { 0x5d, 0xff, input_input,    &input_state_dcs_handler },
  657 
  658     { -1, -1, NULL, NULL }
  659 };
  660 
  661 /* dcs_ignore state table. */
  662 static const struct input_transition input_state_dcs_ignore_table[] = {
  663     INPUT_STATE_ANYWHERE,
  664 
  665     { 0x00, 0x17, NULL,     NULL },
  666     { 0x19, 0x19, NULL,     NULL },
  667     { 0x1c, 0x1f, NULL,     NULL },
  668     { 0x20, 0xff, NULL,     NULL },
  669 
  670     { -1, -1, NULL, NULL }
  671 };
  672 
  673 /* osc_string state table. */
  674 static const struct input_transition input_state_osc_string_table[] = {
  675     INPUT_STATE_ANYWHERE,
  676 
  677     { 0x00, 0x06, NULL,      NULL },
  678     { 0x07, 0x07, input_end_bel, &input_state_ground },
  679     { 0x08, 0x17, NULL,      NULL },
  680     { 0x19, 0x19, NULL,      NULL },
  681     { 0x1c, 0x1f, NULL,      NULL },
  682     { 0x20, 0xff, input_input,   NULL },
  683 
  684     { -1, -1, NULL, NULL }
  685 };
  686 
  687 /* apc_string state table. */
  688 static const struct input_transition input_state_apc_string_table[] = {
  689     INPUT_STATE_ANYWHERE,
  690 
  691     { 0x00, 0x17, NULL,     NULL },
  692     { 0x19, 0x19, NULL,     NULL },
  693     { 0x1c, 0x1f, NULL,     NULL },
  694     { 0x20, 0xff, input_input,  NULL },
  695 
  696     { -1, -1, NULL, NULL }
  697 };
  698 
  699 /* rename_string state table. */
  700 static const struct input_transition input_state_rename_string_table[] = {
  701     INPUT_STATE_ANYWHERE,
  702 
  703     { 0x00, 0x17, NULL,     NULL },
  704     { 0x19, 0x19, NULL,     NULL },
  705     { 0x1c, 0x1f, NULL,     NULL },
  706     { 0x20, 0xff, input_input,  NULL },
  707 
  708     { -1, -1, NULL, NULL }
  709 };
  710 
  711 /* consume_st state table. */
  712 static const struct input_transition input_state_consume_st_table[] = {
  713     INPUT_STATE_ANYWHERE,
  714 
  715     { 0x00, 0x17, NULL,     NULL },
  716     { 0x19, 0x19, NULL,     NULL },
  717     { 0x1c, 0x1f, NULL,     NULL },
  718     { 0x20, 0xff, NULL,     NULL },
  719 
  720     { -1, -1, NULL, NULL }
  721 };
  722 
  723 /* Input table compare. */
  724 static int
  725 input_table_compare(const void *key, const void *value)
  726 {
  727     const struct input_ctx      *ictx = key;
  728     const struct input_table_entry  *entry = value;
  729 
  730     if (ictx->ch != entry->ch)
  731         return (ictx->ch - entry->ch);
  732     return (strcmp(ictx->interm_buf, entry->interm));
  733 }
  734 
  735 /*
  736  * Timer - if this expires then have been waiting for a terminator for too
  737  * long, so reset to ground.
  738  */
  739 static void
  740 input_timer_callback(__unused int fd, __unused short events, void *arg)
  741 {
  742     struct input_ctx    *ictx = arg;
  743 
  744     log_debug("%s: %s expired" , __func__, ictx->state->name);
  745     input_reset(ictx, 0);
  746 }
  747 
  748 /* Start the timer. */
  749 static void
  750 input_start_timer(struct input_ctx *ictx)
  751 {
  752     struct timeval  tv = { .tv_sec = 5, .tv_usec = 0 };
  753 
  754     event_del(&ictx->timer);
  755     event_add(&ictx->timer, &tv);
  756 }
  757 
  758 /* Reset cell state to default. */
  759 static void
  760 input_reset_cell(struct input_ctx *ictx)
  761 {
  762     memcpy(&ictx->cell.cell, &grid_default_cell, sizeof ictx->cell.cell);
  763     ictx->cell.set = 0;
  764     ictx->cell.g0set = ictx->cell.g1set = 0;
  765 
  766     memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
  767     ictx->old_cx = 0;
  768     ictx->old_cy = 0;
  769 }
  770 
  771 /* Save screen state. */
  772 static void
  773 input_save_state(struct input_ctx *ictx)
  774 {
  775     struct screen_write_ctx *sctx = &ictx->ctx;
  776     struct screen       *s = sctx->s;
  777 
  778     memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
  779     ictx->old_cx = s->cx;
  780     ictx->old_cy = s->cy;
  781     ictx->old_mode = s->mode;
  782 }
  783 
  784 /* Restore screen state. */
  785 static void
  786 input_restore_state(struct input_ctx *ictx)
  787 {
  788     struct screen_write_ctx *sctx = &ictx->ctx;
  789 
  790     memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell);
  791     if (ictx->old_mode & MODE_ORIGIN)
  792         screen_write_mode_set(sctx, MODE_ORIGIN);
  793     else
  794         screen_write_mode_clear(sctx, MODE_ORIGIN);
  795     screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy, 0);
  796 }
  797 
  798 /* Initialise input parser. */
  799 struct input_ctx *
  800 input_init(struct window_pane *wp, struct bufferevent *bev)
  801 {
  802     struct input_ctx    *ictx;
  803 
  804     ictx = xcalloc(1, sizeof *ictx);
  805     ictx->wp = wp;
  806     ictx->event = bev;
  807 
  808     ictx->input_space = INPUT_BUF_START;
  809     ictx->input_buf = xmalloc(INPUT_BUF_START);
  810 
  811     ictx->since_ground = evbuffer_new();
  812     if (ictx->since_ground == NULL)
  813         fatalx("out of memory");
  814 
  815     evtimer_set(&ictx->timer, input_timer_callback, ictx);
  816 
  817     input_reset(ictx, 0);
  818     return (ictx);
  819 }
  820 
  821 /* Destroy input parser. */
  822 void
  823 input_free(struct input_ctx *ictx)
  824 {
  825     u_int   i;
  826 
  827     for (i = 0; i < ictx->param_list_len; i++) {
  828         if (ictx->param_list[i].type == INPUT_STRING)
  829             free(ictx->param_list[i].str);
  830     }
  831 
  832     event_del(&ictx->timer);
  833 
  834     free(ictx->input_buf);
  835     evbuffer_free(ictx->since_ground);
  836 
  837     free(ictx);
  838 }
  839 
  840 /* Reset input state and clear screen. */
  841 void
  842 input_reset(struct input_ctx *ictx, int clear)
  843 {
  844     struct screen_write_ctx *sctx = &ictx->ctx;
  845     struct window_pane  *wp = ictx->wp;
  846 
  847     input_reset_cell(ictx);
  848 
  849     if (clear && wp != NULL) {
  850         if (TAILQ_EMPTY(&wp->modes))
  851             screen_write_start_pane(sctx, wp, &wp->base);
  852         else
  853             screen_write_start(sctx, &wp->base);
  854         screen_write_reset(sctx);
  855         screen_write_stop(sctx);
  856     }
  857 
  858     input_clear(ictx);
  859 
  860     ictx->last = -1;
  861 
  862     ictx->state = &input_state_ground;
  863     ictx->flags = 0;
  864 }
  865 
  866 /* Return pending data. */
  867 struct evbuffer *
  868 input_pending(struct input_ctx *ictx)
  869 {
  870     return (ictx->since_ground);
  871 }
  872 
  873 /* Change input state. */
  874 static void
  875 input_set_state(struct input_ctx *ictx, const struct input_transition *itr)
  876 {
  877     if (ictx->state->exit != NULL)
  878         ictx->state->exit(ictx);
  879     ictx->state = itr->state;
  880     if (ictx->state->enter != NULL)
  881         ictx->state->enter(ictx);
  882 }
  883 
  884 /* Parse data. */
  885 static void
  886 input_parse(struct input_ctx *ictx, u_char *buf, size_t len)
  887 {
  888     struct screen_write_ctx     *sctx = &ictx->ctx;
  889     const struct input_state    *state = NULL;
  890     const struct input_transition   *itr = NULL;
  891     size_t               off = 0;
  892 
  893     /* Parse the input. */
  894     while (off < len) {
  895         ictx->ch = buf[off++];
  896 
  897         /* Find the transition. */
  898         if (ictx->state != state ||
  899             itr == NULL ||
  900             ictx->ch < itr->first ||
  901             ictx->ch > itr->last) {
  902             itr = ictx->state->transitions;
  903             while (itr->first != -1 && itr->last != -1) {
  904                 if (ictx->ch >= itr->first &&
  905                     ictx->ch <= itr->last)
  906                     break;
  907                 itr++;
  908             }
  909             if (itr->first == -1 || itr->last == -1) {
  910                 /* No transition? Eh? */
  911                 fatalx("no transition from state");
  912             }
  913         }
  914         state = ictx->state;
  915 
  916         /*
  917          * Any state except print stops the current collection. This is
  918          * an optimization to avoid checking if the attributes have
  919          * changed for every character. It will stop unnecessarily for
  920          * sequences that don't make a terminal change, but they should
  921          * be the minority.
  922          */
  923         if (itr->handler != input_print)
  924             screen_write_collect_end(sctx);
  925 
  926         /*
  927          * Execute the handler, if any. Don't switch state if it
  928          * returns non-zero.
  929          */
  930         if (itr->handler != NULL && itr->handler(ictx) != 0)
  931             continue;
  932 
  933         /* And switch state, if necessary. */
  934         if (itr->state != NULL)
  935             input_set_state(ictx, itr);
  936 
  937         /* If not in ground state, save input. */
  938         if (ictx->state != &input_state_ground)
  939             evbuffer_add(ictx->since_ground, &ictx->ch, 1);
  940     }
  941 }
  942 
  943 /* Parse input from pane. */
  944 void
  945 input_parse_pane(struct window_pane *wp)
  946 {
  947     void    *new_data;
  948     size_t   new_size;
  949 
  950     new_data = window_pane_get_new_data(wp, &wp->offset, &new_size);
  951     input_parse_buffer(wp, new_data, new_size);
  952     window_pane_update_used_data(wp, &wp->offset, new_size);
  953 }
  954 
  955 /* Parse given input. */
  956 void
  957 input_parse_buffer(struct window_pane *wp, u_char *buf, size_t len)
  958 {
  959     struct input_ctx    *ictx = wp->ictx;
  960     struct screen_write_ctx *sctx = &ictx->ctx;
  961 
  962     if (len == 0)
  963         return;
  964 
  965     window_update_activity(wp->window);
  966     wp->flags |= PANE_CHANGED;
  967 
  968     /* NULL wp if there is a mode set as don't want to update the tty. */
  969     if (TAILQ_EMPTY(&wp->modes))
  970         screen_write_start_pane(sctx, wp, &wp->base);
  971     else
  972         screen_write_start(sctx, &wp->base);
  973 
  974     log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id,
  975         ictx->state->name, len, (int)len, buf);
  976 
  977     input_parse(ictx, buf, len);
  978     screen_write_stop(sctx);
  979 }
  980 
  981 /* Parse given input for screen. */
  982 void
  983 input_parse_screen(struct input_ctx *ictx, struct screen *s,
  984     screen_write_init_ctx_cb cb, void *arg, u_char *buf, size_t len)
  985 {
  986     struct screen_write_ctx *sctx = &ictx->ctx;
  987 
  988     if (len == 0)
  989         return;
  990 
  991     screen_write_start_callback(sctx, s, cb, arg);
  992     input_parse(ictx, buf, len);
  993     screen_write_stop(sctx);
  994 }
  995 
  996 /* Split the parameter list (if any). */
  997 static int
  998 input_split(struct input_ctx *ictx)
  999 {
 1000     const char      *errstr;
 1001     char            *ptr, *out;
 1002     struct input_param  *ip;
 1003     u_int            i;
 1004 
 1005     for (i = 0; i < ictx->param_list_len; i++) {
 1006         if (ictx->param_list[i].type == INPUT_STRING)
 1007             free(ictx->param_list[i].str);
 1008     }
 1009     ictx->param_list_len = 0;
 1010 
 1011     if (ictx->param_len == 0)
 1012         return (0);
 1013     ip = &ictx->param_list[0];
 1014 
 1015     ptr = ictx->param_buf;
 1016     while ((out = strsep(&ptr, ";")) != NULL) {
 1017         if (*out == '\0')
 1018             ip->type = INPUT_MISSING;
 1019         else {
 1020             if (strchr(out, ':') != NULL) {
 1021                 ip->type = INPUT_STRING;
 1022                 ip->str = xstrdup(out);
 1023             } else {
 1024                 ip->type = INPUT_NUMBER;
 1025                 ip->num = strtonum(out, 0, INT_MAX, &errstr);
 1026                 if (errstr != NULL)
 1027                     return (-1);
 1028             }
 1029         }
 1030         ip = &ictx->param_list[++ictx->param_list_len];
 1031         if (ictx->param_list_len == nitems(ictx->param_list))
 1032             return (-1);
 1033     }
 1034 
 1035     for (i = 0; i < ictx->param_list_len; i++) {
 1036         ip = &ictx->param_list[i];
 1037         if (ip->type == INPUT_MISSING)
 1038             log_debug("parameter %u: missing", i);
 1039         else if (ip->type == INPUT_STRING)
 1040             log_debug("parameter %u: string %s", i, ip->str);
 1041         else if (ip->type == INPUT_NUMBER)
 1042             log_debug("parameter %u: number %d", i, ip->num);
 1043     }
 1044 
 1045     return (0);
 1046 }
 1047 
 1048 /* Get an argument or return default value. */
 1049 static int
 1050 input_get(struct input_ctx *ictx, u_int validx, int minval, int defval)
 1051 {
 1052     struct input_param  *ip;
 1053     int          retval;
 1054 
 1055     if (validx >= ictx->param_list_len)
 1056         return (defval);
 1057     ip = &ictx->param_list[validx];
 1058     if (ip->type == INPUT_MISSING)
 1059         return (defval);
 1060     if (ip->type == INPUT_STRING)
 1061         return (-1);
 1062     retval = ip->num;
 1063     if (retval < minval)
 1064         return (minval);
 1065     return (retval);
 1066 }
 1067 
 1068 /* Reply to terminal query. */
 1069 static void
 1070 input_reply(struct input_ctx *ictx, const char *fmt, ...)
 1071 {
 1072     struct bufferevent  *bev = ictx->event;
 1073     va_list          ap;
 1074     char            *reply;
 1075 
 1076     va_start(ap, fmt);
 1077     xvasprintf(&reply, fmt, ap);
 1078     va_end(ap);
 1079 
 1080     bufferevent_write(bev, reply, strlen(reply));
 1081     free(reply);
 1082 }
 1083 
 1084 /* Clear saved state. */
 1085 static void
 1086 input_clear(struct input_ctx *ictx)
 1087 {
 1088     event_del(&ictx->timer);
 1089 
 1090     *ictx->interm_buf = '\0';
 1091     ictx->interm_len = 0;
 1092 
 1093     *ictx->param_buf = '\0';
 1094     ictx->param_len = 0;
 1095 
 1096     *ictx->input_buf = '\0';
 1097     ictx->input_len = 0;
 1098 
 1099     ictx->input_end = INPUT_END_ST;
 1100 
 1101     ictx->flags &= ~INPUT_DISCARD;
 1102 }
 1103 
 1104 /* Reset for ground state. */
 1105 static void
 1106 input_ground(struct input_ctx *ictx)
 1107 {
 1108     event_del(&ictx->timer);
 1109     evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground));
 1110 
 1111     if (ictx->input_space > INPUT_BUF_START) {
 1112         ictx->input_space = INPUT_BUF_START;
 1113         ictx->input_buf = xrealloc(ictx->input_buf, INPUT_BUF_START);
 1114     }
 1115 }
 1116 
 1117 /* Output this character to the screen. */
 1118 static int
 1119 input_print(struct input_ctx *ictx)
 1120 {
 1121     struct screen_write_ctx *sctx = &ictx->ctx;
 1122     int          set;
 1123 
 1124     ictx->utf8started = 0; /* can't be valid UTF-8 */
 1125 
 1126     set = ictx->cell.set == 0 ? ictx->cell.g0set : ictx->cell.g1set;
 1127     if (set == 1)
 1128         ictx->cell.cell.attr |= GRID_ATTR_CHARSET;
 1129     else
 1130         ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
 1131 
 1132     utf8_set(&ictx->cell.cell.data, ictx->ch);
 1133     screen_write_collect_add(sctx, &ictx->cell.cell);
 1134     ictx->last = ictx->ch;
 1135 
 1136     ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
 1137 
 1138     return (0);
 1139 }
 1140 
 1141 /* Collect intermediate string. */
 1142 static int
 1143 input_intermediate(struct input_ctx *ictx)
 1144 {
 1145     if (ictx->interm_len == (sizeof ictx->interm_buf) - 1)
 1146         ictx->flags |= INPUT_DISCARD;
 1147     else {
 1148         ictx->interm_buf[ictx->interm_len++] = ictx->ch;
 1149         ictx->interm_buf[ictx->interm_len] = '\0';
 1150     }
 1151 
 1152     return (0);
 1153 }
 1154 
 1155 /* Collect parameter string. */
 1156 static int
 1157 input_parameter(struct input_ctx *ictx)
 1158 {
 1159     if (ictx->param_len == (sizeof ictx->param_buf) - 1)
 1160         ictx->flags |= INPUT_DISCARD;
 1161     else {
 1162         ictx->param_buf[ictx->param_len++] = ictx->ch;
 1163         ictx->param_buf[ictx->param_len] = '\0';
 1164     }
 1165 
 1166     return (0);
 1167 }
 1168 
 1169 /* Collect input string. */
 1170 static int
 1171 input_input(struct input_ctx *ictx)
 1172 {
 1173     size_t available;
 1174 
 1175     available = ictx->input_space;
 1176     while (ictx->input_len + 1 >= available) {
 1177         available *= 2;
 1178         if (available > INPUT_BUF_LIMIT) {
 1179             ictx->flags |= INPUT_DISCARD;
 1180             return (0);
 1181         }
 1182         ictx->input_buf = xrealloc(ictx->input_buf, available);
 1183         ictx->input_space = available;
 1184     }
 1185     ictx->input_buf[ictx->input_len++] = ictx->ch;
 1186     ictx->input_buf[ictx->input_len] = '\0';
 1187 
 1188     return (0);
 1189 }
 1190 
 1191 /* Execute C0 control sequence. */
 1192 static int
 1193 input_c0_dispatch(struct input_ctx *ictx)
 1194 {
 1195     struct screen_write_ctx *sctx = &ictx->ctx;
 1196     struct window_pane  *wp = ictx->wp;
 1197     struct screen       *s = sctx->s;
 1198 
 1199     ictx->utf8started = 0; /* can't be valid UTF-8 */
 1200 
 1201     log_debug("%s: '%c'", __func__, ictx->ch);
 1202 
 1203     switch (ictx->ch) {
 1204     case '\000':    /* NUL */
 1205         break;
 1206     case '\007':    /* BEL */
 1207         if (wp != NULL)
 1208             alerts_queue(wp->window, WINDOW_BELL);
 1209         break;
 1210     case '\010':    /* BS */
 1211         screen_write_backspace(sctx);
 1212         break;
 1213     case '\011':    /* HT */
 1214         /* Don't tab beyond the end of the line. */
 1215         if (s->cx >= screen_size_x(s) - 1)
 1216             break;
 1217 
 1218         /* Find the next tab point, or use the last column if none. */
 1219         do {
 1220             s->cx++;
 1221             if (bit_test(s->tabs, s->cx))
 1222                 break;
 1223         } while (s->cx < screen_size_x(s) - 1);
 1224         break;
 1225     case '\012':    /* LF */
 1226     case '\013':    /* VT */
 1227     case '\014':    /* FF */
 1228         screen_write_linefeed(sctx, 0, ictx->cell.cell.bg);
 1229         if (s->mode & MODE_CRLF)
 1230             screen_write_carriagereturn(sctx);
 1231         break;
 1232     case '\015':    /* CR */
 1233         screen_write_carriagereturn(sctx);
 1234         break;
 1235     case '\016':    /* SO */
 1236         ictx->cell.set = 1;
 1237         break;
 1238     case '\017':    /* SI */
 1239         ictx->cell.set = 0;
 1240         break;
 1241     default:
 1242         log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1243         break;
 1244     }
 1245 
 1246     ictx->last = -1;
 1247     return (0);
 1248 }
 1249 
 1250 /* Execute escape sequence. */
 1251 static int
 1252 input_esc_dispatch(struct input_ctx *ictx)
 1253 {
 1254     struct screen_write_ctx     *sctx = &ictx->ctx;
 1255     struct window_pane      *wp = ictx->wp;
 1256     struct screen           *s = sctx->s;
 1257     struct input_table_entry    *entry;
 1258 
 1259     if (ictx->flags & INPUT_DISCARD)
 1260         return (0);
 1261     log_debug("%s: '%c', %s", __func__, ictx->ch, ictx->interm_buf);
 1262 
 1263     entry = bsearch(ictx, input_esc_table, nitems(input_esc_table),
 1264         sizeof input_esc_table[0], input_table_compare);
 1265     if (entry == NULL) {
 1266         log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1267         return (0);
 1268     }
 1269 
 1270     switch (entry->type) {
 1271     case INPUT_ESC_RIS:
 1272         if (wp != NULL)
 1273             window_pane_reset_palette(wp);
 1274         input_reset_cell(ictx);
 1275         screen_write_reset(sctx);
 1276         break;
 1277     case INPUT_ESC_IND:
 1278         screen_write_linefeed(sctx, 0, ictx->cell.cell.bg);
 1279         break;
 1280     case INPUT_ESC_NEL:
 1281         screen_write_carriagereturn(sctx);
 1282         screen_write_linefeed(sctx, 0, ictx->cell.cell.bg);
 1283         break;
 1284     case INPUT_ESC_HTS:
 1285         if (s->cx < screen_size_x(s))
 1286             bit_set(s->tabs, s->cx);
 1287         break;
 1288     case INPUT_ESC_RI:
 1289         screen_write_reverseindex(sctx, ictx->cell.cell.bg);
 1290         break;
 1291     case INPUT_ESC_DECKPAM:
 1292         screen_write_mode_set(sctx, MODE_KKEYPAD);
 1293         break;
 1294     case INPUT_ESC_DECKPNM:
 1295         screen_write_mode_clear(sctx, MODE_KKEYPAD);
 1296         break;
 1297     case INPUT_ESC_DECSC:
 1298         input_save_state(ictx);
 1299         break;
 1300     case INPUT_ESC_DECRC:
 1301         input_restore_state(ictx);
 1302         break;
 1303     case INPUT_ESC_DECALN:
 1304         screen_write_alignmenttest(sctx);
 1305         break;
 1306     case INPUT_ESC_SCSG0_ON:
 1307         ictx->cell.g0set = 1;
 1308         break;
 1309     case INPUT_ESC_SCSG0_OFF:
 1310         ictx->cell.g0set = 0;
 1311         break;
 1312     case INPUT_ESC_SCSG1_ON:
 1313         ictx->cell.g1set = 1;
 1314         break;
 1315     case INPUT_ESC_SCSG1_OFF:
 1316         ictx->cell.g1set = 0;
 1317         break;
 1318     case INPUT_ESC_ST:
 1319         /* ST terminates OSC but the state transition already did it. */
 1320         break;
 1321     }
 1322 
 1323     ictx->last = -1;
 1324     return (0);
 1325 }
 1326 
 1327 /* Execute control sequence. */
 1328 static int
 1329 input_csi_dispatch(struct input_ctx *ictx)
 1330 {
 1331     struct screen_write_ctx        *sctx = &ictx->ctx;
 1332     struct screen              *s = sctx->s;
 1333     struct input_table_entry       *entry;
 1334     int             i, n, m;
 1335     u_int               cx, bg = ictx->cell.cell.bg;
 1336 
 1337     if (ictx->flags & INPUT_DISCARD)
 1338         return (0);
 1339 
 1340     log_debug("%s: '%c' \"%s\" \"%s\"",
 1341         __func__, ictx->ch, ictx->interm_buf, ictx->param_buf);
 1342 
 1343     if (input_split(ictx) != 0)
 1344         return (0);
 1345 
 1346     entry = bsearch(ictx, input_csi_table, nitems(input_csi_table),
 1347         sizeof input_csi_table[0], input_table_compare);
 1348     if (entry == NULL) {
 1349         log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1350         return (0);
 1351     }
 1352 
 1353     switch (entry->type) {
 1354     case INPUT_CSI_CBT:
 1355         /* Find the previous tab point, n times. */
 1356         cx = s->cx;
 1357         if (cx > screen_size_x(s) - 1)
 1358             cx = screen_size_x(s) - 1;
 1359         n = input_get(ictx, 0, 1, 1);
 1360         if (n == -1)
 1361             break;
 1362         while (cx > 0 && n-- > 0) {
 1363             do
 1364                 cx--;
 1365             while (cx > 0 && !bit_test(s->tabs, cx));
 1366         }
 1367         s->cx = cx;
 1368         break;
 1369     case INPUT_CSI_CUB:
 1370         n = input_get(ictx, 0, 1, 1);
 1371         if (n != -1)
 1372             screen_write_cursorleft(sctx, n);
 1373         break;
 1374     case INPUT_CSI_CUD:
 1375         n = input_get(ictx, 0, 1, 1);
 1376         if (n != -1)
 1377             screen_write_cursordown(sctx, n);
 1378         break;
 1379     case INPUT_CSI_CUF:
 1380         n = input_get(ictx, 0, 1, 1);
 1381         if (n != -1)
 1382             screen_write_cursorright(sctx, n);
 1383         break;
 1384     case INPUT_CSI_CUP:
 1385         n = input_get(ictx, 0, 1, 1);
 1386         m = input_get(ictx, 1, 1, 1);
 1387         if (n != -1 && m != -1)
 1388             screen_write_cursormove(sctx, m - 1, n - 1, 1);
 1389         break;
 1390     case INPUT_CSI_MODSET:
 1391         n = input_get(ictx, 0, 0, 0);
 1392         m = input_get(ictx, 1, 0, 0);
 1393         if (options_get_number(global_options, "extended-keys") == 2)
 1394             break;
 1395         if (n == 0 || (n == 4 && m == 0))
 1396             screen_write_mode_clear(sctx, MODE_KEXTENDED);
 1397         else if (n == 4 && (m == 1 || m == 2))
 1398             screen_write_mode_set(sctx, MODE_KEXTENDED);
 1399         break;
 1400     case INPUT_CSI_MODOFF:
 1401         n = input_get(ictx, 0, 0, 0);
 1402         if (n == 4)
 1403             screen_write_mode_clear(sctx, MODE_KEXTENDED);
 1404         break;
 1405     case INPUT_CSI_WINOPS:
 1406         input_csi_dispatch_winops(ictx);
 1407         break;
 1408     case INPUT_CSI_CUU:
 1409         n = input_get(ictx, 0, 1, 1);
 1410         if (n != -1)
 1411             screen_write_cursorup(sctx, n);
 1412         break;
 1413     case INPUT_CSI_CNL:
 1414         n = input_get(ictx, 0, 1, 1);
 1415         if (n != -1) {
 1416             screen_write_carriagereturn(sctx);
 1417             screen_write_cursordown(sctx, n);
 1418         }
 1419         break;
 1420     case INPUT_CSI_CPL:
 1421         n = input_get(ictx, 0, 1, 1);
 1422         if (n != -1) {
 1423             screen_write_carriagereturn(sctx);
 1424             screen_write_cursorup(sctx, n);
 1425         }
 1426         break;
 1427     case INPUT_CSI_DA:
 1428         switch (input_get(ictx, 0, 0, 0)) {
 1429         case -1:
 1430             break;
 1431         case 0:
 1432             input_reply(ictx, "\033[?1;2c");
 1433             break;
 1434         default:
 1435             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1436             break;
 1437         }
 1438         break;
 1439     case INPUT_CSI_DA_TWO:
 1440         switch (input_get(ictx, 0, 0, 0)) {
 1441         case -1:
 1442             break;
 1443         case 0:
 1444             input_reply(ictx, "\033[>84;0;0c");
 1445             break;
 1446         default:
 1447             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1448             break;
 1449         }
 1450         break;
 1451     case INPUT_CSI_ECH:
 1452         n = input_get(ictx, 0, 1, 1);
 1453         if (n != -1)
 1454             screen_write_clearcharacter(sctx, n, bg);
 1455         break;
 1456     case INPUT_CSI_DCH:
 1457         n = input_get(ictx, 0, 1, 1);
 1458         if (n != -1)
 1459             screen_write_deletecharacter(sctx, n, bg);
 1460         break;
 1461     case INPUT_CSI_DECSTBM:
 1462         n = input_get(ictx, 0, 1, 1);
 1463         m = input_get(ictx, 1, 1, screen_size_y(s));
 1464         if (n != -1 && m != -1)
 1465             screen_write_scrollregion(sctx, n - 1, m - 1);
 1466         break;
 1467     case INPUT_CSI_DL:
 1468         n = input_get(ictx, 0, 1, 1);
 1469         if (n != -1)
 1470             screen_write_deleteline(sctx, n, bg);
 1471         break;
 1472     case INPUT_CSI_DSR:
 1473         switch (input_get(ictx, 0, 0, 0)) {
 1474         case -1:
 1475             break;
 1476         case 5:
 1477             input_reply(ictx, "\033[0n");
 1478             break;
 1479         case 6:
 1480             input_reply(ictx, "\033[%u;%uR", s->cy + 1, s->cx + 1);
 1481             break;
 1482         default:
 1483             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1484             break;
 1485         }
 1486         break;
 1487     case INPUT_CSI_ED:
 1488         switch (input_get(ictx, 0, 0, 0)) {
 1489         case -1:
 1490             break;
 1491         case 0:
 1492             screen_write_clearendofscreen(sctx, bg);
 1493             break;
 1494         case 1:
 1495             screen_write_clearstartofscreen(sctx, bg);
 1496             break;
 1497         case 2:
 1498             screen_write_clearscreen(sctx, bg);
 1499             break;
 1500         case 3:
 1501             if (input_get(ictx, 1, 0, 0) == 0) {
 1502                 /*
 1503                  * Linux console extension to clear history
 1504                  * (for example before locking the screen).
 1505                  */
 1506                 screen_write_clearhistory(sctx);
 1507             }
 1508             break;
 1509         default:
 1510             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1511             break;
 1512         }
 1513         break;
 1514     case INPUT_CSI_EL:
 1515         switch (input_get(ictx, 0, 0, 0)) {
 1516         case -1:
 1517             break;
 1518         case 0:
 1519             screen_write_clearendofline(sctx, bg);
 1520             break;
 1521         case 1:
 1522             screen_write_clearstartofline(sctx, bg);
 1523             break;
 1524         case 2:
 1525             screen_write_clearline(sctx, bg);
 1526             break;
 1527         default:
 1528             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1529             break;
 1530         }
 1531         break;
 1532     case INPUT_CSI_HPA:
 1533         n = input_get(ictx, 0, 1, 1);
 1534         if (n != -1)
 1535             screen_write_cursormove(sctx, n - 1, -1, 1);
 1536         break;
 1537     case INPUT_CSI_ICH:
 1538         n = input_get(ictx, 0, 1, 1);
 1539         if (n != -1)
 1540             screen_write_insertcharacter(sctx, n, bg);
 1541         break;
 1542     case INPUT_CSI_IL:
 1543         n = input_get(ictx, 0, 1, 1);
 1544         if (n != -1)
 1545             screen_write_insertline(sctx, n, bg);
 1546         break;
 1547     case INPUT_CSI_REP:
 1548         n = input_get(ictx, 0, 1, 1);
 1549         if (n == -1)
 1550             break;
 1551 
 1552         m = screen_size_x(s) - s->cx;
 1553         if (n > m)
 1554             n = m;
 1555 
 1556         if (ictx->last == -1)
 1557             break;
 1558         ictx->ch = ictx->last;
 1559 
 1560         for (i = 0; i < n; i++)
 1561             input_print(ictx);
 1562         break;
 1563     case INPUT_CSI_RCP:
 1564         input_restore_state(ictx);
 1565         break;
 1566     case INPUT_CSI_RM:
 1567         input_csi_dispatch_rm(ictx);
 1568         break;
 1569     case INPUT_CSI_RM_PRIVATE:
 1570         input_csi_dispatch_rm_private(ictx);
 1571         break;
 1572     case INPUT_CSI_SCP:
 1573         input_save_state(ictx);
 1574         break;
 1575     case INPUT_CSI_SGR:
 1576         input_csi_dispatch_sgr(ictx);
 1577         break;
 1578     case INPUT_CSI_SM:
 1579         input_csi_dispatch_sm(ictx);
 1580         break;
 1581     case INPUT_CSI_SM_PRIVATE:
 1582         input_csi_dispatch_sm_private(ictx);
 1583         break;
 1584     case INPUT_CSI_SU:
 1585         n = input_get(ictx, 0, 1, 1);
 1586         if (n != -1)
 1587             screen_write_scrollup(sctx, n, bg);
 1588         break;
 1589     case INPUT_CSI_SD:
 1590         n = input_get(ictx, 0, 1, 1);
 1591         if (n != -1)
 1592             screen_write_scrolldown(sctx, n, bg);
 1593         break;
 1594     case INPUT_CSI_TBC:
 1595         switch (input_get(ictx, 0, 0, 0)) {
 1596         case -1:
 1597             break;
 1598         case 0:
 1599             if (s->cx < screen_size_x(s))
 1600                 bit_clear(s->tabs, s->cx);
 1601             break;
 1602         case 3:
 1603             bit_nclear(s->tabs, 0, screen_size_x(s) - 1);
 1604             break;
 1605         default:
 1606             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1607             break;
 1608         }
 1609         break;
 1610     case INPUT_CSI_VPA:
 1611         n = input_get(ictx, 0, 1, 1);
 1612         if (n != -1)
 1613             screen_write_cursormove(sctx, -1, n - 1, 1);
 1614         break;
 1615     case INPUT_CSI_DECSCUSR:
 1616         n = input_get(ictx, 0, 0, 0);
 1617         if (n != -1)
 1618             screen_set_cursor_style(s, n);
 1619         break;
 1620     case INPUT_CSI_XDA:
 1621         n = input_get(ictx, 0, 0, 0);
 1622         if (n == 0)
 1623             input_reply(ictx, "\033P>|tmux %s\033\\", getversion());
 1624         break;
 1625 
 1626     }
 1627 
 1628     ictx->last = -1;
 1629     return (0);
 1630 }
 1631 
 1632 /* Handle CSI RM. */
 1633 static void
 1634 input_csi_dispatch_rm(struct input_ctx *ictx)
 1635 {
 1636     struct screen_write_ctx *sctx = &ictx->ctx;
 1637     u_int            i;
 1638 
 1639     for (i = 0; i < ictx->param_list_len; i++) {
 1640         switch (input_get(ictx, i, 0, -1)) {
 1641         case -1:
 1642             break;
 1643         case 4:     /* IRM */
 1644             screen_write_mode_clear(sctx, MODE_INSERT);
 1645             break;
 1646         case 34:
 1647             screen_write_mode_set(sctx, MODE_BLINKING);
 1648             break;
 1649         default:
 1650             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1651             break;
 1652         }
 1653     }
 1654 }
 1655 
 1656 /* Handle CSI private RM. */
 1657 static void
 1658 input_csi_dispatch_rm_private(struct input_ctx *ictx)
 1659 {
 1660     struct screen_write_ctx *sctx = &ictx->ctx;
 1661     struct grid_cell    *gc = &ictx->cell.cell;
 1662     u_int            i;
 1663 
 1664     for (i = 0; i < ictx->param_list_len; i++) {
 1665         switch (input_get(ictx, i, 0, -1)) {
 1666         case -1:
 1667             break;
 1668         case 1:     /* DECCKM */
 1669             screen_write_mode_clear(sctx, MODE_KCURSOR);
 1670             break;
 1671         case 3:     /* DECCOLM */
 1672             screen_write_cursormove(sctx, 0, 0, 1);
 1673             screen_write_clearscreen(sctx, gc->bg);
 1674             break;
 1675         case 6:     /* DECOM */
 1676             screen_write_mode_clear(sctx, MODE_ORIGIN);
 1677             screen_write_cursormove(sctx, 0, 0, 1);
 1678             break;
 1679         case 7:     /* DECAWM */
 1680             screen_write_mode_clear(sctx, MODE_WRAP);
 1681             break;
 1682         case 12:
 1683             screen_write_mode_clear(sctx, MODE_BLINKING);
 1684             break;
 1685         case 25:    /* TCEM */
 1686             screen_write_mode_clear(sctx, MODE_CURSOR);
 1687             break;
 1688         case 1000:
 1689         case 1001:
 1690         case 1002:
 1691         case 1003:
 1692             screen_write_mode_clear(sctx, ALL_MOUSE_MODES);
 1693             break;
 1694         case 1004:
 1695             screen_write_mode_clear(sctx, MODE_FOCUSON);
 1696             break;
 1697         case 1005:
 1698             screen_write_mode_clear(sctx, MODE_MOUSE_UTF8);
 1699             break;
 1700         case 1006:
 1701             screen_write_mode_clear(sctx, MODE_MOUSE_SGR);
 1702             break;
 1703         case 47:
 1704         case 1047:
 1705             screen_write_alternateoff(sctx, gc, 0);
 1706             break;
 1707         case 1049:
 1708             screen_write_alternateoff(sctx, gc, 1);
 1709             break;
 1710         case 2004:
 1711             screen_write_mode_clear(sctx, MODE_BRACKETPASTE);
 1712             break;
 1713         default:
 1714             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1715             break;
 1716         }
 1717     }
 1718 }
 1719 
 1720 /* Handle CSI SM. */
 1721 static void
 1722 input_csi_dispatch_sm(struct input_ctx *ictx)
 1723 {
 1724     struct screen_write_ctx *sctx = &ictx->ctx;
 1725     u_int            i;
 1726 
 1727     for (i = 0; i < ictx->param_list_len; i++) {
 1728         switch (input_get(ictx, i, 0, -1)) {
 1729         case -1:
 1730             break;
 1731         case 4:     /* IRM */
 1732             screen_write_mode_set(sctx, MODE_INSERT);
 1733             break;
 1734         case 34:
 1735             screen_write_mode_clear(sctx, MODE_BLINKING);
 1736             break;
 1737         default:
 1738             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1739             break;
 1740         }
 1741     }
 1742 }
 1743 
 1744 /* Handle CSI private SM. */
 1745 static void
 1746 input_csi_dispatch_sm_private(struct input_ctx *ictx)
 1747 {
 1748     struct screen_write_ctx *sctx = &ictx->ctx;
 1749     struct window_pane  *wp = ictx->wp;
 1750     struct grid_cell    *gc = &ictx->cell.cell;
 1751     u_int            i;
 1752 
 1753     for (i = 0; i < ictx->param_list_len; i++) {
 1754         switch (input_get(ictx, i, 0, -1)) {
 1755         case -1:
 1756             break;
 1757         case 1:     /* DECCKM */
 1758             screen_write_mode_set(sctx, MODE_KCURSOR);
 1759             break;
 1760         case 3:     /* DECCOLM */
 1761             screen_write_cursormove(sctx, 0, 0, 1);
 1762             screen_write_clearscreen(sctx, ictx->cell.cell.bg);
 1763             break;
 1764         case 6:     /* DECOM */
 1765             screen_write_mode_set(sctx, MODE_ORIGIN);
 1766             screen_write_cursormove(sctx, 0, 0, 1);
 1767             break;
 1768         case 7:     /* DECAWM */
 1769             screen_write_mode_set(sctx, MODE_WRAP);
 1770             break;
 1771         case 12:
 1772             screen_write_mode_set(sctx, MODE_BLINKING);
 1773             break;
 1774         case 25:    /* TCEM */
 1775             screen_write_mode_set(sctx, MODE_CURSOR);
 1776             break;
 1777         case 1000:
 1778             screen_write_mode_clear(sctx, ALL_MOUSE_MODES);
 1779             screen_write_mode_set(sctx, MODE_MOUSE_STANDARD);
 1780             break;
 1781         case 1002:
 1782             screen_write_mode_clear(sctx, ALL_MOUSE_MODES);
 1783             screen_write_mode_set(sctx, MODE_MOUSE_BUTTON);
 1784             break;
 1785         case 1003:
 1786             screen_write_mode_clear(sctx, ALL_MOUSE_MODES);
 1787             screen_write_mode_set(sctx, MODE_MOUSE_ALL);
 1788             break;
 1789         case 1004:
 1790             if (sctx->s->mode & MODE_FOCUSON)
 1791                 break;
 1792             screen_write_mode_set(sctx, MODE_FOCUSON);
 1793             if (wp != NULL)
 1794                 wp->flags |= PANE_FOCUSPUSH; /* force update */
 1795             break;
 1796         case 1005:
 1797             screen_write_mode_set(sctx, MODE_MOUSE_UTF8);
 1798             break;
 1799         case 1006:
 1800             screen_write_mode_set(sctx, MODE_MOUSE_SGR);
 1801             break;
 1802         case 47:
 1803         case 1047:
 1804             screen_write_alternateon(sctx, gc, 0);
 1805             break;
 1806         case 1049:
 1807             screen_write_alternateon(sctx, gc, 1);
 1808             break;
 1809         case 2004:
 1810             screen_write_mode_set(sctx, MODE_BRACKETPASTE);
 1811             break;
 1812         default:
 1813             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1814             break;
 1815         }
 1816     }
 1817 }
 1818 
 1819 /* Handle CSI window operations. */
 1820 static void
 1821 input_csi_dispatch_winops(struct input_ctx *ictx)
 1822 {
 1823     struct screen_write_ctx *sctx = &ictx->ctx;
 1824     struct screen       *s = sctx->s;
 1825     struct window_pane  *wp = ictx->wp;
 1826     u_int            x = screen_size_x(s), y = screen_size_y(s);
 1827     int          n, m;
 1828 
 1829     m = 0;
 1830     while ((n = input_get(ictx, m, 0, -1)) != -1) {
 1831         switch (n) {
 1832         case 1:
 1833         case 2:
 1834         case 5:
 1835         case 6:
 1836         case 7:
 1837         case 11:
 1838         case 13:
 1839         case 14:
 1840         case 19:
 1841         case 20:
 1842         case 21:
 1843         case 24:
 1844             break;
 1845         case 3:
 1846         case 4:
 1847         case 8:
 1848             m++;
 1849             if (input_get(ictx, m, 0, -1) == -1)
 1850                 return;
 1851             /* FALLTHROUGH */
 1852         case 9:
 1853         case 10:
 1854             m++;
 1855             if (input_get(ictx, m, 0, -1) == -1)
 1856                 return;
 1857             break;
 1858         case 22:
 1859             m++;
 1860             switch (input_get(ictx, m, 0, -1)) {
 1861             case -1:
 1862                 return;
 1863             case 0:
 1864             case 2:
 1865                 screen_push_title(sctx->s);
 1866                 break;
 1867             }
 1868             break;
 1869         case 23:
 1870             m++;
 1871             switch (input_get(ictx, m, 0, -1)) {
 1872             case -1:
 1873                 return;
 1874             case 0:
 1875             case 2:
 1876                 screen_pop_title(sctx->s);
 1877                 if (wp != NULL) {
 1878                     notify_pane("pane-title-changed", wp);
 1879                     server_redraw_window_borders(wp->window);
 1880                     server_status_window(wp->window);
 1881                 }
 1882                 break;
 1883             }
 1884             break;
 1885         case 18:
 1886             input_reply(ictx, "\033[8;%u;%ut", x, y);
 1887             break;
 1888         default:
 1889             log_debug("%s: unknown '%c'", __func__, ictx->ch);
 1890             break;
 1891         }
 1892         m++;
 1893     }
 1894 }
 1895 
 1896 /* Helper for 256 colour SGR. */
 1897 static int
 1898 input_csi_dispatch_sgr_256_do(struct input_ctx *ictx, int fgbg, int c)
 1899 {
 1900     struct grid_cell    *gc = &ictx->cell.cell;
 1901 
 1902     if (c == -1 || c > 255) {
 1903         if (fgbg == 38)
 1904             gc->fg = 8;
 1905         else if (fgbg == 48)
 1906             gc->bg = 8;
 1907     } else {
 1908         if (fgbg == 38)
 1909             gc->fg = c | COLOUR_FLAG_256;
 1910         else if (fgbg == 48)
 1911             gc->bg = c | COLOUR_FLAG_256;
 1912         else if (fgbg == 58)
 1913             gc->us = c | COLOUR_FLAG_256;
 1914     }
 1915     return (1);
 1916 }
 1917 
 1918 /* Handle CSI SGR for 256 colours. */
 1919 static void
 1920 input_csi_dispatch_sgr_256(struct input_ctx *ictx, int fgbg, u_int *i)
 1921 {
 1922     int c;
 1923 
 1924     c = input_get(ictx, (*i) + 1, 0, -1);
 1925     if (input_csi_dispatch_sgr_256_do(ictx, fgbg, c))
 1926         (*i)++;
 1927 }
 1928 
 1929 /* Helper for RGB colour SGR. */
 1930 static int
 1931 input_csi_dispatch_sgr_rgb_do(struct input_ctx *ictx, int fgbg, int r, int g,
 1932     int b)
 1933 {
 1934     struct grid_cell    *gc = &ictx->cell.cell;
 1935 
 1936     if (r == -1 || r > 255)
 1937         return (0);
 1938     if (g == -1 || g > 255)
 1939         return (0);
 1940     if (b == -1 || b > 255)
 1941         return (0);
 1942 
 1943     if (fgbg == 38)
 1944         gc->fg = colour_join_rgb(r, g, b);
 1945     else if (fgbg == 48)
 1946         gc->bg = colour_join_rgb(r, g, b);
 1947     else if (fgbg == 58)
 1948         gc->us = colour_join_rgb(r, g, b);
 1949     return (1);
 1950 }
 1951 
 1952 /* Handle CSI SGR for RGB colours. */
 1953 static void
 1954 input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
 1955 {
 1956     int r, g, b;
 1957 
 1958     r = input_get(ictx, (*i) + 1, 0, -1);
 1959     g = input_get(ictx, (*i) + 2, 0, -1);
 1960     b = input_get(ictx, (*i) + 3, 0, -1);
 1961     if (input_csi_dispatch_sgr_rgb_do(ictx, fgbg, r, g, b))
 1962         (*i) += 3;
 1963 }
 1964 
 1965 /* Handle CSI SGR with a ISO parameter. */
 1966 static void
 1967 input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i)
 1968 {
 1969     struct grid_cell    *gc = &ictx->cell.cell;
 1970     char            *s = ictx->param_list[i].str, *copy, *ptr, *out;
 1971     int          p[8];
 1972     u_int            n;
 1973     const char      *errstr;
 1974 
 1975     for (n = 0; n < nitems(p); n++)
 1976         p[n] = -1;
 1977     n = 0;
 1978 
 1979     ptr = copy = xstrdup(s);
 1980     while ((out = strsep(&ptr, ":")) != NULL) {
 1981         if (*out != '\0') {
 1982             p[n++] = strtonum(out, 0, INT_MAX, &errstr);
 1983             if (errstr != NULL || n == nitems(p)) {
 1984                 free(copy);
 1985                 return;
 1986             }
 1987         } else {
 1988             n++;
 1989             if (n == nitems(p)) {
 1990                 free(copy);
 1991                 return;
 1992             }
 1993         }
 1994         log_debug("%s: %u = %d", __func__, n - 1, p[n - 1]);
 1995     }
 1996     free(copy);
 1997 
 1998     if (n == 0)
 1999         return;
 2000     if (p[0] == 4) {
 2001         if (n != 2)
 2002             return;
 2003         switch (p[1]) {
 2004         case 0:
 2005             gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 2006             break;
 2007         case 1:
 2008             gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 2009             gc->attr |= GRID_ATTR_UNDERSCORE;
 2010             break;
 2011         case 2:
 2012             gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 2013             gc->attr |= GRID_ATTR_UNDERSCORE_2;
 2014             break;
 2015         case 3:
 2016             gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 2017             gc->attr |= GRID_ATTR_UNDERSCORE_3;
 2018             break;
 2019         case 4:
 2020             gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 2021             gc->attr |= GRID_ATTR_UNDERSCORE_4;
 2022             break;
 2023         case 5:
 2024             gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 2025             gc->attr |= GRID_ATTR_UNDERSCORE_5;
 2026             break;
 2027         }
 2028         return;
 2029     }
 2030     if (n < 2 || (p[0] != 38 && p[0] != 48 && p[0] != 58))
 2031         return;
 2032     switch (p[1]) {
 2033     case 2:
 2034         if (n < 3)
 2035             break;
 2036         if (n == 5)
 2037             i = 2;
 2038         else
 2039             i = 3;
 2040         if (n < i + 3)
 2041             break;
 2042         input_csi_dispatch_sgr_rgb_do(ictx, p[0], p[i], p[i + 1],
 2043             p[i + 2]);
 2044         break;
 2045     case 5:
 2046         if (n < 3)
 2047             break;
 2048         input_csi_dispatch_sgr_256_do(ictx, p[0], p[2]);
 2049         break;
 2050     }
 2051 }
 2052 
 2053 /* Handle CSI SGR. */
 2054 static void
 2055 input_csi_dispatch_sgr(struct input_ctx *ictx)
 2056 {
 2057     struct grid_cell    *gc = &ictx->cell.cell;
 2058     u_int            i;
 2059     int          n;
 2060 
 2061     if (ictx->param_list_len == 0) {
 2062         memcpy(gc, &grid_default_cell, sizeof *gc);
 2063         return;
 2064     }
 2065 
 2066     for (i = 0; i < ictx->param_list_len; i++) {
 2067         if (ictx->param_list[i].type == INPUT_STRING) {
 2068             input_csi_dispatch_sgr_colon(ictx, i);
 2069             continue;
 2070         }
 2071         n = input_get(ictx, i, 0, 0);
 2072         if (n == -1)
 2073             continue;
 2074 
 2075         if (n == 38 || n == 48 || n == 58) {
 2076             i++;
 2077             switch (input_get(ictx, i, 0, -1)) {
 2078             case 2:
 2079                 input_csi_dispatch_sgr_rgb(ictx, n, &i);
 2080                 break;
 2081             case 5:
 2082                 input_csi_dispatch_sgr_256(ictx, n, &i);
 2083                 break;
 2084             }
 2085             continue;
 2086         }
 2087 
 2088         switch (n) {
 2089         case 0:
 2090             memcpy(gc, &grid_default_cell, sizeof *gc);
 2091             break;
 2092         case 1:
 2093             gc->attr |= GRID_ATTR_BRIGHT;
 2094             break;
 2095         case 2:
 2096             gc->attr |= GRID_ATTR_DIM;
 2097             break;
 2098         case 3:
 2099             gc->attr |= GRID_ATTR_ITALICS;
 2100             break;
 2101         case 4:
 2102             gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 2103             gc->attr |= GRID_ATTR_UNDERSCORE;
 2104             break;
 2105         case 5:
 2106         case 6:
 2107             gc->attr |= GRID_ATTR_BLINK;
 2108             break;
 2109         case 7:
 2110             gc->attr |= GRID_ATTR_REVERSE;
 2111             break;
 2112         case 8:
 2113             gc->attr |= GRID_ATTR_HIDDEN;
 2114             break;
 2115         case 9:
 2116             gc->attr |= GRID_ATTR_STRIKETHROUGH;
 2117             break;
 2118         case 21:
 2119             gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 2120             gc->attr |= GRID_ATTR_UNDERSCORE_2;
 2121             break;
 2122         case 22:
 2123             gc->attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_DIM);
 2124             break;
 2125         case 23:
 2126             gc->attr &= ~GRID_ATTR_ITALICS;
 2127             break;
 2128         case 24:
 2129             gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 2130             break;
 2131         case 25:
 2132             gc->attr &= ~GRID_ATTR_BLINK;
 2133             break;
 2134         case 27:
 2135             gc->attr &= ~GRID_ATTR_REVERSE;
 2136             break;
 2137         case 28:
 2138             gc->attr &= ~GRID_ATTR_HIDDEN;
 2139             break;
 2140         case 29:
 2141             gc->attr &= ~GRID_ATTR_STRIKETHROUGH;
 2142             break;
 2143         case 30:
 2144         case 31:
 2145         case 32:
 2146         case 33:
 2147         case 34:
 2148         case 35:
 2149         case 36:
 2150         case 37:
 2151             gc->fg = n - 30;
 2152             break;
 2153         case 39:
 2154             gc->fg = 8;
 2155             break;
 2156         case 40:
 2157         case 41:
 2158         case 42:
 2159         case 43:
 2160         case 44:
 2161         case 45:
 2162         case 46:
 2163         case 47:
 2164             gc->bg = n - 40;
 2165             break;
 2166         case 49:
 2167             gc->bg = 8;
 2168             break;
 2169         case 53:
 2170             gc->attr |= GRID_ATTR_OVERLINE;
 2171             break;
 2172         case 55:
 2173             gc->attr &= ~GRID_ATTR_OVERLINE;
 2174             break;
 2175         case 59:
 2176             gc->us = 0;
 2177             break;
 2178         case 90:
 2179         case 91:
 2180         case 92:
 2181         case 93:
 2182         case 94:
 2183         case 95:
 2184         case 96:
 2185         case 97:
 2186             gc->fg = n;
 2187             break;
 2188         case 100:
 2189         case 101:
 2190         case 102:
 2191         case 103:
 2192         case 104:
 2193         case 105:
 2194         case 106:
 2195         case 107:
 2196             gc->bg = n - 10;
 2197             break;
 2198         }
 2199     }
 2200 }
 2201 
 2202 /* End of input with BEL. */
 2203 static int
 2204 input_end_bel(struct input_ctx *ictx)
 2205 {
 2206     log_debug("%s", __func__);
 2207 
 2208     ictx->input_end = INPUT_END_BEL;
 2209 
 2210     return (0);
 2211 }
 2212 
 2213 /* DCS string started. */
 2214 static void
 2215 input_enter_dcs(struct input_ctx *ictx)
 2216 {
 2217     log_debug("%s", __func__);
 2218 
 2219     input_clear(ictx);
 2220     input_start_timer(ictx);
 2221     ictx->last = -1;
 2222 }
 2223 
 2224 /* DCS terminator (ST) received. */
 2225 static int
 2226 input_dcs_dispatch(struct input_ctx *ictx)
 2227 {
 2228     struct screen_write_ctx *sctx = &ictx->ctx;
 2229     u_char          *buf = ictx->input_buf;
 2230     size_t           len = ictx->input_len;
 2231     const char       prefix[] = "tmux;";
 2232     const u_int      prefixlen = (sizeof prefix) - 1;
 2233 
 2234     if (ictx->flags & INPUT_DISCARD)
 2235         return (0);
 2236 
 2237     log_debug("%s: \"%s\"", __func__, buf);
 2238 
 2239     if (len >= prefixlen && strncmp(buf, prefix, prefixlen) == 0)
 2240         screen_write_rawstring(sctx, buf + prefixlen, len - prefixlen);
 2241 
 2242     return (0);
 2243 }
 2244 
 2245 /* OSC string started. */
 2246 static void
 2247 input_enter_osc(struct input_ctx *ictx)
 2248 {
 2249     log_debug("%s", __func__);
 2250 
 2251     input_clear(ictx);
 2252     input_start_timer(ictx);
 2253     ictx->last = -1;
 2254 }
 2255 
 2256 /* OSC terminator (ST) received. */
 2257 static void
 2258 input_exit_osc(struct input_ctx *ictx)
 2259 {
 2260     struct screen_write_ctx *sctx = &ictx->ctx;
 2261     struct window_pane  *wp = ictx->wp;
 2262     u_char          *p = ictx->input_buf;
 2263     u_int            option;
 2264 
 2265     if (ictx->flags & INPUT_DISCARD)
 2266         return;
 2267     if (ictx->input_len < 1 || *p < '0' || *p > '9')
 2268         return;
 2269 
 2270     log_debug("%s: \"%s\" (end %s)", __func__, p,
 2271         ictx->input_end == INPUT_END_ST ? "ST" : "BEL");
 2272 
 2273     option = 0;
 2274     while (*p >= '0' && *p <= '9')
 2275         option = option * 10 + *p++ - '0';
 2276     if (*p == ';')
 2277         p++;
 2278 
 2279     switch (option) {
 2280     case 0:
 2281     case 2:
 2282         if (screen_set_title(sctx->s, p) && wp != NULL) {
 2283             notify_pane("pane-title-changed", wp);
 2284             server_redraw_window_borders(wp->window);
 2285             server_status_window(wp->window);
 2286         }
 2287         break;
 2288     case 4:
 2289         input_osc_4(ictx, p);
 2290         break;
 2291     case 7:
 2292         if (utf8_isvalid(p)) {
 2293             screen_set_path(sctx->s, p);
 2294             if (wp != NULL) {
 2295                 server_redraw_window_borders(wp->window);
 2296                 server_status_window(wp->window);
 2297             }
 2298         }
 2299         break;
 2300     case 10:
 2301         input_osc_10(ictx, p);
 2302         break;
 2303     case 11:
 2304         input_osc_11(ictx, p);
 2305         break;
 2306     case 12:
 2307         if (utf8_isvalid(p) && *p != '?') /* ? is colour request */
 2308             screen_set_cursor_colour(sctx->s, p);
 2309         break;
 2310     case 52:
 2311         input_osc_52(ictx, p);
 2312         break;
 2313     case 104:
 2314         input_osc_104(ictx, p);
 2315         break;
 2316     case 110:
 2317         input_osc_110(ictx, p);
 2318         break;
 2319     case 111:
 2320         input_osc_111(ictx, p);
 2321         break;
 2322     case 112:
 2323         if (*p == '\0') /* no arguments allowed */
 2324             screen_set_cursor_colour(sctx->s, "");
 2325         break;
 2326     default:
 2327         log_debug("%s: unknown '%u'", __func__, option);
 2328         break;
 2329     }
 2330 }
 2331 
 2332 /* APC string started. */
 2333 static void
 2334 input_enter_apc(struct input_ctx *ictx)
 2335 {
 2336     log_debug("%s", __func__);
 2337 
 2338     input_clear(ictx);
 2339     input_start_timer(ictx);
 2340     ictx->last = -1;
 2341 }
 2342 
 2343 /* APC terminator (ST) received. */
 2344 static void
 2345 input_exit_apc(struct input_ctx *ictx)
 2346 {
 2347     struct screen_write_ctx *sctx = &ictx->ctx;
 2348     struct window_pane  *wp = ictx->wp;
 2349 
 2350     if (ictx->flags & INPUT_DISCARD)
 2351         return;
 2352     log_debug("%s: \"%s\"", __func__, ictx->input_buf);
 2353 
 2354     if (screen_set_title(sctx->s, ictx->input_buf) && wp != NULL) {
 2355         notify_pane("pane-title-changed", wp);
 2356         server_redraw_window_borders(wp->window);
 2357         server_status_window(wp->window);
 2358     }
 2359 }
 2360 
 2361 /* Rename string started. */
 2362 static void
 2363 input_enter_rename(struct input_ctx *ictx)
 2364 {
 2365     log_debug("%s", __func__);
 2366 
 2367     input_clear(ictx);
 2368     input_start_timer(ictx);
 2369     ictx->last = -1;
 2370 }
 2371 
 2372 /* Rename terminator (ST) received. */
 2373 static void
 2374 input_exit_rename(struct input_ctx *ictx)
 2375 {
 2376     struct window_pane  *wp = ictx->wp;
 2377     struct options_entry    *o;
 2378 
 2379     if (wp == NULL)
 2380         return;
 2381     if (ictx->flags & INPUT_DISCARD)
 2382         return;
 2383     if (!options_get_number(ictx->wp->options, "allow-rename"))
 2384         return;
 2385     log_debug("%s: \"%s\"", __func__, ictx->input_buf);
 2386 
 2387     if (!utf8_isvalid(ictx->input_buf))
 2388         return;
 2389 
 2390     if (ictx->input_len == 0) {
 2391         o = options_get_only(wp->window->options, "automatic-rename");
 2392         if (o != NULL)
 2393             options_remove_or_default(o, -1, NULL);
 2394         return;
 2395     }
 2396     window_set_name(wp->window, ictx->input_buf);
 2397     options_set_number(wp->window->options, "automatic-rename", 0);
 2398     server_redraw_window_borders(wp->window);
 2399     server_status_window(wp->window);
 2400 }
 2401 
 2402 /* Open UTF-8 character. */
 2403 static int
 2404 input_top_bit_set(struct input_ctx *ictx)
 2405 {
 2406     struct screen_write_ctx *sctx = &ictx->ctx;
 2407     struct utf8_data    *ud = &ictx->utf8data;
 2408 
 2409     ictx->last = -1;
 2410 
 2411     if (!ictx->utf8started) {
 2412         if (utf8_open(ud, ictx->ch) != UTF8_MORE)
 2413             return (0);
 2414         ictx->utf8started = 1;
 2415         return (0);
 2416     }
 2417 
 2418     switch (utf8_append(ud, ictx->ch)) {
 2419     case UTF8_MORE:
 2420         return (0);
 2421     case UTF8_ERROR:
 2422         ictx->utf8started = 0;
 2423         return (0);
 2424     case UTF8_DONE:
 2425         break;
 2426     }
 2427     ictx->utf8started = 0;
 2428 
 2429     log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size,
 2430         (int)ud->size, ud->data, ud->width);
 2431 
 2432     utf8_copy(&ictx->cell.cell.data, ud);
 2433     screen_write_collect_add(sctx, &ictx->cell.cell);
 2434 
 2435     return (0);
 2436 }
 2437 
 2438 /* Parse colour from OSC. */
 2439 static int
 2440 input_osc_parse_colour(const char *p)
 2441 {
 2442     double   c, m, y, k = 0;
 2443     u_int    r, g, b;
 2444     size_t   len = strlen(p);
 2445     int  colour = -1;
 2446     char    *copy;
 2447 
 2448     if ((len == 12 && sscanf(p, "rgb:%02x/%02x/%02x", &r, &g, &b) == 3) ||
 2449         (len == 7 && sscanf(p, "#%02x%02x%02x", &r, &g, &b) == 3) ||
 2450         sscanf(p, "%d,%d,%d", &r, &g, &b) == 3)
 2451         colour = colour_join_rgb(r, g, b);
 2452     else if ((len == 18 &&
 2453         sscanf(p, "rgb:%04x/%04x/%04x", &r, &g, &b) == 3) ||
 2454         (len == 13 && sscanf(p, "#%04x%04x%04x", &r, &g, &b) == 3))
 2455         colour = colour_join_rgb(r >> 8, g >> 8, b >> 8);
 2456     else if ((sscanf(p, "cmyk:%lf/%lf/%lf/%lf", &c, &m, &y, &k) == 4 ||
 2457         sscanf(p, "cmy:%lf/%lf/%lf", &c, &m, &y) == 3) &&
 2458         c >= 0 && c <= 1 && m >= 0 && m <= 1 &&
 2459         y >= 0 && y <= 1 && k >= 0 && k <= 1) {
 2460         colour = colour_join_rgb(
 2461             (1 - c) * (1 - k) * 255,
 2462             (1 - m) * (1 - k) * 255,
 2463             (1 - y) * (1 - k) * 255);
 2464     } else {
 2465         while (len != 0 && *p == ' ') {
 2466             p++;
 2467             len--;
 2468         }
 2469         while (len != 0 && p[len - 1] == ' ')
 2470             len--;
 2471         copy = xstrndup(p, len);
 2472         colour = colour_byname(copy);
 2473         free(copy);
 2474     }
 2475     log_debug("%s: %s = %s", __func__, p, colour_tostring(colour));
 2476     return (colour);
 2477 }
 2478 
 2479 /* Reply to a colour request. */
 2480 static void
 2481 input_osc_colour_reply(struct input_ctx *ictx, u_int n, int c)
 2482 {
 2483     u_char   r, g, b;
 2484     const char  *end;
 2485 
 2486     if (c == 8 || (~c & COLOUR_FLAG_RGB))
 2487         return;
 2488     colour_split_rgb(c, &r, &g, &b);
 2489 
 2490     if (ictx->input_end == INPUT_END_BEL)
 2491         end = "\007";
 2492     else
 2493         end = "\033\\";
 2494     input_reply(ictx, "\033]%u;rgb:%02hhx/%02hhx/%02hhx%s", n, r, g, b, end);
 2495 }
 2496 
 2497 /* Handle the OSC 4 sequence for setting (multiple) palette entries. */
 2498 static void
 2499 input_osc_4(struct input_ctx *ictx, const char *p)
 2500 {
 2501     struct window_pane  *wp = ictx->wp;
 2502     char            *copy, *s, *next = NULL;
 2503     long             idx;
 2504     int          c;
 2505 
 2506     if (wp == NULL)
 2507         return;
 2508 
 2509     copy = s = xstrdup(p);
 2510     while (s != NULL && *s != '\0') {
 2511         idx = strtol(s, &next, 10);
 2512         if (*next++ != ';')
 2513             goto bad;
 2514         if (idx < 0 || idx >= 0x100)
 2515             goto bad;
 2516 
 2517         s = strsep(&next, ";");
 2518         if ((c = input_osc_parse_colour(s)) == -1) {
 2519             s = next;
 2520             continue;
 2521         }
 2522 
 2523         window_pane_set_palette(wp, idx, c);
 2524         s = next;
 2525     }
 2526 
 2527     free(copy);
 2528     return;
 2529 
 2530 bad:
 2531     log_debug("bad OSC 4: %s", p);
 2532     free(copy);
 2533 }
 2534 
 2535 /* Handle the OSC 10 sequence for setting and querying foreground colour. */
 2536 static void
 2537 input_osc_10(struct input_ctx *ictx, const char *p)
 2538 {
 2539     struct window_pane  *wp = ictx->wp;
 2540     struct grid_cell     defaults;
 2541     int          c;
 2542 
 2543     if (wp == NULL)
 2544         return;
 2545 
 2546     if (strcmp(p, "?") == 0) {
 2547         tty_default_colours(&defaults, wp);
 2548         input_osc_colour_reply(ictx, 10, defaults.fg);
 2549         return;
 2550     }
 2551 
 2552     if ((c = input_osc_parse_colour(p)) == -1)
 2553         goto bad;
 2554     wp->fg = c;
 2555     wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
 2556 
 2557     return;
 2558 
 2559 bad:
 2560     log_debug("bad OSC 10: %s", p);
 2561 }
 2562 
 2563 /* Handle the OSC 110 sequence for resetting background colour. */
 2564 static void
 2565 input_osc_110(struct input_ctx *ictx, const char *p)
 2566 {
 2567     struct window_pane  *wp = ictx->wp;
 2568 
 2569     if (wp == NULL)
 2570         return;
 2571 
 2572     if (*p != '\0')
 2573         return;
 2574 
 2575     wp->fg = 8;
 2576     wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
 2577 }
 2578 
 2579 /* Handle the OSC 11 sequence for setting and querying background colour. */
 2580 static void
 2581 input_osc_11(struct input_ctx *ictx, const char *p)
 2582 {
 2583     struct window_pane  *wp = ictx->wp;
 2584     struct grid_cell     defaults;
 2585     int          c;
 2586 
 2587     if (wp == NULL)
 2588         return;
 2589 
 2590     if (strcmp(p, "?") == 0) {
 2591         tty_default_colours(&defaults, wp);
 2592         input_osc_colour_reply(ictx, 11, defaults.bg);
 2593         return;
 2594     }
 2595 
 2596     if ((c = input_osc_parse_colour(p)) == -1)
 2597         goto bad;
 2598     wp->bg = c;
 2599     wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
 2600 
 2601     return;
 2602 
 2603 bad:
 2604     log_debug("bad OSC 11: %s", p);
 2605 }
 2606 
 2607 /* Handle the OSC 111 sequence for resetting background colour. */
 2608 static void
 2609 input_osc_111(struct input_ctx *ictx, const char *p)
 2610 {
 2611     struct window_pane  *wp = ictx->wp;
 2612 
 2613     if (wp == NULL)
 2614         return;
 2615 
 2616     if (*p != '\0')
 2617         return;
 2618 
 2619     wp->bg = 8;
 2620     wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
 2621 }
 2622 
 2623 /* Handle the OSC 52 sequence for setting the clipboard. */
 2624 static void
 2625 input_osc_52(struct input_ctx *ictx, const char *p)
 2626 {
 2627     struct window_pane  *wp = ictx->wp;
 2628     char            *end;
 2629     const char      *buf;
 2630     size_t           len;
 2631     u_char          *out;
 2632     int          outlen, state;
 2633     struct screen_write_ctx  ctx;
 2634     struct paste_buffer *pb;
 2635 
 2636     if (wp == NULL)
 2637         return;
 2638     state = options_get_number(global_options, "set-clipboard");
 2639     if (state != 2)
 2640         return;
 2641 
 2642     if ((end = strchr(p, ';')) == NULL)
 2643         return;
 2644     end++;
 2645     if (*end == '\0')
 2646         return;
 2647     log_debug("%s: %s", __func__, end);
 2648 
 2649     if (strcmp(end, "?") == 0) {
 2650         if ((pb = paste_get_top(NULL)) != NULL) {
 2651             buf = paste_buffer_data(pb, &len);
 2652             outlen = 4 * ((len + 2) / 3) + 1;
 2653             out = xmalloc(outlen);
 2654             if ((outlen = b64_ntop(buf, len, out, outlen)) == -1) {
 2655                 free(out);
 2656                 return;
 2657             }
 2658         } else {
 2659             outlen = 0;
 2660             out = NULL;
 2661         }
 2662         bufferevent_write(ictx->event, "\033]52;;", 6);
 2663         if (outlen != 0)
 2664             bufferevent_write(ictx->event, out, outlen);
 2665         if (ictx->input_end == INPUT_END_BEL)
 2666             bufferevent_write(ictx->event, "\007", 1);
 2667         else
 2668             bufferevent_write(ictx->event, "\033\\", 2);
 2669         free(out);
 2670         return;
 2671     }
 2672 
 2673     len = (strlen(end) / 4) * 3;
 2674     if (len == 0)
 2675         return;
 2676 
 2677     out = xmalloc(len);
 2678     if ((outlen = b64_pton(end, out, len)) == -1) {
 2679         free(out);
 2680         return;
 2681     }
 2682 
 2683     screen_write_start_pane(&ctx, wp, NULL);
 2684     screen_write_setselection(&ctx, out, outlen);
 2685     screen_write_stop(&ctx);
 2686     notify_pane("pane-set-clipboard", wp);
 2687 
 2688     paste_add(NULL, out, outlen);
 2689 }
 2690 
 2691 /* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */
 2692 static void
 2693 input_osc_104(struct input_ctx *ictx, const char *p)
 2694 {
 2695     struct window_pane  *wp = ictx->wp;
 2696     char            *copy, *s;
 2697     long             idx;
 2698 
 2699     if (wp == NULL)
 2700         return;
 2701 
 2702     if (*p == '\0') {
 2703         window_pane_reset_palette(wp);
 2704         return;
 2705     }
 2706 
 2707     copy = s = xstrdup(p);
 2708     while (*s != '\0') {
 2709         idx = strtol(s, &s, 10);
 2710         if (*s != '\0' && *s != ';')
 2711             goto bad;
 2712         if (idx < 0 || idx >= 0x100)
 2713             goto bad;
 2714 
 2715         window_pane_unset_palette(wp, idx);
 2716         if (*s == ';')
 2717             s++;
 2718     }
 2719     free(copy);
 2720     return;
 2721 
 2722 bad:
 2723     log_debug("bad OSC 104: %s", p);
 2724     free(copy);
 2725 }