gtk: Fix mouse offset in scaled gtk-gl display for VFIO/iGVT-g DMA Buf mode
PATCH 1/1 gtk: Fix mouse offset in scaled gtk-gl display for VFIO/iGVT-g DMA Buf mode
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.
---
ui/gtk-egl.c | 10 +++++++---
ui/gtk.c | 19 +++++++++++++------
2 files changed, 20 insertions(+), 9 deletions(-)
ui/gtk-egl.c +0 -0
@@ -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,
ui/gtk.c +0 -0
@@ -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
Quoted 8 lines · Chen Zhang
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.
Hmm, we already have logic in place to deal with that. I suspect the root cause is simply that the scale_{x,y} variables are not set properly in egl mode. Can you try the patch below?
thanks,
Gerd
========================== [ cut here ] ===========================
Quoted 1 line
From
ebecaab0102aca37a3101131c20f45576835b6b3Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <[email protected]>
Date: Tue, 6 Nov 2018 13:18:39 +0100
Subject: [PATCH] try fix gtk egl cursor
--- ui/gtk-egl.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
ui/gtk-egl.c +12 -5
@@ -68,8 +68,15 @@ void gd_egl_draw(VirtualConsole *vc)return ; } + window =gtk_widget_get_window (vc->gfx.drawing_area); + ww =gdk_window_get_width (window); + wh =gdk_window_get_height (window); +if (vc->gfx.scanout_mode) {gd_egl_scanout_flush (&vc->gfx.dcl,0 ,0 , vc->gfx.w, vc->gfx.h); + + vc->gfx.scale_x = (double )ww / vc->gfx.w; + vc->gfx.scale_y = (double )wh / vc->gfx.h; }else {if (!vc->gfx.ds) {return ;
@@ -77,13 +84,13 @@ void gd_egl_draw(VirtualConsole *vc)eglMakeCurrent (qemu_egl_display, vc->gfx.esurface, vc->gfx.esurface, vc->gfx.ectx); - window =gtk_widget_get_window (vc->gfx.drawing_area); - ww =gdk_window_get_width (window); - wh =gdk_window_get_height (window);surface_gl_setup_viewport (vc->gfx.gls, vc->gfx.ds, ww, wh);surface_gl_render_texture (vc->gfx.gls, vc->gfx.ds);eglSwapBuffers (qemu_egl_display, vc->gfx.esurface); + + vc->gfx.scale_x = (double )ww /surface_width (vc->gfx.ds); + vc->gfx.scale_y = (double )wh /surface_height (vc->gfx.ds); } }
@@ -232,8 +239,8 @@ void gd_egl_cursor_position(DisplayChangeListener *dcl, {VirtualConsole *vc =container_of (dcl, VirtualConsole, gfx.dcl); - vc->gfx.cursor_x = pos_x; - vc->gfx.cursor_y = pos_y; + vc->gfx.cursor_x = pos_x * vc->gfx.scale_x; + vc->gfx.cursor_y = pos_y * vc->gfx.scale_y; } void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
Signature · 1 line
2.9.3