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