1 /* GDK - The GIMP Drawing Kit
2  * gdkdisplay-x11.c
3  *
4  * Copyright 2001 Sun Microsystems Inc.
5  * Copyright (C) 2004 Nokia Corporation
6  *
7  * Erwann Chenede <erwann.chenede@sun.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24 
25 #include "config.h"
26 
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <unistd.h>
31 
32 #include <glib.h>
33 #include "gdkx.h"
34 #include "gdkasync.h"
35 #include "gdkdisplay.h"
36 #include "gdkdisplay-x11.h"
37 #include "gdkscreen.h"
38 #include "gdkscreen-x11.h"
39 #include "gdkinternals.h"
40 #include "gdkinputprivate.h"
41 #include "xsettings-client.h"
42 #include "gdkalias.h"
43 
44 #include <X11/Xatom.h>
45 
46 #ifdef HAVE_XKB
47 #include <X11/XKBlib.h>
48 #endif
49 
50 #ifdef HAVE_XFIXES
51 #include <X11/extensions/Xfixes.h>
52 #endif
53 
54 #include <X11/extensions/shape.h>
55 
56 #ifdef HAVE_XCOMPOSITE
57 #include <X11/extensions/Xcomposite.h>
58 #endif
59 
60 #ifdef HAVE_XDAMAGE
61 #include <X11/extensions/Xdamage.h>
62 #endif
63 
64 #ifdef HAVE_RANDR
65 #include <X11/extensions/Xrandr.h>
66 #endif
67 
68 
69 static void   gdk_display_x11_dispose            (GObject            *object);
70 static void   gdk_display_x11_finalize           (GObject            *object);
71 
72 #ifdef HAVE_X11R6
73 static void gdk_internal_connection_watch (Display  *display,
74 					   XPointer  arg,
75 					   gint      fd,
76 					   gboolean  opening,
77 					   XPointer *watch_data);
78 #endif /* HAVE_X11R6 */
79 
80 /* Note that we never *directly* use WM_LOCALE_NAME, WM_PROTOCOLS,
81  * but including them here has the side-effect of getting them
82  * into the internal Xlib cache
83  */
84 static const char *const precache_atoms[] = {
85   "UTF8_STRING",
86   "WM_CLIENT_LEADER",
87   "WM_DELETE_WINDOW",
88   "WM_ICON_NAME",
89   "WM_LOCALE_NAME",
90   "WM_NAME",
91   "WM_PROTOCOLS",
92   "WM_TAKE_FOCUS",
93   "WM_WINDOW_ROLE",
94   "_NET_ACTIVE_WINDOW",
95   "_NET_CURRENT_DESKTOP",
96   "_NET_FRAME_EXTENTS",
97   "_NET_STARTUP_ID",
98   "_NET_WM_CM_S0",
99   "_NET_WM_DESKTOP",
100   "_NET_WM_ICON",
101   "_NET_WM_ICON_NAME",
102   "_NET_WM_NAME",
103   "_NET_WM_PID",
104   "_NET_WM_PING",
105   "_NET_WM_STATE",
106   "_NET_WM_STATE_ABOVE",
107   "_NET_WM_STATE_BELOW",
108   "_NET_WM_STATE_FULLSCREEN",
109   "_NET_WM_STATE_MODAL",
110   "_NET_WM_STATE_MAXIMIZED_VERT",
111   "_NET_WM_STATE_MAXIMIZED_HORZ",
112   "_NET_WM_STATE_SKIP_TASKBAR",
113   "_NET_WM_STATE_SKIP_PAGER",
114   "_NET_WM_STATE_STICKY",
115   "_NET_WM_SYNC_REQUEST",
116   "_NET_WM_SYNC_REQUEST_COUNTER",
117   "_NET_WM_WINDOW_TYPE",
118   "_NET_WM_WINDOW_TYPE_NORMAL",
119   "_NET_WM_USER_TIME",
120   "_NET_VIRTUAL_ROOTS"
121 };
122 
G_DEFINE_TYPE(GdkDisplayX11,_gdk_display_x11,GDK_TYPE_DISPLAY)123 G_DEFINE_TYPE (GdkDisplayX11, _gdk_display_x11, GDK_TYPE_DISPLAY)
124 
125 static void
126 _gdk_display_x11_class_init (GdkDisplayX11Class * class)
127 {
128   GObjectClass *object_class = G_OBJECT_CLASS (class);
129 
130   object_class->dispose = gdk_display_x11_dispose;
131   object_class->finalize = gdk_display_x11_finalize;
132 }
133 
134 static void
_gdk_display_x11_init(GdkDisplayX11 * display)135 _gdk_display_x11_init (GdkDisplayX11 *display)
136 {
137 }
138 
139 /**
140  * gdk_display_open:
141  * @display_name: the name of the display to open
142  * @returns: a #GdkDisplay, or %NULL if the display
143  *  could not be opened.
144  *
145  * Opens a display.
146  *
147  * Since: 2.2
148  */
149 GdkDisplay *
gdk_display_open(const gchar * display_name)150 gdk_display_open (const gchar *display_name)
151 {
152   Display *xdisplay;
153   GdkDisplay *display;
154   GdkDisplayX11 *display_x11;
155   GdkWindowAttr attr;
156   gint argc;
157   gchar *argv[1];
158   const char *sm_client_id;
159 
160   XClassHint *class_hint;
161   gulong pid;
162   gint i;
163   gint ignore;
164   gint maj, min;
165 
166   xdisplay = XOpenDisplay (display_name);
167   if (!xdisplay)
168     return NULL;
169 
170   display = g_object_new (GDK_TYPE_DISPLAY_X11, NULL);
171   display_x11 = GDK_DISPLAY_X11 (display);
172 
173   display_x11->use_xshm = TRUE;
174   display_x11->xdisplay = xdisplay;
175 
176 #ifdef HAVE_X11R6
177   /* Set up handlers for Xlib internal connections */
178   XAddConnectionWatch (xdisplay, gdk_internal_connection_watch, NULL);
179 #endif /* HAVE_X11R6 */
180 
181   _gdk_x11_precache_atoms (display, precache_atoms, G_N_ELEMENTS (precache_atoms));
182 
183   /* RandR must be initialized before we initialize the screens */
184   display_x11->have_randr13 = FALSE;
185   display_x11->have_randr15 = FALSE;
186 #ifdef HAVE_RANDR
187   if (XRRQueryExtension (display_x11->xdisplay,
188 			 &display_x11->xrandr_event_base, &ignore))
189   {
190       int major, minor;
191 
192       XRRQueryVersion (display_x11->xdisplay, &major, &minor);
193 
194       if ((major == 1 && minor >= 3) || major > 1)
195 	  display_x11->have_randr13 = TRUE;
196 
197 #ifdef HAVE_RANDR15
198       if (minor >= 5 || major > 1)
199 	display_x11->have_randr15 = TRUE;
200 #endif
201 
202        gdk_x11_register_standard_event_type (display, display_x11->xrandr_event_base, RRNumberEvents);
203   }
204 #endif
205 
206   /* initialize the display's screens */
207   display_x11->screens = g_new (GdkScreen *, ScreenCount (display_x11->xdisplay));
208   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
209     display_x11->screens[i] = _gdk_x11_screen_new (display, i);
210 
211   /* We need to initialize events after we have the screen
212    * structures in places
213    */
214   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
215     _gdk_x11_events_init_screen (display_x11->screens[i]);
216 
217   /*set the default screen */
218   display_x11->default_screen = display_x11->screens[DefaultScreen (display_x11->xdisplay)];
219 
220   attr.window_type = GDK_WINDOW_TOPLEVEL;
221   attr.wclass = GDK_INPUT_OUTPUT;
222   attr.x = 10;
223   attr.y = 10;
224   attr.width = 10;
225   attr.height = 10;
226   attr.event_mask = 0;
227 
228   display_x11->leader_gdk_window = gdk_window_new (GDK_SCREEN_X11 (display_x11->default_screen)->root_window,
229 						   &attr, GDK_WA_X | GDK_WA_Y);
230   (_gdk_x11_window_get_toplevel (display_x11->leader_gdk_window))->is_leader = TRUE;
231 
232   display_x11->leader_window = GDK_WINDOW_XID (display_x11->leader_gdk_window);
233 
234   display_x11->leader_window_title_set = FALSE;
235 
236   display_x11->have_render = GDK_UNKNOWN;
237 
238 #ifdef HAVE_XFIXES
239   if (XFixesQueryExtension (display_x11->xdisplay,
240 			    &display_x11->xfixes_event_base,
241 			    &ignore))
242     {
243       display_x11->have_xfixes = TRUE;
244 
245       gdk_x11_register_standard_event_type (display,
246 					    display_x11->xfixes_event_base,
247 					    XFixesNumberEvents);
248     }
249   else
250 #endif
251     display_x11->have_xfixes = FALSE;
252 
253 #ifdef HAVE_XCOMPOSITE
254   if (XCompositeQueryExtension (display_x11->xdisplay,
255 				&ignore, &ignore))
256     {
257       int major, minor;
258 
259       XCompositeQueryVersion (display_x11->xdisplay, &major, &minor);
260 
261       /* Prior to Composite version 0.4, composited windows clipped their
262        * parents, so you had to use IncludeInferiors to draw to the parent
263        * This isn't useful for our purposes, so require 0.4
264        */
265       display_x11->have_xcomposite = major > 0 || (major == 0 && minor >= 4);
266     }
267   else
268 #endif
269     display_x11->have_xcomposite = FALSE;
270 
271 #ifdef HAVE_XDAMAGE
272   if (XDamageQueryExtension (display_x11->xdisplay,
273 			     &display_x11->xdamage_event_base,
274 			     &ignore))
275     {
276       display_x11->have_xdamage = TRUE;
277 
278       gdk_x11_register_standard_event_type (display,
279 					    display_x11->xdamage_event_base,
280 					    XDamageNumberEvents);
281     }
282   else
283 #endif
284     display_x11->have_xdamage = FALSE;
285 
286   display_x11->have_shapes = FALSE;
287   display_x11->have_input_shapes = FALSE;
288 
289   if (XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display), &display_x11->shape_event_base, &ignore))
290     {
291       display_x11->have_shapes = TRUE;
292 #ifdef ShapeInput
293       if (XShapeQueryVersion (GDK_DISPLAY_XDISPLAY (display), &maj, &min))
294 	display_x11->have_input_shapes = (maj == 1 && min >= 1);
295 #endif
296     }
297 
298   display_x11->trusted_client = TRUE;
299   {
300     Window root, child;
301     int rootx, rooty, winx, winy;
302     unsigned int xmask;
303 
304     gdk_error_trap_push ();
305     XQueryPointer (display_x11->xdisplay,
306 		   GDK_SCREEN_X11 (display_x11->default_screen)->xroot_window,
307 		   &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
308     gdk_flush ();
309     if (G_UNLIKELY (gdk_error_trap_pop () == BadWindow))
310       {
311 	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));
312 	display_x11->trusted_client = FALSE;
313       }
314   }
315 
316   if (_gdk_synchronize)
317     XSynchronize (display_x11->xdisplay, True);
318 
319   class_hint = XAllocClassHint();
320   class_hint->res_name = g_get_prgname ();
321 
322   class_hint->res_class = (char *)gdk_get_program_class ();
323 
324   /* XmbSetWMProperties sets the RESOURCE_NAME environment variable
325    * from argv[0], so we just synthesize an argument array here.
326    */
327   argc = 1;
328   argv[0] = g_get_prgname ();
329 
330   XmbSetWMProperties (display_x11->xdisplay,
331 		      display_x11->leader_window,
332 		      NULL, NULL, argv, argc, NULL, NULL,
333 		      class_hint);
334   XFree (class_hint);
335 
336   sm_client_id = _gdk_get_sm_client_id ();
337   if (sm_client_id)
338     _gdk_windowing_display_set_sm_client_id (display, sm_client_id);
339 
340   pid = getpid ();
341   XChangeProperty (display_x11->xdisplay,
342 		   display_x11->leader_window,
343 		   gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
344 		   XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1);
345 
346   /* We don't yet know a valid time. */
347   display_x11->user_time = 0;
348 
349 #ifdef HAVE_XKB
350   {
351     gint xkb_major = XkbMajorVersion;
352     gint xkb_minor = XkbMinorVersion;
353     if (XkbLibraryVersion (&xkb_major, &xkb_minor))
354       {
355         xkb_major = XkbMajorVersion;
356         xkb_minor = XkbMinorVersion;
357 
358         if (XkbQueryExtension (display_x11->xdisplay,
359 			       NULL, &display_x11->xkb_event_type, NULL,
360                                &xkb_major, &xkb_minor))
361           {
362 	    Bool detectable_autorepeat_supported;
363 
364 	    display_x11->use_xkb = TRUE;
365 
366             XkbSelectEvents (display_x11->xdisplay,
367                              XkbUseCoreKbd,
368                              XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask,
369                              XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask);
370 
371 	    /* keep this in sync with _gdk_keymap_state_changed() */
372 	    XkbSelectEventDetails (display_x11->xdisplay,
373 				   XkbUseCoreKbd, XkbStateNotify,
374 				   XkbAllStateComponentsMask,
375                                    XkbGroupLockMask|XkbModifierLockMask);
376 
377 	    XkbSetDetectableAutoRepeat (display_x11->xdisplay,
378 					True,
379 					&detectable_autorepeat_supported);
380 
381 	    GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.",
382 				       detectable_autorepeat_supported ?
383 				       "supported" : "not supported"));
384 
385 	    display_x11->have_xkb_autorepeat = detectable_autorepeat_supported;
386           }
387       }
388   }
389 #endif
390 
391   display_x11->use_sync = FALSE;
392 #ifdef HAVE_XSYNC
393   {
394     int major, minor;
395     int error_base, event_base;
396 
397     if (XSyncQueryExtension (display_x11->xdisplay,
398 			     &event_base, &error_base) &&
399         XSyncInitialize (display_x11->xdisplay,
400                          &major, &minor))
401       display_x11->use_sync = TRUE;
402   }
403 #endif
404 
405   _gdk_windowing_image_init (display);
406   _gdk_events_init (display);
407   _gdk_input_init (display);
408   _gdk_dnd_init (display);
409 
410   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
411     _gdk_x11_screen_setup (display_x11->screens[i]);
412 
413   g_signal_emit_by_name (gdk_display_manager_get(),
414 			 "display_opened", display);
415 
416   return display;
417 }
418 
419 #ifdef HAVE_X11R6
420 /*
421  * XLib internal connection handling
422  */
423 typedef struct _GdkInternalConnection GdkInternalConnection;
424 
425 struct _GdkInternalConnection
426 {
427   gint	         fd;
428   GSource	*source;
429   Display	*display;
430 };
431 
432 static gboolean
process_internal_connection(GIOChannel * gioc,GIOCondition cond,gpointer data)433 process_internal_connection (GIOChannel  *gioc,
434 			     GIOCondition cond,
435 			     gpointer     data)
436 {
437   GdkInternalConnection *connection = (GdkInternalConnection *)data;
438 
439   GDK_THREADS_ENTER ();
440 
441   XProcessInternalConnection ((Display*)connection->display, connection->fd);
442 
443   GDK_THREADS_LEAVE ();
444 
445   return TRUE;
446 }
447 
448 gulong
_gdk_windowing_window_get_next_serial(GdkDisplay * display)449 _gdk_windowing_window_get_next_serial (GdkDisplay *display)
450 {
451   return NextRequest (GDK_DISPLAY_XDISPLAY (display));
452 }
453 
454 
455 static GdkInternalConnection *
gdk_add_connection_handler(Display * display,guint fd)456 gdk_add_connection_handler (Display *display,
457 			    guint    fd)
458 {
459   GIOChannel *io_channel;
460   GdkInternalConnection *connection;
461 
462   connection = g_new (GdkInternalConnection, 1);
463 
464   connection->fd = fd;
465   connection->display = display;
466 
467   io_channel = g_io_channel_unix_new (fd);
468 
469   connection->source = g_io_create_watch (io_channel, G_IO_IN);
470   g_source_set_callback (connection->source,
471 			 (GSourceFunc)process_internal_connection, connection, NULL);
472   g_source_attach (connection->source, NULL);
473 
474   g_io_channel_unref (io_channel);
475 
476   return connection;
477 }
478 
479 static void
gdk_remove_connection_handler(GdkInternalConnection * connection)480 gdk_remove_connection_handler (GdkInternalConnection *connection)
481 {
482   g_source_destroy (connection->source);
483   g_free (connection);
484 }
485 
486 static void
gdk_internal_connection_watch(Display * display,XPointer arg,gint fd,gboolean opening,XPointer * watch_data)487 gdk_internal_connection_watch (Display  *display,
488 			       XPointer  arg,
489 			       gint      fd,
490 			       gboolean  opening,
491 			       XPointer *watch_data)
492 {
493   if (opening)
494     *watch_data = (XPointer)gdk_add_connection_handler (display, fd);
495   else
496     gdk_remove_connection_handler ((GdkInternalConnection *)*watch_data);
497 }
498 #endif /* HAVE_X11R6 */
499 
500 /**
501  * gdk_display_get_name:
502  * @display: a #GdkDisplay
503  *
504  * Gets the name of the display.
505  *
506  * Returns: a string representing the display name. This string is owned
507  * by GDK and should not be modified or freed.
508  *
509  * Since: 2.2
510  */
511 const gchar *
gdk_display_get_name(GdkDisplay * display)512 gdk_display_get_name (GdkDisplay *display)
513 {
514   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
515 
516   return (gchar *) DisplayString (GDK_DISPLAY_X11 (display)->xdisplay);
517 }
518 
519 /**
520  * gdk_display_get_n_screens:
521  * @display: a #GdkDisplay
522  *
523  * Gets the number of screen managed by the @display.
524  *
525  * Returns: number of screens.
526  *
527  * Since: 2.2
528  */
529 gint
gdk_display_get_n_screens(GdkDisplay * display)530 gdk_display_get_n_screens (GdkDisplay *display)
531 {
532   g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
533 
534   return ScreenCount (GDK_DISPLAY_X11 (display)->xdisplay);
535 }
536 
537 /**
538  * gdk_display_get_screen:
539  * @display: a #GdkDisplay
540  * @screen_num: the screen number
541  *
542  * Returns a screen object for one of the screens of the display.
543  *
544  * Returns: the #GdkScreen object
545  *
546  * Since: 2.2
547  */
548 GdkScreen *
gdk_display_get_screen(GdkDisplay * display,gint screen_num)549 gdk_display_get_screen (GdkDisplay *display,
550 			gint        screen_num)
551 {
552   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
553   g_return_val_if_fail (ScreenCount (GDK_DISPLAY_X11 (display)->xdisplay) > screen_num, NULL);
554 
555   return GDK_DISPLAY_X11 (display)->screens[screen_num];
556 }
557 
558 /**
559  * gdk_display_get_default_screen:
560  * @display: a #GdkDisplay
561  *
562  * Get the default #GdkScreen for @display.
563  *
564  * Returns: the default #GdkScreen object for @display
565  *
566  * Since: 2.2
567  */
568 GdkScreen *
gdk_display_get_default_screen(GdkDisplay * display)569 gdk_display_get_default_screen (GdkDisplay *display)
570 {
571   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
572 
573   return GDK_DISPLAY_X11 (display)->default_screen;
574 }
575 
576 gboolean
_gdk_x11_display_is_root_window(GdkDisplay * display,Window xroot_window)577 _gdk_x11_display_is_root_window (GdkDisplay *display,
578 				 Window      xroot_window)
579 {
580   GdkDisplayX11 *display_x11;
581   gint i;
582 
583   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
584 
585   display_x11 = GDK_DISPLAY_X11 (display);
586 
587   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
588     {
589       if (GDK_SCREEN_XROOTWIN (display_x11->screens[i]) == xroot_window)
590 	return TRUE;
591     }
592   return FALSE;
593 }
594 
595 struct XPointerUngrabInfo {
596   GdkDisplay *display;
597   guint32 time;
598 };
599 
600 static void
pointer_ungrab_callback(GdkDisplay * display,gpointer data,gulong serial)601 pointer_ungrab_callback (GdkDisplay *display,
602 			 gpointer data,
603 			 gulong serial)
604 {
605   _gdk_display_pointer_grab_update (display, serial);
606 }
607 
608 
609 #define XSERVER_TIME_IS_LATER(time1, time2)                        \
610   ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) ||  \
611     (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 ))     \
612   )
613 
614 /**
615  * gdk_display_pointer_ungrab:
616  * @display: a #GdkDisplay.
617  * @time_: a timestap (e.g. %GDK_CURRENT_TIME).
618  *
619  * Release any pointer grab.
620  *
621  * Since: 2.2
622  */
623 void
gdk_display_pointer_ungrab(GdkDisplay * display,guint32 time_)624 gdk_display_pointer_ungrab (GdkDisplay *display,
625 			    guint32     time_)
626 {
627   Display *xdisplay;
628   GdkDisplayX11 *display_x11;
629   GdkPointerGrabInfo *grab;
630   unsigned long serial;
631 
632   g_return_if_fail (GDK_IS_DISPLAY (display));
633 
634   display_x11 = GDK_DISPLAY_X11 (display);
635   xdisplay = GDK_DISPLAY_XDISPLAY (display);
636 
637   serial = NextRequest (xdisplay);
638 
639   _gdk_input_ungrab_pointer (display, time_);
640   XUngrabPointer (xdisplay, time_);
641   XFlush (xdisplay);
642 
643   grab = _gdk_display_get_last_pointer_grab (display);
644   if (grab &&
645       (time_ == GDK_CURRENT_TIME ||
646        grab->time == GDK_CURRENT_TIME ||
647        !XSERVER_TIME_IS_LATER (grab->time, time_)))
648     {
649       grab->serial_end = serial;
650       _gdk_x11_roundtrip_async (display,
651 				pointer_ungrab_callback,
652 				NULL);
653     }
654 }
655 
656 /**
657  * gdk_display_keyboard_ungrab:
658  * @display: a #GdkDisplay.
659  * @time_: a timestap (e.g #GDK_CURRENT_TIME).
660  *
661  * Release any keyboard grab
662  *
663  * Since: 2.2
664  */
665 void
gdk_display_keyboard_ungrab(GdkDisplay * display,guint32 time)666 gdk_display_keyboard_ungrab (GdkDisplay *display,
667 			     guint32     time)
668 {
669   Display *xdisplay;
670   GdkDisplayX11 *display_x11;
671 
672   g_return_if_fail (GDK_IS_DISPLAY (display));
673 
674   display_x11 = GDK_DISPLAY_X11 (display);
675   xdisplay = GDK_DISPLAY_XDISPLAY (display);
676 
677   XUngrabKeyboard (xdisplay, time);
678   XFlush (xdisplay);
679 
680   if (time == GDK_CURRENT_TIME ||
681       display->keyboard_grab.time == GDK_CURRENT_TIME ||
682       !XSERVER_TIME_IS_LATER (display->keyboard_grab.time, time))
683     _gdk_display_unset_has_keyboard_grab (display, FALSE);
684 }
685 
686 /**
687  * gdk_display_beep:
688  * @display: a #GdkDisplay
689  *
690  * Emits a short beep on @display
691  *
692  * Since: 2.2
693  */
694 void
gdk_display_beep(GdkDisplay * display)695 gdk_display_beep (GdkDisplay *display)
696 {
697   g_return_if_fail (GDK_IS_DISPLAY (display));
698 
699 #ifdef HAVE_XKB
700   XkbBell (GDK_DISPLAY_XDISPLAY (display), None, 0, None);
701 #else
702   XBell (GDK_DISPLAY_XDISPLAY (display), 0);
703 #endif
704 }
705 
706 /**
707  * gdk_display_sync:
708  * @display: a #GdkDisplay
709  *
710  * Flushes any requests queued for the windowing system and waits until all
711  * requests have been handled. This is often used for making sure that the
712  * display is synchronized with the current state of the program. Calling
713  * gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors
714  * generated from earlier requests are handled before the error trap is
715  * removed.
716  *
717  * This is most useful for X11. On windowing systems where requests are
718  * handled synchronously, this function will do nothing.
719  *
720  * Since: 2.2
721  */
722 void
gdk_display_sync(GdkDisplay * display)723 gdk_display_sync (GdkDisplay *display)
724 {
725   g_return_if_fail (GDK_IS_DISPLAY (display));
726 
727   XSync (GDK_DISPLAY_XDISPLAY (display), False);
728 }
729 
730 /**
731  * gdk_display_flush:
732  * @display: a #GdkDisplay
733  *
734  * Flushes any requests queued for the windowing system; this happens automatically
735  * when the main loop blocks waiting for new events, but if your application
736  * is drawing without returning control to the main loop, you may need
737  * to call this function explicitely. A common case where this function
738  * needs to be called is when an application is executing drawing commands
739  * from a thread other than the thread where the main loop is running.
740  *
741  * This is most useful for X11. On windowing systems where requests are
742  * handled synchronously, this function will do nothing.
743  *
744  * Since: 2.4
745  */
746 void
gdk_display_flush(GdkDisplay * display)747 gdk_display_flush (GdkDisplay *display)
748 {
749   g_return_if_fail (GDK_IS_DISPLAY (display));
750 
751   if (!display->closed)
752     XFlush (GDK_DISPLAY_XDISPLAY (display));
753 }
754 
755 /**
756  * gdk_display_get_default_group:
757  * @display: a #GdkDisplay
758  *
759  * Returns the default group leader window for all toplevel windows
760  * on @display. This window is implicitly created by GDK.
761  * See gdk_window_set_group().
762  *
763  * Return value: The default group leader window for @display
764  *
765  * Since: 2.4
766  **/
767 GdkWindow *
gdk_display_get_default_group(GdkDisplay * display)768 gdk_display_get_default_group (GdkDisplay *display)
769 {
770   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
771 
772   return GDK_DISPLAY_X11 (display)->leader_gdk_window;
773 }
774 
775 /**
776  * gdk_x11_display_grab:
777  * @display: a #GdkDisplay
778  *
779  * Call XGrabServer() on @display.
780  * To ungrab the display again, use gdk_x11_display_ungrab().
781  *
782  * gdk_x11_display_grab()/gdk_x11_display_ungrab() calls can be nested.
783  *
784  * Since: 2.2
785  **/
786 void
gdk_x11_display_grab(GdkDisplay * display)787 gdk_x11_display_grab (GdkDisplay *display)
788 {
789   GdkDisplayX11 *display_x11;
790 
791   g_return_if_fail (GDK_IS_DISPLAY (display));
792 
793   display_x11 = GDK_DISPLAY_X11 (display);
794 
795   if (display_x11->grab_count == 0)
796     XGrabServer (display_x11->xdisplay);
797   display_x11->grab_count++;
798 }
799 
800 /**
801  * gdk_x11_display_ungrab:
802  * @display: a #GdkDisplay
803  *
804  * Ungrab @display after it has been grabbed with
805  * gdk_x11_display_grab().
806  *
807  * Since: 2.2
808  **/
809 void
gdk_x11_display_ungrab(GdkDisplay * display)810 gdk_x11_display_ungrab (GdkDisplay *display)
811 {
812   GdkDisplayX11 *display_x11;
813 
814   g_return_if_fail (GDK_IS_DISPLAY (display));
815 
816   display_x11 = GDK_DISPLAY_X11 (display);;
817   g_return_if_fail (display_x11->grab_count > 0);
818 
819   display_x11->grab_count--;
820   if (display_x11->grab_count == 0)
821     {
822       XUngrabServer (display_x11->xdisplay);
823       XFlush (display_x11->xdisplay);
824     }
825 }
826 
827 static void
gdk_display_x11_dispose(GObject * object)828 gdk_display_x11_dispose (GObject *object)
829 {
830   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object);
831   gint           i;
832 
833   g_list_foreach (display_x11->input_devices, (GFunc) g_object_run_dispose, NULL);
834 
835   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
836     _gdk_screen_close (display_x11->screens[i]);
837 
838   _gdk_events_uninit (GDK_DISPLAY_OBJECT (object));
839 
840   G_OBJECT_CLASS (_gdk_display_x11_parent_class)->dispose (object);
841 }
842 
843 static void
gdk_display_x11_finalize(GObject * object)844 gdk_display_x11_finalize (GObject *object)
845 {
846   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object);
847   gint           i;
848 
849   /* Keymap */
850   if (display_x11->keymap)
851     g_object_unref (display_x11->keymap);
852 
853   /* Free motif Dnd */
854   if (display_x11->motif_target_lists)
855     {
856       for (i = 0; i < display_x11->motif_n_target_lists; i++)
857         g_list_free (display_x11->motif_target_lists[i]);
858       g_free (display_x11->motif_target_lists);
859     }
860 
861   _gdk_x11_cursor_display_finalize (GDK_DISPLAY_OBJECT(display_x11));
862 
863   /* Atom Hashtable */
864   g_hash_table_destroy (display_x11->atom_from_virtual);
865   g_hash_table_destroy (display_x11->atom_to_virtual);
866 
867   /* Leader Window */
868   XDestroyWindow (display_x11->xdisplay, display_x11->leader_window);
869 
870   /* list of filters for client messages */
871   g_list_foreach (display_x11->client_filters, (GFunc) g_free, NULL);
872   g_list_free (display_x11->client_filters);
873 
874   /* List of event window extraction functions */
875   g_slist_foreach (display_x11->event_types, (GFunc)g_free, NULL);
876   g_slist_free (display_x11->event_types);
877 
878   /* input GdkDevice list */
879   g_list_foreach (display_x11->input_devices, (GFunc) g_object_unref, NULL);
880   g_list_free (display_x11->input_devices);
881 
882   /* input GdkWindow list */
883   g_list_foreach (display_x11->input_windows, (GFunc) g_free, NULL);
884   g_list_free (display_x11->input_windows);
885 
886   /* Free all GdkScreens */
887   for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
888     g_object_unref (display_x11->screens[i]);
889   g_free (display_x11->screens);
890 
891   g_free (display_x11->startup_notification_id);
892 
893   /* X ID hashtable */
894   g_hash_table_destroy (display_x11->xid_ht);
895 
896   XCloseDisplay (display_x11->xdisplay);
897 
898   G_OBJECT_CLASS (_gdk_display_x11_parent_class)->finalize (object);
899 }
900 
901 /**
902  * gdk_x11_lookup_xdisplay:
903  * @xdisplay: a pointer to an X Display
904  *
905  * Find the #GdkDisplay corresponding to @display, if any exists.
906  *
907  * Return value: the #GdkDisplay, if found, otherwise %NULL.
908  *
909  * Since: 2.2
910  **/
911 GdkDisplay *
gdk_x11_lookup_xdisplay(Display * xdisplay)912 gdk_x11_lookup_xdisplay (Display *xdisplay)
913 {
914   GSList *tmp_list;
915 
916   for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
917     {
918       if (GDK_DISPLAY_XDISPLAY (tmp_list->data) == xdisplay)
919 	return tmp_list->data;
920     }
921 
922   return NULL;
923 }
924 
925 /**
926  * _gdk_x11_display_screen_for_xrootwin:
927  * @display: a #GdkDisplay
928  * @xrootwin: window ID for one of of the screen's of the display.
929  *
930  * Given the root window ID of one of the screen's of a #GdkDisplay,
931  * finds the screen.
932  *
933  * Return value: (transfer none): the #GdkScreen corresponding to
934  *     @xrootwin, or %NULL.
935  **/
936 GdkScreen *
_gdk_x11_display_screen_for_xrootwin(GdkDisplay * display,Window xrootwin)937 _gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
938 				      Window      xrootwin)
939 {
940   gint i;
941 
942   for (i = 0; i < ScreenCount (GDK_DISPLAY_X11 (display)->xdisplay); i++)
943     {
944       GdkScreen *screen = gdk_display_get_screen (display, i);
945       if (GDK_SCREEN_XROOTWIN (screen) == xrootwin)
946 	return screen;
947     }
948 
949   return NULL;
950 }
951 
952 /**
953  * gdk_x11_display_get_xdisplay:
954  * @display: a #GdkDisplay
955  * @returns: an X display.
956  *
957  * Returns the X display of a #GdkDisplay.
958  *
959  * Since: 2.2
960  */
961 Display *
gdk_x11_display_get_xdisplay(GdkDisplay * display)962 gdk_x11_display_get_xdisplay (GdkDisplay *display)
963 {
964   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
965   return GDK_DISPLAY_X11 (display)->xdisplay;
966 }
967 
968 void
_gdk_windowing_set_default_display(GdkDisplay * display)969 _gdk_windowing_set_default_display (GdkDisplay *display)
970 {
971   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
972   const gchar *startup_id;
973 
974   if (!display)
975     {
976       gdk_display = NULL;
977       return;
978     }
979 
980   gdk_display = GDK_DISPLAY_XDISPLAY (display);
981 
982   g_free (display_x11->startup_notification_id);
983   display_x11->startup_notification_id = NULL;
984 
985   startup_id = g_getenv ("DESKTOP_STARTUP_ID");
986   if (startup_id && *startup_id != '\0')
987     {
988       gchar *time_str;
989 
990       if (!g_utf8_validate (startup_id, -1, NULL))
991 	g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
992       else
993 	display_x11->startup_notification_id = g_strdup (startup_id);
994 
995       /* Find the launch time from the startup_id, if it's there.  Newer spec
996        * states that the startup_id is of the form <unique>_TIME<timestamp>
997        */
998       time_str = g_strrstr (startup_id, "_TIME");
999       if (time_str != NULL)
1000         {
1001 	  gulong retval;
1002           gchar *end;
1003           errno = 0;
1004 
1005           /* Skip past the "_TIME" part */
1006           time_str += 5;
1007 
1008           retval = strtoul (time_str, &end, 0);
1009           if (end != time_str && errno == 0)
1010             display_x11->user_time = retval;
1011         }
1012 
1013       /* Clear the environment variable so it won't be inherited by
1014        * child processes and confuse things.
1015        */
1016       g_unsetenv ("DESKTOP_STARTUP_ID");
1017 
1018       /* Set the startup id on the leader window so it
1019        * applies to all windows we create on this display
1020        */
1021       XChangeProperty (display_x11->xdisplay,
1022 		       display_x11->leader_window,
1023 		       gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
1024 		       gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
1025 		       PropModeReplace,
1026 		       (guchar *)startup_id, strlen (startup_id));
1027     }
1028 }
1029 
1030 static void
broadcast_xmessage(GdkDisplay * display,const char * message_type,const char * message_type_begin,const char * message)1031 broadcast_xmessage (GdkDisplay *display,
1032 		    const char *message_type,
1033 		    const char *message_type_begin,
1034 		    const char *message)
1035 {
1036   Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
1037   GdkScreen *screen = gdk_display_get_default_screen (display);
1038   GdkWindow *root_window = gdk_screen_get_root_window (screen);
1039   Window xroot_window = GDK_WINDOW_XID (root_window);
1040 
1041   Atom type_atom;
1042   Atom type_atom_begin;
1043   Window xwindow;
1044 
1045   if (!G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
1046     return;
1047 
1048   {
1049     XSetWindowAttributes attrs;
1050 
1051     attrs.override_redirect = True;
1052     attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
1053 
1054     xwindow =
1055       XCreateWindow (xdisplay,
1056                      xroot_window,
1057                      -100, -100, 1, 1,
1058                      0,
1059                      CopyFromParent,
1060                      CopyFromParent,
1061                      (Visual *)CopyFromParent,
1062                      CWOverrideRedirect | CWEventMask,
1063                      &attrs);
1064   }
1065 
1066   type_atom = gdk_x11_get_xatom_by_name_for_display (display,
1067                                                      message_type);
1068   type_atom_begin = gdk_x11_get_xatom_by_name_for_display (display,
1069                                                            message_type_begin);
1070 
1071   {
1072     XClientMessageEvent xclient;
1073     const char *src;
1074     const char *src_end;
1075     char *dest;
1076     char *dest_end;
1077 
1078 		memset(&xclient, 0, sizeof (xclient));
1079     xclient.type = ClientMessage;
1080     xclient.message_type = type_atom_begin;
1081     xclient.display =xdisplay;
1082     xclient.window = xwindow;
1083     xclient.format = 8;
1084 
1085     src = message;
1086     src_end = message + strlen (message) + 1; /* +1 to include nul byte */
1087 
1088     while (src != src_end)
1089       {
1090         dest = &xclient.data.b[0];
1091         dest_end = dest + 20;
1092 
1093         while (dest != dest_end &&
1094                src != src_end)
1095           {
1096             *dest = *src;
1097             ++dest;
1098             ++src;
1099           }
1100 
1101 	while (dest != dest_end)
1102 	  {
1103 	    *dest = 0;
1104 	    ++dest;
1105 	  }
1106 
1107         XSendEvent (xdisplay,
1108                     xroot_window,
1109                     False,
1110                     PropertyChangeMask,
1111                     (XEvent *)&xclient);
1112 
1113         xclient.message_type = type_atom;
1114       }
1115   }
1116 
1117   XDestroyWindow (xdisplay, xwindow);
1118   XFlush (xdisplay);
1119 }
1120 
1121 /**
1122  * gdk_x11_display_broadcast_startup_message:
1123  * @display: a #GdkDisplay
1124  * @message_type: startup notification message type ("new", "change",
1125  * or "remove")
1126  * @...: a list of key/value pairs (as strings), terminated by a
1127  * %NULL key. (A %NULL value for a key will cause that key to be
1128  * skipped in the output.)
1129  *
1130  * Sends a startup notification message of type @message_type to
1131  * @display.
1132  *
1133  * This is a convenience function for use by code that implements the
1134  * freedesktop startup notification specification. Applications should
1135  * not normally need to call it directly. See the <ulink
1136  * url="http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt">Startup
1137  * Notification Protocol specification</ulink> for
1138  * definitions of the message types and keys that can be used.
1139  *
1140  * Since: 2.12
1141  **/
1142 void
gdk_x11_display_broadcast_startup_message(GdkDisplay * display,const char * message_type,...)1143 gdk_x11_display_broadcast_startup_message (GdkDisplay *display,
1144 					   const char *message_type,
1145 					   ...)
1146 {
1147   GString *message;
1148   va_list ap;
1149   const char *key, *value, *p;
1150 
1151   message = g_string_new (message_type);
1152   g_string_append_c (message, ':');
1153 
1154   va_start (ap, message_type);
1155   while ((key = va_arg (ap, const char *)))
1156     {
1157       value = va_arg (ap, const char *);
1158       if (!value)
1159 	continue;
1160 
1161       g_string_append_printf (message, " %s=\"", key);
1162       for (p = value; *p; p++)
1163 	{
1164 	  switch (*p)
1165 	    {
1166 	    case ' ':
1167 	    case '"':
1168 	    case '\\':
1169 	      g_string_append_c (message, '\\');
1170 	      break;
1171 	    }
1172 
1173 	  g_string_append_c (message, *p);
1174 	}
1175       g_string_append_c (message, '\"');
1176     }
1177   va_end (ap);
1178 
1179   broadcast_xmessage (display,
1180 		      "_NET_STARTUP_INFO",
1181                       "_NET_STARTUP_INFO_BEGIN",
1182                       message->str);
1183 
1184   g_string_free (message, TRUE);
1185 }
1186 
1187 /**
1188  * gdk_notify_startup_complete:
1189  *
1190  * Indicates to the GUI environment that the application has finished
1191  * loading. If the applications opens windows, this function is
1192  * normally called after opening the application's initial set of
1193  * windows.
1194  *
1195  * GTK+ will call this function automatically after opening the first
1196  * #GtkWindow unless gtk_window_set_auto_startup_notification() is called
1197  * to disable that feature.
1198  *
1199  * Since: 2.2
1200  **/
1201 void
gdk_notify_startup_complete(void)1202 gdk_notify_startup_complete (void)
1203 {
1204   GdkDisplay *display;
1205   GdkDisplayX11 *display_x11;
1206 
1207   display = gdk_display_get_default ();
1208   if (!display)
1209     return;
1210 
1211   display_x11 = GDK_DISPLAY_X11 (display);
1212 
1213   if (display_x11->startup_notification_id == NULL)
1214     return;
1215 
1216   gdk_notify_startup_complete_with_id (display_x11->startup_notification_id);
1217 }
1218 
1219 /**
1220  * gdk_notify_startup_complete_with_id:
1221  * @startup_id: a startup-notification identifier, for which notification
1222  *              process should be completed
1223  *
1224  * Indicates to the GUI environment that the application has finished
1225  * loading, using a given identifier.
1226  *
1227  * GTK+ will call this function automatically for #GtkWindow with custom
1228  * startup-notification identifier unless
1229  * gtk_window_set_auto_startup_notification() is called to disable
1230  * that feature.
1231  *
1232  * Since: 2.12
1233  **/
1234 void
gdk_notify_startup_complete_with_id(const gchar * startup_id)1235 gdk_notify_startup_complete_with_id (const gchar* startup_id)
1236 {
1237   GdkDisplay *display;
1238 
1239   display = gdk_display_get_default ();
1240   if (!display)
1241     return;
1242 
1243   gdk_x11_display_broadcast_startup_message (display, "remove",
1244 					     "ID", startup_id,
1245 					     NULL);
1246 }
1247 
1248 /**
1249  * gdk_display_supports_selection_notification:
1250  * @display: a #GdkDisplay
1251  *
1252  * Returns whether #GdkEventOwnerChange events will be
1253  * sent when the owner of a selection changes.
1254  *
1255  * Return value: whether #GdkEventOwnerChange events will
1256  *               be sent.
1257  *
1258  * Since: 2.6
1259  **/
1260 gboolean
gdk_display_supports_selection_notification(GdkDisplay * display)1261 gdk_display_supports_selection_notification (GdkDisplay *display)
1262 {
1263   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1264 
1265   return display_x11->have_xfixes;
1266 }
1267 
1268 /**
1269  * gdk_display_request_selection_notification:
1270  * @display: a #GdkDisplay
1271  * @selection: the #GdkAtom naming the selection for which
1272  *             ownership change notification is requested
1273  *
1274  * Request #GdkEventOwnerChange events for ownership changes
1275  * of the selection named by the given atom.
1276  *
1277  * Return value: whether #GdkEventOwnerChange events will
1278  *               be sent.
1279  *
1280  * Since: 2.6
1281  **/
1282 gboolean
gdk_display_request_selection_notification(GdkDisplay * display,GdkAtom selection)1283 gdk_display_request_selection_notification (GdkDisplay *display,
1284 					    GdkAtom     selection)
1285 
1286 {
1287 #ifdef HAVE_XFIXES
1288   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1289   Atom atom;
1290 
1291   if (display_x11->have_xfixes)
1292     {
1293       atom = gdk_x11_atom_to_xatom_for_display (display,
1294 						selection);
1295       XFixesSelectSelectionInput (display_x11->xdisplay,
1296 				  display_x11->leader_window,
1297 				  atom,
1298 				  XFixesSetSelectionOwnerNotifyMask |
1299 				  XFixesSelectionWindowDestroyNotifyMask |
1300 				  XFixesSelectionClientCloseNotifyMask);
1301       return TRUE;
1302     }
1303   else
1304 #endif
1305     return FALSE;
1306 }
1307 
1308 /**
1309  * gdk_display_supports_clipboard_persistence
1310  * @display: a #GdkDisplay
1311  *
1312  * Returns whether the speicifed display supports clipboard
1313  * persistance; i.e. if it's possible to store the clipboard data after an
1314  * application has quit. On X11 this checks if a clipboard daemon is
1315  * running.
1316  *
1317  * Returns: %TRUE if the display supports clipboard persistance.
1318  *
1319  * Since: 2.6
1320  */
1321 gboolean
gdk_display_supports_clipboard_persistence(GdkDisplay * display)1322 gdk_display_supports_clipboard_persistence (GdkDisplay *display)
1323 {
1324   Atom clipboard_manager;
1325 
1326   /* It might make sense to cache this */
1327   clipboard_manager = gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
1328   return XGetSelectionOwner (GDK_DISPLAY_X11 (display)->xdisplay, clipboard_manager) != None;
1329 }
1330 
1331 /**
1332  * gdk_display_store_clipboard
1333  * @display:          a #GdkDisplay
1334  * @clipboard_window: a #GdkWindow belonging to the clipboard owner
1335  * @time_:            a timestamp
1336  * @targets:	      an array of targets that should be saved, or %NULL
1337  *                    if all available targets should be saved.
1338  * @n_targets:        length of the @targets array
1339  *
1340  * Issues a request to the clipboard manager to store the
1341  * clipboard data. On X11, this is a special program that works
1342  * according to the freedesktop clipboard specification, available at
1343  * <ulink url="http://www.freedesktop.org/Standards/clipboard-manager-spec">
1344  * http://www.freedesktop.org/Standards/clipboard-manager-spec</ulink>.
1345  *
1346  * Since: 2.6
1347  */
1348 void
gdk_display_store_clipboard(GdkDisplay * display,GdkWindow * clipboard_window,guint32 time_,const GdkAtom * targets,gint n_targets)1349 gdk_display_store_clipboard (GdkDisplay    *display,
1350 			     GdkWindow     *clipboard_window,
1351 			     guint32        time_,
1352 			     const GdkAtom *targets,
1353 			     gint           n_targets)
1354 {
1355   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1356   Atom clipboard_manager, save_targets;
1357 
1358   g_return_if_fail (GDK_WINDOW_IS_X11 (clipboard_window));
1359 
1360   clipboard_manager = gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
1361   save_targets = gdk_x11_get_xatom_by_name_for_display (display, "SAVE_TARGETS");
1362 
1363   gdk_error_trap_push ();
1364 
1365   if (XGetSelectionOwner (display_x11->xdisplay, clipboard_manager) != None)
1366     {
1367       Atom property_name = None;
1368       Atom *xatoms;
1369       int i;
1370 
1371       if (n_targets > 0)
1372 	{
1373 	  property_name = gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property);
1374 
1375 	  xatoms = g_new (Atom, n_targets);
1376 	  for (i = 0; i < n_targets; i++)
1377 	    xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, targets[i]);
1378 
1379 	  XChangeProperty (display_x11->xdisplay, GDK_WINDOW_XID (clipboard_window),
1380 			   property_name, XA_ATOM,
1381 			   32, PropModeReplace, (guchar *)xatoms, n_targets);
1382 	  g_free (xatoms);
1383 
1384 	}
1385 
1386       XConvertSelection (display_x11->xdisplay,
1387 			 clipboard_manager, save_targets, property_name,
1388 			 GDK_WINDOW_XID (clipboard_window), time_);
1389 
1390     }
1391   gdk_error_trap_pop ();
1392 
1393 }
1394 
1395 /**
1396  * gdk_x11_display_get_user_time:
1397  * @display: a #GdkDisplay
1398  *
1399  * Returns the timestamp of the last user interaction on
1400  * @display. The timestamp is taken from events caused
1401  * by user interaction such as key presses or pointer
1402  * movements. See gdk_x11_window_set_user_time().
1403  *
1404  * Returns: the timestamp of the last user interaction
1405  *
1406  * Since: 2.8
1407  */
1408 guint32
gdk_x11_display_get_user_time(GdkDisplay * display)1409 gdk_x11_display_get_user_time (GdkDisplay *display)
1410 {
1411   return GDK_DISPLAY_X11 (display)->user_time;
1412 }
1413 
1414 /**
1415  * gdk_display_supports_shapes:
1416  * @display: a #GdkDisplay
1417  *
1418  * Returns %TRUE if gdk_window_shape_combine_mask() can
1419  * be used to create shaped windows on @display.
1420  *
1421  * Returns: %TRUE if shaped windows are supported
1422  *
1423  * Since: 2.10
1424  */
1425 gboolean
gdk_display_supports_shapes(GdkDisplay * display)1426 gdk_display_supports_shapes (GdkDisplay *display)
1427 {
1428   return GDK_DISPLAY_X11 (display)->have_shapes;
1429 }
1430 
1431 /**
1432  * gdk_display_supports_input_shapes:
1433  * @display: a #GdkDisplay
1434  *
1435  * Returns %TRUE if gdk_window_input_shape_combine_mask() can
1436  * be used to modify the input shape of windows on @display.
1437  *
1438  * Returns: %TRUE if windows with modified input shape are supported
1439  *
1440  * Since: 2.10
1441  */
1442 gboolean
gdk_display_supports_input_shapes(GdkDisplay * display)1443 gdk_display_supports_input_shapes (GdkDisplay *display)
1444 {
1445   return GDK_DISPLAY_X11 (display)->have_input_shapes;
1446 }
1447 
1448 
1449 /**
1450  * gdk_x11_display_get_startup_notification_id:
1451  * @display: a #GdkDisplay
1452  *
1453  * Gets the startup notification ID for a display.
1454  *
1455  * Returns: the startup notification ID for @display
1456  *
1457  * Since: 2.12
1458  */
1459 const gchar *
gdk_x11_display_get_startup_notification_id(GdkDisplay * display)1460 gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
1461 {
1462   return GDK_DISPLAY_X11 (display)->startup_notification_id;
1463 }
1464 
1465 /**
1466  * gdk_display_supports_composite:
1467  * @display: a #GdkDisplay
1468  *
1469  * Returns %TRUE if gdk_window_set_composited() can be used
1470  * to redirect drawing on the window using compositing.
1471  *
1472  * Currently this only works on X11 with XComposite and
1473  * XDamage extensions available.
1474  *
1475  * Returns: %TRUE if windows may be composited.
1476  *
1477  * Since: 2.12
1478  */
1479 gboolean
gdk_display_supports_composite(GdkDisplay * display)1480 gdk_display_supports_composite (GdkDisplay *display)
1481 {
1482   GdkDisplayX11 *x11_display = GDK_DISPLAY_X11 (display);
1483 
1484   return x11_display->have_xcomposite &&
1485 	 x11_display->have_xdamage &&
1486 	 x11_display->have_xfixes;
1487 }
1488 
1489 
1490 #define __GDK_DISPLAY_X11_C__
1491 #include "gdkaliasdef.c"
1492