[gnome-settings-daemon] Handle video out keys in media-keys
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] Handle video out keys in media-keys
- Date: Mon, 8 Nov 2010 21:00:32 +0000 (UTC)
commit d1a4f8cd587d7817fc7685f287c0e71190751ca6
Author: Ray Strode <rstrode redhat com>
Date: Wed Jun 30 17:55:59 2010 +0100
Handle video out keys in media-keys
Instead of reimplementing keyboard events capture in xrandr,
add D-Bus methods to rotate the screen, and switch video modes
to the xrandr plugin, and make the media-keys plugin handle call
those methods when the keys are pressed.
This patch almost entirely written by:
Bastien Nocera <hadess hadess net>
with minor fixes.
https://bugzilla.gnome.org/show_bug.cgi?id=623223
plugins/media-keys/acme.h | 10 ++-
plugins/media-keys/gsd-media-keys-manager.c | 138 +++++++++++++++++++++++---
plugins/xrandr/gsd-xrandr-manager.c | 124 +++++-------------------
plugins/xrandr/gsd-xrandr-manager.xml | 8 ++
4 files changed, 162 insertions(+), 118 deletions(-)
---
diff --git a/plugins/media-keys/acme.h b/plugins/media-keys/acme.h
index 4ba6859..d52535f 100644
--- a/plugins/media-keys/acme.h
+++ b/plugins/media-keys/acme.h
@@ -49,6 +49,9 @@ enum {
FORWARD_KEY,
REPEAT_KEY,
RANDOM_KEY,
+ VIDEO_OUT_KEY,
+ VIDEO_OUT2_KEY,
+ ROTATE_VIDEO_KEY,
HANDLED_KEYS
};
@@ -80,7 +83,12 @@ static struct {
{ REWIND_KEY, "rewind", "XF86AudioRewind", NULL },
{ FORWARD_KEY, "forward", "XF86AudioForward", NULL },
{ REPEAT_KEY, "repeat", "XF86AudioRepeat", NULL },
- { RANDOM_KEY, "random", "XF86AudioRandomPlay", NULL}
+ { RANDOM_KEY, "random", "XF86AudioRandomPlay", NULL},
+ { VIDEO_OUT_KEY, NULL, "<Mod4>p", NULL },
+ /* Key code of the XF86Display key (Fn-F7 on Thinkpads, Fn-F4 on HP machines, etc.) */
+ { VIDEO_OUT2_KEY, NULL, "XF86Display", NULL },
+ /* Key code of the XF86RotateWindows key (present on some tablets) */
+ { ROTATE_VIDEO_KEY, NULL, "XF86RotateWindows", NULL },
};
#endif /* __ACME_H__ */
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index dbbc21d..eec7d9b 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -106,6 +106,8 @@ struct GsdMediaKeysManagerPrivate
guint owner_id;
GDBusNodeInfo *introspection_data;
GDBusConnection *connection;
+ GDBusProxy *xrandr_proxy;
+ GCancellable *cancellable;
};
static void gsd_media_keys_manager_class_init (GsdMediaKeysManagerClass *klass);
@@ -948,9 +950,86 @@ do_multimedia_player_action (GsdMediaKeysManager *manager,
return gsd_media_player_key_pressed (manager, key);
}
+static void
+on_xrandr_action_call_finished (GObject *source_object,
+ GAsyncResult *res,
+ GsdMediaKeysManager *manager)
+{
+ GError *error = NULL;
+ GVariant *variant;
+ char *action;
+
+ action = g_object_get_data (G_OBJECT (source_object),
+ "gsd-media-keys-manager-xrandr-action");
+
+ variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
+
+ g_object_unref (manager->priv->cancellable);
+ manager->priv->cancellable = NULL;
+
+ if (!res) {
+ g_warning ("Unable to call '%s': %s", action, error->message);
+ g_error_free (error);
+ } else {
+ g_variant_unref (variant);
+ }
+
+ g_free (action);
+}
+
+static void
+do_xrandr_action (GsdMediaKeysManager *manager,
+ const char *action,
+ gint64 timestamp)
+{
+ GsdMediaKeysManagerPrivate *priv = manager->priv;
+
+ if (priv->connection == NULL || priv->xrandr_proxy == NULL) {
+ g_warning ("No existing D-Bus connection trying to handle XRANDR keys");
+ return;
+ }
+
+ if (priv->cancellable != NULL) {
+ g_debug ("xrandr action already in flight");
+ return;
+ }
+
+ priv->cancellable = g_cancellable_new ();
+
+ g_object_set_data (G_OBJECT (priv->xrandr_proxy),
+ "gsd-media-keys-manager-xrandr-action",
+ g_strdup (action));
+
+ g_dbus_proxy_call (priv->xrandr_proxy,
+ action,
+ g_variant_new ("(x)", timestamp),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->cancellable,
+ (GAsyncReadyCallback) on_xrandr_action_call_finished,
+ manager);
+}
+
+static gboolean
+do_video_out_action (GsdMediaKeysManager *manager,
+ gint64 timestamp)
+{
+ do_xrandr_action (manager, "VideoModeSwitch", timestamp);
+ return FALSE;
+}
+
+static gboolean
+do_video_rotate_action (GsdMediaKeysManager *manager,
+ gint64 timestamp)
+{
+ do_xrandr_action (manager, "Rotate", timestamp);
+ return FALSE;
+}
+
static gboolean
do_action (GsdMediaKeysManager *manager,
- int type)
+ int type,
+ gint64 timestamp)
{
char *cmd;
char *path;
@@ -1032,8 +1111,16 @@ do_action (GsdMediaKeysManager *manager,
return do_multimedia_player_action (manager, "Repeat");
case RANDOM_KEY:
return do_multimedia_player_action (manager, "Shuffle");
- default:
+ case VIDEO_OUT_KEY:
+ case VIDEO_OUT2_KEY:
+ do_video_out_action (manager, timestamp);
+ break;
+ case ROTATE_VIDEO_KEY:
+ do_video_rotate_action (manager, timestamp);
+ break;
+ case HANDLED_KEYS:
g_assert_not_reached ();
+ /* Note, no default so compiler catches missing keys */
}
return FALSE;
@@ -1092,7 +1179,7 @@ acme_filter_events (GdkXEvent *xevent,
manager->priv->current_screen = acme_get_screen_from_event (manager, xany);
- if (do_action (manager, keys[i].key_type) == FALSE) {
+ if (do_action (manager, keys[i].key_type, xev->xkey.time) == FALSE) {
return GDK_FILTER_REMOVE;
} else {
return GDK_FILTER_CONTINUE;
@@ -1200,6 +1287,12 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
priv->volume_monitor = NULL;
}
+ if (priv->cancellable != NULL) {
+ g_cancellable_cancel (priv->cancellable);
+ g_object_unref (priv->cancellable);
+ priv->cancellable = NULL;
+ }
+
if (priv->owner_id > 0) {
g_bus_unown_name (priv->owner_id);
priv->owner_id = 0;
@@ -1311,16 +1404,6 @@ gsd_media_keys_manager_constructor (GType type,
}
static void
-gsd_media_keys_manager_dispose (GObject *object)
-{
- GsdMediaKeysManager *media_keys_manager;
-
- media_keys_manager = GSD_MEDIA_KEYS_MANAGER (object);
-
- G_OBJECT_CLASS (gsd_media_keys_manager_parent_class)->dispose (object);
-}
-
-static void
gsd_media_keys_manager_class_init (GsdMediaKeysManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -1328,7 +1411,6 @@ gsd_media_keys_manager_class_init (GsdMediaKeysManagerClass *klass)
object_class->get_property = gsd_media_keys_manager_get_property;
object_class->set_property = gsd_media_keys_manager_set_property;
object_class->constructor = gsd_media_keys_manager_constructor;
- object_class->dispose = gsd_media_keys_manager_dispose;
object_class->finalize = gsd_media_keys_manager_finalize;
g_type_class_add_private (klass, sizeof (GsdMediaKeysManagerPrivate));
@@ -1338,7 +1420,6 @@ static void
gsd_media_keys_manager_init (GsdMediaKeysManager *manager)
{
manager->priv = GSD_MEDIA_KEYS_MANAGER_GET_PRIVATE (manager);
-
}
static void
@@ -1357,6 +1438,20 @@ gsd_media_keys_manager_finalize (GObject *object)
}
static void
+xrandr_ready_cb (GObject *source_object,
+ GAsyncResult *res,
+ GsdMediaKeysManager *manager)
+{
+ GError *error = NULL;
+
+ manager->priv->xrandr_proxy = g_dbus_proxy_new_finish (res, &error);
+ if (manager->priv->xrandr_proxy == NULL) {
+ g_warning ("Failed to get proxy for XRandR operations: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
on_bus_acquired (GDBusConnection *connection,
const gchar *name,
GsdMediaKeysManager *manager)
@@ -1370,8 +1465,19 @@ on_bus_acquired (GDBusConnection *connection,
manager,
NULL,
NULL);
- if (registration_id > 0)
+ if (registration_id > 0) {
manager->priv->connection = connection;
+
+ g_dbus_proxy_new (manager->priv->connection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.gnome.SettingsDaemon",
+ "/org/gnome/SettingsDaemon/XRANDR",
+ "org.gnome.SettingsDaemon.XRANDR_2",
+ NULL,
+ (GAsyncReadyCallback) xrandr_ready_cb,
+ manager);
+ }
}
static void
diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index fec9c16..e5a0404 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -81,12 +81,6 @@ struct GsdXrandrManagerPrivate
{
DBusGConnection *dbus_connection;
- /* Key code of the XF86Display key (Fn-F7 on Thinkpads, Fn-F4 on HP machines, etc.) */
- guint switch_video_mode_keycode;
-
- /* Key code of the XF86RotateWindows key (present on some tablets) */
- guint rotate_windows_keycode;
-
GnomeRRScreen *rw_screen;
gboolean running;
@@ -119,6 +113,8 @@ static void get_allowed_rotations_for_output (GnomeRRConfig *config,
GnomeOutputInfo *output,
int *out_num_rotations,
GnomeRRRotation *out_rotations);
+static void handle_fn_f7 (GsdXrandrManager *mgr, guint32 timestamp);
+static void handle_rotate_windows (GsdXrandrManager *mgr, guint32 timestamp);
G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT)
@@ -613,7 +609,27 @@ gsd_xrandr_manager_2_apply_configuration (GsdXrandrManager *manager,
return result;
}
-/* We include this after the definition of gsd_xrandr_manager_apply_configuration() so the prototype will already exist */
+/* DBus method for org.gnome.SettingsDaemon.XRANDR_2 VideoModeSwitch; see gsd-xrandr-manager.xml for the interface definition */
+static gboolean
+gsd_xrandr_manager_2_video_mode_switch (GsdXrandrManager *manager,
+ guint32 timestamp,
+ GError **error)
+{
+ handle_fn_f7 (manager, timestamp);
+ return TRUE;
+}
+
+/* DBus method for org.gnome.SettingsDaemon.XRANDR_2 Rotate; see gsd-xrandr-manager.xml for the interface definition */
+static gboolean
+gsd_xrandr_manager_2_rotate (GsdXrandrManager *manager,
+ guint32 timestamp,
+ GError **error)
+{
+ handle_rotate_windows (manager, timestamp);
+ return TRUE;
+}
+
+/* We include this after the definition of gsd_xrandr_manager_* D-Bus methods so the prototype will already exist */
#include "gsd-xrandr-manager-glue.h"
static gboolean
@@ -1301,33 +1317,6 @@ out:
gnome_rr_config_free (current);
}
-static GdkFilterReturn
-event_filter (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
-{
- GsdXrandrManager *manager = data;
- XEvent *xev = (XEvent *) xevent;
-
- if (!manager->priv->running)
- return GDK_FILTER_CONTINUE;
-
- /* verify we have a key event */
- if (xev->xany.type != KeyPress && xev->xany.type != KeyRelease)
- return GDK_FILTER_CONTINUE;
-
- if (xev->xany.type == KeyPress) {
- if (xev->xkey.keycode == manager->priv->switch_video_mode_keycode)
- handle_fn_f7 (manager, xev->xkey.time);
- else if (xev->xkey.keycode == manager->priv->rotate_windows_keycode)
- handle_rotate_windows (manager, xev->xkey.time);
-
- return GDK_FILTER_CONTINUE;
- }
-
- return GDK_FILTER_CONTINUE;
-}
-
static void
auto_configure_outputs (GsdXrandrManager *manager, guint32 timestamp)
{
@@ -1741,30 +1730,6 @@ gsd_xrandr_manager_start (GsdXrandrManager *manager,
manager->priv->running = TRUE;
manager->priv->settings = g_settings_new (CONF_DIR);
- if (manager->priv->switch_video_mode_keycode) {
- gdk_error_trap_push ();
-
- XGrabKey (gdk_x11_get_default_xdisplay(),
- manager->priv->switch_video_mode_keycode, AnyModifier,
- gdk_x11_get_default_root_xwindow(),
- True, GrabModeAsync, GrabModeAsync);
-
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
- if (manager->priv->rotate_windows_keycode) {
- gdk_error_trap_push ();
-
- XGrabKey (gdk_x11_get_default_xdisplay(),
- manager->priv->rotate_windows_keycode, AnyModifier,
- gdk_x11_get_default_root_xwindow(),
- True, GrabModeAsync, GrabModeAsync);
-
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
show_timestamps_dialog (manager, "Startup");
if (!apply_stored_configuration_at_startup (manager, GDK_CURRENT_TIME)) /* we don't have a real timestamp at startup anyway */
if (!apply_default_configuration_from_file (manager, GDK_CURRENT_TIME))
@@ -1774,10 +1739,6 @@ gsd_xrandr_manager_start (GsdXrandrManager *manager,
log_msg ("State of screen after initial configuration:\n");
log_screen (manager->priv->rw_screen);
- gdk_window_add_filter (gdk_get_default_root_window(),
- (GdkFilterFunc)event_filter,
- manager);
-
log_close ();
gnome_settings_profile_end (NULL);
@@ -1792,30 +1753,6 @@ gsd_xrandr_manager_stop (GsdXrandrManager *manager)
manager->priv->running = FALSE;
- if (manager->priv->switch_video_mode_keycode) {
- gdk_error_trap_push ();
-
- XUngrabKey (gdk_x11_get_default_xdisplay(),
- manager->priv->switch_video_mode_keycode, AnyModifier,
- gdk_x11_get_default_root_xwindow());
-
- gdk_error_trap_pop ();
- }
-
- if (manager->priv->rotate_windows_keycode) {
- gdk_error_trap_push ();
-
- XUngrabKey (gdk_x11_get_default_xdisplay(),
- manager->priv->rotate_windows_keycode, AnyModifier,
- gdk_x11_get_default_root_xwindow());
-
- gdk_error_trap_pop ();
- }
-
- gdk_window_remove_filter (gdk_get_default_root_window (),
- (GdkFilterFunc) event_filter,
- manager);
-
if (manager->priv->settings != NULL) {
g_object_unref (manager->priv->settings);
manager->priv->settings = NULL;
@@ -1913,26 +1850,11 @@ gsd_xrandr_manager_class_init (GsdXrandrManagerClass *klass)
g_type_class_add_private (klass, sizeof (GsdXrandrManagerPrivate));
}
-static guint
-get_keycode_for_keysym_name (const char *name)
-{
- Display *dpy;
- guint keyval;
-
- dpy = gdk_x11_get_default_xdisplay ();
-
- keyval = gdk_keyval_from_name (name);
- return XKeysymToKeycode (dpy, keyval);
-}
-
static void
gsd_xrandr_manager_init (GsdXrandrManager *manager)
{
manager->priv = GSD_XRANDR_MANAGER_GET_PRIVATE (manager);
- manager->priv->switch_video_mode_keycode = get_keycode_for_keysym_name (VIDEO_KEYSYM);
- manager->priv->rotate_windows_keycode = get_keycode_for_keysym_name (ROTATE_KEYSYM);
-
manager->priv->current_fn_f7_config = -1;
manager->priv->fn_f7_configs = NULL;
}
diff --git a/plugins/xrandr/gsd-xrandr-manager.xml b/plugins/xrandr/gsd-xrandr-manager.xml
index 365a552..1057d75 100644
--- a/plugins/xrandr/gsd-xrandr-manager.xml
+++ b/plugins/xrandr/gsd-xrandr-manager.xml
@@ -19,5 +19,13 @@
the future) for the RANDR calls themselves -->
<arg name="timestamp" type="x" direction="in"/>
</method>
+ <method name="VideoModeSwitch">
+ <!-- Timestamp for the RANDR call itself -->
+ <arg name="timestamp" type="x" direction="in"/>
+ </method>
+ <method name="Rotate">
+ <!-- Timestamp for the RANDR call itself -->
+ <arg name="timestamp" type="x" direction="in"/>
+ </method>
</interface>
</node>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]