summaryrefslogtreecommitdiff
path: root/plugins/mpris
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mpris')
-rw-r--r--plugins/mpris/Makefile.am40
-rw-r--r--plugins/mpris/mpris.mate-settings-plugin.in8
-rw-r--r--plugins/mpris/msd-mpris-manager.c472
-rw-r--r--plugins/mpris/msd-mpris-manager.h63
-rw-r--r--plugins/mpris/msd-mpris-plugin.c111
-rw-r--r--plugins/mpris/msd-mpris-plugin.h65
6 files changed, 759 insertions, 0 deletions
diff --git a/plugins/mpris/Makefile.am b/plugins/mpris/Makefile.am
new file mode 100644
index 0000000..a3d4d4b
--- /dev/null
+++ b/plugins/mpris/Makefile.am
@@ -0,0 +1,40 @@
+plugin_LTLIBRARIES = \
+ libmpris.la
+
+libmpris_la_SOURCES = \
+ msd-mpris-manager.c \
+ msd-mpris-manager.h \
+ msd-mpris-plugin.c \
+ msd-mpris-plugin.h
+
+libmpris_la_CPPFLAGS = \
+ -I$(top_srcdir)/mate-settings-daemon \
+ -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
+ $(AM_CPPFLAGS)
+
+libmpris_la_CFLAGS = \
+ $(SETTINGS_PLUGIN_CFLAGS) \
+ $(AM_CFLAGS)
+
+libmpris_la_LDFLAGS = \
+ $(MSD_PLUGIN_LDFLAGS)
+
+libmpris_la_LIBADD = \
+ $(SETTINGS_PLUGIN_LIBS)
+
+plugin_in_files = \
+ mpris.mate-settings-plugin.in
+
+plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin)
+
+EXTRA_DIST = \
+ $(plugin_in_files)
+
+CLEANFILES = \
+ $(plugin_DATA)
+
+DISTCLEANFILES = \
+ $(plugin_DATA)
+
+@MSD_INTLTOOL_PLUGIN_RULE@
+
diff --git a/plugins/mpris/mpris.mate-settings-plugin.in b/plugins/mpris/mpris.mate-settings-plugin.in
new file mode 100644
index 0000000..c7edcf9
--- /dev/null
+++ b/plugins/mpris/mpris.mate-settings-plugin.in
@@ -0,0 +1,8 @@
+[MATE Settings Plugin]
+Module=mpris
+IAge=0
+_Name=Mpris
+_Description=Mpris plugin
+Authors=Stefano Karapetsas
+Copyright=Copyright © 2013 Stefano Karapetsas
+Website=
diff --git a/plugins/mpris/msd-mpris-manager.c b/plugins/mpris/msd-mpris-manager.c
new file mode 100644
index 0000000..00cd8dc
--- /dev/null
+++ b/plugins/mpris/msd-mpris-manager.c
@@ -0,0 +1,472 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Stefano Karapetsas <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ * Stefano Karapetsas <[email protected]>
+ * Steve Zesch <[email protected]>
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include "mate-settings-profile.h"
+#include "msd-mpris-manager.h"
+
+#define MPRIS_OBJECT_PATH "/org/mpris/MediaPlayer2"
+#define MPRIS_INTERFACE "org.mpris.MediaPlayer2.Player"
+#define MPRIS_PREFIX "org.mpris.MediaPlayer2."
+
+/* Number of media players supported.
+ * Correlates to the number of elements in BUS_NAMES */
+static const gint NUM_BUS_NAMES = 16;
+
+/* Names to we want to watch */
+static const gchar *BUS_NAMES[] = {"org.mpris.MediaPlayer2.audacious",
+ "org.mpris.MediaPlayer2.clementine",
+ "org.mpris.MediaPlayer2.vlc",
+ "org.mpris.MediaPlayer2.mpd",
+ "org.mpris.MediaPlayer2.exaile",
+ "org.mpris.MediaPlayer2.banshee",
+ "org.mpris.MediaPlayer2.rhythmbox",
+ "org.mpris.MediaPlayer2.pragha",
+ "org.mpris.MediaPlayer2.quodlibet",
+ "org.mpris.MediaPlayer2.guayadeque",
+ "org.mpris.MediaPlayer2.amarok",
+ "org.mpris.MediaPlayer2.googlemusicframe",
+ "org.mpris.MediaPlayer2.xbmc",
+ "org.mpris.MediaPlayer2.xnoise",
+ "org.mpris.MediaPlayer2.gmusicbrowser",
+ "org.mpris.MediaPlayer2.spotify"};
+
+#define MSD_MPRIS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MSD_TYPE_MPRIS_MANAGER, MsdMprisManagerPrivate))
+
+struct MsdMprisManagerPrivate
+{
+ GQueue *media_player_queue;
+ GDBusProxy *media_keys_proxy;
+ guint watch_id;
+};
+
+enum {
+ PROP_0,
+};
+
+static void msd_mpris_manager_class_init (MsdMprisManagerClass *klass);
+static void msd_mpris_manager_init (MsdMprisManager *mpris_manager);
+static void msd_mpris_manager_finalize (GObject *object);
+
+G_DEFINE_TYPE (MsdMprisManager, msd_mpris_manager, G_TYPE_OBJECT)
+
+static gpointer manager_object = NULL;
+
+/* Returns the name of the media player.
+ * User must free. */
+static gchar*
+get_player_name(const gchar *name)
+{
+ gchar **tokens;
+ gchar *player_name;
+
+ /* max_tokens is 4 because a player could have additional instances,
+ * lile org.mpris.MediaPlayer2.vlc.instance7389 */
+ tokens = g_strsplit (name, ".", 4);
+ player_name = g_strdup (tokens[3]);
+ g_strfreev (tokens);
+
+ return player_name;
+}
+
+/* A media player was just run and should be
+ * added to the head of media_player_queue. */
+static void
+mp_name_appeared (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ MsdMprisManager *manager)
+{
+ GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
+ GDBusProxy *proxy = NULL;
+ GError *error = NULL;
+ gchar *player_name;
+
+ g_debug ("MPRIS Name acquired: %s\n", name);
+
+ player_name = get_player_name(name);
+ g_queue_push_head (manager->priv->media_player_queue,
+ player_name);
+}
+
+/* A media player quit running and should be
+ * removed from media_player_queue. */
+static void
+mp_name_vanished (GDBusConnection *connection,
+ const gchar *name,
+ MsdMprisManager *manager)
+{
+ gchar *player_name;
+
+ if (g_queue_is_empty (manager->priv->media_player_queue))
+ return;
+
+ g_debug ("MPRIS Name vanished: %s\n", name);
+
+ player_name = get_player_name(name);
+
+ g_queue_remove (manager->priv->media_player_queue, player_name);
+
+ g_free (player_name);
+}
+
+static void
+on_media_player_key_pressed (MsdMprisManager *manager,
+ const gchar *key)
+{
+ GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
+ GDBusProxy *proxy = NULL;
+ GError *error = NULL;
+ const char *mpris_key = NULL;
+ const char *mpris_head = NULL;
+ char *mpris_name = NULL;
+
+ if (g_queue_is_empty (manager->priv->media_player_queue))
+ return;
+
+ if (strcmp ("Play", key) == 0)
+ mpris_key = "PlayPause";
+ else if (strcmp ("Pause", key) == 0)
+ mpris_key = "Pause";
+ else if (strcmp ("Previous", key) == 0)
+ mpris_key = "Previous";
+ else if (strcmp ("Next", key) == 0)
+ mpris_key = "Next";
+ else if (strcmp ("Stop", key) == 0)
+ mpris_key = "Stop";
+
+ if (mpris_key != NULL)
+ {
+ mpris_head = g_queue_peek_head (manager->priv->media_player_queue);
+ mpris_name = g_strdup_printf (MPRIS_PREFIX "%s", mpris_head);
+
+ g_debug ("MPRIS Sending '%s' to '%s'!", mpris_key, mpris_head);
+
+ proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
+ flags,
+ NULL,
+ mpris_name,
+ MPRIS_OBJECT_PATH,
+ MPRIS_INTERFACE,
+ NULL,
+ &error);
+ g_free (mpris_name);
+ if (proxy == NULL)
+ {
+ g_printerr("Error creating proxy: %s\n", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ g_dbus_proxy_call (proxy, mpris_key, NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, NULL, NULL);
+ g_object_unref (proxy);
+
+ }
+}
+
+static void
+grab_media_player_keys_cb (GDBusProxy *proxy,
+ GAsyncResult *res,
+ MsdMprisManager *manager)
+{
+ GVariant *variant;
+ GError *error = NULL;
+
+ variant = g_dbus_proxy_call_finish (proxy, res, &error);
+
+ if (variant == NULL) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("Failed to call \"GrabMediaPlayerKeys\": %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ g_variant_unref (variant);
+}
+
+static void
+grab_media_player_keys (MsdMprisManager *manager)
+{
+ if (manager->priv->media_keys_proxy == NULL)
+ return;
+
+ g_dbus_proxy_call (manager->priv->media_keys_proxy,
+ "GrabMediaPlayerKeys",
+ g_variant_new ("(su)", "MsdMpris", 0),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL,
+ (GAsyncReadyCallback) grab_media_player_keys_cb,
+ manager);
+}
+
+static void
+key_pressed (GDBusProxy *proxy,
+ gchar *sender_name,
+ gchar *signal_name,
+ GVariant *parameters,
+ MsdMprisManager *manager)
+{
+ char *app, *cmd;
+
+ if (g_strcmp0 (signal_name, "MediaPlayerKeyPressed") != 0)
+ return;
+ g_variant_get (parameters, "(ss)", &app, &cmd);
+ if (g_strcmp0 (app, "MsdMpris") == 0) {
+ on_media_player_key_pressed (manager, cmd);
+ }
+ g_free (app);
+ g_free (cmd);
+}
+
+static void
+got_proxy_cb (GObject *source_object,
+ GAsyncResult *res,
+ MsdMprisManager *manager)
+{
+ GError *error = NULL;
+
+ manager->priv->media_keys_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+
+ if (manager->priv->media_keys_proxy == NULL) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("Failed to contact settings daemon: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ grab_media_player_keys (manager);
+
+ g_signal_connect (G_OBJECT (manager->priv->media_keys_proxy), "g-signal",
+ G_CALLBACK (key_pressed), manager);
+}
+
+static void
+msd_name_appeared (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ MsdMprisManager *manager)
+{
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ NULL,
+ "org.mate.SettingsDaemon",
+ "/org/mate/SettingsDaemon/MediaKeys",
+ "org.mate.SettingsDaemon.MediaKeys",
+ NULL,
+ (GAsyncReadyCallback) got_proxy_cb,
+ manager);
+}
+
+static void
+msd_name_vanished (GDBusConnection *connection,
+ const gchar *name,
+ MsdMprisManager *manager)
+{
+ if (manager->priv->media_keys_proxy != NULL) {
+ g_object_unref (manager->priv->media_keys_proxy);
+ manager->priv->media_keys_proxy = NULL;
+ }
+}
+
+
+gboolean
+msd_mpris_manager_start (MsdMprisManager *manager,
+ GError **error)
+{
+ GBusNameWatcherFlags flags = G_BUS_NAME_WATCHER_FLAGS_NONE;
+ int i;
+
+ g_debug ("Starting mpris manager");
+ mate_settings_profile_start (NULL);
+
+ manager->priv->media_player_queue = g_queue_new();
+
+ /* Register all the names we wish to watch.*/
+ for (i = 0; i < NUM_BUS_NAMES; i++)
+ {
+ g_bus_watch_name(G_BUS_TYPE_SESSION,
+ BUS_NAMES[i],
+ flags,
+ mp_name_appeared,
+ mp_name_vanished,
+ manager,
+ NULL);
+ }
+
+
+ manager->priv->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
+ "org.mate.SettingsDaemon",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ (GBusNameAppearedCallback) msd_name_appeared,
+ (GBusNameVanishedCallback) msd_name_vanished,
+ manager, NULL);
+
+ mate_settings_profile_end (NULL);
+ return TRUE;
+}
+
+void
+msd_mpris_manager_stop (MsdMprisManager *manager)
+{
+ g_debug ("Stopping mpris manager");
+
+ if (manager->priv->media_keys_proxy != NULL) {
+ g_object_unref (manager->priv->media_keys_proxy);
+ manager->priv->media_keys_proxy = NULL;
+ }
+
+ if (manager->priv->watch_id != 0) {
+ g_bus_unwatch_name (manager->priv->watch_id);
+ manager->priv->watch_id = 0;
+ }
+}
+
+static void
+msd_mpris_manager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MsdMprisManager *self;
+
+ self = MSD_MPRIS_MANAGER (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+msd_mpris_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MsdMprisManager *self;
+
+ self = MSD_MPRIS_MANAGER (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GObject *
+msd_mpris_manager_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ MsdMprisManager *mpris_manager;
+ MsdMprisManagerClass *klass;
+
+ klass = MSD_MPRIS_MANAGER_CLASS (g_type_class_peek (MSD_TYPE_MPRIS_MANAGER));
+
+ mpris_manager = MSD_MPRIS_MANAGER (G_OBJECT_CLASS (msd_mpris_manager_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+
+ return G_OBJECT (mpris_manager);
+}
+
+static void
+msd_mpris_manager_dispose (GObject *object)
+{
+ MsdMprisManager *mpris_manager;
+
+ mpris_manager = MSD_MPRIS_MANAGER (object);
+
+ G_OBJECT_CLASS (msd_mpris_manager_parent_class)->dispose (object);
+}
+
+static void
+msd_mpris_manager_class_init (MsdMprisManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = msd_mpris_manager_get_property;
+ object_class->set_property = msd_mpris_manager_set_property;
+ object_class->constructor = msd_mpris_manager_constructor;
+ object_class->dispose = msd_mpris_manager_dispose;
+ object_class->finalize = msd_mpris_manager_finalize;
+
+ g_type_class_add_private (klass, sizeof (MsdMprisManagerPrivate));
+}
+
+static void
+msd_mpris_manager_init (MsdMprisManager *manager)
+{
+ manager->priv = MSD_MPRIS_MANAGER_GET_PRIVATE (manager);
+
+}
+
+static void
+msd_mpris_manager_finalize (GObject *object)
+{
+ MsdMprisManager *mpris_manager;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (MSD_IS_MPRIS_MANAGER (object));
+
+ mpris_manager = MSD_MPRIS_MANAGER (object);
+
+ g_return_if_fail (mpris_manager->priv != NULL);
+
+ G_OBJECT_CLASS (msd_mpris_manager_parent_class)->finalize (object);
+}
+
+MsdMprisManager *
+msd_mpris_manager_new (void)
+{
+ if (manager_object != NULL) {
+ g_object_ref (manager_object);
+ } else {
+ manager_object = g_object_new (MSD_TYPE_MPRIS_MANAGER, NULL);
+ g_object_add_weak_pointer (manager_object,
+ (gpointer *) &manager_object);
+ }
+
+ return MSD_MPRIS_MANAGER (manager_object);
+}
diff --git a/plugins/mpris/msd-mpris-manager.h b/plugins/mpris/msd-mpris-manager.h
new file mode 100644
index 0000000..9b2e8e3
--- /dev/null
+++ b/plugins/mpris/msd-mpris-manager.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Stefano Karapetsas <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ * Stefano Karapetsas <[email protected]>
+ */
+
+#ifndef __MSD_MPRIS_MANAGER_H
+#define __MSD_MPRIS_MANAGER_H
+
+#include <glib-object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MSD_TYPE_MPRIS_MANAGER (msd_mpris_manager_get_type ())
+#define MSD_MPRIS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MSD_TYPE_MPRIS_MANAGER, MsdMprisManager))
+#define MSD_MPRIS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MSD_TYPE_MPRIS_MANAGER, MsdMprisManagerClass))
+#define MSD_IS_MPRIS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MSD_TYPE_MPRIS_MANAGER))
+#define MSD_IS_MPRIS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MSD_TYPE_MPRIS_MANAGER))
+#define MSD_MPRIS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MSD_TYPE_MPRIS_MANAGER, MsdMprisManagerClass))
+
+typedef struct MsdMprisManagerPrivate MsdMprisManagerPrivate;
+
+typedef struct
+{
+ GObject parent;
+ MsdMprisManagerPrivate *priv;
+} MsdMprisManager;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} MsdMprisManagerClass;
+
+GType msd_mpris_manager_get_type (void);
+
+MsdMprisManager * msd_mpris_manager_new (void);
+gboolean msd_mpris_manager_start (MsdMprisManager *manager,
+ GError **error);
+void msd_mpris_manager_stop (MsdMprisManager *manager);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSD_MPRIS_MANAGER_H */
diff --git a/plugins/mpris/msd-mpris-plugin.c b/plugins/mpris/msd-mpris-plugin.c
new file mode 100644
index 0000000..56b48cc
--- /dev/null
+++ b/plugins/mpris/msd-mpris-plugin.c
@@ -0,0 +1,111 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ * Stefano Karapetsas <[email protected]>
+*/
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+
+#include "mate-settings-plugin.h"
+#include "msd-mpris-plugin.h"
+#include "msd-mpris-manager.h"
+
+struct MsdMprisPluginPrivate {
+ MsdMprisManager *manager;
+};
+
+#define MSD_MPRIS_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), MSD_TYPE_MPRIS_PLUGIN, MsdMprisPluginPrivate))
+
+MATE_SETTINGS_PLUGIN_REGISTER (MsdMprisPlugin, msd_mpris_plugin)
+
+static void
+msd_mpris_plugin_init (MsdMprisPlugin *plugin)
+{
+ plugin->priv = MSD_MPRIS_PLUGIN_GET_PRIVATE (plugin);
+
+ g_debug ("MsdMprisPlugin initializing");
+
+ plugin->priv->manager = msd_mpris_manager_new ();
+}
+
+static void
+msd_mpris_plugin_finalize (GObject *object)
+{
+ MsdMprisPlugin *plugin;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (MSD_IS_MPRIS_PLUGIN (object));
+
+ g_debug ("MsdMprisPlugin finalizing");
+
+ plugin = MSD_MPRIS_PLUGIN (object);
+
+ g_return_if_fail (plugin->priv != NULL);
+
+ if (plugin->priv->manager != NULL) {
+ g_object_unref (plugin->priv->manager);
+ }
+
+ G_OBJECT_CLASS (msd_mpris_plugin_parent_class)->finalize (object);
+}
+
+static void
+impl_activate (MateSettingsPlugin *plugin)
+{
+ gboolean res;
+ GError *error;
+
+ g_debug ("Activating mpris plugin");
+
+ error = NULL;
+ res = msd_mpris_manager_start (MSD_MPRIS_PLUGIN (plugin)->priv->manager, &error);
+ if (! res) {
+ g_warning ("Unable to start mpris manager: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+impl_deactivate (MateSettingsPlugin *plugin)
+{
+ g_debug ("Deactivating mpris plugin");
+ msd_mpris_manager_stop (MSD_MPRIS_PLUGIN (plugin)->priv->manager);
+}
+
+static void
+msd_mpris_plugin_class_init (MsdMprisPluginClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass);
+
+ object_class->finalize = msd_mpris_plugin_finalize;
+
+ plugin_class->activate = impl_activate;
+ plugin_class->deactivate = impl_deactivate;
+
+ g_type_class_add_private (klass, sizeof (MsdMprisPluginPrivate));
+}
+
+static void
+msd_mpris_plugin_class_finalize (MsdMprisPluginClass *klass)
+{
+}
diff --git a/plugins/mpris/msd-mpris-plugin.h b/plugins/mpris/msd-mpris-plugin.h
new file mode 100644
index 0000000..cf9cf52
--- /dev/null
+++ b/plugins/mpris/msd-mpris-plugin.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ * Stefano Karapetsas <[email protected]>
+ */
+
+#ifndef __MSD_MPRIS_PLUGIN_H__
+#define __MSD_MPRIS_PLUGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gmodule.h>
+
+#include "mate-settings-plugin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MSD_TYPE_MPRIS_PLUGIN (msd_mpris_plugin_get_type ())
+#define MSD_MPRIS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MSD_TYPE_MPRIS_PLUGIN, MsdMprisPlugin))
+#define MSD_MPRIS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MSD_TYPE_MPRIS_PLUGIN, MsdMprisPluginClass))
+#define MSD_IS_MPRIS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MSD_TYPE_MPRIS_PLUGIN))
+#define MSD_IS_MPRIS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MSD_TYPE_MPRIS_PLUGIN))
+#define MSD_MPRIS_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MSD_TYPE_MPRIS_PLUGIN, MsdMprisPluginClass))
+
+typedef struct MsdMprisPluginPrivate MsdMprisPluginPrivate;
+
+typedef struct
+{
+ MateSettingsPlugin parent;
+ MsdMprisPluginPrivate *priv;
+} MsdMprisPlugin;
+
+typedef struct
+{
+ MateSettingsPluginClass parent_class;
+} MsdMprisPluginClass;
+
+GType msd_mpris_plugin_get_type (void) G_GNUC_CONST;
+
+/* All the plugins must implement this function */
+G_MODULE_EXPORT GType register_mate_settings_plugin (GTypeModule *module);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MSD_MPRIS_PLUGIN_H__ */