summaryrefslogtreecommitdiff
path: root/src/libaudclient/audctrl.c
blob: 87b36a621e9d2c97f65992a60e5918bcbf47fd72 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
/*
 * audctrl.c
 * Copyright 2007-2011 Ben Tucker, William Pitcock, Yoshiki Yazawa,
 *                     Matti Hämäläinen, and John Lindgren
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions, and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions, and the following disclaimer in the documentation
 *    provided with the distribution.
 *
 * This software is provided "as is" and without any warranty, express or
 * implied. In no event shall the authors be liable for any damages arising from
 * the use of this software.
 */

#include <stdlib.h>
#include <glib.h>
#include <string.h>
#include <dbus/dbus-glib.h>

#include "audacious/dbus.h"
#include "audacious/dbus-client-bindings.h"
#include "audctrl.h"

static GError *error = NULL; //it must be hidden from outside, otherwise symbol conflict likely to happen.

/**
 * Sends a list of URIs to Audacious, either replacing current
 * playlist or enqueuing them.
 *
 * @param[in] proxy DBus proxy for Audacious
 * @param[in] list An array of URI strings to add.
 * @param[in] num Number of URIs to add.
 * @param[in] enqueue Whether or not the new playlist should be added on, or replace the current playlist.
 **/
EXPORT void audacious_remote_playlist(DBusGProxy *proxy, gchar **list, gint num, gboolean enqueue) {
    GList *glist = NULL;
    gchar **data = list;

    g_return_if_fail(list != NULL);
    g_return_if_fail(num > 0);

    if (!enqueue)
        audacious_remote_playlist_clear(proxy);

    // construct a GList
    while(data) {
        glist = g_list_append(glist, (gpointer)data);
        data++;
    }

    org_atheme_audacious_playlist_add(proxy, (gpointer)glist, &error);

    g_list_free(glist);
    glist = NULL;

    if (!enqueue)
        audacious_remote_play(proxy);
}

/**
 * Queries Audacious for its version identifier.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return String describing the version of Audacious.
 **/
EXPORT gchar *audacious_remote_get_version(DBusGProxy *proxy) {
    char *string = NULL;
    org_atheme_audacious_version(proxy, &string, &error);
    g_clear_error(&error);

    return (string ? string : NULL);
}

/**
 * Sends a list of URIs to Audacious to add to the playlist.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] list A GList of URIs to add to the playlist.
 **/
EXPORT void audacious_remote_playlist_add (DBusGProxy * proxy, GList * list)
{
    const gchar * filenames[g_list_length (list) + 1];
    int count;

    for (count = 0; list != NULL; count ++, list = list->next)
        filenames[count] = list->data;

    filenames[count] = NULL;

    org_atheme_audacious_add_list (proxy, filenames, & error);
    g_clear_error (& error);
}

/**
 * Sends a list of URIs for Audacious to open.  New in Audacious 2.3.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] list A GList of URIs to open
 **/
EXPORT void audacious_remote_playlist_open_list (DBusGProxy * proxy, GList * list)
{
    const gchar * filenames[g_list_length (list) + 1];
    int count;

    for (count = 0; list != NULL; count ++, list = list->next)
        filenames[count] = list->data;

    filenames[count] = NULL;

    org_atheme_audacious_open_list (proxy, filenames, & error);
    g_clear_error (& error);
}

/**
 * Sends a list of URIs for Audacious to open in a temporary playlist.  New in
 * Audacious 2.3.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] list A GList of URIs to open
 **/
EXPORT void audacious_remote_playlist_open_list_to_temp (DBusGProxy * proxy, GList *
 list)
{
    const gchar * filenames[g_list_length (list) + 1];
    int count;

    for (count = 0; list != NULL; count ++, list = list->next)
        filenames[count] = list->data;

    filenames[count] = NULL;

    org_atheme_audacious_open_list_to_temp (proxy, filenames, & error);
    g_clear_error (& error);
}

