2
* Copyright (c) Linux community.
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Library General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Library General Public License for more details.
14
* You should have received a copy of the GNU Library General Public
15
* License along with this library; if not, write to the
16
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
* Boston, MA 02111-1307, USA.
19
#include "dbus-player.h"
20
#include "dbus-mpris.h"
21
#include "dbus-rhythmbox.h"
26
void rhythmbox_player_track_changed(MediaPlayerRec *player) {
27
// Called when the track changes
29
// Re-read all player data
30
rhythmbox_get_info(player);
32
TrackInfo *tr = &player->track;
33
tr->status = PLAYER_STATUS_STOPPED;
36
// dbus_player_debug_print(player);
39
dbus_player_process_data(player);
42
void rhythmbox_player_status_changed(MediaPlayerRec *player) {
43
// Called when player's status changes
45
// Re-read all player data
46
rhythmbox_get_info(player);
49
// dbus_player_debug_print(player);
52
dbus_player_process_data(player);
55
void rhythmbox_get_app_name(MediaPlayerRec *player) {
56
// Name of the RhythmBox Media Player.
57
player->app_name = g_strdup(_("RhythmBox Media Player"));
60
void rhythmbox_track_signal_cb(DBusGProxy *player_proxy, gpointer data, MediaPlayerRec *player) {
61
// Track changed signal from RhythmBox
63
gchar *track = (gchar*)data;
65
/*suppress unused variable msg*/
68
LOG_PLAYER("rhythmbox_track_signal_cb: %s (%s), TrackChanged: %s\n", player->app_name, player->service_name, track);
70
rhythmbox_player_track_changed(player);
73
void rhythmbox_status_signal_cb(DBusGProxy *player_proxy, gpointer data, MediaPlayerRec *player) {
74
// Status signal from RhythmBox
76
gboolean status = (gint)(long)data;
78
/*suppress unused variable msg*/
83
LOG_PLAYER("rhythmbox_status_signal_cb: %s (%s) Status: %d\n", player->app_name, player->service_name, status);
85
rhythmbox_player_status_changed(player);
88
gboolean rhythmbox_check_proxy(MediaPlayerRec *player) {
89
// Check and set proxy
90
if (!player) return FALSE;
93
DBusGConnection *dbus_conn = dbus_player_connect_to_dbus();
95
player->proxy = dbus_g_proxy_new_for_name(dbus_conn,
97
"/org/gnome/Rhythmbox/Player",
98
"org.gnome.Rhythmbox.Player");
101
if (!player->proxy) {
102
LOG_ERROR("rhythmbox_check_proxy: Cannot create DBus proxy for RhythmBox.\n");
105
return (player->proxy != NULL);
108
void rhythmbox_set_signals(gpointer player_rec, gboolean connect) {
109
// Connect/disconnect signals
111
MediaPlayerRec *player = (MediaPlayerRec*)player_rec;
114
if (!player->proxy) {
117
if (!rhythmbox_check_proxy(player)) return;
119
// Register arguments.
120
dbus_g_proxy_add_signal(player->proxy, "playingUriChanged", G_TYPE_STRING, G_TYPE_INVALID);
121
dbus_g_proxy_add_signal(player->proxy, "playingChanged", G_TYPE_BOOLEAN, G_TYPE_INVALID);
124
if (!rhythmbox_check_proxy(player)) return;
128
dbus_g_proxy_connect_signal(player->proxy, "playingUriChanged", G_CALLBACK(rhythmbox_track_signal_cb), (gpointer)player, NULL);
129
dbus_g_proxy_connect_signal(player->proxy, "playingChanged", G_CALLBACK(rhythmbox_status_signal_cb), (gpointer)player, NULL);
131
// Disconnect signals
132
dbus_g_proxy_disconnect_signal(player->proxy, "playingUriChanged", G_CALLBACK(rhythmbox_track_signal_cb), (gpointer)player);
133
dbus_g_proxy_disconnect_signal(player->proxy, "playingChanged", G_CALLBACK(rhythmbox_status_signal_cb), (gpointer)player);
137
gboolean get_hash_str(GHashTable *table, gchar *key, gchar *dest) {
140
GValue* value = (GValue*)g_hash_table_lookup(table, key);
142
if (value && G_VALUE_HOLDS_STRING(value)) {
143
str_copy(dest, (gchar*)g_value_get_string(value), MPRIS_STRLEN-1);
150
guint get_hash_uint(GHashTable *table, gchar *key) {
152
GValue* value = (GValue*) g_hash_table_lookup(table, key);
154
if (G_VALUE_HOLDS_UINT(value)) {
155
ret = g_value_get_uint(value);
161
void rhythmbox_get_info(gpointer player_rec) {
162
MediaPlayerRec *player = (MediaPlayerRec*)player_rec;
163
TrackInfo *tr = &player->track;
165
tr->status = PLAYER_STATUS_STOPPED;
168
if (!rhythmbox_check_proxy(player)) return;
170
DBusGProxy *shell_proxy = NULL;
172
// Is this player running/active?
173
player->active = mpris_service_is_running_by_name(player->service_name);
174
if (!player->active) {
175
tr->status = PLAYER_STATUS_CLOSED;
179
DBusGConnection *dbus_conn = dbus_player_connect_to_dbus();
181
GError *error = NULL;
182
shell_proxy = dbus_g_proxy_new_for_name(dbus_conn,
183
"org.gnome.Rhythmbox",
184
"/org/gnome/Rhythmbox/Shell",
185
"org.gnome.Rhythmbox.Shell");
188
if (!dbus_g_proxy_call_with_timeout(player->proxy, "getPlaying", DBUS_MPRIS_TIMEOUT, &error,
190
G_TYPE_BOOLEAN, &playing,
193
LOG_ERROR("rhythmbox_get_info: Failed to get playing state from RhythmBox. %s.", error ? error->message : "");
194
tr->status = PLAYER_STATUS_STOPPED;
203
if (!dbus_g_proxy_call_with_timeout(player->proxy, "getPlayingUri", DBUS_MPRIS_TIMEOUT, &error,
207
LOG_ERROR("rhythmbox_get_info: Failed to get song uri from RhythmBox. %s.", error ? error->message : "");
215
GHashTable *table = NULL;
216
if (!dbus_g_proxy_call_with_timeout(shell_proxy, "getSongProperties", DBUS_MPRIS_TIMEOUT, &error, G_TYPE_STRING, uri, G_TYPE_INVALID,
217
dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &table, G_TYPE_INVALID)) {
220
tr->status = PLAYER_STATUS_STOPPED;
232
tr->status = PLAYER_STATUS_PLAYING;
234
tr->status = PLAYER_STATUS_PAUSED;
236
// Check if stream title is nonempty, if so, take title
237
if (!get_hash_str(table, "rb:stream-song-title", tr->track)) {
238
get_hash_str(table, "title", tr->track);
241
get_hash_str(table, "artist", tr->artist);
242
get_hash_str(table, "album", tr->album);
244
tr->total_secs = get_hash_uint(table, "duration");
246
g_hash_table_destroy(table);
248
if (!dbus_g_proxy_call_with_timeout(player->proxy, "getElapsed", DBUS_MPRIS_TIMEOUT, &error,
250
G_TYPE_UINT, &tr->current_secs,
253
LOG_ERROR("rhythmbox_get_info: Failed to get elapsed time from RhythmBox. %s.", error ? error->message : "");
262
g_object_unref(shell_proxy);
266
void rhythmbox_start_app(gpointer player_rec) {
267
// Function to start RhythmBox
268
MediaPlayerRec *player = (MediaPlayerRec*)player_rec;
270
LOG_PLAYER("rhythmbox_start_app: %s\n", player->app_name);
272
if (!rhythmbox_check_proxy(player)) return;
275
dbus_g_proxy_call_no_reply(player->proxy, "Play", G_TYPE_INVALID);