summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--deadbeef.h21
-rw-r--r--playlist.c246
-rw-r--r--playlist.h7
-rw-r--r--plmeta.c232
-rw-r--r--pltmeta.c211
-rw-r--r--pltmeta.h55
-rw-r--r--plugins.c17
-rw-r--r--plugins/gtkui/ddbtabstrip.c56
-rw-r--r--plugins/gtkui/fileman.c5
-rw-r--r--plugins/gtkui/gtkui.c5
11 files changed, 598 insertions, 258 deletions
diff --git a/Makefile.am b/Makefile.am
index e6ed3fd1..056b4a9d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,6 +20,7 @@ deadbeef_SOURCES =\
main.c common.h deadbeef.h\
plugins.c plugins.h moduleconf.h\
playlist.c playlist.h \
+ plmeta.c pltmeta.c pltmeta.h\
streamer.c streamer.h\
premix.c premix.h\
messagepump.c messagepump.h\
diff --git a/deadbeef.h b/deadbeef.h
index 0070bc3c..a8f55d15 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -360,12 +360,27 @@ typedef struct {
int (*plt_get_sel_count) (int plt);
int (*plt_add) (int before, const char *title);
void (*plt_remove) (int plt);
- void (*plt_free) (void);
void (*plt_set_curr) (int plt);
int (*plt_get_curr) (void);
- int (*plt_get_title) (int plt, char *buffer, int bufsize);
- int (*plt_set_title) (int plt, const char *title);
void (*plt_move) (int from, int before);
+
+ // 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);
+ // 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);
// playlist control
void (*pl_lock) (void);
void (*pl_unlock) (void);
diff --git a/playlist.c b/playlist.c
index 562763fb..31b22b5c 100644
--- a/playlist.c
+++ b/playlist.c
@@ -48,6 +48,7 @@
#include "threading.h"
#include "metacache.h"
#include "volume.h"
+#include "pltmeta.h"
#define DISABLE_LOCKING 0
#define DEBUG_LOCKING 0
@@ -501,49 +502,33 @@ plt_get_idx_of (playlist_t *plt) {
}
int
-plt_get_title (int plt, char *buffer, int bufsize) {
+plt_get_title (playlist_t *p, char *buffer, int bufsize) {
int i;
PLT_LOCK;
- playlist_t *p = playlists_head;
- for (i = 0; p && i <= plt; i++) {
- if (i == plt) {
- if (!buffer) {
- int l = strlen (p->title);
- PLT_UNLOCK;
- return l;
- }
- strncpy (buffer, p->title, bufsize);
- buffer[bufsize-1] = 0;
- PLT_UNLOCK;
- return 0;
- }
- p = p->next;
+ if (!buffer) {
+ int l = strlen (p->title);
+ PLT_UNLOCK;
+ return l;
}
+ strncpy (buffer, p->title, bufsize);
+ buffer[bufsize-1] = 0;
PLT_UNLOCK;
- buffer[0] = 0;
- return -1;
+ return 0;
}
int
-plt_set_title (int plt, const char *title) {
+plt_set_title (playlist_t *p, const char *title) {
int i;
PLT_LOCK;
- playlist_t *p = playlists_head;
- for (i = 0; p && i <= plt; i++) {
- if (i == plt) {
- free (p->title);
- p->title = strdup (title);
- break;
- }
- p = p->next;
- }
- PLT_UNLOCK;
+ free (p->title);
+ p->title = strdup (title);
plt_gen_conf ();
+ PLT_UNLOCK;
conf_save ();
if (!plt_loading) {
plug_trigger_event (DB_EV_PLAYLISTSWITCH, 0);
}
- return i == plt ? 0 : -1;
+ return 0;
}
void
@@ -1888,209 +1873,6 @@ pl_item_unref (playItem_t *it) {
UNLOCK;
}
-void
-pl_add_meta (playItem_t *it, const char *key, const char *value) {
- LOCK;
- // check if it's already set
- DB_metaInfo_t *tail = NULL;
- DB_metaInfo_t *m = it->meta;
- while (m) {
- if (!strcasecmp (key, m->key)) {
- // duplicate key
- UNLOCK;
- return;
- }
- tail = m;
- m = m->next;
- }
- // add
- char str[256];
- if (!value || !*value) {
- UNLOCK;
- return;
-#if 0
- if (!strcasecmp (key, "title")) {
- // cut filename without path and extension
- const char *pext = pl_find_meta (it, ":URI") + strlen (pl_find_meta (it, ":URI")) - 1;
- while (pext >= pl_find_meta (it, ":URI") && *pext != '.') {
- pext--;
- }
- const char *pname = pext;
- while (pname >= pl_find_meta (it, ":URI") && *pname != '/') {
- pname--;
- }
- if (*pname == '/') {
- pname++;
- }
- strncpy (str, pname, pext-pname);
- str[pext-pname] = 0;
- value = str;
- }
- else {
- UNLOCK;
- return;
- }
-#endif
- }
- m = malloc (sizeof (DB_metaInfo_t));
- memset (m, 0, sizeof (DB_metaInfo_t));
- m->key = metacache_add_string (key); //key;
- m->value = metacache_add_string (value); //strdup (value);
-
- if (tail) {
- tail->next = m;
- }
- else {
- it->meta = m;
- }
- UNLOCK;
-}
-
-void
-pl_append_meta (playItem_t *it, const char *key, const char *value) {
- const char *old = pl_find_meta (it, key);
- size_t newlen = strlen (value);
- if (!old) {
- pl_add_meta (it, key, value);
- }
- else {
- // check for duplicate data
- const char *str = old;
- int len;
- while (str) {
- char *next = strchr (str, '\n');
-
- if (next) {
- len = next - str;
- next++;
- }
- else {
- len = strlen (str);
- }
-
- if (len == newlen && !memcmp (str, value, len)) {
- return;
- }
-
- str = next;
- }
- int sz = strlen (old) + newlen + 2;
- char out[sz];
- snprintf (out, sz, "%s\n%s", old, value);
- pl_replace_meta (it, key, out);
- }
-}
-
-void
-pl_replace_meta (playItem_t *it, const char *key, const char *value) {
- LOCK;
- // check if it's already set
- DB_metaInfo_t *m = it->meta;
- while (m) {
- if (!strcasecmp (key, m->key)) {
- break;
- }
- m = m->next;
- }
- if (m) {
- metacache_remove_string (m->value);
- m->value = metacache_add_string (value);
- UNLOCK;
- return;
- }
- else {
- pl_add_meta (it, key, value);
- }
- UNLOCK;
-}
-
-void
-pl_set_meta_int (playItem_t *it, const char *key, int value) {
- char s[20];
- snprintf (s, sizeof (s), "%d", value);
- pl_replace_meta (it, key, s);
-}
-
-void
-pl_set_meta_float (playItem_t *it, const char *key, float value) {
- char s[20];
- snprintf (s, sizeof (s), "%f", value);
- pl_replace_meta (it, key, s);
-}
-
-void
-pl_delete_meta (playItem_t *it, const char *key) {
- DB_metaInfo_t *prev = NULL;
- DB_metaInfo_t *m = it->meta;
- while (m) {
- if (!strcasecmp (key, m->key)) {
- if (prev) {
- prev->next = m->next;
- }
- else {
- it->meta = m->next;
- }
- metacache_remove_string (m->key);
- metacache_remove_string (m->value);
- free (m);
- break;
- }
- prev = m;
- m = m->next;
- }
-}
-
-const char *
-pl_find_meta (playItem_t *it, const char *key) {
- DB_metaInfo_t *m = it->meta;
- while (m) {
- if (!strcasecmp (key, m->key)) {
- return m->value;
- }
- m = m->next;
- }
- return NULL;
-}
-
-int
-pl_find_meta_int (playItem_t *it, const char *key, int def) {
- const char *val = pl_find_meta (it, key);
- return val ? atoi (val) : def;
-}
-
-float
-pl_find_meta_float (playItem_t *it, const char *key, float def) {
- const char *val = pl_find_meta (it, key);
- return val ? atof (val) : def;
-}
-
-DB_metaInfo_t *
-pl_get_metadata_head (playItem_t *it) {
- return it->meta;
-}
-
-void
-pl_delete_metadata (playItem_t *it, DB_metaInfo_t *meta) {
- DB_metaInfo_t *prev = NULL;
- DB_metaInfo_t *m = it->meta;
- while (m) {
- if (m == meta) {
- if (prev) {
- prev->next = m->next;
- }
- else {
- it->meta = m->next;
- }
- metacache_remove_string (m->key);
- metacache_remove_string (m->value);
- free (m);
- break;
- }
- prev = m;
- m = m->next;
- }
-}
-
int
pl_delete_selected (void) {
GLOBAL_LOCK;
diff --git a/playlist.h b/playlist.h
index 40cfa1d6..c96c1870 100644
--- a/playlist.h
+++ b/playlist.h
@@ -49,12 +49,13 @@ typedef struct playItem_s {
typedef struct playlist_s {
char *title;
+ struct playlist_s *next;
int count[2];
float totaltime;
playItem_t *head[PL_MAX_ITERATORS]; // head of linked list
playItem_t *tail[PL_MAX_ITERATORS]; // tail of linked list
int current_row[PL_MAX_ITERATORS]; // current row (cursor)
- struct playlist_s *next;
+ struct DB_metaInfo_s *meta; // linked list storing metainfo
} playlist_t;
// global playlist control functions
@@ -126,10 +127,10 @@ int
plt_get_idx_of (playlist_t *plt);
int
-plt_get_title (int plt, char *buffer, int bufsize);
+plt_get_title (playlist_t *plt, char *buffer, int bufsize);
int
-plt_set_title (int plt, const char *title);
+plt_set_title (playlist_t *plt, const char *title);
// moves playlist #from to position #to
void
diff --git a/plmeta.c b/plmeta.c
new file mode 100644
index 00000000..ed1329e4
--- /dev/null
+++ b/plmeta.c
@@ -0,0 +1,232 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "playlist.h"
+#include "deadbeef.h"
+#include "metacache.h"
+
+#define LOCK {pl_lock();}
+#define UNLOCK {pl_unlock();}
+
+void
+pl_add_meta (playItem_t *it, const char *key, const char *value) {
+ LOCK;
+ // check if it's already set
+ DB_metaInfo_t *tail = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ // duplicate key
+ UNLOCK;
+ return;
+ }
+ tail = m;
+ m = m->next;
+ }
+ // add
+ char str[256];
+ if (!value || !*value) {
+ UNLOCK;
+ return;
+#if 0
+ if (!strcasecmp (key, "title")) {
+ // cut filename without path and extension
+ const char *pext = pl_find_meta (it, ":URI") + strlen (pl_find_meta (it, ":URI")) - 1;
+ while (pext >= pl_find_meta (it, ":URI") && *pext != '.') {
+ pext--;
+ }
+ const char *pname = pext;
+ while (pname >= pl_find_meta (it, ":URI") && *pname != '/') {
+ pname--;
+ }
+ if (*pname == '/') {
+ pname++;
+ }
+ strncpy (str, pname, pext-pname);
+ str[pext-pname] = 0;
+ value = str;
+ }
+ else {
+ UNLOCK;
+ return;
+ }
+#endif
+ }
+ m = malloc (sizeof (DB_metaInfo_t));
+ memset (m, 0, sizeof (DB_metaInfo_t));
+ m->key = metacache_add_string (key); //key;
+ m->value = metacache_add_string (value); //strdup (value);
+
+ if (tail) {
+ tail->next = m;
+ }
+ else {
+ it->meta = m;
+ }
+ UNLOCK;
+}
+
+void
+pl_append_meta (playItem_t *it, const char *key, const char *value) {
+ const char *old = pl_find_meta (it, key);
+ size_t newlen = strlen (value);
+ if (!old) {
+ pl_add_meta (it, key, value);
+ }
+ else {
+ // check for duplicate data
+ const char *str = old;
+ int len;
+ while (str) {
+ char *next = strchr (str, '\n');
+
+ if (next) {
+ len = next - str;
+ next++;
+ }
+ else {
+ len = strlen (str);
+ }
+
+ if (len == newlen && !memcmp (str, value, len)) {
+ return;
+ }
+
+ str = next;
+ }
+ int sz = strlen (old) + newlen + 2;
+ char out[sz];
+ snprintf (out, sz, "%s\n%s", old, value);
+ pl_replace_meta (it, key, out);
+ }
+}
+
+void
+pl_replace_meta (playItem_t *it, const char *key, const char *value) {
+ LOCK;
+ // check if it's already set
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ break;
+ }
+ m = m->next;
+ }
+ if (m) {
+ metacache_remove_string (m->value);
+ m->value = metacache_add_string (value);
+ UNLOCK;
+ return;
+ }
+ else {
+ pl_add_meta (it, key, value);
+ }
+ UNLOCK;
+}
+
+void
+pl_set_meta_int (playItem_t *it, const char *key, int value) {
+ char s[20];
+ snprintf (s, sizeof (s), "%d", value);
+ pl_replace_meta (it, key, s);
+}
+
+void
+pl_set_meta_float (playItem_t *it, const char *key, float value) {
+ char s[20];
+ snprintf (s, sizeof (s), "%f", value);
+ pl_replace_meta (it, key, s);
+}
+
+void
+pl_delete_meta (playItem_t *it, const char *key) {
+ DB_metaInfo_t *prev = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ if (prev) {
+ prev->next = m->next;
+ }
+ else {
+ it->meta = m->next;
+ }
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ break;
+ }
+ prev = m;
+ m = m->next;
+ }
+}
+
+const char *
+pl_find_meta (playItem_t *it, const char *key) {
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ return m->value;
+ }
+ m = m->next;
+ }
+ return NULL;
+}
+
+int
+pl_find_meta_int (playItem_t *it, const char *key, int def) {
+ const char *val = pl_find_meta (it, key);
+ return val ? atoi (val) : def;
+}
+
+float
+pl_find_meta_float (playItem_t *it, const char *key, float def) {
+ const char *val = pl_find_meta (it, key);
+ return val ? atof (val) : def;
+}
+
+DB_metaInfo_t *
+pl_get_metadata_head (playItem_t *it) {
+ return it->meta;
+}
+
+void
+pl_delete_metadata (playItem_t *it, DB_metaInfo_t *meta) {
+ DB_metaInfo_t *prev = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (m == meta) {
+ if (prev) {
+ prev->next = m->next;
+ }
+ else {
+ it->meta = m->next;
+ }
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ break;
+ }
+ prev = m;
+ m = m->next;
+ }
+}
+
+
diff --git a/pltmeta.c b/pltmeta.c
new file mode 100644
index 00000000..b3895b26
--- /dev/null
+++ b/pltmeta.c
@@ -0,0 +1,211 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "playlist.h"
+#include "deadbeef.h"
+#include "metacache.h"
+#include "pltmeta.h"
+
+#define LOCK {pl_lock();}
+#define UNLOCK {pl_unlock();}
+
+void
+plt_add_meta (playlist_t *it, const char *key, const char *value) {
+ LOCK;
+ // check if it's already set
+ DB_metaInfo_t *tail = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ // duplicate key
+ UNLOCK;
+ return;
+ }
+ tail = m;
+ m = m->next;
+ }
+ // add
+ char str[256];
+ if (!value || !*value) {
+ UNLOCK;
+ return;
+ }
+ m = malloc (sizeof (DB_metaInfo_t));
+ memset (m, 0, sizeof (DB_metaInfo_t));
+ m->key = metacache_add_string (key); //key;
+ m->value = metacache_add_string (value); //strdup (value);
+
+ if (tail) {
+ tail->next = m;
+ }
+ else {
+ it->meta = m;
+ }
+ UNLOCK;
+}
+
+void
+plt_append_meta (playlist_t *it, const char *key, const char *value) {
+ const char *old = plt_find_meta (it, key);
+ size_t newlen = strlen (value);
+ if (!old) {
+ plt_add_meta (it, key, value);
+ }
+ else {
+ // check for duplicate data
+ const char *str = old;
+ int len;
+ while (str) {
+ char *next = strchr (str, '\n');
+
+ if (next) {
+ len = next - str;
+ next++;
+ }
+ else {
+ len = strlen (str);
+ }
+
+ if (len == newlen && !memcmp (str, value, len)) {
+ return;
+ }
+
+ str = next;
+ }
+ int sz = strlen (old) + newlen + 2;
+ char out[sz];
+ snprintf (out, sz, "%s\n%s", old, value);
+ plt_replace_meta (it, key, out);
+ }
+}
+
+void
+plt_replace_meta (playlist_t *it, const char *key, const char *value) {
+ LOCK;
+ // check if it's already set
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ break;
+ }
+ m = m->next;
+ }
+ if (m) {
+ metacache_remove_string (m->value);
+ m->value = metacache_add_string (value);
+ UNLOCK;
+ return;
+ }
+ else {
+ plt_add_meta (it, key, value);
+ }
+ UNLOCK;
+}
+
+void
+plt_set_meta_int (playlist_t *it, const char *key, int value) {
+ char s[20];
+ snprintf (s, sizeof (s), "%d", value);
+ plt_replace_meta (it, key, s);
+}
+
+void
+plt_set_meta_float (playlist_t *it, const char *key, float value) {
+ char s[20];
+ snprintf (s, sizeof (s), "%f", value);
+ plt_replace_meta (it, key, s);
+}
+
+void
+plt_delete_meta (playlist_t *it, const char *key) {
+ DB_metaInfo_t *prev = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ if (prev) {
+ prev->next = m->next;
+ }
+ else {
+ it->meta = m->next;
+ }
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ break;
+ }
+ prev = m;
+ m = m->next;
+ }
+}
+
+const char *
+plt_find_meta (playlist_t *it, const char *key) {
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ return m->value;
+ }
+ m = m->next;
+ }
+ return NULL;
+}
+
+int
+plt_find_meta_int (playlist_t *it, const char *key, int def) {
+ const char *val = plt_find_meta (it, key);
+ return val ? atoi (val) : def;
+}
+
+float
+plt_find_meta_float (playlist_t *it, const char *key, float def) {
+ const char *val = plt_find_meta (it, key);
+ return val ? atof (val) : def;
+}
+
+DB_metaInfo_t *
+plt_get_metadata_head (playlist_t *it) {
+ return it->meta;
+}
+
+void
+plt_delete_metadata (playlist_t *it, DB_metaInfo_t *meta) {
+ DB_metaInfo_t *prev = NULL;
+ DB_metaInfo_t *m = it->meta;
+ while (m) {
+ if (m == meta) {
+ if (prev) {
+ prev->next = m->next;
+ }
+ else {
+ it->meta = m->next;
+ }
+ metacache_remove_string (m->key);
+ metacache_remove_string (m->value);
+ free (m);
+ break;
+ }
+ prev = m;
+ m = m->next;
+ }
+}
+
+
+
diff --git a/pltmeta.h b/pltmeta.h
new file mode 100644
index 00000000..594d40db
--- /dev/null
+++ b/pltmeta.h
@@ -0,0 +1,55 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2011 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef __PLMETA_H
+#define __PLMETA_H
+
+void
+plt_add_meta (playlist_t *it, const char *key, const char *value);
+
+void
+plt_append_meta (playlist_t *it, const char *key, const char *value);
+
+void
+plt_replace_meta (playlist_t *it, const char *key, const char *value);
+
+void
+plt_set_meta_int (playlist_t *it, const char *key, int value);
+
+void
+plt_set_meta_float (playlist_t *it, const char *key, float value);
+
+void
+plt_delete_meta (playlist_t *it, const char *key);
+
+const char *
+plt_find_meta (playlist_t *it, const char *key);
+
+int
+plt_find_meta_int (playlist_t *it, const char *key, int def);
+
+float
+plt_find_meta_float (playlist_t *it, const char *key, float def);
+
+DB_metaInfo_t *
+plt_get_metadata_head (playlist_t *it);
+
+void
+plt_delete_metadata (playlist_t *it, DB_metaInfo_t *meta);
+
+#endif
diff --git a/plugins.c b/plugins.c
index 58204a6c..136080e7 100644
--- a/plugins.c
+++ b/plugins.c
@@ -44,6 +44,7 @@
#include "vfs.h"
#include "premix.h"
#include "dsppreset.h"
+#include "pltmeta.h"
#define trace(...) { fprintf(stderr, __VA_ARGS__); }
//#define trace(fmt,...)
@@ -114,12 +115,22 @@ static DB_functions_t deadbeef_api = {
.plt_get_sel_count = plt_get_sel_count,
.plt_add = plt_add,
.plt_remove = plt_remove,
- .plt_free = plt_free,
.plt_set_curr = plt_set_curr,
.plt_get_curr = plt_get_curr,
- .plt_get_title = plt_get_title,
- .plt_set_title = plt_set_title,
.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,
+
+ // 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,
+
// playlist access
.pl_lock = pl_lock,
.pl_unlock = pl_unlock,
diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c
index 325f7a25..503368c3 100644
--- a/plugins/gtkui/ddbtabstrip.c
+++ b/plugins/gtkui/ddbtabstrip.c
@@ -43,7 +43,14 @@ extern GtkWidget *theme_button;
void
plt_get_title_wrapper (int plt, char *buffer, int len) {
- deadbeef->plt_get_title (plt, buffer, len);
+ if (plt == -1) {
+ strcpy (buffer, "");
+ return;
+ }
+ deadbeef->plt_lock ();
+ void *p = deadbeef->plt_get_handle (plt);
+ deadbeef->plt_get_title (p, buffer, len);
+ deadbeef->plt_unlock ();
char *end;
if (!g_utf8_validate (buffer, -1, (const gchar **)&end)) {
*end = 0;
@@ -458,6 +465,32 @@ tabstrip_adjust_hscroll (DdbTabStrip *ts) {
}
void
+set_tab_text_color (int idx) {
+ if (idx == -1) {
+ return;
+ }
+ deadbeef->plt_lock ();
+ void *plt = deadbeef->plt_get_handle (idx);
+ const char *clr = deadbeef->plt_find_meta (plt, "gui.color");
+ int fallback = 1;
+ if (clr) {
+ int r, g, b;
+ if (3 == sscanf (clr, "%02x%02x%02x", &r, &g, &b)) {
+ fallback = 0;
+ float fg[3] = {(float)r/0xff, (float)g/0xff, (float)b/0xff};
+ draw_set_fg_color (fg);
+ }
+ }
+ if (fallback) {
+ GdkColor color;
+ gtkui_get_tabstrip_text_color (&color);
+ float fg[3] = {(float)color.red/0xffff, (float)color.green/0xffff, (float)color.blue/0xffff};
+ draw_set_fg_color (fg);
+ }
+ deadbeef->plt_unlock ();
+}
+
+void
tabstrip_render (DdbTabStrip *ts) {
GtkWidget *widget = GTK_WIDGET (ts);
GdkDrawable *backbuf = gtk_widget_get_window (widget);
@@ -520,10 +553,8 @@ tabstrip_render (DdbTabStrip *ts) {
ddb_tabstrip_draw_tab (widget, backbuf, idx == tab_selected, x, y, w, h);
char tab_title[100];
plt_get_title_wrapper (idx, tab_title, sizeof (tab_title));
- GdkColor color;
- gtkui_get_tabstrip_text_color (&color);
- float fg[3] = {(float)color.red/0xffff, (float)color.green/0xffff, (float)color.blue/0xffff};
- draw_set_fg_color (fg);
+
+ set_tab_text_color (idx);
draw_text (x + text_left_padding, y + h/2 - draw_get_font_size()/2 + text_vert_offset, w, 0, tab_title);
}
x += w - tab_overlap_size;
@@ -548,10 +579,7 @@ tabstrip_render (DdbTabStrip *ts) {
ddb_tabstrip_draw_tab (widget, backbuf, 1, x, y, w, h);
char tab_title[100];
plt_get_title_wrapper (idx, tab_title, sizeof (tab_title));
- GdkColor color;
- gtkui_get_tabstrip_text_color (&color);
- float fg[3] = {(float)color.red/0xffff, (float)color.green/0xffff, (float)color.blue/0xffff};
- draw_set_fg_color (fg);
+ set_tab_text_color (idx);
draw_text (x + text_left_padding, y + h/2 - draw_get_font_size()/2 + text_vert_offset, w, 0, tab_title);
}
else {
@@ -570,10 +598,7 @@ tabstrip_render (DdbTabStrip *ts) {
ddb_tabstrip_draw_tab (widget, backbuf, 1, x, y, w, h);
char tab_title[100];
plt_get_title_wrapper (idx, tab_title, sizeof (tab_title));
- GdkColor color;
- gtkui_get_tabstrip_text_color (&color);
- float fg[3] = {(float)color.red/0xffff, (float)color.green/0xffff, (float)color.blue/0xffff};
- draw_set_fg_color (fg);
+ set_tab_text_color (idx);
draw_text (x + text_left_padding, y + h/2 - draw_get_font_size()/2 + text_vert_offset, w, 0, tab_title);
}
break;
@@ -643,7 +668,10 @@ on_rename_playlist1_activate (GtkMenuItem *menuitem,
int res = gtk_dialog_run (GTK_DIALOG (dlg));
if (res == GTK_RESPONSE_OK) {
const char *text = gtk_entry_get_text (GTK_ENTRY (e));
- deadbeef->plt_set_title (tab_clicked, text);
+ deadbeef->plt_lock ();
+ void *p = deadbeef->plt_get_handle (tab_clicked);
+ deadbeef->plt_set_title (p, text);
+ deadbeef->plt_unlock ();
}
gtk_widget_destroy (dlg);
}
diff --git a/plugins/gtkui/fileman.c b/plugins/gtkui/fileman.c
index d4ffb518..d33764c0 100644
--- a/plugins/gtkui/fileman.c
+++ b/plugins/gtkui/fileman.c
@@ -28,15 +28,16 @@ gtkpl_add_dirs (GSList *lst) {
&& 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);
char t[1000];
- if (!deadbeef->plt_get_title (plt, t, sizeof (t))) {
+ if (!deadbeef->plt_get_title (p, t, sizeof (t))) {
char *def = _("New Playlist");
if (!strncmp (t, def, strlen (def))) {
const char *folder = strrchr ((char*)lst->data, '/');
if (!folder) {
folder = lst->data;
}
- deadbeef->plt_set_title (plt, folder+1);
+ deadbeef->plt_set_title (p, folder+1);
}
}
}
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index f2c6d30d..7700e20f 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -904,13 +904,16 @@ gtkui_add_new_playlist (void) {
else {
snprintf (name, sizeof (name), _("New Playlist (%d)"), idx);
}
+ deadbeef->plt_lock ();
for (i = 0; i < cnt; i++) {
char t[100];
- deadbeef->plt_get_title (i, t, sizeof (t));
+ void *plt = deadbeef->plt_get_handle (i);
+ deadbeef->plt_get_title (plt, t, sizeof (t));
if (!strcasecmp (t, name)) {
break;
}
}
+ deadbeef->plt_unlock ();
if (i == cnt) {
return deadbeef->plt_add (cnt, name);
}