From nobody Sun May 12 11:40:56 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@intel.com; 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=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1668736857; cv=none; d=zohomail.com; s=zohoarc; b=EFcO5m5EnhYvtpK7tffarDQSFkzWwtF3+UF+gDy6RF2ggsDsTOfbR8pibLx3TUWpa1ycpENb783SGRNNjG5Mu76rIVacIY/JNqaLNpQD7h8K71MqlSfmim8O1g0b6EpzoEmH7PyiXK83faqEvix9WYitTGB6njLlPhL5qIM8u1s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1668736857; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=1aQGt1ZmdmM4gvuCT+Z+7lyK3uLibBRVzt3v/1ERk6A=; b=ektKjWlxDApGCG6Ah/KihDHrjUBSB/3l5ulFV9nqlKhBUP3etZFkpYLC7ymfMBlQ3BSHet+QvkBxRCvVjyaVSzVP5vLzwXhvzneEhhvLYD4jc5lGq0+KuXW4TNsOqw5R2cowCCrtIWKfHw0LSW9P7v0aR+4q17VU/WRFJOGR98I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@intel.com; 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=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1668736857435862.8250714559415; Thu, 17 Nov 2022 18:00:57 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ovqgM-0006ve-HF; Thu, 17 Nov 2022 21:00:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ovqgA-0006qi-IA for qemu-devel@nongnu.org; Thu, 17 Nov 2022 21:00:35 -0500 Received: from mga01.intel.com ([192.55.52.88]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ovqg7-0007uB-Sx for qemu-devel@nongnu.org; Thu, 17 Nov 2022 21:00:29 -0500 Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Nov 2022 18:00:26 -0800 Received: from vkasired-desk2.fm.intel.com ([10.105.128.127]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Nov 2022 18:00:25 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1668736827; x=1700272827; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=LtssbtygmjzHpfF9OGz3VzYwF4F8brwNiH/OEBZLkFs=; b=jXiBVUoZhIqgnPlnb3SDeCskHF1CrNnq/8OJPTWyEbqpqZYWX29X9WUK CD/6Eu+2JJ1l9hVkfWDvT+0pFgzlZalMc9ojdCy4Arum3kLFvHK54+tlf 4pJR4+Se/P3FtLhUl2jMVvT3odqjk+hGE+8vRpp3Z2zPWPA9z3hEZgyAE 8UR72FqdUm0lMb1K+8xWoMMRjE/cae4QlKiEH20XIgWXRms38o1z62o9e CJOUps9RInvX9Hmd71aJwTae6Y3evA6py6l7Bht38Tr6seWyXV9alQhxt KqZK75X0RxbdKIhq6GfH+8Cl4goJQjowkGu1N8XxHzEa6yz9nw9iQ8/bQ g==; X-IronPort-AV: E=McAfee;i="6500,9779,10534"; a="339863637" X-IronPort-AV: E=Sophos;i="5.96,172,1665471600"; d="scan'208";a="339863637" X-IronPort-AV: E=McAfee;i="6500,9779,10534"; a="617844221" X-IronPort-AV: E=Sophos;i="5.96,172,1665471600"; d="scan'208";a="617844221" From: Vivek Kasireddy To: qemu-devel@nongnu.org Cc: Vivek Kasireddy , Gerd Hoffmann , Dongwon Kim Subject: [PATCH v1] ui/gtk: Add support for extended absolute mode for the pointer device Date: Thu, 17 Nov 2022 17:40:03 -0800 Message-Id: <20221118014003.182504-1-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.37.2 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists.gnu.org; Received-SPF: pass client-ip=192.55.52.88; envelope-from=vivek.kasireddy@intel.com; helo=mga01.intel.com X-Spam_score_int: -70 X-Spam_score: -7.1 X-Spam_bar: ------- X-Spam_report: (-7.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=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: 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 @intel.com) X-ZM-MESSAGEID: 1668736858999100001 Content-Type: text/plain; charset="utf-8" Currently, the range of the absolute pointer device (usb-tablet) is restricted to any one monitor. This presents a problem when there are multiple VCs (Guest GTK windows) located on different monitors. Therefore, it makes sense to extend the range of the absolute pointer device to span all monitors. This would work nicely as long as the monitors (aka outputs/connectors/displays) on the Host and Guest are in alignment with each other (i.e, if the Host has monitor 2, 3, 4 to the right of monitor 1, then Guest's need to be arranged accordingly). Relative mode could also be used in these situations but the user experience is not as seamless as the absolute mode. Cc: Gerd Hoffmann Cc: Dongwon Kim Signed-off-by: Vivek Kasireddy --- include/ui/gtk.h | 1 + qapi/ui.json | 6 ++++- qemu-options.hx | 5 +++- ui/gtk.c | 63 +++++++++++++++++++++++++++++++++++------------- 4 files changed, 56 insertions(+), 19 deletions(-) diff --git a/include/ui/gtk.h b/include/ui/gtk.h index ae0f53740d..01eb560b0b 100644 --- a/include/ui/gtk.h +++ b/include/ui/gtk.h @@ -136,6 +136,7 @@ struct GtkDisplayState { VirtualConsole *ptr_owner; =20 gboolean full_screen; + gboolean ext_abs_mode; =20 GdkCursor *null_cursor; Notifier mouse_mode_notifier; diff --git a/qapi/ui.json b/qapi/ui.json index 0abba3e930..1ce2945c84 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1201,6 +1201,9 @@ # Since 7.1 # @show-menubar: Display the main window menubar. Defaults to "on". # Since 8.0 +# @extend-abs-mode: Extend the absolute mode across all monitors or +# limit it to just one. Defaults to "off". +# Since 8.0 # # Since: 2.12 ## @@ -1208,7 +1211,8 @@ 'data' : { '*grab-on-hover' : 'bool', '*zoom-to-fit' : 'bool', '*show-tabs' : 'bool', - '*show-menubar' : 'bool' } } + '*show-menubar' : 'bool', + '*extend-abs-mode' : 'bool' } } =20 ## # @DisplayEGLHeadless: diff --git a/qemu-options.hx b/qemu-options.hx index eb38e5dc40..e6ef0634cd 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1980,7 +1980,7 @@ DEF("display", HAS_ARG, QEMU_OPTION_display, #if defined(CONFIG_GTK) "-display gtk[,full-screen=3Don|off][,gl=3Don|off][,grab-on-hover=3Don= |off]\n" " [,show-tabs=3Don|off][,show-cursor=3Don|off][,window-clos= e=3Don|off]\n" - " [,show-menubar=3Don|off]\n" + " [,show-menubar=3Don|off][,extend-abs-mode=3Don|off]\n" #endif #if defined(CONFIG_VNC) "-display vnc=3D[,]\n" @@ -2075,6 +2075,9 @@ SRST =20 ``show-menubar=3Don|off`` : Display the main window menubar, defau= lts to "on" =20 + ``extend-abs-mode=3Don|off`` : Extend the absolute mode across all + monitors or limit it to just one. + ``curses[,charset=3D]`` Display video output via curses. For graphics device models which support a text mode, QEMU can display this output using a diff --git a/ui/gtk.c b/ui/gtk.c index 2be9755b0a..a4644675b2 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -883,12 +883,42 @@ static gboolean gd_draw_event(GtkWidget *widget, cair= o_t *cr, void *opaque) return TRUE; } =20 +static void gd_calc_width_height(VirtualConsole *vc, + uint32_t *max_w, uint32_t *max_h) +{ + GtkDisplayState *s =3D vc->s; + GdkDisplay *dpy =3D gtk_widget_get_display(vc->gfx.drawing_area); + GdkRectangle geometry; + int i; + + if (s->ext_abs_mode) { + for (i =3D 0; i < gdk_display_get_n_monitors(dpy); i++) { + gdk_monitor_get_geometry(gdk_display_get_monitor(dpy, i), + &geometry); + if (geometry.x + geometry.width > *max_w) { + *max_w =3D geometry.x + geometry.width; + } + if (geometry.y + geometry.height > *max_h) { + *max_h =3D geometry.y + geometry.height; + } + } + } else { + *max_w =3D surface_width(vc->gfx.ds); + *max_h =3D surface_height(vc->gfx.ds); + } +} + static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, void *opaque) { VirtualConsole *vc =3D opaque; GtkDisplayState *s =3D vc->s; - GdkWindow *window; + GdkScreen *screen =3D gtk_widget_get_screen(vc->gfx.drawing_area); + GdkDisplay *dpy =3D gtk_widget_get_display(widget); + GdkWindow *window =3D gtk_widget_get_window(widget); + GdkMonitor *monitor =3D gdk_display_get_monitor_at_window(dpy, window); + GdkRectangle geometry; + uint32_t max_w =3D 0, max_h =3D 0; int x, y; int mx, my; int fbh, fbw; @@ -901,7 +931,6 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkE= ventMotion *motion, fbw =3D surface_width(vc->gfx.ds) * vc->gfx.scale_x; fbh =3D surface_height(vc->gfx.ds) * vc->gfx.scale_y; =20 - window =3D gtk_widget_get_window(vc->gfx.drawing_area); ww =3D gdk_window_get_width(window); wh =3D gdk_window_get_height(window); ws =3D gdk_window_get_scale_factor(window); @@ -916,17 +945,20 @@ static gboolean gd_motion_event(GtkWidget *widget, Gd= kEventMotion *motion, =20 x =3D (motion->x - mx) / vc->gfx.scale_x * ws; y =3D (motion->y - my) / vc->gfx.scale_y * ws; + gdk_monitor_get_geometry(monitor, &geometry); =20 if (qemu_input_is_absolute()) { - if (x < 0 || y < 0 || - x >=3D surface_width(vc->gfx.ds) || - y >=3D surface_height(vc->gfx.ds)) { + if (s->ext_abs_mode) { + x =3D x + geometry.x; + y =3D y + geometry.y; + } + + gd_calc_width_height(vc, &max_w, &max_h); + if (x < 0 || y < 0 || x >=3D max_w || y >=3D max_h) { return TRUE; } - qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_X, x, - 0, surface_width(vc->gfx.ds)); - qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y, - 0, surface_height(vc->gfx.ds)); + qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_X, x, 0, max_w); + qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y, 0, max_h); qemu_input_event_sync(); } else if (s->last_set && s->ptr_owner =3D=3D vc) { qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, x - s->last_x); @@ -938,17 +970,9 @@ static gboolean gd_motion_event(GtkWidget *widget, Gdk= EventMotion *motion, s->last_set =3D TRUE; =20 if (!qemu_input_is_absolute() && s->ptr_owner =3D=3D vc) { - GdkScreen *screen =3D gtk_widget_get_screen(vc->gfx.drawing_area); - GdkDisplay *dpy =3D gtk_widget_get_display(widget); - GdkWindow *win =3D gtk_widget_get_window(widget); - GdkMonitor *monitor =3D gdk_display_get_monitor_at_window(dpy, win= ); - GdkRectangle geometry; - int x =3D (int)motion->x_root; int y =3D (int)motion->y_root; =20 - gdk_monitor_get_geometry(monitor, &geometry); - /* In relative mode check to see if client pointer hit * one of the monitor edges, and if so move it back to the * center of the monitor. This is important because the pointer @@ -2423,6 +2447,11 @@ static void gtk_display_init(DisplayState *ds, Displ= ayOptions *opts) opts->u.gtk.show_tabs) { gtk_menu_item_activate(GTK_MENU_ITEM(s->show_tabs_item)); } + if (opts->u.gtk.has_extend_abs_mode && + opts->u.gtk.extend_abs_mode && + qemu_input_is_absolute()) { + s->ext_abs_mode =3D TRUE; + } gd_clipboard_init(s); } =20 --=20 2.37.2