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 "main.h"
00041 #include "playback.h"
00042 #include "playlist.h"
00043 #include "interface.h"
00044
00045 struct StatusRequest
00046 {
00047 gboolean playing, paused;
00048 gint time, length;
00049 gint bitrate, samplerate, channels;
00050 };
00051
00052 struct PositionRequest
00053 {
00054 gint playlist;
00055 gint entry;
00056 gint entry_count, queue_count;
00057 };
00058
00059 struct InfoRequest
00060 {
00061 gint playlist;
00062 gint entry;
00063 gchar *filename, *title, *pltitle;
00064 gint length;
00065 };
00066
00067 struct FieldRequest
00068 {
00069 gint playlist;
00070 gint entry;
00071 const gchar *field;
00072 GValue *value;
00073 };
00074
00075 struct AddRequest
00076 {
00077 gint position;
00078 gchar *filename;
00079 gboolean play;
00080 };
00081
00082 struct MprisMetadataRequest
00083 {
00084 gint playlist;
00085 gint entry;
00086 GHashTable *metadata;
00087 };
00088
00089 static DBusGConnection *dbus_conn = NULL;
00090 static guint signals[LAST_SIG] = { 0 };
00091 static guint tracklist_signals[LAST_TRACKLIST_SIG] = { 0 };
00092
00093 static GThread *main_thread;
00094 static GMutex *info_mutex;
00095 static GCond *info_cond;
00096
00097 G_DEFINE_TYPE (RemoteObject, audacious_rc, G_TYPE_OBJECT)
00098 G_DEFINE_TYPE (MprisRoot, mpris_root, G_TYPE_OBJECT)
00099 G_DEFINE_TYPE (MprisPlayer, mpris_player, G_TYPE_OBJECT)
00100 G_DEFINE_TYPE (MprisTrackList, mpris_tracklist, G_TYPE_OBJECT)
00101
00102 #define DBUS_TYPE_G_STRING_VALUE_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
00103
00104 static void mpris_playlist_update_hook(gpointer unused, MprisTrackList *obj);
00105
00106 void audacious_rc_class_init(RemoteObjectClass * klass)
00107 {
00108 }
00109
00110 void mpris_root_class_init(MprisRootClass * klass)
00111 {
00112 }
00113
00114 void mpris_player_class_init(MprisPlayerClass * klass)
00115 {
00116 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);
00117 signals[TRACK_CHANGE_SIG] =
00118 g_signal_new("track_change",
00119 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);
00120 signals[STATUS_CHANGE_SIG] =
00121 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);
00122 }
00123
00124 void mpris_tracklist_class_init(MprisTrackListClass * klass)
00125 {
00126 tracklist_signals[TRACKLIST_CHANGE_SIG] = g_signal_new("track_list_change", G_OBJECT_CLASS_TYPE(klass),
00127 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
00128 }
00129
00130 void audacious_rc_init(RemoteObject * object)
00131 {
00132 GError *error = NULL;
00133 DBusGProxy *driver_proxy;
00134 guint request_ret;
00135
00136 AUDDBG ("Registering remote D-Bus interfaces.\n");
00137
00138 dbus_g_object_type_install_info(audacious_rc_get_type(), &dbus_glib_audacious_rc_object_info);
00139
00140
00141 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH, G_OBJECT(object));
00142
00143
00144
00145 driver_proxy = dbus_g_proxy_new_for_name(dbus_conn, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
00146
00147 if (!org_freedesktop_DBus_request_name(driver_proxy, AUDACIOUS_DBUS_SERVICE, 0, &request_ret, &error))
00148 {
00149 g_warning("Unable to register service: %s", error->message);
00150 g_error_free(error);
00151 }
00152
00153 if (!org_freedesktop_DBus_request_name(driver_proxy, AUDACIOUS_DBUS_SERVICE_MPRIS, 0, &request_ret, &error))
00154 {
00155 g_warning("Unable to register service: %s", error->message);
00156 g_error_free(error);
00157 }
00158
00159 g_object_unref(driver_proxy);
00160 }
00161
00162 void mpris_root_init(MprisRoot * object)
00163 {
00164 dbus_g_object_type_install_info(mpris_root_get_type(), &dbus_glib_mpris_root_object_info);
00165
00166
00167 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH_MPRIS_ROOT, G_OBJECT(object));
00168 }
00169
00170 void mpris_player_init(MprisPlayer * object)
00171 {
00172 dbus_g_object_type_install_info(mpris_player_get_type(), &dbus_glib_mpris_player_object_info);
00173
00174
00175 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH_MPRIS_PLAYER, G_OBJECT(object));
00176
00177
00178 DBusGProxy *proxy = object->proxy;
00179 if (proxy != NULL)
00180 {
00181 dbus_g_proxy_add_signal (proxy, "StatusChange", dbus_g_type_get_struct
00182 ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
00183 G_TYPE_INVALID), G_TYPE_INVALID);
00184 dbus_g_proxy_add_signal (proxy, "CapsChange", G_TYPE_INT, G_TYPE_INVALID);
00185 dbus_g_proxy_add_signal(proxy, "TrackChange", DBUS_TYPE_G_STRING_VALUE_HASHTABLE, G_TYPE_INVALID);
00186 }
00187 else
00188 {
00189
00190 AUDDBG ("object->proxy == NULL; not adding some signals.\n");
00191 }
00192 }
00193
00194 void mpris_tracklist_init(MprisTrackList * object)
00195 {
00196 dbus_g_object_type_install_info(mpris_tracklist_get_type(), &dbus_glib_mpris_tracklist_object_info);
00197
00198
00199 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH_MPRIS_TRACKLIST, G_OBJECT(object));
00200
00201
00202 DBusGProxy *proxy = object->proxy;
00203 if (proxy != NULL)
00204 {
00205 dbus_g_proxy_add_signal(proxy, "TrackListChange", G_TYPE_INT, G_TYPE_INVALID);
00206 }
00207 else
00208 {
00209
00210 AUDDBG ("object->proxy == NULL, not adding some signals.\n");
00211 }
00212
00213 hook_associate("playlist update", (HookFunction) mpris_playlist_update_hook, object);
00214 }
00215
00216 void init_dbus()
00217 {
00218 GError *error = NULL;
00219 DBusConnection *local_conn;
00220
00221 main_thread = g_thread_self();
00222 info_mutex = g_mutex_new();
00223 info_cond = g_cond_new();
00224
00225 AUDDBG ("Trying to initialize D-Bus.\n");
00226 dbus_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
00227 if (dbus_conn == NULL)
00228 {
00229 g_warning("Unable to connect to dbus: %s", error->message);
00230 g_error_free(error);
00231 return;
00232 }
00233
00234 g_type_init();
00235 g_object_new(audacious_rc_get_type(), NULL);
00236 g_object_new(mpris_root_get_type(), NULL);
00237 mpris = g_object_new(mpris_player_get_type(), NULL);
00238 g_object_new(mpris_tracklist_get_type(), NULL);
00239
00240 local_conn = dbus_g_connection_get_connection(dbus_conn);
00241 dbus_connection_set_exit_on_disconnect(local_conn, FALSE);
00242 }
00243
00244 static GValue *tuple_value_to_gvalue(const Tuple * tuple, const gchar * key)
00245 {
00246 GValue *val;
00247 TupleValueType type = tuple_get_value_type((Tuple *) tuple, -1, key);
00248
00249 if (type == TUPLE_STRING)
00250 {
00251 val = g_new0(GValue, 1);
00252 g_value_init(val, G_TYPE_STRING);
00253 g_value_take_string(val, g_strdup(tuple_get_string((Tuple *) tuple, -1, key)));
00254 return val;
00255 }
00256 else if (type == TUPLE_INT)
00257 {
00258 val = g_new0(GValue, 1);
00259 g_value_init(val, G_TYPE_INT);
00260 g_value_set_int(val, tuple_get_int((Tuple *) tuple, -1, key));
00261 return val;
00262 }
00263 return NULL;
00264 }
00265
00274 static void tuple_insert_to_hash_full(GHashTable * md, const Tuple * tuple,
00275 const gchar * tuple_key, const gchar *key)
00276 {
00277 GValue *value = tuple_value_to_gvalue(tuple, tuple_key);
00278 if (value != NULL)
00279 g_hash_table_insert (md, (void *) key, value);
00280 }
00281
00282 static void tuple_insert_to_hash(GHashTable * md, const Tuple * tuple,
00283 const gchar *key)
00284 {
00285 tuple_insert_to_hash_full(md, tuple, key, key);
00286 }
00287
00288 static void remove_metadata_value(gpointer value)
00289 {
00290 g_value_unset((GValue *) value);
00291 g_free((GValue *) value);
00292 }
00293
00294 static GHashTable *make_mpris_metadata(const gchar * filename, const Tuple * tuple)
00295 {
00296 GHashTable *md = NULL;
00297 gpointer value;
00298
00299 md = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, remove_metadata_value);
00300
00301 value = g_malloc(sizeof(GValue));
00302 memset(value, 0, sizeof(GValue));
00303 g_value_init(value, G_TYPE_STRING);
00304 g_value_take_string(value, g_strdup(filename));
00305 g_hash_table_insert(md, "location", value);
00306
00307 if (tuple != NULL)
00308 {
00309 tuple_insert_to_hash_full(md, tuple, "length", "mtime");
00310 tuple_insert_to_hash(md, tuple, "title");
00311 tuple_insert_to_hash(md, tuple, "artist");
00312 tuple_insert_to_hash(md, tuple, "album");
00313 tuple_insert_to_hash(md, tuple, "comment");
00314 tuple_insert_to_hash(md, tuple, "genre");
00315 tuple_insert_to_hash(md, tuple, "year");
00316 tuple_insert_to_hash(md, tuple, "codec");
00317 tuple_insert_to_hash(md, tuple, "quality");
00318 tuple_insert_to_hash_full(md, tuple, "track-number", "tracknumber");
00319 tuple_insert_to_hash_full(md, tuple, "bitrate", "audio-bitrate");
00320 }
00321
00322 return md;
00323 }
00324
00325 static void real_position(gint * playlist, gint * entry)
00326 {
00327 if (*playlist == -2)
00328 *playlist = playlist_get_playing();
00329 if (*playlist == -1)
00330 *playlist = playlist_get_active();
00331 if (*entry == -1)
00332 *entry = playlist_get_position(*playlist);
00333 }
00334
00335 static gboolean get_status_cb(void *data)
00336 {
00337 struct StatusRequest *request = data;
00338
00339 g_mutex_lock(info_mutex);
00340
00341 memset (request, 0, sizeof (* request));
00342 request->playing = playback_get_playing();
00343
00344 if (request->playing)
00345 {
00346 request->paused = playback_get_paused ();
00347 request->time = playback_get_time ();
00348 request->length = playback_get_length ();
00349 playback_get_info (& request->bitrate, & request->samplerate,
00350 & request->channels);
00351 }
00352
00353 g_cond_signal(info_cond);
00354 g_mutex_unlock(info_mutex);
00355 return FALSE;
00356 }
00357
00358 static void get_status(struct StatusRequest *request)
00359 {
00360 if (g_thread_self() == main_thread)
00361 get_status_cb(request);
00362 else
00363 {
00364 g_mutex_lock(info_mutex);
00365 g_timeout_add(0, get_status_cb, request);
00366 g_cond_wait(info_cond, info_mutex);
00367 g_mutex_unlock(info_mutex);
00368 }
00369 }
00370
00371 static gboolean get_position_cb(void *data)
00372 {
00373 struct PositionRequest *request = data;
00374
00375 g_mutex_lock(info_mutex);
00376
00377 real_position(&request->playlist, &request->entry);
00378 request->entry_count = playlist_entry_count(request->playlist);
00379 request->queue_count = playlist_queue_count(request->playlist);
00380
00381 g_cond_signal(info_cond);
00382 g_mutex_unlock(info_mutex);
00383 return FALSE;
00384 }
00385
00386 static void get_position(struct PositionRequest *request)
00387 {
00388 if (g_thread_self() == main_thread)
00389 get_position_cb(request);
00390 else
00391 {
00392 g_mutex_lock(info_mutex);
00393 g_timeout_add(0, get_position_cb, request);
00394 g_cond_wait(info_cond, info_mutex);
00395 g_mutex_unlock(info_mutex);
00396 }
00397 }
00398
00399 static gboolean get_info_cb(void *data)
00400 {
00401 struct InfoRequest *request = data;
00402 const gchar *filename, *title, *pltitle;
00403
00404 g_mutex_lock(info_mutex);
00405
00406 real_position(&request->playlist, &request->entry);
00407 filename = playlist_entry_get_filename(request->playlist, request->entry);
00408 request->filename = (filename == NULL) ? NULL : g_strdup(filename);
00409 title = playlist_entry_get_title (request->playlist, request->entry, FALSE);
00410 request->title = (title == NULL) ? NULL : g_strdup(title);
00411 request->length = playlist_entry_get_length (request->playlist,
00412 request->entry, FALSE);
00413 pltitle = playlist_get_title(request->playlist);
00414 request->pltitle = (pltitle == NULL) ? NULL : g_strdup(pltitle);
00415
00416 g_cond_signal(info_cond);
00417 g_mutex_unlock(info_mutex);
00418 return FALSE;
00419 }
00420
00421 static void get_info(struct InfoRequest *request)
00422 {
00423 if (g_thread_self() == main_thread)
00424 get_info_cb(request);
00425 else
00426 {
00427 g_mutex_lock(info_mutex);
00428 g_timeout_add(0, get_info_cb, request);
00429 g_cond_wait(info_cond, info_mutex);
00430 g_mutex_unlock(info_mutex);
00431 }
00432 }
00433
00434 static gboolean get_field_cb(void *data)
00435 {
00436 struct FieldRequest *request = data;
00437 const Tuple *tuple;
00438
00439 g_mutex_lock(info_mutex);
00440
00441 real_position(&request->playlist, &request->entry);
00442 tuple = playlist_entry_get_tuple (request->playlist, request->entry, FALSE);
00443 request->value = (tuple == NULL) ? NULL : tuple_value_to_gvalue(tuple, request->field);
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 const gchar *filename;
00634
00635 g_mutex_lock(info_mutex);
00636
00637 real_position(&request->playlist, &request->entry);
00638 filename = playlist_entry_get_filename(request->playlist, request->entry);
00639
00640 if (filename == NULL)
00641 request->metadata = NULL;
00642 else
00643 request->metadata = make_mpris_metadata (filename,
00644 playlist_entry_get_tuple (request->playlist, request->entry, FALSE));
00645
00646 g_cond_signal(info_cond);
00647 g_mutex_unlock(info_mutex);
00648 return FALSE;
00649 }
00650
00651 static void get_mpris_metadata(struct MprisMetadataRequest *request)
00652 {
00653 if (g_thread_self() == main_thread)
00654 get_mpris_metadata_cb(request);
00655 else
00656 {
00657 g_mutex_lock(info_mutex);
00658 g_timeout_add(0, get_mpris_metadata_cb, request);
00659 g_cond_wait(info_cond, info_mutex);
00660 g_mutex_unlock(info_mutex);
00661 }
00662 }
00663
00664 static gboolean set_shuffle_cb (void * shuffle)
00665 {
00666 cfg.shuffle = GPOINTER_TO_INT (shuffle);
00667 event_queue ("toggle shuffle", NULL);
00668 return FALSE;
00669 }
00670
00671 static gboolean set_repeat_cb (void * repeat)
00672 {
00673 cfg.repeat = GPOINTER_TO_INT (repeat);
00674 event_queue ("toggle repeat", NULL);
00675 return FALSE;
00676 }
00677
00678
00679
00680 gboolean mpris_root_identity(MprisRoot * obj, gchar ** identity, GError ** error)
00681 {
00682 *identity = g_strdup_printf("Audacious %s", VERSION);
00683 return TRUE;
00684 }
00685
00686 gboolean mpris_root_quit(MprisPlayer * obj, GError ** error)
00687 {
00688 event_queue("quit", NULL);
00689 return TRUE;
00690 }
00691
00692
00693
00694 gboolean mpris_player_next(MprisPlayer * obj, GError * *error)
00695 {
00696 g_timeout_add(0, next_cb, NULL);
00697 return TRUE;
00698 }
00699
00700 gboolean mpris_player_prev(MprisPlayer * obj, GError * *error)
00701 {
00702 g_timeout_add(0, prev_cb, NULL);
00703 return TRUE;
00704 }
00705
00706 gboolean mpris_player_pause(MprisPlayer * obj, GError * *error)
00707 {
00708 g_timeout_add(0, pause_cb, NULL);
00709 return TRUE;
00710 }
00711
00712 gboolean mpris_player_stop(MprisPlayer * obj, GError * *error)
00713 {
00714 g_timeout_add(0, stop_cb, NULL);
00715 return TRUE;
00716 }
00717
00718 gboolean mpris_player_play(MprisPlayer * obj, GError * *error)
00719 {
00720 g_timeout_add(0, play_cb, NULL);
00721 return TRUE;
00722 }
00723
00724 gboolean mpris_player_repeat(MprisPlayer * obj, gboolean rpt, GError ** error)
00725 {
00726 fprintf (stderr, "implement me\n");
00727 return TRUE;
00728 }
00729
00730 static void append_int_value(GValueArray * ar, gint tmp)
00731 {
00732 GValue value;
00733 memset(&value, 0, sizeof(value));
00734 g_value_init(&value, G_TYPE_INT);
00735 g_value_set_int(&value, tmp);
00736 g_value_array_append(ar, &value);
00737 }
00738
00739 static gint get_playback_status(void)
00740 {
00741 struct StatusRequest request;
00742 get_status(&request);
00743
00744 return (!request.playing ? MPRIS_STATUS_STOP : request.paused ? MPRIS_STATUS_PAUSE : MPRIS_STATUS_PLAY);
00745 }
00746
00747 gboolean mpris_player_get_status(MprisPlayer * obj, GValueArray * *status, GError * *error)
00748 {
00749 *status = g_value_array_new(4);
00750
00751 append_int_value(*status, (gint) get_playback_status());
00752 append_int_value(*status, (gint) cfg.shuffle);
00753 append_int_value(*status, (gint) cfg.no_playlist_advance);
00754 append_int_value(*status, (gint) cfg.repeat);
00755 return TRUE;
00756 }
00757
00758 gboolean mpris_player_get_metadata(MprisPlayer * obj, GHashTable * *metadata, GError * *error)
00759 {
00760 struct MprisMetadataRequest request = {.playlist = -1,.entry = -1 };
00761
00762 get_mpris_metadata(&request);
00763 *metadata = request.metadata;
00764 return TRUE;
00765 }
00766
00767 gboolean mpris_player_get_caps(MprisPlayer * obj, gint * capabilities, GError ** error)
00768 {
00769 *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;
00770 return TRUE;
00771 }
00772
00773 gboolean mpris_player_volume_set(MprisPlayer * obj, gint vol, GError ** error)
00774 {
00775 gint vl, vr, v;
00776
00777
00778 input_get_volume(&vl, &vr);
00779
00780
00781 vl = CLAMP(vl, 0, 100);
00782 vr = CLAMP(vr, 0, 100);
00783 v = CLAMP(vol, 0, 100);
00784
00785 if (vl > vr)
00786 {
00787 input_set_volume(v, (gint) rint(((gdouble) vr / vl) * v));
00788 }
00789 else if (vl < vr)
00790 {
00791 input_set_volume((gint) rint(((gdouble) vl / vr) * v), v);
00792 }
00793 else
00794 {
00795 input_set_volume(v, v);
00796 }
00797 return TRUE;
00798 }
00799
00800 gboolean mpris_player_volume_get(MprisPlayer * obj, gint * vol, GError ** error)
00801 {
00802 gint vl, vr;
00803 input_get_volume(&vl, &vr);
00804
00805
00806 *vol = MAX(vl, vr);
00807 return TRUE;
00808 }
00809
00810 gboolean mpris_player_position_set(MprisPlayer * obj, gint pos, GError * *error)
00811 {
00812 g_timeout_add(0, seek_cb, GINT_TO_POINTER(pos));
00813 return TRUE;
00814 }
00815
00816 gboolean mpris_player_position_get(MprisPlayer * obj, gint * pos, GError * *error)
00817 {
00818 struct StatusRequest request;
00819
00820 get_status(&request);
00821 *pos = request.time;
00822 return TRUE;
00823 }
00824
00825
00826 gboolean mpris_emit_caps_change(MprisPlayer * obj)
00827 {
00828 g_signal_emit(obj, signals[CAPS_CHANGE_SIG], 0, 0);
00829 return TRUE;
00830 }
00831
00832 gboolean mpris_emit_track_change(MprisPlayer * obj)
00833 {
00834 gint playlist, entry;
00835 const gchar *filename;
00836 GHashTable *metadata;
00837
00838 playlist = playlist_get_playing();
00839 entry = playlist_get_position(playlist);
00840 filename = playlist_entry_get_filename(playlist, entry);
00841
00842 if (filename == NULL)
00843 return FALSE;
00844
00845 metadata = make_mpris_metadata (filename, playlist_entry_get_tuple
00846 (playlist, entry, FALSE));
00847
00848 g_signal_emit(obj, signals[TRACK_CHANGE_SIG], 0, metadata);
00849 g_hash_table_destroy(metadata);
00850 return TRUE;
00851 }
00852
00853 gboolean mpris_emit_status_change(MprisPlayer * obj, PlaybackStatus status)
00854 {
00855 GValueArray *ar = g_value_array_new(4);
00856
00857 if (status < 0) status = get_playback_status();
00858 append_int_value(ar, (gint) status);
00859 append_int_value(ar, (gint) cfg.shuffle);
00860 append_int_value(ar, (gint) cfg.no_playlist_advance);
00861 append_int_value(ar, (gint) cfg.repeat);
00862
00863 g_signal_emit(obj, signals[STATUS_CHANGE_SIG], 0, ar);
00864 g_value_array_free(ar);
00865 return TRUE;
00866 }
00867
00868
00869 gboolean mpris_emit_tracklist_change(MprisTrackList * obj, gint playlist)
00870 {
00871 g_signal_emit(obj, tracklist_signals[TRACKLIST_CHANGE_SIG], 0, playlist_entry_count(playlist));
00872 return TRUE;
00873 }
00874
00875 static void mpris_playlist_update_hook(gpointer unused, MprisTrackList * obj)
00876 {
00877 gint playlist = playlist_get_active();
00878
00879 mpris_emit_tracklist_change(obj, playlist);
00880 }
00881
00882 gboolean mpris_tracklist_get_metadata(MprisTrackList * obj, gint pos, GHashTable * *metadata, GError * *error)
00883 {
00884 struct MprisMetadataRequest request = {.playlist = -1,.entry = pos };
00885
00886 get_mpris_metadata(&request);
00887 *metadata = request.metadata;
00888 return TRUE;
00889 }
00890
00891 gboolean mpris_tracklist_get_current_track(MprisTrackList * obj, gint * pos, GError * *error)
00892 {
00893 struct PositionRequest request = {.playlist = -1,.entry = -1 };
00894
00895 get_position(&request);
00896 *pos = request.entry;
00897 return TRUE;
00898 }
00899
00900 gboolean mpris_tracklist_get_length(MprisTrackList * obj, gint * length, GError * *error)
00901 {
00902 struct PositionRequest request = {.playlist = -1,.entry = -1 };
00903
00904 get_position(&request);
00905 *length = request.entry_count;
00906 return TRUE;
00907 }
00908
00909 gboolean mpris_tracklist_add_track(MprisTrackList * obj, gchar * uri, gboolean play, GError * *error)
00910 {
00911 struct AddRequest *request = g_malloc(sizeof(struct AddRequest));
00912
00913 request->position = -1;
00914 request->filename = g_strdup(uri);
00915 request->play = play;
00916
00917 g_timeout_add(0, add_cb, request);
00918 return TRUE;
00919 }
00920
00921 gboolean mpris_tracklist_del_track(MprisTrackList * obj, gint pos, GError * *error)
00922 {
00923 g_timeout_add(0, delete_cb, GINT_TO_POINTER(pos));
00924 return TRUE;
00925 }
00926
00927 gboolean mpris_tracklist_loop (MprisTrackList * obj, gboolean loop, GError * *
00928 error)
00929 {
00930 g_timeout_add (0, set_repeat_cb, GINT_TO_POINTER (loop));
00931 return TRUE;
00932 }
00933
00934 gboolean mpris_tracklist_random (MprisTrackList * obj, gboolean random,
00935 GError * * error)
00936 {
00937 g_timeout_add (0, set_shuffle_cb, GINT_TO_POINTER (random));
00938 return TRUE;
00939 }
00940
00941
00942 gboolean audacious_rc_version(RemoteObject * obj, gchar ** version, GError ** error)
00943 {
00944 *version = g_strdup(VERSION);
00945 return TRUE;
00946 }
00947
00948 gboolean audacious_rc_quit(RemoteObject * obj, GError * *error)
00949 {
00950 event_queue("quit", NULL);
00951 return TRUE;
00952 }
00953
00954 gboolean audacious_rc_eject(RemoteObject * obj, GError ** error)
00955 {
00956 interface_run_filebrowser (TRUE);
00957 return TRUE;
00958 }
00959
00960 gboolean audacious_rc_main_win_visible(RemoteObject * obj, gboolean * is_main_win, GError ** error)
00961 {
00962 *is_main_win = cfg.player_visible;
00963 return TRUE;
00964 }
00965
00966 gboolean audacious_rc_show_main_win(RemoteObject * obj, gboolean show, GError ** error)
00967 {
00968 interface_toggle_visibility ();
00969 return TRUE;
00970 }
00971
00972 gboolean audacious_rc_equalizer_visible(RemoteObject * obj, gboolean * is_eq_win, GError ** error)
00973 {
00974 *is_eq_win = cfg.equalizer_visible;
00975 return TRUE;
00976 }
00977
00978 gboolean audacious_rc_show_equalizer(RemoteObject * obj, gboolean show, GError ** error)
00979 {
00980 #if 0
00981 drct_eq_win_toggle(show);
00982 #endif
00983 return TRUE;
00984 }
00985
00986 gboolean audacious_rc_playlist_visible(RemoteObject * obj, gboolean * is_pl_win, GError ** error)
00987 {
00988 *is_pl_win = cfg.playlist_visible;
00989 return TRUE;
00990 }
00991
00992 gboolean audacious_rc_show_playlist(RemoteObject * obj, gboolean show, GError ** error)
00993 {
00994 #if 0
00995 drct_pl_win_toggle(show);
00996 #endif
00997 return TRUE;
00998 }
00999
01000 gboolean audacious_rc_get_tuple_fields(RemoteObject * obj, gchar *** fields, GError ** error)
01001 {
01002 gchar **res = g_new0(gchar *, FIELD_LAST + 1);
01003 gint i;
01004 for (i = 0; i < FIELD_LAST; i++)
01005 {
01006 res[i] = g_strdup(tuple_fields[i].name);
01007 }
01008 *fields = res;
01009
01010 return TRUE;
01011 }
01012
01013
01014
01015
01016 gboolean audacious_rc_play(RemoteObject * obj, GError * *error)
01017 {
01018 g_timeout_add(0, play_cb, NULL);
01019 return TRUE;
01020 }
01021
01022 gboolean audacious_rc_pause(RemoteObject * obj, GError * *error)
01023 {
01024 g_timeout_add(0, pause_cb, NULL);
01025 return TRUE;
01026 }
01027
01028 gboolean audacious_rc_stop(RemoteObject * obj, GError * *error)
01029 {
01030 g_timeout_add(0, stop_cb, NULL);
01031 return TRUE;
01032 }
01033
01034 gboolean audacious_rc_playing(RemoteObject * obj, gboolean * is_playing, GError * *error)
01035 {
01036 struct StatusRequest request;
01037
01038 get_status(&request);
01039 *is_playing = request.playing;
01040 return TRUE;
01041 }
01042
01043 gboolean audacious_rc_paused(RemoteObject * obj, gboolean * is_paused, GError * *error)
01044 {
01045 struct StatusRequest request;
01046
01047 get_status(&request);
01048 *is_paused = request.paused;
01049 return TRUE;
01050 }
01051
01052 gboolean audacious_rc_stopped(RemoteObject * obj, gboolean * is_stopped, GError * *error)
01053 {
01054 struct StatusRequest request;
01055
01056 get_status(&request);
01057 *is_stopped = !request.playing;
01058 return TRUE;
01059 }
01060
01061 gboolean audacious_rc_status(RemoteObject * obj, gchar * *status, GError * *error)
01062 {
01063 struct StatusRequest request;
01064
01065 get_status(&request);
01066 *status = g_strdup(!request.playing ? "stopped" : request.paused ? "paused" : "playing");
01067 return TRUE;
01068 }
01069
01070 gboolean audacious_rc_info(RemoteObject * obj, gint * rate, gint * freq, gint * nch, GError * *error)
01071 {
01072 struct StatusRequest request;
01073
01074 get_status(&request);
01075 *rate = request.bitrate;
01076 *freq = request.samplerate;
01077 *nch = request.channels;
01078 return TRUE;
01079 }
01080
01081 gboolean audacious_rc_time(RemoteObject * obj, gint * time, GError * *error)
01082 {
01083 struct StatusRequest request;
01084
01085 get_status(&request);
01086 *time = request.time;
01087 return TRUE;
01088 }
01089
01090 gboolean audacious_rc_seek(RemoteObject * obj, guint pos, GError * *error)
01091 {
01092 g_timeout_add(0, seek_cb, GINT_TO_POINTER(pos));
01093 return TRUE;
01094 }
01095
01096 gboolean audacious_rc_volume(RemoteObject * obj, gint * vl, gint * vr, GError ** error)
01097 {
01098 input_get_volume(vl, vr);
01099 return TRUE;
01100 }
01101
01102 gboolean audacious_rc_set_volume(RemoteObject * obj, gint vl, gint vr, GError ** error)
01103 {
01104 if (vl > 100)
01105 vl = 100;
01106 if (vr > 100)
01107 vr = 100;
01108 input_set_volume(vl, vr);
01109 return TRUE;
01110 }
01111
01112 gboolean audacious_rc_balance(RemoteObject * obj, gint * balance, GError ** error)
01113 {
01114 gint vl, vr;
01115 input_get_volume(&vl, &vr);
01116 if (vl < 0 || vr < 0)
01117 *balance = 0;
01118 else if (vl > vr)
01119 *balance = -100 + ((vr * 100) / vl);
01120 else if (vr > vl)
01121 *balance = 100 - ((vl * 100) / vr);
01122 else
01123 *balance = 0;
01124 return TRUE;
01125 }
01126
01127
01128
01129 gboolean audacious_rc_position(RemoteObject * obj, gint * pos, GError * *error)
01130 {
01131 struct PositionRequest request = {.playlist = -1,.entry = -1 };
01132
01133 get_position(&request);
01134 *pos = request.entry;
01135 return TRUE;
01136 }
01137
01138 gboolean audacious_rc_advance(RemoteObject * obj, GError * *error)
01139 {
01140 g_timeout_add(0, next_cb, NULL);
01141 return TRUE;
01142 }
01143
01144 gboolean audacious_rc_reverse(RemoteObject * obj, GError * *error)
01145 {
01146 g_timeout_add(0, prev_cb, NULL);
01147 return TRUE;
01148 }
01149
01150 gboolean audacious_rc_length(RemoteObject * obj, gint * length, GError * *error)
01151 {
01152 struct PositionRequest request = {.playlist = -1,.entry = -1 };
01153
01154 get_position(&request);
01155 *length = request.entry_count;
01156 return TRUE;
01157 }
01158
01159 gboolean audacious_rc_song_title(RemoteObject * obj, guint pos, gchar * *title, GError * *error)
01160 {
01161 struct InfoRequest request = {.playlist = -1,.entry = pos };
01162
01163 get_info(&request);
01164 g_free(request.filename);
01165 g_free(request.pltitle);
01166 *title = request.title;
01167 return TRUE;
01168 }
01169
01170 gboolean audacious_rc_song_filename(RemoteObject * obj, guint pos, gchar * *filename, GError * *error)
01171 {
01172 struct InfoRequest request = {.playlist = -1,.entry = pos };
01173
01174 get_info(&request);
01175 *filename = request.filename;
01176 g_free(request.title);
01177 g_free(request.pltitle);
01178 return TRUE;
01179 }
01180
01181 gboolean audacious_rc_song_length(RemoteObject * obj, guint pos, gint * length, GError * *error)
01182 {
01183 audacious_rc_song_frames(obj, pos, length, error);
01184 *length /= 1000;
01185 return TRUE;
01186 }
01187
01188 gboolean audacious_rc_song_frames(RemoteObject * obj, guint pos, gint * length, GError * *error)
01189 {
01190 struct InfoRequest request = {.playlist = -1,.entry = pos };
01191
01192 get_info(&request);
01193 g_free(request.filename);
01194 g_free(request.title);
01195 g_free(request.pltitle);
01196 *length = request.length;
01197 return TRUE;
01198 }
01199
01200 gboolean audacious_rc_song_tuple(RemoteObject * obj, guint pos, gchar * field, GValue * value, GError * *error)
01201 {
01202 struct FieldRequest request = {.playlist = -1,.entry = pos,.field = field };
01203
01204 get_field(&request);
01205
01206 if (request.value == NULL)
01207 return FALSE;
01208
01209 memset(value, 0, sizeof(GValue));
01210 g_value_init(value, G_VALUE_TYPE(request.value));
01211 g_value_copy(request.value, value);
01212 g_value_unset(request.value);
01213 g_free(request.value);
01214 return TRUE;
01215 }
01216
01217 gboolean audacious_rc_jump(RemoteObject * obj, guint pos, GError * *error)
01218 {
01219 g_timeout_add(0, jump_cb, GINT_TO_POINTER(pos));
01220 return TRUE;
01221 }
01222
01223 gboolean audacious_rc_add(RemoteObject * obj, gchar * file, GError * *error)
01224 {
01225 return audacious_rc_playlist_ins_url_string(obj, file, -1, error);
01226 }
01227
01228 gboolean audacious_rc_add_url(RemoteObject * obj, gchar * file, GError * *error)
01229 {
01230 return audacious_rc_playlist_ins_url_string(obj, file, -1, error);
01231 }
01232
01233 static GList * string_array_to_list (gchar * * strings)
01234 {
01235 GList * list = NULL;
01236
01237 while (* strings != NULL)
01238 list = g_list_prepend (list, * strings ++);
01239
01240 return g_list_reverse (list);
01241 }
01242
01243 gboolean audacious_rc_add_list (RemoteObject * obj, gchar * * filenames,
01244 GError * * error)
01245 {
01246 GList * list = string_array_to_list (filenames);
01247
01248 drct_pl_add_list (list, -1);
01249 g_list_free (list);
01250 return TRUE;
01251 }
01252
01253 gboolean audacious_rc_open_list (RemoteObject * obj, gchar * * filenames,
01254 GError * * error)
01255 {
01256 GList * list = string_array_to_list (filenames);
01257
01258 drct_pl_open_list (list);
01259 g_list_free (list);
01260 return TRUE;
01261 }
01262
01263 gboolean audacious_rc_open_list_to_temp (RemoteObject * obj, gchar * *
01264 filenames, GError * * error)
01265 {
01266 GList * list = string_array_to_list (filenames);
01267
01268 drct_pl_open_temp_list (list);
01269 g_list_free (list);
01270 return TRUE;
01271 }
01272
01273 gboolean audacious_rc_delete(RemoteObject * obj, guint pos, GError * *error)
01274 {
01275 g_timeout_add(0, delete_cb, GINT_TO_POINTER(pos));
01276 return TRUE;
01277 }
01278
01279 gboolean audacious_rc_clear(RemoteObject * obj, GError * *error)
01280 {
01281 g_timeout_add(0, clear_cb, NULL);
01282 return TRUE;
01283 }
01284
01285 gboolean audacious_rc_auto_advance(RemoteObject * obj, gboolean * is_advance, GError ** error)
01286 {
01287 *is_advance = !cfg.no_playlist_advance;
01288 return TRUE;
01289 }
01290
01291 gboolean audacious_rc_toggle_auto_advance(RemoteObject * obj, GError ** error)
01292 {
01293 cfg.no_playlist_advance = !cfg.no_playlist_advance;
01294 return TRUE;
01295 }
01296
01297 gboolean audacious_rc_repeat(RemoteObject * obj, gboolean * is_repeating, GError ** error)
01298 {
01299 *is_repeating = cfg.repeat;
01300 return TRUE;
01301 }
01302
01303 gboolean audacious_rc_toggle_repeat (RemoteObject * obj, GError * * error)
01304 {
01305 g_timeout_add (0, set_repeat_cb, GINT_TO_POINTER (! cfg.repeat));
01306 return TRUE;
01307 }
01308
01309 gboolean audacious_rc_shuffle(RemoteObject * obj, gboolean * is_shuffling, GError ** error)
01310 {
01311 *is_shuffling = cfg.shuffle;
01312 return TRUE;
01313 }
01314
01315 gboolean audacious_rc_toggle_shuffle (RemoteObject * obj, GError * * error)
01316 {
01317 g_timeout_add (0, set_shuffle_cb, GINT_TO_POINTER (! cfg.shuffle));
01318 return TRUE;
01319 }
01320
01321
01322 gboolean audacious_rc_show_prefs_box(RemoteObject * obj, gboolean show, GError ** error)
01323 {
01324 event_queue("prefswin show", GINT_TO_POINTER(show));
01325 return TRUE;
01326 }
01327
01328 gboolean audacious_rc_show_about_box(RemoteObject * obj, gboolean show, GError ** error)
01329 {
01330 event_queue("aboutwin show", GINT_TO_POINTER(show));
01331 return TRUE;
01332 }
01333
01334 gboolean audacious_rc_show_jtf_box(RemoteObject * obj, gboolean show, GError ** error)
01335 {
01336 if (show)
01337 event_queue("interface show jump to track", NULL);
01338 else
01339 event_queue("interface hide jump to track", NULL);
01340 return TRUE;
01341 }
01342
01343 gboolean audacious_rc_show_filebrowser(RemoteObject * obj, gboolean show, GError ** error)
01344 {
01345 if (show)
01346 event_queue("filebrowser show", GINT_TO_POINTER(FALSE));
01347 else
01348 event_queue("filebrowser hide", NULL);
01349 return TRUE;
01350 }
01351
01352 gboolean audacious_rc_play_pause(RemoteObject * obj, GError * *error)
01353 {
01354 g_timeout_add(0, play_pause_cb, NULL);
01355 return TRUE;
01356 }
01357
01358 gboolean audacious_rc_activate(RemoteObject * obj, GError ** error)
01359 {
01360 fprintf (stderr, "implement me\n");
01361 return TRUE;
01362 }
01363
01364 gboolean audacious_rc_get_info(RemoteObject * obj, gint * rate, gint * freq, gint * nch, GError * *error)
01365 {
01366 struct StatusRequest request;
01367
01368 get_status(&request);
01369 *rate = request.bitrate;
01370 *freq = request.samplerate;
01371 *nch = request.channels;
01372 return TRUE;
01373 }
01374
01375 gboolean audacious_rc_toggle_aot(RemoteObject * obj, gboolean ontop, GError ** error)
01376 {
01377 hook_call("mainwin set always on top", &ontop);
01378 return TRUE;
01379 }
01380
01381 gboolean audacious_rc_playqueue_add(RemoteObject * obj, gint pos, GError * *error)
01382 {
01383 g_timeout_add(0, add_to_queue_cb, GINT_TO_POINTER(pos));
01384 return TRUE;
01385 }
01386
01387 gboolean audacious_rc_playqueue_remove(RemoteObject * obj, gint pos, GError * *error)
01388 {
01389 g_timeout_add(0, remove_from_queue_cb, GINT_TO_POINTER(pos));
01390 return TRUE;
01391 }
01392
01393 gboolean audacious_rc_playqueue_clear(RemoteObject * obj, GError * *error)
01394 {
01395 g_timeout_add(0, clear_queue_cb, NULL);
01396 return TRUE;
01397 }
01398
01399 gboolean audacious_rc_get_playqueue_length(RemoteObject * obj, gint * length, GError * *error)
01400 {
01401 struct PositionRequest request = {.playlist = -1,.entry = -1 };
01402
01403 get_position(&request);
01404 *length = request.queue_count;
01405 return TRUE;
01406 }
01407
01408 gboolean audacious_rc_queue_get_list_pos(RemoteObject * obj, gint qpos, gint * pos, GError * *error)
01409 {
01410 *pos = queue_get_entry(qpos);
01411 return TRUE;
01412 }
01413
01414 gboolean audacious_rc_queue_get_queue_pos(RemoteObject * obj, gint pos, gint * qpos, GError * *error)
01415 {
01416 *qpos = queue_find_entry(pos);
01417 return TRUE;
01418 }
01419
01420 gboolean audacious_rc_playqueue_is_queued(RemoteObject * obj, gint pos, gboolean * is_queued, GError * *error)
01421 {
01422 *is_queued = (queue_find_entry(pos) != -1);
01423 return TRUE;
01424 }
01425
01426 gboolean audacious_rc_playlist_ins_url_string(RemoteObject * obj, gchar * url, gint pos, GError * *error)
01427 {
01428 struct AddRequest *request = g_malloc(sizeof(struct AddRequest));
01429
01430 request->position = pos;
01431 request->filename = g_strdup(url);
01432 request->play = FALSE;
01433
01434 g_timeout_add(0, add_cb, request);
01435 return TRUE;
01436 }
01437
01438 gboolean audacious_rc_playlist_add(RemoteObject * obj, void *list, GError * *error)
01439 {
01440 return audacious_rc_playlist_ins_url_string(obj, list, -1, error);
01441 }
01442
01443 gboolean audacious_rc_playlist_enqueue_to_temp(RemoteObject * obj, gchar * url, GError * *error)
01444 {
01445 g_timeout_add(0, add_to_new_playlist_cb, g_strdup(url));
01446 return TRUE;
01447 }
01448
01449
01450 gboolean audacious_rc_get_eq(RemoteObject * obj, gdouble * preamp, GArray ** bands, GError ** error)
01451 {
01452 int i;
01453
01454 * preamp = cfg.equalizer_preamp;
01455 *bands = g_array_sized_new(FALSE, FALSE, sizeof(gdouble), AUD_EQUALIZER_NBANDS);
01456
01457 for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
01458 g_array_append_val (* bands, cfg.equalizer_bands[i]);
01459
01460 return TRUE;
01461 }
01462
01463 gboolean audacious_rc_get_eq_preamp(RemoteObject * obj, gdouble * preamp, GError ** error)
01464 {
01465 * preamp = cfg.equalizer_preamp;
01466 return TRUE;
01467 }
01468
01469 gboolean audacious_rc_get_eq_band(RemoteObject * obj, gint band, gdouble * value, GError ** error)
01470 {
01471 * value = cfg.equalizer_bands[band];
01472 return TRUE;
01473 }
01474
01475 gboolean audacious_rc_set_eq(RemoteObject * obj, gdouble preamp, GArray * bands, GError ** error)
01476 {
01477 int i;
01478
01479 cfg.equalizer_preamp = preamp;
01480
01481 for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
01482 cfg.equalizer_bands[i] = g_array_index (bands, gdouble, i);
01483
01484 hook_call ("equalizer changed", NULL);
01485 return TRUE;
01486 }
01487
01488 gboolean audacious_rc_set_eq_preamp(RemoteObject * obj, gdouble preamp, GError ** error)
01489 {
01490 cfg.equalizer_preamp = preamp;
01491 hook_call ("equalizer changed", NULL);
01492 return TRUE;
01493 }
01494
01495 gboolean audacious_rc_set_eq_band(RemoteObject * obj, gint band, gdouble value, GError ** error)
01496 {
01497 cfg.equalizer_bands[band] = value;
01498 hook_call ("equalizer changed", NULL);
01499 return TRUE;
01500 }
01501
01502 gboolean audacious_rc_equalizer_activate(RemoteObject * obj, gboolean active, GError ** error)
01503 {
01504 cfg.equalizer_active = active;
01505 hook_call ("equalizer changed", NULL);
01506 return TRUE;
01507 }
01508
01509 gboolean audacious_rc_get_active_playlist_name(RemoteObject * obj, gchar * *title, GError * *error)
01510 {
01511 struct InfoRequest request = {.playlist = -2 };
01512
01513 get_info(&request);
01514 g_free(request.title);
01515 g_free(request.filename);
01516 *title = request.pltitle;
01517 return TRUE;
01518 }
01519
01520 DBusGProxy *audacious_get_dbus_proxy(void)
01521 {
01522 DBusGConnection *connection = NULL;
01523 GError *error = NULL;
01524 connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
01525 g_clear_error(&error);
01526 return dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE, AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE);
01527 }