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 const gchar *filename, *title, *pltitle;
00404
00405 g_mutex_lock(info_mutex);
00406
00407 real_position(&request->playlist, &request->entry);
00408 filename = playlist_entry_get_filename(request->playlist, request->entry);
00409 request->filename = (filename == NULL) ? NULL : g_strdup(filename);
00410 title = playlist_entry_get_title (request->playlist, request->entry, FALSE);
00411 request->title = (title == NULL) ? NULL : g_strdup(title);
00412 request->length = playlist_entry_get_length (request->playlist,
00413 request->entry, FALSE);
00414 pltitle = playlist_get_title(request->playlist);
00415 request->pltitle = (pltitle == NULL) ? NULL : g_strdup(pltitle);
00416
00417 g_cond_signal(info_cond);
00418 g_mutex_unlock(info_mutex);
00419 return FALSE;
00420 }
00421
00422 static void get_info(struct InfoRequest *request)
00423 {
00424 if (g_thread_self() == main_thread)
00425 get_info_cb(request);
00426 else
00427 {
00428 g_mutex_lock(info_mutex);
00429 g_timeout_add(0, get_info_cb, request);
00430 g_cond_wait(info_cond, info_mutex);
00431 g_mutex_unlock(info_mutex);
00432 }
00433 }
00434
00435 static gboolean get_field_cb(void *data)
00436 {
00437 struct FieldRequest *request = data;
00438 const Tuple *tuple;
00439
00440 g_mutex_lock(info_mutex);
00441
00442 real_position(&request->playlist, &request->entry);
00443 tuple = playlist_entry_get_tuple (request->playlist, request->entry, FALSE);
00444 request->value = (tuple == NULL) ? NULL : tuple_value_to_gvalue(tuple, request->field);
00445
00446 g_cond_signal(info_cond);
00447 g_mutex_unlock(info_mutex);
00448 return FALSE;
00449 }
00450
00451 static void get_field(struct FieldRequest *request)
00452 {
00453 if (g_thread_self() == main_thread)
00454 get_field_cb(request);
00455 else
00456 {
00457 g_mutex_lock(info_mutex);
00458 g_timeout_add(0, get_field_cb, request);
00459 g_cond_wait(info_cond, info_mutex);
00460 g_mutex_unlock(info_mutex);
00461 }
00462 }
00463
00464 static gboolean play_cb(void *unused)
00465 {
00466
00467
00468 if (playlist_get_playing () != playlist_get_active ())
00469 playlist_set_playing (playlist_get_active ());
00470
00471 drct_play();
00472 return FALSE;
00473 }
00474
00475 static gboolean pause_cb(void *unused)
00476 {
00477 playback_pause();
00478 return FALSE;
00479 }
00480
00481 static gboolean play_pause_cb(void *unused)
00482 {
00483 if (playback_get_playing())
00484 playback_pause();
00485 else
00486 playback_play (0, FALSE);
00487
00488 return FALSE;
00489 }
00490
00491 static gboolean seek_cb(void *data)
00492 {
00493 playback_seek (GPOINTER_TO_INT (data));
00494 return FALSE;
00495 }
00496
00497 static gboolean stop_cb(void *unused)
00498 {
00499 playback_stop();
00500 return FALSE;
00501 }
00502
00503 static gboolean prev_cb(void *unused)
00504 {
00505 drct_pl_prev();
00506 return FALSE;
00507 }
00508
00509 static gboolean next_cb(void *unused)
00510 {
00511 drct_pl_next();
00512 return FALSE;
00513 }
00514
00515 static gboolean jump_cb(void *data)
00516 {
00517 drct_pl_set_pos(GPOINTER_TO_INT(data));
00518 return FALSE;
00519 }
00520
00521 static gboolean add_cb(void *data)
00522 {
00523 struct AddRequest *request = data;
00524 gint playlist = playlist_get_active();
00525
00526 if (request->position < 0)
00527 request->position = playlist_entry_count (playlist);
00528
00529 drct_pl_add (request->filename, request->position);
00530
00531 if (request->play)
00532 {
00533 playlist_set_playing(playlist);
00534 playlist_set_position(playlist, request->position);
00535 playback_play (0, FALSE);
00536 }
00537
00538 g_free(request);
00539 return FALSE;
00540 }
00541
00542 static gboolean delete_cb(void *data)
00543 {
00544 drct_pl_delete(GPOINTER_TO_INT(data));
00545 return FALSE;
00546 }
00547
00548 static gboolean clear_cb(void *unused)
00549 {
00550 drct_pl_clear();
00551 return FALSE;
00552 }
00553
00554 static gboolean add_to_queue_cb(void *data)
00555 {
00556 drct_pq_add(GPOINTER_TO_INT(data));
00557 return FALSE;
00558 }
00559
00560 static gboolean remove_from_queue_cb(void *data)
00561 {
00562 drct_pq_remove(GPOINTER_TO_INT(data));
00563 return FALSE;
00564 }
00565
00566 static gboolean clear_queue_cb(void *unused)
00567 {
00568 drct_pq_clear();
00569 return FALSE;
00570 }
00571
00572 static gboolean queue_get_entry_cb(void *data)
00573 {
00574 g_mutex_lock(info_mutex);
00575
00576 * (gint *) data = drct_pq_get_entry (* (gint *) data);
00577
00578 g_cond_signal(info_cond);
00579 g_mutex_unlock(info_mutex);
00580 return FALSE;
00581 }
00582
00583 static gint queue_get_entry(gint position)
00584 {
00585 if (g_thread_self() == main_thread)
00586 queue_get_entry_cb(&position);
00587 else
00588 {
00589 g_mutex_lock(info_mutex);
00590 g_timeout_add(0, queue_get_entry_cb, &position);
00591 g_cond_wait(info_cond, info_mutex);
00592 g_mutex_unlock(info_mutex);
00593 }
00594
00595 return position;
00596 }
00597
00598 static gboolean queue_find_entry_cb(void *data)
00599 {
00600 g_mutex_lock(info_mutex);
00601
00602 *(gint *) data = drct_pq_get_queue_position(*(gint *) data);
00603
00604 g_cond_signal(info_cond);
00605 g_mutex_unlock(info_mutex);
00606 return FALSE;
00607 }
00608
00609 static gint queue_find_entry(gint position)
00610 {
00611 if (g_thread_self() == main_thread)
00612 queue_find_entry_cb(&position);
00613 else
00614 {
00615 g_mutex_lock(info_mutex);
00616 g_timeout_add(0, queue_find_entry_cb, &position);
00617 g_cond_wait(info_cond, info_mutex);
00618 g_mutex_unlock(info_mutex);
00619 }
00620
00621 return position;
00622 }
00623
00624 gboolean add_to_new_playlist_cb(void *data)
00625 {
00626 drct_pl_open_temp (data);
00627 g_free(data);
00628 return FALSE;
00629 }
00630
00631 static gboolean get_mpris_metadata_cb(void *data)
00632 {
00633 struct MprisMetadataRequest *request = data;
00634 const gchar *filename;
00635
00636 g_mutex_lock(info_mutex);
00637
00638 real_position(&request->playlist, &request->entry);
00639 filename = playlist_entry_get_filename(request->playlist, request->entry);
00640
00641 if (filename == NULL)
00642 request->metadata = NULL;
00643 else
00644 request->metadata = make_mpris_metadata (filename,
00645 playlist_entry_get_tuple (request->playlist, request->entry, FALSE));
00646
00647 g_cond_signal(info_cond);
00648 g_mutex_unlock(info_mutex);
00649 return FALSE;
00650 }
00651
00652 static void get_mpris_metadata(struct MprisMetadataRequest *request)
00653 {
00654 if (g_thread_self() == main_thread)
00655 get_mpris_metadata_cb(request);
00656 else
00657 {
00658 g_mutex_lock(info_mutex);
00659 g_timeout_add(0, get_mpris_metadata_cb, request);
00660 g_cond_wait(info_cond, info_mutex);
00661 g_mutex_unlock(info_mutex);
00662 }
00663 }
00664
00665 static gboolean set_shuffle_cb (void * shuffle)
00666 {
00667 cfg.shuffle = GPOINTER_TO_INT (shuffle);
00668 event_queue ("toggle shuffle", NULL);
00669 return FALSE;
00670 }
00671
00672 static gboolean set_repeat_cb (void * repeat)
00673 {
00674 cfg.repeat = GPOINTER_TO_INT (repeat);
00675 event_queue ("toggle repeat", NULL);
00676 return FALSE;
00677 }
00678
00679
00680
00681 gboolean mpris_root_identity(MprisRoot * obj, gchar ** identity, GError ** error)
00682 {
00683 *identity = g_strdup_printf("Audacious %s", VERSION);
00684 return TRUE;
00685 }
00686
00687 gboolean mpris_root_quit(MprisPlayer * obj, GError ** error)
00688 {
00689 event_queue("quit", NULL);
00690 return TRUE;
00691 }
00692
00693
00694
00695 gboolean mpris_player_next(MprisPlayer * obj, GError * *error)
00696 {
00697 g_timeout_add(0, next_cb, NULL);
00698 return TRUE;
00699 }
00700
00701 gboolean mpris_player_prev(MprisPlayer * obj, GError * *error)
00702 {
00703 g_timeout_add(0, prev_cb, NULL);
00704 return TRUE;
00705 }
00706
00707 gboolean mpris_player_pause(MprisPlayer * obj, GError * *error)
00708 {
00709 g_timeout_add(0, pause_cb, NULL);
00710 return TRUE;
00711 }
00712
00713 gboolean mpris_player_stop(MprisPlayer * obj, GError * *error)
00714 {
00715 g_timeout_add(0, stop_cb, NULL);
00716 return TRUE;
00717 }
00718
00719 gboolean mpris_player_play(MprisPlayer * obj, GError * *error)
00720 {
00721 g_timeout_add(0, play_cb, NULL);
00722 return TRUE;
00723 }
00724
00725 gboolean mpris_player_repeat(MprisPlayer * obj, gboolean rpt, GError ** error)
00726 {
00727 fprintf (stderr, "implement me\n");
00728 return TRUE;
00729 }
00730
00731 static void append_int_value(GValueArray * ar, gint tmp)
00732 {
00733 GValue value;
00734 memset(&value, 0, sizeof(value));
00735 g_value_init(&value, G_TYPE_INT);
00736 g_value_set_int(&value, tmp);
00737 g_value_array_append(ar, &value);
00738 }
00739
00740 static gint get_playback_status(void)
00741 {
00742 struct StatusRequest request;
00743 get_status(&request);
00744
00745 return (!request.playing ? MPRIS_STATUS_STOP : request.paused ? MPRIS_STATUS_PAUSE : MPRIS_STATUS_PLAY);
00746 }
00747
00748 gboolean mpris_player_get_status(MprisPlayer * obj, GValueArray * *status, GError * *error)
00749 {
00750 *status = g_value_array_new(4);
00751
00752 append_int_value(*status, (gint) get_playback_status());
00753 append_int_value(*status, (gint) cfg.shuffle);
00754 append_int_value(*status, (gint) cfg.no_playlist_advance);
00755 append_int_value(*status, (gint) cfg.repeat);
00756 return TRUE;
00757 }
00758
00759 gboolean mpris_player_get_metadata(MprisPlayer * obj, GHashTable * *metadata, GError * *error)
00760 {
00761 struct MprisMetadataRequest request = {.playlist = -1,.entry = -1 };
00762
00763 get_mpris_metadata(&request);
00764 *metadata = request.metadata;
00765 return TRUE;
00766 }
00767
00768 gboolean mpris_player_get_caps(MprisPlayer * obj, gint * capabilities, GError ** error)
00769 {
00770 *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;
00771 return TRUE;
00772 }
00773
00774 gboolean mpris_player_volume_set(MprisPlayer * obj, gint vol, GError ** error)
00775 {
00776 drct_set_volume_main (vol);
00777 return TRUE;
00778 }
00779
00780 gboolean mpris_player_volume_get(MprisPlayer * obj, gint * vol, GError ** error)
00781 {
00782 drct_get_volume_main (vol);
00783 return TRUE;
00784 }
00785
00786 gboolean mpris_player_position_set(MprisPlayer * obj, gint pos, GError * *error)
00787 {
00788 g_timeout_add(0, seek_cb, GINT_TO_POINTER(pos));
00789 return TRUE;
00790 }
00791
00792 gboolean mpris_player_position_get(MprisPlayer * obj, gint * pos, GError * *error)
00793 {
00794 struct StatusRequest request;
00795
00796 get_status(&request);
00797 *pos = request.time;
00798 return TRUE;
00799 }
00800
00801
00802 gboolean mpris_emit_caps_change(MprisPlayer * obj)
00803 {
00804 g_signal_emit(obj, signals[CAPS_CHANGE_SIG], 0, 0);
00805 return TRUE;
00806 }
00807
00808 gboolean mpris_emit_track_change(MprisPlayer * obj)
00809 {
00810 gint playlist, entry;
00811 const gchar *filename;
00812 GHashTable *metadata;
00813
00814 playlist = playlist_get_playing();
00815 entry = playlist_get_position(playlist);
00816 filename = playlist_entry_get_filename(playlist, entry);
00817
00818 if (filename == NULL)
00819 return FALSE;
00820
00821 metadata = make_mpris_metadata (filename, playlist_entry_get_tuple
00822 (playlist, entry, FALSE));
00823
00824 g_signal_emit(obj, signals[TRACK_CHANGE_SIG], 0, metadata);
00825 g_hash_table_destroy(metadata);
00826 return TRUE;
00827 }
00828
00829 gboolean mpris_emit_status_change(MprisPlayer * obj, PlaybackStatus status)
00830 {
00831 GValueArray *ar = g_value_array_new(4);
00832
00833 if (status == MPRIS_STATUS_INVALID)
00834 status = get_playback_status ();
00835
00836 append_int_value(ar, (gint) status);
00837 append_int_value(ar, (gint) cfg.shuffle);
00838 append_int_value(ar, (gint) cfg.no_playlist_advance);
00839 append_int_value(ar, (gint) cfg.repeat);
00840
00841 g_signal_emit(obj, signals[STATUS_CHANGE_SIG], 0, ar);
00842 g_value_array_free(ar);
00843 return TRUE;
00844 }
00845
00846
00847 gboolean mpris_emit_tracklist_change(MprisTrackList * obj, gint playlist)
00848 {
00849 g_signal_emit(obj, tracklist_signals[TRACKLIST_CHANGE_SIG], 0, playlist_entry_count(playlist));
00850 return TRUE;
00851 }
00852
00853 static void mpris_playlist_update_hook(gpointer unused, MprisTrackList * obj)
00854 {
00855 gint playlist = playlist_get_active();
00856
00857 mpris_emit_tracklist_change(obj, playlist);
00858 }
00859
00860 gboolean mpris_tracklist_get_metadata(MprisTrackList * obj, gint pos, GHashTable * *metadata, GError * *error)
00861 {
00862 struct MprisMetadataRequest request = {.playlist = -1,.entry = pos };
00863
00864 get_mpris_metadata(&request);
00865 *metadata = request.metadata;
00866 return TRUE;
00867 }
00868
00869 gboolean mpris_tracklist_get_current_track(MprisTrackList * obj, gint * pos, GError * *error)
00870 {
00871 struct PositionRequest request = {.playlist = -1,.entry = -1 };
00872
00873 get_position(&request);
00874 *pos = request.entry;
00875 return TRUE;
00876 }
00877
00878 gboolean mpris_tracklist_get_length(MprisTrackList * obj, gint * length, GError * *error)
00879 {
00880 struct PositionRequest request = {.playlist = -1,.entry = -1 };
00881
00882 get_position(&request);
00883 *length = request.entry_count;
00884 return TRUE;
00885 }
00886
00887 gboolean mpris_tracklist_add_track(MprisTrackList * obj, gchar * uri, gboolean play, GError * *error)
00888 {
00889 struct AddRequest *request = g_malloc(sizeof(struct AddRequest));
00890
00891 request->position = -1;
00892 request->filename = g_strdup(uri);
00893 request->play = play;
00894
00895 g_timeout_add(0, add_cb, request);
00896 return TRUE;
00897 }
00898
00899 gboolean mpris_tracklist_del_track(MprisTrackList * obj, gint pos, GError * *error)
00900 {
00901 g_timeout_add(0, delete_cb, GINT_TO_POINTER(pos));
00902 return TRUE;
00903 }
00904
00905 gboolean mpris_tracklist_loop (MprisTrackList * obj, gboolean loop, GError * *
00906 error)
00907 {
00908 g_timeout_add (0, set_repeat_cb, GINT_TO_POINTER (loop));
00909 return TRUE;
00910 }
00911
00912 gboolean mpris_tracklist_random (MprisTrackList * obj, gboolean random,
00913 GError * * error)
00914 {
00915 g_timeout_add (0, set_shuffle_cb, GINT_TO_POINTER (random));
00916 return TRUE;
00917 }
00918
00919
00920 gboolean audacious_rc_version(RemoteObject * obj, gchar ** version, GError ** error)
00921 {
00922 *version = g_strdup(VERSION);
00923 return TRUE;
00924 }
00925
00926 gboolean audacious_rc_quit(RemoteObject * obj, GError * *error)
00927 {
00928 event_queue("quit", NULL);
00929 return TRUE;
00930 }
00931
00932 gboolean audacious_rc_eject(RemoteObject * obj, GError ** error)
00933 {
00934 interface_run_filebrowser (TRUE);
00935 return TRUE;
00936 }
00937
00938 gboolean audacious_rc_main_win_visible(RemoteObject * obj, gboolean * is_main_win, GError ** error)
00939 {
00940 *is_main_win = cfg.player_visible;
00941 return TRUE;
00942 }
00943
00944 gboolean audacious_rc_show_main_win(RemoteObject * obj, gboolean show, GError ** error)
00945 {
00946 interface_toggle_visibility ();
00947 return TRUE;
00948 }
00949
00950 gboolean audacious_rc_equalizer_visible(RemoteObject * obj, gboolean * is_eq_win, GError ** error)
00951 {
00952 *is_eq_win = cfg.equalizer_visible;
00953 return TRUE;
00954 }
00955
00956 gboolean audacious_rc_show_equalizer(RemoteObject * obj, gboolean show, GError ** error)
00957 {
00958 #if 0
00959 drct_eq_win_toggle(show);
00960 #endif
00961 return TRUE;
00962 }
00963
00964 gboolean audacious_rc_playlist_visible(RemoteObject * obj, gboolean * is_pl_win, GError ** error)
00965 {
00966 *is_pl_win = cfg.playlist_visible;
00967 return TRUE;
00968 }
00969
00970 gboolean audacious_rc_show_playlist(RemoteObject * obj, gboolean show, GError ** error)
00971 {
00972 #if 0
00973 drct_pl_win_toggle(show);
00974 #endif
00975 return TRUE;
00976 }
00977
00978 gboolean audacious_rc_get_tuple_fields(RemoteObject * obj, gchar *** fields, GError ** error)
00979 {
00980 gchar **res = g_new0(gchar *, FIELD_LAST + 1);
00981 gint i;
00982 for (i = 0; i < FIELD_LAST; i++)
00983 {
00984 res[i] = g_strdup(tuple_fields[i].name);
00985 }
00986 *fields = res;
00987
00988 return TRUE;
00989 }
00990
00991
00992
00993
00994 gboolean audacious_rc_play(RemoteObject * obj, GError * *error)
00995 {
00996 g_timeout_add(0, play_cb, NULL);
00997 return TRUE;
00998 }
00999
01000 gboolean audacious_rc_pause(RemoteObject * obj, GError * *error)
01001 {
01002 g_timeout_add(0, pause_cb, NULL);
01003 return TRUE;
01004 }
01005
01006 gboolean audacious_rc_stop(RemoteObject * obj, GError * *error)
01007 {
01008 g_timeout_add(0, stop_cb, NULL);
01009 return TRUE;
01010 }
01011
01012 gboolean audacious_rc_playing(RemoteObject * obj, gboolean * is_playing, GError * *error)
01013 {
01014 struct StatusRequest request;
01015
01016 get_status(&request);
01017 *is_playing = request.playing;
01018 return TRUE;
01019 }
01020
01021 gboolean audacious_rc_paused(RemoteObject * obj, gboolean * is_paused, GError * *error)
01022 {
01023 struct StatusRequest request;
01024
01025 get_status(&request);
01026 *is_paused = request.paused;
01027 return TRUE;
01028 }
01029
01030 gboolean audacious_rc_stopped(RemoteObject * obj, gboolean * is_stopped, GError * *error)
01031 {
01032 struct StatusRequest request;
01033
01034 get_status(&request);
01035 *is_stopped = !request.playing;
01036 return TRUE;
01037 }
01038
01039 gboolean audacious_rc_status(RemoteObject * obj, gchar * *status, GError * *error)
01040 {
01041 struct StatusRequest request;
01042
01043 get_status(&request);
01044 *status = g_strdup(!request.playing ? "stopped" : request.paused ? "paused" : "playing");
01045 return TRUE;
01046 }
01047
01048 gboolean audacious_rc_info(RemoteObject * obj, gint * rate, gint * freq, gint * nch, GError * *error)
01049 {
01050 struct StatusRequest request;
01051
01052 get_status(&request);
01053 *rate = request.bitrate;
01054 *freq = request.samplerate;
01055 *nch = request.channels;
01056 return TRUE;
01057 }
01058
01059 gboolean audacious_rc_time(RemoteObject * obj, gint * time, GError * *error)
01060 {
01061 struct StatusRequest request;
01062
01063 get_status(&request);
01064 *time = request.time;
01065 return TRUE;
01066 }
01067
01068 gboolean audacious_rc_seek(RemoteObject * obj, guint pos, GError * *error)
01069 {
01070 g_timeout_add(0, seek_cb, GINT_TO_POINTER(pos));
01071 return TRUE;
01072 }
01073
01074 gboolean audacious_rc_volume(RemoteObject * obj, gint * vl, gint * vr, GError ** error)
01075 {
01076 drct_get_volume (vl, vr);
01077 return TRUE;
01078 }
01079
01080 gboolean audacious_rc_set_volume(RemoteObject * obj, gint vl, gint vr, GError ** error)
01081 {
01082 drct_set_volume (vl, vr);
01083 return TRUE;
01084 }
01085
01086 gboolean audacious_rc_balance(RemoteObject * obj, gint * balance, GError ** error)
01087 {
01088 drct_get_volume_balance (balance);
01089 return TRUE;
01090 }
01091
01092
01093
01094 gboolean audacious_rc_position(RemoteObject * obj, gint * pos, GError * *error)
01095 {
01096 struct PositionRequest request = {.playlist = -1,.entry = -1 };
01097
01098 get_position(&request);
01099 *pos = request.entry;
01100 return TRUE;
01101 }
01102
01103 gboolean audacious_rc_advance(RemoteObject * obj, GError * *error)
01104 {
01105 g_timeout_add(0, next_cb, NULL);
01106 return TRUE;
01107 }
01108
01109 gboolean audacious_rc_reverse(RemoteObject * obj, GError * *error)
01110 {
01111 g_timeout_add(0, prev_cb, NULL);
01112 return TRUE;
01113 }
01114
01115 gboolean audacious_rc_length(RemoteObject * obj, gint * length, GError * *error)
01116 {
01117 struct PositionRequest request = {.playlist = -1,.entry = -1 };
01118
01119 get_position(&request);
01120 *length = request.entry_count;
01121 return TRUE;
01122 }
01123
01124 gboolean audacious_rc_song_title(RemoteObject * obj, guint pos, gchar * *title, GError * *error)
01125 {
01126 struct InfoRequest request = {.playlist = -1,.entry = pos };
01127
01128 get_info(&request);
01129 g_free(request.filename);
01130 g_free(request.pltitle);
01131 *title = request.title;
01132 return TRUE;
01133 }
01134
01135 gboolean audacious_rc_song_filename(RemoteObject * obj, guint pos, gchar * *filename, GError * *error)
01136 {
01137 struct InfoRequest request = {.playlist = -1,.entry = pos };
01138
01139 get_info(&request);
01140 *filename = request.filename;
01141 g_free(request.title);
01142 g_free(request.pltitle);
01143 return TRUE;
01144 }
01145
01146 gboolean audacious_rc_song_length(RemoteObject * obj, guint pos, gint * length, GError * *error)
01147 {
01148 audacious_rc_song_frames(obj, pos, length, error);
01149 *length /= 1000;
01150 return TRUE;
01151 }
01152
01153 gboolean audacious_rc_song_frames(RemoteObject * obj, guint pos, gint * length, GError * *error)
01154 {
01155 struct InfoRequest request = {.playlist = -1,.entry = pos };
01156
01157 get_info(&request);
01158 g_free(request.filename);
01159 g_free(request.title);
01160 g_free(request.pltitle);
01161 *length = request.length;
01162 return TRUE;
01163 }
01164
01165 gboolean audacious_rc_song_tuple(RemoteObject * obj, guint pos, gchar * field, GValue * value, GError * *error)
01166 {
01167 struct FieldRequest request = {.playlist = -1,.entry = pos,.field = field };
01168
01169 get_field(&request);
01170
01171 if (request.value == NULL)
01172 return FALSE;
01173
01174 memset(value, 0, sizeof(GValue));
01175 g_value_init(value, G_VALUE_TYPE(request.value));
01176 g_value_copy(request.value, value);
01177 g_value_unset(request.value);
01178 g_free(request.value);
01179 return TRUE;
01180 }
01181
01182 gboolean audacious_rc_jump(RemoteObject * obj, guint pos, GError * *error)
01183 {
01184 g_timeout_add(0, jump_cb, GINT_TO_POINTER(pos));
01185 return TRUE;
01186 }
01187
01188 gboolean audacious_rc_add(RemoteObject * obj, gchar * file, GError * *error)
01189 {
01190 return audacious_rc_playlist_ins_url_string(obj, file, -1, error);
01191 }
01192
01193 gboolean audacious_rc_add_url(RemoteObject * obj, gchar * file, GError * *error)
01194 {
01195 return audacious_rc_playlist_ins_url_string(obj, file, -1, error);
01196 }
01197
01198 static GList * string_array_to_list (gchar * * strings)
01199 {
01200 GList * list = NULL;
01201
01202 while (* strings != NULL)
01203 list = g_list_prepend (list, * strings ++);
01204
01205 return g_list_reverse (list);
01206 }
01207
01208 gboolean audacious_rc_add_list (RemoteObject * obj, gchar * * filenames,
01209 GError * * error)
01210 {
01211 GList * list = string_array_to_list (filenames);
01212
01213 drct_pl_add_list (list, -1);
01214 g_list_free (list);
01215 return TRUE;
01216 }
01217
01218 gboolean audacious_rc_open_list (RemoteObject * obj, gchar * * filenames,
01219 GError * * error)
01220 {
01221 GList * list = string_array_to_list (filenames);
01222
01223 drct_pl_open_list (list);
01224 g_list_free (list);
01225 return TRUE;
01226 }
01227
01228 gboolean audacious_rc_open_list_to_temp (RemoteObject * obj, gchar * *
01229 filenames, GError * * error)
01230 {
01231 GList * list = string_array_to_list (filenames);
01232
01233 drct_pl_open_temp_list (list);
01234 g_list_free (list);
01235 return TRUE;
01236 }
01237
01238 gboolean audacious_rc_delete(RemoteObject * obj, guint pos, GError * *error)
01239 {
01240 g_timeout_add(0, delete_cb, GINT_TO_POINTER(pos));
01241 return TRUE;
01242 }
01243
01244 gboolean audacious_rc_clear(RemoteObject * obj, GError * *error)
01245 {
01246 g_timeout_add(0, clear_cb, NULL);
01247 return TRUE;
01248 }
01249
01250 gboolean audacious_rc_auto_advance(RemoteObject * obj, gboolean * is_advance, GError ** error)
01251 {
01252 *is_advance = !cfg.no_playlist_advance;
01253 return TRUE;
01254 }
01255
01256 gboolean audacious_rc_toggle_auto_advance(RemoteObject * obj, GError ** error)
01257 {
01258 cfg.no_playlist_advance = !cfg.no_playlist_advance;
01259 return TRUE;
01260 }
01261
01262 gboolean audacious_rc_repeat(RemoteObject * obj, gboolean * is_repeating, GError ** error)
01263 {
01264 *is_repeating = cfg.repeat;
01265 return TRUE;
01266 }
01267
01268 gboolean audacious_rc_toggle_repeat (RemoteObject * obj, GError * * error)
01269 {
01270 g_timeout_add (0, set_repeat_cb, GINT_TO_POINTER (! cfg.repeat));
01271 return TRUE;
01272 }
01273
01274 gboolean audacious_rc_shuffle(RemoteObject * obj, gboolean * is_shuffling, GError ** error)
01275 {
01276 *is_shuffling = cfg.shuffle;
01277 return TRUE;
01278 }
01279
01280 gboolean audacious_rc_toggle_shuffle (RemoteObject * obj, GError * * error)
01281 {
01282 g_timeout_add (0, set_shuffle_cb, GINT_TO_POINTER (! cfg.shuffle));
01283 return TRUE;
01284 }
01285
01286
01287 gboolean audacious_rc_show_prefs_box(RemoteObject * obj, gboolean show, GError ** error)
01288 {
01289 event_queue("prefswin show", GINT_TO_POINTER(show));
01290 return TRUE;
01291 }
01292
01293 gboolean audacious_rc_show_about_box(RemoteObject * obj, gboolean show, GError ** error)
01294 {
01295 event_queue("aboutwin show", GINT_TO_POINTER(show));
01296 return TRUE;
01297 }
01298
01299 gboolean audacious_rc_show_jtf_box(RemoteObject * obj, gboolean show, GError ** error)
01300 {
01301 if (show)
01302 event_queue("interface show jump to track", NULL);
01303 else
01304 event_queue("interface hide jump to track", NULL);
01305 return TRUE;
01306 }
01307
01308 gboolean audacious_rc_show_filebrowser(RemoteObject * obj, gboolean show, GError ** error)
01309 {
01310 if (show)
01311 event_queue("filebrowser show", GINT_TO_POINTER(FALSE));
01312 else
01313 event_queue("filebrowser hide", NULL);
01314 return TRUE;
01315 }
01316
01317 gboolean audacious_rc_play_pause(RemoteObject * obj, GError * *error)
01318 {
01319 g_timeout_add(0, play_pause_cb, NULL);
01320 return TRUE;
01321 }
01322
01323 gboolean audacious_rc_activate(RemoteObject * obj, GError ** error)
01324 {
01325 fprintf (stderr, "implement me\n");
01326 return TRUE;
01327 }
01328
01329 gboolean audacious_rc_get_info(RemoteObject * obj, gint * rate, gint * freq, gint * nch, GError * *error)
01330 {
01331 struct StatusRequest request;
01332
01333 get_status(&request);
01334 *rate = request.bitrate;
01335 *freq = request.samplerate;
01336 *nch = request.channels;
01337 return TRUE;
01338 }
01339
01340 gboolean audacious_rc_toggle_aot(RemoteObject * obj, gboolean ontop, GError ** error)
01341 {
01342 hook_call("mainwin set always on top", &ontop);
01343 return TRUE;
01344 }
01345
01346 gboolean audacious_rc_playqueue_add(RemoteObject * obj, gint pos, GError * *error)
01347 {
01348 g_timeout_add(0, add_to_queue_cb, GINT_TO_POINTER(pos));
01349 return TRUE;
01350 }
01351
01352 gboolean audacious_rc_playqueue_remove(RemoteObject * obj, gint pos, GError * *error)
01353 {
01354 g_timeout_add(0, remove_from_queue_cb, GINT_TO_POINTER(pos));
01355 return TRUE;
01356 }
01357
01358 gboolean audacious_rc_playqueue_clear(RemoteObject * obj, GError * *error)
01359 {
01360 g_timeout_add(0, clear_queue_cb, NULL);
01361 return TRUE;
01362 }
01363
01364 gboolean audacious_rc_get_playqueue_length(RemoteObject * obj, gint * length, GError * *error)
01365 {
01366 struct PositionRequest request = {.playlist = -1,.entry = -1 };
01367
01368 get_position(&request);
01369 *length = request.queue_count;
01370 return TRUE;
01371 }
01372
01373 gboolean audacious_rc_queue_get_list_pos(RemoteObject * obj, gint qpos, gint * pos, GError * *error)
01374 {
01375 *pos = queue_get_entry(qpos);
01376 return TRUE;
01377 }
01378
01379 gboolean audacious_rc_queue_get_queue_pos(RemoteObject * obj, gint pos, gint * qpos, GError * *error)
01380 {
01381 *qpos = queue_find_entry(pos);
01382 return TRUE;
01383 }
01384
01385 gboolean audacious_rc_playqueue_is_queued(RemoteObject * obj, gint pos, gboolean * is_queued, GError * *error)
01386 {
01387 *is_queued = (queue_find_entry(pos) != -1);
01388 return TRUE;
01389 }
01390
01391 gboolean audacious_rc_playlist_ins_url_string(RemoteObject * obj, gchar * url, gint pos, GError * *error)
01392 {
01393 struct AddRequest *request = g_malloc(sizeof(struct AddRequest));
01394
01395 request->position = pos;
01396 request->filename = g_strdup(url);
01397 request->play = FALSE;
01398
01399 g_timeout_add(0, add_cb, request);
01400 return TRUE;
01401 }
01402
01403 gboolean audacious_rc_playlist_add(RemoteObject * obj, void *list, GError * *error)
01404 {
01405 return audacious_rc_playlist_ins_url_string(obj, list, -1, error);
01406 }
01407
01408 gboolean audacious_rc_playlist_enqueue_to_temp(RemoteObject * obj, gchar * url, GError * *error)
01409 {
01410 g_timeout_add(0, add_to_new_playlist_cb, g_strdup(url));
01411 return TRUE;
01412 }
01413
01414
01415 gboolean audacious_rc_get_eq(RemoteObject * obj, gdouble * preamp, GArray ** bands, GError ** error)
01416 {
01417 int i;
01418
01419 * preamp = cfg.equalizer_preamp;
01420 *bands = g_array_sized_new(FALSE, FALSE, sizeof(gdouble), AUD_EQUALIZER_NBANDS);
01421
01422 for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
01423 g_array_append_val (* bands, cfg.equalizer_bands[i]);
01424
01425 return TRUE;
01426 }
01427
01428 gboolean audacious_rc_get_eq_preamp(RemoteObject * obj, gdouble * preamp, GError ** error)
01429 {
01430 * preamp = cfg.equalizer_preamp;
01431 return TRUE;
01432 }
01433
01434 gboolean audacious_rc_get_eq_band(RemoteObject * obj, gint band, gdouble * value, GError ** error)
01435 {
01436 * value = cfg.equalizer_bands[band];
01437 return TRUE;
01438 }
01439
01440 gboolean audacious_rc_set_eq(RemoteObject * obj, gdouble preamp, GArray * bands, GError ** error)
01441 {
01442 int i;
01443
01444 cfg.equalizer_preamp = preamp;
01445
01446 for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
01447 cfg.equalizer_bands[i] = g_array_index (bands, gdouble, i);
01448
01449 hook_call ("equalizer changed", NULL);
01450 return TRUE;
01451 }
01452
01453 gboolean audacious_rc_set_eq_preamp(RemoteObject * obj, gdouble preamp, GError ** error)
01454 {
01455 cfg.equalizer_preamp = preamp;
01456 hook_call ("equalizer changed", NULL);
01457 return TRUE;
01458 }
01459
01460 gboolean audacious_rc_set_eq_band(RemoteObject * obj, gint band, gdouble value, GError ** error)
01461 {
01462 cfg.equalizer_bands[band] = value;
01463 hook_call ("equalizer changed", NULL);
01464 return TRUE;
01465 }
01466
01467 gboolean audacious_rc_equalizer_activate(RemoteObject * obj, gboolean active, GError ** error)
01468 {
01469 cfg.equalizer_active = active;
01470 hook_call ("equalizer changed", NULL);
01471 return TRUE;
01472 }
01473
01474 gboolean audacious_rc_get_active_playlist_name(RemoteObject * obj, gchar * *title, GError * *error)
01475 {
01476 struct InfoRequest request = {.playlist = -2 };
01477
01478 get_info(&request);
01479 g_free(request.title);
01480 g_free(request.filename);
01481 *title = request.pltitle;
01482 return TRUE;
01483 }
01484
01485 DBusGProxy *audacious_get_dbus_proxy(void)
01486 {
01487 DBusGConnection *connection = NULL;
01488 GError *error = NULL;
01489 connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
01490 g_clear_error(&error);
01491 return dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE, AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE);
01492 }