"Fossies" - the Fresh Open Source Software Archive

Member "tmux-3.2a/input-keys.c" (10 Jun 2021, 15133 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-keys.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 <stdlib.h>
   22 #include <string.h>
   23 
   24 #include "tmux.h"
   25 
   26 /*
   27  * This file is rather misleadingly named, it contains the code which takes a
   28  * key code and translates it into something suitable to be sent to the
   29  * application running in a pane (similar to input.c does in the other
   30  * direction with output).
   31  */
   32 
   33 static void  input_key_mouse(struct window_pane *, struct mouse_event *);
   34 
   35 /* Entry in the key tree. */
   36 struct input_key_entry {
   37     key_code             key;
   38     const char          *data;
   39 
   40     RB_ENTRY(input_key_entry)    entry;
   41 };
   42 RB_HEAD(input_key_tree, input_key_entry);
   43 
   44 /* Tree of input keys. */
   45 static int  input_key_cmp(struct input_key_entry *,
   46             struct input_key_entry *);
   47 RB_GENERATE_STATIC(input_key_tree, input_key_entry, entry, input_key_cmp);
   48 struct input_key_tree input_key_tree = RB_INITIALIZER(&input_key_tree);
   49 
   50 /* List of default keys, the tree is built from this. */
   51 static struct input_key_entry input_key_defaults[] = {
   52     /* Paste keys. */
   53     { .key = KEYC_PASTE_START,
   54       .data = "\033[200~"
   55     },
   56     { .key = KEYC_PASTE_END,
   57       .data = "\033[201~"
   58     },
   59 
   60     /* Function keys. */
   61     { .key = KEYC_F1,
   62       .data = "\033OP"
   63     },
   64     { .key = KEYC_F2,
   65       .data = "\033OQ"
   66     },
   67     { .key = KEYC_F3,
   68       .data = "\033OR"
   69     },
   70     { .key = KEYC_F4,
   71       .data = "\033OS"
   72     },
   73     { .key = KEYC_F5,
   74       .data = "\033[15~"
   75     },
   76     { .key = KEYC_F6,
   77       .data = "\033[17~"
   78     },
   79     { .key = KEYC_F7,
   80       .data = "\033[18~"
   81     },
   82     { .key = KEYC_F8,
   83       .data = "\033[19~"
   84     },
   85     { .key = KEYC_F9,
   86       .data = "\033[20~"
   87     },
   88     { .key = KEYC_F10,
   89       .data = "\033[21~"
   90     },
   91     { .key = KEYC_F11,
   92       .data = "\033[23~"
   93     },
   94     { .key = KEYC_F12,
   95       .data = "\033[24~"
   96     },
   97     { .key = KEYC_IC,
   98       .data = "\033[2~"
   99     },
  100     { .key = KEYC_DC,
  101       .data = "\033[3~"
  102     },
  103     { .key = KEYC_HOME,
  104       .data = "\033[1~"
  105     },
  106     { .key = KEYC_END,
  107       .data = "\033[4~"
  108     },
  109     { .key = KEYC_NPAGE,
  110       .data = "\033[6~"
  111     },
  112     { .key = KEYC_PPAGE,
  113       .data = "\033[5~"
  114     },
  115     { .key = KEYC_BTAB,
  116       .data = "\033[Z"
  117     },
  118 
  119     /* Arrow keys. */
  120     { .key = KEYC_UP|KEYC_CURSOR,
  121       .data = "\033OA"
  122     },
  123     { .key = KEYC_DOWN|KEYC_CURSOR,
  124       .data = "\033OB"
  125     },
  126     { .key = KEYC_RIGHT|KEYC_CURSOR,
  127       .data = "\033OC"
  128     },
  129     { .key = KEYC_LEFT|KEYC_CURSOR,
  130       .data = "\033OD"
  131     },
  132     { .key = KEYC_UP,
  133       .data = "\033[A"
  134     },
  135     { .key = KEYC_DOWN,
  136       .data = "\033[B"
  137     },
  138     { .key = KEYC_RIGHT,
  139       .data = "\033[C"
  140     },
  141     { .key = KEYC_LEFT,
  142       .data = "\033[D"
  143     },
  144 
  145     /* Keypad keys. */
  146     { .key = KEYC_KP_SLASH|KEYC_KEYPAD,
  147       .data = "\033Oo"
  148     },
  149     { .key = KEYC_KP_STAR|KEYC_KEYPAD,
  150       .data = "\033Oj"
  151     },
  152     { .key = KEYC_KP_MINUS|KEYC_KEYPAD,
  153       .data = "\033Om"
  154     },
  155     { .key = KEYC_KP_SEVEN|KEYC_KEYPAD,
  156       .data = "\033Ow"
  157     },
  158     { .key = KEYC_KP_EIGHT|KEYC_KEYPAD,
  159       .data = "\033Ox"
  160     },
  161     { .key = KEYC_KP_NINE|KEYC_KEYPAD,
  162       .data = "\033Oy"
  163     },
  164     { .key = KEYC_KP_PLUS|KEYC_KEYPAD,
  165       .data = "\033Ok"
  166     },
  167     { .key = KEYC_KP_FOUR|KEYC_KEYPAD,
  168       .data = "\033Ot"
  169     },
  170     { .key = KEYC_KP_FIVE|KEYC_KEYPAD,
  171       .data = "\033Ou"
  172     },
  173     { .key = KEYC_KP_SIX|KEYC_KEYPAD,
  174       .data = "\033Ov"
  175     },
  176     { .key = KEYC_KP_ONE|KEYC_KEYPAD,
  177       .data = "\033Oq"
  178     },
  179     { .key = KEYC_KP_TWO|KEYC_KEYPAD,
  180       .data = "\033Or"
  181     },
  182     { .key = KEYC_KP_THREE|KEYC_KEYPAD,
  183       .data = "\033Os"
  184     },
  185     { .key = KEYC_KP_ENTER|KEYC_KEYPAD,
  186       .data = "\033OM"
  187     },
  188     { .key = KEYC_KP_ZERO|KEYC_KEYPAD,
  189       .data = "\033Op"
  190     },
  191     { .key = KEYC_KP_PERIOD|KEYC_KEYPAD,
  192       .data = "\033On"
  193     },
  194     { .key = KEYC_KP_SLASH,
  195       .data = "/"
  196     },
  197     { .key = KEYC_KP_STAR,
  198       .data = "*"
  199     },
  200     { .key = KEYC_KP_MINUS,
  201       .data = "-"
  202     },
  203     { .key = KEYC_KP_SEVEN,
  204       .data = "7"
  205     },
  206     { .key = KEYC_KP_EIGHT,
  207       .data = "8"
  208     },
  209     { .key = KEYC_KP_NINE,
  210       .data = "9"
  211     },
  212     { .key = KEYC_KP_PLUS,
  213       .data = "+"
  214     },
  215     { .key = KEYC_KP_FOUR,
  216       .data = "4"
  217     },
  218     { .key = KEYC_KP_FIVE,
  219       .data = "5"
  220     },
  221     { .key = KEYC_KP_SIX,
  222       .data = "6"
  223     },
  224     { .key = KEYC_KP_ONE,
  225       .data = "1"
  226     },
  227     { .key = KEYC_KP_TWO,
  228       .data = "2"
  229     },
  230     { .key = KEYC_KP_THREE,
  231       .data = "3"
  232     },
  233     { .key = KEYC_KP_ENTER,
  234       .data = "\n"
  235     },
  236     { .key = KEYC_KP_ZERO,
  237       .data = "0"
  238     },
  239     { .key = KEYC_KP_PERIOD,
  240       .data = "."
  241     },
  242 
  243     /* Keys with an embedded modifier. */
  244     { .key = KEYC_F1|KEYC_BUILD_MODIFIERS,
  245       .data = "\033[1;_P"
  246     },
  247     { .key = KEYC_F2|KEYC_BUILD_MODIFIERS,
  248       .data = "\033[1;_Q"
  249     },
  250     { .key = KEYC_F3|KEYC_BUILD_MODIFIERS,
  251       .data = "\033[1;_R"
  252     },
  253     { .key = KEYC_F4|KEYC_BUILD_MODIFIERS,
  254       .data = "\033[1;_S"
  255     },
  256     { .key = KEYC_F5|KEYC_BUILD_MODIFIERS,
  257       .data = "\033[15;_~"
  258     },
  259     { .key = KEYC_F6|KEYC_BUILD_MODIFIERS,
  260       .data = "\033[17;_~"
  261     },
  262     { .key = KEYC_F7|KEYC_BUILD_MODIFIERS,
  263       .data = "\033[18;_~"
  264     },
  265     { .key = KEYC_F8|KEYC_BUILD_MODIFIERS,
  266       .data = "\033[19;_~"
  267     },
  268     { .key = KEYC_F9|KEYC_BUILD_MODIFIERS,
  269       .data = "\033[20;_~"
  270     },
  271     { .key = KEYC_F10|KEYC_BUILD_MODIFIERS,
  272       .data = "\033[21;_~"
  273     },
  274     { .key = KEYC_F11|KEYC_BUILD_MODIFIERS,
  275       .data = "\033[23;_~"
  276     },
  277     { .key = KEYC_F12|KEYC_BUILD_MODIFIERS,
  278       .data = "\033[24;_~"
  279     },
  280     { .key = KEYC_UP|KEYC_BUILD_MODIFIERS,
  281       .data = "\033[1;_A"
  282     },
  283     { .key = KEYC_DOWN|KEYC_BUILD_MODIFIERS,
  284       .data = "\033[1;_B"
  285     },
  286     { .key = KEYC_RIGHT|KEYC_BUILD_MODIFIERS,
  287       .data = "\033[1;_C"
  288     },
  289     { .key = KEYC_LEFT|KEYC_BUILD_MODIFIERS,
  290       .data = "\033[1;_D"
  291     },
  292     { .key = KEYC_HOME|KEYC_BUILD_MODIFIERS,
  293       .data = "\033[1;_H"
  294     },
  295     { .key = KEYC_END|KEYC_BUILD_MODIFIERS,
  296       .data = "\033[1;_F"
  297     },
  298     { .key = KEYC_PPAGE|KEYC_BUILD_MODIFIERS,
  299       .data = "\033[5;_~"
  300     },
  301     { .key = KEYC_NPAGE|KEYC_BUILD_MODIFIERS,
  302       .data = "\033[6;_~"
  303     },
  304     { .key = KEYC_IC|KEYC_BUILD_MODIFIERS,
  305       .data = "\033[2;_~"
  306     },
  307     { .key = KEYC_DC|KEYC_BUILD_MODIFIERS,
  308       .data = "\033[3;_~"
  309     }
  310 };
  311 static const key_code input_key_modifiers[] = {
  312     0,
  313     0,
  314     KEYC_SHIFT,
  315     KEYC_META|KEYC_IMPLIED_META,
  316     KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META,
  317     KEYC_CTRL,
  318     KEYC_SHIFT|KEYC_CTRL,
  319     KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL,
  320     KEYC_SHIFT|KEYC_META|KEYC_IMPLIED_META|KEYC_CTRL
  321 };
  322 
  323 /* Input key comparison function. */
  324 static int
  325 input_key_cmp(struct input_key_entry *ike1, struct input_key_entry *ike2)
  326 {
  327     if (ike1->key < ike2->key)
  328         return (-1);
  329     if (ike1->key > ike2->key)
  330         return (1);
  331     return (0);
  332 }
  333 
  334 /* Look for key in tree. */
  335 static struct input_key_entry *
  336 input_key_get (key_code key)
  337 {
  338     struct input_key_entry  entry = { .key = key };
  339 
  340     return (RB_FIND(input_key_tree, &input_key_tree, &entry));
  341 }
  342 
  343 /* Split a character into two UTF-8 bytes. */
  344 static size_t
  345 input_key_split2(u_int c, u_char *dst)
  346 {
  347     if (c > 0x7f) {
  348         dst[0] = (c >> 6) | 0xc0;
  349         dst[1] = (c & 0x3f) | 0x80;
  350         return (2);
  351     }
  352     dst[0] = c;
  353     return (1);
  354 }
  355 
  356 /* Build input key tree. */
  357 void
  358 input_key_build(void)
  359 {
  360     struct input_key_entry  *ike, *new;
  361     u_int            i, j;
  362     char            *data;
  363     key_code         key;
  364 
  365     for (i = 0; i < nitems(input_key_defaults); i++) {
  366         ike = &input_key_defaults[i];
  367         if (~ike->key & KEYC_BUILD_MODIFIERS) {
  368             RB_INSERT(input_key_tree, &input_key_tree, ike);
  369             continue;
  370         }
  371 
  372         for (j = 2; j < nitems(input_key_modifiers); j++) {
  373             key = (ike->key & ~KEYC_BUILD_MODIFIERS);
  374             data = xstrdup(ike->data);
  375             data[strcspn(data, "_")] = '0' + j;
  376 
  377             new = xcalloc(1, sizeof *new);
  378             new->key = key|input_key_modifiers[j];
  379             new->data = data;
  380             RB_INSERT(input_key_tree, &input_key_tree, new);
  381         }
  382     }
  383 
  384     RB_FOREACH(ike, input_key_tree, &input_key_tree) {
  385         log_debug("%s: 0x%llx (%s) is %s", __func__, ike->key,
  386             key_string_lookup_key(ike->key, 1), ike->data);
  387     }
  388 }
  389 
  390 /* Translate a key code into an output key sequence for a pane. */
  391 int
  392 input_key_pane(struct window_pane *wp, key_code key, struct mouse_event *m)
  393 {
  394     if (log_get_level() != 0) {
  395         log_debug("writing key 0x%llx (%s) to %%%u", key,
  396             key_string_lookup_key(key, 1), wp->id);
  397     }
  398 
  399     if (KEYC_IS_MOUSE(key)) {
  400         if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id)
  401             input_key_mouse(wp, m);
  402         return (0);
  403     }
  404     return (input_key(wp->screen, wp->event, key));
  405 }
  406 
  407 static void
  408 input_key_write(const char *from, struct bufferevent *bev, const char *data,
  409     size_t size)
  410 {
  411     log_debug("%s: %.*s", from, (int)size, data);
  412     bufferevent_write(bev, data, size);
  413 }
  414 
  415 /* Translate a key code into an output key sequence. */
  416 int
  417 input_key(struct screen *s, struct bufferevent *bev, key_code key)
  418 {
  419     struct input_key_entry  *ike;
  420     key_code         justkey, newkey, outkey;
  421     struct utf8_data     ud;
  422     char             tmp[64], modifier;
  423 
  424     /* Mouse keys need a pane. */
  425     if (KEYC_IS_MOUSE(key))
  426         return (0);
  427 
  428     /* Literal keys go as themselves (can't be more than eight bits). */
  429     if (key & KEYC_LITERAL) {
  430         ud.data[0] = (u_char)key;
  431         input_key_write(__func__, bev, &ud.data[0], 1);
  432         return (0);
  433     }
  434 
  435     /* Is this backspace? */
  436     if ((key & KEYC_MASK_KEY) == KEYC_BSPACE) {
  437         newkey = options_get_number(global_options, "backspace");
  438         if (newkey >= 0x7f)
  439             newkey = '\177';
  440         key = newkey|(key & (KEYC_MASK_MODIFIERS|KEYC_MASK_FLAGS));
  441     }
  442 
  443     /*
  444      * If this is a normal 7-bit key, just send it, with a leading escape
  445      * if necessary. If it is a UTF-8 key, split it and send it.
  446      */
  447     justkey = (key & ~(KEYC_META|KEYC_IMPLIED_META));
  448     if (justkey <= 0x7f) {
  449         if (key & KEYC_META)
  450             input_key_write(__func__, bev, "\033", 1);
  451         ud.data[0] = justkey;
  452         input_key_write(__func__, bev, &ud.data[0], 1);
  453         return (0);
  454     }
  455     if (KEYC_IS_UNICODE(justkey)) {
  456         if (key & KEYC_META)
  457             input_key_write(__func__, bev, "\033", 1);
  458         utf8_to_data(justkey, &ud);
  459         input_key_write(__func__, bev, ud.data, ud.size);
  460         return (0);
  461     }
  462 
  463     /*
  464      * Look up in the tree. If not in application keypad or cursor mode,
  465      * remove the flags from the key.
  466      */
  467     if (~s->mode & MODE_KKEYPAD)
  468         key &= ~KEYC_KEYPAD;
  469     if (~s->mode & MODE_KCURSOR)
  470         key &= ~KEYC_CURSOR;
  471     ike = input_key_get(key);
  472     if (ike == NULL && (key & KEYC_META) && (~key & KEYC_IMPLIED_META))
  473         ike = input_key_get(key & ~KEYC_META);
  474     if (ike == NULL && (key & KEYC_CURSOR))
  475         ike = input_key_get(key & ~KEYC_CURSOR);
  476     if (ike == NULL && (key & KEYC_KEYPAD))
  477         ike = input_key_get(key & ~KEYC_KEYPAD);
  478     if (ike != NULL) {
  479         log_debug("found key 0x%llx: \"%s\"", key, ike->data);
  480         if ((key & KEYC_META) && (~key & KEYC_IMPLIED_META))
  481             input_key_write(__func__, bev, "\033", 1);
  482         input_key_write(__func__, bev, ike->data, strlen(ike->data));
  483         return (0);
  484     }
  485 
  486     /* No builtin key sequence; construct an extended key sequence. */
  487     if (~s->mode & MODE_KEXTENDED) {
  488         if ((key & KEYC_MASK_MODIFIERS) != KEYC_CTRL)
  489             goto missing;
  490         justkey = (key & KEYC_MASK_KEY);
  491         switch (justkey) {
  492         case ' ':
  493         case '2':
  494             key = 0|(key & ~KEYC_MASK_KEY);
  495             break;
  496         case '|':
  497             key = 28|(key & ~KEYC_MASK_KEY);
  498             break;
  499         case '6':
  500             key = 30|(key & ~KEYC_MASK_KEY);
  501             break;
  502         case '-':
  503         case '/':
  504             key = 31|(key & ~KEYC_MASK_KEY);
  505             break;
  506         case '?':
  507             key = 127|(key & ~KEYC_MASK_KEY);
  508             break;
  509         default:
  510             if (justkey >= 'A' && justkey <= '_')
  511                 key = (justkey - 'A')|(key & ~KEYC_MASK_KEY);
  512             else if (justkey >= 'a' && justkey <= '~')
  513                 key = (justkey - 96)|(key & ~KEYC_MASK_KEY);
  514             else
  515                 return (0);
  516             break;
  517         }
  518         return (input_key(s, bev, key & ~KEYC_CTRL));
  519     }
  520     outkey = (key & KEYC_MASK_KEY);
  521     switch (key & KEYC_MASK_MODIFIERS) {
  522     case KEYC_SHIFT:
  523         modifier = '2';
  524         break;
  525     case KEYC_META:
  526         modifier = '3';
  527         break;
  528     case KEYC_SHIFT|KEYC_META:
  529         modifier = '4';
  530         break;
  531     case KEYC_CTRL:
  532         modifier = '5';
  533         break;
  534     case KEYC_SHIFT|KEYC_CTRL:
  535         modifier = '6';
  536         break;
  537     case KEYC_META|KEYC_CTRL:
  538         modifier = '7';
  539         break;
  540     case KEYC_SHIFT|KEYC_META|KEYC_CTRL:
  541         modifier = '8';
  542         break;
  543     default:
  544         goto missing;
  545     }
  546     xsnprintf(tmp, sizeof tmp, "\033[%llu;%cu", outkey, modifier);
  547     input_key_write(__func__, bev, tmp, strlen(tmp));
  548     return (0);
  549 
  550 missing:
  551     log_debug("key 0x%llx missing", key);
  552     return (-1);
  553 }
  554 
  555 /* Get mouse event string. */
  556 int
  557 input_key_get_mouse(struct screen *s, struct mouse_event *m, u_int x, u_int y,
  558     const char **rbuf, size_t *rlen)
  559 {
  560     static char  buf[40];
  561     size_t       len;
  562 
  563     *rbuf = NULL;
  564     *rlen = 0;
  565 
  566     /* If this pane is not in button or all mode, discard motion events. */
  567     if (MOUSE_DRAG(m->b) && (s->mode & MOTION_MOUSE_MODES) == 0)
  568         return (0);
  569     if ((s->mode & ALL_MOUSE_MODES) == 0)
  570         return (0);
  571 
  572     /*
  573      * If this event is a release event and not in all mode, discard it.
  574      * In SGR mode we can tell absolutely because a release is normally
  575      * shown by the last character. Without SGR, we check if the last
  576      * buttons was also a release.
  577      */
  578     if (m->sgr_type != ' ') {
  579         if (MOUSE_DRAG(m->sgr_b) &&
  580             MOUSE_BUTTONS(m->sgr_b) == 3 &&
  581             (~s->mode & MODE_MOUSE_ALL))
  582             return (0);
  583     } else {
  584         if (MOUSE_DRAG(m->b) &&
  585             MOUSE_BUTTONS(m->b) == 3 &&
  586             MOUSE_BUTTONS(m->lb) == 3 &&
  587             (~s->mode & MODE_MOUSE_ALL))
  588             return (0);
  589     }
  590 
  591     /*
  592      * Use the SGR (1006) extension only if the application requested it
  593      * and the underlying terminal also sent the event in this format (this
  594      * is because an old style mouse release event cannot be converted into
  595      * the new SGR format, since the released button is unknown). Otherwise
  596      * pretend that tmux doesn't speak this extension, and fall back to the
  597      * UTF-8 (1005) extension if the application requested, or to the
  598      * legacy format.
  599      */
  600     if (m->sgr_type != ' ' && (s->mode & MODE_MOUSE_SGR)) {
  601         len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c",
  602             m->sgr_b, x + 1, y + 1, m->sgr_type);
  603     } else if (s->mode & MODE_MOUSE_UTF8) {
  604         if (m->b > 0x7ff - 32 || x > 0x7ff - 33 || y > 0x7ff - 33)
  605             return (0);
  606         len = xsnprintf(buf, sizeof buf, "\033[M");
  607         len += input_key_split2(m->b + 32, &buf[len]);
  608         len += input_key_split2(x + 33, &buf[len]);
  609         len += input_key_split2(y + 33, &buf[len]);
  610     } else {
  611         if (m->b > 223)
  612             return (0);
  613         len = xsnprintf(buf, sizeof buf, "\033[M");
  614         buf[len++] = m->b + 32;
  615         buf[len++] = x + 33;
  616         buf[len++] = y + 33;
  617     }
  618 
  619     *rbuf = buf;
  620     *rlen = len;
  621     return (1);
  622 }
  623 
  624 /* Translate mouse and output. */
  625 static void
  626 input_key_mouse(struct window_pane *wp, struct mouse_event *m)
  627 {
  628     struct screen   *s = wp->screen;
  629     u_int        x, y;
  630     const char  *buf;
  631     size_t       len;
  632 
  633     /* Ignore events if no mouse mode or the pane is not visible. */
  634     if (m->ignore || (s->mode & ALL_MOUSE_MODES) == 0)
  635         return;
  636     if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
  637         return;
  638     if (!window_pane_visible(wp))
  639         return;
  640     if (!input_key_get_mouse(s, m, x, y, &buf, &len))
  641         return;
  642     log_debug("writing mouse %.*s to %%%u", (int)len, buf, wp->id);
  643     input_key_write(__func__, wp->event, buf, len);
  644 }