~cairo-dock-team/cairo-dock-plug-ins/plug-ins

« back to all changes in this revision

Viewing changes to musicPlayer/src/applet-rhythmbox.c

  • Committer: Matthieu Baerts
  • Date: 2014-10-19 00:26:10 UTC
  • Revision ID: matttbe@gmail.com-20141019002610-ulf26s9b4c4rw10r
We just switched from BZR to Git.
Follow us on Github: https://github.com/Cairo-Dock

Note: we will only use Github to manage our source code and all pull requests.
Please continue to report your bugs/ideas/messages on our forum or Launchpad! 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
* This file is a part of the Cairo-Dock project
3
 
*
4
 
* Copyright : (C) see the 'copyright' file.
5
 
* E-mail    : see the 'copyright' file.
6
 
*
7
 
* This program is free software; you can redistribute it and/or
8
 
* modify it under the terms of the GNU General Public License
9
 
* as published by the Free Software Foundation; either version 3
10
 
* of the License, or (at your option) any later version.
11
 
*
12
 
* This program is distributed in the hope that it will be useful,
13
 
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
* GNU General Public License for more details.
16
 
* You should have received a copy of the GNU General Public License
17
 
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
*/
19
 
 
20
 
#include <stdlib.h>
21
 
#include <string.h>
22
 
#include <stdio.h>
23
 
#include <glib/gi18n.h>
24
 
#include <cairo-dock.h>
25
 
 
26
 
#include "applet-struct.h"
27
 
#include "applet-musicplayer.h"
28
 
#include "applet-dbus.h"
29
 
#include "applet-draw.h"
30
 
#include "applet-cover.h"
31
 
#include "applet-mpris.h"
32
 
#include "applet-rhythmbox.h"
33
 
 
34
 
/////////////////////////////////
35
 
// Les Fonctions propres a RB. //
36
 
/////////////////////////////////
37
 
 
38
 
/* Teste si Rhythmbox joue de la musique ou non
39
 
 */
40
 
static void _rhythmbox_getPlaying (void)
41
 
{
42
 
        cd_message ("");
43
 
        if (cairo_dock_dbus_get_boolean (myData.dbus_proxy_player,"getPlaying"))
44
 
                myData.iPlayingStatus = PLAYER_PLAYING;
45
 
        else
46
 
                myData.iPlayingStatus = PLAYER_PAUSED;
47
 
}
48
 
 
49
 
/* Retourne l'adresse de la musique jouée
50
 
 */
51
 
static void _rhythmbox_getPlayingUri(void)
52
 
{
53
 
        cd_message ("");
54
 
        g_free (myData.cPlayingUri);
55
 
        myData.cPlayingUri = cairo_dock_dbus_get_string (myData.dbus_proxy_player, "getPlayingUri");
56
 
}
57
 
 
58
 
/* Recupere les infos de la chanson courante, y compris le chemin de la couverture (la telecharge au besoin).
59
 
 */
60
 
static void cd_rhythmbox_getSongInfos (gboolean bGetAll)
61
 