/**
 * Deletes a playlist entry from current playlist in given position.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos The playlist position to delete.
 **/
EXPORT void audacious_remote_playlist_delete(DBusGProxy *proxy, guint pos) {
    org_atheme_audacious_delete(proxy, pos, &error);
    g_clear_error(&error);
}

/**
 * Requests audacious to begin playback.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_play(DBusGProxy *proxy) {
    org_atheme_audacious_play(proxy, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to pause.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_pause(DBusGProxy *proxy) {
    org_atheme_audacious_pause(proxy, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to stop.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_stop(DBusGProxy *proxy) {
    org_atheme_audacious_stop(proxy, &error);
    g_clear_error(&error);
}

/**
 * Queries audacious about whether it is playing or not.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return TRUE if playing, FALSE otherwise.
 **/
EXPORT gboolean audacious_remote_is_playing(DBusGProxy *proxy) {
    gboolean is_playing = FALSE;
    org_atheme_audacious_playing(proxy, &is_playing, &error);
    g_clear_error(&error);
    return is_playing;
}

/**
 * audacious_remote_is_paused:
 * @param[in] proxy DBus proxy for audacious
 *
 * Queries audacious about whether it is paused or not.
 *
 * @return TRUE if playing, FALSE otherwise.
 **/
EXPORT gboolean audacious_remote_is_paused(DBusGProxy *proxy) {
    gboolean is_paused = FALSE;
    org_atheme_audacious_paused(proxy, &is_paused, &error);
    g_clear_error(&error);
    return is_paused;
}

/**
 * audacious_remote_get_playlist_pos:
 * @param[in] proxy DBus proxy for audacious
 *
 * Queries audacious about the current playlist position.
 *
 * @return The current playlist position.
 **/
EXPORT gint audacious_remote_get_playlist_pos(DBusGProxy *proxy) {
    guint pos = 0;
    org_atheme_audacious_position(proxy, &pos, &error);
    g_clear_error(&error);
    return pos;
}

/**
 * audacious_remote_set_playlist_pos:
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos Playlist position to jump to.
 *
 * Tells audacious to jump to a different playlist position.
 **/
EXPORT void audacious_remote_set_playlist_pos(DBusGProxy *proxy, guint pos) {
    org_atheme_audacious_jump (proxy, pos, &error);
    g_clear_error(&error);
}

/**
 * audacious_remote_get_playlist_length:
 * @param[in] proxy DBus proxy for audacious
 *
 * Queries audacious about the current playlist length.
 *
 * @return The amount of entries in the playlist.
 **/
EXPORT gint audacious_remote_get_playlist_length(DBusGProxy *proxy) {
    gint len = 0;
    org_atheme_audacious_length(proxy, &len, &error);
    g_clear_error(&error);
    return len;
}

/**
 * audacious_remote_playlist_clear:
 * @param[in] proxy DBus proxy for audacious
 *
 * Clears the playlist.
 **/
EXPORT void audacious_remote_playlist_clear(DBusGProxy *proxy) {
    org_atheme_audacious_clear(proxy, &error);
    g_clear_error(&error);
}

/**
 * audacious_remote_get_output_time:
 * @param[in] proxy DBus proxy for audacious
 *
 * Queries audacious about the current output position.
 *
 * @return The current output position.
 **/
EXPORT gint audacious_remote_get_output_time(DBusGProxy *proxy) {
    guint time = 0;
    org_atheme_audacious_time(proxy, &time, &error);
    g_clear_error(&error);
    return time;
}

/**
 * audacious_remote_jump_to_time:
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos The time (in milliseconds) to jump to.
 *
 * Tells audacious to seek to a new time position.
 **/
EXPORT void audacious_remote_jump_to_time(DBusGProxy *proxy, guint pos) {
    org_atheme_audacious_seek (proxy, pos, &error);
    g_clear_error(&error);
}

