2011-08-29 12:54:34 -07:00
|
|
|
#include <Eina.h>
|
2013-05-02 03:21:05 -07:00
|
|
|
#include <Eldbus.h>
|
2011-08-29 12:54:34 -07:00
|
|
|
#include <Ecore.h>
|
|
|
|
|
|
|
|
#include "plugin.h"
|
|
|
|
#include "song.h"
|
2010-11-10 13:04:56 -08:00
|
|
|
|
|
|
|
typedef struct _MPRIS_Method MPRIS_Method;
|
|
|
|
typedef struct _MPRIS_Signal MPRIS_Signal;
|
|
|
|
|
2011-09-03 18:33:10 -07:00
|
|
|
static int _mpris_log_domain = -1;
|
|
|
|
|
|
|
|
#ifdef CRITICAL
|
|
|
|
#undef CRITICAL
|
|
|
|
#endif
|
|
|
|
#ifdef ERR
|
|
|
|
#undef ERR
|
|
|
|
#endif
|
|
|
|
#ifdef WRN
|
|
|
|
#undef WRN
|
|
|
|
#endif
|
|
|
|
#ifdef INF
|
|
|
|
#undef INF
|
|
|
|
#endif
|
|
|
|
#ifdef DBG
|
|
|
|
#undef DBG
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define CRITICAL(...) EINA_LOG_DOM_CRIT(_mpris_log_domain, __VA_ARGS__)
|
|
|
|
#define ERR(...) EINA_LOG_DOM_ERR(_mpris_log_domain, __VA_ARGS__)
|
|
|
|
#define WRN(...) EINA_LOG_DOM_WARN(_mpris_log_domain, __VA_ARGS__)
|
|
|
|
#define INF(...) EINA_LOG_DOM_INFO(_mpris_log_domain, __VA_ARGS__)
|
|
|
|
#define DBG(...) EINA_LOG_DOM_DBG(_mpris_log_domain, __VA_ARGS__)
|
|
|
|
|
2010-11-10 13:04:56 -08:00
|
|
|
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
/*
|
|
|
|
* Capabilities and player status values conform to the MPRIS 1.0 standard:
|
|
|
|
* http://www.mpris.org/1.0/spec.html
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
MPRIS_CAPABILITY_CAN_GO_NEXT = 1 << 0,
|
|
|
|
MPRIS_CAPABILITY_CAN_GO_PREV = 1 << 1,
|
|
|
|
MPRIS_CAPABILITY_CAN_PAUSE = 1 << 2,
|
|
|
|
MPRIS_CAPABILITY_CAN_PLAY = 1 << 3,
|
|
|
|
MPRIS_CAPABILITY_CAN_SEEK = 1 << 4,
|
|
|
|
MPRIS_CAPABILITY_CAN_PROVIDE_METADATA = 1 << 5,
|
|
|
|
MPRIS_CAPABILITY_HAS_TRACKLIST = 1 << 6
|
|
|
|
} Mpris_Capabilities;
|
|
|
|
|
2010-11-10 13:04:56 -08:00
|
|
|
#define APPLICATION_NAME "org.mpris.enjoy"
|
|
|
|
#define PLAYER_INTERFACE_NAME "org.freedesktop.MediaPlayer"
|
|
|
|
#define ROOT_NAME "/Root" /* should really be "/", but this doesn't work correctly :( */
|
|
|
|
#define TRACKLIST_NAME "/TrackList"
|
|
|
|
#define PLAYER_NAME "/Player"
|
|
|
|
|
2011-08-26 12:24:05 -07:00
|
|
|
static void _mpris_signal_player_caps_change(int caps);
|
|
|
|
static void _mpris_signal_player_status_change(int playback, int shuffle, int repeat, int endless);
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
static void _mpris_signal_player_track_change(const Song *song);
|
2011-08-26 12:24:05 -07:00
|
|
|
static void _mpris_signal_tracklist_tracklist_change(int size);
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static void _mpris_append_dict_entry(Eldbus_Message_Iter *array, const char *key, const char *value_type, ...);
|
|
|
|
static Eldbus_Message *_mpris_player_next(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_previous(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_pause(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_stop(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_play(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_seek(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_root_identity(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_root_quit(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_root_version(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_caps_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_volume_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_volume_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_repeat_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_status_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_position_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_player_position_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_song_metadata_reply(const Eldbus_Message *msg, const Song *song);
|
|
|
|
static Eldbus_Message *_mpris_player_metadata_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_tracklist_current_track_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_tracklist_count(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_tracklist_metadata_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
static Eldbus_Message *_mpris_tracklist_shuffle_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg);
|
|
|
|
|
|
|
|
static void _cb_dbus_request_name(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending);
|
|
|
|
|
|
|
|
static Eldbus_Connection *conn = NULL;
|
|
|
|
static Eldbus_Service_Interface *root, *player, *tracklist;
|
2012-12-03 13:25:04 -08:00
|
|
|
static Eina_List *ev_handlers = NULL;
|
2010-11-10 13:04:56 -08:00
|
|
|
|
2012-12-03 13:25:04 -08:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
PLAYER_TRACK = 0,
|
|
|
|
PLAYER_STATUS,
|
|
|
|
PLAYER_CAPS
|
2010-11-10 13:04:56 -08:00
|
|
|
};
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static const Eldbus_Signal mpris_player_signals[] = {
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Emitted whenever a new song is played; gives the song metadata */
|
2013-05-02 03:21:05 -07:00
|
|
|
[PLAYER_TRACK] = { "TrackChange", ELDBUS_ARGS({"a{sv}", ""}), 0 },
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Emitted whenever player's status changes */
|
2013-05-02 03:21:05 -07:00
|
|
|
[PLAYER_STATUS] = { "StatusChange", ELDBUS_ARGS({"(iiii)", ""}), 0 },
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Emitted whenever player's capabilities changes */
|
2013-05-02 03:21:05 -07:00
|
|
|
[PLAYER_CAPS] = { "CapsChange", ELDBUS_ARGS({"i", ""}), 0 },
|
2012-12-03 13:25:04 -08:00
|
|
|
{ }
|
|
|
|
};
|
2010-11-10 13:04:56 -08:00
|
|
|
|
2012-12-03 13:25:04 -08:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
TRACK_LIST = 0,
|
2010-11-10 13:04:56 -08:00
|
|
|
};
|
2012-12-03 13:25:04 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static const Eldbus_Signal mpris_tracklist_signals[] = {
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Emitted whenever the tracklist changes; gives the number of items */
|
2013-05-02 03:21:05 -07:00
|
|
|
[TRACK_LIST] = { "TrackListChange", ELDBUS_ARGS({"i", ""}), 0 },
|
2012-12-03 13:25:04 -08:00
|
|
|
{ }
|
2010-11-10 13:04:56 -08:00
|
|
|
};
|
2012-12-03 13:25:04 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static const Eldbus_Method mpris_root_methods[] = {
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Returns a string representing the player name */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"Identity", NULL, ELDBUS_ARGS({"s", "name"}), _mpris_root_identity, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
/* Quits the player */
|
|
|
|
{ "Quit", NULL, NULL, _mpris_root_quit, 0 },
|
|
|
|
/* Returns a tuple containing the version of MPRIS protocol implemented */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"MprisVersion", NULL, ELDBUS_ARGS({"(qq)", ""}), _mpris_root_version, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
{ }
|
2010-11-10 13:04:56 -08:00
|
|
|
};
|
2012-12-03 13:25:04 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static const Eldbus_Method mpris_player_methods[] = {
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Goes to the next song */
|
|
|
|
{
|
|
|
|
"Next", NULL, NULL, _mpris_player_next, 0
|
|
|
|
},
|
|
|
|
/* Goes to the previous song */
|
|
|
|
{
|
|
|
|
"Prev", NULL, NULL, _mpris_player_previous, 0
|
|
|
|
},
|
|
|
|
/* Pauses the song */
|
|
|
|
{
|
|
|
|
"Pause", NULL, NULL, _mpris_player_pause, 0
|
|
|
|
},
|
|
|
|
/* Stops the song */
|
|
|
|
{
|
|
|
|
"Stop", NULL, NULL, _mpris_player_stop, 0
|
|
|
|
},
|
|
|
|
/* If playing, rewind to the beginning of the current track; else, start playing */
|
|
|
|
{
|
|
|
|
"Play", NULL, NULL, _mpris_player_play, 0
|
|
|
|
},
|
|
|
|
/* Seek the current song by given miliseconds */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"Seek", ELDBUS_ARGS({"x", "time"}), NULL, _mpris_player_seek, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
/* Toggle the current track repeat */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"Repeat", ELDBUS_ARGS({"b", ""}), NULL, _mpris_player_repeat_set, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
/* Return the status of the media player */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"GetStatus", NULL, ELDBUS_ARGS({"(iiii)", ""}), _mpris_player_status_get, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
/* Gets all the metadata for the currently played element */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"GetMetadata", NULL, ELDBUS_ARGS({"a{sv}", "data"}),
|
2012-12-03 13:25:04 -08:00
|
|
|
_mpris_player_metadata_get, 0
|
|
|
|
},
|
|
|
|
/* Returns the media player's current capabilities */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"GetCaps", NULL, ELDBUS_ARGS({"i", ""}), _mpris_player_caps_get, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
/* Sets the volume */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"VolumeSet", ELDBUS_ARGS({"i", ""}), NULL, _mpris_player_volume_set, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
/* Gets the current volume */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"VolumeGet", NULL, ELDBUS_ARGS({"i", ""}), _mpris_player_volume_get, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
/* Sets the playing position (in ms) */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"PositionSet", ELDBUS_ARGS({"i", ""}), NULL, _mpris_player_position_set, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
/* Gets the playing position (in ms) */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"PositionGet", NULL, ELDBUS_ARGS({"i", ""}), _mpris_player_position_get, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
{ }
|
2010-11-10 13:04:56 -08:00
|
|
|
};
|
2012-12-03 13:25:04 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static const Eldbus_Method mpris_tracklist_methods[] = {
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Gives all the metadata available at the given position in the track list */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"GetMetadata", ELDBUS_ARGS({"i", ""}), ELDBUS_ARGS({"a{sv}", ""}),
|
2012-12-03 13:25:04 -08:00
|
|
|
_mpris_tracklist_metadata_get, 0
|
|
|
|
},
|
|
|
|
/* Returns the position of the current URI in the track list */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"GetCurrentTrack", NULL, ELDBUS_ARGS({"i", ""}),
|
2012-12-03 13:25:04 -08:00
|
|
|
_mpris_tracklist_current_track_get, 0
|
|
|
|
},
|
|
|
|
/* Returns the number of elements in the track list */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"GetLength", NULL, ELDBUS_ARGS({"i", ""}), _mpris_tracklist_count, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
/* Appends an URI to the track list */
|
2013-05-02 03:21:05 -07:00
|
|
|
/*{ "AddTrack", ELDBUS_ARGS({"sb", ""}), ELDBUS_ARGS({"i", ""}), NULL, 0 },*/
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Removes an URL from the track list */
|
2013-05-02 03:21:05 -07:00
|
|
|
/*{ "DelTrack", ELDBUS_ARGS({"i", ""}), NULL, NULL, 0 },*/
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Toggle playlist loop */
|
2013-05-02 03:21:05 -07:00
|
|
|
/*{ "SetLoop", ELDBUS_ARGS({"b", ""}), NULL, NULL, 0 },*/
|
2012-12-03 13:25:04 -08:00
|
|
|
/* Toggle playlist shuffle/random */
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
"SetRandom", ELDBUS_ARGS({"b", ""}), NULL, _mpris_tracklist_shuffle_set, 0
|
2012-12-03 13:25:04 -08:00
|
|
|
},
|
|
|
|
{ }
|
2010-11-10 13:04:56 -08:00
|
|
|
};
|
|
|
|
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
static int
|
|
|
|
_caps_to_mpris_bits(const Enjoy_Player_Caps caps)
|
|
|
|
{
|
|
|
|
int bits = 0;
|
|
|
|
if (caps.can_go_next) bits |= MPRIS_CAPABILITY_CAN_GO_NEXT;
|
|
|
|
if (caps.can_go_prev) bits |= MPRIS_CAPABILITY_CAN_GO_PREV;
|
|
|
|
if (caps.can_pause) bits |= MPRIS_CAPABILITY_CAN_PAUSE;
|
|
|
|
if (caps.can_play) bits |= MPRIS_CAPABILITY_CAN_PLAY;
|
|
|
|
if (caps.can_seek) bits |= MPRIS_CAPABILITY_CAN_SEEK;
|
|
|
|
if (caps.can_provide_metadata) bits |= MPRIS_CAPABILITY_CAN_PROVIDE_METADATA;
|
|
|
|
if (caps.has_tracklist) bits |= MPRIS_CAPABILITY_HAS_TRACKLIST;
|
|
|
|
return bits;
|
|
|
|
}
|
2011-08-26 12:24:05 -07:00
|
|
|
|
|
|
|
static Eina_Bool
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
_cb_player_caps_change(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
|
2011-08-26 12:24:05 -07:00
|
|
|
{
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
Enjoy_Player_Caps caps = enjoy_player_caps_get();
|
|
|
|
int bits = _caps_to_mpris_bits(caps);
|
|
|
|
_mpris_signal_player_caps_change(bits);
|
2011-08-26 12:24:05 -07:00
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
_cb_player_status_change(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
|
2011-08-26 12:24:05 -07:00
|
|
|
{
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
Enjoy_Player_Status status = enjoy_player_status_get();
|
|
|
|
_mpris_signal_player_status_change
|
|
|
|
(status.playback, status.shuffle, status.repeat, status.endless);
|
2011-08-26 12:24:05 -07:00
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
_cb_player_track_change(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
|
2011-08-26 12:24:05 -07:00
|
|
|
{
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
_mpris_signal_player_track_change(enjoy_song_current_get());
|
2011-08-26 12:24:05 -07:00
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
_cb_player_tracklist_change(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
|
2011-08-26 12:24:05 -07:00
|
|
|
{
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
_mpris_signal_tracklist_tracklist_change(enjoy_playlist_count());
|
2011-08-26 12:24:05 -07:00
|
|
|
return ECORE_CALLBACK_PASS_ON;
|
|
|
|
}
|
2010-11-10 13:04:56 -08:00
|
|
|
|
2011-09-04 11:37:05 -07:00
|
|
|
static Eina_Bool
|
|
|
|
mpris_enable(Enjoy_Plugin *p __UNUSED__)
|
|
|
|
{
|
|
|
|
#define EV_HANDLER(ev, func, data) \
|
|
|
|
ev_handlers = eina_list_append \
|
|
|
|
(ev_handlers, ecore_event_handler_add(ev, func, data))
|
|
|
|
|
|
|
|
EV_HANDLER(ENJOY_EVENT_PLAYER_CAPS_CHANGE, _cb_player_caps_change, NULL);
|
|
|
|
EV_HANDLER(ENJOY_EVENT_PLAYER_STATUS_CHANGE, _cb_player_status_change, NULL);
|
|
|
|
EV_HANDLER(ENJOY_EVENT_PLAYER_TRACK_CHANGE, _cb_player_track_change, NULL);
|
|
|
|
EV_HANDLER(ENJOY_EVENT_TRACKLIST_TRACKLIST_CHANGE,
|
|
|
|
_cb_player_tracklist_change, NULL);
|
|
|
|
#undef EV_HANDLER
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_name_request(conn, APPLICATION_NAME,
|
|
|
|
ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
|
2012-12-03 13:25:04 -08:00
|
|
|
_cb_dbus_request_name, NULL);
|
2011-09-04 11:37:05 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
mpris_disable(Enjoy_Plugin *p __UNUSED__)
|
|
|
|
{
|
|
|
|
Ecore_Event_Handler *eh;
|
|
|
|
|
2012-12-03 13:25:04 -08:00
|
|
|
if (root)
|
2011-09-04 11:37:05 -07:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_service_object_unregister(root);
|
|
|
|
eldbus_service_object_unregister(tracklist);
|
|
|
|
eldbus_service_object_unregister(player);
|
2012-12-03 13:25:04 -08:00
|
|
|
root = NULL;
|
|
|
|
tracklist = NULL;
|
|
|
|
player = NULL;
|
2011-09-04 11:37:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EINA_LIST_FREE(ev_handlers, eh)
|
|
|
|
ecore_event_handler_del(eh);
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const Enjoy_Plugin_Api api = {
|
|
|
|
ENJOY_PLUGIN_API_VERSION,
|
|
|
|
mpris_enable,
|
|
|
|
mpris_disable
|
|
|
|
};
|
|
|
|
|
2011-09-03 18:33:10 -07:00
|
|
|
static Eina_Bool
|
2010-11-10 13:04:56 -08:00
|
|
|
mpris_init(void)
|
|
|
|
{
|
2011-09-03 18:33:10 -07:00
|
|
|
if (_mpris_log_domain < 0)
|
|
|
|
{
|
|
|
|
_mpris_log_domain = eina_log_domain_register
|
|
|
|
("enjoy-mpris", EINA_COLOR_LIGHTCYAN);
|
|
|
|
if (_mpris_log_domain < 0)
|
|
|
|
{
|
|
|
|
EINA_LOG_CRIT("Could not register log domain 'enjoy-mpris'");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-04 08:58:50 -07:00
|
|
|
if (!ENJOY_ABI_CHECK())
|
|
|
|
{
|
|
|
|
ERR("ABI versions differ: enjoy=%u, mpris=%u",
|
|
|
|
enjoy_abi_version(), ENJOY_ABI_VERSION);
|
2011-09-04 11:37:05 -07:00
|
|
|
goto error;
|
2011-09-04 08:58:50 -07:00
|
|
|
}
|
|
|
|
|
2011-09-03 18:33:10 -07:00
|
|
|
if (conn) return EINA_TRUE;
|
2011-09-04 11:37:05 -07:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_init();
|
|
|
|
conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
|
2011-09-04 11:37:05 -07:00
|
|
|
if (!conn)
|
|
|
|
{
|
|
|
|
ERR("Could not get DBus session bus");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
enjoy_plugin_register("listener/mpris", &api, ENJOY_PLUGIN_PRIORITY_HIGH);
|
|
|
|
|
2011-08-29 12:54:34 -07:00
|
|
|
return EINA_TRUE;
|
2011-09-04 11:37:05 -07:00
|
|
|
|
|
|
|
error:
|
|
|
|
eina_log_domain_unregister(_mpris_log_domain);
|
|
|
|
_mpris_log_domain = -1;
|
|
|
|
return EINA_FALSE;
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
mpris_shutdown(void)
|
|
|
|
{
|
|
|
|
if (!conn) return;
|
2011-09-04 11:37:05 -07:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_connection_unref(conn);
|
|
|
|
eldbus_shutdown();
|
2010-11-10 13:04:56 -08:00
|
|
|
conn = NULL;
|
2011-09-03 18:33:10 -07:00
|
|
|
|
|
|
|
if (_mpris_log_domain >= 0)
|
|
|
|
{
|
|
|
|
eina_log_domain_unregister(_mpris_log_domain);
|
|
|
|
_mpris_log_domain = -1;
|
|
|
|
}
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static const Eldbus_Service_Interface_Desc root_desc = {
|
2012-12-03 13:25:04 -08:00
|
|
|
PLAYER_INTERFACE_NAME, mpris_root_methods
|
|
|
|
};
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static const Eldbus_Service_Interface_Desc player_desc = {
|
2012-12-03 13:25:04 -08:00
|
|
|
PLAYER_INTERFACE_NAME, mpris_player_methods, mpris_player_signals
|
|
|
|
};
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static const Eldbus_Service_Interface_Desc tracklist_desc = {
|
2012-12-03 13:25:04 -08:00
|
|
|
PLAYER_INTERFACE_NAME, mpris_tracklist_methods, mpris_tracklist_signals
|
|
|
|
};
|
|
|
|
|
2010-11-10 13:04:56 -08:00
|
|
|
static void
|
2013-05-02 03:21:05 -07:00
|
|
|
_cb_dbus_request_name(void *data __UNUSED__, const Eldbus_Message *msg, Eldbus_Pending *pending __UNUSED__)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
const char *error_name, *error_txt;
|
|
|
|
unsigned flag;
|
2011-09-04 16:27:15 -07:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
if (eldbus_message_error_get(msg, &error_name, &error_txt))
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
ERR("Error %s %s", error_name, error_txt);
|
2010-11-10 13:04:56 -08:00
|
|
|
return;
|
|
|
|
}
|
2011-09-04 11:37:05 -07:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
if (!eldbus_message_arguments_get(msg, "u", &flag))
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
ERR("Error getting arguments.");
|
2011-09-04 16:27:15 -07:00
|
|
|
return;
|
|
|
|
}
|
2010-11-10 13:04:56 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
if (flag != ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER)
|
2011-09-04 16:27:15 -07:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
ERR("Bus name in use by another application.");
|
|
|
|
return;
|
2011-09-04 16:27:15 -07:00
|
|
|
}
|
2010-11-10 13:04:56 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
root = eldbus_service_interface_register(conn, ROOT_NAME, &root_desc);
|
|
|
|
player = eldbus_service_interface_register(conn, PLAYER_NAME, &player_desc);
|
|
|
|
tracklist = eldbus_service_interface_register(conn, TRACKLIST_NAME,
|
2012-12-03 13:25:04 -08:00
|
|
|
&tracklist_desc);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-05-02 03:21:05 -07:00
|
|
|
_mpris_append_dict_entry(Eldbus_Message_Iter *array, const char *key,
|
2012-12-03 13:25:04 -08:00
|
|
|
const char *value_type, ...)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message_Iter *dict, *val;
|
2012-12-03 13:25:04 -08:00
|
|
|
va_list ap;
|
2010-11-10 13:04:56 -08:00
|
|
|
|
2012-12-03 13:25:04 -08:00
|
|
|
va_start(ap, value_type);
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_message_iter_arguments_append(array, "{sv}", &dict);
|
|
|
|
eldbus_message_iter_basic_append(dict, 's', key);
|
|
|
|
val = eldbus_message_iter_container_new(dict, 'v', value_type);
|
|
|
|
eldbus_message_iter_arguments_vappend(val, value_type, ap);
|
|
|
|
eldbus_message_iter_container_close(dict, val);
|
|
|
|
eldbus_message_iter_container_close(array, dict);
|
2012-12-03 13:25:04 -08:00
|
|
|
va_end(ap);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-05-02 03:21:05 -07:00
|
|
|
_mpris_message_fill_song_metadata(Eldbus_Message *msg, const Song *song)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message_Iter *array, *main_iter;
|
2010-11-10 13:04:56 -08:00
|
|
|
|
|
|
|
if (!song) return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Other possible metadata:
|
|
|
|
location s time u
|
|
|
|
mtime u comment s
|
|
|
|
rating u year u
|
|
|
|
date u arturl s
|
|
|
|
genre s mpris:length u
|
|
|
|
trackno s
|
|
|
|
*/
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
main_iter = eldbus_message_iter_get(msg);
|
|
|
|
eldbus_message_iter_arguments_append(main_iter, "a{sv}", &array);
|
2010-11-10 13:04:56 -08:00
|
|
|
|
|
|
|
if (song->title)
|
2012-12-03 13:25:04 -08:00
|
|
|
_mpris_append_dict_entry(array, "title", "s", song->title);
|
2010-11-10 13:04:56 -08:00
|
|
|
if (song->flags.fetched_album && song->album)
|
2012-12-03 13:25:04 -08:00
|
|
|
_mpris_append_dict_entry(array, "album", "s", song->album);
|
2010-11-10 13:04:56 -08:00
|
|
|
if (song->flags.fetched_artist && song->artist)
|
2012-12-03 13:25:04 -08:00
|
|
|
_mpris_append_dict_entry(array, "artist", "s", song->artist);
|
2010-11-10 13:04:56 -08:00
|
|
|
if (song->flags.fetched_genre && song->genre)
|
2012-12-03 13:25:04 -08:00
|
|
|
_mpris_append_dict_entry(array, "genre", "s", song->genre);
|
|
|
|
_mpris_append_dict_entry(array, "rating", "u", song->rating);
|
|
|
|
_mpris_append_dict_entry(array, "length", "u", song->length);
|
|
|
|
_mpris_append_dict_entry(array, "enjoy:playcount", "i", song->playcnt);
|
|
|
|
_mpris_append_dict_entry(array, "enjoy:filesize", "i", song->size);
|
2010-11-10 13:04:56 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_message_iter_container_close(main_iter, array);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-08-26 12:24:05 -07:00
|
|
|
_mpris_signal_player_caps_change(int caps)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
|
|
|
static int old_caps = 0;
|
|
|
|
if (caps != old_caps)
|
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
int32_t caps32 = caps;
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_service_signal_emit(player, PLAYER_CAPS, caps32);
|
2010-11-10 13:04:56 -08:00
|
|
|
old_caps = caps;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-26 12:24:05 -07:00
|
|
|
static void
|
|
|
|
_mpris_signal_player_status_change(int playback, int shuffle, int repeat, int endless)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *sig;
|
|
|
|
Eldbus_Message_Iter *st, *main_iter;
|
2010-11-10 13:04:56 -08:00
|
|
|
static int old_playback = 0, old_shuffle = 0, old_repeat = 0, old_endless = 0;
|
|
|
|
|
|
|
|
if (old_playback == playback && old_shuffle == shuffle &&
|
|
|
|
old_repeat == repeat && old_endless == endless) return;
|
|
|
|
old_playback = playback;
|
|
|
|
old_shuffle = shuffle;
|
|
|
|
old_repeat = repeat;
|
|
|
|
old_endless = endless;
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
sig = eldbus_service_signal_new(player, PLAYER_STATUS);
|
2010-11-10 13:04:56 -08:00
|
|
|
if (!sig) return;
|
2012-12-03 13:25:04 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
main_iter = eldbus_message_iter_get(sig);
|
|
|
|
eldbus_message_iter_arguments_append(main_iter, "(iiii)", &st);
|
|
|
|
eldbus_message_iter_basic_append(st, 'i', playback);
|
|
|
|
eldbus_message_iter_basic_append(st, 'i', shuffle);
|
|
|
|
eldbus_message_iter_basic_append(st, 'i', repeat);
|
|
|
|
eldbus_message_iter_basic_append(st, 'i', endless);
|
|
|
|
eldbus_message_iter_container_close(main_iter, st);
|
2012-12-03 13:25:04 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_service_signal_send(player, sig);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2011-08-26 12:24:05 -07:00
|
|
|
static void
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
_mpris_signal_player_track_change(const Song *song)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
static const void *old_song = NULL;
|
2010-11-10 13:04:56 -08:00
|
|
|
if (old_song != song)
|
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *sig = eldbus_service_signal_new(player, PLAYER_TRACK);
|
2010-11-10 13:04:56 -08:00
|
|
|
if (!sig) return;
|
|
|
|
_mpris_message_fill_song_metadata(sig, song);
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_service_signal_send(player, sig);
|
2010-11-10 13:04:56 -08:00
|
|
|
old_song = song;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-26 12:24:05 -07:00
|
|
|
static void
|
|
|
|
_mpris_signal_tracklist_tracklist_change(int size)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
int32_t size32 = size;
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_service_signal_emit(tracklist, TRACK_LIST, size32);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_next(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
|
|
|
enjoy_control_next();
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_previous(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
|
|
|
enjoy_control_previous();
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_pause(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
|
|
|
enjoy_control_pause();
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_stop(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
|
|
|
enjoy_control_stop();
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_play(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
Enjoy_Player_Status status = enjoy_player_status_get();
|
|
|
|
if (!status.playback)
|
2010-11-10 13:04:56 -08:00
|
|
|
enjoy_position_set(0);
|
|
|
|
enjoy_control_play();
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_seek(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
int64_t position;
|
2013-05-02 03:21:05 -07:00
|
|
|
if (!eldbus_message_arguments_get(msg, "x", &position))
|
2012-12-03 13:25:04 -08:00
|
|
|
goto end;
|
2010-11-10 13:04:56 -08:00
|
|
|
enjoy_control_seek(position);
|
2012-12-03 13:25:04 -08:00
|
|
|
end:
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_root_identity(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
|
|
|
const char *identity = PACKAGE_STRING;
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
|
|
|
eldbus_message_arguments_append(reply, "s", identity);
|
2010-11-10 13:04:56 -08:00
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_root_quit(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
|
|
|
enjoy_quit();
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_root_version(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
|
|
|
Eldbus_Message_Iter *main_iter, *s;
|
2012-12-03 13:25:04 -08:00
|
|
|
uint16_t v1 = 1, v2 = 0;
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
main_iter = eldbus_message_iter_get(reply);
|
|
|
|
eldbus_message_iter_arguments_append(main_iter, "(qq)", &s);
|
|
|
|
eldbus_message_iter_arguments_append(s, "qq", v1, v2);
|
|
|
|
eldbus_message_iter_container_close(main_iter, s);
|
2010-11-10 13:04:56 -08:00
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_caps_get(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
2012-12-03 13:25:04 -08:00
|
|
|
int32_t bits = _caps_to_mpris_bits(enjoy_player_caps_get());
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_message_arguments_append(reply, "i", bits);
|
2010-11-10 13:04:56 -08:00
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_volume_set(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
int volume;
|
2010-11-10 13:04:56 -08:00
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
if (!eldbus_message_arguments_get(msg, "i", &volume))
|
2012-12-03 13:25:04 -08:00
|
|
|
goto end;
|
2010-11-10 13:04:56 -08:00
|
|
|
if (volume > 100)
|
|
|
|
volume = 100;
|
|
|
|
else if (volume < 0)
|
|
|
|
volume = 0;
|
|
|
|
enjoy_volume_set(volume);
|
2012-12-03 13:25:04 -08:00
|
|
|
end:
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_volume_get(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
2012-12-03 13:25:04 -08:00
|
|
|
int32_t vol = enjoy_volume_get();
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_message_arguments_append(reply, "i", vol);
|
2010-11-10 13:04:56 -08:00
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_repeat_set(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
Eina_Bool repeat;
|
2013-05-02 03:21:05 -07:00
|
|
|
if (!eldbus_message_arguments_get(msg, "b", &repeat))
|
2012-12-03 13:25:04 -08:00
|
|
|
goto end;
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
enjoy_control_loop_set(repeat);
|
2012-12-03 13:25:04 -08:00
|
|
|
end:
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_status_get(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
Enjoy_Player_Status status = enjoy_player_status_get();
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message_Iter *main_iter, *st;
|
2012-12-03 13:25:04 -08:00
|
|
|
int32_t p, s, r, e;
|
|
|
|
|
|
|
|
p = status.playback;
|
|
|
|
s = status.shuffle;
|
|
|
|
r = status.repeat;
|
|
|
|
e = status.endless;
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
main_iter = eldbus_message_iter_get(reply);
|
|
|
|
eldbus_message_iter_arguments_append(main_iter, "(iiii)", &st);
|
|
|
|
eldbus_message_iter_arguments_append(st, "iiii", p, s, r, e);
|
|
|
|
eldbus_message_iter_container_close(main_iter, st);
|
2010-11-10 13:04:56 -08:00
|
|
|
|
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_position_set(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
int position;
|
2013-05-02 03:21:05 -07:00
|
|
|
if (!eldbus_message_arguments_get(msg, "i", &position))
|
2012-12-03 13:25:04 -08:00
|
|
|
goto end;
|
2010-11-10 13:04:56 -08:00
|
|
|
enjoy_position_set(position);
|
2012-12-03 13:25:04 -08:00
|
|
|
end:
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_position_get(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
2012-12-03 13:25:04 -08:00
|
|
|
int32_t pos = enjoy_position_get();
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_message_arguments_append(reply, "i", pos);
|
2010-11-10 13:04:56 -08:00
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_song_metadata_reply(const Eldbus_Message *msg, const Song *song)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
_mpris_message_fill_song_metadata(reply, song);
|
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_player_metadata_get(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
return _mpris_song_metadata_reply(msg, enjoy_song_current_get());
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_tracklist_current_track_get(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
2012-12-03 13:25:04 -08:00
|
|
|
int32_t pos = enjoy_playlist_current_position_get();
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_message_arguments_append(reply, "i", pos);
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_tracklist_count(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
2012-12-03 13:25:04 -08:00
|
|
|
int32_t count = enjoy_playlist_count();
|
2013-05-02 03:21:05 -07:00
|
|
|
eldbus_message_arguments_append(reply, "i", count);
|
2010-11-10 13:04:56 -08:00
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_tracklist_metadata_get(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2013-05-02 03:21:05 -07:00
|
|
|
Eldbus_Message *reply;
|
enjoy: simplify events and isolate mpris bit more.
Keep mpris stuff into mpris itself. Things like status and
capabilities will go into a structure that is easier to use.
Events were simplified, couple of them do not carry arguments anymore,
removing the need of "no_free" and hacks like alocating an integer to
later free it.
The point of event data is when you must use that value, in that exact
sequence. When you have things that just the latest version matters,
like the capabilities or the current song you'll inform MPRIS, then
it's simpler to just query before using. Remember that events are
asynchronous and may run after timers, fd-handlers (mouse, kbd) and
even other events.
I've also fixed the behavior of setting repeat (loop), reflect the
UI. Shuffle also were not updating toolbar, etc.
As a bonus I've added a missing MPRIS TrackList.GetLength :-)
Last but not least... watch out things like giving Edje a MSG_INT
where the given pointer is Eina_Bool (1 byte), it may cause problems
depending on the sibling values :-/
SVN revision: 63145
2011-09-03 20:40:14 -07:00
|
|
|
const Song *song;
|
2012-12-03 13:25:04 -08:00
|
|
|
int position;
|
2013-05-02 03:21:05 -07:00
|
|
|
if (!eldbus_message_arguments_get(msg, "i", &position))
|
2012-12-03 13:25:04 -08:00
|
|
|
return NULL;
|
2010-11-10 13:04:56 -08:00
|
|
|
song = enjoy_playlist_song_position_get(position);
|
|
|
|
reply = _mpris_song_metadata_reply(msg, song);
|
|
|
|
return reply;
|
|
|
|
}
|
|
|
|
|
2013-05-02 03:21:05 -07:00
|
|
|
static Eldbus_Message *
|
|
|
|
_mpris_tracklist_shuffle_set(const Eldbus_Service_Interface *iface __UNUSED__, const Eldbus_Message *msg)
|
2010-11-10 13:04:56 -08:00
|
|
|
{
|
2012-12-03 13:25:04 -08:00
|
|
|
Eina_Bool param;
|
2013-05-02 03:21:05 -07:00
|
|
|
if (!eldbus_message_arguments_get(msg, "b", ¶m))
|
2012-12-03 13:25:04 -08:00
|
|
|
goto end;
|
2010-11-10 13:04:56 -08:00
|
|
|
enjoy_control_shuffle_set(param);
|
2012-12-03 13:25:04 -08:00
|
|
|
end:
|
2013-05-02 03:21:05 -07:00
|
|
|
return eldbus_message_method_return_new(msg);
|
2010-11-10 13:04:56 -08:00
|
|
|
}
|
2011-08-29 12:54:34 -07:00
|
|
|
|
|
|
|
EINA_MODULE_INIT(mpris_init);
|
|
|
|
EINA_MODULE_SHUTDOWN(mpris_shutdown);
|