{
62
 
        GHashTable *data_list = NULL;
63
 
        GValue *value;
64
 
                
65
 
        if(dbus_g_proxy_call (myData.dbus_proxy_shell, "getSongProperties", NULL,
66
 
                G_TYPE_STRING, myData.cPlayingUri,
67
 
                G_TYPE_INVALID,
68
 
                MP_DBUS_TYPE_SONG_METADATA,
69
 
                &data_list,
70
 
                G_TYPE_INVALID))
71
 
        {
72
 
                if (bGetAll)
73
 
                {
74
 
                        g_free (myData.cArtist);
75
 
                        value = (GValue *) g_hash_table_lookup(data_list, "artist");
76
 
                        if (value != NULL && G_VALUE_HOLDS_STRING(value)) myData.cArtist = g_strdup (g_value_get_string(value));
77
 
                        else myData.cArtist = NULL;
78
 
                        cd_message ("  cArtist <- %s", myData.cArtist);
79
 
                        
80
 
                        g_free (myData.cAlbum);
81
 
                        value = (GValue *) g_hash_table_lookup(data_list, "album");
82
 
                        if (value != NULL && G_VALUE_HOLDS_STRING(value)) myData.cAlbum = g_strdup (g_value_get_string(value));
83
 
                        else myData.cAlbum = NULL;
84
 
                        cd_message ("  cAlbum <- %s", myData.cAlbum);
85
 
                        
86
 
                        g_free (myData.cTitle);
87
 
                        value = (GValue *) g_hash_table_lookup(data_list, "title");
88
 
                        if (value != NULL && G_VALUE_HOLDS_STRING(value)) myData.cTitle = g_strdup (g_value_get_string(value));
89
 
                        else myData.cTitle = NULL;
90
 
                        cd_message ("  cTitle <- %s", myData.cTitle);
91
 
                        
92
 
                        value = (GValue *) g_hash_table_lookup(data_list, "track-number");
93
 
                        if (value != NULL && G_VALUE_HOLDS_UINT(value)) myData.iTrackNumber = g_value_get_uint(value);
94
 
                        else myData.iTrackNumber = 0;
95
 
                        cd_message ("  iTrackNumber <- %d", myData.iTrackNumber);
96
 
                        
97
 
                        value = (GValue *) g_hash_table_lookup(data_list, "duration");
98
 
                        if (value != NULL && G_VALUE_HOLDS_UINT(value)) myData.iSongLength = g_value_get_uint(value);
99
 
                        else myData.iSongLength = 0;
100
 
                        cd_message ("  iSongLength <- %ds", myData.iSongLength);
101
 
                }
102
 
                
103
 
                const gchar *cString = NULL;
104
 
                value = (GValue *) g_hash_table_lookup(data_list, "rb:coverArt-uri");
105
 
                if (value != NULL && G_VALUE_HOLDS_STRING(value))  // RB nous donne une adresse, eventuellement distante.
106
 
                        cString = g_value_get_string(value);
107
 
                cd_musicplayer_set_cover_path (cString);
108
 
                cd_debug ("MP :  cCoverPath <- %s", myData.cCoverPath);
109
 
                
110
 
                g_hash_table_destroy (data_list);
111
 
        }
112
 
        else
113
 
        {
114
 
                cd_debug ("  can't get song properties");
115
 
                g_free (myData.cPlayingUri);
116
 
                myData.cPlayingUri = NULL;
117
 
                g_free (myData.cTitle);
118
 
                myData.cTitle = NULL;
119
 
                g_free (myData.cAlbum);
120
 
                myData.cAlbum = NULL;
121
 
                g_free (myData.cCoverPath);
122
 
                myData.cCoverPath = NULL;
123
 
        }
124
 
}
125
 
 
126
 
 
127
 
/////////////////////////////////////
128
 
// Les callbacks des signaux DBus. //
129
 
/////////////////////////////////////
130
 
 
131
 
/* Fonction executee a chaque changement de musique.
132
 
 */
133
 
static void onChangeSong(DBusGProxy *player_proxy,const gchar *uri, gpointer data)
134
 
{
135
 
        CD_APPLET_ENTER;
136
 
        cd_message ("MP : %s (%s)",__func__,uri);
137
 
        
138
 
        g_free (myData.cPlayingUri);
139
 
        if(uri != NULL && *uri != '\0')
140
 
        {
141
 
                myData.cPlayingUri = g_strdup (uri);
142
 
                cd_rhythmbox_getSongInfos (TRUE);  // TRUE <=> get all
143
 
        }
144
 
        else
145
 
        {
146
 
                myData.cPlayingUri = NULL;
147
 
                myData.cover_exist = FALSE;
148
 
                
149
 
                g_free (myData.cArtist);
150
 
                myData.cArtist = NULL;
151
 
                g_free (myData.cAlbum);
152
 
                myData.cAlbum = NULL;
153
 
                g_free (myData.cTitle);
154
 
                myData.cTitle = NULL;
155
 
                g_free (myData.cCoverPath);
156
 
                myData.cCoverPath = NULL;
157
 
                myData.iSongLength = 0;
158
 
                myData.iTrackNumber = 0;
159
 
        }
160
 
        cd_musicplayer_update_icon ();
161
 
        CD_APPLET_LEAVE ();
162
 
}
163
 
 
164
 
/* Fonction executee a chaque changement play/pause
165
 
 */
166
 
static void onChangePlaying(DBusGProxy *player_proxy, gboolean playing, gpointer data)
167
 
{
168
 
        CD_APPLET_ENTER;
169
 
        if (playing)
170
 
                myData.iPlayingStatus = PLAYER_PLAYING;
171
 
        else
172
 
                myData.iPlayingStatus = PLAYER_PAUSED;
173
 
        if(! myData.cover_exist && myData.cPlayingUri != NULL)
174
 
        {
175
 
                cd_message ("  cPlayingUri : %s", myData.cPlayingUri);
176
 
                cd_musicplayer_apply_status_surface (myData.iPlayingStatus);
177
 
        }
178
 
        else
179
 
        {
180
 
                CD_APPLET_REDRAW_MY_ICON;
181
 
        }
182
 
        CD_APPLET_LEAVE ();
183
 
}
184
 
 
185
 
 
186
 
/* Fonction executee a chaque changement de temps joué
187
 
 */
188
 
static void onElapsedChanged (DBusGProxy *player_proxy, int elapsed, gpointer data)
189
 