/**
 * Queries audacious for the current volume settings.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[out] vl Pointer to integer containing the left channel's volume (0-100).
 * @param[out] vr Pointer to integer containing the right channel's volume (0-100).
 **/
EXPORT void audacious_remote_get_volume(DBusGProxy *proxy, gint * vl, gint * vr) {
    org_atheme_audacious_volume(proxy, vl, vr, &error);
    g_clear_error(&error);
}

/**
 * Queries audacious about the current volume.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return The current volume (0-100).
 **/
EXPORT gint audacious_remote_get_main_volume(DBusGProxy *proxy) {
    gint vl = 0, vr = 0;

    audacious_remote_get_volume(proxy, &vl, &vr);

    return (vl > vr) ? vl : vr;
}

/**
 * Queries audacious about the current balance.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return The current balance.
 **/
EXPORT gint audacious_remote_get_balance(DBusGProxy *proxy) {
    gint balance = 50;
    org_atheme_audacious_balance(proxy, &balance,  &error);
    g_clear_error(&error);
    return balance;
}

/**
 * Sets the volume for the left and right channels in Audacious.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] vl The volume for the left channel (0-100).
 * @param[in] vr The volume for the right channel (0-100).
 **/
EXPORT void audacious_remote_set_volume(DBusGProxy *proxy, gint vl, gint vr) {
    org_atheme_audacious_set_volume(proxy, vl, vr,  &error);
    g_clear_error(&error);
}


/**
 * Sets the volume in Audacious.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] v The volume to set (0-100).
 **/
EXPORT void audacious_remote_set_main_volume(DBusGProxy *proxy, gint v) {
    gint b = 50, vl = 0, vr = 0;

    b = audacious_remote_get_balance(proxy);

    if (b < 0) {
        vl = v;
        vr = (v * (100 - abs(b))) / 100;
    } else if (b > 0) {
        vl = (v * (100 - b)) / 100;
        vr = v;
    } else
        vl = vr = v;
    audacious_remote_set_volume(proxy, vl, vr);
}

/**
 * Sets the balance in Audacious.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] b The balance to set.
 **/
EXPORT void audacious_remote_set_balance(DBusGProxy *proxy, gint b) {
    gint v = 0, vl = 0, vr = 0;

    if (b < -100)
        b = -100;
    if (b > 100)
        b = 100;

    v = audacious_remote_get_main_volume(proxy);

    if (b < 0) {
        vl = v;
        vr = (v * (100 - abs(b))) / 100;
    } else if (b > 0) {
        vl = (v * (100 - b)) / 100;
        vr = v;
    } else
        vl = vr = v;
    audacious_remote_set_volume(proxy, vl, vr);
}

/**
 * Queries Audacious about a playlist entry's file.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos The playlist position to query for.
 * @return A path to the file in the playlist at %pos position.
 **/
EXPORT gchar *audacious_remote_get_playlist_file(DBusGProxy *proxy, guint pos) {
    gchar *out = NULL;
    org_atheme_audacious_song_filename(proxy, pos, &out, &error);
    g_clear_error(&error);
    return out;
}

/**
 * Queries Audacious about a playlist entry's title.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos The playlist position to query for.
 * @return The title for the entry in the playlist at %pos position.
 **/
EXPORT gchar *audacious_remote_get_playlist_title(DBusGProxy *proxy, guint pos) {
    gchar *out = NULL;
    org_atheme_audacious_song_title(proxy, pos, &out, &error);
    g_clear_error(&error);
    return out;
}

/**
 * Queries Audacious about a playlist entry's length.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos The playlist position to query for.
 * @return The length of the entry in the playlist at %pos position.
 **/
EXPORT gint audacious_remote_get_playlist_time(DBusGProxy *proxy, guint pos) {
    gint out = 0;
    org_atheme_audacious_song_frames(proxy, pos, &out, &error);
    g_clear_error(&error);
    return out;
}

