[PATCH] #447: Add hooks to enable grab/scroll button functionality.

Erik Garrison erik at laptop.org
Wed Jul 9 18:26:39 EDT 2008


---
 src/sugar/Makefile.am         |    2 +-
 src/sugar/_sugarext.defs      |   20 ++++++++++++
 src/sugar/sugar-key-grabber.c |   66 +++++++++++++++++++++++++++++++++++++++++
 src/sugar/sugar-key-grabber.h |   10 ++++++
 4 files changed, 97 insertions(+), 1 deletions(-)

diff --git a/src/sugar/Makefile.am b/src/sugar/Makefile.am
index ef91efe..7e91769 100644
--- a/src/sugar/Makefile.am
+++ b/src/sugar/Makefile.am
@@ -18,7 +18,7 @@ _sugarext_la_CFLAGS = 		\
 	$(PYTHON_INCLUDES)
 
 _sugarext_la_LDFLAGS = -module -avoid-version
-_sugarext_la_LIBADD = $(EXT_LIBS) -lSM -lICE
+_sugarext_la_LIBADD = $(EXT_LIBS) -lSM -lICE -lXtst
 
 _sugarext_la_SOURCES =			\
 	$(BUILT_SOURCES)		\
diff --git a/src/sugar/_sugarext.defs b/src/sugar/_sugarext.defs
index 6e741dc..e57001d 100644
--- a/src/sugar/_sugarext.defs
+++ b/src/sugar/_sugarext.defs
@@ -131,6 +131,26 @@
   )
 )
 
+(define-method grab_pointer
+  (of-object "SugarKeyGrabber")
+  (c-name "sugar_key_grabber_grab_pointer")
+  (return-type "gboolean")
+)
+
+(define-method ungrab_pointer
+  (of-object "SugarKeyGrabber")
+  (c-name "sugar_key_grabber_ungrab_pointer")
+  (return-type "gboolean")
+)
+
+(define-method fake_button_event
+  (of-object "SugarKeyGrabber")
+  (c-name "sugar_key_grabber_fake_button_event")
+  (return-type "none")
+  (parameters
+    '("guint" "button"))
+)
+
 ;; From sexy-icon-entry.h
 
 (define-function sexy_icon_entry_get_type
diff --git a/src/sugar/sugar-key-grabber.c b/src/sugar/sugar-key-grabber.c
index 8e18c86..1bd3c14 100644
--- a/src/sugar/sugar-key-grabber.c
+++ b/src/sugar/sugar-key-grabber.c
@@ -18,6 +18,7 @@
  */
 
 #include <X11/X.h>
+#include <X11/extensions/XTest.h>
 #include <gdk/gdkscreen.h>
 #include <gdk/gdkx.h>
 #include <gdk/gdk.h>
@@ -38,6 +39,7 @@
 enum {
 	KEY_PRESSED,
 	KEY_RELEASED,
+  MOTION_NOTIFY,
 	N_SIGNALS
 };
 
@@ -96,6 +98,15 @@ sugar_key_grabber_class_init(SugarKeyGrabberClass *grabber_class)
                          G_TYPE_BOOLEAN, 2,
                          G_TYPE_UINT,
                          G_TYPE_UINT);
+	signals[MOTION_NOTIFY] = g_signal_new ("motion-notify",
+                         G_TYPE_FROM_CLASS (grabber_class),
+                         G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                         G_STRUCT_OFFSET (SugarKeyGrabberClass, motion_notify),
+                         NULL, NULL,
+                         sugar_marshal_BOOLEAN__UINT_UINT,
+                         G_TYPE_BOOLEAN, 2,
+                         G_TYPE_UINT,
+                         G_TYPE_UINT);
 }
 
 char *
@@ -136,6 +147,18 @@ filter_events(GdkXEvent *xevent, GdkEvent *event, gpointer data)
 			return GDK_FILTER_REMOVE;
 	}
 
+  if (xev->type == MotionNotify) {
+    /* the following give us mouse x and y coords
+        xev->xmotion.x
+        xev->xmotion.y
+    */
+		int return_value;
+		g_signal_emit (grabber, signals[MOTION_NOTIFY], 0, xev->xmotion.x,
+					   xev->xmotion.y, &return_value);
+		if(return_value)
+			return GDK_FILTER_REMOVE;
+  }
+
 	return GDK_FILTER_CONTINUE;
 }
 
@@ -151,6 +174,49 @@ sugar_key_grabber_init(SugarKeyGrabber *grabber)
 	gdk_window_add_filter(grabber->root, filter_events, grabber);
 }
 
+gboolean
+sugar_key_grabber_grab_pointer (SugarKeyGrabber *grabber)
+{
+
+    int result = XGrabPointer( GDK_DISPLAY(),
+                   GDK_WINDOW_XID (grabber->root),
+                   False, // owner_events
+                   PointerMotionMask|ButtonPressMask|ButtonReleaseMask, // event_mask
+                   GrabModeAsync,
+                   GrabModeAsync,
+                   None,
+                   None,
+                   CurrentTime );
+    if (result)
+      return TRUE;
+    else
+      return FALSE;
+}
+
+gboolean
+sugar_key_grabber_ungrab_pointer (SugarKeyGrabber *grabber)
+{
+    int result = XUngrabPointer(GDK_DISPLAY(), CurrentTime);
+    if (result)
+      return TRUE;
+    else
+      return FALSE;
+}
+
+/* Used to issue fake button 4/5/6/7 events when the grab button is pressed. */
+void
+sugar_key_grabber_fake_button_event (SugarKeyGrabber *grabber,
+                                     unsigned int button_number)
+{
+
+  Display *display = GDK_DISPLAY();
+
+  XTestFakeButtonEvent(display, button_number, True, CurrentTime);
+  XTestFakeButtonEvent(display, button_number, False, CurrentTime);
+  XFlush(display);
+
+}
+
 /* grab_key and grab_key_real are from 
  * gnome-control-center/gnome-settings-daemon/gnome-settings-multimedia-keys.c
  */
diff --git a/src/sugar/sugar-key-grabber.h b/src/sugar/sugar-key-grabber.h
index f131ee3..99b5ea8 100644
--- a/src/sugar/sugar-key-grabber.h
+++ b/src/sugar/sugar-key-grabber.h
@@ -52,6 +52,9 @@ struct _SugarKeyGrabberClass {
 	gboolean (* key_released) (SugarKeyGrabber *grabber,
 							   guint            keycode,
 							   guint            state);
+	gboolean (* motion_notify) (SugarKeyGrabber *grabber,
+							   guint            x,
+							   guint            y);
 };
 
 GType	 sugar_key_grabber_get_type	(void);
@@ -64,6 +67,13 @@ gboolean sugar_key_grabber_is_modifier (SugarKeyGrabber *grabber,
                                         guint            keycode,
                                         guint            mask);
 
+
+gboolean sugar_key_grabber_grab_pointer (SugarKeyGrabber *grabber);
+gboolean sugar_key_grabber_ungrab_pointer (SugarKeyGrabber *grabber);
+
+void sugar_key_grabber_fake_button_event (SugarKeyGrabber *grabber,
+                                          unsigned int button_number);
+
 G_END_DECLS
 
 #endif /* __SUGAR_KEY_GRABBER_H__ */
-- 
1.5.4.3


--XMCwj5IQnwKtuyBG--


More information about the Sugar mailing list