{
190
 
        CD_APPLET_ENTER;
191
 
        myData.iCurrentTime = elapsed;
192
 
        if(elapsed > 0)
193
 
        {
194
 
                cd_debug ("%s (%ds/%ds)", __func__, elapsed, myData.iSongLength);
195
 
                if(myConfig.iQuickInfoType == MY_APPLET_TIME_ELAPSED)
196
 
                {
197
 
                        CD_APPLET_SET_MINUTES_SECONDES_AS_QUICK_INFO (elapsed);
198
 
                        CD_APPLET_REDRAW_MY_ICON;
199
 
                }
200
 
                else if(myConfig.iQuickInfoType == MY_APPLET_TIME_LEFT)  // avec un '-' devant.
201
 
                {
202
 
                        CD_APPLET_SET_MINUTES_SECONDES_AS_QUICK_INFO (elapsed - myData.iSongLength);
203
 
                        CD_APPLET_REDRAW_MY_ICON;
204
 
                }
205
 
                else if(myConfig.iQuickInfoType == MY_APPLET_PERCENTAGE)
206
 
                {
207
 
                        CD_APPLET_SET_QUICK_INFO_ON_MY_ICON_PRINTF ("%d%%", (int) (100.*elapsed/myData.iSongLength));
208
 
                        CD_APPLET_REDRAW_MY_ICON;
209
 
                }
210
 
        }
211
 
        CD_APPLET_LEAVE ();
212
 
}
213
 
 
214
 
 
215
 
/*static void onSongPropertyChanged (DBusGProxy *player_proxy, const gchar *a, const gchar *cProperty, GValue *c, GValue *d, gpointer data)
216
 
{
217
 
        CD_APPLET_ENTER;
218
 
        cd_debug ("\n%s (%s)\n\n",__func__,cImageURI);
219
 
        g_free (myData.cCoverPath);
220
 
        myData.cCoverPath = g_strdup (cImageURI);
221
 
        
222
 
        CD_APPLET_SET_IMAGE_ON_MY_ICON (myData.cCoverPath);
223
 
        CD_APPLET_REDRAW_MY_ICON;
224
 
        myData.cover_exist = TRUE;
225
 
        if (myData.iSidCheckCover != 0)
226
 
        {
227
 
                g_source_remove (myData.iSidCheckCover);
228
 
                myData.iSidCheckCover = 0;
229
 
        }
230
 
        CD_APPLET_LEAVE ();
231
 
}*/
232
 
 
233
 
 
234
 
////////////////////////////
235
 
// Definition du backend. //
236
 
////////////////////////////
237
 
 
238
 
/* Controle du lecteur (permet d'effectuer les actions de bases sur le lecteur)
239
 
 */
240
 
void cd_rhythmbox_control (MyPlayerControl pControl, const char* song)
241
 
{
242
 
        cd_debug ("");
243
 
        const gchar *cCommand = NULL;
244
 
                
245
 
        switch (pControl) {
246
 
                case PLAYER_PREVIOUS :
247
 
                        cCommand = "previous";  // ou bien rhythmbox-client --previous
248
 
                break;
249
 
                
250
 
                case PLAYER_PLAY_PAUSE :
251
 
                        cCommand = "playPause";  // ou bien rhythmbox-client --pause/--play
252
 
                break;
253
 
 
254
 
                case PLAYER_NEXT :
255
 
                        cCommand = "next";  // ou bien rhythmbox-client --next
256
 
                break;
257
 
                
258
 
                case PLAYER_ENQUEUE :
259
 
                {
260
 
                        gchar *cCommand2 = g_strdup_printf ("rhythmbox-client --enqueue %s", song);
261
 
                        g_spawn_command_line_async (cCommand2, NULL);
262
 
                        g_free (cCommand2);
263
 
                }
264
 
                break;
265
 
                
266
 
                default :
267
 
                        return;
268
 
                break;
269
 
        }
270
 
        
271
 
        if (pControl == PLAYER_PLAY_PAUSE) // Cas special pour RB qui necessite un argument pour le PlayPause
272
 
        {
273
 
                gboolean bStartPlaying = (myData.iPlayingStatus != PLAYER_PLAYING);
274
 
                dbus_g_proxy_call_no_reply (myData.dbus_proxy_player, cCommand, 
275
 
                        G_TYPE_BOOLEAN, bStartPlaying,
276
 
                        G_TYPE_INVALID,
277
 
                        G_TYPE_INVALID);
278
 
        }
279
 
        else if (cCommand != NULL) 
280
 
        {
281
 
                cd_debug ("MP : Handler rhythmbox : will use '%s'", cCommand);
282
 
                cairo_dock_dbus_call (myData.dbus_proxy_player, cCommand);
283
 
        }
284
 
}
285
 
 
286
 
void cd_rhythmbox_get_cover_path (void)
287
 
