手機 - Unihertz Titan 2 (None-EEA) - Debian - QEMU按鍵修改



ui/gtk.c

--- b/gtk.c	2025-12-08 21:46:00.849740777 +0800
+++ a/gtk.c	2025-12-09 07:21:14.029533173 +0800
@@ -114,7 +114,7 @@
 # define VTE_CHECK_VERSION(a, b, c) 0
 #endif
 
-#define HOTKEY_MODIFIERS        (GDK_CONTROL_MASK | GDK_MOD1_MASK)
+#define HOTKEY_MODIFIERS        (GDK_CONTROL_MASK) // | GDK_MOD1_MASK)
 
 static const guint16 *keycode_map;
 static size_t keycode_maplen;
@@ -226,7 +226,7 @@
 
     if (s->ptr_owner != NULL &&
         s->ptr_owner->window == NULL) {
-        grab = _(" - Press Ctrl+Alt+G to release grab");
+        grab = _(" - Press Ctrl+G to release grab");
     }
 
     if (is_paused) {
@@ -1169,6 +1169,11 @@
     VirtualConsole *vc = opaque;
     int keycode, qcode;
 
+    int handled = 0;
+    int keydown = 0;
+    static int ralt_down = 0;
+    static int lalt_down = 0;
+
 #ifdef G_OS_WIN32
     /* on windows, we ought to ignore the reserved key event? */
     if (key->hardware_keycode == 0xff)
@@ -1198,6 +1203,609 @@
     keycode = gd_get_keycode(key);
     qcode = gd_map_keycode(keycode);
 
+    handled = 0;
+    keydown = (key->type == GDK_KEY_PRESS);
+    //printf("%d, %d\n", qcode, keydown);
+    switch (qcode) {
+    case 3: // LALT
+        lalt_down = keydown;
+        return FALSE;
+    case 22: // RALT
+        ralt_down = keydown;
+        return FALSE;
+    case 5: // LCTRL
+        // Escape
+        //qkbd_state_key_event(vc->gfx.kbd, 8, keydown);
+
+        // LATL
+        qkbd_state_key_event(vc->gfx.kbd, 3, keydown);
+        return TRUE;
+    case 23: // 'q'
+        if (lalt_down) {
+            // '0'
+            qkbd_state_key_event(vc->gfx.kbd, 18, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '^'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 14, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 14, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 24: // 'w'
+        if (lalt_down) {
+            // '1'
+            qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '|'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 48, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 48, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 25: // 'e'
+        if (lalt_down) {
+            // '2'
+            qkbd_state_key_event(vc->gfx.kbd, 10, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '&'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 15, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 15, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 26: // 'r'
+        if (lalt_down) {
+            // '3'
+            qkbd_state_key_event(vc->gfx.kbd, 11, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '$'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 12, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 12, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 27: // 't'
+        if (lalt_down) {
+            // '('
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 17, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 17, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '{'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 33, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 33, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 28: // 'y'
+        if (lalt_down) {
+            // ')'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 18, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 18, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '}'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 34, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 34, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 29: // 'u'
+        if (lalt_down) {
+            // '-'
+            qkbd_state_key_event(vc->gfx.kbd, 19, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '='
+            qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+            handled = 1;
+        }
+        break;
+    case 30: // 'i'
+        if (lalt_down) {
+            // '_'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 19, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 19, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '~'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 47, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 47, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 31: // 'o'
+        if (lalt_down) {
+            // '\''
+            qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '\\'
+            qkbd_state_key_event(vc->gfx.kbd, 48, keydown);
+            handled = 1;
+        }
+        break;
+    case 32: // 'p'
+        if (lalt_down) {
+            // ':'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 45, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 45, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // ';'
+            qkbd_state_key_event(vc->gfx.kbd, 45, keydown);
+            handled = 1;
+        }
+        break;
+    case 36: // 'a'
+        if (lalt_down) {
+            // '@'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 10, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 10, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '%'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 13, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 13, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 37: // 's'
+        if (lalt_down) {
+            // '4'
+            qkbd_state_key_event(vc->gfx.kbd, 12, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '4'
+            qkbd_state_key_event(vc->gfx.kbd, 12, keydown);
+            handled = 1;
+        }
+        break;
+    case 38: // 'd'
+        if (lalt_down) {
+            // '5'
+            qkbd_state_key_event(vc->gfx.kbd, 13, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '5'
+            qkbd_state_key_event(vc->gfx.kbd, 13, keydown);
+            handled = 1;
+        }
+        break;
+    case 39: // 'f'
+        if (lalt_down) {
+            // '6'
+            qkbd_state_key_event(vc->gfx.kbd, 14, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '6'
+            qkbd_state_key_event(vc->gfx.kbd, 14, keydown);
+            handled = 1;
+        }
+        break;
+    case 40: // 'g'
+        if (lalt_down) {
+            // '*'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 16, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 16, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '['
+            qkbd_state_key_event(vc->gfx.kbd, 33, keydown);
+            handled = 1;
+        }
+        break;
+    case 41: // 'h'
+        if (lalt_down) {
+            // '#'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 11, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 11, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // ']'
+            qkbd_state_key_event(vc->gfx.kbd, 34, keydown);
+            handled = 1;
+        }
+        break;
+    case 42: // 'j'
+        if (lalt_down) {
+            // '+'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '+'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 20, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 43: // 'k'
+        if (lalt_down) {
+            // '"'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '"'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 44: // 'l'
+        if (lalt_down) {
+            // '\''
+            qkbd_state_key_event(vc->gfx.kbd, 46, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '`'
+            qkbd_state_key_event(vc->gfx.kbd, 47, keydown);
+            handled = 1;
+        }
+        break;
+    case 49: // 'z'
+        if (lalt_down) {
+            // '!'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '!'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 9, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 50: // 'x'
+        if (lalt_down) {
+            // '7'
+            qkbd_state_key_event(vc->gfx.kbd, 15, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '7'
+            qkbd_state_key_event(vc->gfx.kbd, 15, keydown);
+            handled = 1;
+        }
+        break;
+    case 51: // 'c'
+        if (lalt_down) {
+            // '8'
+            qkbd_state_key_event(vc->gfx.kbd, 16, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '8'
+            qkbd_state_key_event(vc->gfx.kbd, 16, keydown);
+            handled = 1;
+        }
+        break;
+    case 52: // 'v'
+        if (lalt_down) {
+            // '9'
+            qkbd_state_key_event(vc->gfx.kbd, 17, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '<'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 56, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 56, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 53: // 'b'
+        if (lalt_down) {
+            // '.'
+            qkbd_state_key_event(vc->gfx.kbd, 57, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '>'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 57, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 57, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 54: // 'n'
+        if (lalt_down) {
+            // ','
+            qkbd_state_key_event(vc->gfx.kbd, 56, keydown);
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // ','
+            qkbd_state_key_event(vc->gfx.kbd, 56, keydown);
+            handled = 1;
+        }
+        break;
+    case 55: // 'm'
+        if (lalt_down) {
+            // '?'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 58, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 58, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+
+        if (ralt_down) {
+            // '?'
+            if (keydown) {
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 58, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 58, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 2, keydown);
+            }
+            handled = 1;
+        }
+        break;
+    case 21: // BACKSPACE
+        if (lalt_down) {
+            // TAB
+            qkbd_state_key_event(vc->gfx.kbd, 22, keydown);
+            handled = 1;
+        }
+        break;
+    case 35: // ENTER
+        if (lalt_down) {
+            // Escape
+            qkbd_state_key_event(vc->gfx.kbd, 8, keydown);
+            handled = 1;
+        }
+        break;
+    case 60: // SPACE
+        if (lalt_down) {
+            // Escape
+            //qkbd_state_key_event(vc->gfx.kbd, 8, keydown);
+
+            if (keydown) {
+                // ALT
+                qkbd_state_key_event(vc->gfx.kbd, 3, keydown);
+                // PrintScr
+                qkbd_state_key_event(vc->gfx.kbd, 80, keydown);
+            }
+            else {
+                qkbd_state_key_event(vc->gfx.kbd, 80, keydown);
+                qkbd_state_key_event(vc->gfx.kbd, 3, keydown);
+            }
+
+            // F1
+            //qkbd_state_key_event(vc->gfx.kbd, 62, keydown);
+
+            // WIN
+            //qkbd_state_key_event(vc->gfx.kbd, 117, keydown);
+
+            handled = 1;
+        }
+        break;
+    case 100: // UP
+        if (lalt_down) {
+            // PageUp
+            qkbd_state_key_event(vc->gfx.kbd, 96, keydown);
+            handled = 1;
+        }
+        break;
+    case 101: // DOWN
+        if (lalt_down) {
+            // PageDown
+            qkbd_state_key_event(vc->gfx.kbd, 97, keydown);
+            handled = 1;
+        }
+        break;
+    case 99: // LEFT
+        if (lalt_down) {
+            // HOME
+            qkbd_state_key_event(vc->gfx.kbd, 95, keydown);
+            handled = 1;
+        }
+        break;
+    case 102: // RIGHT
+        if (lalt_down) {
+            // End
+            qkbd_state_key_event(vc->gfx.kbd, 98, keydown);
+            handled = 1;
+        }
+        break;
+    }
+
+    if (handled) {
+        return TRUE;
+    }
+
     trace_gd_key_event(vc->label, keycode, qcode,
                        (key->type == GDK_KEY_PRESS) ? "down" : "up");