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