[mingw-gtk-vnc: 4/22] Pull in patch for relative mouse handling from native branch

epienbro epienbro at fedoraproject.org
Wed Mar 7 17:38:21 UTC 2012


commit f6c1b8778af7a129ac877e22a20bcb25d3ac193f
Author: Daniel P. Berrange <berrange at fedoraproject.org>
Date:   Fri Mar 6 11:01:43 2009 +0000

    Pull in patch for relative mouse handling from native branch

 gtk-vnc-0.3.8-relative-mouse.patch |  142 ++++++++++++++++++++++++++++++++++++
 mingw32-gtk-vnc.spec               |    9 ++-
 2 files changed, 150 insertions(+), 1 deletions(-)
---
diff --git a/gtk-vnc-0.3.8-relative-mouse.patch b/gtk-vnc-0.3.8-relative-mouse.patch
new file mode 100644
index 0000000..6177405
--- /dev/null
+++ b/gtk-vnc-0.3.8-relative-mouse.patch
@@ -0,0 +1,142 @@
+commit 85279b75576fcce7465754a8cc7b21cb6db5c355
+Author: Daniel P. Berrange <berrange at redhat.com>
+Date:   Thu Feb 26 13:29:16 2009 +0000
+
+    Change pointer grab to allow movement across entire desktop and
+    fix warping of pointer at desktop edges, to make relative mouse
+    mode work correctly. Document what's going on with more comments.
+
+diff --git a/src/vncdisplay.c b/src/vncdisplay.c
+index 5a25b91..f1082da 100644
+--- a/src/vncdisplay.c
++++ b/src/vncdisplay.c
+@@ -439,14 +439,22 @@ static void do_pointer_grab(VncDisplay *obj, gboolean quiet)
+ 	if (!priv->grab_keyboard)
+ 		do_keyboard_grab(obj, quiet);
+ 
++	/*
++	 * For relative mouse to work correctly when grabbed we need to
++	 * allow the pointer to move anywhere on the local desktop, so
++	 * use NULL for the 'confine_to' argument. Furthermore we need
++	 * the coords to be reported to our VNC window, regardless of
++	 * what window the pointer is actally over, so use 'FALSE' for
++	 * 'owner_events' parameter
++	 */
+ 	gdk_pointer_grab(GTK_WIDGET(obj)->window,
+-			 TRUE,
++			 FALSE, /* All events to come to our window directly */
+ 			 GDK_POINTER_MOTION_MASK |
+ 			 GDK_BUTTON_PRESS_MASK |
+ 			 GDK_BUTTON_RELEASE_MASK |
+ 			 GDK_BUTTON_MOTION_MASK |
+ 			 GDK_SCROLL_MASK,
+-			 GTK_WIDGET(obj)->window,
++			 NULL, /* Allow cursor to move over entire desktop */
+ 			 priv->remote_cursor ? priv->remote_cursor : priv->null_cursor,
+ 			 GDK_CURRENT_TIME);
+ 	priv->in_pointer_grab = TRUE;
+@@ -551,15 +559,33 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll)
+ 	return TRUE;
+ }
+ 
++
++/*
++ * There are several scenarios to considier when handling client
++ * mouse motion events:
++ *
++ *  - Mouse in relative mode + centered rendering of desktop
++ *  - Mouse in relative mode + scaled rendering of desktop
++ *  - Mouse in absolute mode + centered rendering of desktop
++ *  - Mouse in absolute mode + scaled rendering of desktop
++ *
++ * Once scaled / offset, absolute mode is easy.
++ *
++ * Relative mode has a couple of special complications
++ *
++ *  - Need to turn client absolute events into a delta
++ *  - Need to warp local pointer to avoid hitting a wall
++ */
+ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
+ {
+ 	VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
+-	int dx, dy;
+ 	int ww, wh;
+ 
+ 	if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
+ 		return FALSE;
+ 
++	/* In relative mode, only move the server mouse pointer
++	 * if the client grab is active */
+ 	if (!priv->absolute && !priv->in_pointer_grab)
+ 		return FALSE;
+ 
+@@ -568,11 +594,14 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
+ 
+ 	gdk_drawable_get_size(widget->window, &ww, &wh);
+ 
++	/* First apply adjustments to the coords in the motion event */
+ 	if (priv->allow_scaling) {
+ 		double sx, sy;
+ 		sx = (double)priv->fb.width / (double)ww;
+ 		sy = (double)priv->fb.height / (double)wh;
+ 
++		/* Scaling the desktop, so scale the mouse coords
++		 * by same ratio */
+ 		motion->x *= sx;
+ 		motion->y *= sy;
+ 	} else {
+@@ -583,21 +612,28 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
+ 		if (wh > priv->fb.height)
+ 			mh = (wh - priv->fb.height) / 2;
+ 
++		/* Not scaling, drawing the desktop centered
++		 * in the larger window, so offset the mouse
++		 * coords to match centering */
+ 		motion->x -= mw;
+ 		motion->y -= mh;
+-
+-		if (motion->x < 0 || motion->x >= priv->fb.width ||
+-		    motion->y < 0 || motion->y >= priv->fb.height)
+-			return FALSE;
+ 	}
+ 
+-	if (!priv->absolute && priv->in_pointer_grab) {
++	/* Next adjust the real client pointer */
++	if (!priv->absolute) {
+ 		GdkDrawable *drawable = GDK_DRAWABLE(widget->window);
+ 		GdkDisplay *display = gdk_drawable_get_display(drawable);
+ 		GdkScreen *screen = gdk_drawable_get_screen(drawable);
+ 		int x = (int)motion->x_root;
+ 		int y = (int)motion->y_root;
+ 
++		/* In relative mode check to see if client pointer hit
++		 * one of the screen edges, and if so move it back by
++		 * 200 pixels. This is important because the pointer
++		 * in the server doesn't correspond 1-for-1, and so
++		 * may still be only half way across the screen. Without
++		 * this warp, the server pointer would thus appear to hit
++		 * an invisible wall */
+ 		if (x == 0) x += 200;
+ 		if (y == 0) y += 200;
+ 		if (x == (gdk_screen_get_width(screen) - 1)) x -= 200;
+@@ -611,11 +647,20 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
+ 		}
+ 	}
+ 
++	/* Finally send the event to server */
+ 	if (priv->last_x != -1) {
++		int dx, dy;
+ 		if (priv->absolute) {
+ 			dx = (int)motion->x;
+ 			dy = (int)motion->y;
++
++			/* Drop out of bounds motion to avoid upsetting
++			 * the server */
++			if (dx < 0 || dx >= priv->fb.width ||
++			    dy < 0 || dy >= priv->fb.height)
++				return FALSE;
+ 		} else {
++			/* Just send the delta since last motion event */
+ 			dx = (int)motion->x + 0x7FFF - priv->last_x;
+ 			dy = (int)motion->y + 0x7FFF - priv->last_y;
+ 		}
diff --git a/mingw32-gtk-vnc.spec b/mingw32-gtk-vnc.spec
index 28af59b..fbc62da 100644
--- a/mingw32-gtk-vnc.spec
+++ b/mingw32-gtk-vnc.spec
@@ -8,13 +8,16 @@
 
 Name:           mingw32-gtk-vnc
 Version:        0.3.8
-Release:        4%{?dist}
+Release:        5%{?dist}
 Summary:        MinGW Windows port of VNC client GTK widget
 
 License:        LGPLv2+
 Group:          Development/Libraries
 URL:            http://sourceforge.net/projects/gtk-vnc
 Source0:        http://downloads.sourceforge.net/gtk-vnc/gtk-vnc-%{version}.tar.gz
+Patch1:         gtk-vnc-%{version}-relative-mouse.patch
+# XXX need to add the SASL patches too, but this is
+# blocking on a mingw32-cyrus-sasl port or equiv
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 BuildArch:      noarch
@@ -41,6 +44,7 @@ allowing it to be completely asynchronous while remaining single threaded.
 
 %prep
 %setup -q -n gtk-vnc-%{version}
+%patch1 -p1
 
 
 %build
@@ -73,6 +77,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Fri Mar  6 2009 Daniel P. Berrange <berrange at redhat.com> - 0.3.8-5
+- Fix relative mouse handling to avoid 'invisible wall'
+
 * Wed Feb 25 2009 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 0.3.8-4
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
 


More information about the scm-commits mailing list