From nobody Tue Aug 25 03:44:53 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1779365103; cv=none; d=zohomail.com; s=zohoarc; b=EOlLkCp7BbFQOCGSZMmkDOeu3PS7Zauh7QBZBwLkX/LWS4j6P8l5mqOHv/XrUvFTagzEZ4oxWxNKoGcrGlQNjzOEDB1PeIgoE0jOS5qIVGmOsIK88v1CEZBQhvAvRKyzUEqTV0mFdaJIKiBCVZD4fHkZDVQXWa/Miui4NCfMcFE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1779365103; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=X1k9ze6YWErIgmVSMwxO43L2UxMS0Nawp0xFT0NHEbY=; b=eyVVtP+QYQyJ05kq7atIymWmcjt44Wt36C3uoxOPZJUB/X2JzEclZ5eLigSLSJPi1v9/zHaZ0HB/0YLALUz+UmojwpcbsmK7jZB9Cj6XTzwU9N5DVuh1z7TjQzAiu5UpsMHLF8ls3NnoutEyLLuBDp71q3EI+lgewQeR/Z7vstQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1779365103653866.9628162382659; Thu, 21 May 2026 05:05:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wQ25Q-0001rN-Pu; Thu, 21 May 2026 08:01:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wQ24Q-0000IE-91 for qemu-devel@nongnu.org; Thu, 21 May 2026 08:00:13 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wQ24N-0005En-UN for qemu-devel@nongnu.org; Thu, 21 May 2026 08:00:09 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-524-1zfzQo-jOQiPC3Sb4j4V_g-1; Thu, 21 May 2026 08:00:02 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B151018005B4; Thu, 21 May 2026 12:00:01 +0000 (UTC) Received: from localhost (unknown [10.44.24.26]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9AF8C300019F; Thu, 21 May 2026 12:00:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1779364807; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=X1k9ze6YWErIgmVSMwxO43L2UxMS0Nawp0xFT0NHEbY=; b=JbKmQdjn4IKnCQgbDXTnZeDPJQEGvPdLlcLs/0oN3hvOye/IXrsFOyzNzGp9pS9Wua4hEs ccPsTC9egGA68Q5rhpcQmmtH8kS7XqHOcUmhyPFEs7/hW2j8YB3E6cS/bhd1gUtvs0HKqk Up11KyyfNf2k5zc69355Qd29dVk4J1M= X-MC-Unique: 1zfzQo-jOQiPC3Sb4j4V_g-1 X-Mimecast-MFC-AGG-ID: 1zfzQo-jOQiPC3Sb4j4V_g_1779364801 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Cc: stefanha@gmail.com, Akihiko Odaki , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Subject: [PULL 27/38] ui/gtk: Use Linux key codes Date: Thu, 21 May 2026 15:57:04 +0400 Message-ID: <20260521115717.1701482-28-marcandre.lureau@redhat.com> In-Reply-To: <20260521115717.1701482-1-marcandre.lureau@redhat.com> References: <20260521115717.1701482-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1779365106656158500 From: Akihiko Odaki QemuInputEvent now stores Linux key codes for key events. Use those codes directly instead of translating between internal key code representations. Signed-off-by: Akihiko Odaki Reviewed-by: Marc-Andr=C3=A9 Lureau Message-ID: <20260520-input-v3-19-7c9e4c7abe34@rsg.ci.i.u-tokyo.ac.jp> --- ui/x_keymap.h | 3 ++- ui/gtk.c | 51 ++++++++++++++++++++++++++++--------------------- ui/x_keymap.c | 24 ++++++++++++----------- ui/trace-events | 2 +- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/ui/x_keymap.h b/ui/x_keymap.h index 0395e335fff..0d58459dd21 100644 --- a/ui/x_keymap.h +++ b/ui/x_keymap.h @@ -27,6 +27,7 @@ =20 #include =20 -const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen); +const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen, + bool *evdev); =20 #endif diff --git a/ui/gtk.c b/ui/gtk.c index 757ee80fa6a..9f9b2416c8a 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -55,6 +55,7 @@ #include =20 #include "trace.h" +#include "standard-headers/linux/input-event-codes.h" #include "ui/input.h" #include "system/runstate.h" #include "system/system.h" @@ -120,6 +121,7 @@ =20 static const guint16 *keycode_map; static size_t keycode_maplen; +static bool keycode_xorgevdev; =20 struct VCChardev { Chardev parent; @@ -1211,39 +1213,42 @@ static gboolean gd_touch_event(GtkWidget *widget, G= dkEventTouch *touch, return TRUE; } =20 -static const guint16 *gd_get_keymap(size_t *maplen) +static const guint16 *gd_get_keymap(size_t *maplen, bool *xorgevdev) { GdkDisplay *dpy =3D gdk_display_get_default(); =20 + *maplen =3D 0; + *xorgevdev =3D false; + #ifdef GDK_WINDOWING_X11 if (GDK_IS_X11_DISPLAY(dpy)) { trace_gd_keymap_windowing("x11"); return qemu_xkeymap_mapping_table( - gdk_x11_display_get_xdisplay(dpy), maplen); + gdk_x11_display_get_xdisplay(dpy), maplen, xorgevdev); } #endif =20 #ifdef GDK_WINDOWING_WAYLAND if (GDK_IS_WAYLAND_DISPLAY(dpy)) { trace_gd_keymap_windowing("wayland"); - *maplen =3D qemu_input_map_xorgevdev_to_qcode_len; - return qemu_input_map_xorgevdev_to_qcode; + *xorgevdev =3D true; + return NULL; } #endif =20 #ifdef GDK_WINDOWING_WIN32 if (GDK_IS_WIN32_DISPLAY(dpy)) { trace_gd_keymap_windowing("win32"); - *maplen =3D qemu_input_map_atset1_to_qcode_len; - return qemu_input_map_atset1_to_qcode; + *maplen =3D qemu_input_map_atset1_to_linux_len; + return qemu_input_map_atset1_to_linux; } #endif =20 #ifdef GDK_WINDOWING_QUARTZ if (GDK_IS_QUARTZ_DISPLAY(dpy)) { trace_gd_keymap_windowing("quartz"); - *maplen =3D qemu_input_map_osx_to_qcode_len; - return qemu_input_map_osx_to_qcode; + *maplen =3D qemu_input_map_osx_to_linux_len; + return qemu_input_map_osx_to_linux; } #endif =20 @@ -1253,8 +1258,8 @@ static const guint16 *gd_get_keymap(size_t *maplen) g_warning("experimental: using broadway, x11 virtual keysym\n" "mapping - with very limited support. See also\n" "https://bugzilla.gnome.org/show_bug.cgi?id=3D700105"); - *maplen =3D qemu_input_map_x11_to_qcode_len; - return qemu_input_map_x11_to_qcode; + *maplen =3D qemu_input_map_x11_to_linux_len; + return qemu_input_map_x11_to_linux; } #endif =20 @@ -1269,8 +1274,11 @@ static const guint16 *gd_get_keymap(size_t *maplen) } =20 =20 -static int gd_map_keycode(int scancode) +static unsigned int gd_map_keycode(int scancode) { + if (keycode_xorgevdev) { + return scancode < 8 ? KEY_RESERVED : scancode - 8; + } if (!keycode_map) { return 0; } @@ -1307,12 +1315,12 @@ static gboolean gd_text_key_down(GtkWidget *widget, QemuTextConsole *con =3D QEMU_TEXT_CONSOLE(vc->gfx.dcl.con); =20 if (key->keyval =3D=3D GDK_KEY_Delete) { - qemu_text_console_put_qcode(con, Q_KEY_CODE_DELETE, false); + qemu_text_console_put_linux(con, KEY_DELETE, false); } else if (key->length) { qemu_text_console_put_string(con, key->string, key->length); } else { - int qcode =3D gd_map_keycode(gd_get_keycode(key)); - qemu_text_console_put_qcode(con, qcode, false); + unsigned int lnx =3D gd_map_keycode(gd_get_keycode(key)); + qemu_text_console_put_linux(con, lnx, false); } return TRUE; } @@ -1320,7 +1328,8 @@ static gboolean gd_text_key_down(GtkWidget *widget, static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *op= aque) { VirtualConsole *vc =3D opaque; - int keycode, qcode; + int keycode; + unsigned int lnx; =20 #ifdef G_OS_WIN32 /* on windows, we ought to ignore the reserved key event? */ @@ -1343,20 +1352,18 @@ static gboolean gd_key_event(GtkWidget *widget, Gdk= EventKey *key, void *opaque) || key->hardware_keycode =3D=3D VK_PAUSE #endif ) { - qkbd_state_key_event(vc->gfx.kbd, - qemu_input_map_qcode_to_linux[Q_KEY_CODE_PAUS= E], + qkbd_state_key_event(vc->gfx.kbd, KEY_PAUSE, key->type =3D=3D GDK_KEY_PRESS); return TRUE; } =20 keycode =3D gd_get_keycode(key); - qcode =3D gd_map_keycode(keycode); + lnx =3D gd_map_keycode(keycode); =20 - trace_gd_key_event(vc->label, keycode, qemu_input_map_qcode_to_linux[q= code], + trace_gd_key_event(vc->label, keycode, lnx, (key->type =3D=3D GDK_KEY_PRESS) ? "down" : "up"); =20 - qkbd_state_key_event(vc->gfx.kbd, qemu_input_map_qcode_to_linux[qcode], - key->type =3D=3D GDK_KEY_PRESS); + qkbd_state_key_event(vc->gfx.kbd, lnx, key->type =3D=3D GDK_KEY_PRESS); =20 return TRUE; } @@ -2660,7 +2667,7 @@ static void early_gtk_display_init(DisplayOptions *op= ts) #endif } =20 - keycode_map =3D gd_get_keymap(&keycode_maplen); + keycode_map =3D gd_get_keymap(&keycode_maplen, &keycode_xorgevdev); =20 #if defined(CONFIG_VTE) type_register_static(&char_gd_vc_type_info); diff --git a/ui/x_keymap.c b/ui/x_keymap.c index 2ce7b899615..f7dc2edb91d 100644 --- a/ui/x_keymap.c +++ b/ui/x_keymap.c @@ -52,11 +52,12 @@ static gboolean check_for_xquartz(Display *dpy) return match; } =20 -const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen) +const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen, + bool *evdev) { XkbDescPtr desc; const gchar *keycodes =3D NULL; - const guint16 *map; + const guint16 *map =3D NULL; =20 /* There is no easy way to determine what X11 server * and platform & keyboard driver is in use. Thus we @@ -81,24 +82,26 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy,= size_t *maplen) XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True); } =20 + *maplen =3D 0; + *evdev =3D false; + if (check_for_xwin(dpy)) { trace_xkeymap_keymap("xwin"); - *maplen =3D qemu_input_map_xorgxwin_to_qcode_len; - map =3D qemu_input_map_xorgxwin_to_qcode; + *maplen =3D qemu_input_map_xorgxwin_to_linux_len; + map =3D qemu_input_map_xorgxwin_to_linux; } else if (check_for_xquartz(dpy)) { trace_xkeymap_keymap("xquartz"); - *maplen =3D qemu_input_map_xorgxquartz_to_qcode_len; - map =3D qemu_input_map_xorgxquartz_to_qcode; + *maplen =3D qemu_input_map_xorgxquartz_to_linux_len; + map =3D qemu_input_map_xorgxquartz_to_linux; } else if ((keycodes && g_str_has_prefix(keycodes, "evdev")) || (XKeysymToKeycode(dpy, XK_Page_Up) =3D=3D 0x70)) { trace_xkeymap_keymap("evdev"); - *maplen =3D qemu_input_map_xorgevdev_to_qcode_len; - map =3D qemu_input_map_xorgevdev_to_qcode; + *evdev =3D true; } else if ((keycodes && g_str_has_prefix(keycodes, "xfree86")) || (XKeysymToKeycode(dpy, XK_Page_Up) =3D=3D 0x63)) { trace_xkeymap_keymap("kbd"); - *maplen =3D qemu_input_map_xorgkbd_to_qcode_len; - map =3D qemu_input_map_xorgkbd_to_qcode; + *maplen =3D qemu_input_map_xorgkbd_to_linux_len; + map =3D qemu_input_map_xorgkbd_to_linux; } else { trace_xkeymap_keymap("NULL"); g_warning("Unknown X11 keycode mapping '%s'.\n" @@ -110,7 +113,6 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy,= size_t *maplen) " - xprop -root\n" " - xdpyinfo\n", keycodes ? keycodes : ""); - map =3D NULL; } if (keycodes) { XFree((void *)keycodes); diff --git a/ui/trace-events b/ui/trace-events index 1c0d96a92c3..237f5a65af2 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -22,7 +22,7 @@ ppm_save(int fd, void *image) "fd=3D%d image=3D%p" # gtk.c gd_switch(const char *tab, int width, int height) "tab=3D%s, width=3D%d, h= eight=3D%d" gd_update(const char *tab, int x, int y, int w, int h) "tab=3D%s, x=3D%d, = y=3D%d, w=3D%d, h=3D%d" -gd_key_event(const char *tab, int gdk_keycode, int qkeycode, const char *a= ction) "tab=3D%s, translated GDK keycode %d to QKeyCode %d (%s)" +gd_key_event(const char *tab, int gdk_keycode, unsigned int lnx, const cha= r *action) "tab=3D%s, translated GDK keycode %d to Linux %u (%s)" gd_grab(const char *tab, const char *device, const char *reason) "tab=3D%s= , dev=3D%s, reason=3D%s" gd_ungrab(const char *tab, const char *device) "tab=3D%s, dev=3D%s" gd_keymap_windowing(const char *name) "backend=3D%s" --=20 2.54.0