]> Pileus Git - ~andy/gtk/blob - gdk/gdkdisplay.c
Fix some possible crashes if the default display is NULL
[~andy/gtk] / gdk / gdkdisplay.c
1 /* GDK - The GIMP Drawing Kit
2  * gdkdisplay.c
3  * 
4  * Copyright 2001 Sun Microsystems Inc. 
5  *
6  * Erwann Chenede <erwann.chenede@sun.com>
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 #include "config.h"
25
26 #include "gdkdisplay.h"
27 #include "gdkdisplayprivate.h"
28
29 #include "gdkdeviceprivate.h"
30 #include "gdkevents.h"
31 #include "gdkwindowimpl.h"
32 #include "gdkinternals.h"
33 #include "gdkmarshalers.h"
34 #include "gdkscreen.h"
35
36 #include <glib.h>
37
38
39 /**
40  * SECTION:gdkdisplay
41  * @Short_description: Controls a set of GdkScreens and their associated input devices
42  * @Title: GdkDisplay
43  *
44  * #GdkDisplay objects purpose are two fold:
45  * <itemizedlist>
46  * <listitem>
47  *   To manage and provide information about input devices (pointers
48  *   and keyboards)
49  * </listitem>
50  * <listitem>
51  *   To manage and provide information about the available #GdkScreens
52  * </listitem>
53  * </itemizedlist>
54  *
55  * GdkDisplay objects are the GDK representation of an X Display,
56  * which can be described as <emphasis>a workstation consisting of
57  * a keyboard, a pointing device (such as a mouse) and one or more
58  * screens</emphasis>.
59  * It is used to open and keep track of various GdkScreen objects
60  * currently instantiated by the application. It is also used to
61  * access the keyboard(s) and mouse pointer(s) of the display.
62  *
63  * Most of the input device handling has been factored out into
64  * the separate #GdkDeviceManager object. Every display has a
65  * device manager, which you can obtain using
66  * gdk_display_get_device_manager().
67  */
68
69
70 enum {
71   OPENED,
72   CLOSED,
73   LAST_SIGNAL
74 };
75
76 static void gdk_display_dispose     (GObject         *object);
77 static void gdk_display_finalize    (GObject         *object);
78
79
80 static GdkAppLaunchContext *gdk_display_real_get_app_launch_context (GdkDisplay *display);
81
82 static guint signals[LAST_SIGNAL] = { 0 };
83
84 G_DEFINE_TYPE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
85
86 static void
87 gdk_display_class_init (GdkDisplayClass *class)
88 {
89   GObjectClass *object_class = G_OBJECT_CLASS (class);
90
91   object_class->finalize = gdk_display_finalize;
92   object_class->dispose = gdk_display_dispose;
93
94   class->get_app_launch_context = gdk_display_real_get_app_launch_context;
95   class->window_type = GDK_TYPE_WINDOW;
96
97   /**
98    * GdkDisplay::opened:
99    * @display: the object on which the signal is emitted
100    *
101    * The ::opened signal is emitted when the connection to the windowing
102    * system for @display is opened.
103    */
104   signals[OPENED] =
105     g_signal_new (g_intern_static_string ("opened"),
106                   G_OBJECT_CLASS_TYPE (object_class),
107                   G_SIGNAL_RUN_LAST,
108                   0, NULL, NULL,
109                   g_cclosure_marshal_VOID__VOID,
110                   G_TYPE_NONE, 0);
111
112   /**
113    * GdkDisplay::closed:
114    * @display: the object on which the signal is emitted
115    * @is_error: %TRUE if the display was closed due to an error
116    *
117    * The ::closed signal is emitted when the connection to the windowing
118    * system for @display is closed.
119    *
120    * Since: 2.2
121    */   
122   signals[CLOSED] =
123     g_signal_new (g_intern_static_string ("closed"),
124                   G_OBJECT_CLASS_TYPE (object_class),
125                   G_SIGNAL_RUN_LAST,
126                   G_STRUCT_OFFSET (GdkDisplayClass, closed),
127                   NULL, NULL,
128                   _gdk_marshal_VOID__BOOLEAN,
129                   G_TYPE_NONE,
130                   1,
131                   G_TYPE_BOOLEAN);
132 }
133
134 static void
135 free_pointer_info (GdkPointerWindowInfo *info)
136 {
137   if (info->toplevel_under_pointer)
138     g_object_unref (info->toplevel_under_pointer);
139   g_slice_free (GdkPointerWindowInfo, info);
140 }
141
142 static void
143 free_device_grab (GdkDeviceGrabInfo *info)
144 {
145   g_object_unref (info->window);
146   g_object_unref (info->native_window);
147   g_free (info);
148 }
149
150 static gboolean
151 free_device_grabs_foreach (gpointer key,
152                            gpointer value,
153                            gpointer user_data)
154 {
155   GList *list = value;
156
157   g_list_foreach (list, (GFunc) free_device_grab, NULL);
158   g_list_free (list);
159
160   return TRUE;
161 }
162
163 static void
164 device_removed_cb (GdkDeviceManager *device_manager,
165                    GdkDevice        *device,
166                    GdkDisplay       *display)
167 {
168   g_hash_table_remove (display->multiple_click_info, device);
169   g_hash_table_remove (display->device_grabs, device);
170   g_hash_table_remove (display->pointers_info, device);
171
172   /* FIXME: change core pointer and remove from device list */
173 }
174
175 static void
176 gdk_display_opened (GdkDisplay *display)
177 {
178   GdkDeviceManager *device_manager;
179
180   device_manager = gdk_display_get_device_manager (display);
181
182   g_signal_connect (device_manager, "device-removed",
183                     G_CALLBACK (device_removed_cb), display);
184 }
185
186 static void
187 gdk_display_init (GdkDisplay *display)
188 {
189   display->double_click_time = 250;
190   display->double_click_distance = 5;
191
192   display->device_grabs = g_hash_table_new (NULL, NULL);
193   display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
194                                                      (GDestroyNotify) g_free);
195
196   display->pointers_info = g_hash_table_new_full (NULL, NULL, NULL,
197                                                   (GDestroyNotify) free_pointer_info);
198
199   display->multiple_click_info = g_hash_table_new_full (NULL, NULL, NULL,
200                                                         (GDestroyNotify) g_free);
201
202   g_signal_connect (display, "opened",
203                     G_CALLBACK (gdk_display_opened), NULL);
204 }
205
206 static void
207 gdk_display_dispose (GObject *object)
208 {
209   GdkDisplay *display = GDK_DISPLAY (object);
210   GdkDeviceManager *device_manager;
211
212   device_manager = gdk_display_get_device_manager (GDK_DISPLAY (object));
213
214   g_list_foreach (display->queued_events, (GFunc)gdk_event_free, NULL);
215   g_list_free (display->queued_events);
216   display->queued_events = NULL;
217   display->queued_tail = NULL;
218
219   if (device_manager)
220     {
221       /* this is to make it drop devices which may require using the X
222        * display and therefore can't be cleaned up in finalize.
223        * It will also disconnect device_removed_cb
224        */
225       g_object_run_dispose (G_OBJECT (display->device_manager));
226     }
227
228   G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
229 }
230
231 static void
232 gdk_display_finalize (GObject *object)
233 {
234   GdkDisplay *display = GDK_DISPLAY (object);
235
236   g_hash_table_foreach_remove (display->device_grabs,
237                                free_device_grabs_foreach,
238                                NULL);
239   g_hash_table_destroy (display->device_grabs);
240
241   g_hash_table_destroy (display->motion_hint_info);
242   g_hash_table_destroy (display->pointers_info);
243   g_hash_table_destroy (display->multiple_click_info);
244
245   if (display->device_manager)
246     g_object_unref (display->device_manager);
247
248   G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
249 }
250
251 /**
252  * gdk_display_close:
253  * @display: a #GdkDisplay
254  *
255  * Closes the connection to the windowing system for the given display,
256  * and cleans up associated resources.
257  *
258  * Since: 2.2
259  */
260 void
261 gdk_display_close (GdkDisplay *display)
262 {
263   g_return_if_fail (GDK_IS_DISPLAY (display));
264
265   if (!display->closed)
266     {
267       display->closed = TRUE;
268       
269       g_signal_emit (display, signals[CLOSED], 0, FALSE);
270       g_object_run_dispose (G_OBJECT (display));
271       
272       g_object_unref (display);
273     }
274 }
275
276 /**
277  * gdk_display_is_closed:
278  * @display: a #GdkDisplay
279  *
280  * Finds out if the display has been closed.
281  *
282  * Returns: %TRUE if the display is closed.
283  *
284  * Since: 2.22
285  */
286 gboolean
287 gdk_display_is_closed  (GdkDisplay  *display)
288 {
289   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
290
291   return display->closed;
292 }
293
294 /**
295  * gdk_display_get_event:
296  * @display: a #GdkDisplay
297  * 
298  * Gets the next #GdkEvent to be processed for @display, fetching events from the
299  * windowing system if necessary.
300  * 
301  * Return value: the next #GdkEvent to be processed, or %NULL if no events
302  * are pending. The returned #GdkEvent should be freed with gdk_event_free().
303  *
304  * Since: 2.2
305  **/
306 GdkEvent*
307 gdk_display_get_event (GdkDisplay *display)
308 {
309   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
310
311   GDK_DISPLAY_GET_CLASS (display)->queue_events (display);
312   return _gdk_event_unqueue (display);
313 }
314
315 /**
316  * gdk_display_peek_event:
317  * @display: a #GdkDisplay 
318  * 
319  * Gets a copy of the first #GdkEvent in the @display's event queue, without
320  * removing the event from the queue.  (Note that this function will
321  * not get more events from the windowing system.  It only checks the events
322  * that have already been moved to the GDK event queue.)
323  * 
324  * Return value: a copy of the first #GdkEvent on the event queue, or %NULL 
325  * if no events are in the queue. The returned #GdkEvent should be freed with
326  * gdk_event_free().
327  *
328  * Since: 2.2
329  **/
330 GdkEvent*
331 gdk_display_peek_event (GdkDisplay *display)
332 {
333   GList *tmp_list;
334
335   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
336
337   tmp_list = _gdk_event_queue_find_first (display);
338   
339   if (tmp_list)
340     return gdk_event_copy (tmp_list->data);
341   else
342     return NULL;
343 }
344
345 /**
346  * gdk_display_put_event:
347  * @display: a #GdkDisplay
348  * @event: a #GdkEvent.
349  *
350  * Appends a copy of the given event onto the front of the event
351  * queue for @display.
352  *
353  * Since: 2.2
354  **/
355 void
356 gdk_display_put_event (GdkDisplay     *display,
357                        const GdkEvent *event)
358 {
359   g_return_if_fail (GDK_IS_DISPLAY (display));
360   g_return_if_fail (event != NULL);
361
362   _gdk_event_queue_append (display, gdk_event_copy (event));
363   /* If the main loop is blocking in a different thread, wake it up */
364   g_main_context_wakeup (NULL); 
365 }
366
367 /**
368  * gdk_display_pointer_ungrab:
369  * @display: a #GdkDisplay.
370  * @time_: a timestap (e.g. %GDK_CURRENT_TIME).
371  *
372  * Release any pointer grab.
373  *
374  * Since: 2.2
375  *
376  * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
377  *             instead.
378  */
379 void
380 gdk_display_pointer_ungrab (GdkDisplay *display,
381                             guint32     time_)
382 {
383   GdkDeviceManager *device_manager;
384   GList *devices, *dev;
385   GdkDevice *device;
386
387   g_return_if_fail (GDK_IS_DISPLAY (display));
388
389   device_manager = gdk_display_get_device_manager (display);
390   devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
391
392   /* FIXME: Should this be generic to all backends? */
393   /* FIXME: What happens with extended devices? */
394   for (dev = devices; dev; dev = dev->next)
395     {
396       device = dev->data;
397
398       if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
399         continue;
400
401       gdk_device_ungrab (device, time_);
402     }
403
404   g_list_free (devices);
405 }
406
407 /**
408  * gdk_pointer_ungrab:
409  * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no 
410  *  timestamp is available.
411  *
412  * Ungrabs the pointer on the default display, if it is grabbed by this 
413  * application.
414  *
415  * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
416  *             instead.
417  **/
418 void
419 gdk_pointer_ungrab (guint32 time)
420 {
421   gdk_display_pointer_ungrab (gdk_display_get_default (), time);
422 }
423
424 /**
425  * gdk_pointer_is_grabbed:
426  * 
427  * Returns %TRUE if the pointer on the default display is currently 
428  * grabbed by this application.
429  *
430  * Note that this does not take the inmplicit pointer grab on button
431  * presses into account.
432  *
433  * Return value: %TRUE if the pointer is currently grabbed by this application.
434  *
435  * Deprecated: 3.0: Use gdk_display_device_is_grabbed() instead.
436  **/
437 gboolean
438 gdk_pointer_is_grabbed (void)
439 {
440   return gdk_display_pointer_is_grabbed (gdk_display_get_default ());
441 }
442
443 /**
444  * gdk_display_keyboard_ungrab:
445  * @display: a #GdkDisplay.
446  * @time_: a timestap (e.g #GDK_CURRENT_TIME).
447  *
448  * Release any keyboard grab
449  *
450  * Since: 2.2
451  *
452  * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
453  *             instead.
454  */
455 void
456 gdk_display_keyboard_ungrab (GdkDisplay *display,
457                              guint32     time)
458 {
459   GdkDeviceManager *device_manager;
460   GList *devices, *dev;
461   GdkDevice *device;
462
463   g_return_if_fail (GDK_IS_DISPLAY (display));
464
465   device_manager = gdk_display_get_device_manager (display);
466   devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
467
468   /* FIXME: Should this be generic to all backends? */
469   /* FIXME: What happens with extended devices? */
470   for (dev = devices; dev; dev = dev->next)
471     {
472       device = dev->data;
473
474       if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
475         continue;
476
477       gdk_device_ungrab (device, time);
478     }
479
480   g_list_free (devices);
481 }
482
483 /**
484  * gdk_keyboard_ungrab:
485  * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no
486  *        timestamp is available.
487  * 
488  * Ungrabs the keyboard on the default display, if it is grabbed by this 
489  * application.
490  *
491  * Deprecated: 3.0: Use gdk_device_ungrab(), together with gdk_device_grab()
492  *             instead.
493  **/
494 void
495 gdk_keyboard_ungrab (guint32 time)
496 {
497   gdk_display_keyboard_ungrab (gdk_display_get_default (), time);
498 }
499
500 /**
501  * gdk_beep:
502  * 
503  * Emits a short beep on the default display.
504  **/
505 void
506 gdk_beep (void)
507 {
508   gdk_display_beep (gdk_display_get_default ());
509 }
510
511 /**
512  * gdk_flush:
513  *
514  * Flushes the output buffers of all display connections and waits
515  * until all requests have been processed.
516  * This is rarely needed by applications.
517  */
518 void
519 gdk_flush (void)
520 {
521   GSList *list, *l;
522
523   list = gdk_display_manager_list_displays (gdk_display_manager_get ());
524   for (l = list; l; l = l->next)
525     {
526       GdkDisplay *display = l->data;
527
528       GDK_DISPLAY_GET_CLASS (display)->sync (display);
529     }
530
531   g_slist_free (list);
532 }
533
534 void
535 _gdk_display_enable_motion_hints (GdkDisplay *display,
536                                   GdkDevice  *device)
537 {
538   gulong *device_serial, serial;
539
540   device_serial = g_hash_table_lookup (display->motion_hint_info, device);
541
542   if (!device_serial)
543     {
544       device_serial = g_new0 (gulong, 1);
545       *device_serial = G_MAXULONG;
546       g_hash_table_insert (display->motion_hint_info, device, device_serial);
547     }
548
549   if (*device_serial != 0)
550     {
551       serial = _gdk_display_get_next_serial (display);
552       /* We might not actually generate the next request, so
553          make sure this triggers always, this may cause it to
554          trigger slightly too early, but this is just a hint
555          anyway. */
556       if (serial > 0)
557         serial--;
558       if (serial < *device_serial)
559         *device_serial = serial;
560     }
561 }
562
563 /**
564  * gdk_display_get_pointer:
565  * @display: a #GdkDisplay
566  * @screen: (out) (allow-none): location to store the screen that the
567  *          cursor is on, or %NULL.
568  * @x: (out) (allow-none): location to store root window X coordinate of pointer, or %NULL.
569  * @y: (out) (allow-none): location to store root window Y coordinate of pointer, or %NULL.
570  * @mask: (out) (allow-none): location to store current modifier mask, or %NULL
571  *
572  * Gets the current location of the pointer and the current modifier
573  * mask for a given display.
574  *
575  * Since: 2.2
576  *
577  * Deprecated: 3.0: Use gdk_device_get_position() instead.
578  **/
579 void
580 gdk_display_get_pointer (GdkDisplay      *display,
581                          GdkScreen      **screen,
582                          gint            *x,
583                          gint            *y,
584                          GdkModifierType *mask)
585 {
586   GdkScreen *default_screen;
587   GdkWindow *root;
588   gint tmp_x, tmp_y;
589   GdkModifierType tmp_mask;
590
591   g_return_if_fail (GDK_IS_DISPLAY (display));
592
593   if (gdk_display_is_closed (display))
594     return;
595
596   default_screen = gdk_display_get_default_screen (display);
597
598   /* We call _gdk_device_query_state() here manually instead of
599    * gdk_device_get_position() because we care about the modifier mask */
600
601   _gdk_device_query_state (display->core_pointer,
602                            gdk_screen_get_root_window (default_screen),
603                            &root, NULL,
604                            &tmp_x, &tmp_y,
605                            NULL, NULL,
606                            &tmp_mask);
607
608   if (screen)
609     *screen = gdk_window_get_screen (root);
610   if (x)
611     *x = tmp_x;
612   if (y)
613     *y = tmp_y;
614   if (mask)
615     *mask = tmp_mask;
616 }
617
618 /**
619  * gdk_display_get_window_at_pointer:
620  * @display: a #GdkDisplay
621  * @win_x: (out) (allow-none): return location for x coordinate of the pointer location relative
622  *    to the window origin, or %NULL
623  * @win_y: (out) (allow-none): return location for y coordinate of the pointer location relative
624  &    to the window origin, or %NULL
625  *
626  * Obtains the window underneath the mouse pointer, returning the location
627  * of the pointer in that window in @win_x, @win_y for @screen. Returns %NULL
628  * if the window under the mouse pointer is not known to GDK (for example, 
629  * belongs to another application).
630  *
631  * Returns: (transfer none): the window under the mouse pointer, or %NULL
632  *
633  * Since: 2.2
634  *
635  * Deprecated: 3.0: Use gdk_device_get_window_at_position() instead.
636  **/
637 GdkWindow *
638 gdk_display_get_window_at_pointer (GdkDisplay *display,
639                                    gint       *win_x,
640                                    gint       *win_y)
641 {
642   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
643
644   return gdk_device_get_window_at_position (display->core_pointer, win_x, win_y);
645 }
646
647 static void
648 generate_grab_broken_event (GdkWindow *window,
649                             GdkDevice *device,
650                             gboolean   implicit,
651                             GdkWindow *grab_window)
652 {
653   g_return_if_fail (window != NULL);
654
655   if (!GDK_WINDOW_DESTROYED (window))
656     {
657       GdkEvent *event;
658
659       event = gdk_event_new (GDK_GRAB_BROKEN);
660       event->grab_broken.window = g_object_ref (window);
661       event->grab_broken.send_event = FALSE;
662       event->grab_broken.implicit = implicit;
663       event->grab_broken.grab_window = grab_window;
664       gdk_event_set_device (event, device);
665       event->grab_broken.keyboard = (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) ? TRUE : FALSE;
666
667       gdk_event_put (event);
668       gdk_event_free (event);
669     }
670 }
671
672 GdkDeviceGrabInfo *
673 _gdk_display_get_last_device_grab (GdkDisplay *display,
674                                    GdkDevice  *device)
675 {
676   GList *l;
677
678   l = g_hash_table_lookup (display->device_grabs, device);
679
680   if (l)
681     {
682       l = g_list_last (l);
683       return l->data;
684     }
685
686   return NULL;
687 }
688
689 GdkDeviceGrabInfo *
690 _gdk_display_add_device_grab (GdkDisplay       *display,
691                               GdkDevice        *device,
692                               GdkWindow        *window,
693                               GdkWindow        *native_window,
694                               GdkGrabOwnership  grab_ownership,
695                               gboolean          owner_events,
696                               GdkEventMask      event_mask,
697                               unsigned long     serial_start,
698                               guint32           time,
699                               gboolean          implicit)
700 {
701   GdkDeviceGrabInfo *info, *other_info;
702   GList *grabs, *l;
703
704   info = g_new0 (GdkDeviceGrabInfo, 1);
705
706   info->window = g_object_ref (window);
707   info->native_window = g_object_ref (native_window);
708   info->serial_start = serial_start;
709   info->serial_end = G_MAXULONG;
710   info->owner_events = owner_events;
711   info->event_mask = event_mask;
712   info->time = time;
713   info->implicit = implicit;
714   info->ownership = grab_ownership;
715
716   grabs = g_hash_table_lookup (display->device_grabs, device);
717
718   /* Find the first grab that has a larger start time (if any) and insert
719    * before that. I.E we insert after already existing grabs with same
720    * start time */
721   for (l = grabs; l != NULL; l = l->next)
722     {
723       other_info = l->data;
724
725       if (info->serial_start < other_info->serial_start)
726         break;
727     }
728
729   grabs = g_list_insert_before (grabs, l, info);
730
731   /* Make sure the new grab end before next grab */
732   if (l)
733     {
734       other_info = l->data;
735       info->serial_end = other_info->serial_start;
736     }
737
738   /* Find any previous grab and update its end time */
739   l = g_list_find (grabs, info);
740   l = l->prev;
741   if (l)
742     {
743       other_info = l->data;
744       other_info->serial_end = serial_start;
745     }
746
747   g_hash_table_insert (display->device_grabs, device, grabs);
748
749   return info;
750 }
751
752 /* _gdk_synthesize_crossing_events only works inside one toplevel.
753    This function splits things into two calls if needed, converting the
754    coordinates to the right toplevel */
755 static void
756 synthesize_crossing_events (GdkDisplay      *display,
757                             GdkDevice       *device,
758                             GdkDevice       *source_device,
759                             GdkWindow       *src_window,
760                             GdkWindow       *dest_window,
761                             GdkCrossingMode  crossing_mode,
762                             guint32          time,
763                             gulong           serial)
764 {
765   GdkWindow *src_toplevel, *dest_toplevel;
766   GdkModifierType state;
767   int x, y;
768
769   if (src_window)
770     src_toplevel = gdk_window_get_toplevel (src_window);
771   else
772     src_toplevel = NULL;
773   if (dest_window)
774     dest_toplevel = gdk_window_get_toplevel (dest_window);
775   else
776     dest_toplevel = NULL;
777
778   if (src_toplevel == NULL && dest_toplevel == NULL)
779     return;
780   
781   if (src_toplevel == NULL ||
782       src_toplevel == dest_toplevel)
783     {
784       /* Same toplevels */
785       gdk_window_get_pointer (dest_toplevel,
786                               &x, &y, &state);
787       _gdk_synthesize_crossing_events (display,
788                                        src_window,
789                                        dest_window,
790                                        device, source_device,
791                                        crossing_mode,
792                                        x, y, state,
793                                        time,
794                                        NULL,
795                                        serial, FALSE);
796     }
797   else if (dest_toplevel == NULL)
798     {
799       gdk_window_get_pointer (src_toplevel,
800                               &x, &y, &state);
801       _gdk_synthesize_crossing_events (display,
802                                        src_window,
803                                        NULL,
804                                        device, source_device,
805                                        crossing_mode,
806                                        x, y, state,
807                                        time,
808                                        NULL,
809                                        serial, FALSE);
810     }
811   else
812     {
813       /* Different toplevels */
814       gdk_window_get_pointer (src_toplevel,
815                               &x, &y, &state);
816       _gdk_synthesize_crossing_events (display,
817                                        src_window,
818                                        NULL,
819                                        device, source_device,
820                                        crossing_mode,
821                                        x, y, state,
822                                        time,
823                                        NULL,
824                                        serial, FALSE);
825       gdk_window_get_pointer (dest_toplevel,
826                               &x, &y, &state);
827       _gdk_synthesize_crossing_events (display,
828                                        NULL,
829                                        dest_window,
830                                        device, source_device,
831                                        crossing_mode,
832                                        x, y, state,
833                                        time,
834                                        NULL,
835                                        serial, FALSE);
836     }
837 }
838
839 static GdkWindow *
840 get_current_toplevel (GdkDisplay      *display,
841                       GdkDevice       *device,
842                       int             *x_out,
843                       int             *y_out,
844                       GdkModifierType *state_out)
845 {
846   GdkWindow *pointer_window;
847   int x, y;
848   GdkModifierType state;
849
850   pointer_window = _gdk_device_window_at_position (device, &x, &y, &state, TRUE);
851
852   if (pointer_window != NULL &&
853       (GDK_WINDOW_DESTROYED (pointer_window) ||
854        GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT ||
855        GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN))
856     pointer_window = NULL;
857
858   *x_out = x;
859   *y_out = y;
860   *state_out = state;
861
862   return pointer_window;
863 }
864
865 static void
866 switch_to_pointer_grab (GdkDisplay        *display,
867                         GdkDevice         *device,
868                         GdkDevice         *source_device,
869                         GdkDeviceGrabInfo *grab,
870                         GdkDeviceGrabInfo *last_grab,
871                         guint32            time,
872                         gulong             serial)
873 {
874   GdkWindow *src_window, *pointer_window, *new_toplevel;
875   GdkPointerWindowInfo *info;
876   GList *old_grabs;
877   GdkModifierType state;
878   int x = 0, y = 0;
879
880   /* Temporarily unset pointer to make sure we send the crossing events below */
881   old_grabs = g_hash_table_lookup (display->device_grabs, device);
882   g_hash_table_steal (display->device_grabs, device);
883   info = _gdk_display_get_pointer_info (display, device);
884
885   if (grab)
886     {
887       /* New grab is in effect */
888
889       /* We need to generate crossing events for the grab.
890        * However, there are never any crossing events for implicit grabs
891        * TODO: ... Actually, this could happen if the pointer window
892        *           doesn't have button mask so a parent gets the event...
893        */
894       if (!grab->implicit)
895         {
896           /* We send GRAB crossing events from the window under the pointer to the
897              grab window. Except if there is an old grab then we start from that */
898           if (last_grab)
899             src_window = last_grab->window;
900           else
901             src_window = info->window_under_pointer;
902
903           if (src_window != grab->window)
904             synthesize_crossing_events (display, device, source_device,
905                                         src_window, grab->window,
906                                         GDK_CROSSING_GRAB, time, serial);
907
908           /* !owner_event Grabbing a window that we're not inside, current status is
909              now NULL (i.e. outside grabbed window) */
910           if (!grab->owner_events && info->window_under_pointer != grab->window)
911             _gdk_display_set_window_under_pointer (display, device, NULL);
912         }
913
914       grab->activated = TRUE;
915     }
916
917   if (last_grab)
918     {
919       new_toplevel = NULL;
920
921       if (grab == NULL /* ungrab */ ||
922           (!last_grab->owner_events && grab->owner_events) /* switched to owner_events */ )
923         {
924           /* We force check what window we're in, and update the toplevel_under_pointer info,
925            * as that won't get told of this change with toplevel enter events.
926            */
927           if (info->toplevel_under_pointer)
928             g_object_unref (info->toplevel_under_pointer);
929           info->toplevel_under_pointer = NULL;
930
931           /* Ungrabbed slave devices don't have a position by
932            * itself, rather depend on its master pointer, so
933            * it doesn't make sense to track any position for
934            * these after the grab
935            */
936           if (grab || gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE)
937             new_toplevel = get_current_toplevel (display, device, &x, &y, &state);
938
939           if (new_toplevel)
940             {
941               /* w is now toplevel and x,y in toplevel coords */
942               info->toplevel_under_pointer = g_object_ref (new_toplevel);
943               info->toplevel_x = x;
944               info->toplevel_y = y;
945               info->state = state;
946             }
947         }
948
949       if (grab == NULL) /* Ungrabbed, send events */
950         {
951           pointer_window = NULL;
952           if (new_toplevel)
953             {
954               /* Find (possibly virtual) child window */
955               pointer_window =
956                 _gdk_window_find_descendant_at (new_toplevel,
957                                                 x, y,
958                                                 NULL, NULL);
959             }
960
961           if (pointer_window != last_grab->window)
962             synthesize_crossing_events (display, device, source_device,
963                                         last_grab->window, pointer_window,
964                                         GDK_CROSSING_UNGRAB, time, serial);
965
966           /* We're now ungrabbed, update the window_under_pointer */
967           _gdk_display_set_window_under_pointer (display, device, pointer_window);
968         }
969     }
970
971   g_hash_table_insert (display->device_grabs, device, old_grabs);
972 }
973
974 void
975 _gdk_display_device_grab_update (GdkDisplay *display,
976                                  GdkDevice  *device,
977                                  GdkDevice  *source_device,
978                                  gulong      current_serial)
979 {
980   GdkDeviceGrabInfo *current_grab, *next_grab;
981   GList *grabs;
982   guint32 time;
983
984   time = display->last_event_time;
985   grabs = g_hash_table_lookup (display->device_grabs, device);
986
987   while (grabs != NULL)
988     {
989       current_grab = grabs->data;
990
991       if (current_grab->serial_start > current_serial)
992         return; /* Hasn't started yet */
993
994       if (current_grab->serial_end > current_serial)
995         {
996           /* This one hasn't ended yet.
997              its the currently active one or scheduled to be active */
998
999           if (!current_grab->activated)
1000             {
1001               if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
1002                 switch_to_pointer_grab (display, device, source_device, current_grab, NULL, time, current_serial);
1003             }
1004
1005           break;
1006         }
1007
1008       next_grab = NULL;
1009       if (grabs->next)
1010         {
1011           /* This is the next active grab */
1012           next_grab = grabs->next->data;
1013
1014           if (next_grab->serial_start > current_serial)
1015             next_grab = NULL; /* Actually its not yet active */
1016         }
1017
1018       if ((next_grab == NULL && current_grab->implicit_ungrab) ||
1019           (next_grab != NULL && current_grab->window != next_grab->window))
1020         generate_grab_broken_event (GDK_WINDOW (current_grab->window),
1021                                     device,
1022                                     current_grab->implicit,
1023                                     next_grab? next_grab->window : NULL);
1024
1025       /* Remove old grab */
1026       grabs = g_list_delete_link (grabs, grabs);
1027       g_hash_table_insert (display->device_grabs, device, grabs);
1028
1029       if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
1030         switch_to_pointer_grab (display, device, source_device,
1031                                 next_grab, current_grab,
1032                                 time, current_serial);
1033
1034       free_device_grab (current_grab);
1035     }
1036 }
1037
1038 static GList *
1039 grab_list_find (GList  *grabs,
1040                 gulong  serial)
1041 {
1042   GdkDeviceGrabInfo *grab;
1043
1044   while (grabs)
1045     {
1046       grab = grabs->data;
1047
1048       if (serial >= grab->serial_start && serial < grab->serial_end)
1049         return grabs;
1050
1051       grabs = grabs->next;
1052     }
1053
1054   return NULL;
1055 }
1056
1057 static GList *
1058 find_device_grab (GdkDisplay *display,
1059                    GdkDevice  *device,
1060                    gulong      serial)
1061 {
1062   GList *l;
1063
1064   l = g_hash_table_lookup (display->device_grabs, device);
1065   return grab_list_find (l, serial);
1066 }
1067
1068 GdkDeviceGrabInfo *
1069 _gdk_display_has_device_grab (GdkDisplay *display,
1070                               GdkDevice  *device,
1071                               gulong      serial)
1072 {
1073   GList *l;
1074
1075   l = find_device_grab (display, device, serial);
1076   if (l)
1077     return l->data;
1078
1079   return NULL;
1080 }
1081
1082 /* Returns true if last grab was ended
1083  * If if_child is non-NULL, end the grab only if the grabbed
1084  * window is the same as if_child or a descendant of it */
1085 gboolean
1086 _gdk_display_end_device_grab (GdkDisplay *display,
1087                               GdkDevice  *device,
1088                               gulong      serial,
1089                               GdkWindow  *if_child,
1090                               gboolean    implicit)
1091 {
1092   GdkDeviceGrabInfo *grab;
1093   GList *l;
1094
1095   l = find_device_grab (display, device, serial);
1096
1097   if (l == NULL)
1098     return FALSE;
1099
1100   grab = l->data;
1101   if (grab &&
1102       (if_child == NULL ||
1103        _gdk_window_event_parent_of (if_child, grab->window)))
1104     {
1105       grab->serial_end = serial;
1106       grab->implicit_ungrab = implicit;
1107       return l->next == NULL;
1108     }
1109   
1110   return FALSE;
1111 }
1112
1113 /* Returns TRUE if device events are not blocked by any grab */
1114 gboolean
1115 _gdk_display_check_grab_ownership (GdkDisplay *display,
1116                                    GdkDevice  *device,
1117                                    gulong      serial)
1118 {
1119   GHashTableIter iter;
1120   gpointer key, value;
1121   GdkGrabOwnership higher_ownership, device_ownership;
1122   gboolean device_is_keyboard;
1123
1124   g_hash_table_iter_init (&iter, display->device_grabs);
1125   higher_ownership = device_ownership = GDK_OWNERSHIP_NONE;
1126   device_is_keyboard = (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD);
1127
1128   while (g_hash_table_iter_next (&iter, &key, &value))
1129     {
1130       GdkDeviceGrabInfo *grab;
1131       GdkDevice *dev;
1132       GList *grabs;
1133
1134       dev = key;
1135       grabs = value;
1136       grabs = grab_list_find (grabs, serial);
1137
1138       if (!grabs)
1139         continue;
1140
1141       /* Discard device if it's not of the same type */
1142       if ((device_is_keyboard && gdk_device_get_source (dev) != GDK_SOURCE_KEYBOARD) ||
1143           (!device_is_keyboard && gdk_device_get_source (dev) == GDK_SOURCE_KEYBOARD))
1144         continue;
1145
1146       grab = grabs->data;
1147
1148       if (dev == device)
1149         device_ownership = grab->ownership;
1150       else
1151         {
1152           if (grab->ownership > higher_ownership)
1153             higher_ownership = grab->ownership;
1154         }
1155     }
1156
1157   if (higher_ownership > device_ownership)
1158     {
1159       /* There's a higher priority ownership
1160        * going on for other device(s)
1161        */
1162       return FALSE;
1163     }
1164
1165   return TRUE;
1166 }
1167
1168 GdkPointerWindowInfo *
1169 _gdk_display_get_pointer_info (GdkDisplay *display,
1170                                GdkDevice  *device)
1171 {
1172   GdkPointerWindowInfo *info;
1173
1174   if (G_UNLIKELY (!device))
1175     return NULL;
1176
1177   info = g_hash_table_lookup (display->pointers_info, device);
1178
1179   if (G_UNLIKELY (!info))
1180     {
1181       info = g_slice_new0 (GdkPointerWindowInfo);
1182       g_hash_table_insert (display->pointers_info, device, info);
1183     }
1184
1185   return info;
1186 }
1187
1188 void
1189 _gdk_display_pointer_info_foreach (GdkDisplay                   *display,
1190                                    GdkDisplayPointerInfoForeach  func,
1191                                    gpointer                      user_data)
1192 {
1193   GHashTableIter iter;
1194   gpointer key, value;
1195
1196   g_hash_table_iter_init (&iter, display->pointers_info);
1197
1198   while (g_hash_table_iter_next (&iter, &key, &value))
1199     {
1200       GdkPointerWindowInfo *info = value;
1201       GdkDevice *device = key;
1202
1203       (func) (display, device, info, user_data);
1204     }
1205 }
1206
1207 /**
1208  * gdk_device_grab_info_libgtk_only:
1209  * @display: the display for which to get the grab information
1210  * @device: device to get the grab information from
1211  * @grab_window: (out) (transfer none): location to store current grab window
1212  * @owner_events: (out): location to store boolean indicating whether
1213  *   the @owner_events flag to gdk_keyboard_grab() or
1214  *   gdk_pointer_grab() was %TRUE.
1215  *
1216  * Determines information about the current keyboard grab.
1217  * This is not public API and must not be used by applications.
1218  *
1219  * Return value: %TRUE if this application currently has the
1220  *  keyboard grabbed.
1221  **/
1222 gboolean
1223 gdk_device_grab_info_libgtk_only (GdkDisplay  *display,
1224                                   GdkDevice   *device,
1225                                   GdkWindow  **grab_window,
1226                                   gboolean    *owner_events)
1227 {
1228   GdkDeviceGrabInfo *info;
1229
1230   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1231   g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
1232
1233   info = _gdk_display_get_last_device_grab (display, device);
1234
1235   if (info)
1236     {
1237       if (grab_window)
1238         *grab_window = info->window;
1239       if (owner_events)
1240         *owner_events = info->owner_events;
1241
1242       return TRUE;
1243     }
1244   else
1245     return FALSE;
1246 }
1247
1248 /**
1249  * gdk_display_pointer_is_grabbed:
1250  * @display: a #GdkDisplay
1251  *
1252  * Test if the pointer is grabbed.
1253  *
1254  * Returns: %TRUE if an active X pointer grab is in effect
1255  *
1256  * Since: 2.2
1257  *
1258  * Deprecated: 3.0: Use gdk_display_device_is_grabbed() instead.
1259  */
1260 gboolean
1261 gdk_display_pointer_is_grabbed (GdkDisplay *display)
1262 {
1263   GdkDeviceManager *device_manager;
1264   GList *devices, *dev;
1265   GdkDevice *device;
1266
1267   g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
1268
1269   device_manager = gdk_display_get_device_manager (display);
1270   devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
1271
1272   for (dev = devices; dev; dev = dev->next)
1273     {
1274       device = dev->data;
1275
1276       if (gdk_device_get_source (device) == GDK_SOURCE_MOUSE &&
1277           gdk_display_device_is_grabbed (display, device))
1278         return TRUE;
1279     }
1280
1281   return FALSE;
1282 }
1283
1284 /**
1285  * gdk_display_device_is_grabbed:
1286  * @display: a #GdkDisplay
1287  * @device: a #GdkDevice
1288  *
1289  * Returns %TRUE if there is an ongoing grab on @device for @display.
1290  *
1291  * Returns: %TRUE if there is a grab in effect for @device.
1292  **/
1293 gboolean
1294 gdk_display_device_is_grabbed (GdkDisplay *display,
1295                                GdkDevice  *device)
1296 {
1297   GdkDeviceGrabInfo *info;
1298
1299   g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
1300   g_return_val_if_fail (GDK_IS_DEVICE (device), TRUE);
1301
1302   /* What we're interested in is the steady state (ie last grab),
1303      because we're interested e.g. if we grabbed so that we
1304      can ungrab, even if our grab is not active just yet. */
1305   info = _gdk_display_get_last_device_grab (display, device);
1306
1307   return (info && !info->implicit);
1308 }
1309
1310 /**
1311  * gdk_display_get_device_manager:
1312  * @display: a #GdkDisplay.
1313  *
1314  * Returns the #GdkDeviceManager associated to @display.
1315  *
1316  * Returns: (transfer none): A #GdkDeviceManager, or %NULL. This memory is
1317  *          owned by GDK and must not be freed or unreferenced.
1318  *
1319  * Since: 3.0
1320  **/
1321 GdkDeviceManager *
1322 gdk_display_get_device_manager (GdkDisplay *display)
1323 {
1324   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1325
1326   return display->device_manager;
1327 }
1328
1329 /**
1330  * gdk_display_get_name:
1331  * @display: a #GdkDisplay
1332  *
1333  * Gets the name of the display.
1334  *
1335  * Returns: a string representing the display name. This string is owned
1336  * by GDK and should not be modified or freed.
1337  *
1338  * Since: 2.2
1339  */
1340 G_CONST_RETURN gchar *
1341 gdk_display_get_name (GdkDisplay *display)
1342 {
1343   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1344
1345   return GDK_DISPLAY_GET_CLASS (display)->get_name (display);
1346 }
1347
1348 gchar *
1349 gdk_get_display (void)
1350 {
1351   return g_strdup (gdk_display_get_name (gdk_display_get_default ()));
1352 }
1353
1354 /**
1355  * gdk_display_get_n_screens:
1356  * @display: a #GdkDisplay
1357  *
1358  * Gets the number of screen managed by the @display.
1359  *
1360  * Returns: number of screens.
1361  *
1362  * Since: 2.2
1363  */
1364 gint
1365 gdk_display_get_n_screens (GdkDisplay *display)
1366 {
1367   g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
1368
1369   return GDK_DISPLAY_GET_CLASS (display)->get_n_screens (display);
1370 }
1371
1372 /**
1373  * gdk_display_get_screen:
1374  * @display: a #GdkDisplay
1375  * @screen_num: the screen number
1376  *
1377  * Returns a screen object for one of the screens of the display.
1378  *
1379  * Returns: (transfer none): the #GdkScreen object
1380  *
1381  * Since: 2.2
1382  */
1383 GdkScreen *
1384 gdk_display_get_screen (GdkDisplay *display,
1385                         gint        screen_num)
1386 {
1387   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1388
1389   return GDK_DISPLAY_GET_CLASS (display)->get_screen (display, screen_num);
1390 }
1391
1392 /**
1393  * gdk_display_get_default_screen:
1394  * @display: a #GdkDisplay
1395  *
1396  * Get the default #GdkScreen for @display.
1397  *
1398  * Returns: (transfer none): the default #GdkScreen object for @display
1399  *
1400  * Since: 2.2
1401  */
1402 GdkScreen *
1403 gdk_display_get_default_screen (GdkDisplay *display)
1404 {
1405   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1406
1407   return GDK_DISPLAY_GET_CLASS (display)->get_default_screen (display);
1408 }
1409
1410 /**
1411  * gdk_display_beep:
1412  * @display: a #GdkDisplay
1413  *
1414  * Emits a short beep on @display
1415  *
1416  * Since: 2.2
1417  */
1418 void
1419 gdk_display_beep (GdkDisplay *display)
1420 {
1421   g_return_if_fail (GDK_IS_DISPLAY (display));
1422
1423   GDK_DISPLAY_GET_CLASS (display)->beep (display);
1424 }
1425
1426 /**
1427  * gdk_display_sync:
1428  * @display: a #GdkDisplay
1429  *
1430  * Flushes any requests queued for the windowing system and waits until all
1431  * requests have been handled. This is often used for making sure that the
1432  * display is synchronized with the current state of the program. Calling
1433  * gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors
1434  * generated from earlier requests are handled before the error trap is
1435  * removed.
1436  *
1437  * This is most useful for X11. On windowing systems where requests are
1438  * handled synchronously, this function will do nothing.
1439  *
1440  * Since: 2.2
1441  */
1442 void
1443 gdk_display_sync (GdkDisplay *display)
1444 {
1445   g_return_if_fail (GDK_IS_DISPLAY (display));
1446
1447   GDK_DISPLAY_GET_CLASS (display)->sync (display);
1448 }
1449
1450 /**
1451  * gdk_display_flush:
1452  * @display: a #GdkDisplay
1453  *
1454  * Flushes any requests queued for the windowing system; this happens automatically
1455  * when the main loop blocks waiting for new events, but if your application
1456  * is drawing without returning control to the main loop, you may need
1457  * to call this function explicitely. A common case where this function
1458  * needs to be called is when an application is executing drawing commands
1459  * from a thread other than the thread where the main loop is running.
1460  *
1461  * This is most useful for X11. On windowing systems where requests are
1462  * handled synchronously, this function will do nothing.
1463  *
1464  * Since: 2.4
1465  */
1466 void
1467 gdk_display_flush (GdkDisplay *display)
1468 {
1469   g_return_if_fail (GDK_IS_DISPLAY (display));
1470
1471   GDK_DISPLAY_GET_CLASS (display)->flush (display);
1472 }
1473
1474 /**
1475  * gdk_display_get_default_group:
1476  * @display: a #GdkDisplay
1477  *
1478  * Returns the default group leader window for all toplevel windows
1479  * on @display. This window is implicitly created by GDK.
1480  * See gdk_window_set_group().
1481  *
1482  * Return value: (transfer none): The default group leader window
1483  * for @display
1484  *
1485  * Since: 2.4
1486  **/
1487 GdkWindow *
1488 gdk_display_get_default_group (GdkDisplay *display)
1489 {
1490   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1491
1492   return GDK_DISPLAY_GET_CLASS (display)->get_default_group (display);
1493 }
1494
1495 /**
1496  * gdk_display_supports_selection_notification:
1497  * @display: a #GdkDisplay
1498  *
1499  * Returns whether #GdkEventOwnerChange events will be
1500  * sent when the owner of a selection changes.
1501  *
1502  * Return value: whether #GdkEventOwnerChange events will
1503  *               be sent.
1504  *
1505  * Since: 2.6
1506  **/
1507 gboolean
1508 gdk_display_supports_selection_notification (GdkDisplay *display)
1509 {
1510   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1511
1512   return GDK_DISPLAY_GET_CLASS (display)->supports_selection_notification (display);
1513 }
1514
1515 /**
1516  * gdk_display_request_selection_notification:
1517  * @display: a #GdkDisplay
1518  * @selection: the #GdkAtom naming the selection for which
1519  *             ownership change notification is requested
1520  *
1521  * Request #GdkEventOwnerChange events for ownership changes
1522  * of the selection named by the given atom.
1523  *
1524  * Return value: whether #GdkEventOwnerChange events will
1525  *               be sent.
1526  *
1527  * Since: 2.6
1528  **/
1529 gboolean
1530 gdk_display_request_selection_notification (GdkDisplay *display,
1531                                             GdkAtom     selection)
1532
1533 {
1534   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1535
1536   return GDK_DISPLAY_GET_CLASS (display)->request_selection_notification (display, selection);
1537 }
1538
1539 /**
1540  * gdk_display_supports_clipboard_persistence
1541  * @display: a #GdkDisplay
1542  *
1543  * Returns whether the speicifed display supports clipboard
1544  * persistance; i.e. if it's possible to store the clipboard data after an
1545  * application has quit. On X11 this checks if a clipboard daemon is
1546  * running.
1547  *
1548  * Returns: %TRUE if the display supports clipboard persistance.
1549  *
1550  * Since: 2.6
1551  */
1552 gboolean
1553 gdk_display_supports_clipboard_persistence (GdkDisplay *display)
1554 {
1555   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1556
1557   return GDK_DISPLAY_GET_CLASS (display)->supports_clipboard_persistence (display);
1558 }
1559
1560 /**
1561  * gdk_display_store_clipboard
1562  * @display:          a #GdkDisplay
1563  * @clipboard_window: a #GdkWindow belonging to the clipboard owner
1564  * @time_:            a timestamp
1565  * @targets:          (array length=n_targets): an array of targets
1566  *                    that should be saved, or %NULL
1567  *                    if all available targets should be saved.
1568  * @n_targets:        length of the @targets array
1569  *
1570  * Issues a request to the clipboard manager to store the
1571  * clipboard data. On X11, this is a special program that works
1572  * according to the freedesktop clipboard specification, available at
1573  * <ulink url="http://www.freedesktop.org/Standards/clipboard-manager-spec">
1574  * http://www.freedesktop.org/Standards/clipboard-manager-spec</ulink>.
1575  *
1576  * Since: 2.6
1577  */
1578 void
1579 gdk_display_store_clipboard (GdkDisplay    *display,
1580                              GdkWindow     *clipboard_window,
1581                              guint32        time_,
1582                              const GdkAtom *targets,
1583                              gint           n_targets)
1584 {
1585   g_return_if_fail (GDK_IS_DISPLAY (display));
1586
1587   GDK_DISPLAY_GET_CLASS (display)->store_clipboard (display, clipboard_window, time_, targets, n_targets);
1588 }
1589
1590 /**
1591  * gdk_display_supports_shapes:
1592  * @display: a #GdkDisplay
1593  *
1594  * Returns %TRUE if gdk_window_shape_combine_mask() can
1595  * be used to create shaped windows on @display.
1596  *
1597  * Returns: %TRUE if shaped windows are supported
1598  *
1599  * Since: 2.10
1600  */
1601 gboolean
1602 gdk_display_supports_shapes (GdkDisplay *display)
1603 {
1604   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1605
1606   return GDK_DISPLAY_GET_CLASS (display)->supports_shapes (display);
1607 }
1608
1609 /**
1610  * gdk_display_supports_input_shapes:
1611  * @display: a #GdkDisplay
1612  *
1613  * Returns %TRUE if gdk_window_input_shape_combine_mask() can
1614  * be used to modify the input shape of windows on @display.
1615  *
1616  * Returns: %TRUE if windows with modified input shape are supported
1617  *
1618  * Since: 2.10
1619  */
1620 gboolean
1621 gdk_display_supports_input_shapes (GdkDisplay *display)
1622 {
1623   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1624
1625   return GDK_DISPLAY_GET_CLASS (display)->supports_input_shapes (display);
1626 }
1627
1628 /**
1629  * gdk_display_supports_composite:
1630  * @display: a #GdkDisplay
1631  *
1632  * Returns %TRUE if gdk_window_set_composited() can be used
1633  * to redirect drawing on the window using compositing.
1634  *
1635  * Currently this only works on X11 with XComposite and
1636  * XDamage extensions available.
1637  *
1638  * Returns: %TRUE if windows may be composited.
1639  *
1640  * Since: 2.12
1641  */
1642 gboolean
1643 gdk_display_supports_composite (GdkDisplay *display)
1644 {
1645   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1646
1647   return GDK_DISPLAY_GET_CLASS (display)->supports_composite (display);
1648 }
1649
1650 /**
1651  * gdk_display_list_devices:
1652  * @display: a #GdkDisplay
1653  *
1654  * Returns the list of available input devices attached to @display.
1655  * The list is statically allocated and should not be freed.
1656  *
1657  * Return value: (transfer none) (element-type GdkDevice):
1658  *     a list of #GdkDevice
1659  *
1660  * Since: 2.2
1661  *
1662  * Deprecated: 3.0: Use gdk_device_manager_list_devices() instead.
1663  **/
1664 GList *
1665 gdk_display_list_devices (GdkDisplay *display)
1666 {
1667   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1668
1669   return GDK_DISPLAY_GET_CLASS (display)->list_devices (display);
1670 }
1671
1672 static GdkAppLaunchContext *
1673 gdk_display_real_get_app_launch_context (GdkDisplay *display)
1674 {
1675   GdkAppLaunchContext *ctx;
1676
1677   ctx = g_object_new (GDK_TYPE_APP_LAUNCH_CONTEXT,
1678                       "display", display,
1679                       NULL);
1680
1681   return ctx;
1682 }
1683
1684 /**
1685  * gdk_display_get_app_launch_context:
1686  * @display: a #GdkDisplay
1687  *
1688  * Returns a #GdkAppLaunchContext suitable for launching
1689  * applications on the given display.
1690  *
1691  * Returns: (transfer full): a new #GdkAppLaunchContext for @display.
1692  *     Free with g_object_unref() when done
1693  *
1694  * Since: 3.0
1695  */
1696 GdkAppLaunchContext *
1697 gdk_display_get_app_launch_context (GdkDisplay *display)
1698 {
1699   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1700
1701   return GDK_DISPLAY_GET_CLASS (display)->get_app_launch_context (display);
1702 }
1703
1704 /**
1705  * gdk_display_open:
1706  * @display_name: the name of the display to open
1707  *
1708  * Opens a display.
1709  *
1710  * Return value: (transfer none): a #GdkDisplay, or %NULL
1711  *     if the display could not be opened
1712  *
1713  * Since: 2.2
1714  */
1715 GdkDisplay *
1716 gdk_display_open (const gchar *display_name)
1717 {
1718   return gdk_display_manager_open_display (gdk_display_manager_get (),
1719                                            display_name);
1720 }
1721
1722 /**
1723  * gdk_display_has_pending:
1724  * @display: a #GdkDisplay
1725  *
1726  * Returns whether the display has events that are waiting
1727  * to be processed.
1728  *
1729  * Returns: %TRUE if there are events ready to be processed.
1730  *
1731  * Since: 3.0
1732  */
1733 gboolean
1734 gdk_display_has_pending (GdkDisplay *display)
1735 {
1736   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1737
1738   return GDK_DISPLAY_GET_CLASS (display)->has_pending (display);
1739 }
1740
1741 /**
1742  * gdk_display_supports_cursor_alpha:
1743  * @display: a #GdkDisplay
1744  *
1745  * Returns %TRUE if cursors can use an 8bit alpha channel
1746  * on @display. Otherwise, cursors are restricted to bilevel
1747  * alpha (i.e. a mask).
1748  *
1749  * Returns: whether cursors can have alpha channels.
1750  *
1751  * Since: 2.4
1752  */
1753 gboolean
1754 gdk_display_supports_cursor_alpha (GdkDisplay *display)
1755 {
1756   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1757
1758   return GDK_DISPLAY_GET_CLASS (display)->supports_cursor_alpha (display);
1759 }
1760
1761 /**
1762  * gdk_display_supports_cursor_color:
1763  * @display: a #GdkDisplay
1764  *
1765  * Returns %TRUE if multicolored cursors are supported
1766  * on @display. Otherwise, cursors have only a forground
1767  * and a background color.
1768  *
1769  * Returns: whether cursors can have multiple colors.
1770  *
1771  * Since: 2.4
1772  */
1773 gboolean
1774 gdk_display_supports_cursor_color (GdkDisplay *display)
1775 {
1776   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1777
1778   return GDK_DISPLAY_GET_CLASS (display)->supports_cursor_color (display);
1779 }
1780
1781 /**
1782  * gdk_display_get_default_cursor_size:
1783  * @display: a #GdkDisplay
1784  *
1785  * Returns the default size to use for cursors on @display.
1786  *
1787  * Returns: the default cursor size.
1788  *
1789  * Since: 2.4
1790  */
1791 guint
1792 gdk_display_get_default_cursor_size (GdkDisplay *display)
1793 {
1794   guint width, height;
1795
1796   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
1797
1798   GDK_DISPLAY_GET_CLASS (display)->get_default_cursor_size (display,
1799                                                             &width,
1800                                                             &height);
1801
1802   return MIN (width, height);
1803 }
1804
1805 /**
1806  * gdk_display_get_maximal_cursor_size:
1807  * @display: a #GdkDisplay
1808  * @width: (out): the return location for the maximal cursor width
1809  * @height: (out): the return location for the maximal cursor height
1810  *
1811  * Gets the maximal size to use for cursors on @display.
1812  *
1813  * Since: 2.4
1814  */
1815 void
1816 gdk_display_get_maximal_cursor_size (GdkDisplay *display,
1817                                      guint       *width,
1818                                      guint       *height)
1819 {
1820   g_return_if_fail (GDK_IS_DISPLAY (display));
1821
1822   GDK_DISPLAY_GET_CLASS (display)->get_maximal_cursor_size (display,
1823                                                             width,
1824                                                             height);
1825 }
1826
1827 /**
1828  * gdk_display_warp_pointer:
1829  * @display: a #GdkDisplay
1830  * @screen: the screen of @display to warp the pointer to
1831  * @x: the x coordinate of the destination
1832  * @y: the y coordinate of the destination
1833  *
1834  * Warps the pointer of @display to the point @x,@y on
1835  * the screen @screen, unless the pointer is confined
1836  * to a window by a grab, in which case it will be moved
1837  * as far as allowed by the grab. Warping the pointer
1838  * creates events as if the user had moved the mouse
1839  * instantaneously to the destination.
1840  *
1841  * Note that the pointer should normally be under the
1842  * control of the user. This function was added to cover
1843  * some rare use cases like keyboard navigation support
1844  * for the color picker in the #GtkColorSelectionDialog.
1845  *
1846  * Since: 2.8
1847  *
1848  * Deprecated: 3.0: Use gdk_device_warp() instead.
1849  */
1850 void
1851 gdk_display_warp_pointer (GdkDisplay *display,
1852                           GdkScreen  *screen,
1853                           gint        x,
1854                           gint        y)
1855 {
1856   g_return_if_fail (GDK_IS_DISPLAY (display));
1857
1858   gdk_device_warp (display->core_pointer,
1859                    screen,
1860                    x, y);
1861 }
1862
1863 gulong
1864 _gdk_display_get_next_serial (GdkDisplay *display)
1865 {
1866   return GDK_DISPLAY_GET_CLASS (display)->get_next_serial (display);
1867 }
1868
1869
1870 /**
1871  * gdk_notify_startup_complete:
1872  *
1873  * Indicates to the GUI environment that the application has finished
1874  * loading. If the applications opens windows, this function is
1875  * normally called after opening the application's initial set of
1876  * windows.
1877  *
1878  * GTK+ will call this function automatically after opening the first
1879  * #GtkWindow unless gtk_window_set_auto_startup_notification() is called
1880  * to disable that feature.
1881  *
1882  * Since: 2.2
1883  **/
1884 void
1885 gdk_notify_startup_complete (void)
1886 {
1887   gdk_notify_startup_complete_with_id (NULL);
1888 }
1889
1890 /**
1891  * gdk_notify_startup_complete_with_id:
1892  * @startup_id: a startup-notification identifier, for which
1893  *     notification process should be completed
1894  *
1895  * Indicates to the GUI environment that the application has
1896  * finished loading, using a given identifier.
1897  *
1898  * GTK+ will call this function automatically for #GtkWindow
1899  * with custom startup-notification identifier unless
1900  * gtk_window_set_auto_startup_notification() is called to
1901  * disable that feature.
1902  *
1903  * Since: 2.12
1904  */
1905 void
1906 gdk_notify_startup_complete_with_id (const gchar* startup_id)
1907 {
1908   GdkDisplay *display;
1909
1910   display = gdk_display_get_default ();
1911   if (display)
1912     gdk_display_notify_startup_complete (display, startup_id);
1913 }
1914
1915 /**
1916  * gdk_display_notify_startup_complete:
1917  * @display: a #GdkDisplay
1918  * @startup_id: a startup-notification identifier, for which
1919  *     notification process should be completed
1920  *
1921  * Indicates to the GUI environment that the application has
1922  * finished loading, using a given identifier.
1923  *
1924  * GTK+ will call this function automatically for #GtkWindow
1925  * with custom startup-notification identifier unless
1926  * gtk_window_set_auto_startup_notification() is called to
1927  * disable that feature.
1928  *
1929  * Since: 3.0
1930  */
1931 void
1932 gdk_display_notify_startup_complete (GdkDisplay  *display,
1933                                      const gchar *startup_id)
1934 {
1935   g_return_if_fail (GDK_IS_DISPLAY (display));
1936
1937   GDK_DISPLAY_GET_CLASS (display)->notify_startup_complete (display, startup_id);
1938 }
1939
1940 void
1941 _gdk_display_event_data_copy (GdkDisplay     *display,
1942                               const GdkEvent *event,
1943                               GdkEvent       *new_event)
1944 {
1945   GDK_DISPLAY_GET_CLASS (display)->event_data_copy (display, event, new_event);
1946 }
1947
1948 void
1949 _gdk_display_event_data_free (GdkDisplay *display,
1950                               GdkEvent   *event)
1951 {
1952   GDK_DISPLAY_GET_CLASS (display)->event_data_free (display, event);
1953 }
1954
1955 void
1956 _gdk_display_create_window_impl (GdkDisplay       *display,
1957                                  GdkWindow        *window,
1958                                  GdkWindow        *real_parent,
1959                                  GdkScreen        *screen,
1960                                  GdkEventMask      event_mask,
1961                                  GdkWindowAttr    *attributes,
1962                                  gint              attributes_mask)
1963 {
1964   GDK_DISPLAY_GET_CLASS (display)->create_window_impl (display,
1965                                                        window,
1966                                                        real_parent,
1967                                                        screen,
1968                                                        event_mask,
1969                                                        attributes,
1970                                                        attributes_mask);
1971 }
1972
1973 GdkWindow *
1974 _gdk_display_create_window (GdkDisplay *display)
1975 {
1976   return g_object_new (GDK_DISPLAY_GET_CLASS (display)->window_type, NULL);
1977 }
1978
1979 /**
1980  * gdk_keymap_get_for_display:
1981  * @display: the #GdkDisplay.
1982  *
1983  * Returns the #GdkKeymap attached to @display.
1984  *
1985  * Return value: (transfer none): the #GdkKeymap attached to @display.
1986  *
1987  * Since: 2.2
1988  */
1989 GdkKeymap*
1990 gdk_keymap_get_for_display (GdkDisplay *display)
1991 {
1992   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1993
1994   return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
1995 }
1996
1997 typedef struct _GdkGlobalErrorTrap  GdkGlobalErrorTrap;
1998
1999 struct _GdkGlobalErrorTrap
2000 {
2001   GSList *displays;
2002 };
2003
2004 static GQueue gdk_error_traps = G_QUEUE_INIT;
2005
2006 /**
2007  * gdk_error_trap_push:
2008  *
2009  * This function allows X errors to be trapped instead of the normal
2010  * behavior of exiting the application. It should only be used if it
2011  * is not possible to avoid the X error in any other way. Errors are
2012  * ignored on all #GdkDisplay currently known to the
2013  * #GdkDisplayManager. If you don't care which error happens and just
2014  * want to ignore everything, pop with gdk_error_trap_pop_ignored().
2015  * If you need the error code, use gdk_error_trap_pop() which may have
2016  * to block and wait for the error to arrive from the X server.
2017  *
2018  * This API exists on all platforms but only does anything on X.
2019  *
2020  * You can use gdk_x11_display_error_trap_push() to ignore errors
2021  * on only a single display.
2022  *
2023 * <example>
2024  * <title>Trapping an X error</title>
2025  * <programlisting>
2026  * gdk_error_trap_push (<!-- -->);
2027  *
2028  *  // ... Call the X function which may cause an error here ...
2029  *
2030  *
2031  * if (gdk_error_trap_pop (<!-- -->))
2032  *  {
2033  *    // ... Handle the error here ...
2034  *  }
2035  * </programlisting>
2036  * </example>
2037  */
2038 void
2039 gdk_error_trap_push (void)
2040 {
2041   GdkDisplayManager *manager;
2042   GdkDisplayClass *class;
2043   GdkGlobalErrorTrap *trap;
2044   GSList *l;
2045
2046   manager = gdk_display_manager_get ();
2047   class = GDK_DISPLAY_GET_CLASS (gdk_display_manager_get_default_display (manager));
2048
2049   if (class->push_error_trap == NULL)
2050     return;
2051
2052   trap = g_slice_new (GdkGlobalErrorTrap);
2053   trap->displays = gdk_display_manager_list_displays (manager);
2054
2055   g_slist_foreach (trap->displays, (GFunc) g_object_ref, NULL);
2056   for (l = trap->displays; l != NULL; l = l->next)
2057     {
2058       class->push_error_trap (l->data);
2059     }
2060
2061   g_queue_push_head (&gdk_error_traps, trap);
2062 }
2063
2064 static gint
2065 gdk_error_trap_pop_internal (gboolean need_code)
2066 {
2067   GdkDisplayManager *manager;
2068   GdkDisplayClass *class;
2069   GdkGlobalErrorTrap *trap;
2070   gint result;
2071   GSList *l;
2072
2073   manager = gdk_display_manager_get ();
2074   class = GDK_DISPLAY_GET_CLASS (gdk_display_manager_get_default_display (manager));
2075
2076   if (class->pop_error_trap == NULL)
2077     return 0;
2078
2079   trap = g_queue_pop_head (&gdk_error_traps);
2080
2081   g_return_val_if_fail (trap != NULL, 0);
2082
2083   result = 0;
2084   for (l = trap->displays; l != NULL; l = l->next)
2085     {
2086       gint code = 0;
2087
2088       code = class->pop_error_trap (l->data, !need_code);
2089
2090       /* we use the error on the last display listed, why not. */
2091       if (code != 0)
2092         result = code;
2093     }
2094
2095   g_slist_free_full (trap->displays, g_object_unref);
2096   g_slice_free (GdkGlobalErrorTrap, trap);
2097
2098   return result;
2099 }
2100
2101 /**
2102  * gdk_error_trap_pop_ignored:
2103  *
2104  * Removes an error trap pushed with gdk_error_trap_push(), but
2105  * without bothering to wait and see whether an error occurred.  If an
2106  * error arrives later asynchronously that was triggered while the
2107  * trap was pushed, that error will be ignored.
2108  *
2109  * Since: 3.0
2110  */
2111 void
2112 gdk_error_trap_pop_ignored (void)
2113 {
2114   gdk_error_trap_pop_internal (FALSE);
2115 }
2116
2117 /**
2118  * gdk_error_trap_pop:
2119  *
2120  * Removes an error trap pushed with gdk_error_trap_push().
2121  * May block until an error has been definitively received
2122  * or not received from the X server. gdk_error_trap_pop_ignored()
2123  * is preferred if you don't need to know whether an error
2124  * occurred, because it never has to block. If you don't
2125  * need the return value of gdk_error_trap_pop(), use
2126  * gdk_error_trap_pop_ignored().
2127  *
2128  * Prior to GDK 3.0, this function would not automatically
2129  * sync for you, so you had to gdk_flush() if your last
2130  * call to Xlib was not a blocking round trip.
2131  *
2132  * Return value: X error code or 0 on success
2133  */
2134 gint
2135 gdk_error_trap_pop (void)
2136 {
2137   return gdk_error_trap_pop_internal (TRUE);
2138 }