*/
/*
- * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * Modified by the GTK+ Team and others 1997-2007. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
#include <string.h>
#include "gdkinputprivate.h"
+#include "gdksettings.c"
+#include "gdkalias.h"
+
#ifdef HAVE_XKB
#include <X11/XKBlib.h>
/* Keep a flag to avoid extra notifies that we don't need
*/
screen_x11->xsettings_in_init = TRUE;
- screen_x11->xsettings_client = xsettings_client_new (screen_x11->xdisplay,
- screen_x11->screen_num,
- gdk_xsettings_notify_cb,
- gdk_xsettings_watch_cb,
- screen);
- xsettings_client_set_grab_func (screen_x11->xsettings_client,
- refcounted_grab_server);
- xsettings_client_set_ungrab_func (screen_x11->xsettings_client,
- refcounted_ungrab_server);
+ screen_x11->xsettings_client = xsettings_client_new_with_grab_funcs (screen_x11->xdisplay,
+ screen_x11->screen_num,
+ gdk_xsettings_notify_cb,
+ gdk_xsettings_watch_cb,
+ screen,
+ refcounted_grab_server,
+ refcounted_ungrab_server);
screen_x11->xsettings_in_init = FALSE;
}
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
- xsettings_client_destroy (screen_x11->xsettings_client);
- screen_x11->xsettings_client = NULL;
+ if (screen_x11->xsettings_client)
+ {
+ xsettings_client_destroy (screen_x11->xsettings_client);
+ screen_x11->xsettings_client = NULL;
+ }
}
void
display_sources = g_list_prepend (display_sources,display_source);
gdk_display_add_client_message_filter (display,
- gdk_atom_intern ("WM_PROTOCOLS", FALSE),
+ gdk_atom_intern_static_string ("WM_PROTOCOLS"),
gdk_wm_protocols_filter,
NULL);
}
+void
+_gdk_events_uninit (GdkDisplay *display)
+{
+ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+
+ if (display_x11->event_source)
+ {
+ display_sources = g_list_remove (display_sources,
+ display_x11->event_source);
+ g_source_destroy (display_x11->event_source);
+ g_source_unref (display_x11->event_source);
+ display_x11->event_source = NULL;
+ }
+}
/**
* gdk_events_pending:
}
else
{
- if (toplevel->have_sticky && toplevel->on_all_desktops)
+ if (toplevel->have_sticky || toplevel->on_all_desktops)
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_STICKY);
gint format;
gulong nitems;
gulong bytes_after;
+ guchar *data;
+ gulong *desktop;
- if (toplevel->have_sticky)
- {
- gulong *desktop;
-
- XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
- 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);
+ type = None;
+ gdk_error_trap_push ();
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ 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, &data);
+ gdk_error_trap_pop ();
- if (type != None)
- {
- toplevel->on_all_desktops = (*desktop == 0xFFFFFFFF);
- XFree (desktop);
- }
- else
- toplevel->on_all_desktops = FALSE;
-
- do_net_wm_state_changes (window);
+ if (type != None)
+ {
+ desktop = (gulong *)data;
+ toplevel->on_all_desktops = (*desktop == 0xFFFFFFFF);
+ XFree (desktop);
}
+ else
+ toplevel->on_all_desktops = FALSE;
+
+ do_net_wm_state_changes (window);
}
static void
gint format;
gulong nitems;
gulong bytes_after;
+ guchar *data;
Atom *atoms = NULL;
gulong i;
toplevel->have_maxhorz = FALSE;
toplevel->have_fullscreen = FALSE;
+ type = None;
+ gdk_error_trap_push ();
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
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);
+ &bytes_after, &data);
+ gdk_error_trap_pop ();
if (type != None)
{
Atom maxhorz_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
Atom fullscreen_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
+ atoms = (Atom *)data;
+
i = 0;
while (i < nitems)
{
gdk_event_put (&event);
}
-static void
+static gboolean
set_screen_from_root (GdkDisplay *display,
GdkEvent *event,
Window xrootwin)
GdkScreen *screen;
screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
- g_assert (screen);
- gdk_event_set_screen (event, screen);
+ if (screen)
+ {
+ gdk_event_set_screen (event, screen);
+
+ return TRUE;
+ }
+
+ return FALSE;
}
static void
{
GdkKeymap *keymap = gdk_keymap_get_for_display (display);
gunichar c = 0;
- guchar buf[7];
+ gchar buf[7];
event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
event->key.time = xevent->xkey.time;
&event->key.keyval,
NULL, NULL, NULL);
+ _gdk_keymap_add_virtual_modifiers (keymap, &event->key.state);
+ event->key.is_modifier = _gdk_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
+
/* Fill in event->string crudely, since various programs
* depend on it.
*/
event->scroll.y_root = (gfloat)xevent->xbutton.y_root;
event->scroll.state = (GdkModifierType) xevent->xbutton.state;
event->scroll.device = display->core_pointer;
-
- set_screen_from_root (display, event, xevent->xbutton.root);
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
break;
event->button.button = xevent->xbutton.button;
event->button.device = display->core_pointer;
- set_screen_from_root (display, event, xevent->xbutton.root);
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
_gdk_event_button_generate (display, event);
break;
}
set_user_time (window, event);
+
+ _gdk_xgrab_check_button_event (window, xevent);
break;
case ButtonRelease:
event->button.button = xevent->xbutton.button;
event->button.device = display->core_pointer;
- set_screen_from_root (display, event, xevent->xbutton.root);
-
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ _gdk_xgrab_check_button_event (window, xevent);
break;
case MotionNotify:
return_val = FALSE;
break;
}
-
+
event->motion.type = GDK_MOTION_NOTIFY;
event->motion.window = window;
event->motion.time = xevent->xmotion.time;
event->motion.is_hint = xevent->xmotion.is_hint;
event->motion.device = display->core_pointer;
- set_screen_from_root (display, event, xevent->xmotion.root);
-
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
break;
case EnterNotify:
break;
}
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
/* Handle focusing (in the case where no window manager is running */
- if (toplevel &&
- xevent->xcrossing.detail != NotifyInferior &&
- xevent->xcrossing.focus && !toplevel->has_focus_window)
+ if (toplevel && xevent->xcrossing.detail != NotifyInferior)
{
- gboolean had_focus = HAS_FOCUS (toplevel);
-
- toplevel->has_pointer_focus = TRUE;
+ toplevel->has_pointer = TRUE;
- if (HAS_FOCUS (toplevel) != had_focus)
- generate_focus_event (window, TRUE);
+ if (xevent->xcrossing.focus && !toplevel->has_focus_window)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ toplevel->has_pointer_focus = TRUE;
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, TRUE);
+ }
}
/* Tell XInput stuff about it if appropriate */
event->crossing.x_root = xevent->xcrossing.x_root;
event->crossing.y_root = xevent->xcrossing.y_root;
- set_screen_from_root (display, event, xevent->xcrossing.root);
-
/* Translate the crossing mode into Gdk terms.
*/
switch (xevent->xcrossing.mode)
return_val = FALSE;
break;
}
-
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
/* Handle focusing (in the case where no window manager is running */
- if (toplevel &&
- xevent->xcrossing.detail != NotifyInferior &&
- xevent->xcrossing.focus && !toplevel->has_focus_window)
+ if (toplevel && xevent->xcrossing.detail != NotifyInferior)
{
- gboolean had_focus = HAS_FOCUS (toplevel);
-
- toplevel->has_pointer_focus = FALSE;
-
- if (HAS_FOCUS (toplevel) != had_focus)
- generate_focus_event (window, FALSE);
+ toplevel->has_pointer = FALSE;
+
+ if (xevent->xcrossing.focus && !toplevel->has_focus_window)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ toplevel->has_pointer_focus = FALSE;
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, FALSE);
+ }
}
event->crossing.type = GDK_LEAVE_NOTIFY;
event->crossing.x_root = xevent->xcrossing.x_root;
event->crossing.y_root = xevent->xcrossing.y_root;
- set_screen_from_root (display, event, xevent->xcrossing.root);
-
/* Translate the crossing mode into Gdk terms.
*/
switch (xevent->xcrossing.mode)
switch (xevent->xfocus.detail)
{
case NotifyAncestor:
- case NotifyNonlinear:
case NotifyVirtual:
+ /* When the focus moves from an ancestor of the window to
+ * the window or a descendent of the window, *and* the
+ * pointer is inside the window, then we were previously
+ * receiving keystroke events in the has_pointer_focus
+ * case and are now receiving them in the
+ * has_focus_window case.
+ */
+ if (toplevel->has_pointer &&
+ xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = FALSE;
+
+ /* fall through */
+ case NotifyNonlinear:
case NotifyNonlinearVirtual:
- toplevel->has_focus_window = TRUE;
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_focus_window = TRUE;
/* We pretend that the focus moves to the grab
* window, so we pay attention to NotifyGrab
* NotifyUngrab, and ignore NotifyWhileGrabbed
* but the pointer focus is ignored while a
* grab is in effect
*/
- if (xevent->xfocus.mode != NotifyGrab)
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
toplevel->has_pointer_focus = TRUE;
break;
case NotifyInferior:
switch (xevent->xfocus.detail)
{
case NotifyAncestor:
- case NotifyNonlinear:
case NotifyVirtual:
+ /* When the focus moves from the window or a descendent
+ * of the window to an ancestor of the window, *and* the
+ * pointer is inside the window, then we were previously
+ * receiving keystroke events in the has_focus_window
+ * case and are now receiving them in the
+ * has_pointer_focus case.
+ */
+ if (toplevel->has_pointer &&
+ xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = TRUE;
+
+ /* fall through */
+ case NotifyNonlinear:
case NotifyNonlinearVirtual:
- toplevel->has_focus_window = FALSE;
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_focus_window = FALSE;
if (xevent->xfocus.mode != NotifyWhileGrabbed)
toplevel->has_focus = FALSE;
break;
case NotifyPointer:
- if (xevent->xfocus.mode != NotifyUngrab)
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
toplevel->has_pointer_focus = FALSE;
break;
case NotifyInferior:
? " (discarding substructure)"
: ""));
if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
- _gdk_x11_screen_size_changed (screen, xevent);
+ {
+ window_impl->width = xevent->xconfigure.width;
+ window_impl->height = xevent->xconfigure.height;
+
+ _gdk_x11_drawable_update_size (window_private->impl);
+ _gdk_x11_screen_size_changed (screen, xevent);
+ }
if (window &&
xevent->xconfigure.event == xevent->xconfigure.window &&
window_private->y = event->configure.y;
window_impl->width = xevent->xconfigure.width;
window_impl->height = xevent->xconfigure.height;
+
+ _gdk_x11_drawable_update_size (window_private->impl);
+
if (window_private->resize_count >= 1)
{
window_private->resize_count -= 1;
break;
case XkbStateNotify:
- _gdk_keymap_state_changed (display);
+ _gdk_keymap_state_changed (display, xevent);
break;
}
}
if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify)
{
XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
+
+ _gdk_x11_screen_process_owner_change (screen, xevent);
+
event->owner_change.type = GDK_OWNER_CHANGE;
event->owner_change.window = window;
event->owner_change.owner = selection_notify->owner;
selection_notify->selection);
event->owner_change.time = selection_notify->timestamp;
event->owner_change.selection_time = selection_notify->selection_timestamp;
-
+
return_val = TRUE;
}
else
{
XEvent *xevent = (XEvent *)xev;
GdkWindow *win = event->any.window;
- GdkDisplay *display = GDK_WINDOW_DISPLAY (win);
- Atom atom = (Atom)xevent->xclient.data.l[0];
+ GdkDisplay *display;
+ Atom atom;
+
+ if (!win)
+ return GDK_FILTER_REMOVE;
+
+ display = GDK_WINDOW_DISPLAY (win);
+ atom = (Atom)xevent->xclient.data.l[0];
if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
{
event->any.type = GDK_DELETE;
+ gdk_x11_window_set_user_time (win, xevent->xclient.data.l[1]);
+
return GDK_FILTER_TRANSLATE;
}
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
!_gdk_x11_display_is_root_window (display,
xevent->xclient.window))
{
- XEvent xev = *xevent;
+ XClientMessageEvent xclient = xevent->xclient;
- xev.xclient.window = GDK_WINDOW_XROOTWIN (win);
+ xclient.window = GDK_WINDOW_XROOTWIN (win);
XSendEvent (GDK_WINDOW_XDISPLAY (win),
- xev.xclient.window,
+ xclient.window,
False,
- SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xclient);
return GDK_FILTER_REMOVE;
}
/* Sends a ClientMessage to all toplevel client windows */
-gboolean
+static gboolean
gdk_event_send_client_message_to_all_recurse (GdkDisplay *display,
XEvent *xev,
guint32 xid,
gint format;
gulong n_items;
gulong bytes_after;
+ guchar *data;
Window *xwindow;
/* This function is very slow on every call if you are not running a
screen_x11 = GDK_SCREEN_X11 (screen);
display = screen_x11->display;
+
+ g_return_if_fail (GDK_DISPLAY_X11 (display)->trusted_client);
if (screen_x11->wmspec_check_window != None)
return; /* already have it */
+ data = NULL;
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,
- &n_items, &bytes_after, (guchar **) & xwindow);
+ &n_items, &bytes_after, &data);
if (type != XA_WINDOW)
- return;
+ {
+ if (data)
+ XFree (data);
+ return;
+ }
+
+ xwindow = (Window *)data;
gdk_error_trap_push ();
if (gdk_error_trap_pop () == Success)
{
screen_x11->wmspec_check_window = *xwindow;
- XFree (xwindow);
-
screen_x11->need_refetch_net_supported = TRUE;
screen_x11->need_refetch_wm_name = TRUE;
/* Careful, reentrancy */
_gdk_x11_screen_window_manager_changed (GDK_SCREEN (screen_x11));
}
+
+ XFree (xwindow);
}
/**
screen_x11 = GDK_SCREEN_X11 (screen);
+ if (!G_LIKELY (GDK_DISPLAY_X11 (screen_x11->display)->trusted_client))
+ return screen_x11->window_manager_name;
+
fetch_net_wm_check_window (screen);
if (screen_x11->need_refetch_wm_name)
gint format;
gulong n_items;
gulong bytes_after;
- guchar *name;
+ gchar *name;
name = NULL;
screen_x11 = GDK_SCREEN_X11 (screen);
display = screen_x11->display;
+ if (!G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
+ return FALSE;
+
supported_atoms = g_object_get_data (G_OBJECT (screen), "gdk-net-wm-supported-atoms");
if (!supported_atoms)
{
return gdk_x11_screen_supports_net_wm_hint (gdk_screen_get_default (), property);
}
-static struct
-{
- const char *xsettings_name;
- const char *gdk_name;
-} settings_map[] = {
- { "Net/DoubleClickTime", "gtk-double-click-time" },
- { "Net/DoubleClickDistance", "gtk-double-click-distance" },
- { "Net/DndDragThreshold", "gtk-dnd-drag-threshold" },
- { "Gtk/CanChangeAccels", "gtk-can-change-accels" },
- { "Gtk/ColorPalette", "gtk-color-palette" },
- { "Gtk/FontName", "gtk-font-name" },
- { "Gtk/IconSizes", "gtk-icon-sizes" },
- { "Gtk/KeyThemeName", "gtk-key-theme-name" },
- { "Gtk/ToolbarStyle", "gtk-toolbar-style" },
- { "Gtk/ToolbarIconSize", "gtk-toolbar-icon-size" },
- { "Gtk/IMPreeditStyle", "gtk-im-preedit-style" },
- { "Gtk/IMStatusStyle", "gtk-im-status-style" },
- { "Net/CursorBlink", "gtk-cursor-blink" },
- { "Net/CursorBlinkTime", "gtk-cursor-blink-time" },
- { "Net/ThemeName", "gtk-theme-name" },
- { "Net/IconThemeName", "gtk-icon-theme-name" },
- { "Gtk/FileChooserBackend", "gtk-file-chooser-backend" },
- { "Gtk/ButtonImages", "gtk-button-images" },
- { "Gtk/MenuImages", "gtk-menu-images" },
- { "Xft/Antialias", "gtk-xft-antialias" },
- { "Xft/Hinting", "gtk-xft-hinting" },
- { "Xft/HintStyle", "gtk-xft-hintstyle" },
- { "Xft/RGBA", "gtk-xft-rgba" },
- { "Xft/DPI", "gtk-xft-dpi" },
-};
static void
gdk_xsettings_notify_cb (const char *name,
new_event.setting.send_event = FALSE;
new_event.setting.name = NULL;
- for (i = 0; i < G_N_ELEMENTS (settings_map) ; i++)
- if (strcmp (settings_map[i].xsettings_name, name) == 0)
+ for (i = 0; i < GDK_SETTINGS_N_ELEMENTS() ; i++)
+ if (strcmp (GDK_SETTINGS_X_NAME (i), name) == 0)
{
- new_event.setting.name = (char *)settings_map[i].gdk_name;
+ new_event.setting.name = (char*) GDK_SETTINGS_GDK_NAME (i);
break;
}
{
if (!g_value_type_transformable (src_type, dest_type))
{
- g_warning ("Cannot tranform xsetting %s of type %s to type %s\n",
+ g_warning ("Cannot transform xsetting %s of type %s to type %s\n",
xsettings_name,
g_type_name (src_type),
g_type_name (dest_type));
const char *xsettings_name = NULL;
XSettingsResult result;
- XSettingsSetting *setting;
+ XSettingsSetting *setting = NULL;
GdkScreenX11 *screen_x11;
gboolean success = FALSE;
gint i;
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)
+ for (i = 0; i < GDK_SETTINGS_N_ELEMENTS(); i++)
+ if (strcmp (GDK_SETTINGS_GDK_NAME (i), name) == 0)
{
- xsettings_name = settings_map[i].xsettings_name;
+ xsettings_name = GDK_SETTINGS_X_NAME (i);
break;
}
if (!xsettings_name)
- return FALSE;
+ goto out;
result = xsettings_client_get_setting (screen_x11->xsettings_client,
xsettings_name, &setting);
if (result != XSETTINGS_SUCCESS)
- return FALSE;
+ goto out;
switch (setting->type)
{
g_value_unset (&tmp_val);
- xsettings_setting_free (setting);
+ out:
+ if (setting)
+ xsettings_setting_free (setting);
- return success;
+ if (success)
+ return TRUE;
+ else
+ return _gdk_x11_get_xft_setting (screen, name, value);
}
static GdkFilterReturn
{
if (!gdkwin)
gdkwin = gdk_window_foreign_new_for_display (gdk_screen_get_display (screen), window);
- else
- g_object_ref (gdkwin);
gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
}
else
{
- g_assert (gdkwin);
- gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
- g_object_unref (gdkwin);
+ if (gdkwin)
+ gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
}
}
+
+#define __GDK_EVENTS_X11_C__
+#include "gdkaliasdef.c"