This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository terminology.

View the commit online.

commit 9084ef0da2dea525e395dc3c70c1d914e27faa9f
Author: Boris Faure <[email protected]>
AuthorDate: Sat Sep 12 16:06:51 2026 +0200

    keyin: implement modifyOtherKeys
    
    xmod[] was write-only, so a client asking for level 2 still got the
    legacy encoding. Emit CSI 27 ; Pm ; Pc ~ for the keys that qualify.
---
 src/bin/keyin.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 106 insertions(+), 17 deletions(-)

diff --git a/src/bin/keyin.c b/src/bin/keyin.c
index 9236bc61..fc065d0a 100644
--- a/src/bin/keyin.c
+++ b/src/bin/keyin.c
@@ -57,6 +57,69 @@ static Eina_Hash *_key_bindings = NULL;
 
 /* {{{ Keys to TTY */
 
+/* {{{ modifyOtherKeys */
+
+static Eina_Bool
+_xmod_other_keys(const Termpty *ty)
+{
+   return ty->termstate.xmod[XMOD_OTHER] == 2;
+}
+
+static void
+_xmod_write(Termpty *ty, int code, int alt, int shift, int ctrl)
+{
+   char buf[32];
+   int param = 1 + (shift ? 1 : 0) + (alt ? 2 : 0) + (ctrl ? 4 : 0);
+   int len = snprintf(buf, sizeof(buf), "\033[27;%d;%d~", param, code);
+
+   termpty_write(ty, buf, len);
+}
+
+/* xterm's ModifyOtherKeys(), modifyOtherKeys=2, for an ordinary key */
+static Eina_Bool
+_xmod_wants_other(int code, int alt, int shift, int ctrl)
+{
+   if (!alt && !shift && !ctrl)
+     return EINA_FALSE;
+   if ((code >= 0x40) && (code <= 0x7f))
+     return EINA_TRUE;
+   if (alt || ctrl)
+     return EINA_TRUE;
+   return (code == ' ');
+}
+
+/* Keysym name -> the character xterm would report for it, or -1 */
+static int
+_xmod_key_code(const char *key)
+{
+   static const struct {
+      const char *name;
+      char code;
+   } named[] = {
+      { "space", ' ' },        { "exclam", '!' },       { "quotedbl", '"' },
+      { "numbersign", '#' },   { "dollar", '$' },       { "percent", '%' },
+      { "ampersand", '&' },    { "apostrophe", '\'' },  { "parenleft", '(' },
+      { "parenright", ')' },   { "asterisk", '*' },     { "plus", '+' },
+      { "comma", ',' },        { "minus", '-' },        { "period", '.' },
+      { "slash", '/' },        { "colon", ':' },        { "semicolon", ';' },
+      { "less", '<' },         { "equal", '=' },        { "greater", '>' },
+      { "question", '?' },     { "at", '@' },           { "bracketleft", '[' },
+      { "backslash", '\\' },   { "bracketright", ']' }, { "asciicircum", '^' },
+      { "underscore", '_' },   { "grave", '`' },        { "braceleft", '{' },
+      { "bar", '|' },          { "braceright", '}' },   { "asciitilde", '~' },
+   };
+   unsigned int i;
+
+   if (key[0] && !key[1] && (key[0] >= 0x20) && (key[0] < 0x7f))
+     return key[0];
+   for (i = 0; i < sizeof(named)/sizeof(named[0]); i++)
+     if (!strcmp(key, named[i].name))
+       return named[i].code;
+   return -1;
+}
+
+/* }}} */
+
 static Eina_Bool
 _key_try(Termpty *ty, const Tty_Key *map, int len, const Evas_Event_Key_Down *ev,
          int alt, int shift, int ctrl)
@@ -112,25 +175,21 @@ keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
 
    if (!strcmp(ev->key, "BackSpace"))
      {
+        const Config *cfg = ty->config;
+        char code = '\b';
+
+        if (!ty->termstate.send_bs && cfg->erase_is_del && !ctrl)
+          code = '\177';
+
+        /* xterm strips Control here, as per IsBackarrowToggle() */
+        if (_xmod_other_keys(ty) && (alt || shift))
+          {
+             _xmod_write(ty, code, alt, shift, ctrl);
+             return;
+          }
         if (alt)
           termpty_write(ty, "\033", 1);
-        if (ty->termstate.send_bs)
-          {
-             termpty_write(ty, "\b", 1);
-          }
-        else
-          {
-             const Config *cfg = ty->config;
-
-             if (cfg->erase_is_del && !ctrl)
-               {
-                  termpty_write(ty, "\177", sizeof("\177") - 1);
-               }
-             else
-               {
-                  termpty_write(ty, "\b", sizeof("\b") - 1);
-               }
-          }
+        termpty_write(ty, &code, 1);
         return;
      }
    if (!strcmp(ev->key, "Escape"))
@@ -143,6 +202,10 @@ keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
           {
              TERMPTY_WRITE_STR("\034");
           }
+        else if (_xmod_other_keys(ty) && (alt || shift || ctrl))
+          {
+             _xmod_write(ty, '\033', alt, shift, ctrl);
+          }
         else
           {
              if (alt)
@@ -158,6 +221,11 @@ keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
      }
    if (!strcmp(ev->key, "Return"))
      {
+        if (_xmod_other_keys(ty) && (alt || shift || ctrl))
+          {
+             _xmod_write(ty, '\r', alt, shift, ctrl);
+             return;
+          }
         if (alt)
           termpty_write(ty, "\033", 1);
         if (ty->termstate.crlf)
@@ -171,6 +239,27 @@ keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
              return;
           }
      }
+   if (_xmod_other_keys(ty))
+     {
+        if (!strcmp(ev->key, "Tab") || !strcmp(ev->key, "ISO_Left_Tab"))
+          {
+             if (alt || shift || ctrl)
+               {
+                  _xmod_write(ty, '\t', alt, shift, ctrl);
+                  return;
+               }
+          }
+        else
+          {
+             int code = _xmod_key_code(ev->key);
+
+             if ((code >= 0) && _xmod_wants_other(code, alt, shift, ctrl))
+               {
+                  _xmod_write(ty, code, alt, shift, ctrl);
+                  return;
+               }
+          }
+     }
    if (ev->key[0] == 'K' && (ev->key[1] == 'k' || ev->key[1] == 'P'))
      {
         if (!evas_key_lock_is_set(ev->locks, "Num_Lock"))

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to