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