[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