summaryrefslogtreecommitdiff
path: root/src/audacious
diff options
context:
space:
mode:
authorMateusz Łukasik <mati75@linuxmint.pl>2015-06-05 16:46:36 +0200
committerMateusz Łukasik <mati75@linuxmint.pl>2015-06-05 16:46:36 +0200
commitb541fedc97ad4ed5e658ce34ee50c74ad756f330 (patch)
tree5da244a1063a2529a5419083b2ea23f8fa76cb63 /src/audacious
parent5f4fd4397e8b75ad152aec919f59ecb039ac6105 (diff)
Imported Upstream version 3.6.2
Diffstat (limited to 'src/audacious')
-rw-r--r--src/audacious/Makefile98
-rw-r--r--src/audacious/adder.c573
-rw-r--r--src/audacious/api-alias-begin.h46
-rw-r--r--src/audacious/api-alias-end.h44
-rw-r--r--src/audacious/api-declare-begin.h46
-rw-r--r--src/audacious/api-declare-end.h46
-rw-r--r--src/audacious/api-define-begin.h46
-rw-r--r--src/audacious/api-define-end.h46
-rw-r--r--src/audacious/api-local-begin.h44
-rw-r--r--src/audacious/api-local-end.h44
-rw-r--r--src/audacious/api.h55
-rw-r--r--src/audacious/art.c284
-rw-r--r--src/audacious/audacious.rc2
-rw-r--r--src/audacious/chardet.c52
-rw-r--r--src/audacious/config.c453
-rw-r--r--src/audacious/dbus-server.c779
-rw-r--r--src/audacious/dbus-server.cc815
-rw-r--r--src/audacious/drct-api.h78
-rw-r--r--src/audacious/drct.c195
-rw-r--r--src/audacious/drct.h69
-rw-r--r--src/audacious/effect.c260
-rw-r--r--src/audacious/effect.h36
-rw-r--r--src/audacious/equalizer.c214
-rw-r--r--src/audacious/equalizer.h28
-rw-r--r--src/audacious/equalizer_preset.c242
-rw-r--r--src/audacious/fft.c118
-rw-r--r--src/audacious/fft.h25
-rw-r--r--src/audacious/general.c160
-rw-r--r--src/audacious/general.h33
-rw-r--r--src/audacious/history.c116
-rw-r--r--src/audacious/i18n.h32
-rw-r--r--src/audacious/images/about-logo.pngbin20019 -> 0 bytes
-rw-r--r--src/audacious/images/album.pngbin5418 -> 0 bytes
-rw-r--r--src/audacious/images/appearance.pngbin2721 -> 0 bytes
-rw-r--r--src/audacious/images/audio.pngbin3224 -> 0 bytes
-rw-r--r--src/audacious/images/connectivity.pngbin4452 -> 0 bytes
-rw-r--r--src/audacious/images/info.pngbin3194 -> 0 bytes
-rw-r--r--src/audacious/images/playlist.pngbin1995 -> 0 bytes
-rw-r--r--src/audacious/images/plugins.pngbin4241 -> 0 bytes
-rw-r--r--src/audacious/input-api.h60
-rw-r--r--src/audacious/input.h69
-rw-r--r--src/audacious/interface.c216
-rw-r--r--src/audacious/interface.h36
-rw-r--r--src/audacious/main.c634
-rw-r--r--src/audacious/main.cc384
-rw-r--r--src/audacious/main.h38
-rw-r--r--src/audacious/misc-api.h128
-rw-r--r--src/audacious/misc.h109
-rw-r--r--src/audacious/output.c642
-rw-r--r--src/audacious/output.h47
-rw-r--r--src/audacious/playback.c652
-rw-r--r--src/audacious/playback.h30
-rw-r--r--src/audacious/playlist-api.h362
-rw-r--r--src/audacious/playlist-files.c194
-rw-r--r--src/audacious/playlist-new.c2401
-rw-r--r--src/audacious/playlist-utils.c507
-rw-r--r--src/audacious/playlist.h147
-rw-r--r--src/audacious/plugin-init.c333
-rw-r--r--src/audacious/plugin-preferences.c132
-rw-r--r--src/audacious/plugin-registry.c871
-rw-r--r--src/audacious/plugin-view.c258
-rw-r--r--src/audacious/plugin.h373
-rw-r--r--src/audacious/pluginenum.c210
-rw-r--r--src/audacious/plugins-api.h60
-rw-r--r--src/audacious/plugins.h107
-rw-r--r--src/audacious/preferences.c641
-rw-r--r--src/audacious/preferences.h142
-rw-r--r--src/audacious/probe-buffer.c161
-rw-r--r--src/audacious/probe-buffer.h27
-rw-r--r--src/audacious/probe.c287
-rw-r--r--src/audacious/scanner.c175
-rw-r--r--src/audacious/scanner.h48
-rw-r--r--src/audacious/signals.cc (renamed from src/audacious/signals.c)11
-rw-r--r--src/audacious/types.h67
-rw-r--r--src/audacious/ui_albumart.c188
-rw-r--r--src/audacious/ui_plugin_menu.c105
-rw-r--r--src/audacious/ui_preferences.c814
-rw-r--r--src/audacious/ui_preferences.h38
-rw-r--r--src/audacious/util.c474
-rw-r--r--src/audacious/util.cc (renamed from src/audacious/debug.h)35
-rw-r--r--src/audacious/util.h25
-rw-r--r--src/audacious/vis_runner.c289
-rw-r--r--src/audacious/vis_runner.h30
-rw-r--r--src/audacious/visualization.c261
-rw-r--r--src/audacious/visualization.h36
85 files changed, 1253 insertions, 16680 deletions
diff --git a/src/audacious/Makefile b/src/audacious/Makefile
index bccf836..89a017e 100644
--- a/src/audacious/Makefile
+++ b/src/audacious/Makefile
@@ -1,79 +1,17 @@
include ../../extra.mk
PROG = audacious${PROG_SUFFIX}
-SRCS = adder.c \
- art.c \
- chardet.c \
- config.c \
- drct.c \
- effect.c \
- equalizer.c \
- equalizer_preset.c \
- fft.c \
- general.c \
- history.c \
- interface.c \
- main.c \
- output.c \
- playback.c \
- playlist-files.c \
- playlist-new.c \
- playlist-utils.c \
- pluginenum.c \
- plugin-preferences.c \
- plugin-registry.c \
- plugin-init.c \
- plugin-view.c \
- preferences.c \
- probe.c \
- probe-buffer.c \
- scanner.c \
- signals.c \
- ui_plugin_menu.c \
- ui_preferences.c \
- util.c \
- vis_runner.c \
- visualization.c \
- ui_albumart.c
+
+SRCS = main.cc \
+ signals.cc \
+ util.cc
ifeq ($(HAVE_MSWINDOWS),yes)
SRCS += audacious.rc
endif
-INCLUDES = api.h \
- api-alias-begin.h \
- api-alias-end.h \
- api-define-begin.h \
- api-define-end.h \
- debug.h \
- drct.h \
- drct-api.h \
- i18n.h \
- input.h \
- input-api.h \
- misc.h \
- misc-api.h \
- playlist.h \
- playlist-api.h \
- plugin.h \
- plugins.h \
- plugins-api.h \
- preferences.h \
- types.h
-
-DATA = images/about-logo.png \
- images/album.png \
- images/appearance.png \
- images/audio.png \
- images/connectivity.png \
- images/info.png \
- images/playlist.png \
- images/plugins.png
-
-CLEAN = build_stamp.c
-
ifeq ($(USE_DBUS),yes)
-SRCS += dbus-server.c
+SRCS += dbus-server.cc
EXT_DEPS += ../dbus/aud-dbus.a
endif
@@ -84,30 +22,16 @@ CPPFLAGS := -I../dbus ${CPPFLAGS} ${GIO_CFLAGS}
LIBS := ../dbus/aud-dbus.a ${LIBS} ${GIO_LIBS}
endif
+LD = ${CXX}
+
CPPFLAGS := -I.. -I../.. \
${CPPFLAGS} \
- ${GLIB_CFLAGS} \
- ${GMODULE_CFLAGS} \
- ${GTK_CFLAGS} \
- ${LIBGUESS_CFLAGS}
+ ${GLIB_CFLAGS}
-CPPFLAGS := ${CPPFLAGS} \
- -D_AUDACIOUS_CORE \
- -DHARDCODE_BINDIR=\"${bindir}\" \
- -DHARDCODE_DATADIR=\"${datadir}/audacious\" \
- -DHARDCODE_PLUGINDIR=\"${plugindir}\" \
- -DHARDCODE_LOCALEDIR=\"${localedir}\" \
- -DHARDCODE_DESKTOPFILE=\"${datarootdir}/applications/audacious.desktop\" \
- -DHARDCODE_ICONFILE=\"${datarootdir}/pixmaps/audacious.png\"
+CPPFLAGS += -D_AUDACIOUS_CORE
LIBS := -L../libaudcore -laudcore \
- -L../libaudgui -laudgui \
- -L../libaudtag -laudtag \
${LIBS} -lm \
- ${LIBINTL} \
- ${GLIB_LIBS} \
- ${GMODULE_LIBS} \
- ${GTK_LIBS}
+ ${LIBINTL} \
+ ${GLIB_LIBS}
-desktop_DATA = audacious.desktop
-desktopdir = ${datarootdir}/applications
diff --git a/src/audacious/adder.c b/src/audacious/adder.c
deleted file mode 100644
index 509f363..0000000
--- a/src/audacious/adder.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * adder.c
- * Copyright 2011-2013 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 <pthread.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include <glib/gstdio.h>
-#include <gtk/gtk.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-
-#include "drct.h"
-#include "i18n.h"
-#include "playlist.h"
-#include "plugins.h"
-#include "main.h"
-#include "misc.h"
-#include "util.h"
-
-typedef struct {
- int playlist_id, at;
- bool_t play;
- Index * filenames, * tuples;
- PlaylistFilterFunc filter;
- void * user;
-} AddTask;
-
-typedef struct {
- int playlist_id, at;
- bool_t play;
- char * title;
- Index * filenames, * tuples, * decoders;
-} AddResult;
-
-static GList * add_tasks = NULL;
-static GList * add_results = NULL;
-static int current_playlist_id = -1;
-
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-static bool_t add_quit;
-static pthread_t add_thread;
-static int add_source = 0;
-
-static int status_source = 0;
-static char status_path[512];
-static int status_count;
-static GtkWidget * status_window = NULL, * status_path_label,
- * status_count_label;
-
-static bool_t status_cb (void * unused)
-{
- if (! headless_mode () && ! status_window)
- {
- status_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_type_hint ((GtkWindow *) status_window,
- GDK_WINDOW_TYPE_HINT_DIALOG);
- gtk_window_set_title ((GtkWindow *) status_window, _("Searching ..."));
- gtk_window_set_resizable ((GtkWindow *) status_window, FALSE);
- gtk_container_set_border_width ((GtkContainer *) status_window, 6);
-
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_container_add ((GtkContainer *) status_window, vbox);
-
- status_path_label = gtk_label_new (NULL);
- gtk_label_set_width_chars ((GtkLabel *) status_path_label, 40);
- gtk_label_set_max_width_chars ((GtkLabel *) status_path_label, 40);
- gtk_label_set_ellipsize ((GtkLabel *) status_path_label,
- PANGO_ELLIPSIZE_MIDDLE);
- gtk_box_pack_start ((GtkBox *) vbox, status_path_label, FALSE, FALSE, 0);
-
- status_count_label = gtk_label_new (NULL);
- gtk_label_set_width_chars ((GtkLabel *) status_count_label, 40);
- gtk_label_set_max_width_chars ((GtkLabel *) status_count_label, 40);
- gtk_box_pack_start ((GtkBox *) vbox, status_count_label, FALSE, FALSE, 0);
-
- gtk_widget_show_all (status_window);
-
- g_signal_connect (status_window, "destroy", (GCallback)
- gtk_widget_destroyed, & status_window);
- }
-
- pthread_mutex_lock (& mutex);
-
- char scratch[128];
- snprintf (scratch, sizeof scratch, dngettext (PACKAGE, "%d file found",
- "%d files found", status_count), status_count);
-
- if (headless_mode ())
- {
- printf ("Searching, %s ...\r", scratch);
- fflush (stdout);
- }
- else
- {
- gtk_label_set_text ((GtkLabel *) status_path_label, status_path);
- gtk_label_set_text ((GtkLabel *) status_count_label, scratch);
- }
-
- pthread_mutex_unlock (& mutex);
- return TRUE;
-}
-
-static void status_update (const char * filename, int found)
-{
- pthread_mutex_lock (& mutex);
-
- snprintf (status_path, sizeof status_path, "%s", filename);
- status_count = found;
-
- if (! status_source)
- status_source = g_timeout_add (250, status_cb, NULL);
-
- pthread_mutex_unlock (& mutex);
-}
-
-static void status_done_locked (void)
-{
- if (status_source)
- {
- g_source_remove (status_source);
- status_source = 0;
- }
-
- if (headless_mode ())
- printf ("\n");
- else if (status_window)
- gtk_widget_destroy (status_window);
-}
-
-static AddTask * add_task_new (int playlist_id, int at, bool_t play,
- Index * filenames, Index * tuples, PlaylistFilterFunc filter,
- void * user)
-{
- AddTask * task = g_slice_new (AddTask);
- task->playlist_id = playlist_id;
- task->at = at;
- task->play = play;
- task->filenames = filenames;
- task->tuples = tuples;
- task->filter = filter;
- task->user = user;
- return task;
-}
-
-static void add_task_free (AddTask * task)
-{
- if (task->filenames)
- index_free_full (task->filenames, (IndexFreeFunc) str_unref);
- if (task->tuples)
- index_free_full (task->tuples, (IndexFreeFunc) tuple_unref);
-
- g_slice_free (AddTask, task);
-}
-
-static AddResult * add_result_new (int playlist_id, int at, bool_t play)
-{
- AddResult * result = g_slice_new (AddResult);
- result->playlist_id = playlist_id;
- result->at = at;
- result->play = play;
- result->title = NULL;
- result->filenames = index_new ();
- result->tuples = index_new ();
- result->decoders = index_new ();
- return result;
-}
-
-static void add_result_free (AddResult * result)
-{
- str_unref (result->title);
-
- if (result->filenames)
- index_free_full (result->filenames, (IndexFreeFunc) str_unref);
- if (result->tuples)
- index_free_full (result->tuples, (IndexFreeFunc) tuple_unref);
- if (result->decoders)
- index_free (result->decoders);
-
- g_slice_free (AddResult, result);
-}
-
-static void add_file (char * filename, Tuple * tuple, PluginHandle * decoder,
- PlaylistFilterFunc filter, void * user, AddResult * result, bool_t validate)
-{
- g_return_if_fail (filename);
- if (filter && ! filter (filename, user))
- {
- str_unref (filename);
- return;
- }
-
- status_update (filename, index_count (result->filenames));
-
- if (! tuple && ! decoder)
- {
- decoder = file_find_decoder (filename, TRUE);
- if (validate && ! decoder)
- {
- str_unref (filename);
- return;
- }
- }
-
- if (! tuple && decoder && input_plugin_has_subtunes (decoder) && ! strchr
- (filename, '?'))
- tuple = file_read_tuple (filename, decoder);
-
- int n_subtunes = tuple ? tuple_get_n_subtunes (tuple) : 0;
-
- if (n_subtunes)
- {
- for (int sub = 0; sub < n_subtunes; sub ++)
- {
- char * subname = str_printf ("%s?%d", filename,
- tuple_get_nth_subtune (tuple, sub));
- add_file (subname, NULL, decoder, filter, user, result, FALSE);
- }
-
- str_unref (filename);
- tuple_unref (tuple);
- return;
- }
-
- index_insert (result->filenames, -1, filename);
- index_insert (result->tuples, -1, tuple);
- index_insert (result->decoders, -1, decoder);
-}
-
-static void add_folder (char * filename, PlaylistFilterFunc filter,
- void * user, AddResult * result, bool_t is_single)
-{
- char * path = NULL;
-
- g_return_if_fail (filename);
-
- if (filter && ! filter (filename, user))
- goto DONE;
-
- status_update (filename, index_count (result->filenames));
-
- if (! (path = uri_to_filename (filename)))
- goto DONE;
-
- GList * files = NULL;
- GDir * folder = g_dir_open (path, 0, NULL);
- if (! folder)
- goto DONE;
-
- const char * name;
- while ((name = g_dir_read_name (folder)))
- {
- char * filepath = filename_build (path, name);
- files = g_list_prepend (files, filepath);
- }
-
- g_dir_close (folder);
-
- if (files && is_single)
- {
- char * last = last_path_element (path);
- result->title = str_get (last ? last : path);
- }
-
- files = g_list_sort (files, (GCompareFunc) str_compare);
-
- while (files)
- {
- GStatBuf info;
- if (g_lstat (files->data, & info) < 0)
- goto NEXT;
-
- if (S_ISREG (info.st_mode))
- {
- char * item_name = filename_to_uri (files->data);
- if (item_name)
- add_file (item_name, NULL, NULL, filter, user, result, TRUE);
- }
- else if (S_ISDIR (info.st_mode))
- {
- char * item_name = filename_to_uri (files->data);
- if (item_name)
- add_folder (item_name, filter, user, result, FALSE);
- }
-
- NEXT:
- str_unref (files->data);
- files = g_list_delete_link (files, files);
- }
-
-DONE:
- str_unref (filename);
- str_unref (path);
-}
-
-static void add_playlist (char * filename, PlaylistFilterFunc filter,
- void * user, AddResult * result, bool_t is_single)
-{
- g_return_if_fail (filename);
- if (filter && ! filter (filename, user))
- {
- str_unref (filename);
- return;
- }
-
- status_update (filename, index_count (result->filenames));
-
- char * title = NULL;
- Index * filenames, * tuples;
- if (! playlist_load (filename, & title, & filenames, & tuples))
- {
- str_unref (filename);
- return;
- }
-
- if (is_single)
- result->title = title;
- else
- str_unref (title);
-
- int count = index_count (filenames);
- for (int i = 0; i < count; i ++)
- add_file (index_get (filenames, i), tuples ? index_get (tuples, i) :
- NULL, NULL, filter, user, result, FALSE);
-
- str_unref (filename);
- index_free (filenames);
- if (tuples)
- index_free (tuples);
-}
-
-static void add_generic (char * filename, Tuple * tuple,
- PlaylistFilterFunc filter, void * user, AddResult * result, bool_t is_single)
-{
- g_return_if_fail (filename);
-
- if (tuple)
- add_file (filename, tuple, NULL, filter, user, result, FALSE);
- else if (vfs_file_test (filename, G_FILE_TEST_IS_DIR))
- add_folder (filename, filter, user, result, is_single);
- else if (filename_is_playlist (filename))
- add_playlist (filename, filter, user, result, is_single);
- else
- add_file (filename, NULL, NULL, filter, user, result, FALSE);
-}
-
-static bool_t add_finish (void * unused)
-{
- pthread_mutex_lock (& mutex);
-
- while (add_results)
- {
- AddResult * result = add_results->data;
- add_results = g_list_delete_link (add_results, add_results);
-
- int playlist = playlist_by_unique_id (result->playlist_id);
- if (playlist < 0) /* playlist deleted */
- goto FREE;
-
- int count = playlist_entry_count (playlist);
- if (result->at < 0 || result->at > count)
- result->at = count;
-
- if (result->title && ! count)
- {
- char * old_title = playlist_get_title (playlist);
-
- if (! strcmp (old_title, N_("New Playlist")))
- playlist_set_title (playlist, result->title);
-
- str_unref (old_title);
- }
-
- playlist_entry_insert_batch_raw (playlist, result->at,
- result->filenames, result->tuples, result->decoders);
- result->filenames = NULL;
- result->tuples = NULL;
- result->decoders = NULL;
-
- if (result->play && playlist_entry_count (playlist) > count)
- {
- if (! get_bool (NULL, "shuffle"))
- playlist_set_position (playlist, result->at);
-
- drct_play_playlist (playlist);
- }
-
- FREE:
- add_result_free (result);
- }
-
- if (add_source)
- {
- g_source_remove (add_source);
- add_source = 0;
- }
-
- if (! add_tasks)
- status_done_locked ();
-
- pthread_mutex_unlock (& mutex);
-
- hook_call ("playlist add complete", NULL);
- return FALSE;
-}
-
-static void * add_worker (void * unused)
-{
- pthread_mutex_lock (& mutex);
-
- while (! add_quit)
- {
- if (! add_tasks)
- {
- pthread_cond_wait (& cond, & mutex);
- continue;
- }
-
- AddTask * task = add_tasks->data;
- add_tasks = g_list_delete_link (add_tasks, add_tasks);
-
- current_playlist_id = task->playlist_id;
- pthread_mutex_unlock (& mutex);
-
- AddResult * result = add_result_new (task->playlist_id, task->at,
- task->play);
-
- int count = index_count (task->filenames);
- if (task->tuples)
- count = MIN (count, index_count (task->tuples));
-
- for (int i = 0; i < count; i ++)
- {
- add_generic (index_get (task->filenames, i), task->tuples ?
- index_get (task->tuples, i) : NULL, task->filter, task->user,
- result, (count == 1));
-
- index_set (task->filenames, i, NULL);
- if (task->tuples)
- index_set (task->tuples, i, NULL);
- }
-
- add_task_free (task);
-
- pthread_mutex_lock (& mutex);
- current_playlist_id = -1;
-
- add_results = g_list_append (add_results, result);
-
- if (! add_source)
- add_source = g_timeout_add (0, add_finish, NULL);
- }
-
- pthread_mutex_unlock (& mutex);
- return NULL;
-}
-
-void adder_init (void)
-{
- pthread_mutex_lock (& mutex);
- add_quit = FALSE;
- pthread_create (& add_thread, NULL, add_worker, NULL);
- pthread_mutex_unlock (& mutex);
-}
-
-void adder_cleanup (void)
-{
- pthread_mutex_lock (& mutex);
- add_quit = TRUE;
- pthread_cond_broadcast (& cond);
- pthread_mutex_unlock (& mutex);
- pthread_join (add_thread, NULL);
-
- g_list_free_full (add_tasks, (GDestroyNotify) add_task_free);
- add_tasks = NULL;
- g_list_free_full (add_results, (GDestroyNotify) add_result_free);
- add_results = NULL;
-
- if (add_source)
- {
- g_source_remove (add_source);
- add_source = 0;
- }
-
- status_done_locked ();
-}
-
-void playlist_entry_insert (int playlist, int at, const char * filename,
- Tuple * tuple, bool_t play)
-{
- Index * filenames = index_new ();
- Index * tuples = index_new ();
- index_insert (filenames, -1, str_get (filename));
- index_insert (tuples, -1, tuple);
-
- playlist_entry_insert_batch (playlist, at, filenames, tuples, play);
-}
-
-void playlist_entry_insert_batch (int playlist, int at,
- Index * filenames, Index * tuples, bool_t play)
-{
- playlist_entry_insert_filtered (playlist, at, filenames, tuples, NULL, NULL, play);
-}
-
-void playlist_entry_insert_filtered (int playlist, int at,
- Index * filenames, Index * tuples, PlaylistFilterFunc filter,
- void * user, bool_t play)
-{
- int playlist_id = playlist_get_unique_id (playlist);
- g_return_if_fail (playlist_id >= 0);
-
- AddTask * task = add_task_new (playlist_id, at, play, filenames, tuples, filter, user);
-
- pthread_mutex_lock (& mutex);
- add_tasks = g_list_append (add_tasks, task);
- pthread_cond_broadcast (& cond);
- pthread_mutex_unlock (& mutex);
-}
-
-bool_t playlist_add_in_progress (int playlist)
-{
- pthread_mutex_lock (& mutex);
-
- if (playlist >= 0)
- {
- int playlist_id = playlist_get_unique_id (playlist);
-
- for (GList * node = add_tasks; node; node = node->next)
- {
- if (((AddTask *) node->data)->playlist_id == playlist_id)
- goto YES;
- }
-
- if (current_playlist_id == playlist_id)
- goto YES;
-
- for (GList * node = add_results; node; node = node->next)
- {
- if (((AddResult *) node->data)->playlist_id == playlist_id)
- goto YES;
- }
- }
- else
- {
- if (add_tasks || current_playlist_id >= 0 || add_results)
- goto YES;
- }
-
- pthread_mutex_unlock (& mutex);
- return FALSE;
-
-YES:
- pthread_mutex_unlock (& mutex);
- return TRUE;
-}
diff --git a/src/audacious/api-alias-begin.h b/src/audacious/api-alias-begin.h
deleted file mode 100644
index 457d29d..0000000
--- a/src/audacious/api-alias-begin.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * api-alias-begin.h
- * Copyright 2010-2011 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.
- */
-
-#if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || defined AUD_API_ALIAS
-#error Bad usage of api-alias-begin.h
-#endif
-
-#define AUD_API_ALIAS
-
-extern AudAPITable * _aud_api_table;
-
-#define AUD_FUNC0(t,n) static inline t aud_##n(void) {return _aud_api_table->AUD_API_SYMBOL->n();}
-#define AUD_FUNC1(t,n,t1,n1) static inline t aud_##n(t1 n1) {return _aud_api_table->AUD_API_SYMBOL->n(n1);}
-#define AUD_FUNC2(t,n,t1,n1,t2,n2) static inline t aud_##n(t1 n1, t2 n2) {return _aud_api_table->AUD_API_SYMBOL->n(n1,n2);}
-#define AUD_FUNC3(t,n,t1,n1,t2,n2,t3,n3) static inline t aud_##n(t1 n1, t2 n2, t3 n3) {return _aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3);}
-#define AUD_FUNC4(t,n,t1,n1,t2,n2,t3,n3,t4,n4) static inline t aud_##n(t1 n1, t2 n2, t3 n3, t4 n4) {return _aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4);}
-#define AUD_FUNC5(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) static inline t aud_##n(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5) {return _aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4,n5);}
-#define AUD_FUNC6(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) static inline t aud_##n(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6) {return _aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4,n5,n6);}
-#define AUD_FUNC7(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) static inline t aud_##n(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7) {return _aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4,n5,n6,n7);}
-#define AUD_FUNC8(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7,t8,n8) static inline t aud_##n(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7, t8 n8) {return _aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4,n5,n6,n7,n8);}
-
-#define AUD_VFUNC0(n) static inline void aud_##n(void) {_aud_api_table->AUD_API_SYMBOL->n();}
-#define AUD_VFUNC1(n,t1,n1) static inline void aud_##n(t1 n1) {_aud_api_table->AUD_API_SYMBOL->n(n1);}
-#define AUD_VFUNC2(n,t1,n1,t2,n2) static inline void aud_##n(t1 n1, t2 n2) {_aud_api_table->AUD_API_SYMBOL->n(n1,n2);}
-#define AUD_VFUNC3(n,t1,n1,t2,n2,t3,n3) static inline void aud_##n(t1 n1, t2 n2, t3 n3) {_aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3);}
-#define AUD_VFUNC4(n,t1,n1,t2,n2,t3,n3,t4,n4) static inline void aud_##n(t1 n1, t2 n2, t3 n3, t4 n4) {_aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4);}
-#define AUD_VFUNC5(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) static inline void aud_##n(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5) {_aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4,n5);}
-#define AUD_VFUNC6(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) static inline void aud_##n(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6) {_aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4,n5,n6);}
-#define AUD_VFUNC7(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) static inline void aud_##n(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7) {_aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4,n5,n6,n7);}
-#define AUD_VFUNC8(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7,t8,n8) static inline void aud_##n(t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7, t8 n8) {_aud_api_table->AUD_API_SYMBOL->n(n1,n2,n3,n4,n5,n6,n7,n8);}
diff --git a/src/audacious/api-alias-end.h b/src/audacious/api-alias-end.h
deleted file mode 100644
index a003cde..0000000
--- a/src/audacious/api-alias-end.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * api-alias-end.h
- * Copyright 2010-2011 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.
- */
-
-#if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || ! defined AUD_API_ALIAS
-#error Bad usage of api-alias-end.h
-#endif
-
-#undef AUD_API_ALIAS
-
-#undef AUD_FUNC0
-#undef AUD_FUNC1
-#undef AUD_FUNC2
-#undef AUD_FUNC3
-#undef AUD_FUNC4
-#undef AUD_FUNC5
-#undef AUD_FUNC6
-#undef AUD_FUNC7
-#undef AUD_FUNC8
-
-#undef AUD_VFUNC0
-#undef AUD_VFUNC1
-#undef AUD_VFUNC2
-#undef AUD_VFUNC3
-#undef AUD_VFUNC4
-#undef AUD_VFUNC5
-#undef AUD_VFUNC6
-#undef AUD_VFUNC7
-#undef AUD_VFUNC8
diff --git a/src/audacious/api-declare-begin.h b/src/audacious/api-declare-begin.h
deleted file mode 100644
index defc557..0000000
--- a/src/audacious/api-declare-begin.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * api-declare-begin.h
- * Copyright 2010-2011 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.
- */
-
-#if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || defined AUD_API_DECLARE_H
-#error Bad usage of api-declare-begin.h
-#endif
-
-#define AUD_API_DECLARE_H
-
-#define AUD_FUNC0(t,n) .n = n,
-#define AUD_FUNC1(t,n,t1,n1) .n = n,
-#define AUD_FUNC2(t,n,t1,n1,t2,n2) .n = n,
-#define AUD_FUNC3(t,n,t1,n1,t2,n2,t3,n3) .n = n,
-#define AUD_FUNC4(t,n,t1,n1,t2,n2,t3,n3,t4,n4) .n = n,
-#define AUD_FUNC5(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) .n = n,
-#define AUD_FUNC6(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) .n = n,
-#define AUD_FUNC7(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) .n = n,
-#define AUD_FUNC8(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7,t8,n8) .n = n,
-
-#define AUD_VFUNC0(n) .n = n,
-#define AUD_VFUNC1(n,t1,n1) .n = n,
-#define AUD_VFUNC2(n,t1,n1,t2,n2) .n = n,
-#define AUD_VFUNC3(n,t1,n1,t2,n2,t3,n3) .n = n,
-#define AUD_VFUNC4(n,t1,n1,t2,n2,t3,n3,t4,n4) .n = n,
-#define AUD_VFUNC5(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) .n = n,
-#define AUD_VFUNC6(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) .n = n,
-#define AUD_VFUNC7(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) .n = n,
-#define AUD_VFUNC8(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7,t8,n8) .n = n,
-
-const struct AUD_API_NAME AUD_API_SYMBOL = {
diff --git a/src/audacious/api-declare-end.h b/src/audacious/api-declare-end.h
deleted file mode 100644
index fa73092..0000000
--- a/src/audacious/api-declare-end.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * api-declare-end.h
- * Copyright 2010-2011 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.
- */
-
-#if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || ! defined AUD_API_DECLARE_H
-#error Bad usage of api-declare-end.h
-#endif
-
-};
-
-#undef AUD_API_DECLARE_H
-
-#undef AUD_FUNC0
-#undef AUD_FUNC1
-#undef AUD_FUNC2
-#undef AUD_FUNC3
-#undef AUD_FUNC4
-#undef AUD_FUNC5
-#undef AUD_FUNC6
-#undef AUD_FUNC7
-#undef AUD_FUNC8
-
-#undef AUD_VFUNC0
-#undef AUD_VFUNC1
-#undef AUD_VFUNC2
-#undef AUD_VFUNC3
-#undef AUD_VFUNC4
-#undef AUD_VFUNC5
-#undef AUD_VFUNC6
-#undef AUD_VFUNC7
-#undef AUD_VFUNC8
diff --git a/src/audacious/api-define-begin.h b/src/audacious/api-define-begin.h
deleted file mode 100644
index 5fe32cd..0000000
--- a/src/audacious/api-define-begin.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * api-define-begin.h
- * Copyright 2010-2011 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.
- */
-
-#if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || defined AUD_API_DEFINE_H
-#error Bad usage of api-define-begin.h
-#endif
-
-#define AUD_API_DEFINE_H
-
-#define AUD_FUNC0(t,n) t (* n) (void);
-#define AUD_FUNC1(t,n,t1,n1) t (* n) (t1 n1);
-#define AUD_FUNC2(t,n,t1,n1,t2,n2) t (* n) (t1 n1, t2 n2);
-#define AUD_FUNC3(t,n,t1,n1,t2,n2,t3,n3) t (* n) (t1 n1, t2 n2, t3 n3);
-#define AUD_FUNC4(t,n,t1,n1,t2,n2,t3,n3,t4,n4) t (* n) (t1 n1, t2 n2, t3 n3, t4 n4);
-#define AUD_FUNC5(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) t (* n) (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5);
-#define AUD_FUNC6(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) t (* n) (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6);
-#define AUD_FUNC7(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) t (* n) (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7);
-#define AUD_FUNC8(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7,t8,n8) t (* n) (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7, t8 n8);
-
-#define AUD_VFUNC0(n) void (* n) (void);
-#define AUD_VFUNC1(n,t1,n1) void (* n) (t1 n1);
-#define AUD_VFUNC2(n,t1,n1,t2,n2) void (* n) (t1 n1, t2 n2);
-#define AUD_VFUNC3(n,t1,n1,t2,n2,t3,n3) void (* n) (t1 n1, t2 n2, t3 n3);
-#define AUD_VFUNC4(n,t1,n1,t2,n2,t3,n3,t4,n4) void (* n) (t1 n1, t2 n2, t3 n3, t4 n4);
-#define AUD_VFUNC5(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) void (* n) (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5);
-#define AUD_VFUNC6(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) void (* n) (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6);
-#define AUD_VFUNC7(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) void (* n) (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7);
-#define AUD_VFUNC8(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7,t8,n8) void (* n) (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7, t8 n8);
-
-struct AUD_API_NAME {
diff --git a/src/audacious/api-define-end.h b/src/audacious/api-define-end.h
deleted file mode 100644
index 91bd85f..0000000
--- a/src/audacious/api-define-end.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * api-define-end.h
- * Copyright 2010-2011 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.
- */
-
-#if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || ! defined AUD_API_DEFINE_H
-#error Bad usage of api-define-end.h
-#endif
-
-};
-
-#undef AUD_API_DEFINE_H
-
-#undef AUD_FUNC0
-#undef AUD_FUNC1
-#undef AUD_FUNC2
-#undef AUD_FUNC3
-#undef AUD_FUNC4
-#undef AUD_FUNC5
-#undef AUD_FUNC6
-#undef AUD_FUNC7
-#undef AUD_FUNC8
-
-#undef AUD_VFUNC0
-#undef AUD_VFUNC1
-#undef AUD_VFUNC2
-#undef AUD_VFUNC3
-#undef AUD_VFUNC4
-#undef AUD_VFUNC5
-#undef AUD_VFUNC6
-#undef AUD_VFUNC7
-#undef AUD_VFUNC8
diff --git a/src/audacious/api-local-begin.h b/src/audacious/api-local-begin.h
deleted file mode 100644
index b32eeb1..0000000
--- a/src/audacious/api-local-begin.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * api-local-begin.h
- * Copyright 2010-2011 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.
- */
-
-#if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || defined AUD_API_LOCAL_H
-#error Bad usage of api-local-begin.h
-#endif
-
-#define AUD_API_LOCAL_H
-
-#define AUD_FUNC0(t,n) t n (void);
-#define AUD_FUNC1(t,n,t1,n1) t n (t1 n1);
-#define AUD_FUNC2(t,n,t1,n1,t2,n2) t n (t1 n1, t2 n2);
-#define AUD_FUNC3(t,n,t1,n1,t2,n2,t3,n3) t n (t1 n1, t2 n2, t3 n3);
-#define AUD_FUNC4(t,n,t1,n1,t2,n2,t3,n3,t4,n4) t n (t1 n1, t2 n2, t3 n3, t4 n4);
-#define AUD_FUNC5(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) t n (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5);
-#define AUD_FUNC6(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) t n (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6);
-#define AUD_FUNC7(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) t n (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7);
-#define AUD_FUNC8(t,n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7,t8,n8) t n (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7, t8 n8);
-
-#define AUD_VFUNC0(n) void n (void);
-#define AUD_VFUNC1(n,t1,n1) void n (t1 n1);
-#define AUD_VFUNC2(n,t1,n1,t2,n2) void n (t1 n1, t2 n2);
-#define AUD_VFUNC3(n,t1,n1,t2,n2,t3,n3) void n (t1 n1, t2 n2, t3 n3);
-#define AUD_VFUNC4(n,t1,n1,t2,n2,t3,n3,t4,n4) void n (t1 n1, t2 n2, t3 n3, t4 n4);
-#define AUD_VFUNC5(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) void n (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5);
-#define AUD_VFUNC6(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) void n (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6);
-#define AUD_VFUNC7(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7) void n (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7);
-#define AUD_VFUNC8(n,t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6,t7,n7,t8,n8) void n (t1 n1, t2 n2, t3 n3, t4 n4, t5 n5, t6 n6, t7 n7, t8 n8);
diff --git a/src/audacious/api-local-end.h b/src/audacious/api-local-end.h
deleted file mode 100644
index 81ec43d..0000000
--- a/src/audacious/api-local-end.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * api-local-end.h
- * Copyright 2010-2011 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.
- */
-
-#if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || ! defined AUD_API_LOCAL_H
-#error Bad usage of api-local-end.h
-#endif
-
-#undef AUD_API_LOCAL_H
-
-#undef AUD_FUNC0
-#undef AUD_FUNC1
-#undef AUD_FUNC2
-#undef AUD_FUNC3
-#undef AUD_FUNC4
-#undef AUD_FUNC5
-#undef AUD_FUNC6
-#undef AUD_FUNC7
-#undef AUD_FUNC8
-
-#undef AUD_VFUNC0
-#undef AUD_VFUNC1
-#undef AUD_VFUNC2
-#undef AUD_VFUNC3
-#undef AUD_VFUNC4
-#undef AUD_VFUNC5
-#undef AUD_VFUNC6
-#undef AUD_VFUNC7
-#undef AUD_VFUNC8
diff --git a/src/audacious/api.h b/src/audacious/api.h
deleted file mode 100644
index f68987a..0000000
--- a/src/audacious/api.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * api.h
- * Copyright 2010-2013 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.
- */
-
-#ifndef AUDACIOUS_API_H
-#define AUDACIOUS_API_H
-
-/* API version. Plugins are marked with this number at compile time.
- *
- * _AUD_PLUGIN_VERSION is the current version; _AUD_PLUGIN_VERSION_MIN is
- * the oldest one we are backward compatible with. Plugins marked older than
- * _AUD_PLUGIN_VERSION_MIN or newer than _AUD_PLUGIN_VERSION are not loaded.
- *
- * Before releases that add new pointers to the end of the API tables, increment
- * _AUD_PLUGIN_VERSION but leave _AUD_PLUGIN_VERSION_MIN the same.
- *
- * Before releases that break backward compatibility (e.g. remove pointers from
- * the API tables), increment _AUD_PLUGIN_VERSION *and* set
- * _AUD_PLUGIN_VERSION_MIN to the same value. */
-
-#define _AUD_PLUGIN_VERSION_MIN 45 /* 3.5-devel */
-#define _AUD_PLUGIN_VERSION 45 /* 3.5-devel */
-
-typedef const struct {
- const struct ConfigDBAPI * configdb_api;
- const struct DRCTAPI * drct_api;
- const struct InputAPI * input_api;
- const struct MiscAPI * misc_api;
- const struct PlaylistAPI * playlist_api;
- const struct PluginsAPI * plugins_api;
- char * verbose;
-} AudAPITable;
-
-#ifdef _AUDACIOUS_CORE
-extern char verbose;
-#else
-extern AudAPITable * _aud_api_table;
-#endif
-
-#endif
diff --git a/src/audacious/art.c b/src/audacious/art.c
deleted file mode 100644
index 24658a0..0000000
--- a/src/audacious/art.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * art.c
- * Copyright 2011-2012 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 <assert.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-
-#include "main.h"
-#include "misc.h"
-#include "playlist.h"
-#include "scanner.h"
-#include "util.h"
-
-#define FLAG_DONE 1
-#define FLAG_SENT 2
-
-typedef struct {
- int refcount;
- int flag;
-
- /* album art as JPEG or PNG data */
- void * data;
- int64_t len;
-
- /* album art as (possibly a temporary) file */
- char * art_file; /* pooled */
- bool_t is_temp;
-} ArtItem;
-
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static GHashTable * art_items; /* of ArtItem */
-static char * current_ref; /* pooled */
-static int send_source;
-
-static void art_item_free (ArtItem * item)
-{
- /* delete temporary file */
- if (item->art_file && item->is_temp)
- {
- char * unixname = uri_to_filename (item->art_file);
- if (unixname)
- {
- g_unlink (unixname);
- str_unref (unixname);
- }
- }
-
- g_free (item->data);
- str_unref (item->art_file);
- g_slice_free (ArtItem, item);
-}
-
-static bool_t send_requests (void * unused)
-{
- pthread_mutex_lock (& mutex);
-
- GQueue queue = G_QUEUE_INIT;
-
- GHashTableIter iter;
- void * ptr1, * ptr2;
-
- g_hash_table_iter_init (& iter, art_items);
- while (g_hash_table_iter_next (& iter, & ptr1, & ptr2))
- {
- char * file = ptr1;
- ArtItem * item = ptr2;
-
- if (item->flag == FLAG_DONE)
- {
- g_queue_push_tail (& queue, str_ref (file));
- item->flag = FLAG_SENT;
- }
- }
-
- if (send_source)
- {
- g_source_remove (send_source);
- send_source = 0;
- }
-
- pthread_mutex_unlock (& mutex);
-
- char * current = NULL;
- if (! current_ref)
- current = playback_entry_get_filename ();
-
- char * file;
- while ((file = g_queue_pop_head (& queue)))
- {
- hook_call ("art ready", file);
-
- if (current && ! strcmp (file, current))
- {
- hook_call ("current art ready", file);
- current_ref = file;
- }
- else
- {
- art_unref (file); /* release temporary reference */
- str_unref (file);
- }
- }
-
- str_unref (current);
- return FALSE;
-}
-
-static void request_callback (ScanRequest * request)
-{
- pthread_mutex_lock (& mutex);
-
- const char * file = scan_request_get_filename (request);
- ArtItem * item = g_hash_table_lookup (art_items, file);
- assert (item != NULL && ! item->flag);
-
- scan_request_get_image_data (request, & item->data, & item->len);
- item->art_file = str_get (scan_request_get_image_file (request));
- item->flag = FLAG_DONE;
-
- if (! send_source)
- send_source = g_idle_add (send_requests, NULL);
-
- pthread_mutex_unlock (& mutex);
-}
-
-static ArtItem * art_item_get (const char * file)
-{
- ArtItem * item = g_hash_table_lookup (art_items, file);
-
- if (item && item->flag)
- {
- item->refcount ++;
- return item;
- }
-
- if (! item)
- {
- item = g_slice_new0 (ArtItem);
- g_hash_table_insert (art_items, str_get (file), item);
- item->refcount = 1; /* temporary reference */
-
- scan_request (file, SCAN_IMAGE, NULL, request_callback);
- }
-
- return NULL;
-}
-
-static void art_item_unref (const char * file, ArtItem * item)
-{
- if (! -- item->refcount)
- g_hash_table_remove (art_items, file);
-}
-
-static void release_current (void)
-{
- if (current_ref)
- {
- art_unref (current_ref);
- str_unref (current_ref);
- current_ref = NULL;
- }
-}
-
-void art_init (void)
-{
- art_items = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) str_unref, (GDestroyNotify) art_item_free);
-
- hook_associate ("playlist position", (HookFunction) release_current, NULL);
- hook_associate ("playlist set playing", (HookFunction) release_current, NULL);
-}
-
-void art_cleanup (void)
-{
- hook_dissociate ("playlist position", (HookFunction) release_current);
- hook_dissociate ("playlist set playing", (HookFunction) release_current);
-
- if (send_source)
- {
- g_source_remove (send_source);
- send_source = 0;
- }
-
- release_current ();
-
- g_hash_table_destroy (art_items);
- art_items = NULL;
-}
-
-void art_request_data (const char * file, const void * * data, int64_t * len)
-{
- * data = NULL;
- * len = 0;
-
- pthread_mutex_lock (& mutex);
-
- ArtItem * item = art_item_get (file);
- if (! item)
- goto UNLOCK;
-
- /* load data from external image file */
- if (! item->data && item->art_file)
- vfs_file_get_contents (item->art_file, & item->data, & item->len);
-
- if (item->data)
- {
- * data = item->data;
- * len = item->len;
- }
- else
- art_item_unref (file, item);
-
-UNLOCK:
- pthread_mutex_unlock (& mutex);
-}
-
-const char * art_request_file (const char * file)
-{
- const char * art_file = NULL;
- pthread_mutex_lock (& mutex);
-
- ArtItem * item = art_item_get (file);
- if (! item)
- goto UNLOCK;
-
- /* save data to temporary file */
- if (item->data && ! item->art_file)
- {
- char * unixname = write_temp_file (item->data, item->len);
- if (unixname)
- {
- item->art_file = filename_to_uri (unixname);
- item->is_temp = TRUE;
- str_unref (unixname);
- }
- }
-
- if (item->art_file)
- art_file = item->art_file;
- else
- art_item_unref (file, item);
-
-UNLOCK:
- pthread_mutex_unlock (& mutex);
- return art_file;
-}
-
-void art_unref (const char * file)
-{
- pthread_mutex_lock (& mutex);
-
- ArtItem * item = g_hash_table_lookup (art_items, file);
- assert (item != NULL);
-
- art_item_unref (file, item);
-
- pthread_mutex_unlock (& mutex);
-}
diff --git a/src/audacious/audacious.rc b/src/audacious/audacious.rc
index b37beeb..c7b9839 100644
--- a/src/audacious/audacious.rc
+++ b/src/audacious/audacious.rc
@@ -4,4 +4,4 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#define IDI_ICON_AUDACIOUS 102
-IDI_ICON_AUDACIOUS ICON "../../pixmaps/audacious.ico"
+IDI_ICON_AUDACIOUS ICON "../../images/audacious.ico"
diff --git a/src/audacious/chardet.c b/src/audacious/chardet.c
deleted file mode 100644
index 08fe97e..0000000
--- a/src/audacious/chardet.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * chardet.c
- * Copyright 2013 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 <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-
-#include "main.h"
-#include "misc.h"
-
-static void chardet_update (void)
-{
- char * region = get_str (NULL, "chardet_detector");
- char * fallbacks = get_str (NULL, "chardet_fallback");
-
- Index * list = str_list_to_index (fallbacks, ", ");
- str_set_charsets (region[0] ? region : NULL, list);
-
- str_unref (region);
- str_unref (fallbacks);
-}
-
-void chardet_init (void)
-{
- chardet_update ();
-
- hook_associate ("set chardet_detector", (HookFunction) chardet_update, NULL);
- hook_associate ("set chardet_fallback", (HookFunction) chardet_update, NULL);
-}
-
-void chardet_cleanup (void)
-{
- hook_dissociate ("set chardet_detector", (HookFunction) chardet_update);
- hook_dissociate ("set chardet_fallback", (HookFunction) chardet_update);
-
- str_set_charsets (NULL, NULL);
-}
diff --git a/src/audacious/config.c b/src/audacious/config.c
deleted file mode 100644
index 0bc4966..0000000
--- a/src/audacious/config.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * config.c
- * Copyright 2011-2013 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 <glib.h>
-#include <string.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudcore/inifile.h>
-#include <libaudcore/multihash.h>
-
-#include "main.h"
-#include "misc.h"
-
-#define DEFAULT_SECTION "audacious"
-
-static const char * const core_defaults[] = {
-
- /* general */
- "advance_on_delete", "FALSE",
- "clear_playlist", "TRUE",
- "open_to_temporary", "TRUE",
- "resume_playback_on_startup", "FALSE",
- "show_interface", "TRUE",
-
- /* equalizer */
- "eqpreset_default_file", "",
- "eqpreset_extension", "",
- "equalizer_active", "FALSE",
- "equalizer_autoload", "FALSE",
- "equalizer_bands", "0,0,0,0,0,0,0,0,0,0",
- "equalizer_preamp", "0",
-
- /* info popup / info window */
- "cover_name_exclude", "back",
- "cover_name_include", "album,cover,front,folder",
- "filepopup_delay", "5",
- "filepopup_showprogressbar", "TRUE",
- "recurse_for_cover", "FALSE",
- "recurse_for_cover_depth", "0",
- "show_filepopup_for_tuple", "TRUE",
- "use_file_cover", "FALSE",
-
- /* network */
- "use_proxy", "FALSE",
- "use_proxy_auth", "FALSE",
-
- /* output */
- "default_gain", "0",
- "enable_replay_gain", "TRUE",
- "enable_clipping_prevention", "TRUE",
- "output_bit_depth", "16",
- "output_buffer_size", "500",
- "replay_gain_album", "FALSE",
- "replay_gain_preamp", "0",
- "soft_clipping", "FALSE",
- "software_volume_control", "FALSE",
- "sw_volume_left", "100",
- "sw_volume_right", "100",
-
- /* playback */
- "no_playlist_advance", "FALSE",
- "repeat", "FALSE",
- "shuffle", "FALSE",
- "stop_after_current_song", "FALSE",
-
- /* playlist */
- "chardet_fallback", "ISO-8859-1",
-#ifdef _WIN32
- "convert_backslash", "TRUE",
-#else
- "convert_backslash", "FALSE",
-#endif
- "generic_title_format", "${?artist:${artist} - }${?album:${album} - }${title}",
- "leading_zero", "FALSE",
- "metadata_on_play", "FALSE",
- "show_numbers_in_pl", "FALSE",
-
- NULL};
-
-typedef enum {
- OP_IS_DEFAULT,
- OP_GET,
- OP_SET,
- OP_SET_NO_FLAG,
- OP_CLEAR,
- OP_CLEAR_NO_FLAG
-} OpType;
-
-typedef struct {
- const char * section;
- const char * key;
- const char * value;
-} ConfigItem;
-
-typedef struct {
- MultihashNode node;
- ConfigItem item;
-} ConfigNode;
-
-typedef struct {
- OpType type;
- ConfigItem item;
- unsigned hash;
- bool_t result;
-} ConfigOp;
-
-typedef struct {
- char * section;
-} LoadState;
-
-typedef struct {
- GArray * list;
-} SaveState;
-
-static unsigned item_hash (const ConfigItem * item)
-{
- return g_str_hash (item->section) + g_str_hash (item->key);
-}
-
-/* assumes pooled strings */
-static int item_compare (const ConfigItem * a, const ConfigItem * b)
-{
- if (str_equal (a->section, b->section))
- return strcmp (a->key, b->key);
- else
- return strcmp (a->section, b->section);
-}
-
-/* assumes pooled strings */
-static void item_clear (ConfigItem * item)
-{
- str_unref ((char *) item->section);
- str_unref ((char *) item->key);
- str_unref ((char *) item->value);
-}
-
-static unsigned config_node_hash (const MultihashNode * node0)
-{
- const ConfigNode * node = (const ConfigNode *) node0;
-
- return item_hash (& node->item);
-}
-
-static bool_t config_node_match (const MultihashNode * node0, const void * data, unsigned hash)
-{
- const ConfigNode * node = (const ConfigNode *) node0;
- const ConfigItem * item = data;
-
- return ! strcmp (node->item.section, item->section) && ! strcmp (node->item.key, item->key);
-}
-
-static MultihashTable defaults = {
- .hash_func = config_node_hash,
- .match_func = config_node_match
-};
-
-static MultihashTable config = {
- .hash_func = config_node_hash,
- .match_func = config_node_match
-};
-
-static volatile bool_t modified;
-
-static MultihashNode * add_cb (const void * data, unsigned hash, void * state)
-{
- ConfigOp * op = state;
-
- switch (op->type)
- {
- case OP_IS_DEFAULT:
- op->result = ! op->item.value[0]; /* empty string is default */
- return NULL;
-
- case OP_SET:
- op->result = TRUE;
- modified = TRUE;
-
- case OP_SET_NO_FLAG:;
- ConfigNode * node = g_slice_new (ConfigNode);
- node->item.section = str_get (op->item.section);
- node->item.key = str_get (op->item.key);
- node->item.value = str_get (op->item.value);
- return (MultihashNode *) node;
-
- default:
- return NULL;
- }
-}
-
-static bool_t action_cb (MultihashNode * node0, void * state)
-{
- ConfigNode * node = (ConfigNode *) node0;
- ConfigOp * op = state;
-
- switch (op->type)
- {
- case OP_IS_DEFAULT:
- op->result = ! strcmp (node->item.value, op->item.value);
- return FALSE;
-
- case OP_GET:
- op->item.value = str_ref (node->item.value);
- return FALSE;
-
- case OP_SET:
- op->result = !! strcmp (node->item.value, op->item.value);
- if (op->result)
- modified = TRUE;
-
- case OP_SET_NO_FLAG:
- str_unref ((char *) node->item.value);
- node->item.value = str_get (op->item.value);
- return FALSE;
-
- case OP_CLEAR:
- op->result = TRUE;
- modified = TRUE;
-
- case OP_CLEAR_NO_FLAG:
- item_clear (& node->item);
- g_slice_free (ConfigNode, node);
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-static bool_t config_op_run (ConfigOp * op, OpType type, MultihashTable * table)
-{
- if (! op->hash)
- op->hash = item_hash (& op->item);
-
- op->type = type;
- op->result = FALSE;
- multihash_lookup (table, & op->item, op->hash, add_cb, action_cb, op);
- return op->result;
-}
-
-static void load_heading (const char * section, void * data)
-{
- LoadState * state = data;
-
- str_unref (state->section);
- state->section = str_get (section);
-}
-
-static void load_entry (const char * key, const char * value, void * data)
-{
- LoadState * state = data;
- g_return_if_fail (state->section);
-
- ConfigOp op = {.item = {state->section, key, value}};
- config_op_run (& op, OP_SET_NO_FLAG, & config);
-}
-
-void config_load (void)
-{
- char * folder = filename_to_uri (get_path (AUD_PATH_USER_DIR));
- SCONCAT2 (path, folder, "/config");
- str_unref (folder);
-
- if (vfs_file_test (path, VFS_EXISTS))
- {
- VFSFile * file = vfs_fopen (path, "r");
-
- if (file)
- {
- LoadState state = {0};
-
- inifile_parse (file, load_heading, load_entry, & state);
-
- str_unref (state.section);
- vfs_fclose (file);
- }
- }
-
- config_set_defaults (NULL, core_defaults);
-}
-
-static bool_t add_to_save_list (MultihashNode * node0, void * state0)
-{
- ConfigNode * node = (ConfigNode *) node0;
- SaveState * state = state0;
-
- int pos = state->list->len;
- g_array_set_size (state->list, pos + 1);
-
- ConfigItem * copy = & g_array_index (state->list, ConfigItem, pos);
- copy->section = str_ref (node->item.section);
- copy->key = str_ref (node->item.key);
- copy->value = str_ref (node->item.value);
-
- modified = FALSE;
-
- return FALSE;
-}
-
-void config_save (void)
-{
- if (! modified)
- return;
-
- SaveState state = {.list = g_array_new (FALSE, FALSE, sizeof (ConfigItem))};
-
- multihash_iterate (& config, add_to_save_list, & state);
- g_array_sort (state.list, (GCompareFunc) item_compare);
-
- char * folder = filename_to_uri (get_path (AUD_PATH_USER_DIR));
- SCONCAT2 (path, folder, "/config");
- str_unref (folder);
-
- VFSFile * file = vfs_fopen (path, "w");
-
- if (file)
- {
- const char * current_heading = NULL;
-
- for (int i = 0; i < state.list->len; i ++)
- {
- ConfigItem * item = & g_array_index (state.list, ConfigItem, i);
-
- if (! str_equal (item->section, current_heading))
- {
- inifile_write_heading (file, item->section);
- current_heading = item->section;
- }
-
- inifile_write_entry (file, item->key, item->value);
- }
-
- vfs_fclose (file);
- }
-
- g_array_set_clear_func (state.list, (GDestroyNotify) item_clear);
- g_array_free (state.list, TRUE);
-}
-
-void config_set_defaults (const char * section, const char * const * entries)
-{
- if (! section)
- section = DEFAULT_SECTION;
-
- while (1)
- {
- const char * name = * entries ++;
- const char * value = * entries ++;
- if (! name || ! value)
- break;
-
- ConfigOp op = {.item = {section, name, value}};
- config_op_run (& op, OP_SET_NO_FLAG, & defaults);
- }
-}
-
-void config_cleanup (void)
-{
- ConfigOp op = {.type = OP_CLEAR_NO_FLAG};
- multihash_iterate (& config, action_cb, & op);
- multihash_iterate (& defaults, action_cb, & op);
-}
-
-void set_str (const char * section, const char * name, const char * value)
-{
- g_return_if_fail (name && value);
-
- ConfigOp op = {.item = {section ? section : DEFAULT_SECTION, name, value}};
-
- bool_t is_default = config_op_run (& op, OP_IS_DEFAULT, & defaults);
- bool_t changed = config_op_run (& op, is_default ? OP_CLEAR : OP_SET, & config);
-
- if (changed && ! section)
- {
- SCONCAT2 (event, "set ", name);
- event_queue (event, NULL);
- }
-}
-
-char * get_str (const char * section, const char * name)
-{
- g_return_val_if_fail (name, NULL);
-
- ConfigOp op = {.item = {section ? section : DEFAULT_SECTION, name, NULL}};
-
- config_op_run (& op, OP_GET, & config);
-
- if (! op.item.value)
- config_op_run (& op, OP_GET, & defaults);
-
- return op.item.value ? (char *) op.item.value : str_get ("");
-}
-
-void set_bool (const char * section, const char * name, bool_t value)
-{
- set_str (section, name, value ? "TRUE" : "FALSE");
-}
-
-bool_t get_bool (const char * section, const char * name)
-{
- char * string = get_str (section, name);
- bool_t value = ! strcmp (string, "TRUE");
- str_unref (string);
- return value;
-}
-
-void set_int (const char * section, const char * name, int value)
-{
- char * string = int_to_str (value);
- g_return_if_fail (string);
- set_str (section, name, string);
- str_unref (string);
-}
-
-int get_int (const char * section, const char * name)
-{
- char * string = get_str (section, name);
- int value = str_to_int (string);
- str_unref (string);
- return value;
-}
-
-void set_double (const char * section, const char * name, double value)
-{
- char * string = double_to_str (value);
- g_return_if_fail (string);
- set_str (section, name, string);
- str_unref (string);
-}
-
-double get_double (const char * section, const char * name)
-{
- char * string = get_str (section, name);
- double value = str_to_double (string);
- str_unref (string);
- return value;
-}
diff --git a/src/audacious/dbus-server.c b/src/audacious/dbus-server.c
deleted file mode 100644
index af55f20..0000000
--- a/src/audacious/dbus-server.c
+++ /dev/null
@@ -1,779 +0,0 @@
-/*
- * dbus-server.c
- * Copyright 2013 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 <stdio.h>
-
-#include <libaudgui/libaudgui.h>
-
-#include "aud-dbus.h"
-#include "drct.h"
-#include "main.h"
-#include "misc.h"
-#include "playlist.h"
-#include "ui_preferences.h"
-
-typedef ObjAudacious Obj;
-typedef GDBusMethodInvocation Invoc;
-
-#define FINISH(name) \
- obj_audacious_complete_##name (obj, invoc)
-
-#define FINISH2(name, ...) \
- obj_audacious_complete_##name (obj, invoc, __VA_ARGS__)
-
-static Index * strv_to_index (const char * const * strv)
-{
- Index * index = index_new ();
- while (* strv)
- index_insert (index, -1, str_get (* strv ++));
-
- return index;
-}
-
-static bool_t do_add (Obj * obj, Invoc * invoc, const char * file)
-{
- playlist_entry_insert (playlist_get_active (), -1, file, NULL, FALSE);
- FINISH (add);
- return TRUE;
-}
-
-static bool_t do_add_list (Obj * obj, Invoc * invoc, const char * const * filenames)
-{
- playlist_entry_insert_batch (playlist_get_active (), -1,
- strv_to_index (filenames), NULL, FALSE);
- FINISH (add_list);
- return TRUE;
-}
-
-static bool_t do_add_url (Obj * obj, Invoc * invoc, const char * url)
-{
- playlist_entry_insert (playlist_get_active (), -1, url, NULL, FALSE);
- FINISH (add_url);
- return TRUE;
-}
-
-static bool_t do_advance (Obj * obj, Invoc * invoc)
-{
- drct_pl_next ();
- FINISH (advance);
- return TRUE;
-}
-
-static bool_t do_auto_advance (Obj * obj, Invoc * invoc)
-{
- FINISH2 (auto_advance, ! get_bool (NULL, "no_playlist_advance"));
- return TRUE;
-}
-
-static bool_t do_balance (Obj * obj, Invoc * invoc)
-{
- int balance;
- drct_get_volume_balance (& balance);
- FINISH2 (balance, balance);
- return TRUE;
-}
-
-static bool_t do_clear (Obj * obj, Invoc * invoc)
-{
- int playlist = playlist_get_active ();
- playlist_entry_delete (playlist, 0, playlist_entry_count (playlist));
- FINISH (clear);
- return TRUE;
-}
-
-static bool_t do_delete (Obj * obj, Invoc * invoc, unsigned pos)
-{
- playlist_entry_delete (playlist_get_active (), pos, 1);
- FINISH (delete);
- return TRUE;
-}
-
-static bool_t do_delete_active_playlist (Obj * obj, Invoc * invoc)
-{
- playlist_delete (playlist_get_active ());
- FINISH (delete_active_playlist);
- return TRUE;
-}
-
-static bool_t do_eject (Obj * obj, Invoc * invoc)
-{
- if (! headless_mode ())
- audgui_run_filebrowser (TRUE);
-
- FINISH (eject);
- return TRUE;
-}
-
-static bool_t do_equalizer_activate (Obj * obj, Invoc * invoc, bool_t active)
-{
- set_bool (NULL, "equalizer_active", active);
- FINISH (equalizer_activate);
- return TRUE;
-}
-
-static bool_t do_get_active_playlist (Obj * obj, Invoc * invoc)
-{
- FINISH2 (get_active_playlist, playlist_get_active ());
- return TRUE;
-}
-
-static bool_t do_get_active_playlist_name (Obj * obj, Invoc * invoc)
-{
- char * title = playlist_get_title (playlist_get_active ());
- FINISH2 (get_active_playlist_name, title ? title : "");
- str_unref (title);
- return TRUE;
-}
-
-static bool_t do_get_eq (Obj * obj, Invoc * invoc)
-{
- double preamp = get_double (NULL, "equalizer_preamp");
- double bands[AUD_EQUALIZER_NBANDS];
- eq_get_bands (bands);
-
- GVariant * var = g_variant_new_fixed_array (G_VARIANT_TYPE_DOUBLE, bands,
- AUD_EQUALIZER_NBANDS, sizeof (double));
- FINISH2 (get_eq, preamp, var);
- return TRUE;
-}
-
-static bool_t do_get_eq_band (Obj * obj, Invoc * invoc, int band)
-{
- FINISH2 (get_eq_band, eq_get_band (band));
- return TRUE;
-}
-
-static bool_t do_get_eq_preamp (Obj * obj, Invoc * invoc)
-{
- FINISH2 (get_eq_preamp, get_double (NULL, "equalizer_preamp"));
- return TRUE;
-}
-
-static bool_t do_get_info (Obj * obj, Invoc * invoc)
-{
- int bitrate, samplerate, channels;
- drct_get_info (& bitrate, & samplerate, & channels);
- FINISH2 (get_info, bitrate, samplerate, channels);
- return TRUE;
-}
-
-static bool_t do_get_playqueue_length (Obj * obj, Invoc * invoc)
-{
- FINISH2 (get_playqueue_length, playlist_queue_count (playlist_get_active ()));
- return TRUE;
-}
-
-static bool_t do_get_tuple_fields (Obj * obj, Invoc * invoc)
-{
- const char * fields[TUPLE_FIELDS + 1];
-
- for (int i = 0; i < TUPLE_FIELDS; i ++)
- fields[i] = tuple_field_get_name (i);
-
- fields[TUPLE_FIELDS] = NULL;
-
- FINISH2 (get_tuple_fields, fields);
- return TRUE;
-}
-
-static bool_t do_info (Obj * obj, Invoc * invoc)
-{
- int bitrate, samplerate, channels;
- drct_get_info (& bitrate, & samplerate, & channels);
- FINISH2 (info, bitrate, samplerate, channels);
- return TRUE;
-}
-
-static bool_t do_jump (Obj * obj, Invoc * invoc, unsigned pos)
-{
- playlist_set_position (playlist_get_active (), pos);
- FINISH (jump);
- return TRUE;
-}
-
-static bool_t do_length (Obj * obj, Invoc * invoc)
-{
- FINISH2 (length, playlist_entry_count (playlist_get_active ()));
- return TRUE;
-}
-
-static bool_t do_main_win_visible (Obj * obj, Invoc * invoc)
-{
- FINISH2 (main_win_visible, ! headless_mode () && interface_is_shown ());
- return TRUE;
-}
-
-static bool_t do_new_playlist (Obj * obj, Invoc * invoc)
-{
- playlist_insert (-1);
- playlist_set_active (playlist_count () - 1);
- FINISH (new_playlist);
- return TRUE;
-}
-
-static bool_t do_number_of_playlists (Obj * obj, Invoc * invoc)
-{
- FINISH2 (number_of_playlists, playlist_count ());
- return TRUE;
-}
-
-static bool_t do_open_list (Obj * obj, Invoc * invoc, const char * const * filenames)
-{
- drct_pl_open_list (strv_to_index (filenames));
- FINISH (open_list);
- return TRUE;
-}
-
-static bool_t do_open_list_to_temp (Obj * obj, Invoc * invoc, const char * const * filenames)
-{
- drct_pl_open_temp_list (strv_to_index (filenames));
- FINISH (open_list_to_temp);
- return TRUE;
-}
-
-static bool_t do_pause (Obj * obj, Invoc * invoc)
-{
- drct_pause ();
- FINISH (pause);
- return TRUE;
-}
-
-static bool_t do_paused (Obj * obj, Invoc * invoc)
-{
- FINISH2 (paused, drct_get_paused ());
- return TRUE;
-}
-
-static bool_t do_play (Obj * obj, Invoc * invoc)
-{
- drct_play ();
- FINISH (play);
- return TRUE;
-}
-
-static bool_t do_play_active_playlist (Obj * obj, Invoc * invoc)
-{
- drct_play_playlist (playlist_get_active ());
- FINISH (play_active_playlist);
- return TRUE;
-}
-
-static bool_t do_play_pause (Obj * obj, Invoc * invoc)
-{
- drct_play_pause ();
- FINISH (play_pause);
- return TRUE;
-}
-
-static bool_t do_playing (Obj * obj, Invoc * invoc)
-{
- FINISH2 (playing, drct_get_playing ());
- return TRUE;
-}
-
-static bool_t do_playlist_add (Obj * obj, Invoc * invoc, const char * list)
-{
- playlist_entry_insert (playlist_get_active (), -1, list, NULL, FALSE);
- FINISH (playlist_add);
- return TRUE;
-}
-
-static bool_t do_playlist_enqueue_to_temp (Obj * obj, Invoc * invoc, const char * url)
-{
- drct_pl_open_temp (url);
- FINISH (playlist_enqueue_to_temp);
- return TRUE;
-}
-
-static bool_t do_playlist_ins_url_string (Obj * obj, Invoc * invoc, const char * url, int pos)
-{
- playlist_entry_insert (playlist_get_active (), pos, url, NULL, FALSE);
- FINISH (playlist_ins_url_string);
- return TRUE;
-}
-
-static bool_t do_playqueue_add (Obj * obj, Invoc * invoc, int pos)
-{
- playlist_queue_insert (playlist_get_active (), -1, pos);
- FINISH (playqueue_add);
- return TRUE;
-}
-
-static bool_t do_playqueue_clear (Obj * obj, Invoc * invoc)
-{
- int playlist = playlist_get_active ();
- playlist_queue_delete (playlist, 0, playlist_queue_count (playlist));
- FINISH (playqueue_clear);
- return TRUE;
-}
-
-static bool_t do_playqueue_is_queued (Obj * obj, Invoc * invoc, int pos)
-{
- bool_t queued = (playlist_queue_find_entry (playlist_get_active (), pos) >= 0);
- FINISH2 (playqueue_is_queued, queued);
- return TRUE;
-}
-
-static bool_t do_playqueue_remove (Obj * obj, Invoc * invoc, int pos)
-{
- int playlist = playlist_get_active ();
- int qpos = playlist_queue_find_entry (playlist, pos);
-
- if (qpos >= 0)
- playlist_queue_delete (playlist, qpos, 1);
-
- FINISH (playqueue_remove);
- return TRUE;
-}
-
-static bool_t do_position (Obj * obj, Invoc * invoc)
-{
- FINISH2 (position, playlist_get_position (playlist_get_active ()));
- return TRUE;
-}
-
-static bool_t do_queue_get_list_pos (Obj * obj, Invoc * invoc, unsigned qpos)
-{
- FINISH2 (queue_get_list_pos, playlist_queue_get_entry (playlist_get_active (), qpos));
- return TRUE;
-}
-
-static bool_t do_queue_get_queue_pos (Obj * obj, Invoc * invoc, unsigned pos)
-{
- FINISH2 (queue_get_queue_pos, playlist_queue_find_entry (playlist_get_active (), pos));
- return TRUE;
-}
-
-static bool_t do_quit (Obj * obj, Invoc * invoc)
-{
- drct_quit ();
- FINISH (quit);
- return TRUE;
-}
-
-static bool_t do_repeat (Obj * obj, Invoc * invoc)
-{
- FINISH2 (repeat, get_bool (NULL, "repeat"));
- return TRUE;
-}
-
-static bool_t do_reverse (Obj * obj, Invoc * invoc)
-{
- drct_pl_prev ();
- FINISH (reverse);
- return TRUE;
-}
-
-static bool_t do_seek (Obj * obj, Invoc * invoc, unsigned pos)
-{
- drct_seek (pos);
- FINISH (seek);
- return TRUE;
-}
-
-static bool_t do_set_active_playlist (Obj * obj, Invoc * invoc, int playlist)
-{
- playlist_set_active (playlist);
- FINISH (set_active_playlist);
- return TRUE;
-}
-
-static bool_t do_set_active_playlist_name (Obj * obj, Invoc * invoc, const char * title)
-{
- playlist_set_title (playlist_get_active (), title);
- FINISH (set_active_playlist_name);
- return TRUE;
-}
-
-static bool_t do_set_eq (Obj * obj, Invoc * invoc, double preamp, GVariant * var)
-{
- if (! g_variant_is_of_type (var, G_VARIANT_TYPE ("ad")))
- return FALSE;
-
- size_t nbands = 0;
- const double * bands = g_variant_get_fixed_array (var, & nbands, sizeof (double));
-
- if (nbands != AUD_EQUALIZER_NBANDS)
- return FALSE;
-
- set_double (NULL, "equalizer_preamp", preamp);
- eq_set_bands (bands);
- FINISH (set_eq);
- return TRUE;
-}
-
-static bool_t do_set_eq_band (Obj * obj, Invoc * invoc, int band, double value)
-{
- eq_set_band (band, value);
- FINISH (set_eq_band);
- return TRUE;
-}
-
-static bool_t do_set_eq_preamp (Obj * obj, Invoc * invoc, double preamp)
-{
- set_double (NULL, "equalizer_preamp", preamp);
- FINISH (set_eq_preamp);
- return TRUE;
-}
-
-static bool_t do_set_volume (Obj * obj, Invoc * invoc, int vl, int vr)
-{
- drct_set_volume (vl, vr);
- FINISH (set_volume);
- return TRUE;
-}
-
-static bool_t do_show_about_box (Obj * obj, Invoc * invoc, bool_t show)
-{
- if (! headless_mode ())
- {
- if (show)
- audgui_show_about_window ();
- else
- audgui_hide_about_window ();
- }
-
- FINISH (show_about_box);
- return TRUE;
-}
-
-static bool_t do_show_filebrowser (Obj * obj, Invoc * invoc, bool_t show)
-{
- if (! headless_mode ())
- {
- if (show)
- audgui_run_filebrowser (FALSE);
- else
- audgui_hide_filebrowser ();
- }
-
- FINISH (show_filebrowser);
- return TRUE;
-}
-
-static bool_t do_show_jtf_box (Obj * obj, Invoc * invoc, bool_t show)
-{
- if (! headless_mode ())
- {
- if (show)
- audgui_jump_to_track ();
- else
- audgui_jump_to_track_hide ();
- }
-
- FINISH (show_jtf_box);
- return TRUE;
-}
-
-static bool_t do_show_main_win (Obj * obj, Invoc * invoc, bool_t show)
-{
- if (! headless_mode ())
- interface_show (show);
-
- FINISH (show_main_win);
- return TRUE;
-}
-
-static bool_t do_show_prefs_box (Obj * obj, Invoc * invoc, bool_t show)
-{
- if (! headless_mode ())
- {
- if (show)
- show_prefs_window ();
- else
- hide_prefs_window ();
- }
-
- FINISH (show_prefs_box);
- return TRUE;
-}
-
-static bool_t do_shuffle (Obj * obj, Invoc * invoc)
-{
- FINISH2 (shuffle, get_bool (NULL, "shuffle"));
- return TRUE;
-}
-
-static bool_t do_song_filename (Obj * obj, Invoc * invoc, unsigned pos)
-{
- char * filename = playlist_entry_get_filename (playlist_get_active (), pos);
- FINISH2 (song_filename, filename ? filename : "");
- str_unref (filename);
- return TRUE;
-}
-
-static bool_t do_song_frames (Obj * obj, Invoc * invoc, unsigned pos)
-{
- FINISH2 (song_frames, playlist_entry_get_length (playlist_get_active (), pos, FALSE));
- return TRUE;
-}
-
-static bool_t do_song_length (Obj * obj, Invoc * invoc, unsigned pos)
-{
- int length = playlist_entry_get_length (playlist_get_active (), pos, FALSE);
- FINISH2 (song_length, length >= 0 ? length / 1000 : -1);
- return TRUE;
-}
-
-static bool_t do_song_title (Obj * obj, Invoc * invoc, unsigned pos)
-{
- char * title = playlist_entry_get_title (playlist_get_active (), pos, FALSE);
- FINISH2 (song_title, title ? title : "");
- str_unref (title);
- return TRUE;
-}
-
-static bool_t do_song_tuple (Obj * obj, Invoc * invoc, unsigned pos, const char * key)
-{
- int field = tuple_field_by_name (key);
- Tuple * tuple = NULL;
- GVariant * var = NULL;
-
- if (field >= 0)
- tuple = playlist_entry_get_tuple (playlist_get_active (), pos, FALSE);
-
- if (tuple)
- {
- char * str;
-
- switch (tuple_get_value_type (tuple, field))
- {
- case TUPLE_STRING:
- str = tuple_get_str (tuple, field);
- var = g_variant_new_string (str);
- str_unref (str);
- break;
-
- case TUPLE_INT:
- var = g_variant_new_int32 (tuple_get_int (tuple, field));
- break;
-
- default:
- break;
- }
-
- tuple_unref (tuple);
- }
-
- if (! var)
- var = g_variant_new_string ("");
-
- FINISH2 (song_tuple, g_variant_new_variant (var));
- return TRUE;
-}
-
-static bool_t do_status (Obj * obj, Invoc * invoc)
-{
- const char * status = "stopped";
- if (drct_get_playing ())
- status = drct_get_paused () ? "paused" : "playing";
-
- FINISH2 (status, status);
- return TRUE;
-}
-
-static bool_t do_stop (Obj * obj, Invoc * invoc)
-{
- drct_stop ();
- FINISH (stop);
- return TRUE;
-}
-
-static bool_t do_stop_after (Obj * obj, Invoc * invoc)
-{
- FINISH2 (stop_after, get_bool (NULL, "stop_after_current_song"));
- return TRUE;
-}
-
-static bool_t do_stopped (Obj * obj, Invoc * invoc)
-{
- FINISH2 (stopped, ! drct_get_playing ());
- return TRUE;
-}
-
-static bool_t do_time (Obj * obj, Invoc * invoc)
-{
- FINISH2 (time, drct_get_time ());
- return TRUE;
-}
-
-static bool_t do_toggle_auto_advance (Obj * obj, Invoc * invoc)
-{
- set_bool (NULL, "no_playlist_advance", ! get_bool (NULL, "no_playlist_advance"));
- FINISH (toggle_auto_advance);
- return TRUE;
-}
-
-static bool_t do_toggle_repeat (Obj * obj, Invoc * invoc)
-{
- set_bool (NULL, "repeat", ! get_bool (NULL, "repeat"));
- FINISH (toggle_repeat);
- return TRUE;
-}
-
-static bool_t do_toggle_shuffle (Obj * obj, Invoc * invoc)
-{
- set_bool (NULL, "shuffle", ! get_bool (NULL, "shuffle"));
- FINISH (toggle_shuffle);
- return TRUE;
-}
-
-static bool_t do_toggle_stop_after (Obj * obj, Invoc * invoc)
-{
- set_bool (NULL, "stop_after_current_song", ! get_bool (NULL, "stop_after_current_song"));
- FINISH (toggle_stop_after);
- return TRUE;
-}
-
-static bool_t do_version (Obj * obj, Invoc * invoc)
-{
- FINISH2 (version, VERSION);
- return TRUE;
-}
-
-static bool_t do_volume (Obj * obj, Invoc * invoc)
-{
- int left, right;
- drct_get_volume (& left, & right);
- FINISH2 (volume, left, right);
- return TRUE;
-}
-
-static const struct
-{
- const char * signal;
- GCallback callback;
-}
-handlers[] =
-{
- {"handle-add", (GCallback) do_add},
- {"handle-add-list", (GCallback) do_add_list},
- {"handle-add-url", (GCallback) do_add_url},
- {"handle-advance", (GCallback) do_advance},
- {"handle-auto-advance", (GCallback) do_auto_advance},
- {"handle-balance", (GCallback) do_balance},
- {"handle-clear", (GCallback) do_clear},
- {"handle-delete", (GCallback) do_delete},
- {"handle-delete-active-playlist", (GCallback) do_delete_active_playlist},
- {"handle-eject", (GCallback) do_eject},
- {"handle-equalizer-activate", (GCallback) do_equalizer_activate},
- {"handle-get-active-playlist", (GCallback) do_get_active_playlist},
- {"handle-get-active-playlist-name", (GCallback) do_get_active_playlist_name},
- {"handle-get-eq", (GCallback) do_get_eq},
- {"handle-get-eq-band", (GCallback) do_get_eq_band},
- {"handle-get-eq-preamp", (GCallback) do_get_eq_preamp},
- {"handle-get-info", (GCallback) do_get_info},
- {"handle-get-playqueue-length", (GCallback) do_get_playqueue_length},
- {"handle-get-tuple-fields", (GCallback) do_get_tuple_fields},
- {"handle-info", (GCallback) do_info},
- {"handle-jump", (GCallback) do_jump},
- {"handle-length", (GCallback) do_length},
- {"handle-main-win-visible", (GCallback) do_main_win_visible},
- {"handle-new-playlist", (GCallback) do_new_playlist},
- {"handle-number-of-playlists", (GCallback) do_number_of_playlists},
- {"handle-open-list", (GCallback) do_open_list},
- {"handle-open-list-to-temp", (GCallback) do_open_list_to_temp},
- {"handle-pause", (GCallback) do_pause},
- {"handle-paused", (GCallback) do_paused},
- {"handle-play", (GCallback) do_play},
- {"handle-play-active-playlist", (GCallback) do_play_active_playlist},
- {"handle-play-pause", (GCallback) do_play_pause},
- {"handle-playing", (GCallback) do_playing},
- {"handle-playlist-add", (GCallback) do_playlist_add},
- {"handle-playlist-enqueue-to-temp", (GCallback) do_playlist_enqueue_to_temp},
- {"handle-playlist-ins-url-string", (GCallback) do_playlist_ins_url_string},
- {"handle-playqueue-add", (GCallback) do_playqueue_add},
- {"handle-playqueue-clear", (GCallback) do_playqueue_clear},
- {"handle-playqueue-is-queued", (GCallback) do_playqueue_is_queued},
- {"handle-playqueue-remove", (GCallback) do_playqueue_remove},
- {"handle-position", (GCallback) do_position},
- {"handle-queue-get-list-pos", (GCallback) do_queue_get_list_pos},
- {"handle-queue-get-queue-pos", (GCallback) do_queue_get_queue_pos},
- {"handle-quit", (GCallback) do_quit},
- {"handle-repeat", (GCallback) do_repeat},
- {"handle-reverse", (GCallback) do_reverse},
- {"handle-seek", (GCallback) do_seek},
- {"handle-set-active-playlist", (GCallback) do_set_active_playlist},
- {"handle-set-active-playlist-name", (GCallback) do_set_active_playlist_name},
- {"handle-set-eq", (GCallback) do_set_eq},
- {"handle-set-eq-band", (GCallback) do_set_eq_band},
- {"handle-set-eq-preamp", (GCallback) do_set_eq_preamp},
- {"handle-set-volume", (GCallback) do_set_volume},
- {"handle-show-about-box", (GCallback) do_show_about_box},
- {"handle-show-filebrowser", (GCallback) do_show_filebrowser},
- {"handle-show-jtf-box", (GCallback) do_show_jtf_box},
- {"handle-show-main-win", (GCallback) do_show_main_win},
- {"handle-show-prefs-box", (GCallback) do_show_prefs_box},
- {"handle-shuffle", (GCallback) do_shuffle},
- {"handle-song-filename", (GCallback) do_song_filename},
- {"handle-song-frames", (GCallback) do_song_frames},
- {"handle-song-length", (GCallback) do_song_length},
- {"handle-song-title", (GCallback) do_song_title},
- {"handle-song-tuple", (GCallback) do_song_tuple},
- {"handle-status", (GCallback) do_status},
- {"handle-stop", (GCallback) do_stop},
- {"handle-stop-after", (GCallback) do_stop_after},
- {"handle-stopped", (GCallback) do_stopped},
- {"handle-time", (GCallback) do_time},
- {"handle-toggle-auto-advance", (GCallback) do_toggle_auto_advance},
- {"handle-toggle-repeat", (GCallback) do_toggle_repeat},
- {"handle-toggle-shuffle", (GCallback) do_toggle_shuffle},
- {"handle-toggle-stop-after", (GCallback) do_toggle_stop_after},
- {"handle-version", (GCallback) do_version},
- {"handle-volume", (GCallback) do_volume}
-};
-
-static GDBusInterfaceSkeleton * skeleton = NULL;
-
-void dbus_server_init (void)
-{
- GError * error = NULL;
- GDBusConnection * bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, & error);
-
- if (! bus)
- goto ERROR;
-
- g_bus_own_name_on_connection (bus, "org.atheme.audacious", 0, NULL, NULL, NULL, NULL);
-
- skeleton = (GDBusInterfaceSkeleton *) obj_audacious_skeleton_new ();
-
- for (int i = 0; i < ARRAY_LEN (handlers); i ++)
- g_signal_connect (skeleton, handlers[i].signal, handlers[i].callback, NULL);
-
- if (! g_dbus_interface_skeleton_export (skeleton, bus, "/org/atheme/audacious", & error))
- goto ERROR;
-
- return;
-
-ERROR:
- if (error)
- {
- fprintf (stderr, "D-Bus error: %s\n", error->message);
- g_error_free (error);
- }
-}
-
-void dbus_server_cleanup (void)
-{
- if (skeleton)
- {
- g_object_unref (skeleton);
- skeleton = NULL;
- }
-}
diff --git a/src/audacious/dbus-server.cc b/src/audacious/dbus-server.cc
new file mode 100644
index 0000000..90f464e
--- /dev/null
+++ b/src/audacious/dbus-server.cc
@@ -0,0 +1,815 @@
+/*
+ * dbus-server.c
+ * Copyright 2013 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 <libaudcore/drct.h>
+#include <libaudcore/equalizer.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/tuple.h>
+
+#include "aud-dbus.h"
+#include "main.h"
+
+typedef ObjAudacious Obj;
+typedef GDBusMethodInvocation Invoc;
+
+#define FINISH(name) \
+ obj_audacious_complete_##name (obj, invoc)
+
+#define FINISH2(name, ...) \
+ obj_audacious_complete_##name (obj, invoc, __VA_ARGS__)
+
+static Index<PlaylistAddItem> strv_to_index (const char * const * strv)
+{
+ Index<PlaylistAddItem> index;
+ while (* strv)
+ index.append (String (* strv ++));
+
+ return index;
+}
+
+static gboolean do_add (Obj * obj, Invoc * invoc, const char * file)
+{
+ aud_playlist_entry_insert (aud_playlist_get_active (), -1, file, Tuple (), false);
+ FINISH (add);
+ return true;
+}
+
+static gboolean do_add_list (Obj * obj, Invoc * invoc, const char * const * filenames)
+{
+ aud_playlist_entry_insert_batch (aud_playlist_get_active (), -1,
+ strv_to_index (filenames), false);
+ FINISH (add_list);
+ return true;
+}
+
+static gboolean do_add_url (Obj * obj, Invoc * invoc, const char * url)
+{
+ aud_playlist_entry_insert (aud_playlist_get_active (), -1, url, Tuple (), false);
+ FINISH (add_url);
+ return true;
+}
+
+static gboolean do_advance (Obj * obj, Invoc * invoc)
+{
+ aud_drct_pl_next ();
+ FINISH (advance);
+ return true;
+}
+
+static gboolean do_auto_advance (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (auto_advance, ! aud_get_bool (nullptr, "no_playlist_advance"));
+ return true;
+}
+
+static gboolean do_balance (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (balance, aud_drct_get_volume_balance ());
+ return true;
+}
+
+static gboolean do_clear (Obj * obj, Invoc * invoc)
+{
+ int playlist = aud_playlist_get_active ();
+ aud_playlist_entry_delete (playlist, 0, aud_playlist_entry_count (playlist));
+ FINISH (clear);
+ return true;
+}
+
+static gboolean do_delete (Obj * obj, Invoc * invoc, unsigned pos)
+{
+ aud_playlist_entry_delete (aud_playlist_get_active (), pos, 1);
+ FINISH (delete);
+ return true;
+}
+
+static gboolean do_delete_active_playlist (Obj * obj, Invoc * invoc)
+{
+ aud_playlist_delete (aud_playlist_get_active ());
+ FINISH (delete_active_playlist);
+ return true;
+}
+
+static gboolean do_eject (Obj * obj, Invoc * invoc)
+{
+ if (! aud_get_headless_mode ())
+ aud_ui_show_filebrowser (true);
+
+ FINISH (eject);
+ return true;
+}
+
+static gboolean do_equalizer_activate (Obj * obj, Invoc * invoc, gboolean active)
+{
+ aud_set_bool (nullptr, "equalizer_active", active);
+ FINISH (equalizer_activate);
+ return true;
+}
+
+static gboolean do_get_active_playlist (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (get_active_playlist, aud_playlist_get_active ());
+ return true;
+}
+
+static gboolean do_get_active_playlist_name (Obj * obj, Invoc * invoc)
+{
+ String title = aud_playlist_get_title (aud_playlist_get_active ());
+ FINISH2 (get_active_playlist_name, title ? title : "");
+ return true;
+}
+
+static gboolean do_get_eq (Obj * obj, Invoc * invoc)
+{
+ double preamp = aud_get_double (nullptr, "equalizer_preamp");
+ double bands[AUD_EQ_NBANDS];
+ aud_eq_get_bands (bands);
+
+ GVariant * var = g_variant_new_fixed_array (G_VARIANT_TYPE_DOUBLE, bands,
+ AUD_EQ_NBANDS, sizeof (double));
+ FINISH2 (get_eq, preamp, var);
+ return true;
+}
+
+static gboolean do_get_eq_band (Obj * obj, Invoc * invoc, int band)
+{
+ FINISH2 (get_eq_band, aud_eq_get_band (band));
+ return true;
+}
+
+static gboolean do_get_eq_preamp (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (get_eq_preamp, aud_get_double (nullptr, "equalizer_preamp"));
+ return true;
+}
+
+static gboolean do_get_info (Obj * obj, Invoc * invoc)
+{
+ int bitrate, samplerate, channels;
+ aud_drct_get_info (bitrate, samplerate, channels);
+ FINISH2 (get_info, bitrate, samplerate, channels);
+ return true;
+}
+
+static gboolean do_get_playqueue_length (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (get_playqueue_length, aud_playlist_queue_count (aud_playlist_get_active ()));
+ return true;
+}
+
+static gboolean do_get_tuple_fields (Obj * obj, Invoc * invoc)
+{
+ const char * fields[Tuple::n_fields + 1];
+
+ for (auto f : Tuple::all_fields ())
+ fields[f] = Tuple::field_get_name (f);
+
+ fields[Tuple::n_fields] = nullptr;
+
+ FINISH2 (get_tuple_fields, fields);
+ return true;
+}
+
+static gboolean do_info (Obj * obj, Invoc * invoc)
+{
+ int bitrate, samplerate, channels;
+ aud_drct_get_info (bitrate, samplerate, channels);
+ FINISH2 (info, bitrate, samplerate, channels);
+ return true;
+}
+
+static gboolean do_jump (Obj * obj, Invoc * invoc, unsigned pos)
+{
+ aud_playlist_set_position (aud_playlist_get_active (), pos);
+ FINISH (jump);
+ return true;
+}
+
+static gboolean do_length (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (length, aud_playlist_entry_count (aud_playlist_get_active ()));
+ return true;
+}
+
+static gboolean do_main_win_visible (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (main_win_visible, ! aud_get_headless_mode () && aud_ui_is_shown ());
+ return true;
+}
+
+static gboolean do_new_playlist (Obj * obj, Invoc * invoc)
+{
+ aud_playlist_insert (-1);
+ aud_playlist_set_active (aud_playlist_count () - 1);
+ FINISH (new_playlist);
+ return true;
+}
+
+static gboolean do_number_of_playlists (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (number_of_playlists, aud_playlist_count ());
+ return true;
+}
+
+static gboolean do_open_list (Obj * obj, Invoc * invoc, const char * const * filenames)
+{
+ aud_drct_pl_open_list (strv_to_index (filenames));
+ FINISH (open_list);
+ return true;
+}
+
+static gboolean do_open_list_to_temp (Obj * obj, Invoc * invoc, const char * const * filenames)
+{
+ aud_drct_pl_open_temp_list (strv_to_index (filenames));
+ FINISH (open_list_to_temp);
+ return true;
+}
+
+static gboolean do_pause (Obj * obj, Invoc * invoc)
+{
+ aud_drct_pause ();
+ FINISH (pause);
+ return true;
+}
+
+static gboolean do_paused (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (paused, aud_drct_get_paused ());
+ return true;
+}
+
+static gboolean do_play (Obj * obj, Invoc * invoc)
+{
+ aud_drct_play ();
+ FINISH (play);
+ return true;
+}
+
+static gboolean do_play_active_playlist (Obj * obj, Invoc * invoc)
+{
+ aud_playlist_play (aud_playlist_get_active ());
+ FINISH (play_active_playlist);
+ return true;
+}
+
+static gboolean do_play_pause (Obj * obj, Invoc * invoc)
+{
+ aud_drct_play_pause ();
+ FINISH (play_pause);
+ return true;
+}
+
+static gboolean do_playing (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (playing, aud_drct_get_playing ());
+ return true;
+}
+
+static gboolean do_playlist_add (Obj * obj, Invoc * invoc, const char * list)
+{
+ aud_playlist_entry_insert (aud_playlist_get_active (), -1, list, Tuple (), false);
+ FINISH (playlist_add);
+ return true;
+}
+
+static gboolean do_playlist_enqueue_to_temp (Obj * obj, Invoc * invoc, const char * url)
+{
+ aud_drct_pl_open_temp (url);
+ FINISH (playlist_enqueue_to_temp);
+ return true;
+}
+
+static gboolean do_playlist_ins_url_string (Obj * obj, Invoc * invoc, const char * url, int pos)
+{
+ aud_playlist_entry_insert (aud_playlist_get_active (), pos, url, Tuple (), false);
+ FINISH (playlist_ins_url_string);
+ return true;
+}
+
+static gboolean do_playqueue_add (Obj * obj, Invoc * invoc, int pos)
+{
+ aud_playlist_queue_insert (aud_playlist_get_active (), -1, pos);
+ FINISH (playqueue_add);
+ return true;
+}
+
+static gboolean do_playqueue_clear (Obj * obj, Invoc * invoc)
+{
+ int playlist = aud_playlist_get_active ();
+ aud_playlist_queue_delete (playlist, 0, aud_playlist_queue_count (playlist));
+ FINISH (playqueue_clear);
+ return true;
+}
+
+static gboolean do_playqueue_is_queued (Obj * obj, Invoc * invoc, int pos)
+{
+ bool queued = (aud_playlist_queue_find_entry (aud_playlist_get_active (), pos) >= 0);
+ FINISH2 (playqueue_is_queued, queued);
+ return true;
+}
+
+static gboolean do_playqueue_remove (Obj * obj, Invoc * invoc, int pos)
+{
+ int playlist = aud_playlist_get_active ();
+ int qpos = aud_playlist_queue_find_entry (playlist, pos);
+
+ if (qpos >= 0)
+ aud_playlist_queue_delete (playlist, qpos, 1);
+
+ FINISH (playqueue_remove);
+ return true;
+}
+
+static gboolean do_position (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (position, aud_playlist_get_position (aud_playlist_get_active ()));
+ return true;
+}
+
+static gboolean do_queue_get_list_pos (Obj * obj, Invoc * invoc, unsigned qpos)
+{
+ FINISH2 (queue_get_list_pos, aud_playlist_queue_get_entry (aud_playlist_get_active (), qpos));
+ return true;
+}
+
+static gboolean do_queue_get_queue_pos (Obj * obj, Invoc * invoc, unsigned pos)
+{
+ FINISH2 (queue_get_queue_pos, aud_playlist_queue_find_entry (aud_playlist_get_active (), pos));
+ return true;
+}
+
+static gboolean do_quit (Obj * obj, Invoc * invoc)
+{
+ aud_quit ();
+ FINISH (quit);
+ return true;
+}
+
+static gboolean do_repeat (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (repeat, aud_get_bool (nullptr, "repeat"));
+ return true;
+}
+
+static gboolean do_reverse (Obj * obj, Invoc * invoc)
+{
+ aud_drct_pl_prev ();
+ FINISH (reverse);
+ return true;
+}
+
+static gboolean do_seek (Obj * obj, Invoc * invoc, unsigned pos)
+{
+ aud_drct_seek (pos);
+ FINISH (seek);
+ return true;
+}
+
+static gboolean do_set_active_playlist (Obj * obj, Invoc * invoc, int playlist)
+{
+ aud_playlist_set_active (playlist);
+ FINISH (set_active_playlist);
+ return true;
+}
+
+static gboolean do_set_active_playlist_name (Obj * obj, Invoc * invoc, const char * title)
+{
+ aud_playlist_set_title (aud_playlist_get_active (), title);
+ FINISH (set_active_playlist_name);
+ return true;
+}
+
+static gboolean do_set_eq (Obj * obj, Invoc * invoc, double preamp, GVariant * var)
+{
+ if (! g_variant_is_of_type (var, G_VARIANT_TYPE ("ad")))
+ return false;
+
+ size_t nbands = 0;
+ const double * bands = (double *) g_variant_get_fixed_array (var, & nbands, sizeof (double));
+
+ if (nbands != AUD_EQ_NBANDS)
+ return false;
+
+ aud_set_double (nullptr, "equalizer_preamp", preamp);
+ aud_eq_set_bands (bands);
+ FINISH (set_eq);
+ return true;
+}
+
+static gboolean do_set_eq_band (Obj * obj, Invoc * invoc, int band, double value)
+{
+ aud_eq_set_band (band, value);
+ FINISH (set_eq_band);
+ return true;
+}
+
+static gboolean do_set_eq_preamp (Obj * obj, Invoc * invoc, double preamp)
+{
+ aud_set_double (nullptr, "equalizer_preamp", preamp);
+ FINISH (set_eq_preamp);
+ return true;
+}
+
+static gboolean do_set_volume (Obj * obj, Invoc * invoc, int vl, int vr)
+{
+ aud_drct_set_volume ({vl, vr});
+ FINISH (set_volume);
+ return true;
+}
+
+static gboolean do_show_about_box (Obj * obj, Invoc * invoc, gboolean show)
+{
+ if (! aud_get_headless_mode ())
+ {
+ if (show)
+ aud_ui_show_about_window ();
+ else
+ aud_ui_hide_about_window ();
+ }
+
+ FINISH (show_about_box);
+ return true;
+}
+
+static gboolean do_show_filebrowser (Obj * obj, Invoc * invoc, gboolean show)
+{
+ if (! aud_get_headless_mode ())
+ {
+ if (show)
+ aud_ui_show_filebrowser (false);
+ else
+ aud_ui_hide_filebrowser ();
+ }
+
+ FINISH (show_filebrowser);
+ return true;
+}
+
+static gboolean do_show_jtf_box (Obj * obj, Invoc * invoc, gboolean show)
+{
+ if (! aud_get_headless_mode ())
+ {
+ if (show)
+ aud_ui_show_jump_to_song ();
+ else
+ aud_ui_hide_jump_to_song ();
+ }
+
+ FINISH (show_jtf_box);
+ return true;
+}
+
+static gboolean do_show_main_win (Obj * obj, Invoc * invoc, gboolean show)
+{
+ if (! aud_get_headless_mode ())
+ aud_ui_show (show);
+
+ FINISH (show_main_win);
+ return true;
+}
+
+static gboolean do_show_prefs_box (Obj * obj, Invoc * invoc, gboolean show)
+{
+ if (! aud_get_headless_mode ())
+ {
+ if (show)
+ aud_ui_show_prefs_window ();
+ else
+ aud_ui_hide_prefs_window ();
+ }
+
+ FINISH (show_prefs_box);
+ return true;
+}
+
+static gboolean do_shuffle (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (shuffle, aud_get_bool (nullptr, "shuffle"));
+ return true;
+}
+
+static gboolean do_song_filename (Obj * obj, Invoc * invoc, unsigned pos)
+{
+ String filename = aud_playlist_entry_get_filename (aud_playlist_get_active (), pos);
+ FINISH2 (song_filename, filename ? filename : "");
+ return true;
+}
+
+static gboolean do_song_frames (Obj * obj, Invoc * invoc, unsigned pos)
+{
+ Tuple tuple = aud_playlist_entry_get_tuple (aud_playlist_get_active (), pos);
+ FINISH2 (song_frames, aud::max (0, tuple.get_int (Tuple::Length)));
+ return true;
+}
+
+static gboolean do_song_length (Obj * obj, Invoc * invoc, unsigned pos)
+{
+ Tuple tuple = aud_playlist_entry_get_tuple (aud_playlist_get_active (), pos);
+ int length = aud::max (0, tuple.get_int (Tuple::Length));
+ FINISH2 (song_length, length / 1000);
+ return true;
+}
+
+static gboolean do_song_title (Obj * obj, Invoc * invoc, unsigned pos)
+{
+ Tuple tuple = aud_playlist_entry_get_tuple (aud_playlist_get_active (), pos);
+ String title = tuple.get_str (Tuple::FormattedTitle);
+ FINISH2 (song_title, title ? title : "");
+ return true;
+}
+
+static gboolean do_song_tuple (Obj * obj, Invoc * invoc, unsigned pos, const char * key)
+{
+ Tuple::Field field = Tuple::field_by_name (key);
+ Tuple tuple;
+ GVariant * var = nullptr;
+
+ if (field >= 0)
+ tuple = aud_playlist_entry_get_tuple (aud_playlist_get_active (), pos);
+
+ if (tuple)
+ {
+ switch (tuple.get_value_type (field))
+ {
+ case Tuple::String:
+ var = g_variant_new_string (tuple.get_str (field));
+ break;
+
+ case Tuple::Int:
+ var = g_variant_new_int32 (tuple.get_int (field));
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (! var)
+ var = g_variant_new_string ("");
+
+ FINISH2 (song_tuple, g_variant_new_variant (var));
+ return true;
+}
+
+static gboolean do_status (Obj * obj, Invoc * invoc)
+{
+ const char * status = "stopped";
+ if (aud_drct_get_playing ())
+ status = aud_drct_get_paused () ? "paused" : "playing";
+
+ FINISH2 (status, status);
+ return true;
+}
+
+static gboolean do_stop (Obj * obj, Invoc * invoc)
+{
+ aud_drct_stop ();
+ FINISH (stop);
+ return true;
+}
+
+static gboolean do_stop_after (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (stop_after, aud_get_bool (nullptr, "stop_after_current_song"));
+ return true;
+}
+
+static gboolean do_stopped (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (stopped, ! aud_drct_get_playing ());
+ return true;
+}
+
+static gboolean do_time (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (time, aud_drct_get_time ());
+ return true;
+}
+
+static gboolean do_toggle_auto_advance (Obj * obj, Invoc * invoc)
+{
+ aud_set_bool (nullptr, "no_playlist_advance", ! aud_get_bool (nullptr, "no_playlist_advance"));
+ FINISH (toggle_auto_advance);
+ return true;
+}
+
+static gboolean do_toggle_repeat (Obj * obj, Invoc * invoc)
+{
+ aud_set_bool (nullptr, "repeat", ! aud_get_bool (nullptr, "repeat"));
+ FINISH (toggle_repeat);
+ return true;
+}
+
+static gboolean do_toggle_shuffle (Obj * obj, Invoc * invoc)
+{
+ aud_set_bool (nullptr, "shuffle", ! aud_get_bool (nullptr, "shuffle"));
+ FINISH (toggle_shuffle);
+ return true;
+}
+
+static gboolean do_toggle_stop_after (Obj * obj, Invoc * invoc)
+{
+ aud_set_bool (nullptr, "stop_after_current_song", ! aud_get_bool (nullptr, "stop_after_current_song"));
+ FINISH (toggle_stop_after);
+ return true;
+}
+
+static gboolean do_version (Obj * obj, Invoc * invoc)
+{
+ FINISH2 (version, VERSION);
+ return true;
+}
+
+static gboolean do_volume (Obj * obj, Invoc * invoc)
+{
+ StereoVolume volume = aud_drct_get_volume ();
+ FINISH2 (volume, volume.left, volume.right);
+ return true;
+}
+
+static const struct
+{
+ const char * signal;
+ GCallback callback;
+}
+handlers[] =
+{
+ {"handle-add", (GCallback) do_add},
+ {"handle-add-list", (GCallback) do_add_list},
+ {"handle-add-url", (GCallback) do_add_url},
+ {"handle-advance", (GCallback) do_advance},
+ {"handle-auto-advance", (GCallback) do_auto_advance},
+ {"handle-balance", (GCallback) do_balance},
+ {"handle-clear", (GCallback) do_clear},
+ {"handle-delete", (GCallback) do_delete},
+ {"handle-delete-active-playlist", (GCallback) do_delete_active_playlist},
+ {"handle-eject", (GCallback) do_eject},
+ {"handle-equalizer-activate", (GCallback) do_equalizer_activate},
+ {"handle-get-active-playlist", (GCallback) do_get_active_playlist},
+ {"handle-get-active-playlist-name", (GCallback) do_get_active_playlist_name},
+ {"handle-get-eq", (GCallback) do_get_eq},
+ {"handle-get-eq-band", (GCallback) do_get_eq_band},
+ {"handle-get-eq-preamp", (GCallback) do_get_eq_preamp},
+ {"handle-get-info", (GCallback) do_get_info},
+ {"handle-get-playqueue-length", (GCallback) do_get_playqueue_length},
+ {"handle-get-tuple-fields", (GCallback) do_get_tuple_fields},
+ {"handle-info", (GCallback) do_info},
+ {"handle-jump", (GCallback) do_jump},
+ {"handle-length", (GCallback) do_length},
+ {"handle-main-win-visible", (GCallback) do_main_win_visible},
+ {"handle-new-playlist", (GCallback) do_new_playlist},
+ {"handle-number-of-playlists", (GCallback) do_number_of_playlists},
+ {"handle-open-list", (GCallback) do_open_list},
+ {"handle-open-list-to-temp", (GCallback) do_open_list_to_temp},
+ {"handle-pause", (GCallback) do_pause},
+ {"handle-paused", (GCallback) do_paused},
+ {"handle-play", (GCallback) do_play},
+ {"handle-play-active-playlist", (GCallback) do_play_active_playlist},
+ {"handle-play-pause", (GCallback) do_play_pause},
+ {"handle-playing", (GCallback) do_playing},
+ {"handle-playlist-add", (GCallback) do_playlist_add},
+ {"handle-playlist-enqueue-to-temp", (GCallback) do_playlist_enqueue_to_temp},
+ {"handle-playlist-ins-url-string", (GCallback) do_playlist_ins_url_string},
+ {"handle-playqueue-add", (GCallback) do_playqueue_add},
+ {"handle-playqueue-clear", (GCallback) do_playqueue_clear},
+ {"handle-playqueue-is-queued", (GCallback) do_playqueue_is_queued},
+ {"handle-playqueue-remove", (GCallback) do_playqueue_remove},
+ {"handle-position", (GCallback) do_position},
+ {"handle-queue-get-list-pos", (GCallback) do_queue_get_list_pos},
+ {"handle-queue-get-queue-pos", (GCallback) do_queue_get_queue_pos},
+ {"handle-quit", (GCallback) do_quit},
+ {"handle-repeat", (GCallback) do_repeat},
+ {"handle-reverse", (GCallback) do_reverse},
+ {"handle-seek", (GCallback) do_seek},
+ {"handle-set-active-playlist", (GCallback) do_set_active_playlist},
+ {"handle-set-active-playlist-name", (GCallback) do_set_active_playlist_name},
+ {"handle-set-eq", (GCallback) do_set_eq},
+ {"handle-set-eq-band", (GCallback) do_set_eq_band},
+ {"handle-set-eq-preamp", (GCallback) do_set_eq_preamp},
+ {"handle-set-volume", (GCallback) do_set_volume},
+ {"handle-show-about-box", (GCallback) do_show_about_box},
+ {"handle-show-filebrowser", (GCallback) do_show_filebrowser},
+ {"handle-show-jtf-box", (GCallback) do_show_jtf_box},
+ {"handle-show-main-win", (GCallback) do_show_main_win},
+ {"handle-show-prefs-box", (GCallback) do_show_prefs_box},
+ {"handle-shuffle", (GCallback) do_shuffle},
+ {"handle-song-filename", (GCallback) do_song_filename},
+ {"handle-song-frames", (GCallback) do_song_frames},
+ {"handle-song-length", (GCallback) do_song_length},
+ {"handle-song-title", (GCallback) do_song_title},
+ {"handle-song-tuple", (GCallback) do_song_tuple},
+ {"handle-status", (GCallback) do_status},
+ {"handle-stop", (GCallback) do_stop},
+ {"handle-stop-after", (GCallback) do_stop_after},
+ {"handle-stopped", (GCallback) do_stopped},
+ {"handle-time", (GCallback) do_time},
+ {"handle-toggle-auto-advance", (GCallback) do_toggle_auto_advance},
+ {"handle-toggle-repeat", (GCallback) do_toggle_repeat},
+ {"handle-toggle-shuffle", (GCallback) do_toggle_shuffle},
+ {"handle-toggle-stop-after", (GCallback) do_toggle_stop_after},
+ {"handle-version", (GCallback) do_version},
+ {"handle-volume", (GCallback) do_volume}
+};
+
+static GMainLoop * mainloop = nullptr;
+static unsigned owner_id = 0;
+
+static GDBusInterfaceSkeleton * skeleton = nullptr;
+
+static void name_acquired (GDBusConnection *, const char *, void *)
+{
+ AUDINFO ("Owned D-Bus name (org.atheme.audacious) on session bus.\n");
+
+ g_main_loop_quit (mainloop);
+}
+
+static void name_lost (GDBusConnection *, const char *, void *)
+{
+ AUDINFO ("Owning D-Bus name (org.atheme.audacious) failed, already taken?\n");
+
+ g_bus_unown_name (owner_id);
+ owner_id = 0;
+
+ g_main_loop_quit (mainloop);
+}
+
+StartupType dbus_server_init (void)
+{
+ GError * error = nullptr;
+ GDBusConnection * bus = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, & error);
+ GMainContext * context;
+
+ if (! bus)
+ goto ERROR;
+
+ skeleton = (GDBusInterfaceSkeleton *) obj_audacious_skeleton_new ();
+
+ for (auto & handler : handlers)
+ g_signal_connect (skeleton, handler.signal, handler.callback, nullptr);
+
+ if (! g_dbus_interface_skeleton_export (skeleton, bus, "/org/atheme/audacious", & error))
+ goto ERROR;
+
+ context = g_main_context_new ();
+ g_main_context_push_thread_default (context);
+
+ owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, "org.atheme.audacious",
+ (GBusNameOwnerFlags) 0, nullptr, name_acquired, name_lost, nullptr, nullptr);
+
+ mainloop = g_main_loop_new (context, true);
+ g_main_loop_run (mainloop);
+ g_main_loop_unref (mainloop);
+ mainloop = nullptr;
+
+ g_main_context_pop_thread_default (context);
+ g_main_context_unref (context);
+
+ if (owner_id)
+ return StartupType::Server;
+
+ dbus_server_cleanup ();
+ return StartupType::Client;
+
+ERROR:
+ if (error)
+ {
+ AUDERR ("D-Bus error: %s\n", error->message);
+ g_error_free (error);
+ }
+
+ dbus_server_cleanup ();
+ return StartupType::Unknown;
+}
+
+void dbus_server_cleanup (void)
+{
+ if (owner_id)
+ {
+ g_bus_unown_name (owner_id);
+ owner_id = 0;
+ }
+
+ if (skeleton)
+ {
+ g_object_unref (skeleton);
+ skeleton = nullptr;
+ }
+}
diff --git a/src/audacious/drct-api.h b/src/audacious/drct-api.h
deleted file mode 100644
index cffaf4b..0000000
--- a/src/audacious/drct-api.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * drct-api.h
- * Copyright 2010-2012 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.
- */
-
-/* Do not include this file directly; use drct.h instead. */
-
-/* CAUTION: These functions are not thread safe. */
-
-/* --- PROGRAM CONTROL --- */
-
-AUD_VFUNC0 (drct_quit)
-
-/* --- PLAYBACK CONTROL --- */
-
-/* The strings returned by drct_get_filename() and drct_get_title() are pooled
- * and must be freed with str_unref(). */
-
-AUD_VFUNC0 (drct_play)
-AUD_VFUNC0 (drct_play_pause)
-AUD_VFUNC1 (drct_play_playlist, int, playlist)
-AUD_VFUNC0 (drct_pause)
-AUD_VFUNC0 (drct_stop)
-AUD_FUNC0 (bool_t, drct_get_playing)
-AUD_FUNC0 (bool_t, drct_get_ready)
-AUD_FUNC0 (bool_t, drct_get_paused)
-AUD_FUNC0 (char *, drct_get_filename)
-AUD_FUNC0 (char *, drct_get_title)
-AUD_VFUNC3 (drct_get_info, int *, bitrate, int *, samplerate, int *, channels)
-AUD_FUNC0 (int, drct_get_time)
-AUD_FUNC0 (int, drct_get_length)
-AUD_VFUNC1 (drct_seek, int, time)
-
-/* "A-B repeat": when playback reaches point B, it returns to point A (where A
- * and B are in milliseconds). The value -1 is interpreted as the beginning of
- * the song (for A) or the end of the song (for B). A-B repeat is disabled
- * entirely by setting both A and B to -1. */
-AUD_VFUNC2 (drct_set_ab_repeat, int, a, int, b)
-AUD_VFUNC2 (drct_get_ab_repeat, int *, a, int *, b)
-
-/* --- VOLUME CONTROL --- */
-
-AUD_VFUNC2 (drct_get_volume, int *, left, int *, right)
-AUD_VFUNC2 (drct_set_volume, int, left, int, right)
-AUD_VFUNC1 (drct_get_volume_main, int *, volume)
-AUD_VFUNC1 (drct_set_volume_main, int, volume)
-AUD_VFUNC1 (drct_get_volume_balance, int *, balance)
-AUD_VFUNC1 (drct_set_volume_balance, int, balance)
-
-/* --- PLAYLIST CONTROL --- */
-
-/* The indexes passed to drct_pl_add_list(), drct_pl_open_list(), and
- * drct_pl_open_temp_list() contain pooled strings to which the caller gives up
- * one reference. The indexes themselves are freed by these functions. */
-
-AUD_VFUNC0 (drct_pl_next)
-AUD_VFUNC0 (drct_pl_prev)
-
-AUD_VFUNC2 (drct_pl_add, const char *, filename, int, at)
-AUD_VFUNC2 (drct_pl_add_list, Index *, filenames, int, at)
-AUD_VFUNC1 (drct_pl_open, const char *, filename)
-AUD_VFUNC1 (drct_pl_open_list, Index *, filenames)
-AUD_VFUNC1 (drct_pl_open_temp, const char *, filename)
-AUD_VFUNC1 (drct_pl_open_temp_list, Index *, filenames)
diff --git a/src/audacious/drct.c b/src/audacious/drct.c
deleted file mode 100644
index 5fbef8f..0000000
--- a/src/audacious/drct.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * drct.c
- * Copyright 2009-2013 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 <libaudcore/hook.h>
-#include <libaudcore/vfs.h>
-
-#include "drct.h"
-#include "i18n.h"
-#include "misc.h"
-#include "playlist.h"
-
-/* --- PLAYBACK CONTROL --- */
-
-void drct_play (void)
-{
- if (drct_get_playing ())
- {
- if (drct_get_paused ())
- drct_pause ();
- else
- {
- int a, b;
- drct_get_ab_repeat (& a, & b);
- drct_seek (MAX (a, 0));
- }
- }
- else
- {
- int playlist = playlist_get_active ();
- playlist_set_position (playlist, playlist_get_position (playlist));
- drct_play_playlist (playlist);
- }
-}
-
-void drct_play_pause (void)
-{
- if (drct_get_playing ())
- drct_pause ();
- else
- drct_play ();
-}
-
-void drct_play_playlist (int playlist)
-{
- playlist_set_playing (playlist);
- if (drct_get_paused ())
- drct_pause ();
-}
-
-void drct_stop (void)
-{
- playlist_set_playing (-1);
-}
-
-/* --- VOLUME CONTROL --- */
-
-void drct_get_volume_main (int * volume)
-{
- int left, right;
- drct_get_volume (& left, & right);
- * volume = MAX (left, right);
-}
-
-void drct_set_volume_main (int volume)
-{
- int left, right, current;
- drct_get_volume (& left, & right);
- current = MAX (left, right);
-
- if (current > 0)
- drct_set_volume (volume * left / current, volume * right / current);
- else
- drct_set_volume (volume, volume);
-}
-
-void drct_get_volume_balance (int * balance)
-{
- int left, right;
- drct_get_volume (& left, & right);
-
- if (left == right)
- * balance = 0;
- else if (left > right)
- * balance = -100 + right * 100 / left;
- else
- * balance = 100 - left * 100 / right;
-}
-
-void drct_set_volume_balance (int balance)
-{
- int left, right;
- drct_get_volume_main (& left);
-
- if (balance < 0)
- right = left * (100 + balance) / 100;
- else
- {
- right = left;
- left = right * (100 - balance) / 100;
- }
-
- drct_set_volume (left, right);
-}
-
-/* --- PLAYLIST CONTROL --- */
-
-void drct_pl_next (void)
-{
- int playlist = playlist_get_playing ();
- if (playlist < 0)
- playlist = playlist_get_active ();
-
- playlist_next_song (playlist, get_bool (NULL, "repeat"));
-}
-
-void drct_pl_prev (void)
-{
- int playlist = playlist_get_playing ();
- if (playlist < 0)
- playlist = playlist_get_active ();
-
- playlist_prev_song (playlist);
-}
-
-static void add_list (Index * filenames, int at, bool_t to_temp, bool_t play)
-{
- if (to_temp)
- playlist_set_active (playlist_get_temporary ());
-
- int playlist = playlist_get_active ();
-
- /* queue the new entries before deleting the old ones */
- /* this is to avoid triggering the --quit-after-play condition */
- playlist_entry_insert_batch (playlist, at, filenames, NULL, play);
-
- if (play)
- {
- if (get_bool (NULL, "clear_playlist"))
- playlist_entry_delete (playlist, 0, playlist_entry_count (playlist));
- else
- playlist_queue_delete (playlist, 0, playlist_queue_count (playlist));
- }
-}
-
-void drct_pl_add (const char * filename, int at)
-{
- Index * filenames = index_new ();
- index_insert (filenames, -1, str_get (filename));
- add_list (filenames, at, FALSE, FALSE);
-}
-
-void drct_pl_add_list (Index * filenames, int at)
-{
- add_list (filenames, at, FALSE, FALSE);
-}
-
-void drct_pl_open (const char * filename)
-{
- Index * filenames = index_new ();
- index_insert (filenames, -1, str_get (filename));
- add_list (filenames, -1, get_bool (NULL, "open_to_temporary"), TRUE);
-}
-
-void drct_pl_open_list (Index * filenames)
-{
- add_list (filenames, -1, get_bool (NULL, "open_to_temporary"), TRUE);
-}
-
-void drct_pl_open_temp (const char * filename)
-{
- Index * filenames = index_new ();
- index_insert (filenames, -1, str_get (filename));
- add_list (filenames, -1, TRUE, TRUE);
-}
-
-void drct_pl_open_temp_list (Index * filenames)
-{
- add_list (filenames, -1, TRUE, TRUE);
-}
diff --git a/src/audacious/drct.h b/src/audacious/drct.h
deleted file mode 100644
index 836a9bc..0000000
--- a/src/audacious/drct.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * drct.h
- * Copyright 2010 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.
- */
-
-#ifndef AUDACIOUS_DRCT_H
-#define AUDACIOUS_DRCT_H
-
-#include <audacious/api.h>
-#include <libaudcore/core.h>
-#include <libaudcore/index.h>
-
-#define AUD_API_NAME DRCTAPI
-#define AUD_API_SYMBOL drct_api
-
-#ifdef _AUDACIOUS_CORE
-
-#include "api-local-begin.h"
-#include "drct-api.h"
-#include "api-local-end.h"
-
-#else
-
-#include <audacious/api-define-begin.h>
-#include <audacious/drct-api.h>
-#include <audacious/api-define-end.h>
-
-#include <audacious/api-alias-begin.h>
-#include <audacious/drct-api.h>
-#include <audacious/api-alias-end.h>
-
-#endif
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
-
-#ifdef AUD_API_DECLARE
-
-#define AUD_API_NAME DRCTAPI
-#define AUD_API_SYMBOL drct_api
-
-#include "api-define-begin.h"
-#include "drct-api.h"
-#include "api-define-end.h"
-
-#include "api-declare-begin.h"
-#include "drct-api.h"
-#include "api-declare-end.h"
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
diff --git a/src/audacious/effect.c b/src/audacious/effect.c
deleted file mode 100644
index 7d34368..0000000
--- a/src/audacious/effect.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * effect.c
- * Copyright 2010-2012 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 <glib.h>
-#include <pthread.h>
-
-#include "debug.h"
-#include "drct.h"
-#include "effect.h"
-#include "misc.h"
-#include "plugin.h"
-#include "plugins.h"
-
-typedef struct {
- PluginHandle * plugin;
- EffectPlugin * header;
- int channels_returned, rate_returned;
- bool_t remove_flag;
-} RunningEffect;
-
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static GList * running_effects = NULL; /* (RunningEffect *) */
-static int input_channels, input_rate;
-
-typedef struct {
- int * channels, * rate;
-} EffectStartState;
-
-static bool_t effect_start_cb (PluginHandle * plugin, EffectStartState * state)
-{
- AUDDBG ("Starting %s at %d channels, %d Hz.\n", plugin_get_name (plugin),
- * state->channels, * state->rate);
- EffectPlugin * header = plugin_get_header (plugin);
- g_return_val_if_fail (header != NULL, TRUE);
- header->start (state->channels, state->rate);
-
- RunningEffect * effect = g_slice_new (RunningEffect);
- effect->plugin = plugin;
- effect->header = header;
- effect->channels_returned = * state->channels;
- effect->rate_returned = * state->rate;
- effect->remove_flag = FALSE;
-
- running_effects = g_list_prepend (running_effects, effect);
- return TRUE;
-}
-
-void effect_start (int * channels, int * rate)
-{
- pthread_mutex_lock (& mutex);
-
- AUDDBG ("Starting effects.\n");
-
- for (GList * node = running_effects; node; node = node->next)
- g_slice_free (RunningEffect, node->data);
-
- g_list_free (running_effects);
- running_effects = NULL;
-
- input_channels = * channels;
- input_rate = * rate;
-
- EffectStartState state = {channels, rate};
- plugin_for_enabled (PLUGIN_TYPE_EFFECT, (PluginForEachFunc) effect_start_cb,
- & state);
- running_effects = g_list_reverse (running_effects);
-
- pthread_mutex_unlock (& mutex);
-}
-
-typedef struct {
- float * * data;
- int * samples;
-} EffectProcessState;
-
-static void effect_process_cb (RunningEffect * effect, EffectProcessState *
- state)
-{
- if (effect->remove_flag)
- {
- /* call finish twice to completely drain buffers */
- effect->header->finish (state->data, state->samples);
- effect->header->finish (state->data, state->samples);
-
- running_effects = g_list_remove (running_effects, effect);
- g_slice_free (RunningEffect, effect);
- }
- else
- effect->header->process (state->data, state->samples);
-}
-
-void effect_process (float * * data, int * samples)
-{
- pthread_mutex_lock (& mutex);
-
- EffectProcessState state = {data, samples};
- g_list_foreach (running_effects, (GFunc) effect_process_cb, & state);
-
- pthread_mutex_unlock (& mutex);
-}
-
-void effect_flush (void)
-{
- pthread_mutex_lock (& mutex);
-
- for (GList * node = running_effects; node != NULL; node = node->next)
- {
- if (PLUGIN_HAS_FUNC (((RunningEffect *) node->data)->header, flush))
- ((RunningEffect *) node->data)->header->flush ();
- }
-
- pthread_mutex_unlock (& mutex);
-}
-
-void effect_finish (float * * data, int * samples)
-{
- pthread_mutex_lock (& mutex);
-
- for (GList * node = running_effects; node != NULL; node = node->next)
- ((RunningEffect *) node->data)->header->finish (data, samples);
-
- pthread_mutex_unlock (& mutex);
-}
-
-int effect_adjust_delay (int delay)
-{
- pthread_mutex_lock (& mutex);
-
- for (GList * node = g_list_last (running_effects); node != NULL; node = node->prev)
- {
- if (PLUGIN_HAS_FUNC (((RunningEffect *) node->data)->header, adjust_delay))
- delay = ((RunningEffect *) node->data)->header->adjust_delay (delay);
- }
-
- pthread_mutex_unlock (& mutex);
- return delay;
-}
-
-static int effect_find_cb (RunningEffect * effect, PluginHandle * plugin)
-{
- return (effect->plugin == plugin) ? 0 : -1;
-}
-
-static int effect_compare (RunningEffect * a, RunningEffect * b)
-{
- return plugin_compare (a->plugin, b->plugin);
-}
-
-static void effect_insert (PluginHandle * plugin, EffectPlugin * header)
-{
- GList * node = g_list_find_custom (running_effects, plugin, (GCompareFunc) effect_find_cb);
-
- if (node)
- {
- ((RunningEffect *) node->data)->remove_flag = FALSE;
- return;
- }
-
- AUDDBG ("Adding %s without reset.\n", plugin_get_name (plugin));
- RunningEffect * effect = g_slice_new (RunningEffect);
- effect->plugin = plugin;
- effect->header = header;
- effect->remove_flag = FALSE;
-
- running_effects = g_list_insert_sorted (running_effects, effect,
- (GCompareFunc) effect_compare);
- node = g_list_find (running_effects, effect);
-
- int channels, rate;
- if (node->prev != NULL)
- {
- RunningEffect * prev = node->prev->data;
- AUDDBG ("Added %s after %s.\n", plugin_get_name (plugin),
- plugin_get_name (prev->plugin));
- channels = prev->channels_returned;
- rate = prev->rate_returned;
- }
- else
- {
- AUDDBG ("Added %s as first effect.\n", plugin_get_name (plugin));
- channels = input_channels;
- rate = input_rate;
- }
-
- AUDDBG ("Starting %s at %d channels, %d Hz.\n", plugin_get_name (plugin),
- channels, rate);
- header->start (& channels, & rate);
- effect->channels_returned = channels;
- effect->rate_returned = rate;
-}
-
-static void effect_remove (PluginHandle * plugin)
-{
- GList * node = g_list_find_custom (running_effects, plugin, (GCompareFunc)
- effect_find_cb);
- if (node == NULL)
- return;
-
- AUDDBG ("Removing %s without reset.\n", plugin_get_name (plugin));
- ((RunningEffect *) node->data)->remove_flag = TRUE;
-}
-
-static void effect_enable (PluginHandle * plugin, EffectPlugin * ep, bool_t
- enable)
-{
- if (ep->preserves_format)
- {
- pthread_mutex_lock (& mutex);
-
- if (enable)
- effect_insert (plugin, ep);
- else
- effect_remove (plugin);
-
- pthread_mutex_unlock (& mutex);
- }
- else
- {
- AUDDBG ("Reset to add/remove %s.\n", plugin_get_name (plugin));
- output_reset (OUTPUT_RESET_EFFECTS_ONLY);
- }
-}
-
-bool_t effect_plugin_start (PluginHandle * plugin)
-{
- if (drct_get_playing ())
- {
- EffectPlugin * ep = plugin_get_header (plugin);
- g_return_val_if_fail (ep != NULL, FALSE);
- effect_enable (plugin, ep, TRUE);
- }
-
- return TRUE;
-}
-
-void effect_plugin_stop (PluginHandle * plugin)
-{
- if (drct_get_playing ())
- {
- EffectPlugin * ep = plugin_get_header (plugin);
- g_return_if_fail (ep != NULL);
- effect_enable (plugin, ep, FALSE);
- }
-}
diff --git a/src/audacious/effect.h b/src/audacious/effect.h
deleted file mode 100644
index 2a0add9..0000000
--- a/src/audacious/effect.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * effect.h
- * Copyright 2010-2012 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.
- */
-
-#ifndef AUDACIOUS_EFFECT_H
-#define AUDACIOUS_EFFECT_H
-
-#include <libaudcore/core.h>
-
-#include "types.h"
-
-void effect_start (int * channels, int * rate);
-void effect_process (float * * data, int * samples);
-void effect_flush (void);
-void effect_finish (float * * data, int * samples);
-int effect_adjust_delay (int delay);
-
-bool_t effect_plugin_start (PluginHandle * plugin);
-void effect_plugin_stop (PluginHandle * plugin);
-
-#endif
diff --git a/src/audacious/equalizer.c b/src/audacious/equalizer.c
deleted file mode 100644
index 1b74f31..0000000
--- a/src/audacious/equalizer.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * equalizer.c
- * Copyright 2001 Anders Johansson
- * Copyright 2010-2011 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.
- */
-
-/*
- * Anders Johansson prefers float *ptr; formatting. Please keep it that way.
- * - tallica
- */
-
-#include <glib.h>
-#include <math.h>
-#include <pthread.h>
-#include <string.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-
-#include "equalizer.h"
-#include "misc.h"
-#include "types.h"
-
-#define EQ_BANDS AUD_EQUALIZER_NBANDS
-#define MAX_CHANNELS 10
-
-/* Q value for band-pass filters 1.2247 = (3/2)^(1/2)
- * Gives 4 dB suppression at Fc*2 and Fc/2 */
-#define Q 1.2247449
-
-/* Center frequencies for band-pass filters (Hz) */
-/* These are not the historical WinAmp frequencies, because the IIR filters used
- * here are designed for each frequency to be twice the previous. Using WinAmp
- * frequencies leads to too much gain in some bands and too little in others. */
-static const float CF[EQ_BANDS] = {31.25, 62.5, 125, 250, 500, 1000, 2000,
- 4000, 8000, 16000};
-
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static bool_t active;
-static int channels, rate;
-static float a[EQ_BANDS][2]; /* A weights */
-static float b[EQ_BANDS][2]; /* B weights */
-static float wqv[MAX_CHANNELS][EQ_BANDS][2]; /* Circular buffer for W data */
-static float gv[MAX_CHANNELS][EQ_BANDS]; /* Gain factor for each channel and band */
-static int K; /* Number of used eq bands */
-
-/* 2nd order band-pass filter design */
-static void bp2 (float *a, float *b, float fc, float q)
-{
- float th = 2 * M_PI * fc;
- float C = (1 - tanf (th * q / 2)) / (1 + tanf (th * q / 2));
-
- a[0] = (1 + C) * cosf (th);
- a[1] = -C;
- b[0] = (1 - C) / 2;
- b[1] = -1.005;
-}
-
-void eq_set_format (int new_channels, int new_rate)
-{
- int k;
-
- pthread_mutex_lock (& mutex);
-
- channels = new_channels;
- rate = new_rate;
-
- /* Calculate number of active filters */
- K = EQ_BANDS;
-
- while (CF[K - 1] > (float) rate / 2.2)
- K --;
-
- /* Generate filter taps */
- for (k = 0; k < K; k ++)
- bp2 (a[k], b[k], CF[k] / (float) rate, Q);
-
- /* Reset state */
- memset (wqv[0][0], 0, sizeof wqv);
-
- pthread_mutex_unlock (& mutex);
-}
-
-static void eq_set_bands_real (double preamp, double *values)
-{
- float adj[EQ_BANDS];
- for (int i = 0; i < EQ_BANDS; i ++)
- adj[i] = preamp + values[i];
-
- for (int c = 0; c < MAX_CHANNELS; c ++)
- for (int i = 0; i < EQ_BANDS; i ++)
- gv[c][i] = pow (10, adj[i] / 20) - 1;
-}
-
-void eq_filter (float *data, int samples)
-{
- int channel;
-
- pthread_mutex_lock (& mutex);
-
- if (! active)
- {
- pthread_mutex_unlock (& mutex);
- return;
- }
-
- for (channel = 0; channel < channels; channel ++)
- {
- float *g = gv[channel]; /* Gain factor */
- float *end = data + samples;
- float *f;
-
- for (f = data + channel; f < end; f += channels)
- {
- int k; /* Frequency band index */
- float yt = *f; /* Current input sample */
-
- for (k = 0; k < K; k ++)
- {
- /* Pointer to circular buffer wq */
- float *wq = wqv[channel][k];
- /* Calculate output from AR part of current filter */
- float w = yt * b[k][0] + wq[0] * a[k][0] + wq[1] * a[k][1];
-
- /* Calculate output from MA part of current filter */
- yt += (w + wq[1] * b[k][1]) * g[k];
-
- /* Update circular buffer */
- wq[1] = wq[0];
- wq[0] = w;
- }
-
- /* Calculate output */
- *f = yt;
- }
- }
-
- pthread_mutex_unlock (& mutex);
-}
-
-static void eq_update (void *data, void *user)
-{
- pthread_mutex_lock (& mutex);
-
- active = get_bool (NULL, "equalizer_active");
-
- double values[EQ_BANDS];
- eq_get_bands (values);
- eq_set_bands_real (get_double (NULL, "equalizer_preamp"), values);
-
- pthread_mutex_unlock (& mutex);
-}
-
-void eq_init (void)
-{
- eq_update (NULL, NULL);
- hook_associate ("set equalizer_active", eq_update, NULL);
- hook_associate ("set equalizer_preamp", eq_update, NULL);
- hook_associate ("set equalizer_bands", eq_update, NULL);
-}
-
-void eq_cleanup (void)
-{
- hook_dissociate ("set equalizer_active", eq_update);
- hook_dissociate ("set equalizer_preamp", eq_update);
- hook_dissociate ("set equalizer_bands", eq_update);
-}
-
-void eq_set_bands (const double *values)
-{
- char *string = double_array_to_str (values, EQ_BANDS);
- g_return_if_fail (string);
- set_str (NULL, "equalizer_bands", string);
- str_unref (string);
-}
-
-void eq_get_bands (double *values)
-{
- memset (values, 0, sizeof (double) * EQ_BANDS);
- char *string = get_str (NULL, "equalizer_bands");
- str_to_double_array (string, values, EQ_BANDS);
- str_unref (string);
-}
-
-void eq_set_band (int band, double value)
-{
- g_return_if_fail (band >= 0 && band < EQ_BANDS);
- double values[EQ_BANDS];
- eq_get_bands (values);
- values[band] = value;
- eq_set_bands (values);
-}
-
-double eq_get_band (int band)
-{
- g_return_val_if_fail (band >= 0 && band < EQ_BANDS, 0);
- double values[EQ_BANDS];
- eq_get_bands (values);
- return values[band];
-}
diff --git a/src/audacious/equalizer.h b/src/audacious/equalizer.h
deleted file mode 100644
index 3acb472..0000000
--- a/src/audacious/equalizer.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * equalizer.h
- * Copyright 2010 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.
- */
-
-#ifndef AUDACIOUS_EQUALIZER_H
-#define AUDACIOUS_EQUALIZER_H
-
-void eq_init (void);
-void eq_cleanup (void);
-void eq_set_format (int new_channels, int new_rate);
-void eq_filter (float * data, int samples);
-
-#endif
diff --git a/src/audacious/equalizer_preset.c b/src/audacious/equalizer_preset.c
deleted file mode 100644
index 6c70eb8..0000000
--- a/src/audacious/equalizer_preset.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * equalizer_preset.c
- * Copyright 2003-2013 Eugene Zagidullin, William Pitcock, John Lindgren, and
- * Thomas Lange
- *
- * 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 <glib.h>
-#include <math.h>
-#include <string.h>
-
-#include <libaudcore/audstrings.h>
-
-#include "debug.h"
-#include "i18n.h"
-#include "misc.h"
-
-EqualizerPreset * equalizer_preset_new (const char * name)
-{
- EqualizerPreset * preset = g_slice_new0 (EqualizerPreset);
- preset->name = str_get (name);
- return preset;
-}
-
-void equalizer_preset_free (EqualizerPreset * preset)
-{
- str_unref (preset->name);
- g_slice_free (EqualizerPreset, preset);
-}
-
-Index * equalizer_read_presets (const char * basename)
-{
- GKeyFile * rcfile = g_key_file_new ();
-
- char * filename = filename_build (get_path (AUD_PATH_USER_DIR), basename);
-
- if (! g_key_file_load_from_file (rcfile, filename, G_KEY_FILE_NONE, NULL))
- {
- str_unref (filename);
- filename = filename_build (get_path (AUD_PATH_DATA_DIR), basename);
-
- if (! g_key_file_load_from_file (rcfile, filename, G_KEY_FILE_NONE, NULL))
- {
- str_unref (filename);
- g_key_file_free (rcfile);
- return NULL;
- }
- }
-
- str_unref (filename);
-
- Index * list = index_new ();
-
- for (int p = 0;; p ++)
- {
- SPRINTF (section, "Preset%d", p);
-
- char * name = g_key_file_get_string (rcfile, "Presets", section, NULL);
- if (! name)
- break;
-
- EqualizerPreset * preset = equalizer_preset_new (name);
- preset->preamp = g_key_file_get_double (rcfile, name, "Preamp", NULL);
-
- for (int i = 0; i < AUD_EQUALIZER_NBANDS; i++)
- {
- SPRINTF (band, "Band%d", i);
- preset->bands[i] = g_key_file_get_double (rcfile, name, band, NULL);
- }
-
- index_insert (list, -1, preset);
-
- g_free (name);
- }
-
- g_key_file_free (rcfile);
-
- return list;
-}
-
-bool_t equalizer_write_presets (Index * list, const char * basename)
-{
- GKeyFile * rcfile = g_key_file_new ();
-
- for (int p = 0; p < index_count (list); p ++)
- {
- EqualizerPreset * preset = index_get (list, p);
-
- SPRINTF (tmp, "Preset%d", p);
- g_key_file_set_string (rcfile, "Presets", tmp, preset->name);
- g_key_file_set_double (rcfile, preset->name, "Preamp", preset->preamp);
-
- for (int i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- {
- SPRINTF (tmp, "Band%d", i);
- g_key_file_set_double (rcfile, preset->name, tmp, preset->bands[i]);
- }
- }
-
- size_t len;
- char * data = g_key_file_to_data (rcfile, & len, NULL);
-
- char * filename = filename_build (get_path (AUD_PATH_USER_DIR), basename);
- bool_t success = g_file_set_contents (filename, data, len, NULL);
- str_unref (filename);
-
- g_key_file_free (rcfile);
- g_free (data);
-
- return success;
-}
-
-/* Note: Winamp 2.x had a +/- 20 dB range.
- * Winamp 5.x had a +/- 12 dB range, which we use here. */
-#define FROM_WINAMP_VAL(x) ((31.5 - (x)) * (12.0 / 31.5))
-#define TO_WINAMP_VAL(x) (round (31.5 - (x) * (31.5 / 12.0)))
-
-Index * import_winamp_presets (VFSFile * file)
-{
- char header[31];
- char bands[11];
- char preset_name[181];
-
- if (vfs_fread (header, 1, sizeof header, file) != sizeof header ||
- strncmp (header, "Winamp EQ library file v1.1", 27))
- return NULL;
-
- Index * list = index_new ();
-
- while (vfs_fread (preset_name, 1, 180, file) == 180)
- {
- preset_name[180] = 0; /* protect against buffer overflow */
-
- if (vfs_fseek (file, 77, SEEK_CUR)) /* unknown crap --asphyx */
- break;
-
- if (vfs_fread (bands, 1, 11, file) != 11)
- break;
-
- EqualizerPreset * preset = equalizer_preset_new (preset_name);
- preset->preamp = FROM_WINAMP_VAL (bands[10]);
-
- for (int i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- preset->bands[i] = FROM_WINAMP_VAL (bands[i]);
-
- index_insert (list, -1, preset);
- }
-
- return list;
-}
-
-bool_t export_winamp_preset (EqualizerPreset * preset, VFSFile * file)
-{
- char name[257];
- char bands[11];
-
- if (vfs_fwrite ("Winamp EQ library file v1.1\x1a!--", 1, 31, file) != 31)
- return FALSE;
-
- strncpy (name, preset->name, 257);
-
- if (vfs_fwrite (name, 1, 257, file) != 257)
- return FALSE;
-
- for (int i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- bands[i] = TO_WINAMP_VAL (preset->bands[i]);
-
- bands[10] = TO_WINAMP_VAL (preset->preamp);
-
- if (vfs_fwrite (bands, 1, 11, file) != 11)
- return FALSE;
-
- return TRUE;
-}
-
-bool_t save_preset_file (EqualizerPreset * preset, const char * filename)
-{
- GKeyFile * rcfile = g_key_file_new ();
-
- g_key_file_set_double (rcfile, "Equalizer preset", "Preamp", preset->preamp);
-
- for (int i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- {
- SPRINTF (tmp, "Band%d", i);
- g_key_file_set_double (rcfile, "Equalizer preset", tmp, preset->bands[i]);
- }
-
- size_t len;
- char * data = g_key_file_to_data (rcfile, & len, NULL);
-
- VFSFile * file = vfs_fopen (filename, "w");
- bool_t success = FALSE;
-
- if (file)
- {
- success = (vfs_fwrite (data, 1, len, file) == len);
- vfs_fclose (file);
- }
-
- g_key_file_free (rcfile);
- g_free (data);
-
- return success;
-}
-
-EqualizerPreset * load_preset_file (const char * filename)
-{
- GKeyFile * rcfile = g_key_file_new ();
-
- if (! g_key_file_load_from_file (rcfile, filename, G_KEY_FILE_NONE, NULL))
- {
- g_key_file_free (rcfile);
- return NULL;
- }
-
- EqualizerPreset * preset = equalizer_preset_new ("");
-
- preset->preamp = g_key_file_get_double (rcfile, "Equalizer preset", "Preamp", NULL);
-
- for (int i = 0; i < AUD_EQUALIZER_NBANDS; i ++)
- {
- SPRINTF (tmp, "Band%d", i);
- preset->bands[i] = g_key_file_get_double (rcfile, "Equalizer preset", tmp, NULL);
- }
-
- g_key_file_free (rcfile);
-
- return preset;
-}
diff --git a/src/audacious/fft.c b/src/audacious/fft.c
deleted file mode 100644
index 09a6602..0000000
--- a/src/audacious/fft.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * fft.c
- * Copyright 2011 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 <complex.h>
-#include <math.h>
-
-#include "fft.h"
-
-#define N 512 /* size of the DFT */
-#define LOGN 9 /* log N (base 2) */
-
-static float hamming[N]; /* hamming window, scaled to sum to 1 */
-static int reversed[N]; /* bit-reversal table */
-static float complex roots[N / 2]; /* N-th roots of unity */
-static char generated = 0; /* set if tables have been generated */
-
-/* Reverse the order of the lowest LOGN bits in an integer. */
-
-static int bit_reverse (int x)
-{
- int y = 0;
-
- for (int n = LOGN; n --; )
- {
- y = (y << 1) | (x & 1);
- x >>= 1;
- }
-
- return y;
-}
-
-/* Generate lookup tables. */
-
-static void generate_tables (void)
-{
- if (generated)
- return;
-
- for (int n = 0; n < N; n ++)
- hamming[n] = 1 - 0.85 * cosf (2 * M_PI * n / N);
- for (int n = 0; n < N; n ++)
- reversed[n] = bit_reverse (n);
- for (int n = 0; n < N / 2; n ++)
- roots[n] = cexpf (2 * M_PI * I * n / N);
-
- generated = 1;
-}
-
-/* Perform the DFT using the Cooley-Tukey algorithm. At each step s, where
- * s=1..log N (base 2), there are N/(2^s) groups of intertwined butterfly
- * operations. Each group contains (2^s)/2 butterflies, and each butterfly has
- * a span of (2^s)/2. The twiddle factors are nth roots of unity where n = 2^s. */
-
-static void do_fft (float complex a[N])
-{
- int half = 1; /* (2^s)/2 */
- int inv = N / 2; /* N/(2^s) */
-
- /* loop through steps */
- while (inv)
- {
- /* loop through groups */
- for (int g = 0; g < N; g += half << 1)
- {
- /* loop through butterflies */
- for (int b = 0, r = 0; b < half; b ++, r += inv)
- {
- float complex even = a[g + b];
- float complex odd = roots[r] * a[g + half + b];
- a[g + b] = even + odd;
- a[g + half + b] = even - odd;
- }
- }
-
- half <<= 1;
- inv >>= 1;
- }
-}
-
-/* Input is N=512 PCM samples.
- * Output is intensity of frequencies from 1 to N/2=256. */
-
-void calc_freq (const float data[N], float freq[N / 2])
-{
- generate_tables ();
-
- /* input is filtered by a Hamming window */
- /* input values are in bit-reversed order */
- float complex a[N];
- for (int n = 0; n < N; n ++)
- a[reversed[n]] = data[n] * hamming[n];
-
- do_fft (a);
-
- /* output values are divided by N */
- /* frequencies from 1 to N/2-1 are doubled */
- for (int n = 0; n < N / 2 - 1; n ++)
- freq[n] = 2 * cabsf (a[1 + n]) / N;
-
- /* frequency N/2 is not doubled */
- freq[N / 2 - 1] = cabsf (a[N / 2]) / N;
-}
diff --git a/src/audacious/fft.h b/src/audacious/fft.h
deleted file mode 100644
index bb8cba3..0000000
--- a/src/audacious/fft.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * fft.h
- * Copyright 2011 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.
- */
-
-#ifndef AUDACIOUS_FFT_H
-#define AUDACIOUS_FFT_H
-
-void calc_freq (const float data[512], float freq[256]);
-
-#endif
diff --git a/src/audacious/general.c b/src/audacious/general.c
deleted file mode 100644
index e0b9ea2..0000000
--- a/src/audacious/general.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * general.c
- * Copyright 2011 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 <gtk/gtk.h>
-
-#include "debug.h"
-#include "general.h"
-#include "interface.h"
-#include "plugin.h"
-#include "plugins.h"
-#include "ui_preferences.h"
-
-typedef struct {
- PluginHandle * plugin;
- GeneralPlugin * gp;
- GtkWidget * widget;
-} LoadedGeneral;
-
-static int running = FALSE;
-static GList * loaded_general_plugins = NULL;
-
-static int general_find_cb (LoadedGeneral * general, PluginHandle * plugin)
-{
- return (general->plugin == plugin) ? 0 : -1;
-}
-
-static void general_load (PluginHandle * plugin)
-{
- GList * node = g_list_find_custom (loaded_general_plugins, plugin,
- (GCompareFunc) general_find_cb);
- if (node != NULL)
- return;
-
- AUDDBG ("Loading %s.\n", plugin_get_name (plugin));
- GeneralPlugin * gp = plugin_get_header (plugin);
- g_return_if_fail (gp != NULL);
-
- LoadedGeneral * general = g_slice_new (LoadedGeneral);
- general->plugin = plugin;
- general->gp = gp;
- general->widget = NULL;
-
- if (gp->get_widget != NULL)
- general->widget = gp->get_widget ();
-
- if (general->widget != NULL)
- {
- AUDDBG ("Adding %s to interface.\n", plugin_get_name (plugin));
- g_signal_connect (general->widget, "destroy", (GCallback)
- gtk_widget_destroyed, & general->widget);
- interface_add_plugin_widget (plugin, general->widget);
- }
-
- loaded_general_plugins = g_list_prepend (loaded_general_plugins, general);
-}
-
-static void general_unload (PluginHandle * plugin)
-{
- GList * node = g_list_find_custom (loaded_general_plugins, plugin,
- (GCompareFunc) general_find_cb);
- if (node == NULL)
- return;
-
- AUDDBG ("Unloading %s.\n", plugin_get_name (plugin));
- LoadedGeneral * general = node->data;
- loaded_general_plugins = g_list_delete_link (loaded_general_plugins, node);
-
- if (general->widget != NULL)
- {
- AUDDBG ("Removing %s from interface.\n", plugin_get_name (plugin));
- interface_remove_plugin_widget (plugin, general->widget);
- g_return_if_fail (general->widget == NULL); /* not destroyed? */
- }
-
- g_slice_free (LoadedGeneral, general);
-}
-
-static bool_t general_init_cb (PluginHandle * plugin)
-{
- general_load (plugin);
- return TRUE;
-}
-
-void general_init (void)
-{
- g_return_if_fail (! running);
- running = TRUE;
-
- plugin_for_enabled (PLUGIN_TYPE_GENERAL, (PluginForEachFunc)
- general_init_cb, NULL);
-}
-
-static void general_cleanup_cb (LoadedGeneral * general)
-{
- general_unload (general->plugin);
-}
-
-void general_cleanup (void)
-{
- g_return_if_fail (running);
- running = FALSE;
-
- g_list_foreach (loaded_general_plugins, (GFunc) general_cleanup_cb, NULL);
-}
-
-bool_t general_plugin_start (PluginHandle * plugin)
-{
- GeneralPlugin * gp = plugin_get_header (plugin);
- g_return_val_if_fail (gp != NULL, FALSE);
-
- if (gp->init != NULL && ! gp->init ())
- return FALSE;
-
- if (running)
- general_load (plugin);
-
- return TRUE;
-}
-
-void general_plugin_stop (PluginHandle * plugin)
-{
- GeneralPlugin * gp = plugin_get_header (plugin);
- g_return_if_fail (gp != NULL);
-
- if (running)
- general_unload (plugin);
-
- if (gp->cleanup != NULL)
- gp->cleanup ();
-}
-
-PluginHandle * general_plugin_by_widget (/* GtkWidget * */ void * widget)
-{
- g_return_val_if_fail (widget, NULL);
-
- for (GList * node = loaded_general_plugins; node; node = node->next)
- {
- LoadedGeneral * general = node->data;
- if (general->widget == widget)
- return general->plugin;
- }
-
- return NULL;
-}
diff --git a/src/audacious/general.h b/src/audacious/general.h
deleted file mode 100644
index c9a7c9e..0000000
--- a/src/audacious/general.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * general.h
- * Copyright 2011 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.
- */
-
-#ifndef AUDACIOUS_GENERAL_H
-#define AUDACIOUS_GENERAL_H
-
-#include "plugins.h"
-
-void general_init (void);
-void general_cleanup (void);
-
-bool_t general_plugin_start (PluginHandle * plugin);
-void general_plugin_stop (PluginHandle * plugin);
-
-PluginHandle * general_plugin_by_widget (/* GtkWidget * */ void * widget);
-
-#endif
diff --git a/src/audacious/history.c b/src/audacious/history.c
deleted file mode 100644
index 4dde368..0000000
--- a/src/audacious/history.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * history.c
- * Copyright 2011 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 <glib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <libaudcore/hook.h>
-
-#include "main.h"
-#include "misc.h"
-
-#define MAX_ENTRIES 30
-
-static GQueue history = G_QUEUE_INIT;
-static bool_t loaded, modified;
-
-static void history_save (void)
-{
- if (! modified)
- return;
-
- GList * node = history.head;
- for (int i = 0; i < MAX_ENTRIES; i ++)
- {
- if (! node)
- break;
-
- char name[32];
- snprintf (name, sizeof name, "entry%d", i);
- set_str ("history", name, node->data);
-
- node = node->next;
- }
-
- modified = FALSE;
-}
-
-static void history_load (void)
-{
- if (loaded)
- return;
-
- for (int i = 0; ; i ++)
- {
- char name[32];
- snprintf (name, sizeof name, "entry%d", i);
- char * path = get_str ("history", name);
-
- if (! path[0])
- {
- str_unref (path);
- break;
- }
-
- g_queue_push_tail (& history, path);
- }
-
- loaded = TRUE;
- hook_associate ("config save", (HookFunction) history_save, NULL);
-}
-
-void history_cleanup (void)
-{
- if (! loaded)
- return;
-
- hook_dissociate ("config save", (HookFunction) history_save);
-
- g_queue_foreach (& history, (GFunc) str_unref, NULL);
- g_queue_clear (& history);
-
- loaded = FALSE;
- modified = FALSE;
-}
-
-const char * history_get (int entry)
-{
- history_load ();
- return g_queue_peek_nth (& history, entry);
-}
-
-void history_add (const char * path)
-{
- history_load ();
-
- GList * next;
- for (GList * node = history.head; node; node = next)
- {
- next = node->next;
- if (! strcmp (node->data, path))
- {
- str_unref (node->data);
- g_queue_delete_link (& history, node);
- }
- }
-
- g_queue_push_head (& history, str_get (path));
- modified = TRUE;
-}
diff --git a/src/audacious/i18n.h b/src/audacious/i18n.h
deleted file mode 100644
index 5b5205c..0000000
--- a/src/audacious/i18n.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * i18n.h
- * Copyright 2007 William Pitcock
- *
- * 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.
- */
-
-#ifndef AUDACIOUS_I18N_H
-#define AUDACIOUS_I18N_H
-
-#include <libintl.h>
-
-#define _(String) dgettext (PACKAGE, String)
-#ifdef gettext_noop
-#define N_(String) gettext_noop (String)
-#else
-#define N_(String) (String)
-#endif
-
-#endif /* AUDACIOUS_I18N_H */
diff --git a/src/audacious/images/about-logo.png b/src/audacious/images/about-logo.png
deleted file mode 100644
index 32fb69f..0000000
--- a/src/audacious/images/about-logo.png
+++ /dev/null
Binary files differ
diff --git a/src/audacious/images/album.png b/src/audacious/images/album.png
deleted file mode 100644
index a47bc7d..0000000
--- a/src/audacious/images/album.png
+++ /dev/null
Binary files differ
diff --git a/src/audacious/images/appearance.png b/src/audacious/images/appearance.png
deleted file mode 100644
index f73239a..0000000
--- a/src/audacious/images/appearance.png
+++ /dev/null
Binary files differ
diff --git a/src/audacious/images/audio.png b/src/audacious/images/audio.png
deleted file mode 100644
index a41d51a..0000000
--- a/src/audacious/images/audio.png
+++ /dev/null
Binary files differ
diff --git a/src/audacious/images/connectivity.png b/src/audacious/images/connectivity.png
deleted file mode 100644
index 2d80e79..0000000
--- a/src/audacious/images/connectivity.png
+++ /dev/null
Binary files differ
diff --git a/src/audacious/images/info.png b/src/audacious/images/info.png
deleted file mode 100644
index 91e2c17..0000000
--- a/src/audacious/images/info.png
+++ /dev/null
Binary files differ
diff --git a/src/audacious/images/playlist.png b/src/audacious/images/playlist.png
deleted file mode 100644
index 2574ef0..0000000
--- a/src/audacious/images/playlist.png
+++ /dev/null
Binary files differ
diff --git a/src/audacious/images/plugins.png b/src/audacious/images/plugins.png
deleted file mode 100644
index da9f9e1..0000000
--- a/src/audacious/images/plugins.png
+++ /dev/null
Binary files differ
diff --git a/src/audacious/input-api.h b/src/audacious/input-api.h
deleted file mode 100644
index 7c49b0e..0000000
--- a/src/audacious/input-api.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * input-api.h
- * Copyright 2013 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.
- */
-
-/* Do not include this file directly; use input.h instead. */
-
-/* These functions are to be used only from the play() function of an input plugin. */
-
-/* Prepares the output system for playback in the specified format. Returns
- * TRUE on success, FALSE if the selected format is not supported. */
-AUD_FUNC3 (bool_t, input_open_audio, int, format, int, rate, int, channels)
-
-/* Informs the output system of replay gain values for the current song so
- * that volume levels can be adjusted accordingly, if the user so desires.
- * This may be called at any time during playback should the values change. */
-AUD_VFUNC1 (input_set_gain, const ReplayGainInfo *, info)
-
-/* Passes audio data to the output system for playback. The data must be in
- * the format passed to open_audio, and the length (in bytes) must be an
- * integral number of frames. This function blocks until all the data has
- * been written (though it may not yet be heard by the user). */
-AUD_VFUNC2 (input_write_audio, void *, data, int, length)
-
-/* Returns the time counter. Note that this represents the amount of audio
- * data passed to the output system, not the amount actually heard by the
- * user. */
-AUD_FUNC0 (int, input_written_time)
-
-/* Returns a reference to the current tuple for the stream. */
-AUD_FUNC0 (Tuple *, input_get_tuple)
-
-/* Updates the tuple for the stream. The caller gives up ownership of one
- * reference to the tuple. */
-AUD_VFUNC1 (input_set_tuple, Tuple *, tuple)
-
-/* Updates the displayed bitrate, in bits per second. */
-AUD_VFUNC1 (input_set_bitrate, int, bitrate)
-
-/* Checks whether playback is to be stopped. The play() function should poll
- * check_stop() periodically and return as soon as check_stop() returns TRUE. */
-AUD_FUNC0 (bool_t, input_check_stop)
-
-/* Checks whether a seek has been requested. If so, discards any buffered audio
- * and returns the position to seek to, in milliseconds. Otherwise, returns -1. */
-AUD_FUNC0 (int, input_check_seek)
diff --git a/src/audacious/input.h b/src/audacious/input.h
deleted file mode 100644
index 4935483..0000000
--- a/src/audacious/input.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * input.h
- * Copyright 2013 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.
- */
-
-#ifndef AUDACIOUS_INPUT_H
-#define AUDACIOUS_INPUT_H
-
-#include <audacious/api.h>
-#include <audacious/types.h>
-#include <libaudcore/tuple.h>
-
-#define AUD_API_NAME InputAPI
-#define AUD_API_SYMBOL input_api
-
-#ifdef _AUDACIOUS_CORE
-
-#include "api-local-begin.h"
-#include "input-api.h"
-#include "api-local-end.h"
-
-#else
-
-#include <audacious/api-define-begin.h>
-#include <audacious/input-api.h>
-#include <audacious/api-define-end.h>
-
-#include <audacious/api-alias-begin.h>
-#include <audacious/input-api.h>
-#include <audacious/api-alias-end.h>
-
-#endif
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
-
-#ifdef AUD_API_DECLARE
-
-#define AUD_API_NAME InputAPI
-#define AUD_API_SYMBOL input_api
-
-#include "api-define-begin.h"
-#include "input-api.h"
-#include "api-define-end.h"
-
-#include "api-declare-begin.h"
-#include "input-api.h"
-#include "api-declare-end.h"
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
diff --git a/src/audacious/interface.c b/src/audacious/interface.c
deleted file mode 100644
index 5c8045f..0000000
--- a/src/audacious/interface.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * interface.c
- * Copyright 2010-2013 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 <gtk/gtk.h>
-#include <pthread.h>
-
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "debug.h"
-#include "general.h"
-#include "i18n.h"
-#include "interface.h"
-#include "misc.h"
-#include "plugin.h"
-#include "plugins.h"
-#include "visualization.h"
-
-static IfacePlugin * current_interface = NULL;
-
-static pthread_mutex_t error_mutex = PTHREAD_MUTEX_INITIALIZER;
-static GQueue error_queue = G_QUEUE_INIT;
-static int error_source;
-static GtkWidget * error_win;
-
-bool_t interface_load (PluginHandle * plugin)
-{
- IfacePlugin * i = plugin_get_header (plugin);
- g_return_val_if_fail (i, FALSE);
-
- if (PLUGIN_HAS_FUNC (i, init) && ! i->init ())
- return FALSE;
-
- current_interface = i;
- return TRUE;
-}
-
-void interface_unload (void)
-{
- g_return_if_fail (current_interface);
-
- if (PLUGIN_HAS_FUNC (current_interface, cleanup))
- current_interface->cleanup ();
-
- current_interface = NULL;
-}
-
-void interface_show (bool_t show)
-{
- g_return_if_fail (current_interface);
-
- set_bool (NULL, "show_interface", show);
-
- if (PLUGIN_HAS_FUNC (current_interface, show))
- current_interface->show (show);
-}
-
-bool_t interface_is_shown (void)
-{
- g_return_val_if_fail (current_interface, FALSE);
-
- return get_bool (NULL, "show_interface");
-}
-
-static bool_t error_idle_func (void * unused)
-{
- pthread_mutex_lock (& error_mutex);
-
- char * message;
- while ((message = g_queue_pop_head (& error_queue)))
- {
- pthread_mutex_unlock (& error_mutex);
-
- if (headless_mode ())
- fprintf (stderr, "ERROR: %s\n", message);
- else
- audgui_simple_message (& error_win, GTK_MESSAGE_ERROR, _("Error"), message);
-
- str_unref (message);
-
- pthread_mutex_lock (& error_mutex);
- }
-
- error_source = 0;
-
- pthread_mutex_unlock (& error_mutex);
- return FALSE;
-}
-
-void interface_show_error (const char * message)
-{
- pthread_mutex_lock (& error_mutex);
-
- g_queue_push_tail (& error_queue, str_get (message));
-
- if (! error_source)
- error_source = g_idle_add (error_idle_func, NULL);
-
- pthread_mutex_unlock (& error_mutex);
-}
-
-static bool_t delete_cb (GtkWidget * window, GdkEvent * event, PluginHandle *
- plugin)
-{
- plugin_enable (plugin, FALSE);
- return TRUE;
-}
-
-void interface_add_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
-{
- g_return_if_fail (current_interface);
-
- if (PLUGIN_HAS_FUNC (current_interface, run_gtk_plugin))
- current_interface->run_gtk_plugin (widget, plugin_get_name (plugin));
- else
- {
- GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title ((GtkWindow *) window, plugin_get_name (plugin));
- gtk_window_set_default_size ((GtkWindow *) window, 300, 200);
- gtk_window_set_has_resize_grip ((GtkWindow *) window, FALSE);
- gtk_container_add ((GtkContainer *) window, widget);
- g_signal_connect (window, "delete-event", (GCallback) delete_cb, plugin);
- gtk_widget_show_all (window);
- }
-}
-
-void interface_remove_plugin_widget (PluginHandle * plugin, GtkWidget * widget)
-{
- g_return_if_fail (current_interface);
-
- if (PLUGIN_HAS_FUNC (current_interface, stop_gtk_plugin))
- current_interface->stop_gtk_plugin (widget);
- else
- gtk_widget_destroy (gtk_widget_get_parent (widget));
-}
-
-static bool_t probe_cb (PluginHandle * p, PluginHandle * * pp)
-{
- * pp = p;
- return FALSE;
-}
-
-PluginHandle * iface_plugin_probe (void)
-{
- PluginHandle * p = NULL;
- plugin_for_each (PLUGIN_TYPE_IFACE, (PluginForEachFunc) probe_cb, & p);
- return p;
-}
-
-static PluginHandle * current_plugin = NULL;
-
-PluginHandle * iface_plugin_get_current (void)
-{
- return current_plugin;
-}
-
-bool_t iface_plugin_set_current (PluginHandle * plugin)
-{
- hook_call ("config save", NULL); /* tell interface to save layout */
-
- if (current_plugin != NULL)
- {
- if (get_bool (NULL, "show_interface") && current_interface &&
- PLUGIN_HAS_FUNC (current_interface, show))
- current_interface->show (FALSE);
-
- AUDDBG ("Unloading plugin widgets.\n");
- general_cleanup ();
-
- AUDDBG ("Unloading visualizers.\n");
- vis_cleanup ();
-
- AUDDBG ("Unloading %s.\n", plugin_get_name (current_plugin));
- interface_unload ();
-
- current_plugin = NULL;
- }
-
- if (plugin != NULL)
- {
- AUDDBG ("Loading %s.\n", plugin_get_name (plugin));
-
- if (! interface_load (plugin))
- return FALSE;
-
- current_plugin = plugin;
-
- AUDDBG ("Loading visualizers.\n");
- vis_init ();
-
- AUDDBG ("Loading plugin widgets.\n");
- general_init ();
-
- if (get_bool (NULL, "show_interface") && current_interface &&
- PLUGIN_HAS_FUNC (current_interface, show))
- current_interface->show (TRUE);
- }
-
- return TRUE;
-}
diff --git a/src/audacious/interface.h b/src/audacious/interface.h
deleted file mode 100644
index 8bc5727..0000000
--- a/src/audacious/interface.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * interface.h
- * Copyright 2010-2011 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.
- */
-
-#ifndef __AUDACIOUS2_INTERFACE_H__
-#define __AUDACIOUS2_INTERFACE_H__
-
-#include <gtk/gtk.h>
-#include <audacious/plugins.h>
-
-bool_t interface_load (PluginHandle * plugin);
-void interface_unload (void);
-
-void interface_add_plugin_widget (PluginHandle * plugin, GtkWidget * widget);
-void interface_remove_plugin_widget (PluginHandle * plugin, GtkWidget * widget);
-
-PluginHandle * iface_plugin_probe (void);
-PluginHandle * iface_plugin_get_current (void);
-bool_t iface_plugin_set_current (PluginHandle * plugin);
-
-#endif
diff --git a/src/audacious/main.c b/src/audacious/main.c
deleted file mode 100644
index 8440969..0000000
--- a/src/audacious/main.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * main.c
- * Copyright 2007-2013 William Pitcock 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 <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <locale.h>
-
-#include <gtk/gtk.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-#include <libaudtag/audtag.h>
-
-#ifdef USE_DBUS
-#include "aud-dbus.h"
-#endif
-
-#include "debug.h"
-#include "drct.h"
-#include "equalizer.h"
-#include "i18n.h"
-#include "interface.h"
-#include "main.h"
-#include "misc.h"
-#include "playlist.h"
-#include "plugins.h"
-#include "scanner.h"
-#include "util.h"
-
-#define AUTOSAVE_INTERVAL 300 /* seconds */
-
-static struct {
- bool_t help, version;
- bool_t play, pause, play_pause, stop, fwd, rew;
- bool_t enqueue, enqueue_to_temp;
- bool_t mainwin, show_jump_box;
- bool_t headless, quit_after_play;
- bool_t verbose;
-} options;
-
-static Index * filenames;
-
-static const struct {
- const char * long_arg;
- char short_arg;
- bool_t * value;
- const char * desc;
-} arg_map[] = {
- {"help", 'h', & options.help, N_("Show command-line help")},
- {"version", 'v', & options.version, N_("Show version")},
- {"play", 'p', & options.play, N_("Start playback")},
- {"pause", 'u', & options.pause, N_("Pause playback")},
- {"play-pause", 't', & options.play_pause, N_("Pause if playing, play otherwise")},
- {"stop", 's', & options.stop, N_("Stop playback")},
- {"rew", 'r', & options.rew, N_("Skip to previous song")},
- {"fwd", 'f', & options.fwd, N_("Skip to next song")},
- {"enqueue", 'e', & options.enqueue, N_("Add files to the playlist")},
- {"enqueue-to-temp", 'E', & options.enqueue_to_temp, N_("Add files to a temporary playlist")},
- {"show-main-window", 'm', & options.mainwin, N_("Display the main window")},
- {"show-jump-box", 'j', & options.show_jump_box, N_("Display the jump-to-song window")},
- {"headless", 'H', & options.headless, N_("Start without a graphical interface")},
- {"quit-after-play", 'q', & options.quit_after_play, N_("Quit on playback stop")},
- {"verbose", 'V', & options.verbose, N_("Print debugging messages")},
-};
-
-static char * aud_paths[AUD_PATH_COUNT];
-
-static void make_dirs(void)
-{
-#ifdef S_IRGRP
- const mode_t mode755 = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
-#else
- const mode_t mode755 = S_IRWXU;
-#endif
-
- make_directory(aud_paths[AUD_PATH_USER_DIR], mode755);
- make_directory(aud_paths[AUD_PATH_PLAYLISTS_DIR], mode755);
-}
-
-static char * relocate_path (const char * path, const char * old, const char * new)
-{
- int oldlen = strlen (old);
- int newlen = strlen (new);
-
- if (oldlen && old[oldlen - 1] == G_DIR_SEPARATOR)
- oldlen --;
- if (newlen && new[newlen - 1] == G_DIR_SEPARATOR)
- newlen --;
-
-#ifdef _WIN32
- if (g_ascii_strncasecmp (path, old, oldlen) || (path[oldlen] && path[oldlen] != G_DIR_SEPARATOR))
-#else
- if (strncmp (path, old, oldlen) || (path[oldlen] && path[oldlen] != G_DIR_SEPARATOR))
-#endif
- {
- fprintf (stderr, "Failed to relocate a data path. Falling back to "
- "compile-time path: %s\n", path);
- return str_get (path);
- }
-
- return str_printf ("%.*s%s", newlen, new, path + oldlen);
-}
-
-static void relocate_paths (void)
-{
- char bindir[] = HARDCODE_BINDIR;
- char datadir[] = HARDCODE_DATADIR;
- char plugindir[] = HARDCODE_PLUGINDIR;
- char localedir[] = HARDCODE_LOCALEDIR;
- char desktopfile[] = HARDCODE_DESKTOPFILE;
- char iconfile[] = HARDCODE_ICONFILE;
-
- filename_normalize (bindir);
- filename_normalize (datadir);
- filename_normalize (plugindir);
- filename_normalize (localedir);
- filename_normalize (desktopfile);
- filename_normalize (iconfile);
-
- /* Compare the compile-time path to the executable and the actual path to
- * see if we have been moved. */
- char * self = get_path_to_self ();
- if (! self)
- {
-FALLBACK:
- /* Fall back to compile-time paths. */
- aud_paths[AUD_PATH_BIN_DIR] = str_get (bindir);
- aud_paths[AUD_PATH_DATA_DIR] = str_get (datadir);
- aud_paths[AUD_PATH_PLUGIN_DIR] = str_get (plugindir);
- aud_paths[AUD_PATH_LOCALE_DIR] = str_get (localedir);
- aud_paths[AUD_PATH_DESKTOP_FILE] = str_get (desktopfile);
- aud_paths[AUD_PATH_ICON_FILE] = str_get (iconfile);
-
- return;
- }
-
- SCOPY (old, bindir);
- SCOPY (new, self);
-
- str_unref (self);
-
- filename_normalize (new);
-
- /* Strip the name of the executable file, leaving the path. */
- char * base = last_path_element (new);
- if (! base)
- goto FALLBACK;
-
- cut_path_element (new, base);
-
- /* Strip innermost folder names from both paths as long as they match. This
- * leaves a compile-time prefix and a run-time one to replace it with. */
- char * a, * b;
- while ((a = last_path_element (old)) && (b = last_path_element (new)) &&
-#ifdef _WIN32
- ! g_ascii_strcasecmp (a, b))
-#else
- ! strcmp (a, b))
-#endif
- {
- cut_path_element (old, a);
- cut_path_element (new, b);
- }
-
- /* Do the replacements. */
- aud_paths[AUD_PATH_BIN_DIR] = relocate_path (bindir, old, new);
- aud_paths[AUD_PATH_DATA_DIR] = relocate_path (datadir, old, new);
- aud_paths[AUD_PATH_PLUGIN_DIR] = relocate_path (plugindir, old, new);
- aud_paths[AUD_PATH_LOCALE_DIR] = relocate_path (localedir, old, new);
- aud_paths[AUD_PATH_DESKTOP_FILE] = relocate_path (desktopfile, old, new);
- aud_paths[AUD_PATH_ICON_FILE] = relocate_path (iconfile, old, new);
-}
-
-static void init_paths (void)
-{
- relocate_paths ();
-
- const char * xdg_config_home = g_get_user_config_dir ();
-
- aud_paths[AUD_PATH_USER_DIR] = filename_build (xdg_config_home, "audacious");
- aud_paths[AUD_PATH_PLAYLISTS_DIR] = filename_build (aud_paths[AUD_PATH_USER_DIR], "playlists");
-
-#ifdef _WIN32
- /* Some libraries (libmcs) and plugins (filewriter) use these variables,
- * which are generally not set on Windows. */
- g_setenv ("HOME", g_get_home_dir (), TRUE);
- g_setenv ("XDG_CONFIG_HOME", xdg_config_home, TRUE);
- g_setenv ("XDG_DATA_HOME", g_get_user_data_dir (), TRUE);
- g_setenv ("XDG_CACHE_HOME", g_get_user_cache_dir (), TRUE);
-#endif
-}
-
-const char * get_path (int id)
-{
- g_return_val_if_fail (id >= 0 && id < AUD_PATH_COUNT, NULL);
- return aud_paths[id];
-}
-
-static bool_t parse_options (int argc, char * * argv)
-{
- char * cur = g_get_current_dir ();
- bool_t success = TRUE;
-
-#ifdef _WIN32
- get_argv_utf8 (& argc, & argv);
-#endif
-
- for (int n = 1; n < argc; n ++)
- {
- if (argv[n][0] != '-') /* filename */
- {
- char * uri = NULL;
-
- if (strstr (argv[n], "://"))
- uri = str_get (argv[n]);
- else if (g_path_is_absolute (argv[n]))
- uri = filename_to_uri (argv[n]);
- else
- {
- char * tmp = filename_build (cur, argv[n]);
- uri = filename_to_uri (tmp);
- str_unref (tmp);
- }
-
- if (uri)
- {
- if (! filenames)
- filenames = index_new ();
-
- index_insert (filenames, -1, uri);
- }
- }
- else if (argv[n][1] == '-') /* long option */
- {
- int i;
-
- for (i = 0; i < ARRAY_LEN (arg_map); i ++)
- {
- if (! strcmp (argv[n] + 2, arg_map[i].long_arg))
- {
- * arg_map[i].value = TRUE;
- break;
- }
- }
-
- if (i == ARRAY_LEN (arg_map))
- {
- fprintf (stderr, _("Unknown option: %s\n"), argv[n]);
- success = FALSE;
- goto OUT;
- }
- }
- else /* short form */
- {
- for (int c = 1; argv[n][c]; c ++)
- {
- int i;
-
- for (i = 0; i < ARRAY_LEN (arg_map); i ++)
- {
- if (argv[n][c] == arg_map[i].short_arg)
- {
- * arg_map[i].value = TRUE;
- break;
- }
- }
-
- if (i == ARRAY_LEN (arg_map))
- {
- fprintf (stderr, _("Unknown option: -%c\n"), argv[n][c]);
- success = FALSE;
- goto OUT;
- }
- }
- }
- }
-
- verbose = options.verbose;
-
-OUT:
-#ifdef _WIN32
- free_argv_utf8 (& argc, & argv);
-#endif
-
- g_free (cur);
- return success;
-}
-
-static void print_help (void)
-{
- static const char pad[20] = " ";
-
- fprintf (stderr, _("Usage: audacious [OPTION] ... [FILE] ...\n\n"));
-
- for (int i = 0; i < ARRAY_LEN (arg_map); i ++)
- fprintf (stderr, " -%c, --%s%.*s%s\n", arg_map[i].short_arg,
- arg_map[i].long_arg, (int) (20 - strlen (arg_map[i].long_arg)), pad,
- _(arg_map[i].desc));
-
- fprintf (stderr, "\n");
-}
-
-bool_t headless_mode (void)
-{
- return options.headless;
-}
-
-#ifdef USE_DBUS
-static void do_remote (void)
-{
- GDBusConnection * bus = NULL;
- ObjAudacious * obj = NULL;
- GError * error = NULL;
-
- if (! (bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, & error)))
- goto ERR;
-
- if (! (obj = obj_audacious_proxy_new_sync (bus, 0, "org.atheme.audacious",
- "/org/atheme/audacious", NULL, & error)))
- goto ERR;
-
- /* check whether remote is running */
- char * version = NULL;
- obj_audacious_call_version_sync (obj, & version, NULL, NULL);
-
- if (! version)
- goto DONE;
-
- AUDDBG ("Connected to remote version %s.\n", version);
-
- /* if no command line options, then present running instance */
- if (! (filenames || options.play || options.pause || options.play_pause ||
- options.stop || options.rew || options.fwd || options.show_jump_box ||
- options.mainwin))
- options.mainwin = TRUE;
-
- if (filenames)
- {
- int n_filenames = index_count (filenames);
- const char * * list = g_new (const char *, n_filenames + 1);
-
- for (int i = 0; i < n_filenames; i ++)
- list[i] = index_get (filenames, i);
-
- list[n_filenames] = NULL;
-
- if (options.enqueue_to_temp)
- obj_audacious_call_open_list_to_temp_sync (obj, list, NULL, NULL);
- else if (options.enqueue)
- obj_audacious_call_add_list_sync (obj, list, NULL, NULL);
- else
- obj_audacious_call_open_list_sync (obj, list, NULL, NULL);
-
- g_free (list);
- }
-
- if (options.play)
- obj_audacious_call_play_sync (obj, NULL, NULL);
- if (options.pause)
- obj_audacious_call_pause_sync (obj, NULL, NULL);
- if (options.play_pause)
- obj_audacious_call_play_pause_sync (obj, NULL, NULL);
- if (options.stop)
- obj_audacious_call_stop_sync (obj, NULL, NULL);
- if (options.rew)
- obj_audacious_call_reverse_sync (obj, NULL, NULL);
- if (options.fwd)
- obj_audacious_call_advance_sync (obj, NULL, NULL);
- if (options.show_jump_box)
- obj_audacious_call_show_jtf_box_sync (obj, TRUE, NULL, NULL);
- if (options.mainwin)
- obj_audacious_call_show_main_win_sync (obj, TRUE, NULL, NULL);
-
- g_free (version);
- g_object_unref (obj);
-
- exit (EXIT_SUCCESS);
-
-ERR:
- fprintf (stderr, "D-Bus error: %s\n", error->message);
- g_error_free (error);
-
-DONE:
- if (obj)
- g_object_unref (obj);
-
- return;
-}
-#endif
-
-static void do_commands (void)
-{
- bool_t resume = get_bool (NULL, "resume_playback_on_startup");
-
- if (filenames)
- {
- if (options.enqueue_to_temp)
- {
- drct_pl_open_temp_list (filenames);
- resume = FALSE;
- }
- else if (options.enqueue)
- drct_pl_add_list (filenames, -1);
- else
- {
- drct_pl_open_list (filenames);
- resume = FALSE;
- }
-
- filenames = NULL;
- }
-
- if (resume)
- playlist_resume ();
-
- if (options.play || options.play_pause)
- {
- if (! drct_get_playing ())
- drct_play ();
- else if (drct_get_paused ())
- drct_pause ();
- }
-
- if (options.show_jump_box && ! options.headless)
- audgui_jump_to_track ();
- if (options.mainwin && ! options.headless)
- interface_show (TRUE);
-}
-
-static void main_cleanup (void)
-{
- for (int i = 0; i < AUD_PATH_COUNT; i ++)
- str_unref (aud_paths[i]);
-
- if (filenames)
- index_free_full (filenames, (IndexFreeFunc) str_unref);
-
- strpool_shutdown ();
-}
-
-static void init_one (void)
-{
- atexit (main_cleanup);
-
-#ifdef HAVE_SIGWAIT
- signals_init_one ();
-#endif
-
- init_paths ();
- make_dirs ();
-
- setlocale (LC_ALL, "");
- bindtextdomain (PACKAGE, aud_paths[AUD_PATH_LOCALE_DIR]);
- bind_textdomain_codeset (PACKAGE, "UTF-8");
- bindtextdomain (PACKAGE "-plugins", aud_paths[AUD_PATH_LOCALE_DIR]);
- bind_textdomain_codeset (PACKAGE "-plugins", "UTF-8");
- textdomain (PACKAGE);
-
-#if ! GLIB_CHECK_VERSION (2, 36, 0)
- g_type_init ();
-#endif
-}
-
-static void init_two (void)
-{
- if (! options.headless)
- gtk_init (NULL, NULL);
-
-#ifdef HAVE_SIGWAIT
- signals_init_two ();
-#endif
-
- AUDDBG ("Loading configuration.\n");
- config_load ();
-
- AUDDBG ("Initializing.\n");
- art_init ();
- chardet_init ();
- eq_init ();
- playlist_init ();
-
- tag_set_verbose (verbose);
- vfs_set_verbose (verbose);
-
- AUDDBG ("Loading lowlevel plugins.\n");
- start_plugins_one ();
-
- AUDDBG ("Starting worker threads.\n");
- adder_init ();
- scanner_init ();
-
- AUDDBG ("Restoring state.\n");
- load_playlists ();
-
- do_commands ();
-
- AUDDBG ("Loading highlevel plugins.\n");
- start_plugins_two ();
-
-#ifdef USE_DBUS
- dbus_server_init ();
-#endif
-}
-
-static void shut_down (void)
-{
- AUDDBG ("Saving playlist state.\n");
- save_playlists (TRUE);
-
- AUDDBG ("Unloading highlevel plugins.\n");
- stop_plugins_two ();
-
-#ifdef USE_DBUS
- dbus_server_cleanup ();
-#endif
-
- AUDDBG ("Stopping playback.\n");
- if (drct_get_playing ())
- drct_stop ();
-
- AUDDBG ("Stopping worker threads.\n");
- adder_cleanup ();
- scanner_cleanup ();
-
- AUDDBG ("Unloading lowlevel plugins.\n");
- stop_plugins_one ();
-
- event_queue_cancel_all ();
-
- AUDDBG ("Saving configuration.\n");
- config_save ();
- config_cleanup ();
-
- AUDDBG ("Cleaning up.\n");
- art_cleanup ();
- chardet_cleanup ();
- eq_cleanup ();
- history_cleanup ();
- playlist_end ();
-}
-
-bool_t do_autosave (void)
-{
- AUDDBG ("Saving configuration.\n");
- hook_call ("config save", NULL);
- save_playlists (FALSE);
- config_save ();
- return TRUE;
-}
-
-static bool_t check_should_quit (void)
-{
- return options.quit_after_play && ! drct_get_playing () && ! playlist_add_in_progress (-1);
-}
-
-static void maybe_quit (void)
-{
- if (check_should_quit ())
- gtk_main_quit ();
-}
-
-int main (int argc, char * * argv)
-{
- init_one ();
-
- if (! parse_options (argc, argv))
- {
- print_help ();
- return EXIT_FAILURE;
- }
-
- if (options.help)
- {
- print_help ();
- return EXIT_SUCCESS;
- }
-
- if (options.version)
- {
- printf ("%s %s (%s)\n", _("Audacious"), VERSION, BUILDSTAMP);
- return EXIT_SUCCESS;
- }
-
-#if USE_DBUS
- do_remote (); /* may exit */
-#endif
-
- AUDDBG ("No remote session; starting up.\n");
- init_two ();
-
- AUDDBG ("Startup complete.\n");
- g_timeout_add_seconds (AUTOSAVE_INTERVAL, (GSourceFunc) do_autosave, NULL);
-
- if (check_should_quit ())
- goto QUIT;
-
- hook_associate ("playback stop", (HookFunction) maybe_quit, NULL);
- hook_associate ("playlist add complete", (HookFunction) maybe_quit, NULL);
-
- gtk_main ();
-
- hook_dissociate ("playback stop", (HookFunction) maybe_quit);
- hook_dissociate ("playlist add complete", (HookFunction) maybe_quit);
-
-QUIT:
- shut_down ();
- return EXIT_SUCCESS;
-}
-
-void drct_quit (void)
-{
- gtk_main_quit ();
-}
diff --git a/src/audacious/main.cc b/src/audacious/main.cc
new file mode 100644
index 0000000..ca6526f
--- /dev/null
+++ b/src/audacious/main.cc
@@ -0,0 +1,384 @@
+/*
+ * main.c
+ * Copyright 2007-2013 William Pitcock 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h> /* for g_get_current_dir, g_path_is_absolute */
+
+#include <libaudcore/audstrings.h>
+#include <libaudcore/drct.h>
+#include <libaudcore/hook.h>
+#include <libaudcore/i18n.h>
+#include <libaudcore/interface.h>
+#include <libaudcore/playlist.h>
+#include <libaudcore/runtime.h>
+#include <libaudcore/tuple.h>
+
+#ifdef USE_DBUS
+#include "aud-dbus.h"
+#endif
+
+#include "main.h"
+#include "util.h"
+
+static struct {
+ int help, version;
+ int play, pause, play_pause, stop, fwd, rew;
+ int enqueue, enqueue_to_temp;
+ int mainwin, show_jump_box;
+ int headless, quit_after_play;
+ int verbose;
+ int qt;
+} options;
+
+static Index<PlaylistAddItem> filenames;
+
+static const struct {
+ const char * long_arg;
+ char short_arg;
+ int * value;
+ const char * desc;
+} arg_map[] = {
+ {"help", 'h', & options.help, N_("Show command-line help")},
+ {"version", 'v', & options.version, N_("Show version")},
+ {"play", 'p', & options.play, N_("Start playback")},
+ {"pause", 'u', & options.pause, N_("Pause playback")},
+ {"play-pause", 't', & options.play_pause, N_("Pause if playing, play otherwise")},
+ {"stop", 's', & options.stop, N_("Stop playback")},
+ {"rew", 'r', & options.rew, N_("Skip to previous song")},
+ {"fwd", 'f', & options.fwd, N_("Skip to next song")},
+ {"enqueue", 'e', & options.enqueue, N_("Add files to the playlist")},
+ {"enqueue-to-temp", 'E', & options.enqueue_to_temp, N_("Add files to a temporary playlist")},
+ {"show-main-window", 'm', & options.mainwin, N_("Display the main window")},
+ {"show-jump-box", 'j', & options.show_jump_box, N_("Display the jump-to-song window")},
+ {"headless", 'H', & options.headless, N_("Start without a graphical interface")},
+ {"quit-after-play", 'q', & options.quit_after_play, N_("Quit on playback stop")},
+ {"verbose", 'V', & options.verbose, N_("Print debugging messages (may be used twice)")},
+#if defined(USE_QT) && defined(USE_GTK)
+ {"qt", 'Q', & options.qt, N_("Run in Qt mode")},
+#endif
+};
+
+static bool parse_options (int argc, char * * argv)
+{
+ char * cur = g_get_current_dir ();
+ bool success = true;
+
+#ifdef _WIN32
+ Index<String> args = get_argv_utf8 ();
+
+ for (int n = 1; n < args.len (); n ++)
+ {
+ const char * arg = args[n];
+#else
+ for (int n = 1; n < argc; n ++)
+ {
+ const char * arg = argv[n];
+#endif
+
+ if (arg[0] != '-') /* filename */
+ {
+ String uri;
+
+ if (strstr (arg, "://"))
+ uri = String (arg);
+ else if (g_path_is_absolute (arg))
+ uri = String (filename_to_uri (arg));
+ else
+ uri = String (filename_to_uri (filename_build ({cur, arg})));
+
+ if (uri)
+ filenames.append (uri);
+ }
+ else if (arg[1] == '-') /* long option */
+ {
+ bool found = false;
+
+ for (auto & arg_info : arg_map)
+ {
+ if (! strcmp (arg + 2, arg_info.long_arg))
+ {
+ (* arg_info.value) ++;
+ found = true;
+ break;
+ }
+ }
+
+ if (! found)
+ {
+ fprintf (stderr, _("Unknown option: %s\n"), arg);
+ success = false;
+ goto OUT;
+ }
+ }
+ else /* short form */
+ {
+ for (int c = 1; arg[c]; c ++)
+ {
+ bool found = false;
+
+ for (auto & arg_info : arg_map)
+ {
+ if (arg[c] == arg_info.short_arg)
+ {
+ (* arg_info.value) ++;
+ found = true;
+ break;
+ }
+ }
+
+ if (! found)
+ {
+ fprintf (stderr, _("Unknown option: -%c\n"), arg[c]);
+ success = false;
+ goto OUT;
+ }
+ }
+ }
+ }
+
+ aud_set_headless_mode (options.headless);
+
+ if (options.verbose >= 2)
+ audlog::set_stderr_level (audlog::Debug);
+ else if (options.verbose)
+ audlog::set_stderr_level (audlog::Info);
+
+ if (options.qt)
+ aud_set_mainloop_type (MainloopType::Qt);
+
+OUT:
+ g_free (cur);
+ return success;
+}
+
+static void print_help (void)
+{
+ static const char pad[21] = " ";
+
+ fprintf (stderr, _("Usage: audacious [OPTION] ... [FILE] ...\n\n"));
+
+ for (auto & arg_info : arg_map)
+ fprintf (stderr, " -%c, --%s%.*s%s\n", arg_info.short_arg,
+ arg_info.long_arg, (int) (20 - strlen (arg_info.long_arg)), pad,
+ _(arg_info.desc));
+
+ fprintf (stderr, "\n");
+}
+
+#ifdef USE_DBUS
+static void do_remote (void)
+{
+ GDBusConnection * bus = nullptr;
+ ObjAudacious * obj = nullptr;
+ GError * error = nullptr;
+
+#if ! GLIB_CHECK_VERSION (2, 36, 0)
+ g_type_init ();
+#endif
+
+ /* check whether this is the first instance */
+ if (dbus_server_init () != StartupType::Client)
+ return;
+
+ if (! (bus = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, & error)))
+ goto ERR;
+
+ if (! (obj = obj_audacious_proxy_new_sync (bus, (GDBusProxyFlags) 0,
+ "org.atheme.audacious", "/org/atheme/audacious", nullptr, & error)))
+ goto ERR;
+
+ AUDINFO ("Connected to remote session.\n");
+
+ /* if no command line options, then present running instance */
+ if (! (filenames.len () || options.play || options.pause ||
+ options.play_pause || options.stop || options.rew || options.fwd ||
+ options.show_jump_box || options.mainwin))
+ options.mainwin = true;
+
+ if (filenames.len ())
+ {
+ Index<const char *> list;
+
+ for (auto & item : filenames)
+ list.append (item.filename);
+
+ list.append (nullptr);
+
+ if (options.enqueue_to_temp)
+ obj_audacious_call_open_list_to_temp_sync (obj, list.begin (), nullptr, nullptr);
+ else if (options.enqueue)
+ obj_audacious_call_add_list_sync (obj, list.begin (), nullptr, nullptr);
+ else
+ obj_audacious_call_open_list_sync (obj, list.begin (), nullptr, nullptr);
+ }
+
+ if (options.play)
+ obj_audacious_call_play_sync (obj, nullptr, nullptr);
+ if (options.pause)
+ obj_audacious_call_pause_sync (obj, nullptr, nullptr);
+ if (options.play_pause)
+ obj_audacious_call_play_pause_sync (obj, nullptr, nullptr);
+ if (options.stop)
+ obj_audacious_call_stop_sync (obj, nullptr, nullptr);
+ if (options.rew)
+ obj_audacious_call_reverse_sync (obj, nullptr, nullptr);
+ if (options.fwd)
+ obj_audacious_call_advance_sync (obj, nullptr, nullptr);
+ if (options.show_jump_box)
+ obj_audacious_call_show_jtf_box_sync (obj, true, nullptr, nullptr);
+ if (options.mainwin)
+ obj_audacious_call_show_main_win_sync (obj, true, nullptr, nullptr);
+
+ g_object_unref (obj);
+
+ exit (EXIT_SUCCESS);
+
+ERR:
+ if (error)
+ {
+ AUDERR ("D-Bus error: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+#endif
+
+static void do_commands (void)
+{
+ bool resume = aud_get_bool (nullptr, "resume_playback_on_startup");
+
+ if (filenames.len ())
+ {
+ if (options.enqueue_to_temp)
+ {
+ aud_drct_pl_open_temp_list (std::move (filenames));
+ resume = false;
+ }
+ else if (options.enqueue)
+ aud_drct_pl_add_list (std::move (filenames), -1);
+ else
+ {
+ aud_drct_pl_open_list (std::move (filenames));
+ resume = false;
+ }
+ }
+
+ if (resume)
+ aud_resume ();
+
+ if (options.play || options.play_pause)
+ {
+ if (! aud_drct_get_playing ())
+ aud_drct_play ();
+ else if (aud_drct_get_paused ())
+ aud_drct_pause ();
+ }
+
+ if (options.show_jump_box && ! options.headless)
+ aud_ui_show_jump_to_song ();
+ if (options.mainwin && ! options.headless)
+ aud_ui_show (true);
+}
+
+static void main_cleanup (void)
+{
+ filenames.clear ();
+ aud_cleanup_paths ();
+ aud_leak_check ();
+}
+
+static bool check_should_quit (void)
+{
+ return options.quit_after_play && ! aud_drct_get_playing () &&
+ ! aud_playlist_add_in_progress (-1);
+}
+
+static void maybe_quit (void)
+{
+ if (check_should_quit ())
+ aud_quit ();
+}
+
+int main (int argc, char * * argv)
+{
+ atexit (main_cleanup);
+
+#ifdef HAVE_SIGWAIT
+ signals_init_one ();
+#endif
+
+ aud_init_paths ();
+ aud_init_i18n ();
+
+ if (! parse_options (argc, argv))
+ {
+ print_help ();
+ return EXIT_FAILURE;
+ }
+
+ if (options.help)
+ {
+ print_help ();
+ return EXIT_SUCCESS;
+ }
+
+ if (options.version)
+ {
+ printf ("%s %s (%s)\n", _("Audacious"), VERSION, BUILDSTAMP);
+ return EXIT_SUCCESS;
+ }
+
+#if USE_DBUS
+ do_remote (); /* may exit */
+#endif
+
+ AUDINFO ("No remote session; starting up.\n");
+
+#ifdef HAVE_SIGWAIT
+ signals_init_two ();
+#endif
+
+ aud_init ();
+
+ do_commands ();
+
+ if (check_should_quit ())
+ goto QUIT;
+
+ hook_associate ("playback stop", (HookFunction) maybe_quit, nullptr);
+ hook_associate ("playlist add complete", (HookFunction) maybe_quit, nullptr);
+ hook_associate ("quit", (HookFunction) aud_quit, nullptr);
+
+ aud_run ();
+
+ hook_dissociate ("playback stop", (HookFunction) maybe_quit);
+ hook_dissociate ("playlist add complete", (HookFunction) maybe_quit);
+ hook_dissociate ("quit", (HookFunction) aud_quit);
+
+QUIT:
+#ifdef USE_DBUS
+ dbus_server_cleanup ();
+#endif
+
+ aud_cleanup ();
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/audacious/main.h b/src/audacious/main.h
index 0fa3432..88fd0de 100644
--- a/src/audacious/main.h
+++ b/src/audacious/main.h
@@ -17,41 +17,22 @@
* the use of this software.
*/
-/* Header for all those files that have just one or two public identifiers. */
-
#ifndef _AUDACIOUS_MAIN_H
#define _AUDACIOUS_MAIN_H
-#include <libaudcore/core.h>
-
-/* adder.c */
-void adder_init (void);
-void adder_cleanup (void);
-
-/* art.c */
-void art_init (void);
-void art_cleanup (void);
-
/* dbus-server.c */
#ifdef USE_DBUS
-void dbus_server_init (void);
-void dbus_server_cleanup (void);
-#endif
-
-/* chardet.c */
-void chardet_init (void);
-void chardet_cleanup (void);
-/* config.c */
-void config_load (void);
-void config_save (void);
-void config_cleanup (void);
+enum class StartupType {
+ Server,
+ Client,
+ Unknown
+};
-/* history.c */
-void history_cleanup (void);
+StartupType dbus_server_init (void);
+void dbus_server_cleanup (void);
-/* main.c */
-bool_t do_autosave (void);
+#endif
/* signals.c */
#ifdef HAVE_SIGWAIT
@@ -59,7 +40,4 @@ void signals_init_one (void);
void signals_init_two (void);
#endif
-/* ui_albumart.c */
-char * get_associated_image_file (const char * filename); /* pooled */
-
#endif
diff --git a/src/audacious/misc-api.h b/src/audacious/misc-api.h
deleted file mode 100644
index b9ea2a5..0000000
--- a/src/audacious/misc-api.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * misc-api.h
- * Copyright 2010-2013 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.
- */
-
-/* Do not include this file directly; use misc.h instead. */
-
-/* all (char *) return values must be freed with str_unref() */
-
-/* art.c (thread-safe) */
-
-/* Gets album art for <file> (the URI of a song file) as JPEG or PNG data. If
- * the album art is not yet loaded, sets <data> to NULL and begins to load the
- * album art in the background. On completion, the "art ready" hook is called,
- * with <file> as a parameter. The "current art ready" hook is also called if
- * <file> is the currently playing song. */
-AUD_VFUNC3 (art_request_data, const char *, file, const void * *, data, int64_t *, len)
-
-/* Similar to art_request_data() but returns the URI of an image file.
- * (A temporary file will be created if necessary.) */
-AUD_FUNC1 (const char *, art_request_file, const char *, file)
-
-/* Releases album art returned by art_request_data() or art_request_file(). */
-AUD_VFUNC1 (art_unref, const char *, file)
-
-/* config.c (thread-safe) */
-
-AUD_VFUNC2 (config_set_defaults, const char *, section, const char * const *, entries)
-
-AUD_VFUNC3 (set_str, const char *, section, const char *, name, const char *, value)
-AUD_FUNC2 (char *, get_str, const char *, section, const char *, name)
-AUD_VFUNC3 (set_bool, const char *, section, const char *, name, bool_t, value)
-AUD_FUNC2 (bool_t, get_bool, const char *, section, const char *, name)
-AUD_VFUNC3 (set_int, const char *, section, const char *, name, int, value)
-AUD_FUNC2 (int, get_int, const char *, section, const char *, name)
-AUD_VFUNC3 (set_double, const char *, section, const char *, name, double, value)
-AUD_FUNC2 (double, get_double, const char *, section, const char *, name)
-
-/* equalizer.c */
-AUD_VFUNC1 (eq_set_bands, const double *, values)
-AUD_VFUNC1 (eq_get_bands, double *, values)
-AUD_VFUNC2 (eq_set_band, int, band, double, value)
-AUD_FUNC1 (double, eq_get_band, int, band)
-
-/* equalizer_preset.c */
-AUD_FUNC1 (EqualizerPreset *, equalizer_preset_new, const char *, name)
-AUD_VFUNC1 (equalizer_preset_free, EqualizerPreset *, preset)
-AUD_FUNC1 (Index *, equalizer_read_presets, const char *, basename)
-AUD_FUNC2 (bool_t, equalizer_write_presets, Index *, list, const char *, basename)
-
-/* note: legacy code! these are local filenames, not URIs */
-AUD_FUNC1 (EqualizerPreset *, load_preset_file, const char *, filename)
-AUD_FUNC2 (bool_t, save_preset_file, EqualizerPreset *, preset, const char *, filename)
-
-AUD_FUNC1 (Index *, import_winamp_presets, VFSFile *, file)
-AUD_FUNC2 (bool_t, export_winamp_preset, EqualizerPreset *, preset, VFSFile *, file)
-
-/* history.c */
-AUD_FUNC1 (const char *, history_get, int, entry)
-AUD_VFUNC1 (history_add, const char *, path)
-
-/* interface.c */
-AUD_VFUNC1 (interface_show, bool_t, show)
-AUD_FUNC0 (bool_t, interface_is_shown)
-
-/* interface_show_error() is safe to call from any thread */
-AUD_VFUNC1 (interface_show_error, const char *, message)
-
-/* main.c */
-AUD_FUNC1 (const char *, get_path, int, path)
-AUD_FUNC0 (bool_t, headless_mode)
-
-/* output.c */
-AUD_VFUNC1 (output_reset, int, type)
-
-/* probe.c */
-AUD_FUNC2 (PluginHandle *, file_find_decoder, const char *, filename, bool_t,
- fast)
-AUD_FUNC2 (Tuple *, file_read_tuple, const char *, filename, PluginHandle *,
- decoder)
-AUD_FUNC4 (bool_t, file_read_image, const char *, filename, PluginHandle *,
- decoder, void * *, data, int64_t *, size)
-AUD_FUNC2 (bool_t, file_can_write_tuple, const char *, filename,
- PluginHandle *, decoder)
-AUD_FUNC3 (bool_t, file_write_tuple, const char *, filename, PluginHandle *,
- decoder, const Tuple *, tuple)
-AUD_FUNC2 (bool_t, custom_infowin, const char *, filename, PluginHandle *,
- decoder)
-
-/* ui_plugin_menu.c */
-AUD_FUNC1 (/* GtkWidget * */ void *, get_plugin_menu, int, id)
-AUD_VFUNC4 (plugin_menu_add, int, id, MenuFunc, func, const char *, name,
- const char *, icon)
-AUD_VFUNC2 (plugin_menu_remove, int, id, MenuFunc, func)
-
-/* ui_preferences.c */
-AUD_VFUNC4 (create_widgets_with_domain, /* GtkWidget * */ void *, box,
- const PreferencesWidget *, widgets, int, n_widgets, const char *, domain)
-AUD_VFUNC0 (show_prefs_window)
-AUD_VFUNC1 (show_prefs_for_plugin_type, int, type)
-
-/* util.c */
-
-/* Constructs a full URI given:
- * 1. path: one of the following:
- * a. a full URI (returned unchanged)
- * b. an absolute filename (in the system locale)
- * c. a relative path (character set detected according to user settings)
- * 2. reference: the full URI of the playlist containing <path> */
-AUD_FUNC2 (char *, construct_uri, const char *, path, const char *, reference)
-
-/* visualization.c */
-AUD_VFUNC2 (vis_func_add, int, type, VisFunc, func)
-AUD_VFUNC1 (vis_func_remove, VisFunc, func)
diff --git a/src/audacious/misc.h b/src/audacious/misc.h
deleted file mode 100644
index 3d25517..0000000
--- a/src/audacious/misc.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * misc.h
- * Copyright 2010-2012 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.
- */
-
-#ifndef AUDACIOUS_MISC_H
-#define AUDACIOUS_MISC_H
-
-#include <audacious/api.h>
-#include <audacious/types.h>
-#include <libaudcore/index.h>
-#include <libaudcore/tuple.h>
-#include <libaudcore/vfs.h>
-
-enum {
- AUD_PATH_BIN_DIR,
- AUD_PATH_DATA_DIR,
- AUD_PATH_PLUGIN_DIR,
- AUD_PATH_LOCALE_DIR,
- AUD_PATH_DESKTOP_FILE,
- AUD_PATH_ICON_FILE,
- AUD_PATH_USER_DIR,
- AUD_PATH_PLAYLISTS_DIR,
- AUD_PATH_COUNT
-};
-
-enum {OUTPUT_RESET_EFFECTS_ONLY, OUTPUT_RESET_SOFT, OUTPUT_RESET_HARD};
-
-enum {
- AUD_MENU_MAIN,
- AUD_MENU_PLAYLIST,
- AUD_MENU_PLAYLIST_ADD,
- AUD_MENU_PLAYLIST_REMOVE,
- AUD_MENU_COUNT};
-
-typedef void (* MenuFunc) (void);
-
-enum {
- AUD_VIS_TYPE_CLEAR, /* like VisPlugin::clear() */
- AUD_VIS_TYPE_MONO_PCM, /* like VisPlugin::render_mono_pcm() */
- AUD_VIS_TYPE_MULTI_PCM, /* like VisPlugin::render_multi_pcm() */
- AUD_VIS_TYPE_FREQ, /* like VisPlugin::render_freq() */
- AUD_VIS_TYPES};
-
-/* generic type; does not correspond to actual function types */
-typedef void (* VisFunc) (void);
-
-#define AUD_API_NAME MiscAPI
-#define AUD_API_SYMBOL misc_api
-
-#ifdef _AUDACIOUS_CORE
-
-#include "api-local-begin.h"
-#include "misc-api.h"
-#include "api-local-end.h"
-
-#define create_widgets(b, w, a) create_widgets_with_domain (b, w, a, PACKAGE)
-
-#else
-
-#include <audacious/api-define-begin.h>
-#include <audacious/misc-api.h>
-#include <audacious/api-define-end.h>
-
-#include <audacious/api-alias-begin.h>
-#include <audacious/misc-api.h>
-#include <audacious/api-alias-end.h>
-
-#define aud_create_widgets(b, w, a) aud_create_widgets_with_domain (b, w, a, \
- PACKAGE)
-
-#endif
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
-
-#ifdef AUD_API_DECLARE
-
-#define AUD_API_NAME MiscAPI
-#define AUD_API_SYMBOL misc_api
-
-#include "api-define-begin.h"
-#include "misc-api.h"
-#include "api-define-end.h"
-
-#include "api-declare-begin.h"
-#include "misc-api.h"
-#include "api-declare-end.h"
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
diff --git a/src/audacious/output.c b/src/audacious/output.c
deleted file mode 100644
index b6f862a..0000000
--- a/src/audacious/output.c
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * output.c
- * Copyright 2009-2013 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 <math.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h> /* for g_usleep */
-
-#include "debug.h"
-#include "effect.h"
-#include "equalizer.h"
-#include "misc.h"
-#include "output.h"
-#include "plugin.h"
-#include "plugins.h"
-#include "vis_runner.h"
-
-#define SW_VOLUME_RANGE 40 /* decibels */
-
-static pthread_mutex_t mutex_major = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t mutex_minor = PTHREAD_MUTEX_INITIALIZER;
-
-#define LOCK_MAJOR pthread_mutex_lock (& mutex_major)
-#define UNLOCK_MAJOR pthread_mutex_unlock (& mutex_major)
-#define LOCK_MINOR pthread_mutex_lock (& mutex_minor)
-#define UNLOCK_MINOR pthread_mutex_unlock (& mutex_minor)
-#define LOCK_ALL do { LOCK_MAJOR; LOCK_MINOR; } while (0)
-#define UNLOCK_ALL do { UNLOCK_MINOR; UNLOCK_MAJOR; } while (0)
-
-/* State variables. State changes that are allowed between LOCK_MINOR and
- * UNLOCK_MINOR (all others must take place between LOCK_ALL and UNLOCK_ALL):
- * s_paused -> TRUE or FALSE, s_aborted -> TRUE, s_resetting -> TRUE */
-
-static bool_t s_input; /* input plugin connected */
-static bool_t s_output; /* output plugin connected */
-static bool_t s_gain; /* replay gain info set */
-static bool_t s_paused; /* paused */
-static bool_t s_aborted; /* writes aborted */
-static bool_t s_resetting; /* resetting output system */
-
-static OutputPlugin * cop;
-static int seek_time;
-static int in_format, in_channels, in_rate;
-static int out_format, out_channels, out_rate;
-static int64_t in_frames, out_frames;
-static ReplayGainInfo gain_info;
-
-static bool_t change_op;
-static OutputPlugin * new_op;
-
-static void * buffer1, * buffer2;
-static int buffer1_size, buffer2_size;
-
-static inline int FR2MS (int64_t f, int r)
- { return (f > 0) ? (f * 1000 + r / 2) / r : (f * 1000 - r / 2) / r; }
-static inline int MS2FR (int64_t ms, int r)
- { return (ms > 0) ? (ms * r + 500) / 1000 : (ms * r - 500) / 1000; }
-
-static inline int get_format (void)
-{
- switch (get_int (NULL, "output_bit_depth"))
- {
- case 16: return FMT_S16_NE;
- case 24: return FMT_S24_NE;
- case 32: return FMT_S32_NE;
- default: return FMT_FLOAT;
- }
-}
-
-static void ensure_buffer (void * * buffer, int * size, int newsize)
-{
- if (newsize > * size)
- {
- g_free (* buffer);
- * buffer = g_malloc (newsize);
- * size = newsize;
- }
-}
-
-/* assumes LOCK_ALL, s_output */
-static void cleanup_output (void)
-{
- if (! (s_paused || s_aborted) && PLUGIN_HAS_FUNC (cop, drain))
- {
- UNLOCK_MINOR;
- cop->drain ();
- LOCK_MINOR;
- }
-
- s_output = FALSE;
-
- g_free (buffer1);
- g_free (buffer2);
- buffer1 = NULL;
- buffer2 = NULL;
- buffer1_size = 0;
- buffer2_size = 0;
-
- if (PLUGIN_HAS_FUNC (cop, close_audio))
- cop->close_audio ();
-
- effect_flush ();
- vis_runner_start_stop (FALSE, FALSE);
-}
-
-/* assumes LOCK_ALL, s_output */
-static void apply_pause (void)
-{
- if (PLUGIN_HAS_FUNC (cop, pause))
- cop->pause (s_paused);
-
- vis_runner_start_stop (TRUE, s_paused);
-}
-
-/* assumes LOCK_ALL, s_input */
-static void setup_output (void)
-{
- int format = get_format ();
- int channels = in_channels;
- int rate = in_rate;
-
- effect_start (& channels, & rate);
- eq_set_format (channels, rate);
-
- if (s_output && format == out_format && channels == out_channels && rate ==
- out_rate && ! PLUGIN_HAS_FUNC (cop, force_reopen))
- return;
-
- if (s_output)
- cleanup_output ();
-
- if (! cop || ! PLUGIN_HAS_FUNC (cop, open_audio) || ! cop->open_audio (format, rate, channels))
- return;
-
- s_output = TRUE;
-
- out_format = format;
- out_channels = channels;
- out_rate = rate;
- out_frames = 0;
-
- apply_pause ();
-}
-
-/* assumes LOCK_MINOR, s_output */
-static void flush_output (void)
-{
- if (PLUGIN_HAS_FUNC (cop, flush))
- {
- cop->flush (0);
- out_frames = 0;
- }
-
- effect_flush ();
- vis_runner_flush ();
-}
-
-static void apply_replay_gain (float * data, int samples)
-{
- if (! get_bool (NULL, "enable_replay_gain"))
- return;
-
- float factor = powf (10, get_double (NULL, "replay_gain_preamp") / 20);
-
- if (s_gain)
- {
- float peak;
-
- if (get_bool (NULL, "replay_gain_album"))
- {
- factor *= powf (10, gain_info.album_gain / 20);
- peak = gain_info.album_peak;
- }
- else
- {
- factor *= powf (10, gain_info.track_gain / 20);
- peak = gain_info.track_peak;
- }
-
- if (get_bool (NULL, "enable_clipping_prevention") && peak * factor > 1)
- factor = 1 / peak;
- }
- else
- factor *= powf (10, get_double (NULL, "default_gain") / 20);
-
- if (factor < 0.99 || factor > 1.01)
- audio_amplify (data, 1, samples, & factor);
-}
-
-static void apply_software_volume (float * data, int channels, int samples)
-{
- if (! get_bool (NULL, "software_volume_control"))
- return;
-
- int l = get_int (NULL, "sw_volume_left");
- int r = get_int (NULL, "sw_volume_right");
-
- if (l == 100 && r == 100)
- return;
-
- float lfactor = (l == 0) ? 0 : powf (10, (float) SW_VOLUME_RANGE * (l - 100) / 100 / 20);
- float rfactor = (r == 0) ? 0 : powf (10, (float) SW_VOLUME_RANGE * (r - 100) / 100 / 20);
- float factors[channels];
-
- if (channels == 2)
- {
- factors[0] = lfactor;
- factors[1] = rfactor;
- }
- else
- {
- for (int c = 0; c < channels; c ++)
- factors[c] = MAX (lfactor, rfactor);
- }
-
- audio_amplify (data, channels, samples / channels, factors);
-}
-
-/* assumes LOCK_ALL, s_output */
-static void write_output_raw (void * data, int samples)
-{
- vis_runner_pass_audio (FR2MS (out_frames, out_rate), data, samples,
- out_channels, out_rate);
- out_frames += samples / out_channels;
-
- eq_filter (data, samples);
- apply_software_volume (data, out_channels, samples);
-
- if (get_bool (NULL, "soft_clipping"))
- audio_soft_clip (data, samples);
-
- if (out_format != FMT_FLOAT)
- {
- ensure_buffer (& buffer2, & buffer2_size, FMT_SIZEOF (out_format) * samples);
- audio_to_int (data, buffer2, out_format, samples);
- data = buffer2;
- }
-
- while (! (s_aborted || s_resetting))
- {
- bool_t blocking = ! PLUGIN_HAS_FUNC (cop, buffer_free);
- int ready;
-
- if (blocking)
- ready = out_channels * (out_rate / 50);
- else
- ready = cop->buffer_free () / FMT_SIZEOF (out_format);
-
- ready = MIN (ready, samples);
-
- if (PLUGIN_HAS_FUNC (cop, write_audio))
- {
- cop->write_audio (data, FMT_SIZEOF (out_format) * ready);
- data = (char *) data + FMT_SIZEOF (out_format) * ready;
- samples -= ready;
- }
-
- if (samples == 0)
- break;
-
- UNLOCK_MINOR;
-
- if (! blocking)
- {
- if (PLUGIN_HAS_FUNC (cop, period_wait))
- cop->period_wait ();
- else
- g_usleep (20000);
- }
-
- LOCK_MINOR;
- }
-}
-
-/* assumes LOCK_ALL, s_input, s_output */
-static bool_t write_output (void * data, int size, int stop_time)
-{
- bool_t stopped = FALSE;
-
- int64_t cur_frame = in_frames;
- int samples = size / FMT_SIZEOF (in_format);
-
- /* always update in_frames, whether we use all the decoded frames or not */
- in_frames += samples / in_channels;
-
- if (stop_time != -1)
- {
- int64_t frames_left = MS2FR (stop_time - seek_time, in_rate) - cur_frame;
- int64_t samples_left = in_channels * MAX (0, frames_left);
-
- if (samples >= samples_left)
- {
- samples = samples_left;
- stopped = TRUE;
- }
- }
-
- if (s_aborted)
- return ! stopped;
-
- if (in_format != FMT_FLOAT)
- {
- ensure_buffer (& buffer1, & buffer1_size, sizeof (float) * samples);
- audio_from_int (data, in_format, buffer1, samples);
- data = buffer1;
- }
-
- float * fdata = data;
- apply_replay_gain (fdata, samples);
- effect_process (& fdata, & samples);
- write_output_raw (fdata, samples);
-
- return ! stopped;
-}
-
-/* assumes LOCK_ALL, s_output */
-static void finish_effects (void)
-{
- float * data = NULL;
- int samples = 0;
-
- effect_finish (& data, & samples);
- write_output_raw (data, samples);
-}
-
-bool_t output_open_audio (int format, int rate, int channels)
-{
- /* prevent division by zero */
- if (rate < 1 || channels < 1)
- return FALSE;
-
- LOCK_ALL;
-
- if (s_output && s_paused)
- {
- flush_output ();
- s_paused = FALSE;
- apply_pause ();
- }
-
- s_input = TRUE;
- s_gain = s_paused = s_aborted = FALSE;
- seek_time = 0;
-
- in_format = format;
- in_channels = channels;
- in_rate = rate;
- in_frames = 0;
-
- setup_output ();
-
- UNLOCK_ALL;
- return TRUE;
-}
-
-void output_set_replaygain_info (const ReplayGainInfo * info)
-{
- LOCK_ALL;
-
- if (s_input)
- {
- memcpy (& gain_info, info, sizeof (ReplayGainInfo));
- s_gain = TRUE;
-
- AUDDBG ("Replay Gain info:\n");
- AUDDBG (" album gain: %f dB\n", info->album_gain);
- AUDDBG (" album peak: %f\n", info->album_peak);
- AUDDBG (" track gain: %f dB\n", info->track_gain);
- AUDDBG (" track peak: %f\n", info->track_peak);
- }
-
- UNLOCK_ALL;
-}
-
-/* returns FALSE if stop_time is reached */
-bool_t output_write_audio (void * data, int size, int stop_time)
-{
- LOCK_ALL;
- bool_t good = FALSE;
-
- if (s_input)
- {
- while ((! s_output || s_resetting) && ! s_aborted)
- {
- UNLOCK_ALL;
- g_usleep (20000);
- LOCK_ALL;
- }
-
- good = write_output (data, size, stop_time);
- }
-
- UNLOCK_ALL;
- return good;
-}
-
-void output_abort_write (void)
-{
- LOCK_MINOR;
-
- if (s_input)
- {
- s_aborted = TRUE;
-
- if (s_output)
- flush_output ();
- }
-
- UNLOCK_MINOR;
-}
-
-void output_pause (bool_t pause)
-{
- LOCK_MINOR;
-
- if (s_input)
- {
- s_paused = pause;
-
- if (s_output)
- apply_pause ();
- }
-
- UNLOCK_MINOR;
-}
-
-int output_written_time (void)
-{
- LOCK_MINOR;
- int time = 0;
-
- if (s_input)
- time = seek_time + FR2MS (in_frames, in_rate);
-
- UNLOCK_MINOR;
- return time;
-}
-
-void output_set_time (int time)
-{
- LOCK_ALL;
-
- if (s_input)
- {
- s_aborted = FALSE;
- seek_time = time;
- in_frames = 0;
- }
-
- UNLOCK_ALL;
-}
-
-bool_t output_is_open (void)
-{
- LOCK_MINOR;
- bool_t is_open = s_input;
- UNLOCK_MINOR;
- return is_open;
-}
-
-int output_get_time (void)
-{
- LOCK_MINOR;
- int time = 0, delay = 0;
-
- if (s_input)
- {
- if (s_output && PLUGIN_HAS_FUNC (cop, output_time))
- delay = FR2MS (out_frames, out_rate) - cop->output_time ();
-
- delay = effect_adjust_delay (delay);
- time = FR2MS (in_frames, in_rate);
- time = seek_time + MAX (time - delay, 0);
- }
-
- UNLOCK_MINOR;
- return time;
-}
-
-int output_get_raw_time (void)
-{
- LOCK_MINOR;
- int time = 0;
-
- if (s_output && PLUGIN_HAS_FUNC (cop, output_time))
- time = cop->output_time ();
-
- UNLOCK_MINOR;
- return time;
-}
-
-void output_close_audio (void)
-{
- LOCK_ALL;
-
- if (s_input)
- {
- s_input = FALSE;
-
- if (s_output && ! (s_paused || s_aborted || s_resetting))
- finish_effects (); /* first time for end of song */
- }
-
- UNLOCK_ALL;
-}
-
-void output_drain (void)
-{
- LOCK_ALL;
-
- if (! s_input && s_output)
- {
- finish_effects (); /* second time for end of playlist */
- cleanup_output ();
- }
-
- UNLOCK_ALL;
-}
-
-void output_reset (int type)
-{
- LOCK_MINOR;
-
- s_resetting = TRUE;
-
- if (s_output)
- flush_output ();
-
- UNLOCK_MINOR;
- LOCK_ALL;
-
- if (s_output && type != OUTPUT_RESET_EFFECTS_ONLY)
- cleanup_output ();
-
- if (type == OUTPUT_RESET_HARD)
- {
- if (cop && PLUGIN_HAS_FUNC (cop, cleanup))
- cop->cleanup ();
-
- if (change_op)
- cop = new_op;
-
- if (cop && PLUGIN_HAS_FUNC (cop, init) && ! cop->init ())
- cop = NULL;
- }
-
- if (s_input)
- setup_output ();
-
- s_resetting = FALSE;
-
- UNLOCK_ALL;
-}
-
-void output_get_volume (int * left, int * right)
-{
- LOCK_MINOR;
-
- * left = * right = 0;
-
- if (get_bool (NULL, "software_volume_control"))
- {
- * left = get_int (NULL, "sw_volume_left");
- * right = get_int (NULL, "sw_volume_right");
- }
- else if (cop && PLUGIN_HAS_FUNC (cop, get_volume))
- cop->get_volume (left, right);
-
- UNLOCK_MINOR;
-}
-
-void output_set_volume (int left, int right)
-{
- LOCK_MINOR;
-
- if (get_bool (NULL, "software_volume_control"))
- {
- set_int (NULL, "sw_volume_left", left);
- set_int (NULL, "sw_volume_right", right);
- }
- else if (cop && PLUGIN_HAS_FUNC (cop, set_volume))
- cop->set_volume (left, right);
-
- UNLOCK_MINOR;
-}
-
-static bool_t probe_cb (PluginHandle * p, PluginHandle * * pp)
-{
- OutputPlugin * op = plugin_get_header (p);
-
- if (! op || (PLUGIN_HAS_FUNC (op, init) && ! op->init ()))
- return TRUE; /* keep searching */
-
- if (PLUGIN_HAS_FUNC (op, cleanup))
- op->cleanup ();
-
- * pp = p;
- return FALSE; /* stop searching */
-}
-
-PluginHandle * output_plugin_probe (void)
-{
- PluginHandle * p = NULL;
- plugin_for_each (PLUGIN_TYPE_OUTPUT, (PluginForEachFunc) probe_cb, & p);
- return p;
-}
-
-PluginHandle * output_plugin_get_current (void)
-{
- return cop ? plugin_by_header (cop) : NULL;
-}
-
-bool_t output_plugin_set_current (PluginHandle * plugin)
-{
- change_op = TRUE;
- new_op = plugin ? plugin_get_header (plugin) : NULL;
- output_reset (OUTPUT_RESET_HARD);
-
- bool_t success = (cop == new_op);
- change_op = FALSE;
- new_op = NULL;
-
- return success;
-}
diff --git a/src/audacious/output.h b/src/audacious/output.h
deleted file mode 100644
index ac9ee48..0000000
--- a/src/audacious/output.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * output.h
- * Copyright 2010-2013 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.
- */
-
-#ifndef AUDACIOUS_OUTPUT_H
-#define AUDACIOUS_OUTPUT_H
-
-#include <libaudcore/core.h>
-#include "types.h"
-
-bool_t output_open_audio (int format, int rate, int channels);
-void output_set_replaygain_info (const ReplayGainInfo * info);
-bool_t output_write_audio (void * data, int size, int stop_time);
-void output_abort_write (void);
-void output_pause (bool_t pause);
-int output_written_time (void);
-void output_set_time (int time);
-
-bool_t output_is_open (void);
-int output_get_time (void);
-int output_get_raw_time (void);
-void output_close_audio (void);
-void output_drain (void);
-
-void output_get_volume (int * left, int * right);
-void output_set_volume (int left, int right);
-
-PluginHandle * output_plugin_probe (void);
-PluginHandle * output_plugin_get_current (void);
-bool_t output_plugin_set_current (PluginHandle * plugin);
-
-#endif /* AUDACIOUS_OUTPUT_H */
diff --git a/src/audacious/playback.c b/src/audacious/playback.c
deleted file mode 100644
index 7d9c56f..0000000
--- a/src/audacious/playback.c
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
- * playback.c
- * Copyright 2009-2013 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 <glib.h>
-#include <pthread.h>
-#include <string.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui.h>
-
-#include "drct.h"
-#include "i18n.h"
-#include "input.h"
-#include "interface.h"
-#include "misc.h"
-#include "output.h"
-#include "playback.h"
-#include "playlist.h"
-#include "plugin.h"
-
-static pthread_t playback_thread_handle;
-static int end_source = 0;
-
-static pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER;
-
-static pthread_mutex_t control_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/* level 1 data (persists to end of song) */
-static bool_t playing = FALSE;
-static int time_offset = 0;
-static int stop_time = -1;
-static bool_t paused = FALSE;
-static bool_t ready_flag = FALSE;
-static bool_t playback_error = FALSE;
-static bool_t song_finished = FALSE;
-
-static int seek_request = -1; /* under control_mutex */
-static int repeat_a = -1; /* under control_mutex */
-
-static volatile int repeat_b = -1; /* atomic */
-static volatile int stop_flag = FALSE; /* atomic */
-
-static int current_bitrate = -1, current_samplerate = -1, current_channels = -1;
-
-static int current_entry = -1;
-static char * current_filename = NULL; /* pooled */
-static char * current_title = NULL; /* pooled */
-static int current_length = -1;
-
-static InputPlugin * current_decoder = NULL;
-static VFSFile * current_file = NULL;
-static ReplayGainInfo current_gain;
-
-/* level 2 data (persists to end of playlist) */
-static bool_t stopped = TRUE;
-static int failed_entries = 0;
-
-/* clears gain info if tuple == NULL */
-static void read_gain_from_tuple (const Tuple * tuple)
-{
- memset (& current_gain, 0, sizeof current_gain);
-
- if (tuple == NULL)
- return;
-
- int album_gain = tuple_get_int (tuple, FIELD_GAIN_ALBUM_GAIN);
- int album_peak = tuple_get_int (tuple, FIELD_GAIN_ALBUM_PEAK);
- int track_gain = tuple_get_int (tuple, FIELD_GAIN_TRACK_GAIN);
- int track_peak = tuple_get_int (tuple, FIELD_GAIN_TRACK_PEAK);
- int gain_unit = tuple_get_int (tuple, FIELD_GAIN_GAIN_UNIT);
- int peak_unit = tuple_get_int (tuple, FIELD_GAIN_PEAK_UNIT);
-
- if (gain_unit)
- {
- current_gain.album_gain = album_gain / (float) gain_unit;
- current_gain.track_gain = track_gain / (float) gain_unit;
- }
-
- if (peak_unit)
- {
- current_gain.album_peak = album_peak / (float) peak_unit;
- current_gain.track_peak = track_peak / (float) peak_unit;
- }
-}
-
-static bool_t update_from_playlist (void)
-{
- int entry = playback_entry_get_position ();
- char * title = playback_entry_get_title ();
- int length = playback_entry_get_length ();
-
- if (entry == current_entry && str_equal (title, current_title) && length == current_length)
- {
- str_unref (title);
- return FALSE;
- }
-
- current_entry = entry;
- str_unref (current_title);
- current_title = title;
- current_length = length;
- return TRUE;
-}
-
-bool_t drct_get_ready (void)
-{
- if (! playing)
- return FALSE;
-
- pthread_mutex_lock (& ready_mutex);
- bool_t ready = ready_flag;
- pthread_mutex_unlock (& ready_mutex);
- return ready;
-}
-
-static void set_ready (void)
-{
- g_return_if_fail (playing);
-
- pthread_mutex_lock (& ready_mutex);
-
- update_from_playlist ();
- event_queue ("playback ready", NULL);
- ready_flag = TRUE;
-
- pthread_cond_signal (& ready_cond);
- pthread_mutex_unlock (& ready_mutex);
-}
-
-static void wait_until_ready (void)
-{
- g_return_if_fail (playing);
- pthread_mutex_lock (& ready_mutex);
-
- /* on restart, we still have to wait, but presumably not long */
- while (! ready_flag)
- pthread_cond_wait (& ready_cond, & ready_mutex);
-
- pthread_mutex_unlock (& ready_mutex);
-}
-
-static void update_cb (void * hook_data, void * user_data)
-{
- g_return_if_fail (playing);
-
- if (GPOINTER_TO_INT (hook_data) < PLAYLIST_UPDATE_METADATA || ! drct_get_ready ())
- return;
-
- if (update_from_playlist ())
- event_queue ("title change", NULL);
-}
-
-int drct_get_time (void)
-{
- if (! playing)
- return 0;
-
- wait_until_ready ();
-
- return output_get_time () - time_offset;
-}
-
-void drct_pause (void)
-{
- if (! playing)
- return;
-
- wait_until_ready ();
-
- paused = ! paused;
-
- output_pause (paused);
-
- if (paused)
- hook_call ("playback pause", NULL);
- else
- hook_call ("playback unpause", NULL);
-}
-
-static void playback_cleanup (void)
-{
- g_return_if_fail (playing);
- wait_until_ready ();
-
- if (! song_finished)
- {
- g_atomic_int_set (& stop_flag, TRUE);
- output_abort_write ();
- }
-
- pthread_join (playback_thread_handle, NULL);
- output_close_audio ();
-
- hook_dissociate ("playlist update", update_cb);
-
- event_queue_cancel ("playback ready", NULL);
- event_queue_cancel ("playback seek", NULL);
- event_queue_cancel ("info change", NULL);
- event_queue_cancel ("title change", NULL);
-
- if (end_source)
- {
- g_source_remove (end_source);
- end_source = 0;
- }
-
- /* level 1 data cleanup */
- playing = FALSE;
- time_offset = 0;
- stop_time = -1;
- paused = FALSE;
- ready_flag = FALSE;
- playback_error = FALSE;
- song_finished = FALSE;
-
- seek_request = -1;
- repeat_a = -1;
-
- g_atomic_int_set (& repeat_b, -1);
- g_atomic_int_set (& stop_flag, FALSE);
-
- current_bitrate = current_samplerate = current_channels = -1;
-
- current_entry = -1;
- str_unref (current_filename);
- current_filename = NULL;
- str_unref (current_title);
- current_title = NULL;
- current_length = -1;
-
- current_decoder = NULL;
-
- if (current_file)
- {
- vfs_fclose (current_file);
- current_file = NULL;
- }
-
- read_gain_from_tuple (NULL);
-
- set_bool (NULL, "stop_after_current_song", FALSE);
-}
-
-void playback_stop (void)
-{
- if (stopped)
- return;
-
- if (playing)
- playback_cleanup ();
-
- output_drain ();
-
- /* level 2 data cleanup */
- stopped = TRUE;
- failed_entries = 0;
-
- hook_call ("playback stop", NULL);
-}
-
-static void do_stop (int playlist)
-{
- playlist_set_playing (-1);
- playlist_set_position (playlist, playlist_get_position (playlist));
-}
-
-static void do_next (int playlist)
-{
- if (! playlist_next_song (playlist, get_bool (NULL, "repeat")))
- {
- playlist_set_position (playlist, -1);
- hook_call ("playlist end reached", NULL);
- }
-}
-
-static bool_t end_cb (void * unused)
-{
- g_return_val_if_fail (playing, FALSE);
-
- if (! playback_error)
- song_finished = TRUE;
-
- hook_call ("playback end", NULL);
-
- if (playback_error)
- failed_entries ++;
- else
- failed_entries = 0;
-
- int playlist = playlist_get_playing ();
-
- if (get_bool (NULL, "stop_after_current_song"))
- {
- do_stop (playlist);
-
- if (! get_bool (NULL, "no_playlist_advance"))
- do_next (playlist);
- }
- else if (get_bool (NULL, "no_playlist_advance"))
- {
- if (get_bool (NULL, "repeat") && ! failed_entries)
- playback_play (0, FALSE);
- else
- do_stop (playlist);
- }
- else
- {
- if (failed_entries < 10)
- do_next (playlist);
- else
- do_stop (playlist);
- }
-
- return FALSE;
-}
-
-static bool_t open_file (void)
-{
- /* no need to open a handle for custom URI schemes */
- if (current_decoder->schemes && current_decoder->schemes[0])
- return TRUE;
-
- current_file = vfs_fopen (current_filename, "r");
- return (current_file != NULL);
-}
-
-static void * playback_thread (void * unused)
-{
- if (! current_decoder)
- {
- PluginHandle * p = playback_entry_get_decoder ();
- current_decoder = p ? plugin_get_header (p) : NULL;
-
- if (! current_decoder)
- {
- SPRINTF (error, _("No decoder found for %s."), current_filename);
- interface_show_error (error);
- playback_error = TRUE;
- goto DONE;
- }
- }
-
- Tuple * tuple = playback_entry_get_tuple ();
- int length = playback_entry_get_length ();
-
- if (length < 1)
- seek_request = -1;
-
- if (tuple && length > 0)
- {
- if (tuple_get_value_type (tuple, FIELD_SEGMENT_START) == TUPLE_INT)
- {
- time_offset = tuple_get_int (tuple, FIELD_SEGMENT_START);
- if (time_offset)
- seek_request = time_offset + MAX (seek_request, 0);
- }
-
- if (tuple_get_value_type (tuple, FIELD_SEGMENT_END) == TUPLE_INT)
- stop_time = tuple_get_int (tuple, FIELD_SEGMENT_END);
- }
-
- read_gain_from_tuple (tuple);
-
- if (tuple)
- tuple_unref (tuple);
-
- if (! open_file ())
- {
- SPRINTF (error, _("%s could not be opened."), current_filename);
- interface_show_error (error);
- playback_error = TRUE;
- goto DONE;
- }
-
- playback_error = ! current_decoder->play (current_filename, current_file);
-
-DONE:
- if (! ready_flag)
- set_ready ();
-
- end_source = g_timeout_add (0, end_cb, NULL);
- return NULL;
-}
-
-void playback_play (int seek_time, bool_t pause)
-{
- char * new_filename = playback_entry_get_filename ();
- g_return_if_fail (new_filename);
-
- if (playing)
- playback_cleanup ();
-
- current_filename = new_filename;
-
- playing = TRUE;
- paused = pause;
-
- seek_request = (seek_time > 0) ? seek_time : -1;
-
- stopped = FALSE;
-
- hook_associate ("playlist update", update_cb, NULL);
- pthread_create (& playback_thread_handle, NULL, playback_thread, NULL);
-
- hook_call ("playback begin", NULL);
-}
-
-bool_t drct_get_playing (void)
-{
- return playing;
-}
-
-bool_t drct_get_paused (void)
-{
- return paused;
-}
-
-void drct_seek (int time)
-{
- if (! playing)
- return;
-
- wait_until_ready ();
-
- if (current_length < 1)
- return;
-
- pthread_mutex_lock (& control_mutex);
-
- seek_request = time_offset + CLAMP (time, 0, current_length);
- output_abort_write ();
-
- pthread_mutex_unlock (& control_mutex);
-}
-
-bool_t input_open_audio (int format, int rate, int channels)
-{
- g_return_val_if_fail (playing, FALSE);
-
- if (! output_open_audio (format, rate, channels))
- return FALSE;
-
- output_set_replaygain_info (& current_gain);
-
- if (paused)
- output_pause (TRUE);
-
- current_samplerate = rate;
- current_channels = channels;
-
- if (ready_flag)
- event_queue ("info change", NULL);
-
- return TRUE;
-}
-
-void input_set_gain (const ReplayGainInfo * info)
-{
- g_return_if_fail (playing);
- memcpy (& current_gain, info, sizeof current_gain);
- output_set_replaygain_info (& current_gain);
-}
-
-void input_write_audio (void * data, int length)
-{
- g_return_if_fail (playing);
-
- if (! ready_flag)
- set_ready ();
-
- int b = g_atomic_int_get (& repeat_b);
-
- if (b >= 0)
- {
- if (! output_write_audio (data, length, b))
- {
- pthread_mutex_lock (& control_mutex);
- seek_request = MAX (repeat_a, time_offset);
- pthread_mutex_unlock (& control_mutex);
- }
- }
- else
- {
- if (! output_write_audio (data, length, stop_time))
- g_atomic_int_set (& stop_flag, TRUE);
- }
-}
-
-int input_written_time (void)
-{
- g_return_val_if_fail (playing, -1);
- return output_written_time ();
-}
-
-Tuple * input_get_tuple (void)
-{
- g_return_val_if_fail (playing, NULL);
- return playback_entry_get_tuple ();
-}
-
-void input_set_tuple (Tuple * tuple)
-{
- g_return_if_fail (playing);
- playback_entry_set_tuple (tuple);
-}
-
-void input_set_bitrate (int bitrate)
-{
- g_return_if_fail (playing);
- current_bitrate = bitrate;
-
- if (ready_flag)
- event_queue ("info change", NULL);
-}
-
-bool_t input_check_stop (void)
-{
- g_return_val_if_fail (playing, TRUE);
- return g_atomic_int_get (& stop_flag);
-}
-
-int input_check_seek (void)
-{
- g_return_val_if_fail (playing, -1);
-
- pthread_mutex_lock (& control_mutex);
- int seek = seek_request;
-
- if (seek != -1)
- {
- output_set_time (seek);
- seek_request = -1;
-
- event_queue ("playback seek", NULL);
- }
-
- pthread_mutex_unlock (& control_mutex);
- return seek;
-}
-
-char * drct_get_filename (void)
-{
- if (! playing)
- return NULL;
-
- return str_ref (current_filename);
-}
-
-char * drct_get_title (void)
-{
- if (! playing)
- return NULL;
-
- wait_until_ready ();
-
- char s[32];
-
- if (current_length > 0)
- {
- char t[16];
- audgui_format_time (t, sizeof t, current_length);
- snprintf (s, sizeof s, " (%s)", t);
- }
- else
- s[0] = 0;
-
- if (get_bool (NULL, "show_numbers_in_pl"))
- return str_printf ("%d. %s%s", 1 + current_entry, current_title, s);
-
- return str_printf ("%s%s", current_title, s);
-}
-
-int drct_get_length (void)
-{
- if (playing)
- wait_until_ready ();
-
- return current_length;
-}
-
-void drct_get_info (int * bitrate, int * samplerate, int * channels)
-{
- if (playing)
- wait_until_ready ();
-
- * bitrate = current_bitrate;
- * samplerate = current_samplerate;
- * channels = current_channels;
-}
-
-void drct_get_volume (int * l, int * r)
-{
- output_get_volume (l, r);
-}
-
-void drct_set_volume (int l, int r)
-{
- output_set_volume (CLAMP (l, 0, 100), CLAMP (r, 0, 100));
-}
-
-void drct_set_ab_repeat (int a, int b)
-{
- if (! playing)
- return;
-
- wait_until_ready ();
-
- if (current_length < 1)
- return;
-
- if (a >= 0)
- a += time_offset;
- if (b >= 0)
- b += time_offset;
-
- pthread_mutex_lock (& control_mutex);
-
- repeat_a = a;
- g_atomic_int_set (& repeat_b, b);
-
- if (b != -1 && output_get_time () >= b)
- {
- seek_request = MAX (a, time_offset);
- output_abort_write ();
- }
-
- pthread_mutex_unlock (& control_mutex);
-}
-
-void drct_get_ab_repeat (int * a, int * b)
-{
- * a = (playing && repeat_a != -1) ? repeat_a - time_offset : -1;
- * b = (playing && repeat_b != -1) ? repeat_b - time_offset : -1;
-}
diff --git a/src/audacious/playback.h b/src/audacious/playback.h
deleted file mode 100644
index 2937791..0000000
--- a/src/audacious/playback.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * playback.h
- * Copyright 2013 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.
- */
-
-#ifndef AUDACIOUS_PLAYBACK_H
-#define AUDACIOUS_PLAYBACK_H
-
-#include <libaudcore/core.h>
-
-/* for use from playback.c and playlist-new.c ONLY */
-/* anywhere else, use drct_* and/or playlist_* functions */
-void playback_play (int seek_time, bool_t pause);
-void playback_stop (void);
-
-#endif /* AUDACIOUS_PLAYBACK_H */
diff --git a/src/audacious/playlist-api.h b/src/audacious/playlist-api.h
deleted file mode 100644
index 634fd05..0000000
--- a/src/audacious/playlist-api.h
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * playlist-api.h
- * Copyright 2010-2013 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.
- */
-
-/* Do not include this file directly; use playlist.h instead. */
-
-/* Any functions in this API with a return type of (char *) return pooled
- * strings that must not be modified and must be released with str_unref() when
- * no longer needed. */
-
-/* --- PLAYLIST CORE API --- */
-
-/* Returns the number of playlists currently open. There will always be at
- * least one playlist open. The playlists are numbered starting from zero. */
-AUD_FUNC0 (int, playlist_count)
-
-/* Adds a new playlist before the one numbered <at>. If <at> is -1 or equal to
- * the number of playlists, adds a new playlist after the last one. */
-AUD_VFUNC1 (playlist_insert, int, at)
-
-/* Moves a contiguous block of <count> playlists starting with the one numbered
- * <from> such that that playlist ends up at the position <to>. */
-AUD_VFUNC3 (playlist_reorder, int, from, int, to, int, count)
-
-/* Closes a playlist. CAUTION: The playlist is not saved, and no confirmation
- * is presented to the user. If <playlist> is the only playlist, a new playlist
- * is added. If <playlist> is the active playlist, another playlist is marked
- * active. If <playlist> is the currently playing playlist, playback is
- * stopped. */
-AUD_VFUNC1 (playlist_delete, int, playlist)
-
-/* Returns a unique non-negative integer which can be used to identify a given
- * playlist even if its numbering changes (as when playlists are reordered).
- * On error, returns -1. */
-AUD_FUNC1 (int, playlist_get_unique_id, int, playlist)
-
-/* Returns the number of the playlist identified by a given integer ID as
- * returned by playlist_get_unique_id(). If the playlist no longer exists,
- * returns -1. */
-AUD_FUNC1 (int, playlist_by_unique_id, int, id)
-
-/* Sets the filename associated with a playlist. (Audacious currently makes no
- * use of the filename.) */
-AUD_VFUNC2 (playlist_set_filename, int, playlist, const char *, filename)
-
-/* Returns the filename associated with a playlist. */
-AUD_FUNC1 (char *, playlist_get_filename, int, playlist)
-
-/* Sets the title associated with a playlist. */
-AUD_VFUNC2 (playlist_set_title, int, playlist, const char *, title)
-
-/* Returns the title associated with a playlist. */
-AUD_FUNC1 (char *, playlist_get_title, int, playlist)
-
-/* Sets the active playlist. This is the playlist that user interfaces will
- * show to the user. */
-AUD_VFUNC1 (playlist_set_active, int, playlist)
-
-/* Returns the number of the active playlist. */
-AUD_FUNC0 (int, playlist_get_active)
-
-/* Sets the currently playing playlist. Starts playback, resuming from the
- * position last played if possible. If <playlist> is -1 or if the requested
- * playlist is empty, stops playback. */
-AUD_VFUNC1 (playlist_set_playing, int, playlist)
-
-/* Returns the number of the currently playing playlist. If no playlist is
- * playing, returns -1. */
-AUD_FUNC0 (int, playlist_get_playing)
-
-/* Returns the number of a "blank" playlist. The active playlist is returned if
- * it has the default title and has no entries; otherwise, a new playlist is
- * added and returned. */
-AUD_FUNC0 (int, playlist_get_blank)
-
-/* Returns the number of the "temporary" playlist (which is no different from
- * any other playlist except in name). If the playlist does not exist, a
- * "blank" playlist is obtained from playlist_get_blank() and is renamed to
- * become the temporary playlist. */
-AUD_FUNC0 (int, playlist_get_temporary)
-
-/* Returns the number of entries in a playlist. The entries are numbered
- * starting from zero. */
-AUD_FUNC1 (int, playlist_entry_count, int, playlist)
-
-/* Adds a song file, playlist file, or folder to a playlist before the entry
- * numbered <at>. If <at> is negative or equal to the number of entries, the
- * item is added after the last entry. <tuple> may be NULL, in which case
- * Audacious will attempt to read metadata from the song file. The caller gives
- * up one reference count to <tuple>. If <play> is nonzero, Audacious will
- * begin playback of the items once they have been added.
- *
- * Because adding items to the playlist can be a slow process, this function may
- * return before the process is complete. Hence, the caller must not assume
- * that there will be new entries in the playlist immediately. */
-AUD_VFUNC5 (playlist_entry_insert, int, playlist, int, at, const char *,
- filename, Tuple *, tuple, bool_t, play)
-
-/* Similar to playlist_entry_insert, adds multiple song files, playlist files,
- * or folders to a playlist. The filenames, stored as (char *) in an index
- * (see libaudcore/index.h), must be pooled with str_get(); the caller gives up
- * one reference count to each filename. Tuples are likewise stored as
- * (Tuple *) in an index of the same length; the caller gives up one reference
- * count to each tuple. <tuples> may be NULL, or individual pointers within it
- * may be NULL. Finally, the caller also gives up ownership of the indexes
- * themselves and should not access them after the call. */
-AUD_VFUNC5 (playlist_entry_insert_batch, int, playlist, int, at,
- Index *, filenames, Index *, tuples, bool_t, play)
-
-/* Similar to playlist_entry_insert_batch, but allows the caller to prevent some
- * items from being added by returning false from the <filter> callback. Useful
- * for searching a folder and adding only new files to the playlist. Filenames
- * passed to the callback can be used with str_ref(), str_equal(), etc. <user>
- * is an additional, untyped pointer passed to the callback. */
-AUD_VFUNC7 (playlist_entry_insert_filtered, int, playlist, int, at,
- Index *, filenames, Index *, tuples, PlaylistFilterFunc, filter,
- void *, user, bool_t, play)
-
-/* Removes a contiguous block of <number> entries starting from the one numbered
- * <at> from a playlist. If necessary, the playback position is moved elsewhere
- * in the playlist and playback is restarted (or stopped). */
-AUD_VFUNC3 (playlist_entry_delete, int, playlist, int, at, int, number)
-
-/* Returns the filename of an entry. */
-AUD_FUNC2 (char *, playlist_entry_get_filename, int, playlist, int, entry)
-
-/* Returns a handle to the decoder plugin associated with an entry, or NULL if
- * none can be found. If <fast> is nonzero, returns NULL if no decoder plugin
- * has yet been found. */
-AUD_FUNC3 (PluginHandle *, playlist_entry_get_decoder, int, playlist, int,
- entry, bool_t, fast)
-
-/* Returns the tuple associated with an entry, or NULL if one is not available.
- * The reference count of the tuple is incremented. If <fast> is nonzero,
- * returns NULL if metadata for the entry has not yet been read from the song
- * file. */
-AUD_FUNC3 (Tuple *, playlist_entry_get_tuple, int, playlist, int, entry,
- bool_t, fast)
-
-/* Returns a formatted title string for an entry. This may include information
- * such as the filename, song title, and/or artist. If <fast> is nonzero,
- * returns a "best guess" based on the entry's filename if metadata for the
- * entry has not yet been read. */
-AUD_FUNC3 (char *, playlist_entry_get_title, int, playlist, int, entry,
- bool_t, fast)
-
-/* Returns three strings (title, artist, and album) describing an entry. The
- * strings are pooled, and the usual cautions apply. If <fast> is nonzero,
- * returns a "best guess" based on the entry's filename if metadata for the
- * entry has not yet been read. The caller may pass NULL for any values that
- * are not needed; NULL may also be returned for any values that are not
- * available. */
-AUD_VFUNC6 (playlist_entry_describe, int, playlist, int, entry,
- char * *, title, char * *, artist, char * *, album, bool_t, fast)
-
-/* Returns the length in milliseconds of an entry, or -1 if the length is not
- * known. <fast> is as in playlist_entry_get_tuple(). */
-AUD_FUNC3 (int, playlist_entry_get_length, int, playlist, int, entry,
- bool_t, fast)
-
-/* Moves the playback position to the beginning of the entry at <position>. If
- * <position> is -1, unsets the playback position. If <playlist> is the
- * currently playing playlist, playback is restarted (or stopped). */
-AUD_VFUNC2 (playlist_set_position, int, playlist, int, position)
-
-/* Returns the playback position, or -1 if it is not set. Note that the
- * position may be set even if <playlist> is not currently playing. */
-AUD_FUNC1 (int, playlist_get_position, int, playlist)
-
-/* Sets whether an entry is selected. */
-AUD_VFUNC3 (playlist_entry_set_selected, int, playlist, int, entry,
- bool_t, selected)
-
-/* Returns whether an entry is selected. */
-AUD_FUNC2 (bool_t, playlist_entry_get_selected, int, playlist, int, entry)
-
-/* Returns the number of selected entries in a playlist. */
-AUD_FUNC1 (int, playlist_selected_count, int, playlist)
-
-/* Selects all (or none) of the entries in a playlist. */
-AUD_VFUNC2 (playlist_select_all, int, playlist, bool_t, selected)
-
-/* Moves a selected entry within a playlist by an offset of <distance> entries.
- * Other selected entries are gathered around it. Returns the offset by which
- * the entry was actually moved, which may be less in absolute value than the
- * requested offset. */
-AUD_FUNC3 (int, playlist_shift, int, playlist, int, position, int, distance)
-
-/* Removes the selected entries from a playlist. If necessary, the playback
- * position is moved elsewhere in the playlist and playback is restarted (or
- * stopped). */
-AUD_VFUNC1 (playlist_delete_selected, int, playlist)
-
-/* Sorts the entries in a playlist based on filename. The callback function
- * should return negative if the first filename comes before the second,
- * positive if it comes after, or zero if the two are indistinguishable. */
-AUD_VFUNC2 (playlist_sort_by_filename, int, playlist,
- PlaylistStringCompareFunc, compare)
-
-/* Sorts the entries in a playlist based on tuple. May fail if metadata
- * scanning is still in progress (or has been disabled). */
-AUD_VFUNC2 (playlist_sort_by_tuple, int, playlist,
- PlaylistTupleCompareFunc, compare)
-
-/* Sorts the entries in a playlist based on formatted title string. May fail if
- * metadata scanning is still in progress (or has been disabled). */
-AUD_VFUNC2 (playlist_sort_by_title, int, playlist,
- PlaylistStringCompareFunc, compare)
-
-/* Sorts only the selected entries in a playlist based on filename. */
-AUD_VFUNC2 (playlist_sort_selected_by_filename, int, playlist,
- PlaylistStringCompareFunc, compare)
-
-/* Sorts only the selected entries in a playlist based on tuple. May fail if
- * metadata scanning is still in progress (or has been disabled). */
-AUD_VFUNC2 (playlist_sort_selected_by_tuple, int, playlist,
- PlaylistTupleCompareFunc, compare)
-
-/* Sorts only the selected entries in a playlist based on formatted title
- * string. May fail if metadata scanning is still in progress (or has been
- * disabled). */
-AUD_VFUNC2 (playlist_sort_selected_by_title, int, playlist,
- PlaylistStringCompareFunc, compare)
-
-/* Reverses the order of the entries in a playlist. */
-AUD_VFUNC1 (playlist_reverse, int, playlist)
-
-/* Reorders the entries in a playlist randomly. */
-AUD_VFUNC1 (playlist_randomize, int, playlist)
-
-/* Discards the metadata stored for all the entries in a playlist and starts
- * reading it afresh from the song files in the background. */
-AUD_VFUNC1 (playlist_rescan, int, playlist)
-
-/* Like playlist_rescan, but applies only to the selected entries in a playlist. */
-AUD_VFUNC1 (playlist_rescan_selected, int, playlist)
-
-/* Discards the metadata stored for all the entries that refer to a particular
- * song file, in whatever playlist they appear, and starts reading it afresh
- * from that file in the background. */
-AUD_VFUNC1 (playlist_rescan_file, const char *, filename)
-
-/* Calculates the total length in milliseconds of all the entries in a playlist.
- * Only takes into account entries for which metadata has already been read. */
-AUD_FUNC1 (int64_t, playlist_get_total_length, int, playlist)
-
-/* Calculates the total length in milliseconds of only the selected entries in a
- * playlist. Only takes into account entries for which metadata has already
- * been read. */
-AUD_FUNC1 (int64_t, playlist_get_selected_length, int, playlist)
-
-/* Returns the number of entries in a playlist queue. The entries are numbered
- * starting from zero, lower numbers being played first. */
-AUD_FUNC1 (int, playlist_queue_count, int, playlist)
-
-/* Adds an entry to a playlist's queue before the entry numbered <at> in the
- * queue. If <at> is negative or equal to the number of entries in the queue,
- * adds the entry after the last one in the queue. The same entry cannot be
- * added to the queue more than once. */
-AUD_VFUNC3 (playlist_queue_insert, int, playlist, int, at, int, entry)
-
-/* Adds the selected entries in a playlist to the queue, if they are not already
- * in it. */
-AUD_VFUNC2 (playlist_queue_insert_selected, int, playlist, int, at)
-
-/* Returns the position in the playlist of the entry at a given position in the
- * queue. */
-AUD_FUNC2 (int, playlist_queue_get_entry, int, playlist, int, at)
-
-/* Returns the position in the queue of the entry at a given position in the
- * playlist. If it is not in the queue, returns -1. */
-AUD_FUNC2 (int, playlist_queue_find_entry, int, playlist, int, entry)
-
-/* Removes a contiguous block of <number> entries starting with the one numbered
- * <at> from the queue. */
-AUD_VFUNC3 (playlist_queue_delete, int, playlist, int, at, int, number)
-
-/* Removes the selected entries in a playlist from the queue, if they are in it. */
-AUD_VFUNC1 (playlist_queue_delete_selected, int, playlist)
-
-/* Returns nonzero if a "playlist update" hook call is pending. If called from
- * within the hook, the current hook call is not considered pending. */
-AUD_FUNC0 (bool_t, playlist_update_pending)
-
-/* May be called within the "playlist update" hook to determine the update level
- * and number of entries changed in a playlist. Returns the update level for
- * the playlist, storing the number of the first entry changed in <at> and the
- * number of contiguous entries to be updated in <count>. Note that entries may
- * have been added or removed within this range. If no entries in the playlist
- * have changed, returns zero. */
-AUD_FUNC3 (int, playlist_updated_range, int, playlist, int *, at, int *, count)
-
-/* Returns nonzero if entries are being added to a playlist in the background.
- * If <playlist> is -1, checks all playlists. */
-AUD_FUNC1 (bool_t, playlist_add_in_progress, int, playlist)
-
-/* Returns nonzero if entries in a playlist are being scanned for metadata in
- * the background. If <playlist> is -1, checks all playlists. */
-AUD_FUNC1 (bool_t, playlist_scan_in_progress, int, playlist)
-
-/* --- PLAYLIST UTILITY API --- */
-
-/* Sorts the entries in a playlist according to one of the schemes listed in
- * playlist.h. */
-AUD_VFUNC2 (playlist_sort_by_scheme, int, playlist, int, scheme)
-
-/* Sorts only the selected entries in a playlist according to one of those
- * schemes. */
-AUD_VFUNC2 (playlist_sort_selected_by_scheme, int, playlist, int, scheme)
-
-/* Removes duplicate entries in a playlist according to one of those schemes.
- * As currently implemented, first sorts the playlist. */
-AUD_VFUNC2 (playlist_remove_duplicates_by_scheme, int, playlist, int,
- scheme)
-
-/* Removes all entries referring to unavailable files in a playlist. ("Remove
- * failed" is something of a misnomer for the current behavior.) As currently
- * implemented, only works for file:// URIs. */
-AUD_VFUNC1 (playlist_remove_failed, int, playlist)
-
-/* Selects all the entries in a playlist that match regular expressions stored
- * in the fields of a tuple. Does not free the memory used by the tuple.
- * Example: To select all the songs whose title starts with the letter "A",
- * create a blank tuple and set its title field to "^A". */
-AUD_VFUNC2 (playlist_select_by_patterns, int, playlist, const Tuple *,
- patterns)
-
-/* Returns nonzero if <filename> refers to a playlist file. */
-AUD_FUNC1 (bool_t, filename_is_playlist, const char *, filename)
-
-/* Saves the entries in a playlist to a playlist file. The format of the file
- * is determined from the file extension. Returns nonzero on success. */
-AUD_FUNC2 (bool_t, playlist_save, int, playlist, const char *, filename)
-
-/* added in Audacious 3.4 */
-
-/* Reverses the order of the selected entries in a playlist. */
-AUD_VFUNC1 (playlist_reverse_selected, int, playlist)
-
-/* Reorders the selected entries in a playlist randomly. */
-AUD_VFUNC1 (playlist_randomize_selected, int, playlist)
-
-/* Sets the entry which has keyboard focus (-1 means no entry). */
-AUD_VFUNC2 (playlist_set_focus, int, playlist_num, int, entry_num)
-
-/* Gets the entry which has keyboard focus (-1 means no entry). */
-AUD_FUNC1 (int, playlist_get_focus, int, playlist_num)
diff --git a/src/audacious/playlist-files.c b/src/audacious/playlist-files.c
deleted file mode 100644
index 8ebe521..0000000
--- a/src/audacious/playlist-files.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * playlist-files.c
- * Copyright 2010-2013 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 <glib.h>
-#include <libaudcore/audstrings.h>
-
-#include "debug.h"
-#include "i18n.h"
-#include "misc.h"
-#include "playlist.h"
-#include "plugin.h"
-#include "plugins.h"
-
-typedef struct
-{
- const char * filename;
- char * title;
- Index * filenames;
- Index * tuples;
- bool_t plugin_found;
- bool_t success;
-}
-PlaylistData;
-
-static void plugin_for_filename (const char * filename, PluginForEachFunc func, void * data)
-{
- char ext[32];
- if (uri_get_extension (filename, ext, sizeof ext))
- playlist_plugin_for_ext (ext, func, data);
-}
-
-static bool_t plugin_found_cb (PluginHandle * plugin, void * data)
-{
- * (PluginHandle * *) data = plugin;
- return FALSE; /* stop when first plugin is found */
-}
-
-bool_t filename_is_playlist (const char * filename)
-{
- PluginHandle * plugin = NULL;
- plugin_for_filename (filename, plugin_found_cb, & plugin);
- return (plugin != NULL);
-}
-
-static bool_t playlist_load_cb (PluginHandle * plugin, void * data_)
-{
- PlaylistData * data = (PlaylistData *) data_;
-
- PlaylistPlugin * pp = plugin_get_header (plugin);
- if (! pp || ! PLUGIN_HAS_FUNC (pp, load))
- return TRUE; /* try another plugin */
-
- data->plugin_found = TRUE;
-
- VFSFile * file = vfs_fopen (data->filename, "r");
- if (! file)
- return FALSE; /* stop if we can't open file */
-
- data->success = pp->load (data->filename, file, & data->title, data->filenames, data->tuples);
-
- vfs_fclose (file);
- return ! data->success; /* stop when playlist is loaded */
-}
-
-bool_t playlist_load (const char * filename, char * * title, Index * * filenames, Index * * tuples)
-{
- PlaylistData data =
- {
- .filename = filename,
- .filenames = index_new (),
- .tuples = index_new ()
- };
-
- AUDDBG ("Loading playlist %s.\n", filename);
- plugin_for_filename (filename, playlist_load_cb, & data);
-
- if (! data.plugin_found)
- {
- SPRINTF (error, _("Cannot load %s: unsupported file extension."), filename);
- interface_show_error (error);
- }
-
- if (! data.success)
- {
- str_unref (data.title);
- index_free_full (data.filenames, (IndexFreeFunc) str_unref);
- index_free_full (data.tuples, (IndexFreeFunc) tuple_unref);
- return FALSE;
- }
-
- if (index_count (data.tuples))
- g_return_val_if_fail (index_count (data.tuples) == index_count (data.filenames), FALSE);
- else
- {
- index_free (data.tuples);
- data.tuples = NULL;
- }
-
- * title = data.title;
- * filenames = data.filenames;
- * tuples = data.tuples;
- return TRUE;
-}
-
-bool_t playlist_insert_playlist_raw (int list, int at, const char * filename)
-{
- char * title = NULL;
- Index * filenames, * tuples;
-
- if (! playlist_load (filename, & title, & filenames, & tuples))
- return FALSE;
-
- if (title && ! playlist_entry_count (list))
- playlist_set_title (list, title);
-
- playlist_entry_insert_batch_raw (list, at, filenames, tuples, NULL);
-
- str_unref (title);
- return TRUE;
-}
-
-static bool_t playlist_save_cb (PluginHandle * plugin, void * data_)
-{
- PlaylistData * data = data_;
-
- PlaylistPlugin * pp = plugin_get_header (plugin);
- if (! pp || ! PLUGIN_HAS_FUNC (pp, save))
- return TRUE; /* try another plugin */
-
- data->plugin_found = TRUE;
-
- VFSFile * file = vfs_fopen (data->filename, "w");
- if (! file)
- return FALSE; /* stop if we can't open file */
-
- data->success = pp->save (data->filename, file, data->title, data->filenames, data->tuples);
-
- vfs_fclose (file);
- return FALSE; /* stop after first attempt (successful or not) */
-}
-
-bool_t playlist_save (int list, const char * filename)
-{
- PlaylistData data =
- {
- .filename = filename,
- .title = playlist_get_title (list),
- .filenames = index_new (),
- .tuples = index_new ()
- };
-
- int entries = playlist_entry_count (list);
- bool_t fast = get_bool (NULL, "metadata_on_play");
-
- index_allocate (data.filenames, entries);
- index_allocate (data.tuples, entries);
-
- for (int i = 0; i < entries; i ++)
- {
- index_insert (data.filenames, -1, playlist_entry_get_filename (list, i));
- index_insert (data.tuples, -1, playlist_entry_get_tuple (list, i, fast));
- }
-
- AUDDBG ("Saving playlist %s.\n", filename);
- plugin_for_filename (filename, playlist_save_cb, & data);
-
- if (! data.plugin_found)
- {
- SPRINTF (error, _("Cannot save %s: unsupported file extension."), filename);
- interface_show_error (error);
- }
-
- str_unref (data.title);
- index_free_full (data.filenames, (IndexFreeFunc) str_unref);
- index_free_full (data.tuples, (IndexFreeFunc) tuple_unref);
-
- return data.success;
-}
diff --git a/src/audacious/playlist-new.c b/src/audacious/playlist-new.c
deleted file mode 100644
index 23696b0..0000000
--- a/src/audacious/playlist-new.c
+++ /dev/null
@@ -1,2401 +0,0 @@
-/*
- * playlist-new.c
- * Copyright 2009-2013 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 <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudcore/tuple.h>
-
-#include "drct.h"
-#include "i18n.h"
-#include "misc.h"
-#include "playback.h"
-#include "playlist.h"
-#include "plugins.h"
-#include "scanner.h"
-#include "util.h"
-
-enum {RESUME_STOP, RESUME_PLAY, RESUME_PAUSE};
-
-#define STATE_FILE "playlist-state"
-
-#define ENTER pthread_mutex_lock (& mutex)
-#define LEAVE pthread_mutex_unlock (& mutex)
-
-#define RETURN(...) do { \
- pthread_mutex_unlock (& mutex); \
- return __VA_ARGS__; \
-} while (0)
-
-#define ENTER_GET_PLAYLIST(...) ENTER; \
- Playlist * playlist = lookup_playlist (playlist_num); \
- if (! playlist) \
- RETURN (__VA_ARGS__);
-
-#define ENTER_GET_ENTRY(...) ENTER_GET_PLAYLIST (__VA_ARGS__); \
- Entry * entry = lookup_entry (playlist, entry_num); \
- if (! entry) \
- RETURN (__VA_ARGS__);
-
-typedef struct {
- int level, before, after;
-} Update;
-
-typedef struct {
- int number;
- char * filename;
- PluginHandle * decoder;
- Tuple * tuple;
- char * formatted, * title, * artist, * album;
- int length;
- bool_t failed;
- bool_t selected;
- int shuffle_num;
- bool_t queued;
-} Entry;
-
-typedef struct {
- int number, unique_id;
- char * filename, * title;
- bool_t modified;
- Index * entries;
- Entry * position, * focus;
- int selected_count;
- int last_shuffle_num;
- GList * queued;
- int64_t total_length, selected_length;
- bool_t scanning, scan_ending;
- Update next_update, last_update;
- bool_t resume_paused;
- int resume_time;
-} Playlist;
-
-static const char * const default_title = N_("New Playlist");
-static const char * const temp_title = N_("Now Playing");
-
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-
-/* The unique ID table contains pointers to Playlist for ID's in use and NULL
- * for "dead" (previously used and therefore unavailable) ID's. */
-static GHashTable * unique_id_table = NULL;
-static int next_unique_id = 1000;
-
-static Index * playlists = NULL;
-static Playlist * active_playlist = NULL;
-static Playlist * playing_playlist = NULL;
-static int resume_playlist = -1;
-
-static int update_source = 0, update_level;
-
-typedef struct {
- Playlist * playlist;
- Entry * entry;
- ScanRequest * request;
-} ScanItem;
-
-static int scan_playlist, scan_row;
-static GList * scan_list = NULL;
-
-static void scan_finish (ScanRequest * request);
-static void scan_cancel (Entry * entry);
-static void scan_restart (void);
-
-static bool_t next_song_locked (Playlist * playlist, bool_t repeat, int hint);
-
-static TupleFormatter * title_formatter;
-
-static void entry_set_tuple_real (Entry * entry, Tuple * tuple)
-{
- /* Hack: We cannot refresh segmented entries (since their info is read from
- * the cue sheet when it is first loaded), so leave them alone. -jlindgren */
- if (entry->tuple && tuple_get_value_type (entry->tuple, FIELD_SEGMENT_START) == TUPLE_INT)
- {
- if (tuple)
- tuple_unref (tuple);
- return;
- }
-
- if (entry->tuple)
- tuple_unref (entry->tuple);
-
- entry->tuple = tuple;
- entry->failed = FALSE;
-
- str_unref (entry->formatted);
- str_unref (entry->title);
- str_unref (entry->artist);
- str_unref (entry->album);
-
- describe_song (entry->filename, tuple, & entry->title, & entry->artist, & entry->album);
-
- if (! tuple)
- {
- entry->formatted = NULL;
- entry->length = 0;
- }
- else
- {
- entry->formatted = tuple_format_title (title_formatter, tuple);
- entry->length = tuple_get_int (tuple, FIELD_LENGTH);
- if (entry->length < 0)
- entry->length = 0;
- }
-}
-
-static void entry_set_tuple (Playlist * playlist, Entry * entry, Tuple * tuple)
-{
- scan_cancel (entry);
-
- if (entry->tuple)
- {
- playlist->total_length -= entry->length;
- if (entry->selected)
- playlist->selected_length -= entry->length;
- }
-
- entry_set_tuple_real (entry, tuple);
-
- if (tuple)
- {
- playlist->total_length += entry->length;
- if (entry->selected)
- playlist->selected_length += entry->length;
- }
-}
-
-static void entry_set_failed (Playlist * playlist, Entry * entry)
-{
- entry_set_tuple (playlist, entry, tuple_new_from_filename (entry->filename));
- entry->failed = TRUE;
-}
-
-static Entry * entry_new (char * filename, Tuple * tuple, PluginHandle * decoder)
-{
- Entry * entry = g_slice_new (Entry);
-
- entry->filename = filename;
- entry->decoder = decoder;
- entry->tuple = NULL;
- entry->formatted = NULL;
- entry->title = NULL;
- entry->artist = NULL;
- entry->album = NULL;
- entry->failed = FALSE;
- entry->number = -1;
- entry->selected = FALSE;
- entry->shuffle_num = 0;
- entry->queued = FALSE;
-
- entry_set_tuple_real (entry, tuple);
- return entry;
-}
-
-static void entry_free (Entry * entry)
-{
- scan_cancel (entry);
-
- str_unref (entry->filename);
- if (entry->tuple)
- tuple_unref (entry->tuple);
-
- str_unref (entry->formatted);
- str_unref (entry->title);
- str_unref (entry->artist);
- str_unref (entry->album);
- g_slice_free (Entry, entry);
-}
-
-static int new_unique_id (int preferred)
-{
- if (preferred >= 0 && ! g_hash_table_lookup_extended (unique_id_table,
- GINT_TO_POINTER (preferred), NULL, NULL))
- return preferred;
-
- while (g_hash_table_lookup_extended (unique_id_table,
- GINT_TO_POINTER (next_unique_id), NULL, NULL))
- next_unique_id ++;
-
- return next_unique_id ++;
-}
-
-static Playlist * playlist_new (int id)
-{
- Playlist * playlist = g_slice_new (Playlist);
-
- playlist->number = -1;
- playlist->unique_id = new_unique_id (id);
- playlist->filename = NULL;
- playlist->title = str_get (_(default_title));
- playlist->modified = TRUE;
- playlist->entries = index_new();
- playlist->position = NULL;
- playlist->focus = NULL;
- playlist->selected_count = 0;
- playlist->last_shuffle_num = 0;
- playlist->queued = NULL;
- playlist->total_length = 0;
- playlist->selected_length = 0;
- playlist->scanning = FALSE;
- playlist->scan_ending = FALSE;
- playlist->resume_paused = FALSE;
- playlist->resume_time = 0;
-
- memset (& playlist->last_update, 0, sizeof (Update));
- memset (& playlist->next_update, 0, sizeof (Update));
-
- g_hash_table_insert (unique_id_table, GINT_TO_POINTER (playlist->unique_id), playlist);
- return playlist;
-}
-
-static void playlist_free (Playlist * playlist)
-{
- g_hash_table_insert (unique_id_table, GINT_TO_POINTER (playlist->unique_id), NULL);
-
- str_unref (playlist->filename);
- str_unref (playlist->title);
- index_free_full (playlist->entries, (IndexFreeFunc) entry_free);
- g_list_free (playlist->queued);
- g_slice_free (Playlist, playlist);
-}
-
-static void number_playlists (int at, int length)
-{
- for (int count = 0; count < length; count ++)
- {
- Playlist * playlist = index_get (playlists, at + count);
- playlist->number = at + count;
- }
-}
-
-static Playlist * lookup_playlist (int playlist_num)
-{
- return (playlists && playlist_num >= 0 && playlist_num < index_count
- (playlists)) ? index_get (playlists, playlist_num) : NULL;
-}
-
-static void number_entries (Playlist * playlist, int at, int length)
-{
- for (int count = 0; count < length; count ++)
- {
- Entry * entry = index_get (playlist->entries, at + count);
- entry->number = at + count;
- }
-}
-
-static Entry * lookup_entry (Playlist * playlist, int entry_num)
-{
- return (entry_num >= 0 && entry_num < index_count (playlist->entries)) ?
- index_get (playlist->entries, entry_num) : NULL;
-}
-
-static bool_t update (void * unused)
-{
- ENTER;
-
- for (int i = 0; i < index_count (playlists); i ++)
- {
- Playlist * p = index_get (playlists, i);
- memcpy (& p->last_update, & p->next_update, sizeof (Update));
- memset (& p->next_update, 0, sizeof (Update));
- }
-
- int level = update_level;
- update_level = 0;
-
- if (update_source)
- {
- g_source_remove (update_source);
- update_source = 0;
- }
-
- LEAVE;
-
- hook_call ("playlist update", GINT_TO_POINTER (level));
- return FALSE;
-}
-
-static void queue_update (int level, int list, int at, int count)
-{
- Playlist * p = lookup_playlist (list);
-
- if (p)
- {
- if (level >= PLAYLIST_UPDATE_METADATA)
- {
- p->modified = TRUE;
-
- if (! get_bool (NULL, "metadata_on_play"))
- {
- p->scanning = TRUE;
- p->scan_ending = FALSE;
- scan_restart ();
- }
- }
-
- if (p->next_update.level)
- {
- p->next_update.level = MAX (p->next_update.level, level);
- p->next_update.before = MIN (p->next_update.before, at);
- p->next_update.after = MIN (p->next_update.after,
- index_count (p->entries) - at - count);
- }
- else
- {
- p->next_update.level = level;
- p->next_update.before = at;
- p->next_update.after = index_count (p->entries) - at - count;
- }
- }
-
- update_level = MAX (update_level, level);
-
- if (! update_source)
- update_source = g_idle_add_full (G_PRIORITY_HIGH, update, NULL, NULL);
-}
-
-bool_t playlist_update_pending (void)
-{
- ENTER;
- bool_t pending = update_level ? TRUE : FALSE;
- RETURN (pending);
-}
-
-int playlist_updated_range (int playlist_num, int * at, int * count)
-{
- ENTER_GET_PLAYLIST (0);
-
- Update * u = & playlist->last_update;
-
- int level = u->level;
- * at = u->before;
- * count = index_count (playlist->entries) - u->before - u->after;
-
- RETURN (level);
-}
-
-bool_t playlist_scan_in_progress (int playlist_num)
-{
- if (playlist_num >= 0)
- {
- ENTER_GET_PLAYLIST (FALSE);
- bool_t scanning = playlist->scanning || playlist->scan_ending;
- RETURN (scanning);
- }
- else
- {
- ENTER;
-
- bool_t scanning = FALSE;
- for (playlist_num = 0; playlist_num < index_count (playlists); playlist_num ++)
- {
- Playlist * playlist = index_get (playlists, playlist_num);
- if (playlist->scanning || playlist->scan_ending)
- scanning = TRUE;
- }
-
- RETURN (scanning);
- }
-}
-
-static GList * scan_list_find_playlist (Playlist * playlist)
-{
- for (GList * node = scan_list; node; node = node->next)
- {
- ScanItem * item = node->data;
- if (item->playlist == playlist)
- return node;
- }
-
- return NULL;
-}
-
-static GList * scan_list_find_entry (Entry * entry)
-{
- for (GList * node = scan_list; node; node = node->next)
- {
- ScanItem * item = node->data;
- if (item->entry == entry)
- return node;
- }
-
- return NULL;
-}
-
-static GList * scan_list_find_request (ScanRequest * request)
-{
- for (GList * node = scan_list; node; node = node->next)
- {
- ScanItem * item = node->data;
- if (item->request == request)
- return node;
- }
-
- return NULL;
-}
-
-static void scan_queue_entry (Playlist * playlist, Entry * entry)
-{
- int flags = 0;
- if (! entry->tuple)
- flags |= SCAN_TUPLE;
-
- ScanItem * item = g_slice_new (ScanItem);
- item->playlist = playlist;
- item->entry = entry;
- item->request = scan_request (entry->filename, flags, entry->decoder, scan_finish);
- scan_list = g_list_prepend (scan_list, item);
-}
-
-static void scan_check_complete (Playlist * playlist)
-{
- if (! playlist->scan_ending || scan_list_find_playlist (playlist))
- return;
-
- playlist->scan_ending = FALSE;
- event_queue_cancel ("playlist scan complete", NULL);
- event_queue ("playlist scan complete", NULL);
-}
-
-static bool_t scan_queue_next_entry (void)
-{
- while (scan_playlist < index_count (playlists))
- {
- Playlist * playlist = index_get (playlists, scan_playlist);
-
- if (playlist->scanning)
- {
- while (scan_row < index_count (playlist->entries))
- {
- Entry * entry = index_get (playlist->entries, scan_row ++);
-
- if (! entry->tuple && ! scan_list_find_entry (entry))
- {
- scan_queue_entry (playlist, entry);
- return TRUE;
- }
- }
-
- playlist->scanning = FALSE;
- playlist->scan_ending = TRUE;
- scan_check_complete (playlist);
- }
-
- scan_playlist ++;
- scan_row = 0;
- }
-
- return FALSE;
-}
-
-static void scan_schedule (void)
-{
- while (g_list_length (scan_list) < SCAN_THREADS)
- {
- if (! scan_queue_next_entry ())
- break;
- }
-}
-
-static void scan_finish (ScanRequest * request)
-{
- ENTER;
-
- GList * node = scan_list_find_request (request);
- if (! node)
- RETURN ();
-
- ScanItem * item = node->data;
- Playlist * playlist = item->playlist;
- Entry * entry = item->entry;
- bool_t changed = FALSE;
-
- scan_list = g_list_delete_link (scan_list, node);
- g_slice_free (ScanItem, item);
-
- if (! entry->decoder)
- entry->decoder = scan_request_get_decoder (request);
-
- if (! entry->tuple)
- {
- Tuple * tuple = scan_request_get_tuple (request);
- if (tuple)
- {
- entry_set_tuple (playlist, entry, tuple);
- changed = TRUE;
- }
- }
-
- if (! entry->decoder || ! entry->tuple)
- entry_set_failed (playlist, entry);
-
- if (changed)
- queue_update (PLAYLIST_UPDATE_METADATA, playlist->number, entry->number, 1);
-
- scan_check_complete (playlist);
- scan_schedule ();
-
- pthread_cond_broadcast (& cond);
-
- LEAVE;
-}
-
-static void scan_cancel (Entry * entry)
-{
- GList * node = scan_list_find_entry (entry);
- if (! node)
- return;
-
- ScanItem * item = node->data;
- scan_list = g_list_delete_link (scan_list, node);
- g_slice_free (ScanItem, item);
-}
-
-static void scan_restart (void)
-{
- scan_playlist = 0;
- scan_row = 0;
- scan_schedule ();
-}
-
-/* mutex may be unlocked during the call */
-static Entry * get_entry (int playlist_num, int entry_num,
- bool_t need_decoder, bool_t need_tuple)
-{
- while (1)
- {
- Playlist * playlist = lookup_playlist (playlist_num);
- Entry * entry = playlist ? lookup_entry (playlist, entry_num) : NULL;
-
- if (! entry || entry->failed)
- return entry;
-
- if ((need_decoder && ! entry->decoder) || (need_tuple && ! entry->tuple))
- {
- if (! scan_list_find_entry (entry))
- scan_queue_entry (playlist, entry);
-
- pthread_cond_wait (& cond, & mutex);
- continue;
- }
-
- return entry;
- }
-}
-
-/* mutex may be unlocked during the call */
-static Entry * get_playback_entry (bool_t need_decoder, bool_t need_tuple)
-{
- while (1)
- {
- Entry * entry = playing_playlist ? playing_playlist->position : NULL;
-
- if (! entry || entry->failed)
- return entry;
-
- if ((need_decoder && ! entry->decoder) || (need_tuple && ! entry->tuple))
- {
- if (! scan_list_find_entry (entry))
- scan_queue_entry (playing_playlist, entry);
-
- pthread_cond_wait (& cond, & mutex);
- continue;
- }
-
- return entry;
- }
-}
-
-void playlist_init (void)
-{
- srand (time (NULL));
-
- ENTER;
-
- unique_id_table = g_hash_table_new (g_direct_hash, g_direct_equal);
- playlists = index_new ();
-
- update_level = 0;
- scan_playlist = scan_row = 0;
-
- LEAVE;
-
- /* initialize title formatter */
- playlist_reformat_titles ();
-}
-
-void playlist_end (void)
-{
- ENTER;
-
- if (update_source)
- {
- g_source_remove (update_source);
- update_source = 0;
- }
-
- active_playlist = playing_playlist = NULL;
- resume_playlist = -1;
-
- index_free_full (playlists, (IndexFreeFunc) playlist_free);
- playlists = NULL;
-
- g_hash_table_destroy (unique_id_table);
- unique_id_table = NULL;
-
- tuple_formatter_free (title_formatter);
- title_formatter = NULL;
-
- LEAVE;
-}
-
-int playlist_count (void)
-{
- ENTER;
- int count = index_count (playlists);
- RETURN (count);
-}
-
-void playlist_insert_with_id (int at, int id)
-{
- ENTER;
-
- if (at < 0 || at > index_count (playlists))
- at = index_count (playlists);
-
- index_insert (playlists, at, playlist_new (id));
- number_playlists (at, index_count (playlists) - at);
-
- queue_update (PLAYLIST_UPDATE_STRUCTURE, -1, 0, 0);
- LEAVE;
-}
-
-void playlist_insert (int at)
-{
- playlist_insert_with_id (at, -1);
-}
-
-void playlist_reorder (int from, int to, int count)
-{
- ENTER;
-
- if (from < 0 || from + count > index_count (playlists) || to < 0 || to +
- count > index_count (playlists) || count < 0)
- RETURN ();
-
- Index * displaced = index_new ();
-
- if (to < from)
- index_copy_insert (playlists, to, displaced, -1, from - to);
- else
- index_copy_insert (playlists, from + count, displaced, -1, to - from);
-
- index_copy_set (playlists, from, playlists, to, count);
-
- if (to < from)
- {
- index_copy_set (displaced, 0, playlists, to + count, from - to);
- number_playlists (to, from + count - to);
- }
- else
- {
- index_copy_set (displaced, 0, playlists, from, to - from);
- number_playlists (from, to + count - from);
- }
-
- index_free (displaced);
-
- queue_update (PLAYLIST_UPDATE_STRUCTURE, -1, 0, 0);
- LEAVE;
-}
-
-void playlist_delete (int playlist_num)
-{
- ENTER_GET_PLAYLIST ();
-
- bool_t was_playing = (playlist == playing_playlist);
-
- index_delete_full (playlists, playlist_num, 1, (IndexFreeFunc) playlist_free);
-
- if (! index_count (playlists))
- index_insert (playlists, 0, playlist_new (-1));
-
- number_playlists (playlist_num, index_count (playlists) - playlist_num);
-
- if (playlist == active_playlist)
- active_playlist = index_get (playlists, MIN (playlist_num, index_count (playlists) - 1));
- if (playlist == playing_playlist)
- playing_playlist = NULL;
-
- queue_update (PLAYLIST_UPDATE_STRUCTURE, -1, 0, 0);
- LEAVE;
-
- if (was_playing)
- playback_stop ();
-}
-
-int playlist_get_unique_id (int playlist_num)
-{
- ENTER_GET_PLAYLIST (-1);
- int unique_id = playlist->unique_id;
- RETURN (unique_id);
-}
-
-int playlist_by_unique_id (int id)
-{
- ENTER;
-
- Playlist * p = g_hash_table_lookup (unique_id_table, GINT_TO_POINTER (id));
- int num = p ? p->number : -1;
-
- RETURN (num);
-}
-
-void playlist_set_filename (int playlist_num, const char * filename)
-{
- ENTER_GET_PLAYLIST ();
-
- str_unref (playlist->filename);
- playlist->filename = str_get (filename);
- playlist->modified = TRUE;
-
- queue_update (PLAYLIST_UPDATE_METADATA, -1, 0, 0);
- LEAVE;
-}
-
-char * playlist_get_filename (int playlist_num)
-{
- ENTER_GET_PLAYLIST (NULL);
- char * filename = str_ref (playlist->filename);
- RETURN (filename);
-}
-
-void playlist_set_title (int playlist_num, const char * title)
-{
- ENTER_GET_PLAYLIST ();
-
- str_unref (playlist->title);
- playlist->title = str_get (title);
- playlist->modified = TRUE;
-
- queue_update (PLAYLIST_UPDATE_METADATA, -1, 0, 0);
- LEAVE;
-}
-
-char * playlist_get_title (int playlist_num)
-{
- ENTER_GET_PLAYLIST (NULL);
- char * title = str_ref (playlist->title);
- RETURN (title);
-}
-
-void playlist_set_modified (int playlist_num, bool_t modified)
-{
- ENTER_GET_PLAYLIST ();
- playlist->modified = modified;
- LEAVE;
-}
-
-bool_t playlist_get_modified (int playlist_num)
-{
- ENTER_GET_PLAYLIST (FALSE);
- bool_t modified = playlist->modified;
- RETURN (modified);
-}
-
-void playlist_set_active (int playlist_num)
-{
- ENTER_GET_PLAYLIST ();
-
- bool_t changed = FALSE;
-
- if (playlist != active_playlist)
- {
- changed = TRUE;
- active_playlist = playlist;
- }
-
- LEAVE;
-
- if (changed)
- hook_call ("playlist activate", NULL);
-}
-
-int playlist_get_active (void)
-{
- ENTER;
- int list = active_playlist ? active_playlist->number : -1;
- RETURN (list);
-}
-
-void playlist_set_playing (int playlist_num)
-{
- /* get playback state before locking playlists */
- bool_t paused = drct_get_paused ();
- int time = drct_get_time ();
-
- ENTER;
-
- Playlist * playlist = lookup_playlist (playlist_num);
- bool_t can_play = FALSE;
- bool_t position_changed = FALSE;
-
- if (playlist == playing_playlist)
- RETURN ();
-
- if (playing_playlist)
- {
- playing_playlist->resume_paused = paused;
- playing_playlist->resume_time = time;
- }
-
- /* is there anything to play? */
- if (playlist && ! playlist->position)
- {
- if (next_song_locked (playlist, TRUE, 0))
- position_changed = TRUE;
- else
- playlist = NULL;
- }
-
- if (playlist)
- {
- can_play = TRUE;
- paused = playlist->resume_paused;
- time = playlist->resume_time;
- }
-
- playing_playlist = playlist;
-
- LEAVE;
-
- if (position_changed)
- hook_call ("playlist position", GINT_TO_POINTER (playlist_num));
-
- hook_call ("playlist set playing", NULL);
-
- /* start playback after unlocking playlists */
- if (can_play)
- playback_play (time, paused);
- else
- playback_stop ();
-}
-
-int playlist_get_playing (void)
-{
- ENTER;
- int list = playing_playlist ? playing_playlist->number: -1;
- RETURN (list);
-}
-
-int playlist_get_blank (void)
-{
- int list = playlist_get_active ();
- char * title = playlist_get_title (list);
-
- if (strcmp (title, _(default_title)) || playlist_entry_count (list) > 0)
- {
- list = playlist_count ();
- playlist_insert (list);
- }
-
- str_unref (title);
- return list;
-}
-
-int playlist_get_temporary (void)
-{
- int list, count = playlist_count ();
- bool_t found = FALSE;
-
- for (list = 0; list < count; list ++)
- {
- char * title = playlist_get_title (list);
- found = ! strcmp (title, _(temp_title));
- str_unref (title);
-
- if (found)
- break;
- }
-
- if (! found)
- {
- list = playlist_get_blank ();
- playlist_set_title (list, _(temp_title));
- }
-
- return list;
-}
-
-static void set_position (Playlist * playlist, Entry * entry, bool_t update_shuffle)
-{
- playlist->position = entry;
- playlist->resume_time = 0;
-
- /* move entry to top of shuffle list */
- if (entry && update_shuffle)
- entry->shuffle_num = ++ playlist->last_shuffle_num;
-}
-
-/* unlocked */
-static void change_playback (bool_t can_play)
-{
- if (can_play && drct_get_playing ())
- playback_play (0, drct_get_paused ());
- else
- playlist_set_playing (-1);
-}
-
-int playlist_entry_count (int playlist_num)
-{
- ENTER_GET_PLAYLIST (0);
- int count = index_count (playlist->entries);
- RETURN (count);
-}
-
-void playlist_entry_insert_batch_raw (int playlist_num, int at,
- Index * filenames, Index * tuples, Index * decoders)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
-
- if (at < 0 || at > entries)
- at = entries;
-
- int number = index_count (filenames);
-
- Index * add = index_new ();
- index_allocate (add, number);
-
- for (int i = 0; i < number; i ++)
- {
- char * filename = index_get (filenames, i);
- Tuple * tuple = tuples ? index_get (tuples, i) : NULL;
- PluginHandle * decoder = decoders ? index_get (decoders, i) : NULL;
- index_insert (add, -1, entry_new (filename, tuple, decoder));
- }
-
- index_free (filenames);
- if (decoders)
- index_free (decoders);
- if (tuples)
- index_free (tuples);
-
- number = index_count (add);
- index_copy_insert (add, 0, playlist->entries, at, -1);
- index_free (add);
-
- number_entries (playlist, at, entries + number - at);
-
- for (int count = 0; count < number; count ++)
- {
- Entry * entry = index_get (playlist->entries, at + count);
- playlist->total_length += entry->length;
- }
-
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, at, number);
- LEAVE;
-}
-
-void playlist_entry_delete (int playlist_num, int at, int number)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
- bool_t position_changed = FALSE;
- bool_t was_playing = FALSE;
- bool_t can_play = FALSE;
-
- if (at < 0 || at > entries)
- at = entries;
- if (number < 0 || number > entries - at)
- number = entries - at;
-
- if (playlist->position && playlist->position->number >= at &&
- playlist->position->number < at + number)
- {
- position_changed = TRUE;
- was_playing = (playlist == playing_playlist);
-
- set_position (playlist, NULL, FALSE);
- }
-
- if (playlist->focus && playlist->focus->number >= at &&
- playlist->focus->number < at + number)
- {
- if (at + number < entries)
- playlist->focus = index_get (playlist->entries, at + number);
- else if (at > 0)
- playlist->focus = index_get (playlist->entries, at - 1);
- else
- playlist->focus = NULL;
- }
-
- for (int count = 0; count < number; count ++)
- {
- Entry * entry = index_get (playlist->entries, at + count);
-
- if (entry->queued)
- playlist->queued = g_list_remove (playlist->queued, entry);
-
- if (entry->selected)
- {
- playlist->selected_count --;
- playlist->selected_length -= entry->length;
- }
-
- playlist->total_length -= entry->length;
- }
-
- index_delete_full (playlist->entries, at, number, (IndexFreeFunc) entry_free);
- number_entries (playlist, at, entries - at - number);
-
- if (position_changed && get_bool (NULL, "advance_on_delete"))
- can_play = next_song_locked (playlist, get_bool (NULL, "repeat"), at);
-
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, at, 0);
- LEAVE;
-
- if (position_changed)
- hook_call ("playlist position", GINT_TO_POINTER (playlist_num));
- if (was_playing)
- change_playback (can_play);
-}
-
-char * playlist_entry_get_filename (int playlist_num, int entry_num)
-{
- ENTER_GET_ENTRY (NULL);
- char * filename = str_ref (entry->filename);
- RETURN (filename);
-}
-
-PluginHandle * playlist_entry_get_decoder (int playlist_num, int entry_num, bool_t fast)
-{
- ENTER;
-
- Entry * entry = get_entry (playlist_num, entry_num, ! fast, FALSE);
- PluginHandle * decoder = entry ? entry->decoder : NULL;
-
- RETURN (decoder);
-}
-
-Tuple * playlist_entry_get_tuple (int playlist_num, int entry_num, bool_t fast)
-{
- ENTER;
-
- Entry * entry = get_entry (playlist_num, entry_num, FALSE, ! fast);
- Tuple * tuple = entry ? entry->tuple : NULL;
-
- if (tuple)
- tuple_ref (tuple);
-
- RETURN (tuple);
-}
-
-char * playlist_entry_get_title (int playlist_num, int entry_num, bool_t fast)
-{
- ENTER;
-
- Entry * entry = get_entry (playlist_num, entry_num, FALSE, ! fast);
- char * title = entry ? str_ref (entry->formatted ? entry->formatted : entry->title) : NULL;
-
- RETURN (title);
-}
-
-void playlist_entry_describe (int playlist_num, int entry_num,
- char * * title, char * * artist, char * * album, bool_t fast)
-{
- ENTER;
-
- Entry * entry = get_entry (playlist_num, entry_num, FALSE, ! fast);
-
- if (title)
- * title = (entry && entry->title) ? str_ref (entry->title) : NULL;
- if (artist)
- * artist = (entry && entry->artist) ? str_ref (entry->artist) : NULL;
- if (album)
- * album = (entry && entry->album) ? str_ref (entry->album) : NULL;
-
- LEAVE;
-}
-
-int playlist_entry_get_length (int playlist_num, int entry_num, bool_t fast)
-{
- ENTER;
-
- Entry * entry = get_entry (playlist_num, entry_num, FALSE, ! fast);
- int length = entry ? entry->length : 0;
-
- RETURN (length);
-}
-
-void playlist_set_position (int playlist_num, int entry_num)
-{
- ENTER_GET_PLAYLIST ();
-
- Entry * entry = lookup_entry (playlist, entry_num);
- bool_t was_playing = (playlist == playing_playlist);
- bool_t can_play = !! entry;
-
- set_position (playlist, entry, TRUE);
-
- LEAVE;
-
- hook_call ("playlist position", GINT_TO_POINTER (playlist_num));
- if (was_playing)
- change_playback (can_play);
-}
-
-int playlist_get_position (int playlist_num)
-{
- ENTER_GET_PLAYLIST (-1);
- int position = playlist->position ? playlist->position->number : -1;
- RETURN (position);
-}
-
-void playlist_set_focus (int playlist_num, int entry_num)
-{
- ENTER_GET_PLAYLIST ();
-
- int first = INT_MAX;
- int last = -1;
-
- if (playlist->focus)
- {
- first = MIN (first, playlist->focus->number);
- last = MAX (last, playlist->focus->number);
- }
-
- playlist->focus = lookup_entry (playlist, entry_num);
-
- if (playlist->focus)
- {
- first = MIN (first, playlist->focus->number);
- last = MAX (last, playlist->focus->number);
- }
-
- if (first <= last)
- queue_update (PLAYLIST_UPDATE_SELECTION, playlist_num, first, last + 1 - first);
-
- LEAVE;
-}
-
-int playlist_get_focus (int playlist_num)
-{
- ENTER_GET_PLAYLIST (-1);
- int focus = playlist->focus ? playlist->focus->number : -1;
- RETURN (focus);
-}
-
-void playlist_entry_set_selected (int playlist_num, int entry_num,
- bool_t selected)
-{
- ENTER_GET_ENTRY ();
-
- if (entry->selected == selected)
- RETURN ();
-
- entry->selected = selected;
-
- if (selected)
- {
- playlist->selected_count++;
- playlist->selected_length += entry->length;
- }
- else
- {
- playlist->selected_count--;
- playlist->selected_length -= entry->length;
- }
-
- queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, entry_num, 1);
- LEAVE;
-}
-
-bool_t playlist_entry_get_selected (int playlist_num, int entry_num)
-{
- ENTER_GET_ENTRY (FALSE);
- bool_t selected = entry->selected;
- RETURN (selected);
-}
-
-int playlist_selected_count (int playlist_num)
-{
- ENTER_GET_PLAYLIST (0);
- int selected_count = playlist->selected_count;
- RETURN (selected_count);
-}
-
-void playlist_select_all (int playlist_num, bool_t selected)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
- int first = entries, last = 0;
-
- for (int count = 0; count < entries; count ++)
- {
- Entry * entry = index_get (playlist->entries, count);
-
- if ((selected && ! entry->selected) || (entry->selected && ! selected))
- {
- entry->selected = selected;
- first = MIN (first, entry->number);
- last = entry->number;
- }
- }
-
- if (selected)
- {
- playlist->selected_count = entries;
- playlist->selected_length = playlist->total_length;
- }
- else
- {
- playlist->selected_count = 0;
- playlist->selected_length = 0;
- }
-
- if (first < entries)
- queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, first, last + 1 - first);
-
- LEAVE;
-}
-
-int playlist_shift (int playlist_num, int entry_num, int distance)
-{
- ENTER_GET_ENTRY (0);
-
- if (! entry->selected || ! distance)
- RETURN (0);
-
- int entries = index_count (playlist->entries);
- int shift = 0, center, top, bottom;
-
- if (distance < 0)
- {
- for (center = entry_num; center > 0 && shift > distance; )
- {
- entry = index_get (playlist->entries, -- center);
- if (! entry->selected)
- shift --;
- }
- }
- else
- {
- for (center = entry_num + 1; center < entries && shift < distance; )
- {
- entry = index_get (playlist->entries, center ++);
- if (! entry->selected)
- shift ++;
- }
- }
-
- top = bottom = center;
-
- for (int i = 0; i < top; i ++)
- {
- entry = index_get (playlist->entries, i);
- if (entry->selected)
- top = i;
- }
-
- for (int i = entries; i > bottom; i --)
- {
- entry = index_get (playlist->entries, i - 1);
- if (entry->selected)
- bottom = i;
- }
-
- Index * temp = index_new ();
-
- for (int i = top; i < center; i ++)
- {
- entry = index_get (playlist->entries, i);
- if (! entry->selected)
- index_insert (temp, -1, entry);
- }
-
- for (int i = top; i < bottom; i ++)
- {
- entry = index_get (playlist->entries, i);
- if (entry->selected)
- index_insert (temp, -1, entry);
- }
-
- for (int i = center; i < bottom; i ++)
- {
- entry = index_get (playlist->entries, i);
- if (! entry->selected)
- index_insert (temp, -1, entry);
- }
-
- index_copy_set (temp, 0, playlist->entries, top, bottom - top);
-
- number_entries (playlist, top, bottom - top);
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, top, bottom - top);
-
- RETURN (shift);
-}
-
-static Entry * find_unselected_focus (Playlist * playlist)
-{
- if (! playlist->focus || ! playlist->focus->selected)
- return playlist->focus;
-
- int entries = index_count (playlist->entries);
-
- for (int search = playlist->focus->number + 1; search < entries; search ++)
- {
- Entry * entry = index_get (playlist->entries, search);
- if (! entry->selected)
- return entry;
- }
-
- for (int search = playlist->focus->number; search --;)
- {
- Entry * entry = index_get (playlist->entries, search);
- if (! entry->selected)
- return entry;
- }
-
- return NULL;
-}
-
-void playlist_delete_selected (int playlist_num)
-{
- ENTER_GET_PLAYLIST ();
-
- if (! playlist->selected_count)
- RETURN ();
-
- int entries = index_count (playlist->entries);
- bool_t position_changed = FALSE;
- bool_t was_playing = FALSE;
- bool_t can_play = FALSE;
-
- Index * others = index_new ();
- index_allocate (others, entries - playlist->selected_count);
-
- if (playlist->position && playlist->position->selected)
- {
- position_changed = TRUE;
- was_playing = (playlist == playing_playlist);
-
- set_position (playlist, NULL, FALSE);
- }
-
- playlist->focus = find_unselected_focus (playlist);
-
- int before = 0, after = 0;
- bool_t found = FALSE;
-
- for (int count = 0; count < entries; count++)
- {
- Entry * entry = index_get (playlist->entries, count);
-
- if (entry->selected)
- {
- if (entry->queued)
- playlist->queued = g_list_remove (playlist->queued, entry);
-
- playlist->total_length -= entry->length;
- entry_free (entry);
-
- found = TRUE;
- after = 0;
- }
- else
- {
- index_insert (others, -1, entry);
-
- if (found)
- after ++;
- else
- before ++;
- }
- }
-
- index_free (playlist->entries);
- playlist->entries = others;
-
- playlist->selected_count = 0;
- playlist->selected_length = 0;
-
- entries = index_count (playlist->entries);
- number_entries (playlist, before, entries - before);
-
- if (position_changed && get_bool (NULL, "advance_on_delete"))
- can_play = next_song_locked (playlist, get_bool (NULL, "repeat"), entries - after);
-
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, before, entries - after - before);
- LEAVE;
-
- if (position_changed)
- hook_call ("playlist position", GINT_TO_POINTER (playlist_num));
- if (was_playing)
- change_playback (can_play);
-}
-
-void playlist_reverse (int playlist_num)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
-
- Index * reversed = index_new ();
- index_allocate (reversed, entries);
-
- for (int count = entries; count --; )
- index_insert (reversed, -1, index_get (playlist->entries, count));
-
- index_free (playlist->entries);
- playlist->entries = reversed;
-
- number_entries (playlist, 0, entries);
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, entries);
- LEAVE;
-}
-
-void playlist_reverse_selected (int playlist_num)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
-
- Index * reversed = index_new ();
- index_allocate (reversed, playlist->selected_count);
-
- for (int count = entries; count --; )
- {
- Entry * entry = index_get (playlist->entries, count);
- if (entry->selected)
- index_insert (reversed, -1, index_get (playlist->entries, count));
- }
-
- int count2 = 0;
- for (int count = 0; count < entries; count++)
- {
- Entry * entry = index_get (playlist->entries, count);
- if (entry->selected)
- index_set (playlist->entries, count, index_get (reversed, count2 ++));
- }
-
- index_free (reversed);
-
- number_entries (playlist, 0, entries);
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, entries);
- LEAVE;
-}
-
-void playlist_randomize (int playlist_num)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
-
- for (int i = 0; i < entries; i ++)
- {
- int j = i + rand () % (entries - i);
-
- Entry * entry = index_get (playlist->entries, j);
- index_set (playlist->entries, j, index_get (playlist->entries, i));
- index_set (playlist->entries, i, entry);
- }
-
- number_entries (playlist, 0, entries);
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, entries);
- LEAVE;
-}
-
-void playlist_randomize_selected (int playlist_num)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
-
- Index * selected = index_new ();
- index_allocate (selected, playlist->selected_count);
-
- for (int count = 0; count < entries; count++)
- {
- Entry * entry = index_get (playlist->entries, count);
- if (entry->selected)
- index_insert (selected, -1, entry);
- }
-
- for (int i = 0; i < playlist->selected_count; i ++)
- {
- int j = i + rand () % (playlist->selected_count - i);
-
- Entry * entry = index_get (selected, j);
- index_set (selected, j, index_get (selected, i));
- index_set (selected, i, entry);
- }
-
- int count2 = 0;
- for (int count = 0; count < entries; count++)
- {
- Entry * entry = index_get (playlist->entries, count);
- if (entry->selected)
- index_set (playlist->entries, count, index_get (selected, count2 ++));
- }
-
- index_free (selected);
-
- number_entries (playlist, 0, entries);
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, entries);
- LEAVE;
-}
-
-enum {COMPARE_TYPE_FILENAME, COMPARE_TYPE_TUPLE, COMPARE_TYPE_TITLE};
-
-typedef int (* CompareFunc) (const void * a, const void * b);
-
-typedef struct {
- int type;
- CompareFunc func;
-} CompareData;
-
-static int compare_cb (const void * _a, const void * _b, void * _data)
-{
- const Entry * a = _a, * b = _b;
- CompareData * data = _data;
-
- int diff = 0;
-
- if (data->type == COMPARE_TYPE_FILENAME)
- diff = data->func (a->filename, b->filename);
- else if (data->type == COMPARE_TYPE_TUPLE)
- diff = data->func (a->tuple, b->tuple);
- else if (data->type == COMPARE_TYPE_TITLE)
- diff = data->func (a->formatted ? a->formatted : a->filename,
- b->formatted ? b->formatted : b->filename);
-
- if (diff)
- return diff;
-
- /* preserve order of "equal" entries */
- return a->number - b->number;
-}
-
-static void sort (Playlist * playlist, CompareData * data)
-{
- index_sort_with_data (playlist->entries, compare_cb, data);
- number_entries (playlist, 0, index_count (playlist->entries));
-
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, index_count (playlist->entries));
-}
-
-static void sort_selected (Playlist * playlist, CompareData * data)
-{
- int entries = index_count (playlist->entries);
-
- Index * selected = index_new ();
- index_allocate (selected, playlist->selected_count);
-
- for (int count = 0; count < entries; count++)
- {
- Entry * entry = index_get (playlist->entries, count);
- if (entry->selected)
- index_insert (selected, -1, entry);
- }
-
- index_sort_with_data (selected, compare_cb, data);
-
- int count2 = 0;
- for (int count = 0; count < entries; count++)
- {
- Entry * entry = index_get (playlist->entries, count);
- if (entry->selected)
- index_set (playlist->entries, count, index_get (selected, count2 ++));
- }
-
- index_free (selected);
-
- number_entries (playlist, 0, entries);
- queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, entries);
-}
-
-static bool_t entries_are_scanned (Playlist * playlist, bool_t selected)
-{
- int entries = index_count (playlist->entries);
- for (int count = 0; count < entries; count ++)
- {
- Entry * entry = index_get (playlist->entries, count);
- if (selected && ! entry->selected)
- continue;
-
- if (! entry->tuple)
- {
- interface_show_error (_("The playlist cannot be sorted because "
- "metadata scanning is still in progress (or has been disabled)."));
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-void playlist_sort_by_filename (int playlist_num, int (* compare)
- (const char * a, const char * b))
-{
- ENTER_GET_PLAYLIST ();
-
- CompareData data = {COMPARE_TYPE_FILENAME, (CompareFunc) compare};
- sort (playlist, & data);
-
- LEAVE;
-}
-
-void playlist_sort_by_tuple (int playlist_num, int (* compare)
- (const Tuple * a, const Tuple * b))
-{
- ENTER_GET_PLAYLIST ();
-
- CompareData data = {COMPARE_TYPE_TUPLE, (CompareFunc) compare};
- if (entries_are_scanned (playlist, FALSE))
- sort (playlist, & data);
-
- LEAVE;
-}
-
-void playlist_sort_by_title (int playlist_num, int (* compare) (const char *
- a, const char * b))
-{
- ENTER_GET_PLAYLIST ();
-
- CompareData data = {COMPARE_TYPE_TITLE, (CompareFunc) compare};
- if (entries_are_scanned (playlist, FALSE))
- sort (playlist, & data);
-
- LEAVE;
-}
-
-void playlist_sort_selected_by_filename (int playlist_num, int (* compare)
- (const char * a, const char * b))
-{
- ENTER_GET_PLAYLIST ();
-
- CompareData data = {COMPARE_TYPE_FILENAME, (CompareFunc) compare};
- sort_selected (playlist, & data);
-
- LEAVE;
-}
-
-void playlist_sort_selected_by_tuple (int playlist_num, int (* compare)
- (const Tuple * a, const Tuple * b))
-{
- ENTER_GET_PLAYLIST ();
-
- CompareData data = {COMPARE_TYPE_TUPLE, (CompareFunc) compare};
- if (entries_are_scanned (playlist, TRUE))
- sort_selected (playlist, & data);
-
- LEAVE;
-}
-
-void playlist_sort_selected_by_title (int playlist_num, int (* compare)
- (const char * a, const char * b))
-{
- ENTER_GET_PLAYLIST ();
-
- CompareData data = {COMPARE_TYPE_TITLE, (CompareFunc) compare};
- if (entries_are_scanned (playlist, TRUE))
- sort_selected (playlist, & data);
-
- LEAVE;
-}
-
-void playlist_reformat_titles (void)
-{
- ENTER;
-
- if (title_formatter)
- tuple_formatter_free (title_formatter);
-
- char * format = get_str (NULL, "generic_title_format");
- title_formatter = tuple_formatter_new (format);
- str_unref (format);
-
- for (int playlist_num = 0; playlist_num < index_count (playlists); playlist_num ++)
- {
- Playlist * playlist = index_get (playlists, playlist_num);
- int entries = index_count (playlist->entries);
-
- for (int count = 0; count < entries; count++)
- {
- Entry * entry = index_get (playlist->entries, count);
- str_unref (entry->formatted);
-
- if (entry->tuple)
- entry->formatted = tuple_format_title (title_formatter, entry->tuple);
- else
- entry->formatted = NULL;
- }
-
- queue_update (PLAYLIST_UPDATE_METADATA, playlist_num, 0, entries);
- }
-
- LEAVE;
-}
-
-void playlist_trigger_scan (void)
-{
- ENTER;
-
- for (int i = 0; i < index_count (playlists); i ++)
- {
- Playlist * p = index_get (playlists, i);
- p->scanning = TRUE;
- }
-
- scan_restart ();
-
- LEAVE;
-}
-
-static void playlist_rescan_real (int playlist_num, bool_t selected)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
-
- for (int count = 0; count < entries; count ++)
- {
- Entry * entry = index_get (playlist->entries, count);
- if (! selected || entry->selected)
- entry_set_tuple (playlist, entry, NULL);
- }
-
- queue_update (PLAYLIST_UPDATE_METADATA, playlist->number, 0, entries);
- LEAVE;
-}
-
-void playlist_rescan (int playlist_num)
-{
- playlist_rescan_real (playlist_num, FALSE);
-}
-
-void playlist_rescan_selected (int playlist_num)
-{
- playlist_rescan_real (playlist_num, TRUE);
-}
-
-void playlist_rescan_file (const char * filename)
-{
- ENTER;
-
- int num_playlists = index_count (playlists);
-
- for (int playlist_num = 0; playlist_num < num_playlists; playlist_num ++)
- {
- Playlist * playlist = index_get (playlists, playlist_num);
- int num_entries = index_count (playlist->entries);
-
- for (int entry_num = 0; entry_num < num_entries; entry_num ++)
- {
- Entry * entry = index_get (playlist->entries, entry_num);
-
- if (! strcmp (entry->filename, filename))
- {
- entry_set_tuple (playlist, entry, NULL);
- queue_update (PLAYLIST_UPDATE_METADATA, playlist_num, entry_num, 1);
- }
- }
- }
-
- LEAVE;
-}
-
-int64_t playlist_get_total_length (int playlist_num)
-{
- ENTER_GET_PLAYLIST (0);
- int64_t length = playlist->total_length;
- RETURN (length);
-}
-
-int64_t playlist_get_selected_length (int playlist_num)
-{
- ENTER_GET_PLAYLIST (0);
- int64_t length = playlist->selected_length;
- RETURN (length);
-}
-
-int playlist_queue_count (int playlist_num)
-{
- ENTER_GET_PLAYLIST (0);
- int count = g_list_length (playlist->queued);
- RETURN (count);
-}
-
-void playlist_queue_insert (int playlist_num, int at, int entry_num)
-{
- ENTER_GET_ENTRY ();
-
- if (entry->queued)
- RETURN ();
-
- if (at < 0)
- playlist->queued = g_list_append (playlist->queued, entry);
- else
- playlist->queued = g_list_insert (playlist->queued, entry, at);
-
- entry->queued = TRUE;
-
- queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, entry_num, 1);
- LEAVE;
-}
-
-void playlist_queue_insert_selected (int playlist_num, int at)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count(playlist->entries);
- int first = entries, last = 0;
-
- for (int count = 0; count < entries; count++)
- {
- Entry * entry = index_get (playlist->entries, count);
-
- if (! entry->selected || entry->queued)
- continue;
-
- if (at < 0)
- playlist->queued = g_list_append (playlist->queued, entry);
- else
- playlist->queued = g_list_insert (playlist->queued, entry, at++);
-
- entry->queued = TRUE;
- first = MIN (first, entry->number);
- last = entry->number;
- }
-
- if (first < entries)
- queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, first, last + 1 - first);
-
- LEAVE;
-}
-
-int playlist_queue_get_entry (int playlist_num, int at)
-{
- ENTER_GET_PLAYLIST (-1);
-
- GList * node = g_list_nth (playlist->queued, at);
- int entry_num = node ? ((Entry *) node->data)->number : -1;
-
- RETURN (entry_num);
-}
-
-int playlist_queue_find_entry (int playlist_num, int entry_num)
-{
- ENTER_GET_ENTRY (-1);
- int pos = entry->queued ? g_list_index (playlist->queued, entry) : -1;
- RETURN (pos);
-}
-
-void playlist_queue_delete (int playlist_num, int at, int number)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
- int first = entries, last = 0;
-
- if (at == 0)
- {
- while (playlist->queued && number --)
- {
- Entry * entry = playlist->queued->data;
- entry->queued = FALSE;
- first = MIN (first, entry->number);
- last = entry->number;
-
- playlist->queued = g_list_delete_link (playlist->queued, playlist->queued);
- }
- }
- else
- {
- GList * anchor = g_list_nth (playlist->queued, at - 1);
- if (! anchor)
- goto DONE;
-
- while (anchor->next && number --)
- {
- Entry * entry = anchor->next->data;
- entry->queued = FALSE;
- first = MIN (first, entry->number);
- last = entry->number;
-
- playlist->queued = g_list_delete_link (playlist->queued, anchor->next);
- }
- }
-
-DONE:
- if (first < entries)
- queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, first, last + 1 - first);
-
- LEAVE;
-}
-
-void playlist_queue_delete_selected (int playlist_num)
-{
- ENTER_GET_PLAYLIST ();
-
- int entries = index_count (playlist->entries);
- int first = entries, last = 0;
-
- for (GList * node = playlist->queued; node; )
- {
- GList * next = node->next;
- Entry * entry = node->data;
-
- if (entry->selected)
- {
- entry->queued = FALSE;
- playlist->queued = g_list_delete_link (playlist->queued, node);
- first = MIN (first, entry->number);
- last = entry->number;
- }
-
- node = next;
- }
-
- if (first < entries)
- queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, first, last + 1 - first);
-
- LEAVE;
-}
-
-static bool_t shuffle_prev (Playlist * playlist)
-{
- int entries = index_count (playlist->entries);
- Entry * found = NULL;
-
- for (int count = 0; count < entries; count ++)
- {
- Entry * entry = index_get (playlist->entries, count);
-
- if (entry->shuffle_num && (! playlist->position ||
- entry->shuffle_num < playlist->position->shuffle_num) && (! found
- || entry->shuffle_num > found->shuffle_num))
- found = entry;
- }
-
- if (! found)
- return FALSE;
-
- set_position (playlist, found, FALSE);
- return TRUE;
-}
-
-bool_t playlist_prev_song (int playlist_num)
-{
- ENTER_GET_PLAYLIST (FALSE);
-
- bool_t was_playing = (playlist == playing_playlist);
-
- if (get_bool (NULL, "shuffle"))
- {
- if (! shuffle_prev (playlist))
- RETURN (FALSE);
- }
- else
- {
- if (! playlist->position || playlist->position->number == 0)
- RETURN (FALSE);
-
- set_position (playlist, index_get (playlist->entries,
- playlist->position->number - 1), TRUE);
- }
-
- LEAVE;
-
- hook_call ("playlist position", GINT_TO_POINTER (playlist_num));
- if (was_playing)
- change_playback (TRUE);
-
- return TRUE;
-}
-
-static bool_t shuffle_next (Playlist * playlist)
-{
- int entries = index_count (playlist->entries), choice = 0, count;
- Entry * found = NULL;
-
- for (count = 0; count < entries; count ++)
- {
- Entry * entry = index_get (playlist->entries, count);
-
- if (! entry->shuffle_num)
- choice ++;
- else if (playlist->position && entry->shuffle_num >
- playlist->position->shuffle_num && (! found || entry->shuffle_num
- < found->shuffle_num))
- found = entry;
- }
-
- if (found)
- {
- set_position (playlist, found, FALSE);
- return TRUE;
- }
-
- if (! choice)
- return FALSE;
-
- choice = rand () % choice;
-
- for (count = 0; ; count ++)
- {
- Entry * entry = index_get (playlist->entries, count);
-
- if (! entry->shuffle_num)
- {
- if (! choice)
- {
- set_position (playlist, entry, TRUE);
- return TRUE;
- }
-
- choice --;
- }
- }
-}
-
-static void shuffle_reset (Playlist * playlist)
-{
- int entries = index_count (playlist->entries);
-
- playlist->last_shuffle_num = 0;
-
- for (int count = 0; count < entries; count ++)
- {
- Entry * entry = index_get (playlist->entries, count);
- entry->shuffle_num = 0;
- }
-}
-
-static bool_t next_song_locked (Playlist * playlist, bool_t repeat, int hint)
-{
- int entries = index_count (playlist->entries);
- if (! entries)
- return FALSE;
-
- if (playlist->queued)
- {
- set_position (playlist, playlist->queued->data, TRUE);
- playlist->queued = g_list_remove (playlist->queued, playlist->position);
- playlist->position->queued = FALSE;
- }
- else if (get_bool (NULL, "shuffle"))
- {
- if (! shuffle_next (playlist))
- {
- if (! repeat)
- return FALSE;
-
- shuffle_reset (playlist);
-
- if (! shuffle_next (playlist))
- return FALSE;
- }
- }
- else
- {
- if (hint >= entries)
- {
- if (! repeat)
- return FALSE;
-
- hint = 0;
- }
-
- set_position (playlist, index_get (playlist->entries, hint), TRUE);
- }
-
- return TRUE;
-}
-
-bool_t playlist_next_song (int playlist_num, bool_t repeat)
-{
- ENTER_GET_PLAYLIST (FALSE);
-
- int hint = playlist->position ? playlist->position->number + 1 : 0;
- bool_t was_playing = (playlist == playing_playlist);
-
- if (! next_song_locked (playlist, repeat, hint))
- RETURN (FALSE);
-
- LEAVE;
-
- hook_call ("playlist position", GINT_TO_POINTER (playlist_num));
- if (was_playing)
- change_playback (TRUE);
-
- return TRUE;
-}
-
-int playback_entry_get_position (void)
-{
- ENTER;
-
- Entry * entry = get_playback_entry (FALSE, FALSE);
- int entry_num = entry ? entry->number : -1;
-
- RETURN (entry_num);
-}
-
-char * playback_entry_get_filename (void)
-{
- ENTER;
-
- Entry * entry = get_playback_entry (FALSE, FALSE);
- char * filename = entry ? str_ref (entry->filename) : NULL;
-
- RETURN (filename);
-}
-
-PluginHandle * playback_entry_get_decoder (void)
-{
- ENTER;
-
- Entry * entry = get_playback_entry (TRUE, FALSE);
- PluginHandle * decoder = entry ? entry->decoder : NULL;
-
- RETURN (decoder);
-}
-
-Tuple * playback_entry_get_tuple (void)
-{
- ENTER;
-
- Entry * entry = get_playback_entry (FALSE, TRUE);
- Tuple * tuple = entry ? entry->tuple : NULL;
-
- if (tuple)
- tuple_ref (tuple);
-
- RETURN (tuple);
-}
-
-char * playback_entry_get_title (void)
-{
- ENTER;
-
- Entry * entry = get_playback_entry (FALSE, TRUE);
- char * title = entry ? str_ref (entry->formatted ? entry->formatted : entry->title) : NULL;
-
- RETURN (title);
-}
-
-int playback_entry_get_length (void)
-{
- ENTER;
-
- Entry * entry = get_playback_entry (FALSE, TRUE);
- int length = entry ? entry->length : 0;
-
- RETURN (length);
-}
-
-void playback_entry_set_tuple (Tuple * tuple)
-{
- ENTER;
- if (! playing_playlist || ! playing_playlist->position)
- RETURN ();
-
- Entry * entry = playing_playlist->position;
- entry_set_tuple (playing_playlist, entry, tuple);
-
- queue_update (PLAYLIST_UPDATE_METADATA, playing_playlist->number, entry->number, 1);
- LEAVE;
-}
-
-void playlist_save_state (void)
-{
- /* get playback state before locking playlists */
- bool_t paused = drct_get_paused ();
- int time = drct_get_time ();
-
- ENTER;
-
- const char * user_dir = get_path (AUD_PATH_USER_DIR);
- SCONCAT2 (path, user_dir, "/" STATE_FILE);
-
- FILE * handle = g_fopen (path, "w");
- if (! handle)
- RETURN ();
-
- fprintf (handle, "active %d\n", active_playlist ? active_playlist->number : -1);
- fprintf (handle, "playing %d\n", playing_playlist ? playing_playlist->number : -1);
-
- for (int playlist_num = 0; playlist_num < index_count (playlists);
- playlist_num ++)
- {
- Playlist * playlist = index_get (playlists, playlist_num);
-
- fprintf (handle, "playlist %d\n", playlist_num);
-
- if (playlist->filename)
- fprintf (handle, "filename %s\n", playlist->filename);
-
- fprintf (handle, "position %d\n", playlist->position ? playlist->position->number : -1);
-
- if (playlist == playing_playlist)
- {
- playlist->resume_paused = paused;
- playlist->resume_time = time;
- }
-
- fprintf (handle, "resume-state %d\n", paused ? RESUME_PAUSE : RESUME_PLAY);
- fprintf (handle, "resume-time %d\n", playlist->resume_time);
- }
-
- fclose (handle);
- LEAVE;
-}
-
-static char parse_key[512];
-static char * parse_value;
-
-static void parse_next (FILE * handle)
-{
- parse_value = NULL;
-
- if (! fgets (parse_key, sizeof parse_key, handle))
- return;
-
- char * space = strchr (parse_key, ' ');
- if (! space)
- return;
-
- * space = 0;
- parse_value = space + 1;
-
- char * newline = strchr (parse_value, '\n');
- if (newline)
- * newline = 0;
-}
-
-static bool_t parse_integer (const char * key, int * value)
-{
- return (parse_value && ! strcmp (parse_key, key) && sscanf (parse_value, "%d", value) == 1);
-}
-
-static char * parse_string (const char * key)
-{
- return (parse_value && ! strcmp (parse_key, key)) ? str_get (parse_value) : NULL;
-}
-
-void playlist_load_state (void)
-{
- ENTER;
- int playlist_num;
-
- const char * user_dir = get_path (AUD_PATH_USER_DIR);
- SCONCAT2 (path, user_dir, "/" STATE_FILE);
-
- FILE * handle = g_fopen (path, "r");
- if (! handle)
- RETURN ();
-
- parse_next (handle);
-
- if (parse_integer ("active", & playlist_num))
- {
- if (! (active_playlist = lookup_playlist (playlist_num)))
- active_playlist = index_get (playlists, 0);
- parse_next (handle);
- }
-
- if (parse_integer ("playing", & resume_playlist))
- parse_next (handle);
-
- while (parse_integer ("playlist", & playlist_num) && playlist_num >= 0 &&
- playlist_num < index_count (playlists))
- {
- Playlist * playlist = index_get (playlists, playlist_num);
- int entries = index_count (playlist->entries);
-
- parse_next (handle);
-
- char * s;
- if ((s = parse_string ("filename")))
- {
- str_unref (playlist->filename);
- playlist->filename = s;
- parse_next (handle);
- }
-
- int position = -1;
- if (parse_integer ("position", & position))
- parse_next (handle);
-
- if (position >= 0 && position < entries)
- set_position (playlist, index_get (playlist->entries, position), TRUE);
-
- int resume_state = RESUME_PLAY;
- if (parse_integer ("resume-state", & resume_state))
- parse_next (handle);
-
- playlist->resume_paused = (resume_state == RESUME_PAUSE);
-
- if (parse_integer ("resume-time", & playlist->resume_time))
- parse_next (handle);
-
- /* compatibility with Audacious 3.3 */
- if (playlist_num == resume_playlist && resume_state == RESUME_STOP)
- resume_playlist = -1;
- }
-
- fclose (handle);
-
- /* clear updates queued during init sequence */
-
- for (int i = 0; i < index_count (playlists); i ++)
- {
- Playlist * p = index_get (playlists, i);
- memset (& p->last_update, 0, sizeof (Update));
- memset (& p->next_update, 0, sizeof (Update));
- }
-
- update_level = 0;
-
- if (update_source)
- {
- g_source_remove (update_source);
- update_source = 0;
- }
-
- LEAVE;
-}
-
-void playlist_resume (void)
-{
- playlist_set_playing (resume_playlist);
-}
diff --git a/src/audacious/playlist-utils.c b/src/audacious/playlist-utils.c
deleted file mode 100644
index c51dfa2..0000000
--- a/src/audacious/playlist-utils.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * playlist-utils.c
- * Copyright 2009-2011 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-
-#include "misc.h"
-#include "playlist.h"
-
-static const char * get_basename (const char * filename)
-{
- const char * slash = strrchr (filename, '/');
-
- return (slash == NULL) ? filename : slash + 1;
-}
-
-static int filename_compare_basename (const char * a, const char * b)
-{
- return str_compare_encoded (get_basename (a), get_basename (b));
-}
-
-static int tuple_compare_string (const Tuple * a, const Tuple * b, int field)
-{
- char * string_a = tuple_get_str (a, field);
- char * string_b = tuple_get_str (b, field);
- int ret;
-
- if (string_a == NULL)
- ret = (string_b == NULL) ? 0 : -1;
- else if (string_b == NULL)
- ret = 1;
- else
- ret = str_compare (string_a, string_b);
-
- str_unref (string_a);
- str_unref (string_b);
- return ret;
-}
-
-static int tuple_compare_int (const Tuple * a, const Tuple * b, int field)
-{
- if (tuple_get_value_type (a, field) != TUPLE_INT)
- return (tuple_get_value_type (b, field) != TUPLE_INT) ? 0 : -1;
- if (tuple_get_value_type (b, field) != TUPLE_INT)
- return 1;
-
- int int_a = tuple_get_int (a, field);
- int int_b = tuple_get_int (b, field);
-
- return (int_a < int_b) ? -1 : (int_a > int_b);
-}
-
-static int tuple_compare_title (const Tuple * a, const Tuple * b)
-{
- return tuple_compare_string (a, b, FIELD_TITLE);
-}
-
-static int tuple_compare_album (const Tuple * a, const Tuple * b)
-{
- return tuple_compare_string (a, b, FIELD_ALBUM);
-}
-
-static int tuple_compare_artist (const Tuple * a, const Tuple * b)
-{
- return tuple_compare_string (a, b, FIELD_ARTIST);
-}
-
-static int tuple_compare_date (const Tuple * a, const Tuple * b)
-{
- return tuple_compare_int (a, b, FIELD_YEAR);
-}
-
-static int tuple_compare_track (const Tuple * a, const Tuple * b)
-{
- return tuple_compare_int (a, b, FIELD_TRACK_NUMBER);
-}
-
-static int tuple_compare_length (const Tuple * a, const Tuple * b)
-{
- return tuple_compare_int (a, b, FIELD_LENGTH);
-}
-
-static const PlaylistStringCompareFunc filename_comparisons[] = {
- [PLAYLIST_SORT_PATH] = str_compare_encoded,
- [PLAYLIST_SORT_FILENAME] = filename_compare_basename,
- [PLAYLIST_SORT_TITLE] = NULL,
- [PLAYLIST_SORT_ALBUM] = NULL,
- [PLAYLIST_SORT_ARTIST] = NULL,
- [PLAYLIST_SORT_DATE] = NULL,
- [PLAYLIST_SORT_TRACK] = NULL,
- [PLAYLIST_SORT_FORMATTED_TITLE] = NULL,
- [PLAYLIST_SORT_LENGTH] = NULL};
-
-static const PlaylistTupleCompareFunc tuple_comparisons[] = {
- [PLAYLIST_SORT_PATH] = NULL,
- [PLAYLIST_SORT_FILENAME] = NULL,
- [PLAYLIST_SORT_TITLE] = tuple_compare_title,
- [PLAYLIST_SORT_ALBUM] = tuple_compare_album,
- [PLAYLIST_SORT_ARTIST] = tuple_compare_artist,
- [PLAYLIST_SORT_DATE] = tuple_compare_date,
- [PLAYLIST_SORT_TRACK] = tuple_compare_track,
- [PLAYLIST_SORT_FORMATTED_TITLE] = NULL,
- [PLAYLIST_SORT_LENGTH] = tuple_compare_length};
-
-static const PlaylistStringCompareFunc title_comparisons[] = {
- [PLAYLIST_SORT_PATH] = NULL,
- [PLAYLIST_SORT_FILENAME] = NULL,
- [PLAYLIST_SORT_TITLE] = NULL,
- [PLAYLIST_SORT_ALBUM] = NULL,
- [PLAYLIST_SORT_ARTIST] = NULL,
- [PLAYLIST_SORT_DATE] = NULL,
- [PLAYLIST_SORT_TRACK] = NULL,
- [PLAYLIST_SORT_FORMATTED_TITLE] = str_compare,
- [PLAYLIST_SORT_LENGTH] = NULL};
-
-void playlist_sort_by_scheme (int playlist, int scheme)
-{
- if (filename_comparisons[scheme] != NULL)
- playlist_sort_by_filename (playlist, filename_comparisons[scheme]);
- else if (tuple_comparisons[scheme] != NULL)
- playlist_sort_by_tuple (playlist, tuple_comparisons[scheme]);
- else if (title_comparisons[scheme] != NULL)
- playlist_sort_by_title (playlist, title_comparisons[scheme]);
-}
-
-void playlist_sort_selected_by_scheme (int playlist, int scheme)
-{
- if (filename_comparisons[scheme] != NULL)
- playlist_sort_selected_by_filename (playlist,
- filename_comparisons[scheme]);
- else if (tuple_comparisons[scheme] != NULL)
- playlist_sort_selected_by_tuple (playlist, tuple_comparisons[scheme]);
- else if (title_comparisons[scheme] != NULL)
- playlist_sort_selected_by_title (playlist, title_comparisons[scheme]);
-}
-
-/* Fix me: This considers empty fields as duplicates. */
-void playlist_remove_duplicates_by_scheme (int playlist, int scheme)
-{
- int entries = playlist_entry_count (playlist);
- int count;
-
- if (entries < 1)
- return;
-
- playlist_select_all (playlist, FALSE);
-
- if (filename_comparisons[scheme] != NULL)
- {
- int (* compare) (const char * a, const char * b) =
- filename_comparisons[scheme];
-
- playlist_sort_by_filename (playlist, compare);
- char * last = playlist_entry_get_filename (playlist, 0);
-
- for (count = 1; count < entries; count ++)
- {
- char * current = playlist_entry_get_filename (playlist, count);
-
- if (compare (last, current) == 0)
- playlist_entry_set_selected (playlist, count, TRUE);
-
- str_unref (last);
- last = current;
- }
-
- str_unref (last);
- }
- else if (tuple_comparisons[scheme] != NULL)
- {
- int (* compare) (const Tuple * a, const Tuple * b) =
- tuple_comparisons[scheme];
-
- playlist_sort_by_tuple (playlist, compare);
- Tuple * last = playlist_entry_get_tuple (playlist, 0, FALSE);
-
- for (count = 1; count < entries; count ++)
- {
- Tuple * current = playlist_entry_get_tuple (playlist, count, FALSE);
-
- if (last != NULL && current != NULL && compare (last, current) == 0)
- playlist_entry_set_selected (playlist, count, TRUE);
-
- if (last)
- tuple_unref (last);
- last = current;
- }
-
- if (last)
- tuple_unref (last);
- }
-
- playlist_delete_selected (playlist);
-}
-
-void playlist_remove_failed (int playlist)
-{
- int entries = playlist_entry_count (playlist);
- int count;
-
- playlist_select_all (playlist, FALSE);
-
- for (count = 0; count < entries; count ++)
- {
- char * filename = playlist_entry_get_filename (playlist, count);
-
- /* vfs_file_test() only works for file:// URIs currently */
- if (! strncmp (filename, "file://", 7) && ! vfs_file_test (filename,
- G_FILE_TEST_EXISTS))
- playlist_entry_set_selected (playlist, count, TRUE);
-
- str_unref (filename);
- }
-
- playlist_delete_selected (playlist);
-}
-
-void playlist_select_by_patterns (int playlist, const Tuple * patterns)
-{
- const int fields[] = {FIELD_TITLE, FIELD_ALBUM, FIELD_ARTIST,
- FIELD_FILE_NAME};
-
- int entries = playlist_entry_count (playlist);
- int field, entry;
-
- playlist_select_all (playlist, TRUE);
-
- for (field = 0; field < ARRAY_LEN (fields); field ++)
- {
- char * pattern = tuple_get_str (patterns, fields[field]);
- GRegex * regex;
-
- if (! pattern || ! pattern[0] || ! (regex = g_regex_new (pattern,
- G_REGEX_CASELESS, 0, NULL)))
- {
- str_unref (pattern);
- continue;
- }
-
- for (entry = 0; entry < entries; entry ++)
- {
- if (! playlist_entry_get_selected (playlist, entry))
- continue;
-
- Tuple * tuple = playlist_entry_get_tuple (playlist, entry, FALSE);
- char * string = tuple ? tuple_get_str (tuple, fields[field]) : NULL;
-
- if (! string || ! g_regex_match (regex, string, 0, NULL))
- playlist_entry_set_selected (playlist, entry, FALSE);
-
- str_unref (string);
- if (tuple)
- tuple_unref (tuple);
- }
-
- g_regex_unref (regex);
- str_unref (pattern);
- }
-}
-
-static char * make_playlist_path (int playlist)
-{
- if (! playlist)
- return filename_build (get_path (AUD_PATH_USER_DIR), "playlist.xspf");
-
- SPRINTF (name, "playlist_%02d.xspf", 1 + playlist);
- return filename_build (get_path (AUD_PATH_PLAYLISTS_DIR), name);
-}
-
-static void load_playlists_real (void)
-{
- const char * folder = get_path (AUD_PATH_PLAYLISTS_DIR);
-
- /* old (v3.1 and earlier) naming scheme */
-
- int count;
- for (count = 0; ; count ++)
- {
- char * path = make_playlist_path (count);
-
- if (! g_file_test (path, G_FILE_TEST_EXISTS))
- {
- str_unref (path);
- break;
- }
-
- char * uri = filename_to_uri (path);
-
- playlist_insert (count);
- playlist_insert_playlist_raw (count, 0, uri);
- playlist_set_modified (count, TRUE);
-
- str_unref (path);
- str_unref (uri);
- }
-
- /* unique ID-based naming scheme */
-
- char * order_path = filename_build (folder, "order");
- char * order_string;
- g_file_get_contents (order_path, & order_string, NULL, NULL);
- str_unref (order_path);
-
- if (! order_string)
- goto DONE;
-
- Index * order = str_list_to_index (order_string, " ");
- g_free (order_string);
-
- for (int i = 0; i < index_count (order); i ++)
- {
- char * number = index_get (order, i);
-
- SCONCAT2 (name, number, ".audpl");
- char * path = filename_build (folder, name);
-
- if (! g_file_test (path, G_FILE_TEST_EXISTS))
- {
- str_unref (path);
-
- SCONCAT2 (name2, number, ".xspf");
- path = filename_build (folder, name2);
- }
-
- char * uri = filename_to_uri (path);
-
- playlist_insert_with_id (count + i, atoi (number));
- playlist_insert_playlist_raw (count + i, 0, uri);
- playlist_set_modified (count + i, FALSE);
-
- if (g_str_has_suffix (path, ".xspf"))
- playlist_set_modified (count + i, TRUE);
-
- str_unref (path);
- str_unref (uri);
- }
-
- index_free_full (order, (IndexFreeFunc) str_unref);
-
-DONE:
- if (! playlist_count ())
- playlist_insert (0);
-
- playlist_set_active (0);
-}
-
-static void save_playlists_real (void)
-{
- int lists = playlist_count ();
- const char * folder = get_path (AUD_PATH_PLAYLISTS_DIR);
-
- /* save playlists */
-
- Index * order = index_new ();
- GHashTable * saved = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) str_unref, NULL);
-
- for (int i = 0; i < lists; i ++)
- {
- int id = playlist_get_unique_id (i);
- char * number = int_to_str (id);
-
- SCONCAT2 (name, number, ".audpl");
-
- if (playlist_get_modified (i))
- {
- char * path = filename_build (folder, name);
- char * uri = filename_to_uri (path);
-
- playlist_save (i, uri);
- playlist_set_modified (i, FALSE);
-
- str_unref (path);
- str_unref (uri);
- }
-
- index_insert (order, -1, number);
- g_hash_table_insert (saved, str_get (name), NULL);
- }
-
- char * order_string = index_to_str_list (order, " ");
- index_free_full (order, (IndexFreeFunc) str_unref);
-
- GError * error = NULL;
- char * order_path = filename_build (folder, "order");
-
- char * old_order_string;
- g_file_get_contents (order_path, & old_order_string, NULL, NULL);
-
- if (! old_order_string || strcmp (old_order_string, order_string))
- {
- if (! g_file_set_contents (order_path, order_string, -1, & error))
- {
- fprintf (stderr, "Cannot write to %s: %s\n", order_path, error->message);
- g_error_free (error);
- }
- }
-
- str_unref (order_string);
- str_unref (order_path);
- g_free (old_order_string);
-
- /* clean up deleted playlists and files from old naming scheme */
-
- char * path = make_playlist_path (0);
- g_unlink (path);
- str_unref (path);
-
- GDir * dir = g_dir_open (folder, 0, NULL);
- if (! dir)
- goto DONE;
-
- const char * name;
- while ((name = g_dir_read_name (dir)))
- {
- if (! g_str_has_suffix (name, ".audpl") && ! g_str_has_suffix (name, ".xspf"))
- continue;
-
- if (! g_hash_table_contains (saved, name))
- {
- char * path = filename_build (folder, name);
- g_unlink (path);
- str_unref (path);
- }
- }
-
- g_dir_close (dir);
-
-DONE:
- g_hash_table_destroy (saved);
-}
-
-static bool_t hooks_added, state_changed;
-
-static void update_cb (void * data, void * user)
-{
- if (GPOINTER_TO_INT (data) < PLAYLIST_UPDATE_METADATA)
- return;
-
- state_changed = TRUE;
-}
-
-static void state_cb (void * data, void * user)
-{
- state_changed = TRUE;
-}
-
-void load_playlists (void)
-{
- load_playlists_real ();
- playlist_load_state ();
-
- state_changed = FALSE;
-
- if (! hooks_added)
- {
- hook_associate ("playlist update", update_cb, NULL);
- hook_associate ("playlist activate", state_cb, NULL);
- hook_associate ("playlist position", state_cb, NULL);
-
- hooks_added = TRUE;
- }
-}
-
-void save_playlists (bool_t exiting)
-{
- save_playlists_real ();
-
- /* on exit, save resume states */
- if (state_changed || exiting)
- {
- playlist_save_state ();
- state_changed = FALSE;
- }
-
- if (exiting && hooks_added)
- {
- hook_dissociate ("playlist update", update_cb);
- hook_dissociate ("playlist activate", state_cb);
- hook_dissociate ("playlist position", state_cb);
-
- hooks_added = FALSE;
- }
-}
diff --git a/src/audacious/playlist.h b/src/audacious/playlist.h
deleted file mode 100644
index d457ea0..0000000
--- a/src/audacious/playlist.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * playlist.h
- * Copyright 2010-2012 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.
- */
-
-#ifndef AUDACIOUS_PLAYLIST_H
-#define AUDACIOUS_PLAYLIST_H
-
-#include <stdint.h>
-
-#include <audacious/api.h>
-#include <audacious/types.h>
-#include <libaudcore/index.h>
-#include <libaudcore/tuple.h>
-
-/* The values which can be passed (packed into a pointer) to the "playlist
- * update" hook. PLAYLIST_UPDATE_SELECTION means that entries have been
- * selected or unselected, or that entries have been added to or removed from
- * the queue. PLAYLIST_UPDATE_METADATA means that new metadata has been read
- * for some entries, or that the title or filename of a playlist has changed,
- * and implies PLAYLIST_UPDATE_SELECTION. PLAYLIST_UPDATE_STRUCTURE covers any
- * change not listed under the other types, and implies both
- * PLAYLIST_UPDATE_SELECTION and PLAYLIST_UPDATE_METADATA. */
-enum {
- PLAYLIST_UPDATE_SELECTION = 1,
- PLAYLIST_UPDATE_METADATA,
- PLAYLIST_UPDATE_STRUCTURE};
-
-/* The values which can be passed to playlist_sort_by_scheme(),
- * playlist_sort_selected_by_scheme(), and
- * playlist_remove_duplicates_by_scheme(). PLAYLIST_SORT_PATH means the entire
- * URI of a song file; PLAYLIST_SORT_FILENAME means the portion after the last
- * "/" (forward slash). PLAYLIST_SORT_DATE means the song's release date (not
- * the file's modification time). */
-enum {
- PLAYLIST_SORT_PATH,
- PLAYLIST_SORT_FILENAME,
- PLAYLIST_SORT_TITLE,
- PLAYLIST_SORT_ALBUM,
- PLAYLIST_SORT_ARTIST,
- PLAYLIST_SORT_DATE,
- PLAYLIST_SORT_TRACK,
- PLAYLIST_SORT_FORMATTED_TITLE,
- PLAYLIST_SORT_LENGTH,
- PLAYLIST_SORT_SCHEMES};
-
-typedef bool_t (* PlaylistFilterFunc) (const char * filename, void * user);
-typedef int (* PlaylistStringCompareFunc) (const char * a, const char * b);
-typedef int (* PlaylistTupleCompareFunc) (const Tuple * a, const Tuple * b);
-
-#define AUD_API_NAME PlaylistAPI
-#define AUD_API_SYMBOL playlist_api
-
-#ifdef _AUDACIOUS_CORE
-
-#include "api-local-begin.h"
-#include "playlist-api.h"
-#include "api-local-end.h"
-
-/* playlist-files.c */
-bool_t playlist_load (const char * filename, char * * title,
- Index * * filenames, Index * * tuples);
-bool_t playlist_insert_playlist_raw (int list, int at,
- const char * filename);
-
-/* playlist-new.c */
-void playlist_init (void);
-void playlist_end (void);
-
-void playlist_insert_with_id (int at, int id);
-void playlist_set_modified (int playlist, bool_t modified);
-bool_t playlist_get_modified (int playlist);
-
-void playlist_load_state (void);
-void playlist_save_state (void);
-void playlist_resume (void);
-
-void playlist_reformat_titles (void);
-void playlist_trigger_scan (void);
-
-void playlist_entry_insert_batch_raw (int playlist, int at,
- Index * filenames, Index * tuples, Index * decoders);
-
-bool_t playlist_prev_song (int playlist);
-bool_t playlist_next_song (int playlist, bool_t repeat);
-
-int playback_entry_get_position (void);
-char * playback_entry_get_filename (void);
-PluginHandle * playback_entry_get_decoder (void);
-Tuple * playback_entry_get_tuple (void);
-char * playback_entry_get_title (void);
-int playback_entry_get_length (void);
-
-void playback_entry_set_tuple (Tuple * tuple);
-
-/* playlist-utils.c */
-void load_playlists (void);
-void save_playlists (bool_t exiting);
-
-#else
-
-#include <audacious/api-define-begin.h>
-#include <audacious/playlist-api.h>
-#include <audacious/api-define-end.h>
-
-#include <audacious/api-alias-begin.h>
-#include <audacious/playlist-api.h>
-#include <audacious/api-alias-end.h>
-
-#endif
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
-
-#ifdef AUD_API_DECLARE
-
-#define AUD_API_NAME PlaylistAPI
-#define AUD_API_SYMBOL playlist_api
-
-#include "api-define-begin.h"
-#include "playlist-api.h"
-#include "api-define-end.h"
-
-#include "api-declare-begin.h"
-#include "playlist-api.h"
-#include "api-declare-end.h"
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
diff --git a/src/audacious/plugin-init.c b/src/audacious/plugin-init.c
deleted file mode 100644
index b7690e3..0000000
--- a/src/audacious/plugin-init.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * plugin-init.c
- * Copyright 2010-2013 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 <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include "debug.h"
-#include "effect.h"
-#include "general.h"
-#include "interface.h"
-#include "misc.h"
-#include "output.h"
-#include "plugin.h"
-#include "plugins.h"
-#include "ui_preferences.h"
-#include "visualization.h"
-
-static const struct {
- const char * name;
- bool_t is_single;
-
- union {
- struct {
- bool_t (* start) (PluginHandle * plugin);
- void (* stop) (PluginHandle * plugin);
- } m;
-
- struct {
- PluginHandle * (* probe) (void);
- PluginHandle * (* get_current) (void);
- bool_t (* set_current) (PluginHandle * plugin);
- } s;
- } u;
-} table[PLUGIN_TYPES] = {
- [PLUGIN_TYPE_TRANSPORT] = {"transport", FALSE, .u.m = {NULL, NULL}},
- [PLUGIN_TYPE_PLAYLIST] = {"playlist", FALSE, .u.m = {NULL, NULL}},
- [PLUGIN_TYPE_INPUT] = {"input", FALSE, .u.m = {NULL, NULL}},
- [PLUGIN_TYPE_EFFECT] = {"effect", FALSE, .u.m = {effect_plugin_start, effect_plugin_stop}},
- [PLUGIN_TYPE_OUTPUT] = {"output", TRUE, .u.s = {output_plugin_probe,
- output_plugin_get_current, output_plugin_set_current}},
- [PLUGIN_TYPE_VIS] = {"visualization", FALSE, .u.m = {vis_plugin_start, vis_plugin_stop}},
- [PLUGIN_TYPE_GENERAL] = {"general", FALSE, .u.m = {general_plugin_start, general_plugin_stop}},
- [PLUGIN_TYPE_IFACE] = {"interface", TRUE, .u.s = {iface_plugin_probe,
- iface_plugin_get_current, iface_plugin_set_current}}};
-
-static bool_t find_enabled_cb (PluginHandle * p, void * pp)
-{
- * (PluginHandle * *) pp = p;
- return FALSE;
-}
-
-static PluginHandle * find_enabled (int type)
-{
- PluginHandle * p = NULL;
- plugin_for_enabled (type, find_enabled_cb, & p);
- return p;
-}
-
-static void start_single (int type)
-{
- PluginHandle * p;
-
- if ((p = find_enabled (type)) != NULL)
- {
- AUDDBG ("Starting selected %s plugin %s.\n", table[type].name,
- plugin_get_name (p));
-
- if (table[type].u.s.set_current (p))
- return;
-
- AUDDBG ("%s failed to start.\n", plugin_get_name (p));
- plugin_set_enabled (p, FALSE);
- }
-
- AUDDBG ("Probing for %s plugin.\n", table[type].name);
-
- if ((p = table[type].u.s.probe ()) == NULL)
- {
- fprintf (stderr, "FATAL: No %s plugin found.\n"
- "(Did you forget to install audacious-plugins?)\n", table[type].name);
- abort ();
- }
-
- AUDDBG ("Starting %s.\n", plugin_get_name (p));
- plugin_set_enabled (p, TRUE);
-
- if (! table[type].u.s.set_current (p))
- {
- fprintf (stderr, "FATAL: %s failed to start.\n", plugin_get_name (p));
- abort ();
- }
-}
-
-static bool_t start_multi_cb (PluginHandle * p, void * type)
-{
- AUDDBG ("Starting %s.\n", plugin_get_name (p));
-
- if (! table[GPOINTER_TO_INT (type)].u.m.start (p))
- {
- AUDDBG ("%s failed to start; disabling.\n", plugin_get_name (p));
- plugin_set_enabled (p, FALSE);
- }
-
- return TRUE;
-}
-
-static void start_plugins (int type)
-{
- if (type == PLUGIN_TYPE_IFACE && headless_mode ())
- return;
-
- if (table[type].is_single)
- start_single (type);
- else
- {
- if (table[type].u.m.start)
- plugin_for_enabled (type, start_multi_cb, GINT_TO_POINTER (type));
- }
-}
-
-static VFSConstructor * lookup_transport (const char * scheme)
-{
- PluginHandle * plugin = transport_plugin_for_scheme (scheme);
- if (! plugin)
- return NULL;
-
- TransportPlugin * tp = plugin_get_header (plugin);
- return tp ? tp->vtable : NULL;
-}
-
-void start_plugins_one (void)
-{
- plugin_system_init ();
- vfs_set_lookup_func (lookup_transport);
-
- for (int i = 0; i < PLUGIN_TYPE_GENERAL; i ++)
- start_plugins (i);
-}
-
-void start_plugins_two (void)
-{
- for (int i = PLUGIN_TYPE_GENERAL; i < PLUGIN_TYPES; i ++)
- start_plugins (i);
-}
-
-static bool_t misc_cleanup_cb (PluginHandle * p, void * unused)
-{
- plugin_misc_cleanup (p);
- return TRUE;
-}
-
-static bool_t stop_multi_cb (PluginHandle * p, void * type)
-{
- AUDDBG ("Shutting down %s.\n", plugin_get_name (p));
- table[GPOINTER_TO_INT (type)].u.m.stop (p);
- return TRUE;
-}
-
-static void stop_plugins (int type)
-{
- if (type == PLUGIN_TYPE_IFACE && headless_mode ())
- return;
-
- plugin_for_enabled (type, misc_cleanup_cb, GINT_TO_POINTER (type));
-
- if (table[type].is_single)
- {
- AUDDBG ("Shutting down %s.\n", plugin_get_name
- (table[type].u.s.get_current ()));
- table[type].u.s.set_current (NULL);
- }
- else
- {
- if (table[type].u.m.stop)
- plugin_for_enabled (type, stop_multi_cb, GINT_TO_POINTER (type));
- }
-}
-
-void stop_plugins_two (void)
-{
- for (int i = PLUGIN_TYPES - 1; i >= PLUGIN_TYPE_GENERAL; i --)
- stop_plugins (i);
-}
-
-void stop_plugins_one (void)
-{
- for (int i = PLUGIN_TYPE_GENERAL - 1; i >= 0; i --)
- stop_plugins (i);
-
- vfs_set_lookup_func (NULL);
- plugin_system_cleanup ();
-}
-
-PluginHandle * plugin_get_current (int type)
-{
- g_return_val_if_fail (table[type].is_single, NULL);
- return table[type].u.s.get_current ();
-}
-
-static bool_t enable_single (int type, PluginHandle * p)
-{
- PluginHandle * old = table[type].u.s.get_current ();
-
- plugin_misc_cleanup (old);
-
- AUDDBG ("Switching from %s to %s.\n", plugin_get_name (old),
- plugin_get_name (p));
- plugin_set_enabled (old, FALSE);
- plugin_set_enabled (p, TRUE);
-
- if (table[type].u.s.set_current (p))
- return TRUE;
-
- fprintf (stderr, "%s failed to start; falling back to %s.\n",
- plugin_get_name (p), plugin_get_name (old));
- plugin_set_enabled (p, FALSE);
- plugin_set_enabled (old, TRUE);
-
- if (table[type].u.s.set_current (old))
- return FALSE;
-
- fprintf (stderr, "FATAL: %s failed to start.\n", plugin_get_name (old));
- abort ();
-}
-
-static bool_t enable_multi (int type, PluginHandle * p, bool_t enable)
-{
- if (! enable)
- plugin_misc_cleanup (p);
-
- AUDDBG ("%sabling %s.\n", enable ? "En" : "Dis", plugin_get_name (p));
- plugin_set_enabled (p, enable);
-
- if (enable)
- {
- if (table[type].u.m.start && ! table[type].u.m.start (p))
- {
- fprintf (stderr, "%s failed to start.\n", plugin_get_name (p));
- plugin_set_enabled (p, FALSE);
- return FALSE;
- }
- }
- else
- {
- if (table[type].u.m.stop)
- table[type].u.m.stop (p);
- }
-
- return TRUE;
-}
-
-bool_t plugin_enable (PluginHandle * plugin, bool_t enable)
-{
- if (! enable == ! plugin_get_enabled (plugin))
- return TRUE;
-
- int type = plugin_get_type (plugin);
-
- if (table[type].is_single)
- {
- g_return_val_if_fail (enable, FALSE);
- return enable_single (type, plugin);
- }
-
- return enable_multi (type, plugin, enable);
-}
-
-/* Miscellaneous plugin-related functions ... */
-
-PluginHandle * plugin_by_widget (/* GtkWidget * */ void * widget)
-{
- PluginHandle * p;
- if ((p = vis_plugin_by_widget (widget)))
- return p;
- if ((p = general_plugin_by_widget (widget)))
- return p;
- return NULL;
-}
-
-int plugin_send_message (PluginHandle * plugin, const char * code, const void * data, int size)
-{
- if (! plugin_get_enabled (plugin))
- return ENOSYS;
-
- Plugin * header = plugin_get_header (plugin);
- if (! header || ! PLUGIN_HAS_FUNC (header, take_message))
- return ENOSYS;
-
- return header->take_message (code, data, size);
-}
-
-void plugin_do_about (PluginHandle * plugin)
-{
- g_return_if_fail (plugin_get_enabled (plugin));
- Plugin * header = plugin_get_header (plugin);
- g_return_if_fail (header);
-
- if (PLUGIN_HAS_FUNC (header, about))
- header->about ();
- else if (PLUGIN_HAS_FUNC (header, about_text))
- plugin_make_about_window (plugin);
-}
-
-void plugin_do_configure (PluginHandle * plugin)
-{
- g_return_if_fail (plugin_get_enabled (plugin));
- Plugin * header = plugin_get_header (plugin);
- g_return_if_fail (header);
-
- if (PLUGIN_HAS_FUNC (header, configure))
- header->configure ();
- else if (PLUGIN_HAS_FUNC (header, prefs))
- plugin_make_config_window (plugin);
-}
diff --git a/src/audacious/plugin-preferences.c b/src/audacious/plugin-preferences.c
deleted file mode 100644
index 8a0bf81..0000000
--- a/src/audacious/plugin-preferences.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * plugin-preferences.c
- * Copyright 2012-2013 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 <libaudcore/audstrings.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "i18n.h"
-#include "misc.h"
-#include "plugin.h"
-#include "plugins.h"
-#include "preferences.h"
-#include "ui_preferences.h"
-
-typedef struct {
- GtkWidget * about_window;
- GtkWidget * config_window;
-} PluginMiscData;
-
-void plugin_make_about_window (PluginHandle * plugin)
-{
- PluginMiscData * misc = plugin_get_misc_data (plugin, sizeof (PluginMiscData));
- Plugin * header = plugin_get_header (plugin);
-
- if (misc->about_window)
- {
- gtk_window_present ((GtkWindow *) misc->about_window);
- return;
- }
-
- const char * name = header->name;
- const char * text = header->about_text;
-
- if (PLUGIN_HAS_FUNC (header, domain))
- {
- name = dgettext (header->domain, name);
- text = dgettext (header->domain, text);
- }
-
- SCONCAT3 (title, _("About"), " ", name);
- audgui_simple_message (& misc->about_window, GTK_MESSAGE_INFO, title, text);
-}
-
-static void response_cb (GtkWidget * window, int response, const PluginPreferences * p)
-{
- if (response == GTK_RESPONSE_OK && p->apply)
- p->apply ();
-
- gtk_widget_destroy (window);
-}
-
-static void destroy_cb (GtkWidget * window, const PluginPreferences * p)
-{
- if (p->cleanup)
- p->cleanup ();
-}
-
-void plugin_make_config_window (PluginHandle * plugin)
-{
- PluginMiscData * misc = plugin_get_misc_data (plugin, sizeof (PluginMiscData));
- Plugin * header = plugin_get_header (plugin);
- const PluginPreferences * p = header->prefs;
-
- if (misc->config_window)
- {
- gtk_window_present ((GtkWindow *) misc->config_window);
- return;
- }
-
- if (p->init)
- p->init ();
-
- const char * name = header->name;
- if (PLUGIN_HAS_FUNC (header, domain))
- name = dgettext (header->domain, header->name);
-
- GtkWidget * window = gtk_dialog_new ();
-
- SCONCAT3 (title, name, " ", _("Settings"));
- gtk_window_set_title ((GtkWindow *) window, title);
-
- if (p->apply)
- {
- GtkWidget * button1 = audgui_button_new (_("_Set"), "system-run", NULL, NULL);
- GtkWidget * button2 = audgui_button_new (_("_Cancel"), "process-stop", NULL, NULL);
- gtk_dialog_add_action_widget ((GtkDialog *) window, button2, GTK_RESPONSE_CANCEL);
- gtk_dialog_add_action_widget ((GtkDialog *) window, button1, GTK_RESPONSE_OK);
- }
- else
- {
- GtkWidget * button = audgui_button_new (_("_Close"), "window-close", NULL, NULL);
- gtk_dialog_add_action_widget ((GtkDialog *) window, button, GTK_RESPONSE_CLOSE);
- }
-
- GtkWidget * content = gtk_dialog_get_content_area ((GtkDialog *) window);
- GtkWidget * box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- create_widgets_with_domain (box, p->widgets, p->n_widgets, header->domain);
- gtk_box_pack_start ((GtkBox *) content, box, TRUE, TRUE, 0);
-
- g_signal_connect (window, "response", (GCallback) response_cb, (void *) p);
- g_signal_connect (window, "destroy", (GCallback) destroy_cb, (void *) p);
-
- misc->config_window = window;
- g_signal_connect (window, "destroy", (GCallback) gtk_widget_destroyed, & misc->config_window);
-
- gtk_widget_show_all (window);
-}
-
-void plugin_misc_cleanup (PluginHandle * plugin)
-{
- PluginMiscData * misc = plugin_get_misc_data (plugin, sizeof (PluginMiscData));
-
- if (misc->about_window)
- gtk_widget_destroy (misc->about_window);
- if (misc->config_window)
- gtk_widget_destroy (misc->config_window);
-}
diff --git a/src/audacious/plugin-registry.c b/src/audacious/plugin-registry.c
deleted file mode 100644
index bc0d441..0000000
--- a/src/audacious/plugin-registry.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * plugin-registry.c
- * Copyright 2009-2013 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.
- */
-
-/* While the registry is being built (during early startup) or destroyed (during
- * late shutdown), the registry_locked flag will be set. Once this flag is
- * cleared, the registry will not be modified and can be read by concurrent
- * threads. The one change that can happen during this time is that a plugin is
- * loaded; hence the mutex must be locked before checking that a plugin is
- * loaded and while loading it. */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#include <libaudcore/audstrings.h>
-
-#include "debug.h"
-#include "i18n.h"
-#include "interface.h"
-#include "misc.h"
-#include "plugin.h"
-#include "plugins.h"
-
-#define FILENAME "plugin-registry"
-#define FORMAT 8
-
-typedef struct {
- GList * schemes;
-} TransportPluginData;
-
-typedef struct {
- GList * exts;
-} PlaylistPluginData;
-
-typedef struct {
- GList * keys[INPUT_KEYS];
- bool_t has_images, has_subtunes, can_write_tuple, has_infowin;
-} InputPluginData;
-
-struct PluginHandle {
- char * path;
- bool_t confirmed, loaded;
- int timestamp, type;
- Plugin * header;
- char * name, * domain;
- int priority;
- bool_t has_about, has_configure, enabled;
- GList * watches;
- void * misc;
-
- union {
- TransportPluginData t;
- PlaylistPluginData p;
- InputPluginData i;
- } u;
-};
-
-typedef struct {
- PluginForEachFunc func;
- void * data;
-} PluginWatch;
-
-static const char * plugin_type_names[] = {
- [PLUGIN_TYPE_TRANSPORT] = "transport",
- [PLUGIN_TYPE_PLAYLIST] = "playlist",
- [PLUGIN_TYPE_INPUT] = "input",
- [PLUGIN_TYPE_EFFECT] = "effect",
- [PLUGIN_TYPE_OUTPUT] = "output",
- [PLUGIN_TYPE_VIS] = "vis",
- [PLUGIN_TYPE_GENERAL] = "general",
- [PLUGIN_TYPE_IFACE] = "iface"};
-
-static const char * input_key_names[] = {
- [INPUT_KEY_SCHEME] = "scheme",
- [INPUT_KEY_EXTENSION] = "ext",
- [INPUT_KEY_MIME] = "mime"};
-
-static GList * plugin_list = NULL;
-static bool_t registry_locked = TRUE;
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static PluginHandle * plugin_new (char * path, bool_t confirmed, bool_t
- loaded, int timestamp, int type, Plugin * header)
-{
- PluginHandle * plugin = g_slice_new (PluginHandle);
-
- plugin->path = path;
- plugin->confirmed = confirmed;
- plugin->loaded = loaded;
- plugin->timestamp = timestamp;
- plugin->type = type;
- plugin->header = header;
- plugin->name = NULL;
- plugin->domain = NULL;
- plugin->priority = 0;
- plugin->has_about = FALSE;
- plugin->has_configure = FALSE;
- plugin->enabled = FALSE;
- plugin->watches = NULL;
- plugin->misc = NULL;
-
- if (type == PLUGIN_TYPE_TRANSPORT)
- {
- plugin->enabled = TRUE;
- plugin->u.t.schemes = NULL;
- }
- else if (type == PLUGIN_TYPE_PLAYLIST)
- {
- plugin->enabled = TRUE;
- plugin->u.p.exts = NULL;
- }
- else if (type == PLUGIN_TYPE_INPUT)
- {
- plugin->enabled = TRUE;
- memset (plugin->u.i.keys, 0, sizeof plugin->u.i.keys);
- plugin->u.i.has_images = FALSE;
- plugin->u.i.has_subtunes = FALSE;
- plugin->u.i.can_write_tuple = FALSE;
- plugin->u.i.has_infowin = FALSE;
- }
-
- plugin_list = g_list_prepend (plugin_list, plugin);
- return plugin;
-}
-
-static void plugin_free (PluginHandle * plugin)
-{
- plugin_list = g_list_remove (plugin_list, plugin);
-
- for (GList * node = plugin->watches; node; node = node->next)
- g_slice_free (PluginWatch, node->data);
-
- if (plugin->type == PLUGIN_TYPE_TRANSPORT)
- g_list_free_full (plugin->u.t.schemes, (GDestroyNotify) str_unref);
- else if (plugin->type == PLUGIN_TYPE_PLAYLIST)
- g_list_free_full (plugin->u.p.exts, (GDestroyNotify) str_unref);
- else if (plugin->type == PLUGIN_TYPE_INPUT)
- {
- for (int key = 0; key < INPUT_KEYS; key ++)
- g_list_free_full (plugin->u.i.keys[key], (GDestroyNotify) str_unref);
- }
-
- str_unref (plugin->path);
- str_unref (plugin->name);
- str_unref (plugin->domain);
- g_free (plugin->misc);
- g_slice_free (PluginHandle, plugin);
-}
-
-static FILE * open_registry_file (const char * mode)
-{
- const char * user_dir = get_path (AUD_PATH_USER_DIR);
- SCONCAT2 (path, user_dir, "/" FILENAME);
- return g_fopen (path, mode);
-}
-
-static void transport_plugin_save (PluginHandle * plugin, FILE * handle)
-{
- for (GList * node = plugin->u.t.schemes; node; node = node->next)
- fprintf (handle, "scheme %s\n", (const char *) node->data);
-}
-
-static void playlist_plugin_save (PluginHandle * plugin, FILE * handle)
-{
- for (GList * node = plugin->u.p.exts; node; node = node->next)
- fprintf (handle, "ext %s\n", (const char *) node->data);
-}
-
-static void input_plugin_save (PluginHandle * plugin, FILE * handle)
-{
- for (int key = 0; key < INPUT_KEYS; key ++)
- {
- for (GList * node = plugin->u.i.keys[key]; node; node = node->next)
- fprintf (handle, "%s %s\n", input_key_names[key], (const char *)
- node->data);
- }
-
- fprintf (handle, "images %d\n", plugin->u.i.has_images);
- fprintf (handle, "subtunes %d\n", plugin->u.i.has_subtunes);
- fprintf (handle, "writes %d\n", plugin->u.i.can_write_tuple);
- fprintf (handle, "infowin %d\n", plugin->u.i.has_infowin);
-}
-
-static void plugin_save (PluginHandle * plugin, FILE * handle)
-{
- fprintf (handle, "%s %s\n", plugin_type_names[plugin->type], plugin->path);
- fprintf (handle, "stamp %d\n", plugin->timestamp);
- fprintf (handle, "name %s\n", plugin->name);
-
- if (plugin->domain)
- fprintf (handle, "domain %s\n", plugin->domain);
-
- fprintf (handle, "priority %d\n", plugin->priority);
- fprintf (handle, "about %d\n", plugin->has_about);
- fprintf (handle, "config %d\n", plugin->has_configure);
- fprintf (handle, "enabled %d\n", plugin->enabled);
-
- if (plugin->type == PLUGIN_TYPE_TRANSPORT)
- transport_plugin_save (plugin, handle);
- else if (plugin->type == PLUGIN_TYPE_PLAYLIST)
- playlist_plugin_save (plugin, handle);
- else if (plugin->type == PLUGIN_TYPE_INPUT)
- input_plugin_save (plugin, handle);
-}
-
-void plugin_registry_save (void)
-{
- FILE * handle = open_registry_file ("w");
- g_return_if_fail (handle);
-
- fprintf (handle, "format %d\n", FORMAT);
-
- g_list_foreach (plugin_list, (GFunc) plugin_save, handle);
- fclose (handle);
-
- g_list_foreach (plugin_list, (GFunc) plugin_free, NULL);
- registry_locked = TRUE;
-}
-
-static char parse_key[512];
-static char * parse_value;
-
-static void parse_next (FILE * handle)
-{
- parse_value = NULL;
-
- if (! fgets (parse_key, sizeof parse_key, handle))
- return;
-
- char * space = strchr (parse_key, ' ');
- if (! space)
- return;
-
- * space = 0;
- parse_value = space + 1;
-
- char * newline = strchr (parse_value, '\n');
- if (newline)
- * newline = 0;
-}
-
-static bool_t parse_integer (const char * key, int * value)
-{
- return (parse_value && ! strcmp (parse_key, key) && sscanf (parse_value,
- "%d", value) == 1);
-}
-
-static char * parse_string (const char * key)
-{
- return (parse_value && ! strcmp (parse_key, key)) ? str_get (parse_value) : NULL;
-}
-
-static void transport_plugin_parse (PluginHandle * plugin, FILE * handle)
-{
- char * value;
- while ((value = parse_string ("scheme")))
- {
- plugin->u.t.schemes = g_list_prepend (plugin->u.t.schemes, value);
- parse_next (handle);
- }
-}
-
-static void playlist_plugin_parse (PluginHandle * plugin, FILE * handle)
-{
- char * value;
- while ((value = parse_string ("ext")))
- {
- plugin->u.p.exts = g_list_prepend (plugin->u.p.exts, value);
- parse_next (handle);
- }
-}
-
-static void input_plugin_parse (PluginHandle * plugin, FILE * handle)
-{
- for (int key = 0; key < INPUT_KEYS; key ++)
- {
- char * value;
- while ((value = parse_string (input_key_names[key])))
- {
- plugin->u.i.keys[key] = g_list_prepend (plugin->u.i.keys[key],
- value);
- parse_next (handle);
- }
- }
-
- if (parse_integer ("images", & plugin->u.i.has_images))
- parse_next (handle);
- if (parse_integer ("subtunes", & plugin->u.i.has_subtunes))
- parse_next (handle);
- if (parse_integer ("writes", & plugin->u.i.can_write_tuple))
- parse_next (handle);
- if (parse_integer ("infowin", & plugin->u.i.has_infowin))
- parse_next (handle);
-}
-
-static bool_t plugin_parse (FILE * handle)
-{
- char * path = NULL;
-
- int type;
- for (type = 0; type < PLUGIN_TYPES; type ++)
- {
- if ((path = parse_string (plugin_type_names[type])))
- goto FOUND;
- }
-
- return FALSE;
-
-FOUND:
- parse_next (handle);
-
- int timestamp;
- if (! parse_integer ("stamp", & timestamp))
- {
- str_unref (path);
- return FALSE;
- }
-
- PluginHandle * plugin = plugin_new (path, FALSE, FALSE, timestamp, type,
- NULL);
- parse_next (handle);
-
- if ((plugin->name = parse_string ("name")))
- parse_next (handle);
- if ((plugin->domain = parse_string ("domain")))
- parse_next (handle);
- if (parse_integer ("priority", & plugin->priority))
- parse_next (handle);
- if (parse_integer ("about", & plugin->has_about))
- parse_next (handle);
- if (parse_integer ("config", & plugin->has_configure))
- parse_next (handle);
- if (parse_integer ("enabled", & plugin->enabled))
- parse_next (handle);
-
- if (type == PLUGIN_TYPE_TRANSPORT)
- transport_plugin_parse (plugin, handle);
- else if (type == PLUGIN_TYPE_PLAYLIST)
- playlist_plugin_parse (plugin, handle);
- else if (type == PLUGIN_TYPE_INPUT)
- input_plugin_parse (plugin, handle);
-
- return TRUE;
-}
-
-void plugin_registry_load (void)
-{
- FILE * handle = open_registry_file ("r");
- if (! handle)
- goto UNLOCK;
-
- parse_next (handle);
-
- int format;
- if (! parse_integer ("format", & format) || format != FORMAT)
- goto ERR;
-
- parse_next (handle);
-
- while (plugin_parse (handle))
- ;
-
-ERR:
- fclose (handle);
-UNLOCK:
- registry_locked = FALSE;
-}
-
-static void plugin_prune (PluginHandle * plugin)
-{
- if (plugin->confirmed)
- return;
-
- AUDDBG ("Plugin not found: %s\n", plugin->path);
- plugin_free (plugin);
-}
-
-int plugin_compare (PluginHandle * a, PluginHandle * b)
-{
- if (a->type < b->type)
- return -1;
- if (a->type > b->type)
- return 1;
- if (a->priority < b->priority)
- return -1;
- if (a->priority > b->priority)
- return 1;
-
- int diff;
- if ((diff = str_compare (dgettext (a->domain, a->name), dgettext (b->domain, b->name))))
- return diff;
-
- return str_compare (a->path, b->path);
-}
-
-void plugin_registry_prune (void)
-{
- g_list_foreach (plugin_list, (GFunc) plugin_prune, NULL);
- plugin_list = g_list_sort (plugin_list, (GCompareFunc) plugin_compare);
- registry_locked = TRUE;
-}
-
-static int plugin_lookup_cb (PluginHandle * plugin, const char * path)
-{
- return strcmp (plugin->path, path);
-}
-
-PluginHandle * plugin_lookup (const char * path)
-{
- GList * node = g_list_find_custom (plugin_list, path, (GCompareFunc)
- plugin_lookup_cb);
- return node ? node->data : NULL;
-}
-
-static int plugin_lookup_basename_cb (PluginHandle * plugin, const char * basename)
-{
- const char * slash = strrchr (plugin->path, G_DIR_SEPARATOR);
- if (! slash)
- return TRUE;
-
- const char * dot = strrchr (slash + 1, '.');
- if (! dot)
- return TRUE;
-
- return strncmp (slash + 1, basename, dot - (slash + 1));
-}
-
-/* Note: If there are multiple plugins with the same basename, this returns only
- * one of them. So give different plugins different basenames. --jlindgren */
-PluginHandle * plugin_lookup_basename (const char * basename)
-{
- GList * node = g_list_find_custom (plugin_list, basename, (GCompareFunc)
- plugin_lookup_basename_cb);
- return node ? node->data : NULL;
-}
-
-static void plugin_get_info (PluginHandle * plugin, bool_t new)
-{
- Plugin * header = plugin->header;
-
- str_unref (plugin->name);
- str_unref (plugin->domain);
- plugin->name = str_get (header->name);
- plugin->domain = PLUGIN_HAS_FUNC (header, domain) ? str_get (header->domain) : NULL;
- plugin->has_about = PLUGIN_HAS_FUNC (header, about) || PLUGIN_HAS_FUNC (header, about_text);
- plugin->has_configure = PLUGIN_HAS_FUNC (header, configure) || PLUGIN_HAS_FUNC (header, prefs);
-
- if (header->type == PLUGIN_TYPE_TRANSPORT)
- {
- TransportPlugin * tp = (TransportPlugin *) header;
-
- g_list_free_full (plugin->u.t.schemes, (GDestroyNotify) str_unref);
- plugin->u.t.schemes = NULL;
-
- for (int i = 0; tp->schemes[i]; i ++)
- plugin->u.t.schemes = g_list_prepend (plugin->u.t.schemes, str_get (tp->schemes[i]));
- }
- else if (header->type == PLUGIN_TYPE_PLAYLIST)
- {
- PlaylistPlugin * pp = (PlaylistPlugin *) header;
-
- g_list_free_full (plugin->u.p.exts, (GDestroyNotify) str_unref);
- plugin->u.p.exts = NULL;
-
- for (int i = 0; pp->extensions[i]; i ++)
- plugin->u.p.exts = g_list_prepend (plugin->u.p.exts, str_get (pp->extensions[i]));
- }
- else if (header->type == PLUGIN_TYPE_INPUT)
- {
- InputPlugin * ip = (InputPlugin *) header;
- plugin->priority = ip->priority;
-
- for (int key = 0; key < INPUT_KEYS; key ++)
- {
- g_list_free_full (plugin->u.i.keys[key], (GDestroyNotify) str_unref);
- plugin->u.i.keys[key] = NULL;
- }
-
- if (PLUGIN_HAS_FUNC (ip, extensions))
- {
- for (int i = 0; ip->extensions[i]; i ++)
- plugin->u.i.keys[INPUT_KEY_EXTENSION] = g_list_prepend
- (plugin->u.i.keys[INPUT_KEY_EXTENSION],
- str_get (ip->extensions[i]));
- }
-
- if (PLUGIN_HAS_FUNC (ip, mimes))
- {
- for (int i = 0; ip->mimes[i]; i ++)
- plugin->u.i.keys[INPUT_KEY_MIME] = g_list_prepend
- (plugin->u.i.keys[INPUT_KEY_MIME], str_get (ip->mimes[i]));
- }
-
- if (PLUGIN_HAS_FUNC (ip, schemes))
- {
- for (int i = 0; ip->schemes[i]; i ++)
- plugin->u.i.keys[INPUT_KEY_SCHEME] = g_list_prepend
- (plugin->u.i.keys[INPUT_KEY_SCHEME], str_get (ip->schemes[i]));
- }
-
- plugin->u.i.has_images = PLUGIN_HAS_FUNC (ip, get_song_image);
- plugin->u.i.has_subtunes = ip->have_subtune;
- plugin->u.i.can_write_tuple = PLUGIN_HAS_FUNC (ip, update_song_tuple);
- plugin->u.i.has_infowin = PLUGIN_HAS_FUNC (ip, file_info_box);
- }
- else if (header->type == PLUGIN_TYPE_OUTPUT)
- {
- OutputPlugin * op = (OutputPlugin *) header;
- plugin->priority = 10 - op->probe_priority;
- }
- else if (header->type == PLUGIN_TYPE_EFFECT)
- {
- EffectPlugin * ep = (EffectPlugin *) header;
- plugin->priority = ep->order;
- }
- else if (header->type == PLUGIN_TYPE_GENERAL)
- {
- GeneralPlugin * gp = (GeneralPlugin *) header;
- if (new)
- plugin->enabled = gp->enabled_by_default;
- }
-}
-
-void plugin_register (const char * path, int timestamp)
-{
- PluginHandle * plugin = plugin_lookup (path);
-
- if (plugin)
- {
- AUDDBG ("Register plugin: %s\n", path);
- plugin->confirmed = TRUE;
-
- if (plugin->timestamp != timestamp)
- {
- AUDDBG ("Rescan plugin: %s\n", path);
- Plugin * header = plugin_load (path);
- if (! header || header->type != plugin->type)
- return;
-
- plugin->loaded = TRUE;
- plugin->header = header;
- plugin->timestamp = timestamp;
-
- plugin_get_info (plugin, FALSE);
- }
- }
- else
- {
- AUDDBG ("New plugin: %s\n", path);
- Plugin * header = plugin_load (path);
- if (! header)
- return;
-
- plugin = plugin_new (str_get (path), TRUE, TRUE, timestamp,
- header->type, header);
-
- plugin_get_info (plugin, TRUE);
- }
-}
-
-int plugin_get_type (PluginHandle * plugin)
-{
- return plugin->type;
-}
-
-const char * plugin_get_filename (PluginHandle * plugin)
-{
- return plugin->path;
-}
-
-const void * plugin_get_header (PluginHandle * plugin)
-{
- pthread_mutex_lock (& mutex);
-
- if (! plugin->loaded)
- {
- Plugin * header = plugin_load (plugin->path);
- if (! header || header->type != plugin->type)
- goto DONE;
-
- plugin->loaded = TRUE;
- plugin->header = header;
- }
-
-DONE:
- pthread_mutex_unlock (& mutex);
- return plugin->header;
-}
-
-static int plugin_by_header_cb (PluginHandle * plugin, const void * header)
-{
- return (plugin->header == header) ? 0 : -1;
-}
-
-PluginHandle * plugin_by_header (const void * header)
-{
- GList * node = g_list_find_custom (plugin_list, header, (GCompareFunc)
- plugin_by_header_cb);
- return node ? node->data : NULL;
-}
-
-int plugin_count (int type)
-{
- int count = 0;
-
- for (GList * node = plugin_list; node; node = node->next)
- {
- PluginHandle * plugin = node->data;
- if (plugin->type == type)
- count ++;
- }
-
- return count;
-}
-
-int plugin_get_index (PluginHandle * plugin)
-{
- int index = 0;
-
- for (GList * node = plugin_list; node; node = node->next)
- {
- PluginHandle * plugin2 = node->data;
- if (plugin2->type == plugin->type)
- {
- if (plugin2 == plugin)
- return index;
- index ++;
- }
- }
-
- return -1;
-}
-
-PluginHandle * plugin_by_index (int type, int index)
-{
- for (GList * node = plugin_list; node; node = node->next)
- {
- PluginHandle * plugin = node->data;
- if (plugin->type == type)
- {
- if (! index)
- return plugin;
- index --;
- }
- }
-
- return NULL;
-}
-
-void plugin_for_each (int type, PluginForEachFunc func, void * data)
-{
- for (GList * node = plugin_list; node; node = node->next)
- {
- if (((PluginHandle *) node->data)->type != type)
- continue;
- if (! func (node->data, data))
- break;
- }
-}
-
-const char * plugin_get_name (PluginHandle * plugin)
-{
- return dgettext (plugin->domain, plugin->name);
-}
-
-bool_t plugin_has_about (PluginHandle * plugin)
-{
- return plugin->has_about;
-}
-
-bool_t plugin_has_configure (PluginHandle * plugin)
-{
- return plugin->has_configure;
-}
-
-bool_t plugin_get_enabled (PluginHandle * plugin)
-{
- return plugin->enabled;
-}
-
-static void plugin_call_watches (PluginHandle * plugin)
-{
- for (GList * node = plugin->watches; node; )
- {
- GList * next = node->next;
- PluginWatch * watch = node->data;
-
- if (! watch->func (plugin, watch->data))
- {
- g_slice_free (PluginWatch, watch);
- plugin->watches = g_list_delete_link (plugin->watches, node);
- }
-
- node = next;
- }
-}
-
-void plugin_set_enabled (PluginHandle * plugin, bool_t enabled)
-{
- plugin->enabled = enabled;
- plugin_call_watches (plugin);
-}
-
-typedef struct {
- PluginForEachFunc func;
- void * data;
-} PluginForEnabledState;
-
-static bool_t plugin_for_enabled_cb (PluginHandle * plugin,
- PluginForEnabledState * state)
-{
- if (! plugin->enabled)
- return TRUE;
- return state->func (plugin, state->data);
-}
-
-void plugin_for_enabled (int type, PluginForEachFunc func, void * data)
-{
- PluginForEnabledState state = {func, data};
- plugin_for_each (type, (PluginForEachFunc) plugin_for_enabled_cb, & state);
-}
-
-void plugin_add_watch (PluginHandle * plugin, PluginForEachFunc func, void *
- data)
-{
- PluginWatch * watch = g_slice_new (PluginWatch);
- watch->func = func;
- watch->data = data;
- plugin->watches = g_list_prepend (plugin->watches, watch);
-}
-
-void plugin_remove_watch (PluginHandle * plugin, PluginForEachFunc func, void *
- data)
-{
- for (GList * node = plugin->watches; node; )
- {
- GList * next = node->next;
- PluginWatch * watch = node->data;
-
- if (watch->func == func && watch->data == data)
- {
- g_slice_free (PluginWatch, watch);
- plugin->watches = g_list_delete_link (plugin->watches, node);
- }
-
- node = next;
- }
-}
-
-void * plugin_get_misc_data (PluginHandle * plugin, int size)
-{
- if (! plugin->misc)
- plugin->misc = g_malloc0 (size);
-
- return plugin->misc;
-}
-
-typedef struct {
- const char * scheme;
- PluginHandle * plugin;
-} TransportPluginForSchemeState;
-
-static bool_t transport_plugin_for_scheme_cb (PluginHandle * plugin,
- TransportPluginForSchemeState * state)
-{
- if (! g_list_find_custom (plugin->u.t.schemes, state->scheme,
- (GCompareFunc) g_ascii_strcasecmp))
- return TRUE;
-
- state->plugin = plugin;
- return FALSE;
-}
-
-PluginHandle * transport_plugin_for_scheme (const char * scheme)
-{
- TransportPluginForSchemeState state = {scheme, NULL};
- plugin_for_enabled (PLUGIN_TYPE_TRANSPORT, (PluginForEachFunc)
- transport_plugin_for_scheme_cb, & state);
- return state.plugin;
-}
-
-typedef struct {
- const char * ext;
- PluginForEachFunc func;
- void * data;
-} PlaylistPluginForExtState;
-
-static bool_t playlist_plugin_for_ext_cb (PluginHandle * plugin,
- PlaylistPluginForExtState * state)
-{
- if (! g_list_find_custom (plugin->u.p.exts, state->ext,
- (GCompareFunc) g_ascii_strcasecmp))
- return TRUE;
-
- return state->func (plugin, state->data);
-}
-
-void playlist_plugin_for_ext (const char * ext, PluginForEachFunc func, void * data)
-{
- PlaylistPluginForExtState state = {ext, func, data};
- plugin_for_enabled (PLUGIN_TYPE_PLAYLIST, (PluginForEachFunc)
- playlist_plugin_for_ext_cb, & state);
-}
-
-typedef struct {
- int key;
- const char * value;
- PluginForEachFunc func;
- void * data;
-} InputPluginForKeyState;
-
-static bool_t input_plugin_for_key_cb (PluginHandle * plugin,
- InputPluginForKeyState * state)
-{
- if (! g_list_find_custom (plugin->u.i.keys[state->key], state->value,
- (GCompareFunc) g_ascii_strcasecmp))
- return TRUE;
-
- return state->func (plugin, state->data);
-}
-
-void input_plugin_for_key (int key, const char * value, PluginForEachFunc
- func, void * data)
-{
- InputPluginForKeyState state = {key, value, func, data};
- plugin_for_enabled (PLUGIN_TYPE_INPUT, (PluginForEachFunc)
- input_plugin_for_key_cb, & state);
-}
-
-bool_t input_plugin_has_images (PluginHandle * plugin)
-{
- g_return_val_if_fail (plugin->type == PLUGIN_TYPE_INPUT, FALSE);
- return plugin->u.i.has_images;
-}
-
-bool_t input_plugin_has_subtunes (PluginHandle * plugin)
-{
- g_return_val_if_fail (plugin->type == PLUGIN_TYPE_INPUT, FALSE);
- return plugin->u.i.has_subtunes;
-}
-
-bool_t input_plugin_can_write_tuple (PluginHandle * plugin)
-{
- g_return_val_if_fail (plugin->type == PLUGIN_TYPE_INPUT, FALSE);
- return plugin->u.i.can_write_tuple;
-}
-
-bool_t input_plugin_has_infowin (PluginHandle * plugin)
-{
- g_return_val_if_fail (plugin->type == PLUGIN_TYPE_INPUT, FALSE);
- return plugin->u.i.has_infowin;
-}
diff --git a/src/audacious/plugin-view.c b/src/audacious/plugin-view.c
deleted file mode 100644
index 36959af..0000000
--- a/src/audacious/plugin-view.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * plugin-view.c
- * Copyright 2010-2012 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 <gtk/gtk.h>
-
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "i18n.h"
-#include "plugin.h"
-#include "plugins.h"
-#include "ui_preferences.h"
-
-enum {
- PVIEW_COL_NODE,
- PVIEW_COL_ENABLED,
- PVIEW_COL_NAME,
- PVIEW_COLS
-};
-
-typedef struct {
- PluginHandle * p;
- GtkTreeModel * model;
- GtkTreePath * path;
-} Node;
-
-static PluginHandle * get_selected_plugin (GtkTreeView * tree)
-{
- Node * n = NULL;
-
- GtkTreeSelection * sel = gtk_tree_view_get_selection (tree);
-
- /* the treeview may not have a model yet */
- if (! sel)
- return NULL;
-
- GtkTreeModel * model;
- GtkTreeIter iter;
- if (gtk_tree_selection_get_selected (sel, & model, & iter))
- gtk_tree_model_get (model, & iter, PVIEW_COL_NODE, & n, -1);
-
- return n == NULL ? NULL : n->p;
-}
-
-static void do_enable (GtkCellRendererToggle * cell, const char * path_str,
- GtkTreeModel * model)
-{
- GtkTreePath * path = gtk_tree_path_new_from_string (path_str);
- GtkTreeIter iter;
- gtk_tree_model_get_iter (model, & iter, path);
- gtk_tree_path_free (path);
-
- Node * n = NULL;
- bool_t enabled;
- gtk_tree_model_get (model, & iter, PVIEW_COL_NODE, & n,
- PVIEW_COL_ENABLED, & enabled, -1);
- g_return_if_fail (n != NULL);
-
- plugin_enable (n->p, ! enabled);
-}
-
-static bool_t list_watcher (PluginHandle * p, Node * n)
-{
- GtkTreeIter iter;
- gtk_tree_model_get_iter (n->model, & iter, n->path);
- gtk_list_store_set ((GtkListStore *) n->model, & iter, PVIEW_COL_ENABLED,
- plugin_get_enabled (n->p), -1);
- return TRUE;
-}
-
-static bool_t fill_cb (PluginHandle * p, GtkTreeModel * model)
-{
- Node * n = g_slice_new (Node);
-
- GtkTreeIter iter;
- gtk_list_store_append ((GtkListStore *) model, & iter);
- gtk_list_store_set ((GtkListStore *) model, & iter, PVIEW_COL_NODE, n,
- PVIEW_COL_ENABLED, plugin_get_enabled (p), PVIEW_COL_NAME,
- plugin_get_name (p), -1);
-
- n->p = p;
- n->model = model;
- n->path = gtk_tree_model_get_path (model, & iter);
-
- plugin_add_watch (p, (PluginForEachFunc) list_watcher, n);
-
- return TRUE;
-}
-
-static void list_fill (GtkTreeView * tree, void * type)
-{
- GtkTreeModel * model = (GtkTreeModel *) gtk_list_store_new (PVIEW_COLS,
- G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_STRING);
- gtk_tree_view_set_model (tree, model);
-
- GtkTreeViewColumn * col = gtk_tree_view_column_new ();
- gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
- gtk_tree_view_column_set_resizable (col, FALSE);
- gtk_tree_view_append_column (tree, col);
-
- GtkCellRenderer * rend = gtk_cell_renderer_toggle_new ();
- g_signal_connect (rend, "toggled", (GCallback) do_enable, model);
- gtk_tree_view_column_pack_start (col, rend, FALSE);
- gtk_tree_view_column_set_attributes (col, rend, "active", PVIEW_COL_ENABLED,
- NULL);
-
- col = gtk_tree_view_column_new ();
- gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
- gtk_tree_view_column_set_expand (col, TRUE);
- gtk_tree_view_column_set_resizable (col, FALSE);
- gtk_tree_view_append_column (tree, col);
-
- rend = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (col, rend, FALSE);
- gtk_tree_view_column_set_attributes (col, rend, "text", PVIEW_COL_NAME, NULL);
-
- plugin_for_each (GPOINTER_TO_INT (type), (PluginForEachFunc) fill_cb, model);
-}
-
-static void list_destroy (GtkTreeView * tree)
-{
- GtkTreeModel * model = gtk_tree_view_get_model (tree);
- if (model == NULL)
- return;
-
- GtkTreeIter iter;
- if (gtk_tree_model_get_iter_first (model, & iter))
- {
- do
- {
- Node * n = NULL;
- gtk_tree_model_get (model, & iter, PVIEW_COL_NODE, & n, -1);
- g_return_if_fail (n != NULL);
-
- plugin_remove_watch (n->p, (PluginForEachFunc) list_watcher, n);
- gtk_tree_path_free (n->path);
- g_slice_free (Node, n);
- }
- while (gtk_tree_model_iter_next (model, & iter));
- }
-
- g_object_unref ((GObject *) model);
-}
-
-static bool_t config_watcher (PluginHandle * p, GtkWidget * config)
-{
- gtk_widget_set_sensitive (config, plugin_has_configure (p) &&
- plugin_get_enabled (p));
- return TRUE;
-}
-
-static bool_t about_watcher (PluginHandle * p, GtkWidget * about)
-{
- gtk_widget_set_sensitive (about, plugin_has_about (p) && plugin_get_enabled
- (p));
- return TRUE;
-}
-
-static void button_update (GtkTreeView * tree, GtkWidget * b)
-{
- PluginForEachFunc watcher = (PluginForEachFunc) g_object_get_data
- ((GObject *) b, "watcher");
- g_return_if_fail (watcher != NULL);
-
- PluginHandle * p = g_object_steal_data ((GObject *) b, "plugin");
- if (p != NULL)
- plugin_remove_watch (p, watcher, b);
-
- p = get_selected_plugin (tree);
- if (p != NULL)
- {
- g_object_set_data ((GObject *) b, "plugin", p);
- watcher (p, b);
- plugin_add_watch (p, watcher, b);
- }
- else
- gtk_widget_set_sensitive (b, FALSE);
-}
-
-static void do_config (void * tree)
-{
- PluginHandle * plugin = get_selected_plugin (tree);
- g_return_if_fail (plugin != NULL);
- plugin_do_configure (plugin);
-}
-
-static void do_about (void * tree)
-{
- PluginHandle * plugin = get_selected_plugin (tree);
- g_return_if_fail (plugin != NULL);
- plugin_do_about (plugin);
-}
-
-static void button_destroy (GtkWidget * b)
-{
- PluginForEachFunc watcher = (PluginForEachFunc) g_object_get_data
- ((GObject *) b, "watcher");
- g_return_if_fail (watcher != NULL);
-
- PluginHandle * p = g_object_steal_data ((GObject *) b, "plugin");
- if (p != NULL)
- plugin_remove_watch (p, watcher, b);
-}
-
-GtkWidget * plugin_view_new (int type)
-{
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_container_set_border_width ((GtkContainer *) vbox, 6);
-
- GtkWidget * scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_box_pack_start ((GtkBox *) vbox, scrolled, TRUE, TRUE, 0);
- gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled,
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled,
- GTK_SHADOW_IN);
-
- GtkWidget * tree = gtk_tree_view_new ();
- gtk_container_add ((GtkContainer *) scrolled, tree);
- gtk_tree_view_set_headers_visible ((GtkTreeView *) tree, FALSE);
- g_signal_connect (tree, "realize", (GCallback) list_fill, GINT_TO_POINTER
- (type));
- g_signal_connect (tree, "destroy", (GCallback) list_destroy, NULL);
-
- GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0);
-
- GtkWidget * config = audgui_button_new (_("_Settings"),
- "preferences-system", do_config, tree);
- gtk_box_pack_start ((GtkBox *) hbox, config, FALSE, FALSE, 0);
- gtk_widget_set_sensitive (config, FALSE);
- g_object_set_data ((GObject *) config, "watcher", (void *) config_watcher);
- g_signal_connect (tree, "cursor-changed", (GCallback) button_update, config);
- g_signal_connect (config, "destroy", (GCallback) button_destroy, NULL);
-
- GtkWidget * about = audgui_button_new (_("_About"), "help-about", do_about, tree);
- gtk_box_pack_start ((GtkBox *) hbox, about, FALSE, FALSE, 0);
- gtk_widget_set_sensitive (about, FALSE);
- g_object_set_data ((GObject *) about, "watcher", (void *) about_watcher);
- g_signal_connect (tree, "cursor-changed", (GCallback) button_update, about);
- g_signal_connect (about, "destroy", (GCallback) button_destroy, NULL);
-
- return vbox;
-}
diff --git a/src/audacious/plugin.h b/src/audacious/plugin.h
deleted file mode 100644
index 49f5f27..0000000
--- a/src/audacious/plugin.h
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * plugin.h
- * Copyright 2005-2013 William Pitcock, Yoshiki Yazawa, Eugene Zagidullin, 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.
- */
-
-#ifndef AUDACIOUS_PLUGIN_H
-#define AUDACIOUS_PLUGIN_H
-
-#include <audacious/api.h>
-#include <audacious/types.h>
-#include <libaudcore/audio.h>
-#include <libaudcore/index.h>
-#include <libaudcore/tuple.h>
-#include <libaudcore/vfs.h>
-
-/* "Magic" bytes identifying an Audacious plugin header. */
-#define _AUD_PLUGIN_MAGIC 0x8EAC8DE2
-
-/* A NOTE ON THREADS
- *
- * How thread-safe a plugin must be depends on the type of plugin. Note that
- * some parts of the Audacious API are *not* thread-safe and therefore cannot be
- * used in some parts of some plugins; for example, input plugins cannot use
- * GUI-related calls or access the playlist except in about() and configure().
- *
- * Thread-safe plugins: transport, playlist, input, effect, and output. These
- * must be mostly thread-safe. init() and cleanup() may be called from
- * secondary threads; however, no other functions provided by the plugin will be
- * called at the same time. about() and configure() will be called only from
- * the main thread. All other functions provided by the plugin may be called
- * from any thread and from multiple threads simultaneously.
- *
- * Exceptions:
- * - Because many existing input plugins are not coded to handle simultaneous
- * calls to play(), play() will only be called from one thread at a time. New
- * plugins should not rely on this exception, though.
- * - Some combinations of calls, especially for output and effect plugins, make
- * no sense; for example, flush() in an output plugin will only be called
- * after open_audio() and before close_audio().
- *
- * Single-thread plugins: visualization, general, and interface. Functions
- * provided by these plugins will only be called from the main thread. */
-
-/* CROSS-PLUGIN MESSAGES
- *
- * Since 3.2, Audacious implements a basic messaging system between plugins.
- * Messages are sent using aud_plugin_send_message() and received through the
- * take_message() method specified in the header of the receiving plugin.
- * Plugins that do not need to receive messages can set take_message() to NULL.
- *
- * Each message includes a code indicating the type of message, a pointer to
- * some data, and a value indicating the size of that data. What the message
- * data contains is entirely up to the two plugins involved. For this reason, it
- * is crucial that both plugins agree on the meaning of the message codes used.
- *
- * Once the message is sent, an integer error code is returned. If the receiving
- * plugin does not provide the take_message() method, ENOSYS is returned. If
- * take_message() does not recognize the message code, it should ignore the
- * message and return EINVAL. An error code of zero represents success. Other
- * error codes may be used with more specific meanings.
- *
- * For the time being, aud_plugin_send_message() should only be called from the
- * program's main thread. */
-
-#define PLUGIN_COMMON_FIELDS \
- int magic; /* checked against _AUD_PLUGIN_MAGIC */ \
- int version; /* checked against _AUD_PLUGIN_VERSION */ \
- int type; /* PLUGIN_TYPE_XXX */ \
- int size; /* size in bytes of the struct */ \
- const char * name; \
- const char * domain; /* for gettext */ \
- const char * about_text; \
- const PluginPreferences * prefs; \
- bool_t (* init) (void); \
- void (* cleanup) (void); \
- int (* take_message) (const char * code, const void * data, int size); \
- void (* about) (void); /* use about_text instead if possible */ \
- void (* configure) (void); /* use prefs instead if possible */ \
- void * reserved1; \
- void * reserved2; \
- void * reserved3; \
- void * reserved4;
-
-struct _Plugin
-{
- PLUGIN_COMMON_FIELDS
-};
-
-struct _TransportPlugin
-{
- PLUGIN_COMMON_FIELDS
-
- /* supported URI schemes (without "://")
- * (array terminated with null pointer) */
- const char * const * schemes;
-
- /* file operation implementations
- * (struct of function pointers, may contain null pointers) */
- const VFSConstructor * vtable;
-};
-
-struct _PlaylistPlugin
-{
- PLUGIN_COMMON_FIELDS
-
- /* supported file extensions (without periods)
- * (array terminated with null pointer) */
- const char * const * extensions;
-
- /* path: URI of playlist file (in)
- * file: VFS handle of playlist file (in, read-only file, not seekable)
- * title: title of playlist (out, string-pooled)
- * filenames: container to fill with URIs read from playlist file
- * (in-out, list of (char *), string-pooled)
- * tuples: container to fill with metadata read from playlist
- * (in-out, list of (Tuple *), may contain null pointers) */
- bool_t (* load) (const char * path, VFSFile * file, char * * title,
- Index * filenames, Index * tuples);
-
- /* path: URI of playlist file (in)
- * file: VFS handle of playlist file (in, write-only file, not seekable)
- * title: title of playlist (in)
- * filenames: container filled with URIs to be written to playlist
- * (in, list of (char *))
- * tuples: container filled with metadata to be written to playlist
- * (in, list of (Tuple *), may contain null pointers) */
- bool_t (* save) (const char * path, VFSFile * file, const char * title,
- Index * filenames, Index * tuples);
-};
-
-struct _OutputPlugin
-{
- PLUGIN_COMMON_FIELDS
-
- /* During probing, plugins with higher priority (10 to 0) are tried first. */
- int probe_priority;
-
- /* Returns current volume for left and right channels (0 to 100). */
- void (* get_volume) (int * l, int * r);
-
- /* Changes volume for left and right channels (0 to 100). */
- void (* set_volume) (int l, int r);
-
- /* Begins playback of a PCM stream. <format> is one of the FMT_*
- * enumeration values defined in libaudcore/audio.h. Returns nonzero on
- * success. */
- bool_t (* open_audio) (int format, int rate, int chans);
-
- /* Ends playback. Any buffered audio data is discarded. */
- void (* close_audio) (void);
-
- /* Returns how many bytes of data may be passed to a following write_audio()
- * call. NULL if the plugin supports only blocking writes (not recommended). */
- int (* buffer_free) (void);
-
- /* Waits until buffer_free() will return a size greater than zero.
- * output_time(), pause(), and flush() may be called meanwhile; if flush()
- * is called, period_wait() should return immediately. NULL if the plugin
- * supports only blocking writes (not recommended). */
- void (* period_wait) (void);
-
- /* Buffers <size> bytes of data, in the format given to open_audio(). */
- void (* write_audio) (void * data, int size);
-
- /* Waits until all buffered data has been heard by the user. */
- void (* drain) (void);
-
- /* Returns time count (in milliseconds) of how much data has been heard by
- * the user. */
- int (* output_time) (void);
-
- /* Pauses the stream if <p> is nonzero; otherwise unpauses it.
- * write_audio() will not be called while the stream is paused. */
- void (* pause) (bool_t p);
-
- /* Discards any buffered audio data and sets the time counter (in
- * milliseconds) of data written. */
- void (* flush) (int time);
-
- /* Whether close_audio() and open_audio() must always be called between
- * songs, even if the audio format is the same. Note that this defeats
- * gapless playback. */
- bool_t force_reopen;
-};
-
-struct _EffectPlugin
-{
- PLUGIN_COMMON_FIELDS
-
- /* All processing is done in floating point. If the effect plugin wants to
- * change the channel count or sample rate, it can change the parameters
- * passed to start(). They cannot be changed in the middle of a song. */
- void (* start) (int * channels, int * rate);
-
- /* process() has two options: modify the samples in place and leave the data
- * pointer unchanged or copy them into a buffer of its own. If it sets the
- * pointer to dynamically allocated memory, it is the plugin's job to free
- * that memory. process() may return different lengths of audio than it is
- * passed, even a zero length. */
- void (* process) (float * * data, int * samples);
-
- /* Optional. A seek is taking place; any buffers should be discarded. */
- void (* flush) (void);
-
- /* Exactly like process() except that any buffers should be drained (i.e.
- * the data processed and returned). finish() will be called a second time
- * at the end of the last song in the playlist. */
- void (* finish) (float * * data, int * samples);
-
- /* Required only for plugins that change the time domain (e.g. a time
- * stretch) or use read-ahead buffering. translate_delay() must do two
- * things: first, translate <delay> (which is in milliseconds) from the
- * output time domain back to the input time domain; second, increase
- * <delay> by the size of the read-ahead buffer. It should return the
- * adjusted delay. */
- int (* adjust_delay) (int delay);
-
- /* Effects with lowest order (0 to 9) are applied first. */
- int order;
-
- /* If the effect does not change the number of channels or the sampling
- * rate, it can be enabled and disabled more smoothly. */
- bool_t preserves_format;
-};
-
-struct _InputPlugin
-{
- PLUGIN_COMMON_FIELDS
-
- /* Nonzero if the files handled by the plugin may contain more than one
- * song. When reading the tuple for such a file, the plugin should set the
- * FIELD_SUBSONG_NUM field to the number of songs in the file. For all
- * other files, the field should be left unset.
- *
- * Example:
- * 1. User adds a file named "somefile.xxx" to the playlist. Having
- * determined that this plugin can handle the file, Audacious opens the file
- * and calls probe_for_tuple(). probe_for_tuple() sees that there are 3
- * songs in the file and sets FIELD_SUBSONG_NUM to 3.
- * 2. For each song in the file, Audacious opens the file and calls
- * probe_for_tuple() -- this time, however, a question mark and song number
- * are appended to the file name passed: "somefile.sid?2" refers to the
- * second song in the file "somefile.sid".
- * 3. When one of the songs is played, Audacious opens the file and calls
- * play() with a file name modified in this way.
- */
- bool_t have_subtune;
-
- /* Pointer to an array (terminated with NULL) of file extensions associated
- * with file types the plugin can handle. */
- const char * const * extensions;
- /* Pointer to an array (terminated with NULL) of MIME types the plugin can
- * handle. */
- const char * const * mimes;
-
- /* Pointer to an array (terminated with NULL) of custom URI schemes the
- * plugin supports. Plugins using custom URI schemes are expected to
- * handle their own I/O. Hence, any VFSFile pointers passed to play(),
- * probe_for_tuple(), etc. will be NULL. */
- const char * const * schemes;
-
- /* How quickly the plugin should be tried in searching for a plugin to
- * handle a file which could not be identified from its extension. Plugins
- * with priority 0 are tried first, 10 last. */
- int priority;
-
- /* Returns TRUE if the plugin can handle the file. */
- bool_t (* is_our_file_from_vfs) (const char * filename, VFSFile * file);
-
- /* Reads metadata from the file, returning a reference to the tuple produced. */
- Tuple * (* probe_for_tuple) (const char * filename, VFSFile * file);
-
- /* Plays the file. Returns FALSE on error. Also see input-api.h. */
- bool_t (* play) (const char * filename, VFSFile * file);
-
- /* Optional. Writes metadata to the file, returning FALSE on error. */
- bool_t (* update_song_tuple) (const char * filename, VFSFile * file, const Tuple * tuple);
-
- /* Optional. Reads an album art image (JPEG or PNG data) from the file.
- * Returns a pointer to the data along with its size in bytes. The returned
- * data will be freed when no longer needed. Returns FALSE on error. */
- bool_t (* get_song_image) (const char * filename, VFSFile * file,
- void * * data, int64_t * size);
-
- /* Optional. Displays a window showing info about the file. In general,
- * this function should be avoided since Audacious already provides a file
- * info window. */
- void (* file_info_box) (const char * filename);
-};
-
-struct _GeneralPlugin
-{
- PLUGIN_COMMON_FIELDS
-
- bool_t enabled_by_default;
-
- /* GtkWidget * (* get_widget) (void); */
- void * (* get_widget) (void);
-};
-
-struct _VisPlugin
-{
- PLUGIN_COMMON_FIELDS
-
- /* reset internal state and clear display */
- void (* clear) (void);
-
- /* 512 frames of a single-channel PCM signal */
- void (* render_mono_pcm) (const float * pcm);
-
- /* 512 frames of an interleaved multi-channel PCM signal */
- void (* render_multi_pcm) (const float * pcm, int channels);
-
- /* intensity of frequencies 1/512, 2/512, ..., 256/512 of sample rate */
- void (* render_freq) (const float * freq);
-
- /* GtkWidget * (* get_widget) (void); */
- void * (* get_widget) (void);
-};
-
-struct _IfacePlugin
-{
- PLUGIN_COMMON_FIELDS
-
- void (* show) (bool_t show);
-
- void (* run_gtk_plugin) (void /* GtkWidget */ * widget, const char * name);
- void (* stop_gtk_plugin) (void /* GtkWidget */ * widget);
-};
-
-#undef PLUGIN_COMMON_FIELDS
-
-#define AUD_PLUGIN(stype, itype, ...) \
-AudAPITable * _aud_api_table = NULL; \
-stype _aud_plugin_self = { \
- .magic = _AUD_PLUGIN_MAGIC, \
- .version = _AUD_PLUGIN_VERSION, \
- .type = itype, \
- .size = sizeof (stype), \
- __VA_ARGS__}; \
-stype * get_plugin_info (AudAPITable * table) { \
- _aud_api_table = table; \
- return & _aud_plugin_self; \
-}
-
-#define AUD_TRANSPORT_PLUGIN(...) AUD_PLUGIN (TransportPlugin, PLUGIN_TYPE_TRANSPORT, __VA_ARGS__)
-#define AUD_PLAYLIST_PLUGIN(...) AUD_PLUGIN (PlaylistPlugin, PLUGIN_TYPE_PLAYLIST, __VA_ARGS__)
-#define AUD_INPUT_PLUGIN(...) AUD_PLUGIN (InputPlugin, PLUGIN_TYPE_INPUT, __VA_ARGS__)
-#define AUD_EFFECT_PLUGIN(...) AUD_PLUGIN (EffectPlugin, PLUGIN_TYPE_EFFECT, __VA_ARGS__)
-#define AUD_OUTPUT_PLUGIN(...) AUD_PLUGIN (OutputPlugin, PLUGIN_TYPE_OUTPUT, __VA_ARGS__)
-#define AUD_VIS_PLUGIN(...) AUD_PLUGIN (VisPlugin, PLUGIN_TYPE_VIS, __VA_ARGS__)
-#define AUD_GENERAL_PLUGIN(...) AUD_PLUGIN (GeneralPlugin, PLUGIN_TYPE_GENERAL, __VA_ARGS__)
-#define AUD_IFACE_PLUGIN(...) AUD_PLUGIN (IfacePlugin, PLUGIN_TYPE_IFACE, __VA_ARGS__)
-
-#define PLUGIN_HAS_FUNC(p, func) \
- ((p)->size > (char *) & (p)->func - (char *) (p) && (p)->func)
-
-#endif /* AUDACIOUS_PLUGIN_H */
diff --git a/src/audacious/pluginenum.c b/src/audacious/pluginenum.c
deleted file mode 100644
index 58216a5..0000000
--- a/src/audacious/pluginenum.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * pluginenum.c
- * Copyright 2007-2013 William Pitcock 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 <assert.h>
-#include <errno.h>
-#include <pthread.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <gmodule.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudgui/init.h>
-
-#include "debug.h"
-#include "plugin.h"
-#include "util.h"
-
-#define AUD_API_DECLARE
-#include "drct.h"
-#include "input.h"
-#include "misc.h"
-#include "playlist.h"
-#include "plugins.h"
-#undef AUD_API_DECLARE
-
-static const char * plugin_dir_list[] = {
- "Transport",
- "Container",
- "Input",
- "Output",
- "Effect",
- "General",
- "Visualization"
-};
-
-char verbose = 0;
-
-AudAPITable api_table = {
- .drct_api = & drct_api,
- .input_api = & input_api,
- .misc_api = & misc_api,
- .playlist_api = & playlist_api,
- .plugins_api = & plugins_api,
- .verbose = & verbose};
-
-typedef struct {
- Plugin * header;
- GModule * module;
-} LoadedModule;
-
-static GList * loaded_modules = NULL;
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-Plugin * plugin_load (const char * filename)
-{
- AUDDBG ("Loading plugin: %s.\n", filename);
-
- GModule * module = g_module_open (filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
- if (! module)
- {
- fprintf (stderr, " *** ERROR: %s could not be loaded: %s\n", filename,
- g_module_error ());
- return NULL;
- }
-
- void * ptr;
- if (! g_module_symbol (module, "get_plugin_info", & ptr))
- ptr = NULL;
-
- Plugin * (* func) (AudAPITable * table) = ptr;
- Plugin * header;
-
- if (! func || ! (header = func (& api_table)) || header->magic != _AUD_PLUGIN_MAGIC)
- {
- fprintf (stderr, " *** ERROR: %s is not a valid Audacious plugin.\n", filename);
- g_module_close (module);
- return NULL;
- }
-
- if (header->version < _AUD_PLUGIN_VERSION_MIN ||
- header->version > _AUD_PLUGIN_VERSION)
- {
- fprintf (stderr, " *** ERROR: %s is not compatible with this version "
- "of Audacious.\n", filename);
- g_module_close (module);
- return NULL;
- }
-
- if (header->type == PLUGIN_TYPE_TRANSPORT ||
- header->type == PLUGIN_TYPE_PLAYLIST ||
- header->type == PLUGIN_TYPE_INPUT ||
- header->type == PLUGIN_TYPE_EFFECT)
- {
- if (PLUGIN_HAS_FUNC (header, init) && ! header->init ())
- {
- fprintf (stderr, " *** ERROR: %s failed to initialize.\n", filename);
- g_module_close (module);
- return NULL;
- }
- }
-
- pthread_mutex_lock (& mutex);
- LoadedModule * loaded = g_slice_new (LoadedModule);
- loaded->header = header;
- loaded->module = module;
- loaded_modules = g_list_prepend (loaded_modules, loaded);
- pthread_mutex_unlock (& mutex);
-
- return header;
-}
-
-static void plugin2_unload (LoadedModule * loaded)
-{
- Plugin * header = loaded->header;
-
- switch (header->type)
- {
- case PLUGIN_TYPE_TRANSPORT:
- case PLUGIN_TYPE_PLAYLIST:
- case PLUGIN_TYPE_INPUT:
- case PLUGIN_TYPE_EFFECT:
- if (PLUGIN_HAS_FUNC (header, cleanup))
- header->cleanup ();
- break;
- }
-
- pthread_mutex_lock (& mutex);
-#ifndef VALGRIND_FRIENDLY
- g_module_close (loaded->module);
-#endif
- g_slice_free (LoadedModule, loaded);
- pthread_mutex_unlock (& mutex);
-}
-
-/******************************************************************/
-
-static bool_t scan_plugin_func(const char * path, const char * basename, void * data)
-{
- if (!str_has_suffix_nocase(basename, PLUGIN_SUFFIX))
- return FALSE;
-
- GStatBuf st;
- if (g_stat (path, & st) < 0)
- {
- fprintf (stderr, "Unable to stat %s: %s\n", path, strerror (errno));
- return FALSE;
- }
-
- if (S_ISREG (st.st_mode))
- plugin_register (path, st.st_mtime);
-
- return FALSE;
-}
-
-static void scan_plugins(const char * path)
-{
- dir_foreach (path, scan_plugin_func, NULL);
-}
-
-void plugin_system_init(void)
-{
- assert (g_module_supported ());
-
- audgui_init (& api_table, _AUD_PLUGIN_VERSION);
-
- plugin_registry_load ();
-
- const char * path = get_path (AUD_PATH_PLUGIN_DIR);
-
- for (int i = 0; i < ARRAY_LEN (plugin_dir_list); i ++)
- {
- char * dir = filename_build (path, plugin_dir_list[i]);
- scan_plugins (dir);
- str_unref (dir);
- }
-
- plugin_registry_prune ();
-}
-
-void plugin_system_cleanup(void)
-{
- plugin_registry_save ();
-
- for (GList * node = loaded_modules; node != NULL; node = node->next)
- plugin2_unload (node->data);
-
- g_list_free (loaded_modules);
- loaded_modules = NULL;
-
- audgui_cleanup ();
-}
diff --git a/src/audacious/plugins-api.h b/src/audacious/plugins-api.h
deleted file mode 100644
index af4c1b2..0000000
--- a/src/audacious/plugins-api.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * plugins-api.h
- * Copyright 2010-2012 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.
- */
-
-/* Do not include this file directly; use misc.h instead. */
-
-/* CAUTION: These functions are not thread safe. */
-
-/* plugin-init.c */
-AUD_FUNC1 (PluginHandle *, plugin_get_current, int, type)
-AUD_FUNC2 (bool_t, plugin_enable, PluginHandle *, plugin, bool_t, enable)
-AUD_FUNC1 (PluginHandle *, plugin_by_widget, void /* GtkWidget */ *, widget)
-AUD_FUNC4 (int, plugin_send_message, PluginHandle *, plugin,
- const char *, code, const void *, data, int, size)
-
-/* plugin-registry.c */
-AUD_FUNC1 (int, plugin_get_type, PluginHandle *, plugin)
-AUD_FUNC1 (const char *, plugin_get_filename, PluginHandle *, plugin)
-AUD_FUNC1 (PluginHandle *, plugin_lookup, const char *, filename)
-AUD_FUNC1 (PluginHandle *, plugin_lookup_basename, const char *, basename)
-
-AUD_FUNC1 (const void *, plugin_get_header, PluginHandle *, plugin)
-AUD_FUNC1 (PluginHandle *, plugin_by_header, const void *, header)
-
-AUD_FUNC1 (int, plugin_count, int, type)
-AUD_FUNC1 (int, plugin_get_index, PluginHandle *, plugin)
-AUD_FUNC2 (PluginHandle *, plugin_by_index, int, type, int, index)
-
-AUD_FUNC2 (int, plugin_compare, PluginHandle *, a, PluginHandle *, b)
-AUD_VFUNC3 (plugin_for_each, int, type, PluginForEachFunc, func, void *, data)
-
-AUD_FUNC1 (bool_t, plugin_get_enabled, PluginHandle *, plugin)
-AUD_VFUNC3 (plugin_for_enabled, int, type, PluginForEachFunc, func,
- void *, data)
-
-AUD_FUNC1 (const char *, plugin_get_name, PluginHandle *, plugin)
-AUD_FUNC1 (bool_t, plugin_has_about, PluginHandle *, plugin)
-AUD_FUNC1 (bool_t, plugin_has_configure, PluginHandle *, plugin)
-AUD_VFUNC1 (plugin_do_about, PluginHandle *, plugin)
-AUD_VFUNC1 (plugin_do_configure, PluginHandle *, plugin)
-
-AUD_VFUNC3 (plugin_add_watch, PluginHandle *, plugin, PluginForEachFunc,
- func, void *, data)
-AUD_VFUNC3 (plugin_remove_watch, PluginHandle *, plugin, PluginForEachFunc,
- func, void *, data)
diff --git a/src/audacious/plugins.h b/src/audacious/plugins.h
deleted file mode 100644
index ea956ee..0000000
--- a/src/audacious/plugins.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * plugins.h
- * Copyright 2010-2013 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.
- */
-
-#ifndef AUDACIOUS_PLUGINS_H
-#define AUDACIOUS_PLUGINS_H
-
-#include <audacious/api.h>
-#include <audacious/types.h>
-#include <libaudcore/core.h>
-
-/* returns TRUE to call again for the next plugin, FALSE to stop */
-typedef bool_t (* PluginForEachFunc) (PluginHandle * plugin, void * data);
-
-#define AUD_API_NAME PluginsAPI
-#define AUD_API_SYMBOL plugins_api
-
-#ifdef _AUDACIOUS_CORE
-
-#include "api-local-begin.h"
-#include "plugins-api.h"
-#include "api-local-end.h"
-
-enum {
- INPUT_KEY_SCHEME,
- INPUT_KEY_EXTENSION,
- INPUT_KEY_MIME,
- INPUT_KEYS};
-
-/* plugin-init.c */
-void start_plugins_one (void);
-void start_plugins_two (void);
-void stop_plugins_two (void);
-void stop_plugins_one (void);
-
-/* plugin-registry.c */
-void plugin_registry_load (void);
-void plugin_registry_prune (void);
-void plugin_registry_save (void);
-
-void plugin_register (const char * path, int timestamp);
-
-void plugin_set_enabled (PluginHandle * plugin, bool_t enabled);
-void * plugin_get_misc_data (PluginHandle * plugin, int size);
-
-PluginHandle * transport_plugin_for_scheme (const char * scheme);
-void playlist_plugin_for_ext (const char * ext, PluginForEachFunc func, void * data);
-void input_plugin_for_key (int key, const char * value, PluginForEachFunc func, void * data);
-bool_t input_plugin_has_images (PluginHandle * plugin);
-bool_t input_plugin_has_subtunes (PluginHandle * plugin);
-bool_t input_plugin_can_write_tuple (PluginHandle * plugin);
-bool_t input_plugin_has_infowin (PluginHandle * plugin);
-
-/* pluginenum.c */
-void plugin_system_init (void);
-void plugin_system_cleanup (void);
-Plugin * plugin_load (const char * path);
-
-#else
-
-#include <audacious/api-define-begin.h>
-#include <audacious/plugins-api.h>
-#include <audacious/api-define-end.h>
-
-#include <audacious/api-alias-begin.h>
-#include <audacious/plugins-api.h>
-#include <audacious/api-alias-end.h>
-
-#endif
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
-
-#ifdef AUD_API_DECLARE
-
-#define AUD_API_NAME PluginsAPI
-#define AUD_API_SYMBOL plugins_api
-
-#include "api-define-begin.h"
-#include "plugins-api.h"
-#include "api-define-end.h"
-
-#include "api-declare-begin.h"
-#include "plugins-api.h"
-#include "api-declare-end.h"
-
-#undef AUD_API_NAME
-#undef AUD_API_SYMBOL
-
-#endif
diff --git a/src/audacious/preferences.c b/src/audacious/preferences.c
deleted file mode 100644
index eb1b651..0000000
--- a/src/audacious/preferences.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * preferences.c
- * Copyright 2007-2012 Tomasz Moń, William Pitcock, 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 "preferences.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-
-#include "i18n.h"
-#include "misc.h"
-
-/* HELPERS */
-
-static bool_t widget_get_bool (const PreferencesWidget * widget)
-{
- g_return_val_if_fail (widget->cfg_type == VALUE_BOOLEAN, FALSE);
-
- if (widget->cfg)
- return * (bool_t *) widget->cfg;
- else if (widget->cname)
- return get_bool (widget->csect, widget->cname);
- else
- return FALSE;
-}
-
-static void widget_set_bool (const PreferencesWidget * widget, bool_t value)
-{
- g_return_if_fail (widget->cfg_type == VALUE_BOOLEAN);
-
- if (widget->cfg)
- * (bool_t *) widget->cfg = value;
- else if (widget->cname)
- set_bool (widget->csect, widget->cname, value);
-
- if (widget->callback)
- widget->callback ();
-}
-
-static int widget_get_int (const PreferencesWidget * widget)
-{
- g_return_val_if_fail (widget->cfg_type == VALUE_INT, 0);
-
- if (widget->cfg)
- return * (int *) widget->cfg;
- else if (widget->cname)
- return get_int (widget->csect, widget->cname);
- else
- return 0;
-}
-
-static void widget_set_int (const PreferencesWidget * widget, int value)
-{
- g_return_if_fail (widget->cfg_type == VALUE_INT);
-
- if (widget->cfg)
- * (int *) widget->cfg = value;
- else if (widget->cname)
- set_int (widget->csect, widget->cname, value);
-
- if (widget->callback)
- widget->callback ();
-}
-
-static double widget_get_double (const PreferencesWidget * widget)
-{
- g_return_val_if_fail (widget->cfg_type == VALUE_FLOAT, 0);
-
- if (widget->cfg)
- return * (float *) widget->cfg;
- else if (widget->cname)
- return get_double (widget->csect, widget->cname);
- else
- return 0;
-}
-
-static void widget_set_double (const PreferencesWidget * widget, double value)
-{
- g_return_if_fail (widget->cfg_type == VALUE_FLOAT);
-
- if (widget->cfg)
- * (float *) widget->cfg = value;
- else if (widget->cname)
- set_double (widget->csect, widget->cname, value);
-
- if (widget->callback)
- widget->callback ();
-}
-
-static char * widget_get_string (const PreferencesWidget * widget)
-{
- g_return_val_if_fail (widget->cfg_type == VALUE_STRING, NULL);
-
- if (widget->cfg)
- return str_get (* (char * *) widget->cfg);
- else if (widget->cname)
- return get_str (widget->csect, widget->cname);
- else
- return NULL;
-}
-
-static void widget_set_string (const PreferencesWidget * widget, const char * value)
-{
- g_return_if_fail (widget->cfg_type == VALUE_STRING);
-
- if (widget->cfg)
- {
- g_free (* (char * *) widget->cfg);
- * (char * *) widget->cfg = g_strdup (value);
- }
- else if (widget->cname)
- set_str (widget->csect, widget->cname, value);
-
- if (widget->callback)
- widget->callback ();
-}
-
-/* WIDGET_CHK_BTN */
-
-static void on_toggle_button_toggled (GtkToggleButton * button, const PreferencesWidget * widget)
-{
- bool_t active = gtk_toggle_button_get_active (button);
- widget_set_bool (widget, active);
-
- GtkWidget * child = g_object_get_data ((GObject *) button, "child");
- if (child)
- gtk_widget_set_sensitive (child, active);
-}
-
-static void init_toggle_button (GtkWidget * button, const PreferencesWidget * widget)
-{
- if (widget->cfg_type != VALUE_BOOLEAN)
- return;
-
- gtk_toggle_button_set_active ((GtkToggleButton *) button, widget_get_bool (widget));
- g_signal_connect (button, "toggled", (GCallback) on_toggle_button_toggled, (void *) widget);
-}
-
-/* WIDGET_LABEL */
-
-static void create_label (const PreferencesWidget * widget, GtkWidget * * label,
- GtkWidget * * icon, const char * domain)
-{
- if (widget->data.label.stock_id)
- * icon = gtk_image_new_from_icon_name (widget->data.label.stock_id, GTK_ICON_SIZE_BUTTON);
-
- * label = gtk_label_new_with_mnemonic (dgettext (domain, widget->label));
- gtk_label_set_use_markup ((GtkLabel *) * label, TRUE);
-
- if (widget->data.label.single_line == FALSE)
- gtk_label_set_line_wrap ((GtkLabel *) * label, TRUE);
-
- gtk_misc_set_alignment ((GtkMisc *) * label, 0, 0.5);
-}
-
-/* WIDGET_RADIO_BTN */
-
-static void on_radio_button_toggled (GtkWidget * button, const PreferencesWidget * widget)
-{
- if (gtk_toggle_button_get_active ((GtkToggleButton *) button))
- widget_set_int (widget, widget->data.radio_btn.value);
-}
-
-static void init_radio_button (GtkWidget * button, const PreferencesWidget * widget)
-{
- if (widget->cfg_type != VALUE_INT)
- return;
-
- if (widget_get_int (widget) == widget->data.radio_btn.value)
- gtk_toggle_button_set_active ((GtkToggleButton *) button, TRUE);
-
- g_signal_connect (button, "toggled", (GCallback) on_radio_button_toggled, (void *) widget);
-}
-
-/* WIDGET_SPIN_BTN */
-
-static void on_spin_btn_changed_int (GtkSpinButton * button, const PreferencesWidget * widget)
-{
- widget_set_int (widget, gtk_spin_button_get_value_as_int (button));
-}
-
-static void on_spin_btn_changed_float (GtkSpinButton * button, const PreferencesWidget * widget)
-{
- widget_set_double (widget, gtk_spin_button_get_value (button));
-}
-
-static void create_spin_button (const PreferencesWidget * widget,
- GtkWidget * * label_pre, GtkWidget * * spin_btn, GtkWidget * * label_past,
- const char * domain)
-{
- * label_pre = gtk_label_new (dgettext (domain, widget->label));
- * spin_btn = gtk_spin_button_new_with_range (widget->data.spin_btn.min,
- widget->data.spin_btn.max, widget->data.spin_btn.step);
-
- if (widget->tooltip)
- gtk_widget_set_tooltip_text (* spin_btn, dgettext (domain, widget->tooltip));
-
- if (widget->data.spin_btn.right_label)
- * label_past = gtk_label_new (dgettext (domain, widget->data.spin_btn.right_label));
-
- switch (widget->cfg_type)
- {
- case VALUE_INT:
- gtk_spin_button_set_value ((GtkSpinButton *) * spin_btn, widget_get_int (widget));
- g_signal_connect (* spin_btn, "value_changed", (GCallback)
- on_spin_btn_changed_int, (void *) widget);
- break;
-
- case VALUE_FLOAT:
- gtk_spin_button_set_value ((GtkSpinButton *) * spin_btn, widget_get_double (widget));
- g_signal_connect (* spin_btn, "value_changed", (GCallback)
- on_spin_btn_changed_float, (void *) widget);
- break;
-
- default:
- break;
- }
-}
-
-/* WIDGET_FONT_BTN */
-
-static void on_font_btn_font_set (GtkFontButton * button, const PreferencesWidget * widget)
-{
- widget_set_string (widget, gtk_font_button_get_font_name (button));
-}
-
-void create_font_btn (const PreferencesWidget * widget, GtkWidget * * label,
- GtkWidget * * font_btn, const char * domain)
-{
- * font_btn = gtk_font_button_new ();
- gtk_font_button_set_use_font ((GtkFontButton *) * font_btn, TRUE);
- gtk_font_button_set_use_size ((GtkFontButton *) * font_btn, TRUE);
- gtk_widget_set_hexpand (* font_btn, TRUE);
-
- if (widget->label)
- {
- * label = gtk_label_new_with_mnemonic (dgettext (domain, widget->label));
- gtk_label_set_use_markup ((GtkLabel *) * label, TRUE);
- gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5);
- gtk_label_set_justify ((GtkLabel *) * label, GTK_JUSTIFY_RIGHT);
- gtk_label_set_mnemonic_widget ((GtkLabel *) * label, * font_btn);
- }
-
- if (widget->data.font_btn.title)
- gtk_font_button_set_title ((GtkFontButton *) * font_btn,
- dgettext (domain, widget->data.font_btn.title));
-
- char * name = widget_get_string (widget);
- if (name)
- {
- gtk_font_button_set_font_name ((GtkFontButton *) * font_btn, name);
- str_unref (name);
- }
-
- g_signal_connect (* font_btn, "font_set", (GCallback) on_font_btn_font_set, (void *) widget);
-}
-
-/* WIDGET_ENTRY */
-
-static void on_entry_changed (GtkEntry * entry, const PreferencesWidget * widget)
-{
- widget_set_string (widget, gtk_entry_get_text (entry));
-}
-
-static void create_entry (const PreferencesWidget * widget, GtkWidget * * label,
- GtkWidget * * entry, const char * domain)
-{
- * entry = gtk_entry_new ();
- gtk_entry_set_visibility ((GtkEntry *) * entry, ! widget->data.entry.password);
- gtk_widget_set_hexpand (* entry, TRUE);
-
- if (widget->label)
- * label = gtk_label_new (dgettext (domain, widget->label));
-
- if (widget->tooltip)
- gtk_widget_set_tooltip_text (* entry, dgettext (domain, widget->tooltip));
-
- if (widget->cfg_type == VALUE_STRING)
- {
- char * value = widget_get_string (widget);
- if (value)
- {
- gtk_entry_set_text ((GtkEntry *) * entry, value);
- str_unref (value);
- }
-
- g_signal_connect (* entry, "changed", (GCallback) on_entry_changed, (void *) widget);
- }
-}
-
-/* WIDGET_COMBO_BOX */
-
-static void on_cbox_changed_int (GtkComboBox * combobox, const PreferencesWidget * widget)
-{
- int position = gtk_combo_box_get_active (combobox);
- const ComboBoxElements * elements = g_object_get_data ((GObject *) combobox, "comboboxelements");
- widget_set_int (widget, GPOINTER_TO_INT (elements[position].value));
-}
-
-static void on_cbox_changed_string (GtkComboBox * combobox, const PreferencesWidget * widget)
-{
- int position = gtk_combo_box_get_active (combobox);
- const ComboBoxElements * elements = g_object_get_data ((GObject *) combobox, "comboboxelements");
- widget_set_string (widget, elements[position].value);
-}
-
-static void fill_cbox (GtkWidget * combobox, const PreferencesWidget * widget, const char * domain)
-{
- const ComboBoxElements * elements = widget->data.combo.elements;
- int n_elements = widget->data.combo.n_elements;
-
- if (widget->data.combo.fill)
- elements = widget->data.combo.fill (& n_elements);
-
- g_object_set_data ((GObject *) combobox, "comboboxelements", (void *) elements);
-
- for (int i = 0; i < n_elements; i ++)
- gtk_combo_box_text_append_text ((GtkComboBoxText *) combobox,
- dgettext (domain, elements[i].label));
-
- switch (widget->cfg_type)
- {
- case VALUE_INT:;
- int ivalue = widget_get_int (widget);
-
- for (int i = 0; i < n_elements; i++)
- {
- if (GPOINTER_TO_INT (elements[i].value) == ivalue)
- {
- gtk_combo_box_set_active ((GtkComboBox *) combobox, i);
- break;
- }
- }
-
- g_signal_connect (combobox, "changed", (GCallback) on_cbox_changed_int, (void *) widget);
- break;
-
- case VALUE_STRING:;
- char * value = widget_get_string (widget);
-
- for(int i = 0; i < n_elements; i++)
- {
- if (value && ! strcmp (elements[i].value, value))
- {
- gtk_combo_box_set_active ((GtkComboBox *) combobox, i);
- break;
- }
- }
-
- str_unref (value);
-
- g_signal_connect (combobox, "changed", (GCallback) on_cbox_changed_string, (void *) widget);
- break;
-
- default:
- break;
- }
-}
-
-static void create_cbox (const PreferencesWidget * widget, GtkWidget * * label,
- GtkWidget * * combobox, const char * domain)
-{
- * combobox = gtk_combo_box_text_new ();
-
- if (widget->label)
- * label = gtk_label_new (dgettext (domain, widget->label));
-
- fill_cbox (* combobox, widget, domain);
-}
-
-/* WIDGET_TABLE */
-
-static void fill_grid (GtkWidget * grid, const PreferencesWidget * elements,
- int n_elements, const char * domain)
-{
- for (int i = 0; i < n_elements; i ++)
- {
- GtkWidget * widget_left = NULL, * widget_middle = NULL, * widget_right = NULL;
-
- switch (elements[i].type)
- {
- case WIDGET_SPIN_BTN:
- create_spin_button (& elements[i], & widget_left,
- & widget_middle, & widget_right, domain);
- break;
-
- case WIDGET_LABEL:
- create_label (& elements[i], & widget_middle, & widget_left, domain);
- break;
-
- case WIDGET_FONT_BTN:
- create_font_btn (& elements[i], & widget_left, & widget_middle, domain);
- break;
-
- case WIDGET_ENTRY:
- create_entry (& elements[i], & widget_left, & widget_middle, domain);
- break;
-
- case WIDGET_COMBO_BOX:
- create_cbox (& elements[i], & widget_left, & widget_middle, domain);
- break;
-
- default:
- break;
- }
-
- if (widget_left)
- gtk_grid_attach ((GtkGrid *) grid, widget_left, 0, i, 1, 1);
-
- if (widget_middle)
- gtk_grid_attach ((GtkGrid *) grid, widget_middle, 1, i, 1, 1);
-
- if (widget_right)
- gtk_grid_attach ((GtkGrid *) grid, widget_right, 2, i, 1, 1);
- }
-}
-
-/* ALL WIDGETS */
-
-/* box: a GtkBox */
-void create_widgets_with_domain (void * box, const PreferencesWidget * widgets,
- int n_widgets, const char * domain)
-{
- GtkWidget * widget = NULL, * child_box = NULL;
- GSList * radio_btn_group = NULL;
-
- for (int i = 0; i < n_widgets; i ++)
- {
- GtkWidget * label = NULL;
-
- if (widget && widgets[i].child)
- {
- if (! child_box)
- {
- child_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- g_object_set_data ((GObject *) widget, "child", child_box);
-
- GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
- gtk_box_pack_start (box, alignment, FALSE, FALSE, 0);
- gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 12, 0);
- gtk_container_add ((GtkContainer *) alignment, child_box);
-
- if (GTK_IS_TOGGLE_BUTTON (widget))
- gtk_widget_set_sensitive (child_box,
- gtk_toggle_button_get_active ((GtkToggleButton *) widget));
- }
- }
- else
- child_box = NULL;
-
- GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
- gtk_alignment_set_padding ((GtkAlignment *) alignment, 6, 0, 12, 0);
- gtk_box_pack_start (child_box ? (GtkBox *) child_box : box, alignment, FALSE, FALSE, 0);
-
- widget = NULL;
-
- if (radio_btn_group && widgets[i].type != WIDGET_RADIO_BTN)
- radio_btn_group = NULL;
-
- switch (widgets[i].type)
- {
- case WIDGET_CHK_BTN:
- widget = gtk_check_button_new_with_mnemonic (dgettext (domain, widgets[i].label));
- init_toggle_button (widget, & widgets[i]);
- break;
-
- case WIDGET_LABEL:
- if (strstr (widgets[i].label, "<b>"))
- gtk_alignment_set_padding ((GtkAlignment *) alignment,
- (i == 0) ? 0 : 12, 0, 0, 0);
-
- GtkWidget * icon = NULL;
- create_label (& widgets[i], & label, & icon, domain);
-
- if (icon)
- {
- widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start ((GtkBox *) widget, icon, FALSE, FALSE, 0);
- gtk_box_pack_start ((GtkBox *) widget, label, FALSE, FALSE, 0);
- }
- else
- widget = label;
-
- break;
-
- case WIDGET_RADIO_BTN:
- widget = gtk_radio_button_new_with_mnemonic (radio_btn_group,
- dgettext (domain, widgets[i].label));
- radio_btn_group = gtk_radio_button_get_group ((GtkRadioButton *) widget);
- init_radio_button (widget, & widgets[i]);
- break;
-
- case WIDGET_SPIN_BTN:
- widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-
- GtkWidget * label_pre = NULL, * spin_btn = NULL, * label_past = NULL;
- create_spin_button (& widgets[i], & label_pre, & spin_btn, & label_past, domain);
-
- if (label_pre)
- gtk_box_pack_start ((GtkBox *) widget, label_pre, FALSE, FALSE, 0);
- if (spin_btn)
- gtk_box_pack_start ((GtkBox *) widget, spin_btn, FALSE, FALSE, 0);
- if (label_past)
- gtk_box_pack_start ((GtkBox *) widget, label_past, FALSE, FALSE, 0);
-
- break;
-
- case WIDGET_CUSTOM:
- if (widgets[i].data.populate)
- widget = widgets[i].data.populate ();
-
- break;
-
- case WIDGET_FONT_BTN:
- widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-
- GtkWidget * font_btn = NULL;
- create_font_btn (& widgets[i], & label, & font_btn, domain);
-
- if (label)
- gtk_box_pack_start ((GtkBox *) widget, label, FALSE, FALSE, 0);
- if (font_btn)
- gtk_box_pack_start ((GtkBox *) widget, font_btn, FALSE, FALSE, 0);
-
- break;
-
- case WIDGET_TABLE:
- widget = gtk_grid_new ();
- gtk_grid_set_column_spacing ((GtkGrid *) widget, 6);
- gtk_grid_set_row_spacing ((GtkGrid *) widget, 6);
-
- fill_grid (widget, widgets[i].data.table.elem, widgets[i].data.table.rows, domain);
-
- break;
-
- case WIDGET_ENTRY:
- widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-
- GtkWidget * entry = NULL;
- create_entry (& widgets[i], & label, & entry, domain);
-
- if (label)
- gtk_box_pack_start ((GtkBox *) widget, label, FALSE, FALSE, 0);
- if (entry)
- gtk_box_pack_start ((GtkBox *) widget, entry, TRUE, TRUE, 0);
-
- break;
-
- case WIDGET_COMBO_BOX:
- widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-
- GtkWidget * combo = NULL;
- create_cbox (& widgets[i], & label, & combo, domain);
-
- if (label)
- gtk_box_pack_start ((GtkBox *) widget, label, FALSE, FALSE, 0);
- if (combo)
- gtk_box_pack_start ((GtkBox *) widget, combo, FALSE, FALSE, 0);
-
- break;
-
- case WIDGET_BOX:
- if (widgets[i].data.box.horizontal)
- widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- else
- widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-
- create_widgets_with_domain ((GtkBox *) widget,
- widgets[i].data.box.elem, widgets[i].data.box.n_elem, domain);
-
- if (widgets[i].data.box.frame)
- {
- GtkWidget * frame = gtk_frame_new (dgettext (domain, widgets[i].label));
- gtk_container_add ((GtkContainer *) frame, widget);
- widget = frame;
- }
-
- break;
-
- case WIDGET_NOTEBOOK:
- gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 0, 0);
-
- widget = gtk_notebook_new ();
-
- for (int j = 0; j < widgets[i].data.notebook.n_tabs; j ++)
- {
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_set_border_width ((GtkContainer *) vbox, 6);
-
- create_widgets_with_domain ((GtkBox *) vbox,
- widgets[i].data.notebook.tabs[j].widgets,
- widgets[i].data.notebook.tabs[j].n_widgets, domain);
-
- gtk_notebook_append_page ((GtkNotebook *) widget, vbox,
- gtk_label_new (dgettext (domain,
- widgets[i].data.notebook.tabs[j].name)));
- }
-
- break;
-
- case WIDGET_SEPARATOR:
- gtk_alignment_set_padding ((GtkAlignment *) alignment, 6, 6, 0, 0);
-
- widget = gtk_separator_new (widgets[i].data.separator.horizontal
- ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
- break;
-
- default:
- break;
- }
-
- if (widget)
- {
- /* use uniform spacing for horizontal boxes */
- if (gtk_orientable_get_orientation ((GtkOrientable *) box) ==
- GTK_ORIENTATION_HORIZONTAL)
- gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 0, 0);
-
- gtk_container_add ((GtkContainer *) alignment, widget);
-
- if (widgets[i].tooltip && widgets[i].type != WIDGET_SPIN_BTN)
- gtk_widget_set_tooltip_text (widget, dgettext (domain,
- widgets[i].tooltip));
- }
- }
-}
diff --git a/src/audacious/preferences.h b/src/audacious/preferences.h
deleted file mode 100644
index af58567..0000000
--- a/src/audacious/preferences.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * preferences.h
- * Copyright 2007-2012 Tomasz Moń, William Pitcock, 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.
- */
-
-#ifndef AUDACIOUS_PREFERENCES_H
-#define AUDACIOUS_PREFERENCES_H
-
-#include <audacious/types.h>
-
-typedef enum {
- WIDGET_NONE,
- WIDGET_CHK_BTN,
- WIDGET_LABEL,
- WIDGET_RADIO_BTN,
- WIDGET_SPIN_BTN,
- WIDGET_CUSTOM, /* 'custom' widget, you hand back the widget you want to add --nenolod */
- WIDGET_FONT_BTN,
- WIDGET_TABLE,
- WIDGET_ENTRY,
- WIDGET_COMBO_BOX,
- WIDGET_BOX,
- WIDGET_NOTEBOOK,
- WIDGET_SEPARATOR,
-} WidgetType;
-
-typedef enum {
- VALUE_INT,
- VALUE_FLOAT,
- VALUE_BOOLEAN,
- VALUE_STRING,
- VALUE_NULL,
-} ValueType;
-
-typedef struct {
- void * value;
- const char * label;
-} ComboBoxElements;
-
-struct _NotebookTab;
-
-struct _PreferencesWidget {
- WidgetType type; /* widget type */
- const char * label; /* widget title (for SPIN_BTN it's text left to widget) */
- void * cfg; /* connected config value */
- void (* callback) (void); /* this func will be called after value change, can be NULL */
- const char * tooltip; /* widget tooltip, can be NULL */
- bool_t child;
- ValueType cfg_type; /* connected value type */
- const char * csect; /* config file section */
- const char * cname; /* config file key name */
-
- union {
- struct {
- int value;
- } radio_btn;
-
- struct {
- double min, max, step;
- const char * right_label; /* text right to widget */
- } spin_btn;
-
- struct {
- struct _PreferencesWidget *elem;
- int rows;
- } table;
-
- struct {
- const char * stock_id;
- bool_t single_line; /* FALSE to enable line wrap */
- } label;
-
- struct {
- const char * title;
- } font_btn;
-
- struct {
- bool_t password;
- } entry;
-
- struct {
- /* static init */
- const ComboBoxElements * elements;
- int n_elements;
-
- /* runtime init */
- const ComboBoxElements * (* fill) (int * n_elements);
- } combo;
-
- struct {
- const struct _PreferencesWidget * elem;
- int n_elem;
-
- bool_t horizontal; /* FALSE gives vertical, TRUE gives horizontal aligment of child widgets */
- bool_t frame; /* whether to draw frame around box */
- } box;
-
- struct {
- const struct _NotebookTab * tabs;
- int n_tabs;
- } notebook;
-
- struct {
- bool_t horizontal; /* FALSE gives vertical, TRUE gives horizontal separator */
- } separator;
-
- /* for WIDGET_CUSTOM --nenolod */
- /* GtkWidget * (* populate) (void); */
- void * (* populate) (void);
- } data;
-};
-
-typedef struct _NotebookTab {
- const char * name;
- const PreferencesWidget * widgets;
- int n_widgets;
-} NotebookTab;
-
-struct _PluginPreferences {
- const PreferencesWidget * widgets;
- int n_widgets;
-
- void (*init)(void);
- void (*apply)(void);
- void (*cleanup)(void);
-};
-
-#endif /* AUDACIOUS_PREFERENCES_H */
diff --git a/src/audacious/probe-buffer.c b/src/audacious/probe-buffer.c
deleted file mode 100644
index c27995b..0000000
--- a/src/audacious/probe-buffer.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * probe-buffer.c
- * Copyright 2010-2013 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 <string.h>
-
-#include <glib.h>
-
-#include "debug.h"
-#include "probe-buffer.h"
-
-#define BUFSIZE (256 * 1024)
-
-typedef struct
-{
- VFSFile * file;
- int filled, at;
- unsigned char buffer[BUFSIZE];
-}
-ProbeBuffer;
-
-static int probe_buffer_fclose (VFSFile * file)
-{
- ProbeBuffer * p = vfs_get_handle (file);
-
- int ret = vfs_fclose (p->file);
- g_free (p);
- return ret;
-}
-
-static void increase_buffer (ProbeBuffer * p, int64_t size)
-{
- size = (size + 0xFF) & ~0xFF;
-
- if (size > sizeof p->buffer)
- size = sizeof p->buffer;
-
- if (p->filled < size)
- p->filled += vfs_fread (p->buffer + p->filled, 1, size - p->filled,
- p->file);
-}
-
-static int64_t probe_buffer_fread (void * buffer, int64_t size, int64_t count,
- VFSFile * file)
-{
- ProbeBuffer * p = vfs_get_handle (file);
-
- increase_buffer (p, p->at + size * count);
- int readed = (size > 0) ? MIN (count, (p->filled - p->at) / size) : 0;
- memcpy (buffer, p->buffer + p->at, size * readed);
-
- p->at += size * readed;
- return readed;
-}
-
-static int64_t probe_buffer_fwrite (const void * data, int64_t size, int64_t count,
- VFSFile * file)
-{
- return 0; /* not allowed */
-}
-
-static int probe_buffer_fseek (VFSFile * file, int64_t offset, int whence)
-{
- ProbeBuffer * p = vfs_get_handle (file);
-
- if (whence == SEEK_END)
- return -1; /* not allowed */
-
- if (whence == SEEK_CUR)
- offset += p->at;
-
- if (offset < 0 || offset > sizeof p->buffer)
- return -1;
-
- increase_buffer (p, offset);
-
- if (offset > p->filled)
- return -1;
-
- p->at = offset;
- return 0;
-}
-
-static int64_t probe_buffer_ftell (VFSFile * file)
-{
- return ((ProbeBuffer *) vfs_get_handle (file))->at;
-}
-
-static bool_t probe_buffer_feof (VFSFile * file)
-{
- ProbeBuffer * p = vfs_get_handle (file);
-
- if (p->at < p->filled)
- return FALSE;
- if (p->at == sizeof p->buffer)
- return TRUE;
-
- return vfs_feof (p->file);
-}
-
-static int probe_buffer_ftruncate (VFSFile * file, int64_t size)
-{
- return -1; /* not allowed */
-}
-
-static int64_t probe_buffer_fsize (VFSFile * file)
-{
- ProbeBuffer * p = vfs_get_handle (file);
-
- int64_t size = vfs_fsize (p->file);
- return MIN (size, sizeof p->buffer);
-}
-
-static char * probe_buffer_get_metadata (VFSFile * file, const char * field)
-{
- return vfs_get_metadata (((ProbeBuffer *) vfs_get_handle (file))->file, field);
-}
-
-static VFSConstructor probe_buffer_table =
-{
- .vfs_fopen_impl = NULL,
- .vfs_fclose_impl = probe_buffer_fclose,
- .vfs_fread_impl = probe_buffer_fread,
- .vfs_fwrite_impl = probe_buffer_fwrite,
- .vfs_fseek_impl = probe_buffer_fseek,
- .vfs_ftell_impl = probe_buffer_ftell,
- .vfs_feof_impl = probe_buffer_feof,
- .vfs_ftruncate_impl = probe_buffer_ftruncate,
- .vfs_fsize_impl = probe_buffer_fsize,
- .vfs_get_metadata_impl = probe_buffer_get_metadata,
-};
-
-VFSFile * probe_buffer_new (const char * filename)
-{
- VFSFile * file = vfs_fopen (filename, "r");
-
- if (! file)
- return NULL;
-
- ProbeBuffer * p = g_new (ProbeBuffer, 1);
- p->file = file;
- p->filled = 0;
- p->at = 0;
-
- return vfs_new (filename, & probe_buffer_table, p);
-}
diff --git a/src/audacious/probe-buffer.h b/src/audacious/probe-buffer.h
deleted file mode 100644
index d1abf96..0000000
--- a/src/audacious/probe-buffer.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * probe-buffer.h
- * Copyright 2010 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.
- */
-
-#ifndef AUDACIOUS_PROBE_BUFFER_H
-#define AUDACIOUS_PROBE_BUFFER_H
-
-#include <libaudcore/vfs.h>
-
-VFSFile * probe_buffer_new (const char * filename);
-
-#endif
diff --git a/src/audacious/probe.c b/src/audacious/probe.c
deleted file mode 100644
index c627abe..0000000
--- a/src/audacious/probe.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * probe.c
- * Copyright 2009-2013 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 <glib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <libaudcore/audstrings.h>
-
-#include "debug.h"
-#include "misc.h"
-#include "playlist.h"
-#include "plugin.h"
-#include "plugins.h"
-#include "probe-buffer.h"
-
-typedef struct
-{
- const char * filename;
- VFSFile * handle;
- bool_t failed;
- PluginHandle * plugin;
-}
-ProbeState;
-
-static bool_t check_opened (ProbeState * state)
-{
- if (state->handle != NULL)
- return TRUE;
- if (state->failed)
- return FALSE;
-
- AUDDBG ("Opening %s.\n", state->filename);
- state->handle = probe_buffer_new (state->filename);
-
- if (state->handle != NULL)
- return TRUE;
-
- AUDDBG ("FAILED.\n");
- state->failed = TRUE;
- return FALSE;
-}
-
-static bool_t probe_func (PluginHandle * plugin, ProbeState * state)
-{
- AUDDBG ("Trying %s.\n", plugin_get_name (plugin));
- InputPlugin * decoder = plugin_get_header (plugin);
- if (decoder == NULL)
- return TRUE;
-
- if (decoder->is_our_file_from_vfs != NULL)
- {
- if (! check_opened (state))
- return FALSE;
-
- if (decoder->is_our_file_from_vfs (state->filename, state->handle))
- {
- state->plugin = plugin;
- return FALSE;
- }
-
- if (vfs_fseek (state->handle, 0, SEEK_SET) < 0)
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Optimization: If we have found plugins with a key match, assume that at least
- * one of them will succeed. This means that we need not check the very last
- * plugin. (If there is only one, we do not need to check it at all.) This is
- * implemented as follows:
- *
- * 1. On the first call, assume until further notice the plugin passed is the
- * last one and will therefore succeed.
- * 2. On a subsequent call, think twice and probe the plugin we assumed would
- * succeed. If it does in fact succeed, then we are done. If not, assume
- * similarly that the plugin passed in this call is the last one.
- */
-
-static bool_t probe_func_fast (PluginHandle * plugin, ProbeState * state)
-{
- if (state->plugin != NULL)
- {
- PluginHandle * prev = state->plugin;
- state->plugin = NULL;
-
- if (! probe_func (prev, state))
- return FALSE;
- }
-
- AUDDBG ("Guessing %s.\n", plugin_get_name (plugin));
- state->plugin = plugin;
- return TRUE;
-}
-
-static void probe_by_scheme (ProbeState * state)
-{
- const char * s = strstr (state->filename, "://");
- if (s == NULL)
- return;
-
- AUDDBG ("Probing by scheme.\n");
- SNCOPY (buf, state->filename, s - state->filename);
- input_plugin_for_key (INPUT_KEY_SCHEME, buf, (PluginForEachFunc) probe_func_fast, state);
-}
-
-static void probe_by_extension (ProbeState * state)
-{
- char buf[32];
- if (! uri_get_extension (state->filename, buf, sizeof buf))
- return;
-
- AUDDBG ("Probing by extension.\n");
- input_plugin_for_key (INPUT_KEY_EXTENSION, buf, (PluginForEachFunc) probe_func_fast, state);
-}
-
-static void probe_by_mime (ProbeState * state)
-{
- char * mime;
-
- if (! check_opened (state))
- return;
-
- if ((mime = vfs_get_metadata (state->handle, "content-type")) == NULL)
- return;
-
- AUDDBG ("Probing by MIME type.\n");
- input_plugin_for_key (INPUT_KEY_MIME, mime, (PluginForEachFunc)
- probe_func_fast, state);
- str_unref (mime);
-}
-
-static void probe_by_content (ProbeState * state)
-{
- AUDDBG ("Probing by content.\n");
- plugin_for_enabled (PLUGIN_TYPE_INPUT, (PluginForEachFunc) probe_func, state);
-}
-
-PluginHandle * file_find_decoder (const char * filename, bool_t fast)
-{
- ProbeState state;
-
- AUDDBG ("Probing %s.\n", filename);
- state.plugin = NULL;
- state.filename = filename;
- state.handle = NULL;
- state.failed = FALSE;
-
- probe_by_scheme (& state);
-
- if (state.plugin != NULL)
- goto DONE;
-
- probe_by_extension (& state);
-
- if (state.plugin != NULL || fast)
- goto DONE;
-
- probe_by_mime (& state);
-
- if (state.plugin != NULL)
- goto DONE;
-
- probe_by_content (& state);
-
-DONE:
- if (state.handle != NULL)
- vfs_fclose (state.handle);
-
- if (state.plugin != NULL)
- AUDDBG ("Probe succeeded: %s\n", plugin_get_name (state.plugin));
- else
- AUDDBG ("Probe failed.\n");
-
- return state.plugin;
-}
-
-static bool_t open_file (const char * filename, InputPlugin * ip,
- const char * mode, VFSFile * * handle)
-{
- /* no need to open a handle for custom URI schemes */
- if (ip->schemes && ip->schemes[0])
- return TRUE;
-
- * handle = vfs_fopen (filename, mode);
- return (* handle != NULL);
-}
-
-Tuple * file_read_tuple (const char * filename, PluginHandle * decoder)
-{
- InputPlugin * ip = plugin_get_header (decoder);
- g_return_val_if_fail (ip, NULL);
- g_return_val_if_fail (ip->probe_for_tuple, NULL);
-
- VFSFile * handle = NULL;
- if (! open_file (filename, ip, "r", & handle))
- return FALSE;
-
- Tuple * tuple = ip->probe_for_tuple (filename, handle);
-
- if (handle)
- vfs_fclose (handle);
-
- return tuple;
-}
-
-bool_t file_read_image (const char * filename, PluginHandle * decoder,
- void * * data, int64_t * size)
-{
- * data = NULL;
- * size = 0;
-
- if (! input_plugin_has_images (decoder))
- return FALSE;
-
- InputPlugin * ip = plugin_get_header (decoder);
- g_return_val_if_fail (ip, FALSE);
- g_return_val_if_fail (ip->get_song_image, FALSE);
-
- VFSFile * handle = NULL;
- if (! open_file (filename, ip, "r", & handle))
- return FALSE;
-
- bool_t success = ip->get_song_image (filename, handle, data, size);
-
- if (handle)
- vfs_fclose (handle);
-
- return success;
-}
-
-bool_t file_can_write_tuple (const char * filename, PluginHandle * decoder)
-{
- return input_plugin_can_write_tuple (decoder);
-}
-
-bool_t file_write_tuple (const char * filename, PluginHandle * decoder,
- const Tuple * tuple)
-{
- InputPlugin * ip = plugin_get_header (decoder);
- g_return_val_if_fail (ip, FALSE);
- g_return_val_if_fail (ip->update_song_tuple, FALSE);
-
- VFSFile * handle = NULL;
- if (! open_file (filename, ip, "r+", & handle))
- return FALSE;
-
- bool_t success = ip->update_song_tuple (filename, handle, tuple);
-
- if (handle)
- vfs_fclose (handle);
-
- if (success)
- playlist_rescan_file (filename);
-
- return success;
-}
-
-bool_t custom_infowin (const char * filename, PluginHandle * decoder)
-{
- if (! input_plugin_has_infowin (decoder))
- return FALSE;
-
- InputPlugin * ip = plugin_get_header (decoder);
- g_return_val_if_fail (ip, FALSE);
- g_return_val_if_fail (ip->file_info_box, FALSE);
-
- ip->file_info_box (filename);
- return TRUE;
-}
diff --git a/src/audacious/scanner.c b/src/audacious/scanner.c
deleted file mode 100644
index e3257da..0000000
--- a/src/audacious/scanner.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * scanner.c
- * Copyright 2012 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 <glib.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libaudcore/audstrings.h>
-
-#include "main.h"
-#include "misc.h"
-#include "scanner.h"
-
-struct _ScanRequest {
- char * filename; /* pooled */
- int flags;
- PluginHandle * decoder;
- ScanCallback callback;
- Tuple * tuple;
- void * image_data;
- int64_t image_len;
- char * image_file; /* pooled */
-};
-
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-
-static GQueue requests = G_QUEUE_INIT;
-
-static pthread_t scan_threads[SCAN_THREADS];
-
-static bool_t quit_flag = FALSE;
-
-ScanRequest * scan_request (const char * filename, int flags,
- PluginHandle * decoder, ScanCallback callback)
-{
- ScanRequest * request = g_slice_new0 (ScanRequest);
-
- request->filename = str_get (filename);
- request->flags = flags;
- request->decoder = decoder;
- request->callback = callback;
-
- pthread_mutex_lock (& mutex);
-
- g_queue_push_tail (& requests, request);
- pthread_cond_signal (& cond);
-
- pthread_mutex_unlock (& mutex);
- return request;
-}
-
-static void scan_request_free (ScanRequest * request)
-{
- if (request->tuple)
- tuple_unref (request->tuple);
-
- str_unref (request->filename);
- g_free (request->image_data);
- str_unref (request->image_file);
- g_slice_free (ScanRequest, request);
-}
-
-static void * scan_worker (void * unused)
-{
- pthread_mutex_lock (& mutex);
-
- while (! quit_flag)
- {
- ScanRequest * request = g_queue_pop_head (& requests);
-
- if (! request)
- {
- pthread_cond_wait (& cond, & mutex);
- continue;
- }
-
- pthread_mutex_unlock (& mutex);
-
- if (! request->decoder)
- request->decoder = file_find_decoder (request->filename, FALSE);
-
- if (request->decoder && (request->flags & SCAN_TUPLE))
- request->tuple = file_read_tuple (request->filename, request->decoder);
-
- if (request->decoder && (request->flags & SCAN_IMAGE))
- {
- file_read_image (request->filename, request->decoder,
- & request->image_data, & request->image_len);
-
- if (! request->image_data)
- request->image_file = get_associated_image_file (request->filename);
- }
-
- request->callback (request);
- scan_request_free (request);
-
- pthread_mutex_lock (& mutex);
- }
-
- pthread_mutex_unlock (& mutex);
- return NULL;
-}
-
-const char * scan_request_get_filename (ScanRequest * request)
-{
- return request->filename;
-}
-
-PluginHandle * scan_request_get_decoder (ScanRequest * request)
-{
- return request->decoder;
-}
-
-Tuple * scan_request_get_tuple (ScanRequest * request)
-{
- Tuple * tuple = request->tuple;
- request->tuple = NULL;
- return tuple;
-}
-
-void scan_request_get_image_data (ScanRequest * request, void * * data, int64_t * len)
-{
- * data = request->image_data;
- * len = request->image_len;
- request->image_data = NULL;
- request->image_len = 0;
-}
-
-const char * scan_request_get_image_file (ScanRequest * request)
-{
- return request->image_file;
-}
-
-void scanner_init (void)
-{
- for (int i = 0; i < SCAN_THREADS; i ++)
- pthread_create (& scan_threads[i], 0, scan_worker, NULL);
-}
-
-void scanner_cleanup (void)
-{
- pthread_mutex_lock (& mutex);
-
- quit_flag = TRUE;
- pthread_cond_broadcast (& cond);
-
- pthread_mutex_unlock (& mutex);
-
- for (int i = 0; i < SCAN_THREADS; i ++)
- pthread_join (scan_threads[i], NULL);
-
- ScanRequest * request;
- while ((request = g_queue_pop_head (& requests)))
- scan_request_free (request);
-
- quit_flag = FALSE;
-}
diff --git a/src/audacious/scanner.h b/src/audacious/scanner.h
deleted file mode 100644
index 3eee728..0000000
--- a/src/audacious/scanner.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * scanner.h
- * Copyright 2012 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.
- */
-
-#ifndef AUDACIOUS_SCANNER_H
-#define AUDACIOUS_SCANNER_H
-
-#include <audacious/types.h>
-#include <libaudcore/tuple.h>
-
-#define SCAN_TUPLE (1 << 0)
-#define SCAN_IMAGE (1 << 1)
-
-#define SCAN_THREADS 2
-
-struct _ScanRequest;
-typedef struct _ScanRequest ScanRequest;
-
-typedef void (* ScanCallback) (ScanRequest * request);
-
-ScanRequest * scan_request (const char * filename, int flags,
- PluginHandle * decoder, ScanCallback callback);
-
-const char * scan_request_get_filename (ScanRequest * request);
-PluginHandle * scan_request_get_decoder (ScanRequest * request);
-Tuple * scan_request_get_tuple (ScanRequest * request);
-void scan_request_get_image_data (ScanRequest * request, void * * data, int64_t * len);
-const char * scan_request_get_image_file (ScanRequest * request);
-
-void scanner_init (void);
-void scanner_cleanup (void);
-
-#endif
diff --git a/src/audacious/signals.c b/src/audacious/signals.cc
index 2b5515e..0a6f216 100644
--- a/src/audacious/signals.c
+++ b/src/audacious/signals.cc
@@ -22,7 +22,8 @@
#include <pthread.h>
#include <signal.h>
-#include "drct.h"
+#include <libaudcore/hook.h>
+
#include "main.h"
static sigset_t signal_set;
@@ -32,9 +33,9 @@ static void * signal_thread (void * data)
int signal;
while (! sigwait (& signal_set, & signal))
- drct_quit ();
+ event_queue ("quit", nullptr);
- return NULL;
+ return nullptr;
}
/* Must be called before any threads are created. */
@@ -46,13 +47,13 @@ void signals_init_one (void)
sigaddset (& signal_set, SIGQUIT);
sigaddset (& signal_set, SIGTERM);
- sigprocmask (SIG_BLOCK, & signal_set, NULL);
+ sigprocmask (SIG_BLOCK, & signal_set, nullptr);
}
void signals_init_two (void)
{
pthread_t thread;
- pthread_create (& thread, NULL, signal_thread, NULL);
+ pthread_create (& thread, nullptr, signal_thread, nullptr);
}
#endif /* HAVE_SIGWAIT */
diff --git a/src/audacious/types.h b/src/audacious/types.h
deleted file mode 100644
index d160bab..0000000
--- a/src/audacious/types.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * types.h
- * Copyright 2010-2011 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.
- */
-
-#ifndef AUDACIOUS_TYPES_H
-#define AUDACIOUS_TYPES_H
-
-#include <libaudcore/core.h>
-
-#define AUD_EQUALIZER_NBANDS 10
-#define EQUALIZER_MAX_GAIN 12
-
-enum {
- PLUGIN_TYPE_TRANSPORT,
- PLUGIN_TYPE_PLAYLIST,
- PLUGIN_TYPE_INPUT,
- PLUGIN_TYPE_EFFECT,
- PLUGIN_TYPE_OUTPUT,
- PLUGIN_TYPE_VIS,
- PLUGIN_TYPE_GENERAL,
- PLUGIN_TYPE_IFACE,
- PLUGIN_TYPES};
-
-typedef struct PluginHandle PluginHandle;
-
-typedef const struct _Plugin Plugin;
-typedef const struct _TransportPlugin TransportPlugin;
-typedef const struct _PlaylistPlugin PlaylistPlugin;
-typedef const struct _InputPlugin InputPlugin;
-typedef const struct _EffectPlugin EffectPlugin;
-typedef const struct _OutputPlugin OutputPlugin;
-typedef const struct _VisPlugin VisPlugin;
-typedef const struct _GeneralPlugin GeneralPlugin;
-typedef const struct _IfacePlugin IfacePlugin;
-
-typedef struct _PluginPreferences PluginPreferences;
-typedef struct _PreferencesWidget PreferencesWidget;
-
-typedef struct {
- char * name;
- float preamp;
- float bands[AUD_EQUALIZER_NBANDS];
-} EqualizerPreset;
-
-typedef struct {
- float track_gain; /* dB */
- float track_peak; /* 0-1 */
- float album_gain; /* dB */
- float album_peak; /* 0-1 */
-} ReplayGainInfo;
-
-#endif
diff --git a/src/audacious/ui_albumart.c b/src/audacious/ui_albumart.c
deleted file mode 100644
index a3f14a4..0000000
--- a/src/audacious/ui_albumart.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * ui_albumart.c
- * Copyright 2006-2013 Michael Hanselmann, Yoshiki Yazawa, 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 <glib.h>
-#include <string.h>
-
-#include <libaudcore/audstrings.h>
-
-#include "i18n.h"
-#include "main.h"
-#include "misc.h"
-#include "util.h"
-
-typedef struct {
- const char * basename;
- Index * include, * exclude;
-} SearchParams;
-
-static bool_t has_front_cover_extension (const char * name)
-{
- char * ext = strrchr (name, '.');
- if (! ext)
- return FALSE;
-
- return ! g_ascii_strcasecmp (ext, ".jpg") ||
- ! g_ascii_strcasecmp (ext, ".jpeg") || ! g_ascii_strcasecmp (ext, ".png");
-}
-
-static bool_t cover_name_filter (const char * name, Index * keywords, bool_t ret_on_empty)
-{
- int count = index_count (keywords);
- if (! count)
- return ret_on_empty;
-
- for (int i = 0; i < count; i ++)
- {
- if (strstr_nocase (name, index_get (keywords, i)))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static bool_t is_file_image (const char * imgfile, const char * file_name)
-{
- char * imgfile_ext = strrchr (imgfile, '.');
- if (! imgfile_ext)
- return FALSE;
-
- char * file_name_ext = strrchr (file_name, '.');
- if (! file_name_ext)
- return FALSE;
-
- size_t imgfile_len = imgfile_ext - imgfile;
- size_t file_name_len = file_name_ext - file_name;
-
- return imgfile_len == file_name_len && ! g_ascii_strncasecmp (imgfile, file_name, imgfile_len);
-}
-
-static char * fileinfo_recursive_get_image (const char * path,
- const SearchParams * params, int depth)
-{
- GDir * d = g_dir_open (path, 0, NULL);
- if (! d)
- return NULL;
-
- const char * name;
-
- if (get_bool (NULL, "use_file_cover") && ! depth)
- {
- /* Look for images matching file name */
- while ((name = g_dir_read_name (d)))
- {
- char * newpath = filename_build (path, name);
-
- if (! g_file_test (newpath, G_FILE_TEST_IS_DIR) &&
- has_front_cover_extension (name) &&
- is_file_image (name, params->basename))
- {
- g_dir_close (d);
- return newpath;
- }
-
- str_unref (newpath);
- }
-
- g_dir_rewind (d);
- }
-
- /* Search for files using filter */
- while ((name = g_dir_read_name (d)))
- {
- char * newpath = filename_build (path, name);
-
- if (! g_file_test (newpath, G_FILE_TEST_IS_DIR) &&
- has_front_cover_extension (name) &&
- cover_name_filter (name, params->include, TRUE) &&
- ! cover_name_filter (name, params->exclude, FALSE))
- {
- g_dir_close (d);
- return newpath;
- }
-
- str_unref (newpath);
- }
-
- g_dir_rewind (d);
-
- if (get_bool (NULL, "recurse_for_cover") && depth < get_int (NULL, "recurse_for_cover_depth"))
- {
- /* Descend into directories recursively. */
- while ((name = g_dir_read_name (d)))
- {
- char * newpath = filename_build (path, name);
-
- if (g_file_test (newpath, G_FILE_TEST_IS_DIR))
- {
- char * tmp = fileinfo_recursive_get_image (newpath, params, depth + 1);
-
- if (tmp)
- {
- str_unref (newpath);
- g_dir_close (d);
- return tmp;
- }
- }
-
- str_unref (newpath);
- }
- }
-
- g_dir_close (d);
- return NULL;
-}
-
-char * get_associated_image_file (const char * filename)
-{
- char * image_uri = NULL;
-
- char * local = uri_to_filename (filename);
- char * base = local ? last_path_element (local) : NULL;
-
- if (local && base)
- {
- char * include = get_str (NULL, "cover_name_include");
- char * exclude = get_str (NULL, "cover_name_exclude");
-
- SearchParams params = {
- .basename = base,
- .include = str_list_to_index (include, ", "),
- .exclude = str_list_to_index (exclude, ", ")
- };
-
- str_unref (include);
- str_unref (exclude);
-
- SNCOPY (path, local, base - 1 - local);
-
- char * image_local = fileinfo_recursive_get_image (path, & params, 0);
- if (image_local)
- image_uri = filename_to_uri (image_local);
-
- str_unref (image_local);
-
- index_free_full (params.include, (IndexFreeFunc) str_unref);
- index_free_full (params.exclude, (IndexFreeFunc) str_unref);
- }
-
- str_unref (local);
-
- return image_uri;
-}
diff --git a/src/audacious/ui_plugin_menu.c b/src/audacious/ui_plugin_menu.c
deleted file mode 100644
index 9d81b65..0000000
--- a/src/audacious/ui_plugin_menu.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * ui_plugin_menu.c
- * Copyright 2009-2011 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 <glib.h>
-#include <gtk/gtk.h>
-
-#include <libaudgui/menu.h>
-
-#include "i18n.h"
-#include "misc.h"
-
-static GList * items[AUD_MENU_COUNT]; /* of AudguiMenuItem */
-static GtkWidget * menus[AUD_MENU_COUNT];
-
-static void configure_plugins (void)
-{
- show_prefs_for_plugin_type (PLUGIN_TYPE_GENERAL);
-}
-
-static const AudguiMenuItem main_items[] = {
- {N_("_Plugins ..."), .func = configure_plugins},
- {.sep = TRUE}
-};
-
-static void add_to_menu (GtkWidget * menu, const AudguiMenuItem * item)
-{
- GtkWidget * widget = audgui_menu_item_new_with_domain (item, NULL, NULL);
- g_object_set_data ((GObject *) widget, "func", (void *) item->func);
- gtk_widget_show (widget);
- gtk_menu_shell_append ((GtkMenuShell *) menu, widget);
-}
-
-/* GtkWidget * get_plugin_menu (int id) */
-void * get_plugin_menu (int id)
-{
- if (! menus[id])
- {
- menus[id] = gtk_menu_new ();
- g_signal_connect (menus[id], "destroy", (GCallback)
- gtk_widget_destroyed, & menus[id]);
-
- if (id == AUD_MENU_MAIN)
- audgui_menu_init (menus[id], main_items, ARRAY_LEN (main_items), NULL);
-
- for (GList * node = items[id]; node; node = node->next)
- add_to_menu (menus[id], node->data);
- }
-
- return menus[id];
-}
-
-void plugin_menu_add (int id, MenuFunc func, const char * name,
- const char * icon)
-{
- AudguiMenuItem * item = g_slice_new0 (AudguiMenuItem);
- item->name = name;
- item->icon = icon;
- item->func = func;
-
- items[id] = g_list_append (items[id], item);
-
- if (menus[id])
- add_to_menu (menus[id], item);
-}
-
-static void remove_cb (GtkWidget * widget, MenuFunc func)
-{
- if ((MenuFunc) g_object_get_data ((GObject *) widget, "func") == func)
- gtk_widget_destroy (widget);
-}
-
-void plugin_menu_remove (int id, MenuFunc func)
-{
- if (menus[id])
- gtk_container_foreach ((GtkContainer *) menus[id], (GtkCallback)
- remove_cb, (void *) func);
-
- GList * next;
- for (GList * node = items[id]; node; node = next)
- {
- next = node->next;
-
- if (((AudguiMenuItem *) node->data)->func == func)
- {
- g_slice_free (AudguiMenuItem, node->data);
- items[id] = g_list_delete_link (items[id], node);
- }
- }
-}
diff --git a/src/audacious/ui_preferences.c b/src/audacious/ui_preferences.c
deleted file mode 100644
index 2949fdc..0000000
--- a/src/audacious/ui_preferences.c
+++ /dev/null
@@ -1,814 +0,0 @@
-/*
- * ui_preferences.c
- * Copyright 2006-2012 William Pitcock, Tomasz Moń, Michael Färber, 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 <string.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include <libaudcore/audstrings.h>
-#include <libaudcore/hook.h>
-#include <libaudgui/libaudgui-gtk.h>
-
-#include "debug.h"
-#include "i18n.h"
-#include "misc.h"
-#include "output.h"
-#include "playlist.h"
-#include "plugin.h"
-#include "plugins.h"
-#include "preferences.h"
-#include "ui_preferences.h"
-
-#ifdef USE_CHARDET
-#include <libguess.h>
-#endif
-
-enum CategoryViewCols {
- CATEGORY_VIEW_COL_ICON,
- CATEGORY_VIEW_COL_NAME,
- CATEGORY_VIEW_N_COLS
-};
-
-typedef struct {
- const char * icon_path;
- const char * name;
-} Category;
-
-typedef struct {
- int type;
- const char * name;
-} PluginCategory;
-
-typedef struct {
- const char * name;
- const char * tag;
-} TitleFieldTag;
-
-static const char aud_version_string[] =
- "<span size='small'>Audacious " VERSION " (" BUILDSTAMP ")</span>";
-
-static GtkWidget * prefswin;
-static GtkWidget * category_treeview, * category_notebook, * plugin_notebook;
-static GtkWidget * titlestring_entry;
-
-enum {
- CATEGORY_APPEARANCE = 0,
- CATEGORY_AUDIO,
- CATEGORY_NETWORK,
- CATEGORY_PLAYLIST,
- CATEGORY_SONG_INFO,
- CATEGORY_PLUGINS
-};
-
-static const Category categories[] = {
- { "appearance.png", N_("Appearance") },
- { "audio.png", N_("Audio") },
- { "connectivity.png", N_("Network") },
- { "playlist.png", N_("Playlist")} ,
- { "info.png", N_("Song Info") },
- { "plugins.png", N_("Plugins") }
-};
-
-static const PluginCategory plugin_categories[] = {
- { PLUGIN_TYPE_GENERAL, N_("General") },
- { PLUGIN_TYPE_EFFECT, N_("Effect") },
- { PLUGIN_TYPE_VIS, N_("Visualization") },
- { PLUGIN_TYPE_INPUT, N_("Input") },
- { PLUGIN_TYPE_PLAYLIST, N_("Playlist") },
- { PLUGIN_TYPE_TRANSPORT, N_("Transport") }
-};
-
-static TitleFieldTag title_field_tags[] = {
- { N_("Artist") , "${artist}" },
- { N_("Album") , "${album}" },
- { N_("Title") , "${title}" },
- { N_("Tracknumber"), "${track-number}" },
- { N_("Genre") , "${genre}" },
- { N_("Filename") , "${file-name}" },
- { N_("Filepath") , "${file-path}" },
- { N_("Date") , "${date}" },
- { N_("Year") , "${year}" },
- { N_("Comment") , "${comment}" },
- { N_("Codec") , "${codec}" },
- { N_("Quality") , "${quality}" }
-};
-
-#ifdef USE_CHARDET
-static ComboBoxElements chardet_detector_presets[] = {
- { "", N_("None")},
- { GUESS_REGION_AR, N_("Arabic") },
- { GUESS_REGION_BL, N_("Baltic") },
- { GUESS_REGION_CN, N_("Chinese") },
- { GUESS_REGION_GR, N_("Greek") },
- { GUESS_REGION_HW, N_("Hebrew") },
- { GUESS_REGION_JP, N_("Japanese") },
- { GUESS_REGION_KR, N_("Korean") },
- { GUESS_REGION_PL, N_("Polish") },
- { GUESS_REGION_RU, N_("Russian") },
- { GUESS_REGION_TW, N_("Taiwanese") },
- { GUESS_REGION_TR, N_("Turkish") }
-};
-#endif
-
-static ComboBoxElements bitdepth_elements[] = {
- { GINT_TO_POINTER (16), "16" },
- { GINT_TO_POINTER (24), "24" },
- { GINT_TO_POINTER (32), "32" },
- { GINT_TO_POINTER (0), N_("Floating point") }
-};
-
-static GArray * iface_combo_elements;
-static int iface_combo_selected;
-static GtkWidget * iface_prefs_box;
-
-static const ComboBoxElements * iface_combo_fill (int * n_elements);
-static void iface_combo_changed (void);
-static void * iface_create_prefs_box (void);
-
-static PreferencesWidget appearance_page_widgets[] = {
- {WIDGET_LABEL, N_("<b>Interface Settings</b>")},
- {WIDGET_COMBO_BOX, N_("Interface plugin:"),
- .cfg_type = VALUE_INT, .cfg = & iface_combo_selected,
- .data.combo.fill = iface_combo_fill, .callback = iface_combo_changed},
- {WIDGET_CUSTOM, .data.populate = iface_create_prefs_box}};
-
-static GArray * output_combo_elements;
-static int output_combo_selected;
-static GtkWidget * output_config_button;
-static GtkWidget * output_about_button;
-
-static const ComboBoxElements * output_combo_fill (int * n_elements);
-static void output_combo_changed (void);
-static void * output_create_config_button (void);
-static void * output_create_about_button (void);
-static void output_bit_depth_changed (void);
-
-static PreferencesWidget output_combo_widgets[] = {
- {WIDGET_COMBO_BOX, N_("Output plugin:"),
- .cfg_type = VALUE_INT, .cfg = & output_combo_selected,
- .data.combo.fill = output_combo_fill, .callback = output_combo_changed},
- {WIDGET_CUSTOM, .data.populate = output_create_config_button},
- {WIDGET_CUSTOM, .data.populate = output_create_about_button}};
-
-static PreferencesWidget audio_page_widgets[] = {
- {WIDGET_LABEL, N_("<b>Output Settings</b>")},
- {WIDGET_BOX, .data.box = {.elem = output_combo_widgets,
- .n_elem = ARRAY_LEN (output_combo_widgets), .horizontal = TRUE}},
- {WIDGET_COMBO_BOX, N_("Bit depth:"),
- .cfg_type = VALUE_INT, .cname = "output_bit_depth", .callback = output_bit_depth_changed,
- .data.combo = {bitdepth_elements, ARRAY_LEN (bitdepth_elements)}},
- {WIDGET_SPIN_BTN, N_("Buffer size:"),
- .cfg_type = VALUE_INT, .cname = "output_buffer_size",
- .data.spin_btn = {100, 10000, 1000, N_("ms")}},
- {WIDGET_CHK_BTN, N_("Soft clipping"),
- .cfg_type = VALUE_BOOLEAN, .cname = "soft_clipping"},
- {WIDGET_CHK_BTN, N_("Use software volume control (not recommended)"),
- .cfg_type = VALUE_BOOLEAN, .cname = "software_volume_control"},
- {WIDGET_LABEL, N_("<b>Replay Gain</b>")},
- {WIDGET_CHK_BTN, N_("Enable Replay Gain"),
- .cfg_type = VALUE_BOOLEAN, .cname = "enable_replay_gain"},
- {WIDGET_CHK_BTN, N_("Album mode"), .child = TRUE,
- .cfg_type = VALUE_BOOLEAN, .cname = "replay_gain_album"},
- {WIDGET_CHK_BTN, N_("Prevent clipping (recommended)"), .child = TRUE,
- .cfg_type = VALUE_BOOLEAN, .cname = "enable_clipping_prevention"},
- {WIDGET_LABEL, N_("<b>Adjust Levels</b>"), .child = TRUE},
- {WIDGET_SPIN_BTN, N_("Amplify all files:"), .child = TRUE,
- .cfg_type = VALUE_FLOAT, .cname = "replay_gain_preamp",
- .data.spin_btn = {-15, 15, 0.1, N_("dB")}},
- {WIDGET_SPIN_BTN, N_("Amplify untagged files:"), .child = TRUE,
- .cfg_type = VALUE_FLOAT, .cname = "default_gain",
- .data.spin_btn = {-15, 15, 0.1, N_("dB")}}};
-
-static PreferencesWidget proxy_host_port_elements[] = {
- {WIDGET_ENTRY, N_("Proxy hostname:"), .cfg_type = VALUE_STRING, .cname = "proxy_host"},
- {WIDGET_ENTRY, N_("Proxy port:"), .cfg_type = VALUE_STRING, .cname = "proxy_port"}};
-
-static PreferencesWidget proxy_auth_elements[] = {
- {WIDGET_ENTRY, N_("Proxy username:"), .cfg_type = VALUE_STRING, .cname = "proxy_user"},
- {WIDGET_ENTRY, N_("Proxy password:"), .cfg_type = VALUE_STRING, .cname = "proxy_pass",
- .data.entry.password = TRUE}};
-
-static PreferencesWidget connectivity_page_widgets[] = {
- {WIDGET_LABEL, N_("<b>Proxy Configuration</b>"), NULL, NULL, NULL, FALSE},
- {WIDGET_CHK_BTN, N_("Enable proxy usage"), .cfg_type = VALUE_BOOLEAN, .cname = "use_proxy"},
- {WIDGET_TABLE, .child = TRUE, .data.table = {proxy_host_port_elements,
- ARRAY_LEN (proxy_host_port_elements)}},
- {WIDGET_CHK_BTN, N_("Use authentication with proxy"),
- .cfg_type = VALUE_BOOLEAN, .cname = "use_proxy_auth"},
- {WIDGET_TABLE, .child = TRUE, .data.table = {proxy_auth_elements,
- ARRAY_LEN (proxy_auth_elements)}}};
-
-static PreferencesWidget chardet_elements[] = {
-#ifdef USE_CHARDET
- {WIDGET_COMBO_BOX, N_("Auto character encoding detector for:"),
- .cfg_type = VALUE_STRING, .cname = "chardet_detector", .child = TRUE,
- .data.combo = {chardet_detector_presets, ARRAY_LEN (chardet_detector_presets)}},
-#endif
- {WIDGET_ENTRY, N_("Fallback character encodings:"), .cfg_type = VALUE_STRING,
- .cname = "chardet_fallback", .child = TRUE}};
-
-static PreferencesWidget playlist_page_widgets[] = {
- {WIDGET_LABEL, N_("<b>Behavior</b>"), NULL, NULL, NULL, FALSE},
- {WIDGET_CHK_BTN, N_("Continue playback on startup"),
- .cfg_type = VALUE_BOOLEAN, .cname = "resume_playback_on_startup"},
- {WIDGET_CHK_BTN, N_("Advance when the current song is deleted"),
- .cfg_type = VALUE_BOOLEAN, .cname = "advance_on_delete"},
- {WIDGET_CHK_BTN, N_("Clear the playlist when opening files"),
- .cfg_type = VALUE_BOOLEAN, .cname = "clear_playlist"},
- {WIDGET_CHK_BTN, N_("Open files in a temporary playlist"),
- .cfg_type = VALUE_BOOLEAN, .cname = "open_to_temporary"},
- {WIDGET_CHK_BTN, N_("Do not load metadata for songs until played"),
- .cfg_type = VALUE_BOOLEAN, .cname = "metadata_on_play",
- .callback = playlist_trigger_scan},
- {WIDGET_LABEL, N_("<b>Compatibility</b>"), NULL, NULL, NULL, FALSE},
- {WIDGET_CHK_BTN, N_("Interpret \\ (backward slash) as a folder delimiter"),
- .cfg_type = VALUE_BOOLEAN, .cname = "convert_backslash"},
- {WIDGET_TABLE, .data.table = {chardet_elements, ARRAY_LEN (chardet_elements)}}};
-
-static PreferencesWidget song_info_page_widgets[] = {
- {WIDGET_LABEL, N_("<b>Album Art</b>")},
- {WIDGET_LABEL, N_("Search for images matching these words (comma-separated):")},
- {WIDGET_ENTRY, .cfg_type = VALUE_STRING, .cname = "cover_name_include"},
- {WIDGET_LABEL, N_("Exclude images matching these words (comma-separated):")},
- {WIDGET_ENTRY, .cfg_type = VALUE_STRING, .cname = "cover_name_exclude"},
- {WIDGET_CHK_BTN, N_("Search for images matching song file name"),
- .cfg_type = VALUE_BOOLEAN, .cname = "use_file_cover"},
- {WIDGET_CHK_BTN, N_("Search recursively"),
- .cfg_type = VALUE_BOOLEAN, .cname = "recurse_for_cover"},
- {WIDGET_SPIN_BTN, N_("Search depth:"), .child = TRUE,
- .cfg_type = VALUE_INT, .cname = "recurse_for_cover_depth",
- .data.spin_btn = {0, 100, 1}},
- {WIDGET_LABEL, N_("<b>Popup Information</b>")},
- {WIDGET_CHK_BTN, N_("Show popup information"),
- .cfg_type = VALUE_BOOLEAN, .cname = "show_filepopup_for_tuple"},
- {WIDGET_SPIN_BTN, N_("Popup delay (tenths of a second):"), .child = TRUE,
- .cfg_type = VALUE_INT, .cname = "filepopup_delay",
- .data.spin_btn = {0, 100, 1}},
- {WIDGET_CHK_BTN, N_("Show time scale for current song"), .child = TRUE,
- .cfg_type = VALUE_BOOLEAN, .cname = "filepopup_showprogressbar"}};
-
-#define TITLESTRING_NPRESETS 6
-
-static const char * const titlestring_presets[TITLESTRING_NPRESETS] = {
- "${title}",
- "${?artist:${artist} - }${title}",
- "${?artist:${artist} - }${?album:${album} - }${title}",
- "${?artist:${artist} - }${?album:${album} - }${?track-number:${track-number}. }${title}",
- "${?artist:${artist} }${?album:[ ${album} ] }${?artist:- }${?track-number:${track-number}. }${title}",
- "${?album:${album} - }${title}"
-};
-
-static const char * const titlestring_preset_names[TITLESTRING_NPRESETS] = {
- N_("TITLE"),
- N_("ARTIST - TITLE"),
- N_("ARTIST - ALBUM - TITLE"),
- N_("ARTIST - ALBUM - TRACK. TITLE"),
- N_("ARTIST [ ALBUM ] - TRACK. TITLE"),
- N_("ALBUM - TITLE")
-};
-
-static GArray * fill_plugin_combo (int type)
-{
- GArray * array = g_array_new (FALSE, FALSE, sizeof (ComboBoxElements));
- g_array_set_size (array, plugin_count (type));
-
- for (int i = 0; i < array->len; i ++)
- {
- ComboBoxElements * elem = & g_array_index (array, ComboBoxElements, i);
- elem->label = plugin_get_name (plugin_by_index (type, i));
- elem->value = GINT_TO_POINTER (i);
- }
-
- return array;
-}
-
-static void change_category (int category)
-{
- GtkTreeSelection * selection = gtk_tree_view_get_selection ((GtkTreeView *) category_treeview);
- GtkTreePath * path = gtk_tree_path_new_from_indices (category, -1);
- gtk_tree_selection_select_path (selection, path);
- gtk_tree_path_free (path);
-}
-
-static void category_changed (GtkTreeSelection * selection)
-{
- GtkTreeModel * model;
- GtkTreeIter iter;
-
- if (gtk_tree_selection_get_selected (selection, & model, & iter))
- {
- GtkTreePath * path = gtk_tree_model_get_path (model, & iter);
- int category = gtk_tree_path_get_indices (path)[0];
- gtk_notebook_set_current_page ((GtkNotebook *) category_notebook, category);
- gtk_tree_path_free (path);
- }
-}
-
-static void titlestring_tag_menu_cb (GtkMenuItem * menuitem, void * data)
-{
- const char * separator = " - ";
- int item = GPOINTER_TO_INT (data);
- int pos = gtk_editable_get_position ((GtkEditable *) titlestring_entry);
-
- /* insert separator as needed */
- if (gtk_entry_get_text ((GtkEntry *) titlestring_entry)[0])
- gtk_editable_insert_text ((GtkEditable *) titlestring_entry, separator, -1, & pos);
-
- gtk_editable_insert_text ((GtkEditable *) titlestring_entry, _(title_field_tags[item].tag), -1, & pos);
- gtk_editable_set_position ((GtkEditable *) titlestring_entry, pos);
-}
-
-static void on_titlestring_help_button_clicked (GtkButton * button, void * menu)
-{
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME);
-}
-
-static void update_titlestring_cbox (GtkComboBox * cbox, const char * format)
-{
- int preset;
- for (preset = 0; preset < TITLESTRING_NPRESETS; preset ++)
- {
- if (! strcmp (titlestring_presets[preset], format))
- break;
- }
-
- if (gtk_combo_box_get_active (cbox) != preset)
- gtk_combo_box_set_active (cbox, preset);
-}
-
-static void on_titlestring_entry_changed (GtkEntry * entry, GtkComboBox * cbox)
-{
- const char * format = gtk_entry_get_text (entry);
- set_str (NULL, "generic_title_format", format);
- update_titlestring_cbox (cbox, format);
- playlist_reformat_titles ();
-}
-
-static void on_titlestring_cbox_changed (GtkComboBox * cbox, GtkEntry * entry)
-{
- int preset = gtk_combo_box_get_active (cbox);
- if (preset < TITLESTRING_NPRESETS)
- gtk_entry_set_text (entry, titlestring_presets[preset]);
-}
-
-static void fill_category_list (GtkTreeView * treeview, GtkNotebook * notebook)
-{
- GtkTreeViewColumn * column = gtk_tree_view_column_new ();
- gtk_tree_view_column_set_title (column, _("Category"));
- gtk_tree_view_append_column (treeview, column);
- gtk_tree_view_column_set_spacing (column, 2);
-
- GtkCellRenderer * renderer = gtk_cell_renderer_pixbuf_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer, "pixbuf", 0, NULL);
-
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_attributes (column, renderer, "text", 1, NULL);
-
- g_object_set ((GObject *) renderer, "wrap-width", 96, "wrap-mode",
- PANGO_WRAP_WORD_CHAR, NULL);
-
- GtkListStore * store = gtk_list_store_new (CATEGORY_VIEW_N_COLS,
- GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT);
- gtk_tree_view_set_model (treeview, (GtkTreeModel *) store);
-
- const char * data_dir = get_path (AUD_PATH_DATA_DIR);
-
- for (int i = 0; i < ARRAY_LEN (categories); i ++)
- {
- SCONCAT3 (path, data_dir, "/images/", categories[i].icon_path);
-
- GtkTreeIter iter;
-
- gtk_list_store_append (store, & iter);
- gtk_list_store_set (store, & iter, CATEGORY_VIEW_COL_NAME,
- gettext (categories[i].name), -1);
-
- GdkPixbuf * img = gdk_pixbuf_new_from_file (path, NULL);
-
- if (img)
- {
- gtk_list_store_set (store, & iter, CATEGORY_VIEW_COL_ICON, img, -1);
- g_object_unref (img);
- }
- }
-
- g_object_unref (store);
-
- GtkTreeSelection * selection = gtk_tree_view_get_selection (treeview);
- g_signal_connect (selection, "changed", (GCallback) category_changed, NULL);
-}
-
-static GtkWidget * create_titlestring_tag_menu (void)
-{
- GtkWidget * titlestring_tag_menu = gtk_menu_new ();
-
- for (int i = 0; i < ARRAY_LEN (title_field_tags); i ++)
- {
- GtkWidget * menu_item = gtk_menu_item_new_with_label (_(title_field_tags[i].name));
- gtk_menu_shell_append ((GtkMenuShell *) titlestring_tag_menu, menu_item);
- g_signal_connect(menu_item, "activate",
- (GCallback) titlestring_tag_menu_cb, GINT_TO_POINTER (i));
- };
-
- gtk_widget_show_all (titlestring_tag_menu);
-
- return titlestring_tag_menu;
-}
-
-static void show_numbers_cb (GtkToggleButton * numbers, void * unused)
-{
- set_bool (NULL, "show_numbers_in_pl", gtk_toggle_button_get_active (numbers));
- playlist_reformat_titles ();
- hook_call ("title change", NULL);
-}
-
-static void leading_zero_cb (GtkToggleButton * leading)
-{
- set_bool (NULL, "leading_zero", gtk_toggle_button_get_active (leading));
- playlist_reformat_titles ();
- hook_call ("title change", NULL);
-}
-
-static void create_titlestring_widgets (GtkWidget * * cbox, GtkWidget * * entry)
-{
- * cbox = gtk_combo_box_text_new ();
- for (int i = 0; i < TITLESTRING_NPRESETS; i ++)
- gtk_combo_box_text_append_text ((GtkComboBoxText *) * cbox, _(titlestring_preset_names[i]));
- gtk_combo_box_text_append_text ((GtkComboBoxText *) * cbox, _("Custom"));
-
- * entry = gtk_entry_new ();
-
- char * format = get_str (NULL, "generic_title_format");
- update_titlestring_cbox ((GtkComboBox *) * cbox, format);
- gtk_entry_set_text ((GtkEntry *) * entry, format);
- str_unref (format);
-
- g_signal_connect (* cbox, "changed", (GCallback) on_titlestring_cbox_changed, * entry);
- g_signal_connect (* entry, "changed", (GCallback) on_titlestring_entry_changed, * cbox);
-}
-
-static void create_playlist_category (void)
-{
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add ((GtkContainer *) category_notebook, vbox);
-
- create_widgets ((GtkBox *) vbox, playlist_page_widgets, ARRAY_LEN (playlist_page_widgets));
-
- GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
- gtk_box_pack_start ((GtkBox *) vbox, alignment, FALSE, FALSE, 0);
- gtk_alignment_set_padding ((GtkAlignment *) alignment, 12, 3, 0, 0);
-
- GtkWidget * label = gtk_label_new (_("<b>Song Display</b>"));
- gtk_container_add ((GtkContainer *) alignment, label);
- gtk_label_set_use_markup ((GtkLabel *) label, TRUE);
- gtk_misc_set_alignment ((GtkMisc *) label, 0, 0.5);
-
- GtkWidget * numbers_alignment = gtk_alignment_new (0, 0, 0, 0);
- gtk_alignment_set_padding ((GtkAlignment *) numbers_alignment, 0, 0, 12, 0);
- gtk_box_pack_start ((GtkBox *) vbox, numbers_alignment, 0, 0, 3);
-
- GtkWidget * numbers = gtk_check_button_new_with_label (_("Show song numbers"));
- gtk_toggle_button_set_active ((GtkToggleButton *) numbers,
- get_bool (NULL, "show_numbers_in_pl"));
- g_signal_connect (numbers, "toggled", (GCallback) show_numbers_cb, 0);
- gtk_container_add ((GtkContainer *) numbers_alignment, numbers);
-
- numbers_alignment = gtk_alignment_new (0, 0, 0, 0);
- gtk_alignment_set_padding ((GtkAlignment *) numbers_alignment, 0, 0, 12, 0);
- gtk_box_pack_start ((GtkBox *) vbox, numbers_alignment, 0, 0, 3);
-
- numbers = gtk_check_button_new_with_label (
- _("Show leading zeroes (02:00 instead of 2:00)"));
- gtk_toggle_button_set_active ((GtkToggleButton *) numbers, get_bool (NULL, "leading_zero"));
- g_signal_connect (numbers, "toggled", (GCallback) leading_zero_cb, 0);
- gtk_container_add ((GtkContainer *) numbers_alignment, numbers);
-
- alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
- gtk_box_pack_start ((GtkBox *) vbox, alignment, FALSE, FALSE, 0);
- gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 12, 0);
-
- GtkWidget * grid = gtk_grid_new ();
- gtk_container_add ((GtkContainer *) alignment, grid);
- gtk_grid_set_row_spacing ((GtkGrid *) grid, 4);
- gtk_grid_set_column_spacing ((GtkGrid *) grid, 12);
-
- label = gtk_label_new (_("Title format:"));
- gtk_grid_attach ((GtkGrid *) grid, label, 0, 0, 1, 1);
- gtk_label_set_justify ((GtkLabel *) label, GTK_JUSTIFY_RIGHT);
- gtk_misc_set_alignment ((GtkMisc *) label, 1, 0.5);
-
- label = gtk_label_new (_("Custom string:"));
- gtk_grid_attach ((GtkGrid *) grid, label, 0, 1, 1, 1);
- gtk_label_set_justify ((GtkLabel *) label, GTK_JUSTIFY_RIGHT);
- gtk_misc_set_alignment ((GtkMisc *) label, 1, 0.5);
-
- GtkWidget * titlestring_cbox;
- create_titlestring_widgets (& titlestring_cbox, & titlestring_entry);
- gtk_widget_set_hexpand (titlestring_cbox, TRUE);
- gtk_widget_set_hexpand (titlestring_entry, TRUE);
- gtk_grid_attach ((GtkGrid *) grid, titlestring_cbox, 1, 0, 1, 1);
- gtk_grid_attach ((GtkGrid *) grid, titlestring_entry, 1, 1, 1, 1);
-
- GtkWidget * titlestring_help_button = gtk_button_new ();
- gtk_widget_set_can_focus (titlestring_help_button, FALSE);
- gtk_button_set_focus_on_click ((GtkButton *) titlestring_help_button, FALSE);
- gtk_button_set_relief ((GtkButton *) titlestring_help_button, GTK_RELIEF_HALF);
- gtk_grid_attach ((GtkGrid *) grid, titlestring_help_button, 2, 1, 1, 1);
-
- GtkWidget * titlestring_tag_menu = create_titlestring_tag_menu ();
-
- g_signal_connect (titlestring_help_button, "clicked",
- (GCallback) on_titlestring_help_button_clicked, titlestring_tag_menu);
-
- GtkWidget * image = gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_BUTTON);
- gtk_container_add ((GtkContainer *) titlestring_help_button, image);
-}
-
-static void create_song_info_category (void)
-{
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add ((GtkContainer *) category_notebook, vbox);
- create_widgets ((GtkBox *) vbox, song_info_page_widgets,
- ARRAY_LEN (song_info_page_widgets));
-}
-
-static void iface_fill_prefs_box (void)
-{
- Plugin * header = plugin_get_header (plugin_get_current (PLUGIN_TYPE_IFACE));
- if (header && header->prefs)
- create_widgets_with_domain (iface_prefs_box, header->prefs->widgets,
- header->prefs->n_widgets, header->domain);
-}
-
-static void iface_combo_changed (void)
-{
- gtk_container_foreach ((GtkContainer *) iface_prefs_box, (GtkCallback) gtk_widget_destroy, NULL);
-
- plugin_enable (plugin_by_index (PLUGIN_TYPE_IFACE, iface_combo_selected), TRUE);
-
- iface_fill_prefs_box ();
- gtk_widget_show_all (iface_prefs_box);
-}
-
-static const ComboBoxElements * iface_combo_fill (int * n_elements)
-{
- if (! iface_combo_elements)
- {
- iface_combo_elements = fill_plugin_combo (PLUGIN_TYPE_IFACE);
- iface_combo_selected = plugin_get_index (plugin_get_current (PLUGIN_TYPE_IFACE));
- }
-
- * n_elements = iface_combo_elements->len;
- return (const ComboBoxElements *) iface_combo_elements->data;
-}
-
-static void * iface_create_prefs_box (void)
-{
- iface_prefs_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- iface_fill_prefs_box ();
- return iface_prefs_box;
-}
-
-static void create_appearance_category (void)
-{
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add ((GtkContainer *) category_notebook, vbox);
- create_widgets ((GtkBox *) vbox, appearance_page_widgets, ARRAY_LEN (appearance_page_widgets));
-}
-
-static void output_combo_changed (void)
-{
- PluginHandle * plugin = plugin_by_index (PLUGIN_TYPE_OUTPUT, output_combo_selected);
-
- if (plugin_enable (plugin, TRUE))
- {
- gtk_widget_set_sensitive (output_config_button, plugin_has_configure (plugin));
- gtk_widget_set_sensitive (output_about_button, plugin_has_about (plugin));
- }
-}
-
-static const ComboBoxElements * output_combo_fill (int * n_elements)
-{
- if (! output_combo_elements)
- {
- output_combo_elements = fill_plugin_combo (PLUGIN_TYPE_OUTPUT);
- output_combo_selected = plugin_get_index (output_plugin_get_current ());
- }
-
- * n_elements = output_combo_elements->len;
- return (const ComboBoxElements *) output_combo_elements->data;
-}
-
-static void output_bit_depth_changed (void)
-{
- output_reset (OUTPUT_RESET_SOFT);
-}
-
-static void output_do_config (void * unused)
-{
- plugin_do_configure (output_plugin_get_current ());
-}
-
-static void output_do_about (void * unused)
-{
- plugin_do_about (output_plugin_get_current ());
-}
-
-static void * output_create_config_button (void)
-{
- bool_t enabled = plugin_has_configure (output_plugin_get_current ());
-
- output_config_button = audgui_button_new (_("_Settings"),
- "preferences-system", output_do_config, NULL);
- gtk_widget_set_sensitive (output_config_button, enabled);
-
- return output_config_button;
-}
-
-static void * output_create_about_button (void)
-{
- bool_t enabled = plugin_has_about (output_plugin_get_current ());
-
- output_about_button = audgui_button_new (_("_About"), "help-about", output_do_about, NULL);
- gtk_widget_set_sensitive (output_about_button, enabled);
-
- return output_about_button;
-}
-
-static void create_audio_category (void)
-{
- GtkWidget * audio_page_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- create_widgets ((GtkBox *) audio_page_vbox, audio_page_widgets, ARRAY_LEN (audio_page_widgets));
- gtk_container_add ((GtkContainer *) category_notebook, audio_page_vbox);
-}
-
-static void create_connectivity_category (void)
-{
- GtkWidget * connectivity_page_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add ((GtkContainer *) category_notebook, connectivity_page_vbox);
-
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_box_pack_start ((GtkBox *) connectivity_page_vbox, vbox, TRUE, TRUE, 0);
-
- create_widgets ((GtkBox *) vbox, connectivity_page_widgets, ARRAY_LEN (connectivity_page_widgets));
-}
-
-static void create_plugin_category (void)
-{
- plugin_notebook = gtk_notebook_new ();
- gtk_container_add ((GtkContainer *) category_notebook, plugin_notebook);
-
- for (int i = 0; i < ARRAY_LEN (plugin_categories); i ++)
- {
- const PluginCategory * cat = & plugin_categories[i];
- gtk_notebook_append_page ((GtkNotebook *) plugin_notebook,
- plugin_view_new (cat->type), gtk_label_new (_(cat->name)));
- }
-}
-
-static void destroy_cb (void)
-{
- prefswin = NULL;
- category_treeview = NULL;
- category_notebook = NULL;
- titlestring_entry = NULL;
-
- if (iface_combo_elements)
- {
- g_array_free (iface_combo_elements, TRUE);
- iface_combo_elements = NULL;
- }
-
- if (output_combo_elements)
- {
- g_array_free (output_combo_elements, TRUE);
- output_combo_elements = NULL;
- }
-}
-
-static void create_prefs_window (void)
-{
- prefswin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_type_hint ((GtkWindow *) prefswin, GDK_WINDOW_TYPE_HINT_DIALOG);
- gtk_container_set_border_width ((GtkContainer *) prefswin, 12);
- gtk_window_set_title ((GtkWindow *) prefswin, _("Audacious Settings"));
- gtk_window_set_default_size ((GtkWindow *) prefswin, 680, 400);
-
- GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add ((GtkContainer *) prefswin, vbox);
-
- GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
- gtk_box_pack_start ((GtkBox *) vbox, hbox, TRUE, TRUE, 0);
-
- GtkWidget * scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
- gtk_box_pack_start ((GtkBox *) hbox, scrolledwindow, FALSE, FALSE, 0);
- gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolledwindow,
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolledwindow, GTK_SHADOW_IN);
-
- category_treeview = gtk_tree_view_new ();
- gtk_container_add ((GtkContainer *) scrolledwindow, category_treeview);
- gtk_widget_set_size_request (scrolledwindow, 168, -1);
- gtk_tree_view_set_headers_visible ((GtkTreeView *) category_treeview, FALSE);
-
- category_notebook = gtk_notebook_new ();
- gtk_box_pack_start ((GtkBox *) hbox, category_notebook, TRUE, TRUE, 0);
-
- gtk_widget_set_can_focus (category_notebook, FALSE);
- gtk_notebook_set_show_tabs ((GtkNotebook *) category_notebook, FALSE);
- gtk_notebook_set_show_border ((GtkNotebook *) category_notebook, FALSE);
-
- create_appearance_category ();
- create_audio_category ();
- create_connectivity_category ();
- create_playlist_category ();
- create_song_info_category ();
- create_plugin_category ();
-
- GtkWidget * hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_start ((GtkBox *) vbox, hseparator, FALSE, FALSE, 6);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0);
-
- GtkWidget * audversionlabel = gtk_label_new (aud_version_string);
- gtk_box_pack_start ((GtkBox *) hbox, audversionlabel, FALSE, FALSE, 0);
- gtk_label_set_use_markup ((GtkLabel *) audversionlabel, TRUE);
-
- GtkWidget * prefswin_button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_start ((GtkBox *) hbox, prefswin_button_box, TRUE, TRUE, 0);
- gtk_button_box_set_layout ((GtkButtonBox *) prefswin_button_box, GTK_BUTTONBOX_END);
- gtk_box_set_spacing ((GtkBox *) prefswin_button_box, 6);
-
- GtkWidget * close = audgui_button_new (_("_Close"), "window-close",
- (AudguiCallback) gtk_widget_destroy, prefswin);
- gtk_container_add ((GtkContainer *) prefswin_button_box, close);
- gtk_widget_set_can_default (close, TRUE);
-
- fill_category_list ((GtkTreeView *) category_treeview, (GtkNotebook *) category_notebook);
-
- gtk_widget_show_all (vbox);
-
- g_signal_connect (prefswin, "destroy", (GCallback) destroy_cb, NULL);
-
- audgui_destroy_on_escape (prefswin);
-}
-
-void show_prefs_window (void)
-{
- if (! prefswin)
- create_prefs_window ();
-
- change_category (CATEGORY_APPEARANCE);
-
- gtk_window_present ((GtkWindow *) prefswin);
-}
-
-void show_prefs_for_plugin_type (int type)
-{
- if (! prefswin)
- create_prefs_window ();
-
- if (type == PLUGIN_TYPE_IFACE)
- change_category (CATEGORY_APPEARANCE);
- else if (type == PLUGIN_TYPE_OUTPUT)
- change_category (CATEGORY_AUDIO);
- else
- {
- change_category (CATEGORY_PLUGINS);
-
- for (int i = 0; i < ARRAY_LEN (plugin_categories); i ++)
- {
- if (plugin_categories[i].type == type)
- gtk_notebook_set_current_page ((GtkNotebook *) plugin_notebook, i);
- }
- }
-
- gtk_window_present ((GtkWindow *) prefswin);
-}
-
-void hide_prefs_window (void)
-{
- if (prefswin)
- gtk_widget_destroy (prefswin);
-}
diff --git a/src/audacious/ui_preferences.h b/src/audacious/ui_preferences.h
deleted file mode 100644
index b9b2707..0000000
--- a/src/audacious/ui_preferences.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * ui_preferences.h
- * Copyright 2006-2012 William Pitcock, Tomasz Moń, 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.
- */
-
-#ifndef AUDACIOUS_UI_PREFERENCES_H
-#define AUDACIOUS_UI_PREFERENCES_H
-
-#include <gtk/gtk.h>
-
-#include "types.h"
-
-void show_prefs_window(void);
-void hide_prefs_window(void);
-
-/* plugin-preferences.c */
-void plugin_make_about_window (PluginHandle * plugin);
-void plugin_make_config_window (PluginHandle * plugin);
-void plugin_misc_cleanup (PluginHandle * plugin);
-
-/* plugin-view.c */
-GtkWidget * plugin_view_new (int type);
-
-#endif /* AUDACIOUS_UI_PREFERENCES_H */
diff --git a/src/audacious/util.c b/src/audacious/util.c
deleted file mode 100644
index 3556e68..0000000
--- a/src/audacious/util.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * util.c
- * Copyright 2009-2013 John Lindgren and Michał Lipski
- *
- * 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 <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#ifdef __APPLE__
-#include <mach-o/dyld.h>
-#endif
-
-#include <glib.h>
-
-#include <libaudcore/audstrings.h>
-
-#include "debug.h"
-#include "i18n.h"
-#include "misc.h"
-#include "plugins.h"
-#include "util.h"
-
-bool_t dir_foreach (const char * path, DirForeachFunc func, void * user)
-{
- GDir * dir = g_dir_open (path, 0, NULL);
- if (! dir)
- return FALSE;
-
- const char * name;
- while ((name = g_dir_read_name (dir)))
- {
- char * full = filename_build (path, name);
- bool_t stop = func (full, name, user);
- str_unref (full);
-
- if (stop)
- break;
- }
-
- g_dir_close (dir);
- return TRUE;
-}
-
-char * construct_uri (const char * path, const char * reference)
-{
- /* URI */
- if (strstr (path, "://"))
- return str_get (path);
-
- /* absolute filename */
-#ifdef _WIN32
- if (path[0] && path[1] == ':' && path[2] == '\\')
-#else
- if (path[0] == '/')
-#endif
- return filename_to_uri (path);
-
- /* relative path */
- const char * slash = strrchr (reference, '/');
- if (! slash)
- return NULL;
-
- char * utf8 = str_to_utf8 (path, -1);
- if (! utf8)
- return NULL;
-
- int pathlen = slash + 1 - reference;
-
- char buf[pathlen + 3 * strlen (utf8) + 1];
- memcpy (buf, reference, pathlen);
-
- if (get_bool (NULL, "convert_backslash"))
- {
- SCOPY (tmp, utf8);
- str_replace_char (tmp, '\\', '/');
- str_encode_percent (tmp, -1, buf + pathlen);
- }
- else
- str_encode_percent (utf8, -1, buf + pathlen);
-
- str_unref (utf8);
- return str_get (buf);
-}
-
-void
-make_directory(const char * path, mode_t mode)
-{
- if (g_mkdir_with_parents(path, mode) == 0)
- return;
-
- g_printerr(_("Could not create directory (%s): %s\n"), path,
- g_strerror(errno));
-}
-
-char * write_temp_file (void * data, int64_t len)
-{
- char * temp = filename_build (g_get_tmp_dir (), "audacious-temp-XXXXXX");
- SCOPY (name, temp);
- str_unref (temp);
-
- int handle = g_mkstemp (name);
- if (handle < 0)
- {
- fprintf (stderr, "Error creating temporary file: %s\n", strerror (errno));
- return NULL;
- }
-
- while (len)
- {
- int64_t written = write (handle, data, len);
- if (written < 0)
- {
- fprintf (stderr, "Error writing %s: %s\n", name, strerror (errno));
- close (handle);
- return NULL;
- }
-
- data = (char *) data + written;
- len -= written;
- }
-
- if (close (handle) < 0)
- {
- fprintf (stderr, "Error closing %s: %s\n", name, strerror (errno));
- return NULL;
- }
-
- return str_get (name);
-}
-
-char * get_path_to_self (void)
-{
-#ifdef HAVE_PROC_SELF_EXE
- int size = 256;
-
- while (1)
- {
- char buf[size];
- int len;
-
- if ((len = readlink ("/proc/self/exe", buf, size)) < 0)
- {
- fprintf (stderr, "Cannot access /proc/self/exe: %s.\n", strerror (errno));
- return NULL;
- }
-
- if (len < size)
- {
- buf[len] = 0;
- return str_get (buf);
- }
-
- size += size;
- }
-#elif defined _WIN32
- int size = 256;
-
- while (1)
- {
- wchar_t buf[size];
- int len;
-
- if (! (len = GetModuleFileNameW (NULL, buf, size)))
- {
- fprintf (stderr, "GetModuleFileName failed.\n");
- return NULL;
- }
-
- if (len < size)
- {
- char * temp = g_utf16_to_utf8 (buf, len, NULL, NULL, NULL);
- char * path = str_get (temp);
- g_free (temp);
- return path;
- }
-
- size += size;
- }
-#elif defined __APPLE__
- unsigned int size = 256;
-
- while (1)
- {
- char buf[size];
- int res;
-
- if (! (res = _NSGetExecutablePath (buf, &size)))
- return str_get (buf);
-
- if (res != -1)
- return NULL;
- }
-#else
- return NULL;
-#endif
-}
-
-#ifdef _WIN32
-void get_argv_utf8 (int * argc, char * * * argv)
-{
- wchar_t * combined = GetCommandLineW ();
- wchar_t * * split = CommandLineToArgvW (combined, argc);
-
- * argv = g_new (char *, argc + 1);
-
- for (int i = 0; i < * argc; i ++)
- (* argv)[i] = g_utf16_to_utf8 (split[i], -1, NULL, NULL, NULL);
-
- (* argv)[* argc] = 0;
-
- LocalFree (split);
-}
-
-void free_argv_utf8 (int * argc, char * * * argv)
-{
- g_strfreev (* argv);
- * argc = 0;
- * argv = NULL;
-}
-#endif
-
-/* Strips various common top-level folders from a filename. The string passed
- * will not be modified, but the string returned will share the same memory.
- * Examples:
- * "/home/john/folder/file.mp3" -> "folder/file.mp3"
- * "/folder/file.mp3" -> "folder/file.mp3" */
-
-static char * skip_top_folders (char * name)
-{
- static const char * home;
- static int len;
-
- if (! home)
- {
- home = g_get_home_dir ();
- len = strlen (home);
-
- if (len > 0 && home[len - 1] == G_DIR_SEPARATOR)
- len --;
- }
-
-#ifdef _WIN32
- if (! g_ascii_strncasecmp (name, home, len) && name[len] == '\\')
-#else
- if (! strncmp (name, home, len) && name[len] == '/')
-#endif
- return name + len + 1;
-
-#ifdef _WIN32
- if (g_ascii_isalpha (name[0]) && name[1] == ':' && name[2] == '\\')
- return name + 3;
-#else
- if (name[0] == '/')
- return name + 1;
-#endif
-
- return name;
-}
-
-/* Divides a filename into the base name, the lowest folder, and the
- * second lowest folder. The string passed will be modified, and the strings
- * returned will use the same memory. May return NULL for <first> and <second>.
- * Examples:
- * "a/b/c/d/e.mp3" -> "e", "d", "c"
- * "d/e.mp3" -> "e", "d", NULL
- * "e.mp3" -> "e", NULL, NULL */
-
-static void split_filename (char * name, char * * base, char * * first,
- char * * second)
-{
- * first = * second = NULL;
-
- char * c;
-
- if ((c = strrchr (name, G_DIR_SEPARATOR)))
- {
- * base = c + 1;
- * c = 0;
- }
- else
- {
- * base = name;
- goto DONE;
- }
-
- if ((c = strrchr (name, G_DIR_SEPARATOR)))
- {
- * first = c + 1;
- * c = 0;
- }
- else
- {
- * first = name;
- goto DONE;
- }
-
- if ((c = strrchr (name, G_DIR_SEPARATOR)))
- * second = c + 1;
- else
- * second = name;
-
-DONE:
- if ((c = strrchr (* base, '.')))
- * c = 0;
-}
-
-/* Separates the domain name from an internet URI. The string passed will be
- * modified, and the string returned will share the same memory. May return
- * NULL. Examples:
- * "http://some.domain.org/folder/file.mp3" -> "some.domain.org"
- * "http://some.stream.fm:8000" -> "some.stream.fm" */
-
-static char * stream_name (char * name)
-{
- if (! strncmp (name, "http://", 7))
- name += 7;
- else if (! strncmp (name, "https://", 8))
- name += 8;
- else if (! strncmp (name, "mms://", 6))
- name += 6;
- else
- return NULL;
-
- char * c;
-
- if ((c = strchr (name, '/')))
- * c = 0;
- if ((c = strchr (name, ':')))
- * c = 0;
- if ((c = strchr (name, '?')))
- * c = 0;
-
- return name;
-}
-
-static char * get_nonblank_field (const Tuple * tuple, int field)
-{
- char * str = tuple ? tuple_get_str (tuple, field) : NULL;
-
- if (str && ! str[0])
- {
- str_unref (str);
- str = NULL;
- }
-
- return str;
-}
-
-static char * str_get_decoded (char * str)
-{
- if (! str)
- return NULL;
-
- str_decode_percent (str, -1, str);
- return str_get (str);
-}
-
-/* Derives best guesses of title, artist, and album from a file name (URI) and
- * tuple (which may be NULL). The returned strings are stringpooled or NULL. */
-
-void describe_song (const char * name, const Tuple * tuple, char * * _title,
- char * * _artist, char * * _album)
-{
- /* Common folder names to skip */
- static const char * const skip[] = {"music"};
-
- char * title = get_nonblank_field (tuple, FIELD_TITLE);
- char * artist = get_nonblank_field (tuple, FIELD_ARTIST);
- char * album = get_nonblank_field (tuple, FIELD_ALBUM);
-
- if (title && artist && album)
- {
-DONE:
- * _title = title;
- * _artist = artist;
- * _album = album;
- return;
- }
-
- if (! strncmp (name, "file:///", 8))
- {
- char * filename = uri_to_display (name);
- if (! filename)
- goto DONE;
-
- SCOPY (buf, filename);
-
- char * base, * first, * second;
- split_filename (skip_top_folders (buf), & base, & first, & second);
-
- if (! title)
- title = str_get (base);
-
- for (int i = 0; i < ARRAY_LEN (skip); i ++)
- {
- if (first && ! g_ascii_strcasecmp (first, skip[i]))
- first = NULL;
- if (second && ! g_ascii_strcasecmp (second, skip[i]))
- second = NULL;
- }
-
- if (first)
- {
- if (second && ! artist && ! album)
- {
- artist = str_get (second);
- album = str_get (first);
- }
- else if (! artist)
- artist = str_get (first);
- else if (! album)
- album = str_get (first);
- }
-
- str_unref (filename);
- }
- else
- {
- SCOPY (buf, name);
-
- if (! title)
- {
- title = str_get_decoded (stream_name (buf));
-
- if (! title)
- title = str_get_decoded (buf);
- }
- else if (! artist)
- artist = str_get_decoded (stream_name (buf));
- else if (! album)
- album = str_get_decoded (stream_name (buf));
- }
-
- goto DONE;
-}
-
-char * last_path_element (char * path)
-{
- char * slash = strrchr (path, G_DIR_SEPARATOR);
- return (slash && slash[1]) ? slash + 1 : NULL;
-}
-
-void cut_path_element (char * path, char * elem)
-{
-#ifdef _WIN32
- if (elem > path + 3)
-#else
- if (elem > path + 1)
-#endif
- elem[-1] = 0; /* overwrite slash */
- else
- elem[0] = 0; /* leave [drive letter and] leading slash */
-}
diff --git a/src/audacious/debug.h b/src/audacious/util.cc
index 2b372ad..c4449de 100644
--- a/src/audacious/debug.h
+++ b/src/audacious/util.cc
@@ -1,6 +1,6 @@
/*
- * debug.h
- * Copyright 2010-2011 John Lindgren
+ * util.c
+ * Copyright 2009-2013 John Lindgren and Michał Lipski
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -17,17 +17,32 @@
* the use of this software.
*/
-#ifndef AUDACIOUS_DEBUG_H
-#define AUDACIOUS_DEBUG_H
+#include "util.h"
-#include <stdio.h>
+#ifdef _WIN32
+#include <windows.h>
-#include <audacious/api.h>
-
-#ifdef _AUDACIOUS_CORE
-#define AUDDBG(...) do {if (verbose) {printf ("%s:%d [%s]: ", __FILE__, __LINE__, __FUNCTION__); printf (__VA_ARGS__);}} while (0)
+#ifdef WORDS_BIGENDIAN
+#define UTF16_NATIVE "UTF-16BE"
#else
-#define AUDDBG(...) do {if (* _aud_api_table->verbose) {printf ("%s:%d [%s]: ", __FILE__, __LINE__, __FUNCTION__); printf (__VA_ARGS__);}} while (0)
+#define UTF16_NATIVE "UTF-16LE"
#endif
+Index<String> get_argv_utf8 ()
+{
+ int argc;
+ wchar_t * combined = GetCommandLineW ();
+ wchar_t * * split = CommandLineToArgvW (combined, & argc);
+
+ Index<String> argv;
+ argv.insert (0, argc);
+
+ for (int i = 0; i < argc; i ++)
+ argv[i] = String (str_convert ((char *) split[i],
+ wcslen (split[i]) * sizeof (wchar_t), UTF16_NATIVE, "UTF-8"));
+
+ LocalFree (split);
+ return argv;
+}
+
#endif
diff --git a/src/audacious/util.h b/src/audacious/util.h
index 7f92cb3..55bfd6b 100644
--- a/src/audacious/util.h
+++ b/src/audacious/util.h
@@ -1,6 +1,6 @@
/*
* util.h
- * Copyright 2009-2013 John Lindgren
+ * Copyright 2014 John Lindgren
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -20,29 +20,10 @@
#ifndef AUDACIOUS_UTIL_H
#define AUDACIOUS_UTIL_H
-#include <sys/types.h>
-#include <libaudcore/core.h>
-
-typedef bool_t(*DirForeachFunc) (const char * path,
- const char * basename,
- void * user_data);
-
-bool_t dir_foreach (const char * path, DirForeachFunc func, void * user_data);
-
-void make_directory(const char * path, mode_t mode);
-char * write_temp_file (void * data, int64_t len); /* pooled */
-
-char * get_path_to_self (void); /* pooled */
+#include <libaudcore/audstrings.h>
#ifdef _WIN32
-void get_argv_utf8 (int * argc, char * * * argv);
-void free_argv_utf8 (int * argc, char * * * argv);
+Index<String> get_argv_utf8 ();
#endif
-void describe_song (const char * filename, const Tuple * tuple,
- char * * title, char * * artist, char * * album);
-
-char * last_path_element (char * path);
-void cut_path_element (char * path, char * elem);
-
#endif /* AUDACIOUS_UTIL_H */
diff --git a/src/audacious/vis_runner.c b/src/audacious/vis_runner.c
deleted file mode 100644
index ba8390c..0000000
--- a/src/audacious/vis_runner.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * vis_runner.c
- * Copyright 2009-2012 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 <assert.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "output.h"
-#include "vis_runner.h"
-#include "visualization.h"
-
-#define INTERVAL 30 /* milliseconds */
-#define FRAMES_PER_NODE 512
-
-struct _VisNode {
- struct _VisNode * next;
- int channels;
- int time;
- float data[];
-};
-
-typedef struct _VisNode VisNode;
-
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static bool_t enabled = FALSE;
-static bool_t playing = FALSE, paused = FALSE, active = FALSE;
-static VisNode * current_node = NULL;
-static int current_frames;
-static VisNode * vis_list = NULL;
-static VisNode * vis_list_tail = NULL;
-static VisNode * vis_pool = NULL;
-static int send_source = 0, clear_source = 0;
-
-static VisNode * alloc_node_locked (int channels)
-{
- VisNode * node;
-
- if (vis_pool)
- {
- node = vis_pool;
- assert (node->channels == channels);
- vis_pool = node->next;
- }
- else
- {
- node = g_malloc (offsetof (VisNode, data) + sizeof (float) * channels * FRAMES_PER_NODE);
- node->channels = channels;
- }
-
- node->next = NULL;
- return node;
-}
-
-static void free_node_locked (VisNode * node)
-{
- node->next = vis_pool;
- vis_pool = node;
-}
-
-static void push_node_locked (VisNode * node)
-{
- if (vis_list)
- vis_list_tail->next = node;
- else
- vis_list = node;
-
- vis_list_tail = node;
-}
-
-static VisNode * pop_node_locked (void)
-{
- VisNode * node = vis_list;
- vis_list = node->next;
- node->next = NULL;
-
- if (vis_list_tail == node)
- vis_list_tail = NULL;
-
- return node;
-}
-
-static bool_t send_audio (void * unused)
-{
- /* call before locking mutex to avoid deadlock */
- int outputted = output_get_raw_time ();
-
- pthread_mutex_lock (& mutex);
-
- if (! send_source)
- {
- pthread_mutex_unlock (& mutex);
- return FALSE;
- }
-
- VisNode * vis_node = NULL;
-
- while (vis_list)
- {
- /* If we are considering a node, stop searching and use it if it is the
- * most recent (that is, the next one is in the future). Otherwise,
- * consider the next node if it is not in the future by more than the
- * length of an interval. */
- if (vis_list->time > outputted + (vis_node ? 0 : INTERVAL))
- break;
-
- if (vis_node)
- free_node_locked (vis_node);
-
- vis_node = pop_node_locked ();
- }
-
- pthread_mutex_unlock (& mutex);
-
- if (! vis_node)
- return TRUE;
-
- vis_send_audio (vis_node->data, vis_node->channels);
-
- pthread_mutex_lock (& mutex);
- free_node_locked (vis_node);
- pthread_mutex_unlock (& mutex);
-
- return TRUE;
-}
-
-static bool_t send_clear (void * unused)
-{
- pthread_mutex_lock (& mutex);
- clear_source = 0;
- pthread_mutex_unlock (& mutex);
-
- vis_send_clear ();
-
- return FALSE;
-}
-
-static void flush_locked (void)
-{
- g_free (current_node);
- current_node = NULL;
-
- while (vis_list)
- {
- VisNode * node = vis_list;
- vis_list = node->next;
- g_free (node);
- }
-
- vis_list_tail = NULL;
-
- while (vis_pool)
- {
- VisNode * node = vis_pool;
- vis_pool = node->next;
- g_free (node);
- }
-
- if (! clear_source)
- clear_source = g_timeout_add (0, send_clear, NULL);
-}
-
-void vis_runner_flush (void)
-{
- pthread_mutex_lock (& mutex);
- flush_locked ();
- pthread_mutex_unlock (& mutex);
-}
-
-static void start_stop_locked (bool_t new_playing, bool_t new_paused)
-{
- playing = new_playing;
- paused = new_paused;
- active = playing && enabled;
-
- if (send_source)
- {
- g_source_remove (send_source);
- send_source = 0;
- }
-
- if (clear_source)
- {
- g_source_remove (clear_source);
- clear_source = 0;
- }
-
- if (! active)
- flush_locked ();
- else if (! paused)
- send_source = g_timeout_add (INTERVAL, send_audio, NULL);
-}
-
-void vis_runner_start_stop (bool_t new_playing, bool_t new_paused)
-{
- pthread_mutex_lock (& mutex);
- start_stop_locked (new_playing, new_paused);
- pthread_mutex_unlock (& mutex);
-}
-
-void vis_runner_pass_audio (int time, float * data, int samples, int
- channels, int rate)
-{
- pthread_mutex_lock (& mutex);
-
- if (! active)
- goto UNLOCK;
-
- /* We can build a single node from multiple calls; we can also build
- * multiple nodes from the same call. If current_node is present, it was
- * partly built in the last call and needs to be finished. */
-
- int at = 0;
-
- while (1)
- {
- if (current_node)
- assert (current_node->channels == channels);
- else
- {
- int node_time = time;
-
- /* There is no partly-built node, so start a new one. Normally
- * there will be nodes in the queue already; if so, we want to copy
- * audio data from the signal starting at 30 milliseconds after the
- * beginning of the most recent node. If there are no nodes in the
- * queue, we are at the beginning of the song or had an underrun,
- * and we want to copy the earliest audio data we have. */
-
- if (vis_list_tail)
- node_time = vis_list_tail->time + INTERVAL;
-
- at = channels * (int) ((int64_t) (node_time - time) * rate / 1000);
-
- if (at < 0)
- at = 0;
- if (at >= samples)
- break;
-
- current_node = alloc_node_locked (channels);
- current_node->time = node_time;
- current_frames = 0;
- }
-
- /* Copy as much data as we can, limited by how much we have and how much
- * space is left in the node. If we cannot fill the node, we return and
- * wait for more data to be passed in the next call. If we do fill the
- * node, we loop and start building a new one. */
-
- int copy = MIN (samples - at, channels * (FRAMES_PER_NODE - current_frames));
- memcpy (current_node->data + channels * current_frames, data + at, sizeof (float) * copy);
- current_frames += copy / channels;
-
- if (current_frames < FRAMES_PER_NODE)
- break;
-
- push_node_locked (current_node);
- current_node = NULL;
- }
-
-UNLOCK:
- pthread_mutex_unlock (& mutex);
-}
-
-void vis_runner_enable (bool_t enable)
-{
- pthread_mutex_lock (& mutex);
- enabled = enable;
- start_stop_locked (playing, paused);
- pthread_mutex_unlock (& mutex);
-}
diff --git a/src/audacious/vis_runner.h b/src/audacious/vis_runner.h
deleted file mode 100644
index 4b08c5b..0000000
--- a/src/audacious/vis_runner.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * vis_runner.h
- * Copyright 2009-2010 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.
- */
-
-#ifndef AUD_VIS_RUNNER_H
-#define AUD_VIS_RUNNER_H
-
-#include <libaudcore/core.h>
-
-void vis_runner_start_stop (bool_t playing, bool_t paused);
-void vis_runner_pass_audio (int time, float * data, int samples, int channels, int rate);
-void vis_runner_flush (void);
-void vis_runner_enable (bool_t enable);
-
-#endif
diff --git a/src/audacious/visualization.c b/src/audacious/visualization.c
deleted file mode 100644
index 85ef430..0000000
--- a/src/audacious/visualization.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * visualization.c
- * Copyright 2010-2011 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 <glib.h>
-#include <gtk/gtk.h>
-#include <string.h>
-
-#include "debug.h"
-#include "fft.h"
-#include "interface.h"
-#include "misc.h"
-#include "plugin.h"
-#include "plugins.h"
-#include "ui_preferences.h"
-#include "visualization.h"
-#include "vis_runner.h"
-
-static GList * vis_funcs[AUD_VIS_TYPES];
-
-typedef struct {
- PluginHandle * plugin;
- VisPlugin * header;
- GtkWidget * widget;
-} LoadedVis;
-
-static int running = FALSE;
-static GList * loaded_vis_plugins = NULL;
-
-void vis_func_add (int type, GCallback func)
-{
- g_return_if_fail (type >= 0 && type < AUD_VIS_TYPES);
- vis_funcs[type] = g_list_prepend (vis_funcs[type], (void *) func);
-
- vis_runner_enable (TRUE);
-}
-
-void vis_func_remove (GCallback func)
-{
- bool_t disable = TRUE;
-
- for (int i = 0; i < AUD_VIS_TYPES; i ++)
- {
- vis_funcs[i] = g_list_remove_all (vis_funcs[i], (void *) func);
- if (vis_funcs[i])
- disable = FALSE;
- }
-
- if (disable)
- vis_runner_enable (FALSE);
-}
-
-void vis_send_clear (void)
-{
- for (GList * node = vis_funcs[AUD_VIS_TYPE_CLEAR]; node; node = node->next)
- {
- void (* func) (void) = (void (*) (void)) node->data;
- func ();
- }
-}
-
-static void pcm_to_mono (const float * data, float * mono, int channels)
-{
- if (channels == 1)
- memcpy (mono, data, sizeof (float) * 512);
- else
- {
- float * set = mono;
- while (set < & mono[512])
- {
- * set ++ = (data[0] + data[1]) / 2;
- data += channels;
- }
- }
-}
-
-void vis_send_audio (const float * data, int channels)
-{
- float mono[512];
- float freq[256];
-
- if (vis_funcs[AUD_VIS_TYPE_MONO_PCM] || vis_funcs[AUD_VIS_TYPE_FREQ])
- pcm_to_mono (data, mono, channels);
- if (vis_funcs[AUD_VIS_TYPE_FREQ])
- calc_freq (mono, freq);
-
- for (GList * node = vis_funcs[AUD_VIS_TYPE_MONO_PCM]; node; node = node->next)
- {
- void (* func) (const float *) = (void (*) (const float *)) node->data;
- func (mono);
- }
-
- for (GList * node = vis_funcs[AUD_VIS_TYPE_MULTI_PCM]; node; node = node->next)
- {
- void (* func) (const float *, int) = (void (*) (const float *, int)) node->data;
- func (data, channels);
- }
-
- for (GList * node = vis_funcs[AUD_VIS_TYPE_FREQ]; node; node = node->next)
- {
- void (* func) (const float *) = (void (*) (const float *)) node->data;
- func (freq);
- }
-}
-
-static int vis_find_cb (LoadedVis * vis, PluginHandle * plugin)
-{
- return (vis->plugin == plugin) ? 0 : -1;
-}
-
-static void vis_load (PluginHandle * plugin)
-{
- GList * node = g_list_find_custom (loaded_vis_plugins, plugin,
- (GCompareFunc) vis_find_cb);
- if (node != NULL)
- return;
-
- AUDDBG ("Loading %s.\n", plugin_get_name (plugin));
- VisPlugin * header = plugin_get_header (plugin);
- g_return_if_fail (header != NULL);
-
- LoadedVis * vis = g_slice_new (LoadedVis);
- vis->plugin = plugin;
- vis->header = header;
- vis->widget = NULL;
-
- if (header->get_widget != NULL)
- vis->widget = header->get_widget ();
-
- if (vis->widget != NULL)
- {
- AUDDBG ("Adding %s to interface.\n", plugin_get_name (plugin));
- g_signal_connect (vis->widget, "destroy", (GCallback)
- gtk_widget_destroyed, & vis->widget);
- interface_add_plugin_widget (plugin, vis->widget);
- }
-
- if (PLUGIN_HAS_FUNC (header, clear))
- vis_func_add (AUD_VIS_TYPE_CLEAR, (GCallback) header->clear);
- if (PLUGIN_HAS_FUNC (header, render_mono_pcm))
- vis_func_add (AUD_VIS_TYPE_MONO_PCM, (GCallback) header->render_mono_pcm);
- if (PLUGIN_HAS_FUNC (header, render_multi_pcm))
- vis_func_add (AUD_VIS_TYPE_MULTI_PCM, (GCallback) header->render_multi_pcm);
- if (PLUGIN_HAS_FUNC (header, render_freq))
- vis_func_add (AUD_VIS_TYPE_FREQ, (GCallback) header->render_freq);
-
- loaded_vis_plugins = g_list_prepend (loaded_vis_plugins, vis);
-}
-
-static void vis_unload (PluginHandle * plugin)
-{
- GList * node = g_list_find_custom (loaded_vis_plugins, plugin,
- (GCompareFunc) vis_find_cb);
- if (node == NULL)
- return;
-
- AUDDBG ("Unloading %s.\n", plugin_get_name (plugin));
- LoadedVis * vis = node->data;
- loaded_vis_plugins = g_list_delete_link (loaded_vis_plugins, node);
-
- VisPlugin * header = vis->header;
- if (PLUGIN_HAS_FUNC (header, clear))
- vis_func_remove ((GCallback) header->clear);
- if (PLUGIN_HAS_FUNC (header, render_mono_pcm))
- vis_func_remove ((GCallback) header->render_mono_pcm);
- if (PLUGIN_HAS_FUNC (header, render_multi_pcm))
- vis_func_remove ((GCallback) header->render_multi_pcm);
- if (PLUGIN_HAS_FUNC (header, render_freq))
- vis_func_remove ((GCallback) header->render_freq);
-
- if (vis->widget != NULL)
- {
- AUDDBG ("Removing %s from interface.\n", plugin_get_name (plugin));
- interface_remove_plugin_widget (plugin, vis->widget);
- g_return_if_fail (vis->widget == NULL); /* not destroyed? */
- }
-
- g_slice_free (LoadedVis, vis);
-}
-
-static bool_t vis_init_cb (PluginHandle * plugin)
-{
- vis_load (plugin);
- return TRUE;
-}
-
-void vis_init (void)
-{
- g_return_if_fail (! running);
- running = TRUE;
-
- plugin_for_enabled (PLUGIN_TYPE_VIS, (PluginForEachFunc) vis_init_cb, NULL);
-}
-
-static void vis_cleanup_cb (LoadedVis * vis)
-{
- vis_unload (vis->plugin);
-}
-
-void vis_cleanup (void)
-{
- g_return_if_fail (running);
- running = FALSE;
-
- g_list_foreach (loaded_vis_plugins, (GFunc) vis_cleanup_cb, NULL);
-}
-
-bool_t vis_plugin_start (PluginHandle * plugin)
-{
- VisPlugin * vp = plugin_get_header (plugin);
- g_return_val_if_fail (vp != NULL, FALSE);
-
- if (vp->init != NULL && ! vp->init ())
- return FALSE;
-
- if (running)
- vis_load (plugin);
-
- return TRUE;
-}
-
-void vis_plugin_stop (PluginHandle * plugin)
-{
- VisPlugin * vp = plugin_get_header (plugin);
- g_return_if_fail (vp != NULL);
-
- if (running)
- vis_unload (plugin);
-
- if (vp->cleanup != NULL)
- vp->cleanup ();
-}
-
-PluginHandle * vis_plugin_by_widget (/* GtkWidget * */ void * widget)
-{
- g_return_val_if_fail (widget, NULL);
-
- for (GList * node = loaded_vis_plugins; node; node = node->next)
- {
- LoadedVis * vis = node->data;
- if (vis->widget == widget)
- return vis->plugin;
- }
-
- return NULL;
-}
diff --git a/src/audacious/visualization.h b/src/audacious/visualization.h
deleted file mode 100644
index f57e86e..0000000
--- a/src/audacious/visualization.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * visualization.h
- * Copyright 2010-2011 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.
- */
-
-#ifndef AUDACIOUS_VISUALIZATION_H
-#define AUDACIOUS_VISUALIZATION_H
-
-#include "plugins.h"
-
-void vis_send_clear (void);
-void vis_send_audio (const float * data, int channels);
-
-void vis_init (void);
-void vis_cleanup (void);
-
-bool_t vis_plugin_start (PluginHandle * plugin);
-void vis_plugin_stop (PluginHandle * plugin);
-
-PluginHandle * vis_plugin_by_widget (/* GtkWidget * */ void * widget);
-
-#endif