[gtk-vnc-devel] [PATCH 4/7] Compress motion events to the VNC connection can keep up 2008-11-20 Federico Mena Quintero <federico novell com>



	Do compression of motion events, like TightVNC does, so that the
	VNC connection can keep up with the events we send.

	* src/vncdisplay.c (realize): Add a GtkWidget::realize handler.
	We install an event filter for our window, so that the filter can
	eat pending motion events.
	(eat_pending_motion_events_filter_func): New window filter
	function.  We eat all pending motion events in the X event queue.

Signed-off-by: Federico Mena Quintero <federico novell com>
---
 ChangeLog        |   11 +++++++++++
 src/vncdisplay.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6ce4994..a8cf656 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2008-11-20  Federico Mena Quintero  <federico novell com>
 
+	Do compression of motion events, like TightVNC does, so that the
+	VNC connection can keep up with the events we send.
+
+	* src/vncdisplay.c (realize): Add a GtkWidget::realize handler.
+	We install an event filter for our window, so that the filter can
+	eat pending motion events.
+	(eat_pending_motion_events_filter_func): New window filter
+	function.  We eat all pending motion events in the X event queue.
+
+2008-11-20  Federico Mena Quintero  <federico novell com>
+
 	Add support for LastRect encoding to make life easier (?) on the
 	VNC server.
 
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index 45ef57a..fdec881 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -18,6 +18,7 @@
 #include "config.h"
 #include "x_keymap.h"
 
+#include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 #include <string.h>
 #include <stdlib.h>
@@ -263,6 +264,55 @@ static GdkCursor *create_null_cursor(void)
 	return cursor;
 }
 
+static GdkFilterReturn
+eat_pending_motion_events_filter_func (GdkXEvent *xevent,
+				       GdkEvent *event,
+				       gpointer  data)
+{
+	XEvent *xev;
+	GtkWidget *widget;
+
+	xev = (XEvent *) xevent;
+	widget = data;
+
+	if (xev->type == MotionNotify) {
+		Display *xdisplay;
+		Window xwindow;
+
+		xdisplay = gdk_x11_drawable_get_xdisplay (widget->window);
+		xwindow = xev->xmotion.window;
+
+		/* Do compression of motion events:  here we eat all pending
+		 * MotionNotify events.  Then, we return GDK_FILTER_CONTINUE so
+		 * that gdk_event_translate() will process the last event we
+		 * got, instead of the original one it had.
+		 */
+		while (XCheckTypedWindowEvent (xdisplay, xwindow, MotionNotify, xev))
+			;
+
+		return GDK_FILTER_CONTINUE;
+	}
+
+	/* Let other events pass through as usual */
+	return GDK_FILTER_CONTINUE;
+}
+
+static void
+realize (GtkWidget *widget)
+{
+	VncDisplay *obj = VNC_DISPLAY(widget);
+	VncDisplayPrivate *priv = obj->priv;
+
+	GTK_WIDGET_CLASS (vnc_display_parent_class)->realize (widget);
+
+	/* We add an event filter for this window, so that we can compress
+	 * motion events before gdk_event_translate() processes them.  This
+	 * helps especially when the VNC connection cannot keep up with our
+	 * motion events.
+	 */
+	gdk_window_add_filter (widget->window, eat_pending_motion_events_filter_func, widget);
+}
+
 static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose)
 {
 	VncDisplay *obj = VNC_DISPLAY(widget);
@@ -1559,6 +1609,7 @@ static void vnc_display_class_init(VncDisplayClass *klass)
 	GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
 	GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
 
+	gtkwidget_class->realize = realize;
 	gtkwidget_class->expose_event = expose_event;
 	gtkwidget_class->motion_notify_event = motion_event;
 	gtkwidget_class->button_press_event = button_event;
-- 
1.5.6






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