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, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
27 #include "gdk.h" /* gdk_event_send_client_message() */
28 #include "gdkdisplay.h"
29 #include "gdkwindowimpl.h"
30 #include "gdkinternals.h"
31 #include "gdkmarshalers.h"
32 #include "gdkscreen.h"
40 static void gdk_display_dispose (GObject *object);
41 static void gdk_display_finalize (GObject *object);
44 static void singlehead_get_pointer (GdkDisplay *display,
48 GdkModifierType *mask);
49 static GdkWindow* singlehead_window_get_pointer (GdkDisplay *display,
53 GdkModifierType *mask);
54 static GdkWindow* singlehead_window_at_pointer (GdkDisplay *display,
58 static GdkWindow* singlehead_default_window_get_pointer (GdkWindow *window,
61 GdkModifierType *mask);
62 static GdkWindow* singlehead_default_window_at_pointer (GdkScreen *screen,
65 static GdkWindow *gdk_window_real_window_get_pointer (GdkDisplay *display,
69 GdkModifierType *mask);
70 static GdkWindow *gdk_display_real_get_window_at_pointer (GdkDisplay *display,
74 static guint signals[LAST_SIGNAL] = { 0 };
76 static char *gdk_sm_client_id;
78 static const GdkDisplayPointerHooks default_pointer_hooks = {
79 _gdk_windowing_get_pointer,
80 gdk_window_real_window_get_pointer,
81 gdk_display_real_get_window_at_pointer
84 static const GdkDisplayPointerHooks singlehead_pointer_hooks = {
85 singlehead_get_pointer,
86 singlehead_window_get_pointer,
87 singlehead_window_at_pointer
90 static const GdkPointerHooks singlehead_default_pointer_hooks = {
91 singlehead_default_window_get_pointer,
92 singlehead_default_window_at_pointer
95 static const GdkPointerHooks *singlehead_current_pointer_hooks = &singlehead_default_pointer_hooks;
97 G_DEFINE_TYPE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
100 gdk_display_class_init (GdkDisplayClass *class)
102 GObjectClass *object_class = G_OBJECT_CLASS (class);
104 object_class->finalize = gdk_display_finalize;
105 object_class->dispose = gdk_display_dispose;
108 * GdkDisplay::closed:
109 * @display: the object on which the signal is emitted
110 * @is_error: %TRUE if the display was closed due to an error
112 * The ::closed signal is emitted when the connection to the windowing
113 * system for @display is closed.
118 g_signal_new (g_intern_static_string ("closed"),
119 G_OBJECT_CLASS_TYPE (object_class),
121 G_STRUCT_OFFSET (GdkDisplayClass, closed),
123 _gdk_marshal_VOID__BOOLEAN,
130 gdk_display_init (GdkDisplay *display)
132 _gdk_displays = g_slist_prepend (_gdk_displays, display);
134 display->button_click_time[0] = display->button_click_time[1] = 0;
135 display->button_window[0] = display->button_window[1] = NULL;
136 display->button_number[0] = display->button_number[1] = -1;
137 display->button_x[0] = display->button_x[1] = 0;
138 display->button_y[0] = display->button_y[1] = 0;
140 display->double_click_time = 250;
141 display->double_click_distance = 5;
143 display->pointer_hooks = &default_pointer_hooks;
147 gdk_display_dispose (GObject *object)
149 GdkDisplay *display = GDK_DISPLAY_OBJECT (object);
151 g_list_foreach (display->queued_events, (GFunc)gdk_event_free, NULL);
152 g_list_free (display->queued_events);
153 display->queued_events = NULL;
154 display->queued_tail = NULL;
156 _gdk_displays = g_slist_remove (_gdk_displays, object);
158 if (gdk_display_get_default() == display)
161 gdk_display_manager_set_default_display (gdk_display_manager_get(),
162 _gdk_displays->data);
164 gdk_display_manager_set_default_display (gdk_display_manager_get(),
168 G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
172 gdk_display_finalize (GObject *object)
174 G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
179 * @display: a #GdkDisplay
181 * Closes the connection to the windowing system for the given display,
182 * and cleans up associated resources.
187 gdk_display_close (GdkDisplay *display)
189 g_return_if_fail (GDK_IS_DISPLAY (display));
191 if (!display->closed)
193 display->closed = TRUE;
195 g_signal_emit (display, signals[CLOSED], 0, FALSE);
196 g_object_run_dispose (G_OBJECT (display));
198 g_object_unref (display);
203 * gdk_display_get_event:
204 * @display: a #GdkDisplay
206 * Gets the next #GdkEvent to be processed for @display, fetching events from the
207 * windowing system if necessary.
209 * Return value: the next #GdkEvent to be processed, or %NULL if no events
210 * are pending. The returned #GdkEvent should be freed with gdk_event_free().
215 gdk_display_get_event (GdkDisplay *display)
217 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
219 _gdk_events_queue (display);
220 return _gdk_event_unqueue (display);
224 * gdk_display_peek_event:
225 * @display: a #GdkDisplay
227 * Gets a copy of the first #GdkEvent in the @display's event queue, without
228 * removing the event from the queue. (Note that this function will
229 * not get more events from the windowing system. It only checks the events
230 * that have already been moved to the GDK event queue.)
232 * Return value: a copy of the first #GdkEvent on the event queue, or %NULL
233 * if no events are in the queue. The returned #GdkEvent should be freed with
239 gdk_display_peek_event (GdkDisplay *display)
243 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
245 tmp_list = _gdk_event_queue_find_first (display);
248 return gdk_event_copy (tmp_list->data);
254 * gdk_display_put_event:
255 * @display: a #GdkDisplay
256 * @event: a #GdkEvent.
258 * Appends a copy of the given event onto the front of the event
259 * queue for @display.
264 gdk_display_put_event (GdkDisplay *display,
265 const GdkEvent *event)
267 g_return_if_fail (GDK_IS_DISPLAY (display));
268 g_return_if_fail (event != NULL);
270 _gdk_event_queue_append (display, gdk_event_copy (event));
271 /* If the main loop is blocking in a different thread, wake it up */
272 g_main_context_wakeup (NULL);
276 * gdk_pointer_ungrab:
277 * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no
278 * timestamp is available.
280 * Ungrabs the pointer on the default display, if it is grabbed by this
284 gdk_pointer_ungrab (guint32 time)
286 gdk_display_pointer_ungrab (gdk_display_get_default (), time);
290 * gdk_pointer_is_grabbed:
292 * Returns %TRUE if the pointer on the default display is currently
293 * grabbed by this application.
295 * Note that this does not take the inmplicit pointer grab on button
296 * presses into account.
298 * Return value: %TRUE if the pointer is currently grabbed by this application.*
301 gdk_pointer_is_grabbed (void)
303 return gdk_display_pointer_is_grabbed (gdk_display_get_default ());
307 * gdk_keyboard_ungrab:
308 * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no
309 * timestamp is available.
311 * Ungrabs the keyboard on the default display, if it is grabbed by this
315 gdk_keyboard_ungrab (guint32 time)
317 gdk_display_keyboard_ungrab (gdk_display_get_default (), time);
323 * Emits a short beep on the default display.
328 gdk_display_beep (gdk_display_get_default ());
332 * gdk_event_send_client_message:
333 * @event: the #GdkEvent to send, which should be a #GdkEventClient.
334 * @winid: the window to send the X ClientMessage event to.
336 * Sends an X ClientMessage event to a given window (which must be
337 * on the default #GdkDisplay.)
338 * This could be used for communicating between different applications,
339 * though the amount of data is limited to 20 bytes.
341 * Return value: non-zero on success.
344 gdk_event_send_client_message (GdkEvent *event,
345 GdkNativeWindow winid)
347 g_return_val_if_fail (event != NULL, FALSE);
349 return gdk_event_send_client_message_for_display (gdk_display_get_default (),
354 * gdk_event_send_clientmessage_toall:
355 * @event: the #GdkEvent to send, which should be a #GdkEventClient.
357 * Sends an X ClientMessage event to all toplevel windows on the default
360 * Toplevel windows are determined by checking for the WM_STATE property, as
361 * described in the Inter-Client Communication Conventions Manual (ICCCM).
362 * If no windows are found with the WM_STATE property set, the message is sent
363 * to all children of the root window.
366 gdk_event_send_clientmessage_toall (GdkEvent *event)
368 g_return_if_fail (event != NULL);
370 gdk_screen_broadcast_client_message (gdk_screen_get_default (), event);
374 * gdk_device_get_core_pointer:
376 * Returns the core pointer device for the default display.
378 * Return value: the core pointer device; this is owned by the
379 * display and should not be freed.
382 gdk_device_get_core_pointer (void)
384 return gdk_display_get_core_pointer (gdk_display_get_default ());
388 * gdk_display_get_core_pointer:
389 * @display: a #GdkDisplay
391 * Returns the core pointer device for the given display
393 * Return value: the core pointer device; this is owned by the
394 * display and should not be freed.
399 gdk_display_get_core_pointer (GdkDisplay *display)
401 return display->core_pointer;
405 * gdk_set_sm_client_id:
406 * @sm_client_id: the client id assigned by the session manager when the
407 * connection was opened, or %NULL to remove the property.
409 * Sets the <literal>SM_CLIENT_ID</literal> property on the application's leader window so that
410 * the window manager can save the application's state using the X11R6 ICCCM
411 * session management protocol.
413 * See the X Session Management Library documentation for more information on
414 * session management and the Inter-Client Communication Conventions Manual
415 * (ICCCM) for information on the <literal>WM_CLIENT_LEADER</literal> property.
416 * (Both documents are part of the X Window System distribution.)
419 gdk_set_sm_client_id (const gchar* sm_client_id)
421 GSList *displays, *tmp_list;
423 g_free (gdk_sm_client_id);
424 gdk_sm_client_id = g_strdup (sm_client_id);
426 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
427 for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
428 _gdk_windowing_display_set_sm_client_id (tmp_list->data, sm_client_id);
430 g_slist_free (displays);
434 * _gdk_get_sm_client_id:
436 * Gets the client ID set with gdk_set_sm_client_id(), if any.
438 * Return value: Session ID, or %NULL if gdk_set_sm_client_id()
439 * has never been called.
442 _gdk_get_sm_client_id (void)
444 return gdk_sm_client_id;
448 _gdk_display_enable_motion_hints (GdkDisplay *display)
452 if (display->pointer_info.motion_hint_serial != 0)
454 serial = _gdk_windowing_window_get_next_serial (display);
455 /* We might not actually generate the next request, so
456 make sure this triggers always, this may cause it to
457 trigger slightly too early, but this is just a hint
461 if (serial < display->pointer_info.motion_hint_serial)
462 display->pointer_info.motion_hint_serial = serial;
467 * gdk_display_get_pointer:
468 * @display: a #GdkDisplay
469 * @screen: (allow-none): location to store the screen that the
470 * cursor is on, or %NULL.
471 * @x: (out): location to store root window X coordinate of pointer, or %NULL.
472 * @y: (out): location to store root window Y coordinate of pointer, or %NULL.
473 * @mask: (out): location to store current modifier mask, or %NULL
475 * Gets the current location of the pointer and the current modifier
476 * mask for a given display.
481 gdk_display_get_pointer (GdkDisplay *display,
485 GdkModifierType *mask)
487 GdkScreen *tmp_screen;
489 GdkModifierType tmp_mask;
491 g_return_if_fail (GDK_IS_DISPLAY (display));
493 display->pointer_hooks->get_pointer (display, &tmp_screen, &tmp_x, &tmp_y, &tmp_mask);
496 *screen = tmp_screen;
506 gdk_display_real_get_window_at_pointer (GdkDisplay *display,
513 window = _gdk_windowing_window_at_pointer (display, &x, &y, NULL, FALSE);
515 /* This might need corrections, as the native window returned
516 may contain client side children */
521 window = _gdk_window_find_descendant_at (window,
524 x = floor (xx + 0.5);
525 y = floor (yy + 0.5);
535 gdk_window_real_window_get_pointer (GdkDisplay *display,
539 GdkModifierType *mask)
541 GdkWindowObject *private;
543 GdkModifierType tmp_mask;
544 gboolean normal_child;
546 private = (GdkWindowObject *) window;
548 normal_child = GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_pointer (window,
551 /* We got the coords on the impl, convert to the window */
552 tmpx -= private->abs_x;
553 tmpy -= private->abs_y;
563 return _gdk_window_find_child_at (window, tmpx, tmpy);
568 * gdk_display_get_window_at_pointer:
569 * @display: a #GdkDisplay
570 * @win_x: (out) (allow-none): return location for x coordinate of the pointer location relative
571 * to the window origin, or %NULL
572 * @win_y: (out) (allow-none): return location for y coordinate of the pointer location relative
573 & to the window origin, or %NULL
575 * Obtains the window underneath the mouse pointer, returning the location
576 * of the pointer in that window in @win_x, @win_y for @screen. Returns %NULL
577 * if the window under the mouse pointer is not known to GDK (for example,
578 * belongs to another application).
580 * Returns: (transfer none): the window under the mouse pointer, or %NULL
585 gdk_display_get_window_at_pointer (GdkDisplay *display,
592 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
594 window = display->pointer_hooks->window_at_pointer (display, &tmp_x, &tmp_y);
605 * gdk_display_set_pointer_hooks:
606 * @display: a #GdkDisplay
607 * @new_hooks: a table of pointers to functions for getting
608 * quantities related to the current pointer position,
609 * or %NULL to restore the default table.
611 * This function allows for hooking into the operation
612 * of getting the current location of the pointer on a particular
613 * display. This is only useful for such low-level tools as an
614 * event recorder. Applications should never have any
615 * reason to use this facility.
617 * Return value: the previous pointer hook table
621 GdkDisplayPointerHooks *
622 gdk_display_set_pointer_hooks (GdkDisplay *display,
623 const GdkDisplayPointerHooks *new_hooks)
625 const GdkDisplayPointerHooks *result;
627 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
628 result = display->pointer_hooks;
631 display->pointer_hooks = new_hooks;
633 display->pointer_hooks = &default_pointer_hooks;
635 return (GdkDisplayPointerHooks *)result;
639 singlehead_get_pointer (GdkDisplay *display,
643 GdkModifierType *mask)
645 GdkScreen *default_screen = gdk_display_get_default_screen (display);
646 GdkWindow *root_window = gdk_screen_get_root_window (default_screen);
648 *screen = default_screen;
650 singlehead_current_pointer_hooks->get_pointer (root_window, x, y, mask);
654 singlehead_window_get_pointer (GdkDisplay *display,
658 GdkModifierType *mask)
660 return singlehead_current_pointer_hooks->get_pointer (window, x, y, mask);
664 singlehead_window_at_pointer (GdkDisplay *display,
668 GdkScreen *default_screen = gdk_display_get_default_screen (display);
670 return singlehead_current_pointer_hooks->window_at_pointer (default_screen,
675 singlehead_default_window_get_pointer (GdkWindow *window,
678 GdkModifierType *mask)
680 return gdk_window_real_window_get_pointer (gdk_drawable_get_display (window),
685 singlehead_default_window_at_pointer (GdkScreen *screen,
689 return gdk_display_real_get_window_at_pointer (gdk_screen_get_display (screen),
694 * gdk_set_pointer_hooks:
695 * @new_hooks: a table of pointers to functions for getting
696 * quantities related to the current pointer position,
697 * or %NULL to restore the default table.
699 * This function allows for hooking into the operation
700 * of getting the current location of the pointer. This
701 * is only useful for such low-level tools as an
702 * event recorder. Applications should never have any
703 * reason to use this facility.
705 * This function is not multihead safe. For multihead operation,
706 * see gdk_display_set_pointer_hooks().
708 * Return value: the previous pointer hook table
711 gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks)
713 const GdkPointerHooks *result = singlehead_current_pointer_hooks;
716 singlehead_current_pointer_hooks = new_hooks;
718 singlehead_current_pointer_hooks = &singlehead_default_pointer_hooks;
720 gdk_display_set_pointer_hooks (gdk_display_get_default (),
721 &singlehead_pointer_hooks);
723 return (GdkPointerHooks *)result;
727 generate_grab_broken_event (GdkWindow *window,
730 GdkWindow *grab_window)
732 g_return_if_fail (window != NULL);
734 if (!GDK_WINDOW_DESTROYED (window))
737 event.type = GDK_GRAB_BROKEN;
738 event.grab_broken.window = window;
739 event.grab_broken.send_event = 0;
740 event.grab_broken.keyboard = keyboard;
741 event.grab_broken.implicit = implicit;
742 event.grab_broken.grab_window = grab_window;
743 gdk_event_put (&event);
748 _gdk_display_get_last_pointer_grab (GdkDisplay *display)
752 l = g_list_last (display->pointer_grabs);
757 return (GdkPointerGrabInfo *)l->data;
762 _gdk_display_add_pointer_grab (GdkDisplay *display,
764 GdkWindow *native_window,
765 gboolean owner_events,
766 GdkEventMask event_mask,
767 unsigned long serial_start,
771 GdkPointerGrabInfo *info, *other_info;
774 info = g_new0 (GdkPointerGrabInfo, 1);
776 info->window = g_object_ref (window);
777 info->native_window = g_object_ref (native_window);
778 info->serial_start = serial_start;
779 info->serial_end = G_MAXULONG;
780 info->owner_events = owner_events;
781 info->event_mask = event_mask;
783 info->implicit = implicit;
785 /* Find the first grab that has a larger start time (if any) and insert
786 * before that. I.E we insert after already existing grabs with same
788 for (l = display->pointer_grabs; l != NULL; l = l->next)
790 other_info = l->data;
792 if (info->serial_start < other_info->serial_start)
795 display->pointer_grabs =
796 g_list_insert_before (display->pointer_grabs, l, info);
798 /* Make sure the new grab end before next grab */
801 other_info = l->data;
802 info->serial_end = other_info->serial_start;
805 /* Find any previous grab and update its end time */
806 l = g_list_find (display->pointer_grabs, info);
810 other_info = l->data;
811 other_info->serial_end = serial_start;
818 free_pointer_grab (GdkPointerGrabInfo *info)
820 g_object_unref (info->window);
821 g_object_unref (info->native_window);
825 /* _gdk_synthesize_crossing_events only works inside one toplevel.
826 This function splits things into two calls if needed, converting the
827 coordinates to the right toplevel */
829 synthesize_crossing_events (GdkDisplay *display,
830 GdkWindow *src_window,
831 GdkWindow *dest_window,
832 GdkCrossingMode crossing_mode,
836 GdkWindow *src_toplevel, *dest_toplevel;
837 GdkModifierType state;
840 /* We use the native crossing events if all native */
841 if (_gdk_native_windows)
845 src_toplevel = gdk_window_get_toplevel (src_window);
849 dest_toplevel = gdk_window_get_toplevel (dest_window);
851 dest_toplevel = NULL;
853 if (src_toplevel == NULL && dest_toplevel == NULL)
856 if (src_toplevel == NULL ||
857 src_toplevel == dest_toplevel)
860 gdk_window_get_pointer (dest_toplevel,
862 _gdk_synthesize_crossing_events (display,
871 else if (dest_toplevel == NULL)
873 gdk_window_get_pointer (src_toplevel,
875 _gdk_synthesize_crossing_events (display,
886 /* Different toplevels */
887 gdk_window_get_pointer (src_toplevel,
889 _gdk_synthesize_crossing_events (display,
897 gdk_window_get_pointer (dest_toplevel,
899 _gdk_synthesize_crossing_events (display,
911 get_current_toplevel (GdkDisplay *display,
912 int *x_out, int *y_out,
913 GdkModifierType *state_out)
915 GdkWindow *pointer_window;
917 GdkModifierType state;
919 pointer_window = _gdk_windowing_window_at_pointer (display, &x, &y, &state, TRUE);
920 if (pointer_window != NULL &&
921 (GDK_WINDOW_DESTROYED (pointer_window) ||
922 GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT ||
923 GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN))
924 pointer_window = NULL;
929 return pointer_window;
933 switch_to_pointer_grab (GdkDisplay *display,
934 GdkPointerGrabInfo *grab,
935 GdkPointerGrabInfo *last_grab,
939 GdkWindow *src_window, *pointer_window, *new_toplevel;
941 GdkModifierType state;
944 /* Temporarily unset pointer to make sure we send the crossing events below */
945 old_grabs = display->pointer_grabs;
946 display->pointer_grabs = NULL;
950 /* New grab is in effect */
952 /* We need to generate crossing events for the grab.
953 * However, there are never any crossing events for implicit grabs
954 * TODO: ... Actually, this could happen if the pointer window
955 * doesn't have button mask so a parent gets the event...
959 /* We send GRAB crossing events from the window under the pointer to the
960 grab window. Except if there is an old grab then we start from that */
962 src_window = last_grab->window;
964 src_window = display->pointer_info.window_under_pointer;
966 if (src_window != grab->window)
968 synthesize_crossing_events (display,
969 src_window, grab->window,
970 GDK_CROSSING_GRAB, time, serial);
973 /* !owner_event Grabbing a window that we're not inside, current status is
974 now NULL (i.e. outside grabbed window) */
975 if (!grab->owner_events && display->pointer_info.window_under_pointer != grab->window)
976 _gdk_display_set_window_under_pointer (display, NULL);
979 grab->activated = TRUE;
986 if (grab == NULL /* ungrab */ ||
987 (!last_grab->owner_events && grab->owner_events) /* switched to owner_events */ )
989 /* We force check what window we're in, and update the toplevel_under_pointer info,
990 * as that won't get told of this change with toplevel enter events.
992 if (display->pointer_info.toplevel_under_pointer)
993 g_object_unref (display->pointer_info.toplevel_under_pointer);
994 display->pointer_info.toplevel_under_pointer = NULL;
996 new_toplevel = get_current_toplevel (display, &x, &y, &state);
999 /* w is now toplevel and x,y in toplevel coords */
1000 display->pointer_info.toplevel_under_pointer = g_object_ref (new_toplevel);
1001 display->pointer_info.toplevel_x = x;
1002 display->pointer_info.toplevel_y = y;
1003 display->pointer_info.state = state;
1007 if (grab == NULL) /* Ungrabbed, send events */
1009 pointer_window = NULL;
1012 /* Find (possibly virtual) child window */
1014 _gdk_window_find_descendant_at (new_toplevel,
1019 if (pointer_window != last_grab->window)
1020 synthesize_crossing_events (display,
1021 last_grab->window, pointer_window,
1022 GDK_CROSSING_UNGRAB, time, serial);
1024 /* We're now ungrabbed, update the window_under_pointer */
1025 _gdk_display_set_window_under_pointer (display, pointer_window);
1029 display->pointer_grabs = old_grabs;
1034 _gdk_display_pointer_grab_update (GdkDisplay *display,
1035 gulong current_serial)
1037 GdkPointerGrabInfo *current_grab, *next_grab;
1040 time = display->last_event_time;
1042 while (display->pointer_grabs != NULL)
1044 current_grab = display->pointer_grabs->data;
1046 if (current_grab->serial_start > current_serial)
1047 return; /* Hasn't started yet */
1049 if (current_grab->serial_end > current_serial)
1051 /* This one hasn't ended yet.
1052 its the currently active one or scheduled to be active */
1054 if (!current_grab->activated)
1055 switch_to_pointer_grab (display, current_grab, NULL, time, current_serial);
1062 if (display->pointer_grabs->next)
1064 /* This is the next active grab */
1065 next_grab = display->pointer_grabs->next->data;
1067 if (next_grab->serial_start > current_serial)
1068 next_grab = NULL; /* Actually its not yet active */
1071 if ((next_grab == NULL && current_grab->implicit_ungrab) ||
1072 (next_grab != NULL && current_grab->window != next_grab->window))
1073 generate_grab_broken_event (GDK_WINDOW (current_grab->window),
1074 FALSE, current_grab->implicit,
1075 next_grab? next_grab->window : NULL);
1077 /* Remove old grab */
1078 display->pointer_grabs =
1079 g_list_delete_link (display->pointer_grabs,
1080 display->pointer_grabs);
1082 switch_to_pointer_grab (display,
1083 next_grab, current_grab,
1084 time, current_serial);
1086 free_pointer_grab (current_grab);
1091 find_pointer_grab (GdkDisplay *display,
1094 GdkPointerGrabInfo *grab;
1097 for (l = display->pointer_grabs; l != NULL; l = l->next)
1101 if (serial >= grab->serial_start && serial < grab->serial_end)
1110 GdkPointerGrabInfo *
1111 _gdk_display_has_pointer_grab (GdkDisplay *display,
1116 l = find_pointer_grab (display, serial);
1123 /* Returns true if last grab was ended
1124 * If if_child is non-NULL, end the grab only if the grabbed
1125 * window is the same as if_child or a descendant of it */
1127 _gdk_display_end_pointer_grab (GdkDisplay *display,
1129 GdkWindow *if_child,
1132 GdkPointerGrabInfo *grab;
1135 l = find_pointer_grab (display, serial);
1142 (if_child == NULL ||
1143 _gdk_window_event_parent_of (if_child, grab->window)))
1145 grab->serial_end = serial;
1146 grab->implicit_ungrab = implicit;
1147 return l->next == NULL;
1154 _gdk_display_set_has_keyboard_grab (GdkDisplay *display,
1156 GdkWindow *native_window,
1157 gboolean owner_events,
1158 unsigned long serial,
1161 if (display->keyboard_grab.window != NULL &&
1162 display->keyboard_grab.window != window)
1163 generate_grab_broken_event (display->keyboard_grab.window,
1164 TRUE, FALSE, window);
1166 display->keyboard_grab.window = window;
1167 display->keyboard_grab.native_window = native_window;
1168 display->keyboard_grab.owner_events = owner_events;
1169 display->keyboard_grab.serial = serial;
1170 display->keyboard_grab.time = time;
1174 _gdk_display_unset_has_keyboard_grab (GdkDisplay *display,
1178 generate_grab_broken_event (display->keyboard_grab.window,
1180 display->keyboard_grab.window = NULL;
1184 * gdk_keyboard_grab_info_libgtk_only:
1185 * @display: the display for which to get the grab information
1186 * @grab_window: location to store current grab window
1187 * @owner_events: location to store boolean indicating whether
1188 * the @owner_events flag to gdk_keyboard_grab() was %TRUE.
1190 * Determines information about the current keyboard grab.
1191 * This is not public API and must not be used by applications.
1193 * Return value: %TRUE if this application currently has the
1197 gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
1198 GdkWindow **grab_window,
1199 gboolean *owner_events)
1201 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1203 if (display->keyboard_grab.window)
1206 *grab_window = display->keyboard_grab.window;
1208 *owner_events = display->keyboard_grab.owner_events;
1217 * gdk_pointer_grab_info_libgtk_only:
1218 * @display: the #GdkDisplay for which to get the grab information
1219 * @grab_window: location to store current grab window
1220 * @owner_events: location to store boolean indicating whether
1221 * the @owner_events flag to gdk_pointer_grab() was %TRUE.
1223 * Determines information about the current pointer grab.
1224 * This is not public API and must not be used by applications.
1226 * Return value: %TRUE if this application currently has the
1230 gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
1231 GdkWindow **grab_window,
1232 gboolean *owner_events)
1234 GdkPointerGrabInfo *info;
1236 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1238 /* What we're interested in is the steady state (ie last grab),
1239 because we're interested e.g. if we grabbed so that we
1240 can ungrab, even if our grab is not active just yet. */
1241 info = _gdk_display_get_last_pointer_grab (display);
1246 *grab_window = info->window;
1248 *owner_events = info->owner_events;
1258 * gdk_display_pointer_is_grabbed:
1259 * @display: a #GdkDisplay
1261 * Test if the pointer is grabbed.
1263 * Returns: %TRUE if an active X pointer grab is in effect
1268 gdk_display_pointer_is_grabbed (GdkDisplay *display)
1270 GdkPointerGrabInfo *info;
1272 g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
1274 /* What we're interested in is the steady state (ie last grab),
1275 because we're interested e.g. if we grabbed so that we
1276 can ungrab, even if our grab is not active just yet. */
1277 info = _gdk_display_get_last_pointer_grab (display);
1279 return (info && !info->implicit);
1282 #define __GDK_DISPLAY_C__
1283 #include "gdkaliasdef.c"