[gtk+/xi2] GtkWidget: implement gtk_widget_[get|set|add]_events() multidevice counterpart.



commit 1334d7b163dcb9f0f8def0567231d8c6fa750972
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri May 21 14:33:36 2010 +0200

    GtkWidget: implement gtk_widget_[get|set|add]_events() multidevice counterpart.

 gtk/gtkwidget.c |  150 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 gtk/gtkwidget.h |    8 +++
 2 files changed, 148 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 15d6b44..ab695ef 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -384,6 +384,7 @@ static GQuark		quark_aux_info = 0;
 static GQuark		quark_accel_path = 0;
 static GQuark		quark_accel_closures = 0;
 static GQuark		quark_event_mask = 0;
+static GQuark           quark_device_event_mask = 0;
 static GQuark		quark_extension_event_mode = 0;
 static GQuark		quark_parent_window = 0;
 static GQuark		quark_pointer_window = 0;
@@ -482,6 +483,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
   quark_accel_path = g_quark_from_static_string ("gtk-accel-path");
   quark_accel_closures = g_quark_from_static_string ("gtk-accel-closures");
   quark_event_mask = g_quark_from_static_string ("gtk-event-mask");
+  quark_device_event_mask = g_quark_from_static_string ("gtk-device-event-mask");
   quark_extension_event_mode = g_quark_from_static_string ("gtk-extension-event-mode");
   quark_parent_window = g_quark_from_static_string ("gtk-parent-window");
   quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
@@ -8068,10 +8070,53 @@ gtk_widget_set_events (GtkWidget *widget,
   g_object_notify (G_OBJECT (widget), "events");
 }
 
