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