[gtk+] Add gdk_event_[gs]et_source_device().



commit f5a20ab65a3d03fb90c27b2fa1954d965f8ad768
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Dec 13 02:12:43 2010 +0100

    Add gdk_event_[gs]et_source_device().
    
    This function may be used to know the hardware device that triggered
    an event, it could resort to the master device in the few cases there's
    not a direct hardware device to relate to the event (i.e.: crossing events
    due to grabs)

 gdk/gdkdisplay.c               |   19 +++++++-----
 gdk/gdkevents.c                |   60 ++++++++++++++++++++++++++++++++++++++++
 gdk/gdkevents.h                |    3 ++
 gdk/gdkinternals.h             |    3 ++
 gdk/gdkwindow.c                |   49 ++++++++++++++++++++------------
 gdk/x11/gdkdevicemanager-xi2.c |   39 ++++++++++++++++++++++---
 gdk/x11/gdkdisplay-x11.c       |    2 +-
 gdk/x11/gdkmain-x11.c          |    2 +-
 8 files changed, 144 insertions(+), 33 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 5ef630d..9a083e1 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -1302,6 +1302,7 @@ _gdk_display_add_device_grab (GdkDisplay       *display,
 static void
 synthesize_crossing_events (GdkDisplay      *display,
                             GdkDevice       *device,
+                            GdkDevice       *source_device,
 			    GdkWindow       *src_window,
 			    GdkWindow       *dest_window,
 			    GdkCrossingMode  crossing_mode,
@@ -1337,7 +1338,7 @@ synthesize_crossing_events (GdkDisplay      *display,
       _gdk_synthesize_crossing_events (display,
 				       src_window,
 				       dest_window,
-                                       device,
+                                       device, source_device,
 				       crossing_mode,
 				       x, y, state,
 				       time,
@@ -1351,7 +1352,7 @@ synthesize_crossing_events (GdkDisplay      *display,
       _gdk_synthesize_crossing_events (display,
                                        src_window,
                                        NULL,
-                                       device,
+                                       device, source_device,
                                        crossing_mode,
                                        x, y, state,
                                        time,
@@ -1366,7 +1367,7 @@ synthesize_crossing_events (GdkDisplay      *display,
       _gdk_synthesize_crossing_events (display,
 				       src_window,
 				       NULL,
-                                       device,
+                                       device, source_device,
 				       crossing_mode,
 				       x, y, state,
 				       time,
@@ -1377,7 +1378,7 @@ synthesize_crossing_events (GdkDisplay      *display,
       _gdk_synthesize_crossing_events (display,
 				       NULL,
 				       dest_window,
-                                       device,
+                                       device, source_device,
 				       crossing_mode,
 				       x, y, state,
 				       time,
@@ -1414,6 +1415,7 @@ get_current_toplevel (GdkDisplay      *display,
 static void
 switch_to_pointer_grab (GdkDisplay        *display,
                         GdkDevice         *device,
+                        GdkDevice         *source_device,
 			GdkDeviceGrabInfo *grab,
 			GdkDeviceGrabInfo *last_grab,
 			guint32            time,
@@ -1449,7 +1451,7 @@ switch_to_pointer_grab (GdkDisplay        *display,
 	    src_window = info->window_under_pointer;
 
 	  if (src_window != grab->window)
-            synthesize_crossing_events (display, device,
+            synthesize_crossing_events (display, device, source_device,
                                         src_window, grab->window,
                                         GDK_CROSSING_GRAB, time, serial);
 
@@ -1500,7 +1502,7 @@ switch_to_pointer_grab (GdkDisplay        *display,
 	    }
 
 	  if (pointer_window != last_grab->window)
-            synthesize_crossing_events (display, device,
+            synthesize_crossing_events (display, device, source_device,
                                         last_grab->window, pointer_window,
                                         GDK_CROSSING_UNGRAB, time, serial);
 
@@ -1515,6 +1517,7 @@ switch_to_pointer_grab (GdkDisplay        *display,
 void
 _gdk_display_device_grab_update (GdkDisplay *display,
                                  GdkDevice  *device,
+                                 GdkDevice  *source_device,
                                  gulong      current_serial)
 {
   GdkDeviceGrabInfo *current_grab, *next_grab;
@@ -1539,7 +1542,7 @@ _gdk_display_device_grab_update (GdkDisplay *display,
 	  if (!current_grab->activated)
             {
               if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
-                switch_to_pointer_grab (display, device, current_grab, NULL, time, current_serial);
+                switch_to_pointer_grab (display, device, source_device, current_grab, NULL, time, current_serial);
             }
 
 	  break;
@@ -1567,7 +1570,7 @@ _gdk_display_device_grab_update (GdkDisplay *display,
       g_hash_table_insert (display->device_grabs, device, grabs);
 
       if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
-        switch_to_pointer_grab (display, device,
+        switch_to_pointer_grab (display, device, source_device,
                                 next_grab, current_grab,
                                 time, current_serial);
 
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 438beb8..d6322db 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -1077,6 +1077,66 @@ gdk_event_get_device (const GdkEvent *event)
 }
 
 /**
+ * gdk_event_set_source_device:
+ * @event: a #GdkEvent
+ * @device: a #GdkDevice
+ *
+ * Sets the slave device for @event to @device. The event
+ * must have been allocated by GTK+, for instance, by
+ * gdk_event_copy().
+ *
+ * Since: 3.0
+ **/
+void
+gdk_event_set_source_device (GdkEvent  *event,
+                             GdkDevice *device)
+{
+  GdkEventPrivate *private;
+
+  g_return_if_fail (gdk_event_is_allocated (event));
+  g_return_if_fail (GDK_IS_DEVICE (device));
+
+  private = (GdkEventPrivate *) event;
+
+  private->source_device = device;
+}
+
+/**
+ * gdk_event_get_source_device:
+ * @event: a #GdkEvent
+ *
+ * This function returns the hardware (slave) #GdkDevice that has triggered the event,
+ * falling back to the virtual (master) device (as in gdk_event_get_device()) if the
+ * event wasn't caused by interaction with a hardware device. This may happen for
+ * example in synthesized crossing events after a #GdkWindow updates its geometry or
+ * a grab is acquired/released.
+ *
+ * If the event does not contain device field, this function will return %NULL.
+ *
+ * Returns: a #GdkDevice, or %NULL.
+ *
+ * Since: 3.0
+ **/
+GdkDevice *
+gdk_event_get_source_device (const GdkEvent *event)
+{
+  GdkEventPrivate *private;
+
+  g_return_val_if_fail (event != NULL, NULL);
+
+  if (!gdk_event_is_allocated (event))
+    return NULL;
+
+  private = (GdkEventPrivate *) event;
+
+  if (private->source_device)
+    return private->source_device;
+
+  /* Fallback to event device */
+  return gdk_event_get_device (event);
+}
+
+/**
  * gdk_event_request_motions:
  * @event: a valid #GdkEvent
  *
diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h
index fcefc6c..b7e5ed3 100644
--- a/gdk/gdkevents.h
+++ b/gdk/gdkevents.h
@@ -1089,6 +1089,9 @@ gboolean  gdk_event_get_axis            (const GdkEvent  *event,
 void       gdk_event_set_device         (GdkEvent        *event,
                                          GdkDevice       *device);
 GdkDevice* gdk_event_get_device         (const GdkEvent  *event);
+void       gdk_event_set_source_device  (GdkEvent        *event,
+                                         GdkDevice       *device);
+GdkDevice* gdk_event_get_source_device  (const GdkEvent  *event);
 void      gdk_event_request_motions     (const GdkEventMotion *event);
 
 gboolean  gdk_events_get_distance       (GdkEvent        *event1,
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 8ade0c1..a897181 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -156,6 +156,7 @@ struct _GdkEventPrivate
   GdkScreen *screen;
   gpointer   windowing_data;
   GdkDevice *device;
+  GdkDevice *source_device;
 };
 
 /* Tracks information about the pointer grab on this display */
@@ -440,6 +441,7 @@ void  _gdk_windowing_launch_failed         (GAppLaunchContext *context,
 
 void _gdk_display_device_grab_update                     (GdkDisplay *display,
                                                           GdkDevice  *device,
+                                                          GdkDevice  *source_device,
                                                           gulong      current_serial);
 GdkDeviceGrabInfo  *_gdk_display_get_last_device_grab  (GdkDisplay *display,
                                                         GdkDevice  *device);
@@ -498,6 +500,7 @@ void _gdk_synthesize_crossing_events (GdkDisplay                 *display,
 				      GdkWindow                  *src,
 				      GdkWindow                  *dest,
                                       GdkDevice                  *device,
+                                      GdkDevice                  *source_device,
 				      GdkCrossingMode             mode,
 				      gint                        toplevel_x,
 				      gint                        toplevel_y,
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 7ac8396..a2eb699 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -8335,6 +8335,7 @@ send_crossing_event (GdkDisplay                 *display,
 		     GdkNotifyType               notify_type,
 		     GdkWindow                  *subwindow,
                      GdkDevice                  *device,
+                     GdkDevice                  *source_device,
 		     gint                        toplevel_x,
 		     gint                        toplevel_y,
 		     GdkModifierType             mask,
@@ -8394,6 +8395,10 @@ send_crossing_event (GdkDisplay                 *display,
     {
       event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
       gdk_event_set_device (event, device);
+
+      if (source_device)
+        gdk_event_set_source_device (event, source_device);
+
       event->crossing.time = time_;
       event->crossing.subwindow = subwindow;
       if (subwindow)
@@ -8421,6 +8426,7 @@ _gdk_synthesize_crossing_events (GdkDisplay                 *display,
 				 GdkWindow                  *src,
 				 GdkWindow                  *dest,
                                  GdkDevice                  *device,
+                                 GdkDevice                  *source_device,
 				 GdkCrossingMode             mode,
 				 gint                        toplevel_x,
 				 gint                        toplevel_y,
@@ -8476,7 +8482,7 @@ _gdk_synthesize_crossing_events (GdkDisplay                 *display,
 			   a, GDK_LEAVE_NOTIFY,
 			   mode,
 			   notify_type,
-			   NULL, device,
+			   NULL, device, source_device,
 			   toplevel_x, toplevel_y,
 			   mask, time_,
 			   event_in_queue,
@@ -8498,7 +8504,7 @@ _gdk_synthesize_crossing_events (GdkDisplay                 *display,
 				   mode,
 				   notify_type,
 				   (GdkWindow *)last,
-                                   device,
+				   device, source_device,
 				   toplevel_x, toplevel_y,
 				   mask, time_,
 				   event_in_queue,
@@ -8545,7 +8551,7 @@ _gdk_synthesize_crossing_events (GdkDisplay                 *display,
 				   mode,
 				   notify_type,
 				   (GdkWindow *)next,
-                                   device,
+				   device, source_device,
 				   toplevel_x, toplevel_y,
 				   mask, time_,
 				   event_in_queue,
@@ -8567,7 +8573,7 @@ _gdk_synthesize_crossing_events (GdkDisplay                 *display,
 			   mode,
 			   notify_type,
 			   NULL,
-                           device,
+                           device, source_device,
 			   toplevel_x, toplevel_y,
 			   mask, time_,
 			   event_in_queue,
@@ -8939,7 +8945,7 @@ do_synthesize_crossing_event (gpointer data)
               _gdk_synthesize_crossing_events (display,
                                                pointer_info->window_under_pointer,
                                                new_window_under_pointer,
-                                               device,
+                                               device, NULL,
                                                GDK_CROSSING_NORMAL,
                                                pointer_info->toplevel_x,
                                                pointer_info->toplevel_y,
@@ -9055,7 +9061,7 @@ proxy_pointer_event (GdkDisplay                 *display,
   GdkWindow *toplevel_window, *event_window;
   GdkWindow *pointer_window;
   GdkPointerWindowInfo *pointer_info;
-  GdkDevice *device;
+  GdkDevice *device, *source_device;
   GdkEvent *event;
   guint state;
   gdouble toplevel_x, toplevel_y;
@@ -9067,6 +9073,7 @@ proxy_pointer_event (GdkDisplay                 *display,
   gdk_event_get_state (source_event, &state);
   time_ = gdk_event_get_time (source_event);
   device = gdk_event_get_device (source_event);
+  source_device = gdk_event_get_source_device (source_event);
   pointer_info = _gdk_display_get_pointer_info (display, device);
   toplevel_window = convert_native_coords_to_toplevel (event_window,
 						       toplevel_x, toplevel_y,
@@ -9100,7 +9107,7 @@ proxy_pointer_event (GdkDisplay                 *display,
       _gdk_synthesize_crossing_events (display,
 				       pointer_info->window_under_pointer,
 				       event_window,
-                                       device,
+                                       device, source_device,
 				       source_event->crossing.mode,
 				       toplevel_x, toplevel_y,
 				       state, time_,
@@ -9116,7 +9123,7 @@ proxy_pointer_event (GdkDisplay                 *display,
 			   source_event->crossing.mode,
 			   source_event->crossing.detail,
 			   NULL,
-                           device,
+                           device, source_device,
 			   toplevel_x, toplevel_y,
 			   state, time_,
 			   source_event,
@@ -9146,7 +9153,7 @@ proxy_pointer_event (GdkDisplay                 *display,
 			   source_event->crossing.mode,
 			   source_event->crossing.detail,
 			   NULL,
-                           device,
+                           device, source_device,
 			   toplevel_x, toplevel_y,
 			   state, time_,
 			   source_event,
@@ -9156,7 +9163,7 @@ proxy_pointer_event (GdkDisplay                 *display,
       _gdk_synthesize_crossing_events (display,
 				       event_window,
 				       pointer_window,
-                                       device,
+                                       device, source_device,
 				       source_event->crossing.mode,
 				       toplevel_x, toplevel_y,
 				       state, time_,
@@ -9175,7 +9182,7 @@ proxy_pointer_event (GdkDisplay                 *display,
       _gdk_synthesize_crossing_events (display,
 				       pointer_info->window_under_pointer,
 				       pointer_window,
-                                       device,
+                                       device, source_device,
 				       GDK_CROSSING_NORMAL,
 				       toplevel_x, toplevel_y,
 				       state, time_,
@@ -9236,6 +9243,7 @@ proxy_pointer_event (GdkDisplay                 *display,
 	  event->motion.device = source_event->motion.device;
           event->motion.axes = g_memdup (source_event->motion.axes,
                                          sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
+          gdk_event_set_source_device (event, source_device);
 	}
     }
 
@@ -9265,7 +9273,7 @@ proxy_button_event (GdkEvent *source_event,
   gdouble toplevel_x, toplevel_y;
   GdkDisplay *display;
   GdkWindow *w;
-  GdkDevice *device;
+  GdkDevice *device, *source_device;
 
   type = source_event->any.type;
   event_window = source_event->any.window;
@@ -9273,6 +9281,7 @@ proxy_button_event (GdkEvent *source_event,
   gdk_event_get_state (source_event, &state);
   time_ = gdk_event_get_time (source_event);
   device = gdk_event_get_device (source_event);
+  source_device = gdk_event_get_source_device (source_event);
   display = gdk_window_get_display (source_event->any.window);
   toplevel_window = convert_native_coords_to_toplevel (event_window,
 						       toplevel_x, toplevel_y,
@@ -9309,7 +9318,7 @@ proxy_button_event (GdkEvent *source_event,
                                      serial,
 				      time_,
                                      TRUE);
-      _gdk_display_device_grab_update (display, device, serial);
+      _gdk_display_device_grab_update (display, device, source_device, serial);
     }
 
   pointer_window = get_pointer_window (display, toplevel_window, device,
@@ -9346,6 +9355,8 @@ proxy_button_event (GdkEvent *source_event,
       event->button.axes = g_memdup (source_event->button.axes,
                                      sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
 
+      gdk_event_set_source_device (event, source_device);
+
       if (type == GDK_BUTTON_PRESS)
 	_gdk_event_button_generate (display, event);
       return TRUE;
@@ -9359,6 +9370,7 @@ proxy_button_event (GdkEvent *source_event,
       event->scroll.y_root = source_event->scroll.y_root;
       event->scroll.state = state;
       event->scroll.device = source_event->scroll.device;
+      gdk_event_set_source_device (event, source_device);
       return TRUE;
 
     default:
@@ -9452,20 +9464,21 @@ _gdk_windowing_got_event (GdkDisplay *display,
   guint old_state, old_button;
   GdkDeviceGrabInfo *button_release_grab;
   GdkPointerWindowInfo *pointer_info;
-  GdkDevice *device;
+  GdkDevice *device, *source_device;
   gboolean is_toplevel;
 
   if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
     display->last_event_time = gdk_event_get_time (event);
 
   device = gdk_event_get_device (event);
+  source_device = gdk_event_get_source_device (event);
 
   if (device)
     {
       GdkInputMode mode;
 
       g_object_get (device, "input-mode", &mode, NULL);
-      _gdk_display_device_grab_update (display, device, serial);
+      _gdk_display_device_grab_update (display, device, source_device, serial);
 
       if (mode == GDK_MODE_DISABLED ||
           !_gdk_display_check_grab_ownership (display, device, serial))
@@ -9510,7 +9523,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
                                          serial,
                                          gdk_event_get_time (event),
                                          TRUE);
-	  _gdk_display_device_grab_update (display, device, serial);
+	  _gdk_display_device_grab_update (display, device, source_device, serial);
 	}
       if (event->type == GDK_BUTTON_RELEASE &&
 	  !event->any.send_event)
@@ -9523,7 +9536,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
 	    {
 	      button_release_grab->serial_end = serial;
 	      button_release_grab->implicit_ungrab = FALSE;
-	      _gdk_display_device_grab_update (display, device, serial);
+	      _gdk_display_device_grab_update (display, device, source_device, serial);
 	    }
 	}
 
@@ -9645,7 +9658,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
 	{
 	  button_release_grab->serial_end = serial;
 	  button_release_grab->implicit_ungrab = FALSE;
-	  _gdk_display_device_grab_update (display, device, serial);
+	  _gdk_display_device_grab_update (display, device, source_device, serial);
 	}
     }
 
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 25d7a84..1cc2fc2 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -641,6 +641,7 @@ translate_keyboard_string (GdkEventKey *event)
 static void
 generate_focus_event (GdkWindow *window,
                       GdkDevice *device,
+                      GdkDevice *source_device,
                       gboolean   in)
 {
   GdkEvent *event;
@@ -650,6 +651,7 @@ generate_focus_event (GdkWindow *window,
   event->focus_change.send_event = FALSE;
   event->focus_change.in = in;
   gdk_event_set_device (event, device);
+  gdk_event_set_source_device (event, source_device);
 
   gdk_event_put (event);
   gdk_event_free (event);
@@ -658,6 +660,7 @@ generate_focus_event (GdkWindow *window,
 static void
 handle_focus_change (GdkWindow *window,
                      GdkDevice *device,
+                     GdkDevice *source_device,
                      gint       detail,
                      gint       mode,
                      gboolean   in)
@@ -717,7 +720,7 @@ handle_focus_change (GdkWindow *window,
     }
 
   if (HAS_FOCUS (toplevel) != had_focus)
-    generate_focus_event (window, device, (in) ? TRUE : FALSE);
+    generate_focus_event (window, device, source_device, (in) ? TRUE : FALSE);
 }
 
 static gdouble *
@@ -916,7 +919,7 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
         XIDeviceEvent *xev = (XIDeviceEvent *) ev;
         GdkKeymap *keymap = gdk_keymap_get_for_display (display);
         GdkModifierType consumed, state;
-        GdkDevice *device;
+        GdkDevice *device, *source_device;
 
         event->key.type = xev->evtype == XI_KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
 
@@ -933,6 +936,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
                                       GUINT_TO_POINTER (xev->deviceid));
         gdk_event_set_device (event, device);
 
+        source_device = g_hash_table_lookup (device_manager->id_table,
+                                             GUINT_TO_POINTER (xev->sourceid));
+        gdk_event_set_source_device (event, source_device);
+
         event->key.keyval = GDK_KEY_VoidSymbol;
 
         gdk_keymap_translate_keyboard_state (keymap,
@@ -961,6 +968,7 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
     case XI_ButtonRelease:
       {
         XIDeviceEvent *xev = (XIDeviceEvent *) ev;
+        GdkDevice *source_device;
 
         switch (xev->detail)
           {
@@ -989,6 +997,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
             event->scroll.device = g_hash_table_lookup (device_manager->id_table,
                                                         GUINT_TO_POINTER (xev->deviceid));
 
+            source_device = g_hash_table_lookup (device_manager->id_table,
+                                                 GUINT_TO_POINTER (xev->sourceid));
+            gdk_event_set_source_device (event, source_device);
+
             event->scroll.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons);
             break;
           default:
@@ -1004,6 +1016,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
             event->button.device = g_hash_table_lookup (device_manager->id_table,
                                                         GUINT_TO_POINTER (xev->deviceid));
 
+            source_device = g_hash_table_lookup (device_manager->id_table,
+                                                 GUINT_TO_POINTER (xev->sourceid));
+            gdk_event_set_source_device (event, source_device);
+
             event->button.axes = translate_axes (event->button.device,
                                                  event->button.x,
                                                  event->button.y,
@@ -1036,6 +1052,7 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
     case XI_Motion:
       {
         XIDeviceEvent *xev = (XIDeviceEvent *) ev;
+        GdkDevice *source_device;
 
         event->motion.type = GDK_MOTION_NOTIFY;
 
@@ -1050,6 +1067,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
         event->motion.device = g_hash_table_lookup (device_manager->id_table,
                                                     GINT_TO_POINTER (xev->deviceid));
 
+        source_device = g_hash_table_lookup (device_manager->id_table,
+                                             GUINT_TO_POINTER (xev->sourceid));
+        gdk_event_set_source_device (event, source_device);
+
         event->motion.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons);
 
         /* There doesn't seem to be motion hints in XI */
@@ -1075,7 +1096,7 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
     case XI_Leave:
       {
         XIEnterEvent *xev = (XIEnterEvent *) ev;
-        GdkDevice *device;
+        GdkDevice *device, *source_device;
 
         event->crossing.type = (ev->evtype == XI_Enter) ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY;
 
@@ -1093,6 +1114,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
                                       GINT_TO_POINTER (xev->deviceid));
         gdk_event_set_device (event, device);
 
+        source_device = g_hash_table_lookup (device_manager->id_table,
+                                             GUINT_TO_POINTER (xev->sourceid));
+        gdk_event_set_source_device (event, source_device);
+
         event->crossing.mode = translate_crossing_mode (xev->mode);
         event->crossing.detail = translate_notify_type (xev->detail);
         event->crossing.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons);
@@ -1102,12 +1127,16 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
     case XI_FocusOut:
       {
         XIEnterEvent *xev = (XIEnterEvent *) ev;
-        GdkDevice *device;
+        GdkDevice *device, *source_device;
 
         device = g_hash_table_lookup (device_manager->id_table,
                                       GINT_TO_POINTER (xev->deviceid));
 
-        handle_focus_change (window, device, xev->detail, xev->mode,
+        source_device = g_hash_table_lookup (device_manager->id_table,
+                                             GUINT_TO_POINTER (xev->sourceid));
+
+        handle_focus_change (window, device, source_device,
+                             xev->detail, xev->mode,
                              (ev->evtype == XI_FocusIn) ? TRUE : FALSE);
 
         return_val = FALSE;
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index bfcc358..27ef251 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1633,7 +1633,7 @@ device_ungrab_callback (GdkDisplay *display,
 {
   GdkDevice *device = data;
 
-  _gdk_display_device_grab_update (display, device, serial);
+  _gdk_display_device_grab_update (display, device, NULL, serial);
 }
 
 
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
index f9df295..2ce5e34 100644
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@ -136,7 +136,7 @@ has_pointer_grab_callback (GdkDisplay *display,
 {
   GdkDevice *device = data;
 
-  _gdk_display_device_grab_update (display, device, serial);
+  _gdk_display_device_grab_update (display, device, NULL, serial);
 }
 
 GdkGrabStatus



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