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