/**
 * Queries Audacious about the current audio format.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[out] rate Pointer to an integer containing the bitrate.
 * @param[out] freq Pointer to an integer containing the frequency.
 * @param[out] nch Pointer to an integer containing the number of channels.
 **/
EXPORT void audacious_remote_get_info(DBusGProxy *proxy, gint *rate, gint *freq,
                               gint *nch) {
    org_atheme_audacious_info(proxy, rate, freq, nch, &error);
    g_clear_error(&error);
}

/**
 * Toggles the main window's visibility.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] show Whether or not to show the main window.
 **/
EXPORT void audacious_remote_main_win_toggle(DBusGProxy *proxy, gboolean show) {
    org_atheme_audacious_show_main_win(proxy, show, &error);
    g_clear_error(&error);
}

/**
 * Queries Audacious about the main window's visibility.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return TRUE if visible, FALSE otherwise.
 **/
EXPORT gboolean audacious_remote_is_main_win(DBusGProxy *proxy) {
    gboolean visible = TRUE;
    org_atheme_audacious_main_win_visible(proxy, &visible, &error);
    g_clear_error(&error);
    return visible;
}

/**
 * Tells audacious to show the preferences pane.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_show_prefs_box(DBusGProxy *proxy) {
    audacious_remote_toggle_prefs_box(proxy, TRUE);
}

/**
 * Tells audacious to show/hide the preferences pane.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] show shows/hides
 **/
