diff options
-rw-r--r-- | deadbeef.h | 8 | ||||
-rw-r--r-- | playlist.c | 219 | ||||
-rw-r--r-- | playlist.h | 24 | ||||
-rw-r--r-- | plugins.c | 6 | ||||
-rw-r--r-- | plugins/gtkui/ddblistview.c | 59 | ||||
-rw-r--r-- | plugins/gtkui/ddblistview.h | 5 | ||||
-rw-r--r-- | plugins/gtkui/ddbtabstrip.c | 12 | ||||
-rw-r--r-- | plugins/gtkui/fileman.c | 4 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.c | 21 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.h | 3 | ||||
-rw-r--r-- | plugins/gtkui/mainplaylist.c | 5 | ||||
-rw-r--r-- | plugins/gtkui/plcommon.c | 2 | ||||
-rw-r--r-- | plugins/gtkui/search.c | 9 | ||||
-rw-r--r-- | plugins/gtkui/search.h | 3 | ||||
-rw-r--r-- | plugins/gtkui/trkproperties.c | 3 | ||||
-rw-r--r-- | streamer.c | 58 |
16 files changed, 228 insertions, 213 deletions
@@ -383,6 +383,12 @@ typedef struct { int (*plt_get_title) (void *handle, char *buffer, int bufsize); int (*plt_set_title) (void *handle, const char *title); + // sets the modification time using time(NULL) call + void (*plt_modified) (void *handle); + + // returns the time of last modification + time_t (*plt_get_modification_time) (void *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); @@ -400,8 +406,6 @@ typedef struct { // playlist locking void (*pl_lock) (void); void (*pl_unlock) (void); - void (*plt_lock) (void); - void (*plt_unlock) (void); // playlist tracks access DB_playItem_t * (*pl_item_alloc) (void); @@ -85,12 +85,6 @@ static uintptr_t mutex_plt; #define LOCK {pl_lock();} #define UNLOCK {pl_unlock();} -#define PLT_LOCK {plt_lock();} -#define PLT_UNLOCK {plt_unlock();} - -#define GLOBAL_LOCK {pl_global_lock();} -#define GLOBAL_UNLOCK {pl_global_unlock();} - static playlist_t dummy_playlist; // used at startup to prevent crashes static int pl_order; // mirrors "playback.order" config variable @@ -139,45 +133,14 @@ pl_free (void) { } #if DEBUG_LOCKING -int plt_lock_cnt = 0; -#endif -pthread_t plt_lock_tid = 0; -void -plt_lock (void) { - pl_lock (); - return; -#if !DISABLE_LOCKING - mutex_lock (mutex_plt); - plt_lock_tid = pthread_self(); -#if DEBUG_LOCKING - plt_lock_cnt++; - printf ("cnt: %d\n", plt_lock_cnt); -#endif -#endif -} - -void -plt_unlock (void) { - pl_unlock (); - return; -#if !DISABLE_LOCKING - mutex_unlock (mutex_plt); -#if DEBUG_LOCKING - plt_lock_cnt--; - printf ("cnt: %d\n", plt_lock_cnt); -#endif -#endif -} - -#if DEBUG_LOCKING int pl_lock_cnt = 0; #endif -pthread_t pl_lock_tid = 0; +//pthread_t pl_lock_tid = 0; void pl_lock (void) { #if !DISABLE_LOCKING mutex_lock (mutex); - pl_lock_tid = pthread_self(); + //pl_lock_tid = pthread_self(); #if DEBUG_LOCKING pl_lock_cnt++; @@ -197,18 +160,6 @@ pl_unlock (void) { #endif } -void -pl_global_lock (void) { - PLT_LOCK; - LOCK; -} - -void -pl_global_unlock (void) { - UNLOCK; - PLT_UNLOCK; -} - static void pl_item_free (playItem_t *it); @@ -217,7 +168,7 @@ plt_gen_conf (void) { if (plt_loading) { return; } - PLT_LOCK; + LOCK; int cnt = plt_get_count (); int i; conf_remove_items ("playlist.tab."); @@ -228,7 +179,7 @@ plt_gen_conf (void) { snprintf (s, sizeof (s), "playlist.tab.%02d", i); conf_set_str (s, p->title); } - PLT_UNLOCK; + UNLOCK; } playlist_t * @@ -301,9 +252,10 @@ plt_add (int before, const char *title) { playlist_t *plt = malloc (sizeof (playlist_t)); memset (plt, 0, sizeof (playlist_t)); plt->title = strdup (title); + plt_modified (plt); trace ("locking\n"); - PLT_LOCK; + LOCK; trace ("locked\n"); playlist_t *p_before = NULL; playlist_t *p_after = playlists_head; @@ -353,7 +305,7 @@ plt_add (int before, const char *title) { } } } - PLT_UNLOCK; + UNLOCK; plt_gen_conf (); if (!plt_loading) { @@ -369,7 +321,7 @@ void plt_remove (int plt) { int i; assert (plt >= 0 && plt < playlists_count); - PLT_LOCK; + LOCK; // find playlist and notify streamer playlist_t *p = playlists_head; @@ -404,7 +356,7 @@ plt_remove (int plt) { pl_clear (); free (playlist->title); playlist->title = strdup (_("Default")); - PLT_UNLOCK; + UNLOCK; plt_gen_conf (); conf_save (); pl_save_n (0); @@ -447,7 +399,7 @@ plt_remove (int plt) { free (p); playlists_count--; - PLT_UNLOCK; + UNLOCK; plt_gen_conf (); conf_save (); @@ -471,7 +423,7 @@ plt_find (const char *name) { void plt_set_curr (int plt) { int i; - PLT_LOCK; + LOCK; playlist_t *p = playlists_head; for (i = 0; p && p->next && i < plt; i++) { p = p->next; @@ -484,64 +436,64 @@ plt_set_curr (int plt) { conf_save (); } } - PLT_UNLOCK; + UNLOCK; } int plt_get_curr (void) { int i; - PLT_LOCK; + LOCK; playlist_t *p = playlists_head; for (i = 0; p && i < playlists_count; i++) { if (p == playlist) { - PLT_UNLOCK; + UNLOCK; return i; } p = p->next; } - PLT_UNLOCK; + UNLOCK; return -1; } int plt_get_idx_of (playlist_t *plt) { int i; - PLT_LOCK; + LOCK; playlist_t *p = playlists_head; for (i = 0; p && i < playlists_count; i++) { if (p == plt) { - PLT_UNLOCK; + UNLOCK; return i; } p = p->next; } - PLT_UNLOCK; + UNLOCK; return -1; } int plt_get_title (playlist_t *p, char *buffer, int bufsize) { int i; - PLT_LOCK; + LOCK; if (!buffer) { int l = strlen (p->title); - PLT_UNLOCK; + UNLOCK; return l; } strncpy (buffer, p->title, bufsize); buffer[bufsize-1] = 0; - PLT_UNLOCK; + UNLOCK; return 0; } int plt_set_title (playlist_t *p, const char *title) { int i; - PLT_LOCK; + LOCK; free (p->title); p->title = strdup (title); plt_gen_conf (); - PLT_UNLOCK; + UNLOCK; conf_save (); if (!plt_loading) { plug_trigger_event (DB_EV_PLAYLISTSWITCH, 0); @@ -550,9 +502,28 @@ plt_set_title (playlist_t *p, const char *title) { } void +plt_modified (playlist_t *plt) { + pl_lock (); + time_t modtime = time (NULL); + if (modtime <= plt->modification_time) { + modtime = plt->modification_time+1; + } + plt->modification_time = modtime; + pl_unlock (); +} + +time_t +plt_get_modification_time (playlist_t *plt) { + pl_lock (); + time_t res = plt->modification_time; + pl_unlock (); + return res; +} + +void plt_free (void) { trace ("plt_free\n"); - PLT_LOCK; + LOCK; pl_playqueue_clear (); plt_loading = 1; while (playlists_head) { @@ -566,7 +537,7 @@ plt_free (void) { plt_remove (0); } plt_loading = 0; - PLT_UNLOCK; + UNLOCK; } void @@ -576,7 +547,7 @@ plt_move (int from, int to) { } trace ("plt_move %d -> %d\n", from, to); int i; - PLT_LOCK; + LOCK; playlist_t *p = playlists_head; playlist_t *pfrom = NULL; @@ -588,12 +559,12 @@ plt_move (int from, int to) { char temp[PATH_MAX]; if (snprintf (path1, sizeof (path1), "%s/playlists/%d.dbpl", dbconfdir, from) > sizeof (path1)) { fprintf (stderr, "error: failed to make path string for playlist file\n"); - PLT_UNLOCK; + UNLOCK; return; } if (snprintf (temp, sizeof (temp), "%s/playlists/temp.dbpl", dbconfdir) > sizeof (temp)) { fprintf (stderr, "error: failed to make path string for playlist file\n"); - PLT_UNLOCK; + UNLOCK; return; } @@ -606,7 +577,7 @@ plt_move (int from, int to) { int err = rename (path1, temp); if (err != 0) { fprintf (stderr, "playlist rename %s->%s failed: %s\n", path1, temp, strerror (errno)); - PLT_UNLOCK; + UNLOCK; return; } } @@ -705,7 +676,7 @@ plt_move (int from, int to) { } } - PLT_UNLOCK; + UNLOCK; plt_gen_conf (); conf_save (); } @@ -718,6 +689,7 @@ plt_clear (playlist_t *plt) { } plt->current_row[PL_MAIN] = -1; plt->current_row[PL_SEARCH] = -1; + plt_modified (plt); UNLOCK; } @@ -1675,8 +1647,9 @@ plt_remove_item (playlist_t *playlist, playItem_t *it) { playlist->totaltime = 0; } } - UNLOCK; + plt_modified (playlist); pl_item_unref (it); + UNLOCK; return 0; } @@ -1754,7 +1727,7 @@ pl_get_idx_of_iter (playItem_t *it, int iter) { playItem_t * plt_insert_item (playlist_t *playlist, playItem_t *after, playItem_t *it) { - GLOBAL_LOCK; + LOCK; pl_item_ref (it); if (!after) { it->next[PL_MAIN] = playlist->head[PL_MAIN]; @@ -1797,8 +1770,10 @@ plt_insert_item (playlist_t *playlist, playItem_t *after, playItem_t *it) { if (dur > 0) { playlist->totaltime += dur; } - - GLOBAL_UNLOCK; + + plt_modified (playlist); + + UNLOCK; return it; } @@ -1898,7 +1873,7 @@ pl_item_unref (playItem_t *it) { int pl_delete_selected (void) { - GLOBAL_LOCK; + LOCK; int i = 0; int ret = -1; playItem_t *next = NULL; @@ -1917,13 +1892,13 @@ pl_delete_selected (void) { if (playlist->current_row[PL_SEARCH] >= playlist->count[PL_SEARCH]) { playlist->current_row[PL_SEARCH] = playlist->count[PL_SEARCH] - 1; } - GLOBAL_UNLOCK; + UNLOCK; return ret; } void pl_crop_selected (void) { - GLOBAL_LOCK; + LOCK; playItem_t *next = NULL; for (playItem_t *it = playlist->head[PL_MAIN]; it; it = next) { next = it->next[PL_MAIN]; @@ -1931,12 +1906,12 @@ pl_crop_selected (void) { pl_remove_item (it); } } - GLOBAL_UNLOCK; + UNLOCK; } int pl_save (const char *fname) { - GLOBAL_LOCK; + LOCK; const char *ext = strrchr (fname, '.'); if (ext) { DB_playlist_t **plug = deadbeef->plug_get_playlist_list (); @@ -1947,7 +1922,7 @@ pl_save (const char *fname) { for (int e = 0; exts[e]; e++) { if (!strcasecmp (exts[e], ext+1)) { int res = plug[i]->save (fname, (DB_playItem_t *)playlist->head[PL_MAIN], NULL); - GLOBAL_UNLOCK; + UNLOCK; return res; } } @@ -1961,7 +1936,7 @@ pl_save (const char *fname) { uint8_t minorver = PLAYLIST_MINOR_VER; FILE *fp = fopen (fname, "w+b"); if (!fp) { - GLOBAL_UNLOCK; + UNLOCK; return -1; } if (fwrite (magic, 1, 4, fp) != 4) { @@ -2120,11 +2095,11 @@ pl_save (const char *fname) { } } - GLOBAL_UNLOCK; + UNLOCK; fclose (fp); return 0; save_fail: - GLOBAL_UNLOCK; + UNLOCK; fclose (fp); unlink (fname); return -1; @@ -2140,13 +2115,13 @@ pl_save_n (int n) { // make folder mkdir (path, 0755); - PLT_LOCK; + LOCK; int err = 0; plt_loading = 1; if (snprintf (path, sizeof (path), "%s/playlists/%d.dbpl", dbconfdir, n) > sizeof (path)) { fprintf (stderr, "error: failed to make path string for playlist file\n"); - PLT_UNLOCK; + UNLOCK; return -1; } @@ -2156,7 +2131,7 @@ pl_save_n (int n) { err = pl_save (path); playlist = orig; plt_loading = 0; - PLT_UNLOCK; + UNLOCK; return err; } @@ -2176,7 +2151,7 @@ pl_save_all (void) { // make folder mkdir (path, 0755); - PLT_LOCK; + LOCK; playlist_t *p = playlists_head; int i; int cnt = plt_get_count (); @@ -2198,7 +2173,7 @@ pl_save_all (void) { } plt_set_curr (curr); plt_loading = 0; - PLT_UNLOCK; + UNLOCK; return err; } @@ -2208,7 +2183,7 @@ pl_load (const char *fname) { if (!fp) { return -1; } - GLOBAL_LOCK; + LOCK; playlist_t *plt = playlist; plt_clear (plt); @@ -2223,7 +2198,7 @@ pl_load (const char *fname) { 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 (it, fname, NULL, NULL, NULL); - GLOBAL_UNLOCK; + UNLOCK; return 0; } } @@ -2459,7 +2434,7 @@ pl_load (const char *fname) { } } - GLOBAL_UNLOCK; + UNLOCK; if (fp) { fclose (fp); } @@ -2470,7 +2445,7 @@ load_fail: pl_item_unref (it); } pl_clear (); - GLOBAL_UNLOCK; + UNLOCK; if (fp) { fclose (fp); } @@ -2497,7 +2472,7 @@ pl_load_all (void) { return pl_load (defpl); } trace ("pl_load_all started\n"); - GLOBAL_LOCK; + LOCK; trace ("locked\n"); plt_loading = 1; while (it) { @@ -2528,23 +2503,23 @@ pl_load_all (void) { plt_loading = 0; plt_gen_conf (); plug_trigger_event (DB_EV_PLAYLISTSWITCH, 0); - GLOBAL_UNLOCK; + UNLOCK; trace ("pl_load_all finished\n"); return err; } void pl_select_all (void) { - GLOBAL_LOCK; + LOCK; for (playItem_t *it = playlist->head[PL_MAIN]; it; it = it->next[PL_MAIN]) { it->selected = 1; } - GLOBAL_UNLOCK; + UNLOCK; } void plt_reshuffle (playlist_t *playlist, playItem_t **ppmin, playItem_t **ppmax) { - GLOBAL_LOCK; + LOCK; playItem_t *pmin = NULL; playItem_t *pmax = NULL; playItem_t *prev = NULL; @@ -2570,7 +2545,7 @@ plt_reshuffle (playlist_t *playlist, playItem_t **ppmin, playItem_t **ppmax) { if (ppmax) { *ppmax = pmax; } - GLOBAL_UNLOCK; + UNLOCK; } void @@ -2580,7 +2555,7 @@ pl_reshuffle (playItem_t **ppmin, playItem_t **ppmax) { void pl_set_item_duration (playItem_t *it, float duration) { - GLOBAL_LOCK; + LOCK; if (it->in_playlist) { if (it->_duration > 0) { playlist->totaltime -= it->_duration; @@ -2596,7 +2571,7 @@ pl_set_item_duration (playItem_t *it, float duration) { char s[100]; pl_format_time (it->_duration, s, sizeof(s)); pl_replace_meta (it, ":DURATION", s); - GLOBAL_UNLOCK; + UNLOCK; } float @@ -3211,7 +3186,7 @@ pl_sort (int iter, int id, const char *format, int ascending) { if (id == DB_COLUMN_FILENUMBER || !playlist->head[iter] || !playlist->head[iter]->next[iter]) { return; } - GLOBAL_LOCK; + LOCK; struct timeval tm1; gettimeofday (&tm1, NULL); pl_sort_ascending = ascending; @@ -3261,17 +3236,19 @@ pl_sort (int iter, int id, const char *format, int ascending) { int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000); trace ("sort time: %f seconds\n", ms / 1000.f); - GLOBAL_UNLOCK; + plt_modified (playlist); + + UNLOCK; } void pl_reset_cursor (void) { int i; - PLT_LOCK; + LOCK; for (i = 0; i < PL_MAX_ITERATORS; i++) { playlist->current_row[i] = -1; } - PLT_UNLOCK; + UNLOCK; } float @@ -3340,9 +3317,9 @@ pl_get_cursor (int iter) { void pl_set_cursor (int iter, int cursor) { - PLT_LOCK; + LOCK; playlist->current_row[iter] = cursor; - PLT_UNLOCK; + UNLOCK; } // this function must move items in playlist @@ -3350,7 +3327,7 @@ pl_set_cursor (int iter, int cursor) { // drop_before is insertion point void pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexes, int count) { - GLOBAL_LOCK; + LOCK; playlist_t *playlist = playlists_head; playlist_t *to = plt_get_curr_ptr (); @@ -3361,7 +3338,7 @@ pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexe } if (!playlist || !to) { - GLOBAL_UNLOCK; + UNLOCK; return; } @@ -3399,7 +3376,7 @@ pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexe } } no_remove_notify = 0; - GLOBAL_UNLOCK; + UNLOCK; } void @@ -3443,7 +3420,7 @@ pl_copy_items (int iter, int plt_from, playItem_t *before, uint32_t *indices, in void pl_search_reset (void) { - GLOBAL_LOCK; + LOCK; while (playlist->head[PL_SEARCH]) { playItem_t *next = playlist->head[PL_SEARCH]->next[PL_SEARCH]; playlist->head[PL_SEARCH]->selected = 0; @@ -3453,12 +3430,12 @@ pl_search_reset (void) { } playlist->tail[PL_SEARCH] = NULL; playlist->count[PL_SEARCH] = 0; - GLOBAL_UNLOCK; + UNLOCK; } void pl_search_process (const char *text) { - GLOBAL_LOCK; + LOCK; pl_search_reset (); for (playItem_t *it = playlist->head[PL_MAIN]; it; it = it->next[PL_MAIN]) { it->selected = 0; @@ -3482,7 +3459,7 @@ pl_search_process (const char *text) { } } } - GLOBAL_UNLOCK; + UNLOCK; } int @@ -52,6 +52,7 @@ typedef struct playlist_s { struct playlist_s *next; int count[2]; float totaltime; + time_t modification_time; 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) @@ -71,18 +72,11 @@ pl_lock (void); void pl_unlock (void); -void -plt_lock (void); - -void -plt_unlock (void); - -void -pl_global_lock (void); - -void -pl_global_unlock (void); - +//void +//plt_lock (void); +// +//void +//plt_unlock (void); // playlist management functions @@ -132,6 +126,12 @@ plt_get_title (playlist_t *plt, char *buffer, int bufsize); int plt_set_title (playlist_t *plt, const char *title); +void +plt_modified (playlist_t *plt); + +time_t +plt_get_modification_time (playlist_t *plt); + // moves playlist #from to position #to void plt_move (int from, int to); @@ -121,6 +121,8 @@ static DB_functions_t deadbeef_api = { .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_time = (time_t (*) (void *handle))plt_get_modification_time, // playlist metadata .plt_add_meta = (void (*) (void *handle, const char *key, const char *value))plt_add_meta, @@ -134,8 +136,8 @@ static DB_functions_t deadbeef_api = { // playlist access .pl_lock = pl_lock, .pl_unlock = pl_unlock, - .plt_lock = plt_lock, - .plt_unlock = plt_unlock, + //.plt_lock = plt_lock, + //.plt_unlock = plt_unlock, .pl_item_alloc = (DB_playItem_t* (*)(void))pl_item_alloc, .pl_item_alloc_init = (DB_playItem_t* (*)(const char *fname, const char *decoder_id))pl_item_alloc_init, .pl_item_ref = (void (*)(DB_playItem_t *))pl_item_ref, diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c index 18ccf4a4..c50dd9df 100644 --- a/plugins/gtkui/ddblistview.c +++ b/plugins/gtkui/ddblistview.c @@ -85,6 +85,9 @@ static void ddb_listview_init(DdbListview *listview); //static void ddb_listview_paint(GtkWidget *widget); static void ddb_listview_destroy(GtkObject *object); +static void +ddb_listview_build_groups (DdbListview *listview); + // fwd decls void ddb_listview_free_groups (DdbListview *listview); @@ -473,11 +476,6 @@ ddb_listview_destroy(GtkObject *object) void ddb_listview_refresh (DdbListview *listview, uint32_t flags) { if (flags & DDB_REFRESH_LIST) { - int height = listview->fullheight; - ddb_listview_build_groups (listview); - if (height != listview->fullheight) { - flags |= DDB_REFRESH_VSCROLL; - } gtk_widget_queue_draw (listview->list); } if (flags & DDB_REFRESH_VSCROLL) { @@ -527,20 +525,33 @@ ddb_listview_list_configure_event (GtkWidget *widget, return FALSE; } +static void +ddb_listview_groupcheck (DdbListview *listview) { + time_t tm = listview->binding->modification_time (); + if (tm != listview->groups_build_time) { + ddb_listview_build_groups (listview); + } +} + // returns Y coordinate of an item by its index int ddb_listview_get_row_pos (DdbListview *listview, int row_idx) { int y = 0; int idx = 0; + deadbeef->pl_lock (); + ddb_listview_groupcheck (listview); DdbListviewGroup *grp = listview->groups; while (grp) { if (idx + grp->num_items > row_idx) { - return y + listview->grouptitle_height + (row_idx - idx) * listview->rowheight; + int i = y + listview->grouptitle_height + (row_idx - idx) * listview->rowheight; + deadbeef->pl_unlock (); + return i; } y += grp->height; idx += grp->num_items; grp = grp->next; } + deadbeef->pl_unlock (); return y; } @@ -552,6 +563,8 @@ ddb_listview_list_pickpoint_y (DdbListview *listview, int y, DdbListviewGroup ** int idx = 0; int grp_y = 0; int gidx = 0; + deadbeef->pl_lock (); + ddb_listview_groupcheck (listview); DdbListviewGroup *grp = listview->groups; while (grp) { int h = grp->height; @@ -570,6 +583,7 @@ ddb_listview_list_pickpoint_y (DdbListview *listview, int y, DdbListviewGroup ** *group_idx = (y - listview->grouptitle_height) / listview->rowheight; *global_idx = idx + *group_idx; } + deadbeef->pl_unlock (); return 0; } grp_y += grp->height; @@ -577,6 +591,7 @@ ddb_listview_list_pickpoint_y (DdbListview *listview, int y, DdbListviewGroup ** grp = grp->next; gidx++; } + deadbeef->pl_unlock (); return -1; } @@ -589,6 +604,7 @@ ddb_listview_list_render (DdbListview *listview, int x, int y, int w, int h) { int idx = 0; int abs_idx = 0; deadbeef->pl_lock (); + ddb_listview_groupcheck (listview); // find 1st group DdbListviewGroup *grp = listview->groups; printf ("starting to render listview, groups=%p, num_items=%d\n", grp, grp?grp->num_items : 0); @@ -1128,6 +1144,8 @@ ddb_listview_list_setup_hscroll (DdbListview *ps) { // returns -1 if row not found int ddb_listview_list_get_drawinfo (DdbListview *listview, int row, DdbListviewGroup **pgrp, int *even, int *cursor, int *group_y, int *x, int *y, int *w, int *h) { + deadbeef->pl_lock (); + ddb_listview_groupcheck (listview); DdbListviewGroup *grp = listview->groups; int idx = 0; int idx2 = 0; @@ -1145,6 +1163,7 @@ ddb_listview_list_get_drawinfo (DdbListview *listview, int row, DdbListviewGroup *y += listview->grouptitle_height + (row - idx) * listview->rowheight; *w = listview->totalwidth; *h = listview->rowheight; + deadbeef->pl_unlock (); return 0; } *y += grpheight; @@ -1152,6 +1171,7 @@ ddb_listview_list_get_drawinfo (DdbListview *listview, int row, DdbListviewGroup idx2 += grp->num_items + 1; grp = grp->next; } + deadbeef->pl_unlock (); return -1; } @@ -1290,11 +1310,11 @@ ddb_listview_header_expose (DdbListview *ps, int x, int y, int w, int h) { void ddb_listview_select_single (DdbListview *ps, int sel) { int nchanged = 0; - deadbeef->plt_lock (); + deadbeef->pl_lock (); DB_playItem_t *sel_it = ps->binding->get_for_idx (sel); if (!sel_it) { - deadbeef->plt_unlock (); + deadbeef->pl_unlock (); return; } @@ -1325,7 +1345,7 @@ ddb_listview_select_single (DdbListview *ps, int sel) { } UNREF (it); UNREF (sel_it); - deadbeef->plt_unlock (); + deadbeef->pl_unlock (); if (nchanged >= NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW, 1) { ddb_listview_refresh (ps, DDB_REFRESH_LIST); @@ -1337,6 +1357,8 @@ ddb_listview_select_single (DdbListview *ps, int sel) { void ddb_listview_click_selection (DdbListview *ps, int ex, int ey, DdbListviewGroup *grp, int grp_index, int sel, int dnd) { + deadbeef->pl_lock (); + ddb_listview_groupcheck (ps); if (sel == -1 && (!grp || grp_index >= grp->num_items)) { // clicked empty space, deselect everything DdbListviewIter it; @@ -1398,6 +1420,7 @@ ddb_listview_click_selection (DdbListview *ps, int ex, int ey, DdbListviewGroup } UNREF (it); } + deadbeef->pl_unlock (); } // {{{ expected behaviour for mouse1 without modifiers: @@ -1421,8 +1444,11 @@ ddb_listview_click_selection (DdbListview *ps, int ex, int ey, DdbListviewGroup void ddb_listview_list_mouse1_pressed (DdbListview *ps, int state, int ex, int ey, GdkEventType type) { // cursor must be set here, but selection must be handled in keyrelease + deadbeef->pl_lock (); + ddb_listview_groupcheck (ps); int cnt = ps->binding->count (); if (cnt == 0) { + deadbeef->pl_unlock (); return; } // remember mouse coords for doubleclick detection @@ -1433,6 +1459,7 @@ ddb_listview_list_mouse1_pressed (DdbListview *ps, int state, int ex, int ey, Gd int grp_index; int sel; if (ddb_listview_list_pickpoint_y (ps, ey + ps->scrollpos, &grp, &grp_index, &sel) == -1) { + deadbeef->pl_unlock (); return; } @@ -1450,6 +1477,7 @@ ddb_listview_list_mouse1_pressed (DdbListview *ps, int state, int ex, int ey, Gd if (it) { ps->binding->unref (it); } + deadbeef->pl_unlock (); return; } } @@ -1486,6 +1514,7 @@ ddb_listview_list_mouse1_pressed (DdbListview *ps, int state, int ex, int ey, Gd int cursor = sel;//ps->binding->cursor (); if (cursor == -1) { // find group + ddb_listview_groupcheck (ps); DdbListviewGroup *g = ps->groups; int idx = 0; while (g) { @@ -1531,6 +1560,7 @@ ddb_listview_list_mouse1_pressed (DdbListview *ps, int state, int ex, int ey, Gd ddb_listview_draw_row (ps, prev, it); UNREF (it); } + deadbeef->pl_unlock (); } void @@ -1650,6 +1680,7 @@ ddb_listview_list_scroll_cb (gpointer data) { void ddb_listview_list_mousemove (DdbListview *ps, GdkEventMotion *ev, int ex, int ey) { + deadbeef->pl_lock (); if (ps->dragwait) { GtkWidget *widget = ps->list; if (gtk_drag_check_threshold (widget, ps->lastpos[0], ex, ps->lastpos[1], ey)) { @@ -1712,6 +1743,7 @@ ddb_listview_list_mousemove (DdbListview *ps, GdkEventMotion *ev, int ex, int ey int idx = 0; if (y == -1) { // find group + ddb_listview_groupcheck (ps); DdbListviewGroup *g = ps->groups; while (g) { if (g == grp) { @@ -1809,6 +1841,7 @@ ddb_listview_list_mousemove (DdbListview *ps, GdkEventMotion *ev, int ex, int ey // debug only // ddb_listview_list_dbg_draw_areasel (widget, event->x, event->y); } + deadbeef->pl_unlock (); } void @@ -2847,6 +2880,8 @@ ddb_listview_free_groups (DdbListview *listview) { void ddb_listview_build_groups (DdbListview *listview) { deadbeef->pl_lock (); + int old_height = listview->fullheight; + listview->groups_build_time = listview->binding->modification_time (); ddb_listview_free_groups (listview); listview->fullheight = 0; @@ -2881,6 +2916,9 @@ ddb_listview_build_groups (DdbListview *listview) { listview->fullheight = grp->height; listview->fullheight += listview->grouptitle_height; deadbeef->pl_unlock (); + if (old_height != listview->fullheight) { + ddb_listview_refresh (listview, DDB_REFRESH_VSCROLL); + } return; } if (!grp || strcmp (str, curr)) { @@ -2922,6 +2960,9 @@ ddb_listview_build_groups (DdbListview *listview) { printf ("groupsize: %d!\n", listview->groups->num_items); } deadbeef->pl_unlock (); + if (old_height != listview->fullheight) { + ddb_listview_refresh (listview, DDB_REFRESH_VSCROLL); + } } void diff --git a/plugins/gtkui/ddblistview.h b/plugins/gtkui/ddblistview.h index d0a7ceb9..5ba1e0ed 100644 --- a/plugins/gtkui/ddblistview.h +++ b/plugins/gtkui/ddblistview.h @@ -85,6 +85,7 @@ typedef struct { void (*col_free_user_data) (void *user_data); void (*vscroll_changed) (int pos); void (*cursor_changed) (int pos); + time_t (*modification_time) (void); } DdbListviewBinding; struct _DdbListviewColumn; @@ -139,6 +140,7 @@ struct _DdbListview { struct _DdbListviewColumn *columns; struct _DdbListviewGroup *groups; + time_t groups_build_time; int fullheight; int block_redraw_on_scroll; int grouptitle_height; @@ -193,8 +195,7 @@ int ddb_listview_column_get_info (DdbListview *listview, int col, const char **title, int *width, int *align_right, int *minheight, void **user_data); int ddb_listview_column_set_info (DdbListview *listview, int col, const char *title, int width, int align_right, int minheight, void *user_data); -void -ddb_listview_build_groups (DdbListview *listview); + void ddb_listview_show_header (DdbListview *listview, int show); diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c index 60b806c8..a1f2aa10 100644 --- a/plugins/gtkui/ddbtabstrip.c +++ b/plugins/gtkui/ddbtabstrip.c @@ -47,10 +47,10 @@ plt_get_title_wrapper (int plt, char *buffer, int len) { strcpy (buffer, ""); return; } - deadbeef->plt_lock (); + deadbeef->pl_lock (); void *p = deadbeef->plt_get_handle (plt); deadbeef->plt_get_title (p, buffer, len); - deadbeef->plt_unlock (); + deadbeef->pl_unlock (); char *end; if (!g_utf8_validate (buffer, -1, (const gchar **)&end)) { *end = 0; @@ -469,7 +469,7 @@ set_tab_text_color (int idx) { if (idx == -1) { return; } - deadbeef->plt_lock (); + deadbeef->pl_lock (); void *plt = deadbeef->plt_get_handle (idx); const char *clr = deadbeef->plt_find_meta (plt, "gui.color"); int fallback = 1; @@ -487,7 +487,7 @@ set_tab_text_color (int idx) { float fg[3] = {(float)color.red/0xffff, (float)color.green/0xffff, (float)color.blue/0xffff}; draw_set_fg_color (fg); } - deadbeef->plt_unlock (); + deadbeef->pl_unlock (); } void @@ -668,10 +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_lock (); + deadbeef->pl_lock (); void *p = deadbeef->plt_get_handle (tab_clicked); deadbeef->plt_set_title (p, text); - deadbeef->plt_unlock (); + deadbeef->pl_unlock (); } gtk_widget_destroy (dlg); } diff --git a/plugins/gtkui/fileman.c b/plugins/gtkui/fileman.c index d33764c0..3b5db560 100644 --- a/plugins/gtkui/fileman.c +++ b/plugins/gtkui/fileman.c @@ -22,7 +22,7 @@ gtkpl_adddir_cb (gpointer data, gpointer userdata) { void gtkpl_add_dirs (GSList *lst) { - deadbeef->plt_lock (); + deadbeef->pl_lock (); 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)) { @@ -42,7 +42,7 @@ gtkpl_add_dirs (GSList *lst) { } } } - deadbeef->plt_unlock (); + deadbeef->pl_unlock (); g_slist_foreach(lst, gtkpl_adddir_cb, NULL); g_slist_free (lst); deadbeef->pl_add_files_end (); diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index a43bf409..0a268a52 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -492,10 +492,6 @@ playlistchanged_cb (gpointer none) { void gtkui_playlist_changed (void) { - DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); - ddb_listview_build_groups (pl); - search_rebuild_groups (); - g_idle_add (playlistchanged_cb, NULL); } @@ -535,10 +531,6 @@ playlistswitch_cb (gpointer none) { static int gtkui_on_playlistswitch (DB_event_t *ev, uintptr_t data) { - printf ("gtkui_on_playlistchanged\n"); - DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); - ddb_listview_build_groups (pl); - search_rebuild_groups (); g_idle_add (playlistswitch_cb, NULL); return 0; } @@ -628,6 +620,15 @@ gtkui_hide_status_icon () { } } +time_t +gtkui_get_curr_playlist_modtime (void) { + deadbeef->pl_lock (); + void *plt = deadbeef->plt_get_handle (deadbeef->plt_get_curr ()); + time_t res = plt ? deadbeef->plt_get_modification_time (plt) : 0; + deadbeef->pl_unlock (); + return res; +} + static int gtkui_on_configchanged (DB_event_t *ev, uintptr_t data) { // order and looping @@ -938,7 +939,7 @@ gtkui_add_new_playlist (void) { else { snprintf (name, sizeof (name), _("New Playlist (%d)"), idx); } - deadbeef->plt_lock (); + deadbeef->pl_lock (); for (i = 0; i < cnt; i++) { char t[100]; void *plt = deadbeef->plt_get_handle (i); @@ -947,7 +948,7 @@ gtkui_add_new_playlist (void) { break; } } - deadbeef->plt_unlock (); + deadbeef->pl_unlock (); if (i == cnt) { return deadbeef->plt_add (cnt, name); } diff --git a/plugins/gtkui/gtkui.h b/plugins/gtkui/gtkui.h index 4074ddb2..e940bcfa 100644 --- a/plugins/gtkui/gtkui.h +++ b/plugins/gtkui/gtkui.h @@ -166,4 +166,7 @@ gtkui_playlist_set_curr (int playlist); void gtkui_setup_gui_refresh (); +time_t +gtkui_get_curr_playlist_modtime (void); + #endif diff --git a/plugins/gtkui/mainplaylist.c b/plugins/gtkui/mainplaylist.c index 340cbfb3..0c736150 100644 --- a/plugins/gtkui/mainplaylist.c +++ b/plugins/gtkui/mainplaylist.c @@ -108,7 +108,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->plt_lock (); + deadbeef->pl_lock (); int curr = deadbeef->plt_get_curr (); if (copy) { deadbeef->pl_copy_items (PL_MAIN, from_playlist, (DB_playItem_t *)before, indices, length); @@ -116,7 +116,7 @@ main_drag_n_drop (DdbListviewIter before, int from_playlist, uint32_t *indices, else { deadbeef->pl_move_items (PL_MAIN, from_playlist, (DB_playItem_t *)before, indices, length); } - deadbeef->plt_unlock (); + deadbeef->pl_unlock (); } void main_external_drag_n_drop (DdbListviewIter before, char *mem, int length) { @@ -284,6 +284,7 @@ DdbListviewBinding main_binding = { .list_context_menu = list_context_menu, .delete_selected = main_delete_selected, .vscroll_changed = main_vscroll_changed, + .modification_time = gtkui_get_curr_playlist_modtime, }; void diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c index 8fbd8dc7..ad758007 100644 --- a/plugins/gtkui/plcommon.c +++ b/plugins/gtkui/plcommon.c @@ -328,7 +328,6 @@ on_remove_from_disk_activate (GtkMenuItem *menuitem, } deadbeef->pl_lock (); - deadbeef->plt_lock (); DB_playItem_t *it = deadbeef->pl_get_first (PL_MAIN); while (it) { @@ -341,7 +340,6 @@ on_remove_from_disk_activate (GtkMenuItem *menuitem, } int cursor = deadbeef->pl_delete_selected (); - deadbeef->plt_unlock (); deadbeef->pl_unlock (); main_refresh (); diff --git a/plugins/gtkui/search.c b/plugins/gtkui/search.c index cde5ceea..9baf18f3 100644 --- a/plugins/gtkui/search.c +++ b/plugins/gtkui/search.c @@ -92,14 +92,6 @@ search_refresh (void) { } } -void -search_rebuild_groups (void) { - if (searchwin) { - GtkWidget *pl = lookup_widget (searchwin, "searchlist"); - ddb_listview_build_groups (DDB_LISTVIEW (pl)); - } -} - ///////// searchwin header handlers gboolean @@ -377,6 +369,7 @@ DdbListviewBinding search_binding = { .header_context_menu = header_context_menu, .list_context_menu = list_context_menu, .delete_selected = search_delete_selected, + .modification_time = gtkui_get_curr_playlist_modtime, }; void diff --git a/plugins/gtkui/search.h b/plugins/gtkui/search.h index ddfe2844..98216d5c 100644 --- a/plugins/gtkui/search.h +++ b/plugins/gtkui/search.h @@ -36,7 +36,4 @@ search_get_idx (DdbListviewIter it); void search_playlist_init (GtkWidget *widget); -void -search_rebuild_groups (void); - #endif // __SEARCH_H diff --git a/plugins/gtkui/trkproperties.c b/plugins/gtkui/trkproperties.c index cc419d59..5b58890c 100644 --- a/plugins/gtkui/trkproperties.c +++ b/plugins/gtkui/trkproperties.c @@ -339,7 +339,6 @@ trkproperties_fill_metadata (void) { void show_track_properties_dlg (void) { - deadbeef->plt_lock (); deadbeef->pl_lock (); if (tracks) { @@ -371,13 +370,11 @@ show_track_properties_dlg (void) { } else { deadbeef->pl_unlock (); - deadbeef->plt_unlock (); return; } } deadbeef->pl_unlock (); - deadbeef->plt_unlock (); GtkTreeView *tree; GtkTreeView *proptree; @@ -191,7 +191,7 @@ streamer_get_playing_track (void) { int str_get_idx_of (playItem_t *it) { - plt_lock (); + pl_lock (); if (!streamer_playlist) { streamer_playlist = plt_get_curr_ptr (); } @@ -202,23 +202,23 @@ str_get_idx_of (playItem_t *it) { idx++; } if (!c) { - plt_unlock (); + pl_unlock (); return -1; } - plt_unlock (); + pl_unlock (); return idx; } playItem_t * str_get_for_idx (int idx) { - plt_lock (); + pl_lock (); if (!streamer_playlist) { streamer_playlist = plt_get_curr_ptr (); } playItem_t *it = streamer_playlist->head[PL_MAIN]; while (idx--) { if (!it) { - plt_unlock (); + pl_unlock (); return NULL; } it = it->next[PL_MAIN]; @@ -226,7 +226,7 @@ str_get_for_idx (int idx) { if (it) { pl_item_ref (it); } - plt_unlock (); + pl_unlock (); return it; } @@ -234,7 +234,7 @@ str_get_for_idx (int idx) { int streamer_move_to_nextsong (int reason) { trace ("streamer_move_to_nextsong (%d)\n", reason); - pl_global_lock (); + pl_lock (); if (!streamer_playlist) { streamer_playlist = plt_get_curr_ptr (); } @@ -247,7 +247,7 @@ streamer_move_to_nextsong (int reason) { if (r >= 0) { pl_item_unref (it); streamer_set_nextsong (r, 1); - pl_global_unlock (); + pl_unlock (); return 0; } else { @@ -263,7 +263,7 @@ streamer_move_to_nextsong (int reason) { trace ("%s found in playlist %d\n", pl_find_meta (it, ":URI"), i); pl_item_unref (it); streamer_set_nextsong (r, 3); - pl_global_unlock (); + pl_unlock (); return 0; } i++; @@ -288,7 +288,7 @@ streamer_move_to_nextsong (int reason) { playlist_t *plt = streamer_playlist; if (!plt->head[PL_MAIN]) { streamer_set_nextsong (-2, 1); - pl_global_unlock (); + pl_unlock (); return 0; } int pl_order = pl_get_order (); @@ -303,7 +303,7 @@ streamer_move_to_nextsong (int reason) { else { streamer_set_nextsong (r, 1); } - pl_global_unlock (); + pl_unlock (); return 0; } @@ -327,12 +327,12 @@ streamer_move_to_nextsong (int reason) { } } if (!it) { - pl_global_unlock (); + pl_unlock (); return -1; } int r = str_get_idx_of (it); streamer_set_nextsong (r, 1); - pl_global_unlock (); + pl_unlock (); return 0; } else { @@ -362,12 +362,12 @@ streamer_move_to_nextsong (int reason) { playItem_t *temp; plt_reshuffle (streamer_playlist, &temp, NULL); streamer_set_nextsong (-2, -2); - pl_global_unlock (); + pl_unlock (); return -1; } int r = str_get_idx_of (it); streamer_set_nextsong (r, 1); - pl_global_unlock (); + pl_unlock (); return 0; } } @@ -389,35 +389,35 @@ streamer_move_to_nextsong (int reason) { plug_trigger_event_trackinfochanged (streaming_track); badsong = -1; streamer_set_nextsong (-2, -2); - pl_global_unlock (); + pl_unlock (); return 0; } } if (!it) { - pl_global_unlock (); + pl_unlock (); return -1; } int r = str_get_idx_of (it); streamer_set_nextsong (r, 1); - pl_global_unlock (); + pl_unlock (); return 0; } else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random int res = streamer_move_to_randomsong (); if (res == -1) { trace ("streamer_move_to_randomsong error\n"); - pl_global_unlock (); + pl_unlock (); streamer_set_nextsong (-2, 1); return -1; } } - pl_global_unlock (); + pl_unlock (); return -1; } int streamer_move_to_prevsong (void) { - plt_lock (); + pl_lock (); if (!streamer_playlist) { streamer_playlist = plt_get_curr_ptr (); } @@ -431,14 +431,14 @@ streamer_move_to_prevsong (void) { pl_playqueue_clear (); if (!plt->head[PL_MAIN]) { streamer_set_nextsong (-2, 1); - plt_unlock (); + pl_unlock (); return 0; } int pl_order = conf_get_int ("playback.order", 0); int pl_loop_mode = conf_get_int ("playback.loop", 0); if (pl_order == PLAYBACK_ORDER_SHUFFLE_TRACKS || pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS) { // shuffle if (!playlist_track) { - plt_unlock (); + pl_unlock (); return streamer_move_to_nextsong (1); } else { @@ -477,12 +477,12 @@ streamer_move_to_prevsong (void) { } if (!it) { - plt_unlock (); + pl_unlock (); return -1; } int r = str_get_idx_of (it); streamer_set_nextsong (r, 1); - plt_unlock (); + pl_unlock (); return 0; } } @@ -497,24 +497,24 @@ streamer_move_to_prevsong (void) { } } if (!it) { - plt_unlock (); + pl_unlock (); return -1; } int r = str_get_idx_of (it); streamer_set_nextsong (r, 1); - plt_unlock (); + pl_unlock (); return 0; } else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random int res = streamer_move_to_randomsong (); if (res == -1) { - plt_unlock (); + pl_unlock (); streamer_set_nextsong (-2, 1); trace ("streamer_move_to_randomsong error\n"); return -1; } } - plt_unlock (); + pl_unlock (); return -1; } |