00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023
00024 #include <glib.h>
00025 #include <dbus/dbus.h>
00026 #include <dbus/dbus-glib.h>
00027 #include <dbus/dbus-glib-bindings.h>
00028 #include <dbus/dbus-glib-lowlevel.h>
00029 #include "dbus.h"
00030 #include "dbus-service.h"
00031 #include "dbus-server-bindings.h"
00032
00033 #include <math.h>
00034 #include <libaudcore/eventqueue.h>
00035 #include <libaudcore/hook.h>
00036
00037 #include "debug.h"
00038 #include "drct.h"
00039 #include "playback.h"
00040 #include "playlist.h"
00041 #include "interface.h"
00042 #include "misc.h"
00043
00044 struct StatusRequest
00045 {
00046 gboolean playing, paused;
00047 gint time, length;
00048 gint bitrate, samplerate, channels;
00049 };
00050
00051 struct PositionRequest
00052 {
00053 gint playlist;
00054 gint entry;
00055 gint entry_count, queue_count;
00056 };
00057
00058 struct InfoRequest
00059 {
00060 gint playlist;
00061 gint entry;
00062 gchar *filename, *title, *pltitle;
00063 gint length;
00064 };
00065
00066 struct FieldRequest
00067 {
00068 gint playlist;
00069 gint entry;
00070 const gchar *field;
00071 GValue *value;
00072 };
00073
00074 struct AddRequest
00075 {
00076 gint position;
00077 gchar *filename;
00078 gboolean play;
00079 };
00080
00081 struct MprisMetadataRequest
00082 {
00083 gint playlist;
00084 gint entry;
00085 GHashTable *metadata;
00086 };
00087
00088 static DBusGConnection *dbus_conn = NULL;
00089 static guint signals[LAST_SIG] = { 0 };
00090 static guint tracklist_signals[LAST_TRACKLIST_SIG] = { 0 };
00091
00092 MprisPlayer * mpris = NULL;
00093
00094 static GThread *main_thread;
00095 static GMutex *info_mutex;
00096 static GCond *info_cond;
00097
00098 G_DEFINE_TYPE (RemoteObject, audacious_rc, G_TYPE_OBJECT)
00099 G_DEFINE_TYPE (MprisRoot, mpris_root, G_TYPE_OBJECT)
00100 G_DEFINE_TYPE (MprisPlayer, mpris_player, G_TYPE_OBJECT)
00101 G_DEFINE_TYPE (MprisTrackList, mpris_tracklist, G_TYPE_OBJECT)
00102
00103 #define DBUS_TYPE_G_STRING_VALUE_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
00104
00105 static void mpris_playlist_update_hook(gpointer unused, MprisTrackList *obj);
00106
00107 void audacious_rc_class_init(RemoteObjectClass * klass)
00108 {
00109 }
00110
00111 void mpris_root_class_init(MprisRootClass * klass)
00112 {
00113 }
00114
00115 void mpris_player_class_init(MprisPlayerClass * klass)
00116 {
00117 signals[CAPS_CHANGE_SIG] = g_signal_new("caps_change", G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
00118 signals[TRACK_CHANGE_SIG] =
00119 g_signal_new("track_change",
00120 G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_STRING_VALUE_HASHTABLE);
00121
00122 GType status_type = dbus_g_type_get_struct ("GValueArray", G_TYPE_INT,
00123 G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
00124 signals[STATUS_CHANGE_SIG] =
00125 g_signal_new ("status_change", G_OBJECT_CLASS_TYPE (klass),
00126 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL,
00127 g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, status_type);
00128 }
00129
00130 void mpris_tracklist_class_init(MprisTrackListClass * klass)
00131 {
00132 tracklist_signals[TRACKLIST_CHANGE_SIG] = g_signal_new("track_list_change", G_OBJECT_CLASS_TYPE(klass),
00133 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
00134 }
00135
00136 void audacious_rc_init(RemoteObject * object)
00137 {
00138 GError *error = NULL;
00139 DBusGProxy *driver_proxy;
00140 guint request_ret;
00141
00142 AUDDBG ("Registering remote D-Bus interfaces.\n");
00143
00144 dbus_g_object_type_install_info(audacious_rc_get_type(), &dbus_glib_audacious_rc_object_info);
00145
00146
00147 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH, G_OBJECT(object));
00148
00149
00150
00151 driver_proxy = dbus_g_proxy_new_for_name(dbus_conn, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
00152
00153 if (!org_freedesktop_DBus_request_name(driver_proxy, AUDACIOUS_DBUS_SERVICE, 0, &request_ret, &error))
00154 {
00155 g_warning("Unable to register service: %s", error->message);
00156 g_error_free(error);
00157 }
00158
00159 if (!org_freedesktop_DBus_request_name(driver_proxy, AUDACIOUS_DBUS_SERVICE_MPRIS, 0, &request_ret, &error))
00160 {
00161 g_warning("Unable to register service: %s", error->message);
00162 g_error_free(error);
00163 }
00164
00165 g_object_unref(driver_proxy);
00166 }
00167
00168 void mpris_root_init(MprisRoot * object)
00169 {
00170 dbus_g_object_type_install_info(mpris_root_get_type(), &dbus_glib_mpris_root_object_info);
00171
00172
00173 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH_MPRIS_ROOT, G_OBJECT(object));
00174 }
00175
00176 void mpris_player_init(MprisPlayer * object)
00177 {
00178 dbus_g_object_type_install_info(mpris_player_get_type(), &dbus_glib_mpris_player_object_info);
00179
00180
00181 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH_MPRIS_PLAYER, G_OBJECT(object));
00182
00183
00184 DBusGProxy *proxy = object->proxy;
00185 if (proxy != NULL)
00186 {
00187 dbus_g_proxy_add_signal (proxy, "StatusChange", dbus_g_type_get_struct
00188 ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
00189 G_TYPE_INVALID), G_TYPE_INVALID);
00190 dbus_g_proxy_add_signal (proxy, "CapsChange", G_TYPE_INT, G_TYPE_INVALID);
00191 dbus_g_proxy_add_signal(proxy, "TrackChange", DBUS_TYPE_G_STRING_VALUE_HASHTABLE, G_TYPE_INVALID);
00192 }
00193 else
00194 {
00195
00196 AUDDBG ("object->proxy == NULL; not adding some signals.\n");
00197 }
00198 }
00199
00200 void mpris_tracklist_init(MprisTrackList * object)
00201 {
00202 dbus_g_object_type_install_info(mpris_tracklist_get_type(), &dbus_glib_mpris_tracklist_object_info);
00203
00204
00205 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH_MPRIS_TRACKLIST, G_OBJECT(object));
00206
00207
00208 DBusGProxy *proxy = object->proxy;
00209 if (proxy != NULL)
00210 {
00211 dbus_g_proxy_add_signal(proxy, "TrackListChange", G_TYPE_INT, G_TYPE_INVALID);
00212 }
00213 else
00214 {
00215
00216 AUDDBG ("object->proxy == NULL, not adding some signals.\n");
00217 }
00218
00219 hook_associate("playlist update", (HookFunction) mpris_playlist_update_hook, object);
00220 }
00221
00222 void init_dbus()
00223 {
00224 GError *error = NULL;
00225 DBusConnection *local_conn;
00226
00227 main_thread = g_thread_self();
00228 info_mutex = g_mutex_new();
00229 info_cond = g_cond_new();
00230
00231 AUDDBG ("Trying to initialize D-Bus.\n");
00232 dbus_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
00233 if (dbus_conn == NULL)
00234 {
00235 g_warning("Unable to connect to dbus: %s", error->message);
00236 g_error_free(error);
00237 return;
00238 }
00239
00240 g_type_init();
00241 g_object_new(audacious_rc_get_type(), NULL);
00242 g_object_new(mpris_root_get_type(), NULL);
00243 mpris = g_object_new(mpris_player_get_type(), NULL);
00244 g_object_new(mpris_tracklist_get_type(), NULL);
00245
00246 local_conn = dbus_g_connection_get_connection(dbus_conn);
00247 dbus_connection_set_exit_on_disconnect(local_conn, FALSE);
00248 }
00249
00250 static GValue *tuple_value_to_gvalue(const Tuple * tuple, const gchar * key)
00251 {
00252 GValue *val;
00253 TupleValueType type = tuple_get_value_type((Tuple *) tuple, -1, key);
00254
00255 if (type == TUPLE_STRING)
00256 {
00257 val = g_new0(GValue, 1);
00258 g_value_init(val, G_TYPE_STRING);
00259 g_value_take_string(val, g_strdup(tuple_get_string((Tuple *) tuple, -1, key)));
00260 return val;
00261 }
00262 else if (type == TUPLE_INT)
00263 {
00264 val = g_new0(GValue, 1);
00265 g_value_init(val, G_TYPE_INT);
00266 g_value_set_int(val, tuple_get_int((Tuple *) tuple, -1, key));
00267 return val;
00268 }
00269 return NULL;
00270 }
00271
00280 static void tuple_insert_to_hash_full(GHashTable * md, const Tuple * tuple,
00281 const gchar * tuple_key, const gchar *key)
00282 {
00283 GValue *value = tuple_value_to_gvalue(tuple, tuple_key);
00284 if (value != NULL)
00285 g_hash_table_insert (md, (void *) key, value);
00286 }
00287
00288 static void tuple_insert_to_hash(GHashTable * md, const Tuple * tuple,
00289 const gchar *key)
00290 {
00291 tuple_insert_to_hash_full(md, tuple, key, key);
00292 }
00293
00294 static void remove_metadata_value(gpointer value)
00295 {
00296 g_value_unset((GValue *) value);
00297 g_free((GValue *) value);
00298 }
00299
00300 static GHashTable *make_mpris_metadata(const gchar * filename, const Tuple * tuple)
00301 {
00302 GHashTable *md = NULL;
00303 gpointer value;
00304
00305 md = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, remove_metadata_value);
00306
00307 value = g_malloc(sizeof(GValue));
00308 memset(value, 0, sizeof(GValue));
00309 g_value_init(value, G_TYPE_STRING);
00310 g_value_take_string(value, g_strdup(filename));
00311 g_hash_table_insert(md, "location", value);
00312
00313 if (tuple != NULL)
00314 {
00315 tuple_insert_to_hash_full(md, tuple, "length", "mtime");
00316 tuple_insert_to_hash(md, tuple, "title");
00317 tuple_insert_to_hash(md, tuple, "artist");
00318 tuple_insert_to_hash(md, tuple, "album");
00319 tuple_insert_to_hash(md, tuple, "comment");
00320 tuple_insert_to_hash(md, tuple, "genre");
00321 tuple_insert_to_hash(md, tuple, "year");
00322 tuple_insert_to_hash(md, tuple, "codec");
00323 tuple_insert_to_hash(md, tuple, "quality");
00324 tuple_insert_to_hash_full(md, tuple, "track-number", "tracknumber");
00325 tuple_insert_to_hash_full(md, tuple, "bitrate", "audio-bitrate");
00326 }
00327
00328 return md;
00329 }
00330
00331 static void real_position(gint * playlist, gint * entry)
00332 {
00333 if (*playlist == -2)
00334 *playlist = playlist_get_playing();
00335 if (*playlist == -1)
00336 *playlist = playlist_get_active();
00337 if (*entry == -1)
00338 *entry = playlist_get_position(*playlist);
00339 }
00340
00341 static gboolean get_status_cb(void *data)
00342 {
00343 struct StatusRequest *request = data;
00344
00345 g_mutex_lock(info_mutex);
00346
00347 memset (request, 0, sizeof (* request));
00348 request->playing = playback_get_playing();
00349
00350 if (request->playing)
00351 {
00352 request->paused = playback_get_paused ();
00353 request->time = playback_get_time ();
00354 request->length = playback_get_length ();
00355 playback_get_info (& request->bitrate, & request->samplerate,
00356 & request->channels);
00357 }
00358
00359 g_cond_signal(info_cond);
00360 g_mutex_unlock(info_mutex);
00361 return FALSE;
00362 }
00363
00364 static void get_status(struct StatusRequest *request)
00365 {
00366 if (g_thread_self() == main_thread)
00367 get_status_cb(request);
00368 else
00369 {
00370 g_mutex_lock(info_mutex);
00371 g_timeout_add(0, get_status_cb, request);
00372 g_cond_wait(info_cond, info_mutex);
00373 g_mutex_unlock(info_mutex);
00374 }
00375 }
00376
00377 static gboolean get_position_cb(void *data)
00378 {
00379 struct PositionRequest *request = data;
00380
00381 g_mutex_lock(info_mutex);
00382
00383 real_position(&request->playlist, &request->entry);
00384 request->entry_count = playlist_entry_count(request->playlist);
00385 request->queue_count = playlist_queue_count(request->playlist);
00386
00387 g_cond_signal(info_cond);
00388 g_mutex_unlock(info_mutex);
00389 return FALSE;
00390 }
00391
00392 static void get_position(struct PositionRequest *request)
00393 {
00394 if (g_thread_self() == main_thread)
00395 get_position_cb(request);
00396 else
00397 {
00398 g_mutex_lock(info_mutex);
00399 g_timeout_add(0, get_position_cb, request);
00400 g_cond_wait(info_cond, info_mutex);
00401 g_mutex_unlock(info_mutex);
00402 }
00403 }
00404
00405 static gboolean get_info_cb(void *data)
00406 {
00407 struct InfoRequest *request = data;
00408
00409 g_mutex_lock(info_mutex);
00410
00411 real_position(&request->playlist, &request->entry);
00412 request->filename = playlist_entry_get_filename (request->playlist,
00413 request->entry);
00414 request->title = playlist_entry_get_title (request->playlist,
00415 request->entry, FALSE);
00416 request->length = playlist_entry_get_length (request->playlist,
00417 request->entry, FALSE);
00418 request->pltitle = playlist_get_title (request->playlist);
00419
00420 g_cond_signal(info_cond);
00421 g_mutex_unlock(info_mutex);
00422 return FALSE;
00423 }
00424
00425 static void get_info(struct InfoRequest *request)
00426 {
00427 if (g_thread_self() == main_thread)
00428 get_info_cb(request);
00429 else
00430 {
00431 g_mutex_lock(info_mutex);
00432 g_timeout_add(0, get_info_cb, request);
00433 g_cond_wait(info_cond, info_mutex);
00434 g_mutex_unlock(info_mutex);
00435 }
00436 }
00437
00438 static gboolean get_field_cb(void *data)
00439 {
00440 struct FieldRequest *request = data;
00441
00442 g_mutex_lock(info_mutex);
00443
00444 real_position(&request->playlist, &request->entry);
00445 Tuple * tuple = playlist_entry_get_tuple (request->playlist, request->entry, FALSE);
00446 request->value = (tuple == NULL) ? NULL : tuple_value_to_gvalue(tuple, request->field);
00447 if (tuple)
00448 tuple_free (tuple)
00449
00450 g_cond_signal(info_cond);
00451 g_mutex_unlock(info_mutex);
00452 return FALSE;
00453 }
00454
00455 static void get_field(struct FieldRequest *request)
00456 {
00457 if (g_thread_self() == main_thread)
00458 get_field_cb(request);
00459 else
00460 {
00461 g_mutex_lock(info_mutex);
00462 g_timeout_add(0, get_field_cb, request);
00463 g_cond_wait(info_cond, info_mutex);
00464 g_mutex_unlock(info_mutex);
00465 }
00466 }
00467
00468 static gboolean play_cb(void *unused)
00469 {
00470
00471
00472 if (playlist_get_playing () != playlist_get_active ())
00473 playlist_set_playing (playlist_get_active ());
00474
00475 drct_play();
00476 return FALSE;
00477 }
00478
00479 static gboolean pause_cb(void *unused)
00480 {
00481 playback_pause();
00482 return FALSE;
00483 }
00484
00485 static gboolean play_pause_cb(void *unused)
00486 {
00487 if (playback_get_playing())
00488 playback_pause();
00489 else
00490 playback_play (0, FALSE);
00491
00492 return FALSE;
00493 }
00494
00495 static gboolean seek_cb(void *data)
00496 {
00497 playback_seek (GPOINTER_TO_INT (data));
00498 return FALSE;
00499 }
00500
00501 static gboolean stop_cb(void *unused)
00502 {
00503 playback_stop();
00504 return FALSE;
00505 }
00506
00507 static gboolean prev_cb(void *unused)
00508 {
00509 drct_pl_prev();
00510 return FALSE;
00511 }
00512
00513 static gboolean next_cb(void *unused)
00514 {
00515 drct_pl_next();
00516 return FALSE;
00517 }
00518
00519 static gboolean jump_cb(void *data)
00520 {
00521 drct_pl_set_pos(GPOINTER_TO_INT(data));
00522 return FALSE;
00523 }
00524
00525 static gboolean add_cb(void *data)
00526 {
00527 struct AddRequest *request = data;
00528 playlist_entry_insert (playlist_get_active (), request->position,
00529 request->filename, NULL, request->play);
00530 g_free(request);
00531 return FALSE;
00532 }
00533
00534 static gboolean delete_cb(void *data)
00535 {
00536 drct_pl_delete(GPOINTER_TO_INT(data));
00537 return FALSE;
00538 }
00539
00540 static gboolean clear_cb(void *unused)
00541 {
00542 drct_pl_clear();
00543 return FALSE;
00544 }
00545
00546 static gboolean add_to_queue_cb(void *data)
00547 {
00548 drct_pq_add(GPOINTER_TO_INT(data));
00549 return FALSE;
00550 }
00551
00552 static gboolean remove_from_queue_cb(void *data)
00553 {
00554 drct_pq_remove(GPOINTER_TO_INT(data));
00555 return FALSE;
00556 }
00557
00558 static gboolean clear_queue_cb(void *unused)
00559 {
00560 drct_pq_clear();
00561 return FALSE;
00562 }
00563
00564 static gboolean queue_get_entry_cb(void *data)
00565 {
00566 g_mutex_lock(info_mutex);
00567
00568 * (gint *) data = drct_pq_get_entry (* (gint *) data);
00569
00570 g_cond_signal(info_cond);
00571 g_mutex_unlock(info_mutex);
00572 return FALSE;
00573 }
00574
00575 static gint queue_get_entry(gint position)
00576 {
00577 if (g_thread_self() == main_thread)
00578 queue_get_entry_cb(&position);
00579 else
00580 {
00581 g_mutex_lock(info_mutex);
00582 g_timeout_add(0, queue_get_entry_cb, &position);
00583 g_cond_wait(info_cond, info_mutex);
00584 g_mutex_unlock(info_mutex);
00585 }
00586
00587 return position;
00588 }
00589
00590 static gboolean queue_find_entry_cb(void *data)
00591 {
00592 g_mutex_lock(info_mutex);
00593
00594 *(gint *) data = drct_pq_get_queue_position(*(gint *) data);
00595
00596 g_cond_signal(info_cond);
00597 g_mutex_unlock(info_mutex);
00598 return FALSE;
00599 }
00600
00601 static gint queue_find_entry(gint position)
00602 {
00603 if (g_thread_self() == main_thread)
00604 queue_find_entry_cb(&position);
00605 else
00606 {
00607 g_mutex_lock(info_mutex);
00608 g_timeout_add(0, queue_find_entry_cb, &position);
00609 g_cond_wait(info_cond, info_mutex);
00610 g_mutex_unlock(info_mutex);
00611 }
00612
00613 return position;
00614 }
00615
00616 gboolean add_to_new_playlist_cb(void *data)
00617 {
00618 drct_pl_open_temp (data);
00619 g_free(data);
00620 return FALSE;
00621 }
00622
00623 static gboolean get_mpris_metadata_cb(void *data)
00624 {
00625 struct MprisMetadataRequest *request = data;
00626
00627 g_mutex_lock(info_mutex);
00628
00629 real_position(&request->playlist, &request->entry);
00630 gchar * filename = playlist_entry_get_filename (request->playlist,
00631 request->entry);
00632 Tuple * tuple = playlist_entry_get_tuple (request->playlist, request->entry,
00633 FALSE);
00634
00635 if (filename && tuple)
00636 request->metadata = make_mpris_metadata (filename, tuple);
00637 else
00638 request->metadata = NULL;
00639
00640 g_free (filename);
00641 if (tuple)
00642 tuple_free (tuple);
00643
00644 g_cond_signal(info_cond);
00645 g_mutex_unlock(info_mutex);
00646 return FALSE;
00647 }
00648
00649 static void get_mpris_metadata(struct MprisMetadataRequest *request)
00650 {
00651 if (g_thread_self() == main_thread)
00652 get_mpris_metadata_cb(request);
00653 else
00654 {
00655 g_mutex_lock(info_mutex);
00656 g_timeout_add(0, get_mpris_metadata_cb, request);
00657 g_cond_wait(info_cond, info_mutex);
00658 g_mutex_unlock(info_mutex);
00659 }
00660 }
00661
00662
00663
00664 gboolean mpris_root_identity(MprisRoot * obj, gchar ** identity, GError ** error)
00665 {
00666 *identity = g_strdup_printf("Audacious %s", VERSION);
00667 return TRUE;
00668 }
00669
00670 gboolean mpris_root_quit(MprisPlayer * obj, GError ** error)
00671 {
00672 event_queue("quit", NULL);
00673 return TRUE;
00674 }
00675
00676
00677
00678 gboolean mpris_player_next(MprisPlayer * obj, GError * *error)
00679 {
00680 g_timeout_add(0, next_cb, NULL);
00681 return TRUE;
00682 }
00683
00684 gboolean mpris_player_prev(MprisPlayer * obj, GError * *error)
00685 {
00686 g_timeout_add(0, prev_cb, NULL);
00687 return TRUE;
00688 }
00689
00690 gboolean mpris_player_pause(MprisPlayer * obj, GError * *error)
00691 {
00692 g_timeout_add(0, pause_cb, NULL);
00693 return TRUE;
00694 }
00695
00696 gboolean mpris_player_stop(MprisPlayer * obj, GError * *error)
00697 {
00698 g_timeout_add(0, stop_cb, NULL);
00699 return TRUE;
00700 }
00701
00702 gboolean mpris_player_play(MprisPlayer * obj, GError * *error)
00703 {
00704 g_timeout_add(0, play_cb, NULL);
00705 return TRUE;
00706 }
00707
00708 gboolean mpris_player_repeat(MprisPlayer * obj, gboolean rpt, GError ** error)
00709 {
00710 fprintf (stderr, "implement me\n");
00711 return TRUE;
00712 }
00713
00714 static void append_int_value(GValueArray * ar, gint tmp)
00715 {
00716 GValue value;
00717 memset(&value, 0, sizeof(value));
00718 g_value_init(&value, G_TYPE_INT);
00719 g_value_set_int(&value, tmp);
00720 g_value_array_append(ar, &value);
00721 }
00722
00723 static gint get_playback_status(void)
00724 {
00725 struct StatusRequest request;
00726 get_status(&request);
00727
00728 return (!request.playing ? MPRIS_STATUS_STOP : request.paused ? MPRIS_STATUS_PAUSE : MPRIS_STATUS_PLAY);
00729 }
00730
00731 gboolean mpris_player_get_status(MprisPlayer * obj, GValueArray * *status, GError * *error)
00732 {
00733 *status = g_value_array_new(4);
00734
00735 append_int_value(*status, (gint) get_playback_status());
00736 append_int_value (* status, get_bool (NULL, "shuffle"));
00737 append_int_value (* status, get_bool (NULL, "no_playlist_advance"));
00738 append_int_value (* status, get_bool (NULL, "repeat"));
00739 return TRUE;
00740 }
00741
00742 gboolean mpris_player_get_metadata(MprisPlayer * obj, GHashTable * *metadata, GError * *error)
00743 {
00744 struct MprisMetadataRequest request = {.playlist = -1,.entry = -1 };
00745
00746 get_mpris_metadata(&request);
00747 *metadata = request.metadata;
00748
00749 if (! * metadata)
00750 * metadata = g_hash_table_new (g_str_hash, g_str_equal);
00751
00752 return TRUE;
00753 }
00754
00755 gboolean mpris_player_get_caps(MprisPlayer * obj, gint * capabilities, GError ** error)
00756 {
00757 *capabilities = MPRIS_CAPS_CAN_GO_NEXT | MPRIS_CAPS_CAN_GO_PREV | MPRIS_CAPS_CAN_PAUSE | MPRIS_CAPS_CAN_PLAY | MPRIS_CAPS_CAN_SEEK | MPRIS_CAPS_CAN_PROVIDE_METADATA | MPRIS_CAPS_PROVIDES_TIMING;
00758 return TRUE;
00759 }
00760
00761 gboolean mpris_player_volume_set(MprisPlayer * obj, gint vol, GError ** error)
00762 {
00763 drct_set_volume_main (vol);
00764 return TRUE;
00765 }
00766
00767 gboolean mpris_player_volume_get(MprisPlayer * obj, gint * vol, GError ** error)
00768 {
00769 drct_get_volume_main (vol);
00770 return TRUE;
00771 }
00772
00773 gboolean mpris_player_position_set(MprisPlayer * obj, gint pos, GError * *error)
00774 {
00775 g_timeout_add(0, seek_cb, GINT_TO_POINTER(pos));
00776 return TRUE;
00777 }
00778
00779 gboolean mpris_player_position_get(MprisPlayer * obj, gint * pos, GError * *error)
00780 {
00781 struct StatusRequest request;
00782
00783 get_status(&request);
00784 *pos = request.time;
00785 return TRUE;
00786 }
00787
00788
00789 gboolean mpris_emit_caps_change(MprisPlayer * obj)
00790 {
00791 g_signal_emit(obj, signals[CAPS_CHANGE_SIG], 0, 0);
00792 return TRUE;
00793 }
00794
00795 gboolean mpris_emit_track_change(MprisPlayer * obj)
00796 {
00797 gint playlist, entry;
00798 GHashTable *metadata;
00799
00800 playlist = playlist_get_playing();
00801 entry = playlist_get_position(playlist);
00802 gchar * filename = playlist_entry_get_filename (playlist, entry);
00803 Tuple * tuple = playlist_entry_get_tuple (playlist, entry, FALSE);
00804
00805 if (filename && tuple)
00806 {
00807 metadata = make_mpris_metadata (filename, tuple);
00808 g_signal_emit (obj, signals[TRACK_CHANGE_SIG], 0, metadata);
00809 g_hash_table_destroy (metadata);
00810 }
00811
00812 g_free (filename);
00813 if (tuple)
00814 tuple_free (tuple);
00815
00816 return (filename && tuple);
00817 }
00818
00819 gboolean mpris_emit_status_change(MprisPlayer * obj, PlaybackStatus status)
00820 {
00821 GValueArray *ar = g_value_array_new(4);
00822
00823 if (status == MPRIS_STATUS_INVALID)
00824 status = get_playback_status ();
00825
00826 append_int_value(ar, (gint) status);
00827 append_int_value (ar, get_bool (NULL, "shuffle"));
00828 append_int_value (ar, get_bool (NULL, "no_playlist_advance"));
00829 append_int_value (ar, get_bool (NULL, "repeat"));
00830
00831 g_signal_emit(obj, signals[STATUS_CHANGE_SIG], 0, ar);
00832 g_value_array_free(ar);
00833 return TRUE;
00834 }
00835
00836
00837 gboolean mpris_emit_tracklist_change(MprisTrackList * obj, gint playlist)
00838 {
00839 g_signal_emit(obj, tracklist_signals[TRACKLIST_CHANGE_SIG], 0, playlist_entry_count(playlist));
00840 return TRUE;
00841 }
00842
00843 static void mpris_playlist_update_hook(gpointer unused, MprisTrackList * obj)
00844 {
00845 gint playlist = playlist_get_active();
00846
00847 mpris_emit_tracklist_change(obj, playlist);
00848 }
00849
00850 gboolean mpris_tracklist_get_metadata(MprisTrackList * obj, gint pos, GHashTable * *metadata, GError * *error)
00851 {
00852 struct MprisMetadataRequest request = {.playlist = -1,.entry = pos };
00853
00854 get_mpris_metadata(&request);
00855 *metadata = request.metadata;
00856 return TRUE;
00857 }
00858
00859 gboolean mpris_tracklist_get_current_track(MprisTrackList * obj, gint * pos, GError * *error)
00860 {
00861 struct PositionRequest request = {.playlist = -1,.entry = -1 };
00862
00863 get_position(&request);
00864 *pos = request.entry;
00865 return TRUE;
00866 }
00867
00868 gboolean mpris_tracklist_get_length(MprisTrackList * obj, gint * length, GError * *error)
00869 {
00870 struct PositionRequest request = {.playlist = -1,.entry = -1 };
00871
00872 get_position(&request);
00873 *length = request.entry_count;
00874 return TRUE;
00875 }
00876
00877 gboolean mpris_tracklist_add_track(MprisTrackList * obj, gchar * uri, gboolean play, GError * *error)
00878 {
00879 struct AddRequest *request = g_malloc(sizeof(struct AddRequest));
00880
00881 request->position = -1;
00882 request->filename = g_strdup(uri);
00883 request->play = play;
00884
00885 g_timeout_add(0, add_cb, request);
00886 return TRUE;
00887 }
00888
00889 gboolean mpris_tracklist_del_track(MprisTrackList * obj, gint pos, GError * *error)
00890 {
00891 g_timeout_add(0, delete_cb, GINT_TO_POINTER(pos));
00892 return TRUE;
00893 }
00894
00895 gboolean mpris_tracklist_loop (MprisTrackList * obj, gboolean loop, GError * *
00896 error)
00897 {
00898 set_bool (NULL, "repeat", loop);
00899 return TRUE;
00900 }
00901
00902 gboolean mpris_tracklist_random (MprisTrackList * obj, gboolean random,
00903 GError * * error)
00904 {
00905 set_bool (NULL, "shuffle", random);
00906 return TRUE;
00907 }
00908
00909
00910 gboolean audacious_rc_version(RemoteObject * obj, gchar ** version, GError ** error)
00911 {
00912 *version = g_strdup(VERSION);
00913 return TRUE;
00914 }
00915
00916 gboolean audacious_rc_quit(RemoteObject * obj, GError * *error)
00917 {
00918 event_queue("quit", NULL);
00919 return TRUE;
00920 }
00921
00922 gboolean audacious_rc_eject(RemoteObject * obj, GError ** error)
00923 {
00924 interface_show_filebrowser (TRUE);
00925 return TRUE;
00926 }
00927
00928 gboolean audacious_rc_main_win_visible (RemoteObject * obj,
00929 gboolean * visible, GError ** error)
00930 {
00931 * visible = interface_is_shown ();
00932 return TRUE;
00933 }
00934
00935 gboolean audacious_rc_show_main_win (RemoteObject * obj, gboolean show,
00936 GError * * error)
00937 {
00938 interface_show (show);
00939 return TRUE;
00940 }
00941
00942 gboolean audacious_rc_get_tuple_fields(RemoteObject * obj, gchar *** fields, GError ** error)
00943 {
00944 gchar **res = g_new0(gchar *, FIELD_LAST + 1);
00945 gint i;
00946 for (i = 0; i < FIELD_LAST; i++)
00947 {
00948 res[i] = g_strdup(tuple_fields[i].name);
00949 }
00950 *fields = res;
00951
00952 return TRUE;
00953 }
00954
00955
00956
00957
00958 gboolean audacious_rc_play(RemoteObject * obj, GError * *error)
00959 {
00960 g_timeout_add(0, play_cb, NULL);
00961 return TRUE;
00962 }
00963
00964 gboolean audacious_rc_pause(RemoteObject * obj, GError * *error)
00965 {
00966 g_timeout_add(0, pause_cb, NULL);
00967 return TRUE;
00968 }
00969
00970 gboolean audacious_rc_stop(RemoteObject * obj, GError * *error)
00971 {
00972 g_timeout_add(0, stop_cb, NULL);
00973 return TRUE;
00974 }
00975
00976 gboolean audacious_rc_playing(RemoteObject * obj, gboolean * is_playing, GError * *error)
00977 {
00978 struct StatusRequest request;
00979
00980 get_status(&request);
00981 *is_playing = request.playing;
00982 return TRUE;
00983 }
00984
00985 gboolean audacious_rc_paused(RemoteObject * obj, gboolean * is_paused, GError * *error)
00986 {
00987 struct StatusRequest request;
00988
00989 get_status(&request);
00990 *is_paused = request.paused;
00991 return TRUE;
00992 }
00993
00994 gboolean audacious_rc_stopped(RemoteObject * obj, gboolean * is_stopped, GError * *error)
00995 {
00996 struct StatusRequest request;
00997
00998 get_status(&request);
00999 *is_stopped = !request.playing;
01000 return TRUE;
01001 }
01002
01003 gboolean audacious_rc_status(RemoteObject * obj, gchar * *status, GError * *error)
01004 {
01005 struct StatusRequest request;
01006
01007 get_status(&request);
01008 *status = g_strdup(!request.playing ? "stopped" : request.paused ? "paused" : "playing");
01009 return TRUE;
01010 }
01011
01012 gboolean audacious_rc_info(RemoteObject * obj, gint * rate, gint * freq, gint * nch, GError * *error)
01013 {
01014 struct StatusRequest request;
01015
01016 get_status(&request);
01017 *rate = request.bitrate;
01018 *freq = request.samplerate;
01019 *nch = request.channels;
01020 return TRUE;
01021 }
01022
01023 gboolean audacious_rc_time(RemoteObject * obj, gint * time, GError * *error)
01024 {
01025 struct StatusRequest request;
01026
01027 get_status(&request);
01028 *time = request.time;
01029 return TRUE;
01030 }
01031
01032 gboolean audacious_rc_seek(RemoteObject * obj, guint pos, GError * *error)
01033 {
01034 g_timeout_add(0, seek_cb, GINT_TO_POINTER(pos));
01035 return TRUE;
01036 }
01037
01038 gboolean audacious_rc_volume(RemoteObject * obj, gint * vl, gint * vr, GError ** error)
01039 {
01040 drct_get_volume (vl, vr);
01041 return TRUE;
01042 }
01043
01044 gboolean audacious_rc_set_volume(RemoteObject * obj, gint vl, gint vr, GError ** error)
01045 {
01046 drct_set_volume (vl, vr);
01047 return TRUE;
01048 }
01049
01050 gboolean audacious_rc_balance(RemoteObject * obj, gint * balance, GError ** error)
01051 {
01052 drct_get_volume_balance (balance);
01053 return TRUE;
01054 }
01055
01056
01057
01058 gboolean audacious_rc_position(RemoteObject * obj, gint * pos, GError * *error)
01059 {
01060 struct PositionRequest request = {.playlist = -1,.entry = -1 };
01061
01062 get_position(&request);
01063 *pos = request.entry;
01064 return TRUE;
01065 }
01066
01067 gboolean audacious_rc_advance(RemoteObject * obj, GError * *error)
01068 {
01069 g_timeout_add(0, next_cb, NULL);
01070 return TRUE;
01071 }
01072
01073 gboolean audacious_rc_reverse(RemoteObject * obj, GError * *error)
01074 {
01075 g_timeout_add(0, prev_cb, NULL);
01076 return TRUE;
01077 }
01078
01079 gboolean audacious_rc_length(RemoteObject * obj, gint * length, GError * *error)
01080 {
01081 struct PositionRequest request = {.playlist = -1,.entry = -1 };
01082
01083 get_position(&request);
01084 *length = request.entry_count;
01085 return TRUE;
01086 }
01087
01088 gboolean audacious_rc_song_title(RemoteObject * obj, guint pos, gchar * *title, GError * *error)
01089 {
01090 struct InfoRequest request = {.playlist = -1,.entry = pos };
01091
01092 get_info(&request);
01093 g_free(request.filename);
01094 g_free(request.pltitle);
01095 *title = request.title;
01096 return TRUE;
01097 }
01098
01099 gboolean audacious_rc_song_filename(RemoteObject * obj, guint pos, gchar * *filename, GError * *error)
01100 {
01101 struct InfoRequest request = {.playlist = -1,.entry = pos };
01102
01103 get_info(&request);
01104 *filename = request.filename;
01105 g_free(request.title);
01106 g_free(request.pltitle);
01107 return TRUE;
01108 }
01109
01110 gboolean audacious_rc_song_length(RemoteObject * obj, guint pos, gint * length, GError * *error)
01111 {
01112 audacious_rc_song_frames(obj, pos, length, error);
01113 *length /= 1000;
01114 return TRUE;
01115 }
01116
01117 gboolean audacious_rc_song_frames(RemoteObject * obj, guint pos, gint * length, GError * *error)
01118 {
01119 struct InfoRequest request = {.playlist = -1,.entry = pos };
01120
01121 get_info(&request);
01122 g_free(request.filename);
01123 g_free(request.title);
01124 g_free(request.pltitle);
01125 *length = request.length;
01126 return TRUE;
01127 }
01128
01129 gboolean audacious_rc_song_tuple(RemoteObject * obj, guint pos, gchar * field, GValue * value, GError * *error)
01130 {
01131 struct FieldRequest request = {.playlist = -1,.entry = pos,.field = field };
01132
01133 get_field(&request);
01134
01135 if (request.value == NULL)
01136 return FALSE;
01137
01138 memset(value, 0, sizeof(GValue));
01139 g_value_init(value, G_VALUE_TYPE(request.value));
01140 g_value_copy(request.value, value);
01141 g_value_unset(request.value);
01142 g_free(request.value);
01143 return TRUE;
01144 }
01145
01146 gboolean audacious_rc_jump(RemoteObject * obj, guint pos, GError * *error)
01147 {
01148 g_timeout_add(0, jump_cb, GINT_TO_POINTER(pos));
01149 return TRUE;
01150 }
01151
01152 gboolean audacious_rc_add(RemoteObject * obj, gchar * file, GError * *error)
01153 {
01154 return audacious_rc_playlist_ins_url_string(obj, file, -1, error);
01155 }
01156
01157 gboolean audacious_rc_add_url(RemoteObject * obj, gchar * file, GError * *error)
01158 {
01159 return audacious_rc_playlist_ins_url_string(obj, file, -1, error);
01160 }
01161
01162 static GList * string_array_to_list (gchar * * strings)
01163 {
01164 GList * list = NULL;
01165
01166 while (* strings != NULL)
01167 list = g_list_prepend (list, * strings ++);
01168
01169 return g_list_reverse (list);
01170 }
01171
01172 gboolean audacious_rc_add_list (RemoteObject * obj, gchar * * filenames,
01173 GError * * error)
01174 {
01175 GList * list = string_array_to_list (filenames);
01176
01177 drct_pl_add_list (list, -1);
01178 g_list_free (list);
01179 return TRUE;
01180 }
01181
01182 gboolean audacious_rc_open_list (RemoteObject * obj, gchar * * filenames,
01183 GError * * error)
01184 {
01185 GList * list = string_array_to_list (filenames);
01186
01187 drct_pl_open_list (list);
01188 g_list_free (list);
01189 return TRUE;
01190 }
01191
01192 gboolean audacious_rc_open_list_to_temp (RemoteObject * obj, gchar * *
01193 filenames, GError * * error)
01194 {
01195 GList * list = string_array_to_list (filenames);
01196
01197 drct_pl_open_temp_list (list);
01198 g_list_free (list);
01199 return TRUE;
01200 }
01201
01202 gboolean audacious_rc_delete(RemoteObject * obj, guint pos, GError * *error)
01203 {
01204 g_timeout_add(0, delete_cb, GINT_TO_POINTER(pos));
01205 return TRUE;
01206 }
01207
01208 gboolean audacious_rc_clear(RemoteObject * obj, GError * *error)
01209 {
01210 g_timeout_add(0, clear_cb, NULL);
01211 return TRUE;
01212 }
01213
01214 gboolean audacious_rc_auto_advance(RemoteObject * obj, gboolean * is_advance, GError ** error)
01215 {
01216 * is_advance = ! get_bool (NULL, "no_playlist_advance");
01217 return TRUE;
01218 }
01219
01220 gboolean audacious_rc_toggle_auto_advance(RemoteObject * obj, GError ** error)
01221 {
01222 set_bool (NULL, "no_playlist_advance", ! get_bool (NULL, "no_playlist_advance"));
01223 return TRUE;
01224 }
01225
01226 gboolean audacious_rc_repeat(RemoteObject * obj, gboolean * is_repeating, GError ** error)
01227 {
01228 *is_repeating = get_bool (NULL, "repeat");
01229 return TRUE;
01230 }
01231
01232 gboolean audacious_rc_toggle_repeat (RemoteObject * obj, GError * * error)
01233 {
01234 set_bool (NULL, "repeat", ! get_bool (NULL, "repeat"));
01235 return TRUE;
01236 }
01237
01238 gboolean audacious_rc_shuffle(RemoteObject * obj, gboolean * is_shuffling, GError ** error)
01239 {
01240 *is_shuffling = get_bool (NULL, "shuffle");
01241 return TRUE;
01242 }
01243
01244 gboolean audacious_rc_toggle_shuffle (RemoteObject * obj, GError * * error)
01245 {
01246 set_bool (NULL, "shuffle", ! get_bool (NULL, "shuffle"));
01247 return TRUE;
01248 }
01249
01250 gboolean audacious_rc_stop_after (RemoteObject * obj, gboolean * is_stopping, GError * * error)
01251 {
01252 * is_stopping = get_bool (NULL, "stop_after_current_song");
01253 return TRUE;
01254 }
01255
01256 gboolean audacious_rc_toggle_stop_after (RemoteObject * obj, GError * * error)
01257 {
01258 set_bool (NULL, "stop_after_current_song", ! get_bool (NULL, "stop_after_current_song"));
01259 return TRUE;
01260 }
01261
01262
01263 gboolean audacious_rc_show_prefs_box(RemoteObject * obj, gboolean show, GError ** error)
01264 {
01265 event_queue("prefswin show", GINT_TO_POINTER(show));
01266 return TRUE;
01267 }
01268
01269 gboolean audacious_rc_show_about_box(RemoteObject * obj, gboolean show, GError ** error)
01270 {
01271 event_queue("aboutwin show", GINT_TO_POINTER(show));
01272 return TRUE;
01273 }
01274
01275 gboolean audacious_rc_show_jtf_box(RemoteObject * obj, gboolean show, GError ** error)
01276 {
01277 if (show)
01278 event_queue("interface show jump to track", NULL);
01279 else
01280 event_queue("interface hide jump to track", NULL);
01281 return TRUE;
01282 }
01283
01284 gboolean audacious_rc_show_filebrowser(RemoteObject * obj, gboolean show, GError ** error)
01285 {
01286 if (show)
01287 event_queue("filebrowser show", GINT_TO_POINTER(FALSE));
01288 else
01289 event_queue("filebrowser hide", NULL);
01290 return TRUE;
01291 }
01292
01293 gboolean audacious_rc_play_pause(RemoteObject * obj, GError * *error)
01294 {
01295 g_timeout_add(0, play_pause_cb, NULL);
01296 return TRUE;
01297 }
01298
01299 gboolean audacious_rc_get_info(RemoteObject * obj, gint * rate, gint * freq, gint * nch, GError * *error)
01300 {
01301 struct StatusRequest request;
01302
01303 get_status(&request);
01304 *rate = request.bitrate;
01305 *freq = request.samplerate;
01306 *nch = request.channels;
01307 return TRUE;
01308 }
01309
01310 gboolean audacious_rc_toggle_aot(RemoteObject * obj, gboolean ontop, GError ** error)
01311 {
01312 hook_call("mainwin set always on top", &ontop);
01313 return TRUE;
01314 }
01315
01316 gboolean audacious_rc_playqueue_add(RemoteObject * obj, gint pos, GError * *error)
01317 {
01318 g_timeout_add(0, add_to_queue_cb, GINT_TO_POINTER(pos));
01319 return TRUE;
01320 }
01321
01322 gboolean audacious_rc_playqueue_remove(RemoteObject * obj, gint pos, GError * *error)
01323 {
01324 g_timeout_add(0, remove_from_queue_cb, GINT_TO_POINTER(pos));
01325 return TRUE;
01326 }
01327
01328 gboolean audacious_rc_playqueue_clear(RemoteObject * obj, GError * *error)
01329 {
01330 g_timeout_add(0, clear_queue_cb, NULL);
01331 return TRUE;
01332 }
01333
01334 gboolean audacious_rc_get_playqueue_length(RemoteObject * obj, gint * length, GError * *error)
01335 {
01336 struct PositionRequest request = {.playlist = -1,.entry = -1 };
01337
01338 get_position(&request);
01339 *length = request.queue_count;
01340 return TRUE;
01341 }
01342
01343 gboolean audacious_rc_queue_get_list_pos(RemoteObject * obj, gint qpos, gint * pos, GError * *error)
01344 {
01345 *pos = queue_get_entry(qpos);
01346 return TRUE;
01347 }
01348
01349 gboolean audacious_rc_queue_get_queue_pos(RemoteObject * obj, gint pos, gint * qpos, GError * *error)
01350 {
01351 *qpos = queue_find_entry(pos);
01352 return TRUE;
01353 }
01354
01355 gboolean audacious_rc_playqueue_is_queued(RemoteObject * obj, gint pos, gboolean * is_queued, GError * *error)
01356 {
01357 *is_queued = (queue_find_entry(pos) != -1);
01358 return TRUE;
01359 }
01360
01361 gboolean audacious_rc_playlist_ins_url_string(RemoteObject * obj, gchar * url, gint pos, GError * *error)
01362 {
01363 struct AddRequest *request = g_malloc(sizeof(struct AddRequest));
01364
01365 request->position = pos;
01366 request->filename = g_strdup(url);
01367 request->play = FALSE;
01368
01369 g_timeout_add(0, add_cb, request);
01370 return TRUE;
01371 }
01372
01373 gboolean audacious_rc_playlist_add(RemoteObject * obj, void *list, GError * *error)
01374 {
01375 return audacious_rc_playlist_ins_url_string(obj, list, -1, error);
01376 }
01377
01378 gboolean audacious_rc_playlist_enqueue_to_temp(RemoteObject * obj, gchar * url, GError * *error)
01379 {
01380 g_timeout_add(0, add_to_new_playlist_cb, g_strdup(url));
01381 return TRUE;
01382 }
01383
01384
01385 gboolean audacious_rc_get_eq(RemoteObject * obj, gdouble * preamp, GArray ** bands, GError ** error)
01386 {
01387 * preamp = get_double (NULL, "equalizer_preamp");
01388 * bands = g_array_new (FALSE, FALSE, sizeof (gdouble));
01389 g_array_set_size (* bands, AUD_EQUALIZER_NBANDS);
01390 eq_get_bands ((gdouble *) (* bands)->data);
01391
01392 return TRUE;
01393 }
01394
01395 gboolean audacious_rc_get_eq_preamp(RemoteObject * obj, gdouble * preamp, GError ** error)
01396 {
01397 * preamp = get_double (NULL, "equalizer_preamp");
01398 return TRUE;
01399 }
01400
01401 gboolean audacious_rc_get_eq_band(RemoteObject * obj, gint band, gdouble * value, GError ** error)
01402 {
01403 * value = eq_get_band (band);
01404 return TRUE;
01405 }
01406
01407 gboolean audacious_rc_set_eq(RemoteObject * obj, gdouble preamp, GArray * bands, GError ** error)
01408 {
01409 set_double (NULL, "equalizer_preamp", preamp);
01410 eq_set_bands ((gdouble *) bands->data);
01411 return TRUE;
01412 }
01413
01414 gboolean audacious_rc_set_eq_preamp(RemoteObject * obj, gdouble preamp, GError ** error)
01415 {
01416 set_double (NULL, "equalizer_preamp", preamp);
01417 return TRUE;
01418 }
01419
01420 gboolean audacious_rc_set_eq_band(RemoteObject * obj, gint band, gdouble value, GError ** error)
01421 {
01422 eq_set_band (band, value);
01423 return TRUE;
01424 }
01425
01426 gboolean audacious_rc_equalizer_activate(RemoteObject * obj, gboolean active, GError ** error)
01427 {
01428 set_bool (NULL, "equalizer_active", active);
01429 return TRUE;
01430 }
01431
01432 gboolean audacious_rc_get_active_playlist_name(RemoteObject * obj, gchar * *title, GError * *error)
01433 {
01434 struct InfoRequest request = {.playlist = -2 };
01435
01436 get_info(&request);
01437 g_free(request.title);
01438 g_free(request.filename);
01439 *title = request.pltitle;
01440 return TRUE;
01441 }
01442
01443 DBusGProxy *audacious_get_dbus_proxy(void)
01444 {
01445 DBusGConnection *connection = NULL;
01446 GError *error = NULL;
01447 connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
01448 g_clear_error(&error);
01449 return dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE, AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE);
01450 }