EXPORT void audacious_remote_toggle_prefs_box(DBusGProxy *proxy, gboolean show) {
    org_atheme_audacious_show_prefs_box(proxy, show, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to show the about box.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_show_about_box(DBusGProxy *proxy) {
    audacious_remote_toggle_about_box(proxy, TRUE);
}

/**
 * Tells audacious to show/hide the about box.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] show shows/hides
 **/
EXPORT void audacious_remote_toggle_about_box(DBusGProxy *proxy, gboolean show) {
    org_atheme_audacious_show_about_box(proxy, show, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to set the always-on-top feature.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] ontop Boolean value whether or not Audacious should be always-on-top.
 **/
EXPORT void audacious_remote_toggle_aot(DBusGProxy *proxy, gboolean ontop) {
    org_atheme_audacious_toggle_aot(proxy, ontop, &error);
	g_clear_error(&error);
}

/**
 * Tells audacious to display the open files pane.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_eject(DBusGProxy *proxy) {
    org_atheme_audacious_eject(proxy, &error);
    g_clear_error(&error);
}

/**
 * audacious_remote_playlist_prev:
 * @param[in] proxy DBus proxy for audacious
 *
 * Tells audacious to move backwards in the playlist.
 **/
EXPORT void audacious_remote_playlist_prev(DBusGProxy *proxy) {
    org_atheme_audacious_reverse(proxy, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to move forward in the playlist.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_playlist_next(DBusGProxy *proxy) {
    org_atheme_audacious_advance(proxy, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to add an URI to the playlist.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] string The URI to add.
 **/
EXPORT void audacious_remote_playlist_add_url_string(DBusGProxy *proxy,
                                              gchar *string) {
    org_atheme_audacious_add_url(proxy, string, &error);
    g_clear_error(&error);
}

/**
 * Check if an Audacious instance is running.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return TRUE if yes, otherwise FALSE.
 **/
EXPORT gboolean audacious_remote_is_running(DBusGProxy *proxy) {
    char *string = NULL;
    org_atheme_audacious_version(proxy, &string, &error);
    g_clear_error(&error);
    if(string) {
        g_free(string);
        return TRUE;
    }
    else
        return FALSE;
}

/**
 * Tells audacious to toggle the repeat feature.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_toggle_repeat(DBusGProxy *proxy) {
    org_atheme_audacious_toggle_repeat(proxy, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to toggle the shuffle feature.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_toggle_shuffle(DBusGProxy *proxy) {
    org_atheme_audacious_toggle_shuffle (proxy, &error);
    g_clear_error(&error);
}

EXPORT void audacious_remote_toggle_stop_after (DBusGProxy * proxy)
{
    org_atheme_audacious_toggle_stop_after (proxy, & error);
    g_clear_error (& error);
}

/**
 * Queries audacious about whether or not the repeat feature is active.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return TRUE if yes, otherwise FALSE.
 **/
EXPORT gboolean audacious_remote_is_repeat(DBusGProxy *proxy) {
    gboolean is_repeat;
    org_atheme_audacious_repeat(proxy, &is_repeat, &error);
    g_clear_error(&error);
    return is_repeat;
}

/**
 * Queries audacious about whether or not the shuffle feature is active.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return TRUE if yes, otherwise FALSE.
 **/
EXPORT gboolean audacious_remote_is_shuffle(DBusGProxy *proxy) {
    gboolean is_shuffle;
    org_atheme_audacious_shuffle(proxy, &is_shuffle, &error);
    g_clear_error(&error);
    return is_shuffle;
}

EXPORT gboolean audacious_remote_is_stop_after (DBusGProxy * proxy)
{
    gboolean is_stop_after;
    org_atheme_audacious_stop_after (proxy, & is_stop_after, & error);
    g_clear_error (& error);
    return is_stop_after;
}

/**
 * Queries audacious about the equalizer settings.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[out] preamp Pointer to value for preamp setting.
 * @param[out] bands Pointer to array of band settings.
 **/
EXPORT void audacious_remote_get_eq(DBusGProxy *proxy, gdouble *preamp, GArray **bands) {
    org_atheme_audacious_get_eq(proxy, preamp, bands, &error);
    g_clear_error(&error);
}

/**
 * Queries audacious about the equalizer preamp's setting.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return The equalizer preamp's setting.
 **/
EXPORT gdouble audacious_remote_get_eq_preamp(DBusGProxy *proxy) {
    gdouble preamp = 0.0;

    org_atheme_audacious_get_eq_preamp(proxy, &preamp, &error);
    g_clear_error(&error);

    return preamp;
}

/**
 * Queries audacious about an equalizer band's value.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] band Which band to lookup the value for.
 * @return The equalizer band's value.
 **/
EXPORT gdouble audacious_remote_get_eq_band(DBusGProxy *proxy, gint band) {
    gdouble value = 0.0;

    org_atheme_audacious_get_eq_band(proxy, band, &value, &error);
    g_clear_error(&error);

    return value;
}

/**
 * Tells audacious to set the equalizer up using the provided values.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] preamp Value for preamp setting.
 * @param[in] bands Array of band settings.
 **/
EXPORT void audacious_remote_set_eq(DBusGProxy *proxy, gdouble preamp, GArray *bands) {
    org_atheme_audacious_set_eq(proxy, preamp, bands, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to set the equalizer's preamp setting.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] preamp Value for preamp setting.
 **/
EXPORT void audacious_remote_set_eq_preamp(DBusGProxy *proxy, gdouble preamp) {
    org_atheme_audacious_set_eq_preamp(proxy, preamp, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to set an equalizer band's setting.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] band The band to set the value for.
 * @param[in] value The value to set that band to.
 **/
EXPORT void audacious_remote_set_eq_band(DBusGProxy *proxy, gint band, gdouble value) {
    org_atheme_audacious_set_eq_band(proxy, band, value, &error);
    g_clear_error(&error);
}

/**
 * Requests audacious to quit.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_quit(DBusGProxy *proxy) {
    org_atheme_audacious_quit(proxy, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to toggle between play and pause.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_play_pause(DBusGProxy *proxy) {
    org_atheme_audacious_play_pause(proxy, &error);
}

/**
 * Tells audacious to add an URI to the playlist at a specific position.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] string The URI to add.
 * @param[in] pos The position to add the URI at.
 **/
EXPORT void audacious_remote_playlist_ins_url_string(DBusGProxy *proxy,
                                              gchar *string, guint pos) {
    org_atheme_audacious_playlist_ins_url_string (proxy, string, pos, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to add a playlist entry to the playqueue.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos The playlist position to add to the queue.
 **/
EXPORT void audacious_remote_playqueue_add(DBusGProxy *proxy, guint pos) {
    org_atheme_audacious_playqueue_add (proxy, pos, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to remove a playlist entry from the playqueue.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos The playlist position to remove from the queue.
 **/
EXPORT void audacious_remote_playqueue_remove(DBusGProxy *proxy, guint pos) {
    org_atheme_audacious_playqueue_remove (proxy, pos, &error);
    g_clear_error(&error);
}

/**
 * Queries audacious about the playqueue's length.
 *
 * @bug This returns the length of the playlist, NOT the length of the playqueue.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return The number of entries in the playqueue.
 **/
EXPORT gint audacious_remote_get_playqueue_length(DBusGProxy *proxy) {
    gint len = 0;
    org_atheme_audacious_length(proxy, &len, &error);
    g_clear_error(&error);
    return len;
}

/**
 * Tells audacious to toggle the no-playlist-advance feature.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_toggle_advance(DBusGProxy *proxy) {
    org_atheme_audacious_toggle_auto_advance(proxy, &error);
    g_clear_error(&error);
}

/**
 * audacious_remote_is_advance:
 * @param[in] proxy DBus proxy for audacious
 *
 * Queries audacious about whether or not the no-playlist-advance feature is active.
 *
 * @return TRUE if yes, otherwise FALSE.
 **/
EXPORT gboolean audacious_remote_is_advance(DBusGProxy *proxy) {
    gboolean is_advance = FALSE;
    org_atheme_audacious_auto_advance(proxy, &is_advance, &error);
    g_clear_error(&error);
    return is_advance;
}

/**
 * Tells audacious to show the Jump-to-File pane.
 *
 * @param[in] proxy DBus proxy for audacious
 **/
EXPORT void audacious_remote_show_jtf_box(DBusGProxy *proxy) {
    audacious_remote_toggle_jtf_box(proxy, TRUE);
}

/**
 * Tells audacious to show/hide the Jump-to-File pane.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] show shows/hides jtf pane
 **/
EXPORT void audacious_remote_toggle_jtf_box(DBusGProxy *proxy, gboolean show) {
    org_atheme_audacious_show_jtf_box(proxy, show, &error);
    g_clear_error(&error);
}

/**
 * Tells audacious to show the filebrowser dialog.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] show shows/hides filebrowser
 **/
EXPORT void audacious_remote_toggle_filebrowser(DBusGProxy *proxy, gboolean show) {
    org_atheme_audacious_show_filebrowser(proxy, show, &error);
    g_clear_error(&error);
}

/**
 * audacious_remote_playqueue_clear:
 * @param[in] proxy DBus proxy for audacious
 *
 * Tells audacious to clear the playqueue.
 **/
EXPORT void audacious_remote_playqueue_clear(DBusGProxy *proxy) {
    org_atheme_audacious_playqueue_clear(proxy, &error);
    g_clear_error(&error);
}

/**
 * Queries audacious about whether or not a playlist entry is in the playqueue.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos Position to check queue for.
 * @return TRUE if yes, FALSE otherwise.
 **/
EXPORT gboolean audacious_remote_playqueue_is_queued(DBusGProxy *proxy, guint pos) {
    gboolean is_queued;
    org_atheme_audacious_playqueue_is_queued (proxy, pos, &is_queued, &error);
    g_clear_error(&error);
    return is_queued;
}

/**
 * Queries audacious about what the playqueue position is for a playlist entry.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] pos Position to check queue for.
 * @return the playqueue position for a playlist entry
 **/
EXPORT gint audacious_remote_get_playqueue_queue_position(DBusGProxy *proxy, guint pos) {
    guint qpos = 0;
    org_atheme_audacious_queue_get_queue_pos (proxy, pos, &qpos, &error);
    g_clear_error(&error);
    return qpos;
}

/**
 * Queries audacious what is the playlist position for given a playqueue entry index.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] qpos Position to check queue for.
 *
 * @return the playlist position for a playqueue entry
 **/
EXPORT gint audacious_remote_get_playqueue_list_position(DBusGProxy *proxy, guint qpos) {
    guint pos = 0;
    org_atheme_audacious_queue_get_list_pos (proxy, qpos, &pos, &error);
    g_clear_error(&error);
    return pos;
}

/**
 * Tells audacious to add an URI to a temporary playlist.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] string The URI to enqueue to a temporary playlist.
 **/
EXPORT void audacious_remote_playlist_enqueue_to_temp(DBusGProxy *proxy,
                                               gchar *string) {
    org_atheme_audacious_playlist_enqueue_to_temp(proxy, string, &error);
	g_clear_error(&error);
}

/**
 * Queries Audacious about a playlist entry's tuple information.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] field The name of the tuple field to retrieve.
 * @param[in] pos The playlist position to query for.
 * @return The requested field's data for the entry in the playlist at %pos position.
 **/
EXPORT gchar *audacious_get_tuple_field_data(DBusGProxy *proxy, gchar *field,
                                      guint pos) {
    GValue value = {0};
    gchar *s = NULL;

    org_atheme_audacious_song_tuple(proxy, pos, field, &value, &error);

    g_clear_error(&error);

    if (G_IS_VALUE(&value) == FALSE)
        return NULL;

    /* I think the original "purpose" of using g_strescape() here
     * has probably been to escape only \n, \t, \r, etc. but the function
     * actually escapes all non-ASCII characters. Which is bad, since we
     * are using UTF-8.  -- ccr
     */
    if (G_VALUE_HOLDS_STRING(&value))
        //s = g_strescape(g_value_get_string(&value), NULL);
        s = g_strdup(g_value_get_string(&value));
    else if (g_value_type_transformable(G_VALUE_TYPE(&value), G_TYPE_STRING))
    {
        GValue tmp_value = { 0, };

        g_value_init(&tmp_value, G_TYPE_STRING);
        g_value_transform(&value, &tmp_value);

        //s = g_strescape(g_value_get_string(&tmp_value), NULL);
        s = g_strdup(g_value_get_string(&tmp_value));

        g_value_unset(&tmp_value);
    }
    else
        s = g_strdup("<unknown type>");

    g_value_unset(&value);
    return s;
}

/**
 * Toggles the equalizer.
 *
 * @param[in] proxy DBus proxy for audacious
 * @param[in] active Whether or not to activate the equalizer.
 **/
EXPORT void audacious_remote_eq_activate(DBusGProxy *proxy, gboolean active) {
    org_atheme_audacious_equalizer_activate (proxy, active, &error);
    g_clear_error(&error);
}

/**
 * Returns a array of strings with available tuple field names.
 *
 * @param[in] proxy DBus proxy for audacious
 * @return Array of strings.
 **/
EXPORT gchar **audacious_remote_get_tuple_fields(DBusGProxy *proxy) {
    gchar **res = NULL;
    org_atheme_audacious_get_tuple_fields (proxy, &res, &error);
    g_clear_error(&error);
    return res;
}

/**
 * Returns the active playlist name.
 */
EXPORT gchar *audacious_remote_playlist_get_active_name(DBusGProxy *proxy) {
    char *string = NULL;
    org_atheme_audacious_get_active_playlist_name (proxy, &string, &error);
    g_clear_error(&error);

    return (string ? string : NULL);
}