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.
34 #include "gdkdisplay.h"
35 #include "gdkdisplay-x11.h"
36 #include "gdkscreen.h"
37 #include "gdkscreen-x11.h"
38 #include "gdkinternals.h"
39 #include "gdkinputprivate.h"
40 #include "xsettings-client.h"
43 #include <X11/Xatom.h>
46 #include <X11/XKBlib.h>
50 #include <X11/extensions/Xfixes.h>
54 #include <X11/extensions/shape.h>
58 static void gdk_display_x11_dispose (GObject *object);
59 static void gdk_display_x11_finalize (GObject *object);
62 static void gdk_internal_connection_watch (Display *display,
66 XPointer *watch_data);
67 #endif /* HAVE_X11R6 */
69 /* Note that we never *directly* use WM_LOCALE_NAME, WM_PROTOCOLS,
70 * but including them here has the side-effect of getting them
71 * into the internal Xlib cache
73 static const char *const precache_atoms[] = {
88 "_NET_WM_STATE_STICKY",
89 "_NET_WM_STATE_MAXIMIZED_VERT",
90 "_NET_WM_STATE_MAXIMIZED_HORZ",
91 "_NET_WM_STATE_FULLSCREEN",
92 "_NET_WM_SYNC_REQUEST",
93 "_NET_WM_SYNC_REQUEST_COUNTER",
94 "_NET_WM_WINDOW_TYPE",
95 "_NET_WM_WINDOW_TYPE_NORMAL",
100 G_DEFINE_TYPE (GdkDisplayX11, _gdk_display_x11, GDK_TYPE_DISPLAY)
103 _gdk_display_x11_class_init (GdkDisplayX11Class * class)
105 GObjectClass *object_class = G_OBJECT_CLASS (class);
107 object_class->dispose = gdk_display_x11_dispose;
108 object_class->finalize = gdk_display_x11_finalize;
112 _gdk_display_x11_init (GdkDisplayX11 *display)
118 * @display_name: the name of the display to open
119 * @returns: a #GdkDisplay, or %NULL if the display
120 * could not be opened.
127 gdk_display_open (const gchar *display_name)
131 GdkDisplayX11 *display_x11;
135 const char *sm_client_id;
137 XClassHint *class_hint;
140 #if defined(HAVE_XFIXES) || defined(HAVE_SHAPE_EXT)
145 xdisplay = XOpenDisplay (display_name);
149 display = g_object_new (GDK_TYPE_DISPLAY_X11, NULL);
150 display_x11 = GDK_DISPLAY_X11 (display);
152 display_x11->use_xshm = TRUE;
153 display_x11->xdisplay = xdisplay;
156 /* Set up handlers for Xlib internal connections */
157 XAddConnectionWatch (xdisplay, gdk_internal_connection_watch, NULL);
158 #endif /* HAVE_X11R6 */
160 /* initialize the display's screens */
161 display_x11->screens = g_new (GdkScreen *, ScreenCount (display_x11->xdisplay));
162 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
163 display_x11->screens[i] = _gdk_x11_screen_new (display, i);
165 /* We need to initialize events after we have the screen
166 * structures in places
168 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
169 _gdk_x11_events_init_screen (display_x11->screens[i]);
171 /*set the default screen */
172 display_x11->default_screen = display_x11->screens[DefaultScreen (display_x11->xdisplay)];
174 attr.window_type = GDK_WINDOW_TOPLEVEL;
175 attr.wclass = GDK_INPUT_OUTPUT;
182 _gdk_x11_precache_atoms (display, precache_atoms, G_N_ELEMENTS (precache_atoms));
184 display_x11->leader_gdk_window = gdk_window_new (GDK_SCREEN_X11 (display_x11->default_screen)->root_window,
185 &attr, GDK_WA_X | GDK_WA_Y);
186 (_gdk_x11_window_get_toplevel (display_x11->leader_gdk_window))->is_leader = TRUE;
188 display_x11->leader_window = GDK_WINDOW_XID (display_x11->leader_gdk_window);
190 display_x11->leader_window_title_set = FALSE;
192 display_x11->have_render = GDK_UNKNOWN;
195 if (XFixesQueryExtension (display_x11->xdisplay,
196 &display_x11->xfixes_event_base,
199 display_x11->have_xfixes = TRUE;
201 gdk_x11_register_standard_event_type (display,
202 display_x11->xfixes_event_base,
207 display_x11->have_xfixes = FALSE;
209 display_x11->have_shapes = FALSE;
210 display_x11->have_input_shapes = FALSE;
211 #ifdef HAVE_SHAPE_EXT
212 if (XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display), &ignore, &ignore))
214 display_x11->have_shapes = TRUE;
216 if (XShapeQueryVersion (GDK_DISPLAY_XDISPLAY (display), &maj, &min))
217 display_x11->have_input_shapes = (maj == 1 && min >= 1);
222 display_x11->trusted_client = TRUE;
225 int rootx, rooty, winx, winy;
228 gdk_error_trap_push ();
229 XQueryPointer (display_x11->xdisplay,
230 GDK_SCREEN_X11 (display_x11->default_screen)->xroot_window,
231 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
233 if (G_UNLIKELY (gdk_error_trap_pop () == BadWindow))
235 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));
236 display_x11->trusted_client = FALSE;
240 if (_gdk_synchronize)
241 XSynchronize (display_x11->xdisplay, True);
243 class_hint = XAllocClassHint();
244 class_hint->res_name = g_get_prgname ();
246 class_hint->res_class = (char *)gdk_get_program_class ();
248 /* XmbSetWMProperties sets the RESOURCE_NAME environment variable
249 * from argv[0], so we just synthesize an argument array here.
252 argv[0] = g_get_prgname ();
254 XmbSetWMProperties (display_x11->xdisplay,
255 display_x11->leader_window,
256 NULL, NULL, argv, argc, NULL, NULL,
260 sm_client_id = _gdk_get_sm_client_id ();
262 _gdk_windowing_display_set_sm_client_id (display, sm_client_id);
265 XChangeProperty (display_x11->xdisplay,
266 display_x11->leader_window,
267 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
268 XA_CARDINAL, 32, PropModeReplace, (guchar *) & pid, 1);
270 /* We don't yet know a valid time. */
271 display_x11->user_time = 0;
275 gint xkb_major = XkbMajorVersion;
276 gint xkb_minor = XkbMinorVersion;
277 if (XkbLibraryVersion (&xkb_major, &xkb_minor))
279 xkb_major = XkbMajorVersion;
280 xkb_minor = XkbMinorVersion;
282 if (XkbQueryExtension (display_x11->xdisplay,
283 NULL, &display_x11->xkb_event_type, NULL,
284 &xkb_major, &xkb_minor))
286 Bool detectable_autorepeat_supported;
288 display_x11->use_xkb = TRUE;
290 XkbSelectEvents (display_x11->xdisplay,
292 XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask,
293 XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask);
295 /* keep this in sync with _gdk_keymap_state_changed() */
296 XkbSelectEventDetails (display_x11->xdisplay,
297 XkbUseCoreKbd, XkbStateNotify,
298 XkbAllStateComponentsMask,
301 XkbSetDetectableAutoRepeat (display_x11->xdisplay,
303 &detectable_autorepeat_supported);
305 GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.",
306 detectable_autorepeat_supported ?
307 "supported" : "not supported"));
309 display_x11->have_xkb_autorepeat = detectable_autorepeat_supported;
315 display_x11->use_sync = FALSE;
319 int error_base, event_base;
321 if (XSyncQueryExtension (display_x11->xdisplay,
322 &event_base, &error_base) &&
323 XSyncInitialize (display_x11->xdisplay,
325 display_x11->use_sync = TRUE;
329 _gdk_windowing_image_init (display);
330 _gdk_events_init (display);
331 _gdk_input_init (display);
332 _gdk_dnd_init (display);
334 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
335 gdk_display_request_selection_notification (display,
336 GDK_SCREEN_X11 (display_x11->screens[i])->cm_selection_atom);
338 g_signal_emit_by_name (gdk_display_manager_get(),
339 "display_opened", display);
346 * XLib internal connection handling
348 typedef struct _GdkInternalConnection GdkInternalConnection;
350 struct _GdkInternalConnection
358 process_internal_connection (GIOChannel *gioc,
362 GdkInternalConnection *connection = (GdkInternalConnection *)data;
364 GDK_THREADS_ENTER ();
366 XProcessInternalConnection ((Display*)connection->display, connection->fd);
368 GDK_THREADS_LEAVE ();
373 static GdkInternalConnection *
374 gdk_add_connection_handler (Display *display,
377 GIOChannel *io_channel;
378 GdkInternalConnection *connection;
380 connection = g_new (GdkInternalConnection, 1);
383 connection->display = display;
385 io_channel = g_io_channel_unix_new (fd);
387 connection->source = g_io_create_watch (io_channel, G_IO_IN);
388 g_source_set_callback (connection->source,
389 (GSourceFunc)process_internal_connection, connection, NULL);
390 g_source_attach (connection->source, NULL);
392 g_io_channel_unref (io_channel);
398 gdk_remove_connection_handler (GdkInternalConnection *connection)
400 g_source_destroy (connection->source);
405 gdk_internal_connection_watch (Display *display,
409 XPointer *watch_data)
412 *watch_data = (XPointer)gdk_add_connection_handler (display, fd);
414 gdk_remove_connection_handler ((GdkInternalConnection *)*watch_data);
416 #endif /* HAVE_X11R6 */
419 * gdk_display_get_name:
420 * @display: a #GdkDisplay
422 * Gets the name of the display.
424 * Returns: a string representing the display name. This string is owned
425 * by GDK and should not be modified or freed.
429 G_CONST_RETURN gchar *
430 gdk_display_get_name (GdkDisplay *display)
432 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
434 return (gchar *) DisplayString (GDK_DISPLAY_X11 (display)->xdisplay);
438 * gdk_display_get_n_screens:
439 * @display: a #GdkDisplay
441 * Gets the number of screen managed by the @display.
443 * Returns: number of screens.
448 gdk_display_get_n_screens (GdkDisplay *display)
450 g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
452 return ScreenCount (GDK_DISPLAY_X11 (display)->xdisplay);
456 * gdk_display_get_screen:
457 * @display: a #GdkDisplay
458 * @screen_num: the screen number
460 * Returns a screen object for one of the screens of the display.
462 * Returns: the #GdkScreen object
467 gdk_display_get_screen (GdkDisplay *display,
470 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
471 g_return_val_if_fail (ScreenCount (GDK_DISPLAY_X11 (display)->xdisplay) > screen_num, NULL);
473 return GDK_DISPLAY_X11 (display)->screens[screen_num];
477 * gdk_display_get_default_screen:
478 * @display: a #GdkDisplay
480 * Get the default #GdkScreen for @display.
482 * Returns: the default #GdkScreen object for @display
487 gdk_display_get_default_screen (GdkDisplay *display)
489 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
491 return GDK_DISPLAY_X11 (display)->default_screen;
495 _gdk_x11_display_is_root_window (GdkDisplay *display,
498 GdkDisplayX11 *display_x11;
501 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
503 display_x11 = GDK_DISPLAY_X11 (display);
505 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
507 if (GDK_SCREEN_XROOTWIN (display_x11->screens[i]) == xroot_window)
513 #define XSERVER_TIME_IS_LATER(time1, time2) \
514 ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
515 (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
519 * gdk_display_pointer_ungrab:
520 * @display: a #GdkDisplay.
521 * @time_: a timestap (e.g. %GDK_CURRENT_TIME).
523 * Release any pointer grab.
528 gdk_display_pointer_ungrab (GdkDisplay *display,
532 GdkDisplayX11 *display_x11;
534 g_return_if_fail (GDK_IS_DISPLAY (display));
536 display_x11 = GDK_DISPLAY_X11 (display);
537 xdisplay = GDK_DISPLAY_XDISPLAY (display);
539 _gdk_input_ungrab_pointer (display, time);
540 XUngrabPointer (xdisplay, time);
543 if (time == GDK_CURRENT_TIME ||
544 display_x11->pointer_xgrab_time == GDK_CURRENT_TIME ||
545 !XSERVER_TIME_IS_LATER (display_x11->pointer_xgrab_time, time))
546 display_x11->pointer_xgrab_window = NULL;
550 * gdk_display_pointer_is_grabbed:
551 * @display: a #GdkDisplay
553 * Test if the pointer is grabbed.
555 * Returns: %TRUE if an active X pointer grab is in effect
560 gdk_display_pointer_is_grabbed (GdkDisplay *display)
562 g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE);
564 return (GDK_DISPLAY_X11 (display)->pointer_xgrab_window != NULL &&
565 !GDK_DISPLAY_X11 (display)->pointer_xgrab_implicit);
569 * gdk_display_keyboard_ungrab:
570 * @display: a #GdkDisplay.
571 * @time_: a timestap (e.g #GDK_CURRENT_TIME).
573 * Release any keyboard grab
578 gdk_display_keyboard_ungrab (GdkDisplay *display,
582 GdkDisplayX11 *display_x11;
584 g_return_if_fail (GDK_IS_DISPLAY (display));
586 display_x11 = GDK_DISPLAY_X11 (display);
587 xdisplay = GDK_DISPLAY_XDISPLAY (display);
589 XUngrabKeyboard (xdisplay, time);
592 if (time == GDK_CURRENT_TIME ||
593 display_x11->keyboard_xgrab_time == GDK_CURRENT_TIME ||
594 !XSERVER_TIME_IS_LATER (display_x11->keyboard_xgrab_time, time))
595 display_x11->keyboard_xgrab_window = NULL;
600 * @display: a #GdkDisplay
602 * Emits a short beep on @display
607 gdk_display_beep (GdkDisplay *display)
609 g_return_if_fail (GDK_IS_DISPLAY (display));
611 XBell (GDK_DISPLAY_XDISPLAY (display), 0);
616 * @display: a #GdkDisplay
618 * Flushes any requests queued for the windowing system and waits until all
619 * requests have been handled. This is often used for making sure that the
620 * display is synchronized with the current state of the program. Calling
621 * gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors
622 * generated from earlier requests are handled before the error trap is
625 * This is most useful for X11. On windowing systems where requests are
626 * handled synchronously, this function will do nothing.
631 gdk_display_sync (GdkDisplay *display)
633 g_return_if_fail (GDK_IS_DISPLAY (display));
635 XSync (GDK_DISPLAY_XDISPLAY (display), False);
640 * @display: a #GdkDisplay
642 * Flushes any requests queued for the windowing system; this happens automatically
643 * when the main loop blocks waiting for new events, but if your application
644 * is drawing without returning control to the main loop, you may need
645 * to call this function explicitely. A common case where this function
646 * needs to be called is when an application is executing drawing commands
647 * from a thread other than the thread where the main loop is running.
649 * This is most useful for X11. On windowing systems where requests are
650 * handled synchronously, this function will do nothing.
655 gdk_display_flush (GdkDisplay *display)
657 g_return_if_fail (GDK_IS_DISPLAY (display));
659 if (!display->closed)
660 XFlush (GDK_DISPLAY_XDISPLAY (display));
664 * gdk_display_get_default_group:
665 * @display: a #GdkDisplay
667 * Returns the default group leader window for all toplevel windows
668 * on @display. This window is implicitly created by GDK.
669 * See gdk_window_set_group().
671 * Return value: The default group leader window for @display
676 gdk_display_get_default_group (GdkDisplay *display)
678 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
680 return GDK_DISPLAY_X11 (display)->leader_gdk_window;
684 * gdk_x11_display_grab:
685 * @display: a #GdkDisplay
687 * Call XGrabServer() on @display.
688 * To ungrab the display again, use gdk_x11_display_ungrab().
690 * gdk_x11_display_grab()/gdk_x11_display_ungrab() calls can be nested.
695 gdk_x11_display_grab (GdkDisplay *display)
697 GdkDisplayX11 *display_x11;
699 g_return_if_fail (GDK_IS_DISPLAY (display));
701 display_x11 = GDK_DISPLAY_X11 (display);
703 if (display_x11->grab_count == 0)
704 XGrabServer (display_x11->xdisplay);
705 display_x11->grab_count++;
709 * gdk_x11_display_ungrab:
710 * @display: a #GdkDisplay
712 * Ungrab @display after it has been grabbed with
713 * gdk_x11_display_grab().
718 gdk_x11_display_ungrab (GdkDisplay *display)
720 GdkDisplayX11 *display_x11;
722 g_return_if_fail (GDK_IS_DISPLAY (display));
724 display_x11 = GDK_DISPLAY_X11 (display);;
725 g_return_if_fail (display_x11->grab_count > 0);
727 display_x11->grab_count--;
728 if (display_x11->grab_count == 0)
730 XUngrabServer (display_x11->xdisplay);
731 XFlush (display_x11->xdisplay);
736 gdk_display_x11_dispose (GObject *object)
738 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object);
741 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
742 _gdk_screen_close (display_x11->screens[i]);
744 _gdk_events_uninit (GDK_DISPLAY_OBJECT (object));
746 G_OBJECT_CLASS (_gdk_display_x11_parent_class)->dispose (object);
750 gdk_display_x11_finalize (GObject *object)
752 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (object);
756 if (display_x11->keymap)
757 g_object_unref (display_x11->keymap);
760 if (display_x11->motif_target_lists)
762 for (i = 0; i < display_x11->motif_n_target_lists; i++)
763 g_list_free (display_x11->motif_target_lists[i]);
764 g_free (display_x11->motif_target_lists);
768 g_hash_table_destroy (display_x11->atom_from_virtual);
769 g_hash_table_destroy (display_x11->atom_to_virtual);
772 XDestroyWindow (display_x11->xdisplay, display_x11->leader_window);
774 /* list of filters for client messages */
775 g_list_foreach (display_x11->client_filters, (GFunc) g_free, NULL);
776 g_list_free (display_x11->client_filters);
778 /* List of event window extraction functions */
779 g_slist_foreach (display_x11->event_types, (GFunc)g_free, NULL);
780 g_slist_free (display_x11->event_types);
782 /* input GdkDevice list */
783 /* FIXME need to write finalize fct */
784 g_list_foreach (display_x11->input_devices, (GFunc) g_object_unref, NULL);
785 g_list_free (display_x11->input_devices);
787 /* input GdkWindow list */
788 g_list_foreach (display_x11->input_windows, (GFunc) g_free, NULL);
789 g_list_free (display_x11->input_windows);
791 /* Free all GdkScreens */
792 for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
793 g_object_unref (display_x11->screens[i]);
794 g_free (display_x11->screens);
796 g_free (display_x11->startup_notification_id);
799 g_hash_table_destroy (display_x11->xid_ht);
801 XCloseDisplay (display_x11->xdisplay);
803 G_OBJECT_CLASS (_gdk_display_x11_parent_class)->finalize (object);
807 * gdk_x11_lookup_xdisplay:
808 * @xdisplay: a pointer to an X Display
810 * Find the #GdkDisplay corresponding to @display, if any exists.
812 * Return value: the #GdkDisplay, if found, otherwise %NULL.
817 gdk_x11_lookup_xdisplay (Display *xdisplay)
821 for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
823 if (GDK_DISPLAY_XDISPLAY (tmp_list->data) == xdisplay)
824 return tmp_list->data;
831 * _gdk_x11_display_screen_for_xrootwin:
832 * @display: a #GdkDisplay
833 * @xrootwin: window ID for one of of the screen's of the display.
835 * Given the root window ID of one of the screen's of a #GdkDisplay,
838 * Return value: the #GdkScreen corresponding to @xrootwin, or %NULL.
841 _gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
846 for (i = 0; i < ScreenCount (GDK_DISPLAY_X11 (display)->xdisplay); i++)
848 GdkScreen *screen = gdk_display_get_screen (display, i);
849 if (GDK_SCREEN_XROOTWIN (screen) == xrootwin)
857 * gdk_x11_display_get_xdisplay:
858 * @display: a #GdkDisplay
859 * @returns: an X display.
861 * Returns the X display of a #GdkDisplay.
866 gdk_x11_display_get_xdisplay (GdkDisplay *display)
868 return GDK_DISPLAY_X11 (display)->xdisplay;
872 _gdk_windowing_set_default_display (GdkDisplay *display)
874 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
875 const gchar *startup_id;
883 gdk_display = GDK_DISPLAY_XDISPLAY (display);
885 g_free (display_x11->startup_notification_id);
886 display_x11->startup_notification_id = NULL;
888 startup_id = g_getenv ("DESKTOP_STARTUP_ID");
889 if (startup_id && *startup_id != '\0')
893 if (!g_utf8_validate (startup_id, -1, NULL))
894 g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
896 display_x11->startup_notification_id = g_strdup (startup_id);
898 /* Find the launch time from the startup_id, if it's there. Newer spec
899 * states that the startup_id is of the form <unique>_TIME<timestamp>
901 time_str = g_strrstr (startup_id, "_TIME");
902 if (time_str != NULL)
908 /* Skip past the "_TIME" part */
911 retval = strtoul (time_str, &end, 0);
912 if (end != time_str && errno == 0)
913 display_x11->user_time = retval;
916 /* Clear the environment variable so it won't be inherited by
917 * child processes and confuse things.
919 g_unsetenv ("DESKTOP_STARTUP_ID");
921 /* Set the startup id on the leader window so it
922 * applies to all windows we create on this display
924 XChangeProperty (display_x11->xdisplay,
925 display_x11->leader_window,
926 gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
927 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
929 (guchar *)startup_id, strlen (startup_id));
934 escape_for_xmessage (const char *str)
939 retval = g_string_new (NULL);
949 g_string_append_c (retval, '\\');
953 g_string_append_c (retval, *p);
957 return g_string_free (retval, FALSE);
961 broadcast_xmessage (GdkDisplay *display,
962 const char *message_type,
963 const char *message_type_begin,
966 Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
967 GdkScreen *screen = gdk_display_get_default_screen (display);
968 GdkWindow *root_window = gdk_screen_get_root_window (screen);
969 Window xroot_window = GDK_WINDOW_XID (root_window);
972 Atom type_atom_begin;
976 XSetWindowAttributes attrs;
978 attrs.override_redirect = True;
979 attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
982 XCreateWindow (xdisplay,
988 (Visual *)CopyFromParent,
989 CWOverrideRedirect | CWEventMask,
993 type_atom = gdk_x11_get_xatom_by_name_for_display (display,
995 type_atom_begin = gdk_x11_get_xatom_by_name_for_display (display,
1001 const char *src_end;
1005 xevent.xclient.type = ClientMessage;
1006 xevent.xclient.message_type = type_atom_begin;
1007 xevent.xclient.display =xdisplay;
1008 xevent.xclient.window = xwindow;
1009 xevent.xclient.format = 8;
1012 src_end = message + strlen (message) + 1; /* +1 to include nul byte */
1014 while (src != src_end)
1016 dest = &xevent.xclient.data.b[0];
1017 dest_end = dest + 20;
1019 while (dest != dest_end &&
1027 while (dest != dest_end)
1033 XSendEvent (xdisplay,
1039 xevent.xclient.message_type = type_atom;
1043 XDestroyWindow (xdisplay, xwindow);
1048 * gdk_notify_startup_complete:
1050 * Indicates to the GUI environment that the application has finished
1051 * loading. If the applications opens windows, this function is
1052 * normally called after opening the application's initial set of
1055 * GTK+ will call this function automatically after opening the first
1056 * #GtkWindow unless gtk_window_set_auto_startup_notification() is called
1057 * to disable that feature.
1062 gdk_notify_startup_complete (void)
1064 GdkDisplay *display;
1065 GdkDisplayX11 *display_x11;
1069 display = gdk_display_get_default ();
1073 display_x11 = GDK_DISPLAY_X11 (display);
1075 if (display_x11->startup_notification_id == NULL)
1078 if (!G_LIKELY (display_x11->trusted_client))
1081 escaped_id = escape_for_xmessage (display_x11->startup_notification_id);
1082 message = g_strdup_printf ("remove: ID=%s", escaped_id);
1083 g_free (escaped_id);
1085 broadcast_xmessage (display,
1086 "_NET_STARTUP_INFO",
1087 "_NET_STARTUP_INFO_BEGIN",
1095 * gdk_display_supports_selection_notification:
1096 * @display: a #GdkDisplay
1098 * Returns whether #GdkEventOwnerChange events will be
1099 * sent when the owner of a selection changes.
1101 * Return value: whether #GdkEventOwnerChange events will
1107 gdk_display_supports_selection_notification (GdkDisplay *display)
1109 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1111 return display_x11->have_xfixes;
1115 * gdk_display_request_selection_notification:
1116 * @display: a #GdkDisplay
1117 * @selection: the #GdkAtom naming the selection for which
1118 * ownership change notification is requested
1120 * Request #GdkEventOwnerChange events for ownership changes
1121 * of the selection named by the given atom.
1123 * Return value: whether #GdkEventOwnerChange events will
1129 gdk_display_request_selection_notification (GdkDisplay *display,
1134 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1137 if (display_x11->have_xfixes)
1139 atom = gdk_x11_atom_to_xatom_for_display (display,
1141 XFixesSelectSelectionInput (display_x11->xdisplay,
1142 display_x11->leader_window,
1144 XFixesSetSelectionOwnerNotifyMask |
1145 XFixesSelectionWindowDestroyNotifyMask |
1146 XFixesSelectionClientCloseNotifyMask);
1155 * gdk_display_supports_clipboard_persistence
1156 * @display: a #GdkDisplay
1158 * Returns whether the speicifed display supports clipboard
1159 * persistance; i.e. if it's possible to store the clipboard data after an
1160 * application has quit. On X11 this checks if a clipboard daemon is
1163 * Returns: %TRUE if the display supports clipboard persistance.
1168 gdk_display_supports_clipboard_persistence (GdkDisplay *display)
1170 Atom clipboard_manager;
1172 /* It might make sense to cache this */
1173 clipboard_manager = gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
1174 return XGetSelectionOwner (GDK_DISPLAY_X11 (display)->xdisplay, clipboard_manager) != None;
1178 * gdk_display_store_clipboard
1179 * @display: a #GdkDisplay
1180 * @clipboard_window: a #GdkWindow belonging to the clipboard owner
1181 * @time_: a timestamp
1182 * @targets: an array of targets that should be saved, or %NULL
1183 * if all available targets should be saved.
1184 * @n_targets: length of the @targets array
1186 * Issues a request to the clipboard manager to store the
1187 * clipboard data. On X11, this is a special program that works
1188 * according to the freedesktop clipboard specification, available at
1189 * <ulink url="http://www.freedesktop.org/Standards/clipboard-manager-spec">
1190 * http://www.freedesktop.org/Standards/clipboard-manager-spec</ulink>.
1195 gdk_display_store_clipboard (GdkDisplay *display,
1196 GdkWindow *clipboard_window,
1201 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
1202 Atom clipboard_manager, save_targets;
1204 clipboard_manager = gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
1205 save_targets = gdk_x11_get_xatom_by_name_for_display (display, "SAVE_TARGETS");
1207 gdk_error_trap_push ();
1209 if (XGetSelectionOwner (display_x11->xdisplay, clipboard_manager) != None)
1211 Atom property_name = None;
1217 property_name = gdk_x11_atom_to_xatom_for_display (display, _gdk_selection_property);
1219 xatoms = g_new (Atom, n_targets);
1220 for (i = 0; i < n_targets; i++)
1221 xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, targets[i]);
1223 XChangeProperty (display_x11->xdisplay, GDK_WINDOW_XID (clipboard_window),
1224 property_name, XA_ATOM,
1225 32, PropModeReplace, (guchar *)xatoms, n_targets);
1230 XConvertSelection (display_x11->xdisplay,
1231 clipboard_manager, save_targets, property_name,
1232 GDK_WINDOW_XID (clipboard_window), time_);
1235 gdk_error_trap_pop ();
1240 * gdk_x11_display_get_user_time:
1241 * @display: a #GdkDisplay
1243 * Returns the timestamp of the last user interaction on
1244 * @display. The timestamp is taken from events caused
1245 * by user interaction such as key presses or pointer
1246 * movements. See gdk_x11_window_set_user_time().
1248 * Returns: the timestamp of the last user interaction
1253 gdk_x11_display_get_user_time (GdkDisplay *display)
1255 return GDK_DISPLAY_X11 (display)->user_time;
1259 * gdk_display_supports_shapes:
1260 * @display: a #GdkDisplay
1262 * Returns %TRUE if gdk_window_shape_combine_mask() can
1263 * be used to create shaped windows on @display.
1265 * Returns: %TRUE if shaped windows are supported
1270 gdk_display_supports_shapes (GdkDisplay *display)
1272 return GDK_DISPLAY_X11 (display)->have_shapes;
1276 * gdk_display_supports_input_shapes:
1277 * @display: a #GdkDisplay
1279 * Returns %TRUE if gdk_window_input_shape_combine_mask() can
1280 * be used to modify the input shape of windows on @display.
1282 * Returns: %TRUE if windows with modified input shape are supported
1287 gdk_display_supports_input_shapes (GdkDisplay *display)
1289 return GDK_DISPLAY_X11 (display)->have_input_shapes;
1293 #define __GDK_DISPLAY_X11_C__
1294 #include "gdkaliasdef.c"