591 lines
20 KiB
C
591 lines
20 KiB
C
#include "private.h"
|
|
#include "mpris.h"
|
|
|
|
typedef struct _MPRIS_Method MPRIS_Method;
|
|
typedef struct _MPRIS_Signal MPRIS_Signal;
|
|
|
|
|
|
#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"
|
|
|
|
|
|
static void _mpris_signals_add(const char *root, const MPRIS_Signal *signals);
|
|
static void _mpris_methods_add(const char *root, const MPRIS_Method *methods);
|
|
static void _mpris_append_dict_entry(DBusMessageIter *dict_iter, const char *key,
|
|
int value_type, void *value);
|
|
static void _mpris_signal_emit(const char *root, const char *signal_name, int arg_type,
|
|
void *arg_value);
|
|
static DBusMessage *_mpris_player_next(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_previous(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_pause(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_stop(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_play(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_seek(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_root_identity(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_root_quit(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_root_version(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_caps_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_volume_set(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_volume_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_repeat_set(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_status_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_position_set(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_player_position_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_song_metadata_reply(DBusMessage *msg, Song *song);
|
|
static DBusMessage *_mpris_player_metadata_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_tracklist_current_track_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_tracklist_metadata_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
static DBusMessage *_mpris_tracklist_shuffle_set(E_DBus_Object *obj __UNUSED__, DBusMessage *msg);
|
|
|
|
static void _cb_dbus_request_name(void *data, DBusMessage *msg __UNUSED__, DBusError *err);
|
|
|
|
struct _MPRIS_Method {
|
|
const char *name;
|
|
const char *param_sig;
|
|
const char *return_sig;
|
|
void *callback;
|
|
};
|
|
|
|
struct _MPRIS_Signal {
|
|
const char *name;
|
|
const char *sig;
|
|
};
|
|
|
|
|
|
E_DBus_Connection *conn = NULL;
|
|
Eina_Hash *interface_list = NULL;
|
|
|
|
|
|
static const char *object_list[] = { ROOT_NAME, TRACKLIST_NAME, PLAYER_NAME, NULL };
|
|
static const MPRIS_Signal mpris_player_signals[] = {
|
|
/* Emitted whenever a new song is played; gives the song metadata */
|
|
{ "TrackChange", "a{sv}" },
|
|
/* Emitted whenever player's status changes */
|
|
{ "StatusChange", "(iiii)" },
|
|
/* Emitted whenever player's capabilities changes */
|
|
{ "CapsChange", "i" },
|
|
{ NULL, NULL }
|
|
};
|
|
static const MPRIS_Signal mpris_tracklist_signals[] = {
|
|
/* Emitted whenever the tracklist changes; gives the number of items */
|
|
{ "TrackListChange", "i" },
|
|
{ NULL, NULL }
|
|
};
|
|
static const MPRIS_Method mpris_root_methods[] = {
|
|
/* Returns a string representing the player name */
|
|
{ "Identity", "", "s", _mpris_root_identity },
|
|
/* Quits the player */
|
|
{ "Quit", "", "", _mpris_root_quit },
|
|
/* Returns a tuple containing the version of MPRIS protocol implemented */
|
|
{ "MprisVersion", "", "(qq)", _mpris_root_version },
|
|
{ NULL, NULL, NULL, NULL }
|
|
};
|
|
static const MPRIS_Method mpris_player_methods[] = {
|
|
/* Goes to the next song */
|
|
{ "Next", "", "", _mpris_player_next },
|
|
/* Goes to the previous song */
|
|
{ "Prev", "", "", _mpris_player_previous },
|
|
/* Pauses the song */
|
|
{ "Pause", "", "", _mpris_player_pause },
|
|
/* Stops the song */
|
|
{ "Stop", "", "", _mpris_player_stop },
|
|
/* If playing, rewind to the beginning of the current track; else, start playing */
|
|
{ "Play", "", "", _mpris_player_play },
|
|
/* Seek the current song by given miliseconds */
|
|
{ "Seek", "x", "", _mpris_player_seek },
|
|
/* Toggle the current track repeat */
|
|
{ "Repeat", "b", "", _mpris_player_repeat_set },
|
|
/* Return the status of the media player */
|
|
{ "GetStatus", "", "(iiii)", _mpris_player_status_get },
|
|
/* Gets all the metadata for the currently played element */
|
|
{ "GetMetadata", "", "a{sv}", _mpris_player_metadata_get },
|
|
/* Returns the media player's current capabilities */
|
|
{ "GetCaps", "", "i", _mpris_player_caps_get },
|
|
/* Sets the volume */
|
|
{ "VolumeSet", "i", "", _mpris_player_volume_set },
|
|
/* Gets the current volume */
|
|
{ "VolumeGet", "", "i", _mpris_player_volume_get },
|
|
/* Sets the playing position (in ms) */
|
|
{ "PositionSet", "i", "", _mpris_player_position_set },
|
|
/* Gets the playing position (in ms) */
|
|
{ "PositionGet", "", "i", _mpris_player_position_get },
|
|
{ NULL, NULL, NULL, NULL }
|
|
};
|
|
static const MPRIS_Method mpris_tracklist_methods[] = {
|
|
/* Gives all the metadata available at the given position in the track list */
|
|
{ "GetMetadata", "i", "a{sv}", _mpris_tracklist_metadata_get },
|
|
/* Returns the position of the current URI in the track list */
|
|
{ "GetCurrentTrack", "", "i", _mpris_tracklist_current_track_get },
|
|
/* Returns the number of elements in the track list */
|
|
{ "GetLength", "", "i", NULL },
|
|
/* Appends an URI to the track list */
|
|
{ "AddTrack", "sb", "i", NULL },
|
|
/* Removes an URL from the track list */
|
|
{ "DelTrack", "i", "", NULL },
|
|
/* Toggle playlist loop */
|
|
{ "SetLoop", "b", "", NULL },
|
|
/* Toggle playlist shuffle/random */
|
|
{ "SetRandom", "b", "", _mpris_tracklist_shuffle_set },
|
|
{ NULL, NULL, NULL, NULL }
|
|
};
|
|
|
|
|
|
|
|
void
|
|
mpris_init(void)
|
|
{
|
|
if (conn) return;
|
|
e_dbus_init();
|
|
conn = e_dbus_bus_get(DBUS_BUS_SESSION);
|
|
if (conn)
|
|
e_dbus_request_name(conn, APPLICATION_NAME, 0, _cb_dbus_request_name, NULL);
|
|
}
|
|
|
|
void
|
|
mpris_shutdown(void)
|
|
{
|
|
if (!conn) return;
|
|
e_dbus_shutdown();
|
|
eina_hash_free(interface_list);
|
|
conn = NULL;
|
|
interface_list = NULL;
|
|
}
|
|
|
|
static void
|
|
_cb_dbus_request_name(void *data, DBusMessage *msg __UNUSED__, DBusError *err)
|
|
{
|
|
DBusError new_err;
|
|
dbus_uint32_t msgtype;
|
|
|
|
if (dbus_error_is_set(err))
|
|
{
|
|
dbus_error_free(err);
|
|
return;
|
|
}
|
|
|
|
dbus_error_init(&new_err);
|
|
dbus_message_get_args(msg, &new_err, DBUS_TYPE_UINT32, &msgtype, DBUS_TYPE_INVALID);
|
|
|
|
if (msgtype == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ||
|
|
msgtype == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER)
|
|
{
|
|
int i;
|
|
|
|
interface_list = eina_hash_string_small_new((Eina_Free_Cb)e_dbus_interface_unref);
|
|
|
|
for (i = 0; object_list[i]; i++)
|
|
{
|
|
E_DBus_Object *object = e_dbus_object_add(conn, object_list[i], NULL);
|
|
E_DBus_Interface *interface = e_dbus_interface_new(PLAYER_INTERFACE_NAME);
|
|
e_dbus_object_interface_attach(object, interface);
|
|
|
|
eina_hash_add(interface_list, object_list[i], interface);
|
|
}
|
|
|
|
_mpris_signals_add(PLAYER_NAME, mpris_player_signals);
|
|
_mpris_signals_add(TRACKLIST_NAME, mpris_tracklist_signals);
|
|
|
|
_mpris_methods_add(ROOT_NAME, mpris_root_methods);
|
|
_mpris_methods_add(PLAYER_NAME, mpris_player_methods);
|
|
_mpris_methods_add(TRACKLIST_NAME, mpris_tracklist_methods);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_mpris_signals_add(const char *root, const MPRIS_Signal *signals)
|
|
{
|
|
E_DBus_Interface *interface;
|
|
int i;
|
|
|
|
if (!conn) return;
|
|
|
|
interface = eina_hash_find(interface_list, root);
|
|
if (!interface) return;
|
|
|
|
for (i = 0; signals[i].name; i++)
|
|
e_dbus_interface_signal_add(interface, signals[i].name, signals[i].sig);
|
|
}
|
|
|
|
static void
|
|
_mpris_methods_add(const char *root, const MPRIS_Method *methods)
|
|
{
|
|
E_DBus_Interface *interface;
|
|
int i;
|
|
|
|
if (!conn) return;
|
|
|
|
interface = eina_hash_find(interface_list, root);
|
|
if (!interface) return;
|
|
|
|
for (i = 0; methods[i].name; i++)
|
|
e_dbus_interface_method_add(interface, methods[i].name, methods[i].param_sig,
|
|
methods[i].return_sig, methods[i].callback);
|
|
}
|
|
|
|
static void
|
|
_mpris_append_dict_entry(DBusMessageIter *dict_iter, const char *key,
|
|
int value_type, void *value)
|
|
{
|
|
DBusMessageIter entry_iter, value_iter;
|
|
const char *signature;
|
|
|
|
switch (value_type) {
|
|
case DBUS_TYPE_BOOLEAN:
|
|
signature = DBUS_TYPE_BOOLEAN_AS_STRING;
|
|
break;
|
|
case DBUS_TYPE_STRING:
|
|
signature = DBUS_TYPE_STRING_AS_STRING;
|
|
break;
|
|
case DBUS_TYPE_BYTE:
|
|
signature = DBUS_TYPE_BYTE_AS_STRING;
|
|
break;
|
|
case DBUS_TYPE_UINT16:
|
|
signature = DBUS_TYPE_UINT16_AS_STRING;
|
|
break;
|
|
case DBUS_TYPE_UINT32:
|
|
signature = DBUS_TYPE_UINT32_AS_STRING;
|
|
break;
|
|
case DBUS_TYPE_INT16:
|
|
signature = DBUS_TYPE_INT16_AS_STRING;
|
|
break;
|
|
case DBUS_TYPE_INT32:
|
|
signature = DBUS_TYPE_INT32_AS_STRING;
|
|
break;
|
|
case DBUS_TYPE_OBJECT_PATH:
|
|
signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
|
|
break;
|
|
default:
|
|
signature = DBUS_TYPE_VARIANT_AS_STRING;
|
|
}
|
|
|
|
dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry_iter);
|
|
|
|
dbus_message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING, &key);
|
|
|
|
dbus_message_iter_open_container(&entry_iter, DBUS_TYPE_VARIANT, signature, &value_iter);
|
|
dbus_message_iter_append_basic(&value_iter, value_type, value);
|
|
dbus_message_iter_close_container(&entry_iter, &value_iter);
|
|
|
|
dbus_message_iter_close_container(dict_iter, &entry_iter);
|
|
}
|
|
|
|
static void
|
|
_mpris_signal_emit(const char *root, const char *signal_name, int arg_type, void *arg_value)
|
|
{
|
|
DBusMessage *sig = dbus_message_new_signal(root, PLAYER_INTERFACE_NAME, signal_name);
|
|
if (arg_type != DBUS_TYPE_INVALID)
|
|
dbus_message_append_args(sig, arg_type, arg_value, DBUS_TYPE_INVALID);
|
|
e_dbus_message_send(conn, sig, NULL, -1, NULL);
|
|
dbus_message_unref(sig);
|
|
}
|
|
|
|
static void
|
|
_mpris_message_fill_song_metadata(DBusMessage *msg, Song *song)
|
|
{
|
|
DBusMessageIter iter, dict;
|
|
|
|
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
|
|
*/
|
|
|
|
dbus_message_iter_init_append(msg, &iter);
|
|
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
|
|
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
|
|
DBUS_TYPE_STRING_AS_STRING
|
|
DBUS_TYPE_VARIANT_AS_STRING
|
|
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
|
|
|
|
if (song->title)
|
|
_mpris_append_dict_entry(&dict, "title", DBUS_TYPE_STRING, &song->title);
|
|
if (song->flags.fetched_album && song->album)
|
|
_mpris_append_dict_entry(&dict, "album", DBUS_TYPE_STRING, &song->album);
|
|
if (song->flags.fetched_artist && song->artist)
|
|
_mpris_append_dict_entry(&dict, "artist", DBUS_TYPE_STRING, &song->artist);
|
|
if (song->flags.fetched_genre && song->genre)
|
|
_mpris_append_dict_entry(&dict, "genre", DBUS_TYPE_STRING, &song->genre);
|
|
_mpris_append_dict_entry(&dict, "rating", DBUS_TYPE_UINT32, &song->rating);
|
|
_mpris_append_dict_entry(&dict, "length", DBUS_TYPE_UINT32, &song->length);
|
|
_mpris_append_dict_entry(&dict, "enjoy:playcount", DBUS_TYPE_INT32, &song->playcnt);
|
|
_mpris_append_dict_entry(&dict, "enjoy:filesize", DBUS_TYPE_INT32, &song->size);
|
|
|
|
dbus_message_iter_close_container(&iter, &dict);
|
|
}
|
|
|
|
void
|
|
mpris_signal_player_caps_change(int caps)
|
|
{
|
|
static int old_caps = 0;
|
|
if (caps != old_caps)
|
|
{
|
|
_mpris_signal_emit(PLAYER_NAME, "CapsChange", DBUS_TYPE_INT32, &caps);
|
|
old_caps = caps;
|
|
}
|
|
}
|
|
|
|
void
|
|
mpris_signal_player_status_change(int playback, int shuffle, int repeat, int endless)
|
|
{
|
|
DBusMessage *sig;
|
|
DBusMessageIter iter, siter;
|
|
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;
|
|
|
|
sig = dbus_message_new_signal(PLAYER_NAME, PLAYER_INTERFACE_NAME, "StatusChange");
|
|
if (!sig) return;
|
|
dbus_message_iter_init_append(sig, &iter);
|
|
dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &siter);
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT32, &playback);
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT32, &shuffle);
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT32, &repeat);
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT32, &endless);
|
|
dbus_message_iter_close_container(&iter, &siter);
|
|
e_dbus_message_send(conn, sig, NULL, -1, NULL);
|
|
dbus_message_unref(sig);
|
|
}
|
|
|
|
void
|
|
mpris_signal_player_track_change(Song *song)
|
|
{
|
|
static Song *old_song = NULL;
|
|
if (old_song != song)
|
|
{
|
|
DBusMessage *sig = dbus_message_new_signal(PLAYER_NAME, PLAYER_INTERFACE_NAME, "TrackChange");
|
|
if (!sig) return;
|
|
_mpris_message_fill_song_metadata(sig, song);
|
|
e_dbus_message_send(conn, sig, NULL, -1, NULL);
|
|
dbus_message_unref(sig);
|
|
old_song = song;
|
|
}
|
|
}
|
|
|
|
void
|
|
mpris_signal_tracklist_tracklist_change(int size)
|
|
{
|
|
_mpris_signal_emit(TRACKLIST_NAME, "TrackListChange", DBUS_TYPE_INT32, &size);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_next(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
enjoy_control_next();
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_previous(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
enjoy_control_previous();
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_pause(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
enjoy_control_pause();
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_stop(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
enjoy_control_stop();
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_play(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
int playback;
|
|
enjoy_status_get(&playback, NULL, NULL, NULL);
|
|
if (!playback)
|
|
enjoy_position_set(0);
|
|
enjoy_control_play();
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_seek(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
dbus_uint64_t position;
|
|
dbus_message_get_args(msg, NULL, DBUS_TYPE_INT64, &position, DBUS_TYPE_INVALID);
|
|
enjoy_control_seek(position);
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_root_identity(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
const char *identity = PACKAGE_STRING;
|
|
DBusMessageIter iter;
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
dbus_message_iter_init_append(reply, &iter);
|
|
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &identity);
|
|
return reply;
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_root_quit(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
enjoy_quit();
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_root_version(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
DBusMessageIter iter, siter;
|
|
dbus_message_iter_init_append(reply, &iter);
|
|
dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &siter);
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT16, (int[]) { 1 });
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT16, (int[]) { 0 });
|
|
dbus_message_iter_close_container(&iter, &siter);
|
|
return reply;
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_caps_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
DBusMessageIter iter;
|
|
dbus_message_iter_init_append(reply, &iter);
|
|
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, (int[]) { enjoy_caps_get() });
|
|
return reply;
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_volume_set(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
dbus_int32_t volume;
|
|
|
|
dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &volume, DBUS_TYPE_INVALID);
|
|
if (volume > 100)
|
|
volume = 100;
|
|
else if (volume < 0)
|
|
volume = 0;
|
|
enjoy_volume_set(volume);
|
|
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_volume_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
DBusMessageIter iter;
|
|
dbus_message_iter_init_append(reply, &iter);
|
|
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, (int[]) { enjoy_volume_get() });
|
|
return reply;
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_repeat_set(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
dbus_bool_t repeat;
|
|
dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &repeat, DBUS_TYPE_INVALID);
|
|
enjoy_repeat_set(repeat);
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_status_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
DBusMessageIter iter, siter;
|
|
int playback, shuffle, repeat, endless;
|
|
|
|
enjoy_status_get(&playback, &shuffle, &repeat, &endless);
|
|
|
|
dbus_message_iter_init_append(reply, &iter);
|
|
dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &siter);
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT32, &playback);
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT32, &shuffle);
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT32, &repeat);
|
|
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT32, &endless);
|
|
dbus_message_iter_close_container(&iter, &siter);
|
|
return reply;
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_position_set(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
dbus_int32_t position;
|
|
dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &position, DBUS_TYPE_INVALID);
|
|
enjoy_position_set(position);
|
|
return dbus_message_new_method_return(msg);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_position_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
DBusMessageIter iter;
|
|
dbus_message_iter_init_append(reply, &iter);
|
|
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, (int[]) { enjoy_position_get() });
|
|
return reply;
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_song_metadata_reply(DBusMessage *msg, Song *song)
|
|
{
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
_mpris_message_fill_song_metadata(reply, song);
|
|
return reply;
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_player_metadata_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
Song *song = enjoy_song_current_get();
|
|
return _mpris_song_metadata_reply(msg, song);
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_tracklist_current_track_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
DBusMessageIter iter;
|
|
dbus_message_iter_init_append(reply, &iter);
|
|
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, (int[]) { enjoy_playlist_current_position_get() });
|
|
return reply;
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_tracklist_metadata_get(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
DBusMessage *reply;
|
|
Song *song;
|
|
dbus_int32_t position;
|
|
dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &position, DBUS_TYPE_INVALID);
|
|
song = enjoy_playlist_song_position_get(position);
|
|
reply = _mpris_song_metadata_reply(msg, song);
|
|
return reply;
|
|
}
|
|
|
|
static DBusMessage *
|
|
_mpris_tracklist_shuffle_set(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
|
{
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
dbus_bool_t param;
|
|
dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, ¶m, DBUS_TYPE_INVALID);
|
|
enjoy_control_shuffle_set(param);
|
|
return reply;
|
|
}
|