~audio-recorder/audio-recorder/trunk

22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
1
/*
3 by Osmo Antero Maatta
Updated some filenames and traslations
2
 * Copyright (c) Linux community.
3
 *
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.
8
 *
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.
13
 *
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.
18
 */
19
#include "dbus-player.h"
20
#include "dbus-mpris.h"
21
#include "dbus-banshee.h"
22
#include "dbus-marshal.h"
23
#include "log.h"
24
#include "support.h"
25
#include "utility.h"
26
27
// Thanks to:
28
// http://code.google.com/p/pidgin-musictracker/source/browse/trunk/src/banshee.c?r=446
29
//
11 by Osmo Antero Maatta
Filename now includes artist name. Like artist/ track.ext
30
// Read also dev-info/banshee_readme.txt
3 by Osmo Antero Maatta
Updated some filenames and traslations
31
32
void marshal_VOID__STRING_STRING_DOUBLE (GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values,
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
33
        const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED,gpointer marshal_data);
3 by Osmo Antero Maatta
Updated some filenames and traslations
34
62 by Osmo Antero
The recorder now obeys commands from Banshee Player.
35
void banshee_player_track_start(MediaPlayerRec *player) {
36
    // Called when Banshee player starts a new track
37
38
    // Re-read all player data
39
    banshee_get_info(player);
40
41
    // Set track changed signal
42
    TrackInfo *tr = &player->track;
43
    tr->status = PLAYER_STATUS_PLAYING;
44
45
    // Print debug info
46
    dbus_player_debug_print(player);
47
48
    // Process data
49
    dbus_player_process_data(player);
50
}
51
52
void banshee_player_track_stop(MediaPlayerRec *player) {
53
    // Called when Banshee player ends a track
54
55
    // Re-read all player data
56
    banshee_get_info(player);
57
58
    // Set track changed signal
59
    TrackInfo *tr = &player->track;
60
    tr->status = PLAYER_STATUS_STOPPED;
61
62
    // Print debug info
63
    dbus_player_debug_print(player);
64
65
    // Process data
66
    dbus_player_process_data(player);
67
}
68
69
/*
3 by Osmo Antero Maatta
Updated some filenames and traslations
70
void banshee_player_track_changed(MediaPlayerRec *player) {
71
    // Called when track changes
72
73
    // Re-read all player data
74
    banshee_get_info(player);
75
76
    // Set track changed signal
77
    TrackInfo *tr = &player->track;
78
    tr->status = PLAYER_STATUS_TRACK_CHANGE;
79
80
    // Print debug info
62 by Osmo Antero
The recorder now obeys commands from Banshee Player.
81
    dbus_player_debug_print(player);
3 by Osmo Antero Maatta
Updated some filenames and traslations
82
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
83
    // Process data
3 by Osmo Antero Maatta
Updated some filenames and traslations
84
    dbus_player_process_data(player);
85
}
62 by Osmo Antero
The recorder now obeys commands from Banshee Player.
86
*/
3 by Osmo Antero Maatta
Updated some filenames and traslations
87
88
void banshee_player_status_changed(MediaPlayerRec *player) {
89
    // Called when player's status or track changes
90
91
    // Re-read all player data
92
    banshee_get_info(player);
93
94
    // Print debug info
95
    // dbus_player_debug_print(player);
96
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
97
    // Process data
3 by Osmo Antero Maatta
Updated some filenames and traslations
98
    dbus_player_process_data(player);
99
}
100
101
void banshee_get_app_name(MediaPlayerRec *player) {
19 by Osmo Antero Maatta
Added instructions for translators
102
    // Name of the Banshee media player.
3 by Osmo Antero Maatta
Updated some filenames and traslations
103
    player->app_name = g_strdup(_("Banshee Media Player"));
104
}
105
106
void banshee_state_signal_cb(DBusGProxy *player_proxy, gchar *state, MediaPlayerRec *player) {
107
    // State signal from Banshee
108
109
    // state:
110
    // "idle"  (quit player)
111
    // "loading"
112
    // "loaded"
113
    // "playing"  (play)
114
    // "paused"   (pause)
115
62 by Osmo Antero
The recorder now obeys commands from Banshee Player.
116
    // LOG_PLAYER("banshee_state_signal_cb: %s (%s) got state:<%s>\n", player->app_name, player->service_name, state);
117
3 by Osmo Antero Maatta
Updated some filenames and traslations
118
    if ((!g_strcmp0(state, "idle")) || // Quit player
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
119
            (!g_strcmp0(state, "playing")) || // Play
120
            (!g_strcmp0(state, "paused"))) {
3 by Osmo Antero Maatta
Updated some filenames and traslations
121
122
        // We do not utilize these state-events at the moment. See the banshee_event_signal_cb() function below.
123
124
        // Re-read all data and inform GUI
125
        // banshee_player_status_changed(player);
126
    }
127
}
128
129
void banshee_event_signal_cb(DBusGProxy *player_proxy, gchar *event, gchar *message, gdouble buffering_percentage, MediaPlayerRec *player) {
130
    // Event signal from Banshee
131
132
    // event:
133
    // "volume"
134
    // "seek"
135
    // "statechange"
136
    // "requestnexttrack"
137
    // "startofstream"
138
    // "endofstream"
139
140
    LOG_PLAYER("banshee_event_signal_cb: %s (%s) got event:<%s>\n", player->app_name, player->service_name, event);
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
141
3 by Osmo Antero Maatta
Updated some filenames and traslations
142
    if (!g_strcmp0(event, "volume")) {
143
        // Do nothing
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
144
    } else if (!g_strcmp0(event, "seek")) {
145
        // Do nothing
146
    } else if (!g_strcmp0(event, "requestnexttrack")) {
147
        // Do nothing
148
    } else if (!g_strcmp0(event, "statechange")) {
149
150
        // Re-read all data and inform the recorder
151
        banshee_player_status_changed(player);
62 by Osmo Antero
The recorder now obeys commands from Banshee Player.
152
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
153
    } else if (!g_strcmp0(event, "startofstream")) {
154
62 by Osmo Antero
The recorder now obeys commands from Banshee Player.
155
        // Stop and start of a new stream/track. Inform the recorder
156
        banshee_player_track_stop(player);
157
        banshee_player_track_start(player);
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
158
159
    } else if (!g_strcmp0(event, "endofstream")) {
3 by Osmo Antero Maatta
Updated some filenames and traslations
160
62 by Osmo Antero
The recorder now obeys commands from Banshee Player.
161
        // End of track/stream. Inform the recorder
162
        banshee_player_track_stop(player);
3 by Osmo Antero Maatta
Updated some filenames and traslations
163
    }
164
}
165
166
gboolean banshee_check_proxy(MediaPlayerRec *player) {
167
    // Check/set proxy
168
169
    if (!player) return FALSE;
170
171
    if (!player->proxy) {
172
        DBusGConnection *dbus_conn = dbus_player_connect_to_dbus();
173
174
        player->proxy = dbus_g_proxy_new_for_name(dbus_conn,
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
175
                        player->service_name,
176
                        "/org/bansheeproject/Banshee/PlayerEngine",
177
                        "org.bansheeproject.Banshee.PlayerEngine");
3 by Osmo Antero Maatta
Updated some filenames and traslations
178
    }
179
180
    if (!player->proxy) {
181
        LOG_ERROR("banshee_check_proxy: Cannot create DBus proxy for Banshee.\n");
182
    }
183
184
    return (player->proxy != NULL);
185
}
186
187
void banshee_set_signals(gpointer player_rec, gboolean connect) {
188
    // Connect/disconnect signals
189
190
    MediaPlayerRec *player = (MediaPlayerRec*)player_rec;
191
    if (!player) return;
192
193
    if (!player->proxy) {
194
195
        if (!banshee_check_proxy(player)) return;
196
197
        // Register arguments.
198
        dbus_g_object_register_marshaller(marshal_VOID__STRING_STRING_DOUBLE, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_DOUBLE, G_TYPE_INVALID);
199
200
        dbus_g_proxy_add_signal(player->proxy, "StateChanged", G_TYPE_STRING, G_TYPE_INVALID);
201
        dbus_g_proxy_add_signal(player->proxy, "EventChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_DOUBLE, G_TYPE_INVALID);
202
    }
203
204
    if (!banshee_check_proxy(player)) return;
205
206
    if (connect) {
207
        // Connect signals
208
        dbus_g_proxy_connect_signal(player->proxy, "StateChanged", G_CALLBACK(banshee_state_signal_cb), (gpointer)player, NULL);
209
        dbus_g_proxy_connect_signal(player->proxy, "EventChanged", G_CALLBACK(banshee_event_signal_cb), (gpointer)player, NULL);
210
    } else  {
211
        // Disconnect signals
212
        dbus_g_proxy_disconnect_signal(player->proxy, "StateChanged", G_CALLBACK(banshee_state_signal_cb), (gpointer)player);
213
        dbus_g_proxy_disconnect_signal(player->proxy, "EventChanged", G_CALLBACK(banshee_event_signal_cb), (gpointer)player);
214
    }
215
}
216
217
void banshee_hash_str(GHashTable *table, gchar *key, gchar *dest) {
218
    dest[0] = '\0';
219
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
220
    GValue* value = (GValue*) g_hash_table_lookup(table, key);
221
    if (G_VALUE_HOLDS_STRING(value)) {
3 by Osmo Antero Maatta
Updated some filenames and traslations
222
        str_copy(dest, (gchar*)g_value_get_string(value), MPRIS_STRLEN-1);
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
223
    }
3 by Osmo Antero Maatta
Updated some filenames and traslations
224
}
225
226
gboolean banshee_dbus_string(DBusGProxy *proxy, gchar *method, gchar* dest) {
227
    dest[0] = '\0';
228
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
229
    gchar *str = NULL;
230
    GError *error = 0;
231
    if (!dbus_g_proxy_call_with_timeout (proxy, method, DBUS_MPRIS_TIMEOUT, &error,
232
                                         G_TYPE_INVALID,
233
                                         G_TYPE_STRING, &str,
234
                                         G_TYPE_INVALID)) {
3 by Osmo Antero Maatta
Updated some filenames and traslations
235
236
        LOG_ERROR("banshee_dbus_string: Failed to make DBus call %s: %s", method, error ? error->message : "");
237
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
238
        g_free(str);
239
        str = NULL;
3 by Osmo Antero Maatta
Updated some filenames and traslations
240
241
        if (error)
242
            g_error_free(error);
243
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
244
        return FALSE;
245
    }
3 by Osmo Antero Maatta
Updated some filenames and traslations
246
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
247
    str_copy(dest, str, MPRIS_STRLEN-1);
248
    dest[MPRIS_STRLEN-1] = '\0';
249
    g_free(str);
250
    return TRUE;
3 by Osmo Antero Maatta
Updated some filenames and traslations
251
}
252
253
gint banshee_dbus_int(DBusGProxy *proxy, const char *method) {
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
254
    gint ret = 0;
255
    GError *error = NULL;
256
    if (!dbus_g_proxy_call_with_timeout (proxy, method, DBUS_MPRIS_TIMEOUT, &error,
257
                                         G_TYPE_INVALID,
258
                                         G_TYPE_INT, &ret,
259
                                         G_TYPE_INVALID)) {
3 by Osmo Antero Maatta
Updated some filenames and traslations
260
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
261
        LOG_ERROR("banshee_dbus_int: Failed to make DBus call %s: %s", method, error ? error->message : "");
3 by Osmo Antero Maatta
Updated some filenames and traslations
262
263
        if (error)
264
            g_error_free(error);
265
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
266
        return 0;
267
    }
3 by Osmo Antero Maatta
Updated some filenames and traslations
268
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
269
    return ret;
3 by Osmo Antero Maatta
Updated some filenames and traslations
270
}
271
272
guint banshee_dbus_uint(DBusGProxy *proxy, const char *method) {
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
273
    guint ret = 0;
274
    GError *error = NULL;
275
    if (!dbus_g_proxy_call_with_timeout (proxy, method, DBUS_MPRIS_TIMEOUT, &error,
276
                                         G_TYPE_INVALID,
277
                                         G_TYPE_UINT, &ret,
278
                                         G_TYPE_INVALID)) {
3 by Osmo Antero Maatta
Updated some filenames and traslations
279
280
        LOG_ERROR("banshee_dbus_uint: Failed to make DBus call %s: %s", method, error ? error->message : "");
281
282
        if (error)
283
            g_error_free(error);
284
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
285
        return 0;
286
    }
3 by Osmo Antero Maatta
Updated some filenames and traslations
287
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
288
    return ret;
3 by Osmo Antero Maatta
Updated some filenames and traslations
289
}
290
291
void banshee_get_info(gpointer player_rec) {
292
    MediaPlayerRec *player = (MediaPlayerRec*)player_rec;
293
    TrackInfo *tr = &player->track;
294
295
    // Is this player running/active?
296
    player->active = mpris_service_is_running_by_name(player->service_name);
297
    if (!player->active) {
298
        tr->status = PLAYER_STATUS_CLOSED;
299
        goto LBL_1;
300
    }
301
302
    // Check proxy
303
    if (!banshee_check_proxy(player)) return;
304
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
305
    char str[MPRIS_STRLEN];
3 by Osmo Antero Maatta
Updated some filenames and traslations
306
307
    if (!banshee_dbus_string(player->proxy, "GetCurrentState", str)) {
308
        // Application has exited/shutdown
309
        player->active = FALSE;
310
        tr->status = PLAYER_STATUS_STOPPED;
311
        goto LBL_1;
312
    }
313
314
    if (!g_strcmp0(str, "idle")) {
315
        tr->status = PLAYER_STATUS_STOPPED;
316
        goto LBL_1;
317
318
    } else if (!g_strcmp0(str, "playing")) {
319
        tr->status = PLAYER_STATUS_PLAYING;
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
320
    } else {
3 by Osmo Antero Maatta
Updated some filenames and traslations
321
        tr->status = PLAYER_STATUS_PAUSED;
322
    }
323
324
    GError *error = NULL;
325
    GHashTable* table = NULL;
326
327
    if (!dbus_g_proxy_call_with_timeout(player->proxy, "GetCurrentTrack", DBUS_MPRIS_TIMEOUT, &error, G_TYPE_INVALID,
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
328
                                        dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &table,G_TYPE_INVALID)) {
3 by Osmo Antero Maatta
Updated some filenames and traslations
329
330
        LOG_ERROR("banshee_get_info: Failed to make DBus call: %s", error ? error->message : "");
331
332
        if (error)
333
            g_error_free(error);
334
335
        goto LBL_1;
336
    }
337
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
338
    banshee_hash_str(table, "album", tr->album);
339
    banshee_hash_str(table, "artist", tr->artist);
340
    banshee_hash_str(table, "name", tr->track);
3 by Osmo Antero Maatta
Updated some filenames and traslations
341
342
    g_hash_table_destroy(table);
343
344
    tr->total_secs = banshee_dbus_uint(player->proxy, "GetLength") / 1000;
345
    tr->current_secs = banshee_dbus_uint(player->proxy, "GetPosition") / 1000;
346
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
347
LBL_1:
3 by Osmo Antero Maatta
Updated some filenames and traslations
348
    ;
349
}
350
351
void banshee_start_app(gpointer player_rec) {
352
    // Start Banshee
353
354
    MediaPlayerRec *player = (MediaPlayerRec*)player_rec;
355
356
    // Check/set proxy
357
    if (!banshee_check_proxy(player)) return;
358
359
    dbus_g_proxy_call_no_reply(player->proxy, "Start", G_TYPE_INVALID);
360
}
361
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
362
/*
363
 VOID:STRING,STRING,DOUBLE (marshal.list:1)
3 by Osmo Antero Maatta
Updated some filenames and traslations
364
 Ref: http://web.archive.org/web/20080501043040/http://wiki.bluez.org/wiki/HOWTO/DiscoveringDevices
365
366
 An example:
367
 $ echo "VOID:STRING,STRING,DOUBLE" > marshal.list
368
369
 $ glib-genmarshal --prefix=marshal marshal.list --header > sample1.h
370
 $ glib-genmarshal --prefix=marshal marshal.list --body > sample1.c
371
372
 See dbus_marshal.c
373
*/
374
void marshal_VOID__STRING_STRING_DOUBLE (GClosure     *closure,
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
375
        GValue       *return_value G_GNUC_UNUSED,
376
        guint         n_param_values,
377
        const GValue *param_values,
378
        gpointer      invocation_hint G_GNUC_UNUSED,
379
        gpointer      marshal_data) {
3 by Osmo Antero Maatta
Updated some filenames and traslations
380
    typedef void (*GMarshalFunc_VOID__STRING_STRING_DOUBLE) (gpointer     data1,
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
381
            gpointer     arg_1,
382
            gpointer     arg_2,
383
            gdouble      arg_3,
384
            gpointer     data2);
3 by Osmo Antero Maatta
Updated some filenames and traslations
385
    register GMarshalFunc_VOID__STRING_STRING_DOUBLE callback;
386
    register GCClosure *cc = (GCClosure*) closure;
387
    register gpointer data1, data2;
388
389
    g_return_if_fail (n_param_values == 4);
390
391
    if (G_CCLOSURE_SWAP_DATA (closure)) {
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
392
        data1 = closure->data;
393
        data2 = g_value_peek_pointer (param_values + 0);
394
    } else {
395
        data1 = g_value_peek_pointer (param_values + 0);
396
        data2 = closure->data;
3 by Osmo Antero Maatta
Updated some filenames and traslations
397
    }
398
    callback = (GMarshalFunc_VOID__STRING_STRING_DOUBLE) (marshal_data ? marshal_data : cc->callback);
399
400
    callback (data1,
22 by Osmo Antero Maatta
Formatted the code using astyle. See README for instructions.
401
              g_marshal_value_peek_string (param_values + 1),
402
              g_marshal_value_peek_string (param_values + 2),
403
              g_marshal_value_peek_double (param_values + 3),
404
              data2);
3 by Osmo Antero Maatta
Updated some filenames and traslations
405
}
406