1 /* GDK - The GIMP Drawing Kit
4 * Copyright 2001 Sun Microsystems Inc.
5 * Copyright (C) 2004 Nokia Corporation
7 * Erwann Chenede <erwann.chenede@sun.com>
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.
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.
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.
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"
44 #include <X11/Xatom.h>
47 #include <X11/XKBlib.h>
51 #include <X11/extensions/Xfixes.h>
55 #include <X11/extensions/shape.h>
58 #ifdef HAVE_XCOMPOSITE
59 #include <X11/extensions/Xcomposite.h>
63 #include <X11/extensions/Xdamage.h>
67 #include <X11/extensions/Xrandr.h>
71 static void gdk_display_x11_dispose (GObject *object);
72 static void gdk_display_x11_finalize (GObject *object);
75 static void gdk_internal_connection_watch (Display *display,
79 XPointer *watch_data);
80 #endif /* HAVE_X11R6 */
82 /* Note that we never *directly* use WM_LOCALE_NAME, WM_PROTOCOLS,
83 * but including them here has the side-effect of getting them
84 * into the internal Xlib cache
86 static const char *const precache_atoms[] = {
97 "_NET_CURRENT_DESKTOP",
108 "_NET_WM_STATE_ABOVE",
109 "_NET_WM_STATE_BELOW",
110 "_NET_WM_STATE_FULLSCREEN",
111 "_NET_WM_STATE_MODAL",
112 "_NET_WM_STATE_MAXIMIZED_VERT",
113 "_NET_WM_STATE_MAXIMIZED_HORZ",
114 "_NET_WM_STATE_SKIP_TASKBAR",
115 "_NET_WM_STATE_SKIP_PAGER",
116 "_NET_WM_STATE_STICKY",
117 "_NET_WM_SYNC_REQUEST",
118 "_NET_WM_SYNC_REQUEST_COUNTER",
119 "_NET_WM_WINDOW_TYPE",
120 "_NET_WM_WINDOW_TYPE_NORMAL",
125 G_DEFINE_TYPE (GdkDisplayX11, _gdk_display_x11, GDK_TYPE_DISPLAY)
128 _gdk_display_x11_class_init (GdkDisplayX11Class * class)
130 GObjectClass *object_class = G_OBJECT_CLASS (class);
132 object_class->dispose = gdk_display_x11_dispose;
133 object_class->finalize = gdk_display_x11_finalize;
137 _gdk_display_x11_init (GdkDisplayX11 *display)
143 * @display_name: the name of the display to open
144 * @returns: a #GdkDisplay, or %NULL if the display
145 * could not be opened.
152 gdk_display_open (const gchar *display_name)
156 GdkDisplayX11 *display_x11;
160 const char *sm_client_id;
162 XClassHint *class_hint;
165 #if defined(HAVE_XFIXES) || defined(HAVE_SHAPE_EXT)
170 xdisplay = XOpenDisplay (display_name);
174 display = g_object_new (GDK_TYPE_DISPLAY_X11, NULL);
175 display_x11 = GDK_DISPLAY_X11 (display);
177 display_x11->use_xshm = TRUE;
178 display_x11->xdisplay = xdisplay;
181 /* Set up handlers for Xlib internal connections */
182 XAddConnectionWatch (xdisplay, gdk_internal_connection_watch, NULL);
183 #endif /* HAVE_X11R6 */
185 _gdk_x11_precache_atoms (display, precache_atoms, G_N_ELEMENTS (precache_atoms));
187 /* RandR must be initialized before we initialize the screens */
188 display_x11->have_randr13 = FALSE;
190 if (XRRQueryExtension (display_x11->xdisplay,
191 &display_x11->xrandr_event_base, &ignore))
195 XRRQueryVersion (display_x11->xdisplay, &major, &minor);
197 if ((major == 1 && minor >= 3) || major > 1)
198 display_x11->have_randr13 = TRUE;
200 gdk_x11_register_standard_event_type (display, display_x11->xrandr_event_base, RRNumberEvents);
204 /* initialize the display's screens */
205 display_x11->screens = g_new (GdkScreen *, ScreenCount (display_x11->xdisplay));
206 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
207 display_x11->screens[i] = _gdk_x11_screen_new (display, i);
209 /* We need to initialize events after we have the screen
210 * structures in places
212 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
213 _gdk_x11_events_init_screen (display_x11->screens[i]);
215 /*set the default screen */
216 display_x11->default_screen = display_x11->screens[DefaultScreen (display_x11->xdisplay)];
218 attr.window_type = GDK_WINDOW_TOPLEVEL;
219 attr.wclass = GDK_INPUT_OUTPUT;
226 display_x11->leader_gdk_window = gdk_window_new (GDK_SCREEN_X11 (display_x11->default_screen)->root_window,
227 &attr, GDK_WA_X | GDK_WA_Y);
228 (_gdk_x11_window_get_toplevel (display_x11->leader_gdk_window))->is_leader = TRUE;
230 display_x11->leader_window = GDK_WINDOW_XID (display_x11->leader_gdk_window);
232 display_x11->leader_window_title_set = FALSE;
234 display_x11->have_render = GDK_UNKNOWN;
237 if (XFixesQueryExtension (display_x11->xdisplay,
238 &display_x11->xfixes_event_base,
241 display_x11->have_xfixes = TRUE;
243 gdk_x11_register_standard_event_type (display,
244 display_x11->xfixes_event_base,
249 display_x11->have_xfixes = FALSE;
251 #ifdef HAVE_XCOMPOSITE
252 if (XCompositeQueryExtension (display_x11->xdisplay,
257 XCompositeQueryVersion (display_x11->xdisplay, &major, &minor);
259 /* Prior to Composite version 0.4, composited windows clipped their
260 * parents, so you had to use IncludeInferiors to draw to the parent
261 * This isn't useful for our purposes, so require 0.4
263 display_x11->have_xcomposite = major > 0 || (major == 0 && minor >= 4);
267 display_x11->have_xcomposite = FALSE;
270 if (XDamageQueryExtension (display_x11->xdisplay,
271 &display_x11->xdamage_event_base,
274 display_x11->have_xdamage = TRUE;
276 gdk_x11_register_standard_event_type (display,
277 display_x11->xdamage_event_base,
278 XDamageNumberEvents);
282 display_x11->have_xdamage = FALSE;
284 display_x11->have_shapes = FALSE;
285 display_x11->have_input_shapes = FALSE;
286 #ifdef HAVE_SHAPE_EXT
287 if (XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display), &ignore, &ignore))
289 display_x11->have_shapes = TRUE;
291 if (XShapeQueryVersion (GDK_DISPLAY_XDISPLAY (display), &maj, &min))
292 display_x11->have_input_shapes = (maj == 1 && min >= 1);
297 display_x11->trusted_client = TRUE;
300 int rootx, rooty, winx, winy;
303 gdk_error_trap_push ();
304 XQueryPointer (display_x11->xdisplay,
305 GDK_SCREEN_X11 (display_x11->default_screen)->xroot_window,
306 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
308 if (G_UNLIKELY (gdk_error_trap_pop () == BadWindow))
310 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));
311 display_x11->trusted_client = FALSE;
315 if (_gdk_synchronize)
316 XSynchronize (display_x11->xdisplay, True);
318 class_hint = XAllocClassHint();
319 class_hint->res_name = g_get_prgname ();
321 class_hint->res_class = (char *)gdk_get_program_class ();
323 /* XmbSetWMProperties sets the RESOURCE_NAME environment variable
324 * from argv[0], so we just synthesize an argument array here.
327 argv[0] = g_get_prgname ();
329 XmbSetWMProperties (display_x11->xdisplay,
330 display_x11->leader_window,
331 NULL, NULL, argv, argc, NULL, NULL,
335 sm_client_id = _gdk_get_sm_client_id ();
337 _gdk_windowing_display_set_sm_client_id (display, sm_client_id);
340 XChangeProperty (display_x11->xdisplay,
341 display_x11->leader_window,
342 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
343 XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1);
345 /* We don't yet know a valid time. */
346 display_x11->user_time = 0;
350 gint xkb_major = XkbMajorVersion;
351 gint xkb_minor = XkbMinorVersion;
352 if (XkbLibraryVersion (&xkb_major, &xkb_minor))
354 xkb_major = XkbMajorVersion;
355 xkb_minor = XkbMinorVersion;
357 if (XkbQueryExtension (display_x11->xdisplay,
358 NULL, &display_x11->xkb_event_type, NULL,
359 &xkb_major, &xkb_minor))
361 Bool detectable_autorepeat_supported;
363 display_x11->use_xkb = TRUE;
365 XkbSelectEvents (display_x11->xdisplay,
367 XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask,
368 XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask);
370 /* keep this in sync with _gdk_keymap_state_changed() */
371 XkbSelectEventDetails (display_x11->xdisplay,
372 XkbUseCoreKbd, XkbStateNotify,
373 XkbAllStateComponentsMask,
374 XkbGroupLockMask|XkbModifierLockMask);
376 XkbSetDetectableAutoRepeat (display_x11->xdisplay,
378 &detectable_autorepeat_supported);
380 GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.",
381 detectable_autorepeat_supported ?
382 "supported" : "not supported"));
384 display_x11->have_xkb_autorepeat = detectable_autorepeat_supported;
390 display_x11->use_sync = FALSE;
394 int error_base, event_base;
396 if (XSyncQueryExtension (display_x11->xdisplay,
397 &event_base, &error_base) &&
398 XSyncInitialize (display_x11->xdisplay,
400 display_x11->use_sync = TRUE;
404 _gdk_windowing_image_init (display);
405 _gdk_events_init (display);
406 _gdk_input_init (display);
407 _gdk_dnd_init (display);
409 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
410 gdk_display_request_selection_notification (display,
411 GDK_SCREEN_X11 (display_x11->screens[i])->cm_selection_atom);
413 g_signal_emit_by_name (gdk_display_manager_get(),
414 "display_opened", display);
421 * XLib internal connection handling
423 typedef struct _GdkInternalConnection GdkInternalConnection;
425 struct _GdkInternalConnection
433 process_internal_connection (GIOChannel *gioc,
437 GdkInternalConnection *connection = (GdkInternalConnection *)data;
439 GDK_THREADS_ENTER ();
441 XProcessInternalConnection ((Display*)connection->display, connection->fd);
443 GDK_THREADS_LEAVE ();
449 _gdk_windowing_window_get_next_serial (GdkDisplay *display)
451 return NextRequest (GDK_DISPLAY_XDISPLAY (display));
455 static GdkInternalConnection *
456 gdk_add_connection_handler (Display *display,
459 GIOChannel *io_channel;
460 GdkInternalConnection *connection;
462 connection = g_new (GdkInternalConnection, 1);
465 connection->display = display;
467 io_channel = g_io_channel_unix_new (fd);
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);
474 g_io_channel_unref (io_channel);
480 gdk_remove_connection_handler (GdkInternalConnection *connection)
482 g_source_destroy (connection->source);
487 gdk_internal_connection_watch (Display *display,
491 XPointer *watch_data)
494 *watch_data = (XPointer)gdk_add_connection_handler (display, fd);
496 gdk_remove_connection_handler ((GdkInternalConnection *)*watch_data);
498 #endif /* HAVE_X11R6 */
501 * gdk_display_get_name:
502 * @display: a #GdkDisplay
504 * Gets the name of the display.
506 * Returns: a string representing the display name. This string is owned
507 * by GDK and should not be modified or freed.
511 G_CONST_RETURN gchar *
512 gdk_display_get_name (GdkDisplay *display)
514 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
516 return (gchar *) DisplayString (GDK_DISPLAY_X11 (display)->xdisplay);
520 * gdk_display_get_n_screens:
521 * @display: a #GdkDisplay
523 * Gets the number of screen managed by the @display.
525 * Returns: number of screens.
530 gdk_display_get_n_screens (GdkDisplay *display)
532 g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
534 return ScreenCount (GDK_DISPLAY_X11 (display)->xdisplay);
538 * gdk_display_get_screen:
539 * @display: a #GdkDisplay
540 * @screen_num: the screen number
542 * Returns a screen object for one of the screens of the display.
544 * Returns: the #GdkScreen object
549 gdk_display_get_screen (GdkDisplay *display,
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);
555 return GDK_DISPLAY_X11 (display)->screens[screen_num];
559 * gdk_display_get_default_screen:
560 * @display: a #GdkDisplay
562 * Get the default #GdkScreen for @display.
564 * Returns: the default #GdkScreen object for @display
569 gdk_display_get_default_screen (GdkDisplay *display)
571 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
573 return GDK_DISPLAY_X11 (display)->default_screen;
577 _gdk_x11_display_is_root_window (GdkDisplay *display,
580 GdkDisplayX11 *display_x11;
583 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
585 display_x11 = GDK_DISPLAY_X11 (display);
587 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
589 if (GDK_SCREEN_XROOTWIN (display_x11->screens[i]) == xroot_window)
595 struct XPointerUngrabInfo {
601 pointer_ungrab_callback (GdkDisplay *display,
605 _gdk_display_pointer_grab_update (display, serial);
609 #define XSERVER_TIME_IS_LATER(time1, time2) \
610 ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
611 (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
615 * gdk_display_pointer_ungrab:
616 * @display: a #GdkDisplay.
617 * @time_: a timestap (e.g. %GDK_CURRENT_TIME).
619 * Release any pointer grab.
624 gdk_display_pointer_ungrab (GdkDisplay *display,
628 GdkDisplayX11 *display_x11;
629 GdkPointerGrabInfo *grab;
630 unsigned long serial;
632 g_return_if_fail (GDK_IS_DISPLAY (display));
634 display_x11 = GDK_DISPLAY_X11 (display);
635 xdisplay = GDK_DISPLAY_XDISPLAY (display);
637 serial = NextRequest (xdisplay);
639 _gdk_input_ungrab_pointer (display, time_);
640 XUngrabPointer (xdisplay, time_);
643 grab = _gdk_display_get_last_pointer_grab (display);
645 (time_ == GDK_CURRENT_TIME ||
646 grab->time == GDK_CURRENT_TIME ||
647 !XSERVER_TIME_IS_LATER (grab->time, time_)))
649 grab->serial_end = serial;
650 _gdk_x11_roundtrip_async (display,
651 pointer_ungrab_callback,
657 * gdk_display_keyboard_ungrab:
658 * @display: a #GdkDisplay.
659 * @time_: a timestap (e.g #GDK_CURRENT_TIME).
661 * Release any keyboard grab
666 gdk_display_keyboard_ungrab (GdkDisplay *display,
670 GdkDisplayX11 *display_x11;
672 g_return_if_fail (GDK_IS_DISPLAY (display));
674 display_x11 = GDK_DISPLAY_X11 (display);
675 xdisplay = GDK_DISPLAY_XDISPLAY (display);
677 XUngrabKeyboard (xdisplay, time);
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);
688 * @display: a #GdkDisplay
690 * Emits a short beep on @display
695 gdk_display_beep (GdkDisplay *display)
697 g_return_if_fail (GDK_IS_DISPLAY (display));
699 XBell (GDK_DISPLAY_XDISPLAY (display), 0);
704 * @display: a #GdkDisplay
706 * Flushes any requests queued for the windowing system and waits until all
707 * requests have been handled. This is often used for making sure that the
708 * display is synchronized with the current state of the program. Calling
709 * gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors
710 * generated from earlier requests are handled before the error trap is
713 * This is most useful for X11. On windowing systems where requests are
714 * handled synchronously, this function will do nothing.
719 gdk_display_sync (GdkDisplay *display)
721 g_return_if_fail (GDK_IS_DISPLAY (display));
723 XSync (GDK_DISPLAY_XDISPLAY (display), False);
728 * @display: a #GdkDisplay
730 * Flushes any requests queued for the windowing system; this happens automatically
731 * when the main loop blocks waiting for new events, but if your application
732 * is drawing without returning control to the main loop, you may need
733 * to call this function explicitely. A common case where this function
734 * needs to be called is when an application is executing drawing commands
735 * from a thread other than the thread where the main loop is running.
737 * This is most useful for X11. On windowing systems where requests are
738 * handled synchronously, this function will do nothing.
743 gdk_display_flush (GdkDisplay *display)
745 g_return_if_fail (GDK_IS_DISPLAY (display));
747 if (!display->closed)
748 XFlush (GDK_DISPLAY_XDISPLAY (display));
752 * gdk_display_get_default_group:
753 * @display: a #GdkDisplay
755 * Returns the default group leader window for all toplevel windows
756 * on @display. This window is implicitly created by GDK.
757 * See gdk_window_set_group().
759 * Return value: The default group leader window for @display
764 gdk_display_get_default_group (GdkDisplay *display)
766 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
768 return GDK_DISPLAY_X11 (display)->leader_gdk_window;
772 * gdk_x11_display_grab:
773 * @display: a #GdkDisplay
775 * Call XGrabServer() on @display.
776 * To ungrab the display again, use gdk_x11_display_ungrab().
778 * gdk_x11_display_grab()/gdk_x11_display_ungrab() calls can be nested.
783 gdk_x11_display_grab (GdkDisplay *display)
785 GdkDisplayX11 *display_x11;
787 g_return_if_fail (GDK_IS_DISPLAY (display));
789 display_x11 = GDK_DISPLAY_X11 (display);
791 if (display_x11->grab_count == 0)
792 XGrabServer (display_x11->xdisplay);
793 display_x11->grab_count++;
797 * gdk_x11_display_ungrab:
798 * @display: a #GdkDisplay
800 * Ungrab @display after it has been grabbed with
801 * gdk_x11_display_grab().
806 gdk_x11_display_ungrab (GdkDisplay *display)
808 GdkDisplayX11 *display_x11;
810 g_return_if_fail (GDK_IS_DISPLAY (display));
812 display_x11 = GDK_DISPLAY_X11 (display);;
813 g_return_if_fail (display_x11->grab_count > 0);
815 display_x11->grab_count--;
816 if (display_x11->grab_count == 0)
818 XUngrabServer (display_x11->xdisplay);
819 XFlush (display_x11->xdisplay);
824 gdk_display_x11_dispose (GObject *object)
826 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object);
829 g_list_foreach (display_x11->input_devices, (GFunc) g_object_run_dispose, NULL);
831 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
832 _gdk_screen_close (display_x11->screens[i]);
834 _gdk_events_uninit (GDK_DISPLAY_OBJECT (object));
836 G_OBJECT_CLASS (_gdk_display_x11_parent_class)->dispose (object);
840 gdk_display_x11_finalize (GObject *object)
842 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object);
846 if (display_x11->keymap)
847 g_object_unref (display_x11->keymap);
850 if (display_x11->motif_target_lists)
852 for (i = 0; i < display_x11->motif_n_target_lists; i++)
853 g_list_free (display_x11->motif_target_lists[i]);
854 g_free (display_x11->motif_target_lists);
857 _gdk_x11_cursor_display_finalize (GDK_DISPLAY_OBJECT(display_x11));
860 g_hash_table_destroy (display_x11->atom_from_virtual);
861 g_hash_table_destroy (display_x11->atom_to_virtual);
864 XDestroyWindow (display_x11->xdisplay, display_x11->leader_window);
866 /* list of filters for client messages */
867 g_list_foreach (display_x11->client_filters, (GFunc) g_free, NULL);
868 g_list_free (display_x11->client_filters);
870 /* List of event window extraction functions */
871 g_slist_foreach (display_x11->event_types, (GFunc)g_free, NULL);
872 g_slist_free (display_x11->event_types);
874 /* input GdkDevice list */
875 g_list_foreach (display_x11->input_devices, (GFunc) g_object_unref, NULL);
876 g_list_free (display_x11->input_devices);
878 /* input GdkWindow list */
879 g_list_foreach (display_x11->input_windows, (GFunc) g_free, NULL);
880 g_list_free (display_x11->input_windows);
882 /* Free all GdkScreens */
883 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
884 g_object_unref (display_x11->screens[i]);
885 g_free (display_x11->screens);
887 g_free (display_x11->startup_notification_id);
890 g_hash_table_destroy (display_x11->xid_ht);
892 XCloseDisplay (display_x11->xdisplay);
894 G_OBJECT_CLASS (_gdk_display_x11_parent_class)->finalize (object);
898 * gdk_x11_lookup_xdisplay:
899 * @xdisplay: a pointer to an X Display
901 * Find the #GdkDisplay corresponding to @display, if any exists.
903 * Return value: the #GdkDisplay, if found, otherwise %NULL.
908 gdk_x11_lookup_xdisplay (Display *xdisplay)
912 for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
914 if (GDK_DISPLAY_XDISPLAY (tmp_list->data) == xdisplay)
915 return tmp_list->data;
922 * _gdk_x11_display_screen_for_xrootwin:
923 * @display: a #GdkDisplay
924 * @xrootwin: window ID for one of of the screen's of the display.
926 * Given the root window ID of one of the screen's of a #GdkDisplay,
929 * Return value: the #GdkScreen corresponding to @xrootwin, or %NULL.
932 _gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
937 for (i = 0; i < ScreenCount (GDK_DISPLAY_X11 (display)->xdisplay); i++)
939 GdkScreen *screen = gdk_display_get_screen (display, i);
940 if (GDK_SCREEN_XROOTWIN (screen) == xrootwin)
948 * gdk_x11_display_get_xdisplay:
949 * @display: a #GdkDisplay
950 * @returns: an X display.
952 * Returns the X display of a #GdkDisplay.
957 gdk_x11_display_get_xdisplay (GdkDisplay *display)
959 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
960 return GDK_DISPLAY_X11 (display)->xdisplay;
964 _gdk_windowing_set_default_display (GdkDisplay *display)
966 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
967 const gchar *startup_id;
975 gdk_display = GDK_DISPLAY_XDISPLAY (display);
977 g_free (display_x11->startup_notification_id);
978 display_x11->startup_notification_id = NULL;
980 startup_id = g_getenv ("DESKTOP_STARTUP_ID");
981 if (startup_id && *startup_id != '\0')
985 if (!g_utf8_validate (startup_id, -1, NULL))
986 g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
988 display_x11->startup_notification_id = g_strdup (startup_id);
990 /* Find the launch time from the startup_id, if it's there. Newer spec
991 * states that the startup_id is of the form <unique>_TIME<timestamp>
993 time_str = g_strrstr (startup_id, "_TIME");
994 if (time_str != NULL)
1000 /* Skip past the "_TIME" part */
1003 retval = strtoul (time_str, &end, 0);
1004 if (end != time_str && errno == 0)
1005 display_x11->user_time = retval;
1008 /* Clear the environment variable so it won't be inherited by
1009 * child processes and confuse things.
1011 g_unsetenv ("DESKTOP_STARTUP_ID");
1013 /* Set the startup id on the leader window so it
1014 * applies to all windows we create on this display
1016 XChangeProperty (display_x11->xdisplay,
1017 display_x11->leader_window,
1018 gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
1019 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
1021 (guchar *)startup_id, strlen (startup_id));
1026 broadcast_xmessage (GdkDisplay *display,
1027 const char *message_type,
1028 const char *message_type_begin,
1029 const char *message)
1031 Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
1032 GdkScreen *screen = gdk_display_get_default_screen (display);
1033 GdkWindow *root_window = gdk_screen_get_root_window (screen);
1034 Window xroot_window = GDK_WINDOW_XID (root_window);
1037 Atom type_atom_begin;
1040 if (!G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
1044 XSetWindowAttributes attrs;
1046 attrs.override_redirect = True;
1047 attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
1050 XCreateWindow (xdisplay,
1056 (Visual *)CopyFromParent,
1057 CWOverrideRedirect | CWEventMask,
1061 type_atom = gdk_x11_get_xatom_by_name_for_display (display,
1063 type_atom_begin = gdk_x11_get_xatom_by_name_for_display (display,
1064 message_type_begin);
1067 XClientMessageEvent xclient;
1069 const char *src_end;
1073 memset(&xclient, 0, sizeof (xclient));
1074 xclient.type = ClientMessage;
1075 xclient.message_type = type_atom_begin;
1076 xclient.display =xdisplay;
1077 xclient.window = xwindow;
1081 src_end = message + strlen (message) + 1; /* +1 to include nul byte */
1083 while (src != src_end)
1085 dest = &xclient.data.b[0];
1086 dest_end = dest + 20;
1088 while (dest != dest_end &&
1096 while (dest != dest_end)
1102 XSendEvent (xdisplay,
1106 (XEvent *)&xclient);
1108 xclient.message_type = type_atom;
1112 XDestroyWindow (xdisplay, xwindow);
1117 * gdk_x11_display_broadcast_startup_message:
1118 * @display: a #GdkDisplay
1119 * @message_type: startup notification message type ("new", "change",
1121 * @...: a list of key/value pairs (as strings), terminated by a
1122 * %NULL key. (A %NULL value for a key will cause that key to be
1123 * skipped in the output.)
1125 * Sends a startup notification message of type @message_type to
1128 * This is a convenience function for use by code that implements the
1129 * freedesktop startup notification specification. Applications should
1130 * not normally need to call it directly. See the <ulink
1131 * url="http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt">Startup
1132 * Notification Protocol specification</ulink> for
1133 * definitions of the message types and keys that can be used.
1138 gdk_x11_display_broadcast_startup_message (GdkDisplay *display,
1139 const char *message_type,
1144 const char *key, *value, *p;
1146 message = g_string_new (message_type);
1147 g_string_append_c (message, ':');
1149 va_start (ap, message_type);
1150 while ((key = va_arg (ap, const char *)))
1152 value = va_arg (ap, const char *);
1156 g_string_append_printf (message, " %s=\"", key);
1157 for (p = value; *p; p++)
1164 g_string_append_c (message, '\\');
1168 g_string_append_c (message, *p);
1170 g_string_append_c (message, '\"');
1174 broadcast_xmessage (display,
1175 "_NET_STARTUP_INFO",
1176 "_NET_STARTUP_INFO_BEGIN",
1179 g_string_free (message, TRUE);
1183 * gdk_notify_startup_complete:
1185 * Indicates to the GUI environment that the application has finished
1186 * loading. If the applications opens windows, this function is
1187 * normally called after opening the application's initial set of
1190 * GTK+ will call this function automatically after opening the first
1191 * #GtkWindow unless gtk_window_set_auto_startup_notification() is called
1192 * to disable that feature.
1197 gdk_notify_startup_complete (void)
1199 GdkDisplay *display;
1200 GdkDisplayX11 *display_x11;
1202 display = gdk_display_get_default ();
1206 display_x11 = GDK_DISPLAY_X11 (display);
1208 if (display_x11->startup_notification_id == NULL)
1211 gdk_notify_startup_complete_with_id (display_x11->startup_notification_id);
1215 * gdk_notify_startup_complete_with_id:
1216 * @startup_id: a startup-notification identifier, for which notification
1217 * process should be completed
1219 * Indicates to the GUI environment that the application has finished
1220 * loading, using a given identifier.
1222 * GTK+ will call this function automatically for #GtkWindow with custom
1223 * startup-notification identifier unless
1224 * gtk_window_set_auto_startup_notification() is called to disable
1230 gdk_notify_startup_complete_with_id (const gchar* startup_id)
1232 GdkDisplay *display;
1234 display = gdk_display_get_default ();
1238 gdk_x11_display_broadcast_startup_message (display, "remove",
1244 * gdk_display_supports_selection_notification:
1245 * @display: a #GdkDisplay
1247 * Returns whether #GdkEventOwnerChange events will be
1248 * sent when the owner of a selection changes.
1250 * Return value: whether #GdkEventOwnerChange events will
1256 gdk_display_supports_selection_notification (GdkDisplay *display)
1258 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1260 return display_x11->have_xfixes;
1264 * gdk_display_request_selection_notification:
1265 * @display: a #GdkDisplay
1266 * @selection: the #GdkAtom naming the selection for which
1267 * ownership change notification is requested
1269 * Request #GdkEventOwnerChange events for ownership changes
1270 * of the selection named by the given atom.
1272 * Return value: whether #GdkEventOwnerChange events will
1278 gdk_display_request_selection_notification (GdkDisplay *display,
1283 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1286 if (display_x11->have_xfixes)
1288 atom = gdk_x11_atom_to_xatom_for_display (display,
1290 XFixesSelectSelectionInput (display_x11->xdisplay,
1291 display_x11->leader_window,
1293 XFixesSetSelectionOwnerNotifyMask |
1294 XFixesSelectionWindowDestroyNotifyMask |
1295 XFixesSelectionClientCloseNotifyMask);
1304 * gdk_display_supports_clipboard_persistence
1305 * @display: a #GdkDisplay
1307 * Returns whether the speicifed display supports clipboard
1308 * persistance; i.e. if it's possible to store the clipboard data after an
1309 * application has quit. On X11 this checks if a clipboard daemon is
1312 * Returns: %TRUE if the display supports clipboard persistance.
1317 gdk_display_supports_clipboard_persistence (GdkDisplay *display)
1319 Atom clipboard_manager;
1321 /* It might make sense to cache this */
1322 clipboard_manager = gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
1323 return XGetSelectionOwner (GDK_DISPLAY_X11 (display)->xdisplay, clipboard_manager) != None;
1327 * gdk_display_store_clipboard
1328 * @display: a #GdkDisplay
1329 * @clipboard_window: a #GdkWindow belonging to the clipboard owner
1330 * @time_: a timestamp
1331 * @targets: an array of targets that should be saved, or %NULL
1332 * if all available targets should be saved.
1333 * @n_targets: length of the @targets array
1335 * Issues a request to the clipboard manager to store the
1336 * clipboard data. On X11, this is a special program that works
1337 * according to the freedesktop clipboard specification, available at
1338 * <ulink url="http://www.freedesktop.org/Standards/clipboard-manager-spec">
1339 * http://www.freedesktop.org/Standards/clipboard-manager-spec</ulink>.
1344 gdk_display_store_clipboard (GdkDisplay *display,
1345 GdkWindow *clipboard_window,
1347 const GdkAtom *targets,
1350 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1351 Atom clipboard_manager, save_targets;
1353 g_return_if_fail (GDK_WINDOW_IS_X11 (clipboard_window));
1355 clipboard_manager = gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
1356 save_targets = gdk_x11_get_xatom_by_name_for_display (display, "SAVE_TARGETS");
1358 gdk_error_trap_push ();
1360 if (XGetSelectionOwner (display_x11->xdisplay, clipboard_manager) != None)
1362 Atom property_name = None;
1368 property_name = gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property);
1370 xatoms = g_new (Atom, n_targets);
1371 for (i = 0; i < n_targets; i++)
1372 xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, targets[i]);
1374 XChangeProperty (display_x11->xdisplay, GDK_WINDOW_XID (clipboard_window),
1375 property_name, XA_ATOM,
1376 32, PropModeReplace, (guchar *)xatoms, n_targets);
1381 XConvertSelection (display_x11->xdisplay,
1382 clipboard_manager, save_targets, property_name,
1383 GDK_WINDOW_XID (clipboard_window), time_);
1386 gdk_error_trap_pop ();
1391 * gdk_x11_display_get_user_time:
1392 * @display: a #GdkDisplay
1394 * Returns the timestamp of the last user interaction on
1395 * @display. The timestamp is taken from events caused
1396 * by user interaction such as key presses or pointer
1397 * movements. See gdk_x11_window_set_user_time().
1399 * Returns: the timestamp of the last user interaction
1404 gdk_x11_display_get_user_time (GdkDisplay *display)
1406 return GDK_DISPLAY_X11 (display)->user_time;
1410 * gdk_display_supports_shapes:
1411 * @display: a #GdkDisplay
1413 * Returns %TRUE if gdk_window_shape_combine_mask() can
1414 * be used to create shaped windows on @display.
1416 * Returns: %TRUE if shaped windows are supported
1421 gdk_display_supports_shapes (GdkDisplay *display)
1423 return GDK_DISPLAY_X11 (display)->have_shapes;
1427 * gdk_display_supports_input_shapes:
1428 * @display: a #GdkDisplay
1430 * Returns %TRUE if gdk_window_input_shape_combine_mask() can
1431 * be used to modify the input shape of windows on @display.
1433 * Returns: %TRUE if windows with modified input shape are supported
1438 gdk_display_supports_input_shapes (GdkDisplay *display)
1440 return GDK_DISPLAY_X11 (display)->have_input_shapes;
1445 * gdk_x11_display_get_startup_notification_id:
1446 * @display: a #GdkDisplay
1448 * Gets the startup notification ID for a display.
1450 * Returns: the startup notification ID for @display
1454 G_CONST_RETURN gchar *
1455 gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
1457 return GDK_DISPLAY_X11 (display)->startup_notification_id;
1461 * gdk_display_supports_composite:
1462 * @display: a #GdkDisplay
1464 * Returns %TRUE if gdk_window_set_composited() can be used
1465 * to redirect drawing on the window using compositing.
1467 * Currently this only works on X11 with XComposite and
1468 * XDamage extensions available.
1470 * Returns: %TRUE if windows may be composited.
1475 gdk_display_supports_composite (GdkDisplay *display)
1477 GdkDisplayX11 *x11_display = GDK_DISPLAY_X11 (display);
1479 return x11_display->have_xcomposite &&
1480 x11_display->have_xdamage &&
1481 x11_display->have_xfixes;
1485 #define __GDK_DISPLAY_X11_C__
1486 #include "gdkaliasdef.c"