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 <string.h>
00026
00027 #include <dbus/dbus.h>
00028 #include <dbus/dbus-glib.h>
00029 #include <dbus/dbus-glib-bindings.h>
00030 #include <dbus/dbus-glib-lowlevel.h>
00031 #include "dbus.h"
00032 #include "dbus-service.h"
00033 #include "dbus-server-bindings.h"
00034
00035 #include <math.h>
00036
00037 #include <libaudcore/hook.h>
00038
00039 #include "debug.h"
00040 #include "drct.h"
00041 #include "playlist.h"
00042 #include "interface.h"
00043 #include "misc.h"
00044
00045 static DBusGConnection *dbus_conn = NULL;
00046 static unsigned int signals[LAST_SIG] = { 0 };
00047 static unsigned int tracklist_signals[LAST_TRACKLIST_SIG] = { 0 };
00048
00049 MprisPlayer * mpris = NULL;
00050 MprisTrackList * mpris_tracklist = NULL;
00051
00052 G_DEFINE_TYPE (RemoteObject, audacious_rc, G_TYPE_OBJECT)
00053 G_DEFINE_TYPE (MprisRoot, mpris_root, G_TYPE_OBJECT)
00054 G_DEFINE_TYPE (MprisPlayer, mpris_player, G_TYPE_OBJECT)
00055 G_DEFINE_TYPE (MprisTrackList, mpris_tracklist, G_TYPE_OBJECT)
00056
00057 #define DBUS_TYPE_G_STRING_VALUE_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
00058
00059 static void mpris_playlist_update_hook(gpointer unused, MprisTrackList *obj);
00060
00061 void audacious_rc_class_init(RemoteObjectClass * klass)
00062 {
00063 }
00064
00065 void mpris_root_class_init(MprisRootClass * klass)
00066 {
00067 }
00068
00069 void mpris_player_class_init(MprisPlayerClass * klass)
00070 {
00071 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);
00072 signals[TRACK_CHANGE_SIG] =
00073 g_signal_new("track_change",
00074 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);
00075
00076 GType status_type = dbus_g_type_get_struct ("GValueArray", G_TYPE_INT,
00077 G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
00078 signals[STATUS_CHANGE_SIG] =
00079 g_signal_new ("status_change", G_OBJECT_CLASS_TYPE (klass),
00080 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL,
00081 g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, status_type);
00082 }
00083
00084 void mpris_tracklist_class_init(MprisTrackListClass * klass)
00085 {
00086 tracklist_signals[TRACKLIST_CHANGE_SIG] = g_signal_new("track_list_change", G_OBJECT_CLASS_TYPE(klass),
00087 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
00088 }
00089
00090 void audacious_rc_init(RemoteObject * object)
00091 {
00092 GError *error = NULL;
00093 DBusGProxy *driver_proxy;
00094 unsigned int request_ret;
00095
00096 AUDDBG ("Registering remote D-Bus interfaces.\n");
00097
00098 dbus_g_object_type_install_info(audacious_rc_get_type(), &dbus_glib_audacious_rc_object_info);
00099
00100
00101 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH, G_OBJECT(object));
00102
00103
00104
00105 driver_proxy = dbus_g_proxy_new_for_name(dbus_conn, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
00106
00107 if (!org_freedesktop_DBus_request_name(driver_proxy, AUDACIOUS_DBUS_SERVICE, 0, &request_ret, &error))
00108 {
00109 g_warning("Unable to register service: %s", error->message);
00110 g_error_free(error);
00111 }
00112
00113 if (!org_freedesktop_DBus_request_name(driver_proxy, AUDACIOUS_DBUS_SERVICE_MPRIS, 0, &request_ret, &error))
00114 {
00115 g_warning("Unable to register service: %s", error->message);
00116 g_error_free(error);
00117 }
00118
00119 g_object_unref(driver_proxy);
00120 }
00121
00122 void mpris_root_init(MprisRoot * object)
00123 {
00124 dbus_g_object_type_install_info(mpris_root_get_type(), &dbus_glib_mpris_root_object_info);
00125
00126
00127 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH_MPRIS_ROOT, G_OBJECT(object));
00128 }
00129
00130 void mpris_player_init(MprisPlayer * object)
00131 {
00132 dbus_g_object_type_install_info(mpris_player_get_type(), &dbus_glib_mpris_player_object_info);
00133
00134
00135 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH_MPRIS_PLAYER, G_OBJECT(object));
00136
00137
00138 DBusGProxy *proxy = object->proxy;
00139 if (proxy != NULL)
00140 {
00141 dbus_g_proxy_add_signal (proxy, "StatusChange", dbus_g_type_get_struct
00142 ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
00143 G_TYPE_INVALID), G_TYPE_INVALID);
00144 dbus_g_proxy_add_signal (proxy, "CapsChange", G_TYPE_INT, G_TYPE_INVALID);
00145 dbus_g_proxy_add_signal(proxy, "TrackChange", DBUS_TYPE_G_STRING_VALUE_HASHTABLE, G_TYPE_INVALID);
00146 }
00147 else
00148 {
00149
00150 AUDDBG ("object->proxy == NULL; not adding some signals.\n");
00151 }
00152 }
00153
00154 void mpris_tracklist_init(MprisTrackList * object)
00155 {
00156 dbus_g_object_type_install_info(mpris_tracklist_get_type(), &dbus_glib_mpris_tracklist_object_info);
00157
00158
00159 dbus_g_connection_register_g_object(dbus_conn, AUDACIOUS_DBUS_PATH_MPRIS_TRACKLIST, G_OBJECT(object));
00160
00161
00162 DBusGProxy *proxy = object->proxy;
00163 if (proxy != NULL)
00164 {
00165 dbus_g_proxy_add_signal(proxy, "TrackListChange", G_TYPE_INT, G_TYPE_INVALID);
00166 }
00167 else
00168 {
00169
00170 AUDDBG ("object->proxy == NULL, not adding some signals.\n");
00171 }
00172 }
00173
00174 void init_dbus()
00175 {
00176 GError *error = NULL;
00177 DBusConnection *local_conn;
00178
00179 AUDDBG ("Trying to initialize D-Bus.\n");
00180 dbus_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
00181 if (dbus_conn == NULL)
00182 {
00183 g_warning("Unable to connect to dbus: %s", error->message);
00184 g_error_free(error);
00185 return;
00186 }
00187
00188 g_type_init();
00189 g_object_new(audacious_rc_get_type(), NULL);
00190 g_object_new(mpris_root_get_type(), NULL);
00191 mpris = g_object_new(mpris_player_get_type(), NULL);
00192 mpris_tracklist = g_object_new(mpris_tracklist_get_type(), NULL);
00193
00194 local_conn = dbus_g_connection_get_connection(dbus_conn);
00195 dbus_connection_set_exit_on_disconnect(local_conn, FALSE);
00196
00197 hook_associate ("playlist update",
00198 (HookFunction) mpris_playlist_update_hook, mpris_tracklist);
00199 }
00200
00201 void cleanup_dbus (void)
00202 {
00203 hook_dissociate ("playlist update", (HookFunction) mpris_playlist_update_hook);
00204 }
00205
00206 static GValue *tuple_value_to_gvalue(const Tuple * tuple, const char * key)
00207 {
00208 GValue *val;
00209 TupleValueType type = tuple_get_value_type (tuple, -1, key);
00210
00211 if (type == TUPLE_STRING)
00212 {
00213 val = g_new0(GValue, 1);
00214 g_value_init(val, G_TYPE_STRING);
00215 char * str = tuple_get_str (tuple, -1, key);
00216 g_value_set_string (val, str);
00217 str_unref (str);
00218 return val;
00219 }
00220 else if (type == TUPLE_INT)
00221 {
00222 val = g_new0(GValue, 1);
00223 g_value_init(val, G_TYPE_INT);
00224 int x = tuple_get_int (tuple, -1, key);
00225 g_value_set_int (val, x);
00226 return val;
00227 }
00228 return NULL;
00229 }
00230
00239 static void tuple_insert_to_hash_full(GHashTable * md, const Tuple * tuple,
00240 const char * tuple_key, const char *key)
00241 {
00242 GValue *value = tuple_value_to_gvalue(tuple, tuple_key);
00243 if (value != NULL)
00244 g_hash_table_insert (md, (void *) key, value);
00245 }
00246
00247 static void tuple_insert_to_hash(GHashTable * md, const Tuple * tuple,
00248 const char *key)
00249 {
00250 tuple_insert_to_hash_full(md, tuple, key, key);
00251 }
00252
00253 static void remove_metadata_value(gpointer value)
00254 {
00255 g_value_unset((GValue *) value);
00256 g_free((GValue *) value);
00257 }
00258
00259 static GHashTable *make_mpris_metadata(const char * filename, const Tuple * tuple)
00260 {
00261 GHashTable *md = NULL;
00262 gpointer value;
00263
00264 md = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, remove_metadata_value);
00265
00266 value = g_malloc(sizeof(GValue));
00267 memset(value, 0, sizeof(GValue));
00268 g_value_init(value, G_TYPE_STRING);
00269 g_value_take_string(value, g_strdup(filename));
00270 g_hash_table_insert(md, "location", value);
00271
00272 if (tuple != NULL)
00273 {
00274 tuple_insert_to_hash_full(md, tuple, "length", "mtime");
00275 tuple_insert_to_hash(md, tuple, "title");
00276 tuple_insert_to_hash(md, tuple, "artist");
00277 tuple_insert_to_hash(md, tuple, "album");
00278 tuple_insert_to_hash(md, tuple, "comment");
00279 tuple_insert_to_hash(md, tuple, "genre");
00280 tuple_insert_to_hash(md, tuple, "year");
00281 tuple_insert_to_hash(md, tuple, "codec");
00282 tuple_insert_to_hash(md, tuple, "quality");
00283 tuple_insert_to_hash_full(md, tuple, "track-number", "tracknumber");
00284 tuple_insert_to_hash_full(md, tuple, "bitrate", "audio-bitrate");
00285 }
00286
00287 return md;
00288 }
00289
00290 static GValue * get_field (int playlist, int entry, const char * field)
00291 {
00292 Tuple * tuple = playlist_entry_get_tuple (playlist, entry, FALSE);
00293 GValue * value = tuple ? tuple_value_to_gvalue (tuple, field) : NULL;
00294
00295 if (tuple)
00296 tuple_unref (tuple);
00297
00298 return value;
00299 }
00300
00301 static GHashTable * get_mpris_metadata (int playlist, int entry)
00302 {
00303 char * filename = playlist_entry_get_filename (playlist, entry);
00304 Tuple * tuple = playlist_entry_get_tuple (playlist, entry, FALSE);
00305
00306 GHashTable * metadata = NULL;
00307 if (filename && tuple)
00308 metadata = make_mpris_metadata (filename, tuple);
00309
00310 str_unref (filename);
00311 if (tuple)
00312 tuple_unref (tuple);
00313
00314 return metadata;
00315 }
00316
00317
00318
00319 bool_t mpris_root_identity(MprisRoot * obj, char ** identity, GError ** error)
00320 {
00321 *identity = g_strdup_printf("Audacious %s", VERSION);
00322 return TRUE;
00323 }
00324
00325 bool_t mpris_root_quit(MprisPlayer * obj, GError ** error)
00326 {
00327 event_queue("quit", NULL);
00328 return TRUE;
00329 }
00330
00331
00332
00333 bool_t mpris_player_next (MprisPlayer * obj, GError * * error)
00334 {
00335 drct_pl_next ();
00336 return TRUE;
00337 }
00338
00339 bool_t mpris_player_prev (MprisPlayer * obj, GError * * error)
00340 {
00341 drct_pl_prev ();
00342 return TRUE;
00343 }
00344
00345 bool_t mpris_player_pause (MprisPlayer * obj, GError * * error)
00346 {
00347 drct_pause ();
00348 return TRUE;
00349 }
00350
00351 bool_t mpris_player_stop (MprisPlayer * obj, GError * * error)
00352 {
00353 drct_stop ();
00354 return TRUE;
00355 }
00356
00357 bool_t mpris_player_play (MprisPlayer * obj, GError * * error)
00358 {
00359 drct_play ();
00360 return TRUE;
00361 }
00362
00363 bool_t mpris_player_repeat(MprisPlayer * obj, bool_t rpt, GError ** error)
00364 {
00365 fprintf (stderr, "implement me\n");
00366 return TRUE;
00367 }
00368
00369 static void append_int_value(GValueArray * ar, int tmp)
00370 {
00371 GValue value;
00372 memset(&value, 0, sizeof(value));
00373 g_value_init(&value, G_TYPE_INT);
00374 g_value_set_int(&value, tmp);
00375 g_value_array_append(ar, &value);
00376 }
00377
00378 static int get_playback_status (void)
00379 {
00380 if (! drct_get_playing ())
00381 return MPRIS_STATUS_STOP;
00382
00383 return drct_get_paused () ? MPRIS_STATUS_PAUSE : MPRIS_STATUS_PLAY;
00384 }
00385
00386 bool_t mpris_player_get_status(MprisPlayer * obj, GValueArray * *status, GError * *error)
00387 {
00388 *status = g_value_array_new(4);
00389
00390 append_int_value(*status, (int) get_playback_status());
00391 append_int_value (* status, get_bool (NULL, "shuffle"));
00392 append_int_value (* status, get_bool (NULL, "no_playlist_advance"));
00393 append_int_value (* status, get_bool (NULL, "repeat"));
00394 return TRUE;
00395 }
00396
00397 bool_t mpris_player_get_metadata (MprisPlayer * obj, GHashTable * * metadata,
00398 GError * * error)
00399 {
00400 int playlist = playlist_get_playing ();
00401 int entry = (playlist >= 0) ? playlist_get_position (playlist) : -1;
00402
00403 * metadata = (entry >= 0) ? get_mpris_metadata (playlist, entry) : NULL;
00404 if (! * metadata)
00405 * metadata = g_hash_table_new (g_str_hash, g_str_equal);
00406
00407 return TRUE;
00408 }
00409
00410 bool_t mpris_player_get_caps(MprisPlayer * obj, int * capabilities, GError ** error)
00411 {
00412 *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;
00413 return TRUE;
00414 }
00415
00416 bool_t mpris_player_volume_set(MprisPlayer * obj, int vol, GError ** error)
00417 {
00418 drct_set_volume_main (vol);
00419 return TRUE;
00420 }
00421
00422 bool_t mpris_player_volume_get(MprisPlayer * obj, int * vol, GError ** error)
00423 {
00424 drct_get_volume_main (vol);
00425 return TRUE;
00426 }
00427
00428 bool_t mpris_player_position_set (MprisPlayer * obj, int pos, GError * * error)
00429 {
00430 drct_seek (pos);
00431 return TRUE;
00432 }
00433
00434 bool_t mpris_player_position_get (MprisPlayer * obj, int * pos, GError * * error)
00435 {
00436 * pos = drct_get_time ();
00437 return TRUE;
00438 }
00439
00440
00441 bool_t mpris_emit_caps_change(MprisPlayer * obj)
00442 {
00443 g_signal_emit(obj, signals[CAPS_CHANGE_SIG], 0, 0);
00444 return TRUE;
00445 }
00446
00447 bool_t mpris_emit_track_change(MprisPlayer * obj)
00448 {
00449 int playlist, entry;
00450 GHashTable *metadata;
00451
00452 playlist = playlist_get_playing();
00453 entry = playlist_get_position(playlist);
00454 char * filename = playlist_entry_get_filename (playlist, entry);
00455 Tuple * tuple = playlist_entry_get_tuple (playlist, entry, FALSE);
00456
00457 if (filename && tuple)
00458 {
00459 metadata = make_mpris_metadata (filename, tuple);
00460 g_signal_emit (obj, signals[TRACK_CHANGE_SIG], 0, metadata);
00461 g_hash_table_destroy (metadata);
00462 }
00463
00464 str_unref (filename);
00465 if (tuple)
00466 tuple_unref (tuple);
00467
00468 return (filename && tuple);
00469 }
00470
00471 bool_t mpris_emit_status_change(MprisPlayer * obj, PlaybackStatus status)
00472 {
00473 GValueArray *ar = g_value_array_new(4);
00474
00475 if (status == MPRIS_STATUS_INVALID)
00476 status = get_playback_status ();
00477
00478 append_int_value(ar, (int) status);
00479 append_int_value (ar, get_bool (NULL, "shuffle"));
00480 append_int_value (ar, get_bool (NULL, "no_playlist_advance"));
00481 append_int_value (ar, get_bool (NULL, "repeat"));
00482
00483 g_signal_emit(obj, signals[STATUS_CHANGE_SIG], 0, ar);
00484 g_value_array_free(ar);
00485 return TRUE;
00486 }
00487
00488
00489 bool_t mpris_emit_tracklist_change(MprisTrackList * obj, int playlist)
00490 {
00491 g_signal_emit(obj, tracklist_signals[TRACKLIST_CHANGE_SIG], 0, playlist_entry_count(playlist));
00492 return TRUE;
00493 }
00494
00495 static void mpris_playlist_update_hook(gpointer unused, MprisTrackList * obj)
00496 {
00497 int playlist = playlist_get_active();
00498
00499 mpris_emit_tracklist_change(obj, playlist);
00500 }
00501
00502 bool_t mpris_tracklist_get_metadata (MprisTrackList * obj, int pos,
00503 GHashTable * * metadata, GError * * error)
00504 {
00505 * metadata = get_mpris_metadata (playlist_get_active (), pos);
00506 if (! * metadata)
00507 * metadata = g_hash_table_new (g_str_hash, g_str_equal);
00508
00509 return TRUE;
00510 }
00511
00512 bool_t mpris_tracklist_get_current_track (MprisTrackList * obj, int * pos,
00513 GError * * error)
00514 {
00515 * pos = playlist_get_position (playlist_get_active ());
00516 return TRUE;
00517 }
00518
00519 bool_t mpris_tracklist_get_length (MprisTrackList * obj, int * length, GError * * error)
00520 {
00521 * length = playlist_entry_count (playlist_get_active ());
00522 return TRUE;
00523 }
00524
00525 bool_t mpris_tracklist_add_track (MprisTrackList * obj, char * uri, bool_t play,
00526 GError * * error)
00527 {
00528 playlist_entry_insert (playlist_get_active (), -1, uri, NULL, play);
00529 return TRUE;
00530 }
00531
00532 bool_t mpris_tracklist_del_track (MprisTrackList * obj, int pos, GError * * error)
00533 {
00534 playlist_entry_delete (playlist_get_active (), pos, 1);
00535 return TRUE;
00536 }
00537
00538 bool_t mpris_tracklist_loop (MprisTrackList * obj, bool_t loop, GError * *
00539 error)
00540 {
00541 set_bool (NULL, "repeat", loop);
00542 return TRUE;
00543 }
00544
00545 bool_t mpris_tracklist_random (MprisTrackList * obj, bool_t random,
00546 GError * * error)
00547 {
00548 set_bool (NULL, "shuffle", random);
00549 return TRUE;
00550 }
00551
00552
00553 bool_t audacious_rc_version(RemoteObject * obj, char ** version, GError ** error)
00554 {
00555 *version = g_strdup(VERSION);
00556 return TRUE;
00557 }
00558
00559 bool_t audacious_rc_quit(RemoteObject * obj, GError * *error)
00560 {
00561 event_queue("quit", NULL);
00562 return TRUE;
00563 }
00564
00565 bool_t audacious_rc_eject(RemoteObject * obj, GError ** error)
00566 {
00567 interface_show_filebrowser (TRUE);
00568 return TRUE;
00569 }
00570
00571 bool_t audacious_rc_main_win_visible (RemoteObject * obj,
00572 bool_t * visible, GError ** error)
00573 {
00574 * visible = interface_is_shown ();
00575 return TRUE;
00576 }
00577
00578 bool_t audacious_rc_show_main_win (RemoteObject * obj, bool_t show,
00579 GError * * error)
00580 {
00581 interface_show (show);
00582 return TRUE;
00583 }
00584
00585 bool_t audacious_rc_get_tuple_fields(RemoteObject * obj, char *** fields, GError ** error)
00586 {
00587 * fields = g_new (char *, TUPLE_FIELDS);
00588
00589 for (int i = 0; i < TUPLE_FIELDS; i ++)
00590 (* fields)[i] = g_strdup (tuple_field_get_name (i));
00591
00592 (* fields)[TUPLE_FIELDS] = NULL;
00593 return TRUE;
00594 }
00595
00596
00597
00598
00599 bool_t audacious_rc_play (RemoteObject * obj, GError * * error)
00600 {
00601 drct_play ();
00602 return TRUE;
00603 }
00604
00605 bool_t audacious_rc_pause (RemoteObject * obj, GError * * error)
00606 {
00607 drct_pause ();
00608 return TRUE;
00609 }
00610
00611 bool_t audacious_rc_stop (RemoteObject * obj, GError * * error)
00612 {
00613 drct_stop ();
00614 return TRUE;
00615 }
00616
00617 bool_t audacious_rc_playing (RemoteObject * obj, bool_t * is_playing, GError * * error)
00618 {
00619 * is_playing = drct_get_playing ();
00620 return TRUE;
00621 }
00622
00623 bool_t audacious_rc_paused (RemoteObject * obj, bool_t * is_paused, GError * * error)
00624 {
00625 * is_paused = drct_get_paused ();
00626 return TRUE;
00627 }
00628
00629 bool_t audacious_rc_stopped (RemoteObject * obj, bool_t * is_stopped, GError * * error)
00630 {
00631 * is_stopped = ! drct_get_playing ();
00632 return TRUE;
00633 }
00634
00635 bool_t audacious_rc_status (RemoteObject * obj, char * * status, GError * * error)
00636 {
00637 if (drct_get_playing ())
00638 * status = strdup (drct_get_paused () ? "paused" : "playing");
00639 else
00640 * status = strdup ("stopped");
00641
00642 return TRUE;
00643 }
00644
00645 bool_t audacious_rc_info (RemoteObject * obj, int * rate, int * freq, int * nch,
00646 GError * * error)
00647 {
00648 drct_get_info (rate, freq, nch);
00649 return TRUE;
00650 }
00651
00652 bool_t audacious_rc_time (RemoteObject * obj, int * time, GError * * error)
00653 {
00654 * time = drct_get_time ();
00655 return TRUE;
00656 }
00657
00658 bool_t audacious_rc_seek (RemoteObject * obj, unsigned int pos, GError * * error)
00659 {
00660 drct_seek (pos);
00661 return TRUE;
00662 }
00663
00664 bool_t audacious_rc_volume(RemoteObject * obj, int * vl, int * vr, GError ** error)
00665 {
00666 drct_get_volume (vl, vr);
00667 return TRUE;
00668 }
00669
00670 bool_t audacious_rc_set_volume(RemoteObject * obj, int vl, int vr, GError ** error)
00671 {
00672 drct_set_volume (vl, vr);
00673 return TRUE;
00674 }
00675
00676 bool_t audacious_rc_balance(RemoteObject * obj, int * balance, GError ** error)
00677 {
00678 drct_get_volume_balance (balance);
00679 return TRUE;
00680 }
00681
00682
00683
00684 bool_t audacious_rc_position (RemoteObject * obj, int * pos, GError * * error)
00685 {
00686 * pos = playlist_get_position (playlist_get_active ());
00687 return TRUE;
00688 }
00689
00690 bool_t audacious_rc_advance(RemoteObject * obj, GError * *error)
00691 {
00692 drct_pl_next ();
00693 return TRUE;
00694 }
00695
00696 bool_t audacious_rc_reverse (RemoteObject * obj, GError * * error)
00697 {
00698 drct_pl_prev ();
00699 return TRUE;
00700 }
00701
00702 bool_t audacious_rc_length (RemoteObject * obj, int * length, GError * * error)
00703 {
00704 * length = playlist_entry_count (playlist_get_active ());
00705 return TRUE;
00706 }
00707
00708 bool_t audacious_rc_song_title (RemoteObject * obj, unsigned int pos, char * *
00709 title, GError * * error)
00710 {
00711 char * title2 = playlist_entry_get_title (playlist_get_active (), pos, FALSE);
00712 * title = strdup (title2);
00713 str_unref (title2);
00714 return TRUE;
00715 }
00716
00717 bool_t audacious_rc_song_filename (RemoteObject * obj, unsigned int pos,
00718 char * * filename, GError * * error)
00719 {
00720 char * filename2 = playlist_entry_get_filename (playlist_get_active (), pos);
00721 * filename = strdup (filename2);
00722 str_unref (filename2);
00723 return TRUE;
00724 }
00725
00726 bool_t audacious_rc_song_length(RemoteObject * obj, unsigned int pos, int * length, GError * *error)
00727 {
00728 audacious_rc_song_frames(obj, pos, length, error);
00729 *length /= 1000;
00730 return TRUE;
00731 }
00732
00733 bool_t audacious_rc_song_frames (RemoteObject * obj, unsigned int pos, int *
00734 length, GError * * error)
00735 {
00736 * length = playlist_entry_get_length (playlist_get_active (), pos, FALSE);
00737 return TRUE;
00738 }
00739
00740 bool_t audacious_rc_song_tuple (RemoteObject * obj, unsigned int pos, char *
00741 field, GValue * value, GError * * error)
00742 {
00743 GValue * value2 = get_field (playlist_get_active (), pos, field);
00744 if (! value2)
00745 return FALSE;
00746
00747 memset (value, 0, sizeof (GValue));
00748 g_value_init (value, G_VALUE_TYPE (value2));
00749 g_value_copy (value2, value);
00750 g_value_unset (value2);
00751 g_free (value2);
00752 return TRUE;
00753 }
00754
00755 bool_t audacious_rc_jump (RemoteObject * obj, unsigned int pos, GError * * error)
00756 {
00757 playlist_set_position (playlist_get_active (), pos);
00758 return TRUE;
00759 }
00760
00761 bool_t audacious_rc_add(RemoteObject * obj, char * file, GError * *error)
00762 {
00763 return audacious_rc_playlist_ins_url_string(obj, file, -1, error);
00764 }
00765
00766 bool_t audacious_rc_add_url(RemoteObject * obj, char * file, GError * *error)
00767 {
00768 return audacious_rc_playlist_ins_url_string(obj, file, -1, error);
00769 }
00770
00771 static Index * strings_to_index (char * * strings)
00772 {
00773 Index * index = index_new ();
00774
00775 while (* strings)
00776 index_append (index, str_get (* strings ++));
00777
00778 return index;
00779 }
00780
00781 bool_t audacious_rc_add_list (RemoteObject * obj, char * * filenames,
00782 GError * * error)
00783 {
00784 drct_pl_add_list (strings_to_index (filenames), -1);
00785 return TRUE;
00786 }
00787
00788 bool_t audacious_rc_open_list (RemoteObject * obj, char * * filenames,
00789 GError * * error)
00790 {
00791 drct_pl_open_list (strings_to_index (filenames));
00792 return TRUE;
00793 }
00794
00795 bool_t audacious_rc_open_list_to_temp (RemoteObject * obj, char * *
00796 filenames, GError * * error)
00797 {
00798 drct_pl_open_temp_list (strings_to_index (filenames));
00799 return TRUE;
00800 }
00801
00802 bool_t audacious_rc_delete (RemoteObject * obj, unsigned int pos, GError * * error)
00803 {
00804 playlist_entry_delete (playlist_get_active (), pos, 1);
00805 return TRUE;
00806 }
00807
00808 bool_t audacious_rc_clear (RemoteObject * obj, GError * * error)
00809 {
00810 int playlist = playlist_get_active ();
00811 playlist_entry_delete (playlist, 0, playlist_entry_count (playlist));
00812 return TRUE;
00813 }
00814
00815 bool_t audacious_rc_auto_advance(RemoteObject * obj, bool_t * is_advance, GError ** error)
00816 {
00817 * is_advance = ! get_bool (NULL, "no_playlist_advance");
00818 return TRUE;
00819 }
00820
00821 bool_t audacious_rc_toggle_auto_advance(RemoteObject * obj, GError ** error)
00822 {
00823 set_bool (NULL, "no_playlist_advance", ! get_bool (NULL, "no_playlist_advance"));
00824 return TRUE;
00825 }
00826
00827 bool_t audacious_rc_repeat(RemoteObject * obj, bool_t * is_repeating, GError ** error)
00828 {
00829 *is_repeating = get_bool (NULL, "repeat");
00830 return TRUE;
00831 }
00832
00833 bool_t audacious_rc_toggle_repeat (RemoteObject * obj, GError * * error)
00834 {
00835 set_bool (NULL, "repeat", ! get_bool (NULL, "repeat"));
00836 return TRUE;
00837 }
00838
00839 bool_t audacious_rc_shuffle(RemoteObject * obj, bool_t * is_shuffling, GError ** error)
00840 {
00841 *is_shuffling = get_bool (NULL, "shuffle");
00842 return TRUE;
00843 }
00844
00845 bool_t audacious_rc_toggle_shuffle (RemoteObject * obj, GError * * error)
00846 {
00847 set_bool (NULL, "shuffle", ! get_bool (NULL, "shuffle"));
00848 return TRUE;
00849 }
00850
00851 bool_t audacious_rc_stop_after (RemoteObject * obj, bool_t * is_stopping, GError * * error)
00852 {
00853 * is_stopping = get_bool (NULL, "stop_after_current_song");
00854 return TRUE;
00855 }
00856
00857 bool_t audacious_rc_toggle_stop_after (RemoteObject * obj, GError * * error)
00858 {
00859 set_bool (NULL, "stop_after_current_song", ! get_bool (NULL, "stop_after_current_song"));
00860 return TRUE;
00861 }
00862
00863
00864 bool_t audacious_rc_show_prefs_box(RemoteObject * obj, bool_t show, GError ** error)
00865 {
00866 event_queue("prefswin show", GINT_TO_POINTER(show));
00867 return TRUE;
00868 }
00869
00870 bool_t audacious_rc_show_about_box(RemoteObject * obj, bool_t show, GError ** error)
00871 {
00872 event_queue("aboutwin show", GINT_TO_POINTER(show));
00873 return TRUE;
00874 }
00875
00876 bool_t audacious_rc_show_jtf_box(RemoteObject * obj, bool_t show, GError ** error)
00877 {
00878 if (show)
00879 interface_show_jump_to_track ();
00880
00881 return TRUE;
00882 }
00883
00884 bool_t audacious_rc_show_filebrowser(RemoteObject * obj, bool_t show, GError ** error)
00885 {
00886 if (show)
00887 interface_show_filebrowser (FALSE);
00888
00889 return TRUE;
00890 }
00891
00892 bool_t audacious_rc_play_pause (RemoteObject * obj, GError * * error)
00893 {
00894 if (drct_get_playing ())
00895 drct_pause ();
00896 else
00897 drct_play ();
00898
00899 return TRUE;
00900 }
00901
00902 bool_t audacious_rc_get_info (RemoteObject * obj, int * rate, int * freq,
00903 int * nch, GError * * error)
00904 {
00905 drct_get_info (rate, freq, nch);
00906 return TRUE;
00907 }
00908
00909 bool_t audacious_rc_toggle_aot(RemoteObject * obj, bool_t ontop, GError ** error)
00910 {
00911 hook_call("mainwin set always on top", &ontop);
00912 return TRUE;
00913 }
00914
00915 bool_t audacious_rc_playqueue_add (RemoteObject * obj, int pos, GError * * error)
00916 {
00917 playlist_queue_insert (playlist_get_active (), -1, pos);
00918 return TRUE;
00919 }
00920
00921 bool_t audacious_rc_playqueue_remove (RemoteObject * obj, int pos, GError * * error)
00922 {
00923 int playlist = playlist_get_active ();
00924 int at = playlist_queue_find_entry (playlist, pos);
00925
00926 if (at >= 0)
00927 playlist_queue_delete (playlist, at, 1);
00928
00929 return TRUE;
00930 }
00931
00932 bool_t audacious_rc_playqueue_clear (RemoteObject * obj, GError * * error)
00933 {
00934 int playlist = playlist_get_active ();
00935 playlist_queue_delete (playlist, 0, playlist_queue_count (playlist));
00936 return TRUE;
00937 }
00938
00939 bool_t audacious_rc_get_playqueue_length (RemoteObject * obj, int * length,
00940 GError * * error)
00941 {
00942 * length = playlist_queue_count (playlist_get_active ());
00943 return TRUE;
00944 }
00945
00946 bool_t audacious_rc_queue_get_list_pos (RemoteObject * obj, int qpos, int * pos,
00947 GError * * error)
00948 {
00949 * pos = playlist_queue_get_entry (playlist_get_active (), qpos);
00950 return TRUE;
00951 }
00952
00953 bool_t audacious_rc_queue_get_queue_pos (RemoteObject * obj, int pos, int *
00954 qpos, GError * * error)
00955 {
00956 * qpos = playlist_queue_find_entry (playlist_get_active (), pos);
00957 return TRUE;
00958 }
00959
00960 bool_t audacious_rc_playqueue_is_queued (RemoteObject * obj, int pos, bool_t *
00961 is_queued, GError * * error)
00962 {
00963 * is_queued = (playlist_queue_find_entry (playlist_get_active (), pos) >= 0);
00964 return TRUE;
00965 }
00966
00967 bool_t audacious_rc_playlist_ins_url_string (RemoteObject * obj, char * url, int
00968 pos, GError * * error)
00969 {
00970 playlist_entry_insert (playlist_get_active (), pos, url, NULL, FALSE);
00971 return TRUE;
00972 }
00973
00974 bool_t audacious_rc_playlist_add(RemoteObject * obj, void *list, GError * *error)
00975 {
00976 return audacious_rc_playlist_ins_url_string(obj, list, -1, error);
00977 }
00978
00979 bool_t audacious_rc_playlist_enqueue_to_temp (RemoteObject * obj, char * url,
00980 GError * * error)
00981 {
00982 drct_pl_open_temp (url);
00983 return TRUE;
00984 }
00985
00986
00987 bool_t audacious_rc_get_eq(RemoteObject * obj, double * preamp, GArray ** bands, GError ** error)
00988 {
00989 * preamp = get_double (NULL, "equalizer_preamp");
00990 * bands = g_array_new (FALSE, FALSE, sizeof (double));
00991 g_array_set_size (* bands, AUD_EQUALIZER_NBANDS);
00992 eq_get_bands ((double *) (* bands)->data);
00993
00994 return TRUE;
00995 }
00996
00997 bool_t audacious_rc_get_eq_preamp(RemoteObject * obj, double * preamp, GError ** error)
00998 {
00999 * preamp = get_double (NULL, "equalizer_preamp");
01000 return TRUE;
01001 }
01002
01003 bool_t audacious_rc_get_eq_band(RemoteObject * obj, int band, double * value, GError ** error)
01004 {
01005 * value = eq_get_band (band);
01006 return TRUE;
01007 }
01008
01009 bool_t audacious_rc_set_eq(RemoteObject * obj, double preamp, GArray * bands, GError ** error)
01010 {
01011 set_double (NULL, "equalizer_preamp", preamp);
01012 eq_set_bands ((double *) bands->data);
01013 return TRUE;
01014 }
01015
01016 bool_t audacious_rc_set_eq_preamp(RemoteObject * obj, double preamp, GError ** error)
01017 {
01018 set_double (NULL, "equalizer_preamp", preamp);
01019 return TRUE;
01020 }
01021
01022 bool_t audacious_rc_set_eq_band(RemoteObject * obj, int band, double value, GError ** error)
01023 {
01024 eq_set_band (band, value);
01025 return TRUE;
01026 }
01027
01028 bool_t audacious_rc_equalizer_activate(RemoteObject * obj, bool_t active, GError ** error)
01029 {
01030 set_bool (NULL, "equalizer_active", active);
01031 return TRUE;
01032 }
01033
01034 bool_t audacious_rc_get_active_playlist_name (RemoteObject * obj, char * *
01035 title, GError * * error)
01036 {
01037 char * title2 = playlist_get_title (playlist_get_active ());
01038 * title = strdup (title2);
01039 str_unref (title2);
01040 return TRUE;
01041 }
01042
01043 DBusGProxy *audacious_get_dbus_proxy(void)
01044 {
01045 DBusGConnection *connection = NULL;
01046 GError *error = NULL;
01047 connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
01048 g_clear_error(&error);
01049 return dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE, AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE);
01050 }