]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkdisplay-x11.c
x11: Rename GdkScreenX11 to GdkX11Screen
[~andy/gtk] / gdk / x11 / gdkdisplay-x11.c
1 /* GDK - The GIMP Drawing Kit
2  * gdkdisplay-x11.c
3  * 
4  * Copyright 2001 Sun Microsystems Inc.
5  * Copyright (C) 2004 Nokia Corporation
6  *
7  * Erwann Chenede <erwann.chenede@sun.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #include "config.h"
26
27 #include "gdkasync.h"
28 #include "gdkdisplay.h"
29 #include "gdkeventsource.h"
30 #include "gdkeventtranslator.h"
31 #include "gdkinternals.h"
32 #include "gdkscreen.h"
33 #include "gdkinternals.h"
34 #include "gdkdeviceprivate.h"
35 #include "gdkkeysprivate.h"
36 #include "gdkdevicemanager.h"
37 #include "xsettings-client.h"
38 #include "gdkdisplay-x11.h"
39 #include "gdkprivate-x11.h"
40 #include "gdkscreen-x11.h"
41
42 #include <glib.h>
43 #include <glib/gprintf.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <unistd.h>
48
49 #include <X11/Xatom.h>
50
51 #ifdef HAVE_XKB
52 #include <X11/XKBlib.h>
53 #endif
54
55 #ifdef HAVE_XFIXES
56 #include <X11/extensions/Xfixes.h>
57 #endif
58
59 #include <X11/extensions/shape.h>
60
61 #ifdef HAVE_XCOMPOSITE
62 #include <X11/extensions/Xcomposite.h>
63 #endif
64
65 #ifdef HAVE_XDAMAGE
66 #include <X11/extensions/Xdamage.h>
67 #endif
68
69 #ifdef HAVE_RANDR
70 #include <X11/extensions/Xrandr.h>
71 #endif
72
73 typedef struct _GdkErrorTrap  GdkErrorTrap;
74
75 struct _GdkErrorTrap
76 {
77   /* Next sequence when trap was pushed, i.e. first sequence to
78    * ignore
79    */
80   gulong start_sequence;
81
82   /* Next sequence when trap was popped, i.e. first sequence
83    * to not ignore. 0 if trap is still active.
84    */
85   gulong end_sequence;
86
87   /* Most recent error code within the sequence */
88   int error_code;
89 };
90
91 static void   gdk_x11_display_dispose            (GObject            *object);
92 static void   gdk_x11_display_finalize           (GObject            *object);
93
94 static void     gdk_x11_display_event_translator_init (GdkEventTranslatorIface *iface);
95
96 static gboolean gdk_x11_display_translate_event (GdkEventTranslator *translator,
97                                                  GdkDisplay         *display,
98                                                  GdkEvent           *event,
99                                                  XEvent             *xevent);
100
101 #ifdef HAVE_X11R6
102 static void gdk_internal_connection_watch (Display  *display,
103                                            XPointer  arg,
104                                            gint      fd,
105                                            gboolean  opening,
106                                            XPointer *watch_data);
107 #endif /* HAVE_X11R6 */
108
109 typedef struct _GdkEventTypeX11 GdkEventTypeX11;
110
111 struct _GdkEventTypeX11
112 {
113   gint base;
114   gint n_events;
115 };
116
117 /* Note that we never *directly* use WM_LOCALE_NAME, WM_PROTOCOLS,
118  * but including them here has the side-effect of getting them
119  * into the internal Xlib cache
120  */
121 static const char *const precache_atoms[] = {
122   "UTF8_STRING",
123   "WM_CLIENT_LEADER",
124   "WM_DELETE_WINDOW",
125   "WM_ICON_NAME",
126   "WM_LOCALE_NAME",
127   "WM_NAME",
128   "WM_PROTOCOLS",
129   "WM_TAKE_FOCUS",
130   "WM_WINDOW_ROLE",
131   "_NET_ACTIVE_WINDOW",
132   "_NET_CURRENT_DESKTOP",
133   "_NET_FRAME_EXTENTS",
134   "_NET_STARTUP_ID",
135   "_NET_WM_CM_S0",
136   "_NET_WM_DESKTOP",
137   "_NET_WM_ICON",
138   "_NET_WM_ICON_NAME",
139   "_NET_WM_NAME",
140   "_NET_WM_PID",
141   "_NET_WM_PING",
142   "_NET_WM_STATE",
143   "_NET_WM_STATE_ABOVE",
144   "_NET_WM_STATE_BELOW",
145   "_NET_WM_STATE_FULLSCREEN",
146   "_NET_WM_STATE_MODAL",
147   "_NET_WM_STATE_MAXIMIZED_VERT",
148   "_NET_WM_STATE_MAXIMIZED_HORZ",
149   "_NET_WM_STATE_SKIP_TASKBAR",
150   "_NET_WM_STATE_SKIP_PAGER",
151   "_NET_WM_STATE_STICKY",
152   "_NET_WM_SYNC_REQUEST",
153   "_NET_WM_SYNC_REQUEST_COUNTER",
154   "_NET_WM_WINDOW_TYPE",
155   "_NET_WM_WINDOW_TYPE_NORMAL",
156   "_NET_WM_USER_TIME",
157   "_NET_VIRTUAL_ROOTS",
158   "GDK_SELECTION"
159 };
160
161 static char *gdk_sm_client_id;
162
163 G_DEFINE_TYPE_WITH_CODE (GdkX11Display, gdk_x11_display, GDK_TYPE_DISPLAY,
164                          G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
165                                                 gdk_x11_display_event_translator_init))
166
167
168 static void
169 gdk_x11_display_init (GdkX11Display *display)
170 {
171   _gdk_x11_display_manager_add_display (gdk_display_manager_get (),
172                                         GDK_DISPLAY (display));
173 }
174
175 static void
176 gdk_x11_display_event_translator_init (GdkEventTranslatorIface *iface)
177 {
178   iface->translate_event = gdk_x11_display_translate_event;
179 }
180
181 static void
182 do_net_wm_state_changes (GdkWindow *window)
183 {
184   GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
185   GdkWindowState old_state;
186
187   if (GDK_WINDOW_DESTROYED (window) ||
188       gdk_window_get_window_type (window) != GDK_WINDOW_TOPLEVEL)
189     return;
190
191   old_state = gdk_window_get_state (window);
192
193   /* For found_sticky to remain TRUE, we have to also be on desktop
194    * 0xFFFFFFFF
195    */
196   if (old_state & GDK_WINDOW_STATE_STICKY)
197     {
198       if (!(toplevel->have_sticky && toplevel->on_all_desktops))
199         gdk_synthesize_window_state (window,
200                                      GDK_WINDOW_STATE_STICKY,
201                                      0);
202     }
203   else
204     {
205       if (toplevel->have_sticky || toplevel->on_all_desktops)
206         gdk_synthesize_window_state (window,
207                                      0,
208                                      GDK_WINDOW_STATE_STICKY);
209     }
210
211   if (old_state & GDK_WINDOW_STATE_FULLSCREEN)
212     {
213       if (!toplevel->have_fullscreen)
214         gdk_synthesize_window_state (window,
215                                      GDK_WINDOW_STATE_FULLSCREEN,
216                                      0);
217     }
218   else
219     {
220       if (toplevel->have_fullscreen)
221         gdk_synthesize_window_state (window,
222                                      0,
223                                      GDK_WINDOW_STATE_FULLSCREEN);
224     }
225
226   /* Our "maximized" means both vertical and horizontal; if only one,
227    * we don't expose that via GDK
228    */
229   if (old_state & GDK_WINDOW_STATE_MAXIMIZED)
230     {
231       if (!(toplevel->have_maxvert && toplevel->have_maxhorz))
232         gdk_synthesize_window_state (window,
233                                      GDK_WINDOW_STATE_MAXIMIZED,
234                                      0);
235     }
236   else
237     {
238       if (toplevel->have_maxvert && toplevel->have_maxhorz)
239         gdk_synthesize_window_state (window,
240                                      0,
241                                      GDK_WINDOW_STATE_MAXIMIZED);
242     }
243 }
244
245 static void
246 gdk_check_wm_desktop_changed (GdkWindow *window)
247 {
248   GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
249   GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
250
251   Atom type;
252   gint format;
253   gulong nitems;
254   gulong bytes_after;
255   guchar *data;
256   gulong *desktop;
257
258   type = None;
259   gdk_x11_display_error_trap_push (display);
260   XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
261                       GDK_WINDOW_XID (window),
262                       gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
263                       0, G_MAXLONG, False, XA_CARDINAL, &type,
264                       &format, &nitems,
265                       &bytes_after, &data);
266   gdk_x11_display_error_trap_pop_ignored (display);
267
268   if (type != None)
269     {
270       desktop = (gulong *)data;
271       toplevel->on_all_desktops = (*desktop == 0xFFFFFFFF);
272       XFree (desktop);
273     }
274   else
275     toplevel->on_all_desktops = FALSE;
276
277   do_net_wm_state_changes (window);
278 }
279
280 static void
281 gdk_check_wm_state_changed (GdkWindow *window)
282 {
283   GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
284   GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
285
286   Atom type;
287   gint format;
288   gulong nitems;
289   gulong bytes_after;
290   guchar *data;
291   Atom *atoms = NULL;
292   gulong i;
293
294   gboolean had_sticky = toplevel->have_sticky;
295
296   toplevel->have_sticky = FALSE;
297   toplevel->have_maxvert = FALSE;
298   toplevel->have_maxhorz = FALSE;
299   toplevel->have_fullscreen = FALSE;
300
301   type = None;
302   gdk_x11_display_error_trap_push (display);
303   XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
304                       gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
305                       0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
306                       &bytes_after, &data);
307   gdk_x11_display_error_trap_pop_ignored (display);
308
309   if (type != None)
310     {
311       Atom sticky_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY");
312       Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
313       Atom maxhorz_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
314       Atom fullscreen_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
315
316       atoms = (Atom *)data;
317
318       i = 0;
319       while (i < nitems)
320         {
321           if (atoms[i] == sticky_atom)
322             toplevel->have_sticky = TRUE;
323           else if (atoms[i] == maxvert_atom)
324             toplevel->have_maxvert = TRUE;
325           else if (atoms[i] == maxhorz_atom)
326             toplevel->have_maxhorz = TRUE;
327           else if (atoms[i] == fullscreen_atom)
328             toplevel->have_fullscreen = TRUE;
329
330           ++i;
331         }
332
333       XFree (atoms);
334     }
335
336   /* When have_sticky is turned on, we have to check the DESKTOP property
337    * as well.
338    */
339   if (toplevel->have_sticky && !had_sticky)
340     gdk_check_wm_desktop_changed (window);
341   else
342     do_net_wm_state_changes (window);
343 }
344
345 static GdkWindow *
346 get_event_window (GdkEventTranslator *translator,
347                   XEvent             *xevent)
348 {
349   GdkDisplay *display;
350   Window xwindow;
351
352   display = (GdkDisplay *) translator;
353
354   switch (xevent->type)
355     {
356     case DestroyNotify:
357       xwindow = xevent->xdestroywindow.window;
358       break;
359     case UnmapNotify:
360       xwindow = xevent->xunmap.window;
361       break;
362     case MapNotify:
363       xwindow = xevent->xmap.window;
364       break;
365     case ConfigureNotify:
366       xwindow = xevent->xconfigure.window;
367       break;
368     default:
369       xwindow = xevent->xany.window;
370     }
371
372   return gdk_x11_window_lookup_for_display (display, xwindow);
373 }
374
375 static gboolean
376 gdk_x11_display_translate_event (GdkEventTranslator *translator,
377                                  GdkDisplay         *display,
378                                  GdkEvent           *event,
379                                  XEvent             *xevent)
380 {
381   GdkWindow *window;
382   GdkWindowImplX11 *window_impl = NULL;
383   GdkScreen *screen = NULL;
384   GdkX11Screen *x11_screen = NULL;
385   GdkToplevelX11 *toplevel = NULL;
386   GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
387   gboolean return_val;
388   Window xwindow = None;
389
390   /* Find the GdkWindow that this event relates to.
391    * Basically this means substructure events
392    * are reported same as structure events
393    */
394   window = get_event_window (translator, xevent);
395
396   if (window)
397     {
398       /* We may receive events such as NoExpose/GraphicsExpose
399        * and ShmCompletion for pixmaps
400        */
401       if (!GDK_IS_WINDOW (window))
402         return FALSE;
403
404       screen = GDK_WINDOW_SCREEN (window);
405       x11_screen = GDK_X11_SCREEN (screen);
406       toplevel = _gdk_x11_window_get_toplevel (window);
407       window_impl = GDK_WINDOW_IMPL_X11 (window->impl);
408       xwindow = GDK_WINDOW_XID (window);
409
410       g_object_ref (window);
411     }
412
413   event->any.window = window;
414   event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
415
416   if (window && GDK_WINDOW_DESTROYED (window))
417     {
418       if (xevent->type != DestroyNotify)
419         {
420           return_val = FALSE;
421           goto done;
422         }
423     }
424
425   if (xevent->type == DestroyNotify)
426     {
427       int i, n;
428
429       n = gdk_display_get_n_screens (display);
430       for (i = 0; i < n; i++)
431         {
432           screen = gdk_display_get_screen (display, i);
433           x11_screen = GDK_X11_SCREEN (screen);
434
435           if (x11_screen->wmspec_check_window == xwindow)
436             {
437               x11_screen->wmspec_check_window = None;
438               x11_screen->last_wmspec_check_time = 0;
439               g_free (x11_screen->window_manager_name);
440               x11_screen->window_manager_name = g_strdup ("unknown");
441
442               /* careful, reentrancy */
443               _gdk_x11_screen_window_manager_changed (screen);
444
445               return_val = FALSE;
446               goto done;
447             }
448         }
449     }
450
451   /* We do a "manual" conversion of the XEvent to a
452    *  GdkEvent. The structures are mostly the same so
453    *  the conversion is fairly straightforward. We also
454    *  optionally print debugging info regarding events
455    *  received.
456    */
457
458   return_val = TRUE;
459
460   switch (xevent->type)
461     {
462     case KeymapNotify:
463       GDK_NOTE (EVENTS,
464                 g_message ("keymap notify"));
465
466       /* Not currently handled */
467       return_val = FALSE;
468       break;
469
470     case Expose:
471       GDK_NOTE (EVENTS,
472                 g_message ("expose:\t\twindow: %ld  %d  x,y: %d %d  w,h: %d %d%s",
473                            xevent->xexpose.window, xevent->xexpose.count,
474                            xevent->xexpose.x, xevent->xexpose.y,
475                            xevent->xexpose.width, xevent->xexpose.height,
476                            event->any.send_event ? " (send)" : ""));
477
478       if (window == NULL)
479         {
480           return_val = FALSE;
481           break;
482         }
483
484       {
485         GdkRectangle expose_rect;
486
487         expose_rect.x = xevent->xexpose.x;
488         expose_rect.y = xevent->xexpose.y;
489         expose_rect.width = xevent->xexpose.width;
490         expose_rect.height = xevent->xexpose.height;
491
492         _gdk_x11_window_process_expose (window, xevent->xexpose.serial, &expose_rect);
493         return_val = FALSE;
494       }
495
496       break;
497
498     case GraphicsExpose:
499       {
500         GdkRectangle expose_rect;
501
502         GDK_NOTE (EVENTS,
503                   g_message ("graphics expose:\tdrawable: %ld",
504                              xevent->xgraphicsexpose.drawable));
505
506         if (window == NULL)
507           {
508             return_val = FALSE;
509             break;
510           }
511
512         expose_rect.x = xevent->xgraphicsexpose.x;
513         expose_rect.y = xevent->xgraphicsexpose.y;
514         expose_rect.width = xevent->xgraphicsexpose.width;
515         expose_rect.height = xevent->xgraphicsexpose.height;
516
517         _gdk_x11_window_process_expose (window, xevent->xgraphicsexpose.serial, &expose_rect);
518         return_val = FALSE;
519       }
520       break;
521
522     case VisibilityNotify:
523 #ifdef G_ENABLE_DEBUG
524       if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
525         switch (xevent->xvisibility.state)
526           {
527           case VisibilityFullyObscured:
528             g_message ("visibility notify:\twindow: %ld  none",
529                        xevent->xvisibility.window);
530             break;
531           case VisibilityPartiallyObscured:
532             g_message ("visibility notify:\twindow: %ld  partial",
533                        xevent->xvisibility.window);
534             break;
535           case VisibilityUnobscured:
536             g_message ("visibility notify:\twindow: %ld  full",
537                        xevent->xvisibility.window);
538             break;
539           }
540 #endif /* G_ENABLE_DEBUG */
541
542       if (window == NULL)
543         {
544           return_val = FALSE;
545           break;
546         }
547
548       event->visibility.type = GDK_VISIBILITY_NOTIFY;
549       event->visibility.window = window;
550
551       switch (xevent->xvisibility.state)
552         {
553         case VisibilityFullyObscured:
554           event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED;
555           break;
556
557         case VisibilityPartiallyObscured:
558           event->visibility.state = GDK_VISIBILITY_PARTIAL;
559           break;
560
561         case VisibilityUnobscured:
562           event->visibility.state = GDK_VISIBILITY_UNOBSCURED;
563           break;
564         }
565
566       break;
567
568     case CreateNotify:
569       GDK_NOTE (EVENTS,
570                 g_message ("create notify:\twindow: %ld  x,y: %d %d     w,h: %d %d  b-w: %d  parent: %ld         ovr: %d",
571                            xevent->xcreatewindow.window,
572                            xevent->xcreatewindow.x,
573                            xevent->xcreatewindow.y,
574                            xevent->xcreatewindow.width,
575                            xevent->xcreatewindow.height,
576                            xevent->xcreatewindow.border_width,
577                            xevent->xcreatewindow.parent,
578                            xevent->xcreatewindow.override_redirect));
579       /* not really handled */
580       break;
581
582     case DestroyNotify:
583       GDK_NOTE (EVENTS,
584                 g_message ("destroy notify:\twindow: %ld",
585                            xevent->xdestroywindow.window));
586
587       /* Ignore DestroyNotify from SubstructureNotifyMask */
588       if (xevent->xdestroywindow.window == xevent->xdestroywindow.event)
589         {
590           event->any.type = GDK_DESTROY;
591           event->any.window = window;
592
593           return_val = window && !GDK_WINDOW_DESTROYED (window);
594
595           if (window && GDK_WINDOW_XID (window) != x11_screen->xroot_window)
596             gdk_window_destroy_notify (window);
597         }
598       else
599         return_val = FALSE;
600
601       break;
602
603     case UnmapNotify:
604       GDK_NOTE (EVENTS,
605                 g_message ("unmap notify:\t\twindow: %ld",
606                            xevent->xmap.window));
607
608       event->any.type = GDK_UNMAP;
609       event->any.window = window;
610
611       /* If we are shown (not withdrawn) and get an unmap, it means we
612        * were iconified in the X sense. If we are withdrawn, and get
613        * an unmap, it means we hid the window ourselves, so we
614        * will have already flipped the iconified bit off.
615        */
616       if (window)
617         {
618           if (GDK_WINDOW_IS_MAPPED (window))
619             gdk_synthesize_window_state (window,
620                                          0,
621                                          GDK_WINDOW_STATE_ICONIFIED);
622
623           _gdk_x11_window_grab_check_unmap (window, xevent->xany.serial);
624         }
625
626       break;
627
628     case MapNotify:
629       GDK_NOTE (EVENTS,
630                 g_message ("map notify:\t\twindow: %ld",
631                            xevent->xmap.window));
632
633       event->any.type = GDK_MAP;
634       event->any.window = window;
635
636       /* Unset iconified if it was set */
637       if (window && (window->state & GDK_WINDOW_STATE_ICONIFIED))
638         gdk_synthesize_window_state (window,
639                                      GDK_WINDOW_STATE_ICONIFIED,
640                                      0);
641
642       break;
643
644     case ReparentNotify:
645       GDK_NOTE (EVENTS,
646                 g_message ("reparent notify:\twindow: %ld  x,y: %d %d  parent: %ld      ovr: %d",
647                            xevent->xreparent.window,
648                            xevent->xreparent.x,
649                            xevent->xreparent.y,
650                            xevent->xreparent.parent,
651                            xevent->xreparent.override_redirect));
652
653       /* Not currently handled */
654       return_val = FALSE;
655       break;
656
657     case ConfigureNotify:
658       GDK_NOTE (EVENTS,
659                 g_message ("configure notify:\twindow: %ld  x,y: %d %d  w,h: %d %d  b-w: %d  above: %ld  ovr: %d%s",
660                            xevent->xconfigure.window,
661                            xevent->xconfigure.x,
662                            xevent->xconfigure.y,
663                            xevent->xconfigure.width,
664                            xevent->xconfigure.height,
665                            xevent->xconfigure.border_width,
666                            xevent->xconfigure.above,
667                            xevent->xconfigure.override_redirect,
668                            !window
669                            ? " (discarding)"
670                            : window->window_type == GDK_WINDOW_CHILD
671                            ? " (discarding child)"
672                            : xevent->xconfigure.event != xevent->xconfigure.window
673                            ? " (discarding substructure)"
674                            : ""));
675       if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
676         {
677           window->width = xevent->xconfigure.width;
678           window->height = xevent->xconfigure.height;
679
680           _gdk_window_update_size (window);
681           _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
682           _gdk_x11_screen_size_changed (screen, xevent);
683         }
684
685 #ifdef HAVE_XSYNC
686       if (toplevel && display_x11->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
687         {
688           toplevel->current_counter_value = toplevel->pending_counter_value;
689           XSyncIntToValue (&toplevel->pending_counter_value, 0);
690         }
691 #endif
692
693     if (!window ||
694           xevent->xconfigure.event != xevent->xconfigure.window ||
695           GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
696           GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
697         return_val = FALSE;
698       else
699         {
700           event->configure.type = GDK_CONFIGURE;
701           event->configure.window = window;
702           event->configure.width = xevent->xconfigure.width;
703           event->configure.height = xevent->xconfigure.height;
704
705           if (!xevent->xconfigure.send_event &&
706               !xevent->xconfigure.override_redirect &&
707               !GDK_WINDOW_DESTROYED (window))
708             {
709               gint tx = 0;
710               gint ty = 0;
711               Window child_window = 0;
712
713               gdk_x11_display_error_trap_push (display);
714               if (XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
715                                          GDK_WINDOW_XID (window),
716                                          x11_screen->xroot_window,
717                                          0, 0,
718                                          &tx, &ty,
719                                          &child_window))
720                 {
721                   event->configure.x = tx;
722                   event->configure.y = ty;
723                 }
724               gdk_x11_display_error_trap_pop_ignored (display);
725             }
726           else
727             {
728               event->configure.x = xevent->xconfigure.x;
729               event->configure.y = xevent->xconfigure.y;
730             }
731           window->x = event->configure.x;
732           window->y = event->configure.y;
733           window->width = xevent->xconfigure.width;
734           window->height = xevent->xconfigure.height;
735
736           _gdk_window_update_size (window);
737           _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
738
739           if (window->resize_count >= 1)
740             {
741               window->resize_count -= 1;
742
743               if (window->resize_count == 0)
744                 _gdk_x11_moveresize_configure_done (display, window);
745             }
746         }
747       break;
748
749     case PropertyNotify:
750       GDK_NOTE (EVENTS,
751                 g_message ("property notify:\twindow: %ld, atom(%ld): %s%s%s",
752                            xevent->xproperty.window,
753                            xevent->xproperty.atom,
754                            "\"",
755                            gdk_x11_get_xatom_name_for_display (display, xevent->xproperty.atom),
756                            "\""));
757
758       if (window == NULL)
759         {
760           return_val = FALSE;
761           break;
762         }
763
764       /* We compare with the serial of the last time we mapped the
765        * window to avoid refetching properties that we set ourselves
766        */
767       if (toplevel &&
768           xevent->xproperty.serial >= toplevel->map_serial)
769         {
770           if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"))
771             gdk_check_wm_state_changed (window);
772
773           if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
774             gdk_check_wm_desktop_changed (window);
775         }
776
777       if (window->event_mask & GDK_PROPERTY_CHANGE_MASK)
778         {
779           event->property.type = GDK_PROPERTY_NOTIFY;
780           event->property.window = window;
781           event->property.atom = gdk_x11_xatom_to_atom_for_display (display, xevent->xproperty.atom);
782           event->property.time = xevent->xproperty.time;
783           event->property.state = xevent->xproperty.state;
784         }
785       else
786         return_val = FALSE;
787
788       break;
789
790     case SelectionClear:
791       GDK_NOTE (EVENTS,
792                 g_message ("selection clear:\twindow: %ld",
793                            xevent->xproperty.window));
794
795       if (_gdk_x11_selection_filter_clear_event (&xevent->xselectionclear))
796         {
797           event->selection.type = GDK_SELECTION_CLEAR;
798           event->selection.window = window;
799           event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionclear.selection);
800           event->selection.time = xevent->xselectionclear.time;
801         }
802       else
803         return_val = FALSE;
804
805       break;
806
807     case SelectionRequest:
808       GDK_NOTE (EVENTS,
809                 g_message ("selection request:\twindow: %ld",
810                            xevent->xproperty.window));
811
812       event->selection.type = GDK_SELECTION_REQUEST;
813       event->selection.window = window;
814       event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection);
815       event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.target);
816       event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.property);
817       event->selection.requestor = xevent->xselectionrequest.requestor;
818       event->selection.time = xevent->xselectionrequest.time;
819
820       break;
821
822     case SelectionNotify:
823       GDK_NOTE (EVENTS,
824                 g_message ("selection notify:\twindow: %ld",
825                            xevent->xproperty.window));
826
827       event->selection.type = GDK_SELECTION_NOTIFY;
828       event->selection.window = window;
829       event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection);
830       event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target);
831       if (xevent->xselection.property == None)
832         event->selection.property = GDK_NONE;
833       else
834         event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property);
835       event->selection.time = xevent->xselection.time;
836
837       break;
838
839     case ColormapNotify:
840       GDK_NOTE (EVENTS,
841                 g_message ("colormap notify:\twindow: %ld",
842                            xevent->xcolormap.window));
843
844       /* Not currently handled */
845       return_val = FALSE;
846       break;
847
848     case ClientMessage:
849       {
850         GList *tmp_list;
851         GdkFilterReturn result = GDK_FILTER_CONTINUE;
852         GdkAtom message_type = gdk_x11_xatom_to_atom_for_display (display, xevent->xclient.message_type);
853
854         GDK_NOTE (EVENTS,
855                   g_message ("client message:\twindow: %ld",
856                              xevent->xclient.window));
857
858         tmp_list = display_x11->client_filters;
859         while (tmp_list)
860           {
861             GdkClientFilter *filter = tmp_list->data;
862             tmp_list = tmp_list->next;
863
864             if (filter->type == message_type)
865               {
866                 result = (*filter->function) (xevent, event, filter->data);
867                 if (result != GDK_FILTER_CONTINUE)
868                   break;
869               }
870           }
871
872         switch (result)
873           {
874           case GDK_FILTER_REMOVE:
875             return_val = FALSE;
876             break;
877           case GDK_FILTER_TRANSLATE:
878             return_val = TRUE;
879             break;
880           case GDK_FILTER_CONTINUE:
881             /* Send unknown ClientMessage's on to Gtk for it to use */
882             if (window == NULL)
883               {
884                 return_val = FALSE;
885               }
886             else
887               {
888                 event->client.type = GDK_CLIENT_EVENT;
889                 event->client.window = window;
890                 event->client.message_type = message_type;
891                 event->client.data_format = xevent->xclient.format;
892                 memcpy(&event->client.data, &xevent->xclient.data,
893                        sizeof(event->client.data));
894               }
895             break;
896           }
897       }
898
899       break;
900
901     case MappingNotify:
902       GDK_NOTE (EVENTS,
903                 g_message ("mapping notify"));
904
905       /* Let XLib know that there is a new keyboard mapping.
906        */
907       XRefreshKeyboardMapping (&xevent->xmapping);
908       _gdk_x11_keymap_keys_changed (display);
909       return_val = FALSE;
910       break;
911
912     default:
913 #ifdef HAVE_XFIXES
914       if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify)
915         {
916           XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
917
918           _gdk_x11_screen_process_owner_change (screen, xevent);
919           
920           event->owner_change.type = GDK_OWNER_CHANGE;
921           event->owner_change.window = window;
922           event->owner_change.owner = selection_notify->owner;
923           event->owner_change.reason = selection_notify->subtype;
924           event->owner_change.selection = 
925             gdk_x11_xatom_to_atom_for_display (display, 
926                                                selection_notify->selection);
927           event->owner_change.time = selection_notify->timestamp;
928           event->owner_change.selection_time = selection_notify->selection_timestamp;
929           
930           return_val = TRUE;
931         }
932       else
933 #endif
934 #ifdef HAVE_RANDR
935       if (xevent->type - display_x11->xrandr_event_base == RRScreenChangeNotify ||
936           xevent->type - display_x11->xrandr_event_base == RRNotify)
937         {
938           if (screen)
939             _gdk_x11_screen_size_changed (screen, xevent);
940         }
941       else
942 #endif
943 #if defined(HAVE_XCOMPOSITE) && defined (HAVE_XDAMAGE) && defined (HAVE_XFIXES)
944       if (display_x11->have_xdamage && window && window->composited &&
945           xevent->type == display_x11->xdamage_event_base + XDamageNotify &&
946           ((XDamageNotifyEvent *) xevent)->damage == window_impl->damage)
947         {
948           XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) xevent;
949           XserverRegion repair;
950           GdkRectangle rect;
951
952           rect.x = window->x + damage_event->area.x;
953           rect.y = window->y + damage_event->area.y;
954           rect.width = damage_event->area.width;
955           rect.height = damage_event->area.height;
956
957           repair = XFixesCreateRegion (display_x11->xdisplay,
958                                        &damage_event->area, 1);
959           XDamageSubtract (display_x11->xdisplay,
960                            window_impl->damage,
961                            repair, None);
962           XFixesDestroyRegion (display_x11->xdisplay, repair);
963
964           if (window->parent != NULL)
965            _gdk_x11_window_process_expose (window->parent,
966                                            damage_event->serial, &rect);
967
968           return_val = TRUE;
969         }
970       else
971 #endif
972 #ifdef HAVE_XKB
973       if (xevent->type == display_x11->xkb_event_type)
974         {
975           XkbEvent *xkb_event = (XkbEvent *) xevent;
976
977           switch (xkb_event->any.xkb_type)
978             {
979             case XkbNewKeyboardNotify:
980             case XkbMapNotify:
981               _gdk_x11_keymap_keys_changed (display);
982
983               return_val = FALSE;
984               break;
985
986             case XkbStateNotify:
987               _gdk_x11_keymap_state_changed (display, xevent);
988               break;
989             }
990         }
991       else
992 #endif
993         return_val = FALSE;
994     }
995
996  done:
997   if (return_val)
998     {
999       if (event->any.window)
1000         g_object_ref (event->any.window);
1001     }
1002   else
1003     {
1004       /* Mark this event as having no resources to be freed */
1005       event->any.window = NULL;
1006       event->any.type = GDK_NOTHING;
1007     }
1008
1009   if (window)
1010     g_object_unref (window);
1011
1012   return return_val;
1013 }
1014
1015 static GdkFilterReturn
1016 gdk_wm_protocols_filter (GdkXEvent *xev,
1017                          GdkEvent  *event,
1018                          gpointer data)
1019 {
1020   XEvent *xevent = (XEvent *)xev;
1021   GdkWindow *win = event->any.window;
1022   GdkDisplay *display;
1023   Atom atom;
1024
1025   if (!win)
1026       return GDK_FILTER_REMOVE;
1027
1028   display = GDK_WINDOW_DISPLAY (win);
1029   atom = (Atom)xevent->xclient.data.l[0];
1030
1031   if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
1032     {
1033   /* The delete window request specifies a window
1034    *  to delete. We don't actually destroy the
1035    *  window because "it is only a request". (The
1036    *  window might contain vital data that the
1037    *  program does not want destroyed). Instead
1038    *  the event is passed along to the program,
1039    *  which should then destroy the window.
1040    */
1041       GDK_NOTE (EVENTS,
1042                 g_message ("delete window:\t\twindow: %ld",
1043                            xevent->xclient.window));
1044
1045       event->any.type = GDK_DELETE;
1046
1047       gdk_x11_window_set_user_time (win, xevent->xclient.data.l[1]);
1048
1049       return GDK_FILTER_TRANSLATE;
1050     }
1051   else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
1052     {
1053       GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
1054
1055       /* There is no way of knowing reliably whether we are viewable;
1056        * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
1057        */
1058       if (toplevel && win->accept_focus)
1059         _gdk_x11_set_input_focus_safe (display, toplevel->focus_window,
1060                                        RevertToParent,
1061                                        xevent->xclient.data.l[1]);
1062
1063       return GDK_FILTER_REMOVE;
1064     }
1065   else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
1066            !_gdk_x11_display_is_root_window (display,
1067                                              xevent->xclient.window))
1068     {
1069       XClientMessageEvent xclient = xevent->xclient;
1070
1071       xclient.window = GDK_WINDOW_XROOTWIN (win);
1072       XSendEvent (GDK_WINDOW_XDISPLAY (win),
1073                   xclient.window,
1074                   False,
1075                   SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xclient);
1076
1077       return GDK_FILTER_REMOVE;
1078     }
1079   else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST") &&
1080            GDK_X11_DISPLAY (display)->use_sync)
1081     {
1082       GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
1083       if (toplevel)
1084         {
1085 #ifdef HAVE_XSYNC
1086           XSyncIntsToValue (&toplevel->pending_counter_value,
1087                             xevent->xclient.data.l[2],
1088                             xevent->xclient.data.l[3]);
1089 #endif
1090         }
1091       return GDK_FILTER_REMOVE;
1092     }
1093
1094   return GDK_FILTER_CONTINUE;
1095 }
1096
1097 static void
1098 gdk_event_init (GdkDisplay *display)
1099 {
1100   GdkX11Display *display_x11;
1101   GdkDeviceManager *device_manager;
1102
1103   display_x11 = GDK_X11_DISPLAY (display);
1104   display_x11->event_source = gdk_x11_event_source_new (display);
1105
1106   gdk_x11_event_source_add_translator ((GdkEventSource *) display_x11->event_source,
1107                                        GDK_EVENT_TRANSLATOR (display));
1108
1109   device_manager = gdk_display_get_device_manager (display);
1110   gdk_x11_event_source_add_translator ((GdkEventSource *) display_x11->event_source,
1111                                         GDK_EVENT_TRANSLATOR (device_manager));
1112
1113   gdk_display_add_client_message_filter (display,
1114                                          gdk_atom_intern_static_string ("WM_PROTOCOLS"),
1115                                          gdk_wm_protocols_filter,
1116                                          NULL);
1117 }
1118
1119 static void
1120 gdk_x11_display_init_input (GdkDisplay *display)
1121 {
1122   GdkX11Display *display_x11;
1123   GdkDeviceManager *device_manager;
1124   GdkDevice *device;
1125   GList *list, *l;
1126
1127   display_x11 = GDK_X11_DISPLAY (display);
1128   device_manager = gdk_display_get_device_manager (display);
1129
1130   /* For backwards compatibility, just add
1131    * floating devices that are not keyboards.
1132    */
1133   list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);
1134
1135   for (l = list; l; l = l->next)
1136     {
1137       device = l->data;
1138
1139       if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
1140         continue;
1141
1142       display_x11->input_devices = g_list_prepend (display_x11->input_devices,
1143                                                    g_object_ref (l->data));
1144     }
1145
1146   g_list_free (list);
1147
1148   /* Now set "core" pointer to the first
1149    * master device that is a pointer.
1150    */
1151   list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
1152
1153   for (l = list; l; l = l->next)
1154     {
1155       device = list->data;
1156
1157       if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
1158         continue;
1159
1160       display->core_pointer = device;
1161       break;
1162     }
1163
1164   /* Add the core pointer to the devices list */
1165   display_x11->input_devices = g_list_prepend (display_x11->input_devices,
1166                                                g_object_ref (display->core_pointer));
1167
1168   g_list_free (list);
1169 }
1170
1171 static void
1172 set_sm_client_id (GdkDisplay  *display,
1173                   const gchar *sm_client_id)
1174 {
1175   GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
1176
1177   if (gdk_display_is_closed (display))
1178     return;
1179
1180   if (sm_client_id && strcmp (sm_client_id, ""))
1181     XChangeProperty (display_x11->xdisplay, display_x11->leader_window,
1182                      gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"),
1183                      XA_STRING, 8, PropModeReplace, (guchar *)sm_client_id,
1184                      strlen (sm_client_id));
1185   else
1186     XDeleteProperty (display_x11->xdisplay, display_x11->leader_window,
1187                      gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
1188 }
1189
1190 /**
1191  * gdk_display_open:
1192  * @display_name: the name of the display to open
1193  *
1194  * Opens a display.
1195  *
1196  * Return value: (transfer none): a #GdkDisplay, or %NULL if the display
1197  *               could not be opened.
1198  *
1199  * Since: 2.2
1200  */
1201 GdkDisplay *
1202 _gdk_x11_display_open (const gchar *display_name)
1203 {
1204   Display *xdisplay;
1205   GdkDisplay *display;
1206   GdkX11Display *display_x11;
1207   GdkWindowAttr attr;
1208   gint argc;
1209   gchar *argv[1];
1210
1211   XClassHint *class_hint;
1212   gulong pid;
1213   gint i;
1214   gint ignore;
1215   gint maj, min;
1216
1217   xdisplay = XOpenDisplay (display_name);
1218   if (!xdisplay)
1219     return NULL;
1220   
1221   display = g_object_new (GDK_TYPE_X11_DISPLAY, NULL);
1222   display_x11 = GDK_X11_DISPLAY (display);
1223
1224   display_x11->xdisplay = xdisplay;
1225
1226 #ifdef HAVE_X11R6  
1227   /* Set up handlers for Xlib internal connections */
1228   XAddConnectionWatch (xdisplay, gdk_internal_connection_watch, NULL);
1229 #endif /* HAVE_X11R6 */
1230   
1231   _gdk_x11_precache_atoms (display, precache_atoms, G_N_ELEMENTS (precache_atoms));
1232
1233   /* RandR must be initialized before we initialize the screens */
1234   display_x11->have_randr13 = FALSE;
1235 #ifdef HAVE_RANDR
1236   if (XRRQueryExtension (display_x11->xdisplay,
1237                          &display_x11->xrandr_event_base, &ignore))
1238   {
1239       int major, minor;
1240
1241       XRRQueryVersion (display_x11->xdisplay, &major, &minor);
1242
1243       if ((major == 1 && minor >= 3) || major > 1)
1244           display_x11->have_randr13 = TRUE;
1245
1246        gdk_x11_register_standard_event_type (display, display_x11->xrandr_event_base, RRNumberEvents);
1247   }
1248 #endif
1249
1250   /* initialize the display's screens */ 
1251   display_x11->screens = g_new (GdkScreen *, ScreenCount (display_x11->xdisplay));
1252   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
1253     display_x11->screens[i] = _gdk_x11_screen_new (display, i);
1254
1255   /* We need to initialize events after we have the screen
1256    * structures in places
1257    */
1258   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
1259     _gdk_x11_screen_init_events (display_x11->screens[i]);
1260
1261   /*set the default screen */
1262   display_x11->default_screen = display_x11->screens[DefaultScreen (display_x11->xdisplay)];
1263
1264   display->device_manager = _gdk_x11_device_manager_new (display);
1265
1266   gdk_event_init (display);
1267
1268   attr.window_type = GDK_WINDOW_TOPLEVEL;
1269   attr.wclass = GDK_INPUT_OUTPUT;
1270   attr.x = 10;
1271   attr.y = 10;
1272   attr.width = 10;
1273   attr.height = 10;
1274   attr.event_mask = 0;
1275
1276   display_x11->leader_gdk_window = gdk_window_new (GDK_X11_SCREEN (display_x11->default_screen)->root_window, 
1277                                                    &attr, GDK_WA_X | GDK_WA_Y);
1278   (_gdk_x11_window_get_toplevel (display_x11->leader_gdk_window))->is_leader = TRUE;
1279
1280   display_x11->leader_window = GDK_WINDOW_XID (display_x11->leader_gdk_window);
1281
1282   display_x11->leader_window_title_set = FALSE;
1283
1284 #ifdef HAVE_XFIXES
1285   if (XFixesQueryExtension (display_x11->xdisplay, 
1286                             &display_x11->xfixes_event_base, 
1287                             &ignore))
1288     {
1289       display_x11->have_xfixes = TRUE;
1290
1291       gdk_x11_register_standard_event_type (display,
1292                                             display_x11->xfixes_event_base, 
1293                                             XFixesNumberEvents);
1294     }
1295   else
1296 #endif
1297     display_x11->have_xfixes = FALSE;
1298
1299 #ifdef HAVE_XCOMPOSITE
1300   if (XCompositeQueryExtension (display_x11->xdisplay,
1301                                 &ignore, &ignore))
1302     {
1303       int major, minor;
1304
1305       XCompositeQueryVersion (display_x11->xdisplay, &major, &minor);
1306
1307       /* Prior to Composite version 0.4, composited windows clipped their
1308        * parents, so you had to use IncludeInferiors to draw to the parent
1309        * This isn't useful for our purposes, so require 0.4
1310        */
1311       display_x11->have_xcomposite = major > 0 || (major == 0 && minor >= 4);
1312     }
1313   else
1314 #endif
1315     display_x11->have_xcomposite = FALSE;
1316
1317 #ifdef HAVE_XDAMAGE
1318   if (XDamageQueryExtension (display_x11->xdisplay,
1319                              &display_x11->xdamage_event_base,
1320                              &ignore))
1321     {
1322       display_x11->have_xdamage = TRUE;
1323
1324       gdk_x11_register_standard_event_type (display,
1325                                             display_x11->xdamage_event_base,
1326                                             XDamageNumberEvents);
1327     }
1328   else
1329 #endif
1330     display_x11->have_xdamage = FALSE;
1331
1332   display_x11->have_shapes = FALSE;
1333   display_x11->have_input_shapes = FALSE;
1334
1335   if (XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display), &display_x11->shape_event_base, &ignore))
1336     {
1337       display_x11->have_shapes = TRUE;
1338 #ifdef ShapeInput
1339       if (XShapeQueryVersion (GDK_DISPLAY_XDISPLAY (display), &maj, &min))
1340         display_x11->have_input_shapes = (maj == 1 && min >= 1);
1341 #endif
1342     }
1343
1344   display_x11->trusted_client = TRUE;
1345   {
1346     Window root, child;
1347     int rootx, rooty, winx, winy;
1348     unsigned int xmask;
1349
1350     gdk_x11_display_error_trap_push (display);
1351     XQueryPointer (display_x11->xdisplay,
1352                    GDK_X11_SCREEN (display_x11->default_screen)->xroot_window,
1353                    &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
1354     if (G_UNLIKELY (gdk_x11_display_error_trap_pop (display) == BadWindow))
1355       {
1356         g_warning ("Connection to display %s appears to be untrusted. Pointer and keyboard grabs and inter-client communication may not work as expected.", gdk_display_get_name (display));
1357         display_x11->trusted_client = FALSE;
1358       }
1359   }
1360
1361   if (g_getenv ("GDK_SYNCHRONIZE"))
1362     XSynchronize (display_x11->xdisplay, True);
1363
1364   class_hint = XAllocClassHint();
1365   class_hint->res_name = g_get_prgname ();
1366
1367   class_hint->res_class = (char *)gdk_get_program_class ();
1368
1369   /* XmbSetWMProperties sets the RESOURCE_NAME environment variable
1370    * from argv[0], so we just synthesize an argument array here.
1371    */
1372   argc = 1;
1373   argv[0] = g_get_prgname ();
1374
1375   XmbSetWMProperties (display_x11->xdisplay,
1376                       display_x11->leader_window,
1377                       NULL, NULL, argv, argc, NULL, NULL,
1378                       class_hint);
1379   XFree (class_hint);
1380
1381   if (gdk_sm_client_id)
1382     set_sm_client_id (display, gdk_sm_client_id);
1383
1384   pid = getpid ();
1385   XChangeProperty (display_x11->xdisplay,
1386                    display_x11->leader_window,
1387                    gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
1388                    XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1);
1389
1390   /* We don't yet know a valid time. */
1391   display_x11->user_time = 0;
1392   
1393 #ifdef HAVE_XKB
1394   {
1395     gint xkb_major = XkbMajorVersion;
1396     gint xkb_minor = XkbMinorVersion;
1397     if (XkbLibraryVersion (&xkb_major, &xkb_minor))
1398       {
1399         xkb_major = XkbMajorVersion;
1400         xkb_minor = XkbMinorVersion;
1401             
1402         if (XkbQueryExtension (display_x11->xdisplay, 
1403                                NULL, &display_x11->xkb_event_type, NULL,
1404                                &xkb_major, &xkb_minor))
1405           {
1406             Bool detectable_autorepeat_supported;
1407             
1408             display_x11->use_xkb = TRUE;
1409
1410             XkbSelectEvents (display_x11->xdisplay,
1411                              XkbUseCoreKbd,
1412                              XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask,
1413                              XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask);
1414
1415             /* keep this in sync with _gdk_x11_keymap_state_changed() */
1416             XkbSelectEventDetails (display_x11->xdisplay,
1417                                    XkbUseCoreKbd, XkbStateNotify,
1418                                    XkbAllStateComponentsMask,
1419                                    XkbGroupLockMask|XkbModifierLockMask);
1420
1421             XkbSetDetectableAutoRepeat (display_x11->xdisplay,
1422                                         True,
1423                                         &detectable_autorepeat_supported);
1424
1425             GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.",
1426                                        detectable_autorepeat_supported ?
1427                                        "supported" : "not supported"));
1428             
1429             display_x11->have_xkb_autorepeat = detectable_autorepeat_supported;
1430           }
1431       }
1432   }
1433 #endif
1434
1435   display_x11->use_sync = FALSE;
1436 #ifdef HAVE_XSYNC
1437   {
1438     int major, minor;
1439     int error_base, event_base;
1440     
1441     if (XSyncQueryExtension (display_x11->xdisplay,
1442                              &event_base, &error_base) &&
1443         XSyncInitialize (display_x11->xdisplay,
1444                          &major, &minor))
1445       display_x11->use_sync = TRUE;
1446   }
1447 #endif
1448
1449   gdk_x11_display_init_input (display);
1450   _gdk_x11_display_init_dnd (display);
1451
1452   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
1453     _gdk_x11_screen_setup (display_x11->screens[i]);
1454
1455   g_signal_emit_by_name (display, "opened");
1456   g_signal_emit_by_name (gdk_display_manager_get (), "display-opened", display);
1457
1458   return display;
1459 }
1460
1461 #ifdef HAVE_X11R6
1462 /*
1463  * XLib internal connection handling
1464  */
1465 typedef struct _GdkInternalConnection GdkInternalConnection;
1466
1467 struct _GdkInternalConnection
1468 {
1469   gint           fd;
1470   GSource       *source;
1471   Display       *display;
1472 };
1473
1474 static gboolean
1475 process_internal_connection (GIOChannel  *gioc,
1476                              GIOCondition cond,
1477                              gpointer     data)
1478 {
1479   GdkInternalConnection *connection = (GdkInternalConnection *)data;
1480
1481   GDK_THREADS_ENTER ();
1482
1483   XProcessInternalConnection ((Display*)connection->display, connection->fd);
1484
1485   GDK_THREADS_LEAVE ();
1486
1487   return TRUE;
1488 }
1489
1490 static gulong
1491 gdk_x11_display_get_next_serial (GdkDisplay *display)
1492 {
1493   return NextRequest (GDK_DISPLAY_XDISPLAY (display));
1494 }
1495
1496
1497 static GdkInternalConnection *
1498 gdk_add_connection_handler (Display *display,
1499                             guint    fd)
1500 {
1501   GIOChannel *io_channel;
1502   GdkInternalConnection *connection;
1503
1504   connection = g_new (GdkInternalConnection, 1);
1505
1506   connection->fd = fd;
1507   connection->display = display;
1508   
1509   io_channel = g_io_channel_unix_new (fd);
1510   
1511   connection->source = g_io_create_watch (io_channel, G_IO_IN);
1512   g_source_set_callback (connection->source,
1513                          (GSourceFunc)process_internal_connection, connection, NULL);
1514   g_source_attach (connection->source, NULL);
1515   
1516   g_io_channel_unref (io_channel);
1517   
1518   return connection;
1519 }
1520
1521 static void
1522 gdk_remove_connection_handler (GdkInternalConnection *connection)
1523 {
1524   g_source_destroy (connection->source);
1525   g_free (connection);
1526 }
1527
1528 static void
1529 gdk_internal_connection_watch (Display  *display,
1530                                XPointer  arg,
1531                                gint      fd,
1532                                gboolean  opening,
1533                                XPointer *watch_data)
1534 {
1535   if (opening)
1536     *watch_data = (XPointer)gdk_add_connection_handler (display, fd);
1537   else
1538     gdk_remove_connection_handler ((GdkInternalConnection *)*watch_data);
1539 }
1540 #endif /* HAVE_X11R6 */
1541
1542 static G_CONST_RETURN gchar *
1543 gdk_x11_display_get_name (GdkDisplay *display)
1544 {
1545   return (gchar *) DisplayString (GDK_X11_DISPLAY (display)->xdisplay);
1546 }
1547
1548 static gint
1549 gdk_x11_display_get_n_screens (GdkDisplay *display)
1550 {
1551   return ScreenCount (GDK_X11_DISPLAY (display)->xdisplay);
1552 }
1553
1554 static GdkScreen *
1555 gdk_x11_display_get_screen (GdkDisplay *display,
1556                             gint        screen_num)
1557 {
1558   g_return_val_if_fail (ScreenCount (GDK_X11_DISPLAY (display)->xdisplay) > screen_num, NULL);
1559
1560   return GDK_X11_DISPLAY (display)->screens[screen_num];
1561 }
1562
1563 static GdkScreen *
1564 gdk_x11_display_get_default_screen (GdkDisplay *display)
1565 {
1566   return GDK_X11_DISPLAY (display)->default_screen;
1567 }
1568
1569 gboolean
1570 _gdk_x11_display_is_root_window (GdkDisplay *display,
1571                                  Window      xroot_window)
1572 {
1573   GdkX11Display *display_x11;
1574   gint i;
1575
1576   display_x11 = GDK_X11_DISPLAY (display);
1577
1578   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
1579     {
1580       if (GDK_SCREEN_XROOTWIN (display_x11->screens[i]) == xroot_window)
1581         return TRUE;
1582     }
1583   return FALSE;
1584 }
1585
1586 struct XPointerUngrabInfo {
1587   GdkDisplay *display;
1588   guint32 time;
1589 };
1590
1591 #define XSERVER_TIME_IS_LATER(time1, time2)                        \
1592   ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) ||  \
1593     (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 ))     \
1594   )
1595
1596 void
1597 _gdk_x11_display_update_grab_info (GdkDisplay *display,
1598                                    GdkDevice  *device,
1599                                    gint        status)
1600 {
1601   if (status == GrabSuccess)
1602     _gdk_x11_roundtrip_async (display,
1603                               (GdkRoundTripCallback)_gdk_display_device_grab_update,
1604                               device);
1605 }
1606
1607 void
1608 _gdk_x11_display_update_grab_info_ungrab (GdkDisplay *display,
1609                                           GdkDevice  *device,
1610                                           guint32     time,
1611                                           gulong      serial)
1612 {
1613   GdkDeviceGrabInfo *grab;
1614
1615   XFlush (GDK_DISPLAY_XDISPLAY (display));
1616
1617   grab = _gdk_display_get_last_device_grab (display, device);
1618   if (grab &&
1619       (time == GDK_CURRENT_TIME ||
1620        grab->time == GDK_CURRENT_TIME ||
1621        !XSERVER_TIME_IS_LATER (grab->time, time)))
1622     {
1623       grab->serial_end = serial;
1624       _gdk_x11_roundtrip_async (display,
1625                                 (GdkRoundTripCallback)_gdk_display_device_grab_update,
1626                                 device);
1627     }
1628 }
1629
1630 static void
1631 gdk_x11_display_beep (GdkDisplay *display)
1632 {
1633 #ifdef HAVE_XKB
1634   XkbBell (GDK_DISPLAY_XDISPLAY (display), None, 0, None);
1635 #else
1636   XBell (GDK_DISPLAY_XDISPLAY (display), 0);
1637 #endif
1638 }
1639
1640 static void
1641 gdk_x11_display_sync (GdkDisplay *display)
1642 {
1643   XSync (GDK_DISPLAY_XDISPLAY (display), False);
1644 }
1645
1646 static void
1647 gdk_x11_display_flush (GdkDisplay *display)
1648 {
1649   if (!display->closed)
1650     XFlush (GDK_DISPLAY_XDISPLAY (display));
1651 }
1652
1653 static gboolean
1654 gdk_x11_display_has_pending (GdkDisplay *display)
1655 {
1656   return XPending (GDK_DISPLAY_XDISPLAY (display));
1657 }
1658
1659 static GdkWindow *
1660 gdk_x11_display_get_default_group (GdkDisplay *display)
1661 {
1662   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1663
1664   return GDK_X11_DISPLAY (display)->leader_gdk_window;
1665 }
1666
1667 /**
1668  * gdk_x11_display_grab:
1669  * @display: a #GdkDisplay 
1670  * 
1671  * Call XGrabServer() on @display. 
1672  * To ungrab the display again, use gdk_x11_display_ungrab(). 
1673  *
1674  * gdk_x11_display_grab()/gdk_x11_display_ungrab() calls can be nested.
1675  *
1676  * Since: 2.2
1677  **/
1678 void
1679 gdk_x11_display_grab (GdkDisplay *display)
1680 {
1681   GdkX11Display *display_x11;
1682   
1683   g_return_if_fail (GDK_IS_DISPLAY (display));
1684   
1685   display_x11 = GDK_X11_DISPLAY (display);
1686   
1687   if (display_x11->grab_count == 0)
1688     XGrabServer (display_x11->xdisplay);
1689   display_x11->grab_count++;
1690 }
1691
1692 /**
1693  * gdk_x11_display_ungrab:
1694  * @display: a #GdkDisplay
1695  * 
1696  * Ungrab @display after it has been grabbed with 
1697  * gdk_x11_display_grab(). 
1698  *
1699  * Since: 2.2
1700  **/
1701 void
1702 gdk_x11_display_ungrab (GdkDisplay *display)
1703 {
1704   GdkX11Display *display_x11;
1705   
1706   g_return_if_fail (GDK_IS_DISPLAY (display));
1707   
1708   display_x11 = GDK_X11_DISPLAY (display);;
1709   g_return_if_fail (display_x11->grab_count > 0);
1710   
1711   display_x11->grab_count--;
1712   if (display_x11->grab_count == 0)
1713     {
1714       XUngrabServer (display_x11->xdisplay);
1715       XFlush (display_x11->xdisplay);
1716     }
1717 }
1718
1719 static void
1720 gdk_x11_display_dispose (GObject *object)
1721 {
1722   GdkDisplay *display = GDK_DISPLAY (object);
1723   GdkX11Display *display_x11 = GDK_X11_DISPLAY (object);
1724   gint           i;
1725
1726   _gdk_x11_display_manager_remove_display (gdk_display_manager_get (), display);
1727
1728   g_list_foreach (display_x11->input_devices, (GFunc) g_object_run_dispose, NULL);
1729
1730   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
1731     _gdk_screen_close (display_x11->screens[i]);
1732
1733   if (display_x11->event_source)
1734     {
1735       g_source_destroy (display_x11->event_source);
1736       g_source_unref (display_x11->event_source);
1737       display_x11->event_source = NULL;
1738     }
1739
1740   G_OBJECT_CLASS (gdk_x11_display_parent_class)->dispose (object);
1741 }
1742
1743 static void
1744 gdk_x11_display_finalize (GObject *object)
1745 {
1746   GdkX11Display *display_x11 = GDK_X11_DISPLAY (object);
1747   gint           i;
1748
1749   /* Keymap */
1750   if (display_x11->keymap)
1751     g_object_unref (display_x11->keymap);
1752
1753   /* Free motif Dnd */
1754   if (display_x11->motif_target_lists)
1755     {
1756       for (i = 0; i < display_x11->motif_n_target_lists; i++)
1757         g_list_free (display_x11->motif_target_lists[i]);
1758       g_free (display_x11->motif_target_lists);
1759     }
1760
1761   _gdk_x11_cursor_display_finalize (GDK_DISPLAY (display_x11));
1762
1763   /* Atom Hashtable */
1764   g_hash_table_destroy (display_x11->atom_from_virtual);
1765   g_hash_table_destroy (display_x11->atom_to_virtual);
1766
1767   /* Leader Window */
1768   XDestroyWindow (display_x11->xdisplay, display_x11->leader_window);
1769
1770   /* list of filters for client messages */
1771   g_list_foreach (display_x11->client_filters, (GFunc) g_free, NULL);
1772   g_list_free (display_x11->client_filters);
1773
1774   /* List of event window extraction functions */
1775   g_slist_foreach (display_x11->event_types, (GFunc)g_free, NULL);
1776   g_slist_free (display_x11->event_types);
1777
1778   /* input GdkDevice list */
1779   g_list_foreach (display_x11->input_devices, (GFunc) g_object_unref, NULL);
1780   g_list_free (display_x11->input_devices);
1781
1782   /* input GdkWindow list */
1783   g_list_foreach (display_x11->input_windows, (GFunc) g_free, NULL);
1784   g_list_free (display_x11->input_windows);
1785
1786   /* Free all GdkScreens */
1787   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
1788     g_object_unref (display_x11->screens[i]);
1789   g_free (display_x11->screens);
1790
1791   g_free (display_x11->startup_notification_id);
1792
1793   /* X ID hashtable */
1794   g_hash_table_destroy (display_x11->xid_ht);
1795
1796   XCloseDisplay (display_x11->xdisplay);
1797
1798   /* error traps */
1799   while (display_x11->error_traps != NULL)
1800     {
1801       GdkErrorTrap *trap = display_x11->error_traps->data;
1802
1803       display_x11->error_traps =
1804         g_slist_delete_link (display_x11->error_traps,
1805                              display_x11->error_traps);
1806
1807       if (trap->end_sequence == 0)
1808         g_warning ("Display finalized with an unpopped error trap");
1809
1810       g_slice_free (GdkErrorTrap, trap);
1811     }
1812
1813   G_OBJECT_CLASS (gdk_x11_display_parent_class)->finalize (object);
1814 }
1815
1816 /**
1817  * gdk_x11_lookup_xdisplay:
1818  * @xdisplay: a pointer to an X Display
1819  * 
1820  * Find the #GdkDisplay corresponding to @display, if any exists.
1821  * 
1822  * Return value: (transfer none): the #GdkDisplay, if found, otherwise %NULL.
1823  *
1824  * Since: 2.2
1825  **/
1826 GdkDisplay *
1827 gdk_x11_lookup_xdisplay (Display *xdisplay)
1828 {
1829   GSList *list, *l;
1830   GdkDisplay *display;
1831
1832   display = NULL;
1833
1834   list = gdk_display_manager_list_displays (gdk_display_manager_get ());
1835
1836   for (l = list; l; l = l->next)
1837     {
1838       if (GDK_DISPLAY_XDISPLAY (l->data) == xdisplay)
1839         {
1840           display = l->data;
1841           break;
1842         }
1843     }
1844
1845   g_slist_free (list);
1846
1847   return display;
1848 }
1849
1850 /**
1851  * _gdk_x11_display_screen_for_xrootwin:
1852  * @display: a #GdkDisplay
1853  * @xrootwin: window ID for one of of the screen's of the display.
1854  * 
1855  * Given the root window ID of one of the screen's of a #GdkDisplay,
1856  * finds the screen.
1857  * 
1858  * Return value: the #GdkScreen corresponding to @xrootwin, or %NULL.
1859  **/
1860 GdkScreen *
1861 _gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
1862                                       Window      xrootwin)
1863 {
1864   gint i;
1865
1866   for (i = 0; i < ScreenCount (GDK_X11_DISPLAY (display)->xdisplay); i++)
1867     {
1868       GdkScreen *screen = gdk_display_get_screen (display, i);
1869       if (GDK_SCREEN_XROOTWIN (screen) == xrootwin)
1870         return screen;
1871     }
1872
1873   return NULL;
1874 }
1875
1876 /**
1877  * gdk_x11_display_get_xdisplay:
1878  * @display: a #GdkDisplay
1879  * @returns: an X display.
1880  *
1881  * Returns the X display of a #GdkDisplay.
1882  *
1883  * Since: 2.2
1884  */
1885 Display *
1886 gdk_x11_display_get_xdisplay (GdkDisplay *display)
1887 {
1888   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
1889   return GDK_X11_DISPLAY (display)->xdisplay;
1890 }
1891
1892 void
1893 _gdk_x11_display_make_default (GdkDisplay *display)
1894 {
1895   GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
1896   const gchar *startup_id;
1897
1898   g_free (display_x11->startup_notification_id);
1899   display_x11->startup_notification_id = NULL;
1900
1901   startup_id = g_getenv ("DESKTOP_STARTUP_ID");
1902   if (startup_id && *startup_id != '\0')
1903     {
1904       if (!g_utf8_validate (startup_id, -1, NULL))
1905         g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
1906       else
1907         gdk_x11_display_set_startup_notification_id (display, startup_id);
1908
1909       /* Clear the environment variable so it won't be inherited by
1910        * child processes and confuse things.
1911        */
1912       g_unsetenv ("DESKTOP_STARTUP_ID");
1913     }
1914 }
1915
1916 static void
1917 broadcast_xmessage (GdkDisplay *display,
1918                     const char *message_type,
1919                     const char *message_type_begin,
1920                     const char *message)
1921 {
1922   Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
1923   GdkScreen *screen = gdk_display_get_default_screen (display);
1924   GdkWindow *root_window = gdk_screen_get_root_window (screen);
1925   Window xroot_window = GDK_WINDOW_XID (root_window);
1926   
1927   Atom type_atom;
1928   Atom type_atom_begin;
1929   Window xwindow;
1930
1931   if (!G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client))
1932     return;
1933
1934   {
1935     XSetWindowAttributes attrs;
1936
1937     attrs.override_redirect = True;
1938     attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
1939
1940     xwindow =
1941       XCreateWindow (xdisplay,
1942                      xroot_window,
1943                      -100, -100, 1, 1,
1944                      0,
1945                      CopyFromParent,
1946                      CopyFromParent,
1947                      (Visual *)CopyFromParent,
1948                      CWOverrideRedirect | CWEventMask,
1949                      &attrs);
1950   }
1951
1952   type_atom = gdk_x11_get_xatom_by_name_for_display (display,
1953                                                      message_type);
1954   type_atom_begin = gdk_x11_get_xatom_by_name_for_display (display,
1955                                                            message_type_begin);
1956   
1957   {
1958     XClientMessageEvent xclient;
1959     const char *src;
1960     const char *src_end;
1961     char *dest;
1962     char *dest_end;
1963     
1964                 memset(&xclient, 0, sizeof (xclient));
1965     xclient.type = ClientMessage;
1966     xclient.message_type = type_atom_begin;
1967     xclient.display =xdisplay;
1968     xclient.window = xwindow;
1969     xclient.format = 8;
1970
1971     src = message;
1972     src_end = message + strlen (message) + 1; /* +1 to include nul byte */
1973     
1974     while (src != src_end)
1975       {
1976         dest = &xclient.data.b[0];
1977         dest_end = dest + 20;        
1978         
1979         while (dest != dest_end &&
1980                src != src_end)
1981           {
1982             *dest = *src;
1983             ++dest;
1984             ++src;
1985           }
1986
1987         while (dest != dest_end)
1988           {
1989             *dest = 0;
1990             ++dest;
1991           }
1992         
1993         XSendEvent (xdisplay,
1994                     xroot_window,
1995                     False,
1996                     PropertyChangeMask,
1997                     (XEvent *)&xclient);
1998
1999         xclient.message_type = type_atom;
2000       }
2001   }
2002
2003   XDestroyWindow (xdisplay, xwindow);
2004   XFlush (xdisplay);
2005 }
2006
2007 /**
2008  * gdk_x11_display_broadcast_startup_message:
2009  * @display: a #GdkDisplay
2010  * @message_type: startup notification message type ("new", "change",
2011  * or "remove")
2012  * @...: a list of key/value pairs (as strings), terminated by a
2013  * %NULL key. (A %NULL value for a key will cause that key to be
2014  * skipped in the output.)
2015  *
2016  * Sends a startup notification message of type @message_type to
2017  * @display. 
2018  *
2019  * This is a convenience function for use by code that implements the
2020  * freedesktop startup notification specification. Applications should
2021  * not normally need to call it directly. See the <ulink
2022  * url="http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt">Startup
2023  * Notification Protocol specification</ulink> for
2024  * definitions of the message types and keys that can be used.
2025  *
2026  * Since: 2.12
2027  **/
2028 void
2029 gdk_x11_display_broadcast_startup_message (GdkDisplay *display,
2030                                            const char *message_type,
2031                                            ...)
2032 {
2033   GString *message;
2034   va_list ap;
2035   const char *key, *value, *p;
2036
2037   message = g_string_new (message_type);
2038   g_string_append_c (message, ':');
2039
2040   va_start (ap, message_type);
2041   while ((key = va_arg (ap, const char *)))
2042     {
2043       value = va_arg (ap, const char *);
2044       if (!value)
2045         continue;
2046
2047       g_string_append_printf (message, " %s=\"", key);
2048       for (p = value; *p; p++)
2049         {
2050           switch (*p)
2051             {
2052             case ' ':
2053             case '"':
2054             case '\\':
2055               g_string_append_c (message, '\\');
2056               break;
2057             }
2058
2059           g_string_append_c (message, *p);
2060         }
2061       g_string_append_c (message, '\"');
2062     }
2063   va_end (ap);
2064
2065   broadcast_xmessage (display,
2066                       "_NET_STARTUP_INFO",
2067                       "_NET_STARTUP_INFO_BEGIN",
2068                       message->str);
2069
2070   g_string_free (message, TRUE);
2071 }
2072
2073 static void
2074 gdk_x11_display_notify_startup_complete (GdkDisplay  *display,
2075                                          const gchar *startup_id)
2076 {
2077   if (startup_id == NULL)
2078     {
2079       startup_id = GDK_X11_DISPLAY (display)->startup_notification_id;
2080       if (startup_id == NULL)
2081         return;
2082     }
2083
2084   gdk_x11_display_broadcast_startup_message (display, "remove",
2085                                              "ID", startup_id,
2086                                              NULL);
2087 }
2088
2089 static gboolean
2090 gdk_x11_display_supports_selection_notification (GdkDisplay *display)
2091 {
2092   GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
2093
2094   return display_x11->have_xfixes;
2095 }
2096
2097 static gboolean
2098 gdk_x11_display_request_selection_notification (GdkDisplay *display,
2099                                                 GdkAtom     selection)
2100
2101 {
2102 #ifdef HAVE_XFIXES
2103   GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
2104   Atom atom;
2105
2106   if (display_x11->have_xfixes)
2107     {
2108       atom = gdk_x11_atom_to_xatom_for_display (display, 
2109                                                 selection);
2110       XFixesSelectSelectionInput (display_x11->xdisplay, 
2111                                   display_x11->leader_window,
2112                                   atom,
2113                                   XFixesSetSelectionOwnerNotifyMask |
2114                                   XFixesSelectionWindowDestroyNotifyMask |
2115                                   XFixesSelectionClientCloseNotifyMask);
2116       return TRUE;
2117     }
2118   else
2119 #endif
2120     return FALSE;
2121 }
2122
2123 static gboolean
2124 gdk_x11_display_supports_clipboard_persistence (GdkDisplay *display)
2125 {
2126   Atom clipboard_manager;
2127
2128   /* It might make sense to cache this */
2129   clipboard_manager = gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
2130   return XGetSelectionOwner (GDK_X11_DISPLAY (display)->xdisplay, clipboard_manager) != None;
2131 }
2132
2133 static void
2134 gdk_x11_display_store_clipboard (GdkDisplay    *display,
2135                                  GdkWindow     *clipboard_window,
2136                                  guint32        time_,
2137                                  const GdkAtom *targets,
2138                                  gint           n_targets)
2139 {
2140   GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
2141   Atom clipboard_manager, save_targets;
2142
2143   g_return_if_fail (GDK_WINDOW_IS_X11 (clipboard_window));
2144
2145   clipboard_manager = gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
2146   save_targets = gdk_x11_get_xatom_by_name_for_display (display, "SAVE_TARGETS");
2147
2148   gdk_x11_display_error_trap_push (display);
2149
2150   if (XGetSelectionOwner (display_x11->xdisplay, clipboard_manager) != None)
2151     {
2152       Atom property_name = None;
2153       Atom *xatoms;
2154       int i;
2155
2156       if (n_targets > 0)
2157         {
2158           property_name = gdk_x11_get_xatom_by_name_for_display (display, "GDK_SELECTION");
2159
2160           xatoms = g_new (Atom, n_targets);
2161           for (i = 0; i < n_targets; i++)
2162             xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, targets[i]);
2163
2164           XChangeProperty (display_x11->xdisplay, GDK_WINDOW_XID (clipboard_window),
2165                            property_name, XA_ATOM,
2166                            32, PropModeReplace, (guchar *)xatoms, n_targets);
2167           g_free (xatoms);
2168
2169         }
2170
2171       XConvertSelection (display_x11->xdisplay,
2172                          clipboard_manager, save_targets, property_name,
2173                          GDK_WINDOW_XID (clipboard_window), time_);
2174
2175     }
2176   gdk_x11_display_error_trap_pop_ignored (display);
2177
2178 }
2179
2180 /**
2181  * gdk_x11_display_get_user_time:
2182  * @display: a #GdkDisplay
2183  *
2184  * Returns the timestamp of the last user interaction on 
2185  * @display. The timestamp is taken from events caused
2186  * by user interaction such as key presses or pointer 
2187  * movements. See gdk_x11_window_set_user_time().
2188  *
2189  * Returns: the timestamp of the last user interaction 
2190  *
2191  * Since: 2.8
2192  */
2193 guint32
2194 gdk_x11_display_get_user_time (GdkDisplay *display)
2195 {
2196   return GDK_X11_DISPLAY (display)->user_time;
2197 }
2198
2199 static gboolean
2200 gdk_x11_display_supports_shapes (GdkDisplay *display)
2201 {
2202   return GDK_X11_DISPLAY (display)->have_shapes;
2203 }
2204
2205 static gboolean
2206 gdk_x11_display_supports_input_shapes (GdkDisplay *display)
2207 {
2208   return GDK_X11_DISPLAY (display)->have_input_shapes;
2209 }
2210
2211
2212 /**
2213  * gdk_x11_display_get_startup_notification_id:
2214  * @display: a #GdkDisplay
2215  *
2216  * Gets the startup notification ID for a display.
2217  * 
2218  * Returns: the startup notification ID for @display
2219  *
2220  * Since: 2.12
2221  */
2222 G_CONST_RETURN gchar *
2223 gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
2224 {
2225   return GDK_X11_DISPLAY (display)->startup_notification_id;
2226 }
2227
2228 /**
2229  * gdk_x11_display_set_startup_notification_id:
2230  * @display: a #GdkDisplay
2231  * @startup_id: the startup notification ID (must be valid utf8)
2232  *
2233  * Sets the startup notification ID for a display.
2234  *
2235  * This is usually taken from the value of the DESKTOP_STARTUP_ID
2236  * environment variable, but in some cases (such as the application not
2237  * being launched using exec()) it can come from other sources.
2238  *
2239  * If the ID contains the string "_TIME" then the portion following that
2240  * string is taken to be the X11 timestamp of the event that triggered
2241  * the application to be launched and the GDK current event time is set
2242  * accordingly.
2243  *
2244  * The startup ID is also what is used to signal that the startup is
2245  * complete (for example, when opening a window or when calling
2246  * gdk_notify_startup_complete()).
2247  *
2248  * Since: 3.0
2249  **/
2250 void
2251 gdk_x11_display_set_startup_notification_id (GdkDisplay  *display,
2252                                              const gchar *startup_id)
2253 {
2254   GdkX11Display *display_x11;
2255   gchar *time_str;
2256
2257   display_x11 = GDK_X11_DISPLAY (display);
2258
2259   g_free (display_x11->startup_notification_id);
2260   display_x11->startup_notification_id = g_strdup (startup_id);
2261
2262   /* Find the launch time from the startup_id, if it's there.  Newer spec
2263    * states that the startup_id is of the form <unique>_TIME<timestamp>
2264    */
2265   time_str = g_strrstr (startup_id, "_TIME");
2266   if (time_str != NULL)
2267     {
2268       gulong retval;
2269       gchar *end;
2270       errno = 0;
2271
2272       /* Skip past the "_TIME" part */
2273       time_str += 5;
2274
2275       retval = strtoul (time_str, &end, 0);
2276       if (end != time_str && errno == 0)
2277         display_x11->user_time = retval;
2278     }
2279
2280   /* Set the startup id on the leader window so it
2281    * applies to all windows we create on this display
2282    */
2283   XChangeProperty (display_x11->xdisplay,
2284                    display_x11->leader_window,
2285                    gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
2286                    gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2287                    PropModeReplace,
2288                    (guchar *)startup_id, strlen (startup_id));
2289 }
2290
2291 static gboolean
2292 gdk_x11_display_supports_composite (GdkDisplay *display)
2293 {
2294   GdkX11Display *x11_display = GDK_X11_DISPLAY (display);
2295
2296   return x11_display->have_xcomposite &&
2297          x11_display->have_xdamage &&
2298          x11_display->have_xfixes;
2299 }
2300
2301 static GList *
2302 gdk_x11_display_list_devices (GdkDisplay *display)
2303 {
2304   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
2305
2306   return GDK_X11_DISPLAY (display)->input_devices;
2307 }
2308
2309 static gboolean
2310 gdk_x11_display_send_client_message (GdkDisplay     *display,
2311                                      GdkEvent       *event,
2312                                      GdkNativeWindow winid)
2313 {
2314   XEvent sev;
2315
2316   g_return_val_if_fail(event != NULL, FALSE);
2317
2318   /* Set up our event to send, with the exception of its target window */
2319   sev.xclient.type = ClientMessage;
2320   sev.xclient.display = GDK_DISPLAY_XDISPLAY (display);
2321   sev.xclient.format = event->client.data_format;
2322   sev.xclient.window = winid;
2323   memcpy(&sev.xclient.data, &event->client.data, sizeof (sev.xclient.data));
2324   sev.xclient.message_type = gdk_x11_atom_to_xatom_for_display (display, event->client.message_type);
2325
2326   return _gdk_x11_display_send_xevent (display, winid, False, NoEventMask, &sev);
2327 }
2328
2329 static void
2330 gdk_x11_display_add_client_message_filter (GdkDisplay   *display,
2331                                            GdkAtom       message_type,
2332                                            GdkFilterFunc func,
2333                                            gpointer      data)
2334 {
2335   GdkClientFilter *filter;
2336   g_return_if_fail (GDK_IS_DISPLAY (display));
2337   filter = g_new (GdkClientFilter, 1);
2338
2339   filter->type = message_type;
2340   filter->function = func;
2341   filter->data = data;
2342
2343   GDK_X11_DISPLAY(display)->client_filters =
2344     g_list_append (GDK_X11_DISPLAY (display)->client_filters,
2345                    filter);
2346 }
2347
2348 /**
2349  * gdk_x11_register_standard_event_type:
2350  * @display: a #GdkDisplay
2351  * @event_base: first event type code to register
2352  * @n_events: number of event type codes to register
2353  *
2354  * Registers interest in receiving extension events with type codes
2355  * between @event_base and <literal>event_base + n_events - 1</literal>.
2356  * The registered events must have the window field in the same place
2357  * as core X events (this is not the case for e.g. XKB extension events).
2358  *
2359  * If an event type is registered, events of this type will go through
2360  * global and window-specific filters (see gdk_window_add_filter()).
2361  * Unregistered events will only go through global filters.
2362  * GDK may register the events of some X extensions on its own.
2363  *
2364  * This function should only be needed in unusual circumstances, e.g.
2365  * when filtering XInput extension events on the root window.
2366  *
2367  * Since: 2.4
2368  **/
2369 void
2370 gdk_x11_register_standard_event_type (GdkDisplay *display,
2371                                       gint        event_base,
2372                                       gint        n_events)
2373 {
2374   GdkEventTypeX11 *event_type;
2375   GdkX11Display *display_x11;
2376
2377   display_x11 = GDK_X11_DISPLAY (display);
2378   event_type = g_new (GdkEventTypeX11, 1);
2379
2380   event_type->base = event_base;
2381   event_type->n_events = n_events;
2382
2383   display_x11->event_types = g_slist_prepend (display_x11->event_types, event_type);
2384 }
2385
2386 /* compare X sequence numbers handling wraparound */
2387 #define SEQUENCE_COMPARE(a,op,b) (((long) (a) - (long) (b)) op 0)
2388
2389 /* delivers an error event from the error handler in gdkmain-x11.c */
2390 void
2391 _gdk_x11_display_error_event (GdkDisplay  *display,
2392                               XErrorEvent *error)
2393 {
2394   GdkX11Display *display_x11;
2395   GSList *tmp_list;
2396   gboolean ignore;
2397
2398   display_x11 = GDK_X11_DISPLAY (display);
2399
2400   ignore = FALSE;
2401   for (tmp_list = display_x11->error_traps;
2402        tmp_list != NULL;
2403        tmp_list = tmp_list->next)
2404     {
2405       GdkErrorTrap *trap;
2406
2407       trap = tmp_list->data;
2408
2409       if (SEQUENCE_COMPARE (trap->start_sequence, <=, error->serial) &&
2410           (trap->end_sequence == 0 ||
2411            SEQUENCE_COMPARE (trap->end_sequence, >, error->serial)))
2412         {
2413           ignore = TRUE;
2414           trap->error_code = error->error_code;
2415           break; /* only innermost trap gets the error code */
2416         }
2417     }
2418
2419   if (!ignore)
2420     {
2421       gchar buf[64];
2422       gchar *msg;
2423
2424       XGetErrorText (display_x11->xdisplay, error->error_code, buf, 63);
2425
2426       msg =
2427         g_strdup_printf ("The program '%s' received an X Window System error.\n"
2428                          "This probably reflects a bug in the program.\n"
2429                          "The error was '%s'.\n"
2430                          "  (Details: serial %ld error_code %d request_code %d minor_code %d)\n"
2431                          "  (Note to programmers: normally, X errors are reported asynchronously;\n"
2432                          "   that is, you will receive the error a while after causing it.\n"
2433                          "   To debug your program, run it with the --sync command line\n"
2434                          "   option to change this behavior. You can then get a meaningful\n"
2435                          "   backtrace from your debugger if you break on the gdk_x_error() function.)",
2436                          g_get_prgname (),
2437                          buf,
2438                          error->serial,
2439                          error->error_code,
2440                          error->request_code,
2441                          error->minor_code);
2442
2443 #ifdef G_ENABLE_DEBUG
2444       g_error ("%s", msg);
2445 #else /* !G_ENABLE_DEBUG */
2446       g_warning ("%s\n", msg);
2447
2448       exit (1);
2449 #endif /* G_ENABLE_DEBUG */
2450     }
2451 }
2452
2453 static void
2454 delete_outdated_error_traps (GdkX11Display *display_x11)
2455 {
2456   GSList *tmp_list;
2457   gulong processed_sequence;
2458
2459   processed_sequence = XLastKnownRequestProcessed (display_x11->xdisplay);
2460
2461   tmp_list = display_x11->error_traps;
2462   while (tmp_list != NULL)
2463     {
2464       GdkErrorTrap *trap = tmp_list->data;
2465
2466       if (trap->end_sequence != 0 &&
2467           SEQUENCE_COMPARE (trap->end_sequence, <=, processed_sequence))
2468         {
2469           GSList *free_me = tmp_list;
2470
2471           tmp_list = tmp_list->next;
2472           display_x11->error_traps =
2473             g_slist_delete_link (display_x11->error_traps, free_me);
2474           g_slice_free (GdkErrorTrap, trap);
2475         }
2476       else
2477         {
2478           tmp_list = tmp_list->next;
2479         }
2480     }
2481 }
2482
2483 /**
2484  * gdk_x11_display_error_trap_push:
2485  * @display: a #GdkDisplay
2486  *
2487  * Begins a range of X requests on @display for which X error events
2488  * will be ignored. Unignored errors (when no trap is pushed) will abort
2489  * the application. Use gdk_x11_display_error_trap_pop() or
2490  * gdk_x11_display_error_trap_pop_ignored()to lift a trap pushed
2491  * with this function.
2492  *
2493  * See also gdk_error_trap_push() to push a trap on all displays.
2494  *
2495  * Since: 3.0
2496  */
2497 void
2498 gdk_x11_display_error_trap_push (GdkDisplay *display)
2499 {
2500   GdkX11Display *display_x11;
2501   GdkErrorTrap *trap;
2502
2503   display_x11 = GDK_X11_DISPLAY (display);
2504
2505   delete_outdated_error_traps (display_x11);
2506
2507   /* set up the Xlib callback to tell us about errors */
2508   _gdk_x11_error_handler_push ();
2509
2510   trap = g_slice_new0 (GdkErrorTrap);
2511
2512   trap->start_sequence = XNextRequest (display_x11->xdisplay);
2513   trap->error_code = Success;
2514
2515   display_x11->error_traps =
2516     g_slist_prepend (display_x11->error_traps, trap);
2517 }
2518
2519 static gint
2520 gdk_x11_display_error_trap_pop_internal (GdkDisplay *display,
2521                                          gboolean    need_code)
2522 {
2523   GdkX11Display *display_x11;
2524   GdkErrorTrap *trap;
2525   GSList *tmp_list;
2526   int result;
2527
2528   display_x11 = GDK_X11_DISPLAY (display);
2529
2530   g_return_val_if_fail (display_x11->error_traps != NULL, Success);
2531
2532   /* Find the first trap that hasn't been popped already */
2533   trap = NULL; /* quiet gcc */
2534   for (tmp_list = display_x11->error_traps;
2535        tmp_list != NULL;
2536        tmp_list = tmp_list->next)
2537     {
2538       trap = tmp_list->data;
2539
2540       if (trap->end_sequence == 0)
2541         break;
2542     }
2543
2544   g_return_val_if_fail (trap != NULL, Success);
2545   g_assert (trap->end_sequence == 0);
2546
2547   /* May need to sync to fill in trap->error_code if we care about
2548    * getting an error code.
2549    */
2550   if (need_code)
2551     {
2552       gulong processed_sequence;
2553       gulong next_sequence;
2554
2555       next_sequence = XNextRequest (display_x11->xdisplay);
2556       processed_sequence = XLastKnownRequestProcessed (display_x11->xdisplay);
2557
2558       /* If our last request was already processed, there is no point
2559        * in syncing. i.e. if last request was a round trip (or even if
2560        * we got an event with the serial of a non-round-trip)
2561        */
2562       if ((next_sequence - 1) != processed_sequence)
2563         {
2564           XSync (display_x11->xdisplay, False);
2565         }
2566
2567       result = trap->error_code;
2568     }
2569   else
2570     {
2571       result = Success;
2572     }
2573
2574   /* record end of trap, giving us a range of
2575    * error sequences we'll ignore.
2576    */
2577   trap->end_sequence = XNextRequest (display_x11->xdisplay);
2578
2579   /* remove the Xlib callback */
2580   _gdk_x11_error_handler_pop ();
2581
2582   /* we may already be outdated */
2583   delete_outdated_error_traps (display_x11);
2584
2585   return result;
2586 }
2587
2588 /**
2589  * gdk_x11_display_error_trap_pop:
2590  * @display: the display
2591  *
2592  * Pops the error trap pushed by gdk_x11_display_error_trap_push().
2593  * Will XSync() if necessary and will always block until
2594  * the error is known to have occurred or not occurred,
2595  * so the error code can be returned.
2596  *
2597  * If you don't need to use the return value,
2598  * gdk_x11_display_error_trap_pop_ignored() would be more efficient.
2599  *
2600  * See gdk_error_trap_pop() for the all-displays-at-once
2601  * equivalent.
2602  *
2603  * Since: 3.0
2604  *
2605  * Return value: X error code or 0 on success
2606  */
2607 gint
2608 gdk_x11_display_error_trap_pop (GdkDisplay *display)
2609 {
2610   g_return_val_if_fail (GDK_IS_X11_DISPLAY (display), Success);
2611
2612   return gdk_x11_display_error_trap_pop_internal (display, TRUE);
2613 }
2614
2615 /**
2616  * gdk_x11_display_error_trap_pop_ignored:
2617  * @display: the display
2618  *
2619  * Pops the error trap pushed by gdk_x11_display_error_trap_push().
2620  * Does not block to see if an error occurred; merely records the
2621  * range of requests to ignore errors for, and ignores those errors
2622  * if they arrive asynchronously.
2623  *
2624  * See gdk_error_trap_pop_ignored() for the all-displays-at-once
2625  * equivalent.
2626  *
2627  * Since: 3.0
2628  */
2629 void
2630 gdk_x11_display_error_trap_pop_ignored (GdkDisplay *display)
2631 {
2632   g_return_if_fail (GDK_IS_X11_DISPLAY (display));
2633
2634   gdk_x11_display_error_trap_pop_internal (display, FALSE);
2635 }
2636
2637 extern GdkAppLaunchContext *_gdk_x11_display_get_app_launch_context (GdkDisplay *display);
2638 extern GdkNativeWindow      _gdk_x11_display_get_drag_protocol      (GdkDisplay *display,
2639                                                                      GdkNativeWindow  xid,
2640                                                                      GdkDragProtocol *protocol,
2641                                                                      guint           *version);
2642
2643
2644 /**
2645  * gdk_x11_set_sm_client_id:
2646  * @sm_client_id: the client id assigned by the session manager when the
2647  *    connection was opened, or %NULL to remove the property.
2648  *
2649  * Sets the <literal>SM_CLIENT_ID</literal> property on the application's leader window so that
2650  * the window manager can save the application's state using the X11R6 ICCCM
2651  * session management protocol.
2652  *
2653  * See the X Session Management Library documentation for more information on
2654  * session management and the Inter-Client Communication Conventions Manual
2655  *
2656  * Since: 2.24
2657  */
2658 void
2659 gdk_x11_set_sm_client_id (const gchar *sm_client_id)
2660 {
2661  GSList *displays, *l;
2662
2663   g_free (gdk_sm_client_id);
2664   gdk_sm_client_id = g_strdup (sm_client_id);
2665
2666   displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
2667   for (l = displays; l; l = l->next)
2668     set_sm_client_id (l->data, sm_client_id);
2669
2670   g_slist_free (displays);
2671 }
2672
2673 static void
2674 gdk_x11_display_event_data_copy (GdkDisplay    *display,
2675                                 const GdkEvent *src,
2676                                 GdkEvent       *dst)
2677 {
2678 }
2679
2680 static void
2681 gdk_x11_display_event_data_free (GdkDisplay *display,
2682                                  GdkEvent *event)
2683 {
2684 }
2685
2686 static gint
2687 pop_error_trap (GdkDisplay *display,
2688                 gboolean    ignored)
2689 {
2690   if (ignored)
2691     {
2692       gdk_x11_display_error_trap_pop_ignored (display);
2693       return Success;
2694     }
2695   else
2696     {
2697       return gdk_x11_display_error_trap_pop (display);
2698     }
2699 }
2700
2701 static GdkKeymap *
2702 gdk_x11_display_get_keymap (GdkDisplay *display)
2703 {
2704   GdkX11Display *display_x11;
2705   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
2706   display_x11 = GDK_X11_DISPLAY (display);
2707
2708   if (!display_x11->keymap)
2709     display_x11->keymap = g_object_new (_gdk_keymap_x11_get_type (), NULL);
2710
2711   display_x11->keymap->display = display;
2712
2713   return display_x11->keymap;
2714 }
2715
2716 static void
2717 gdk_x11_display_class_init (GdkX11DisplayClass * class)
2718 {
2719   GObjectClass *object_class = G_OBJECT_CLASS (class);
2720   GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (class);
2721
2722   object_class->dispose = gdk_x11_display_dispose;
2723   object_class->finalize = gdk_x11_display_finalize;
2724
2725   display_class->get_name = gdk_x11_display_get_name;
2726   display_class->get_n_screens = gdk_x11_display_get_n_screens;
2727   display_class->get_screen = gdk_x11_display_get_screen;
2728   display_class->get_default_screen = gdk_x11_display_get_default_screen;
2729   display_class->beep = gdk_x11_display_beep;
2730   display_class->sync = gdk_x11_display_sync;
2731   display_class->flush = gdk_x11_display_flush;
2732   display_class->has_pending = gdk_x11_display_has_pending;
2733   display_class->queue_events = _gdk_x11_display_queue_events;
2734   display_class->get_default_group = gdk_x11_display_get_default_group;
2735   display_class->supports_selection_notification = gdk_x11_display_supports_selection_notification;
2736   display_class->request_selection_notification = gdk_x11_display_request_selection_notification;
2737   display_class->supports_clipboard_persistence = gdk_x11_display_supports_clipboard_persistence;
2738   display_class->store_clipboard = gdk_x11_display_store_clipboard;
2739   display_class->supports_shapes = gdk_x11_display_supports_shapes;
2740   display_class->supports_input_shapes = gdk_x11_display_supports_input_shapes;
2741   display_class->supports_composite = gdk_x11_display_supports_composite;
2742   display_class->list_devices = gdk_x11_display_list_devices;
2743   display_class->send_client_message = gdk_x11_display_send_client_message;
2744   display_class->add_client_message_filter = gdk_x11_display_add_client_message_filter;
2745   display_class->get_app_launch_context = _gdk_x11_display_get_app_launch_context;
2746   display_class->get_drag_protocol = _gdk_x11_display_get_drag_protocol;
2747   display_class->get_cursor_for_type = _gdk_x11_display_get_cursor_for_type;
2748   display_class->get_cursor_for_name = _gdk_x11_display_get_cursor_for_name;
2749   display_class->get_cursor_for_pixbuf = _gdk_x11_display_get_cursor_for_pixbuf;
2750   display_class->get_default_cursor_size = _gdk_x11_display_get_default_cursor_size;
2751   display_class->get_maximal_cursor_size = _gdk_x11_display_get_maximal_cursor_size;
2752   display_class->supports_cursor_alpha = _gdk_x11_display_supports_cursor_alpha;
2753   display_class->supports_cursor_color = _gdk_x11_display_supports_cursor_color;
2754
2755   display_class->before_process_all_updates = _gdk_x11_display_before_process_all_updates;
2756   display_class->after_process_all_updates = _gdk_x11_display_after_process_all_updates;
2757   display_class->get_next_serial = gdk_x11_display_get_next_serial;
2758   display_class->notify_startup_complete = gdk_x11_display_notify_startup_complete;
2759   display_class->event_data_copy = gdk_x11_display_event_data_copy;
2760   display_class->event_data_free = gdk_x11_display_event_data_free;
2761   display_class->create_window_impl = _gdk_x11_display_create_window_impl;
2762   display_class->get_keymap = gdk_x11_display_get_keymap;
2763   display_class->push_error_trap = gdk_x11_display_error_trap_push;
2764   display_class->pop_error_trap = pop_error_trap;
2765   display_class->get_selection_owner = _gdk_x11_display_get_selection_owner;
2766   display_class->set_selection_owner = _gdk_x11_display_set_selection_owner;
2767   display_class->send_selection_notify = _gdk_x11_display_send_selection_notify;
2768   display_class->get_selection_property = _gdk_x11_display_get_selection_property;
2769   display_class->convert_selection = _gdk_x11_display_convert_selection;
2770   display_class->text_property_to_utf8_list = _gdk_x11_display_text_property_to_utf8_list;
2771   display_class->utf8_to_string_target = _gdk_x11_display_utf8_to_string_target;
2772 }