summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2011-04-25 21:49:34 +0200
committerGravatar waker <wakeroid@gmail.com>2011-04-25 21:49:34 +0200
commit43a277e9d2dfaa2055184617495e1d3a48b8d9cc (patch)
tree6e98e5d4df0299825c6ec21ca51c37ca23ccf9d2
parent3d8f7348c65f7b071ad488c6d09ecfa6e3baaee6 (diff)
new future-proof playlist API, potentially reducing locking, and allowing more flexibility
-rw-r--r--deadbeef.h80
-rw-r--r--main.c12
-rw-r--r--playlist.c246
-rw-r--r--playlist.h32
-rw-r--r--plugins.c41
-rw-r--r--plugins/cdda/cdda.c18
-rw-r--r--plugins/gtkui/callbacks.c4
-rw-r--r--plugins/gtkui/ddblistview.c2
-rw-r--r--plugins/gtkui/ddbtabstrip.c24
-rw-r--r--plugins/gtkui/fileman.c6
-rw-r--r--plugins/gtkui/gtkui.c58
-rw-r--r--plugins/gtkui/mainplaylist.c4
-rw-r--r--plugins/gtkui/plcommon.c32
-rw-r--r--plugins/gtkui/trkproperties.c6
-rw-r--r--plugins/vfs_curl/vfs_curl.c12
-rw-r--r--plugins/vorbis/vorbis.c7
-rw-r--r--streamer.c46
17 files changed, 422 insertions, 208 deletions
diff --git a/deadbeef.h b/deadbeef.h
index 2e6dfe18..aa1abd66 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -122,7 +122,12 @@ typedef struct DB_playItem_s {
int shufflerating; // sort order for shuffle mode
float playtime; // actual playback time of this track in seconds
time_t started_timestamp; // result of calling time(NULL)
-} DB_playItem_t;
+} ddb_playItem_t;
+
+typedef ddb_playItem_t DB_playItem_t;
+
+typedef struct {
+} ddb_playlist_t;
typedef struct DB_metaInfo_s {
struct DB_metaInfo_s *next;
@@ -373,41 +378,72 @@ typedef struct {
int (*cond_signal) (uintptr_t cond);
int (*cond_broadcast) (uintptr_t cond);
- // playlist management
+ /////// playlist management //////
+ void (*plt_ref) (ddb_playlist_t *plt);
+ void (*plt_unref) (ddb_playlist_t *plt);
+
+ // total number of playlists
int (*plt_get_count) (void);
+
+ // 1st item in playlist nr. 'plt'
DB_playItem_t * (*plt_get_head) (int plt);
+
+ // nr. of selected items in playlist nr. 'plt'
int (*plt_get_sel_count) (int plt);
+
+ // add new playlist into position before nr. 'before', with title='title'
+ // returns index of new playlist
int (*plt_add) (int before, const char *title);
+
+ // remove playlist nr. plt
void (*plt_remove) (int plt);
- void (*plt_set_curr) (int plt);
- int (*plt_get_curr) (void);
+
+ // clear playlist
+ void (*plt_clear) (ddb_playlist_t *plt);
+
+ // set current playlist
+ void (*plt_set_curr) (ddb_playlist_t *plt);
+ void (*plt_set_curr_idx) (int plt);
+
+ // get current playlist
+ // note: caller is responsible to call plt_unref after using pointer
+ // returned by plt_get_curr
+ ddb_playlist_t *(*plt_get_curr) (void);
+ int (*plt_get_curr_idx) (void);
+
+ // move playlist nr. 'from' into position before nr. 'before', where
+ // before=-1 means last position
void (*plt_move) (int from, int before);
+ // playlist saving and loading
+ DB_playItem_t * (*plt_load) (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
+ int (*plt_save) (ddb_playlist_t *plt, DB_playItem_t *first, DB_playItem_t *last, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
+
// getting and working with a handle must be guarded using plt_lock/unlock
- void *(*plt_get_handle) (int idx);
- int (*plt_get_title) (void *handle, char *buffer, int bufsize);
- int (*plt_set_title) (void *handle, const char *title);
+ ddb_playlist_t *(*plt_get_for_idx) (int idx);
+ int (*plt_get_title) (ddb_playlist_t *plt, char *buffer, int bufsize);
+ int (*plt_set_title) (ddb_playlist_t *plt, const char *title);
// increments modification index
- void (*plt_modified) (void *handle);
+ void (*plt_modified) (ddb_playlist_t *handle);
// returns modication index
// the index is incremented by 1 every time playlist changes
- int (*plt_get_modification_idx) (void *handle);
+ int (*plt_get_modification_idx) (ddb_playlist_t *handle);
// playlist metadata
// this kind of metadata is stored in playlist (dbpl) files
- void (*plt_add_meta) (void *handle, const char *key, const char *value);
- void (*plt_replace_meta) (void *handle, const char *key, const char *value);
- void (*plt_append_meta) (void *handle, const char *key, const char *value);
- void (*plt_set_meta_int) (void *handle, const char *key, int value);
- void (*plt_set_meta_float) (void *handle, const char *key, float value);
- const char *(*plt_find_meta) (void *handle, const char *key);
- DB_metaInfo_t * (*plt_get_metadata_head) (void *handle); // returns head of metadata linked list
- void (*plt_delete_metadata) (void *handle, DB_metaInfo_t *meta);
- int (*plt_find_meta_int) (void *handle, const char *key, int def);
- float (*plt_find_meta_float) (void *handle, const char *key, float def);
- void (*plt_delete_all_meta) (void *handle);
+ void (*plt_add_meta) (ddb_playlist_t *handle, const char *key, const char *value);
+ void (*plt_replace_meta) (ddb_playlist_t *handle, const char *key, const char *value);
+ void (*plt_append_meta) (ddb_playlist_t *handle, const char *key, const char *value);
+ void (*plt_set_meta_int) (ddb_playlist_t *handle, const char *key, int value);
+ void (*plt_set_meta_float) (ddb_playlist_t *handle, const char *key, float value);
+ const char *(*plt_find_meta) (ddb_playlist_t *handle, const char *key);
+ DB_metaInfo_t * (*plt_get_metadata_head) (ddb_playlist_t *handle); // returns head of metadata linked list
+ void (*plt_delete_metadata) (ddb_playlist_t *handle, DB_metaInfo_t *meta);
+ int (*plt_find_meta_int) (ddb_playlist_t *handle, const char *key, int def);
+ float (*plt_find_meta_float) (ddb_playlist_t *handle, const char *key, float def);
+ void (*plt_delete_all_meta) (ddb_playlist_t *handle);
// playlist locking
void (*pl_lock) (void);
@@ -425,7 +461,7 @@ typedef struct {
// this function may return -1 if it is not possible to add files right now.
// caller must cancel operation in this case, or wait until previous add
// finishes
- int (*pl_add_files_begin) (int playlist);
+ int (*pl_add_files_begin) (ddb_playlist_t *plt);
void (*pl_add_files_end) (void);
DB_playItem_t *(*pl_insert_item) (DB_playItem_t *after, DB_playItem_t *it);
DB_playItem_t *(*pl_insert_dir) (DB_playItem_t *after, const char *dirname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
@@ -442,8 +478,6 @@ typedef struct {
void (*pl_set_selected) (DB_playItem_t *it, int sel);
int (*pl_is_selected) (DB_playItem_t *it);
void (*pl_clear) (void);
- int (*pl_load) (const char *name);
- int (*pl_save) (const char *name);
int (*pl_save_current) (void);
int (*pl_save_all) (void);
void (*pl_select_all) (void);
diff --git a/main.c b/main.c
index 6bcad18f..554c7459 100644
--- a/main.c
+++ b/main.c
@@ -227,18 +227,19 @@ server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsi
idx = plt_add (plt_get_count (), str);
}
if (idx >= 0) {
- plt_set_curr (idx);
+ plt_set_curr_idx (idx);
}
}
// add files
- int curr_plt = plt_get_curr ();
+ playlist_t *curr_plt = plt_get_curr ();
if (!queue) {
pl_clear ();
plug_trigger_event_playlistchanged ();
pl_reset_cursor ();
}
if (parg < pend) {
- if (deadbeef->pl_add_files_begin (curr_plt) != 0) {
+ if (deadbeef->pl_add_files_begin ((ddb_playlist_t *)curr_plt) != 0) {
+ plt_unref (curr_plt);
snprintf (sendback, sbsize, "it's not allowed to add files to playlist right now, because another file adding operation is in progress. please try again later.");
return 0;
}
@@ -812,7 +813,7 @@ main (int argc, char *argv[]) {
exit (-1);
}
pl_load_all ();
- plt_set_curr (conf_get_int ("playlist.current", 0));
+ plt_set_curr_idx (conf_get_int ("playlist.current", 0));
// execute server commands in local context
int noloadpl = 0;
@@ -890,8 +891,7 @@ main (int argc, char *argv[]) {
plug_unload_all ();
// at this point we can simply do exit(0), but let's clean up for debugging
- plt_free (); // plt_free may access conf_*
- pl_free ();
+ pl_free (); // may access conf_*
conf_free ();
messagepump_free ();
plug_cleanup ();
diff --git a/playlist.c b/playlist.c
index 971b1ede..bf4743ae 100644
--- a/playlist.c
+++ b/playlist.c
@@ -95,7 +95,10 @@ static uintptr_t mutex_plt;
#define LOCK {pl_lock();}
#define UNLOCK {pl_unlock();}
-static playlist_t dummy_playlist; // used at startup to prevent crashes
+// used at startup to prevent crashes
+static playlist_t dummy_playlist = {
+ .refc = 1
+};
static int pl_order; // mirrors "playback.order" config variable
@@ -130,6 +133,22 @@ pl_init (void) {
void
pl_free (void) {
+ trace ("pl_free\n");
+ LOCK;
+ pl_playqueue_clear ();
+ plt_loading = 1;
+ while (playlists_head) {
+
+ for (playItem_t *it = playlists_head->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
+ if (it->_refc > 1) {
+ fprintf (stderr, "\033[0;31mWARNING: playitem %p %s has refc=%d at delete time\033[37;0m\n", it, pl_find_meta (it, ":URI"), it->_refc);
+ }
+ }
+
+ plt_remove (0);
+ }
+ plt_loading = 0;
+ UNLOCK;
#if !DISABLE_LOCKING
if (mutex) {
mutex_free (mutex);
@@ -198,21 +217,53 @@ plt_get_list (void) {
}
playlist_t *
-plt_get_curr_ptr (void) {
- return playlist;
+plt_get_curr (void) {
+ LOCK;
+ playlist_t *plt = playlist;
+ if (plt) {
+ plt_ref (plt);
+ assert (plt->refc > 1);
+ }
+ UNLOCK;
+ return plt;
+
}
playlist_t *
-plt_get (int idx) {
+plt_get_for_idx (int idx) {
+ LOCK;
playlist_t *p = playlists_head;
for (int i = 0; p && i <= idx; i++, p = p->next) {
if (i == idx) {
+ plt_ref (p);
+ UNLOCK;
return p;
}
}
+ UNLOCK;
return NULL;
}
+void
+plt_ref (playlist_t *plt) {
+ LOCK;
+ plt->refc++;
+ UNLOCK;
+}
+
+void
+plt_unref (playlist_t *plt) {
+ LOCK;
+ plt->refc--;
+ if (plt->refc < 0) {
+ trace ("\033[0;31mplaylist: bad refcount on playlist %p (%s)\033[37;0m\n", plt, plt->title);
+ }
+ if (plt->refc <= 0) {
+ plt_free (plt);
+ }
+ UNLOCK;
+}
+
int
plt_get_count (void) {
return playlists_count;
@@ -261,12 +312,11 @@ plt_add (int before, const char *title) {
}
playlist_t *plt = malloc (sizeof (playlist_t));
memset (plt, 0, sizeof (playlist_t));
+ plt->refc = 1;
plt->title = strdup (title);
plt_modified (plt);
- trace ("locking\n");
LOCK;
- trace ("locked\n");
playlist_t *p_before = NULL;
playlist_t *p_after = playlists_head;
@@ -340,7 +390,6 @@ plt_remove (int plt) {
prev = p;
p = p->next;
}
- streamer_notify_playlist_deleted (p);
if (!plt_loading) {
// move files (will decrease number of files by 1)
for (int i = plt+1; i < playlists_count; i++) {
@@ -387,7 +436,6 @@ plt_remove (int plt) {
playlist_t *next = p->next;
playlist_t *old = playlist;
playlist = p;
- pl_clear ();
playlist = old;
if (p == playlist) {
if (next) {
@@ -397,17 +445,8 @@ plt_remove (int plt) {
playlist = prev ? prev : playlists_head;
}
}
- free (p->title);
-
- while (p->meta) {
- DB_metaInfo_t *m = p->meta;
- p->meta = m->next;
- metacache_remove_string (m->key);
- metacache_remove_string (m->value);
- free (m);
- }
- free (p);
+ plt_unref (p);
playlists_count--;
UNLOCK;
@@ -430,8 +469,23 @@ plt_find (const char *name) {
return -1;
}
+
+void
+plt_set_curr (playlist_t *plt) {
+ LOCK;
+ if (plt != playlist) {
+ playlist = plt;
+ if (!plt_loading) {
+ messagepump_push (DB_EV_PLAYLISTSWITCHED, 0, 0, 0);
+ conf_set_int ("playlist.current", plt_get_curr_idx ());
+ conf_save ();
+ }
+ }
+ UNLOCK;
+}
+
void
-plt_set_curr (int plt) {
+plt_set_curr_idx (int plt) {
int i;
LOCK;
playlist_t *p = playlists_head;
@@ -442,7 +496,7 @@ plt_set_curr (int plt) {
playlist = p;
if (!plt_loading) {
messagepump_push (DB_EV_PLAYLISTSWITCHED, 0, 0, 0);
- conf_set_int ("playlist.current", plt_get_curr ());
+ conf_set_int ("playlist.current", plt);
conf_save ();
}
}
@@ -450,7 +504,7 @@ plt_set_curr (int plt) {
}
int
-plt_get_curr (void) {
+plt_get_curr_idx(void) {
int i;
LOCK;
playlist_t *p = playlists_head;
@@ -527,22 +581,21 @@ plt_get_modification_idx (playlist_t *plt) {
}
void
-plt_free (void) {
- trace ("plt_free\n");
+plt_free (playlist_t *plt) {
LOCK;
- pl_playqueue_clear ();
- plt_loading = 1;
- while (playlists_head) {
-
- for (playItem_t *it = playlists_head->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
- if (it->_refc > 1) {
- fprintf (stderr, "\033[0;31mWARNING: playitem %p %s has refc=%d at delete time\033[37;0m\n", it, pl_find_meta (it, ":URI"), it->_refc);
- }
- }
+ streamer_notify_playlist_deleted (plt);
+ plt_clear (plt);
+ free (plt->title);
- plt_remove (0);
+ while (plt->meta) {
+ DB_metaInfo_t *m = plt->meta;
+ plt->meta = m->next;
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
}
- plt_loading = 0;
+
+ free (plt);
UNLOCK;
}
@@ -976,7 +1029,7 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t
pl_get_value_from_cue (p + 9, sizeof (date), date);
}
else if (!strncmp (p, "TRACK ", 6)) {
- trace ("cue: adding track: %s %s %s\n", origin->fname, title, track);
+ trace ("cue: adding track: %s %s %s\n", pl_find_meta (origin, ":URI"), title, track);
if (title[0]) {
// add previous track
const char *filetype = pl_find_meta (origin, ":FILETYPE");
@@ -1609,13 +1662,16 @@ pl_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *us
}
int
-pl_add_files_begin (int plt) {
+pl_add_files_begin (playlist_t *plt) {
pl_lock ();
if (addfiles_playlist) {
pl_unlock ();
return -1;
}
- addfiles_playlist = plt_get (plt);
+ addfiles_playlist = plt;
+ if (addfiles_playlist) {
+ plt_ref (addfiles_playlist);
+ }
pl_unlock ();
trace ("adding to playlist %d (%s)\n", plt, addfiles_playlist->title);
return 0;
@@ -1625,6 +1681,9 @@ void
pl_add_files_end (void) {
trace ("end adding to playlist %s\n", addfiles_playlist->title);
pl_lock ();
+ if (addfiles_playlist) {
+ plt_unref (addfiles_playlist);
+ }
addfiles_playlist = NULL;
pl_unlock ();
}
@@ -1931,7 +1990,7 @@ pl_crop_selected (void) {
}
int
-pl_save (const char *fname) {
+plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
LOCK;
const char *ext = strrchr (fname, '.');
if (ext) {
@@ -2153,7 +2212,7 @@ pl_save_n (int n) {
playlist_t *orig = playlist;
int i;
for (i = 0, playlist = playlists_head; playlist && i < n; i++, playlist = playlist->next);
- err = pl_save (path);
+ err = plt_save (playlist, NULL, NULL, path, NULL, NULL, NULL);
playlist = orig;
plt_loading = 0;
UNLOCK;
@@ -2162,7 +2221,7 @@ pl_save_n (int n) {
int
pl_save_current (void) {
- return pl_save_n (plt_get_curr ());
+ return pl_save_n (plt_get_curr_idx ());
}
int
@@ -2180,38 +2239,34 @@ pl_save_all (void) {
playlist_t *p = playlists_head;
int i;
int cnt = plt_get_count ();
- int curr = plt_get_curr ();
+ int curr = plt_get_curr_idx ();
int err = 0;
plt_loading = 1;
for (i = 0; i < cnt; i++, p = p->next) {
- plt_set_curr (i);
if (snprintf (path, sizeof (path), "%s/playlists/%d.dbpl", dbconfdir, i) > sizeof (path)) {
fprintf (stderr, "error: failed to make path string for playlist file\n");
err = -1;
break;
}
- err = pl_save (path);
+ err = plt_save (p, NULL, NULL, path, NULL, NULL, NULL);
if (err < 0) {
break;
}
}
- plt_set_curr (curr);
plt_loading = 0;
UNLOCK;
return err;
}
-int
-pl_load (const char *fname) {
+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) {
FILE *fp = fopen (fname, "rb");
if (!fp) {
- return -1;
+ trace ("plt_load: failed to open %s\n", fname);
+ return NULL;
}
LOCK;
- playlist_t *plt = playlist;
-
- plt_clear (plt);
// try plugins 1st
const char *ext = strrchr (fname, '.');
@@ -2222,13 +2277,14 @@ pl_load (const char *fname) {
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 (NULL, fname, NULL, NULL, NULL);
+ DB_playItem_t *it = plug[p]->load (NULL, fname, NULL, NULL, NULL);
UNLOCK;
- return 0;
+ return (playItem_t *)it;
}
}
}
}
+ trace ("plt_load: loading dbpl\n");
uint8_t majorver;
uint8_t minorver;
@@ -2260,6 +2316,9 @@ pl_load (const char *fname) {
if (fread (&cnt, 1, 4, fp) != 4) {
goto load_fail;
}
+
+ playItem_t *last_added = NULL;
+
for (uint32_t i = 0; i < cnt; i++) {
it = pl_item_alloc ();
if (!it) {
@@ -2422,8 +2481,10 @@ pl_load (const char *fname) {
}
}
plt_insert_item (plt, plt->tail[PL_MAIN], it);
- pl_item_unref (it);
- it = NULL;
+ if (last_added) {
+ pl_item_unref (last_added);
+ }
+ last_added = it;
}
// load playlist metadata
@@ -2467,18 +2528,15 @@ pl_load (const char *fname) {
if (fp) {
fclose (fp);
}
- return 0;
+ trace ("plt_load: success\n");
+ return last_added;
load_fail:
fprintf (stderr, "playlist load fail (%s)!\n", fname);
- if (it) {
- pl_item_unref (it);
- }
- pl_clear ();
UNLOCK;
if (fp) {
fclose (fp);
}
- return -1;
+ return last_added;
}
int
@@ -2498,7 +2556,14 @@ pl_load_all (void) {
if (plt_add (plt_get_count (), _("Default")) < 0) {
return -1;
}
- return pl_load (defpl);
+
+ playlist_t *plt = plt_get_for_idx (0);
+ playItem_t *it = plt_load (plt, NULL, defpl, NULL, NULL, NULL);
+ if (it) {
+ pl_item_unref (it);
+ }
+ plt_unref (plt);
+ return 0;
}
trace ("pl_load_all started\n");
LOCK;
@@ -2510,7 +2575,7 @@ pl_load_all (void) {
if (plt_add (plt_get_count (), it->value) < 0) {
return -1;
}
- plt_set_curr (plt_get_count () - 1);
+ plt_set_curr_idx (plt_get_count () - 1);
}
err = 0;
if (snprintf (path, sizeof (path), "%s/playlists/%d.dbpl", dbconfdir, i) > sizeof (path)) {
@@ -2519,9 +2584,16 @@ pl_load_all (void) {
}
else {
fprintf (stderr, "INFO: from file %s\n", path);
- int load_err = pl_load (path);
- if (load_err != 0) {
- fprintf (stderr, "WARNING: failed to load playlist '%s' (%s)\n", it->value, path);
+
+ playlist_t *plt = plt_get_curr ();
+ playItem_t *trk = plt_load (plt, NULL, path, NULL, NULL, NULL);
+ if (trk) {
+ pl_item_unref (trk);
+ }
+ plt_unref (plt);
+
+ if (!it) {
+ fprintf (stderr, "WARNING: there were errors while loading playlist '%s' (%s)\n", it->value, path);
}
}
it = conf_find ("playlist.tab.", it);
@@ -3358,15 +3430,16 @@ void
pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexes, int count) {
LOCK;
- playlist_t *playlist = playlists_head;
- playlist_t *to = plt_get_curr_ptr ();
-
- int i;
- for (i = 0; i < plt_from; i++) {
- playlist = playlist->next;
- }
+ playlist_t *playlist = plt_get_for_idx (plt_from);
+ playlist_t *to = plt_get_curr ();
if (!playlist || !to) {
+ if (to) {
+ plt_unref (to);
+ }
+ if (playlist) {
+ plt_unref (playlist);
+ }
UNLOCK;
return;
}
@@ -3405,6 +3478,12 @@ pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexe
}
}
no_remove_notify = 0;
+ if (to) {
+ plt_unref (to);
+ }
+ if (playlist) {
+ plt_unref (playlist);
+ }
UNLOCK;
}
@@ -3412,20 +3491,21 @@ void
pl_copy_items (int iter, int plt_from, playItem_t *before, uint32_t *indices, int cnt) {
pl_lock ();
- playlist_t *from = playlists_head;
- playlist_t *to = plt_get_curr_ptr ();
-
- int i;
- for (i = 0; i < plt_from; i++) {
- from = from->next;
- }
+ playlist_t *from = plt_get_for_idx (plt_from);
+ playlist_t *to = plt_get_curr ();
if (!from || !to) {
+ if (to) {
+ plt_unref (to);
+ }
+ if (from) {
+ plt_unref (from);
+ }
pl_unlock ();
return;
}
- for (i = 0; i < cnt; i++) {
+ for (int i = 0; i < cnt; i++) {
playItem_t *it = from->head[iter];
int idx = 0;
while (it && idx < indices[i]) {
@@ -3444,6 +3524,12 @@ pl_copy_items (int iter, int plt_from, playItem_t *before, uint32_t *indices, in
pl_item_unref (it_new);
}
+ if (to) {
+ plt_unref (to);
+ }
+ if (from) {
+ plt_unref (from);
+ }
pl_unlock ();
}
diff --git a/playlist.h b/playlist.h
index cf156a81..f097198e 100644
--- a/playlist.h
+++ b/playlist.h
@@ -57,6 +57,7 @@ typedef struct playlist_s {
playItem_t *tail[PL_MAX_ITERATORS]; // tail of linked list
int current_row[PL_MAX_ITERATORS]; // current row (cursor)
struct DB_metaInfo_s *meta; // linked list storing metainfo
+ int refc;
} playlist_t;
// global playlist control functions
@@ -85,7 +86,16 @@ playlist_t *
plt_get_curr_ptr (void);
playlist_t *
-plt_get (int idx);
+plt_get_for_idx (int idx);
+
+void
+plt_ref (playlist_t *plt);
+
+void
+plt_unref (playlist_t *plt);
+
+void
+plt_free (playlist_t *plt);
int
plt_get_count (void);
@@ -109,12 +119,15 @@ int
plt_find (const char *name);
void
-plt_free (void);
+plt_set_curr_idx (int plt);
+
+int
+plt_get_curr_idx (void);
void
-plt_set_curr (int plt);
+plt_set_curr (playlist_t *plt);
-int
+playlist_t *
plt_get_curr (void);
int
@@ -140,6 +153,9 @@ plt_move (int from, int to);
void
pl_clear (void);
+void
+plt_clear (playlist_t *plt);
+
int
pl_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data);
@@ -147,7 +163,7 @@ int
pl_add_file (const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data);
int
-pl_add_files_begin (int plt);
+pl_add_files_begin (playlist_t *plt);
void
pl_add_files_end (void);
@@ -246,7 +262,7 @@ void
pl_crop_selected (void);
int
-pl_save (const char *fname);
+plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data);
int
pl_save_n (int n);
@@ -257,8 +273,8 @@ pl_save_current (void);
int
pl_save_all (void);
-int
-pl_load (const char *fname);
+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);
int
pl_load_all (void);
diff --git a/plugins.c b/plugins.c
index 399663bc..d589b518 100644
--- a/plugins.c
+++ b/plugins.c
@@ -105,28 +105,37 @@ static DB_functions_t deadbeef_api = {
.cond_signal = cond_signal,
.cond_broadcast = cond_broadcast,
// playlist management
+ .plt_ref = (void (*) (ddb_playlist_t *plt))plt_ref,
+ .plt_unref = (void (*) (ddb_playlist_t *plt))plt_unref,
.plt_get_count = plt_get_count,
.plt_get_head = (DB_playItem_t * (*) (int plt))plt_get_head,
.plt_get_sel_count = plt_get_sel_count,
.plt_add = plt_add,
.plt_remove = plt_remove,
- .plt_set_curr = plt_set_curr,
- .plt_get_curr = plt_get_curr,
+ .plt_clear = (void (*)(ddb_playlist_t *))plt_clear,
+ .plt_set_curr = (void (*) (ddb_playlist_t *plt))plt_set_curr,
+ .plt_get_curr = (ddb_playlist_t *(*) (void))plt_get_curr,
+ .plt_set_curr_idx = (void (*) (int plt))plt_set_curr_idx,
+ .plt_get_curr_idx = (int (*) (void))plt_get_curr_idx,
.plt_move = plt_move,
- .plt_get_handle = (void *(*)(int idx))plt_get,
- .plt_get_title = (int (*)(void *handle, char *buffer, int sz))plt_get_title,
- .plt_set_title = (int (*)(void *handle, const char *buffer))plt_set_title,
- .plt_modified = (void (*) (void *handle))plt_modified,
- .plt_get_modification_idx = (int (*) (void *handle))plt_get_modification_idx,
+ // playlist saving and loading
+ .plt_load = (DB_playItem_t * (*) (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data))plt_load,
+ .plt_save = (int (*)(ddb_playlist_t *plt, DB_playItem_t *first, DB_playItem_t *last, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data))plt_save,
+ // getting and working with a handle must be guarded using plt_lock/unlock
+ .plt_get_for_idx = (ddb_playlist_t *(*)(int idx))plt_get_for_idx,
+ .plt_get_title = (int (*)(ddb_playlist_t *handle, char *buffer, int sz))plt_get_title,
+ .plt_set_title = (int (*)(ddb_playlist_t *handle, const char *buffer))plt_set_title,
+ .plt_modified = (void (*) (ddb_playlist_t *handle))plt_modified,
+ .plt_get_modification_idx = (int (*) (ddb_playlist_t *handle))plt_get_modification_idx,
// playlist metadata
- .plt_add_meta = (void (*) (void *handle, const char *key, const char *value))plt_add_meta,
- .plt_replace_meta = (void (*) (void *handle, const char *key, const char *value))plt_replace_meta,
- .plt_append_meta = (void (*) (void *handle, const char *key, const char *value))plt_append_meta,
- .plt_set_meta_int = (void (*) (void *handle, const char *key, int value))plt_set_meta_int,
- .plt_set_meta_float = (void (*) (void *handle, const char *key, float value))plt_set_meta_float,
- .plt_find_meta = (const char *(*) (void *handle, const char *key))plt_find_meta,
- .plt_get_metadata_head = (DB_metaInfo_t * (*) (void *handle))plt_get_metadata_head,
+ .plt_add_meta = (void (*) (ddb_playlist_t *handle, const char *key, const char *value))plt_add_meta,
+ .plt_replace_meta = (void (*) (ddb_playlist_t *handle, const char *key, const char *value))plt_replace_meta,
+ .plt_append_meta = (void (*) (ddb_playlist_t *handle, const char *key, const char *value))plt_append_meta,
+ .plt_set_meta_int = (void (*) (ddb_playlist_t *handle, const char *key, int value))plt_set_meta_int,
+ .plt_set_meta_float = (void (*) (ddb_playlist_t *handle, const char *key, float value))plt_set_meta_float,
+ .plt_find_meta = (const char *(*) (ddb_playlist_t *handle, const char *key))plt_find_meta,
+ .plt_get_metadata_head = (DB_metaInfo_t * (*) (ddb_playlist_t *handle))plt_get_metadata_head,
// playlist access
.pl_lock = pl_lock,
@@ -140,7 +149,7 @@ static DB_functions_t deadbeef_api = {
.pl_item_copy = (void (*)(DB_playItem_t *, DB_playItem_t *))pl_item_copy,
.pl_add_file = (int (*) (const char *, int (*cb)(DB_playItem_t *it, void *data), void *))pl_add_file,
.pl_add_dir = (int (*) (const char *dirname, int (*cb)(DB_playItem_t *it, void *data), void *user_data))pl_add_dir,
- .pl_add_files_begin = pl_add_files_begin,
+ .pl_add_files_begin = (int (*) (ddb_playlist_t *plt))pl_add_files_begin,
.pl_add_files_end = pl_add_files_end,
.pl_insert_item = (DB_playItem_t *(*) (DB_playItem_t *after, DB_playItem_t *it))pl_insert_item,
.pl_insert_dir = (DB_playItem_t *(*) (DB_playItem_t *after, const char *dirname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data))pl_insert_dir,
@@ -165,8 +174,6 @@ static DB_functions_t deadbeef_api = {
.pl_set_selected = (void (*) (DB_playItem_t *, int))pl_set_selected,
.pl_is_selected = (int (*) (DB_playItem_t *))pl_is_selected,
.pl_clear = pl_clear,
- .pl_load = pl_load,
- .pl_save = pl_save,
.pl_save_current = pl_save_current,
.pl_save_all = pl_save_all,
.pl_select_all = pl_select_all,
diff --git a/plugins/cdda/cdda.c b/plugins/cdda/cdda.c
index b8b0f84e..9df88719 100644
--- a/plugins/cdda/cdda.c
+++ b/plugins/cdda/cdda.c
@@ -395,7 +395,11 @@ cddb_thread (void *items_i)
}
cddb_disc_destroy (disc);
cleanup_thread_params (params);
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0);
}
@@ -584,10 +588,14 @@ cda_insert (DB_playItem_t *after, const char *fname) {
static int
cda_action_add_cd (DB_plugin_action_t *act, DB_playItem_t *it)
{
- deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ());
- deadbeef->pl_add_file ("all.cda", NULL, NULL);
- deadbeef->pl_add_files_end ();
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->pl_add_files_begin (plt);
+ deadbeef->pl_add_file ("all.cda", NULL, NULL);
+ deadbeef->pl_add_files_end ();
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0);
}
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c
index 1cbbe523..3bf04373 100644
--- a/plugins/gtkui/callbacks.c
+++ b/plugins/gtkui/callbacks.c
@@ -354,7 +354,7 @@ on_mainwin_key_press_event (GtkWidget *widget,
else if ((maskedstate == GDK_MOD1_MASK || maskedstate == 0) && event->keyval >= GDK_1 && event->keyval <= GDK_9) {
int pl = event->keyval - GDK_1;
if (pl >= 0 && pl < deadbeef->plt_get_count ()) {
- deadbeef->plt_set_curr (pl);
+ deadbeef->plt_set_curr_idx (pl);
deadbeef->conf_set_int ("playlist.current", pl);
}
}
@@ -983,7 +983,7 @@ on_new_playlist1_activate (GtkMenuItem *menuitem,
{
int pl = gtkui_add_new_playlist ();
if (pl != -1) {
- deadbeef->plt_set_curr (pl);
+ deadbeef->plt_set_curr_idx (pl);
deadbeef->conf_set_int ("playlist.current", pl);
}
}
diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c
index 588439c6..14dd9a70 100644
--- a/plugins/gtkui/ddblistview.c
+++ b/plugins/gtkui/ddblistview.c
@@ -1687,7 +1687,7 @@ ddb_listview_list_mousemove (DdbListview *ps, GdkEventMotion *ev, int ex, int ey
GtkWidget *widget = ps->list;
if (gtk_drag_check_threshold (widget, ps->lastpos[0], ex, ps->lastpos[1], ey)) {
ps->dragwait = 0;
- ps->drag_source_playlist = deadbeef->plt_get_curr ();
+ ps->drag_source_playlist = deadbeef->plt_get_curr_idx ();
GtkTargetEntry entry = {
.target = "DDB_URI_LIST",
.flags = GTK_TARGET_SAME_WIDGET,
diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c
index 8885d51f..8539a10d 100644
--- a/plugins/gtkui/ddbtabstrip.c
+++ b/plugins/gtkui/ddbtabstrip.c
@@ -48,7 +48,7 @@ plt_get_title_wrapper (int plt, char *buffer, int len) {
return;
}
deadbeef->pl_lock ();
- void *p = deadbeef->plt_get_handle (plt);
+ void *p = deadbeef->plt_get_for_idx (plt);
deadbeef->plt_get_title (p, buffer, len);
deadbeef->pl_unlock ();
char *end;
@@ -353,7 +353,7 @@ ddb_tabstrip_draw_tab (GtkWidget *widget, GdkDrawable *drawable, int idx, int se
GdkColor clr;
int fallback = 1;
deadbeef->pl_lock ();
- void *plt = deadbeef->plt_get_handle (idx);
+ void *plt = deadbeef->plt_get_for_idx (idx);
const char *bgclr = deadbeef->plt_find_meta (plt, "gui.bgcolor");
if (bgclr) {
int r, g, b;
@@ -476,7 +476,7 @@ tabstrip_adjust_hscroll (DdbTabStrip *ts) {
ts->hscrollpos = w - (widget->allocation.width - arrow_widget_width*2);
deadbeef->conf_set_int ("gtkui.tabscroll", ts->hscrollpos);
}
- tabstrip_scroll_to_tab_int (ts, deadbeef->plt_get_curr (), 0);
+ tabstrip_scroll_to_tab_int (ts, deadbeef->plt_get_curr_idx (), 0);
}
else {
ts->hscrollpos = 0;
@@ -491,7 +491,7 @@ set_tab_text_color (int idx, int selected) {
return;
}
deadbeef->pl_lock ();
- void *plt = deadbeef->plt_get_handle (idx);
+ void *plt = deadbeef->plt_get_for_idx (idx);
int fallback = 1;
const char *clr = deadbeef->plt_find_meta (plt, "gui.color");
if (clr) {
@@ -534,7 +534,7 @@ tabstrip_render (DdbTabStrip *ts) {
text_right_padding = h - 3;
const char *detail = "button";
- int tab_selected = deadbeef->plt_get_curr ();
+ int tab_selected = deadbeef->plt_get_curr_idx ();
if (tab_selected == -1) {
return;
}
@@ -655,7 +655,7 @@ get_tab_under_cursor (DdbTabStrip *ts, int x) {
int idx;
int cnt = deadbeef->plt_get_count ();
int fw = tabs_left_margin - hscroll;
- int tab_selected = deadbeef->plt_get_curr ();
+ int tab_selected = deadbeef->plt_get_curr_idx ();
for (idx = 0; idx < cnt; idx++) {
char title[100];
plt_get_title_wrapper (idx, title, sizeof (title));
@@ -693,7 +693,7 @@ on_rename_playlist1_activate (GtkMenuItem *menuitem,
if (res == GTK_RESPONSE_OK) {
const char *text = gtk_entry_get_text (GTK_ENTRY (e));
deadbeef->pl_lock ();
- void *p = deadbeef->plt_get_handle (tab_clicked);
+ void *p = deadbeef->plt_get_for_idx (tab_clicked);
deadbeef->plt_set_title (p, text);
deadbeef->pl_unlock ();
}
@@ -710,7 +710,7 @@ on_remove_playlist1_activate (GtkMenuItem *menuitem,
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
ddb_listview_refresh (pl, DDB_LIST_CHANGED | DDB_REFRESH_LIST | DDB_REFRESH_VSCROLL);
search_refresh ();
- int playlist = deadbeef->plt_get_curr ();
+ int playlist = deadbeef->plt_get_curr_idx ();
deadbeef->conf_set_int ("playlist.current", playlist);
}
}
@@ -772,7 +772,7 @@ create_plmenu (void)
static void
tabstrip_scroll_left (DdbTabStrip *ts) {
- int tab = deadbeef->plt_get_curr ();
+ int tab = deadbeef->plt_get_curr_idx ();
if (tab > 0) {
tab--;
gtkui_playlist_set_curr (tab);
@@ -782,7 +782,7 @@ tabstrip_scroll_left (DdbTabStrip *ts) {
static void
tabstrip_scroll_right (DdbTabStrip *ts) {
- int tab = deadbeef->plt_get_curr ();
+ int tab = deadbeef->plt_get_curr_idx ();
if (tab < deadbeef->plt_get_count ()-1) {
tab++;
gtkui_playlist_set_curr (tab);
@@ -907,7 +907,7 @@ on_tabstrip_button_press_event(GtkWidget *widget,
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
ddb_listview_refresh (pl, DDB_LIST_CHANGED | DDB_REFRESH_LIST | DDB_REFRESH_VSCROLL);
search_refresh ();
- int playlist = deadbeef->plt_get_curr ();
+ int playlist = deadbeef->plt_get_curr_idx ();
deadbeef->conf_set_int ("playlist.current", playlist);
}
}
@@ -1039,7 +1039,7 @@ on_tabstrip_drag_motion_event (GtkWidget *widget,
guint time)
{
int tab = get_tab_under_cursor (DDB_TABSTRIP (widget), x);
- int prev = deadbeef->plt_get_curr ();
+ int prev = deadbeef->plt_get_curr_idx ();
if (tab != -1 && tab != prev) {
gtkui_playlist_set_curr (tab);
}
diff --git a/plugins/gtkui/fileman.c b/plugins/gtkui/fileman.c
index 6ff981b4..a832df09 100644
--- a/plugins/gtkui/fileman.c
+++ b/plugins/gtkui/fileman.c
@@ -26,9 +26,8 @@ gtkpl_add_dirs (GSList *lst) {
deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ());
if (g_slist_length (lst) == 1
&& deadbeef->conf_get_int ("gtkui.name_playlist_from_folder", 0)) {
- int plt = deadbeef->plt_get_curr ();
- if (plt != -1) {
- void *p = deadbeef->plt_get_handle (plt);
+ ddb_playlist_t *p = deadbeef->plt_get_curr ();
+ if (p) {
char t[1000];
if (!deadbeef->plt_get_title (p, t, sizeof (t))) {
char *def = _("New Playlist");
@@ -40,6 +39,7 @@ gtkpl_add_dirs (GSList *lst) {
deadbeef->plt_set_title (p, folder+1);
}
}
+ deadbeef->plt_unref (p);
}
}
deadbeef->pl_unlock ();
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index 4d682d6e..7b0583c2 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -473,7 +473,7 @@ gtkui_playlist_changed (void) {
static gboolean
playlistswitch_cb (gpointer none) {
GtkWidget *tabstrip = lookup_widget (mainwin, "tabstrip");
- int curr = deadbeef->plt_get_curr ();
+ int curr = deadbeef->plt_get_curr_idx ();
char conf[100];
snprintf (conf, sizeof (conf), "playlist.scroll.%d", curr);
int scroll = deadbeef->conf_get_int (conf, 0);
@@ -577,10 +577,11 @@ gtkui_hide_status_icon () {
int
gtkui_get_curr_playlist_mod (void) {
- deadbeef->pl_lock ();
- void *plt = deadbeef->plt_get_handle (deadbeef->plt_get_curr ());
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
int res = plt ? deadbeef->plt_get_modification_idx (plt) : 0;
- deadbeef->pl_unlock ();
+ if (plt) {
+ deadbeef->plt_unref (plt);
+ }
return res;
}
@@ -672,9 +673,13 @@ save_playlist_as (void) {
gtk_widget_destroy (dlg);
if (fname) {
- int res = deadbeef->pl_save (fname);
- if (res >= 0 && strlen (fname) < 1024) {
- strcpy (last_playlist_save_name, fname);
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ int res = deadbeef->plt_save (plt, NULL, NULL, fname, NULL, NULL, NULL);
+ if (res >= 0 && strlen (fname) < 1024) {
+ strcpy (last_playlist_save_name, fname);
+ }
+ deadbeef->plt_unref (plt);
}
g_free (fname);
}
@@ -692,7 +697,11 @@ on_playlist_save_activate (GtkMenuItem *menuitem,
save_playlist_as ();
}
else {
- /*int res = */deadbeef->pl_save (last_playlist_save_name);
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_save (plt, NULL, NULL, last_playlist_save_name, NULL, NULL, NULL);
+ deadbeef->plt_unref (plt);
+ }
}
}
@@ -763,7 +772,15 @@ on_playlist_load_activate (GtkMenuItem *menuitem,
gchar *fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
gtk_widget_destroy (dlg);
if (fname) {
- /*int res = */deadbeef->pl_load (fname);
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_clear (plt);
+ DB_playItem_t *it = deadbeef->plt_load (plt, NULL, fname, NULL, NULL, NULL);
+ if (it) {
+ deadbeef->pl_item_unref (it);
+ }
+ deadbeef->plt_unref (plt);
+ }
g_free (fname);
main_refresh ();
search_refresh ();
@@ -798,22 +815,21 @@ on_add_location_activate (GtkMenuItem *menuitem,
static void
songchanged (DdbListview *ps, DB_playItem_t *from, DB_playItem_t *to) {
- int plt = deadbeef->plt_get_curr ();
int to_idx = -1;
if (!ddb_listview_is_scrolling (ps) && to) {
int cursor_follows_playback = deadbeef->conf_get_int ("playlist.scroll.cursorfollowplayback", 0);
int scroll_follows_playback = deadbeef->conf_get_int ("playlist.scroll.followplayback", 0);
int plt = deadbeef->streamer_get_current_playlist ();
if (plt != -1) {
- if (cursor_follows_playback && plt != deadbeef->plt_get_curr ()) {
- deadbeef->plt_set_curr (plt);
+ if (cursor_follows_playback && plt != deadbeef->plt_get_curr_idx ()) {
+ deadbeef->plt_set_curr_idx (plt);
}
to_idx = deadbeef->pl_get_idx_of (to);
if (to_idx != -1) {
if (cursor_follows_playback) {
ddb_listview_set_cursor_noscroll (ps, to_idx);
}
- if (scroll_follows_playback && plt == deadbeef->plt_get_curr ()) {
+ if (scroll_follows_playback && plt == deadbeef->plt_get_curr_idx ()) {
ddb_listview_scroll_to (ps, to_idx);
}
}
@@ -891,7 +907,7 @@ gtkui_add_new_playlist (void) {
deadbeef->pl_lock ();
for (i = 0; i < cnt; i++) {
char t[100];
- void *plt = deadbeef->plt_get_handle (i);
+ void *plt = deadbeef->plt_get_for_idx (i);
deadbeef->plt_get_title (plt, t, sizeof (t));
if (!strcasecmp (t, name)) {
break;
@@ -1127,7 +1143,7 @@ gtkui_add_file_info_cb (DB_playItem_t *it, void *data) {
int (*gtkui_original_pl_add_dir) (const char *dirname, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
int (*gtkui_original_pl_add_file) (const char *fname, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
-void (*gtkui_original_pl_add_files_begin) (int plt);
+int (*gtkui_original_pl_add_files_begin) (ddb_playlist_t *plt);
void (*gtkui_original_pl_add_files_end) (void);
int
@@ -1142,10 +1158,10 @@ gtkui_pl_add_file (const char *filename, int (*cb)(DB_playItem_t *it, void *data
return res;
}
-void
-gtkui_pl_add_files_begin (int plt) {
+int
+gtkui_pl_add_files_begin (ddb_playlist_t *plt) {
g_idle_add (gtkui_progress_show_idle, NULL);
- gtkui_original_pl_add_files_begin (plt);
+ return gtkui_original_pl_add_files_begin (plt);
}
void
@@ -1159,8 +1175,8 @@ gtkui_focus_on_playing_track (void) {
DB_playItem_t *it = deadbeef->streamer_get_playing_track ();
if (it) {
int plt = deadbeef->streamer_get_current_playlist ();
- if (plt != deadbeef->plt_get_curr ()) {
- deadbeef->plt_set_curr (plt);
+ if (plt != deadbeef->plt_get_curr_idx ()) {
+ deadbeef->plt_set_curr_idx (plt);
}
int idx = deadbeef->pl_get_idx_of (it);
if (idx != -1) {
@@ -1174,7 +1190,7 @@ gtkui_focus_on_playing_track (void) {
void
gtkui_playlist_set_curr (int playlist) {
- deadbeef->plt_set_curr (playlist);
+ deadbeef->plt_set_curr_idx (playlist);
deadbeef->conf_set_int ("playlist.current", playlist);
}
diff --git a/plugins/gtkui/mainplaylist.c b/plugins/gtkui/mainplaylist.c
index e1537ea0..57b693f8 100644
--- a/plugins/gtkui/mainplaylist.c
+++ b/plugins/gtkui/mainplaylist.c
@@ -109,7 +109,7 @@ int main_get_idx (DdbListviewIter it) {
void
main_drag_n_drop (DdbListviewIter before, int from_playlist, uint32_t *indices, int length, int copy) {
deadbeef->pl_lock ();
- int curr = deadbeef->plt_get_curr ();
+// int curr = deadbeef->plt_get_curr_idx ();
if (copy) {
deadbeef->pl_copy_items (PL_MAIN, from_playlist, (DB_playItem_t *)before, indices, length);
}
@@ -238,7 +238,7 @@ void main_col_free_user_data (void *data) {
void
main_vscroll_changed (int pos) {
coverart_reset_queue ();
- int curr = deadbeef->plt_get_curr ();
+ int curr = deadbeef->plt_get_curr_idx ();
char conf[100];
snprintf (conf, sizeof (conf), "playlist.scroll.%d", curr);
deadbeef->conf_set_int (conf, pos);
diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c
index 6945e5d3..e319ac56 100644
--- a/plugins/gtkui/plcommon.c
+++ b/plugins/gtkui/plcommon.c
@@ -538,9 +538,11 @@ on_group_by_none_activate (GtkMenuItem *menuitem,
strcpy (group_by_str, "");
deadbeef->conf_set_str ("playlist.group_by", group_by_str);
- deadbeef->pl_lock ();
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
- deadbeef->pl_unlock ();
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
main_refresh ();
}
@@ -550,9 +552,11 @@ on_group_by_artist_date_album_activate (GtkMenuItem *menuitem,
{
strcpy (group_by_str, "%a - [%y] %b");
deadbeef->conf_set_str ("playlist.group_by", group_by_str);
- deadbeef->pl_lock ();
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
- deadbeef->pl_unlock ();
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
main_refresh ();
}
@@ -562,9 +566,11 @@ on_group_by_artist_activate (GtkMenuItem *menuitem,
{
strcpy (group_by_str, "%a");
deadbeef->conf_set_str ("playlist.group_by", group_by_str);
- deadbeef->pl_lock ();
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
- deadbeef->pl_unlock ();
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
main_refresh ();
}
@@ -585,9 +591,11 @@ on_group_by_custom_activate (GtkMenuItem *menuitem,
strncpy (group_by_str, text, sizeof (group_by_str));
group_by_str[sizeof (group_by_str)-1] = 0;
deadbeef->conf_set_str ("playlist.group_by", group_by_str);
- deadbeef->pl_lock ();
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
- deadbeef->pl_unlock ();
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
main_refresh ();
}
gtk_widget_destroy (dlg);
diff --git a/plugins/gtkui/trkproperties.c b/plugins/gtkui/trkproperties.c
index 12e51924..4e865eee 100644
--- a/plugins/gtkui/trkproperties.c
+++ b/plugins/gtkui/trkproperties.c
@@ -462,7 +462,11 @@ static gboolean
write_finished_cb (void *ctx) {
gtk_widget_destroy (progressdlg);
progressdlg = NULL;
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
main_refresh ();
search_refresh ();
trkproperties_modified = 0;
diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c
index 0ef5cc6a..acb0b561 100644
--- a/plugins/vfs_curl/vfs_curl.c
+++ b/plugins/vfs_curl/vfs_curl.c
@@ -212,7 +212,11 @@ http_parse_shoutcast_meta (HTTP_FILE *fp, const char *meta, int size) {
else {
vfs_curl_set_meta (fp->track, "title", title);
}
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0);
}
return 0;
@@ -468,7 +472,11 @@ http_content_header_handler (void *ptr, size_t size, size_t nmemb, void *stream)
fp->wait_meta = fp->icy_metaint;
}
}
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
if (refresh_playlist) {
deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0);
}
diff --git a/plugins/vorbis/vorbis.c b/plugins/vorbis/vorbis.c
index 27275eec..ee1871a4 100644
--- a/plugins/vorbis/vorbis.c
+++ b/plugins/vorbis/vorbis.c
@@ -165,7 +165,12 @@ update_vorbis_comments (DB_playItem_t *it, vorbis_comment *vc, int refresh_playl
f &= ~DDB_TAG_MASK;
f |= DDB_TAG_VORBISCOMMENTS;
deadbeef->pl_set_item_flags (it, f);
- deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ()));
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ if (plt) {
+ deadbeef->plt_modified (plt);
+ deadbeef->plt_unref (plt);
+ }
+
if (refresh_playlist) {
deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0);
}
diff --git a/streamer.c b/streamer.c
index 82f12f97..b6aee683 100644
--- a/streamer.c
+++ b/streamer.c
@@ -199,7 +199,7 @@ int
str_get_idx_of (playItem_t *it) {
pl_lock ();
if (!streamer_playlist) {
- streamer_playlist = plt_get_curr_ptr ();
+ streamer_playlist = plt_get_curr ();
}
playItem_t *c = streamer_playlist->head[PL_MAIN];
int idx = 0;
@@ -219,7 +219,7 @@ playItem_t *
str_get_for_idx (int idx) {
pl_lock ();
if (!streamer_playlist) {
- streamer_playlist = plt_get_curr_ptr ();
+ streamer_playlist = plt_get_curr ();
}
playItem_t *it = streamer_playlist->head[PL_MAIN];
while (idx--) {
@@ -242,7 +242,7 @@ streamer_move_to_nextsong (int reason) {
trace ("streamer_move_to_nextsong (%d)\n", reason);
pl_lock ();
if (!streamer_playlist) {
- streamer_playlist = plt_get_curr_ptr ();
+ streamer_playlist = plt_get_curr ();
}
while (pl_playqueue_getcount ()) {
trace ("pl_playqueue_getnext\n");
@@ -284,7 +284,11 @@ streamer_move_to_nextsong (int reason) {
playItem_t *curr = playlist_track;
if (reason == 1) {
- streamer_playlist = plt_get_curr_ptr ();
+ if (streamer_playlist) {
+ plt_unref (streamer_playlist);
+ streamer_playlist = NULL;
+ }
+ streamer_playlist = plt_get_curr ();
// check if prev song is in this playlist
if (-1 == str_get_idx_of (curr)) {
curr = NULL;
@@ -424,10 +428,11 @@ streamer_move_to_nextsong (int reason) {
int
streamer_move_to_prevsong (void) {
pl_lock ();
- if (!streamer_playlist) {
- streamer_playlist = plt_get_curr_ptr ();
+ if (streamer_playlist) {
+ plt_unref (streamer_playlist);
+ streamer_playlist = NULL;
}
- streamer_playlist = plt_get_curr_ptr ();
+ streamer_playlist = plt_get_curr ();
// check if prev song is in this playlist
if (-1 == str_get_idx_of (playlist_track)) {
playlist_track = NULL;
@@ -527,7 +532,7 @@ streamer_move_to_prevsong (void) {
int
streamer_move_to_randomsong (void) {
if (!streamer_playlist) {
- streamer_playlist = plt_get_curr_ptr ();
+ streamer_playlist = plt_get_curr ();
}
playlist_t *plt = streamer_playlist;
int cnt = plt->count[PL_MAIN];
@@ -797,7 +802,11 @@ streamer_set_nextsong (int song, int pstate) {
if (output->state () == OUTPUT_STATE_STOPPED) {
if (pstate == 1) { // means user initiated this
pl_lock ();
- streamer_playlist = plt_get_curr_ptr ();
+ if (streamer_playlist) {
+ plt_unref (streamer_playlist);
+ streamer_playlist = NULL;
+ }
+ streamer_playlist = plt_get_curr ();
pl_unlock ();
}
// no sense to wait until end of previous song, reset buffer
@@ -1498,6 +1507,10 @@ streamer_free (void) {
if (playlist_track) {
playlist_track = NULL;
}
+ if (streamer_playlist) {
+ plt_unref (streamer_playlist);
+ streamer_playlist = NULL;
+ }
decodemutex = 0;
mutex_free (mutex);
@@ -1827,7 +1840,7 @@ streamer_configchanged (void) {
void
streamer_play_current_track (void) {
- playlist_t *plt = plt_get_curr_ptr ();
+ playlist_t *plt = plt_get_curr ();
DB_output_t *output = plug_get_output ();
if (output->state () == OUTPUT_STATE_PAUSED && playing_track) {
// unpause currently paused track
@@ -1852,6 +1865,7 @@ streamer_play_current_track (void) {
streamer_set_nextsong (idx, 1);
pl_lock ();
streamer_playlist = plt;
+ plt_ref (plt);
pl_unlock ();
}
else {
@@ -1859,6 +1873,9 @@ streamer_play_current_track (void) {
output->stop ();
streamer_set_nextsong (0, 1);
}
+ if (plt) {
+ plt_unref (plt);
+ }
}
struct DB_fileinfo_s *
@@ -1869,7 +1886,11 @@ streamer_get_current_fileinfo (void) {
void
streamer_set_current_playlist (int plt) {
pl_lock ();
- streamer_playlist = plt_get (plt);
+ if (streamer_playlist) {
+ plt_unref (streamer_playlist);
+ streamer_playlist = NULL;
+ }
+ streamer_playlist = plt_get_for_idx (plt);
pl_unlock ();
}
@@ -1877,7 +1898,7 @@ int
streamer_get_current_playlist (void) {
pl_lock ();
if (!streamer_playlist) {
- streamer_playlist = plt_get_curr_ptr ();
+ streamer_playlist = plt_get_curr ();
}
int idx = plt_get_idx_of (streamer_playlist);
pl_unlock ();
@@ -1888,6 +1909,7 @@ void
streamer_notify_playlist_deleted (playlist_t *plt) {
// this is only called from playlist code, no lock required
if (plt == streamer_playlist) {
+ plt_unref (streamer_playlist);
streamer_playlist = NULL;
}
}