summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deadbeef.h43
-rw-r--r--playlist.c105
2 files changed, 125 insertions, 23 deletions
diff --git a/deadbeef.h b/deadbeef.h
index 3871be25..4c31f809 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -90,6 +90,12 @@ extern "C" {
#define DDB_API_LEVEL DB_API_VERSION_MINOR
#endif
+#if (DDB_API_LEVEL >= 5)
+#define DEPRECATED_15 __attribute__ ((deprecated("since deadbeef API 1.5")))
+#else
+#define DEPRECATED_15
+#endif
+
#define DDB_PLUGIN_SET_API_VERSION\
.plugin.api_vmajor = DB_API_VERSION_MAJOR,\
.plugin.api_vminor = DB_API_VERSION_MINOR,
@@ -367,11 +373,17 @@ typedef struct {
#if (DDB_API_LEVEL >= 5)
#define DDB_FREQ_BANDS 256
#define DDB_FREQ_MAX_CHANNELS 9
-typedef struct {
+typedef struct ddb_audio_data_s {
const ddb_waveformat_t *fmt;
const float *data;
int nframes;
} ddb_audio_data_t;
+
+typedef struct ddb_fileadd_data_s {
+ int visibility;
+ ddb_playlist_t *plt;
+ ddb_playItem_t *track;
+} ddb_fileadd_data_t;
#endif
// forward decl for plugin struct
@@ -537,8 +549,8 @@ typedef struct {
// operating on playlist items
DB_playItem_t * (*plt_insert_item) (ddb_playlist_t *playlist, DB_playItem_t *after, DB_playItem_t *it);
- DB_playItem_t * (*plt_insert_file) (ddb_playlist_t *playlist, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
- DB_playItem_t *(*plt_insert_dir) (ddb_playlist_t *plt, DB_playItem_t *after, const char *dirname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
+ DB_playItem_t * (*plt_insert_file) (ddb_playlist_t *playlist, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) DEPRECATED_15;
+ DB_playItem_t *(*plt_insert_dir) (ddb_playlist_t *plt, DB_playItem_t *after, const char *dirname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) DEPRECATED_15;
void (*plt_set_item_duration) (ddb_playlist_t *plt, DB_playItem_t *it, float duration);
int (*plt_remove_item) (ddb_playlist_t *playlist, DB_playItem_t *it);
int (*plt_getselcount) (ddb_playlist_t *playlist);
@@ -879,6 +891,23 @@ typedef struct {
// save referenced playlist in config
int (*plt_save_n) (int n);
int (*plt_save_config) (ddb_playlist_t *plt);
+
+ // register file added callback
+ // the callback will be called for each file
+ // the visibility is taken from plt_add_* arguments
+
+ void (*listen_file_added) (int (*callback)(ddb_fileadd_data_t *data, void *user_data), void *user_data);
+ void (*unlisten_file_added) (int (*callback)(ddb_fileadd_data_t *data, void *user_data), void *user_data);
+
+ // visibility is a number, which tells listeners about the caller
+ // 0 is reserved for callers which want the GUI to intercept the calls,
+ // and show visual updates.
+ // this is the default value passed from plt_load, plt_add_dir, plt_add_file.
+ DB_playItem_t * (*plt_load2) (int visibility, ddb_playlist_t *plt, ddb_playItem_t *after, const char *fname, int *pabort);
+ int (*plt_add_file2) (int visibility, ddb_playlist_t *plt, const char *fname);
+ int (*plt_add_dir2) (int visibility, ddb_playlist_t *plt, const char *dirname);
+ ddb_playItem_t * (*plt_insert_file2) (int visibility, ddb_playlist_t *playlist, ddb_playItem_t *after, const char *fname, int *pabort);
+ ddb_playItem_t *(*plt_insert_dir2) (int visibility, ddb_playlist_t *plt, ddb_playItem_t *after, const char *dirname, int *pabort);
#endif
} DB_functions_t;
@@ -1203,8 +1232,7 @@ typedef struct DB_vfs_s {
int (*is_container) (const char *fname); // should return 1 if this plugin can parse specified file
-// this is an evil hack to interrupt frozen vfs_curl streams
-// FIXME: pass it through command API
+// this allows interruption of hanging network streams
void (*abort) (DB_FILE *stream);
// file access, follows stdio API with few extension
@@ -1274,6 +1302,11 @@ typedef struct DB_playlist_s {
int (*save) (ddb_playlist_t *plt, const char *fname, DB_playItem_t *first, DB_playItem_t *last);
const char **extensions; // NULL-terminated list of supported file extensions, e.g. {"m3u", "pls", NULL}
+
+ // since 1.5
+#if (DDB_API_LEVEL >= 5)
+ DB_playItem_t * (*load2) (int visibility, ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort);
+#endif
} DB_playlist_t;
#ifdef __cplusplus
diff --git a/playlist.c b/playlist.c
index c6a330d9..0f8c1899 100644
--- a/playlist.c
+++ b/playlist.c
@@ -1232,11 +1232,14 @@ plt_insert_cue (playlist_t *plt, playItem_t *after, playItem_t *origin, int nums
static int follow_symlinks = 0;
static int ignore_archives = 0;
-playItem_t *
-plt_insert_dir_int (playlist_t *playlist, DB_vfs_t *vfs, playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data);
+static playItem_t *
+plt_insert_dir_int (int visibility, playlist_t *playlist, DB_vfs_t *vfs, playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data);
-playItem_t *
-plt_insert_file (playlist_t *playlist, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
+static playItem_t *
+plt_load_int (int visibility, playlist_t *plt, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data);
+
+static playItem_t *
+plt_insert_file_int (int visibility, playlist_t *playlist, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
trace ("count: %d\n", playlist->count[PL_MAIN]);
trace ("pl_insert_file %s\n", fname);
if (!fname || !(*fname)) {
@@ -1251,7 +1254,7 @@ plt_insert_file (playlist_t *playlist, playItem_t *after, const char *fname, int
trace ("%s cont test\n", fname);
if (vfsplugs[i]->is_container (fname)) {
trace ("inserting %s via vfs %s\n", fname, vfsplugs[i]->plugin.id);
- playItem_t *it = plt_insert_dir_int (playlist, vfsplugs[i], after, fname, pabort, cb, user_data);
+ playItem_t *it = plt_insert_dir_int (visibility, playlist, vfsplugs[i], after, fname, pabort, cb, user_data);
if (it) {
return it;
}
@@ -1376,12 +1379,17 @@ plt_insert_file (playlist_t *playlist, playItem_t *after, const char *fname, int
return NULL;
}
+playItem_t *
+plt_insert_file (playlist_t *playlist, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
+ return plt_insert_file_int (0, playlist, after, fname, pabort, cb, user_data);
+}
+
static int dirent_alphasort (const struct dirent **a, const struct dirent **b) {
return strcmp ((*a)->d_name, (*b)->d_name);
}
-playItem_t *
-plt_insert_dir_int (playlist_t *playlist, DB_vfs_t *vfs, playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
+static playItem_t *
+plt_insert_dir_int (int visibility, playlist_t *playlist, DB_vfs_t *vfs, playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
if (!strncmp (dirname, "file://", 7)) {
dirname += 7;
}
@@ -1419,16 +1427,16 @@ plt_insert_dir_int (playlist_t *playlist, DB_vfs_t *vfs, playItem_t *after, cons
if (!vfs) {
char fullname[PATH_MAX];
snprintf (fullname, sizeof (fullname), "%s/%s", dirname, namelist[i]->d_name);
- inserted = plt_insert_dir_int (playlist, vfs, after, fullname, pabort, cb, user_data);
+ inserted = plt_insert_dir_int (visibility, playlist, vfs, after, fullname, pabort, cb, user_data);
if (!inserted) {
- inserted = plt_insert_file (playlist, after, fullname, pabort, cb, user_data);
+ inserted = plt_insert_file_int (visibility, playlist, after, fullname, pabort, cb, user_data);
}
}
else {
- inserted = plt_insert_file (playlist, after, namelist[i]->d_name, pabort, cb, user_data);
+ inserted = plt_insert_file_int (visibility, playlist, after, namelist[i]->d_name, pabort, cb, user_data);
if (!inserted) {
// special case for loading playlists in zip files
- inserted = plt_load (playlist, after, namelist[i]->d_name, pabort, cb, user_data);
+ inserted = plt_load_int (visibility, playlist, after, namelist[i]->d_name, pabort, cb, user_data);
}
}
if (inserted) {
@@ -1450,17 +1458,17 @@ plt_insert_dir (playlist_t *playlist, playItem_t *after, const char *dirname, in
follow_symlinks = conf_get_int ("add_folders_follow_symlinks", 0);
ignore_archives = conf_get_int ("ignore_archives", 1);
- playItem_t *ret = plt_insert_dir_int (playlist, NULL, after, dirname, pabort, cb, user_data);
+ playItem_t *ret = plt_insert_dir_int (0, playlist, NULL, after, dirname, pabort, cb, user_data);
ignore_archives = 0;
return ret;
}
-int
-plt_add_file (playlist_t *plt, const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data) {
+static int
+plt_add_file_int (int visibility, playlist_t *plt, const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data) {
int abort = 0;
- playItem_t *it = plt_insert_file (plt, plt->tail[PL_MAIN], fname, &abort, cb, user_data);
+ playItem_t *it = plt_insert_file_int (visibility, plt, plt->tail[PL_MAIN], fname, &abort, cb, user_data);
if (it) {
// pl_insert_file doesn't hold reference, don't unref here
return 0;
@@ -1469,6 +1477,11 @@ plt_add_file (playlist_t *plt, const char *fname, int (*cb)(playItem_t *it, void
}
int
+plt_add_file (playlist_t *plt, const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data) {
+ return plt_add_file_int (0, plt, fname, cb, user_data);
+}
+
+int
plt_add_dir (playlist_t *plt, const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data) {
int abort = 0;
playItem_t *it = plt_insert_dir (plt, plt->tail[PL_MAIN], dirname, &abort, cb, user_data);
@@ -1914,6 +1927,9 @@ plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fnam
for (playItem_t *it = plt->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
uint16_t l;
uint8_t ll;
+ if (cb) {
+ cb(it, user_data);
+ }
#if (PLAYLIST_MINOR_VER==2)
const char *fname = pl_find_meta_raw (it, ":URI");
l = strlen (fname);
@@ -2141,8 +2157,8 @@ pl_save_all (void) {
return err;
}
-playItem_t *
-plt_load (playlist_t *plt, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
+static playItem_t *
+plt_load_int (int visibility, playlist_t *plt, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
// try plugins 1st
const char *ext = strrchr (fname, '.');
if (ext) {
@@ -2153,7 +2169,13 @@ plt_load (playlist_t *plt, playItem_t *after, const char *fname, int *pabort, in
for (p = 0; plug[p]; p++) {
for (e = 0; plug[p]->extensions[e]; e++) {
if (plug[p]->load && !strcasecmp (ext, plug[p]->extensions[e])) {
- DB_playItem_t *it = plug[p]->load ((ddb_playlist_t *)plt, (DB_playItem_t *)after, fname, pabort, (int (*)(DB_playItem_t *, void *))cb, user_data);
+ DB_playItem_t *it = NULL;
+ if (cb || (plug[p]->load && !plug[p]->load2)) {
+ it = plug[p]->load ((ddb_playlist_t *)plt, (DB_playItem_t *)after, fname, pabort, (int (*)(DB_playItem_t *, void *))cb, user_data);
+ }
+ else if (plug[p]->load2) {
+ plug[p]->load2 (visibility, (ddb_playlist_t *)plt, (DB_playItem_t *)after, fname, pabort);
+ }
return (playItem_t *)it;
}
}
@@ -2419,6 +2441,12 @@ load_fail:
return last_added;
}
+
+playItem_t *
+plt_load (playlist_t *plt, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
+ return plt_load_int (0, plt, after, fname, pabort, cb, user_data);
+}
+
int
pl_load_all (void) {
int i = 0;
@@ -3910,3 +3938,44 @@ plt_save_config (playlist_t *plt) {
}
return plt_save_n (i);
}
+
+void
+listen_file_added (int (*callback)(ddb_fileadd_data_t *data, void *user_data), void *user_data) {
+}
+
+void
+unlisten_file_added (int (*callback)(ddb_fileadd_data_t *data, void *user_data), void *user_data) {
+}
+
+DB_playItem_t *
+plt_load2 (int visibility, playlist_t *plt, playItem_t *after, const char *fname, int *pabort) {
+ plt_load_int (visibility, plt, after, fname, pabort, NULL, NULL);
+}
+
+int
+plt_add_file2 (int visibility, playlist_t *plt, const char *fname) {
+ return plt_add_file_int (visibility, plt, fname, NULL, NULL);
+}
+
+int
+plt_add_dir2 (int visibility, playlist_t *plt, const char *dirname) {
+ follow_symlinks = conf_get_int ("add_folders_follow_symlinks", 0);
+ ignore_archives = conf_get_int ("ignore_archives", 1);
+ int abort = 0;
+ playItem_t *it = plt_insert_dir_int (visibility, plt, NULL, plt->tail[PL_MAIN], dirname, &abort, NULL, NULL);
+ if (it) {
+ // pl_insert_file doesn't hold reference, don't unref here
+ return 0;
+ }
+ return -1;
+}
+
+playItem_t *
+plt_insert_file2 (int visibility, playlist_t *playlist, playItem_t *after, const char *fname, int *pabort) {
+ return plt_insert_file_int (visibility, playlist, after, fname, pabort, NULL, NULL);
+}
+
+playItem_t *
+plt_insert_dir2 (int visibility, playlist_t *plt, playItem_t *after, const char *dirname, int *pabort) {
+ return plt_insert_dir_int (visibility, plt, NULL, after, dirname, pabort, NULL, NULL);
+}