[gnome-settings-daemon/rhel-6.9: 15/25] Handle video out keys in media-keys



commit bb2214f2995d08dc3544ce9ea96f6e4a7aa74abf
Author: Bastien Nocera <hadess hadess net>
Date:   Sat Jul 24 02:50:15 2010 -0400

    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.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=623223

 plugins/media-keys/acme.h                   |    9 ++
 plugins/media-keys/gsd-media-keys-manager.c |  133 +++++++++++++++++++++++---
 plugins/xrandr/gsd-xrandr-manager.c         |   81 ++++------------
 plugins/xrandr/gsd-xrandr-manager.xml       |    8 ++
 4 files changed, 155 insertions(+), 76 deletions(-)
---
diff --git a/plugins/media-keys/acme.h b/plugins/media-keys/acme.h
index 60f9beb..20ae41d 100644
--- a/plugins/media-keys/acme.h
+++ b/plugins/media-keys/acme.h
@@ -46,12 +46,16 @@ enum {
         STOP_KEY,
         PREVIOUS_KEY,
         NEXT_KEY,
+        VIDEO_OUT_KEY,
+        VIDEO_OUT2_KEY,
+        ROTATE_VIDEO_KEY,
         HANDLED_KEYS
 };
 
 static struct {
         int key_type;
         const char *gconf_key;
+        const char *hard_coded;
         Key *key;
 } keys[HANDLED_KEYS] = {
         { MUTE_KEY, GCONF_BINDING_DIR "/volume_mute",NULL },
@@ -73,6 +77,11 @@ static struct {
         { STOP_KEY, GCONF_BINDING_DIR "/stop", NULL },
         { PREVIOUS_KEY, GCONF_BINDING_DIR "/previous", NULL },
         { NEXT_KEY, GCONF_BINDING_DIR "/next", 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 72a0b4c..20f029f 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -100,6 +100,8 @@ struct GsdMediaKeysManagerPrivate
 
         DBusGConnection *connection;
         guint            notify[HANDLED_KEYS];
+
+       DBusGProxyCall  *pending_call;
 };
 
 enum {
@@ -317,8 +319,12 @@ update_kbd_cb (GConfClient         *client,
                         g_free (keys[i].key);
                         keys[i].key = NULL;
 
-                        tmp = gconf_client_get_string (manager->priv->conf_client,
-                                                       keys[i].gconf_key, NULL);
+                       if (keys[i].gconf_key != NULL) {
+                               tmp = gconf_client_get_string (manager->priv->conf_client,
+                                                              keys[i].gconf_key, NULL);
+                       } else {
+                               tmp = g_strdup (keys[i].hard_coded);
+                       }
 
                         if (is_valid_shortcut (tmp) == FALSE) {
                                 g_free (tmp);
@@ -362,17 +368,21 @@ init_kbd (GsdMediaKeysManager *manager)
                 char *tmp;
                 Key  *key;
 
-                manager->priv->notify[i] =
-                        gconf_client_notify_add (manager->priv->conf_client,
-                                                 keys[i].gconf_key,
-                                                 (GConfClientNotifyFunc) update_kbd_cb,
-                                                 manager,
-                                                 NULL,
-                                                 NULL);
-
-                tmp = gconf_client_get_string (manager->priv->conf_client,
-                                               keys[i].gconf_key,
-                                               NULL);
+               if (keys[i].gconf_key != NULL) {
+                       manager->priv->notify[i] =
+                               gconf_client_notify_add (manager->priv->conf_client,
+                                                        keys[i].gconf_key,
+                                                        (GConfClientNotifyFunc) update_kbd_cb,
+                                                        manager,
+                                                        NULL,
+                                                        NULL);
+
+                       tmp = gconf_client_get_string (manager->priv->conf_client,
+                                                      keys[i].gconf_key,
+                                                      NULL);
+               } else {
+                       tmp = g_strdup (keys[i].hard_coded);
+               }
 
                 if (!is_valid_shortcut (tmp)) {
                         g_debug ("Not a valid shortcut: '%s'", tmp);
@@ -853,9 +863,87 @@ do_multimedia_player_action (GsdMediaKeysManager *manager,
         return gsd_media_player_key_pressed (manager, key);
 }
 
+static void
+on_xrandr_action_call_finished (DBusGProxy       *proxy,
+                                DBusGProxyCall   *call_id,
+                                void             *user_data)
+{
+        GsdMediaKeysManager *manager = GSD_MEDIA_KEYS_MANAGER (user_data);
+        GError *error = NULL;
+        gboolean res;
+        char *action;
+
+        action = g_object_get_data (G_OBJECT (proxy), "gsd-media-keys-manager-xrandr-action");
+
+        res = dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID);
+        manager->priv->pending_call = NULL;
+
+        if (!res) {
+                g_warning ("Unable to call '%s': %s", action, error->message);
+                g_error_free (error);
+        }
+
+        g_free (action);
+        g_object_unref (proxy);
+}
+
+static void
+do_xrandr_action (GsdMediaKeysManager *manager,
+                  const char          *action,
+                  gint64               timestamp)
+{
+        GsdMediaKeysManagerPrivate *priv = manager->priv;
+        DBusGProxy *proxy;
+
+        if (priv->connection == NULL) {
+                g_warning ("No existing D-Bus connection trying to handle XRANDR keys");
+                return;
+        }
+
+        if (priv->pending_call != NULL) {
+                g_debug ("xrandr action already in flight");
+                return;
+        }
+
+        proxy = dbus_g_proxy_new_for_name (priv->connection,
+                                           "org.gnome.SettingsDaemon",
+                                           "/org/gnome/SettingsDaemon/XRANDR",
+                                           "org.gnome.SettingsDaemon.XRANDR_2");
+        if (proxy == NULL) {
+                g_debug ("Failed to get D-Bus proxy for XRANDR keyboard shortcut");
+                return;
+        }
+
+        priv->pending_call = dbus_g_proxy_begin_call (proxy,
+                                                      action,
+                                                      on_xrandr_action_call_finished,
+                                                      manager,
+                                                      NULL,
+                                                      G_TYPE_INT64, timestamp,
+                                                      G_TYPE_INVALID);
+        g_object_set_data (G_OBJECT (proxy), "gsd-media-keys-manager-xrandr-action", g_strdup (action));
+}
+
+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;
@@ -934,8 +1022,16 @@ do_action (GsdMediaKeysManager *manager,
         case NEXT_KEY:
                 return do_multimedia_player_action (manager, "Next");
                 break;
-        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;
@@ -994,7 +1090,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;
@@ -1220,6 +1316,11 @@ gsd_media_keys_manager_dispose (GObject *object)
 
         media_keys_manager = GSD_MEDIA_KEYS_MANAGER (object);
 
+        if (media_keys_manager->priv->pending_call != NULL) {
+                g_object_unref (media_keys_manager->priv->pending_call);
+                media_keys_manager->priv->pending_call = NULL;
+        }
+
         G_OBJECT_CLASS (gsd_media_keys_manager_parent_class)->dispose (object);
 }
 
diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
index b432aba..e3028cd 100644
--- a/plugins/xrandr/gsd-xrandr-manager.c
+++ b/plugins/xrandr/gsd-xrandr-manager.c
@@ -87,8 +87,6 @@ struct GsdXrandrManagerPrivate
 {
         DBusGConnection *dbus_connection;
 
-        /* Key code of the fn-F7 video key (XF86Display) */
-        guint keycode;
         GnomeRRScreen *rw_screen;
         gboolean running;
 
@@ -116,6 +114,7 @@ static void error_message (GsdXrandrManager *mgr, const char *primary_text, GErr
 static void status_icon_popup_menu (GsdXrandrManager *manager, guint button, guint32 timestamp);
 static void run_display_capplet (GtkWidget *widget);
 
+static void handle_fn_f7 (GsdXrandrManager *mgr, guint32 timestamp);
 G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT)
 
 static gpointer manager_object = NULL;
@@ -439,6 +438,26 @@ gsd_xrandr_manager_2_apply_configuration (GsdXrandrManager *manager,
         return result;
 }
 
+/* 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_apply_configuration() so the prototype will 
already exist */
 #include "gsd-xrandr-manager-glue.h"
 
@@ -981,30 +1000,6 @@ handle_fn_f7 (GsdXrandrManager *mgr, guint32 timestamp)
         g_debug ("done handling fn-f7");
 }
 
-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 && xev->xkey.keycode == manager->priv->keycode) {
-                handle_fn_f7 (manager, xev->xkey.time);
-
-                return GDK_FILTER_CONTINUE;
-        }
-
-        return GDK_FILTER_CONTINUE;
-}
-
 static void
 refresh_tray_icon_menu_if_active (GsdXrandrManager *manager, guint32 timestamp)
 {
@@ -1912,25 +1907,9 @@ gsd_xrandr_manager_start (GsdXrandrManager *manager,
                         (GConfClientNotifyFunc)on_config_changed,
                         manager, NULL, NULL);
 
-        if (manager->priv->keycode) {
-                gdk_error_trap_push ();
-
-                XGrabKey (gdk_x11_get_default_xdisplay(),
-                          manager->priv->keycode, AnyModifier,
-                          gdk_x11_get_default_root_xwindow(),
-                          True, GrabModeAsync, GrabModeAsync);
-
-                gdk_flush ();
-                gdk_error_trap_pop ();
-        }
-
         show_timestamps_dialog (manager, "Startup");
         apply_stored_configuration_at_startup (manager, GDK_CURRENT_TIME); /* we don't have a real timestamp 
at startup anyway */
 
-        gdk_window_add_filter (gdk_get_default_root_window(),
-                               (GdkFilterFunc)event_filter,
-                               manager);
-
         start_or_stop_icon (manager);
 
         gnome_settings_profile_end (NULL);
@@ -1945,18 +1924,6 @@ gsd_xrandr_manager_stop (GsdXrandrManager *manager)
 
         manager->priv->running = FALSE;
 
-        gdk_error_trap_push ();
-
-        XUngrabKey (gdk_x11_get_default_xdisplay(),
-                    manager->priv->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->notify_id != 0) {
                 gconf_client_remove_dir (manager->priv->client,
                                          CONF_DIR, NULL);
@@ -2063,14 +2030,8 @@ gsd_xrandr_manager_class_init (GsdXrandrManagerClass *klass)
 static void
 gsd_xrandr_manager_init (GsdXrandrManager *manager)
 {
-        Display *dpy = gdk_x11_get_default_xdisplay ();
-        guint keyval = gdk_keyval_from_name (VIDEO_KEYSYM);
-        guint keycode = XKeysymToKeycode (dpy, keyval);
-
         manager->priv = GSD_XRANDR_MANAGER_GET_PRIVATE (manager);
 
-        manager->priv->keycode = keycode;
-
         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]