[gnome-settings-daemon] media-keys: Port to GDBus



commit c94a4d158610f4b42304933ee9eb2d4001e85801
Author: Bastien Nocera <hadess hadess net>
Date:   Fri Nov 5 17:41:54 2010 +0000

    media-keys: Port to GDBus
    
    And track clients, so that applications don't need to call
    ReleaseMediaPlayerKeys when exiting. This also fixes problems
    when application exit ungracefully.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=634104

 plugins/media-keys/Makefile.am                |    7 -
 plugins/media-keys/gsd-media-keys-manager.c   |  275 ++++++++++++++++++-------
 plugins/media-keys/gsd-media-keys-manager.h   |    7 -
 plugins/media-keys/gsd-media-keys-manager.xml |   14 --
 4 files changed, 196 insertions(+), 107 deletions(-)
---
diff --git a/plugins/media-keys/Makefile.am b/plugins/media-keys/Makefile.am
index 917ae06..ab1f683 100644
--- a/plugins/media-keys/Makefile.am
+++ b/plugins/media-keys/Makefile.am
@@ -12,7 +12,6 @@ plugin_LTLIBRARIES += libmedia-keys.la
 endif
 
 BUILT_SOURCES = 			\
-	gsd-media-keys-manager-glue.h	\
 	gsd-marshal.h			\
 	gsd-marshal.c			\
 	$(NULL)
@@ -60,11 +59,6 @@ uninstall-local:
 	rm -f $(DESTDIR)$(icondir)/32x32/$(context)/touchpad-disabled.png
 	rm -f $(DESTDIR)$(icondir)/scalable/$(context)/touchpad-disabled.svg
 
-gsd-media-keys-manager-glue.h: gsd-media-keys-manager.xml Makefile
-	$(AM_V_GEN) dbus-binding-tool --prefix=gsd_media_keys_manager --mode=glib-server $< > xgen-$(@F) \
-	&& ( cmp -s xgen-$(@F) $@ || cp xgen-$(@F) $@ ) \
-	&& rm -f xgen-$(@F)
-
 gsd-marshal.c: gsd-marshal.list
 	$(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=gsd_marshal $< --header --body --internal > $@
 
@@ -188,7 +182,6 @@ gtkbuilder_DATA =	\
 DIST_SUBDIRS = cut-n-paste
 
 EXTRA_DIST = 				\
-	gsd-media-keys-manager.xml	\
 	gsd-marshal.list		\
 	$(plugin_in_files)		\
 	$(gtkbuilder_DATA)		\
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index 59d734b..ec6eba5 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -38,13 +38,9 @@
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
 #include "gnome-settings-profile.h"
 #include "gsd-marshal.h"
 #include "gsd-media-keys-manager.h"
-#include "gsd-media-keys-manager-glue.h"
 
 #include "eggaccelerators.h"
 #include "acme.h"
@@ -61,6 +57,21 @@
 #define GSD_MEDIA_KEYS_DBUS_PATH GSD_DBUS_PATH "/MediaKeys"
 #define GSD_MEDIA_KEYS_DBUS_NAME GSD_DBUS_NAME ".MediaKeys"
 
+static const gchar introspection_xml[] =
+"<node>"
+"  <interface name='org.gnome.SettingsDaemon.MediaKeys'>"
+"    <annotation name='org.freedesktop.DBus.GLib.CSymbol' value='gsd_media_keys_manager'/>"
+"    <method name='GrabMediaPlayerKeys'>"
+"      <arg name='application' direction='in' type='s'/>"
+"      <arg name='time' direction='in' type='u'/>"
+"    </method>"
+"    <method name='ReleaseMediaPlayerKeys'>"
+"      <arg name='application' direction='in' type='s'/>"
+"    </method>"
+"    <signal name='MediaPlayerKeyPressed'/>"
+"  </interface>"
+"</node>";
+
 #define TOUCHPAD_ENABLED_KEY "touchpad-enabled"
 
 #define VOLUME_STEP 6           /* percents for one volume button press */
@@ -70,7 +81,9 @@
 
 typedef struct {
         char   *application;
+        char   *name;
         guint32 time;
+        guint   watch_id;
 } MediaPlayer;
 
 struct GsdMediaKeysManagerPrivate
@@ -90,16 +103,11 @@ struct GsdMediaKeysManagerPrivate
 
         GList           *media_players;
 
-        DBusGConnection *connection;
-};
-
-enum {
-        MEDIA_PLAYER_KEY_PRESSED,
-        LAST_SIGNAL
+        guint            owner_id;
+        GDBusNodeInfo   *introspection_data;
+        GDBusConnection *connection;
 };
 
