From 7aa4517861e27a0857d36e83844d670446c22ee6 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 17 Aug 2010 17:26:47 +0100 Subject: mpris 2 has landed --- src/mpris-bridge.vala | 11 +++ src/mpris2-controller.vala | 171 ++++++++++++++++++++++++++++++++------------- src/sound-service.c | 4 +- src/title-menu-item.vala | 3 + 4 files changed, 139 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/mpris-bridge.vala b/src/mpris-bridge.vala index bb02550..bd9d472 100644 --- a/src/mpris-bridge.vala +++ b/src/mpris-bridge.vala @@ -47,6 +47,17 @@ public class MprisBridge : GLib.Object } } + public void expose() + { + if(this.mode_in_use == mode.MPRIS_2){ + this.mpris2_controller.expose(); + } + else{ + warning("MPRIS1 clients don't have the ability to raise/expose the client"); + } + } + + public void set_track_position(double pos) { if(this.mode_in_use == mode.MPRIS_1){ diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index cfe0d68..c5ca0a5 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -17,9 +17,10 @@ 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 DBus; [DBus (name = "org.mpris.MediaPlayer2")] -public interface MprisRoot : Object { +public interface MprisRoot : DBus.Object { // properties public abstract bool HasTracklist{owned get; set;} public abstract bool CanQuit{owned get; set;} @@ -32,19 +33,25 @@ public interface MprisRoot : Object { } [DBus (name = "org.mpris.MediaPlayer2.Player")] -public interface MprisPlayer : Object { +public interface MprisPlayer : DBus.Object { public abstract HashTable Metadata{owned get; set;} public abstract int32 Position{owned get; set;} public abstract string PlaybackStatus{owned get; set;} - public abstract void SetPosition(string prop, int32 pos) throws DBus.Error; + public abstract void SetPosition(DBus.ObjectPath path, int64 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 signal void Seeked(int new_position); + public signal void Seeked(int64 new_position); + //public signal void PropertiesChanged(string source, HashTable changed_properties, string[] invalid); +} + +[DBus (name = "org.freedesktop.DBus.Properties")] +public interface FreeDesktopProperties : DBus.Object{ + public signal void PropertiesChanged(string source, HashTable changed_properties, string[] invalid); } /* @@ -55,12 +62,13 @@ public class Mpris2Controller : GLib.Object { public static const string root_interface = "org.mpris.MediaPlayer2" ; public MprisRoot mpris2_root {get; construct;} - public MprisPlayer mpris2_player {get; construct;} - public PlayerController owner {get; construct;} + public MprisPlayer player {get; construct;} + public PlayerController owner {get; construct;} + public FreeDesktopProperties properties_interface {get; construct;} public Mpris2Controller(PlayerController ctrl) { - Object(owner: ctrl); + GLib.Object(owner: ctrl); } construct{ @@ -69,35 +77,68 @@ public class Mpris2Controller : GLib.Object this.mpris2_root = (MprisRoot) connection.get_object (root_interface.concat(".").concat(this.owner.name.down()), "/org/mpris/MediaPlayer2", root_interface); - this.mpris2_player = (MprisPlayer) connection.get_object (root_interface.concat(".").concat(this.owner.name.down()), - "/org/mpris/MediaPlayer2/Player", - root_interface.concat(".Player")); - this.mpris2_player.Seeked += onSeeked; - this.mpris2_player.notify["PlaybackStatus"].connect (property_changed); + this.player = (MprisPlayer) connection.get_object (root_interface.concat(".").concat(this.owner.name.down()), + "/org/mpris/MediaPlayer2", + root_interface.concat(".Player")); + this.player.Seeked += onSeeked; + + this.properties_interface = (FreeDesktopProperties) connection.get_object(root_interface.concat(".").concat(this.owner.name.down()), + "/org/mpris/MediaPlayer2", + "org.freedesktop.DBus.Properties"); + this.properties_interface.PropertiesChanged += property_changed_cb; } catch (DBus.Error e) { error("Problems connecting to the session bus - %s", e.message); } } - public void onSeeked(int position){ - debug("Seeked signal callback"); - } + public void property_changed_cb(string interface_source, HashTable changed_properties, string[] invalid ) + { + debug("properties-changed for interface %s", interface_source); + if(changed_properties == null || interface_source.has_prefix(this.root_interface) == false){ + warning("Property-changed hash is null"); + return; + } + Value? play_v = changed_properties.lookup("PlaybackStatus"); + if(play_v != null){ + string state = play_v.get_string(); + debug("new playback state = %s", state); + int p = this.determine_play_state(state); + (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); + (this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem).update_playstate(p); + } + + Value? pos_v = changed_properties.lookup("Position"); + if(pos_v != null){ + int64 pos = pos_v.get_int64(); + debug("new position = %i", (int)pos); + (this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem).update_position((int32)pos); + } - public void property_changed(Object mpris_player, ParamSpec new_status){ - debug("playback status changed, %s", new_status.get_name()); - } - - public bool was_successfull(){ - if(this.mpris2_root == null ||this.mpris2_player == null){ - return false; + Value? meta_v = changed_properties.lookup("Metadata"); + if(meta_v != null){ + debug("metadata is not empty"); + debug("artist : %s", this.player.Metadata.lookup("artist").get_string()); + this.owner.custom_items[PlayerController.widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); + this.owner.custom_items[PlayerController.widget_order.METADATA].update(this.player.Metadata, + MetadataMenuitem.attributes_format()); + this.owner.custom_items[PlayerController.widget_order.SCRUB].reset(ScrubMenuitem.attributes_format()); + if((int)this.player.Metadata.lookup("artist").get_string().len() > 0 || + (int)this.player.Metadata.lookup("artist").get_string().len() > 0){ + this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.player.Metadata, + ScrubMenuitem.attributes_format()); + } + (this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem).update_playstate(this.determine_play_state(this.player.PlaybackStatus)); + } - return true; } - - private int determine_play_state(){ - string status = this.mpris2_player.PlaybackStatus; - if(status == "Playing"){ + + private int determine_play_state(string status){ + if(status == null) + return 1; + + if(status != null && status == "Playing"){ + debug("determine play state - state = %s", status); return 0; } return 1; @@ -105,17 +146,22 @@ public class Mpris2Controller : GLib.Object public void initial_update() { - int32 p = determine_play_state(); - debug("initial update - play state %i", p); + int32 status; + if(this.player.PlaybackStatus == null){ + status = 1; + } + else{ + status = determine_play_state(this.player.PlaybackStatus); + } + debug("initial update - play state %i", status); - (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, + (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(status); + this.owner.custom_items[PlayerController.widget_order.METADATA].update(this.player.Metadata, MetadataMenuitem.attributes_format()); - this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.mpris2_player.Metadata, + this.owner.custom_items[PlayerController.widget_order.SCRUB].update(this.player.Metadata, ScrubMenuitem.attributes_format()); ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; - scrub.update_position(this.mpris2_player.Position); - + scrub.update_position(this.player.Position); } public void transport_event(TransportMenuitem.action command) @@ -124,7 +170,7 @@ public class Mpris2Controller : GLib.Object if(command == TransportMenuitem.action.PLAY_PAUSE){ debug("transport_event PLAY_PAUSE"); try{ - this.mpris2_player.PlayPause(); + this.player.PlayPause(); } catch(DBus.Error error){ warning("DBus Error calling the player objects PlayPause method %s", @@ -133,7 +179,7 @@ public class Mpris2Controller : GLib.Object } else if(command == TransportMenuitem.action.PREVIOUS){ try{ - this.mpris2_player.Previous(); + this.player.Previous(); } catch(DBus.Error error){ warning("DBus Error calling the player objects Previous method %s", @@ -142,7 +188,7 @@ public class Mpris2Controller : GLib.Object } else if(command == TransportMenuitem.action.NEXT){ try{ - this.mpris2_player.Next(); + this.player.Next(); } catch(DBus.Error error){ warning("DBus Error calling the player objects Next method %s", @@ -150,11 +196,14 @@ public class Mpris2Controller : GLib.Object } } } - + /** + TODO: SetPosition on the player object is not working with rhythmbox, + runtime error - "dbus function not supported" + */ public void set_position(double position) { debug("Set position with pos (0-100) %f", position); - HashTable data = this.mpris2_player.Metadata; + HashTable data = this.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"); @@ -165,26 +214,52 @@ public class Mpris2Controller : GLib.Object 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"); + Value? v = this.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))){ + if(v.holds (typeof (string))){ debug("the trackid = %s", v.get_string()); + DBus.ObjectPath path = new ObjectPath(v.get_string()); + try{ + this.player.SetPosition(path, (int64)(new_time_position * 1000)); + } + catch(DBus.Error error){ + warning("DBus Error calling the player objects SetPosition method %s", + error.message); + } } } - /*this.mpris2_player.SetPosition((int32)(new_time_position)); + } + + public void onSeeked(int64 position){ + debug("Seeked signal callback with pos = %i", (int)position/1000); ScrubMenuitem scrub = this.owner.custom_items[PlayerController.widget_order.SCRUB] as ScrubMenuitem; - scrub.update_position(this.mpris2_player.Position); - */ + scrub.update_position((int32)position/1000); } public bool connected() { - return (this.mpris2_player != null); + return (this.player != null && this.mpris2_root != null); } + + public bool was_successfull(){ + if(this.mpris2_root == null ||this.player == null){ + return false; + } + return true; + } + + public void expose() + { + if(this.connected() == true){ + try{ + this.mpris2_root.Raise(); + } + catch(DBus.Error e){ + error("Exception thrown while calling root function Raise - %s", e.message); + } + } + } } diff --git a/src/sound-service.c b/src/sound-service.c index 8768cd3..16fa87c 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -42,8 +42,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) if (mainloop != NULL) { g_debug("Service shutdown !"); // TODO: uncomment for release !! - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } diff --git a/src/title-menu-item.vala b/src/title-menu-item.vala index d7e16df..ec1cc62 100644 --- a/src/title-menu-item.vala +++ b/src/title-menu-item.vala @@ -35,6 +35,9 @@ public class TitleMenuitem : PlayerItem { this.owner.instantiate(); } + else if(this.owner.current_state == PlayerController.state.CONNECTED){ + this.owner.mpris_bridge.expose(); + } } -- cgit v1.2.3