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