qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] gtk: Fix mouse offset in scaled gtk-gl display for


From: Chen Zhang
Subject: [Qemu-devel] [PATCH] gtk: Fix mouse offset in scaled gtk-gl display for VFIO/iGVT-g DMA Buf mode
Date: Wed, 31 Oct 2018 06:24:56 +0000 (GMT)

The issue was reported as in https://bugs.launchpad.net/qemu/+bug/1793859

When an OpenGL accelerated GTK window is used for iGVT-g DMA Buf device,
window scaling would cause guest cursor to move in undesirable velocity.

To fix this usability issue, the gtk mouse motion events was modified to
scale the position of event to match the coordinates of the scaled GL
surface.

Signed-off-by: Chen Zhang <address@hidden>
---
 ui/gtk-egl.c | 10 +++++++---
 ui/gtk.c     | 19 +++++++++++++------
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index a77c25b..824beed 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -231,9 +231,13 @@ void gd_egl_cursor_position(DisplayChangeListener *dcl,
                             uint32_t pos_x, uint32_t pos_y)
 {
     VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
-    vc->gfx.cursor_x = pos_x;
-    vc->gfx.cursor_y = pos_y;
+    uint32_t sw = surface_width(vc->gfx.ds);
+    uint32_t sh = surface_height(vc->gfx.ds);
+    GdkWindow *window = gtk_widget_get_window(vc->gfx.drawing_area);
+    uint32_t ww = gdk_window_get_width(window);
+    uint32_t wh = gdk_window_get_height(window);
+    vc->gfx.cursor_x = pos_x * ww / sw;
+    vc->gfx.cursor_y = pos_y * wh / sh;
 }
 
 void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
diff --git a/ui/gtk.c b/ui/gtk.c
index 579990b..41c82e5 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -875,20 +875,27 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
     x = (motion->x - mx) / vc->gfx.scale_x;
     y = (motion->y - my) / vc->gfx.scale_y;
 
+    bool scaled = display_opengl && !gtk_use_gl_area && s->free_scale;
     if (qemu_input_is_absolute()) {
+        int max_w = scaled ? ww : surface_width(vc->gfx.ds);
+        int max_h = scaled ? wh : surface_height(vc->gfx.ds);
         if (x < 0 || y < 0 ||
-            x >= surface_width(vc->gfx.ds) ||
-            y >= surface_height(vc->gfx.ds)) {
+            x >= max_w ||
+            y >= max_h) {
             return TRUE;
         }
         qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_X, x,
-                             0, surface_width(vc->gfx.ds));
+                             0, max_w);
         qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y,
-                             0, surface_height(vc->gfx.ds));
+                             0, max_h);
         qemu_input_event_sync();
     } else if (s->last_set && s->ptr_owner == vc) {
-        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, x - s->last_x);
-        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_Y, y - s->last_y);
+        int diff_x = scaled
+            ? (x - s->last_x) * surface_width(vc->gfx.ds) / ww : (x - 
s->last_x);
+        int diff_y = scaled
+            ? (y - s->last_y) * surface_height(vc->gfx.ds) / wh : (y - 
s->last_y);
+        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, diff_x);
+        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_Y, diff_y);
         qemu_input_event_sync();
     }
     s->last_x = x;
-- 
2.7.4


reply via email to

[Prev in Thread] Current Thread [Next in Thread]