1 /* GDK - The GIMP Drawing Kit
4 * Copyright 2001 Sun Microsystems Inc.
6 * Erwann Chenede <erwann.chenede@sun.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
24 #include "gdkdisplay.h"
25 #include "gdkdisplayprivate.h"
27 #include "gdkdeviceprivate.h"
28 #include "gdkevents.h"
29 #include "gdkwindowimpl.h"
30 #include "gdkinternals.h"
31 #include "gdkmarshalers.h"
32 #include "gdkscreen.h"
39 * @Short_description: Controls a set of GdkScreens and their associated input devices
42 * #GdkDisplay objects purpose are two fold:
45 * To manage and provide information about input devices (pointers
49 * To manage and provide information about the available #GdkScreens
53 * GdkDisplay objects are the GDK representation of an X Display,
54 * which can be described as <emphasis>a workstation consisting of
55 * a keyboard, a pointing device (such as a mouse) and one or more
57 * It is used to open and keep track of various GdkScreen objects
58 * currently instantiated by the application. It is also used to
59 * access the keyboard(s) and mouse pointer(s) of the display.
61 * Most of the input device handling has been factored out into
62 * the separate #GdkDeviceManager object. Every display has a
63 * device manager, which you can obtain using
64 * gdk_display_get_device_manager().
74 static void gdk_display_dispose (GObject *object);
75 static void gdk_display_finalize (GObject *object);
78 static GdkAppLaunchContext *gdk_display_real_get_app_launch_context (GdkDisplay *display);
80 static guint signals[LAST_SIGNAL] = { 0 };
82 G_DEFINE_TYPE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
85 gdk_display_class_init (GdkDisplayClass *class)
87 GObjectClass *object_class = G_OBJECT_CLASS (class);
89 object_class->finalize = gdk_display_finalize;
90 object_class->dispose = gdk_display_dispose;
92 class->get_app_launch_context = gdk_display_real_get_app_launch_context;
93 class->window_type = GDK_TYPE_WINDOW;
97 * @display: the object on which the signal is emitted
99 * The ::opened signal is emitted when the connection to the windowing
100 * system for @display is opened.
103 g_signal_new (g_intern_static_string ("opened"),
104 G_OBJECT_CLASS_TYPE (object_class),
107 g_cclosure_marshal_VOID__VOID,
111 * GdkDisplay::closed:
112 * @display: the object on which the signal is emitted
113 * @is_error: %TRUE if the display was closed due to an error
115 * The ::closed signal is emitted when the connection to the windowing
116 * system for @display is closed.
121 g_signal_new (g_intern_static_string ("closed"),
122 G_OBJECT_CLASS_TYPE (object_class),
124 G_STRUCT_OFFSET (GdkDisplayClass, closed),
126 _gdk_marshal_VOID__BOOLEAN,
133 free_pointer_info (GdkPointerWindowInfo *info)
135 if (info->toplevel_under_pointer)
136 g_object_unref (info->toplevel_under_pointer);
137 g_slice_free (GdkPointerWindowInfo, info);
141 free_device_grab (GdkDeviceGrabInfo *info)
143 g_object_unref (info->window);
144 g_object_unref (info->native_window);
149 free_device_grabs_foreach (gpointer key,
155 g_list_free_full (list, (GDestroyNotify) free_device_grab);
161 device_removed_cb (GdkDeviceManager *device_manager,
165 g_hash_table_remove (display->multiple_click_info, device);
166 g_hash_table_remove (display->device_grabs, device);
167 g_hash_table_remove (display->pointers_info, device);
169 /* FIXME: change core pointer and remove from device list */
173 gdk_display_opened (GdkDisplay *display)
175 GdkDeviceManager *device_manager;
177 device_manager = gdk_display_get_device_manager (display);
179 g_signal_connect (device_manager, "device-removed",
180 G_CALLBACK (device_removed_cb), display);
184 gdk_display_init (GdkDisplay *display)
186 display->double_click_time = 250;
187 display->double_click_distance = 5;
189 display->touch_implicit_grabs = g_array_new (FALSE, FALSE, sizeof (GdkTouchGrabInfo));
190 display->device_grabs = g_hash_table_new (NULL, NULL);
191 display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
192 (GDestroyNotify) g_free);
194 display->pointers_info = g_hash_table_new_full (NULL, NULL, NULL,
195 (GDestroyNotify) free_pointer_info);
197 display->multiple_click_info = g_hash_table_new_full (NULL, NULL, NULL,
198 (GDestroyNotify) g_free);
200 g_signal_connect (display, "opened",
201 G_CALLBACK (gdk_display_opened), NULL);
205 gdk_display_dispose (GObject *object)
207 GdkDisplay *display = GDK_DISPLAY (object);
208 GdkDeviceManager *device_manager;
210 device_manager = gdk_display_get_device_manager (GDK_DISPLAY (object));
212 g_list_free_full (display->queued_events, (GDestroyNotify) gdk_event_free);
213 display->queued_events = NULL;
214 display->queued_tail = NULL;
218 /* this is to make it drop devices which may require using the X
219 * display and therefore can't be cleaned up in finalize.
220 * It will also disconnect device_removed_cb
222 g_object_run_dispose (G_OBJECT (display->device_manager));
225 G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
229 gdk_display_finalize (GObject *object)
231 GdkDisplay *display = GDK_DISPLAY (object);
233 g_hash_table_foreach_remove (display->device_grabs,
234 free_device_grabs_foreach,
236 g_hash_table_destroy (display->device_grabs);
238 g_array_free (display->touch_implicit_grabs, TRUE);
240 g_hash_table_destroy (display->motion_hint_info);
241 g_hash_table_destroy (display->pointers_info);
242 g_hash_table_destroy (display->multiple_click_info);
244 if (display->device_manager)
245 g_object_unref (display->device_manager);
247 G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
252 * @display: a #GdkDisplay
254 * Closes the connection to the windowing system for the given display,
255 * and cleans up associated resources.
260 gdk_display_close (GdkDisplay *display)
262 g_return_if_fail (GDK_IS_DISPLAY (display));
264 if (!display->closed)
266 display->closed = TRUE;
268 g_signal_emit (display, signals[CLOSED], 0, FALSE);
269 g_object_run_dispose (G_OBJECT (display));
271 g_object_unref (display);
276 * gdk_display_is_closed:
277 * @display: a #GdkDisplay
279 * Finds out if the display has been closed.
281 * Returns: %TRUE if the display is closed.
286 gdk_display_is_closed (GdkDisplay *display)
288 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
290 return display->closed;
294 * gdk_display_get_event:
295 * @display: a #GdkDisplay
297 * Gets the next #GdkEvent to be processed for @display, fetching events from the
298 * windowing system if necessary.
300 * Return value: the next #GdkEvent to be processed, or %NULL if no events
301 * are pending. The returned #GdkEvent should be freed with gdk_event_free().
306 gdk_display_get_event (GdkDisplay *display)
308 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
310 GDK_DISPLAY_GET_CLASS (display)->queue_events (display);
311 return _gdk_event_unqueue (display);
315 * gdk_display_peek_event:
316 * @display: a #GdkDisplay
318 * Gets a copy of the first #GdkEvent in the @display's event queue, without
319 * removing the event from the queue. (Note that this function will
320 * not get more events from the windowing system. It only checks the events
321 * that have already been moved to the GDK event queue.)
323 * Return value: a copy of the first #GdkEvent on the event queue, or %NULL
324 * if no events are in the queue. The returned #GdkEvent should be freed with
330 gdk_display_peek_event (GdkDisplay *display)
334 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
336 tmp_list = _gdk_event_queue_find_first (display);
339 return gdk_event_copy (tmp_list->data);
345 * gdk_display_put_event:
346 * @display: a #GdkDisplay
347 * @event: a #GdkEvent.
349 * Appends a copy of the given event onto the front of the event
350 * queue for @display.
355 gdk_display_put_event (GdkDisplay *display,
356 const GdkEvent *event)
358 g_return_if_fail (GDK_IS_DISPLAY (display));
359 g_return_if_fail (event != NULL);
361 _gdk_event_queue_append (display, gdk_event_copy (event));
362 /* If the main loop is blocking in a different thread, wake it up */
363 g_main_context_wakeup (NULL);
367 * gdk_display_pointer_ungrab:
368 * @display: a #GdkDisplay.
369 * @time_: a timestap (e.g. %GDK_CURRENT_TIME).
371 * Release any pointer grab.
375 * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
379 gdk_display_pointer_ungrab (GdkDisplay *display,
382 GdkDeviceManager *device_manager;
383 GList *devices, *dev;
386 g_return_if_fail (GDK_IS_DISPLAY (display));
388 device_manager = gdk_display_get_device_manager (display);
389 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
391 /* FIXME: Should this be generic to all backends? */
392 /* FIXME: What happens with extended devices? */
393 for (dev = devices; dev; dev = dev->next)
397 if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
400 gdk_device_ungrab (device, time_);
403 g_list_free (devices);
407 * gdk_display_keyboard_ungrab:
408 * @display: a #GdkDisplay.
409 * @time_: a timestap (e.g #GDK_CURRENT_TIME).
411 * Release any keyboard grab
415 * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
419 gdk_display_keyboard_ungrab (GdkDisplay *display,
422 GdkDeviceManager *device_manager;
423 GList *devices, *dev;
426 g_return_if_fail (GDK_IS_DISPLAY (display));
428 device_manager = gdk_display_get_device_manager (display);
429 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
431 /* FIXME: Should this be generic to all backends? */
432 /* FIXME: What happens with extended devices? */
433 for (dev = devices; dev; dev = dev->next)
437 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
440 gdk_device_ungrab (device, time);
443 g_list_free (devices);
449 * Emits a short beep on the default display.
454 gdk_display_beep (gdk_display_get_default ());
460 * Flushes the output buffers of all display connections and waits
461 * until all requests have been processed.
462 * This is rarely needed by applications.
469 list = gdk_display_manager_list_displays (gdk_display_manager_get ());
470 for (l = list; l; l = l->next)
472 GdkDisplay *display = l->data;
474 GDK_DISPLAY_GET_CLASS (display)->sync (display);
481 _gdk_display_enable_motion_hints (GdkDisplay *display,
484 gulong *device_serial, serial;
486 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
490 device_serial = g_new0 (gulong, 1);
491 *device_serial = G_MAXULONG;
492 g_hash_table_insert (display->motion_hint_info, device, device_serial);
495 if (*device_serial != 0)
497 serial = _gdk_display_get_next_serial (display);
498 /* We might not actually generate the next request, so
499 make sure this triggers always, this may cause it to
500 trigger slightly too early, but this is just a hint
504 if (serial < *device_serial)
505 *device_serial = serial;
510 * gdk_display_get_pointer:
511 * @display: a #GdkDisplay
512 * @screen: (out) (allow-none) (transfer none): location to store the screen that the
513 * cursor is on, or %NULL.
514 * @x: (out) (allow-none): location to store root window X coordinate of pointer, or %NULL.
515 * @y: (out) (allow-none): location to store root window Y coordinate of pointer, or %NULL.
516 * @mask: (out) (allow-none): location to store current modifier mask, or %NULL
518 * Gets the current location of the pointer and the current modifier
519 * mask for a given display.
523 * Deprecated: 3.0: Use gdk_device_get_position() instead.
526 gdk_display_get_pointer (GdkDisplay *display,
530 GdkModifierType *mask)
532 GdkScreen *default_screen;
535 GdkModifierType tmp_mask;
537 g_return_if_fail (GDK_IS_DISPLAY (display));
539 if (gdk_display_is_closed (display))
542 default_screen = gdk_display_get_default_screen (display);
544 /* We call _gdk_device_query_state() here manually instead of
545 * gdk_device_get_position() because we care about the modifier mask */
547 _gdk_device_query_state (display->core_pointer,
548 gdk_screen_get_root_window (default_screen),
555 *screen = gdk_window_get_screen (root);
565 * gdk_display_get_window_at_pointer:
566 * @display: a #GdkDisplay
567 * @win_x: (out) (allow-none): return location for x coordinate of the pointer location relative
568 * to the window origin, or %NULL
569 * @win_y: (out) (allow-none): return location for y coordinate of the pointer location relative
570 & to the window origin, or %NULL
572 * Obtains the window underneath the mouse pointer, returning the location
573 * of the pointer in that window in @win_x, @win_y for @screen. Returns %NULL
574 * if the window under the mouse pointer is not known to GDK (for example,
575 * belongs to another application).
577 * Returns: (transfer none): the window under the mouse pointer, or %NULL
581 * Deprecated: 3.0: Use gdk_device_get_window_at_position() instead.
584 gdk_display_get_window_at_pointer (GdkDisplay *display,
588 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
590 return gdk_device_get_window_at_position (display->core_pointer, win_x, win_y);
594 generate_grab_broken_event (GdkWindow *window,
597 GdkWindow *grab_window)
599 g_return_if_fail (window != NULL);
601 if (!GDK_WINDOW_DESTROYED (window))
605 event = gdk_event_new (GDK_GRAB_BROKEN);
606 event->grab_broken.window = g_object_ref (window);
607 event->grab_broken.send_event = FALSE;
608 event->grab_broken.implicit = implicit;
609 event->grab_broken.grab_window = grab_window;
610 gdk_event_set_device (event, device);
611 event->grab_broken.keyboard = (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) ? TRUE : FALSE;
613 gdk_event_put (event);
614 gdk_event_free (event);
619 _gdk_display_get_last_device_grab (GdkDisplay *display,
624 l = g_hash_table_lookup (display->device_grabs, device);
636 _gdk_display_add_device_grab (GdkDisplay *display,
639 GdkWindow *native_window,
640 GdkGrabOwnership grab_ownership,
641 gboolean owner_events,
642 GdkEventMask event_mask,
643 unsigned long serial_start,
647 GdkDeviceGrabInfo *info, *other_info;
650 info = g_new0 (GdkDeviceGrabInfo, 1);
652 info->window = g_object_ref (window);
653 info->native_window = g_object_ref (native_window);
654 info->serial_start = serial_start;
655 info->serial_end = G_MAXULONG;
656 info->owner_events = owner_events;
657 info->event_mask = event_mask;
659 info->implicit = implicit;
660 info->ownership = grab_ownership;
662 grabs = g_hash_table_lookup (display->device_grabs, device);
664 /* Find the first grab that has a larger start time (if any) and insert
665 * before that. I.E we insert after already existing grabs with same
667 for (l = grabs; l != NULL; l = l->next)
669 other_info = l->data;
671 if (info->serial_start < other_info->serial_start)
675 grabs = g_list_insert_before (grabs, l, info);
677 /* Make sure the new grab end before next grab */
680 other_info = l->data;
681 info->serial_end = other_info->serial_start;
684 /* Find any previous grab and update its end time */
685 l = g_list_find (grabs, info);
689 other_info = l->data;
690 other_info->serial_end = serial_start;
693 g_hash_table_insert (display->device_grabs, device, grabs);
699 _gdk_display_break_touch_grabs (GdkDisplay *display,
701 GdkWindow *new_grab_window)
705 for (i = 0; i < display->touch_implicit_grabs->len; i++)
707 GdkTouchGrabInfo *info;
709 info = &g_array_index (display->touch_implicit_grabs,
710 GdkTouchGrabInfo, i);
712 if (info->device == device && info->window != new_grab_window)
713 generate_grab_broken_event (GDK_WINDOW (info->window),
714 device, TRUE, new_grab_window);
719 _gdk_display_add_touch_grab (GdkDisplay *display,
721 GdkEventSequence *sequence,
723 GdkWindow *native_window,
724 GdkEventMask event_mask,
725 unsigned long serial,
728 GdkTouchGrabInfo info;
730 info.device = device;
731 info.sequence = sequence;
732 info.window = g_object_ref (window);
733 info.native_window = g_object_ref (native_window);
734 info.serial = serial;
735 info.event_mask = event_mask;
738 g_array_append_val (display->touch_implicit_grabs, info);
742 _gdk_display_end_touch_grab (GdkDisplay *display,
744 GdkEventSequence *sequence)
748 for (i = 0; i < display->touch_implicit_grabs->len; i++)
750 GdkTouchGrabInfo *info;
752 info = &g_array_index (display->touch_implicit_grabs,
753 GdkTouchGrabInfo, i);
755 if (info->device == device && info->sequence == sequence)
757 g_array_remove_index_fast (display->touch_implicit_grabs, i);
765 /* _gdk_synthesize_crossing_events only works inside one toplevel.
766 This function splits things into two calls if needed, converting the
767 coordinates to the right toplevel */
769 synthesize_crossing_events (GdkDisplay *display,
771 GdkDevice *source_device,
772 GdkWindow *src_window,
773 GdkWindow *dest_window,
774 GdkCrossingMode crossing_mode,
778 GdkWindow *src_toplevel, *dest_toplevel;
779 GdkModifierType state;
783 src_toplevel = gdk_window_get_toplevel (src_window);
787 dest_toplevel = gdk_window_get_toplevel (dest_window);
789 dest_toplevel = NULL;
791 if (src_toplevel == NULL && dest_toplevel == NULL)
794 if (src_toplevel == NULL ||
795 src_toplevel == dest_toplevel)
798 gdk_window_get_device_position (dest_toplevel,
801 _gdk_synthesize_crossing_events (display,
804 device, source_device,
811 else if (dest_toplevel == NULL)
813 gdk_window_get_device_position (src_toplevel,
816 _gdk_synthesize_crossing_events (display,
819 device, source_device,
828 /* Different toplevels */
829 gdk_window_get_device_position (src_toplevel,
832 _gdk_synthesize_crossing_events (display,
835 device, source_device,
841 gdk_window_get_device_position (dest_toplevel,
844 _gdk_synthesize_crossing_events (display,
847 device, source_device,
857 get_current_toplevel (GdkDisplay *display,
861 GdkModifierType *state_out)
863 GdkWindow *pointer_window;
865 GdkModifierType state;
867 pointer_window = _gdk_device_window_at_position (device, &x, &y, &state, TRUE);
869 if (pointer_window != NULL &&
870 (GDK_WINDOW_DESTROYED (pointer_window) ||
871 GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT ||
872 GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN))
873 pointer_window = NULL;
879 return pointer_window;
883 switch_to_pointer_grab (GdkDisplay *display,
885 GdkDevice *source_device,
886 GdkDeviceGrabInfo *grab,
887 GdkDeviceGrabInfo *last_grab,
891 GdkWindow *src_window, *pointer_window, *new_toplevel;
892 GdkPointerWindowInfo *info;
894 GdkModifierType state;
897 /* Temporarily unset pointer to make sure we send the crossing events below */
898 old_grabs = g_hash_table_lookup (display->device_grabs, device);
899 g_hash_table_steal (display->device_grabs, device);
900 info = _gdk_display_get_pointer_info (display, device);
904 /* New grab is in effect */
906 /* We need to generate crossing events for the grab.
907 * However, there are never any crossing events for implicit grabs
908 * TODO: ... Actually, this could happen if the pointer window
909 * doesn't have button mask so a parent gets the event...
913 /* We send GRAB crossing events from the window under the pointer to the
914 grab window. Except if there is an old grab then we start from that */
916 src_window = last_grab->window;
918 src_window = info->window_under_pointer;
920 if (src_window != grab->window)
921 synthesize_crossing_events (display, device, source_device,
922 src_window, grab->window,
923 GDK_CROSSING_GRAB, time, serial);
925 /* !owner_event Grabbing a window that we're not inside, current status is
926 now NULL (i.e. outside grabbed window) */
927 if (!grab->owner_events && info->window_under_pointer != grab->window)
928 _gdk_display_set_window_under_pointer (display, device, NULL);
931 grab->activated = TRUE;
938 if (grab == NULL /* ungrab */ ||
939 (!last_grab->owner_events && grab->owner_events) /* switched to owner_events */ )
941 /* We force check what window we're in, and update the toplevel_under_pointer info,
942 * as that won't get told of this change with toplevel enter events.
944 if (info->toplevel_under_pointer)
945 g_object_unref (info->toplevel_under_pointer);
946 info->toplevel_under_pointer = NULL;
948 /* Ungrabbed slave devices don't have a position by
949 * itself, rather depend on its master pointer, so
950 * it doesn't make sense to track any position for
951 * these after the grab
953 if (grab || gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE)
954 new_toplevel = get_current_toplevel (display, device, &x, &y, &state);
958 /* w is now toplevel and x,y in toplevel coords */
959 info->toplevel_under_pointer = g_object_ref (new_toplevel);
960 info->toplevel_x = x;
961 info->toplevel_y = y;
966 if (grab == NULL) /* Ungrabbed, send events */
968 /* If the source device is a touch device, do not
969 * propagate any enter event yet, until one is
970 * synthesized when needed.
973 (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN ||
974 gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHPAD))
975 info->need_touch_press_enter = TRUE;
977 pointer_window = NULL;
980 !info->need_touch_press_enter)
982 /* Find (possibly virtual) child window */
984 _gdk_window_find_descendant_at (new_toplevel,
989 if (pointer_window != last_grab->window)
990 synthesize_crossing_events (display, device, source_device,
991 last_grab->window, pointer_window,
992 GDK_CROSSING_UNGRAB, time, serial);
994 /* We're now ungrabbed, update the window_under_pointer */
995 _gdk_display_set_window_under_pointer (display, device, pointer_window);
999 g_hash_table_insert (display->device_grabs, device, old_grabs);
1003 _gdk_display_device_grab_update (GdkDisplay *display,
1005 GdkDevice *source_device,
1006 gulong current_serial)
1008 GdkDeviceGrabInfo *current_grab, *next_grab;
1012 time = display->last_event_time;
1013 grabs = g_hash_table_lookup (display->device_grabs, device);
1015 while (grabs != NULL)
1017 current_grab = grabs->data;
1019 if (current_grab->serial_start > current_serial)
1020 return; /* Hasn't started yet */
1022 if (current_grab->serial_end > current_serial)
1024 /* This one hasn't ended yet.
1025 its the currently active one or scheduled to be active */
1027 if (!current_grab->activated)
1029 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
1030 switch_to_pointer_grab (display, device, source_device, current_grab, NULL, time, current_serial);
1039 /* This is the next active grab */
1040 next_grab = grabs->next->data;
1042 if (next_grab->serial_start > current_serial)
1043 next_grab = NULL; /* Actually its not yet active */
1047 _gdk_display_break_touch_grabs (display, device, next_grab->window);
1049 if ((next_grab == NULL && current_grab->implicit_ungrab) ||
1050 (next_grab != NULL && current_grab->window != next_grab->window))
1051 generate_grab_broken_event (GDK_WINDOW (current_grab->window),
1053 current_grab->implicit,
1054 next_grab? next_grab->window : NULL);
1056 /* Remove old grab */
1057 grabs = g_list_delete_link (grabs, grabs);
1058 g_hash_table_insert (display->device_grabs, device, grabs);
1060 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
1061 switch_to_pointer_grab (display, device, source_device,
1062 next_grab, current_grab,
1063 time, current_serial);
1065 free_device_grab (current_grab);
1070 grab_list_find (GList *grabs,
1073 GdkDeviceGrabInfo *grab;
1079 if (serial >= grab->serial_start && serial < grab->serial_end)
1082 grabs = grabs->next;
1089 find_device_grab (GdkDisplay *display,
1095 l = g_hash_table_lookup (display->device_grabs, device);
1096 return grab_list_find (l, serial);
1100 _gdk_display_has_device_grab (GdkDisplay *display,
1106 l = find_device_grab (display, device, serial);
1114 _gdk_display_has_touch_grab (GdkDisplay *display,
1116 GdkEventSequence *sequence,
1121 for (i = 0; i < display->touch_implicit_grabs->len; i++)
1123 GdkTouchGrabInfo *info;
1125 info = &g_array_index (display->touch_implicit_grabs,
1126 GdkTouchGrabInfo, i);
1128 if (info->device == device && info->sequence == sequence)
1130 if (serial >= info->serial)
1140 /* Returns true if last grab was ended
1141 * If if_child is non-NULL, end the grab only if the grabbed
1142 * window is the same as if_child or a descendant of it */
1144 _gdk_display_end_device_grab (GdkDisplay *display,
1147 GdkWindow *if_child,
1150 GdkDeviceGrabInfo *grab;
1153 l = find_device_grab (display, device, serial);
1160 (if_child == NULL ||
1161 _gdk_window_event_parent_of (if_child, grab->window)))
1163 grab->serial_end = serial;
1164 grab->implicit_ungrab = implicit;
1165 return l->next == NULL;
1171 /* Returns TRUE if device events are not blocked by any grab */
1173 _gdk_display_check_grab_ownership (GdkDisplay *display,
1177 GHashTableIter iter;
1178 gpointer key, value;
1179 GdkGrabOwnership higher_ownership, device_ownership;
1180 gboolean device_is_keyboard;
1182 g_hash_table_iter_init (&iter, display->device_grabs);
1183 higher_ownership = device_ownership = GDK_OWNERSHIP_NONE;
1184 device_is_keyboard = (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD);
1186 while (g_hash_table_iter_next (&iter, &key, &value))
1188 GdkDeviceGrabInfo *grab;
1194 grabs = grab_list_find (grabs, serial);
1199 /* Discard device if it's not of the same type */
1200 if ((device_is_keyboard && gdk_device_get_source (dev) != GDK_SOURCE_KEYBOARD) ||
1201 (!device_is_keyboard && gdk_device_get_source (dev) == GDK_SOURCE_KEYBOARD))
1207 device_ownership = grab->ownership;
1210 if (grab->ownership > higher_ownership)
1211 higher_ownership = grab->ownership;
1215 if (higher_ownership > device_ownership)
1217 /* There's a higher priority ownership
1218 * going on for other device(s)
1226 GdkPointerWindowInfo *
1227 _gdk_display_get_pointer_info (GdkDisplay *display,
1230 GdkPointerWindowInfo *info;
1232 if (device && gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
1233 device = gdk_device_get_associated_device (device);
1235 if (G_UNLIKELY (!device))
1238 info = g_hash_table_lookup (display->pointers_info, device);
1240 if (G_UNLIKELY (!info))
1242 info = g_slice_new0 (GdkPointerWindowInfo);
1243 g_hash_table_insert (display->pointers_info, device, info);
1250 _gdk_display_pointer_info_foreach (GdkDisplay *display,
1251 GdkDisplayPointerInfoForeach func,
1254 GHashTableIter iter;
1255 gpointer key, value;
1257 g_hash_table_iter_init (&iter, display->pointers_info);
1259 while (g_hash_table_iter_next (&iter, &key, &value))
1261 GdkPointerWindowInfo *info = value;
1262 GdkDevice *device = key;
1264 (func) (display, device, info, user_data);
1269 * gdk_device_grab_info_libgtk_only:
1270 * @display: the display for which to get the grab information
1271 * @device: device to get the grab information from
1272 * @grab_window: (out) (transfer none): location to store current grab window
1273 * @owner_events: (out): location to store boolean indicating whether
1274 * the @owner_events flag to gdk_keyboard_grab() or
1275 * gdk_pointer_grab() was %TRUE.
1277 * Determines information about the current keyboard grab.
1278 * This is not public API and must not be used by applications.
1280 * Return value: %TRUE if this application currently has the
1284 gdk_device_grab_info_libgtk_only (GdkDisplay *display,
1286 GdkWindow **grab_window,
1287 gboolean *owner_events)
1289 GdkDeviceGrabInfo *info;
1291 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1292 g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
1294 info = _gdk_display_get_last_device_grab (display, device);
1299 *grab_window = info->window;
1301 *owner_events = info->owner_events;
1310 * gdk_display_pointer_is_grabbed:
1311 * @display: a #GdkDisplay
1313 * Test if the pointer is grabbed.
1315 * Returns: %TRUE if an active X pointer grab is in effect
1319 * Deprecated: 3.0: Use gdk_display_device_is_grabbed() instead.
1322 gdk_display_pointer_is_grabbed (GdkDisplay *display)
1324 GdkDeviceManager *device_manager;
1325 GList *devices, *dev;
1328 g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
1330 device_manager = gdk_display_get_device_manager (display);
1331 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
1333 for (dev = devices; dev; dev = dev->next)
1337 if (gdk_device_get_source (device) == GDK_SOURCE_MOUSE &&
1338 gdk_display_device_is_grabbed (display, device))
1340 g_list_free (devices);
1345 g_list_free (devices);
1351 * gdk_display_device_is_grabbed:
1352 * @display: a #GdkDisplay
1353 * @device: a #GdkDevice
1355 * Returns %TRUE if there is an ongoing grab on @device for @display.
1357 * Returns: %TRUE if there is a grab in effect for @device.
1360 gdk_display_device_is_grabbed (GdkDisplay *display,
1363 GdkDeviceGrabInfo *info;
1365 g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
1366 g_return_val_if_fail (GDK_IS_DEVICE (device), TRUE);
1368 /* What we're interested in is the steady state (ie last grab),
1369 because we're interested e.g. if we grabbed so that we
1370 can ungrab, even if our grab is not active just yet. */
1371 info = _gdk_display_get_last_device_grab (display, device);
1373 return (info && !info->implicit);
1377 * gdk_display_get_device_manager:
1378 * @display: a #GdkDisplay.
1380 * Returns the #GdkDeviceManager associated to @display.
1382 * Returns: (transfer none): A #GdkDeviceManager, or %NULL. This memory is
1383 * owned by GDK and must not be freed or unreferenced.
1388 gdk_display_get_device_manager (GdkDisplay *display)
1390 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1392 return display->device_manager;
1396 * gdk_display_get_name:
1397 * @display: a #GdkDisplay
1399 * Gets the name of the display.
1401 * Returns: a string representing the display name. This string is owned
1402 * by GDK and should not be modified or freed.
1407 gdk_display_get_name (GdkDisplay *display)
1409 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1411 return GDK_DISPLAY_GET_CLASS (display)->get_name (display);
1415 gdk_get_display (void)
1417 return g_strdup (gdk_display_get_name (gdk_display_get_default ()));
1421 * gdk_display_get_n_screens:
1422 * @display: a #GdkDisplay
1424 * Gets the number of screen managed by the @display.
1426 * Returns: number of screens.
1431 gdk_display_get_n_screens (GdkDisplay *display)
1433 g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
1435 return GDK_DISPLAY_GET_CLASS (display)->get_n_screens (display);
1439 * gdk_display_get_screen:
1440 * @display: a #GdkDisplay
1441 * @screen_num: the screen number
1443 * Returns a screen object for one of the screens of the display.
1445 * Returns: (transfer none): the #GdkScreen object
1450 gdk_display_get_screen (GdkDisplay *display,
1453 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1455 return GDK_DISPLAY_GET_CLASS (display)->get_screen (display, screen_num);
1459 * gdk_display_get_default_screen:
1460 * @display: a #GdkDisplay
1462 * Get the default #GdkScreen for @display.
1464 * Returns: (transfer none): the default #GdkScreen object for @display
1469 gdk_display_get_default_screen (GdkDisplay *display)
1471 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1473 return GDK_DISPLAY_GET_CLASS (display)->get_default_screen (display);
1478 * @display: a #GdkDisplay
1480 * Emits a short beep on @display
1485 gdk_display_beep (GdkDisplay *display)
1487 g_return_if_fail (GDK_IS_DISPLAY (display));
1489 GDK_DISPLAY_GET_CLASS (display)->beep (display);
1494 * @display: a #GdkDisplay
1496 * Flushes any requests queued for the windowing system and waits until all
1497 * requests have been handled. This is often used for making sure that the
1498 * display is synchronized with the current state of the program. Calling
1499 * gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors
1500 * generated from earlier requests are handled before the error trap is
1503 * This is most useful for X11. On windowing systems where requests are
1504 * handled synchronously, this function will do nothing.
1509 gdk_display_sync (GdkDisplay *display)
1511 g_return_if_fail (GDK_IS_DISPLAY (display));
1513 GDK_DISPLAY_GET_CLASS (display)->sync (display);
1517 * gdk_display_flush:
1518 * @display: a #GdkDisplay
1520 * Flushes any requests queued for the windowing system; this happens automatically
1521 * when the main loop blocks waiting for new events, but if your application
1522 * is drawing without returning control to the main loop, you may need
1523 * to call this function explicitely. A common case where this function
1524 * needs to be called is when an application is executing drawing commands
1525 * from a thread other than the thread where the main loop is running.
1527 * This is most useful for X11. On windowing systems where requests are
1528 * handled synchronously, this function will do nothing.
1533 gdk_display_flush (GdkDisplay *display)
1535 g_return_if_fail (GDK_IS_DISPLAY (display));
1537 GDK_DISPLAY_GET_CLASS (display)->flush (display);
1541 * gdk_display_get_default_group:
1542 * @display: a #GdkDisplay
1544 * Returns the default group leader window for all toplevel windows
1545 * on @display. This window is implicitly created by GDK.
1546 * See gdk_window_set_group().
1548 * Return value: (transfer none): The default group leader window
1554 gdk_display_get_default_group (GdkDisplay *display)
1556 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1558 return GDK_DISPLAY_GET_CLASS (display)->get_default_group (display);
1562 * gdk_display_supports_selection_notification:
1563 * @display: a #GdkDisplay
1565 * Returns whether #GdkEventOwnerChange events will be
1566 * sent when the owner of a selection changes.
1568 * Return value: whether #GdkEventOwnerChange events will
1574 gdk_display_supports_selection_notification (GdkDisplay *display)
1576 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1578 return GDK_DISPLAY_GET_CLASS (display)->supports_selection_notification (display);
1582 * gdk_display_request_selection_notification:
1583 * @display: a #GdkDisplay
1584 * @selection: the #GdkAtom naming the selection for which
1585 * ownership change notification is requested
1587 * Request #GdkEventOwnerChange events for ownership changes
1588 * of the selection named by the given atom.
1590 * Return value: whether #GdkEventOwnerChange events will
1596 gdk_display_request_selection_notification (GdkDisplay *display,
1600 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1602 return GDK_DISPLAY_GET_CLASS (display)->request_selection_notification (display, selection);
1606 * gdk_display_supports_clipboard_persistence
1607 * @display: a #GdkDisplay
1609 * Returns whether the speicifed display supports clipboard
1610 * persistance; i.e. if it's possible to store the clipboard data after an
1611 * application has quit. On X11 this checks if a clipboard daemon is
1614 * Returns: %TRUE if the display supports clipboard persistance.
1619 gdk_display_supports_clipboard_persistence (GdkDisplay *display)
1621 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1623 return GDK_DISPLAY_GET_CLASS (display)->supports_clipboard_persistence (display);
1627 * gdk_display_store_clipboard
1628 * @display: a #GdkDisplay
1629 * @clipboard_window: a #GdkWindow belonging to the clipboard owner
1630 * @time_: a timestamp
1631 * @targets: (array length=n_targets): an array of targets
1632 * that should be saved, or %NULL
1633 * if all available targets should be saved.
1634 * @n_targets: length of the @targets array
1636 * Issues a request to the clipboard manager to store the
1637 * clipboard data. On X11, this is a special program that works
1638 * according to the freedesktop clipboard specification, available at
1639 * <ulink url="http://www.freedesktop.org/Standards/clipboard-manager-spec">
1640 * http://www.freedesktop.org/Standards/clipboard-manager-spec</ulink>.
1645 gdk_display_store_clipboard (GdkDisplay *display,
1646 GdkWindow *clipboard_window,
1648 const GdkAtom *targets,
1651 g_return_if_fail (GDK_IS_DISPLAY (display));
1653 GDK_DISPLAY_GET_CLASS (display)->store_clipboard (display, clipboard_window, time_, targets, n_targets);
1657 * gdk_display_supports_shapes:
1658 * @display: a #GdkDisplay
1660 * Returns %TRUE if gdk_window_shape_combine_mask() can
1661 * be used to create shaped windows on @display.
1663 * Returns: %TRUE if shaped windows are supported
1668 gdk_display_supports_shapes (GdkDisplay *display)
1670 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1672 return GDK_DISPLAY_GET_CLASS (display)->supports_shapes (display);
1676 * gdk_display_supports_input_shapes:
1677 * @display: a #GdkDisplay
1679 * Returns %TRUE if gdk_window_input_shape_combine_mask() can
1680 * be used to modify the input shape of windows on @display.
1682 * Returns: %TRUE if windows with modified input shape are supported
1687 gdk_display_supports_input_shapes (GdkDisplay *display)
1689 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1691 return GDK_DISPLAY_GET_CLASS (display)->supports_input_shapes (display);
1695 * gdk_display_supports_composite:
1696 * @display: a #GdkDisplay
1698 * Returns %TRUE if gdk_window_set_composited() can be used
1699 * to redirect drawing on the window using compositing.
1701 * Currently this only works on X11 with XComposite and
1702 * XDamage extensions available.
1704 * Returns: %TRUE if windows may be composited.
1709 gdk_display_supports_composite (GdkDisplay *display)
1711 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1713 return GDK_DISPLAY_GET_CLASS (display)->supports_composite (display);
1717 * gdk_display_list_devices:
1718 * @display: a #GdkDisplay
1720 * Returns the list of available input devices attached to @display.
1721 * The list is statically allocated and should not be freed.
1723 * Return value: (transfer none) (element-type GdkDevice):
1724 * a list of #GdkDevice
1728 * Deprecated: 3.0: Use gdk_device_manager_list_devices() instead.
1731 gdk_display_list_devices (GdkDisplay *display)
1733 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1735 return GDK_DISPLAY_GET_CLASS (display)->list_devices (display);
1738 static GdkAppLaunchContext *
1739 gdk_display_real_get_app_launch_context (GdkDisplay *display)
1741 GdkAppLaunchContext *ctx;
1743 ctx = g_object_new (GDK_TYPE_APP_LAUNCH_CONTEXT,
1751 * gdk_display_get_app_launch_context:
1752 * @display: a #GdkDisplay
1754 * Returns a #GdkAppLaunchContext suitable for launching
1755 * applications on the given display.
1757 * Returns: (transfer full): a new #GdkAppLaunchContext for @display.
1758 * Free with g_object_unref() when done
1762 GdkAppLaunchContext *
1763 gdk_display_get_app_launch_context (GdkDisplay *display)
1765 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1767 return GDK_DISPLAY_GET_CLASS (display)->get_app_launch_context (display);
1772 * @display_name: the name of the display to open
1776 * Return value: (transfer none): a #GdkDisplay, or %NULL
1777 * if the display could not be opened
1782 gdk_display_open (const gchar *display_name)
1784 return gdk_display_manager_open_display (gdk_display_manager_get (),
1789 * gdk_display_has_pending:
1790 * @display: a #GdkDisplay
1792 * Returns whether the display has events that are waiting
1795 * Returns: %TRUE if there are events ready to be processed.
1800 gdk_display_has_pending (GdkDisplay *display)
1802 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1804 return GDK_DISPLAY_GET_CLASS (display)->has_pending (display);
1808 * gdk_display_supports_cursor_alpha:
1809 * @display: a #GdkDisplay
1811 * Returns %TRUE if cursors can use an 8bit alpha channel
1812 * on @display. Otherwise, cursors are restricted to bilevel
1813 * alpha (i.e. a mask).
1815 * Returns: whether cursors can have alpha channels.
1820 gdk_display_supports_cursor_alpha (GdkDisplay *display)
1822 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1824 return GDK_DISPLAY_GET_CLASS (display)->supports_cursor_alpha (display);
1828 * gdk_display_supports_cursor_color:
1829 * @display: a #GdkDisplay
1831 * Returns %TRUE if multicolored cursors are supported
1832 * on @display. Otherwise, cursors have only a forground
1833 * and a background color.
1835 * Returns: whether cursors can have multiple colors.
1840 gdk_display_supports_cursor_color (GdkDisplay *display)
1842 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1844 return GDK_DISPLAY_GET_CLASS (display)->supports_cursor_color (display);
1848 * gdk_display_get_default_cursor_size:
1849 * @display: a #GdkDisplay
1851 * Returns the default size to use for cursors on @display.
1853 * Returns: the default cursor size.
1858 gdk_display_get_default_cursor_size (GdkDisplay *display)
1860 guint width, height;
1862 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1864 GDK_DISPLAY_GET_CLASS (display)->get_default_cursor_size (display,
1868 return MIN (width, height);
1872 * gdk_display_get_maximal_cursor_size:
1873 * @display: a #GdkDisplay
1874 * @width: (out): the return location for the maximal cursor width
1875 * @height: (out): the return location for the maximal cursor height
1877 * Gets the maximal size to use for cursors on @display.
1882 gdk_display_get_maximal_cursor_size (GdkDisplay *display,
1886 g_return_if_fail (GDK_IS_DISPLAY (display));
1888 GDK_DISPLAY_GET_CLASS (display)->get_maximal_cursor_size (display,
1894 * gdk_display_warp_pointer:
1895 * @display: a #GdkDisplay
1896 * @screen: the screen of @display to warp the pointer to
1897 * @x: the x coordinate of the destination
1898 * @y: the y coordinate of the destination
1900 * Warps the pointer of @display to the point @x,@y on
1901 * the screen @screen, unless the pointer is confined
1902 * to a window by a grab, in which case it will be moved
1903 * as far as allowed by the grab. Warping the pointer
1904 * creates events as if the user had moved the mouse
1905 * instantaneously to the destination.
1907 * Note that the pointer should normally be under the
1908 * control of the user. This function was added to cover
1909 * some rare use cases like keyboard navigation support
1910 * for the color picker in the #GtkColorSelectionDialog.
1914 * Deprecated: 3.0: Use gdk_device_warp() instead.
1917 gdk_display_warp_pointer (GdkDisplay *display,
1922 g_return_if_fail (GDK_IS_DISPLAY (display));
1924 gdk_device_warp (display->core_pointer,
1930 _gdk_display_get_next_serial (GdkDisplay *display)
1932 return GDK_DISPLAY_GET_CLASS (display)->get_next_serial (display);
1937 * gdk_notify_startup_complete:
1939 * Indicates to the GUI environment that the application has finished
1940 * loading. If the applications opens windows, this function is
1941 * normally called after opening the application's initial set of
1944 * GTK+ will call this function automatically after opening the first
1945 * #GtkWindow unless gtk_window_set_auto_startup_notification() is called
1946 * to disable that feature.
1951 gdk_notify_startup_complete (void)
1953 gdk_notify_startup_complete_with_id (NULL);
1957 * gdk_notify_startup_complete_with_id:
1958 * @startup_id: a startup-notification identifier, for which
1959 * notification process should be completed
1961 * Indicates to the GUI environment that the application has
1962 * finished loading, using a given identifier.
1964 * GTK+ will call this function automatically for #GtkWindow
1965 * with custom startup-notification identifier unless
1966 * gtk_window_set_auto_startup_notification() is called to
1967 * disable that feature.
1972 gdk_notify_startup_complete_with_id (const gchar* startup_id)
1974 GdkDisplay *display;
1976 display = gdk_display_get_default ();
1978 gdk_display_notify_startup_complete (display, startup_id);
1982 * gdk_display_notify_startup_complete:
1983 * @display: a #GdkDisplay
1984 * @startup_id: a startup-notification identifier, for which
1985 * notification process should be completed
1987 * Indicates to the GUI environment that the application has
1988 * finished loading, using a given identifier.
1990 * GTK+ will call this function automatically for #GtkWindow
1991 * with custom startup-notification identifier unless
1992 * gtk_window_set_auto_startup_notification() is called to
1993 * disable that feature.
1998 gdk_display_notify_startup_complete (GdkDisplay *display,
1999 const gchar *startup_id)
2001 g_return_if_fail (GDK_IS_DISPLAY (display));
2003 GDK_DISPLAY_GET_CLASS (display)->notify_startup_complete (display, startup_id);
2007 _gdk_display_event_data_copy (GdkDisplay *display,
2008 const GdkEvent *event,
2009 GdkEvent *new_event)
2011 GDK_DISPLAY_GET_CLASS (display)->event_data_copy (display, event, new_event);
2015 _gdk_display_event_data_free (GdkDisplay *display,
2018 GDK_DISPLAY_GET_CLASS (display)->event_data_free (display, event);
2022 _gdk_display_create_window_impl (GdkDisplay *display,
2024 GdkWindow *real_parent,
2026 GdkEventMask event_mask,
2027 GdkWindowAttr *attributes,
2028 gint attributes_mask)
2030 GDK_DISPLAY_GET_CLASS (display)->create_window_impl (display,
2040 _gdk_display_create_window (GdkDisplay *display)
2042 return g_object_new (GDK_DISPLAY_GET_CLASS (display)->window_type, NULL);
2046 * gdk_keymap_get_for_display:
2047 * @display: the #GdkDisplay.
2049 * Returns the #GdkKeymap attached to @display.
2051 * Return value: (transfer none): the #GdkKeymap attached to @display.
2056 gdk_keymap_get_for_display (GdkDisplay *display)
2058 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
2060 return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
2063 typedef struct _GdkGlobalErrorTrap GdkGlobalErrorTrap;
2065 struct _GdkGlobalErrorTrap
2070 static GQueue gdk_error_traps = G_QUEUE_INIT;
2073 * gdk_error_trap_push:
2075 * This function allows X errors to be trapped instead of the normal
2076 * behavior of exiting the application. It should only be used if it
2077 * is not possible to avoid the X error in any other way. Errors are
2078 * ignored on all #GdkDisplay currently known to the
2079 * #GdkDisplayManager. If you don't care which error happens and just
2080 * want to ignore everything, pop with gdk_error_trap_pop_ignored().
2081 * If you need the error code, use gdk_error_trap_pop() which may have
2082 * to block and wait for the error to arrive from the X server.
2084 * This API exists on all platforms but only does anything on X.
2086 * You can use gdk_x11_display_error_trap_push() to ignore errors
2087 * on only a single display.
2090 * <title>Trapping an X error</title>
2092 * gdk_error_trap_push (<!-- -->);
2094 * // ... Call the X function which may cause an error here ...
2097 * if (gdk_error_trap_pop (<!-- -->))
2099 * // ... Handle the error here ...
2105 gdk_error_trap_push (void)
2107 GdkDisplayManager *manager;
2108 GdkDisplayClass *class;
2109 GdkGlobalErrorTrap *trap;
2112 manager = gdk_display_manager_get ();
2113 class = GDK_DISPLAY_GET_CLASS (gdk_display_manager_get_default_display (manager));
2115 if (class->push_error_trap == NULL)
2118 trap = g_slice_new (GdkGlobalErrorTrap);
2119 trap->displays = gdk_display_manager_list_displays (manager);
2121 g_slist_foreach (trap->displays, (GFunc) g_object_ref, NULL);
2122 for (l = trap->displays; l != NULL; l = l->next)
2124 class->push_error_trap (l->data);
2127 g_queue_push_head (&gdk_error_traps, trap);
2131 gdk_error_trap_pop_internal (gboolean need_code)
2133 GdkDisplayManager *manager;
2134 GdkDisplayClass *class;
2135 GdkGlobalErrorTrap *trap;
2139 manager = gdk_display_manager_get ();
2140 class = GDK_DISPLAY_GET_CLASS (gdk_display_manager_get_default_display (manager));
2142 if (class->pop_error_trap == NULL)
2145 trap = g_queue_pop_head (&gdk_error_traps);
2147 g_return_val_if_fail (trap != NULL, 0);
2150 for (l = trap->displays; l != NULL; l = l->next)
2154 code = class->pop_error_trap (l->data, !need_code);
2156 /* we use the error on the last display listed, why not. */
2161 g_slist_free_full (trap->displays, g_object_unref);
2162 g_slice_free (GdkGlobalErrorTrap, trap);
2168 * gdk_error_trap_pop_ignored:
2170 * Removes an error trap pushed with gdk_error_trap_push(), but
2171 * without bothering to wait and see whether an error occurred. If an
2172 * error arrives later asynchronously that was triggered while the
2173 * trap was pushed, that error will be ignored.
2178 gdk_error_trap_pop_ignored (void)
2180 gdk_error_trap_pop_internal (FALSE);
2184 * gdk_error_trap_pop:
2186 * Removes an error trap pushed with gdk_error_trap_push().
2187 * May block until an error has been definitively received
2188 * or not received from the X server. gdk_error_trap_pop_ignored()
2189 * is preferred if you don't need to know whether an error
2190 * occurred, because it never has to block. If you don't
2191 * need the return value of gdk_error_trap_pop(), use
2192 * gdk_error_trap_pop_ignored().
2194 * Prior to GDK 3.0, this function would not automatically
2195 * sync for you, so you had to gdk_flush() if your last
2196 * call to Xlib was not a blocking round trip.
2198 * Return value: X error code or 0 on success
2201 gdk_error_trap_pop (void)
2203 return gdk_error_trap_pop_internal (TRUE);