+ other_info = l->data;
+ other_info->serial_end = serial_start;
+ }
+
+ return info;
+}
+
+static void
+free_pointer_grab (GdkPointerGrabInfo *info)
+{
+ g_object_unref (info->window);
+ g_object_unref (info->native_window);
+ g_free (info);
+}
+
+/* _gdk_syntesize_crossing_events only works inside one toplevel.
+ This function splits things into two calls if needed, converting the
+ coordinates to the right toplevel */
+static void
+synthesize_crossing_events (GdkDisplay *display,
+ GdkWindow *src_window,
+ GdkWindow *dest_window,
+ GdkCrossingMode crossing_mode,
+ guint32 time,
+ gulong serial)
+{
+ GdkWindow *src_toplevel, *dest_toplevel;
+ GdkModifierType state;
+ int x, y;
+
+ if (src_window)
+ src_toplevel = gdk_window_get_toplevel (src_window);
+ else
+ src_toplevel = NULL;
+ if (dest_window)
+ dest_toplevel = gdk_window_get_toplevel (dest_window);
+ else
+ dest_toplevel = NULL;
+
+ if (src_toplevel == NULL && dest_toplevel == NULL)
+ return;
+
+ if (src_toplevel == NULL ||
+ src_toplevel == dest_toplevel)
+ {
+ /* Same toplevels */
+ _gdk_windowing_window_get_pointer (display,
+ dest_toplevel,
+ &x, &y, &state);
+ _gdk_syntesize_crossing_events (display,
+ src_window,
+ dest_window,
+ crossing_mode,
+ x, y, state,
+ time,
+ NULL,
+ serial);
+ }
+ else if (dest_toplevel == NULL)
+ {
+ _gdk_windowing_window_get_pointer (display,
+ src_toplevel,
+ &x, &y, &state);
+ _gdk_syntesize_crossing_events (display,
+ src_window,
+ NULL,
+ crossing_mode,
+ x, y, state,
+ time,
+ NULL,
+ serial);
+ }
+ else
+ {
+ /* Different toplevels */
+ _gdk_windowing_window_get_pointer (display,
+ src_toplevel,
+ &x, &y, &state);
+ _gdk_syntesize_crossing_events (display,
+ src_window,
+ NULL,
+ crossing_mode,
+ x, y, state,
+ time,
+ NULL,
+ serial);
+ _gdk_windowing_window_get_pointer (display,
+ dest_toplevel,
+ &x, &y, &state);
+ _gdk_syntesize_crossing_events (display,
+ NULL,
+ dest_window,
+ crossing_mode,
+ x, y, state,
+ time,
+ NULL,
+ serial);
+ }
+}