-static guint signals[LAST_SIGNAL] = { 0 };
-
 static void     gsd_media_keys_manager_class_init  (GsdMediaKeysManagerClass *klass);
 static void     gsd_media_keys_manager_init        (GsdMediaKeysManager      *media_keys_manager);
 static void     gsd_media_keys_manager_finalize    (GObject                  *object);
@@ -295,8 +303,8 @@ update_kbd_cb (GSettings           *settings,
                         g_free (keys[i].key);
                         keys[i].key = NULL;
 
-			/* We can't have a change in a hard-coded key */
-			g_assert (keys[i].settings_key != NULL);
+                        /* We can't have a change in a hard-coded key */
+                        g_assert (keys[i].settings_key != NULL);
 
                         tmp = g_settings_get_string (manager->priv->settings, keys[i].settings_key);
                         if (is_valid_shortcut (tmp) == FALSE) {
@@ -341,11 +349,11 @@ init_kbd (GsdMediaKeysManager *manager)
                 char *tmp;
                 Key  *key;
 
-		if (keys[i].settings_key != NULL) {
-			tmp = g_settings_get_string (manager->priv->settings, keys[i].settings_key);
-		} else {
-			tmp = g_strdup (keys[i].hard_coded);
-		}
+                if (keys[i].settings_key != NULL) {
+                        tmp = g_settings_get_string (manager->priv->settings, keys[i].settings_key);
+                } else {
+                        tmp = g_strdup (keys[i].hard_coded);
+                }
 
                 if (!is_valid_shortcut (tmp)) {
                         g_debug ("Not a valid shortcut: '%s'", tmp);
@@ -723,6 +731,18 @@ on_control_default_sink_changed (GvcMixerControl     *control,
 
 #endif /* HAVE_PULSE */
 
+static void
+free_media_player (MediaPlayer *player)
+{
+        if (player->watch_id > 0) {
+                g_bus_unwatch_name (player->watch_id);
+                player->watch_id = 0;
+        }
+        g_free (player->application);
+        g_free (player->name);
+        g_free (player);
+}
+
 static gint
 find_by_application (gconstpointer a,
                      gconstpointer b)
@@ -731,12 +751,40 @@ find_by_application (gconstpointer a,
 }
 
 static gint
+find_by_name (gconstpointer a,
+              gconstpointer b)
+{
+        return strcmp (((MediaPlayer *)a)->name, b);
+}
+
+static gint
 find_by_time (gconstpointer a,
               gconstpointer b)
 {
         return ((MediaPlayer *)a)->time < ((MediaPlayer *)b)->time;
 }
 
+static void
+name_vanished_handler (GDBusConnection     *connection,
+                       const gchar         *name,
+                       GsdMediaKeysManager *manager)
+{
+        GList *iter;
+
+        iter = g_list_find_custom (manager->priv->media_players,
+                                   name,
+                                   find_by_name);
+
+        if (iter != NULL) {
+                MediaPlayer *player;
+
+                player = iter->data;
+                g_debug ("Deregistering vanished %s (name: %s)", player->application, player->name);
+                free_media_player (player);
+                manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter);
+        }
+}
+
 /*
  * Register a new media player. Most applications will want to call
  * this with time = GDK_CURRENT_TIME. This way, the last registered
@@ -744,14 +792,15 @@ find_by_time (gconstpointer a,
  * may want to register with a lower priority (usually 1), to grab
  * events only nobody is interested.
  */
-gboolean
+static void
 gsd_media_keys_manager_grab_media_player_keys (GsdMediaKeysManager *manager,
                                                const char          *application,
-                                               guint32              time,
-                                               GError             **error)
+                                               const char          *name,
+                                               guint32              time)
 {
         GList       *iter;
         MediaPlayer *media_player;
+        guint        watch_id;
 
         if (time == GDK_CURRENT_TIME) {
                 GTimeVal tv;
@@ -766,45 +815,63 @@ gsd_media_keys_manager_grab_media_player_keys (GsdMediaKeysManager *manager,
 
         if (iter != NULL) {
                 if (((MediaPlayer *)iter->data)->time < time) {
-                        g_free (((MediaPlayer *)iter->data)->application);
-                        g_free (iter->data);
+                        MediaPlayer *player = iter->data;
+                        free_media_player (player);
                         manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter);
                 } else {
-                        return TRUE;
+                        return;
                 }
         }
 
+        watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
+                                     name,
+                                     G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                     NULL,
+                                     (GBusNameVanishedCallback) name_vanished_handler,
+                                     manager,
+                                     NULL);
+
         g_debug ("Registering %s at %u", application, time);
         media_player = g_new0 (MediaPlayer, 1);
         media_player->application = g_strdup (application);
+        media_player->name = g_strdup (name);
         media_player->time = time;
+        media_player->watch_id = watch_id;
 
         manager->priv->media_players = g_list_insert_sorted (manager->priv->media_players,
                                                              media_player,
                                                              find_by_time);
-
-        return TRUE;
 }
 
-gboolean
+static void
 gsd_media_keys_manager_release_media_player_keys (GsdMediaKeysManager *manager,
                                                   const char          *application,
-                                                  GError             **error)
+                                                  const char          *name)
 {
-        GList *iter;
+        GList *iter = NULL;
 
-        iter = g_list_find_custom (manager->priv->media_players,
-                                   application,
-                                   find_by_application);
+        g_return_if_fail (application != NULL || name != NULL);
+
+        if (application != NULL) {
+                iter = g_list_find_custom (manager->priv->media_players,
+                                           application,
+                                           find_by_application);
+        }
+
+        if (iter == NULL && name != NULL) {
+                iter = g_list_find_custom (manager->priv->media_players,
+                                           name,
+                                           find_by_name);
+        }
 
         if (iter != NULL) {
-                g_debug ("Deregistering %s", application);
-                g_free (((MediaPlayer *)iter->data)->application);
-                g_free (iter->data);
+                MediaPlayer *player;
+
+                player = iter->data;
+                g_debug ("Deregistering %s (name: %s)", application, player->name);
+                free_media_player (player);
                 manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter);
         }
-
-        return TRUE;
 }
 
 static gboolean
