[BACK]Return to input-keys.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/input-keys.c between version 1.71 and 1.72

version 1.71, 2020/04/07 13:38:30 version 1.72, 2020/05/16 16:30:59
Line 33 
Line 33 
   
 static void      input_key_mouse(struct window_pane *, struct mouse_event *);  static void      input_key_mouse(struct window_pane *, struct mouse_event *);
   
 struct input_key_ent {  /* Entry in the key tree. */
         key_code         key;  struct input_key_entry {
         const char      *data;          key_code                         key;
           const char                      *data;
   
         int              flags;          RB_ENTRY(input_key_entry)        entry;
 #define INPUTKEY_KEYPAD 0x1     /* keypad key */  
 #define INPUTKEY_CURSOR 0x2     /* cursor key */  
 };  };
   RB_HEAD(input_key_tree, input_key_entry);
   
 static const struct input_key_ent input_keys[] = {  /* Tree of input keys. */
   static int      input_key_cmp(struct input_key_entry *,
                       struct input_key_entry *);
   RB_GENERATE_STATIC(input_key_tree, input_key_entry, entry, input_key_cmp);
   struct input_key_tree input_key_tree = RB_INITIALIZER(&input_key_tree);
   
   /* List of default keys, the tree is built from this. */
   static struct input_key_entry input_key_defaults[] = {
         /* Paste keys. */          /* Paste keys. */
         { KEYC_PASTE_START,     "\033[200~",    0 },          { .key = KEYC_PASTE_START,
         { KEYC_PASTE_END,       "\033[201~",    0 },            .data = "\033[200~"
           },
           { .key = KEYC_PASTE_END,
             .data = "\033[201~"
           },
   
         /* Function keys. */          /* Function keys. */
         { KEYC_F1,              "\033OP",       0 },          { .key = KEYC_F1,
         { KEYC_F2,              "\033OQ",       0 },            .data = "\033OP"
         { KEYC_F3,              "\033OR",       0 },          },
         { KEYC_F4,              "\033OS",       0 },          { .key = KEYC_F2,
         { KEYC_F5,              "\033[15~",     0 },            .data = "\033OQ"
         { KEYC_F6,              "\033[17~",     0 },          },
         { KEYC_F7,              "\033[18~",     0 },          { .key = KEYC_F3,
         { KEYC_F8,              "\033[19~",     0 },            .data = "\033OR"
         { KEYC_F9,              "\033[20~",     0 },          },
         { KEYC_F10,             "\033[21~",     0 },          { .key = KEYC_F4,
         { KEYC_F11,             "\033[23~",     0 },            .data = "\033OS"
         { KEYC_F12,             "\033[24~",     0 },          },
         { KEYC_F1|KEYC_SHIFT,   "\033[25~",     0 },          { .key = KEYC_F5,
         { KEYC_F2|KEYC_SHIFT,   "\033[26~",     0 },            .data = "\033[15~"
         { KEYC_F3|KEYC_SHIFT,   "\033[28~",     0 },          },
         { KEYC_F4|KEYC_SHIFT,   "\033[29~",     0 },          { .key = KEYC_F6,
         { KEYC_F5|KEYC_SHIFT,   "\033[31~",     0 },            .data = "\033[17~"
         { KEYC_F6|KEYC_SHIFT,   "\033[32~",     0 },          },
         { KEYC_F7|KEYC_SHIFT,   "\033[33~",     0 },          { .key = KEYC_F7,
         { KEYC_F8|KEYC_SHIFT,   "\033[34~",     0 },            .data = "\033[18~"
         { KEYC_IC,              "\033[2~",      0 },          },
         { KEYC_DC,              "\033[3~",      0 },          { .key = KEYC_F8,
         { KEYC_HOME,            "\033[1~",      0 },            .data = "\033[19~"
         { KEYC_END,             "\033[4~",      0 },          },
         { KEYC_NPAGE,           "\033[6~",      0 },          { .key = KEYC_F9,
         { KEYC_PPAGE,           "\033[5~",      0 },            .data = "\033[20~"
         { KEYC_BTAB,            "\033[Z",       0 },          },
           { .key = KEYC_F10,
             .data = "\033[21~"
           },
           { .key = KEYC_F11,
             .data = "\033[23~"
           },
           { .key = KEYC_F12,
             .data = "\033[24~"
           },
           { .key = KEYC_F1|KEYC_SHIFT,
             .data = "\033[25~"
           },
           { .key = KEYC_F2|KEYC_SHIFT,
             .data = "\033[26~"
           },
           { .key = KEYC_F3|KEYC_SHIFT,
             .data = "\033[28~"
           },
           { .key = KEYC_F4|KEYC_SHIFT,
             .data = "\033[29~"
           },
           { .key = KEYC_F5|KEYC_SHIFT,
             .data = "\033[31~"
           },
           { .key = KEYC_F6|KEYC_SHIFT,
             .data = "\033[32~"
           },
           { .key = KEYC_F7|KEYC_SHIFT,
             .data = "\033[33~"
           },
           { .key = KEYC_F8|KEYC_SHIFT,
             .data = "\033[34~"
           },
           { .key = KEYC_IC,
             .data = "\033[2~"
           },
           { .key = KEYC_DC,
             .data = "\033[3~"
           },
           { .key = KEYC_HOME,
             .data = "\033[1~"
           },
           { .key = KEYC_END,
             .data = "\033[4~"
           },
           { .key = KEYC_NPAGE,
             .data = "\033[6~"
           },
           { .key = KEYC_PPAGE,
             .data = "\033[5~"
           },
           { .key = KEYC_BTAB,
             .data = "\033[Z"
           },
   
         /*          /* Arrow keys. */
          * Arrow keys. Cursor versions must come first. The codes are toggled          { .key = KEYC_UP|KEYC_CURSOR,
          * between CSI and SS3 versions when ctrl is pressed.            .data = "\033OA"
          */          },
         { KEYC_UP|KEYC_CTRL,    "\033[A",       INPUTKEY_CURSOR },          { .key = KEYC_DOWN|KEYC_CURSOR,
         { KEYC_DOWN|KEYC_CTRL,  "\033[B",       INPUTKEY_CURSOR },            .data = "\033OB"
         { KEYC_RIGHT|KEYC_CTRL, "\033[C",       INPUTKEY_CURSOR },          },
         { KEYC_LEFT|KEYC_CTRL,  "\033[D",       INPUTKEY_CURSOR },          { .key = KEYC_RIGHT|KEYC_CURSOR,
             .data = "\033OC"
           },
           { .key = KEYC_LEFT|KEYC_CURSOR,
             .data = "\033OD"
           },
           { .key = KEYC_UP,
             .data = "\033[A"
           },
           { .key = KEYC_DOWN,
             .data = "\033[B"
           },
           { .key = KEYC_RIGHT,
             .data = "\033[C"
           },
           { .key = KEYC_LEFT,
             .data = "\033[D"
           },
   
         { KEYC_UP,              "\033OA",       INPUTKEY_CURSOR },          /* Keypad keys. */
         { KEYC_DOWN,            "\033OB",       INPUTKEY_CURSOR },          { .key = KEYC_KP_SLASH|KEYC_KEYPAD,
         { KEYC_RIGHT,           "\033OC",       INPUTKEY_CURSOR },            .data = "\033Oo"
         { KEYC_LEFT,            "\033OD",       INPUTKEY_CURSOR },          },
           { .key = KEYC_KP_STAR|KEYC_KEYPAD,
             .data = "\033Oj"
           },
           { .key = KEYC_KP_MINUS|KEYC_KEYPAD,
             .data = "\033Om"
           },
           { .key = KEYC_KP_SEVEN|KEYC_KEYPAD,
             .data = "\033Ow"
           },
           { .key = KEYC_KP_EIGHT|KEYC_KEYPAD,
             .data = "\033Ox"
           },
           { .key = KEYC_KP_NINE|KEYC_KEYPAD,
             .data = "\033Oy"
           },
           { .key = KEYC_KP_PLUS|KEYC_KEYPAD,
             .data = "\033Ok"
           },
           { .key = KEYC_KP_FOUR|KEYC_KEYPAD,
             .data = "\033Ot"
           },
           { .key = KEYC_KP_FIVE|KEYC_KEYPAD,
             .data = "\033Ou"
           },
           { .key = KEYC_KP_SIX|KEYC_KEYPAD,
             .data = "\033Ov"
           },
           { .key = KEYC_KP_ONE|KEYC_KEYPAD,
             .data = "\033Oq"
           },
           { .key = KEYC_KP_TWO|KEYC_KEYPAD,
             .data = "\033Or"
           },
           { .key = KEYC_KP_THREE|KEYC_KEYPAD,
             .data = "\033Os"
           },
           { .key = KEYC_KP_ENTER|KEYC_KEYPAD,
             .data = "\033OM"
           },
           { .key = KEYC_KP_ZERO|KEYC_KEYPAD,
             .data = "\033Op"
           },
           { .key = KEYC_KP_PERIOD|KEYC_KEYPAD,
             .data = "\033On"
           },
           { .key = KEYC_KP_SLASH,
             .data = "/"
           },
           { .key = KEYC_KP_STAR,
             .data = "*"
           },
           { .key = KEYC_KP_MINUS,
             .data = "-"
           },
           { .key = KEYC_KP_SEVEN,
             .data = "7"
           },
           { .key = KEYC_KP_EIGHT,
             .data = "8"
           },
           { .key = KEYC_KP_NINE,
             .data = "9"
           },
           { .key = KEYC_KP_PLUS,
             .data = "+"
           },
           { .key = KEYC_KP_FOUR,
             .data = "4"
           },
           { .key = KEYC_KP_FIVE,
             .data = "5"
           },
           { .key = KEYC_KP_SIX,
             .data = "6"
           },
           { .key = KEYC_KP_ONE,
             .data = "1"
           },
           { .key = KEYC_KP_TWO,
             .data = "2"
           },
           { .key = KEYC_KP_THREE,
             .data = "3"
           },
           { .key = KEYC_KP_ENTER,
             .data = "\n"
           },
           { .key = KEYC_KP_ZERO,
             .data = "0"
           },
           { .key = KEYC_KP_PERIOD,
             .data = "."
           },
   
         { KEYC_UP|KEYC_CTRL,    "\033OA",       0 },          /* Keys with an embedded modifier. */
         { KEYC_DOWN|KEYC_CTRL,  "\033OB",       0 },          { .key = KEYC_F1|KEYC_XTERM,
         { KEYC_RIGHT|KEYC_CTRL, "\033OC",       0 },            .data = "\033[1;_P"
         { KEYC_LEFT|KEYC_CTRL,  "\033OD",       0 },          },
           { .key = KEYC_F2|KEYC_XTERM,
         { KEYC_UP,              "\033[A",       0 },            .data = "\033[1;_Q"
         { KEYC_DOWN,            "\033[B",       0 },          },
         { KEYC_RIGHT,           "\033[C",       0 },          { .key = KEYC_F3|KEYC_XTERM,
         { KEYC_LEFT,            "\033[D",       0 },            .data = "\033[1;_R"
           },
         /* Keypad keys. Keypad versions must come first. */          { .key = KEYC_F4|KEYC_XTERM,
         { KEYC_KP_SLASH,        "\033Oo",       INPUTKEY_KEYPAD },            .data = "\033[1;_S"
         { KEYC_KP_STAR,         "\033Oj",       INPUTKEY_KEYPAD },          },
         { KEYC_KP_MINUS,        "\033Om",       INPUTKEY_KEYPAD },          { .key = KEYC_F5|KEYC_XTERM,
         { KEYC_KP_SEVEN,        "\033Ow",       INPUTKEY_KEYPAD },            .data = "\033[15;_~"
         { KEYC_KP_EIGHT,        "\033Ox",       INPUTKEY_KEYPAD },          },
         { KEYC_KP_NINE,         "\033Oy",       INPUTKEY_KEYPAD },          { .key = KEYC_F6|KEYC_XTERM,
         { KEYC_KP_PLUS,         "\033Ok",       INPUTKEY_KEYPAD },            .data = "\033[17;_~"
         { KEYC_KP_FOUR,         "\033Ot",       INPUTKEY_KEYPAD },          },
         { KEYC_KP_FIVE,         "\033Ou",       INPUTKEY_KEYPAD },          { .key = KEYC_F7|KEYC_XTERM,
         { KEYC_KP_SIX,          "\033Ov",       INPUTKEY_KEYPAD },            .data = "\033[18;_~"
         { KEYC_KP_ONE,          "\033Oq",       INPUTKEY_KEYPAD },          },
         { KEYC_KP_TWO,          "\033Or",       INPUTKEY_KEYPAD },          { .key = KEYC_F8|KEYC_XTERM,
         { KEYC_KP_THREE,        "\033Os",       INPUTKEY_KEYPAD },            .data = "\033[19;_~"
         { KEYC_KP_ENTER,        "\033OM",       INPUTKEY_KEYPAD },          },
         { KEYC_KP_ZERO,         "\033Op",       INPUTKEY_KEYPAD },          { .key = KEYC_F9|KEYC_XTERM,
         { KEYC_KP_PERIOD,       "\033On",       INPUTKEY_KEYPAD },            .data = "\033[20;_~"
           },
         { KEYC_KP_SLASH,        "/",            0 },          { .key = KEYC_F10|KEYC_XTERM,
         { KEYC_KP_STAR,         "*",            0 },            .data = "\033[21;_~"
         { KEYC_KP_MINUS,        "-",            0 },          },
         { KEYC_KP_SEVEN,        "7",            0 },          { .key = KEYC_F11|KEYC_XTERM,
         { KEYC_KP_EIGHT,        "8",            0 },            .data = "\033[23;_~"
         { KEYC_KP_NINE,         "9",            0 },          },
         { KEYC_KP_PLUS,         "+",            0 },          { .key = KEYC_F12|KEYC_XTERM,
         { KEYC_KP_FOUR,         "4",            0 },            .data = "\033[24;_~"
         { KEYC_KP_FIVE,         "5",            0 },          },
         { KEYC_KP_SIX,          "6",            0 },          { .key = KEYC_UP|KEYC_XTERM,
         { KEYC_KP_ONE,          "1",            0 },            .data = "\033[1;_A"
         { KEYC_KP_TWO,          "2",            0 },          },
         { KEYC_KP_THREE,        "3",            0 },          { .key = KEYC_DOWN|KEYC_XTERM,
         { KEYC_KP_ENTER,        "\n",           0 },            .data = "\033[1;_B"
         { KEYC_KP_ZERO,         "0",            0 },          },
         { KEYC_KP_PERIOD,       ".",            0 },          { .key = KEYC_RIGHT|KEYC_XTERM,
             .data = "\033[1;_C"
           },
           { .key = KEYC_LEFT|KEYC_XTERM,
             .data = "\033[1;_D"
           },
           { .key = KEYC_HOME|KEYC_XTERM,
             .data = "\033[1;_H"
           },
           { .key = KEYC_END|KEYC_XTERM,
             .data = "\033[1;_F"
           },
           { .key = KEYC_PPAGE|KEYC_XTERM,
             .data = "\033[5;_~"
           },
           { .key = KEYC_NPAGE|KEYC_XTERM,
             .data = "\033[6;_~"
           },
           { .key = KEYC_IC|KEYC_XTERM,
             .data = "\033[2;_~"
           },
           { .key = KEYC_DC|KEYC_XTERM,
             .data = "\033[3;_~" }
 };  };
   static const key_code input_key_modifiers[] = {
           0,
           0,
           KEYC_SHIFT|KEYC_XTERM,
           KEYC_ESCAPE|KEYC_XTERM,
           KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM,
           KEYC_CTRL|KEYC_XTERM,
           KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM,
           KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM,
           KEYC_SHIFT|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM
   };
   
   /* Input key comparison function. */
   static int
   input_key_cmp(struct input_key_entry *ike1, struct input_key_entry *ike2)
   {
           if (ike1->key < ike2->key)
                   return (-1);
           if (ike1->key > ike2->key)
                   return (1);
           return (0);
   }
   
 /* Split a character into two UTF-8 bytes. */  /* Split a character into two UTF-8 bytes. */
 static size_t  static size_t
 input_split2(u_int c, u_char *dst)  input_key_split2(u_int c, u_char *dst)
 {  {
         if (c > 0x7f) {          if (c > 0x7f) {
                 dst[0] = (c >> 6) | 0xc0;                  dst[0] = (c >> 6) | 0xc0;
Line 149 
Line 368 
         return (1);          return (1);
 }  }
   
   /* Build input key tree. */
   void
   input_key_build(void)
   {
           struct input_key_entry  *ike, *new;
           u_int                    i, j;
           char                    *data;
   
           for (i = 0; i < nitems(input_key_defaults); i++) {
                   ike = &input_key_defaults[i];
                   if (~ike->key & KEYC_XTERM) {
                           RB_INSERT(input_key_tree, &input_key_tree, ike);
                           continue;
                   }
   
                   for (j = 2; j < nitems(input_key_modifiers); j++) {
                           data = xstrdup(ike->data);
                           data[strcspn(data, "_")] = '0' + j;
   
                           new = xcalloc(1, sizeof *new);
                           new->key = ike->key|input_key_modifiers[j];
                           new->data = data;
                           RB_INSERT(input_key_tree, &input_key_tree, new);
                   }
           }
   
           RB_FOREACH(ike, input_key_tree, &input_key_tree) {
                   log_debug("%s: 0x%llx (%s) is %s", __func__, ike->key,
                       key_string_lookup_key(ike->key), ike->data);
           }
   }
   
 /* Translate a key code into an output key sequence for a pane. */  /* Translate a key code into an output key sequence for a pane. */
 int  int
 input_key_pane(struct window_pane *wp, key_code key, struct mouse_event *m)  input_key_pane(struct window_pane *wp, key_code key, struct mouse_event *m)
 {  {
         log_debug("writing key 0x%llx (%s) to %%%u", key,          if (log_get_level() != 0) {
             key_string_lookup_key(key), wp->id);                  log_debug("writing key 0x%llx (%s) to %%%u", key,
                       key_string_lookup_key(key), wp->id);
           }
   
         if (KEYC_IS_MOUSE(key)) {          if (KEYC_IS_MOUSE(key)) {
                 if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id)                  if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id)
                         input_key_mouse(wp, m);                          input_key_mouse(wp, m);
                 return (0);                  return (0);
         }          }
         return (input_key(wp, wp->screen, wp->event, key));          return (input_key(wp->screen, wp->event, key));
 }  }
   
 /* Translate a key code into an output key sequence. */  /* Translate a key code into an output key sequence. */
 int  int
 input_key(struct window_pane *wp, struct screen *s, struct bufferevent *bev,  input_key(struct screen *s, struct bufferevent *bev, key_code key)
     key_code key)  
 {  {
         const struct input_key_ent      *ike;          struct input_key_entry  *ike, entry;
         u_int                            i;          size_t                   datalen;
         size_t                           dlen;          key_code                 justkey, newkey;
         char                            *out;          struct utf8_data         ud;
         key_code                         justkey, newkey;  
         struct utf8_data                 ud;  
   
         /* Mouse keys need a pane. */          /* Mouse keys need a pane. */
         if (KEYC_IS_MOUSE(key))          if (KEYC_IS_MOUSE(key))
Line 217 
Line 467 
         }          }
   
         /*          /*
          * Then try to look this up as an xterm key, if the flag to output them           * Look up in the tree. If not in application keypad or cursor mode,
          * is set.           * remove the flags from the key.
          */           */
         if (wp == NULL || options_get_number(wp->window->options, "xterm-keys")) {          if (~s->mode & MODE_KKEYPAD)
                 if ((out = xterm_keys_lookup(key)) != NULL) {                  key &= ~KEYC_KEYPAD;
                         bufferevent_write(bev, out, strlen(out));          if (~s->mode & MODE_KCURSOR)
                         free(out);                  key &= ~KEYC_CURSOR;
                         return (0);          entry.key = key;
                 }          if ((ike = RB_FIND(input_key_tree, &input_key_tree, &entry)) == NULL) {
         }  
         key &= ~KEYC_XTERM;  
   
         /* Otherwise look the key up in the table. */  
         for (i = 0; i < nitems(input_keys); i++) {  
                 ike = &input_keys[i];  
   
                 if ((ike->flags & INPUTKEY_KEYPAD) && (~s->mode & MODE_KKEYPAD))  
                         continue;  
                 if ((ike->flags & INPUTKEY_CURSOR) && (~s->mode & MODE_KCURSOR))  
                         continue;  
   
                 if ((key & KEYC_ESCAPE) && (ike->key | KEYC_ESCAPE) == key)  
                         break;  
                 if (ike->key == key)  
                         break;  
         }  
         if (i == nitems(input_keys)) {  
                 log_debug("key 0x%llx missing", key);                  log_debug("key 0x%llx missing", key);
                 return (-1);                  return (-1);
         }          }
         dlen = strlen(ike->data);          datalen = strlen(ike->data);
         log_debug("found key 0x%llx: \"%s\"", key, ike->data);          log_debug("found key 0x%llx: \"%s\"", key, ike->data);
   
         /* Prefix a \033 for escape. */          /* Prefix a \033 for escape. */
         if (key & KEYC_ESCAPE)          if (key & KEYC_ESCAPE)
                 bufferevent_write(bev, "\033", 1);                  bufferevent_write(bev, "\033", 1);
         bufferevent_write(bev, ike->data, dlen);          bufferevent_write(bev, ike->data, datalen);
         return (0);          return (0);
 }  }
   
Line 309 
Line 541 
                 if (m->b > 0x7ff - 32 || x > 0x7ff - 33 || y > 0x7ff - 33)                  if (m->b > 0x7ff - 32 || x > 0x7ff - 33 || y > 0x7ff - 33)
                         return (0);                          return (0);
                 len = xsnprintf(buf, sizeof buf, "\033[M");                  len = xsnprintf(buf, sizeof buf, "\033[M");
                 len += input_split2(m->b + 32, &buf[len]);                  len += input_key_split2(m->b + 32, &buf[len]);
                 len += input_split2(x + 33, &buf[len]);                  len += input_key_split2(x + 33, &buf[len]);
                 len += input_split2(y + 33, &buf[len]);                  len += input_key_split2(y + 33, &buf[len]);
         } else {          } else {
                 if (m->b > 223)                  if (m->b > 223)
                         return (0);                          return (0);

Legend:
Removed from v.1.71  
changed lines
  Added in v.1.72