From ea30986e03e54ee650a1cca610904de9f4d0f745 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 6 Mar 2013 22:40:55 -0500 Subject: Remove libsoundmenu (panel plugin) Indicator panel plugins are deprecated. --- src/Makefile.am | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index 5a36822..a56f82a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,43 +1,5 @@ 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 -- cgit v1.2.3 From 92c98f341c6b5600d4b5fae8753326c866e40860 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 22 Mar 2013 16:24:06 -0400 Subject: Add service that adheres to the new indicator protocol This is the one that gets built now. It doesn't do anything interesting yet, though. --- src/Makefile.am | 8 ++-- src/com.canonical.sound.indicator | 4 ++ src/main.vala | 5 +++ src/service.vala | 84 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/com.canonical.sound.indicator create mode 100644 src/main.vala create mode 100644 src/service.vala (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index a56f82a..39ec6bf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,6 +17,8 @@ glib_marshal_prefix = _sound_service_marshal # Sound service vala ##################### music_bridge_VALASOURCES = \ + service.vala \ + main.vala \ music-player-bridge.vala \ transport-menu-item.vala \ specific-items-manager.vala \ @@ -44,7 +46,9 @@ music_bridge_VALAFLAGS = \ --pkg gio-2.0 \ --pkg gio-unix-2.0 \ --pkg gdk-pixbuf-2.0 \ - --pkg libxml-2.0 + --pkg libxml-2.0 \ + --pkg libpulse \ + --target-glib=2.36 $(MAINTAINER_VALAFLAGS) @@ -60,8 +64,6 @@ music_bridge_vala.stamp $(music_bridge_APIFILES): $(music_bridge_VALASOURCES) ############################### indicator_sound_service_SOURCES = \ common-defs.h \ - sound-service.h \ - sound-service.c \ sound-state.c \ sound-state.h \ pulseaudio-mgr.h \ diff --git a/src/com.canonical.sound.indicator b/src/com.canonical.sound.indicator new file mode 100644 index 0000000..e2f26b0 --- /dev/null +++ b/src/com.canonical.sound.indicator @@ -0,0 +1,4 @@ +[Indicator Service] +Name=indicator-sound +BusName=com.canonical.indicator.sound +ObjectPath=/com/canonical/indicator/sound diff --git a/src/main.vala b/src/main.vala new file mode 100644 index 0000000..1ec7d2c --- /dev/null +++ b/src/main.vala @@ -0,0 +1,5 @@ + +static int main (string[] args) { + var service = new IndicatorSound.Service (); + return service.run (); +} diff --git a/src/service.vala b/src/service.vala new file mode 100644 index 0000000..fc35dd7 --- /dev/null +++ b/src/service.vala @@ -0,0 +1,84 @@ + +public class IndicatorSound.Service { + public Service () { + } + + public int run () { + if (this.loop != null) { + warning ("service is already running"); + return 1; + } + + Bus.own_name (BusType.SESSION, "com.canonical.indicator.sound", BusNameOwnerFlags.NONE, + this.bus_acquired, null, this.name_lost); + + this.loop = new MainLoop (null, false); + this.loop.run (); + + return 0; + } + + const ActionEntry[] action_entries = { + { "root", null, null, "('', 'audio-volume-high-panel', '', true)", null }, + { "mute", activate_mute, null, "false", null }, + { "volume", null, null, "0", volume_changed }, + { "settings", activate_settings, null, null, null } + }; + + MainLoop loop; + SimpleActionGroup actions; + Menu menu; + + void activate_mute (SimpleAction action, Variant? param) { + bool muted = action.get_state ().get_boolean (); + } + + void volume_changed (SimpleAction action, Variant val) { + } + + void activate_settings (SimpleAction action, Variant? param) { + try { + Process.spawn_command_line_async ("gnome-control-center sound"); + } catch (Error e) { + warning ("unable to launch sound settings: %s", e.message); + } + } + + static Menu create_base_menu () { + var submenu = new Menu (); + submenu.append ("Mute", "indicator.mute"); + + var slider = new MenuItem ("null", "indicator.volume"); + slider.set_attribute ("x-canonical-type", "s", "com.canonical.unity.slider"); + submenu.append_item (slider); + + submenu.append ("Sound Settings…", "indicator.settings"); + + var root = new MenuItem (null, "indicator.root"); + root.set_attribute ("x-canonical-type", "s", "com.canonical.indicator.root"); + root.set_submenu (submenu); + + var menu = new Menu (); + menu.append_item (root); + + return menu; + } + + void bus_acquired (DBusConnection connection, string name) { + this.actions = new SimpleActionGroup (); + this.actions.add_entries (action_entries, this); + + this.menu = create_base_menu (); + + try { + connection.export_action_group ("/com/canonical/indicator/sound", this.actions); + connection.export_menu_model ("/com/canonical/indicator/sound/desktop", this.menu); + } catch (Error e) { + critical ("%s", e.message); + } + } + + void name_lost (DBusConnection connection, string name) { + this.loop.quit (); + } +} -- cgit v1.2.3 From c3d504bc66bbd360ca6c8d5742a121441dacbfe2 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 27 Mar 2013 13:06:26 -0400 Subject: Add VolumeControl and hook up mute and volume actions to it The VolumeControl class originated in the phablet branch of this indicator. --- src/Makefile.am | 3 + src/service.vala | 46 +++++++++--- src/volume-control.vala | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+), 9 deletions(-) create mode 100644 src/volume-control.vala (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index 39ec6bf..2421683 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,7 @@ glib_marshal_prefix = _sound_service_marshal music_bridge_VALASOURCES = \ service.vala \ main.vala \ + volume-control.vala \ music-player-bridge.vala \ transport-menu-item.vala \ specific-items-manager.vala \ @@ -48,6 +49,8 @@ music_bridge_VALAFLAGS = \ --pkg gdk-pixbuf-2.0 \ --pkg libxml-2.0 \ --pkg libpulse \ + --pkg libpulse-mainloop-glib \ + --pkg pulseaudio-mgr \ --target-glib=2.36 $(MAINTAINER_VALAFLAGS) diff --git a/src/service.vala b/src/service.vala index fc35dd7..cdb5b15 100644 --- a/src/service.vala +++ b/src/service.vala @@ -1,6 +1,7 @@ public class IndicatorSound.Service { public Service () { + this.volume_control = new VolumeControl (); } public int run () { @@ -20,21 +21,13 @@ public class IndicatorSound.Service { const ActionEntry[] action_entries = { { "root", null, null, "('', 'audio-volume-high-panel', '', true)", null }, - { "mute", activate_mute, null, "false", null }, - { "volume", null, null, "0", volume_changed }, { "settings", activate_settings, null, null, null } }; MainLoop loop; SimpleActionGroup actions; Menu menu; - - void activate_mute (SimpleAction action, Variant? param) { - bool muted = action.get_state ().get_boolean (); - } - - void volume_changed (SimpleAction action, Variant val) { - } + VolumeControl volume_control; void activate_settings (SimpleAction action, Variant? param) { try { @@ -64,10 +57,45 @@ public class IndicatorSound.Service { return menu; } + Action create_mute_action () { + var mute_action = new SimpleAction.stateful ("mute", null, this.volume_control.mute); + + mute_action.activate.connect ( (action, param) => { + action.change_state (!action.get_state ().get_boolean ()); + }); + + mute_action.change_state.connect ( (action, val) => { + volume_control.set_mute (val.get_boolean ()); + }); + + this.volume_control.notify["mute"].connect ( () => { + mute_action.set_state (this.volume_control.mute); + }); + + return mute_action; + } + + Action create_volume_action () { + var volume_action = new SimpleAction.stateful ("volume", null, this.volume_control.get_volume ()); + + volume_action.change_state.connect ( (action, val) => { + volume_control.set_volume (val.get_double ()); + }); + + this.volume_control.volume_changed.connect ( (volume) => { + volume_action.set_state (volume); + }); + + return volume_action; + } + void bus_acquired (DBusConnection connection, string name) { this.actions = new SimpleActionGroup (); this.actions.add_entries (action_entries, this); + this.actions.add_action (this.create_mute_action ()); + this.actions.add_action (this.create_volume_action ()); + this.menu = create_base_menu (); try { diff --git a/src/volume-control.vala b/src/volume-control.vala new file mode 100644 index 0000000..8c88c92 --- /dev/null +++ b/src/volume-control.vala @@ -0,0 +1,192 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * 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; version 3. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authors: + * Alberto Ruiz + */ + +using PulseAudio; + +[CCode(cname="pa_cvolume_set", cheader_filename = "pulse/volume.h")] +extern unowned PulseAudio.CVolume? vol_set (PulseAudio.CVolume? cv, uint channels, PulseAudio.Volume v); + +public class VolumeControl : Object +{ + /* this is static to ensure it being freed after @context (loop does not have ref counting) */ + private static PulseAudio.GLibMainLoop loop; + + private PulseAudio.Context context; + private bool _mute = true; + private double _volume = 0.0; + + public signal void ready (); + public signal void volume_changed (double v); + + public VolumeControl () + { + if (loop == null) + loop = new PulseAudio.GLibMainLoop (); + + var props = new Proplist (); + props.sets (Proplist.PROP_APPLICATION_NAME, "Ubuntu Audio Settings"); + props.sets (Proplist.PROP_APPLICATION_ID, "com.canonical.settings.sound"); + props.sets (Proplist.PROP_APPLICATION_ICON_NAME, "multimedia-volume-control"); + props.sets (Proplist.PROP_APPLICATION_VERSION, "0.1"); + + context = new PulseAudio.Context (loop.get_api(), null, props); + + context.set_state_callback (notify_cb); + + if (context.connect(null, Context.Flags.NOFAIL, null) < 0) + { + warning( "pa_context_connect() failed: %s\n", PulseAudio.strerror(context.errno())); + return; + } + } + + /* PulseAudio logic*/ + private void context_events_cb (Context c, Context.SubscriptionEventType t, uint32 index) + { + if ((t & Context.SubscriptionEventType.FACILITY_MASK) == Context.SubscriptionEventType.SINK) + { + get_properties (); + } + } + + private void sink_info_cb_for_props (Context c, SinkInfo? i, int eol) + { + if (i == null) + return; + + if (_mute != (bool)i.mute) + { + _mute = (bool)i.mute; + this.notify_property ("mute"); + } + + if (_volume != volume_to_double (i.volume.values[0])) + { + _volume = volume_to_double (i.volume.values[0]); + volume_changed (_volume); + } + } + + private void server_info_cb_for_props (Context c, ServerInfo? i) + { + if (i == null) + return; + context.get_sink_info_by_name (i.default_sink_name, sink_info_cb_for_props); + } + + private void get_properties () + { + context.get_server_info (server_info_cb_for_props); + } + + private void notify_cb (Context c) + { + if (c.get_state () == Context.State.READY) + { + c.subscribe (PulseAudio.Context.SubscriptionMask.SINK); + c.set_subscribe_callback (context_events_cb); + get_properties (); + ready (); + } + } + + /* Mute operations */ + public void set_mute (bool mute) + { + if (context.get_state () != Context.State.READY) + { + warning ("Could not mute: PulseAudio server connection is not ready."); + return; + } + + context.get_sink_info_list ((context, sink, eol) => { + if (sink != null) + context.set_sink_mute_by_index (sink.index, mute, null); + }); + } + + public void toggle_mute () + { + this.set_mute (!this._mute); + } + + public bool mute + { + get + { + return this._mute; + } + } + + /* Volume operations */ + private static PulseAudio.Volume double_to_volume (double vol) + { + double tmp = (double)(PulseAudio.Volume.NORM - PulseAudio.Volume.MUTED) * vol; + return (PulseAudio.Volume)tmp + PulseAudio.Volume.MUTED; + } + + private static double volume_to_double (PulseAudio.Volume vol) + { + double tmp = (double)(vol - PulseAudio.Volume.MUTED); + return tmp / (double)(PulseAudio.Volume.NORM - PulseAudio.Volume.MUTED); + } + + private void set_volume_success_cb (Context c, int success) + { + if ((bool)success) + volume_changed (_volume); + } + + private void sink_info_set_volume_cb (Context c, SinkInfo? i, int eol) + { + if (i == null) + return; + + unowned CVolume cvol = vol_set (i.volume, 1, double_to_volume (_volume)); + c.set_sink_volume_by_index (i.index, cvol, set_volume_success_cb); + } + + private void server_info_cb_for_set_volume (Context c, ServerInfo? i) + { + if (i == null) + { + warning ("Could not get PulseAudio server info"); + return; + } + + context.get_sink_info_by_name (i.default_sink_name, sink_info_set_volume_cb); + } + + public void set_volume (double volume) + { + if (context.get_state () != Context.State.READY) + { + warning ("Could not change volume: PulseAudio server connection is not ready."); + return; + } + _volume = volume; + + context.get_server_info (server_info_cb_for_set_volume); + } + + public double get_volume () + { + return _volume; + } +} -- cgit v1.2.3 From 1419ef39b81be9d8a42b915ad9f56e81ab4eb03c Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 28 Mar 2013 12:34:35 -0400 Subject: Show running media players in the menu Each player has its own action with a dictionary state. Right now, this state only contains one key "running", which signifies whether an instance of the player is currently running. It does not yet show non-running players on startup, and ignores the blacklist. --- src/Makefile.am | 2 + src/media-player-list.vala | 70 +++++++++++++++++++++++++ src/media-player.vala | 124 +++++++++++++++++++++++++++++++++++++++++++++ src/service.vala | 40 ++++++++++++++- 4 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 src/media-player-list.vala create mode 100644 src/media-player.vala (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index 2421683..1de360c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,8 @@ music_bridge_VALASOURCES = \ service.vala \ main.vala \ volume-control.vala \ + media-player.vala \ + media-player-list.vala \ music-player-bridge.vala \ transport-menu-item.vala \ specific-items-manager.vala \ diff --git a/src/media-player-list.vala b/src/media-player-list.vala new file mode 100644 index 0000000..0c0a212 --- /dev/null +++ b/src/media-player-list.vala @@ -0,0 +1,70 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * 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; version 3. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authors: + * Lars Uebernickel + */ + +/** + * MediaPlayerList is a list of media players that should appear in the sound menu. Its main responsibility is + * to listen for MPRIS players on the bus and attach them to the corresponding %Player objects. + */ +public class MediaPlayerList { + + public MediaPlayerList () { + this._players = new HashTable (str_hash, str_equal); + + this.mpris_watcher = new Mpris2Watcher (); + this.mpris_watcher.client_appeared.connect (this.player_appeared); + this.mpris_watcher.client_disappeared.connect (this.player_disappeared); + } + + public List players { + owned get { + return this._players.get_values (); + } + } + + public signal void player_added (MediaPlayer player); + + HashTable _players; + Mpris2Watcher mpris_watcher; + + void player_appeared (string desktop_id, string dbus_name, bool use_playlists) { + var appinfo = new DesktopAppInfo (desktop_id + ".desktop"); + if (appinfo == null) { + warning ("unable to find application '%s'", desktop_id); + return; + } + + MediaPlayer? player = this._players.lookup (desktop_id); + if (player == null) { + player = new MediaPlayer (appinfo); + this._players.insert (player.id, player); + this.player_added (player); + } + + player.attach (dbus_name); + } + + void player_disappeared (string dbus_name) { + MediaPlayer? player = this._players.find ( (name, player) => { + return player.dbus_name == dbus_name; + }); + + if (player != null) + player.detach (); + } +} diff --git a/src/media-player.vala b/src/media-player.vala new file mode 100644 index 0000000..8037ddb --- /dev/null +++ b/src/media-player.vala @@ -0,0 +1,124 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * 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; version 3. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authors: + * Lars Uebernickel + */ + +/** + * MediaPlayer represents an MRPIS-capable media player. + */ +public class MediaPlayer: Object { + + public MediaPlayer (DesktopAppInfo appinfo) { + this.appinfo = appinfo; + } + + /** Desktop id of the player */ + public string id { + get { + return this.appinfo.get_id (); + } + } + + /** Display name of the player */ + public string name { + get { + return this.appinfo.get_name (); + } + } + + /** Application icon of the player */ + public Icon icon { + get { + return this.appinfo.get_icon (); + } + } + + /** + * True if an instance of the player is currently running. + * + * See also: attach(), detach() + */ + public bool is_running { + get { + return this.proxy != null; + } + } + + /** Name of the player on the bus, if an instance is currently running */ + public string dbus_name { + get { + return this._dbus_name; + } + } + + /** + * Attach this object to a process of the associated media player. The player must own @dbus_name and + * implement the org.mpris.MediaPlayer2.Player interface. + * + * Only one player can be attached at any given time. Use detach() to detach a player. + * + * This method does not block. If it is successful, "is-running" will be set to %TRUE. + */ + public void attach (string dbus_name) { + return_if_fail (this._dbus_name == null && this.proxy == null); + + this._dbus_name = dbus_name; + Bus.get_proxy.begin (BusType.SESSION, dbus_name, "/org/mpris/MediaPlayer2", + DBusProxyFlags.NONE, null, got_proxy); + } + + /** + * Detach this object from a process running the associated media player. + * + * See also: attach() + */ + public void detach () { + this.proxy = null; + this._dbus_name = null; + this.notify_property ("is-running"); + } + + /** + * Launch the associated media player. + * + * Note: this will _not_ call attach(), because it doesn't know on which dbus-name the player will appear. + * Use attach() to attach this object to a running instance of the player. + */ + public void launch () { + try { + this.appinfo.launch (null, null); + } + catch (Error e) { + warning ("unable to launch %s: %s", appinfo.get_name (), e.message); + } + } + + DesktopAppInfo appinfo; + MprisPlayer? proxy; + string _dbus_name; + + void got_proxy (Object? obj, AsyncResult res) { + try { + this.proxy = Bus.get_proxy.end (res); + this.notify_property ("is-running"); + } + catch (Error e) { + this._dbus_name = null; + warning ("unable to attach to media player: %s", e.message); + } + } +} diff --git a/src/service.vala b/src/service.vala index aa6664e..4ea4a95 100644 --- a/src/service.vala +++ b/src/service.vala @@ -2,6 +2,9 @@ public class IndicatorSound.Service { public Service () { this.volume_control = new VolumeControl (); + + this.players = new MediaPlayerList (); + this.players.player_added.connect (player_added); } public int run () { @@ -28,6 +31,8 @@ public class IndicatorSound.Service { SimpleActionGroup actions; Menu menu; VolumeControl volume_control; + MediaPlayerList players; + uint player_action_update_id; void activate_settings (SimpleAction action, Variant? param) { try { @@ -41,7 +46,7 @@ public class IndicatorSound.Service { var submenu = new Menu (); submenu.append ("Mute", "indicator.mute"); - var slider = new MenuItem ("null", "indicator.volume"); + var slider = new MenuItem (null, "indicator.volume"); slider.set_attribute ("x-canonical-type", "s", "com.canonical.unity.slider"); submenu.append_item (slider); @@ -111,4 +116,37 @@ public class IndicatorSound.Service { void name_lost (DBusConnection connection, string name) { this.loop.quit (); } + + bool update_player_action (MediaPlayer player) { + var builder = new VariantBuilder (new VariantType ("a{sv}")); + builder.add ("{sv}", "running", new Variant ("b", player.is_running)); + var state = builder.end (); + + SimpleAction? action = this.actions.lookup (player.id) as SimpleAction; + if (action == null) { + action = new SimpleAction.stateful (player.id, null, state); + action.activate.connect ( () => { player.launch (); }); + this.actions.insert (action); + } + else { + action.set_state (state); + } + + this.player_action_update_id = 0; + return false; + } + + void eventually_update_player_action (MediaPlayer player) { + if (player_action_update_id == 0) + this.player_action_update_id = Idle.add ( () => this.update_player_action (player) ); + } + + void player_added (MediaPlayer player) { + var item = new MenuItem (player.name, player.id); + item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.media-player"); + this.menu.insert_item (this.menu.get_n_items () -1, item); + + eventually_update_player_action (player); + player.notify.connect ( () => eventually_update_player_action (player) ); + } } -- cgit v1.2.3 From 838d4366a4c5e159ef7cde4caef4d908730df3a7 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 4 Apr 2013 05:51:55 +0200 Subject: Don't build unused files and remove superseded files --- configure.ac | 1 - src/Makefile.am | 56 +----- src/device.c | 276 -------------------------- src/device.h | 84 -------- src/sound-service-dbus.c | 489 ----------------------------------------------- src/sound-service-dbus.h | 66 ------- src/sound-service.c | 127 ------------ src/sound-service.h | 35 ---- src/sound-service.xml | 34 ---- 9 files changed, 1 insertion(+), 1167 deletions(-) delete mode 100644 src/device.c delete mode 100644 src/device.h delete mode 100644 src/sound-service-dbus.c delete mode 100644 src/sound-service-dbus.h delete mode 100644 src/sound-service.c delete mode 100644 src/sound-service.h delete mode 100644 src/sound-service.xml (limited to 'src/Makefile.am') diff --git a/configure.ac b/configure.ac index 119a4f4..ee5ff2b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,4 @@ AC_INIT([indicator-sound],[12.10.1],[conor.curran@canonical.com]) -AC_CONFIG_SRCDIR([src/sound-service.c]) AM_INIT_AUTOMAKE([check-news]) AC_CONFIG_HEADERS([config.h]) diff --git a/src/Makefile.am b/src/Makefile.am index 1de360c..993b0d2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,10 +1,5 @@ libexec_PROGRAMS = indicator-sound-service -checkxml: $(srcdir)/sound-service.xml - @xmllint -valid -noout $< - @echo $< checks out ok - - #################################################################### # Sound Service #################################################################### @@ -22,19 +17,9 @@ music_bridge_VALASOURCES = \ volume-control.vala \ media-player.vala \ media-player-list.vala \ - 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 + freedesktop-interfaces.vala music_bridge_VALAFLAGS = \ --ccode \ @@ -52,7 +37,6 @@ music_bridge_VALAFLAGS = \ --pkg libxml-2.0 \ --pkg libpulse \ --pkg libpulse-mainloop-glib \ - --pkg pulseaudio-mgr \ --target-glib=2.36 $(MAINTAINER_VALAFLAGS) @@ -69,24 +53,6 @@ music_bridge_vala.stamp $(music_bridge_APIFILES): $(music_bridge_VALASOURCES) ############################### indicator_sound_service_SOURCES = \ common-defs.h \ - 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) \ @@ -97,26 +63,8 @@ indicator_sound_service_CFLAGS = $(PULSEAUDIO_CFLAGS) \ 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) @@ -126,8 +74,6 @@ EXTRA_DIST = \ 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 = \ diff --git a/src/device.c b/src/device.c deleted file mode 100644 index 84db596..0000000 --- a/src/device.c +++ /dev/null @@ -1,276 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -#include - -#include "device.h" -#include "slider-menu-item.h" -#include "mute-menu-item.h" -#include "voip-input-menu-item.h" -#include "pulseaudio-mgr.h" -#include "sound-state.h" - -typedef struct _DevicePrivate DevicePrivate; - -struct _DevicePrivate -{ - SliderMenuItem* volume_slider_menuitem; - MuteMenuItem* mute_menuitem; - VoipInputMenuItem* voip_input_menu_item; - SoundState current_sound_state; - SoundServiceDbus* service; -}; - -#define DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEVICE_TYPE, DevicePrivate)) - -/* Prototypes */ -static void device_class_init (DeviceClass *klass); -static void device_init (Device *self); -static void device_dispose (GObject *object); -static void device_finalize (GObject *object); - -static SoundState device_get_state_from_volume (Device* self); -static void device_mute_update (Device* self, gboolean muted); - -G_DEFINE_TYPE (Device, device, G_TYPE_OBJECT); - -static void -device_class_init (DeviceClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (DevicePrivate)); - - gobject_class->dispose = device_dispose; - gobject_class->finalize = device_finalize; -} - -static void -device_init (Device *self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - priv->mute_menuitem = NULL; - priv->volume_slider_menuitem = NULL; - priv->voip_input_menu_item = NULL; - priv->current_sound_state = UNAVAILABLE; - priv->service = NULL; - - // Init our menu items. - priv->mute_menuitem = g_object_new (MUTE_MENU_ITEM_TYPE, NULL); - priv->voip_input_menu_item = g_object_new (VOIP_INPUT_MENU_ITEM_TYPE, NULL);; - priv->volume_slider_menuitem = slider_menu_item_new (self); - mute_menu_item_enable (priv->mute_menuitem, FALSE); - slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); -} - -static void -device_dispose (GObject *object) -{ - G_OBJECT_CLASS (device_parent_class)->dispose (object); -} - -static void -device_finalize (GObject *object) -{ - G_OBJECT_CLASS (device_parent_class)->finalize (object); -} - -void -device_sink_populate (Device* self, - const pa_sink_info* update) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE(self); - mute_menu_item_enable (priv->mute_menuitem, TRUE); - slider_menu_item_populate (priv->volume_slider_menuitem, update); - SoundState state = device_get_state_from_volume (self); - if (priv->current_sound_state != state){ - priv->current_sound_state = state; - sound_service_dbus_update_sound_state (priv->service, - priv->current_sound_state); - } - device_mute_update (self, update->mute); -} - -void -device_sink_update (Device* self, - const pa_sink_info* update) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - slider_menu_item_update (priv->volume_slider_menuitem, update); - - SoundState state = device_get_state_from_volume (self); - if (priv->current_sound_state != state){ - priv->current_sound_state = state; - sound_service_dbus_update_sound_state (priv->service, - priv->current_sound_state); - } - - device_mute_update (self, update->mute); -} - -gint -device_get_voip_source_output_index (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - return voip_input_menu_item_get_source_output_index (priv->voip_input_menu_item); -} - -static void -device_mute_update (Device* self, gboolean muted) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - mute_menu_item_update (priv->mute_menuitem, muted); - SoundState state = device_get_state_from_volume (self); - - if (muted == TRUE){ - state = MUTED; - } - // Only send signals if something has changed - if (priv->current_sound_state != state){ - priv->current_sound_state = state; - sound_service_dbus_update_sound_state (priv->service, state); - } -} - -void -device_ensure_sink_is_unmuted (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - if (mute_menu_item_is_muted (priv->mute_menuitem)){ - pm_update_mute (FALSE); - } -} - - -static SoundState -device_get_state_from_volume (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - GVariant* v = dbusmenu_menuitem_property_get_variant (DBUSMENU_MENUITEM(priv->volume_slider_menuitem), - DBUSMENU_VOLUME_MENUITEM_LEVEL); - gdouble volume_percent = g_variant_get_double (v); - - return sound_state_get_from_volume ((int)volume_percent); -} - -void -device_determine_blocking_state (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - if (mute_menu_item_is_muted (priv->mute_menuitem)){ - /** - We don't want to set the current state to blocking - as this is a fire and forget event. - */ - sound_service_dbus_update_sound_state (priv->service, - BLOCKED); - } -} - -gint -device_get_sink_index (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - return slider_menu_item_get_sink_index (priv->volume_slider_menuitem); -} - -gboolean -device_is_sink_populated (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - return dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM (priv->volume_slider_menuitem), - DBUSMENU_MENUITEM_PROP_ENABLED); -} - -void -device_activate_voip_item (Device* self, gint source_output_index, gint client_index) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - if (voip_input_menu_item_is_interested (priv->voip_input_menu_item, - source_output_index, - client_index)){ - voip_input_menu_item_enable (priv->voip_input_menu_item, TRUE); - } -} - -void -device_deactivate_voip_source (Device* self, gboolean visible) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - visible &= voip_input_menu_item_is_active (priv->voip_input_menu_item); - voip_input_menu_item_deactivate_source (priv->voip_input_menu_item, visible); -} - -void -device_deactivate_voip_client (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - voip_input_menu_item_deactivate_voip_client (priv->voip_input_menu_item); -} - -void -device_sink_deactivated (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - priv->current_sound_state = UNAVAILABLE; - sound_service_dbus_update_sound_state (priv->service, - priv->current_sound_state); - mute_menu_item_enable (priv->mute_menuitem, FALSE); - slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); -} - -SoundState -device_get_state (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - return priv->current_sound_state; -} - -void -device_update_voip_input_source (Device* self, const pa_source_info* update) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - voip_input_menu_item_update (priv->voip_input_menu_item, update); -} - -gboolean -device_is_voip_source_populated (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - return voip_input_menu_item_is_populated (priv->voip_input_menu_item); -} - -gint device_get_source_index (Device* self) -{ - DevicePrivate* priv = DEVICE_GET_PRIVATE (self); - return voip_input_menu_item_get_index (priv->voip_input_menu_item); -} - -Device* -device_new (SoundServiceDbus* service) -{ - Device* sink = g_object_new (DEVICE_TYPE, NULL); - DevicePrivate* priv = DEVICE_GET_PRIVATE (sink); - priv->service = service; - sound_service_dbus_build_sound_menu (service, - mute_menu_item_get_button (priv->mute_menuitem), - DBUSMENU_MENUITEM (priv->volume_slider_menuitem), - DBUSMENU_MENUITEM (priv->voip_input_menu_item)); - pm_establish_pulse_connection (sink); - return sink; -} diff --git a/src/device.h b/src/device.h deleted file mode 100644 index ccaf4ea..0000000 --- a/src/device.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2010 Canonical Ltd. - * - * Authors: - * Conor Curran - * - * 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 . - */ - -#ifndef __DEVICE_H__ -#define __DEVICE_H__ - -#include -#include - -#include "common-defs.h" -#include "sound-service-dbus.h" - -#include - -G_BEGIN_DECLS - -#define DEVICE_TYPE (device_get_type ()) -#define DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DEVICE_TYPE, Device)) -#define DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), DEVICE_TYPE, DeviceClass)) -#define IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DEVICE_TYPE)) -#define IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DEVICE_TYPE)) -#define DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DEVICE_TYPE, DeviceClass)) - -typedef struct _Device Device; -typedef struct _DeviceClass DeviceClass; - -struct _Device { - GObject parent; -}; - -struct _DeviceClass { - GObjectClass parent_class; -}; - -GType device_get_type (void) G_GNUC_CONST; - -/** - * TODO - * Refactor this to become a device manager obj basically acting as wrapper for - * the communication between pulseaudio-mgr and the individual items. - * First steps collapse slider/volume related stuff into slider-menu-item. - */ - -// Sink related -void device_sink_populate (Device* sink, const pa_sink_info* update); -void device_sink_update (Device* sink, const pa_sink_info* update); -gboolean device_is_sink_populated (Device* sink); -gint device_get_sink_index (Device* self); -void device_sink_deactivated (Device* self); -void device_update_mute (Device* self, gboolean mute_update); -void device_ensure_sink_is_unmuted (Device* self); - -// source and sinkinput/client related for VOIP functionality -void device_update_voip_input_source (Device* sink, const pa_source_info* update); -void device_activate_voip_item (Device* sink, gint source_output_index, gint client_index); -gint device_get_voip_source_output_index (Device* sink); -gboolean device_is_voip_source_populated (Device* sink); -gint device_get_source_index (Device* self); -void device_determine_blocking_state (Device* self); -void device_deactivate_voip_source (Device* self, gboolean visible); -void device_deactivate_voip_client (Device* self); -SoundState device_get_state (Device* self); - -Device* device_new (SoundServiceDbus* service); - -G_END_DECLS - -#endif diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c deleted file mode 100644 index 5e004cb..0000000 --- a/src/sound-service-dbus.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright 2010 Canonical Ltd. - * - * Authors: - * Conor Curran - * - * 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 . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include - -#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; - guint registration_id; -}; - -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, - const gchar* player_name, - gboolean blacklist); - -static gboolean sound_service_dbus_is_blacklisted (SoundServiceDbus* self, - const 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_critical ("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_critical("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_critical ("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 */ - priv->registration_id = g_dbus_connection_register_object (priv->connection, - INDICATOR_SOUND_SERVICE_DBUS_OBJECT_PATH, - interface_info, - &interface_table, - self, - NULL, - &error); - if (error != NULL) { - g_critical ("Unable to register the sound service on DBus: %s", error->message); - g_error_free (error); - } -} - -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) -{ - SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (object); - - if (priv->connection && priv->registration_id) { - g_dbus_connection_unregister_object (priv->connection, priv->registration_id); - priv->registration_id = 0; - } - - g_clear_object(&priv->connection); - - 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 - dbus 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; - const 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) { - const 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, - const 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, - const 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/sound-service-dbus.h b/src/sound-service-dbus.h deleted file mode 100644 index 1c15fc7..0000000 --- a/src/sound-service-dbus.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2010 Canonical Ltd. - * - * Authors: - * Conor Curran - * - * 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 . - */ - -#ifndef __SOUND_SERVICE_DBUS_H__ -#define __SOUND_SERVICE_DBUS_H__ - -#include -#include -#include -#include "common-defs.h" - - -G_BEGIN_DECLS - -#define SOUND_SERVICE_DBUS_TYPE (sound_service_dbus_get_type ()) -#define SOUND_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SOUND_SERVICE_DBUS_TYPE, SoundServiceDbus)) -#define SOUND_SERVICE_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SOUND_SERVICE_DBUS_TYPE, SoundServiceDbusClass)) -#define IS_SOUND_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SOUND_SERVICE_DBUS_TYPE)) -#define IS_SOUND_SERVICE_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SOUND_SERVICE_DBUS_TYPE)) -#define SOUND_SERVICE_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SOUND_SERVICE_DBUS_TYPE, SoundServiceDbusClass)) - -typedef struct _SoundServiceDbus SoundServiceDbus; -typedef struct _SoundServiceDbusClass SoundServiceDbusClass; -typedef struct _SoundData SoundData; - -struct _SoundData { - SoundServiceDbus *service; -}; - -struct _SoundServiceDbus { - GObject parent; -}; - -struct _SoundServiceDbusClass { - GObjectClass parent_class; -}; - -GType sound_service_dbus_get_type (void) G_GNUC_CONST; - -DbusmenuMenuitem* sound_service_dbus_create_root_item (SoundServiceDbus* self, gboolean greeter_mode); -void sound_service_dbus_update_sound_state (SoundServiceDbus* self, SoundState new_state); -void sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, - DbusmenuMenuitem* mute_item, - DbusmenuMenuitem* slider_item, - DbusmenuMenuitem* voip_input_menu_item); - - -G_END_DECLS - -#endif diff --git a/src/sound-service.c b/src/sound-service.c deleted file mode 100644 index 0170f81..0000000 --- a/src/sound-service.c +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#include - -#include "sound-service.h" -#include "pulseaudio-mgr.h" -#include "sound-service-dbus.h" -#include "music-player-bridge.h" - -static GMainLoop *mainloop = NULL; -static MusicPlayerBridge* player_bridge = NULL; -/***********************************************************************************************************/ -// Init and exit functions -/**********************************************************************************************************************/ -/** -service_shutdown: -When the service interface starts to shutdown, we -should follow it. -**/ - -void -service_shutdown (IndicatorService *service, gpointer user_data) -{ - if (mainloop != NULL) { - g_debug("Service shutdown !"); - close_pulse_activites(); - g_main_loop_quit(mainloop); - } - return; -} - -static gboolean -get_greeter_mode (void) -{ - const gchar *var; - var = g_getenv("INDICATOR_GREETER_MODE"); - return (g_strcmp0(var, "1") == 0); -} - -void -on_player_specific_item_requested (SoundServiceDbus* sound_service, - const gchar* desktop_id, - const gchar* player_object_path, - gpointer userdata) -{ - if (player_bridge != NULL){ - music_player_bridge_enable_player_specific_items_for_client (player_bridge, - desktop_id, - player_object_path); - } -} - -void -on_track_specific_item_requested (SoundServiceDbus* sound_service, - const gchar* desktop_id, - const gchar* player_object_path, - gpointer userdata) -{ - if (player_bridge != NULL){ - music_player_bridge_enable_track_specific_items_for_client (player_bridge, - desktop_id, - player_object_path); - } -} - -/** -main: -**/ -int -main (int argc, char ** argv) -{ - gboolean greeter_mode; - - g_type_init(); - textdomain (GETTEXT_PACKAGE); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - setlocale (LC_ALL, ""); - - IndicatorService *service = indicator_service_new_version (INDICATOR_SOUND_DBUS_NAME, - INDICATOR_SOUND_DBUS_VERSION); - g_signal_connect(G_OBJECT(service), - INDICATOR_SERVICE_SIGNAL_SHUTDOWN, - G_CALLBACK(service_shutdown), NULL); - - SoundServiceDbus* sound_service = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL); - g_signal_connect(G_OBJECT(sound_service), - "track-specific-item-requested", - G_CALLBACK(on_track_specific_item_requested), NULL); - g_signal_connect(G_OBJECT(sound_service), - "player-specific-item-requested", - G_CALLBACK(on_player_specific_item_requested), NULL); - - greeter_mode = get_greeter_mode(); - - DbusmenuMenuitem* root_menuitem = sound_service_dbus_create_root_item(sound_service, greeter_mode); - if (!greeter_mode) { - player_bridge = music_player_bridge_new(); - music_player_bridge_set_root_menu_item(player_bridge, root_menuitem); - } - - // Run the loop - mainloop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(mainloop); - - return 0; -} - - - - diff --git a/src/sound-service.h b/src/sound-service.h deleted file mode 100644 index 7c5d0c3..0000000 --- a/src/sound-service.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __INCLUDE_SOUND_SERVICE_H__ -#define __INCLUDE_SOUND_SERVICE_H__ - -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#include -#include -#include - -#include - -#include "dbus-shared-names.h" - -// ENTRY AND EXIT POINTS -void service_shutdown(IndicatorService * service, gpointer user_data); -int main (int argc, char ** argv); - -#endif diff --git a/src/sound-service.xml b/src/sound-service.xml deleted file mode 100644 index cb1d928..0000000 --- a/src/sound-service.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 69fc4a3d92bbbf5940769d877650e45a9c2b913b Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 4 Apr 2013 05:57:18 +0200 Subject: Remove sound-service-marshal (not needed anymore) --- Makefile.am.marshal | 45 ------------------------------------------ configure.ac | 3 --- src/Makefile.am | 10 ---------- src/sound-service-marshal.list | 2 -- 4 files changed, 60 deletions(-) delete mode 100644 Makefile.am.marshal delete mode 100644 src/sound-service-marshal.list (limited to 'src/Makefile.am') diff --git a/Makefile.am.marshal b/Makefile.am.marshal deleted file mode 100644 index a6ab024..0000000 --- a/Makefile.am.marshal +++ /dev/null @@ -1,45 +0,0 @@ -# Rules for generating marshal files using glib-genmarshal -# -# Define: -# glib_marshal_list = marshal list file -# glib_marshal_prefix = prefix for marshal functions -# -# before including Makefile.am.marshal. You will also need to have -# the following targets already defined: -# -# CLEANFILES -# DISTCLEANFILES -# BUILT_SOURCES -# EXTRA_DIST -# -# Author: Emmanuele Bassi - -marshal_h = $(glib_marshal_list:.list=.h) -marshal_c = $(glib_marshal_list:.list=.c) - -CLEANFILES += stamp-marshal -DISTCLEANFILES += $(marshal_h) $(marshal_c) -BUILT_SOURCES += $(marshal_h) $(marshal_c) -EXTRA_DIST += $(glib_marshal_list) - -stamp-marshal: $(glib_marshal_list) - $(QUIET_GEN)$(GLIB_GENMARSHAL) \ - --prefix=$(glib_marshal_prefix) \ - --header \ - $(srcdir)/$(glib_marshal_list) > xgen-mh \ - && (cmp -s xgen-mh $(marshal_h) || cp -f xgen-mh $(marshal_h)) \ - && rm -f xgen-mh \ - && echo timestamp > $(@F) - -$(marshal_h): stamp-marshal - @true - -$(marshal_c): $(marshal_h) - $(QUIET_GEN)(echo "#include \"$(marshal_h)\"" ; \ - $(GLIB_GENMARSHAL) \ - --prefix=$(glib_marshal_prefix) \ - --body \ - $(srcdir)/$(glib_marshal_list)) > xgen-mc \ - && cp xgen-mc $(marshal_c) \ - && rm -f xgen-mc - diff --git a/configure.ac b/configure.ac index ee5ff2b..8fdebb8 100644 --- a/configure.ac +++ b/configure.ac @@ -21,8 +21,6 @@ AC_CONFIG_MACRO_DIR([m4]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) -AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal]) - ########################### # Dependencies ########################### @@ -75,7 +73,6 @@ AC_ARG_ENABLE(localinstall, AS_HELP_STRING([--enable-localinstall], [install all ########################### GLIB_GSETTINGS -GLIB_GENMARSHAL ########################### # DBus Service Info diff --git a/src/Makefile.am b/src/Makefile.am index 993b0d2..afbc364 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,13 +1,5 @@ libexec_PROGRAMS = indicator-sound-service -#################################################################### -# Sound Service -#################################################################### - -glib_marshal_list = sound-service-marshal.list -glib_marshal_prefix = _sound_service_marshal - - ##################### # Sound service vala ##################### @@ -80,5 +72,3 @@ CLEANFILES = \ $(BUILT_SOURCES) DISTCLEANFILES = - -include $(top_srcdir)/Makefile.am.marshal diff --git a/src/sound-service-marshal.list b/src/sound-service-marshal.list deleted file mode 100644 index 4c756d4..0000000 --- a/src/sound-service-marshal.list +++ /dev/null @@ -1,2 +0,0 @@ -VOID:STRING,STRING - -- cgit v1.2.3 From 77e3a0bb0453f7be6d98a068345ef4484ebf7792 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 4 Apr 2013 06:11:15 +0200 Subject: Modernize vala compiling in Makefile.am This fixes parallel builds. --- src/Makefile.am | 43 +++---------------------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index afbc364..083c5c2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,7 @@ libexec_PROGRAMS = indicator-sound-service -##################### -# Sound service vala -##################### -music_bridge_VALASOURCES = \ +indicator_sound_service_SOURCES = \ + common-defs.h \ service.vala \ main.vala \ volume-control.vala \ @@ -13,9 +11,8 @@ music_bridge_VALASOURCES = \ mpris2-watcher.vala \ freedesktop-interfaces.vala -music_bridge_VALAFLAGS = \ +indicator_sound_service_VALAFLAGS = \ --ccode \ - -H music-player-bridge.h -d . \ --vapidir=$(top_srcdir)/vapi/ \ --vapidir=./ \ --thread \ @@ -31,22 +28,6 @@ music_bridge_VALAFLAGS = \ --pkg libpulse-mainloop-glib \ --target-glib=2.36 - $(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 \ - $(music_bridge_VALASOURCES:.vala=.c) - indicator_sound_service_CFLAGS = $(PULSEAUDIO_CFLAGS) \ $(SOUNDSERVICE_CFLAGS) \ $(GCONF_CFLAGS) \ @@ -54,21 +35,3 @@ indicator_sound_service_CFLAGS = $(PULSEAUDIO_CFLAGS) \ -DLIBEXECDIR=\"$(libexecdir)\" -Wall indicator_sound_service_LDADD = $(PULSEAUDIO_LIBS) $(SOUNDSERVICE_LIBS) $(GCONF_LIBS) indicator_sound_service_LDFLAGS = $(COVERAGE_LDFLAGS) - -EXTRA_DIST = \ - $(DBUS_SPECS) \ - $(music_bridge_APIFILES) \ - $(music_bridge_VALASOURCES) - -####################### -# Stuff to clean Stuff -####################### -BUILT_SOURCES = \ - music_bridge_vala.stamp \ - $(music_bridge_APIFILES) \ - $(music_bridge_VALASOURCES:.vala=.c) - -CLEANFILES = \ - $(BUILT_SOURCES) - -DISTCLEANFILES = -- cgit v1.2.3 From cb8cb6ef16fc0884d2499421fbeeca12e3288b56 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 18 Jun 2013 08:03:10 -0400 Subject: Remove obsolete files (gtk and dbusmenu) --- Makefile.am | 1 - src/Makefile.am | 5 - src/dbus-shared-names.h | 37 --- src/fetch-file.vala | 86 ----- src/metadata-menu-item.vala | 220 ------------ src/mpris2-controller.vala | 286 ---------------- src/mpris2-watcher.vala | 2 - src/music-player-bridge.vala | 305 ----------------- src/mute-menu-item.c | 154 --------- src/mute-menu-item.h | 59 ---- src/player-controller.vala | 247 -------------- src/player-item.vala | 104 ------ src/playlists-menu-item.vala | 154 --------- src/pulseaudio-mgr.c | 717 ---------------------------------------- src/pulseaudio-mgr.h | 33 -- src/scrub-menu-item.vala | 56 ---- src/settings-manager.vala | 136 -------- src/slider-menu-item.c | 258 --------------- src/slider-menu-item.h | 64 ---- src/sound-state.c | 43 --- src/sound-state.h | 31 -- src/specific-items-manager.vala | 109 ------ src/transport-menu-item.vala | 97 ------ src/voip-input-menu-item.c | 278 ---------------- vapi/common-defs.vapi | 70 ---- 25 files changed, 3552 deletions(-) delete mode 100644 src/dbus-shared-names.h delete mode 100644 src/fetch-file.vala delete mode 100644 src/metadata-menu-item.vala delete mode 100644 src/mpris2-controller.vala delete mode 100644 src/music-player-bridge.vala delete mode 100644 src/mute-menu-item.c delete mode 100644 src/mute-menu-item.h delete mode 100644 src/player-controller.vala delete mode 100644 src/player-item.vala delete mode 100644 src/playlists-menu-item.vala delete mode 100644 src/pulseaudio-mgr.c delete mode 100644 src/pulseaudio-mgr.h delete mode 100644 src/scrub-menu-item.vala delete mode 100644 src/settings-manager.vala delete mode 100644 src/slider-menu-item.c delete mode 100644 src/slider-menu-item.h delete mode 100644 src/sound-state.c delete mode 100644 src/sound-state.h delete mode 100644 src/specific-items-manager.vala delete mode 100644 src/transport-menu-item.vala delete mode 100644 src/voip-input-menu-item.c delete mode 100644 vapi/common-defs.vapi (limited to 'src/Makefile.am') diff --git a/Makefile.am b/Makefile.am index 4753003..3ba6110 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,6 @@ SUBDIRS = \ EXTRA_DIST = \ autogen.sh \ - vapi/common-defs.vapi \ vapi/config.vapi DISTCHECK_CONFIGURE_FLAGS = --enable-localinstall diff --git a/src/Makefile.am b/src/Makefile.am index 083c5c2..84ee0f1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,6 @@ libexec_PROGRAMS = indicator-sound-service indicator_sound_service_SOURCES = \ - common-defs.h \ service.vala \ main.vala \ volume-control.vala \ @@ -16,13 +15,9 @@ indicator_sound_service_VALAFLAGS = \ --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 \ --pkg libpulse \ --pkg libpulse-mainloop-glib \ diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h deleted file mode 100644 index 2517eb9..0000000 --- a/src/dbus-shared-names.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - Ted Gould - -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 . -*/ - - -#ifndef __DBUS_SHARED_NAMES_H__ -#define __DBUS_SHARED_NAMES_H__ - -#define INDICATOR_SOUND_DBUS_NAME "com.canonical.indicator.sound" -#define INDICATOR_SOUND_MENU_DBUS_OBJECT_PATH "/com/canonical/indicator/sound/menu" -#define INDICATOR_SOUND_SERVICE_DBUS_OBJECT_PATH "/com/canonical/indicator/sound/service" -#define INDICATOR_SOUND_DBUS_INTERFACE "com.canonical.indicator.sound" -#define INDICATOR_SOUND_DBUS_VERSION 0 - -#define INDICATOR_SOUND_SIGNAL_STATE_UPDATE "SoundStateUpdate" - - -#endif /* __DBUS_SHARED_NAMES_H__ */ diff --git a/src/fetch-file.vala b/src/fetch-file.vala deleted file mode 100644 index e94afef..0000000 --- a/src/fetch-file.vala +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2010 Canonical, Ltd. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License - * version 3.0 as published by the Free Software Foundation. - * - * This library 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 Lesser General Public License version 3.0 for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors - * Gordon Allott - * Conor Curran - */ - -public class FetchFile : Object -{ - /* public variables */ - public string uri {get; construct;} - public string intended_property {get; construct;} - - /* private variables */ - private DataInputStream stream; - private File? file; - private ByteArray data; - - /* public signals */ - public signal void failed (); - public signal void completed (ByteArray data, string property); - - public FetchFile (string uri, string prop) - { - Object (uri: uri, intended_property: prop); - } - - construct - { - this.file = File.new_for_uri(this.uri); - this.data = new ByteArray (); - } - - public async void fetch_data () - { - try { - this.stream = new DataInputStream(this.file.read(null)); - this.stream.set_byte_order (DataStreamByteOrder.LITTLE_ENDIAN); - } catch (GLib.Error e) { - this.failed (); - } - this.read_something_async (); - } - - private async void read_something_async () - { - ssize_t size = 1024; - uint8[] buffer = new uint8[size]; - - ssize_t bufsize = 1; - do { - try { - bufsize = yield this.stream.read_async (buffer, GLib.Priority.DEFAULT, null); - if (bufsize < 1) { break;} - - if (bufsize != size) - { - uint8[] cpybuf = new uint8[bufsize]; - Memory.copy (cpybuf, buffer, bufsize); - this.data.append (cpybuf); - } - else - { - this.data.append (buffer); - } - } catch (Error e) { - this.failed (); - } - } while (bufsize > 0); - this.completed (this.data, this.intended_property); - } -} diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala deleted file mode 100644 index b2dd752..0000000 --- a/src/metadata-menu-item.vala +++ /dev/null @@ -1,220 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -using Gee; -using Dbusmenu; -using DbusmenuMetadata; -using Gdk; - -public class MetadataMenuitem : PlayerItem -{ - public const string ALBUM_ART_DIR_SUFFIX = "indicator/sound/album-art-cache"; - - public static string album_art_cache_dir; - private static FetchFile fetcher; - private string previous_temp_album_art_path; - - public MetadataMenuitem (PlayerController parent) - { - Object(item_type: MENUITEM_TYPE, owner: parent); - } - - construct{ - MetadataMenuitem.clean_album_art_temp_dir(); - this.previous_temp_album_art_path = null; - this.album_art_cache_dir = MetadataMenuitem.create_album_art_temp_dir(); - //debug ("JUST ABOUT TO ATTEMPT PLAYER NAME SETTING %s", this.owner.app_info.get_name()); - this.property_set (MENUITEM_PLAYER_NAME, this.owner.app_info.get_name()); - this.property_set (MENUITEM_PLAYER_ICON, this.owner.icon_name); - this.property_set_bool (MENUITEM_PLAYER_RUNNING, false); - this.property_set_bool (MENUITEM_HIDE_TRACK_DETAILS, true); - reset (relevant_attributes_for_ui()); - } - - private static void clean_album_art_temp_dir() - { - string path = GLib.Path.build_filename(Environment.get_user_cache_dir(), ALBUM_ART_DIR_SUFFIX); - - GLib.File? album_art_dir = GLib.File.new_for_path(path); - - if(delete_album_art_contents(album_art_dir) == false) - { - warning("could not remove the temp album art files %s", path); - } - } - - private static string? create_album_art_temp_dir() - { - string path = GLib.Path.build_filename(Environment.get_user_cache_dir(), ALBUM_ART_DIR_SUFFIX); - if(DirUtils.create_with_parents(path, 0700) == -1){ - warning("could not create temp dir %s for remote album art, it must have been created already", path); - } - return path; - } - - private static bool delete_album_art_contents (GLib.File dir) - { - bool result = true; - try { - var e = dir.enumerate_children (FILE_ATTRIBUTE_STANDARD_NAME, - FileQueryInfoFlags.NOFOLLOW_SYMLINKS, - null); - while (true) - { - var file = e.next_file (null); - - if (file == null) - break; - - debug("file name = %s", file.get_name()); - - var child = dir.get_child (file.get_name ()); - - try { - child.delete (null); - } catch (Error error_) { - warning (@"Unable to delete file '$(child.get_basename ()): $(error_.message)"); - result = false; - } - } - } catch (Error error) { - warning (@"Unable to read files from directory '$(dir.get_basename ())': %s", - error.message); - result = false; - } - return result; - } - - public void fetch_art(string uri, string prop) - { - File art_file = File.new_for_uri(uri); - if (art_file.is_native() == true){ - if (art_file.query_exists() == false){ - // Can't load the image, set prop to empty and return. - this.property_set_int ( prop, EMPTY ); - return; - } - string path; - try{ - path = Filename.from_uri ( uri.strip() ); - debug ("Populating the artwork field with %s", uri.strip()); - this.property_set ( prop, path ); - } - catch(ConvertError e){ - warning("Problem converting URI %s to file path", - uri); - } - // eitherway return, the artwork was local - return; - } - debug("fetch_art -remotely %s", this.album_art_cache_dir); - // If we didn't manage to create the temp dir - // don't bother with remote - if(this.album_art_cache_dir == null){ - return; - } - // green light to go remote - this.fetcher = new FetchFile (uri, prop); - this.fetcher.failed.connect (() => { this.on_fetcher_failed ();}); - this.fetcher.completed.connect (this.on_fetcher_completed); - this.fetcher.fetch_data (); - } - - private void on_fetcher_failed () - { - warning("on_fetcher_failed -> could not fetch artwork"); - } - - private void on_fetcher_completed(ByteArray update, string property) - { - try{ - PixbufLoader loader = new PixbufLoader (); - loader.write (update.data); - loader.close (); - Pixbuf icon = loader.get_pixbuf (); - string path = this.album_art_cache_dir.concat("/downloaded-coverart-XXXXXX"); - int r = FileUtils.mkstemp(path); - if(r != -1){ - icon.save (path, loader.get_format().get_name()); - this.property_set(property, path); - if(this.previous_temp_album_art_path != null){ - FileUtils.remove(this.previous_temp_album_art_path); - } - this.previous_temp_album_art_path = path; - } - } - catch(GLib.Error e){ - warning("Problem creating file from bytearray fetched from the interweb - error: %s", - e.message); - } - } - - public override void handle_event (string name, - Variant input_value, - uint timestamp) - { - if(this.owner.current_state == PlayerController.state.OFFLINE) - { - this.owner.instantiate(); - } - else if(this.owner.current_state == PlayerController.state.CONNECTED){ - this.owner.mpris_bridge.expose(); - } - } - - public void alter_label (string? new_title) - { - if (new_title == null) return; - this.property_set (MENUITEM_PLAYER_NAME, new_title); - } - - public void toggle_active_triangle (bool update) - { - debug ("toggle active triangle"); - this.property_set_bool (MENUITEM_PLAYER_RUNNING, update); - } - - public void should_collapse(bool collapse) - { - this.property_set_bool (MENUITEM_HIDE_TRACK_DETAILS, collapse); - } - - public static HashSet attributes_format() - { - HashSet attrs = new HashSet(); - attrs.add(MENUITEM_TITLE); - attrs.add(MENUITEM_ARTIST); - attrs.add(MENUITEM_ALBUM); - attrs.add(MENUITEM_ARTURL); - attrs.add(MENUITEM_PLAYER_NAME); - attrs.add(MENUITEM_PLAYER_ICON); - attrs.add(MENUITEM_PLAYER_RUNNING); - return attrs; - } - - public static HashSet relevant_attributes_for_ui() - { - HashSet attrs = new HashSet(); - attrs.add(MENUITEM_TITLE); - attrs.add(MENUITEM_ARTIST); - attrs.add(MENUITEM_ALBUM); - attrs.add(MENUITEM_ARTURL); - return attrs; - } -} diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala deleted file mode 100644 index 2cc8d12..0000000 --- a/src/mpris2-controller.vala +++ /dev/null @@ -1,286 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -using Dbusmenu; -using Transport; - -public class Mpris2Controller : GLib.Object -{ - public const int MAX_PLAYLIST_COUNT = 100; - - public MprisRoot mpris2_root {get; construct;} - public MprisPlayer player {get; construct;} - public MprisPlaylists playlists {get; construct;} - public FreeDesktopProperties properties_interface {get; construct;} - public PlayerController owner {get; construct;} - - public Mpris2Controller(PlayerController ctrl) - { - GLib.Object(owner: ctrl); - } - - construct{ - try { - this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, - this.owner.dbus_name, - "/org/mpris/MediaPlayer2" ); - this.player = Bus.get_proxy_sync ( BusType.SESSION, - this.owner.dbus_name, - "/org/mpris/MediaPlayer2" ); - this.properties_interface = Bus.get_proxy_sync ( BusType.SESSION, - "org.freedesktop.Properties.PropertiesChanged", - "/org/mpris/MediaPlayer2" ); - this.properties_interface.PropertiesChanged.connect ( property_changed_cb ); - if ( this.owner.use_playlists == true ){ - this.playlists = Bus.get_proxy_sync ( BusType.SESSION, - this.owner.dbus_name, - "/org/mpris/MediaPlayer2" ); - this.playlists.PlaylistChanged.connect (on_playlistdetails_changed); - } - } - catch (IOError e) { - critical("Problems connecting to the session bus - %s", e.message); - } - } - /* - * property_changed_cb - * Called when a property changed signal is emitted from any of mpris - * objects on the bus. - * Note that the signal will be received by each instance for each player - * and at that moment there is no way to know what player that signal - * came from therefore it is necessary to query each relevant property - * to update the respective dbusmenuitem property inorder to keep the UI in sync - * Please also note due to some race condition in the depths of gdbus - * a timeout is needed between receiving the prop update and query the respective property. - * This can be seen at various points below. - */ - public void property_changed_cb ( string interface_source, - HashTable changed_properties, - string[] invalid ) - { - if ( changed_properties == null || - interface_source.has_prefix ( MPRIS_PREFIX ) == false ){ - warning("Property-changed hash is null or this is an interface that doesn't concern us"); - return; - } - Variant? play_v = changed_properties.lookup("PlaybackStatus"); - if(play_v != null){ - string state = this.player.PlaybackStatus; - Timeout.add ( 200, ensure_correct_playback_status ); - Transport.State p = (Transport.State)this.determine_play_state(state); - (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); - } - Variant? meta_v = changed_properties.lookup("Metadata"); - if(meta_v != null) - { - Timeout.add ( 200, ensure_correct_metadata ); - } - Variant? playlist_v = changed_properties.lookup("ActivePlaylist"); - if ( playlist_v != null && this.owner.use_playlists == true ){ - Timeout.add (500, this.fetch_active_playlist); - } - Variant? playlist_count_v = changed_properties.lookup("PlaylistCount"); - if ( playlist_count_v != null && this.owner.use_playlists == true ){ - this.fetch_playlists.begin(); - this.fetch_active_playlist(); - } - Variant? playlist_orderings_v = changed_properties.lookup("Orderings"); - if ( playlist_orderings_v != null && this.owner.use_playlists == true ){ - this.fetch_playlists.begin(); - this.fetch_active_playlist(); - } - Variant? identity_v = changed_properties.lookup("Identity"); - if (identity_v != null){ - MetadataMenuitem md = this.owner.custom_items[PlayerController.widget_order.METADATA] as MetadataMenuitem; - md.alter_label (this.mpris2_root.Identity); - } - } - - private bool ensure_correct_metadata () - { - GLib.HashTable changed_updates = clean_metadata(); - PlayerItem metadata = this.owner.custom_items[PlayerController.widget_order.METADATA]; - metadata.reset (MetadataMenuitem.relevant_attributes_for_ui()); - metadata.update ( changed_updates, - MetadataMenuitem.relevant_attributes_for_ui()); - MetadataMenuitem md = this.owner.custom_items[PlayerController.widget_order.METADATA] as MetadataMenuitem; - bool collapsing = !metadata.populated(MetadataMenuitem.relevant_attributes_for_ui()); - md.should_collapse(collapsing); - - return false; - } - - private bool ensure_correct_playback_status() - { - Transport.State p = (Transport.State)this.determine_play_state(this.player.PlaybackStatus); - (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); - return false; - } - - private GLib.HashTable? clean_metadata() - { - GLib.HashTable changed_updates = this.player.Metadata; - - Variant? artist_v = this.player.Metadata.lookup("xesam:artist"); - if(artist_v != null){ - string display_artists; - // Accomodate Spotify (should return 'as' and not 's') - if(artist_v.get_type_string() == "s"){ - display_artists = artist_v.get_string(); - } - else{ - string[] artists = artist_v.dup_strv(); - display_artists = string.joinv(", ", artists); - } - changed_updates.replace("xesam:artist", display_artists); - } - return changed_updates; - } - - private Transport.State determine_play_state(string? status){ - if(status != null && status == "Playing"){ - return Transport.State.PLAYING; - } - return Transport.State.PAUSED; - } - - public void initial_update() - { - Transport.State update; - - if(this.player.PlaybackStatus == null){ - update = Transport.State.PAUSED; - } - else{ - update = determine_play_state (this.player.PlaybackStatus); - } - if (this.mpris2_root.Identity != null){ - MetadataMenuitem md = this.owner.custom_items[PlayerController.widget_order.METADATA] as MetadataMenuitem; - md.alter_label (this.mpris2_root.Identity); - } - (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state (update); - GLib.HashTable? cleaned_metadata = this.clean_metadata(); - this.owner.custom_items[PlayerController.widget_order.METADATA].update (cleaned_metadata, - MetadataMenuitem.attributes_format()); - - if ( this.owner.use_playlists == true ){ - this.fetch_playlists.begin(); - this.fetch_active_playlist(); - } - } - - public void transport_update(Transport.Action command) - { - if(command == Transport.Action.PLAY_PAUSE){ - this.player.PlayPause.begin(); - } - else if(command == Transport.Action.PREVIOUS){ - this.player.Previous.begin(); - } - else if(command == Transport.Action.NEXT){ - this.player.Next.begin(); - } - else if(command == Transport.Action.REWIND){ - this.player.Seek.begin(-500000); - } - else if(command == Transport.Action.FORWIND){ - this.player.Seek.begin(400000); - } - } - - public bool connected() - { - return (this.player != null && this.mpris2_root != null); - } - - public void expose() - { - if(this.connected() == true){ - this.mpris2_root.Raise.begin(); - } - } - - private void on_playlistdetails_changed (PlaylistDetails details) - { - PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; - playlists_item.update_individual_playlist (details); - } - - public async void fetch_playlists() - { - PlaylistDetails[] current_playlists = null; - - try{ - current_playlists = yield this.playlists.GetPlaylists (0, - MAX_PLAYLIST_COUNT, - "Alphabetical", - false); - } - catch (IOError e){ - return; - } - - if( current_playlists != null ){ - PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; - playlists_item.update(current_playlists); - } - else{ - warning(" Playlists are on but %s is returning no current_playlists ?", - this.owner.app_info.get_name()); - this.owner.use_playlists = false; - } - } - - private bool validate_playlists_details() - { - if (this.playlists.ActivePlaylist == null){ - return false; - } - if (this.playlists.ActivePlaylist.valid == false){ - return false; - } - if (this.playlists.ActivePlaylist.details == null){ - return false; - } - if (this.playlists.ActivePlaylist.details.path == null || - this.playlists.ActivePlaylist.details.name == null){ - return false; - } - return true; - } - - private bool fetch_active_playlist() - { - if (this.validate_playlists_details() == false){ - return false; - } - PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; - playlists_item.active_playlist_update ( this.playlists.ActivePlaylist.details ); - return false; - } - - public void activate_playlist (ObjectPath path) - { - try{ - this.playlists.ActivatePlaylist.begin(path); - } - catch(IOError e){ - warning ("Could not activate playlist %s because %s", (string)path, e.message); - } - } -} diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index 4ab75c8..740089d 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -104,8 +104,6 @@ public class Mpris2Watcher : GLib.Object { string name, previous_owner, current_owner; - message ("xyxp"); - parameters.get ("(sss)", out name, out previous_owner, out current_owner); MprisRoot? mpris2_root = this.create_mpris_root (name); diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala deleted file mode 100644 index 59ced36..0000000 --- a/src/music-player-bridge.vala +++ /dev/null @@ -1,305 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -using Dbusmenu; -using Gee; -using GLib; - -public class MusicPlayerBridge : GLib.Object -{ - const int DEVICE_ITEMS_COUNT = 3; - - private SettingsManager settings_manager; - private Dbusmenu.Menuitem root_menu; - private HashMap registered_clients; - private HashMap file_monitors; - private HashMap mpris_to_desktop; - private Mpris2Watcher watcher; - - public MusicPlayerBridge() - { - } - - construct{ - this.registered_clients = new HashMap (); - this.file_monitors = new HashMap (); - this.mpris_to_desktop = new HashMap (); - this.settings_manager = new SettingsManager(); - this.settings_manager.blacklist_updates.connect ( this.on_blacklist_update ); - this.settings_manager.preferred_updates.connect ( this.on_preferred_update ); - } - - private void on_blacklist_update ( string[] blacklist ) - { - debug("some blacklist update"); - - foreach(var desktop_id in blacklist){ - string key = desktop_id; - if (this.registered_clients.has_key (key)){ - debug ("Apparently %s is now blacklisted - remove thy self", key); - this.registered_clients[key].remove_from_menu(); - this.registered_clients.unset (key); - } - } - // double check present players to ensure dynamic removal/addition - this.watcher.check_for_active_clients.begin(); - } - - private void on_preferred_update ( Gee.ArrayList preferred ) - { - debug ("Preferred players update. Clearing current preferred players..."); - - foreach (var player_controller in this.registered_clients.values) { - player_controller.set_as_preferred (false); - } - - foreach (var desktop_id in preferred) { - string key = desktop_id; - if (this.registered_clients.has_key (key)) { - debug ("Setting %s as preferred player", key); - this.registered_clients[key].set_as_preferred (true); - } - } - } - - private void try_to_add_inactive_familiar_clients() - { - var preferred_players = this.settings_manager.fetch_preferred (); - foreach ( string desktop in this.settings_manager.fetch_interested()){ - debug ( "interested client found : %s", desktop ); - AppInfo? app_info = create_app_info ( desktop.concat( ".desktop" ) ); - if ( app_info == null ){ - warning ( "Could not create app_info for path %s \n Getting out of here ", - desktop ); - continue; - } - bool is_preferred = desktop in preferred_players; - PlayerController ctrl = new PlayerController ( this.root_menu, - app_info, - null, - this.fetch_icon_name(desktop), - calculate_menu_position(), - null, - PlayerController.state.OFFLINE, - is_preferred ); - var mpris_key = desktop; - this.registered_clients.set(mpris_key, ctrl); - this.establish_file_monitoring (app_info, mpris_key); - } - } - - private void establish_file_monitoring (AppInfo info, string mpris_key){ - DesktopAppInfo desktop_info = info as DesktopAppInfo; - var file_path = desktop_info.get_filename (); - File f = File.new_for_path (file_path); - try { - FileMonitor monitor = f.monitor (FileMonitorFlags.SEND_MOVED, null); - unowned FileMonitor weak_monitor = monitor; - monitor.changed.connect ((desktop_file, other_file, event_type) => { - this.relevant_desktop_file_changed (desktop_file, other_file, event_type, weak_monitor); - }); - monitor.ref(); // will be unref()ed by relevant_desktop_file_changed() - GLib.debug ("monitoring file '%s'", file_path); - this.file_monitors.set (file_path, mpris_key); - } - catch (Error e){ - warning ("Unable to create a file monitor for %s", info.get_name()); - return; - } - } - - private void relevant_desktop_file_changed (File desktop_file, - File? other_file, - FileMonitorEvent event_type, - FileMonitor monitor) - { - if (event_type != FileMonitorEvent.DELETED) - return; - - string? path = desktop_file.get_path (); - if (path == null){ - warning ("relevant_desktop_file_changed is returning a file with no path !"); - return; - } - if (!this.file_monitors.has_key (path)){ - warning ("relevant_desktop_file_changed is returning a file which we know nothing about - %s", - path); - return; - } - - var mpris_key = this.file_monitors[path]; - GLib.debug ("file \"%s\" was removed; stopping monitoring \"%s\"", path, mpris_key); - this.registered_clients[mpris_key].remove_from_menu(); - this.settings_manager.remove_interested (mpris_key); - this.registered_clients.unset (mpris_key); - monitor.cancel (); - monitor.unref(); - } - - private int calculate_menu_position() - { - if(this.registered_clients.size == 0){ - return DEVICE_ITEMS_COUNT; - } - else{ - return (DEVICE_ITEMS_COUNT + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY)); - } - } - - public void client_has_become_available ( string desktop, - string dbus_name, - bool use_playlists ) - { - if (desktop == null || desktop == ""){ - warning("Client %s attempting to register without desktop entry being set on the mpris root", - dbus_name); - return; - } - if (desktop in this.settings_manager.fetch_blacklist()) { - debug ("Client %s attempting to register but I'm afraid it is blacklisted", - desktop); - return; - } - - debug ( "client_has_become_available %s", desktop ); - AppInfo? app_info = create_app_info ( desktop.concat( ".desktop" ) ); - if ( app_info == null ){ - warning ( "Could not create app_info for path %s \n Getting out of here ", - desktop ); - return; - } - - var mpris_key = desktop; - bool is_preferred = desktop in this.settings_manager.fetch_preferred (); - - mpris_to_desktop.set (dbus_name, desktop); - if ( this.registered_clients.has_key (mpris_key) == false ){ - debug("New client has registered that we have not seen before: %s", dbus_name ); - PlayerController ctrl = new PlayerController ( this.root_menu, - app_info, - dbus_name, - this.fetch_icon_name(desktop), - this.calculate_menu_position(), - use_playlists, - PlayerController.state.READY, - is_preferred); - this.registered_clients.set ( mpris_key, ctrl ); - debug ( "Have not seen this %s before, new controller created.", desktop ); - this.settings_manager.add_interested ( desktop ); - this.establish_file_monitoring (app_info, mpris_key); - debug ( "application added to the interested list" ); - } - else{ - this.registered_clients[mpris_key].use_playlists = use_playlists; - this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); - this.registered_clients[mpris_key].activate ( dbus_name ); - debug("Application has already registered - awaken the hibernation: %s with playlists %s \n", dbus_name, use_playlists.to_string() ); - } - } - - public void client_has_vanished ( string mpris_root_interface ) - { - debug("\n MusicPlayerBridge -> client with dbus interface %s has vanished", - mpris_root_interface ); - if (root_menu != null){ - debug("\n attempt to remove %s", mpris_root_interface); - if (mpris_to_desktop.has_key(mpris_root_interface)){ - var mpris_key = mpris_to_desktop[mpris_root_interface]; - mpris_to_desktop.unset(mpris_root_interface); - if ( mpris_key != null && this.registered_clients.has_key(mpris_key)){ - registered_clients[mpris_key].hibernate(); - debug("\n Successively offlined client %s", mpris_key); - } - } - } - } - - public void set_root_menu_item ( Dbusmenu.Menuitem menu ) - { - this.root_menu = menu; - this.try_to_add_inactive_familiar_clients(); - this.watcher = new Mpris2Watcher (); - this.watcher.client_appeared.connect (this.client_has_become_available); - this.watcher.client_disappeared.connect (this.client_has_vanished); - } - - public void enable_player_specific_items_for_client (string object_path, - string desktop_id) - { - var mpris_key = desktop_id; - if (this.registered_clients.has_key (mpris_key) == false){ - warning ("we don't have a client with desktop id %s registered", desktop_id); - return; - } - this.registered_clients[mpris_key].enable_player_specific_items(object_path); - } - - public void enable_track_specific_items_for_client (string object_path, - string desktop_id) - { - var mpris_key = desktop_id; - if (this.registered_clients.has_key (mpris_key) == false){ - warning ("we don't have a client with desktop id %s registered", desktop_id); - return; - } - this.registered_clients[mpris_key].enable_track_specific_items(object_path); - } - - private static AppInfo? create_app_info ( string desktop ) - { - DesktopAppInfo info = new DesktopAppInfo ( desktop ); - if ( desktop == null || info == null ){ - warning ( "Could not create a desktopappinfo instance from app: %s", desktop ); - return null; - } - GLib.AppInfo app_info = info as GLib.AppInfo; - return app_info; - } - - private static string? fetch_icon_name(string desktop) - { - // We know the appinfo is good because it was loaded in the previous reg step. - DesktopAppInfo info = new DesktopAppInfo ( desktop.concat( ".desktop" ) ) ; - KeyFile desktop_keyfile = new KeyFile (); - try{ - desktop_keyfile.load_from_file (info.get_filename(), KeyFileFlags.NONE); - } - catch(GLib.FileError error){ - warning("Error loading keyfile - FileError"); - return null; - } - catch(GLib.KeyFileError error){ - warning("Error loading keyfile - KeyFileError"); - return null; - } - - try{ - return desktop_keyfile.get_string (KeyFileDesktop.GROUP, - KeyFileDesktop.KEY_ICON); - } - catch(GLib.KeyFileError error){ - warning("Error trying to fetch the icon name from the keyfile"); - return null; - } - } -} - - - - diff --git a/src/mute-menu-item.c b/src/mute-menu-item.c deleted file mode 100644 index 0e6a46f..0000000 --- a/src/mute-menu-item.c +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "common-defs.h" -#include "mute-menu-item.h" -#include "pulseaudio-mgr.h" - -typedef struct _MuteMenuItemPrivate MuteMenuItemPrivate; - -struct _MuteMenuItemPrivate { - DbusmenuMenuitem* button; -}; - -#define MUTE_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MUTE_MENU_ITEM_TYPE, MuteMenuItemPrivate)) - -/* Prototypes */ -static void mute_menu_item_class_init (MuteMenuItemClass *klass); -static void mute_menu_item_init (MuteMenuItem *self); -static void mute_menu_item_dispose (GObject *object); -static void mute_menu_item_finalize (GObject *object); -static void mute_menu_item_set_global_mute_from_ui (gpointer user_data); - -G_DEFINE_TYPE (MuteMenuItem, mute_menu_item, G_TYPE_OBJECT); - -static void -mute_menu_item_class_init (MuteMenuItemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (MuteMenuItemPrivate)); - - object_class->dispose = mute_menu_item_dispose; - object_class->finalize = mute_menu_item_finalize; - - return; -} - -static void -mute_menu_item_init (MuteMenuItem *self) -{ - g_debug("Building new Mute Menu Item"); - MuteMenuItemPrivate* priv = MUTE_MENU_ITEM_GET_PRIVATE(self); - priv->button = NULL; - priv->button = dbusmenu_menuitem_new(); - - dbusmenu_menuitem_property_set(priv->button, - DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_MUTE_MENUITEM_TYPE); - - dbusmenu_menuitem_property_set_bool (priv->button, - DBUSMENU_MENUITEM_PROP_VISIBLE, - TRUE); - - g_signal_connect (G_OBJECT (priv->button), - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (mute_menu_item_set_global_mute_from_ui), - self); - return; -} - -static void -mute_menu_item_dispose (GObject *object) -{ - G_OBJECT_CLASS (mute_menu_item_parent_class)->dispose (object); - return; -} - -static void -mute_menu_item_finalize (GObject *object) -{ - G_OBJECT_CLASS (mute_menu_item_parent_class)->finalize (object); -} - -static void -mute_menu_item_set_global_mute_from_ui (gpointer user_data) -{ - g_return_if_fail (DBUSMENU_IS_MENUITEM (user_data)); - DbusmenuMenuitem* button = DBUSMENU_MENUITEM (user_data); - gboolean current_value = dbusmenu_menuitem_property_get_bool (button, - DBUSMENU_MUTE_MENUITEM_VALUE); - gboolean new_value = !current_value; - pm_update_mute (new_value); -} - -void -mute_menu_item_update (MuteMenuItem* item, gboolean value_update) -{ - MuteMenuItemPrivate* priv = MUTE_MENU_ITEM_GET_PRIVATE (item); - - dbusmenu_menuitem_property_set_bool (priv->button, - DBUSMENU_MUTE_MENUITEM_VALUE, - value_update); - dbusmenu_menuitem_property_set (priv->button, - DBUSMENU_MENUITEM_PROP_LABEL, - value_update == FALSE ? _("Mute") : _("Unmute")); -} - -void -mute_menu_item_enable (MuteMenuItem* item, gboolean active) -{ - MuteMenuItemPrivate* priv = MUTE_MENU_ITEM_GET_PRIVATE (item); - dbusmenu_menuitem_property_set_bool (priv->button, - DBUSMENU_MENUITEM_PROP_VISIBLE, - TRUE); - - dbusmenu_menuitem_property_set_bool (priv->button, - DBUSMENU_MENUITEM_PROP_ENABLED, - active); -} - -DbusmenuMenuitem* -mute_menu_item_get_button (MuteMenuItem* item) -{ - MuteMenuItemPrivate* priv = MUTE_MENU_ITEM_GET_PRIVATE (item); - return priv->button; -} - -gboolean -mute_menu_item_is_muted (MuteMenuItem* item) -{ - MuteMenuItemPrivate* priv = MUTE_MENU_ITEM_GET_PRIVATE (item); - return dbusmenu_menuitem_property_get_bool (priv->button, - DBUSMENU_MUTE_MENUITEM_VALUE); -} - -MuteMenuItem* -mute_menu_item_new (gboolean initial_update, gboolean enabled) -{ - MuteMenuItem *self = g_object_new (MUTE_MENU_ITEM_TYPE, NULL); - mute_menu_item_update (self, initial_update); - mute_menu_item_enable (self, enabled); - return self; -} diff --git a/src/mute-menu-item.h b/src/mute-menu-item.h deleted file mode 100644 index 81a4b33..0000000 --- a/src/mute-menu-item.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#ifndef __MUTE_MENU_ITEM_H__ -#define __MUTE_MENU_ITEM_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define MUTE_MENU_ITEM_TYPE (mute_menu_item_get_type ()) -#define MUTE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTE_MENU_ITEM_TYPE, MuteMenuItem)) -#define MUTE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTE_MENU_ITEM_TYPE, MuteMenuItemClass)) -#define IS_MUTE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTE_MENU_ITEM_TYPE)) -#define IS_MUTE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTE_MENU_ITEM_TYPE)) -#define MUTE_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTE_MENU_ITEM_TYPE, MuteMenuItemClass)) - -typedef struct _MuteMenuItem MuteMenuItem; -typedef struct _MuteMenuItemClass MuteMenuItemClass; - -struct _MuteMenuItemClass { - GObjectClass parent_class; -}; - -struct _MuteMenuItem { - GObject parent; -}; - -GType mute_menu_item_get_type (void); - -MuteMenuItem* mute_menu_item_new (); - -void mute_menu_item_update (MuteMenuItem* item, gboolean update); -void mute_menu_item_enable (MuteMenuItem* item, gboolean active); -gboolean mute_menu_item_is_muted (MuteMenuItem* item); - -DbusmenuMenuitem* mute_menu_item_get_button (MuteMenuItem* item); - -G_END_DECLS - -#endif \ No newline at end of file diff --git a/src/player-controller.vala b/src/player-controller.vala deleted file mode 100644 index fd66a8a..0000000 --- a/src/player-controller.vala +++ /dev/null @@ -1,247 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -using Dbusmenu; -using Gee; - -public class PlayerController : GLib.Object -{ - public const int WIDGET_QUANTITY = 4; - - public enum widget_order{ - SEPARATOR, - METADATA, - TRANSPORT, - PLAYLISTS - } - - public enum state{ - OFFLINE, - INSTANTIATING, - READY, - CONNECTED, - DISCONNECTED - } - - public int current_state = state.OFFLINE; - - public Dbusmenu.Menuitem root_menu; - public string dbus_name { get; set;} - public ArrayList custom_items; - public Mpris2Controller mpris_bridge; - public AppInfo? app_info { get; set;} - public int menu_offset { get; set;} - public string icon_name { get; set; } - public bool? use_playlists; - public bool is_preferred { get; private set; } - private SpecificItemsManager track_specific_mgr; - private SpecificItemsManager player_specific_mgr; - - public PlayerController(Dbusmenu.Menuitem root, - GLib.AppInfo app, - string? dbus_name, - string icon_name, - int offset, - bool? use_playlists, - state initial_state, - bool is_preferred) - { - this.use_playlists = use_playlists; - this.root_menu = root; - this.app_info = app; - this.dbus_name = dbus_name; - this.icon_name = icon_name; - this.custom_items = new ArrayList(); - this.current_state = initial_state; - this.menu_offset = offset; - this.is_preferred = is_preferred; - - this.construct_widgets(); - this.establish_mpris_connection(); - this.update_layout(); - debug ("New player controller for %s with icon name %s", this.app_info.get_name(), this.icon_name); - } - - public void update_state(state new_state) - { - debug("update_state - player controller %s : new state %i", this.app_info.get_name(), - new_state); - this.current_state = new_state; - this.update_layout(); - } - - public void activate( string dbus_name ) - { - this.dbus_name = dbus_name; - this.establish_mpris_connection(); - } - - /* - instantiate() - The user should be able to start the app from the transport bar when in an offline state - There is a need to wait before the application is on DBus before attempting to access its mpris address - Hence only when the it has registered with us via libindicate do we attempt to kick off mpris communication - */ - public void instantiate() - { - debug("instantiate in player controller for %s", this.app_info.get_name() ); - try{ - this.app_info.launch(null, null); - this.update_state(state.INSTANTIATING); - } - catch(GLib.Error error){ - warning("Failed to launch app %s with error message: %s", this.app_info.get_name(), - error.message ); - } - } - - public void enable_track_specific_items (string object_path) - { - if (this.track_specific_mgr == null){ - track_specific_mgr = new SpecificItemsManager (this, - object_path, - SpecificItemsManager.category.TRACK); - } - } - - public void enable_player_specific_items (string object_path) - { - if (this.player_specific_mgr == null){ - player_specific_mgr = new SpecificItemsManager (this, - object_path, - SpecificItemsManager.category.PLAYER); - } - } - - public int track_specific_count () - { - if (this.track_specific_mgr == null) { - return 0; - } - return this.track_specific_mgr.proxy_items.size; - } - - private void establish_mpris_connection() - { - if(this.current_state != state.READY || this.dbus_name == null ){ - debug("establish_mpris_connection - Not ready to connect"); - return; - } - debug ( " establish mpris connection - use playlists value = %s ", - this.use_playlists.to_string() ); - this.mpris_bridge = new Mpris2Controller (this); - this.determine_state (); - } - - public void remove_from_menu() - { - foreach(PlayerItem item in this.custom_items){ - this.root_menu.child_delete(item); - } - if (this.use_playlists == true){ - PlaylistsMenuitem playlists_menuitem = this.custom_items[widget_order.PLAYLISTS] as PlaylistsMenuitem; - this.root_menu.child_delete (playlists_menuitem.root_item); - } - } - - public void set_as_preferred (bool val) { - this.is_preferred = val; - this.update_layout(); - } - - public void hibernate() - { - update_state(PlayerController.state.OFFLINE); - TransportMenuitem transport = this.custom_items[widget_order.TRANSPORT] as TransportMenuitem; - transport.change_play_state (Transport.State.PAUSED); - this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.relevant_attributes_for_ui()); - MetadataMenuitem md = this.custom_items[widget_order.METADATA] as MetadataMenuitem; - md.toggle_active_triangle (false); - this.mpris_bridge = null; - } - - public void update_layout() - { - PlaylistsMenuitem playlists_menuitem = this.custom_items[widget_order.PLAYLISTS] as PlaylistsMenuitem; - MetadataMenuitem metadata_menuitem = this.custom_items[widget_order.METADATA] as MetadataMenuitem; - if(this.current_state != state.CONNECTED){ - metadata_menuitem.should_collapse (true); - playlists_menuitem.root_item.property_set_bool (MENUITEM_PROP_VISIBLE, - false); - this.custom_items[widget_order.TRANSPORT].property_set_bool (MENUITEM_PROP_VISIBLE, is_preferred); - return; - } - - bool should_collapse = !this.custom_items[widget_order.METADATA].populated (MetadataMenuitem.relevant_attributes_for_ui()); - metadata_menuitem.should_collapse (should_collapse); - - if (is_preferred){ - TransportMenuitem transport = this.custom_items[widget_order.TRANSPORT] as TransportMenuitem; - transport.handle_cached_action(); - } - else{ - this.custom_items[widget_order.TRANSPORT].property_set_bool (MENUITEM_PROP_VISIBLE, - true); - } - playlists_menuitem.root_item.property_set_bool ( MENUITEM_PROP_VISIBLE, - this.use_playlists ); - } - - private void construct_widgets() - { - // Separator item - this.custom_items.add(new PlayerItem(CLIENT_TYPES_SEPARATOR)); - - // Metadata item - MetadataMenuitem metadata_item = new MetadataMenuitem(this); - this.custom_items.add(metadata_item); - - // Transport item - TransportMenuitem transport_item = new TransportMenuitem(this); - this.custom_items.add(transport_item); - - // Playlist item - PlaylistsMenuitem playlist_menuitem = new PlaylistsMenuitem(this); - this.custom_items.add(playlist_menuitem); - - foreach(PlayerItem item in this.custom_items){ - if (this.custom_items.index_of(item) == WIDGET_QUANTITY-1) { - PlaylistsMenuitem playlists_menuitem = item as PlaylistsMenuitem; - root_menu.child_add_position(playlists_menuitem.root_item, this.menu_offset + this.custom_items.index_of(item)); - } - else{ - root_menu.child_add_position (item, - this.menu_offset + this.custom_items.index_of(item)); - } - } - } - - private void determine_state() - { - if(this.mpris_bridge.connected() == true){ - this.update_state(state.CONNECTED); - MetadataMenuitem md = this.custom_items[widget_order.METADATA] as MetadataMenuitem; - md.toggle_active_triangle(true); - this.mpris_bridge.initial_update(); - } - else{ - this.update_state(state.DISCONNECTED); - } - } -} diff --git a/src/player-item.vala b/src/player-item.vala deleted file mode 100644 index 7867653..0000000 --- a/src/player-item.vala +++ /dev/null @@ -1,104 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -using Dbusmenu; -using Gee; - -public class PlayerItem : Dbusmenu.Menuitem -{ - public PlayerController owner {get; construct;} - public string item_type { get; construct; } - public const int EMPTY = -1; - - public PlayerItem(string type) - { - Object(item_type: type); - } - - construct { - this.property_set(MENUITEM_PROP_TYPE, item_type); - } - - public void reset(HashSet attrs){ - foreach(string s in attrs){ - this.property_set_int(s, EMPTY); - } - } - - /** - * update() - * Base update method for playeritems, takes the attributes and the incoming updates - * and attmepts to update the appropriate props on the object. - * Album art is handled separately to deal with remote and local file paths. - */ - public void update(HashTable data, HashSet attributes) - { - //debug("PlayerItem::update()"); - if(data == null){ - warning("PlayerItem::Update -> The hashtable was null - just leave it!"); - return; - } - - foreach(string property in attributes){ - string[] input_keys = property.split("-"); - string search_key = input_keys[input_keys.length-1 : input_keys.length][0]; - //debug("search key = %s", search_key); - Variant? v = data.lookup(search_key); - - if (v == null) continue; - - if (v.is_of_type ( VariantType.STRING )){ - string update = v.get_string().strip(); - //debug("with value : %s", update); - if(property.contains("mpris:artUrl")){ - // We know its a metadata instance because thats the only - // object with the arturl prop - MetadataMenuitem metadata = this as MetadataMenuitem; - metadata.fetch_art ( update, property ); - continue; - } - this.property_set(property, update); - } - else if (v.is_of_type (VariantType.INT32 )){ - //debug("with value : %i", v.get_int32()); - this.property_set_int(property, v.get_int32()); - } - else if (v.is_of_type (VariantType.INT64 )){ - //debug("with value : %i", (int)v.get_int64()); - this.property_set_int(property, (int)v.get_int64()); - } - else if(v.is_of_type ( VariantType.BOOLEAN )){ - //debug("with value : %s", v.get_boolean().to_string()); - this.property_set_bool(property, v.get_boolean()); - } - } - } - - public bool populated(HashSet attrs) - { - foreach(string prop in attrs){ - if(property_get_int(prop) != EMPTY){ - return true; - } - } - return false; - } - -} - diff --git a/src/playlists-menu-item.vala b/src/playlists-menu-item.vala deleted file mode 100644 index 4666a50..0000000 --- a/src/playlists-menu-item.vala +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -using Config; -using Dbusmenu; -using DbusmenuPlaylists; -using DbusmenuPlaylist; -using Gee; - - -public class PlaylistsMenuitem : PlayerItem -{ - private HashMap current_playlists; - public Menuitem root_item; - - public PlaylistsMenuitem ( PlayerController parent ) - { - Object ( item_type: MENUITEM_TYPE, owner: parent ); - } - - construct{ - this.current_playlists = new HashMap(); - this.root_item = new Menuitem(); - this.root_item.property_set ( MENUITEM_PROP_LABEL, _("Choose Playlist") ); - this.root_item.property_set ( MENUITEM_PATH, "" ); - } - - public new void update (PlaylistDetails[] playlists) - { - foreach ( PlaylistDetails detail in playlists ){ - // We don't want to list playlists which are for videos)' - if (this.already_observed(detail) || this.is_video_related(detail)) - continue; - - Dbusmenu.Menuitem menuitem = new Menuitem(); - menuitem.property_set (MENUITEM_PROP_LABEL, - truncate_item_label_if_needs_be (detail.name)); - menuitem.property_set (MENUITEM_PROP_ICON_NAME, "playlist-symbolic"); - - menuitem.property_set (MENUITEM_PATH, (string)detail.path); - menuitem.property_set_bool (MENUITEM_PROP_VISIBLE, true); - menuitem.property_set_bool (MENUITEM_PROP_ENABLED, true); - - menuitem.item_activated.connect(() => { - submenu_item_activated (menuitem.id ); - } - ); - this.current_playlists.set( menuitem.id, menuitem ); - this.root_item.child_append( menuitem ); - debug ("populating valid playlists %s", detail.name); - } - // Finally remove any that might have been deleted - foreach (Dbusmenu.Menuitem item in this.current_playlists.values) { - bool within = false; - foreach (PlaylistDetails detail in playlists){ - if (detail.path == item.property_get (MENUITEM_PATH)) { - within = true; - break; - } - } - if (within == false){ - if (this.root_item.property_get (MENUITEM_PATH) == item.property_get (MENUITEM_PATH)){ - this.root_item.property_set (MENUITEM_PROP_LABEL, _("Choose Playlist")); - } - this.root_item.child_delete (item); - } - } - } - - public void update_individual_playlist (PlaylistDetails new_detail) - { - foreach ( Dbusmenu.Menuitem item in this.current_playlists.values ){ - if (new_detail.path == item.property_get (MENUITEM_PATH)){ - item.property_set (MENUITEM_PROP_LABEL, - truncate_item_label_if_needs_be (new_detail.name)); - } - } - // If its active make sure the name is updated on the root item. - if (this.root_item.property_get (MENUITEM_PATH) == new_detail.path) { - this.root_item.property_set (MENUITEM_PROP_LABEL, - truncate_item_label_if_needs_be (new_detail.name)); - } - } - - private bool already_observed (PlaylistDetails new_detail) - { - foreach ( Dbusmenu.Menuitem item in this.current_playlists.values ){ - var path = item.property_get (MENUITEM_PATH); - if (new_detail.path == path) return true; - } - return false; - } - - private bool is_video_related (PlaylistDetails new_detail) - { - var location = (string)new_detail.path; - if (location.contains ("/VideoLibrarySource/")) return true; - return false; - } - - public void active_playlist_update (PlaylistDetails detail) - { - var update = detail.name; - if ( update == "" ) update = _("Choose Playlist"); - this.root_item.property_set (MENUITEM_PROP_LABEL, - truncate_item_label_if_needs_be(update)); - this.root_item.property_set (MENUITEM_PATH, detail.path); - } - - private void submenu_item_activated (int menu_item_id) - { - if (!this.current_playlists.has_key(menu_item_id)) { - warning( "item %i was activated but we don't have a corresponding playlist", - menu_item_id ); - return; - } - this.owner.mpris_bridge.activate_playlist ( (GLib.ObjectPath)this.current_playlists[menu_item_id].property_get (MENUITEM_PATH) ); - } - - private string truncate_item_label_if_needs_be(string item_label) - { - var result = item_label; - if (item_label.char_count(-1) > 17){ - result = item_label.slice ((long)0, (long)15); - result += "…"; - } - return result; - } - - public static HashSet attributes_format() - { - HashSet attrs = new HashSet(); - attrs.add(MENUITEM_TITLE); - attrs.add(MENUITEM_PLAYLISTS); - return attrs; - } - -} diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c deleted file mode 100644 index f205723..0000000 --- a/src/pulseaudio-mgr.c +++ /dev/null @@ -1,717 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -/**Notes - * - * Approach now is to set up the communication channels, query the server - * fetch its default sink/source. If this fails then fetch the list of sinks/sources - * and take the first one which is not the auto-null sink. - * TODO: need to handle the situation where one chink in this linear chain breaks - * i.e. start off the process again and count the attempts (note different to - reconnect attempts) - */ -#include -#include -#include - -#include "pulseaudio-mgr.h" -#include "config.h" - -#define RECONNECT_DELAY 5 - - -static void pm_context_state_callback(pa_context *c, void *userdata); -static void pm_subscribed_events_callback (pa_context *c, - enum pa_subscription_event_type t, - uint32_t index, - void* userdata); -static void pm_server_info_callback (pa_context *c, - const pa_server_info *info, - void *userdata); -static void pm_default_sink_info_callback (pa_context *c, - const pa_sink_info *info, - int eol, - void *userdata); -static void pm_default_source_info_callback (pa_context *c, - const pa_source_info *info, - int eol, - void *userdata); -static void pm_sink_info_callback (pa_context *c, - const pa_sink_info *sink, - int eol, - void *userdata); -static void pm_source_info_callback (pa_context *c, - const pa_source_info *info, - int eol, - void *userdata); -static void pm_update_source_info_callback (pa_context *c, - const pa_source_info *info, - int eol, - void *userdata); -static void pm_sink_input_info_callback (pa_context *c, - const pa_sink_input_info *info, - int eol, - void *userdata); -static void pm_update_device (pa_context *c, - const pa_sink_info *info, - int eol, - void *userdata); -static void pm_toggle_mute_for_every_sink_callback (pa_context *c, - const pa_sink_info *sink, - int eol, - void* userdata); -static void pm_source_output_info_callback (pa_context *c, - const pa_source_output_info *info, - int eol, - void *userdata); - -static gboolean reconnect_to_pulse (gpointer user_data); - -static gint connection_attempts = 0; -static gint reconnect_idle_id = 0; -static pa_context *pulse_context = NULL; -static pa_glib_mainloop *pa_main_loop = NULL; - -/** - Entry Point - **/ -void -pm_establish_pulse_connection (Device* device) -{ - pa_main_loop = pa_glib_mainloop_new (g_main_context_default ()); - g_assert (pa_main_loop); - reconnect_to_pulse ((gpointer)device); -} - -/** -close_pulse_activites() -Gracefully close our connection with the Pulse async library. -**/ -void close_pulse_activites() -{ - if (pulse_context != NULL) { - pa_context_unref(pulse_context); - pulse_context = NULL; - } - pa_glib_mainloop_free(pa_main_loop); - pa_main_loop = NULL; -} - -/** -reconnect_to_pulse (gpointer user_data) -Method which connects to the pulse server and is used to track reconnects. - */ -static gboolean -reconnect_to_pulse (gpointer user_data) -{ - g_debug("Attempt a pulse connection"); - g_return_val_if_fail (IS_DEVICE (user_data), FALSE); - - connection_attempts += 1; - if (pulse_context != NULL) { - pa_context_unref(pulse_context); - pulse_context = NULL; - } - - pa_proplist *proplist; - - proplist = pa_proplist_new (); - pa_proplist_sets (proplist, - PA_PROP_APPLICATION_NAME, - "Indicator Sound"); - pa_proplist_sets (proplist, - PA_PROP_APPLICATION_ID, - "com.canonical.indicator.sound"); - pa_proplist_sets (proplist, - PA_PROP_APPLICATION_ICON_NAME, - "multimedia-volume-control"); - pa_proplist_sets (proplist, - PA_PROP_APPLICATION_VERSION, - PACKAGE_VERSION); - - pulse_context = pa_context_new_with_proplist (pa_glib_mainloop_get_api( pa_main_loop ), - NULL, - proplist); - pa_proplist_free (proplist); - g_assert(pulse_context); - pa_context_set_state_callback (pulse_context, - pm_context_state_callback, - user_data); - int result = pa_context_connect (pulse_context, - NULL, - (pa_context_flags_t)PA_CONTEXT_NOFAIL, - NULL); - - if (result < 0) { - g_warning ("Failed to connect context: %s", - pa_strerror (pa_context_errno (pulse_context))); - } - if (connection_attempts > 5){ - return FALSE; - } - else{ - return TRUE; - } -} - -void -pm_update_volume (gint sink_index, pa_cvolume new_volume) -{ - if (sink_index < 0 || pulse_context == NULL){ - g_warning ("pm_update_volume sink index is negative or the context is null"); - return; - } - - if (pa_context_get_state (pulse_context) != PA_CONTEXT_READY ){ - g_warning ("pm_update_volume context is not in a ready state"); - return; - } - - pa_operation *operation = NULL; - - operation = pa_context_set_sink_volume_by_index (pulse_context, - sink_index, - &new_volume, - NULL, - NULL); - if (!operation){ - g_warning ("pm_update_volume operation failed for some reason"); - return; - } - pa_operation_unref (operation); -} - -void -pm_update_mute (gboolean update) -{ - if (pulse_context == NULL){ - g_warning ("pm_update_mute - the context is null"); - return; - } - - if (pa_context_get_state (pulse_context) != PA_CONTEXT_READY ){ - g_warning ("pm_update_mute context is not in a ready state"); - return; - } - - pa_operation *operation = NULL; - - operation = pa_context_get_sink_info_list (pulse_context, - pm_toggle_mute_for_every_sink_callback, - GINT_TO_POINTER (update)); - if (!operation){ - g_warning ("pm_update_mute operation failed for some reason"); - return; - } - pa_operation_unref (operation); -} - -void -pm_update_mic_gain (gint source_index, pa_cvolume new_gain) -{ - if (source_index < 0 || pulse_context == NULL){ - g_warning ("pm_update_mic_gain source index is negative or the context is null"); - return; - } - - if (pa_context_get_state (pulse_context) != PA_CONTEXT_READY ){ - g_warning ("pm_update_mic_gain context is not in a ready state"); - return; - } - - pa_operation *operation = NULL; - - operation = pa_context_set_source_volume_by_index (pulse_context, - source_index, - &new_gain, - NULL, - NULL); - if (!operation){ - g_warning ("pm_update_mic_gain operation failed for some reason"); - return; - } - pa_operation_unref (operation); -} - -void -pm_update_mic_mute (gint source_index, gint mute_update) -{ - if (source_index < 0){ - return; - } - - if (pa_context_get_state (pulse_context) != PA_CONTEXT_READY ){ - g_warning ("pm_update_mic_mute context is not in a ready state"); - return; - } - - pa_operation *operation = NULL; - - operation = pa_context_set_source_mute_by_index (pulse_context, - source_index, - mute_update, - NULL, - NULL); - if (!operation){ - g_warning ("pm_update_mic_mute operation failed for some reason"); - return; - } - pa_operation_unref (operation); -} - -/**********************************************************************************************************************/ -// Pulse-Audio asychronous call-backs -/**********************************************************************************************************************/ - - -static void -pm_subscribed_events_callback (pa_context *c, - enum pa_subscription_event_type t, - uint32_t index, - void* userdata) -{ - if (IS_DEVICE (userdata) == FALSE){ - g_critical ("subscribed events callback - our userdata is not what we think it should be"); - return; - } - Device* sink = DEVICE (userdata); - - switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { - case PA_SUBSCRIPTION_EVENT_SINK: - - // We don't care about any other sink other than the active one. - if (index != device_get_sink_index (sink)) - return; - - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - device_sink_deactivated (sink); - - } - else{ - pa_operation_unref (pa_context_get_sink_info_by_index (c, - index, - pm_update_device, - userdata) ); - } - break; - case PA_SUBSCRIPTION_EVENT_SOURCE: - g_debug ("Looks like source event of some description - index = %i", index); - // We don't care about any other sink other than the active one. - if (index != device_get_source_index (sink)) - return; - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - g_debug ("Source removal event - index = %i", index); - device_deactivate_voip_source (sink, FALSE); - } - else{ - pa_operation_unref (pa_context_get_source_info_by_index (c, - index, - pm_update_source_info_callback, - userdata) ); - } - break; - case PA_SUBSCRIPTION_EVENT_SINK_INPUT: - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - g_debug ("some new sink input event ? - index = %i", index); - // Maybe blocking state ?. - pa_operation_unref (pa_context_get_sink_input_info (c, - index, - pm_sink_input_info_callback, userdata)); - } - break; - case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: - g_debug ("source output event"); - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - gint cached_source_output_index = device_get_voip_source_output_index (sink); - if (index == cached_source_output_index){ - g_debug ("Just saw a source output removal event - index = %i and cached index = %i", index, cached_source_output_index); - device_deactivate_voip_client (sink); - } - } - else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - g_debug ("some new source output event ? - index = %i", index); - // Determine if its a VOIP app. - pa_operation_unref (pa_context_get_source_output_info (c, - index, - pm_source_output_info_callback, userdata)); - } - break; - case PA_SUBSCRIPTION_EVENT_SERVER: - g_debug("PA_SUBSCRIPTION_EVENT_SERVER event triggered."); - pa_operation *o; - if (!(o = pa_context_get_server_info (c, pm_server_info_callback, userdata))) { - g_warning("subscribed_events_callback - pa_context_get_server_info() failed"); - return; - } - pa_operation_unref(o); - break; - } -} - -static void -pm_context_state_callback (pa_context *c, void *userdata) -{ - switch (pa_context_get_state(c)) { - case PA_CONTEXT_UNCONNECTED: - g_debug("unconnected"); - break; - case PA_CONTEXT_CONNECTING: - g_debug("connecting - waiting for the server to become available"); - break; - case PA_CONTEXT_AUTHORIZING: - g_debug ("Authorizing"); - break; - case PA_CONTEXT_SETTING_NAME: - g_debug ("Setting name"); - break; - case PA_CONTEXT_FAILED: - g_warning("PA_CONTEXT_FAILED - Is PulseAudio Daemon running ?"); - device_sink_deactivated (DEVICE (userdata)); - if (reconnect_idle_id == 0){ - reconnect_idle_id = g_timeout_add_seconds (RECONNECT_DELAY, - reconnect_to_pulse, - (gpointer)userdata); - } - break; - case PA_CONTEXT_TERMINATED: - g_debug ("Terminated"); - device_sink_deactivated (DEVICE (userdata)); - - if (reconnect_idle_id != 0){ - g_source_remove (reconnect_idle_id); - reconnect_idle_id = 0; - } - break; - case PA_CONTEXT_READY: - connection_attempts = 0; - g_debug("PA_CONTEXT_READY"); - - if (reconnect_idle_id != 0){ - g_source_remove (reconnect_idle_id); - reconnect_idle_id = 0; - } - - pa_context_set_subscribe_callback(c, pm_subscribed_events_callback, userdata); - pa_operation *o = NULL; - - o = pa_context_subscribe (c, (pa_subscription_mask_t) - (PA_SUBSCRIPTION_MASK_SINK| - PA_SUBSCRIPTION_MASK_SOURCE| - PA_SUBSCRIPTION_MASK_SINK_INPUT| - PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT| - PA_SUBSCRIPTION_MASK_SERVER), - NULL, - NULL); - - - if (!o){ - g_critical("pa_context_subscribe() failed - ?"); - return; - } - - pa_operation_unref(o); - - o = pa_context_get_server_info (c, pm_server_info_callback, userdata); - - if (!o){ - g_warning("pa_context_get_server_info() failed - ?"); - return; - } - - pa_operation_unref(o); - - break; - } -} - -/** - After startup we go straight for the server info to see if it has details of - the default sink and source. Normally these are valid, if there is none set - fetch the list of each and try to determine the sink. - **/ -static void -pm_server_info_callback (pa_context *c, - const pa_server_info *info, - void *userdata) -{ - pa_operation *operation; - g_debug ("server info callback"); - - if (info == NULL) { - g_warning("No PA server - get the hell out of here"); - device_sink_deactivated (DEVICE (userdata)); - return; - } - // Go for the default sink - if (info->default_sink_name != NULL) { - g_debug ("default sink name from the server ain't null'"); - if (!(operation = pa_context_get_sink_info_by_name (c, - info->default_sink_name, - pm_default_sink_info_callback, - userdata) )) { - g_warning("pa_context_get_sink_info_by_namet() failed"); - device_sink_deactivated (DEVICE (userdata)); - pa_operation_unref(operation); - return; - } - } // If there is no default sink, try to determine a sink from the list of sinks - else if (!(operation = pa_context_get_sink_info_list(c, - pm_sink_info_callback, - userdata))) { - g_warning("pa_context_get_sink_info_list() failed"); - device_sink_deactivated (DEVICE (userdata)); - pa_operation_unref(operation); - return; - } - // And the source - if (info->default_source_name != NULL) { - g_debug ("default source name from the server is not null'"); - if (!(operation = pa_context_get_source_info_by_name (c, - info->default_source_name, - pm_default_source_info_callback, - userdata) )) { - g_warning("pa_context_get_default_source_info() failed"); - // TODO: call some input deactivate method on active sink - pa_operation_unref(operation); - return; - } - } - else if (!(operation = pa_context_get_source_info_list(c, - pm_source_info_callback, - userdata))) { - g_warning("pa_context_get_sink_info_list() failed"); - // TODO: call some input deactivate method for the source - } - pa_operation_unref(operation); -} - -// If the server doesn't have a default sink to give us -// we should attempt to pick up the first of the list of sinks which doesn't have -// the name 'auto_null' (that was all really I was doing before) -static void -pm_sink_info_callback (pa_context *c, - const pa_sink_info *sink, - int eol, - void* userdata) -{ - if (eol > 0) { - return; - } - else { - if (IS_DEVICE (userdata) == FALSE || sink == NULL){ - g_warning ("sink info callback - our user data is not what we think it should be or the sink parameter is null"); - return; - } - Device* a_sink = DEVICE (userdata); - if (device_is_sink_populated (a_sink) == FALSE && - g_ascii_strncasecmp("auto_null", sink->name, 9) != 0){ - device_sink_populate (a_sink, sink); - } - } -} - -static void -pm_default_sink_info_callback (pa_context *c, - const pa_sink_info *info, - int eol, - void *userdata) -{ - if (eol > 0) { - return; - } - else { - if (IS_DEVICE (userdata) == FALSE || info == NULL){ - g_warning ("Default sink info callback - our user data is not what we think it should be or the info parameter is null"); - return; - } - // Only repopulate if there is a change with regards the index - if (device_get_sink_index (DEVICE (userdata)) == info->index) - return; - - g_debug ("Pulse Server has handed us a new default sink"); - device_sink_populate (DEVICE (userdata), info); - } -} - -static void -pm_sink_input_info_callback (pa_context *c, - const pa_sink_input_info *info, - int eol, - void *userdata) -{ - if (eol > 0) { - return; - } - else { - if (info == NULL || IS_DEVICE (userdata) == FALSE) { - g_warning("Sink input info callback : SINK INPUT INFO IS NULL or our user_data is not what we think it should be"); - return; - } - Device* a_sink = DEVICE (userdata); - // And finally check for the mute blocking state - if (device_get_sink_index (a_sink) == info->sink){ - device_determine_blocking_state (a_sink); - } - } -} - -static void -pm_source_output_info_callback (pa_context *c, - const pa_source_output_info *info, - int eol, - void *userdata) -{ - if (eol > 0) { - return; - } - else { - if (info == NULL || IS_DEVICE (userdata) == FALSE) { - g_warning("Source output callback: SOURCE OUTPUT INFO IS NULL or our user_data is not what we think it should be"); - return; - } - - // Check if this is Voip sink input - gint result = pa_proplist_contains (info->proplist, PA_PROP_MEDIA_ROLE); - Device* a_sink = DEVICE (userdata); - - if (result == 1){ - //g_debug ("Source output info has media role property"); - const char* value = pa_proplist_gets (info->proplist, PA_PROP_MEDIA_ROLE); - //g_debug ("prop role = %s", value); - if (g_strcmp0 (value, "phone") == 0 || g_strcmp0 (value, "production") == 0) { - g_debug ("We have a VOIP/PRODUCTION ! - index = %i", info->index); - device_activate_voip_item (a_sink, (gint)info->index, (gint)info->client); - // TODO to start with we will assume our source is the same as what this 'client' - // is pointing at. This should probably be more intelligent : - // query for the list of source output info's and going on the name of the client - // from the sink input ensure our voip item is using the right source. - } - } - } -} - -static void -pm_update_device (pa_context *c, - const pa_sink_info *info, - int eol, - void *userdata) -{ - if (eol > 0) { - return; - } - else{ - if (IS_DEVICE (userdata) == FALSE || info == NULL){ - g_warning ("update_device - our user data is not what we think it should be or the info parameter is null"); - return; - } - device_sink_update (DEVICE(userdata), info); - } -} - -static void -pm_toggle_mute_for_every_sink_callback (pa_context *c, - const pa_sink_info *sink, - int eol, - void* userdata) -{ - if (eol > 0) { - return; - } - - if (sink == NULL) { - g_warning ("toggle_mute cb - sink parameter is null - why ?"); - return; - } - - pa_operation *operation = NULL; - operation = pa_context_set_sink_mute_by_index (c, - sink->index, - GPOINTER_TO_INT(userdata), - NULL, - NULL); - if (!operation){ - g_warning ("pm_update_mic_mute operation failed for some reason"); - return; - } - pa_operation_unref (operation); -} - -// Source info related callbacks -static void -pm_default_source_info_callback (pa_context *c, - const pa_source_info *info, - int eol, - void *userdata) -{ - if (eol > 0) { - return; - } - else { - if (IS_DEVICE (userdata) == FALSE || info == NULL){ - g_warning ("Default source info callback - our user data is not what we think it should be or the source info parameter is null"); - return; - } - // If there is an index change we need to change our cached source - if (device_get_source_index (DEVICE (userdata)) == info->index) - return; - g_debug ("Pulse Server has handed us a new default source"); - device_deactivate_voip_source (DEVICE (userdata), TRUE); - device_update_voip_input_source (DEVICE (userdata), info); - } -} - -static void -pm_source_info_callback (pa_context *c, - const pa_source_info *info, - int eol, - void *userdata) -{ - if (eol > 0) { - return; - } - else { - if (IS_DEVICE (userdata) == FALSE || info == NULL){ - g_warning ("source info callback - our user data is not what we think it should be or the source info parameter is null"); - return; - } - // For now we will take the first available - if (device_is_voip_source_populated (DEVICE (userdata)) == FALSE){ - device_update_voip_input_source (DEVICE (userdata), info); - } - } -} - -static void -pm_update_source_info_callback (pa_context *c, - const pa_source_info *info, - int eol, - void *userdata) -{ - if (eol > 0) { - return; - } - else { - if (IS_DEVICE (userdata) == FALSE || info == NULL ){ - g_warning ("source info update callback - our user data is not what we think it should be or the source info paramter is null"); - return; - } - g_debug ("Got a source update for %s , index %i", info->name, info->index); - device_update_voip_input_source (DEVICE (userdata), info); - } -} diff --git a/src/pulseaudio-mgr.h b/src/pulseaudio-mgr.h deleted file mode 100644 index ace47f3..0000000 --- a/src/pulseaudio-mgr.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#include "device.h" - -void pm_establish_pulse_connection (Device* device); -void close_pulse_activites(); -void pm_update_volume (gint sink_index, pa_cvolume new_volume); -void pm_update_mic_gain (gint source_index, pa_cvolume new_gain); -void pm_update_mic_mute (gint source_index, int mute_update); -void pm_update_mute (gboolean update); - - - - - - diff --git a/src/scrub-menu-item.vala b/src/scrub-menu-item.vala deleted file mode 100644 index e300050..0000000 --- a/src/scrub-menu-item.vala +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -using Dbusmenu; -using DbusmenuScrub; -using Gee; - -public class ScrubMenuitem : PlayerItem -{ - public ScrubMenuitem(PlayerController parent) - { - Object(item_type: MENUITEM_TYPE, owner: parent); - reset(attributes_format()); - } - - public override void handle_event(string name, GLib.Value input_value, uint timestamp) - { - debug("handle_event for owner %s with value: %f", this.owner.name, input_value.get_double()); - this.owner.mpris_bridge.set_track_position(input_value.get_double()); - } - - public void update_position(int32 new_position) - { - this.property_set_int(MENUITEM_POSITION, new_position); - } - - public void update_playstate(int state) - { - this.property_set_int(MENUITEM_PLAY_STATE, state); - } - - public static HashSet attributes_format() - { - HashSet attrs = new HashSet(); - attrs.add(MENUITEM_DURATION); - attrs.add(MENUITEM_POSITION); - attrs.add(MENUITEM_PLAY_STATE); - return attrs; - } -} \ No newline at end of file diff --git a/src/settings-manager.vala b/src/settings-manager.vala deleted file mode 100644 index 458ac21..0000000 --- a/src/settings-manager.vala +++ /dev/null @@ -1,136 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -using Gee; - -public class SettingsManager : GLib.Object -{ - private Settings settings; - public signal void blacklist_updates ( string[] new_blacklist ); - public signal void preferred_updates (Gee.ArrayList new_preferred); - - public SettingsManager ( ){ - } - construct{ - this.settings = new Settings ("com.canonical.indicator.sound"); - this.settings.changed["blacklisted-media-players"].connect (on_blacklist_event); - this.settings.changed["preferred-media-players"].connect (on_preferred_event); - } - - public string[] fetch_blacklist() - { - return this.settings.get_strv ("blacklisted-media-players"); - } - - public ArrayList fetch_preferred() - { - var list = new ArrayList(); - - var preferred = this.settings.get_strv ("preferred-media-players"); - var interested = fetch_interested (); - - foreach (var s in preferred) { - if (!(s in list) && interested.contains (s)) - list.add (s); - } - - return list; - } - - public ArrayList fetch_interested() - { - var blacklisted = fetch_blacklist (); - var interested = this.settings.get_strv ("interested-media-players"); - var list = new ArrayList(); - foreach(var s in interested){ - if (s == "banshee-1"){ - s = "banshee"; - } - if (s in list) continue; - if (s in blacklisted) continue; - list.add(s); - } - return list; - } - - public void clear_list() - { - this.settings.reset("interested-media-players"); - } - - public void remove_interested (string app_desktop_name) - { - const string key = "interested-media-players"; - var players = new GLib.VariantBuilder (new VariantType ("as")); // array of strings - - foreach (var player in this.settings.get_strv (key)) { - if (player != app_desktop_name) - players.add ("s", player); - } - - this.settings.set_value(key, players.end()); - this.settings.apply(); - } - - public void add_interested (string app_desktop_name) - { - const string key = "interested-media-players"; - var players = new GLib.VariantBuilder (new VariantType ("as")); // array of strings - - foreach (var player in this.settings.get_strv (key)) { - if (player == app_desktop_name) - return; - players.add ("s", player); - } - - players.add ("s", app_desktop_name); - this.settings.set_value(key, players.end()); - this.settings.apply(); - } - - private void on_blacklist_event() - { - this.blacklist_updates(this.settings.get_strv ("blacklisted-media-players")); - } - - private void on_preferred_event() - { - this.preferred_updates (this.fetch_preferred()); - } - - // Convenient debug method inorder to provide visability over - // the contents of both interested and blacklisted containers in its gsettings -/** - private void reveal_contents() - { - var already_interested = this.settings.get_strv ("interested-media-players"); - foreach (var s in already_interested) - { - debug ("client %s is in interested array", s); - } - var blacklisted = this.settings.get_strv ("blacklisted-media-players"); - foreach (var s in blacklisted) - { - debug ("client %s is in blacklisted array", s); - } - - debug ("interested array size = %i", already_interested.length); - debug ("blacklisted array size = %i", blacklisted.length); - } -**/ -} diff --git a/src/slider-menu-item.c b/src/slider-menu-item.c deleted file mode 100644 index dc0671c..0000000 --- a/src/slider-menu-item.c +++ /dev/null @@ -1,258 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "slider-menu-item.h" -#include "common-defs.h" -#include "pulseaudio-mgr.h" - -typedef struct _SliderMenuItemPrivate SliderMenuItemPrivate; - -struct _SliderMenuItemPrivate { - Device* a_sink; - gint index; - gchar* name; - gboolean mute; - pa_cvolume volume; - pa_channel_map channel_map; - pa_volume_t base_volume; -}; - -#define SLIDER_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SLIDER_MENU_ITEM_TYPE, SliderMenuItemPrivate)) - -/* Prototypes */ -static void slider_menu_item_class_init (SliderMenuItemClass *klass); -static void slider_menu_item_init (SliderMenuItem *self); -static void slider_menu_item_dispose (GObject *object); -static void slider_menu_item_finalize (GObject *object); -static void handle_event (DbusmenuMenuitem * mi, const gchar * name, - GVariant * value, guint timestamp); -static pa_cvolume slider_menu_item_construct_mono_volume (const pa_cvolume* vol); -static void slider_menu_item_update_volume (SliderMenuItem* self, gdouble percent); - -G_DEFINE_TYPE (SliderMenuItem, slider_menu_item, DBUSMENU_TYPE_MENUITEM); - -static void -slider_menu_item_class_init (SliderMenuItemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (SliderMenuItemPrivate)); - - object_class->dispose = slider_menu_item_dispose; - object_class->finalize = slider_menu_item_finalize; - - DbusmenuMenuitemClass * mclass = DBUSMENU_MENUITEM_CLASS(klass); - mclass->handle_event = handle_event; - return; -} - -static void -slider_menu_item_init (SliderMenuItem *self) -{ - dbusmenu_menuitem_property_set( DBUSMENU_MENUITEM(self), - DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_VOLUME_MENUITEM_TYPE ); - - SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); - - priv->index = NOT_ACTIVE; - priv->name = NULL; - - return; -} - -static void -slider_menu_item_dispose (GObject *object) -{ - G_OBJECT_CLASS (slider_menu_item_parent_class)->dispose (object); - return; -} - -static void -slider_menu_item_finalize (GObject *object) -{ - G_OBJECT_CLASS (slider_menu_item_parent_class)->finalize (object); -} - -static void -handle_event (DbusmenuMenuitem * mi, - const gchar * name, - GVariant * value, - guint timestamp) -{ - g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); - g_return_if_fail (IS_SLIDER_MENU_ITEM (mi)); - - SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (SLIDER_MENU_ITEM (mi)); - gdouble volume_input = g_variant_get_double (value); - -/* - g_debug ("slider menu item handle event with value %f on name %s", - volume_input, - name); -*/ - - slider_menu_item_update_volume (SLIDER_MENU_ITEM (mi), volume_input); - if (volume_input > 0) - device_ensure_sink_is_unmuted (priv->a_sink); -} - - -void -slider_menu_item_populate (SliderMenuItem* self, const pa_sink_info* update) -{ - SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); - priv->name = g_strdup (update->name); - priv->index = update->index; - priv->volume = slider_menu_item_construct_mono_volume (&update->volume); - priv->base_volume = update->base_volume; - priv->channel_map = update->channel_map; - priv->mute = update->mute; - - pa_volume_t vol = pa_cvolume_max (&update->volume); - gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; - GVariant* new_volume = g_variant_new_double (volume_percent); - dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self), - DBUSMENU_VOLUME_MENUITEM_LEVEL, - new_volume); - GVariant* new_mute_update = g_variant_new_boolean (update->mute == 1); - dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self), - DBUSMENU_VOLUME_MENUITEM_MUTE, - new_mute_update); - - slider_menu_item_enable (self, TRUE); -} - -// From the UI -static void -slider_menu_item_update_volume (SliderMenuItem* self, gdouble percent) -{ - g_return_if_fail (IS_SLIDER_MENU_ITEM (self)); - - pa_cvolume mono_new_volume; - pa_cvolume_init(&mono_new_volume); - mono_new_volume.channels = 1; - pa_volume_t new_volume_value = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100); - - if (new_volume_value == PA_VOLUME_INVALID || new_volume_value >= PA_VOLUME_MAX){ - g_warning ("slider_menu_item_update_volume - volume is out of range !"); - return; - } - - pa_cvolume_set(&mono_new_volume, 1, new_volume_value); - - SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); - if (!pa_cvolume_valid (&mono_new_volume)){ - g_warning ("Invalid volume - ignore it!"); - return; - } - if (!pa_channel_map_valid(&priv->channel_map)){ - g_warning ("Invalid channel map - ignore update volume!"); - return; - } - pa_cvolume_set(&priv->volume, priv->channel_map.channels, new_volume_value); - pm_update_volume (priv->index, mono_new_volume); -} - -// To the UI -void -slider_menu_item_update (SliderMenuItem* self, const pa_sink_info* update) -{ - SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); - - priv->volume = slider_menu_item_construct_mono_volume (&update->volume); - priv->base_volume = update->base_volume; - priv->channel_map = update->channel_map; - - pa_volume_t vol = pa_cvolume_max (&update->volume); - gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; - - GVariant* new_volume = g_variant_new_double (volume_percent); - -/* - g_debug ("slider menu item update - volume update to ui to %f", volume_percent); -*/ - - dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self), - DBUSMENU_VOLUME_MENUITEM_LEVEL, - new_volume); - - if (priv->mute != update->mute){ - priv->mute = update->mute; -/* - g_debug ("volume menu item - update - mute on ui = %i", update->mute); -*/ - GVariant* new_mute_update = g_variant_new_boolean (update->mute == 1); - dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self), - DBUSMENU_VOLUME_MENUITEM_MUTE, - new_mute_update); - } -} - -/* - * Enable/Disabled can be considered the equivalent of whether we have an active - * sink or not, let the widget have inherent state. - */ -void -slider_menu_item_enable (SliderMenuItem* self, gboolean active) -{ - SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); - - dbusmenu_menuitem_property_set_bool (DBUSMENU_MENUITEM(self), - DBUSMENU_MENUITEM_PROP_ENABLED, - active); - if(active == FALSE){ - priv->index = NOT_ACTIVE; - if(priv->name != NULL){ - g_free(priv->name); - priv->name = NULL; - } - } -} - -gint -slider_menu_item_get_sink_index (SliderMenuItem* self) -{ - SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); - return priv->index; -} - -static pa_cvolume -slider_menu_item_construct_mono_volume (const pa_cvolume* vol) -{ - pa_cvolume new_volume; - pa_cvolume_init(&new_volume); - new_volume.channels = 1; - pa_volume_t max_vol = pa_cvolume_max(vol); - pa_cvolume_set(&new_volume, 1, max_vol); - return new_volume; -} - -SliderMenuItem* -slider_menu_item_new (Device* sink) -{ - SliderMenuItem *self = g_object_new(SLIDER_MENU_ITEM_TYPE, NULL); - SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); - priv->a_sink = sink; - return self; -} diff --git a/src/slider-menu-item.h b/src/slider-menu-item.h deleted file mode 100644 index 4375971..0000000 --- a/src/slider-menu-item.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -#ifndef __SLIDER_MENU_ITEM_H__ -#define __SLIDER_MENU_ITEM_H__ - -#include -#include - -#include -#include "device.h" - -G_BEGIN_DECLS - -#define SLIDER_MENU_ITEM_TYPE (slider_menu_item_get_type ()) -#define SLIDER_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SLIDER_MENU_ITEM_TYPE, SliderMenuItem)) -#define SLIDER_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SLIDER_MENU_ITEM_TYPE, SliderMenuItemClass)) -#define IS_SLIDER_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SLIDER_MENU_ITEM_TYPE)) -#define IS_SLIDER_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SLIDER_MENU_ITEM_TYPE)) -#define SLIDER_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SLIDER_MENU_ITEM_TYPE, SliderMenuItemClass)) - -typedef struct _SliderMenuItem SliderMenuItem; -typedef struct _SliderMenuItemClass SliderMenuItemClass; - -struct _SliderMenuItemClass { - DbusmenuMenuitemClass parent_class; -}; - -struct _SliderMenuItem { - DbusmenuMenuitem parent; -}; - -GType slider_menu_item_get_type (void); - -void slider_menu_item_update(SliderMenuItem* item, const pa_sink_info* update); -void slider_menu_item_enable(SliderMenuItem* item, gboolean active); -void slider_menu_item_populate (SliderMenuItem* self, const pa_sink_info* update); -//void -//active_sink_update (ActiveSink* sink, -// const pa_sink_info* update) - -gint slider_menu_item_get_sink_index (SliderMenuItem* self); - -SliderMenuItem* slider_menu_item_new (Device* sink); - -G_END_DECLS - -#endif - diff --git a/src/sound-state.c b/src/sound-state.c deleted file mode 100644 index 72e411a..0000000 --- a/src/sound-state.c +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#include "config.h" - -#include "sound-state.h" - -SoundState -sound_state_get_from_volume (int volume_percent) -{ - SoundState state = LOW_LEVEL; - - if (volume_percent < 30 && volume_percent > 0) { - state = LOW_LEVEL; - } - else if (volume_percent < 70 && volume_percent >= 30) { - state = MEDIUM_LEVEL; - } - else if (volume_percent >= 70) { - state = HIGH_LEVEL; - } - else if (volume_percent <= 0) { - state = ZERO_LEVEL; - } - return state; -} - diff --git a/src/sound-state.h b/src/sound-state.h deleted file mode 100644 index 9527c8e..0000000 --- a/src/sound-state.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#ifndef _SOUND_STATE_H_ -#define _SOUND_STATE_H_ - -#include -#include "common-defs.h" - -/* Helper functions for determining SOUNDSTATE */ - -SoundState sound_state_get_from_volume (int volume_percent); - -#endif /* _SOUND_STATE_H_ */ - diff --git a/src/specific-items-manager.vala b/src/specific-items-manager.vala deleted file mode 100644 index 923cf3f..0000000 --- a/src/specific-items-manager.vala +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -using Dbusmenu; -using Gee; - -public class SpecificItemsManager : GLib.Object -{ - public enum category{ - TRACK, - PLAYER - } - - private PlayerController owner {get; set;} - private string dbus_path; - private Dbusmenu.Client client; - public Gee.ArrayList proxy_items {get; construct;} - private int of_type; - - public SpecificItemsManager (PlayerController controller, - string path, - category which_type) - { - this.of_type = which_type; - this.owner = controller; - this.dbus_path = path; - this.client = new Dbusmenu.Client (this.owner.dbus_name, this.dbus_path); - this.client.root_changed.connect (on_root_changed); - } - construct{ - this.proxy_items = new ArrayList(); - } - - private int figure_out_positioning() - { - int result = 0 ; - if (this.of_type == category.TRACK){ - result = this.owner.menu_offset + this.owner.WIDGET_QUANTITY + this.proxy_items.size; - } - else if (this.of_type == category.PLAYER){ - int pos = this.owner.menu_offset + this.owner.WIDGET_QUANTITY + this.owner.track_specific_count(); - //Surely the playlists item is there whether its visible or not ? - //TODO test playlists and player specific item positioning. - pos += this.owner.use_playlists == true ? 1 : 0; - result = pos; - } - debug ("!!!!! Menu pos of type %i is = %i", this.of_type, result); - return result; - } - - private void on_root_changed (GLib.Object? newroot) - { - if (newroot == null){ - debug ("root disappeared -remove proxyitems"); - foreach(var p in proxy_items){ - this.owner.root_menu.child_delete (p); - } - this.proxy_items.clear(); - debug ("array list size is now %i", this.proxy_items.size); - //this.proxy_items = new ArrayList(); - return; - } - - Dbusmenu.Menuitem? root = this.client.get_root(); - root.child_added.connect (on_child_added); - root.child_removed.connect (on_child_removed); - - // Fetch what children are there already. - GLib.List children = root.get_children().copy(); - - foreach (void* child in children) { - int pos = figure_out_positioning(); - unowned Dbusmenu.Menuitem item = (Dbusmenu.Menuitem)child; - Dbusmenu.MenuitemProxy proxy = new Dbusmenu.MenuitemProxy(item); - proxy_items.add (proxy); - debug ("Proxy item of label = %s added to collection", - item.property_get (MENUITEM_PROP_LABEL)); - this.owner.root_menu.child_add_position (proxy, pos); - - } - } - - private void on_child_added (GLib.Object child, uint position) - { - debug ("On child added Specific root node"); - } - - private void on_child_removed (GLib.Object child) - { - debug ("On child removed Specific root node"); - } - -} diff --git a/src/transport-menu-item.vala b/src/transport-menu-item.vala deleted file mode 100644 index 4ec7dad..0000000 --- a/src/transport-menu-item.vala +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -using Dbusmenu; -using Gee; -using DbusmenuTransport; -using Transport; - -public class TransportMenuitem : PlayerItem -{ - private Transport.Action cached_action; - - private bool running { - get{ - return this.owner.current_state == PlayerController.state.CONNECTED; - } - } - - public TransportMenuitem(PlayerController parent) - { - Object(item_type: MENUITEM_TYPE, owner: parent); - } - construct{ - this.property_set_int(MENUITEM_PLAY_STATE, (int)Transport.State.PAUSED); - this.property_set (MENUITEM_PROP_LABEL, this.owner.app_info.get_name()); - this.cached_action = Transport.Action.NO_ACTION; - } - - /** - Please remove this timeout when the default player can handle mpris commands - immediately once it raises its dbus interface - **/ - public void handle_cached_action() - { - if (this.cached_action != Transport.Action.NO_ACTION){ - Timeout.add_seconds (1, send_cached_action); - } - } - - private bool send_cached_action() - { - this.owner.mpris_bridge.transport_update(this.cached_action); - this.cached_action = Transport.Action.NO_ACTION; - return false; - } - - public void change_play_state (Transport.State update) - { - int temp = (int)update; - this.property_set_int(MENUITEM_PLAY_STATE, temp); - } - - public override void handle_event(string name, - Variant input_value, - uint timestamp) - { - Variant v = input_value; - if ( input_value.is_of_type (VariantType.VARIANT)){ - v = input_value.get_variant(); - } - - int32 input = v.get_int32(); - - if (this.running == true){ - this.owner.mpris_bridge.transport_update((Transport.Action)input); - } - else{ - this.cached_action = (Transport.Action)input; - this.owner.instantiate(); - this.property_set_int (MENUITEM_PLAY_STATE, (int)Transport.State.LAUNCHING); - } - } - - public static HashSet attributes_format() - { - HashSet attrs = new HashSet(); - attrs.add(MENUITEM_PLAY_STATE); - return attrs; - } - -} diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c deleted file mode 100644 index 7cbdd45..0000000 --- a/src/voip-input-menu-item.c +++ /dev/null @@ -1,278 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "voip-input-menu-item.h" -#include "common-defs.h" -#include "pulseaudio-mgr.h" - -typedef struct _VoipInputMenuItemPrivate VoipInputMenuItemPrivate; - -struct _VoipInputMenuItemPrivate { - Device* a_sink; - pa_cvolume volume; - gint mute; - guint32 volume_steps; - pa_channel_map channel_map; - pa_volume_t base_volume; - gint source_index; - gint source_output_index; - gint client_index; -}; - -#define VOIP_INPUT_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemPrivate)) - -/* Prototypes */ -static void voip_input_menu_item_class_init (VoipInputMenuItemClass *klass); -static void voip_input_menu_item_init (VoipInputMenuItem *self); -static void voip_input_menu_item_dispose (GObject *object); -static void voip_input_menu_item_finalize (GObject *object); -static void handle_event (DbusmenuMenuitem * mi, const gchar * name, - GVariant * value, guint timestamp); -// TODO: -// This method should really be shared between this and the volume slider obj -// perfectly static - wait until the device mgr wrapper is properly sorted and -// then consolidate -static pa_cvolume voip_input_menu_item_construct_mono_volume (const pa_cvolume* vol); - -G_DEFINE_TYPE (VoipInputMenuItem, voip_input_menu_item, DBUSMENU_TYPE_MENUITEM); - -static void -voip_input_menu_item_class_init (VoipInputMenuItemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (VoipInputMenuItemPrivate)); - - object_class->dispose = voip_input_menu_item_dispose; - object_class->finalize = voip_input_menu_item_finalize; - - DbusmenuMenuitemClass * mclass = DBUSMENU_MENUITEM_CLASS(klass); - mclass->handle_event = handle_event; -} - -static void -voip_input_menu_item_init (VoipInputMenuItem *self) -{ - dbusmenu_menuitem_property_set( DBUSMENU_MENUITEM(self), - DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_VOIP_INPUT_MENUITEM_TYPE ); - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (self); - dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(self), - DBUSMENU_MENUITEM_PROP_VISIBLE, - FALSE ); - - priv->source_index = NOT_ACTIVE; - priv->source_output_index = NOT_ACTIVE; - priv->client_index = NOT_ACTIVE; - priv->mute = NOT_ACTIVE; -} - -static void -voip_input_menu_item_dispose (GObject *object) -{ - G_OBJECT_CLASS (voip_input_menu_item_parent_class)->dispose (object); - return; -} - -static void -voip_input_menu_item_finalize (GObject *object) -{ - G_OBJECT_CLASS (voip_input_menu_item_parent_class)->finalize (object); -} - -static void -handle_event (DbusmenuMenuitem * mi, - const gchar * name, - GVariant * value, - guint timestamp) -{ - GVariant* input = NULL; - input = value; - if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT) == TRUE) { - input = g_variant_get_variant(value); - } - - gdouble percent = g_variant_get_double(input); - if (value != NULL){ - if (IS_VOIP_INPUT_MENU_ITEM (mi)) { - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (VOIP_INPUT_MENU_ITEM (mi)); -/* - g_debug ("Handle event in the voip input level backend instance - %f", percent); -*/ - pa_cvolume new_volume; - pa_cvolume_init(&new_volume); - new_volume.channels = 1; - pa_volume_t new_volume_value = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100); - pa_cvolume_set(&new_volume, 1, new_volume_value); - - pm_update_mic_gain (priv->source_index, new_volume); - // finally unmute if needed - if (priv->mute == 1) { - pm_update_mic_mute (priv->source_index, 0); - } - } - } -} - -static pa_cvolume -voip_input_menu_item_construct_mono_volume (const pa_cvolume* vol) -{ - pa_cvolume new_volume; - pa_cvolume_init(&new_volume); - new_volume.channels = 1; - pa_volume_t max_vol = pa_cvolume_max(vol); - pa_cvolume_set(&new_volume, 1, max_vol); - return new_volume; -} - -void -voip_input_menu_item_update (VoipInputMenuItem* item, - const pa_source_info* source) -{ - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - // only overwrite the constants of each source if the device has changed - if (priv->source_index == NOT_ACTIVE){ - priv->base_volume = source->base_volume; - priv->volume_steps = source->n_volume_steps; - priv->channel_map = source->channel_map; - priv->source_index = source->index; - } - priv->volume = voip_input_menu_item_construct_mono_volume (&source->volume); - pa_volume_t vol = pa_cvolume_max (&source->volume); - gdouble update = ((gdouble) vol * 100) / PA_VOLUME_NORM; - - GVariant* new_volume = g_variant_new_double(update); - dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(item), - DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL, - new_volume); - // Only send over the mute updates if the state has changed. - // in this order - volume first mute last!! - if (priv->mute != source->mute){ -/* - g_debug ("voip menu item - update - mute = %i", priv->mute); -*/ - GVariant* new_mute_update = g_variant_new_int32 (source->mute); - dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(item), - DBUSMENU_VOIP_INPUT_MENUITEM_MUTE, - new_mute_update); - } - - priv->mute = source->mute; - -} - -gboolean -voip_input_menu_item_is_interested (VoipInputMenuItem* item, - gint source_output_index, - gint client_index) -{ - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - // Check to make sure we are not handling another voip beforehand and that we - // have an active sink (might need to match up at start up) - if (priv->source_output_index != NOT_ACTIVE && - priv->source_index != NOT_ACTIVE){ - return FALSE; - } - - priv->source_output_index = source_output_index; - priv->client_index = client_index; - - return TRUE; -} - -gboolean -voip_input_menu_item_is_active (VoipInputMenuItem* item) -{ - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - return (priv->source_output_index != NOT_ACTIVE && priv->client_index != NOT_ACTIVE); -} - - -gboolean -voip_input_menu_item_is_populated (VoipInputMenuItem* item) -{ - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - return priv->source_index != NOT_ACTIVE; -} - -gint -voip_input_menu_item_get_index (VoipInputMenuItem* item) -{ - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - return priv->source_index; -} - -gint -voip_input_menu_item_get_source_output_index (VoipInputMenuItem* item) -{ - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - - return priv->source_output_index; -} - -/** - * If the pulse server informs of a default source change - * or the source in question is removed. - * @param item - */ -void -voip_input_menu_item_deactivate_source (VoipInputMenuItem* item, gboolean visible) -{ - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - priv->source_index = NOT_ACTIVE; - dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(item), - DBUSMENU_MENUITEM_PROP_VISIBLE, - visible ); -} - -void -voip_input_menu_item_deactivate_voip_client (VoipInputMenuItem* item) -{ - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - priv->client_index = NOT_ACTIVE; - priv->source_output_index = NOT_ACTIVE; - voip_input_menu_item_enable (item, FALSE); -} - -void -voip_input_menu_item_enable (VoipInputMenuItem* item, - gboolean active) -{ - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - if (priv->source_index == NOT_ACTIVE && active == TRUE) { - g_warning ("Tried to enable the VOIP menuitem but we don't have an active source ??"); - active = FALSE; - } - dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(item), - DBUSMENU_MENUITEM_PROP_VISIBLE, - active ); -} - -VoipInputMenuItem* -voip_input_menu_item_new (Device* sink) -{ - VoipInputMenuItem *self = g_object_new(VOIP_INPUT_MENU_ITEM_TYPE, NULL); - VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (self); - priv->a_sink = sink; - return self; -} \ No newline at end of file diff --git a/vapi/common-defs.vapi b/vapi/common-defs.vapi deleted file mode 100644 index 33b4aad..0000000 --- a/vapi/common-defs.vapi +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -[CCode (cheader_filename = "common-defs.h")] -namespace DbusmenuMetadata{ - public const string MENUITEM_TYPE; - public const string MENUITEM_ARTIST; - public const string MENUITEM_TITLE; - public const string MENUITEM_ALBUM; - public const string MENUITEM_ARTURL; - public const string MENUITEM_PLAYER_NAME; - public const string MENUITEM_PLAYER_ICON; - public const string MENUITEM_PLAYER_RUNNING; - public const string MENUITEM_HIDE_TRACK_DETAILS; -} - -[CCode (cheader_filename = "common-defs.h")] -namespace DbusmenuTransport{ - public const string MENUITEM_TYPE; - public const string MENUITEM_PLAY_STATE; -} - -[CCode (cheader_filename = "common-defs.h")] -namespace DbusmenuTrackSpecific{ - public const string MENUITEM_TYPE; -} - -[CCode (cheader_filename = "common-defs.h")] -namespace DbusmenuPlaylists{ - public const string MENUITEM_TYPE; - public const string MENUITEM_TITLE; - public const string MENUITEM_PLAYLISTS; -} -[CCode (cheader_filename = "common-defs.h")] -namespace DbusmenuPlaylist{ - public const string MENUITEM_PATH; -} - -[CCode (cprefix ="Transport", cheader_filename = "common-defs.h")] -namespace Transport{ - public enum Action{ - PREVIOUS, - PLAY_PAUSE, - NEXT, - REWIND, - FORWIND, - NO_ACTION - } - public enum State{ - PLAYING, - PAUSED, - LAUNCHING - } -} -- cgit v1.2.3 From 6c65b1d8e63ab351ea4da525ecdfc5226161bfc6 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 19 Jun 2013 12:06:21 -0400 Subject: Mark translatable strings as translatable --- src/Makefile.am | 4 +++- src/service.vala | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index 84ee0f1..15a5cbf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,6 +27,8 @@ indicator_sound_service_CFLAGS = $(PULSEAUDIO_CFLAGS) \ $(SOUNDSERVICE_CFLAGS) \ $(GCONF_CFLAGS) \ $(COVERAGE_CFLAGS) \ - -DLIBEXECDIR=\"$(libexecdir)\" -Wall + -DLIBEXECDIR=\"$(libexecdir)\" -Wall \ + -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" + indicator_sound_service_LDADD = $(PULSEAUDIO_LIBS) $(SOUNDSERVICE_LIBS) $(GCONF_LIBS) indicator_sound_service_LDFLAGS = $(COVERAGE_LDFLAGS) diff --git a/src/service.vala b/src/service.vala index 2196135..add5658 100644 --- a/src/service.vala +++ b/src/service.vala @@ -96,7 +96,7 @@ public class IndicatorSound.Service { static Menu create_menu () { var volume_section = new Menu (); - volume_section.append ("Mute", "indicator.mute"); + volume_section.append (_("Mute"), "indicator.mute"); var slider = new MenuItem (null, "indicator.volume"); slider.set_attribute ("x-canonical-type", "s", "com.canonical.unity.slider"); @@ -109,7 +109,7 @@ public class IndicatorSound.Service { var menu = new Menu (); menu.append_section (null, volume_section); - menu.append ("Sound Settings…", "indicator.settings"); + menu.append (_("Sound Settings…"), "indicator.settings"); return menu; } -- cgit v1.2.3 From a0773c53b13546f4957f2b2ac1f0455fedc05525 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 19 Jun 2013 15:29:12 -0400 Subject: Disable warnings for vala-generated C code --- src/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index 15a5cbf..5958b51 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,11 +23,13 @@ indicator_sound_service_VALAFLAGS = \ --pkg libpulse-mainloop-glib \ --target-glib=2.36 +# -w to disable warnings for vala-generated code indicator_sound_service_CFLAGS = $(PULSEAUDIO_CFLAGS) \ $(SOUNDSERVICE_CFLAGS) \ $(GCONF_CFLAGS) \ $(COVERAGE_CFLAGS) \ - -DLIBEXECDIR=\"$(libexecdir)\" -Wall \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -w \ -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" indicator_sound_service_LDADD = $(PULSEAUDIO_LIBS) $(SOUNDSERVICE_LIBS) $(GCONF_LIBS) -- cgit v1.2.3 From 7ca667494e32d110766c2b4a013b6a2c37b8a084 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 4 Jul 2013 16:09:09 -0400 Subject: Put service into $pkglibexecdir --- data/Makefile.am | 2 +- data/indicator-sound.service.in | 2 +- src/Makefile.am | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/Makefile.am') diff --git a/data/Makefile.am b/data/Makefile.am index 5160dd9..7647d73 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -6,7 +6,7 @@ dbus_servicesdir = $(datadir)/dbus-1/services dbus_services_DATA = indicator-sound.service %.service: %.service.in - sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ + sed -e "s|\@pkglibexecdir\@|$(pkglibexecdir)|" $< > $@ indicatordir = $(INDICATOR_DIR) dist_indicator_DATA = com.canonical.indicator.sound diff --git a/data/indicator-sound.service.in b/data/indicator-sound.service.in index 4cee062..e8b77c6 100644 --- a/data/indicator-sound.service.in +++ b/data/indicator-sound.service.in @@ -1,3 +1,3 @@ [D-BUS Service] Name=com.canonical.indicator.sound -Exec=@libexecdir@/indicator-sound-service +Exec=@pkglibexecdir@/indicator-sound-service diff --git a/src/Makefile.am b/src/Makefile.am index 5958b51..da3df5b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -libexec_PROGRAMS = indicator-sound-service +pkglibexec_PROGRAMS = indicator-sound-service indicator_sound_service_SOURCES = \ service.vala \ -- cgit v1.2.3