@@ -813,6 +880,9 @@ gsd_media_player_key_pressed (GsdMediaKeysManager *manager,
 {
         const char *application = NULL;
         gboolean    have_listeners;
+        GError     *error = NULL;
+
+        g_debug ("Media key '%s' pressed", key);
 
         have_listeners = (manager->priv->media_players != NULL);
 
@@ -820,11 +890,57 @@ gsd_media_player_key_pressed (GsdMediaKeysManager *manager,
                 application = ((MediaPlayer *)manager->priv->media_players->data)->application;
         }
 
-        g_signal_emit (manager, signals[MEDIA_PLAYER_KEY_PRESSED], 0, application, key);
+        if (g_dbus_connection_emit_signal (manager->priv->connection,
+                                           NULL,
+                                           GSD_MEDIA_KEYS_DBUS_PATH,
+                                           GSD_MEDIA_KEYS_DBUS_NAME,
+                                           "MediaPlayerKeyPressed",
+                                           g_variant_new ("(ss)", application, key),
+                                           &error) == FALSE) {
+                g_debug ("Error emitting signal: %s", error->message);
+                g_error_free (error);
+        }
 
         return !have_listeners;
 }
 
+static void
+handle_method_call (GDBusConnection       *connection,
+                    const gchar           *sender,
+                    const gchar           *object_path,
+                    const gchar           *interface_name,
+                    const gchar           *method_name,
+                    GVariant              *parameters,
+                    GDBusMethodInvocation *invocation,
+                    gpointer               user_data)
+{
+        GsdMediaKeysManager *manager = (GsdMediaKeysManager *) user_data;
+
+        g_debug ("Calling method '%s' for media-keys", method_name);
+
+        if (g_strcmp0 (method_name, "ReleaseMediaPlayerKeys") == 0) {
+                const char *app_name;
+
+                g_variant_get (parameters, "(&s)", &app_name);
+                gsd_media_keys_manager_release_media_player_keys (manager, app_name, sender);
+                g_dbus_method_invocation_return_value (invocation, NULL);
+        } else if (g_strcmp0 (method_name, "GrabMediaPlayerKeys") == 0) {
+                const char *app_name;
+                guint32 time;
+
+                g_variant_get (parameters, "(&su)", &app_name, &time);
+                gsd_media_keys_manager_grab_media_player_keys (manager, app_name, sender, time);
+                g_dbus_method_invocation_return_value (invocation, NULL);
+        }
+}
+
+static const GDBusInterfaceVTable interface_vtable =
+{
+        handle_method_call,
+        NULL, /* Get Property */
+        NULL, /* Set Property */
+};
+
 static gboolean
 do_multimedia_player_action (GsdMediaKeysManager *manager,
                              const char          *key)
@@ -1081,11 +1197,18 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
                 priv->volume_monitor = NULL;
         }
 