{
288
 
        cd_rhythmbox_getSongInfos (FALSE);  // FALSE <=> on ne recupere que la couverture.
289
 
}
290
 
 
291
 
/* Initialise le backend de RB.
292
 
 */
293
 
static void cd_rhythmbox_start (void)
294
 
{
295
 
        // register to the signals
296
 
        dbus_g_proxy_add_signal(myData.dbus_proxy_player, "playingChanged",
297
 
                G_TYPE_BOOLEAN,
298
 
                G_TYPE_INVALID);
299
 
        dbus_g_proxy_connect_signal(myData.dbus_proxy_player, "playingChanged",
300
 
                G_CALLBACK(onChangePlaying), NULL, NULL);
301
 
        
302
 
        dbus_g_proxy_add_signal(myData.dbus_proxy_player, "playingUriChanged",
303
 
                G_TYPE_STRING,
304
 
                G_TYPE_INVALID);
305
 
        dbus_g_proxy_connect_signal(myData.dbus_proxy_player, "playingUriChanged",
306
 
                G_CALLBACK(onChangeSong), NULL, NULL);
307
 
        
308
 
        dbus_g_proxy_add_signal(myData.dbus_proxy_player, "elapsedChanged",
309
 
                G_TYPE_UINT,
310
 
                G_TYPE_INVALID);
311
 
        dbus_g_proxy_connect_signal(myData.dbus_proxy_player, "elapsedChanged",
312
 
                G_CALLBACK(onElapsedChanged), NULL, NULL);
313
 
        
314
 
        /*TODO (or maybe not, if they included MPRIS2)
315
 
        dbus_g_proxy_add_signal(myData.dbus_proxy_player, "playingSongPropertyChanged",
316
 
                G_TYPE_STRING,
317
 
                G_TYPE_STRING,
318
 
                G_TYPE_VALUE,
319
 
                G_TYPE_VALUE,
320
 
                G_TYPE_INVALID);
321
 
        dbus_g_proxy_connect_signal(myData.dbus_proxy_player, "playingSongPropertyChanged",
322
 
                G_CALLBACK(onSongPropertyChanged), NULL, NULL);*/
323
 
        
324
 
        // get the current state.
325
 
        _rhythmbox_getPlaying();
326
 
        _rhythmbox_getPlayingUri();
327
 
        cd_rhythmbox_getSongInfos (TRUE);  // TRUE <=> get all
328
 
        cd_musicplayer_update_icon ();
329
 
}
330
 
 
331
 
/* On enregistre notre lecteur.
332
 
 */
333
 
void cd_musicplayer_register_rhythmbox_handler (void)
334
 
{
335
 
        cd_debug ("MP - Used RB DBus methods");
336
 
        MusicPlayerHandler *pHandler = g_new0 (MusicPlayerHandler, 1);
337
 
        pHandler->name = "Rhythmbox";
338
 
        pHandler->get_data = NULL;  // rien a faire vu que l'echange de donnees se fait entierement avec les proxys DBus.
339
 
        pHandler->stop = NULL;  // signals are disconnected when the proxy is destroyed.
340
 
        pHandler->start = cd_rhythmbox_start;  // renseigne les proprietes DBus et se connecte au bus.
341
 
        pHandler->control = cd_rhythmbox_control;
342
 
        pHandler->get_cover = cd_rhythmbox_get_cover_path;
343
 
        
344
 
        pHandler->appclass = "rhythmbox";
345
 
        pHandler->launch = "rhythmbox";
346
 
        pHandler->cMprisService = "org.gnome.Rhythmbox";  // they used MPRIS from version 2.90.1~20110908 with org.mpris.MediaPlayer2.rhythmbox, but we don't care as they quickly switched to MPRIS2 in version 2.90.1~20111126
347
 
        pHandler->cMpris2Service = "org.mpris.MediaPlayer2.rhythmbox"; // after 2.90.1~20111126 (on a previous development version, they used rhythmbox3...)
348
 
        pHandler->path = "/org/gnome/Rhythmbox/Player"; // <= 0.13
349
 
        pHandler->interface = "org.gnome.Rhythmbox.Player";
350
 
        pHandler->path2 = "/org/gnome/Rhythmbox/Shell";
351
 
        pHandler->interface2 = "org.gnome.Rhythmbox.Shell";
352
 
        
353
 
        pHandler->cCoverDir = g_strdup_printf ("%s/.cache/rhythmbox/covers", g_getenv ("HOME"));
354
 
        pHandler->bSeparateAcquisition = FALSE;
355
 
        pHandler->iPlayerControls = PLAYER_PREVIOUS | PLAYER_PLAY_PAUSE | PLAYER_NEXT | PLAYER_ENQUEUE;
356
 
        pHandler->iLevel = PLAYER_EXCELLENT;
357
 
        
358
 
        cd_musicplayer_register_my_handler(pHandler);
359
 
}