+/**
+ * gtk_widget_set_device_events:
+ * @widget: a #GtkWidget
+ * #device: a #GdkDevice
+ * @events: event mask
+ *
+ * Sets the device event mask (see #GdkEventMask) for a widget. The event
+ * mask determines which events a widget will receive from @device. Keep
+ * in mind that different widgets have different default event masks, and by
+ * changing the event mask you may disrupt a widget's functionality,
+ * so be careful. This function must be called while a widget is
+ * unrealized. Consider gtk_widget_add_device_events() for widgets that are
+ * already realized, or if you want to preserve the existing event
+ * mask. This function can't be used with #GTK_NO_WINDOW widgets;
+ * to get events on those widgets, place them inside a #GtkEventBox
+ * and receive events on the event box.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_widget_set_device_events (GtkWidget    *widget,
+                              GdkDevice    *device,
+                              GdkEventMask  events)
+{
+  GHashTable *device_events;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (GDK_IS_DEVICE (device));
+  g_return_if_fail (!gtk_widget_get_realized (widget));
+
+  device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
+
+  if (G_UNLIKELY (!device_events))
+    {
+      device_events = g_hash_table_new (NULL, NULL);
+      g_object_set_qdata_full (G_OBJECT (widget), quark_device_event_mask, device_events,
+                               (GDestroyNotify) g_hash_table_unref);
+    }
+
+  g_hash_table_insert (device_events, device, GUINT_TO_POINTER (events));
+}
+
 static void
 gtk_widget_add_events_internal (GtkWidget *widget,
-				gint       events,
-				GList     *window_list)
+                                GdkDevice *device,
+                                gint       events,
+                                GList     *window_list)
 {
   GList *l;
 
@@ -8082,15 +8127,18 @@ gtk_widget_add_events_internal (GtkWidget *widget,
 
       gdk_window_get_user_data (window, &user_data);
       if (user_data == widget)
-	{
-	  GList *children;
+        {
+          GList *children;
 
-	  gdk_window_set_events (window, gdk_window_get_events (window) | events);
+          if (device)
+            gdk_window_set_device_events (window, device, gdk_window_get_events (window) | events);
+          else
+            gdk_window_set_events (window, gdk_window_get_events (window) | events);
 
-	  children = gdk_window_get_children (window);
-	  gtk_widget_add_events_internal (widget, events, children);
-	  g_list_free (children);
-	}
+          children = gdk_window_get_children (window);
+          gtk_widget_add_events_internal (widget, device, events, children);
+          g_list_free (children);
+        }
     }
 }
 
@@ -8123,7 +8171,60 @@ gtk_widget_add_events (GtkWidget *widget,
       else
 	window_list = g_list_prepend (NULL, widget->window);
 
-      gtk_widget_add_events_internal (widget, events, window_list);
+      gtk_widget_add_events_internal (widget, NULL, events, window_list);
+
+      g_list_free (window_list);
+    }
+
+  g_object_notify (G_OBJECT (widget), "events");
+}
+
+/**
+ * gtk_widget_add_device_events:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ * @events: an event mask, see #GdkEventMask
+ *
+ * Adds the device events in the bitfield @events to the event mask for
+ * @widget. See gtk_widget_set_device_events() for details.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_widget_add_device_events (GtkWidget    *widget,
+                              GdkDevice    *device,
+                              GdkEventMask  events)
+{
+  GdkEventMask old_events;
+  GHashTable *device_events;
+
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (GDK_IS_DEVICE (device));
+
+  old_events = gtk_widget_get_device_events (widget, device);
+
+  device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
+
+  if (G_UNLIKELY (!device_events))
+    {
+      device_events = g_hash_table_new (NULL, NULL);
+      g_object_set_qdata_full (G_OBJECT (widget), quark_device_event_mask, device_events,
+                               (GDestroyNotify) g_hash_table_unref);
+    }
+
+  g_hash_table_insert (device_events, device,
+                       GUINT_TO_POINTER (old_events | events));
+
+  if (gtk_widget_get_realized (widget))
+    {
+      GList *window_list;
+
+      if (!gtk_widget_get_has_window (widget))
+        window_list = gdk_window_get_children (widget->window);
+      else
+        window_list = g_list_prepend (NULL, widget->window);
+
+      gtk_widget_add_events_internal (widget, device, events, window_list);
 
       g_list_free (window_list);
     }
@@ -8348,6 +8449,35 @@ gtk_widget_get_events (GtkWidget *widget)
 }
 
 /**
+ * gtk_widget_get_device_events:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ *
+ * Returns the events mask for the widget corresponding to an specific device. These
+ * are the events that the widget will receive when @device operates on it.
+ *
+ * Returns: device event mask for @widget
+ *
+ * Since: 3.0
+ **/
+GdkEventMask
+gtk_widget_get_device_events (GtkWidget *widget,
+                              GdkDevice *device)
+{
+  GHashTable *device_events;
+
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+  g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
+
+  device_events = g_object_get_qdata (G_OBJECT (widget), quark_device_event_mask);
+
+  if (!device_events)
+    return 0;
+
+  return GPOINTER_TO_UINT (g_hash_table_lookup (device_events, device));
+}
+
+/**
  * gtk_widget_get_extension_events:
  * @widget: a #GtkWidget
  * 
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 32d81ec..02119f6 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -777,6 +777,12 @@ void	   gtk_widget_set_events	  (GtkWidget	       *widget,
 					   gint			events);
 void       gtk_widget_add_events          (GtkWidget           *widget,
 					   gint	                events);
+void	   gtk_widget_set_device_events	  (GtkWidget	       *widget,
+                                           GdkDevice           *device,
+					   GdkEventMask		events);
+void       gtk_widget_add_device_events   (GtkWidget           *widget,
+                                           GdkDevice           *device,
+					   GdkEventMask         events);
 void	   gtk_widget_set_extension_events (GtkWidget		*widget,
 					    GdkExtensionMode	mode);
 
@@ -820,6 +826,8 @@ void         gtk_widget_set_colormap    (GtkWidget      *widget,
 					 GdkColormap    *colormap);
 
 gint	     gtk_widget_get_events	(GtkWidget	*widget);
+GdkEventMask gtk_widget_get_device_events (GtkWidget	*widget,
+                                           GdkDevice    *device);
 void	     gtk_widget_get_pointer	(GtkWidget	*widget,
 					 gint		*x,
 					 gint		*y);



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