* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
static void
free_pointer_info (GdkPointerWindowInfo *info)
{
- g_object_unref (info->toplevel_under_pointer);
+ if (info->toplevel_under_pointer)
+ g_object_unref (info->toplevel_under_pointer);
g_slice_free (GdkPointerWindowInfo, info);
}
{
GList *list = value;
- g_list_foreach (list, (GFunc) free_device_grab, NULL);
- g_list_free (list);
+ g_list_free_full (list, (GDestroyNotify) free_device_grab);
return TRUE;
}
display->double_click_time = 250;
display->double_click_distance = 5;
+ display->touch_implicit_grabs = g_array_new (FALSE, FALSE, sizeof (GdkTouchGrabInfo));
display->device_grabs = g_hash_table_new (NULL, NULL);
display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) g_free);
device_manager = gdk_display_get_device_manager (GDK_DISPLAY (object));
- g_list_foreach (display->queued_events, (GFunc)gdk_event_free, NULL);
- g_list_free (display->queued_events);
+ g_list_free_full (display->queued_events, (GDestroyNotify) gdk_event_free);
display->queued_events = NULL;
display->queued_tail = NULL;
NULL);
g_hash_table_destroy (display->device_grabs);
+ g_array_free (display->touch_implicit_grabs, TRUE);
+
+ g_hash_table_destroy (display->motion_hint_info);
g_hash_table_destroy (display->pointers_info);
g_hash_table_destroy (display->multiple_click_info);
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+ if (display->event_pause_count > 0)
+ return NULL;
+
GDK_DISPLAY_GET_CLASS (display)->queue_events (display);
+
return _gdk_event_unqueue (display);
}
g_list_free (devices);
}
-/**
- * gdk_pointer_ungrab:
- * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no
- * timestamp is available.
- *
- * Ungrabs the pointer on the default display, if it is grabbed by this
- * application.
- *
- * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
- * instead.
- **/
-void
-gdk_pointer_ungrab (guint32 time)
-{
- gdk_display_pointer_ungrab (gdk_display_get_default (), time);
-}
-
-/**
- * gdk_pointer_is_grabbed:
- *
- * Returns %TRUE if the pointer on the default display is currently
- * grabbed by this application.
- *
- * Note that this does not take the inmplicit pointer grab on button
- * presses into account.
- *
- * Return value: %TRUE if the pointer is currently grabbed by this application.
- *
- * Deprecated: 3.0: Use gdk_display_device_is_grabbed() instead.
- **/
-gboolean
-gdk_pointer_is_grabbed (void)
-{
- return gdk_display_pointer_is_grabbed (gdk_display_get_default ());
-}
-
/**
* gdk_display_keyboard_ungrab:
* @display: a #GdkDisplay.
g_list_free (devices);
}
-/**
- * gdk_keyboard_ungrab:
- * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no
- * timestamp is available.
- *
- * Ungrabs the keyboard on the default display, if it is grabbed by this
- * application.
- *
- * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
- * instead.
- **/
-void
-gdk_keyboard_ungrab (guint32 time)
-{
- gdk_display_keyboard_ungrab (gdk_display_get_default (), time);
-}
-
/**
* gdk_beep:
*
/**
* gdk_display_get_pointer:
* @display: a #GdkDisplay
- * @screen: (out) (allow-none): location to store the screen that the
+ * @screen: (out) (allow-none) (transfer none): location to store the screen that the
* cursor is on, or %NULL.
* @x: (out) (allow-none): location to store root window X coordinate of pointer, or %NULL.
* @y: (out) (allow-none): location to store root window Y coordinate of pointer, or %NULL.
return info;
}
+static void
+_gdk_display_break_touch_grabs (GdkDisplay *display,
+ GdkDevice *device,
+ GdkWindow *new_grab_window)
+{
+ guint i;
+
+ for (i = 0; i < display->touch_implicit_grabs->len; i++)
+ {
+ GdkTouchGrabInfo *info;
+
+ info = &g_array_index (display->touch_implicit_grabs,
+ GdkTouchGrabInfo, i);
+
+ if (info->device == device && info->window != new_grab_window)
+ generate_grab_broken_event (GDK_WINDOW (info->window),
+ device, TRUE, new_grab_window);
+ }
+}
+
+void
+_gdk_display_add_touch_grab (GdkDisplay *display,
+ GdkDevice *device,
+ GdkEventSequence *sequence,
+ GdkWindow *window,
+ GdkWindow *native_window,
+ GdkEventMask event_mask,
+ unsigned long serial,
+ guint32 time)
+{
+ GdkTouchGrabInfo info;
+
+ info.device = device;
+ info.sequence = sequence;
+ info.window = g_object_ref (window);
+ info.native_window = g_object_ref (native_window);
+ info.serial = serial;
+ info.event_mask = event_mask;
+ info.time = time;
+
+ g_array_append_val (display->touch_implicit_grabs, info);
+}
+
+gboolean
+_gdk_display_end_touch_grab (GdkDisplay *display,
+ GdkDevice *device,
+ GdkEventSequence *sequence)
+{
+ guint i;
+
+ for (i = 0; i < display->touch_implicit_grabs->len; i++)
+ {
+ GdkTouchGrabInfo *info;
+
+ info = &g_array_index (display->touch_implicit_grabs,
+ GdkTouchGrabInfo, i);
+
+ if (info->device == device && info->sequence == sequence)
+ {
+ g_array_remove_index_fast (display->touch_implicit_grabs, i);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/* _gdk_synthesize_crossing_events only works inside one toplevel.
This function splits things into two calls if needed, converting the
coordinates to the right toplevel */
GdkModifierType state;
int x, y;
- /* We use the native crossing events if all native */
- if (_gdk_native_windows)
- return;
-
if (src_window)
src_toplevel = gdk_window_get_toplevel (src_window);
else
src_toplevel == dest_toplevel)
{
/* Same toplevels */
- gdk_window_get_pointer (dest_toplevel,
- &x, &y, &state);
+ gdk_window_get_device_position (dest_toplevel,
+ device,
+ &x, &y, &state);
_gdk_synthesize_crossing_events (display,
src_window,
dest_window,
}
else if (dest_toplevel == NULL)
{
- gdk_window_get_pointer (src_toplevel,
- &x, &y, &state);
+ gdk_window_get_device_position (src_toplevel,
+ device,
+ &x, &y, &state);
_gdk_synthesize_crossing_events (display,
src_window,
NULL,
else
{
/* Different toplevels */
- gdk_window_get_pointer (src_toplevel,
- &x, &y, &state);
+ gdk_window_get_device_position (src_toplevel,
+ device,
+ &x, &y, &state);
_gdk_synthesize_crossing_events (display,
src_window,
NULL,
time,
NULL,
serial, FALSE);
- gdk_window_get_pointer (dest_toplevel,
- &x, &y, &state);
+ gdk_window_get_device_position (dest_toplevel,
+ device,
+ &x, &y, &state);
_gdk_synthesize_crossing_events (display,
NULL,
dest_window,
if (grab == NULL) /* Ungrabbed, send events */
{
- pointer_window = NULL;
- if (new_toplevel)
- {
- /* Find (possibly virtual) child window */
- pointer_window =
- _gdk_window_find_descendant_at (new_toplevel,
- x, y,
- NULL, NULL);
- }
+ /* If the source device is a touch device, do not
+ * propagate any enter event yet, until one is
+ * synthesized when needed.
+ */
+ if (source_device &&
+ (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN))
+ info->need_touch_press_enter = TRUE;
- if (pointer_window != last_grab->window)
+ pointer_window = NULL;
+
+ if (new_toplevel &&
+ !info->need_touch_press_enter)
+ {
+ /* Find (possibly virtual) child window */
+ pointer_window =
+ _gdk_window_find_descendant_at (new_toplevel,
+ x, y,
+ NULL, NULL);
+ }
+
+ if (!info->need_touch_press_enter &&
+ pointer_window != last_grab->window)
synthesize_crossing_events (display, device, source_device,
last_grab->window, pointer_window,
GDK_CROSSING_UNGRAB, time, serial);
next_grab = NULL; /* Actually its not yet active */
}
+ if (next_grab)
+ _gdk_display_break_touch_grabs (display, device, next_grab->window);
+
if ((next_grab == NULL && current_grab->implicit_ungrab) ||
- (next_grab != NULL && current_grab->window != next_grab->window))
- generate_grab_broken_event (GDK_WINDOW (current_grab->window),
+ (next_grab != NULL && current_grab->window != next_grab->window))
+ generate_grab_broken_event (GDK_WINDOW (current_grab->window),
device,
- current_grab->implicit,
- next_grab? next_grab->window : NULL);
+ current_grab->implicit,
+ next_grab? next_grab->window : NULL);
/* Remove old grab */
grabs = g_list_delete_link (grabs, grabs);
return NULL;
}
+GdkTouchGrabInfo *
+_gdk_display_has_touch_grab (GdkDisplay *display,
+ GdkDevice *device,
+ GdkEventSequence *sequence,
+ gulong serial)
+{
+ guint i;
+
+ for (i = 0; i < display->touch_implicit_grabs->len; i++)
+ {
+ GdkTouchGrabInfo *info;
+
+ info = &g_array_index (display->touch_implicit_grabs,
+ GdkTouchGrabInfo, i);
+
+ if (info->device == device && info->sequence == sequence)
+ {
+ if (serial >= info->serial)
+ return info;
+ else
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
/* Returns true if last grab was ended
* If if_child is non-NULL, end the grab only if the grabbed
* window is the same as if_child or a descendant of it */
{
GdkPointerWindowInfo *info;
+ if (device && gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+ device = gdk_device_get_associated_device (device);
+
if (G_UNLIKELY (!device))
return NULL;
if (gdk_device_get_source (device) == GDK_SOURCE_MOUSE &&
gdk_display_device_is_grabbed (display, device))
- return TRUE;
+ {
+ g_list_free (devices);
+ return TRUE;
+ }
}
+ g_list_free (devices);
+
return FALSE;
}
*
* Since: 2.2
*/
-G_CONST_RETURN gchar *
+const gchar *
gdk_display_get_name (GdkDisplay *display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
}
/**
- * gdk_display_supports_clipboard_persistence
+ * gdk_display_supports_clipboard_persistence:
* @display: a #GdkDisplay
*
* Returns whether the speicifed display supports clipboard
}
/**
- * gdk_display_store_clipboard
+ * gdk_display_store_clipboard:
* @display: a #GdkDisplay
* @clipboard_window: a #GdkWindow belonging to the clipboard owner
* @time_: a timestamp
GDK_DISPLAY_GET_CLASS (display)->notify_startup_complete (display, startup_id);
}
+void
+_gdk_display_pause_events (GdkDisplay *display)
+{
+ display->event_pause_count++;
+}
+
+void
+_gdk_display_unpause_events (GdkDisplay *display)
+{
+ g_return_if_fail (display->event_pause_count > 0);
+
+ display->event_pause_count--;
+}
+
+void
+_gdk_display_flush_events (GdkDisplay *display)
+{
+ display->flushing_events = TRUE;
+
+ while (TRUE)
+ {
+ GdkEvent *event = _gdk_event_unqueue (display);
+ if (event == NULL)
+ break;
+
+ _gdk_event_emit (event);
+ gdk_event_free (event);
+ }
+
+ display->flushing_events = FALSE;
+}
+
void
_gdk_display_event_data_copy (GdkDisplay *display,
const GdkEvent *event,