summaryrefslogtreecommitdiff
path: root/gdk/x11/gdkevents-x11.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/x11/gdkevents-x11.c')
-rw-r--r--gdk/x11/gdkevents-x11.c800
1 files changed, 509 insertions, 291 deletions
diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c
index 0197c62338..1d9e57f8a6 100644
--- a/gdk/x11/gdkevents-x11.c
+++ b/gdk/x11/gdkevents-x11.c
@@ -28,6 +28,8 @@
#include "gdkprivate-x11.h"
#include "gdkinternals.h"
#include "gdkx.h"
+#include "gdkscreen-x11.h"
+#include "gdkdisplay-x11.h"
#include "gdkkeysyms.h"
@@ -50,6 +52,7 @@
typedef struct _GdkIOClosure GdkIOClosure;
typedef struct _GdkEventPrivate GdkEventPrivate;
+typedef struct _GdkDisplaySource GdkDisplaySource;
#define DOUBLE_CLICK_TIME 250
#define TRIPLE_CLICK_TIME 500
@@ -78,6 +81,14 @@ struct _GdkEventPrivate
guint flags;
};
+struct _GdkDisplaySource
+{
+ GSource source;
+
+ GdkDisplay *display;
+ GPollFD event_poll_fd;
+};
+
/*
* Private function declarations
*/
@@ -85,14 +96,10 @@ struct _GdkEventPrivate
static gint gdk_event_apply_filters (XEvent *xevent,
GdkEvent *event,
GList *filters);
-static gint gdk_event_translate (GdkEvent *event,
- XEvent *xevent,
- gboolean return_exposes);
-#if 0
-static Bool gdk_event_get_type (Display *display,
- XEvent *xevent,
- XPointer arg);
-#endif
+static gboolean gdk_event_translate (GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent,
+ gboolean return_exposes);
static gboolean gdk_event_prepare (GSource *source,
gint *timeout);
@@ -105,6 +112,9 @@ static GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev,
GdkEvent *event,
gpointer data);
+static GSource *gdk_display_source_new (GdkDisplay *display);
+static gboolean gdk_check_xpending (GdkDisplay *display);
+
static void gdk_xsettings_watch_cb (Window window,
Bool is_start,
long mask,
@@ -117,13 +127,7 @@ static void gdk_xsettings_notify_cb (const char *name,
/* Private variable declarations
*/
-static int connection_number = 0; /* The file descriptor number of our
- * connection to the X server. This
- * is used so that we may determine
- * when events are pending by using
- * the "select" system call.
- */
-static GList *client_filters; /* Filters for client messages */
+static GList *display_sources;
static GSourceFuncs event_funcs = {
gdk_event_prepare,
@@ -132,86 +136,105 @@ static GSourceFuncs event_funcs = {
NULL
};
-static GPollFD event_poll_fd;
-
-static Window wmspec_check_window = None;
+static GSource *
+gdk_display_source_new (GdkDisplay *display)
+{
+ GSource *source = g_source_new (&event_funcs, sizeof (GdkDisplaySource));
+ GdkDisplaySource *display_source = (GdkDisplaySource *)source;
+
+ display_source->display = display;
+
+ return source;
+}
-static XSettingsClient *xsettings_client;
+static gboolean
+gdk_check_xpending (GdkDisplay *display)
+{
+ return XPending (GDK_DISPLAY_XDISPLAY (display));
+}
/*********************************************
* Functions for maintaining the event queue *
*********************************************/
+void
+_gdk_x11_events_init_screen (GdkScreen *screen)
+{
+ GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+
+ screen_x11->xsettings_client = xsettings_client_new (screen_x11->xdisplay,
+ screen_x11->screen_num,
+ gdk_xsettings_notify_cb,
+ gdk_xsettings_watch_cb,
+ screen);
+}
+
void
-_gdk_events_init (void)
+_gdk_events_init (GdkDisplay *display)
{
GSource *source;
+ GdkDisplaySource *display_source;
+ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
- connection_number = ConnectionNumber (gdk_display);
- GDK_NOTE (MISC,
- g_message ("connection number: %d", connection_number));
+ int connection_number = ConnectionNumber (display_x11->xdisplay);
+ GDK_NOTE (MISC, g_message ("connection number: %d", connection_number));
- source = g_source_new (&event_funcs, sizeof (GSource));
+ source = gdk_display_source_new (display);
+ display_source = (GdkDisplaySource*) source;
g_source_set_priority (source, GDK_PRIORITY_EVENTS);
- event_poll_fd.fd = connection_number;
- event_poll_fd.events = G_IO_IN;
+ display_source->event_poll_fd.fd = connection_number;
+ display_source->event_poll_fd.events = G_IO_IN;
- g_source_add_poll (source, &event_poll_fd);
+ g_source_add_poll (source, &display_source->event_poll_fd);
g_source_set_can_recurse (source, TRUE);
g_source_attach (source, NULL);
- _gdk_wm_window_protocols[0] = gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW");
- _gdk_wm_window_protocols[1] = gdk_x11_get_xatom_by_name ("WM_TAKE_FOCUS");
- _gdk_wm_window_protocols[2] = gdk_x11_get_xatom_by_name ("_NET_WM_PING");
-
- gdk_add_client_message_filter (gdk_atom_intern ("WM_PROTOCOLS", FALSE),
- gdk_wm_protocols_filter, NULL);
+ display_sources = g_list_prepend (display_sources,display_source);
+
+ gdk_display_add_client_message_filter (
+ display,
+ gdk_atom_intern ("WM_PROTOCOLS", FALSE),
+ gdk_wm_protocols_filter,
+ NULL);
- xsettings_client = xsettings_client_new (gdk_display, DefaultScreen (gdk_display),
- gdk_xsettings_notify_cb,
- gdk_xsettings_watch_cb,
- NULL);
+ _gdk_x11_events_init_screen (display_x11->default_screen);
}
-/*
- *--------------------------------------------------------------
- * gdk_events_pending
- *
- * Returns if events are pending on the queue.
- *
- * Arguments:
- *
- * Results:
- * Returns TRUE if events are pending
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
+/**
+ * gdk_events_pending:
+ *
+ * Checks if any events are ready to be processed for any display.
+ *
+ * Return value: %TRUE if any events are pending.
+ **/
gboolean
gdk_events_pending (void)
{
- return (_gdk_event_queue_find_first() || XPending (gdk_display));
-}
+ GList *tmp_list;
-/*
- *--------------------------------------------------------------
- * gdk_event_get_graphics_expose
- *
- * Waits for a GraphicsExpose or NoExpose event
- *
- * Arguments:
- *
- * Results:
- * For GraphicsExpose events, returns a pointer to the event
- * converted into a GdkEvent Otherwise, returns NULL.
- *
- * Side effects:
- *
- *-------------------------------------------------------------- */
+ for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next)
+ {
+ GdkDisplaySource *tmp_source = tmp_list->data;
+ GdkDisplay *display = tmp_source->display;
+
+ if (_gdk_event_queue_find_first (display))
+ return TRUE;
+ }
+
+ for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next)
+ {
+ GdkDisplaySource *tmp_source = tmp_list->data;
+ GdkDisplay *display = tmp_source->display;
+
+ if (gdk_check_xpending (display))
+ return TRUE;
+ }
+
+ return FALSE;
+}
static Bool
graphics_expose_predicate (Display *display,
@@ -226,6 +249,17 @@ graphics_expose_predicate (Display *display,
return False;
}
+/**
+ * gdk_event_get_graphics_expose:
+ * @window: the #GdkWindow to wait for the events for.
+ *
+ * Waits for a GraphicsExpose or NoExpose event from the X server.
+ * This is used in the #GtkText and #GtkCList widgets in GTK+ to make sure any
+ * GraphicsExpose events are handled before the widget is scrolled.
+ *
+ * Return value: a #GdkEventExpose if a GraphicsExpose was received, or %NULL if a
+ * NoExpose event was received.
+ **/
GdkEvent*
gdk_event_get_graphics_expose (GdkWindow *window)
{
@@ -234,13 +268,15 @@ gdk_event_get_graphics_expose (GdkWindow *window)
g_return_val_if_fail (window != NULL, NULL);
- XIfEvent (gdk_display, &xevent, graphics_expose_predicate, (XPointer) window);
+ XIfEvent (GDK_WINDOW_XDISPLAY (window), &xevent,
+ graphics_expose_predicate, (XPointer) window);
if (xevent.xany.type == GraphicsExpose)
{
event = _gdk_event_new ();
- if (gdk_event_translate (event, &xevent, TRUE))
+ if (gdk_event_translate (GDK_WINDOW_DISPLAY (window), event,
+ &xevent, TRUE))
return event;
else
gdk_event_free (event);
@@ -272,22 +308,56 @@ gdk_event_apply_filters (XEvent *xevent,
return GDK_FILTER_CONTINUE;
}
+/**
+ * gdk_display_add_client_message_filter:
+ * @display: a #GdkDisplay for which this message filter applies
+ * @message_type: the type of ClientMessage events to receive.
+ * This will be checked against the @message_type field
+ * of the XClientMessage event struct.
+ * @func: the function to call to process the event.
+ * @data: user data to pass to @func.
+ *
+ * Adds a filter to be called when X ClientMessage events are received.
+ *
+ **/
void
-gdk_add_client_message_filter (GdkAtom message_type,
- GdkFilterFunc func,
- gpointer data)
+gdk_display_add_client_message_filter (GdkDisplay *display,
+ GdkAtom message_type,
+ GdkFilterFunc func,
+ gpointer data)
{
- GdkClientFilter *filter = g_new (GdkClientFilter, 1);
+ GdkClientFilter *filter;
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+ filter = g_new (GdkClientFilter, 1);
filter->type = message_type;
filter->function = func;
filter->data = data;
- client_filters = g_list_prepend (client_filters, filter);
+ GDK_DISPLAY_X11(display)->client_filters =
+ g_list_prepend (GDK_DISPLAY_X11 (display)->client_filters,
+ filter);
}
-static Atom wm_state_atom = 0;
-static Atom wm_desktop_atom = 0;
+/**
+ * gdk_add_client_message_filter:
+ * @message_type: the type of ClientMessage events to receive. This will be
+ * checked against the <structfield>message_type</structfield> field of the
+ * XClientMessage event struct.
+ * @func: the function to call to process the event.
+ * @data: user data to pass to @func.
+ *
+ * Adds a filter to the default display to be called when X ClientMessage events
+ * are received. See gdk_display_add_client_message_filter().
+ **/
+void
+gdk_add_client_message_filter (GdkAtom message_type,
+ GdkFilterFunc func,
+ gpointer data)
+{
+ gdk_display_add_client_message_filter (gdk_get_default_display (),
+ message_type, func, data);
+}
static void
gdk_check_wm_state_changed (GdkWindow *window)
@@ -298,37 +368,28 @@ gdk_check_wm_state_changed (GdkWindow *window)
gulong bytes_after;
Atom *atoms = NULL;
gulong i;
- Atom sticky_atom;
- Atom maxvert_atom;
- Atom maxhorz_atom;
gboolean found_sticky, found_maxvert, found_maxhorz;
GdkWindowState old_state;
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
if (GDK_WINDOW_DESTROYED (window))
return;
- if (wm_state_atom == 0)
- wm_state_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
-
- if (wm_desktop_atom == 0)
- wm_desktop_atom = gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP");
+ found_sticky = FALSE;
+ found_maxvert = FALSE;
+ found_maxhorz = FALSE;
XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
- wm_state_atom, 0, G_MAXLONG,
- False, XA_ATOM, &type, &format, &nitems,
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+ 0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
&bytes_after, (guchar **)&atoms);
if (type != None)
{
+ Atom sticky_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY");
+ Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
+ Atom maxhorz_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
- sticky_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_STICKY");
- maxvert_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MAXIMIZED_VERT");
- maxhorz_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MAXIMIZED_HORZ");
-
- found_sticky = FALSE;
- found_maxvert = FALSE;
- found_maxhorz = FALSE;
-
i = 0;
while (i < nitems)
{
@@ -344,12 +405,6 @@ gdk_check_wm_state_changed (GdkWindow *window)
XFree (atoms);
}
- else
- {
- found_sticky = FALSE;
- found_maxvert = FALSE;
- found_maxhorz = FALSE;
- }
/* For found_sticky to remain TRUE, we have to also be on desktop
* 0xFFFFFFFF
@@ -359,9 +414,12 @@ gdk_check_wm_state_changed (GdkWindow *window)
{
gulong *desktop;
- XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
- wm_desktop_atom, 0, G_MAXLONG,
- False, XA_CARDINAL, &type, &format, &nitems,
+ XGetWindowProperty (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ gdk_x11_get_xatom_by_name_for_display
+ (display, "_NET_WM_DESKTOP"),
+ 0, G_MAXLONG, False, XA_CARDINAL, &type,
+ &format, &nitems,
&bytes_after, (guchar **)&desktop);
if (type != None)
@@ -425,10 +483,11 @@ generate_focus_event (GdkWindow *window,
gdk_event_put (&event);
}
-static gint
-gdk_event_translate (GdkEvent *event,
- XEvent *xevent,
- gboolean return_exposes)
+static gboolean
+gdk_event_translate (GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent,
+ gboolean return_exposes)
{
GdkWindow *window;
@@ -440,6 +499,9 @@ gdk_event_translate (GdkEvent *event,
char buf[16];
gint return_val;
gint xoffset, yoffset;
+ GdkScreen *screen = NULL;
+ GdkScreenX11 *screen_x11 = NULL;
+ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
return_val = FALSE;
@@ -480,9 +542,15 @@ gdk_event_translate (GdkEvent *event,
/* Find the GdkWindow that this event occurred in. */
- window = gdk_window_lookup (xevent->xany.window);
+ window = gdk_window_lookup_for_display (display, xevent->xany.window);
window_private = (GdkWindowObject *) window;
-
+
+ if (window)
+ {
+ screen = GDK_WINDOW_SCREEN (window);
+ screen_x11 = GDK_SCREEN_X11 (screen);
+ }
+
if (window != NULL)
{
/* Window may be a pixmap, so check its type.
@@ -505,7 +573,7 @@ gdk_event_translate (GdkEvent *event,
xevent->xany.window = GDK_WINDOW_XID (window);
break;
default:
- return False;
+ return FALSE;
}
}
}
@@ -538,11 +606,11 @@ gdk_event_translate (GdkEvent *event,
}
}
- if (wmspec_check_window != None &&
- xevent->xany.window == wmspec_check_window)
+ if (screen_x11 && screen_x11->wmspec_check_window != None &&
+ xevent->xany.window == screen_x11->wmspec_check_window)
{
if (xevent->type == DestroyNotify)
- wmspec_check_window = None;
+ screen_x11->wmspec_check_window = None;
/* Eat events on this window unless someone had wrapped
* it as a foreign window
@@ -555,14 +623,14 @@ gdk_event_translate (GdkEvent *event,
}
if (window &&
- _gdk_moveresize_window &&
(xevent->xany.type == MotionNotify ||
xevent->xany.type == ButtonRelease))
{
- _gdk_moveresize_handle_event (xevent);
-
- return_val = FALSE;
- goto done;
+ if (_gdk_moveresize_handle_event (xevent))
+ {
+ return_val = FALSE;
+ goto done;
+ }
}
/* We do a "manual" conversion of the XEvent to a
@@ -630,7 +698,7 @@ gdk_event_translate (GdkEvent *event,
#define KEYBOARD_GROUP_SHIFT 13
#define KEYBOARD_GROUP_MASK ((1 << 13) | (1 << 14))
- event->key.group = _gdk_x11_get_group_for_state (xevent->xkey.state);
+ event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state);
break;
@@ -649,11 +717,11 @@ gdk_event_translate (GdkEvent *event,
* keycode and timestamp, and if so, ignoring the event.
*/
- if (!_gdk_have_xkb_autorepeat && XPending (gdk_display))
+ if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
{
XEvent next_event;
- XPeekEvent (gdk_display, &next_event);
+ XPeekEvent (xevent->xkey.display, &next_event);
if (next_event.type == KeyPress &&
next_event.xkey.keycode == xevent->xkey.keycode &&
@@ -692,7 +760,7 @@ gdk_event_translate (GdkEvent *event,
if (window_private == NULL ||
((window_private->extension_events != 0) &&
- _gdk_input_ignore_core))
+ display_x11->input_ignore_core))
{
return_val = FALSE;
break;
@@ -740,7 +808,7 @@ gdk_event_translate (GdkEvent *event,
event->button.button = xevent->xbutton.button;
event->button.device = _gdk_core_pointer;
- _gdk_event_button_generate (event);
+ _gdk_event_button_generate (display, event);
break;
}
@@ -755,7 +823,7 @@ gdk_event_translate (GdkEvent *event,
if (window_private == NULL ||
((window_private->extension_events != 0) &&
- _gdk_input_ignore_core))
+ display_x11->input_ignore_core))
{
return_val = FALSE;
break;
@@ -792,7 +860,7 @@ gdk_event_translate (GdkEvent *event,
if (window_private == NULL ||
((window_private->extension_events != 0) &&
- _gdk_input_ignore_core))
+ display_x11->input_ignore_core))
{
return_val = FALSE;
break;
@@ -852,7 +920,7 @@ gdk_event_translate (GdkEvent *event,
* lookup the corresponding GdkWindow.
*/
if (xevent->xcrossing.subwindow != None)
- event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow);
+ event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow);
else
event->crossing.subwindow = NULL;
@@ -939,7 +1007,7 @@ gdk_event_translate (GdkEvent *event,
* lookup the corresponding GdkWindow.
*/
if (xevent->xcrossing.subwindow != None)
- event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow);
+ event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow);
else
event->crossing.subwindow = NULL;
@@ -1107,7 +1175,6 @@ gdk_event_translate (GdkEvent *event,
else
{
_gdk_window_process_expose (window, xevent->xexpose.serial, &expose_rect);
-
return_val = FALSE;
}
@@ -1238,11 +1305,12 @@ gdk_event_translate (GdkEvent *event,
return_val = window_private && !GDK_WINDOW_DESTROYED (window);
- if (window && GDK_WINDOW_XID (window) != GDK_ROOT_WINDOW())
+ if (window && GDK_WINDOW_XID (window) != screen_x11->xroot_window)
gdk_window_destroy_notify (window);
}
else
return_val = FALSE;
+
break;
case UnmapNotify:
@@ -1258,12 +1326,15 @@ gdk_event_translate (GdkEvent *event,
* an unmap, it means we hid the window ourselves, so we
* will have already flipped the iconified bit off.
*/
- if (window && GDK_WINDOW_IS_MAPPED (window))
- gdk_synthesize_window_state (window,
- 0,
- GDK_WINDOW_STATE_ICONIFIED);
+ if (window)
+ {
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_ICONIFIED);
- _gdk_xgrab_check_unmap (window, xevent->xany.serial);
+ _gdk_xgrab_check_unmap (window, xevent->xany.serial);
+ }
break;
@@ -1338,7 +1409,7 @@ gdk_event_translate (GdkEvent *event,
gdk_error_trap_push ();
if (XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
GDK_DRAWABLE_XID (window),
- _gdk_root_window,
+ screen_x11->xroot_window,
0, 0,
&tx, &ty,
&child_window))
@@ -1365,9 +1436,8 @@ gdk_event_translate (GdkEvent *event,
{
window_private->resize_count -= 1;
- if (window_private->resize_count == 0 &&
- window == _gdk_moveresize_window)
- _gdk_moveresize_configure_done ();
+ if (window_private->resize_count == 0)
+ _gdk_moveresize_configure_done (display, window);
}
}
break;
@@ -1378,7 +1448,7 @@ gdk_event_translate (GdkEvent *event,
xevent->xproperty.window,
xevent->xproperty.atom,
"\"",
- gdk_x11_get_xatom_name (xevent->xproperty.atom),
+ gdk_x11_get_xatom_name_for_display (display, xevent->xproperty.atom),
"\""));
if (window_private == NULL)
@@ -1389,18 +1459,12 @@ gdk_event_translate (GdkEvent *event,
event->property.type = GDK_PROPERTY_NOTIFY;
event->property.window = window;
- event->property.atom = gdk_x11_xatom_to_atom (xevent->xproperty.atom);
+ event->property.atom = gdk_x11_xatom_to_atom_for_display (display, xevent->xproperty.atom);
event->property.time = xevent->xproperty.time;
event->property.state = xevent->xproperty.state;
- if (wm_state_atom == 0)
- wm_state_atom = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
-
- if (wm_desktop_atom == 0)
- wm_desktop_atom = gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP");
-
- if (xevent->xproperty.atom == wm_state_atom ||
- xevent->xproperty.atom == wm_desktop_atom)
+ if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE") ||
+ xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
{
/* If window state changed, then synthesize those events. */
gdk_check_wm_state_changed (event->property.window);
@@ -1417,7 +1481,7 @@ gdk_event_translate (GdkEvent *event,
{
event->selection.type = GDK_SELECTION_CLEAR;
event->selection.window = window;
- event->selection.selection = gdk_x11_xatom_to_atom (xevent->xselectionclear.selection);
+ event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionclear.selection);
event->selection.time = xevent->xselectionclear.time;
}
else
@@ -1432,9 +1496,9 @@ gdk_event_translate (GdkEvent *event,
event->selection.type = GDK_SELECTION_REQUEST;
event->selection.window = window;
- event->selection.selection = gdk_x11_xatom_to_atom (xevent->xselectionrequest.selection);
- event->selection.target = gdk_x11_xatom_to_atom (xevent->xselectionrequest.target);
- event->selection.property = gdk_x11_xatom_to_atom (xevent->xselectionrequest.property);
+ event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection);
+ event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.target);
+ event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.property);
event->selection.requestor = xevent->xselectionrequest.requestor;
event->selection.time = xevent->xselectionrequest.time;
@@ -1448,9 +1512,9 @@ gdk_event_translate (GdkEvent *event,
event->selection.type = GDK_SELECTION_NOTIFY;
event->selection.window = window;
- event->selection.selection = gdk_x11_xatom_to_atom (xevent->xselection.selection);
- event->selection.target = gdk_x11_xatom_to_atom (xevent->xselection.target);
- event->selection.property = gdk_x11_xatom_to_atom (xevent->xselection.property);
+ event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection);
+ event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target);
+ event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property);
event->selection.time = xevent->xselection.time;
break;
@@ -1468,13 +1532,13 @@ gdk_event_translate (GdkEvent *event,
{
GList *tmp_list;
GdkFilterReturn result = GDK_FILTER_CONTINUE;
- GdkAtom message_type = gdk_x11_xatom_to_atom (xevent->xclient.message_type);
+ GdkAtom message_type = gdk_x11_xatom_to_atom_for_display (display, xevent->xclient.message_type);
GDK_NOTE (EVENTS,
g_message ("client message:\twindow: %ld",
xevent->xclient.window));
- tmp_list = client_filters;
+ tmp_list = display_x11->client_filters;
while (tmp_list)
{
GdkClientFilter *filter = tmp_list->data;
@@ -1523,25 +1587,26 @@ gdk_event_translate (GdkEvent *event,
/* Let XLib know that there is a new keyboard mapping.
*/
XRefreshKeyboardMapping (&xevent->xmapping);
- ++_gdk_keymap_serial;
+ ++display_x11->keymap_serial;
return_val = FALSE;
break;
default:
#ifdef HAVE_XKB
- if (xevent->type == _gdk_xkb_event_type)
+ if (xevent->type == display_x11->xkb_event_type)
{
XkbEvent *xkb_event = (XkbEvent *)xevent;
switch (xkb_event->any.xkb_type)
{
case XkbMapNotify:
- ++_gdk_keymap_serial;
+ ++display_x11->keymap_serial;
+
return_val = FALSE;
break;
case XkbStateNotify:
- _gdk_keymap_state_changed ();
+ _gdk_keymap_state_changed (display);
break;
}
}
@@ -1590,8 +1655,10 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
gpointer data)
{
XEvent *xevent = (XEvent *)xev;
+ GdkWindow *win = event->any.window;
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (win);
- if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW"))
+ if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
{
/* The delete window request specifies a window
* to delete. We don't actually destroy the
@@ -1609,7 +1676,7 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
return GDK_FILTER_TRANSLATE;
}
- else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name ("WM_TAKE_FOCUS"))
+ else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
{
GdkWindow *win = event->any.window;
Window focus_win = GDK_WINDOW_IMPL_X11(((GdkWindowObject *)win)->impl)->focus_window;
@@ -1625,46 +1692,31 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
XSync (GDK_WINDOW_XDISPLAY (win), False);
gdk_error_trap_pop ();
}
- else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name ("_NET_WM_PING"))
+ else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING"))
{
XEvent xev = *xevent;
- xev.xclient.window = _gdk_root_window;
- XSendEvent (gdk_display, _gdk_root_window, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ xev.xclient.window = GDK_WINDOW_XROOTWIN (win);
+ XSendEvent (GDK_WINDOW_XDISPLAY (win),
+ xev.xclient.window,
+ False,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
return GDK_FILTER_REMOVE;
}
-#if 0
-static Bool
-gdk_event_get_type (Display *display,
- XEvent *xevent,
- XPointer arg)
-{
- GdkEvent event;
- GdkPredicate *pred;
-
- if (gdk_event_translate (&event, xevent, FALSE))
- {
- pred = (GdkPredicate*) arg;
- return (* pred->func) (&event, pred->data);
- }
-
- return FALSE;
-}
-#endif
-
void
-_gdk_events_queue (void)
+_gdk_events_queue (GdkDisplay *display)
{
GList *node;
GdkEvent *event;
XEvent xevent;
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
- while (!_gdk_event_queue_find_first() && XPending (gdk_display))
+ while (!_gdk_event_queue_find_first(display) && XPending (xdisplay))
{
- XNextEvent (gdk_display, &xevent);
+ XNextEvent (xdisplay, &xevent);
switch (xevent.type)
{
@@ -1684,16 +1736,15 @@ _gdk_events_queue (void)
((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
- _gdk_event_queue_append (event);
- node = _gdk_queued_tail;
+ node = _gdk_event_queue_append (display, event);
- if (gdk_event_translate (event, &xevent, FALSE))
+ if (gdk_event_translate (display, event, &xevent, FALSE))
{
((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
}
else
{
- _gdk_event_queue_remove_link (node);
+ _gdk_event_queue_remove_link (display, node);
g_list_free_1 (node);
gdk_event_free (event);
}
@@ -1704,28 +1755,31 @@ static gboolean
gdk_event_prepare (GSource *source,
gint *timeout)
{
+ GdkDisplay *display = ((GdkDisplaySource*)source)->display;
gboolean retval;
GDK_THREADS_ENTER ();
*timeout = -1;
-
- retval = (_gdk_event_queue_find_first () != NULL) || XPending (gdk_display);
-
+ retval = (_gdk_event_queue_find_first (display) != NULL ||
+ gdk_check_xpending (display));
+
GDK_THREADS_LEAVE ();
return retval;
}
static gboolean
-gdk_event_check (GSource *source)
+gdk_event_check (GSource *source)
{
+ GdkDisplaySource *display_source = (GdkDisplaySource*)source;
gboolean retval;
-
+
GDK_THREADS_ENTER ();
- if (event_poll_fd.revents & G_IO_IN)
- retval = (_gdk_event_queue_find_first () != NULL) || XPending (gdk_display);
+ if (display_source->event_poll_fd.revents & G_IO_IN)
+ retval = (_gdk_event_queue_find_first (display_source->display) != NULL ||
+ gdk_check_xpending (display_source->display));
else
retval = FALSE;
@@ -1739,12 +1793,13 @@ gdk_event_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data)
{
+ GdkDisplay *display = ((GdkDisplaySource*)source)->display;
GdkEvent *event;
GDK_THREADS_ENTER ();
- _gdk_events_queue();
- event = _gdk_event_unqueue();
+ _gdk_events_queue (display);
+ event = _gdk_event_unqueue (display);
if (event)
{
@@ -1759,32 +1814,69 @@ gdk_event_dispatch (GSource *source,
return TRUE;
}
-/* Sends a ClientMessage to all toplevel client windows */
+/**
+ * gdk_event_send_client_message:
+ * @event: the #GdkEvent to send, which should be a #GdkEventClient.
+ * @xid: the window to send the X ClientMessage event to.
+ *
+ * Sends an X ClientMessage event to a given window (which must be
+ * on the default #GdkDisplay.)
+ * This could be used for communicating between different applications,
+ * though the amount of data is limited to 20 bytes.
+ *
+ * Return value: non-zero on success.
+ **/
gboolean
gdk_event_send_client_message (GdkEvent *event, guint32 xid)
{
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ return gdk_event_send_client_message_for_display (gdk_get_default_display (),
+ event, xid);
+}
+
+/**
+ * gdk_event_send_client_message_for_display :
+ * @display : the #GdkDisplay for the window where the message is to be sent.
+ * @event : the #GdkEvent to send, which should be a #GdkEventClient.
+ * @xid : the X window to send the X ClientMessage event to.
+ *
+ * Sends an X ClientMessage event to a given window.
+ *
+ * This could be used for communicating between different applications,
+ * though the amount of data is limited to 20 bytes.
+ *
+ * Returns : non-zero on success.
+ */
+gboolean
+gdk_event_send_client_message_for_display (GdkDisplay *display,
+ GdkEvent *event,
+ guint32 xid)
+{
XEvent sev;
g_return_val_if_fail(event != NULL, FALSE);
-
+
/* Set up our event to send, with the exception of its target window */
sev.xclient.type = ClientMessage;
- sev.xclient.display = gdk_display;
+ sev.xclient.display = GDK_DISPLAY_XDISPLAY (display);
sev.xclient.format = event->client.data_format;
sev.xclient.window = xid;
- memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data));
- sev.xclient.message_type = gdk_x11_atom_to_xatom (event->client.message_type);
+ memcpy(&sev.xclient.data, &event->client.data, sizeof (sev.xclient.data));
+ sev.xclient.message_type = gdk_x11_atom_to_xatom_for_display (display, event->client.message_type);
- return gdk_send_xevent (xid, False, NoEventMask, &sev);
+ return _gdk_send_xevent (display, xid, False, NoEventMask, &sev);
}
+
+
/* Sends a ClientMessage to all toplevel client windows */
gboolean
-gdk_event_send_client_message_to_all_recurse (XEvent *xev,
- guint32 xid,
- guint level)
+gdk_event_send_client_message_to_all_recurse (GdkDisplay *display,
+ XEvent *xev,
+ guint32 xid,
+ guint level)
{
- static Atom wm_state_atom = None;
Atom type = None;
int format;
unsigned long nitems, after;
@@ -1795,16 +1887,15 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev,
gboolean found = FALSE;
gboolean result = FALSE;
int i;
-
- if (!wm_state_atom)
- wm_state_atom = gdk_x11_get_xatom_by_name ("WM_STATE");
-
+
gdk_error_trap_push ();
- if (XGetWindowProperty (gdk_display, xid, wm_state_atom, 0, 0, False, AnyPropertyType,
+ if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xid,
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+ 0, 0, False, AnyPropertyType,
&type, &format, &nitems, &after, &data) != Success)
goto out;
-
+
if (type)
{
send = TRUE;
@@ -1813,12 +1904,13 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev,
else
{
/* OK, we're all set, now let's find some windows to send this to */
- if (!XQueryTree (gdk_display, xid, &ret_root, &ret_parent,
- &ret_children, &ret_nchildren))
+ if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xid,
+ &ret_root, &ret_parent,
+ &ret_children, &ret_nchildren))
goto out;
for(i = 0; i < ret_nchildren; i++)
- if (gdk_event_send_client_message_to_all_recurse (xev, ret_children[i], level + 1))
+ if (gdk_event_send_client_message_to_all_recurse (display, xev, ret_children[i], level + 1))
found = TRUE;
XFree (ret_children);
@@ -1827,7 +1919,7 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev,
if (send || (!found && (level == 1)))
{
xev->xclient.window = xid;
- gdk_send_xevent (xid, False, NoEventMask, xev);
+ _gdk_send_xevent (display, xid, False, NoEventMask, xev);
}
result = send || found;
@@ -1838,21 +1930,63 @@ gdk_event_send_client_message_to_all_recurse (XEvent *xev,
return result;
}
+/**
+ * gdk_event_send_clientmessage_toall:
+ * @event: the #GdkEvent to send, which should be a #GdkEventClient.
+ *
+ * Sends an X ClientMessage event to all toplevel windows on the default
+ * #GdkScreen.
+ *
+ * Toplevel windows are determined by checking for the WM_STATE property, as
+ * described in the Inter-Client Communication Conventions Manual (ICCCM).
+ * If no windows are found with the WM_STATE property set, the message is sent
+ * to all children of the root window.
+ **/
void
gdk_event_send_clientmessage_toall (GdkEvent *event)
{
+ g_return_if_fail (event != NULL);
+
+ gdk_screen_broadcast_client_message (gdk_get_default_screen (), event);
+}
+
+/**
+ * gdk_screen_broadcast_client_message:
+ * @screen : the #GdkScreen where the event will be broadcasted.
+ * @event : the #GdkEvent.
+ *
+ * Sends an X ClientMessage event to all toplevel windows on @screen.
+ *
+ * Toplevel windows are determined by checking for the WM_STATE property,
+ * as described in the Inter-Client Communication Conventions Manual (ICCCM).
+ * If no windows are found with the WM_STATE property set, the message is
+ * sent to all children of the root window.
+ */
+
+void
+gdk_screen_broadcast_client_message (GdkScreen *screen,
+ GdkEvent *event)
+{
XEvent sev;
+ GdkWindow *root_window;
- g_return_if_fail(event != NULL);
+ g_return_if_fail (event != NULL);
+
+ root_window = gdk_screen_get_root_window (screen);
/* Set up our event to send, with the exception of its target window */
sev.xclient.type = ClientMessage;
- sev.xclient.display = gdk_display;
+ sev.xclient.display = GDK_WINDOW_XDISPLAY (root_window);
sev.xclient.format = event->client.data_format;
- memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data));
- sev.xclient.message_type = gdk_x11_atom_to_xatom (event->client.message_type);
-
- gdk_event_send_client_message_to_all_recurse(&sev, _gdk_root_window, 0);
+ memcpy(&sev.xclient.data, &event->client.data, sizeof (sev.xclient.data));
+ sev.xclient.message_type =
+ gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (root_window),
+ event->client.message_type);
+
+ gdk_event_send_client_message_to_all_recurse (gdk_screen_get_display (screen),
+ &sev,
+ GDK_WINDOW_XID (root_window),
+ 0);
}
/*
@@ -1876,21 +2010,27 @@ gdk_event_send_clientmessage_toall (GdkEvent *event)
void
gdk_flush (void)
{
- XSync (gdk_display, False);
+ GSList *tmp_list = _gdk_displays;
+
+ while (tmp_list)
+ {
+ XSync (GDK_DISPLAY_XDISPLAY (tmp_list->data), False);
+ tmp_list = tmp_list->next;
+ }
}
-static Atom timestamp_prop_atom = 0;
-
static Bool
timestamp_predicate (Display *display,
XEvent *xevent,
XPointer arg)
{
Window xwindow = GPOINTER_TO_UINT (arg);
+ GdkDisplay *gdk_display = gdk_x11_lookup_xdisplay (display);
if (xevent->type == PropertyNotify &&
xevent->xproperty.window == xwindow &&
- xevent->xproperty.atom == timestamp_prop_atom)
+ xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display
+ (gdk_display, "GDK_TIMESTAMP_PROP"))
return True;
return False;
@@ -1913,18 +2053,19 @@ gdk_x11_get_server_time (GdkWindow *window)
Window xwindow;
guchar c = 'a';
XEvent xevent;
+ Atom timestamp_prop_atom;
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
g_return_val_if_fail (!GDK_WINDOW_DESTROYED (window), 0);
- if (!timestamp_prop_atom)
- timestamp_prop_atom = gdk_x11_get_xatom_by_name ("GDK_TIMESTAMP_PROP");
-
xdisplay = GDK_WINDOW_XDISPLAY (window);
xwindow = GDK_WINDOW_XWINDOW (window);
+ timestamp_prop_atom =
+ gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
+ "GDK_TIMESTAMP_PROP");
- XChangeProperty (xdisplay, xwindow,
- timestamp_prop_atom, timestamp_prop_atom,
+ XChangeProperty (xdisplay, xwindow, timestamp_prop_atom,
+ timestamp_prop_atom,
8, PropModeReplace, &c, 1);
XIfEvent (xdisplay, &xevent,
@@ -1933,10 +2074,18 @@ gdk_x11_get_server_time (GdkWindow *window)
return xevent.xproperty.time;
}
+typedef struct _NetWmSupportedAtoms NetWmSupportedAtoms;
+
+struct _NetWmSupportedAtoms
+{
+ Atom *atoms;
+ gulong n_atoms;
+};
/**
- * gdk_net_wm_supports:
- * @property: a property atom
+ * gdk_x11_screen_supports_net_wm_hint:
+ * @screen : the relevant #GdkScreen.
+ * @property: a property atom.
*
* This function is specific to the X11 backend of GDK, and indicates
* whether the window manager supports a certain hint from the
@@ -1953,42 +2102,53 @@ gdk_x11_get_server_time (GdkWindow *window)
* Return value: %TRUE if the window manager supports @property
**/
gboolean
-gdk_net_wm_supports (GdkAtom property)
+gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen,
+ GdkAtom property)
{
- static Atom wmspec_check_atom = 0;
- static Atom wmspec_supported_atom = 0;
- static Atom *atoms = NULL;
- static gulong n_atoms = 0;
- Atom xproperty = gdk_x11_atom_to_xatom (property);
Atom type;
gint format;
gulong nitems;
gulong bytes_after;
Window *xwindow;
gulong i;
+ GdkScreenX11 *screen_x11;
+ NetWmSupportedAtoms *supported_atoms;
+ GdkDisplay *display;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+ screen_x11 = GDK_SCREEN_X11 (screen);
+ display = screen_x11->display;
- if (wmspec_check_window != None)
+ supported_atoms = g_object_get_data (G_OBJECT (screen), "gdk-net-wm-supported-atoms");
+ if (!supported_atoms)
{
- if (atoms == NULL)
- return FALSE;
+ supported_atoms = g_new0 (NetWmSupportedAtoms, 1);
+ g_object_set_data (G_OBJECT (screen), "net-wm-supported-atoms", supported_atoms);
+ }
+ if (screen_x11->wmspec_check_window != None)
+ {
+ if (supported_atoms->atoms == NULL)
+ return FALSE;
+
i = 0;
- while (i < n_atoms)
+ while (i < supported_atoms->n_atoms)
{
- if (atoms[i] == xproperty)
+ if (supported_atoms->atoms[i] == gdk_x11_atom_to_xatom_for_display (display, property))
return TRUE;
++i;
}
-
+
return FALSE;
}
- if (atoms)
- XFree (atoms);
+ if (supported_atoms->atoms)
+ XFree (supported_atoms->atoms);
- atoms = NULL;
- n_atoms = 0;
+ supported_atoms->atoms = NULL;
+ supported_atoms->n_atoms = 0;
/* This function is very slow on every call if you are not running a
* spec-supporting WM. For now not optimized, because it isn't in
@@ -1998,47 +2158,59 @@ gdk_net_wm_supports (GdkAtom property)
* _NET_SUPPORTING_WM_CHECK only once every 10 seconds or something.
*/
- if (wmspec_check_atom == 0)
- wmspec_check_atom = gdk_x11_get_xatom_by_name ("_NET_SUPPORTING_WM_CHECK");
-
- if (wmspec_supported_atom == 0)
- wmspec_supported_atom = gdk_x11_get_xatom_by_name ("_NET_SUPPORTED");
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_x11->xroot_window,
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"),
+ 0, G_MAXLONG, False, XA_WINDOW, &type, &format,
+ &nitems, &bytes_after, (guchar **) & xwindow);
- XGetWindowProperty (gdk_display, _gdk_root_window,
- wmspec_check_atom, 0, G_MAXLONG,
- False, XA_WINDOW, &type, &format, &nitems,
- &bytes_after, (guchar **)&xwindow);
-
if (type != XA_WINDOW)
return FALSE;
gdk_error_trap_push ();
/* Find out if this WM goes away, so we can reset everything. */
- XSelectInput (gdk_display, *xwindow,
- StructureNotifyMask);
-
- gdk_flush ();
+ XSelectInput (screen_x11->xdisplay, *xwindow, StructureNotifyMask);
+
+ gdk_display_sync (screen_x11->display);
if (gdk_error_trap_pop ())
{
XFree (xwindow);
return FALSE;
}
-
- XGetWindowProperty (gdk_display, _gdk_root_window,
- wmspec_supported_atom, 0, G_MAXLONG,
- False, XA_ATOM, &type, &format, &n_atoms,
- &bytes_after, (guchar **)&atoms);
+
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_x11->xroot_window,
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTED"),
+ 0, G_MAXLONG, False, XA_ATOM, &type, &format,
+ &supported_atoms->n_atoms, &bytes_after,
+ (guchar **)&supported_atoms->atoms);
if (type != XA_ATOM)
return FALSE;
- wmspec_check_window = *xwindow;
+ screen_x11->wmspec_check_window = *xwindow;
XFree (xwindow);
/* since wmspec_check_window != None this isn't infinite. ;-) */
- return gdk_net_wm_supports (property);
+ return gdk_x11_screen_supports_net_wm_hint (screen, property);
+}
+
+/**
+ * gdk_net_wm_supports:
+ * @screen : the relevant #GdkScreen.
+ * @property: a property atom.
+ *
+ * This function is specific to the X11 backend of GDK, and indicates
+ * whether the window manager for the default screen supports a certain
+ * hint from the Extended Window Manager Hints Specification. See
+ * gdk_x11_screen_supports_net_wm_hint() for complete details.
+ *
+ * Return value: %TRUE if the window manager supports @property
+ **/
+gboolean
+gdk_net_wm_supports (GdkAtom property)
+{
+ return gdk_x11_screen_supports_net_wm_hint (gdk_get_default_screen (), property);
}
static struct
@@ -2060,16 +2232,17 @@ static struct
};
static void
-gdk_xsettings_notify_cb (const char *name,
- XSettingsAction action,
- XSettingsSetting *setting,
- void *data)
+gdk_xsettings_notify_cb (const char *name,
+ XSettingsAction action,
+ XSettingsSetting *setting,
+ void *data)
{
GdkEvent new_event;
+ GdkScreen *screen = data;
int i;
new_event.type = GDK_SETTING;
- new_event.setting.window = NULL;
+ new_event.setting.window = gdk_screen_get_root_window (screen);
new_event.setting.send_event = FALSE;
new_event.setting.name = NULL;
@@ -2116,16 +2289,56 @@ check_transform (const gchar *xsettings_name,
return TRUE;
}
+/**
+ * gdk_setting_get:
+ * @name: the name of the setting.
+ * @value: location to store the value of the setting.
+ *
+ * Obtains a desktop-wide setting, such as the double-click time,
+ * for the default screen. See gdk_screen_get_setting().
+ *
+ * Returns : %TRUE if the setting existed and a value was stored
+ * in @value, %FALSE otherwise.
+ **/
gboolean
gdk_setting_get (const gchar *name,
GValue *value)
{
+ return gdk_screen_get_setting (gdk_get_default_screen (), name, value);
+}
+
+/**
+ * gdk_screen_get_setting:
+ * @screen: the #GdkScreen where the setting is located
+ * @name: the name of the setting
+ * @value: location to store the value of the setting
+ *
+ * Retrieves a desktop-wide setting such as double-click time
+ * for the #GdkScreen @screen.
+ *
+ * FIXME needs a list of valid settings here, or a link to
+ * more information.
+ *
+ * Returns : %TRUE if the setting existed and a value was stored
+ * in @value, %FALSE otherwise.
+ **/
+gboolean
+gdk_screen_get_setting (GdkScreen *screen,
+ const gchar *name,
+ GValue *value)
+{
+
const char *xsettings_name = NULL;
XSettingsResult result;
XSettingsSetting *setting;
+ GdkScreenX11 *screen_x11;
gboolean success = FALSE;
gint i;
GValue tmp_val = { 0, };
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+
+ screen_x11 = GDK_SCREEN_X11 (screen);
for (i = 0; i < G_N_ELEMENTS (settings_map) ; i++)
if (strcmp (settings_map[i].gdk_name, name) == 0)
@@ -2137,7 +2350,8 @@ gdk_setting_get (const gchar *name,
if (!xsettings_name)
return FALSE;
- result = xsettings_client_get_setting (xsettings_client, xsettings_name, &setting);
+ result = xsettings_client_get_setting (screen_x11->xsettings_client,
+ xsettings_name, &setting);
if (result != XSETTINGS_SUCCESS)
return FALSE;
@@ -2196,23 +2410,27 @@ gdk_xsettings_client_event_filter (GdkXEvent *xevent,
GdkEvent *event,
gpointer data)
{
- if (xsettings_client_process_event (xsettings_client, (XEvent *)xevent))
+ GdkScreenX11 *screen = data;
+
+ if (xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent))
return GDK_FILTER_REMOVE;
else
return GDK_FILTER_CONTINUE;
}
static void
-gdk_xsettings_watch_cb (Window window,
- Bool is_start,
- long mask,
- void *cb_data)
+gdk_xsettings_watch_cb (Window window,
+ Bool is_start,
+ long mask,
+ void *cb_data)
{
GdkWindow *gdkwin;
+ GdkScreen *screen = cb_data;
- gdkwin = gdk_window_lookup (window);
+ gdkwin = gdk_window_lookup_for_display (gdk_screen_get_display (screen), window);
+
if (is_start)
- gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, NULL);
+ gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
else
- gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, NULL);
+ gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
}