summaryrefslogtreecommitdiff
path: root/plugins/media-keys
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/media-keys')
-rw-r--r--plugins/media-keys/Makefile.am7
-rw-r--r--plugins/media-keys/msd-media-keys-manager.c299
-rw-r--r--plugins/media-keys/msd-media-keys-manager.h8
-rw-r--r--plugins/media-keys/msd-media-keys-manager.xml14
4 files changed, 232 insertions, 96 deletions
diff --git a/plugins/media-keys/Makefile.am b/plugins/media-keys/Makefile.am
index 65c3ec2..7111525 100644
--- a/plugins/media-keys/Makefile.am
+++ b/plugins/media-keys/Makefile.am
@@ -6,16 +6,10 @@ NULL =
plugin_LTLIBRARIES = libmedia-keys.la
BUILT_SOURCES = \
- msd-media-keys-manager-glue.h \
msd-marshal.h \
msd-marshal.c \
$(NULL)
-msd-media-keys-manager-glue.h: msd-media-keys-manager.xml Makefile
- $(AM_V_GEN) dbus-binding-tool --prefix=msd_media_keys_manager --mode=glib-server $< > xgen-$(@F) \
- && ( cmp -s xgen-$(@F) $@ || cp xgen-$(@F) $@ ) \
- && rm -f xgen-$(@F)
-
msd-marshal.c: msd-marshal.list
$(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=msd_marshal $< --body --prototypes --internal > $@
@@ -137,7 +131,6 @@ gtkbuilder_DATA = \
$(NULL)
EXTRA_DIST = \
- msd-media-keys-manager.xml \
msd-marshal.list \
$(plugin_in_files) \
$(gtkbuilder_DATA)
diff --git a/plugins/media-keys/msd-media-keys-manager.c b/plugins/media-keys/msd-media-keys-manager.c
index 7422e6f..9d25367 100644
--- a/plugins/media-keys/msd-media-keys-manager.c
+++ b/plugins/media-keys/msd-media-keys-manager.c
@@ -30,9 +30,6 @@
#include <gtk/gtk.h>
#include <gio/gio.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
#ifdef HAVE_LIBMATEMIXER
#include <libmatemixer/matemixer.h>
#endif
@@ -44,7 +41,6 @@
#include "mate-settings-profile.h"
#include "msd-marshal.h"
#include "msd-media-keys-manager.h"
-#include "msd-media-keys-manager-glue.h"
#include "eggaccelerators.h"
#include "acme.h"
@@ -62,9 +58,25 @@
#define SOUND_SCHEMA "org.mate.sound"
#define VOLUME_OVERAMPLIFIABLE_KEY "volume-overamplifiable"
+static const gchar introspection_xml[] =
+"<node name='/org/mate/SettingsDaemon/MediaKeys'>"
+" <interface name='org.mate.SettingsDaemon.MediaKeys'>"
+" <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>";
+
typedef struct {
char *application;
+ char *dbus_name;
guint32 time;
+ guint watch_id;
} MediaPlayer;
struct _MsdMediaKeysManagerPrivate
@@ -93,20 +105,20 @@ struct _MsdMediaKeysManagerPrivate
GList *media_players;
- DBusGConnection *connection;
- guint notify[HANDLED_KEYS];
-};
+ GDBusNodeInfo *introspection_data;
+ GDBusConnection *connection;
+ GCancellable *bus_cancellable;
-enum {
- MEDIA_PLAYER_KEY_PRESSED,
- LAST_SIGNAL
-};
+ guint start_idle_id;
-static guint signals[LAST_SIGNAL] = { 0 };
+ guint owner_id;
+ guint notify[HANDLED_KEYS];
+};
G_DEFINE_TYPE_WITH_PRIVATE (MsdMediaKeysManager, msd_media_keys_manager, G_TYPE_OBJECT)
static gpointer manager_object = NULL;
+static void register_manager (MsdMediaKeysManager *manager);
static void
init_screens (MsdMediaKeysManager *manager)
@@ -135,7 +147,7 @@ acme_error (char * msg)
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
- msg, NULL);
+ "%s", msg);
gtk_dialog_set_default_response (GTK_DIALOG (error_dialog),
GTK_RESPONSE_OK);
gtk_widget_show (error_dialog);
@@ -1047,6 +1059,18 @@ do_display_osd_action (MsdMediaKeysManager *manager)
dialog_show (manager);
}
+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->dbus_name);
+ g_free (player);
+}
+
static gint
find_by_application (gconstpointer a,
gconstpointer b)
@@ -1055,12 +1079,40 @@ find_by_application (gconstpointer a,
}
static gint
+find_by_name (gconstpointer a,
+ gconstpointer b)
+{
+ return strcmp (((MediaPlayer *)a)->dbus_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,
+ MsdMediaKeysManager *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 (dbus_name: %s)", player->application, player->dbus_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
@@ -1068,14 +1120,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
msd_media_keys_manager_grab_media_player_keys (MsdMediaKeysManager *manager,
const char *application,
- guint32 time,
- GError **error)
+ const char *dbus_name,
+ guint32 time)
{
GList *iter;
MediaPlayer *media_player;
+ guint watch_id;
if (time == GDK_CURRENT_TIME) {
time = (guint32)(g_get_monotonic_time () / 1000);
@@ -1087,51 +1140,70 @@ msd_media_keys_manager_grab_media_player_keys (MsdMediaKeysManager *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,
+ dbus_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->dbus_name = g_strdup (dbus_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
msd_media_keys_manager_release_media_player_keys (MsdMediaKeysManager *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 (dbus_name: %s)", application, player->dbus_name);
+ free_media_player (player);
manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter);
}
-
- return TRUE;
}
static gboolean
msd_media_player_key_pressed (MsdMediaKeysManager *manager,
const char *key)
{
+ GError *error = NULL;
const char *application = NULL;
gboolean have_listeners;
@@ -1141,11 +1213,55 @@ msd_media_player_key_pressed (MsdMediaKeysManager *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,
+ MSD_MEDIA_KEYS_DBUS_PATH,
+ MSD_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)
+{
+ MsdMediaKeysManager *manager = (MsdMediaKeysManager *) 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);
+ msd_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);
+ msd_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 =
+{
+ .method_call = handle_method_call,
+};
+
static gboolean
do_multimedia_player_action (MsdMediaKeysManager *manager,
const char *key)
@@ -1474,6 +1590,8 @@ start_media_keys_idle_cb (MsdMediaKeysManager *manager)
mate_settings_profile_end (NULL);
+ manager->priv->start_idle_id = 0;
+
return FALSE;
}
@@ -1510,7 +1628,8 @@ msd_media_keys_manager_start (MsdMediaKeysManager *manager, GError **error)
mate_settings_profile_end ("mate_mixer_context_new");
}
#endif
- g_idle_add ((GSourceFunc) start_media_keys_idle_cb, manager);
+ manager->priv->start_idle_id = g_idle_add ((GSourceFunc) start_media_keys_idle_cb, manager);
+ g_source_set_name_by_id (manager->priv->start_idle_id, "[mate-settings-daemon] start_media_keys_idle_cb");
mate_settings_profile_end (NULL);
@@ -1555,11 +1674,29 @@ msd_media_keys_manager_stop (MsdMediaKeysManager *manager)
priv->volume_monitor = NULL;
}
+ if (priv->start_idle_id != 0) {
+ g_source_remove (priv->start_idle_id);
+ priv->start_idle_id = 0;
+ }
+
+ if (priv->owner_id > 0) {
+ g_bus_unown_name (priv->owner_id);
+ priv->owner_id = 0;
+ }
+
if (priv->connection != NULL) {
- dbus_g_connection_unref (priv->connection);
+ g_object_unref (priv->connection);
priv->connection = NULL;
}
+ if (priv->bus_cancellable != NULL) {
+ g_cancellable_cancel (priv->bus_cancellable);
+ g_object_unref (priv->bus_cancellable);
+ priv->bus_cancellable = NULL;
+ }
+
+ g_clear_pointer (&priv->introspection_data, g_dbus_node_info_unref);
+
need_flush = FALSE;
dpy = gdk_display_get_default ();
gdk_x11_display_error_trap_push (dpy);
@@ -1611,22 +1748,29 @@ msd_media_keys_manager_stop (MsdMediaKeysManager *manager)
}
static void
+msd_media_keys_manager_finalize (GObject *object)
+{
+ MsdMediaKeysManager *manager;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (MSD_IS_MEDIA_KEYS_MANAGER (object));
+
+ manager = MSD_MEDIA_KEYS_MANAGER (object);
+
+ g_return_if_fail (manager->priv != NULL);
+
+ msd_media_keys_manager_stop (manager);
+
+ G_OBJECT_CLASS (msd_media_keys_manager_parent_class)->finalize (object);
+}
+
+
+static void
msd_media_keys_manager_class_init (MsdMediaKeysManagerClass *klass)
{
- signals[MEDIA_PLAYER_KEY_PRESSED] =
- g_signal_new ("media-player-key-pressed",
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (MsdMediaKeysManagerClass, media_player_key_pressed),
- NULL,
- NULL,
- msd_marshal_VOID__STRING_STRING,
- G_TYPE_NONE,
- 2,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- dbus_g_object_type_install_info (MSD_TYPE_MEDIA_KEYS_MANAGER, &dbus_glib_msd_media_keys_manager_object_info);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = msd_media_keys_manager_finalize;
}
static void
@@ -1635,23 +1779,50 @@ msd_media_keys_manager_init (MsdMediaKeysManager *manager)
manager->priv = msd_media_keys_manager_get_instance_private (manager);
}
-static gboolean
-register_manager (MsdMediaKeysManager *manager)
+
+static void
+on_bus_gotten (GObject *source_object,
+ GAsyncResult *res,
+ MsdMediaKeysManager *manager)
{
+ GDBusConnection *connection;
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;
+ connection = g_bus_get_finish (res, &error);
+ if (connection == NULL) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("Could not get session bus: %s", error->message);
+ g_error_free (error);
+ return;
}
+ manager->priv->connection = connection;
+
+ g_dbus_connection_register_object (connection,
+ MSD_MEDIA_KEYS_DBUS_PATH,
+ manager->priv->introspection_data->interfaces[0],
+ &interface_vtable,
+ manager,
+ NULL,
+ NULL);
+
+ manager->priv->owner_id = g_bus_own_name_on_connection (manager->priv->connection,
+ "org.mate.SettingsDaemon",
+ G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
+ NULL, NULL, NULL, NULL);
+}
+
+static void
+register_manager (MsdMediaKeysManager *manager)
+{
- dbus_g_connection_register_g_object (manager->priv->connection, MSD_MEDIA_KEYS_DBUS_PATH, G_OBJECT (manager));
+ manager->priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+ manager->priv->bus_cancellable = g_cancellable_new ();
+ g_assert (manager->priv->introspection_data != NULL);
- return TRUE;
+ g_bus_get (G_BUS_TYPE_SESSION,
+ manager->priv->bus_cancellable,
+ (GAsyncReadyCallback) on_bus_gotten,
+ manager);
}
MsdMediaKeysManager *
@@ -1660,16 +1831,10 @@ msd_media_keys_manager_new (void)
if (manager_object != NULL) {
g_object_ref (manager_object);
} else {
- gboolean res;
-
manager_object = g_object_new (MSD_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 MSD_MEDIA_KEYS_MANAGER (manager_object);
diff --git a/plugins/media-keys/msd-media-keys-manager.h b/plugins/media-keys/msd-media-keys-manager.h
index 35d7233..add29d2 100644
--- a/plugins/media-keys/msd-media-keys-manager.h
+++ b/plugins/media-keys/msd-media-keys-manager.h
@@ -60,14 +60,6 @@ gboolean msd_media_keys_manager_start (MsdMedia
GError **error);
void msd_media_keys_manager_stop (MsdMediaKeysManager *manager);
-gboolean msd_media_keys_manager_grab_media_player_keys (MsdMediaKeysManager *manager,
- const char *application,
- guint32 time,
- GError **error);
-gboolean msd_media_keys_manager_release_media_player_keys (MsdMediaKeysManager *manager,
- const char *application,
- GError **error);
-
G_END_DECLS
#endif /* __MSD_MEDIA_KEYS_MANAGER_H */
diff --git a/plugins/media-keys/msd-media-keys-manager.xml b/plugins/media-keys/msd-media-keys-manager.xml
deleted file mode 100644
index db0552e..0000000
--- a/plugins/media-keys/msd-media-keys-manager.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.mate.SettingsDaemon.MediaKeys">
- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="msd_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>