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