aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorConor Curran <conor.curran@canonical.com>2010-08-11 21:58:44 +0100
committerConor Curran <conor.curran@canonical.com>2010-08-11 21:58:44 +0100
commita2602568c272cc87aa02db62b46de5c05710c29a (patch)
tree2c745c8bfa45f3d45402ce5e21308f5391e11de2 /src
parent8286c9e86314f8ff459576efde19b03709634140 (diff)
parentb63691637ebc766e90c0da44e76cc7b9cc49872e (diff)
downloadayatana-indicator-sound-a2602568c272cc87aa02db62b46de5c05710c29a.tar.gz
ayatana-indicator-sound-a2602568c272cc87aa02db62b46de5c05710c29a.tar.bz2
ayatana-indicator-sound-a2602568c272cc87aa02db62b46de5c05710c29a.zip
mpris v2 branch merged
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/mpris-controller-v2.vala28
-rw-r--r--src/mpris-controller.vala16
-rw-r--r--src/mpris2-controller.vala183
-rw-r--r--src/music-player-bridge.vala6
-rw-r--r--src/play-button.c8
-rw-r--r--src/player-controller.vala82
-rw-r--r--src/player-item.vala2
-rw-r--r--src/scrub-menu-item.vala7
-rw-r--r--src/scrub-widget.c2
-rw-r--r--src/transport-menu-item.vala2
11 files changed, 278 insertions, 61 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ce7a580..0e22fe4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -65,13 +65,14 @@ music_bridge_VALASOURCES = \
scrub-menu-item.vala \
title-menu-item.vala \
player-controller.vala \
- mpris-controller-v2.vala \
mpris-controller.vala \
+ mpris2-controller.vala \
player-item.vala \
familiar-players-db.vala
music_bridge_VALAFLAGS = \
--ccode \
+ --disable-dbus-transformation \
-H music-player-bridge.h -d . \
--vapidir=$(top_srcdir)/vapi/ \
--vapidir=./ \
diff --git a/src/mpris-controller-v2.vala b/src/mpris-controller-v2.vala
deleted file mode 100644
index efb5084..0000000
--- a/src/mpris-controller-v2.vala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-This service primarily controls PulseAudio and is driven by the sound indicator menu on the panel.
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Conor Curran <conor.curran@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-using Gee;
-
-public class MprisControllerV2 : MprisController
-{
- public MprisControllerV2(PlayerController ctrl, string inter="org.mpris.MediaPlayer.Player"){
- Object(owner: ctrl, mpris_interface: inter);
- }
-
-}
diff --git a/src/mpris-controller.vala b/src/mpris-controller.vala
index 8ecd20a..c70c6d5 100644
--- a/src/mpris-controller.vala
+++ b/src/mpris-controller.vala
@@ -124,17 +124,23 @@ public class MprisController : GLib.Object
private void onTrackChange(dynamic DBus.Object mpris_client, HashTable<string,Value?> ht)
{
debug("onTrackChange");
+
this.owner.custom_items[PlayerController.widget_order.METADATA].reset(MetadataMenuitem.attributes_format());
this.owner.custom_items[PlayerController.widget_order.SCRUB].reset(ScrubMenuitem.attributes_format());
+ HashTable<string, Value?> status_hash = new HashTable<string, Value?>(str_hash, str_equal);
+
+ status st = this.mpris_player.GetStatus();
+ int play_state = st.playback;
+ debug("GetStatusChange, about to update scrub with play state - %i", play_state);
+
+ ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem;
+ scrub.update_playstate(play_state);
+ this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.mpris_player.GetMetadata(),
+ ScrubMenuitem.attributes_format());
this.owner.custom_items[PlayerController.widget_order.METADATA].update(ht,
MetadataMenuitem.attributes_format());
debug("about to update the duration on the scrub bar");
- this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.mpris_player.GetMetadata(),
- ScrubMenuitem.attributes_format());
// temporary fix
- ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem;
scrub.update_position(this.mpris_player.PositionGet());
}
-
-
}
diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala
new file mode 100644
index 0000000..20cfc9e
--- /dev/null
+++ b/src/mpris2-controller.vala
@@ -0,0 +1,183 @@
+/*
+This service primarily controls PulseAudio and is driven by the sound indicator menu on the panel.
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+using Gee;
+
+[DBus (name = "org.mpris.MediaPlayer.Player")]
+public interface MprisPlayer : Object {
+
+ public struct Status {
+ public int32 Playback_State;
+ public double Playback_Rate;
+ public bool Repeat_State;
+ public bool Shuffle_State;
+ public bool Endless_State;
+ }
+
+ public abstract HashTable<string, Value?> Metadata{owned get;}
+ public abstract double Volume{get;}
+ public abstract int32 Capabilities{get;}
+ public abstract int32 Position{get;}
+
+ public abstract void SetPosition(string prop, int32 pos) throws DBus.Error;
+ public abstract void PlayPause() throws DBus.Error;
+ public abstract void Pause() throws DBus.Error;
+ public abstract void Next() throws DBus.Error;
+ public abstract void Previous() throws DBus.Error;
+
+ public abstract signal void StatusChanged(Status update);
+ public abstract signal void TrackChanged(HashTable<string,Value?> Metadata);
+}
+
+/*
+ This class will entirely replace mpris-controller.vala hence why there is no
+ point in trying to get encorporate both into the same object model.
+ */
+public class Mpris2Controller : GLib.Object
+{
+ private DBus.Connection connection;
+ public dynamic DBus.Object mpris2_root {get; construct;}
+ public MprisPlayer mpris2_player {get; construct;}
+ public PlayerController owner {get; construct;}
+
+ public Mpris2Controller(PlayerController ctrl)
+ {
+ Object(owner: ctrl);
+ }
+
+ construct{
+ try {
+ debug("going to create this mpris 2 controller");
+ this.connection = DBus.Bus.get (DBus.BusType.SESSION);
+ } catch (Error e) {
+ error("Problems connecting to the session bus - %s", e.message);
+ }
+ this.mpris2_root = this.connection.get_object ("org.mpris.mediaplayers.".concat(this.owner.name.down()),
+ "/org/mpris/MediaPlayer",
+ "org.mpris.MediaPlayer");
+
+ this.mpris2_player = (MprisPlayer)this.connection.get_object ("org.mpris.mediaplayers.".concat(this.owner.name.down()) ,
+ "/org/mpris/MediaPlayer/Player",
+ "org.mpris.MediaPlayer.Player");
+ this.mpris2_player.TrackChanged += onTrackChanged;
+ this.mpris2_player.StatusChanged += onStatusChanged;
+ initial_update();
+ }
+
+ private void initial_update()
+ {
+ bool r = (bool)this.mpris2_player.Status.Shuffle_State;
+ int32 p = (int32)this.mpris2_player.Status.Playback_State;
+
+ debug("initial update - play state %i", p);
+ debug("initial update - shuffle state %s", r.to_string());
+
+ (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p);
+ this.owner.custom_items[PlayerController.widget_order.METADATA].update(this.mpris2_player.Metadata,
+ MetadataMenuitem.attributes_format());
+ this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.mpris2_player.Metadata,
+ ScrubMenuitem.attributes_format());
+ ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem;
+ scrub.update_position(this.mpris2_player.Position);
+
+ }
+
+ public void transport_event(TransportMenuitem.action command)
+ {
+ debug("transport_event input = %i", (int)command);
+ if(command == TransportMenuitem.action.PLAY_PAUSE){
+ debug("transport_event PLAY_PAUSE");
+ this.mpris2_player.PlayPause();
+ }
+ else if(command == TransportMenuitem.action.PREVIOUS){
+ this.mpris2_player.Previous();
+ }
+ else if(command == TransportMenuitem.action.NEXT){
+ this.mpris2_player.Next();
+ }
+ }
+
+ public void set_position(double position)
+ {
+ debug("Set position with pos (0-100) %f", position);
+ HashTable<string, Value?> data = this.mpris2_player.Metadata;
+ Value? time_value = data.lookup("time");
+ if(time_value == null){
+ warning("Can't fetch the duration of the track therefore cant set the position");
+ return;
+ }
+ uint32 total_time = time_value.get_uint();
+ debug("total time of track = %i", (int)total_time);
+ double new_time_position = total_time * position/100.0;
+ debug("new position = %f", (new_time_position * 1000));
+
+ Value? v = this.mpris2_player.Metadata.lookup("trackid");
+ if(v != null){
+ if(v.holds (typeof (int))){
+ debug("the trackid = %i", v.get_int());
+ }
+ else if(v.holds (typeof (string))){
+ debug("the trackid = %s", v.get_string());
+ }
+ }
+
+ //this.mpris2_player.SetPosition((int32)(new_time_position));
+ ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem;
+ scrub.update_position(this.mpris2_player.Position);
+ }
+
+ public bool connected()
+ {
+ return (this.mpris2_player != null);
+ }
+
+ private void onStatusChanged(MprisPlayer.Status st)
+ {
+ debug("onStatusChange - play state %i", st.Playback_State);
+ HashTable<string, Value?> ht = new HashTable<string, Value?>(str_hash, str_equal);
+ Value v = Value(typeof(int));
+ v.set_int(st.Playback_State);
+ ht.insert("state", v);
+ this.owner.custom_items[PlayerController.widget_order.TRANSPORT].update(ht, TransportMenuitem.attributes_format());
+ this.owner.custom_items[PlayerController.widget_order.SCRUB].update(ht, ScrubMenuitem.attributes_format());
+ }
+
+ private void onTrackChanged(HashTable<string,Value?> ht)
+ {
+ this.owner.custom_items[PlayerController.widget_order.METADATA].reset(MetadataMenuitem.attributes_format());
+ this.owner.custom_items[PlayerController.widget_order.SCRUB].reset(ScrubMenuitem.attributes_format());
+ this.owner.custom_items[PlayerController.widget_order.METADATA].update(ht,
+ MetadataMenuitem.attributes_format());
+ debug("about to update the duration on the scrub bar");
+ Value? v = ht.lookup("time");
+ if(v != null)
+ {
+ debug("with the duration of %i", (int)v.get_uint());
+ debug("with Position of %i", this.mpris2_player.Position);
+ }
+ this.owner.custom_items[PlayerController.widget_order.SCRUB].update(ht,
+ ScrubMenuitem.attributes_format());
+ ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem;
+ scrub.update_position(this.mpris2_player.Position);
+ }
+
+}
+
+
+
diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala
index 352ea7f..daad42f 100644
--- a/src/music-player-bridge.vala
+++ b/src/music-player-bridge.vala
@@ -116,10 +116,8 @@ public class MusicPlayerBridge : GLib.Object
if(server_is_not_of_interest(type)) return;
string client_name = type.split(".")[1];
if (root_menu != null && client_name != null){
- registered_clients[client_name].vanish();
- registered_clients.remove(client_name);
- debug("Successively removed menu_item for client %s from registered_clients",
- client_name);
+ registered_clients[client_name].hibernate();
+ debug("Successively offlined client %s", client_name);
}
}
diff --git a/src/play-button.c b/src/play-button.c
index 94e6f98..2f3a553 100644
--- a/src/play-button.c
+++ b/src/play-button.c
@@ -28,7 +28,7 @@ Uses code from ctk
#include "play-button.h"
#define RECT_WIDTH 130.0f
-#define Y 5.0f
+#define Y 7.0f
#define X 37.0f
#define INNER_RADIUS 12.5
#define MIDDLE_RADIUS 13.5f
@@ -42,16 +42,16 @@ Uses code from ctk
#define TRI_HEIGHT 13.0f
#define TRI_OFFSET 6.0f
#define PREV_X 35.0f
-#define PREV_Y 11.0f
+#define PREV_Y 13.0f
#define NEXT_X 113.0f
-#define NEXT_Y 11.0f //prev_y
+#define NEXT_Y 13.0f //prev_y
#define PAUSE_WIDTH 21.0f
#define PAUSE_HEIGHT 27.0f
#define BAR_WIDTH 4.5f
#define BAR_HEIGHT 24.0f
#define BAR_OFFSET 10.0f
#define PAUSE_X 78.0f
-#define PAUSE_Y 5.0f
+#define PAUSE_Y 7.0f
#define PLAY_WIDTH 28.0f
#define PLAY_HEIGHT 29.0f
#define PLAY_PADDING 5.0f
diff --git a/src/player-controller.vala b/src/player-controller.vala
index fc5ca9b..33a5b1a 100644
--- a/src/player-controller.vala
+++ b/src/player-controller.vala
@@ -48,12 +48,15 @@ public class PlayerController : GLib.Object
private Dbusmenu.Menuitem root_menu;
public string name { get; set;}
public ArrayList<PlayerItem> custom_items;
+ public Mpris2Controller mpris2_adaptor;
public MprisController mpris_adaptor;
+ public bool mpris2;
public AppInfo? app_info { get; set;}
public int menu_offset { get; set;}
public PlayerController(Dbusmenu.Menuitem root, string client_name, int offset, state initial_state)
{
+ this.mpris2 = false;
this.root_menu = root;
this.name = format_client_name(client_name.strip());
this.custom_items = new ArrayList<PlayerItem>();
@@ -74,7 +77,7 @@ public class PlayerController : GLib.Object
public void activate()
{
this.establish_mpris_connection();
- this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, true);
+ //this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE, true);
}
/*
@@ -100,23 +103,16 @@ public class PlayerController : GLib.Object
if(this.current_state != state.READY){
debug("establish_mpris_connection - Not ready to connect");
return;
- }
-
+ }
if(this.name == "Vlc"){
debug("establishing a vlc mpris controller");
- this.mpris_adaptor = new MprisController(this, "org.mpris.MediaPlayer.Player");
+ this.mpris2_adaptor = new Mpris2Controller(this);
+ this.mpris2 = true;
}
else{
this.mpris_adaptor = new MprisController(this);
}
- // TODO refactor
- if(this.mpris_adaptor.connected() == true){
- debug("yup I'm connected");
- this.update_state(state.CONNECTED);
- }
- else{
- this.update_state(state.DISCONNECTED);
- }
+ this.determine_state();
}
public void vanish()
@@ -126,8 +122,17 @@ public class PlayerController : GLib.Object
}
}
+ public void hibernate()
+ {
+ update_state(PlayerController.state.OFFLINE);
+ this.custom_items[widget_order.TRANSPORT].reset(TransportMenuitem.attributes_format());
+ this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.attributes_format());
+ this.custom_items[widget_order.SCRUB].reset(ScrubMenuitem.attributes_format());
+ }
+
public void update_layout()
- {
+ {
+
if(this.current_state != state.CONNECTED){
this.custom_items[widget_order.TRANSPORT].property_set_bool(MENUITEM_PROP_VISIBLE,
false);
@@ -137,12 +142,13 @@ public class PlayerController : GLib.Object
false);
this.custom_items[widget_order.PLAYLIST].property_set_bool(MENUITEM_PROP_VISIBLE,
false);
- return;
+ return;
}
-
debug("update layout - metadata %s", this.custom_items[widget_order.METADATA].populated(MetadataMenuitem.attributes_format()).to_string());
this.custom_items[widget_order.METADATA].property_set_bool(MENUITEM_PROP_VISIBLE,
this.custom_items[widget_order.METADATA].populated(MetadataMenuitem.attributes_format()));
+ //debug("metadata id %i", this.custom_items[widget_order.METADATA].id);
+
debug("update layout - scrub %s", this.custom_items[widget_order.SCRUB].populated(ScrubMenuitem.attributes_format()).to_string());
this.custom_items[widget_order.SCRUB].property_set_bool(MENUITEM_PROP_VISIBLE,
this.custom_items[widget_order.SCRUB].populated(ScrubMenuitem.attributes_format()));
@@ -152,7 +158,7 @@ public class PlayerController : GLib.Object
true);
this.custom_items[widget_order.PLAYLIST].property_set_bool(MENUITEM_PROP_VISIBLE,
- true);
+ true);
}
private void construct_widgets()
@@ -214,4 +220,48 @@ public class PlayerController : GLib.Object
return formatted;
}
+ // Temporarily we will need to handle to different mpris implemenations
+ // Do it for now - a couple of weeks should see this messy carry on out of
+ // the codebase.
+ public void set_track_position(double pos)
+ {
+ if(this.mpris2 == true){
+ this.mpris2_adaptor.set_position(pos);
+ }
+ else{
+ this.mpris_adaptor.set_position(pos);
+ }
+ }
+
+ public void transport_update(TransportMenuitem.action update)
+ {
+ if(this.mpris2 == true){
+ this.mpris2_adaptor.transport_event(update);
+ }
+ else{
+ this.mpris_adaptor.transport_event(update);
+ }
+ }
+
+ public void determine_state()
+ {
+ if(this.mpris2 == true){
+ if(this.mpris2_adaptor.connected() == true){
+ debug("yup I'm connected");
+ this.update_state(state.CONNECTED);
+ }
+ else{
+ this.update_state(state.DISCONNECTED);
+ }
+ }
+ else{
+ if(this.mpris_adaptor.connected() == true){
+ debug("yup I'm connected");
+ this.update_state(state.CONNECTED);
+ }
+ else{
+ this.update_state(state.DISCONNECTED);
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/src/player-item.vala b/src/player-item.vala
index 288ac47..e5d8bfc 100644
--- a/src/player-item.vala
+++ b/src/player-item.vala
@@ -79,9 +79,11 @@ public class PlayerItem : Dbusmenu.Menuitem
this.property_set_int(property, (int)v.get_uint());
}
else if(v.holds (typeof (bool))){
+ debug("with value : %s", v.get_boolean().to_string());
this.property_set_bool(property, v.get_boolean());
}
}
+
if(this.property_get_bool(MENUITEM_PROP_VISIBLE) == false){
this.property_set_bool(MENUITEM_PROP_VISIBLE, true);
}
diff --git a/src/scrub-menu-item.vala b/src/scrub-menu-item.vala
index ca81c38..e220612 100644
--- a/src/scrub-menu-item.vala
+++ b/src/scrub-menu-item.vala
@@ -32,13 +32,18 @@ public class ScrubMenuitem : PlayerItem
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_adaptor.set_position(input_value.get_double());
+ this.owner.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<string> attributes_format()
{
diff --git a/src/scrub-widget.c b/src/scrub-widget.c
index 52d7b83..a1d45d5 100644
--- a/src/scrub-widget.c
+++ b/src/scrub-widget.c
@@ -174,7 +174,7 @@ scrub_widget_check_play_state(ScrubWidget* self)
ScrubWidgetPrivate * priv = SCRUB_WIDGET_GET_PRIVATE(self);
gint play_state = dbusmenu_menuitem_property_get_int(priv->twin_item,
DBUSMENU_SCRUB_MENUITEM_PLAY_STATE);
-
+ g_debug("play-state = %i", play_state);
if(play_state == 0){
g_debug("START TIMELINE");
ido_timeline_start(priv->time_line);
diff --git a/src/transport-menu-item.vala b/src/transport-menu-item.vala
index 3d6dcdd..45c2692 100644
--- a/src/transport-menu-item.vala
+++ b/src/transport-menu-item.vala
@@ -45,7 +45,7 @@ public class TransportMenuitem : PlayerItem
int input = input_value.get_int();
debug("handle_event with value %s", input.to_string());
debug("transport owner name = %s", this.owner.name);
- this.owner.mpris_adaptor.transport_event((action)input);
+ this.owner.transport_update((action)input);
}
public static HashSet<string> attributes_format()