diff options
-rw-r--r-- | .pc/.version | 1 | ||||
-rw-r--r-- | .pc/applied-patches | 2 | ||||
-rw-r--r-- | .pc/correct_ldflags_use.patch/src/Makefile.am | 169 | ||||
-rw-r--r-- | .pc/sound_nua.patch/src/sound-service-dbus.c | 480 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/sound-service-dbus.c | 2 |
6 files changed, 654 insertions, 2 deletions
diff --git a/.pc/.version b/.pc/.version new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/.pc/.version @@ -0,0 +1 @@ +2 diff --git a/.pc/applied-patches b/.pc/applied-patches new file mode 100644 index 0000000..caeeae4 --- /dev/null +++ b/.pc/applied-patches @@ -0,0 +1,2 @@ +sound_nua.patch +correct_ldflags_use.patch diff --git a/.pc/correct_ldflags_use.patch/src/Makefile.am b/.pc/correct_ldflags_use.patch/src/Makefile.am new file mode 100644 index 0000000..36fe490 --- /dev/null +++ b/.pc/correct_ldflags_use.patch/src/Makefile.am @@ -0,0 +1,169 @@ +libexec_PROGRAMS = indicator-sound-service + +################### +# Indicator Stuff +################### + +soundmenulibdir = $(INDICATORDIR) +soundmenulib_LTLIBRARIES = libsoundmenu.la +libsoundmenu_la_SOURCES = \ + common-defs.h \ + indicator-sound.h \ + indicator-sound.c \ + sound-state.c \ + sound-state.h \ + sound-state-manager.c \ + sound-state-manager.h \ + transport-widget.c \ + transport-widget.h \ + metadata-widget.c \ + metadata-widget.h \ + mute-widget.c \ + mute-widget.h \ + volume-widget.c \ + volume-widget.h \ + voip-input-widget.c \ + voip-input-widget.h \ + gen-sound-service.xml.h \ + gen-sound-service.xml.c \ + dbus-shared-names.h + +libsoundmenu_la_CFLAGS = \ + $(APPLET_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + -Wall -Werror -DG_LOG_DOMAIN=\"Indicator-Sound\" +libsoundmenu_la_LIBADD = $(APPLET_LIBS) -lm +libsoundmenu_la_LDFLAGS = + $(COVERAGE_LDFLAGS) \ + -module -avoid-version + + +checkxml: $(srcdir)/sound-service.xml + @xmllint -valid -noout $< + @echo $< checks out ok + + +#################################################################### +# Sound Service +#################################################################### + +glib_marshal_list = sound-service-marshal.list +glib_marshal_prefix = _sound_service_marshal + + +##################### +# Sound service vala +##################### +music_bridge_VALASOURCES = \ + music-player-bridge.vala \ + transport-menu-item.vala \ + specific-items-manager.vala \ + metadata-menu-item.vala \ + player-controller.vala \ + mpris2-interfaces.vala \ + mpris2-watcher.vala \ + mpris2-controller.vala \ + player-item.vala \ + settings-manager.vala \ + playlists-menu-item.vala \ + freedesktop-interfaces.vala \ + fetch-file.vala + +music_bridge_VALAFLAGS = \ + --ccode \ + -H music-player-bridge.h -d . \ + --vapidir=$(top_srcdir)/vapi/ \ + --vapidir=./ \ + --thread \ + --pkg gee-1.0 \ + --pkg Dbusmenu-0.4 \ + --pkg common-defs \ + --pkg config \ + --pkg gio-2.0 \ + --pkg gio-unix-2.0 \ + --pkg gdk-pixbuf-2.0 \ + --pkg libxml-2.0 + + $(MAINTAINER_VALAFLAGS) + +music_bridge_APIFILES = \ + music-player-bridge.h + +music_bridge_vala.stamp $(music_bridge_APIFILES): $(music_bridge_VALASOURCES) + $(AM_V_GEN) $(VALAC) $(music_bridge_VALAFLAGS) $^ + touch music_bridge_vala.stamp + +############################### +# Sound Service C +############################### +indicator_sound_service_SOURCES = \ + common-defs.h \ + sound-service.h \ + sound-service.c \ + sound-state.c \ + sound-state.h \ + pulseaudio-mgr.h \ + pulseaudio-mgr.c \ + device.c \ + device.h \ + sound-service-dbus.h \ + sound-service-dbus.c \ + slider-menu-item.h \ + slider-menu-item.c \ + voip-input-menu-item.h \ + voip-input-menu-item.c \ + mute-menu-item.h \ + mute-menu-item.c \ + gen-sound-service.xml.h \ + gen-sound-service.xml.c \ + sound-service-marshal.c \ + sound-service-marshal.h \ + $(music_bridge_VALASOURCES:.vala=.c) + +indicator_sound_service_CFLAGS = $(PULSEAUDIO_CFLAGS) \ + $(SOUNDSERVICE_CFLAGS) \ + $(GCONF_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + -DLIBEXECDIR=\"$(libexecdir)\" -Wall +indicator_sound_service_LDADD = $(PULSEAUDIO_LIBS) $(SOUNDSERVICE_LIBS) $(GCONF_LIBS) +indicator_sound_service_LDFLAGS = $(COVERAGE_LDFLAGS) + +######################### +# Service xml compilation +######################### +DBUS_SPECS = \ + sound-service.xml + +gen-%.xml.h: %.xml + @echo "Building $@ from $<" + @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<))));" > $@ + +gen-%.xml.c: %.xml + @echo "Building $@ from $<" + @echo "const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<)))) = " > $@ + @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@ + @echo ";" >> $@ + + +EXTRA_DIST = \ + $(DBUS_SPECS) \ + sound-service.xml \ + $(music_bridge_APIFILES) \ + $(music_bridge_VALASOURCES) + +####################### +# Stuff to clean Stuff +####################### +BUILT_SOURCES = \ + music_bridge_vala.stamp \ + $(music_bridge_APIFILES) \ + gen-sound-service.xml.h \ + gen-sound-service.xml.c \ + $(music_bridge_VALASOURCES:.vala=.c) + +CLEANFILES = \ + $(BUILT_SOURCES) + +DISTCLEANFILES = + +include $(top_srcdir)/Makefile.am.marshal diff --git a/.pc/sound_nua.patch/src/sound-service-dbus.c b/.pc/sound_nua.patch/src/sound-service-dbus.c new file mode 100644 index 0000000..5650002 --- /dev/null +++ b/.pc/sound_nua.patch/src/sound-service-dbus.c @@ -0,0 +1,480 @@ +/* + * Copyright 2010 Canonical Ltd. + * + * Authors: + * Conor Curran <conor.curran@canonical.com> + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gio/gio.h> +#include <unistd.h> +#include <glib/gi18n.h> +#include <libindicator/indicator-service.h> +#include <libdbusmenu-glib/server.h> +#include <libdbusmenu-glib/client.h> + +#include "sound-service-dbus.h" +#include "device.h" +#include "gen-sound-service.xml.h" +#include "dbus-shared-names.h" +#include "sound-service-marshal.h" + +// DBUS methods +static void bus_method_call (GDBusConnection * connection, + const gchar * sender, + const gchar * path, + const gchar * interface, + const gchar * method, + GVariant * params, + GDBusMethodInvocation * invocation, + gpointer user_data); + +static GDBusInterfaceVTable interface_table = { + method_call: bus_method_call, + get_property: NULL, /* No properties */ + set_property: NULL /* No properties */ +}; + + +typedef struct _SoundServiceDbusPrivate SoundServiceDbusPrivate; + +struct _SoundServiceDbusPrivate { + GDBusConnection* connection; + DbusmenuMenuitem* root_menuitem; + Device* device; + gboolean greeter_mode; +}; + +enum { + TRACK_SPECIFIC_ITEM, + PLAYER_SPECIFIC_ITEM, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static GDBusNodeInfo * node_info = NULL; +static GDBusInterfaceInfo * interface_info = NULL; + +#define SOUND_SERVICE_DBUS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUND_SERVICE_DBUS_TYPE, SoundServiceDbusPrivate)) + +static void sound_service_dbus_class_init (SoundServiceDbusClass *klass); +static void sound_service_dbus_init (SoundServiceDbus *self); +static void sound_service_dbus_dispose (GObject *object); +static void sound_service_dbus_finalize (GObject *object); + +static void show_sound_settings_dialog (DbusmenuMenuitem *mi, + gpointer user_data); +static gboolean sound_service_dbus_blacklist_player (SoundServiceDbus* self, + gchar* player_name, + gboolean blacklist); + +static gboolean sound_service_dbus_is_blacklisted (SoundServiceDbus* self, + gchar* player_name); + +G_DEFINE_TYPE (SoundServiceDbus, sound_service_dbus, G_TYPE_OBJECT); + +static void +sound_service_dbus_class_init (SoundServiceDbusClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof(SoundServiceDbusPrivate)); + + object_class->dispose = sound_service_dbus_dispose; + object_class->finalize = sound_service_dbus_finalize; + + g_assert(klass != NULL); + + if (node_info == NULL) { + GError * error = NULL; + + node_info = g_dbus_node_info_new_for_xml(_sound_service, &error); + if (error != NULL) { + g_error("Unable to parse Indicator Service Interface description: %s", + error->message); + g_error_free(error); + } + } + + if (interface_info == NULL) { + interface_info = g_dbus_node_info_lookup_interface (node_info, + INDICATOR_SOUND_DBUS_INTERFACE); + + if (interface_info == NULL) { + g_error("Unable to find interface '" INDICATOR_SOUND_DBUS_INTERFACE "'"); + } + } + signals[TRACK_SPECIFIC_ITEM] = g_signal_new("track-specific-item-requested", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _sound_service_marshal_VOID__STRING_STRING, + G_TYPE_NONE, 2, G_TYPE_STRING, + G_TYPE_STRING); + signals[PLAYER_SPECIFIC_ITEM] = g_signal_new("player-specific-item-requested", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _sound_service_marshal_VOID__STRING_STRING, + G_TYPE_NONE, 2, G_TYPE_STRING, + G_TYPE_STRING); +} + +static void +sound_service_dbus_init (SoundServiceDbus *self) +{ + GError *error = NULL; + SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); + + priv->connection = NULL; + + /* Fetch the session bus */ + priv->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + + if (error != NULL) { + g_error("sound-service-dbus:Unable to connect to the session bus when creating indicator sound service : %s", error->message); + g_error_free(error); + return; + } + /* register the service on it */ + g_dbus_connection_register_object (priv->connection, + INDICATOR_SOUND_SERVICE_DBUS_OBJECT_PATH, + interface_info, + &interface_table, + self, + NULL, + &error); + if (error != NULL) { + g_error("Unable to register the object to DBus: %s", error->message); + g_error_free(error); + return; + } +} + +DbusmenuMenuitem* +sound_service_dbus_create_root_item (SoundServiceDbus* self, gboolean greeter_mode) +{ + SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); + priv->greeter_mode = greeter_mode; + priv->root_menuitem = dbusmenu_menuitem_new(); + DbusmenuServer *server = dbusmenu_server_new (INDICATOR_SOUND_MENU_DBUS_OBJECT_PATH); + dbusmenu_server_set_root (server, priv->root_menuitem); + g_object_unref (priv->root_menuitem); + priv->device = device_new (self); + return priv->root_menuitem; +} + +void +sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, + DbusmenuMenuitem* mute_item, + DbusmenuMenuitem* slider_item, + DbusmenuMenuitem* voip_input_menu_item) +{ + SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); + + // Mute, Volume and Voip widgets + dbusmenu_menuitem_child_add_position (priv->root_menuitem, mute_item, 0); + dbusmenu_menuitem_child_add_position (priv->root_menuitem, slider_item, 1); + dbusmenu_menuitem_child_add_position (priv->root_menuitem, voip_input_menu_item, 2); + + if (!priv->greeter_mode) { + // Separator + DbusmenuMenuitem* separator = dbusmenu_menuitem_new(); + + dbusmenu_menuitem_property_set (separator, + DBUSMENU_MENUITEM_PROP_TYPE, + DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_add_position (priv->root_menuitem, separator, 3); + g_object_unref (separator); + + // Sound preferences dialog + DbusmenuMenuitem* settings_mi = dbusmenu_menuitem_new(); + + dbusmenu_menuitem_property_set( settings_mi, + DBUSMENU_MENUITEM_PROP_LABEL, + _("Sound Settings...")); + dbusmenu_menuitem_child_append(priv->root_menuitem, settings_mi); + g_object_unref (settings_mi); + g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(show_sound_settings_dialog), NULL); + } +} + +/** +show_sound_settings_dialog: +Bring up the gnome volume preferences dialog +**/ +static void +show_sound_settings_dialog (DbusmenuMenuitem *mi, + gpointer user_data) +{ + GError * error = NULL; + if (!g_spawn_command_line_async("gnome-volume-control --page=applications", &error) && + !g_spawn_command_line_async("gnome-control-center sound", &error) && + !g_spawn_command_line_async("xfce4-mixer", &error)) + { + g_warning("Unable to show dialog: %s", error->message); + g_error_free(error); + } +} + +static void +sound_service_dbus_dispose (GObject *object) +{ + G_OBJECT_CLASS (sound_service_dbus_parent_class)->dispose (object); + //TODO dispose of the active sink instance ! + return; +} + +static void +sound_service_dbus_finalize (GObject *object) +{ + G_OBJECT_CLASS (sound_service_dbus_parent_class)->finalize (object); + return; +} + + +// EMIT STATE SIGNAL +void +sound_service_dbus_update_sound_state (SoundServiceDbus* self, + SoundState new_state) +{ + SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); + + GVariant* v_output = g_variant_new("(i)", (int)new_state); + + GError * error = NULL; + + if (priv->connection == NULL || + g_dbus_connection_is_closed (priv->connection) == TRUE){ + g_critical ("sound_service_dbus_update_sound_state - connection is %s !!", + priv->connection == NULL? "NULL" : "closed"); + return; + } + + g_debug ("emitting state signal with value %i", (int)new_state); + g_dbus_connection_emit_signal( priv->connection, + NULL, + INDICATOR_SOUND_SERVICE_DBUS_OBJECT_PATH, + INDICATOR_SOUND_DBUS_INTERFACE, + INDICATOR_SOUND_SIGNAL_STATE_UPDATE, + v_output, + &error ); + if (error != NULL) { + g_critical ("Unable to emit signal because : %s", error->message); + g_error_free(error); + } +} + +//HANDLE DBUS METHOD CALLS +static void +bus_method_call (GDBusConnection * connection, + const gchar * sender, + const gchar * path, + const gchar * interface, + const gchar * method, + GVariant * params, + GDBusMethodInvocation * invocation, + gpointer user_data) +{ + SoundServiceDbus* service = SOUND_SERVICE_DBUS(user_data); + g_return_if_fail ( IS_SOUND_SERVICE_DBUS(service) ); + GVariant * retval = NULL; + SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (service); + + if (g_strcmp0(method, "GetSoundState") == 0) { + g_debug("Get state - %i", device_get_state (priv->device)); + retval = g_variant_new ( "(i)", device_get_state (priv->device)); + } + else if (g_strcmp0(method, "BlacklistMediaPlayer") == 0) { + gboolean blacklist; + gchar* player_name; + g_variant_get (params, "(sb)", &player_name, &blacklist); + + g_debug ("BlacklistMediaPlayer - bool %i", blacklist); + g_debug ("BlacklistMediaPlayer - name %s", player_name); + gboolean result = sound_service_dbus_blacklist_player (service, + player_name, + blacklist); + retval = g_variant_new ("(b)", result); + } + else if (g_strcmp0(method, "IsBlacklisted") == 0) { + gchar* player_name; + g_variant_get (params, "(s)", &player_name); + + g_debug ("IsBlacklisted - name %s", player_name); + gboolean result = sound_service_dbus_is_blacklisted (service, + player_name); + retval = g_variant_new ("(b)", result); + } + else if (g_strcmp0(method, "EnableTrackSpecificItems") == 0) { + g_debug ("EnableTrackSpecificItems"); + gchar* player_object_path; + gchar* player_id; + g_variant_get (params, "(os)", &player_object_path, &player_id); + //g_debug ("object path = %s and id = %s", player_object_path, player_id); + g_signal_emit (service, + signals[TRACK_SPECIFIC_ITEM], + 0, + player_object_path, + player_id); + g_free (player_object_path); + g_free (player_id); + + } + else if (g_strcmp0(method, "EnablePlayerSpecificItems") == 0) { + gchar* player_object_path; + gchar* player_id; + g_variant_get (params, "(os)", &player_object_path, &player_id); + g_debug ("PLayer specific item - object path = %s and id = %s", + player_object_path, + player_id); + g_signal_emit (service, + signals[PLAYER_SPECIFIC_ITEM], + 0, + player_object_path, + player_id); + g_free (player_object_path); + g_free (player_id); + } + else { + g_warning("Calling method '%s' on the sound service but it's unknown", method); + } + g_dbus_method_invocation_return_value (invocation, retval); +} + +/** + TODO - Works nicely but refactor into at least two different methods +**/ +static gboolean sound_service_dbus_blacklist_player (SoundServiceDbus* self, + gchar* player_name, + gboolean blacklist) +{ + g_return_val_if_fail (player_name != NULL, FALSE); + g_return_val_if_fail (IS_SOUND_SERVICE_DBUS (self), FALSE); + + GVariant* the_black_list; + gboolean result = FALSE; + GSettings* our_settings; + GVariantIter iter; + gchar *str; + GVariantBuilder builder; + + our_settings = g_settings_new ("com.canonical.indicator.sound"); + the_black_list = g_settings_get_value (our_settings, + "blacklisted-media-players"); + g_variant_iter_init (&iter, the_black_list); + g_variant_builder_init(&builder, G_VARIANT_TYPE_STRING_ARRAY); + + while (g_variant_iter_loop (&iter, "s", &str)){ + g_variant_builder_add (&builder, "s", str); + } + g_variant_iter_init (&iter, the_black_list); + + if (blacklist == TRUE){ + while (g_variant_iter_loop (&iter, "s", &str)){ + g_print ("first pass to check if %s is present\n", str); + if (g_strcmp0 (player_name, str) == 0){ + // Return if its already there + g_debug ("we have this already blacklisted, no need to do anything"); + g_variant_builder_clear (&builder); + g_object_unref (our_settings); + g_variant_unref (the_black_list); + return result; + } + } + // Otherwise blacklist it ! + g_debug ("about to blacklist %s", player_name); + g_variant_builder_add (&builder, "s", player_name); + } + else{ + gboolean present = FALSE; + g_variant_iter_init (&iter, the_black_list); + g_debug ("attempting to UN-blacklist %s", player_name); + + while (g_variant_iter_loop (&iter, "s", &str)){ + if (g_strcmp0 (player_name, str) == 0){ + present = TRUE; + } + } + // It was not there anyway, return false + if (present == FALSE){ + g_debug ("it was not blacklisted ?, no need to do anything"); + g_variant_builder_clear (&builder); + g_object_unref (our_settings); + g_variant_unref (the_black_list); + return result; + } + + // Otherwise free the builder and reconstruct ensuring no duplicates. + g_variant_builder_clear (&builder); + g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY); + + g_variant_iter_init (&iter, the_black_list); + + while (g_variant_iter_loop (&iter, "s", &str)){ + if (g_strcmp0 (player_name, str) != 0){ + g_variant_builder_add (&builder, "s", str); + } + } + } + GVariant* value = g_variant_builder_end (&builder); + result = g_settings_set_value (our_settings, + "blacklisted-media-players", + value); + + g_object_unref (our_settings); + g_variant_unref (the_black_list); + + return result; +} + +static gboolean sound_service_dbus_is_blacklisted (SoundServiceDbus *self, + gchar *player_name) +{ + GSettings *our_settings; + GVariant *the_black_list; + GVariantIter iter; + gchar *str; + gboolean result = FALSE; + + g_return_val_if_fail (player_name != NULL, FALSE); + g_return_val_if_fail (IS_SOUND_SERVICE_DBUS (self), FALSE); + + our_settings = g_settings_new ("com.canonical.indicator.sound"); + the_black_list = g_settings_get_value (our_settings, + "blacklisted-media-players"); + g_variant_iter_init (&iter, the_black_list); + while (g_variant_iter_next (&iter, "s", &str)){ + if (g_strcmp0 (player_name, str) == 0) { + result = TRUE; + g_free (str); + break; + } + g_free (str); + } + + g_object_unref (our_settings); + g_variant_unref (the_black_list); + + return result; +} + diff --git a/src/Makefile.am b/src/Makefile.am index 36fe490..199d050 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,7 +33,7 @@ libsoundmenu_la_CFLAGS = \ $(COVERAGE_CFLAGS) \ -Wall -Werror -DG_LOG_DOMAIN=\"Indicator-Sound\" libsoundmenu_la_LIBADD = $(APPLET_LIBS) -lm -libsoundmenu_la_LDFLAGS = +libsoundmenu_la_LDFLAGS = \ $(COVERAGE_LDFLAGS) \ -module -avoid-version diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 5650002..660dd40 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -228,7 +228,7 @@ show_sound_settings_dialog (DbusmenuMenuitem *mi, { GError * error = NULL; if (!g_spawn_command_line_async("gnome-volume-control --page=applications", &error) && - !g_spawn_command_line_async("gnome-control-center sound", &error) && + !g_spawn_command_line_async("gnome-control-center sound-nua", &error) && !g_spawn_command_line_async("xfce4-mixer", &error)) { g_warning("Unable to show dialog: %s", error->message); |