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 if (display->event_pause_count > 0)
313 GDK_DISPLAY_GET_CLASS (display)->queue_events (display);
315 return _gdk_event_unqueue (display);
319 * gdk_display_peek_event:
320 * @display: a #GdkDisplay
322 * Gets a copy of the first #GdkEvent in the @display's event queue, without
323 * removing the event from the queue. (Note that this function will
324 * not get more events from the windowing system. It only checks the events
325 * that have already been moved to the GDK event queue.)
327 * Return value: a copy of the first #GdkEvent on the event queue, or %NULL
328 * if no events are in the queue. The returned #GdkEvent should be freed with
334 gdk_display_peek_event (GdkDisplay *display)
338 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
340 tmp_list = _gdk_event_queue_find_first (display);
343 return gdk_event_copy (tmp_list->data);
349 * gdk_display_put_event:
350 * @display: a #GdkDisplay
351 * @event: a #GdkEvent.
353 * Appends a copy of the given event onto the front of the event
354 * queue for @display.
359 gdk_display_put_event (GdkDisplay *display,
360 const GdkEvent *event)
362 g_return_if_fail (GDK_IS_DISPLAY (display));
363 g_return_if_fail (event != NULL);
365 _gdk_event_queue_append (display, gdk_event_copy (event));
366 /* If the main loop is blocking in a different thread, wake it up */
367 g_main_context_wakeup (NULL);
371 * gdk_display_pointer_ungrab:
372 * @display: a #GdkDisplay.
373 * @time_: a timestap (e.g. %GDK_CURRENT_TIME).
375 * Release any pointer grab.
379 * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
383 gdk_display_pointer_ungrab (GdkDisplay *display,
386 GdkDeviceManager *device_manager;
387 GList *devices, *dev;
390 g_return_if_fail (GDK_IS_DISPLAY (display));
392 device_manager = gdk_display_get_device_manager (display);
393 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
395 /* FIXME: Should this be generic to all backends? */
396 /* FIXME: What happens with extended devices? */
397 for (dev = devices; dev; dev = dev->next)
401 if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
404 gdk_device_ungrab (device, time_);
407 g_list_free (devices);
411 * gdk_display_keyboard_ungrab:
412 * @display: a #GdkDisplay.
413 * @time_: a timestap (e.g #GDK_CURRENT_TIME).
415 * Release any keyboard grab
419 * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
423 gdk_display_keyboard_ungrab (GdkDisplay *display,
426 GdkDeviceManager *device_manager;
427 GList *devices, *dev;
430 g_return_if_fail (GDK_IS_DISPLAY (display));
432 device_manager = gdk_display_get_device_manager (display);
433 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
435 /* FIXME: Should this be generic to all backends? */
436 /* FIXME: What happens with extended devices? */
437 for (dev = devices; dev; dev = dev->next)
441 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
444 gdk_device_ungrab (device, time);
447 g_list_free (devices);
453 * Emits a short beep on the default display.
458 gdk_display_beep (gdk_display_get_default ());
464 * Flushes the output buffers of all display connections and waits
465 * until all requests have been processed.
466 * This is rarely needed by applications.
473 list = gdk_display_manager_list_displays (gdk_display_manager_get ());
474 for (l = list; l; l = l->next)
476 GdkDisplay *display = l->data;
478 GDK_DISPLAY_GET_CLASS (display)->sync (display);
485 _gdk_display_enable_motion_hints (GdkDisplay *display,
488 gulong *device_serial, serial;
490 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
494 device_serial = g_new0 (gulong, 1);
495 *device_serial = G_MAXULONG;
496 g_hash_table_insert (display->motion_hint_info, device, device_serial);
499 if (*device_serial != 0)
501 serial = _gdk_display_get_next_serial (display);
502 /* We might not actually generate the next request, so
503 make sure this triggers always, this may cause it to
504 trigger slightly too early, but this is just a hint
508 if (serial < *device_serial)
509 *device_serial = serial;
514 * gdk_display_get_pointer:
515 * @display: a #GdkDisplay
516 * @screen: (out) (allow-none) (transfer none): location to store the screen that the
517 * cursor is on, or %NULL.
518 * @x: (out) (allow-none): location to store root window X coordinate of pointer, or %NULL.
519 * @y: (out) (allow-none): location to store root window Y coordinate of pointer, or %NULL.
520 * @mask: (out) (allow-none): location to store current modifier mask, or %NULL
522 * Gets the current location of the pointer and the current modifier
523 * mask for a given display.
527 * Deprecated: 3.0: Use gdk_device_get_position() instead.
530 gdk_display_get_pointer (GdkDisplay *display,
534 GdkModifierType *mask)
536 GdkScreen *default_screen;
539 GdkModifierType tmp_mask;
541 g_return_if_fail (GDK_IS_DISPLAY (display));
543 if (gdk_display_is_closed (display))
546 default_screen = gdk_display_get_default_screen (display);
548 /* We call _gdk_device_query_state() here manually instead of
549 * gdk_device_get_position() because we care about the modifier mask */
551 _gdk_device_query_state (display->core_pointer,
552 gdk_screen_get_root_window (default_screen),
559 *screen = gdk_window_get_screen (root);
569 * gdk_display_get_window_at_pointer:
570 * @display: a #GdkDisplay
571 * @win_x: (out) (allow-none): return location for x coordinate of the pointer location relative
572 * to the window origin, or %NULL
573 * @win_y: (out) (allow-none): return location for y coordinate of the pointer location relative
574 & to the window origin, or %NULL
576 * Obtains the window underneath the mouse pointer, returning the location
577 * of the pointer in that window in @win_x, @win_y for @screen. Returns %NULL
578 * if the window under the mouse pointer is not known to GDK (for example,
579 * belongs to another application).
581 * Returns: (transfer none): the window under the mouse pointer, or %NULL
585 * Deprecated: 3.0: Use gdk_device_get_window_at_position() instead.
588 gdk_display_get_window_at_pointer (GdkDisplay *display,
592 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
594 return gdk_device_get_window_at_position (display->core_pointer, win_x, win_y);
598 generate_grab_broken_event (GdkWindow *window,
601 GdkWindow *grab_window)
603 g_return_if_fail (window != NULL);
605 if (!GDK_WINDOW_DESTROYED (window))
609 event = gdk_event_new (GDK_GRAB_BROKEN);
610 event->grab_broken.window = g_object_ref (window);
611 event->grab_broken.send_event = FALSE;
612 event->grab_broken.implicit = implicit;
613 event->grab_broken.grab_window = grab_window;
614 gdk_event_set_device (event, device);
615 event->grab_broken.keyboard = (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) ? TRUE : FALSE;
617 gdk_event_put (event);
618 gdk_event_free (event);
623 _gdk_display_get_last_device_grab (GdkDisplay *display,
628 l = g_hash_table_lookup (display->device_grabs, device);
640 _gdk_display_add_device_grab (GdkDisplay *display,
643 GdkWindow *native_window,
644 GdkGrabOwnership grab_ownership,
645 gboolean owner_events,
646 GdkEventMask event_mask,
647 unsigned long serial_start,
651 GdkDeviceGrabInfo *info, *other_info;
654 info = g_new0 (GdkDeviceGrabInfo, 1);
656 info->window = g_object_ref (window);
657 info->native_window = g_object_ref (native_window);
658 info->serial_start = serial_start;
659 info->serial_end = G_MAXULONG;
660 info->owner_events = owner_events;
661 info->event_mask = event_mask;
663 info->implicit = implicit;
664 info->ownership = grab_ownership;
666 grabs = g_hash_table_lookup (display->device_grabs, device);
668 /* Find the first grab that has a larger start time (if any) and insert
669 * before that. I.E we insert after already existing grabs with same
671 for (l = grabs; l != NULL; l = l->next)
673 other_info = l->data;
675 if (info->serial_start < other_info->serial_start)
679 grabs = g_list_insert_before (grabs, l, info);
681 /* Make sure the new grab end before next grab */
684 other_info = l->data;
685 info->serial_end = other_info->serial_start;
688 /* Find any previous grab and update its end time */
689 l = g_list_find (grabs, info);
693 other_info = l->data;
694 other_info->serial_end = serial_start;
697 g_hash_table_insert (display->device_grabs, device, grabs);
703 _gdk_display_break_touch_grabs (GdkDisplay *display,
705 GdkWindow *new_grab_window)
709 for (i = 0; i < display->touch_implicit_grabs->len; i++)
711 GdkTouchGrabInfo *info;
713 info = &g_array_index (display->touch_implicit_grabs,
714 GdkTouchGrabInfo, i);
716 if (info->device == device && info->window != new_grab_window)
717 generate_grab_broken_event (GDK_WINDOW (info->window),
718 device, TRUE, new_grab_window);
723 _gdk_display_add_touch_grab (GdkDisplay *display,
725 GdkEventSequence *sequence,
727 GdkWindow *native_window,
728 GdkEventMask event_mask,
729 unsigned long serial,
732 GdkTouchGrabInfo info;
734 info.device = device;
735 info.sequence = sequence;
736 info.window = g_object_ref (window);
737 info.native_window = g_object_ref (native_window);
738 info.serial = serial;
739 info.event_mask = event_mask;
742 g_array_append_val (display->touch_implicit_grabs, info);
746 _gdk_display_end_touch_grab (GdkDisplay *display,
748 GdkEventSequence *sequence)
752 for (i = 0; i < display->touch_implicit_grabs->len; i++)
754 GdkTouchGrabInfo *info;
756 info = &g_array_index (display->touch_implicit_grabs,
757 GdkTouchGrabInfo, i);
759 if (info->device == device && info->sequence == sequence)
761 g_array_remove_index_fast (display->touch_implicit_grabs, i);
769 /* _gdk_synthesize_crossing_events only works inside one toplevel.
770 This function splits things into two calls if needed, converting the
771 coordinates to the right toplevel */
773 synthesize_crossing_events (GdkDisplay *display,
775 GdkDevice *source_device,
776 GdkWindow *src_window,
777 GdkWindow *dest_window,
778 GdkCrossingMode crossing_mode,
782 GdkWindow *src_toplevel, *dest_toplevel;
783 GdkModifierType state;
787 src_toplevel = gdk_window_get_toplevel (src_window);
791 dest_toplevel = gdk_window_get_toplevel (dest_window);
793 dest_toplevel = NULL;
795 if (src_toplevel == NULL && dest_toplevel == NULL)
798 if (src_toplevel == NULL ||
799 src_toplevel == dest_toplevel)
802 gdk_window_get_device_position (dest_toplevel,
805 _gdk_synthesize_crossing_events (display,
808 device, source_device,
815 else if (dest_toplevel == NULL)
817 gdk_window_get_device_position (src_toplevel,
820 _gdk_synthesize_crossing_events (display,
823 device, source_device,
832 /* Different toplevels */
833 gdk_window_get_device_position (src_toplevel,
836 _gdk_synthesize_crossing_events (display,
839 device, source_device,
845 gdk_window_get_device_position (dest_toplevel,
848 _gdk_synthesize_crossing_events (display,
851 device, source_device,
861 get_current_toplevel (GdkDisplay *display,
865 GdkModifierType *state_out)
867 GdkWindow *pointer_window;
869 GdkModifierType state;
871 pointer_window = _gdk_device_window_at_position (device, &x, &y, &state, TRUE);
873 if (pointer_window != NULL &&
874 (GDK_WINDOW_DESTROYED (pointer_window) ||
875 GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT ||
876 GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN))
877 pointer_window = NULL;
883 return pointer_window;
887 switch_to_pointer_grab (GdkDisplay *display,
889 GdkDevice *source_device,
890 GdkDeviceGrabInfo *grab,
891 GdkDeviceGrabInfo *last_grab,
895 GdkWindow *src_window, *pointer_window, *new_toplevel;
896 GdkPointerWindowInfo *info;
898 GdkModifierType state;
901 /* Temporarily unset pointer to make sure we send the crossing events below */
902 old_grabs = g_hash_table_lookup (display->device_grabs, device);
903 g_hash_table_steal (display->device_grabs, device);
904 info = _gdk_display_get_pointer_info (display, device);
908 /* New grab is in effect */
910 /* We need to generate crossing events for the grab.
911 * However, there are never any crossing events for implicit grabs
912 * TODO: ... Actually, this could happen if the pointer window
913 * doesn't have button mask so a parent gets the event...
917 /* We send GRAB crossing events from the window under the pointer to the
918 grab window. Except if there is an old grab then we start from that */
920 src_window = last_grab->window;
922 src_window = info->window_under_pointer;
924 if (src_window != grab->window)
925 synthesize_crossing_events (display, device, source_device,
926 src_window, grab->window,
927 GDK_CROSSING_GRAB, time, serial);
929 /* !owner_event Grabbing a window that we're not inside, current status is
930 now NULL (i.e. outside grabbed window) */
931 if (!grab->owner_events && info->window_under_pointer != grab->window)
932 _gdk_display_set_window_under_pointer (display, device, NULL);
935 grab->activated = TRUE;
942 if (grab == NULL /* ungrab */ ||
943 (!last_grab->owner_events && grab->owner_events) /* switched to owner_events */ )
945 /* We force check what window we're in, and update the toplevel_under_pointer info,
946 * as that won't get told of this change with toplevel enter events.
948 if (info->toplevel_under_pointer)
949 g_object_unref (info->toplevel_under_pointer);
950 info->toplevel_under_pointer = NULL;
952 /* Ungrabbed slave devices don't have a position by
953 * itself, rather depend on its master pointer, so
954 * it doesn't make sense to track any position for
955 * these after the grab
957 if (grab || gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE)
958 new_toplevel = get_current_toplevel (display, device, &x, &y, &state);
962 /* w is now toplevel and x,y in toplevel coords */
963 info->toplevel_under_pointer = g_object_ref (new_toplevel);
964 info->toplevel_x = x;
965 info->toplevel_y = y;
970 if (grab == NULL) /* Ungrabbed, send events */
972 /* If the source device is a touch device, do not
973 * propagate any enter event yet, until one is
974 * synthesized when needed.
977 (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN))
978 info->need_touch_press_enter = TRUE;
980 pointer_window = NULL;
983 !info->need_touch_press_enter)
985 /* Find (possibly virtual) child window */
987 _gdk_window_find_descendant_at (new_toplevel,
992 if (!info->need_touch_press_enter &&
993 pointer_window != last_grab->window)
994 synthesize_crossing_events (display, device, source_device,
995 last_grab->window, pointer_window,
996 GDK_CROSSING_UNGRAB, time, serial);
998 /* We're now ungrabbed, update the window_under_pointer */
999 _gdk_display_set_window_under_pointer (display, device, pointer_window);
1003 g_hash_table_insert (display->device_grabs, device, old_grabs);
1007 _gdk_display_device_grab_update (GdkDisplay *display,
1009 GdkDevice *source_device,
1010 gulong current_serial)
1012 GdkDeviceGrabInfo *current_grab, *next_grab;
1016 time = display->last_event_time;
1017 grabs = g_hash_table_lookup (display->device_grabs, device);
1019 while (grabs != NULL)
1021 current_grab = grabs->data;
1023 if (current_grab->serial_start > current_serial)
1024 return; /* Hasn't started yet */
1026 if (current_grab->serial_end > current_serial)
1028 /* This one hasn't ended yet.
1029 its the currently active one or scheduled to be active */
1031 if (!current_grab->activated)
1033 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
1034 switch_to_pointer_grab (display, device, source_device, current_grab, NULL, time, current_serial);
1043 /* This is the next active grab */
1044 next_grab = grabs->next->data;
1046 if (next_grab->serial_start > current_serial)
1047 next_grab = NULL; /* Actually its not yet active */
1051 _gdk_display_break_touch_grabs (display, device, next_grab->window);
1053 if ((next_grab == NULL && current_grab->implicit_ungrab) ||
1054 (next_grab != NULL && current_grab->window != next_grab->window))
1055 generate_grab_broken_event (GDK_WINDOW (current_grab->window),
1057 current_grab->implicit,
1058 next_grab? next_grab->window : NULL);
1060 /* Remove old grab */
1061 grabs = g_list_delete_link (grabs, grabs);
1062 g_hash_table_insert (display->device_grabs, device, grabs);
1064 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
1065 switch_to_pointer_grab (display, device, source_device,
1066 next_grab, current_grab,
1067 time, current_serial);
1069 free_device_grab (current_grab);
1074 grab_list_find (GList *grabs,
1077 GdkDeviceGrabInfo *grab;
1083 if (serial >= grab->serial_start && serial < grab->serial_end)
1086 grabs = grabs->next;
1093 find_device_grab (GdkDisplay *display,
1099 l = g_hash_table_lookup (display->device_grabs, device);
1100 return grab_list_find (l, serial);
1104 _gdk_display_has_device_grab (GdkDisplay *display,
1110 l = find_device_grab (display, device, serial);
1118 _gdk_display_has_touch_grab (GdkDisplay *display,
1120 GdkEventSequence *sequence,
1125 for (i = 0; i < display->touch_implicit_grabs->len; i++)
1127 GdkTouchGrabInfo *info;
1129 info = &g_array_index (display->touch_implicit_grabs,
1130 GdkTouchGrabInfo, i);
1132 if (info->device == device && info->sequence == sequence)
1134 if (serial >= info->serial)
1144 /* Returns true if last grab was ended
1145 * If if_child is non-NULL, end the grab only if the grabbed
1146 * window is the same as if_child or a descendant of it */
1148 _gdk_display_end_device_grab (GdkDisplay *display,
1151 GdkWindow *if_child,
1154 GdkDeviceGrabInfo *grab;
1157 l = find_device_grab (display, device, serial);
1164 (if_child == NULL ||
1165 _gdk_window_event_parent_of (if_child, grab->window)))
1167 grab->serial_end = serial;
1168 grab->implicit_ungrab = implicit;
1169 return l->next == NULL;
1175 /* Returns TRUE if device events are not blocked by any grab */
1177 _gdk_display_check_grab_ownership (GdkDisplay *display,
1181 GHashTableIter iter;
1182 gpointer key, value;
1183 GdkGrabOwnership higher_ownership, device_ownership;
1184 gboolean device_is_keyboard;
1186 g_hash_table_iter_init (&iter, display->device_grabs);
1187 higher_ownership = device_ownership = GDK_OWNERSHIP_NONE;
1188 device_is_keyboard = (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD);
1190 while (g_hash_table_iter_next (&iter, &key, &value))
1192 GdkDeviceGrabInfo *grab;
1198 grabs = grab_list_find (grabs, serial);
1203 /* Discard device if it's not of the same type */
1204 if ((device_is_keyboard && gdk_device_get_source (dev) != GDK_SOURCE_KEYBOARD) ||
1205 (!device_is_keyboard && gdk_device_get_source (dev) == GDK_SOURCE_KEYBOARD))
1211 device_ownership = grab->ownership;
1214 if (grab->ownership > higher_ownership)
1215 higher_ownership = grab->ownership;
1219 if (higher_ownership > device_ownership)
1221 /* There's a higher priority ownership
1222 * going on for other device(s)
1230 GdkPointerWindowInfo *
1231 _gdk_display_get_pointer_info (GdkDisplay *display,
1234 GdkPointerWindowInfo *info;
1236 if (device && gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
1237 device = gdk_device_get_associated_device (device);
1239 if (G_UNLIKELY (!device))
1242 info = g_hash_table_lookup (display->pointers_info, device);
1244 if (G_UNLIKELY (!info))
1246 info = g_slice_new0 (GdkPointerWindowInfo);
1247 g_hash_table_insert (display->pointers_info, device, info);
1254 _gdk_display_pointer_info_foreach (GdkDisplay *display,
1255 GdkDisplayPointerInfoForeach func,
1258 GHashTableIter iter;
1259 gpointer key, value;
1261 g_hash_table_iter_init (&iter, display->pointers_info);
1263 while (g_hash_table_iter_next (&iter, &key, &value))
1265 GdkPointerWindowInfo *info = value;
1266 GdkDevice *device = key;
1268 (func) (display, device, info, user_data);
1273 * gdk_device_grab_info_libgtk_only:
1274 * @display: the display for which to get the grab information
1275 * @device: device to get the grab information from
1276 * @grab_window: (out) (transfer none): location to store current grab window
1277 * @owner_events: (out): location to store boolean indicating whether
1278 * the @owner_events flag to gdk_keyboard_grab() or
1279 * gdk_pointer_grab() was %TRUE.
1281 * Determines information about the current keyboard grab.
1282 * This is not public API and must not be used by applications.
1284 * Return value: %TRUE if this application currently has the
1288 gdk_device_grab_info_libgtk_only (GdkDisplay *display,
1290 GdkWindow **grab_window,
1291 gboolean *owner_events)
1293 GdkDeviceGrabInfo *info;
1295 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1296 g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
1298 info = _gdk_display_get_last_device_grab (display, device);
1303 *grab_window = info->window;
1305 *owner_events = info->owner_events;
1314 * gdk_display_pointer_is_grabbed:
1315 * @display: a #GdkDisplay
1317 * Test if the pointer is grabbed.
1319 * Returns: %TRUE if an active X pointer grab is in effect
1323 * Deprecated: 3.0: Use gdk_display_device_is_grabbed() instead.
1326 gdk_display_pointer_is_grabbed (GdkDisplay *display)
1328 GdkDeviceManager *device_manager;
1329 GList *devices, *dev;
1332 g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
1334 device_manager = gdk_display_get_device_manager (display);
1335 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
1337 for (dev = devices; dev; dev = dev->next)
1341 if (gdk_device_get_source (device) == GDK_SOURCE_MOUSE &&
1342 gdk_display_device_is_grabbed (display, device))
1344 g_list_free (devices);
1349 g_list_free (devices);
1355 * gdk_display_device_is_grabbed:
1356 * @display: a #GdkDisplay
1357 * @device: a #GdkDevice
1359 * Returns %TRUE if there is an ongoing grab on @device for @display.
1361 * Returns: %TRUE if there is a grab in effect for @device.
1364 gdk_display_device_is_grabbed (GdkDisplay *display,
1367 GdkDeviceGrabInfo *info;
1369 g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
1370 g_return_val_if_fail (GDK_IS_DEVICE (device), TRUE);
1372 /* What we're interested in is the steady state (ie last grab),
1373 because we're interested e.g. if we grabbed so that we
1374 can ungrab, even if our grab is not active just yet. */
1375 info = _gdk_display_get_last_device_grab (display, device);
1377 return (info && !info->implicit);
1381 * gdk_display_get_device_manager:
1382 * @display: a #GdkDisplay.
1384 * Returns the #GdkDeviceManager associated to @display.
1386 * Returns: (transfer none): A #GdkDeviceManager, or %NULL. This memory is
1387 * owned by GDK and must not be freed or unreferenced.
1392 gdk_display_get_device_manager (GdkDisplay *display)
1394 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1396 return display->device_manager;
1400 * gdk_display_get_name:
1401 * @display: a #GdkDisplay
1403 * Gets the name of the display.
1405 * Returns: a string representing the display name. This string is owned
1406 * by GDK and should not be modified or freed.
1411 gdk_display_get_name (GdkDisplay *display)
1413 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1415 return GDK_DISPLAY_GET_CLASS (display)->get_name (display);
1419 gdk_get_display (void)
1421 return g_strdup (gdk_display_get_name (gdk_display_get_default ()));
1425 * gdk_display_get_n_screens:
1426 * @display: a #GdkDisplay
1428 * Gets the number of screen managed by the @display.
1430 * Returns: number of screens.
1435 gdk_display_get_n_screens (GdkDisplay *display)
1437 g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
1439 return GDK_DISPLAY_GET_CLASS (display)->get_n_screens (display);
1443 * gdk_display_get_screen:
1444 * @display: a #GdkDisplay
1445 * @screen_num: the screen number
1447 * Returns a screen object for one of the screens of the display.
1449 * Returns: (transfer none): the #GdkScreen object
1454 gdk_display_get_screen (GdkDisplay *display,
1457 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1459 return GDK_DISPLAY_GET_CLASS (display)->get_screen (display, screen_num);
1463 * gdk_display_get_default_screen:
1464 * @display: a #GdkDisplay
1466 * Get the default #GdkScreen for @display.
1468 * Returns: (transfer none): the default #GdkScreen object for @display
1473 gdk_display_get_default_screen (GdkDisplay *display)
1475 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1477 return GDK_DISPLAY_GET_CLASS (display)->get_default_screen (display);
1482 * @display: a #GdkDisplay
1484 * Emits a short beep on @display
1489 gdk_display_beep (GdkDisplay *display)
1491 g_return_if_fail (GDK_IS_DISPLAY (display));
1493 GDK_DISPLAY_GET_CLASS (display)->beep (display);
1498 * @display: a #GdkDisplay
1500 * Flushes any requests queued for the windowing system and waits until all
1501 * requests have been handled. This is often used for making sure that the
1502 * display is synchronized with the current state of the program. Calling
1503 * gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors
1504 * generated from earlier requests are handled before the error trap is
1507 * This is most useful for X11. On windowing systems where requests are
1508 * handled synchronously, this function will do nothing.
1513 gdk_display_sync (GdkDisplay *display)
1515 g_return_if_fail (GDK_IS_DISPLAY (display));
1517 GDK_DISPLAY_GET_CLASS (display)->sync (display);
1521 * gdk_display_flush:
1522 * @display: a #GdkDisplay
1524 * Flushes any requests queued for the windowing system; this happens automatically
1525 * when the main loop blocks waiting for new events, but if your application
1526 * is drawing without returning control to the main loop, you may need
1527 * to call this function explicitely. A common case where this function
1528 * needs to be called is when an application is executing drawing commands
1529 * from a thread other than the thread where the main loop is running.
1531 * This is most useful for X11. On windowing systems where requests are
1532 * handled synchronously, this function will do nothing.
1537 gdk_display_flush (GdkDisplay *display)
1539 g_return_if_fail (GDK_IS_DISPLAY (display));
1541 GDK_DISPLAY_GET_CLASS (display)->flush (display);
1545 * gdk_display_get_default_group:
1546 * @display: a #GdkDisplay
1548 * Returns the default group leader window for all toplevel windows
1549 * on @display. This window is implicitly created by GDK.
1550 * See gdk_window_set_group().
1552 * Return value: (transfer none): The default group leader window
1558 gdk_display_get_default_group (GdkDisplay *display)
1560 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1562 return GDK_DISPLAY_GET_CLASS (display)->get_default_group (display);
1566 * gdk_display_supports_selection_notification:
1567 * @display: a #GdkDisplay
1569 * Returns whether #GdkEventOwnerChange events will be
1570 * sent when the owner of a selection changes.
1572 * Return value: whether #GdkEventOwnerChange events will
1578 gdk_display_supports_selection_notification (GdkDisplay *display)
1580 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1582 return GDK_DISPLAY_GET_CLASS (display)->supports_selection_notification (display);
1586 * gdk_display_request_selection_notification:
1587 * @display: a #GdkDisplay
1588 * @selection: the #GdkAtom naming the selection for which
1589 * ownership change notification is requested
1591 * Request #GdkEventOwnerChange events for ownership changes
1592 * of the selection named by the given atom.
1594 * Return value: whether #GdkEventOwnerChange events will
1600 gdk_display_request_selection_notification (GdkDisplay *display,
1604 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1606 return GDK_DISPLAY_GET_CLASS (display)->request_selection_notification (display, selection);
1610 * gdk_display_supports_clipboard_persistence:
1611 * @display: a #GdkDisplay
1613 * Returns whether the speicifed display supports clipboard
1614 * persistance; i.e. if it's possible to store the clipboard data after an
1615 * application has quit. On X11 this checks if a clipboard daemon is
1618 * Returns: %TRUE if the display supports clipboard persistance.
1623 gdk_display_supports_clipboard_persistence (GdkDisplay *display)
1625 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1627 return GDK_DISPLAY_GET_CLASS (display)->supports_clipboard_persistence (display);
1631 * gdk_display_store_clipboard:
1632 * @display: a #GdkDisplay
1633 * @clipboard_window: a #GdkWindow belonging to the clipboard owner
1634 * @time_: a timestamp
1635 * @targets: (array length=n_targets): an array of targets
1636 * that should be saved, or %NULL
1637 * if all available targets should be saved.
1638 * @n_targets: length of the @targets array
1640 * Issues a request to the clipboard manager to store the
1641 * clipboard data. On X11, this is a special program that works
1642 * according to the freedesktop clipboard specification, available at
1643 * <ulink url="http://www.freedesktop.org/Standards/clipboard-manager-spec">
1644 * http://www.freedesktop.org/Standards/clipboard-manager-spec</ulink>.
1649 gdk_display_store_clipboard (GdkDisplay *display,
1650 GdkWindow *clipboard_window,
1652 const GdkAtom *targets,
1655 g_return_if_fail (GDK_IS_DISPLAY (display));
1657 GDK_DISPLAY_GET_CLASS (display)->store_clipboard (display, clipboard_window, time_, targets, n_targets);
1661 * gdk_display_supports_shapes:
1662 * @display: a #GdkDisplay
1664 * Returns %TRUE if gdk_window_shape_combine_mask() can
1665 * be used to create shaped windows on @display.
1667 * Returns: %TRUE if shaped windows are supported
1672 gdk_display_supports_shapes (GdkDisplay *display)
1674 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1676 return GDK_DISPLAY_GET_CLASS (display)->supports_shapes (display);
1680 * gdk_display_supports_input_shapes:
1681 * @display: a #GdkDisplay
1683 * Returns %TRUE if gdk_window_input_shape_combine_mask() can
1684 * be used to modify the input shape of windows on @display.
1686 * Returns: %TRUE if windows with modified input shape are supported
1691 gdk_display_supports_input_shapes (GdkDisplay *display)
1693 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1695 return GDK_DISPLAY_GET_CLASS (display)->supports_input_shapes (display);
1699 * gdk_display_supports_composite:
1700 * @display: a #GdkDisplay
1702 * Returns %TRUE if gdk_window_set_composited() can be used
1703 * to redirect drawing on the window using compositing.
1705 * Currently this only works on X11 with XComposite and
1706 * XDamage extensions available.
1708 * Returns: %TRUE if windows may be composited.
1713 gdk_display_supports_composite (GdkDisplay *display)
1715 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1717 return GDK_DISPLAY_GET_CLASS (display)->supports_composite (display);
1721 * gdk_display_list_devices:
1722 * @display: a #GdkDisplay
1724 * Returns the list of available input devices attached to @display.
1725 * The list is statically allocated and should not be freed.
1727 * Return value: (transfer none) (element-type GdkDevice):
1728 * a list of #GdkDevice
1732 * Deprecated: 3.0: Use gdk_device_manager_list_devices() instead.
1735 gdk_display_list_devices (GdkDisplay *display)
1737 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1739 return GDK_DISPLAY_GET_CLASS (display)->list_devices (display);
1742 static GdkAppLaunchContext *
1743 gdk_display_real_get_app_launch_context (GdkDisplay *display)
1745 GdkAppLaunchContext *ctx;
1747 ctx = g_object_new (GDK_TYPE_APP_LAUNCH_CONTEXT,
1755 * gdk_display_get_app_launch_context:
1756 * @display: a #GdkDisplay
1758 * Returns a #GdkAppLaunchContext suitable for launching
1759 * applications on the given display.
1761 * Returns: (transfer full): a new #GdkAppLaunchContext for @display.
1762 * Free with g_object_unref() when done
1766 GdkAppLaunchContext *
1767 gdk_display_get_app_launch_context (GdkDisplay *display)
1769 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1771 return GDK_DISPLAY_GET_CLASS (display)->get_app_launch_context (display);
1776 * @display_name: the name of the display to open
1780 * Return value: (transfer none): a #GdkDisplay, or %NULL
1781 * if the display could not be opened
1786 gdk_display_open (const gchar *display_name)
1788 return gdk_display_manager_open_display (gdk_display_manager_get (),
1793 * gdk_display_has_pending:
1794 * @display: a #GdkDisplay
1796 * Returns whether the display has events that are waiting
1799 * Returns: %TRUE if there are events ready to be processed.
1804 gdk_display_has_pending (GdkDisplay *display)
1806 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1808 return GDK_DISPLAY_GET_CLASS (display)->has_pending (display);
1812 * gdk_display_supports_cursor_alpha:
1813 * @display: a #GdkDisplay
1815 * Returns %TRUE if cursors can use an 8bit alpha channel
1816 * on @display. Otherwise, cursors are restricted to bilevel
1817 * alpha (i.e. a mask).
1819 * Returns: whether cursors can have alpha channels.
1824 gdk_display_supports_cursor_alpha (GdkDisplay *display)
1826 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1828 return GDK_DISPLAY_GET_CLASS (display)->supports_cursor_alpha (display);
1832 * gdk_display_supports_cursor_color:
1833 * @display: a #GdkDisplay
1835 * Returns %TRUE if multicolored cursors are supported
1836 * on @display. Otherwise, cursors have only a forground
1837 * and a background color.
1839 * Returns: whether cursors can have multiple colors.
1844 gdk_display_supports_cursor_color (GdkDisplay *display)
1846 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1848 return GDK_DISPLAY_GET_CLASS (display)->supports_cursor_color (display);
1852 * gdk_display_get_default_cursor_size:
1853 * @display: a #GdkDisplay
1855 * Returns the default size to use for cursors on @display.
1857 * Returns: the default cursor size.
1862 gdk_display_get_default_cursor_size (GdkDisplay *display)
1864 guint width, height;
1866 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1868 GDK_DISPLAY_GET_CLASS (display)->get_default_cursor_size (display,
1872 return MIN (width, height);
1876 * gdk_display_get_maximal_cursor_size:
1877 * @display: a #GdkDisplay
1878 * @width: (out): the return location for the maximal cursor width
1879 * @height: (out): the return location for the maximal cursor height
1881 * Gets the maximal size to use for cursors on @display.
1886 gdk_display_get_maximal_cursor_size (GdkDisplay *display,
1890 g_return_if_fail (GDK_IS_DISPLAY (display));
1892 GDK_DISPLAY_GET_CLASS (display)->get_maximal_cursor_size (display,
1898 * gdk_display_warp_pointer:
1899 * @display: a #GdkDisplay
1900 * @screen: the screen of @display to warp the pointer to
1901 * @x: the x coordinate of the destination
1902 * @y: the y coordinate of the destination
1904 * Warps the pointer of @display to the point @x,@y on
1905 * the screen @screen, unless the pointer is confined
1906 * to a window by a grab, in which case it will be moved
1907 * as far as allowed by the grab. Warping the pointer
1908 * creates events as if the user had moved the mouse
1909 * instantaneously to the destination.
1911 * Note that the pointer should normally be under the
1912 * control of the user. This function was added to cover
1913 * some rare use cases like keyboard navigation support
1914 * for the color picker in the #GtkColorSelectionDialog.
1918 * Deprecated: 3.0: Use gdk_device_warp() instead.
1921 gdk_display_warp_pointer (GdkDisplay *display,
1926 g_return_if_fail (GDK_IS_DISPLAY (display));
1928 gdk_device_warp (display->core_pointer,
1934 _gdk_display_get_next_serial (GdkDisplay *display)
1936 return GDK_DISPLAY_GET_CLASS (display)->get_next_serial (display);
1941 * gdk_notify_startup_complete:
1943 * Indicates to the GUI environment that the application has finished
1944 * loading. If the applications opens windows, this function is
1945 * normally called after opening the application's initial set of
1948 * GTK+ will call this function automatically after opening the first
1949 * #GtkWindow unless gtk_window_set_auto_startup_notification() is called
1950 * to disable that feature.
1955 gdk_notify_startup_complete (void)
1957 gdk_notify_startup_complete_with_id (NULL);
1961 * gdk_notify_startup_complete_with_id:
1962 * @startup_id: a startup-notification identifier, for which
1963 * notification process should be completed
1965 * Indicates to the GUI environment that the application has
1966 * finished loading, using a given identifier.
1968 * GTK+ will call this function automatically for #GtkWindow
1969 * with custom startup-notification identifier unless
1970 * gtk_window_set_auto_startup_notification() is called to
1971 * disable that feature.
1976 gdk_notify_startup_complete_with_id (const gchar* startup_id)
1978 GdkDisplay *display;
1980 display = gdk_display_get_default ();
1982 gdk_display_notify_startup_complete (display, startup_id);
1986 * gdk_display_notify_startup_complete:
1987 * @display: a #GdkDisplay
1988 * @startup_id: a startup-notification identifier, for which
1989 * notification process should be completed
1991 * Indicates to the GUI environment that the application has
1992 * finished loading, using a given identifier.
1994 * GTK+ will call this function automatically for #GtkWindow
1995 * with custom startup-notification identifier unless
1996 * gtk_window_set_auto_startup_notification() is called to
1997 * disable that feature.
2002 gdk_display_notify_startup_complete (GdkDisplay *display,
2003 const gchar *startup_id)
2005 g_return_if_fail (GDK_IS_DISPLAY (display));
2007 GDK_DISPLAY_GET_CLASS (display)->notify_startup_complete (display, startup_id);
2011 _gdk_display_pause_events (GdkDisplay *display)
2013 display->event_pause_count++;
2017 _gdk_display_unpause_events (GdkDisplay *display)
2019 g_return_if_fail (display->event_pause_count > 0);
2021 display->event_pause_count--;
2025 _gdk_display_flush_events (GdkDisplay *display)
2027 display->flushing_events = TRUE;
2031 GdkEvent *event = _gdk_event_unqueue (display);
2035 _gdk_event_emit (event);
2036 gdk_event_free (event);
2039 display->flushing_events = FALSE;
2043 _gdk_display_event_data_copy (GdkDisplay *display,
2044 const GdkEvent *event,
2045 GdkEvent *new_event)
2047 GDK_DISPLAY_GET_CLASS (display)->event_data_copy (display, event, new_event);
2051 _gdk_display_event_data_free (GdkDisplay *display,
2054 GDK_DISPLAY_GET_CLASS (display)->event_data_free (display, event);
2058 _gdk_display_create_window_impl (GdkDisplay *display,
2060 GdkWindow *real_parent,
2062 GdkEventMask event_mask,
2063 GdkWindowAttr *attributes,
2064 gint attributes_mask)
2066 GDK_DISPLAY_GET_CLASS (display)->create_window_impl (display,
2076 _gdk_display_create_window (GdkDisplay *display)
2078 return g_object_new (GDK_DISPLAY_GET_CLASS (display)->window_type, NULL);
2082 * gdk_keymap_get_for_display:
2083 * @display: the #GdkDisplay.
2085 * Returns the #GdkKeymap attached to @display.
2087 * Return value: (transfer none): the #GdkKeymap attached to @display.
2092 gdk_keymap_get_for_display (GdkDisplay *display)
2094 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
2096 return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
2099 typedef struct _GdkGlobalErrorTrap GdkGlobalErrorTrap;
2101 struct _GdkGlobalErrorTrap
2106 static GQueue gdk_error_traps = G_QUEUE_INIT;
2109 * gdk_error_trap_push:
2111 * This function allows X errors to be trapped instead of the normal
2112 * behavior of exiting the application. It should only be used if it
2113 * is not possible to avoid the X error in any other way. Errors are
2114 * ignored on all #GdkDisplay currently known to the
2115 * #GdkDisplayManager. If you don't care which error happens and just
2116 * want to ignore everything, pop with gdk_error_trap_pop_ignored().
2117 * If you need the error code, use gdk_error_trap_pop() which may have
2118 * to block and wait for the error to arrive from the X server.
2120 * This API exists on all platforms but only does anything on X.
2122 * You can use gdk_x11_display_error_trap_push() to ignore errors
2123 * on only a single display.
2126 * <title>Trapping an X error</title>
2128 * gdk_error_trap_push (<!-- -->);
2130 * // ... Call the X function which may cause an error here ...
2133 * if (gdk_error_trap_pop (<!-- -->))
2135 * // ... Handle the error here ...
2141 gdk_error_trap_push (void)
2143 GdkDisplayManager *manager;
2144 GdkDisplayClass *class;
2145 GdkGlobalErrorTrap *trap;
2148 manager = gdk_display_manager_get ();
2149 class = GDK_DISPLAY_GET_CLASS (gdk_display_manager_get_default_display (manager));
2151 if (class->push_error_trap == NULL)
2154 trap = g_slice_new (GdkGlobalErrorTrap);
2155 trap->displays = gdk_display_manager_list_displays (manager);
2157 g_slist_foreach (trap->displays, (GFunc) g_object_ref, NULL);
2158 for (l = trap->displays; l != NULL; l = l->next)
2160 class->push_error_trap (l->data);
2163 g_queue_push_head (&gdk_error_traps, trap);
2167 gdk_error_trap_pop_internal (gboolean need_code)
2169 GdkDisplayManager *manager;
2170 GdkDisplayClass *class;
2171 GdkGlobalErrorTrap *trap;
2175 manager = gdk_display_manager_get ();
2176 class = GDK_DISPLAY_GET_CLASS (gdk_display_manager_get_default_display (manager));
2178 if (class->pop_error_trap == NULL)
2181 trap = g_queue_pop_head (&gdk_error_traps);
2183 g_return_val_if_fail (trap != NULL, 0);
2186 for (l = trap->displays; l != NULL; l = l->next)
2190 code = class->pop_error_trap (l->data, !need_code);
2192 /* we use the error on the last display listed, why not. */
2197 g_slist_free_full (trap->displays, g_object_unref);
2198 g_slice_free (GdkGlobalErrorTrap, trap);
2204 * gdk_error_trap_pop_ignored:
2206 * Removes an error trap pushed with gdk_error_trap_push(), but
2207 * without bothering to wait and see whether an error occurred. If an
2208 * error arrives later asynchronously that was triggered while the
2209 * trap was pushed, that error will be ignored.
2214 gdk_error_trap_pop_ignored (void)
2216 gdk_error_trap_pop_internal (FALSE);
2220 * gdk_error_trap_pop:
2222 * Removes an error trap pushed with gdk_error_trap_push().
2223 * May block until an error has been definitively received
2224 * or not received from the X server. gdk_error_trap_pop_ignored()
2225 * is preferred if you don't need to know whether an error
2226 * occurred, because it never has to block. If you don't
2227 * need the return value of gdk_error_trap_pop(), use
2228 * gdk_error_trap_pop_ignored().
2230 * Prior to GDK 3.0, this function would not automatically
2231 * sync for you, so you had to gdk_flush() if your last
2232 * call to Xlib was not a blocking round trip.
2234 * Return value: X error code or 0 on success
2237 gdk_error_trap_pop (void)
2239 return gdk_error_trap_pop_internal (TRUE);