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 (gpointer _data)
603 struct XPointerUngrabInfo *data = _data;
605 _gdk_display_unset_has_pointer_grab (data->display,
614 #define XSERVER_TIME_IS_LATER(time1, time2) \
615 ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
616 (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
620 * gdk_display_pointer_ungrab:
621 * @display: a #GdkDisplay.
622 * @time_: a timestap (e.g. %GDK_CURRENT_TIME).
624 * Release any pointer grab.
629 gdk_display_pointer_ungrab (GdkDisplay *display,
633 GdkDisplayX11 *display_x11;
635 g_return_if_fail (GDK_IS_DISPLAY (display));
637 display_x11 = GDK_DISPLAY_X11 (display);
638 xdisplay = GDK_DISPLAY_XDISPLAY (display);
640 _gdk_input_ungrab_pointer (display, time_);
641 XUngrabPointer (xdisplay, time_);
644 if (time_ == GDK_CURRENT_TIME ||
645 display->pointer_grab.time == GDK_CURRENT_TIME ||
646 !XSERVER_TIME_IS_LATER (display->pointer_grab.time, time_))
648 struct XPointerUngrabInfo *data;
650 data = g_new (struct XPointerUngrabInfo, 1);
652 data->display = GDK_DISPLAY_OBJECT (display_x11);
655 _gdk_x11_roundtrip_async (data->display,
656 pointer_ungrab_callback,
662 * gdk_display_keyboard_ungrab:
663 * @display: a #GdkDisplay.
664 * @time_: a timestap (e.g #GDK_CURRENT_TIME).
666 * Release any keyboard grab
671 gdk_display_keyboard_ungrab (GdkDisplay *display,
675 GdkDisplayX11 *display_x11;
677 g_return_if_fail (GDK_IS_DISPLAY (display));
679 display_x11 = GDK_DISPLAY_X11 (display);
680 xdisplay = GDK_DISPLAY_XDISPLAY (display);
682 XUngrabKeyboard (xdisplay, time);
685 if (time == GDK_CURRENT_TIME ||
686 display->keyboard_grab.time == GDK_CURRENT_TIME ||
687 !XSERVER_TIME_IS_LATER (display->keyboard_grab.time, time))
688 _gdk_display_unset_has_keyboard_grab (display, FALSE);
693 * @display: a #GdkDisplay
695 * Emits a short beep on @display
700 gdk_display_beep (GdkDisplay *display)
702 g_return_if_fail (GDK_IS_DISPLAY (display));
704 XBell (GDK_DISPLAY_XDISPLAY (display), 0);
709 * @display: a #GdkDisplay
711 * Flushes any requests queued for the windowing system and waits until all
712 * requests have been handled. This is often used for making sure that the
713 * display is synchronized with the current state of the program. Calling
714 * gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors
715 * generated from earlier requests are handled before the error trap is
718 * This is most useful for X11. On windowing systems where requests are
719 * handled synchronously, this function will do nothing.
724 gdk_display_sync (GdkDisplay *display)
726 g_return_if_fail (GDK_IS_DISPLAY (display));
728 XSync (GDK_DISPLAY_XDISPLAY (display), False);
733 * @display: a #GdkDisplay
735 * Flushes any requests queued for the windowing system; this happens automatically
736 * when the main loop blocks waiting for new events, but if your application
737 * is drawing without returning control to the main loop, you may need
738 * to call this function explicitely. A common case where this function
739 * needs to be called is when an application is executing drawing commands
740 * from a thread other than the thread where the main loop is running.
742 * This is most useful for X11. On windowing systems where requests are
743 * handled synchronously, this function will do nothing.
748 gdk_display_flush (GdkDisplay *display)
750 g_return_if_fail (GDK_IS_DISPLAY (display));
752 if (!display->closed)
753 XFlush (GDK_DISPLAY_XDISPLAY (display));
757 * gdk_display_get_default_group:
758 * @display: a #GdkDisplay
760 * Returns the default group leader window for all toplevel windows
761 * on @display. This window is implicitly created by GDK.
762 * See gdk_window_set_group().
764 * Return value: The default group leader window for @display
769 gdk_display_get_default_group (GdkDisplay *display)
771 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
773 return GDK_DISPLAY_X11 (display)->leader_gdk_window;
777 * gdk_x11_display_grab:
778 * @display: a #GdkDisplay
780 * Call XGrabServer() on @display.
781 * To ungrab the display again, use gdk_x11_display_ungrab().
783 * gdk_x11_display_grab()/gdk_x11_display_ungrab() calls can be nested.
788 gdk_x11_display_grab (GdkDisplay *display)
790 GdkDisplayX11 *display_x11;
792 g_return_if_fail (GDK_IS_DISPLAY (display));
794 display_x11 = GDK_DISPLAY_X11 (display);
796 if (display_x11->grab_count == 0)
797 XGrabServer (display_x11->xdisplay);
798 display_x11->grab_count++;
802 * gdk_x11_display_ungrab:
803 * @display: a #GdkDisplay
805 * Ungrab @display after it has been grabbed with
806 * gdk_x11_display_grab().
811 gdk_x11_display_ungrab (GdkDisplay *display)
813 GdkDisplayX11 *display_x11;
815 g_return_if_fail (GDK_IS_DISPLAY (display));
817 display_x11 = GDK_DISPLAY_X11 (display);;
818 g_return_if_fail (display_x11->grab_count > 0);
820 display_x11->grab_count--;
821 if (display_x11->grab_count == 0)
823 XUngrabServer (display_x11->xdisplay);
824 XFlush (display_x11->xdisplay);
829 gdk_display_x11_dispose (GObject *object)
831 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object);
834 g_list_foreach (display_x11->input_devices, (GFunc) g_object_run_dispose, NULL);
836 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
837 _gdk_screen_close (display_x11->screens[i]);
839 _gdk_events_uninit (GDK_DISPLAY_OBJECT (object));
841 G_OBJECT_CLASS (_gdk_display_x11_parent_class)->dispose (object);
845 gdk_display_x11_finalize (GObject *object)
847 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object);
851 if (display_x11->keymap)
852 g_object_unref (display_x11->keymap);
855 if (display_x11->motif_target_lists)
857 for (i = 0; i < display_x11->motif_n_target_lists; i++)
858 g_list_free (display_x11->motif_target_lists[i]);
859 g_free (display_x11->motif_target_lists);
862 _gdk_x11_cursor_display_finalize (GDK_DISPLAY_OBJECT(display_x11));
865 g_hash_table_destroy (display_x11->atom_from_virtual);
866 g_hash_table_destroy (display_x11->atom_to_virtual);
869 XDestroyWindow (display_x11->xdisplay, display_x11->leader_window);
871 /* list of filters for client messages */
872 g_list_foreach (display_x11->client_filters, (GFunc) g_free, NULL);
873 g_list_free (display_x11->client_filters);
875 /* List of event window extraction functions */
876 g_slist_foreach (display_x11->event_types, (GFunc)g_free, NULL);
877 g_slist_free (display_x11->event_types);
879 /* input GdkDevice list */
880 g_list_foreach (display_x11->input_devices, (GFunc) g_object_unref, NULL);
881 g_list_free (display_x11->input_devices);
883 /* input GdkWindow list */
884 g_list_foreach (display_x11->input_windows, (GFunc) g_free, NULL);
885 g_list_free (display_x11->input_windows);
887 /* Free all GdkScreens */
888 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
889 g_object_unref (display_x11->screens[i]);
890 g_free (display_x11->screens);
892 g_free (display_x11->startup_notification_id);
895 g_hash_table_destroy (display_x11->xid_ht);
897 XCloseDisplay (display_x11->xdisplay);
899 G_OBJECT_CLASS (_gdk_display_x11_parent_class)->finalize (object);
903 * gdk_x11_lookup_xdisplay:
904 * @xdisplay: a pointer to an X Display
906 * Find the #GdkDisplay corresponding to @display, if any exists.
908 * Return value: the #GdkDisplay, if found, otherwise %NULL.
913 gdk_x11_lookup_xdisplay (Display *xdisplay)
917 for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
919 if (GDK_DISPLAY_XDISPLAY (tmp_list->data) == xdisplay)
920 return tmp_list->data;
927 * _gdk_x11_display_screen_for_xrootwin:
928 * @display: a #GdkDisplay
929 * @xrootwin: window ID for one of of the screen's of the display.
931 * Given the root window ID of one of the screen's of a #GdkDisplay,
934 * Return value: the #GdkScreen corresponding to @xrootwin, or %NULL.
937 _gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
942 for (i = 0; i < ScreenCount (GDK_DISPLAY_X11 (display)->xdisplay); i++)
944 GdkScreen *screen = gdk_display_get_screen (display, i);
945 if (GDK_SCREEN_XROOTWIN (screen) == xrootwin)
953 * gdk_x11_display_get_xdisplay:
954 * @display: a #GdkDisplay
955 * @returns: an X display.
957 * Returns the X display of a #GdkDisplay.
962 gdk_x11_display_get_xdisplay (GdkDisplay *display)
964 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
965 return GDK_DISPLAY_X11 (display)->xdisplay;
969 _gdk_windowing_set_default_display (GdkDisplay *display)
971 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
972 const gchar *startup_id;
980 gdk_display = GDK_DISPLAY_XDISPLAY (display);
982 g_free (display_x11->startup_notification_id);
983 display_x11->startup_notification_id = NULL;
985 startup_id = g_getenv ("DESKTOP_STARTUP_ID");
986 if (startup_id && *startup_id != '\0')
990 if (!g_utf8_validate (startup_id, -1, NULL))
991 g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
993 display_x11->startup_notification_id = g_strdup (startup_id);
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>
998 time_str = g_strrstr (startup_id, "_TIME");
999 if (time_str != NULL)
1005 /* Skip past the "_TIME" part */
1008 retval = strtoul (time_str, &end, 0);
1009 if (end != time_str && errno == 0)
1010 display_x11->user_time = retval;
1013 /* Clear the environment variable so it won't be inherited by
1014 * child processes and confuse things.
1016 g_unsetenv ("DESKTOP_STARTUP_ID");
1018 /* Set the startup id on the leader window so it
1019 * applies to all windows we create on this display
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,
1026 (guchar *)startup_id, strlen (startup_id));
1031 broadcast_xmessage (GdkDisplay *display,
1032 const char *message_type,
1033 const char *message_type_begin,
1034 const char *message)
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);
1042 Atom type_atom_begin;
1045 if (!G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
1049 XSetWindowAttributes attrs;
1051 attrs.override_redirect = True;
1052 attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
1055 XCreateWindow (xdisplay,
1061 (Visual *)CopyFromParent,
1062 CWOverrideRedirect | CWEventMask,
1066 type_atom = gdk_x11_get_xatom_by_name_for_display (display,
1068 type_atom_begin = gdk_x11_get_xatom_by_name_for_display (display,
1069 message_type_begin);
1072 XClientMessageEvent xclient;
1074 const char *src_end;
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;
1086 src_end = message + strlen (message) + 1; /* +1 to include nul byte */
1088 while (src != src_end)
1090 dest = &xclient.data.b[0];
1091 dest_end = dest + 20;
1093 while (dest != dest_end &&
1101 while (dest != dest_end)
1107 XSendEvent (xdisplay,
1111 (XEvent *)&xclient);
1113 xclient.message_type = type_atom;
1117 XDestroyWindow (xdisplay, xwindow);
1122 * gdk_x11_display_broadcast_startup_message:
1123 * @display: a #GdkDisplay
1124 * @message_type: startup notification message type ("new", "change",
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.)
1130 * Sends a startup notification message of type @message_type to
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.
1143 gdk_x11_display_broadcast_startup_message (GdkDisplay *display,
1144 const char *message_type,
1149 const char *key, *value, *p;
1151 message = g_string_new (message_type);
1152 g_string_append_c (message, ':');
1154 va_start (ap, message_type);
1155 while ((key = va_arg (ap, const char *)))
1157 value = va_arg (ap, const char *);
1161 g_string_append_printf (message, " %s=\"", key);
1162 for (p = value; *p; p++)
1169 g_string_append_c (message, '\\');
1173 g_string_append_c (message, *p);
1175 g_string_append_c (message, '\"');
1179 broadcast_xmessage (display,
1180 "_NET_STARTUP_INFO",
1181 "_NET_STARTUP_INFO_BEGIN",
1184 g_string_free (message, TRUE);
1188 * gdk_notify_startup_complete:
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
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.
1202 gdk_notify_startup_complete (void)
1204 GdkDisplay *display;
1205 GdkDisplayX11 *display_x11;
1207 display = gdk_display_get_default ();
1211 display_x11 = GDK_DISPLAY_X11 (display);
1213 if (display_x11->startup_notification_id == NULL)
1216 gdk_notify_startup_complete_with_id (display_x11->startup_notification_id);
1220 * gdk_notify_startup_complete_with_id:
1221 * @startup_id: a startup-notification identifier, for which notification
1222 * process should be completed
1224 * Indicates to the GUI environment that the application has finished
1225 * loading, using a given identifier.
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
1235 gdk_notify_startup_complete_with_id (const gchar* startup_id)
1237 GdkDisplay *display;
1239 display = gdk_display_get_default ();
1243 gdk_x11_display_broadcast_startup_message (display, "remove",
1249 * gdk_display_supports_selection_notification:
1250 * @display: a #GdkDisplay
1252 * Returns whether #GdkEventOwnerChange events will be
1253 * sent when the owner of a selection changes.
1255 * Return value: whether #GdkEventOwnerChange events will
1261 gdk_display_supports_selection_notification (GdkDisplay *display)
1263 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1265 return display_x11->have_xfixes;
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
1274 * Request #GdkEventOwnerChange events for ownership changes
1275 * of the selection named by the given atom.
1277 * Return value: whether #GdkEventOwnerChange events will
1283 gdk_display_request_selection_notification (GdkDisplay *display,
1288 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1291 if (display_x11->have_xfixes)
1293 atom = gdk_x11_atom_to_xatom_for_display (display,
1295 XFixesSelectSelectionInput (display_x11->xdisplay,
1296 display_x11->leader_window,
1298 XFixesSetSelectionOwnerNotifyMask |
1299 XFixesSelectionWindowDestroyNotifyMask |
1300 XFixesSelectionClientCloseNotifyMask);
1309 * gdk_display_supports_clipboard_persistence
1310 * @display: a #GdkDisplay
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
1317 * Returns: %TRUE if the display supports clipboard persistance.
1322 gdk_display_supports_clipboard_persistence (GdkDisplay *display)
1324 Atom clipboard_manager;
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;
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
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>.
1349 gdk_display_store_clipboard (GdkDisplay *display,
1350 GdkWindow *clipboard_window,
1352 const GdkAtom *targets,
1355 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1356 Atom clipboard_manager, save_targets;
1358 g_return_if_fail (GDK_WINDOW_IS_X11 (clipboard_window));
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");
1363 gdk_error_trap_push ();
1365 if (XGetSelectionOwner (display_x11->xdisplay, clipboard_manager) != None)
1367 Atom property_name = None;
1373 property_name = gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property);
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]);
1379 XChangeProperty (display_x11->xdisplay, GDK_WINDOW_XID (clipboard_window),
1380 property_name, XA_ATOM,
1381 32, PropModeReplace, (guchar *)xatoms, n_targets);
1386 XConvertSelection (display_x11->xdisplay,
1387 clipboard_manager, save_targets, property_name,
1388 GDK_WINDOW_XID (clipboard_window), time_);
1391 gdk_error_trap_pop ();
1396 * gdk_x11_display_get_user_time:
1397 * @display: a #GdkDisplay
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().
1404 * Returns: the timestamp of the last user interaction
1409 gdk_x11_display_get_user_time (GdkDisplay *display)
1411 return GDK_DISPLAY_X11 (display)->user_time;
1415 * gdk_display_supports_shapes:
1416 * @display: a #GdkDisplay
1418 * Returns %TRUE if gdk_window_shape_combine_mask() can
1419 * be used to create shaped windows on @display.
1421 * Returns: %TRUE if shaped windows are supported
1426 gdk_display_supports_shapes (GdkDisplay *display)
1428 return GDK_DISPLAY_X11 (display)->have_shapes;
1432 * gdk_display_supports_input_shapes:
1433 * @display: a #GdkDisplay
1435 * Returns %TRUE if gdk_window_input_shape_combine_mask() can
1436 * be used to modify the input shape of windows on @display.
1438 * Returns: %TRUE if windows with modified input shape are supported
1443 gdk_display_supports_input_shapes (GdkDisplay *display)
1445 return GDK_DISPLAY_X11 (display)->have_input_shapes;
1450 * gdk_x11_display_get_startup_notification_id:
1451 * @display: a #GdkDisplay
1453 * Gets the startup notification ID for a display.
1455 * Returns: the startup notification ID for @display
1459 G_CONST_RETURN gchar *
1460 gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
1462 return GDK_DISPLAY_X11 (display)->startup_notification_id;
1466 * gdk_display_supports_composite:
1467 * @display: a #GdkDisplay
1469 * Returns %TRUE if gdk_window_set_composited() can be used
1470 * to redirect drawing on the window using compositing.
1472 * Currently this only works on X11 with XComposite and
1473 * XDamage extensions available.
1475 * Returns: %TRUE if windows may be composited.
1480 gdk_display_supports_composite (GdkDisplay *display)
1482 GdkDisplayX11 *x11_display = GDK_DISPLAY_X11 (display);
1484 return x11_display->have_xcomposite &&
1485 x11_display->have_xdamage &&
1486 x11_display->have_xfixes;
1490 #define __GDK_DISPLAY_X11_C__
1491 #include "gdkaliasdef.c"