-        if (priv->connection != NULL) {
-                dbus_g_connection_unref (priv->connection);
-                priv->connection = NULL;
+        if (priv->owner_id > 0) {
+                g_bus_unown_name (priv->owner_id);
+                priv->owner_id = 0;
         }
 
+        if (priv->introspection_data) {
+                g_dbus_node_info_unref (priv->introspection_data);
+                priv->introspection_data = NULL;
+        }
+
+        priv->connection = NULL;
+
         need_flush = FALSE;
         gdk_error_trap_push ();
 
@@ -1205,21 +1328,6 @@ gsd_media_keys_manager_class_init (GsdMediaKeysManagerClass *klass)
         object_class->dispose = gsd_media_keys_manager_dispose;
         object_class->finalize = gsd_media_keys_manager_finalize;
 
-       signals[MEDIA_PLAYER_KEY_PRESSED] =
-               g_signal_new ("media-player-key-pressed",
-                             G_OBJECT_CLASS_TYPE (klass),
-                             G_SIGNAL_RUN_LAST,
-                             G_STRUCT_OFFSET (GsdMediaKeysManagerClass, media_player_key_pressed),
-                             NULL,
-                             NULL,
-                             gsd_marshal_VOID__STRING_STRING,
-                             G_TYPE_NONE,
-                             2,
-                             G_TYPE_STRING,
-                             G_TYPE_STRING);
-
-        dbus_g_object_type_install_info (GSD_TYPE_MEDIA_KEYS_MANAGER, &dbus_glib_gsd_media_keys_manager_object_info);
-
         g_type_class_add_private (klass, sizeof (GsdMediaKeysManagerPrivate));
 }
 
@@ -1245,23 +1353,38 @@ gsd_media_keys_manager_finalize (GObject *object)
         G_OBJECT_CLASS (gsd_media_keys_manager_parent_class)->finalize (object);
 }
 
-static gboolean
-register_manager (GsdMediaKeysManager *manager)
+static void
+on_bus_acquired (GDBusConnection     *connection,
+                 const gchar         *name,
+                 GsdMediaKeysManager *manager)
 {
-        GError *error = NULL;
-
-        manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-        if (manager->priv->connection == NULL) {
-                if (error != NULL) {
-                        g_error ("Error getting session bus: %s", error->message);
-                        g_error_free (error);
-                }
-                return FALSE;
-        }
-
-        dbus_g_connection_register_g_object (manager->priv->connection, GSD_MEDIA_KEYS_DBUS_PATH, G_OBJECT (manager));
+        guint registration_id;
+
+        registration_id = g_dbus_connection_register_object (connection,
+                                                             GSD_MEDIA_KEYS_DBUS_PATH,
+                                                             manager->priv->introspection_data->interfaces[0],
+                                                             &interface_vtable,
+                                                             manager,
+                                                             NULL,
+                                                             NULL);
+        if (registration_id > 0)
+                manager->priv->connection = connection;
+}
 
-        return TRUE;
+static void
+register_manager (GsdMediaKeysManager *manager)
+{
+        manager->priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+        g_assert (manager->priv->introspection_data != NULL);
+
+        manager->priv->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+                                                  GSD_DBUS_NAME,
+                                                  G_BUS_NAME_OWNER_FLAGS_NONE,
+                                                  (GBusAcquiredCallback) on_bus_acquired,
+                                                  NULL,
+                                                  NULL,
+                                                  manager,
+                                                  NULL);
 }
 
 GsdMediaKeysManager *
@@ -1270,16 +1393,10 @@ gsd_media_keys_manager_new (void)
         if (manager_object != NULL) {
                 g_object_ref (manager_object);
         } else {
-                gboolean res;
-
                 manager_object = g_object_new (GSD_TYPE_MEDIA_KEYS_MANAGER, NULL);
                 g_object_add_weak_pointer (manager_object,
                                            (gpointer *) &manager_object);
-                res = register_manager (manager_object);
-                if (! res) {
-                        g_object_unref (manager_object);
-                        return NULL;
-                }
+                register_manager (manager_object);
         }
 
         return GSD_MEDIA_KEYS_MANAGER (manager_object);
diff --git a/plugins/media-keys/gsd-media-keys-manager.h b/plugins/media-keys/gsd-media-keys-manager.h
index f6449d2..f7b0187 100644
--- a/plugins/media-keys/gsd-media-keys-manager.h
+++ b/plugins/media-keys/gsd-media-keys-manager.h
@@ -55,13 +55,6 @@ gboolean              gsd_media_keys_manager_start                     (GsdMedia
                                                                         GError             **error);
 void                  gsd_media_keys_manager_stop                      (GsdMediaKeysManager *manager);
 
-gboolean              gsd_media_keys_manager_grab_media_player_keys    (GsdMediaKeysManager *manager,
-                                                                        const char          *application,
-                                                                        guint32              time,
-                                                                        GError             **error);
-gboolean              gsd_media_keys_manager_release_media_player_keys (GsdMediaKeysManager *manager,
-                                                                        const char          *application,
-                                                                        GError             **error);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]