changeset 2139:fcd1f54efdb9 trunk

[svn] - multiple playlist support requires separated locking; each Playlist holds its GMutex now; removed playlist_get function cause it doesn't fit with this scheme
author giacomo
date Sat, 16 Dec 2006 02:52:03 -0800
parents 5c33790c5a26
children 299651a8f107
files ChangeLog audacious/mainwin.c audacious/playlist.c audacious/playlist.h audacious/ui_playlist.c audacious/widgets/playlist_list.c
diffstat 6 files changed, 346 insertions(+), 288 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Dec 16 02:35:16 2006 -0800
+++ b/ChangeLog	Sat Dec 16 02:52:03 2006 -0800
@@ -1,3 +1,11 @@
+2006-12-16 10:35:16 +0000  Jerome Poulin <ticpu@ticpu.net>
+  revision [3281]
+  Added playback-seek{-relative} in audtool.1 man page.
+  
+  trunk/audtool.1.in |    6 ++++++
+  1 file changed, 6 insertions(+)
+
+
 2006-12-16 10:20:15 +0000  Jerome Poulin <ticpu@ticpu.net>
   revision [3279]
   Fixed a bug where xmms_remote_jump_to_time was called with seconds instead of milliseconds.
--- a/audacious/mainwin.c	Sat Dec 16 02:35:16 2006 -0800
+++ b/audacious/mainwin.c	Sat Dec 16 02:52:03 2006 -0800
@@ -1883,12 +1883,12 @@
     /* FIXME: Is not in sync with playlist due to delayed extinfo
      * reading */
     gint row;
-    GList *node;
+    GList *playlist_glist;
     gchar *desc_buf = NULL;
     gchar *row_str;
     GtkTreeIter iter;
     GtkTreeSelection *selection;
-    Playlist *playlist = playlist_get_active();
+    Playlist *playlist;
 
     GtkTreeModel *store;
 
@@ -1899,9 +1899,10 @@
     gtk_list_store_clear(GTK_LIST_STORE(store));
 
     row = 1;
-    for (node = playlist->entries; node; node = g_list_next(node))
-    {
-        PlaylistEntry *entry = PLAYLIST_ENTRY(node->data);
+    playlist = playlist_get_active();
+    for (playlist_glist = playlist->entries; playlist_glist;
+         playlist_glist = g_list_next(playlist_glist)) {
+        PlaylistEntry *entry = PLAYLIST_ENTRY(playlist_glist->data);
 
         if (entry->title)
 		desc_buf = g_strdup(entry->title);
@@ -1935,13 +1936,13 @@
     GtkTreeView *treeview = GTK_TREE_VIEW(user_data);
     GtkTreeSelection *selection;
     GtkTreeIter iter;
-    Playlist *playlist = playlist_get_active();
 
     GtkListStore *store;
 
     gint song_index = 0;
     gchar **words;
-    GList *node;
+    GList *playlist_glist;
+    Playlist *playlist;
 
     gboolean match = FALSE;
 
@@ -1963,14 +1964,15 @@
      * (row-selected will still eventually arrive once) */
     store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
     gtk_list_store_clear(store);
-    g_object_ref(store);
-    gtk_tree_view_set_model(treeview, NULL);
-
-    PLAYLIST_LOCK();
-
-    for (node = playlist->entries; node; node = g_list_next(node))
-    {
-        PlaylistEntry *entry = PLAYLIST_ENTRY(node->data);
+
+    playlist = playlist_get_active();
+
+    PLAYLIST_LOCK(playlist->mutex);
+
+    for (playlist_glist = playlist->entries; playlist_glist;
+         playlist_glist = g_list_next(playlist_glist)) {
+
+        PlaylistEntry *entry = PLAYLIST_ENTRY(playlist_glist->data);
         const gchar *title;
         gchar *filename = NULL;
 
@@ -2015,10 +2017,7 @@
 	}
     }
 
-    PLAYLIST_UNLOCK();
-
-    gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
-    g_object_unref(store);
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     if ( regex_list != NULL )
     {
@@ -2047,7 +2046,8 @@
     GtkWidget *jump, *queue, *cancel;
     GtkWidget *rescan, *edit;
     GtkWidget *search_label, *hbox;
-    GList *node;
+    GList *playlist_glist;
+    Playlist *playlist;
     gchar *desc_buf = NULL;
     gchar *row_str;
     gint row;
@@ -2059,8 +2059,6 @@
     GtkCellRenderer *renderer;
     GtkTreeViewColumn *column;
 
-    Playlist *playlist = playlist_get_active();
-
     if (mainwin_jtf) {
         gtk_window_present(GTK_WINDOW(mainwin_jtf));
         return;
@@ -2183,11 +2181,14 @@
 
     row = 1;
 
-    PLAYLIST_LOCK();
-
-    for (node = playlist->entries; node; node = g_list_next(node))
-    {
-        PlaylistEntry *entry = PLAYLIST_ENTRY(node->data);
+    playlist = playlist_get_active();
+
+    PLAYLIST_LOCK(playlist->mutex);
+
+    for (playlist_glist = playlist->entries; playlist_glist;
+         playlist_glist = g_list_next(playlist_glist)) {
+
+        PlaylistEntry *entry = PLAYLIST_ENTRY(playlist_glist->data);
 
         if (entry->title)
 		desc_buf = g_strdup(entry->title);
@@ -2209,7 +2210,7 @@
         g_free(row_str);
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     gtk_widget_show_all(mainwin_jtf);
 }
--- a/audacious/playlist.c	Sat Dec 16 02:35:16 2006 -0800
+++ b/audacious/playlist.c	Sat Dec 16 02:52:03 2006 -0800
@@ -62,7 +62,6 @@
 
 /* If we manually change the song, p_p_b_j will show us where to go back to */
 PlaylistEntry *playlist_position_before_jump = NULL;
-G_LOCK_DEFINE(playlists);
 
 static GList *playlists = NULL;
 static GList *playlists_iter;
@@ -223,7 +222,7 @@
 {
     Playlist *initial_pl;
 
-    REQUIRE_STATIC_LOCK(playlists);
+    /* FIXME: is this really necessary? REQUIRE_STATIC_LOCK(playlists); */
 
     initial_pl = playlist_new();
 
@@ -316,7 +315,7 @@
 static GList *
 find_playlist_position_list(Playlist *playlist)
 {
-    REQUIRE_STATIC_LOCK(playlists);
+    REQUIRE_LOCK(playlist->mutex);
 
     if (!playlist->position) {
         if (cfg.shuffle)
@@ -336,7 +335,7 @@
 {
     GList *tmp = playlist->queue;
 
-    REQUIRE_STATIC_LOCK(playlists);
+    REQUIRE_LOCK( playlist->mutex );
 
     playlist->position = playlist->queue->data;
     playlist->queue = g_list_remove_link(playlist->queue, playlist->queue);
@@ -346,16 +345,22 @@
 void
 playlist_clear(Playlist *playlist)
 {
-    PLAYLIST_LOCK();
-
-    if (playlist) {
-        g_list_foreach(playlist->entries, (GFunc) playlist_entry_free, NULL);
-        g_list_free(playlist->entries);
-	playlist->position = NULL;
-	playlist->entries = NULL;
+    if (!playlist)
+    {
+        playlist_generate_shuffle_list(playlist);
+        playlistwin_update_list();
+        playlist_recalc_total_time(playlist);
+        return;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_LOCK( playlist->mutex );
+
+    g_list_foreach(playlist->entries, (GFunc) playlist_entry_free, NULL);
+    g_list_free(playlist->entries);
+    playlist->position = NULL;
+    playlist->entries = NULL;
+
+    PLAYLIST_UNLOCK( playlist->mutex );
 
     playlist_generate_shuffle_list(playlist);
     playlistwin_update_list();
@@ -369,7 +374,7 @@
     PlaylistEntry *entry;
     GList *playing_song = NULL;
 
-    REQUIRE_STATIC_LOCK(playlists);
+    REQUIRE_LOCK(playlist->mutex);
 
     /* We call g_list_find manually here because we don't want an item
      * in the shuffle_list */
@@ -383,11 +388,11 @@
         *set_info_text = TRUE;
 
         if (bmp_playback_get_playing()) {
-            PLAYLIST_UNLOCK();
+            PLAYLIST_UNLOCK(playlist->mutex);
             ip_data.stop = TRUE;
             bmp_playback_stop();
             ip_data.stop = FALSE;
-            PLAYLIST_LOCK();
+            PLAYLIST_LOCK(playlist->mutex);
             *restart_playing = TRUE;
         }
 
@@ -424,23 +429,21 @@
     gboolean restart_playing = FALSE, set_info_text = FALSE;
     GList *node;
 
-    PLAYLIST_LOCK();
-
-    if (!playlist) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
         return;
-    }
+
+    PLAYLIST_LOCK(playlist->mutex);
 
     node = g_list_nth(playlist->entries, pos);
 
     if (!node) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
 
     playlist_delete_node(playlist, node, &set_info_text, &restart_playing);
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_recalc_total_time(playlist);
 
@@ -464,7 +467,7 @@
     GList *node, *fnode;
     gboolean set_info_text = FALSE, restart_playing = FALSE;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     for (fnode = filenames; fnode; fnode = g_list_next(fnode)) {
         node = playlist->entries;
@@ -481,7 +484,7 @@
     }
 
     playlist_recalc_total_time(playlist);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlistwin_update_list();
 
@@ -508,7 +511,7 @@
 
     g_return_if_fail(playlist != NULL);
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     node = playlist->entries;
 
@@ -524,7 +527,7 @@
         node = next_node;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_recalc_total_time(playlist);
 
@@ -554,11 +557,11 @@
 {
     g_return_if_fail(filename != NULL);
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     playlist->entries = g_list_insert(playlist->entries,
                              playlist_entry_new(filename, title, len, dec),
                              pos);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     g_mutex_lock(mutex_scan);
     playlist_get_info_scan_active = TRUE;
@@ -579,7 +582,7 @@
     g_return_if_fail(playlist != NULL);
     g_return_if_fail(filename != NULL);
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     playlist->entries = g_list_insert(playlist->entries,
                              playlist_entry_new(filename, tuple->track_name, tuple->length, dec),
                              pos);
@@ -596,7 +599,7 @@
         entry->tuple = tuple;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     g_mutex_lock(mutex_scan);
     playlist_get_info_scan_active = TRUE;
@@ -888,9 +891,9 @@
 
         g_free(decoded);
 
-        PLAYLIST_LOCK();
+        PLAYLIST_LOCK(playlist->mutex);
         node = g_list_nth(playlist->entries, pos);
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
 
         entries += i;
 
@@ -920,7 +923,7 @@
 {
     Playlist *playlist = playlist_get_active();
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     g_return_if_fail(playlist != NULL);
 
@@ -930,7 +933,7 @@
         playlist->position->length = length;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_recalc_total_time(playlist);
 
@@ -941,7 +944,7 @@
 playlist_set_info(Playlist * playlist, const gchar * title, gint length, gint rate,
                   gint freq, gint nch)
 {
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     g_return_if_fail(playlist != NULL);
 
@@ -951,7 +954,7 @@
         playlist->position->length = length;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_recalc_total_time(playlist);
 
@@ -963,23 +966,26 @@
 {
     gint pos, row, bottom;
 
-    PLAYLIST_LOCK();
-    if (!playlist || !playlist->position || !playlistwin_list) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
+        return;
+
+    PLAYLIST_LOCK(playlist->mutex);
+    if (!playlist->position || !playlistwin_list) {
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
 
     pos = g_list_index(playlist->entries, playlist->position);
 
     if (playlistwin_item_visible(pos)) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
 
     bottom = MAX(0, playlist_get_length_nolock(playlist) -
                  playlistwin_list->pl_num_visible);
     row = CLAMP(pos - playlistwin_list->pl_num_visible / 2, 0, bottom);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     playlistwin_set_toprow(row);
     g_cond_signal(cond_scan);
 }
@@ -990,12 +996,11 @@
     GList *plist_pos_list;
     gboolean restart_playing = FALSE;
 
-    PLAYLIST_LOCK();
-    if (!playlist) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
         return;
-    }
-    
+
+    PLAYLIST_LOCK(playlist->mutex);
+
     if ((playlist_position_before_jump != NULL) && playlist->queue == NULL)
     {
         playlist->position = playlist_position_before_jump;
@@ -1005,17 +1010,17 @@
     plist_pos_list = find_playlist_position_list(playlist);
 
     if (!cfg.repeat && !g_list_next(plist_pos_list) && playlist->queue == NULL) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
 
     if (bmp_playback_get_playing()) {
         /* We need to stop before changing playlist_position */
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         ip_data.stop = TRUE;
         bmp_playback_stop();
         ip_data.stop = FALSE;
-        PLAYLIST_LOCK();
+        PLAYLIST_LOCK(playlist->mutex);
         restart_playing = TRUE;
     }
 
@@ -1032,7 +1037,7 @@
         else
             playlist->position = playlist->entries->data;
     }
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     playlist_check_pos_current(playlist);
 
     if (restart_playing)
@@ -1049,12 +1054,11 @@
     GList *plist_pos_list;
     gboolean restart_playing = FALSE;
 
-    PLAYLIST_LOCK();
-    if (!playlist) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
         return;
-    }
-    
+
+    PLAYLIST_LOCK(playlist->mutex);
+
     if ((playlist_position_before_jump != NULL) && playlist->queue == NULL)
     {
         playlist->position = playlist_position_before_jump;
@@ -1064,17 +1068,17 @@
     plist_pos_list = find_playlist_position_list(playlist);
 
     if (!cfg.repeat && !g_list_previous(plist_pos_list)) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
 
     if (bmp_playback_get_playing()) {
         /* We need to stop before changing playlist_position */
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         ip_data.stop = TRUE;
         bmp_playback_stop();
         ip_data.stop = FALSE;
-        PLAYLIST_LOCK();
+        PLAYLIST_LOCK(playlist->mutex);
         restart_playing = TRUE;
     }
 
@@ -1094,7 +1098,7 @@
             playlist->position = node->data;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_check_pos_current(playlist);
 
@@ -1112,8 +1116,8 @@
     GList *list = playlist_get_selected(playlist);
     GList *it = list;
 
-    PLAYLIST_LOCK();
-		
+    PLAYLIST_LOCK(playlist->mutex);
+
     if ((cfg.shuffle) && (playlist_position_before_jump == NULL))
     {
         /* Shuffling and this is our first manual jump. */
@@ -1138,7 +1142,7 @@
 
     playlist->queue = g_list_concat(playlist->queue, list);
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_recalc_total_time(playlist);
     playlistwin_update_list();
@@ -1150,8 +1154,8 @@
     GList *tmp;
     PlaylistEntry *entry;
 
-    PLAYLIST_LOCK();
-    
+    PLAYLIST_LOCK(playlist->mutex);
+
     if ((cfg.shuffle) && (playlist_position_before_jump == NULL))
     {
         /* Shuffling and this is our first manual jump. */
@@ -1165,7 +1169,7 @@
     }
     else
         playlist->queue = g_list_append(playlist->queue, entry);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_recalc_total_time(playlist);
     playlistwin_update_list();
@@ -1177,10 +1181,10 @@
     PlaylistEntry *entry;
     GList *tmp;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     entry = g_list_nth_data(playlist->entries, pos);
     tmp = g_list_find(playlist->queue, entry);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return tmp != NULL;
 }
@@ -1191,10 +1195,10 @@
     PlaylistEntry *entry;
     gint tmp;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     entry = g_list_nth_data(playlist->entries, pos);
     tmp = g_list_index(playlist->queue, entry);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return tmp;
 }
@@ -1205,10 +1209,10 @@
     PlaylistEntry *entry;
     gint tmp;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     entry = g_list_nth_data(playlist->queue, pos);
     tmp = g_list_index(playlist->entries, entry);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return tmp;
 }
@@ -1216,10 +1220,10 @@
 void
 playlist_clear_queue(Playlist *playlist)
 {
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     g_list_free(playlist->queue);
     playlist->queue = NULL;
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_recalc_total_time(playlist);
     playlistwin_update_list();
@@ -1230,10 +1234,10 @@
 {
     void *entry;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     entry = g_list_nth_data(playlist->entries, pos);
     playlist->queue = g_list_remove(playlist->queue, entry);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlistwin_update_list();
 }
@@ -1250,25 +1254,24 @@
     GList *node;
     gboolean restart_playing = FALSE;
 
-    PLAYLIST_LOCK();
-    if (!playlist) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
         return;
-    }
+
+    PLAYLIST_LOCK(playlist->mutex);
 
     node = g_list_nth(playlist->entries, pos);
     if (!node) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
 
     if (bmp_playback_get_playing()) {
         /* We need to stop before changing playlist_position */
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         ip_data.stop = TRUE;
         bmp_playback_stop();
         ip_data.stop = FALSE;
-        PLAYLIST_LOCK();
+        PLAYLIST_LOCK(playlist->mutex);
         restart_playing = TRUE;
     }
 
@@ -1279,7 +1282,7 @@
     }
 		
     playlist->position = node->data;
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     playlist_check_pos_current(playlist);
 
     if (restart_playing)
@@ -1301,7 +1304,7 @@
     if ((cfg.no_playlist_advance && !cfg.repeat) || cfg.stopaftersong)  
       ip_data.stop = FALSE;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     
     if ((playlist_position_before_jump != NULL) && playlist->queue == NULL)
     {
@@ -1312,7 +1315,7 @@
     plist_pos_list = find_playlist_position_list(playlist);
 
     if (cfg.no_playlist_advance) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         mainwin_clear_song_info();
         if (cfg.repeat)
             bmp_playback_initiate();
@@ -1320,7 +1323,7 @@
     }
 
     if (cfg.stopaftersong) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         mainwin_clear_song_info();
         mainwin_set_stopaftersong(FALSE);
         return;
@@ -1338,7 +1341,7 @@
             playlist->position = playlist->entries->data;
 
         if (!cfg.repeat) {
-            PLAYLIST_UNLOCK();
+            PLAYLIST_UNLOCK(playlist->mutex);
             mainwin_clear_song_info();
             mainwin_set_info_text();
             return;
@@ -1347,7 +1350,7 @@
     else
         playlist->position = g_list_next(plist_pos_list)->data;
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_check_pos_current(playlist);
     bmp_playback_initiate();
@@ -1360,9 +1363,9 @@
 {
     gint retval;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     retval = playlist_get_length_nolock(playlist);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return retval;
 }
@@ -1372,9 +1375,9 @@
 {
     gint length;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     length = g_list_length(playlist->queue);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return length;
 }
@@ -1392,9 +1395,9 @@
 
     g_return_val_if_fail(playlist != NULL, NULL);
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     if (!playlist->position) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return NULL;
     }
 
@@ -1426,7 +1429,7 @@
     else
         length = g_strdup("");
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     text = convert_title_text(g_strconcat(numbers, title, length, NULL));
 
@@ -1442,10 +1445,13 @@
 {
     gint len = 0;
 
-    PLAYLIST_LOCK();
-    if (playlist && playlist->position)
+    if (!playlist)
+        return 0;
+
+    PLAYLIST_LOCK(playlist->mutex);
+    if (playlist->position)
         len = playlist->position->length;
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return len;
 }
@@ -1625,21 +1631,10 @@
 get_playlist_nth(Playlist *playlist, guint nth)
 {
     g_warning("deprecated function get_playlist_nth() was called");
-
-    REQUIRE_STATIC_LOCK(playlists);
+    REQUIRE_LOCK(playlist->mutex);
     return g_list_nth(playlist->entries, nth);
 }
 
-
-GList *
-playlist_get(void)
-{
-    g_warning("deprecated function playlist_get() was called");
-
-    REQUIRE_STATIC_LOCK(playlists);
-    return playlist_get_active()->entries;
-}
-
 gint
 playlist_get_position_nolock(Playlist *playlist)
 {
@@ -1653,9 +1648,9 @@
 {
     gint pos;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     pos = playlist_get_position_nolock(playlist);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return pos;
 }
@@ -1667,20 +1662,19 @@
     PlaylistEntry *entry;
     GList *node;
 
-    PLAYLIST_LOCK();
-    if (!playlist) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
         return NULL;
-    }
+
+    PLAYLIST_LOCK(playlist->mutex);
     node = g_list_nth(playlist->entries, pos);
     if (!node) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return NULL;
     }
     entry = node->data;
 
     filename = g_strdup(entry->filename);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return filename;
 }
@@ -1692,15 +1686,13 @@
     PlaylistEntry *entry;
     GList *node;
 
-    PLAYLIST_LOCK();
-
-    if (!playlist) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
         return NULL;
-    }
+
+    PLAYLIST_LOCK(playlist->mutex);
 
     if (!(node = g_list_nth(playlist->entries, pos))) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return NULL;
     }
 
@@ -1717,7 +1709,7 @@
         title = entry->title;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     if (!title) {
         title = g_path_get_basename(entry->filename);
@@ -1734,15 +1726,13 @@
     TitleInput *tuple = NULL;
     GList *node;
 
-    PLAYLIST_LOCK();
-
-    if (!playlist) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
         return NULL;
-    }
+
+    PLAYLIST_LOCK(playlist->mutex);
 
     if (!(node = g_list_nth(playlist->entries, pos))) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return NULL;
     }
 
@@ -1758,7 +1748,7 @@
         tuple = entry->tuple;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return tuple;
 }
@@ -1770,15 +1760,13 @@
     PlaylistEntry *entry;
     GList *node;
 
-    PLAYLIST_LOCK();
-
-    if (!playlist) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
         return -1;
-    }
+
+    PLAYLIST_LOCK(playlist->mutex);
 
     if (!(node = g_list_nth(playlist->entries, pos))) {
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return -1;
     }
 
@@ -1789,11 +1777,11 @@
         if (playlist_entry_get_info(entry))
             song_time = entry->length;
 
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
     }
     else {
         song_time = entry->length;
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
     }
 
     return song_time;
@@ -2016,11 +2004,11 @@
 playlist_sort(Playlist *playlist, PlaylistSortType type)
 {
     playlist_remove_dead_files(playlist);
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     playlist->entries =
         g_list_sort(playlist->entries,
                     (GCompareFunc) playlist_compare_func_table[type]);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 }
 
 static GList *
@@ -2075,19 +2063,19 @@
 void
 playlist_sort_selected(Playlist *playlist, PlaylistSortType type)
 {
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     playlist->entries = playlist_sort_selected_generic(playlist->entries, (GCompareFunc)
                                                        playlist_compare_func_table
                                                        [type]);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 }
 
 void
 playlist_reverse(Playlist *playlist)
 {
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     playlist->entries = g_list_reverse(playlist->entries);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 }
 
 static GList *
@@ -2101,8 +2089,9 @@
     gint len = g_list_length(list);
     gint i, j;
     GList *node, **ptrs;
-
-    REQUIRE_STATIC_LOCK(playlists);
+    Playlist *playlist = playlist_get_active();
+
+    REQUIRE_LOCK(playlist->mutex);
 
     if (!len)
         return NULL;
@@ -2134,9 +2123,9 @@
 void
 playlist_random(Playlist *playlist)
 {
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     playlist->entries = playlist_shuffle_list(playlist->entries);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 }
 
 GList *
@@ -2145,13 +2134,13 @@
     GList *node, *list = NULL;
     gint i = 0;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     for (node = playlist->entries; node; node = g_list_next(node), i++) {
         PlaylistEntry *entry = node->data;
         if (entry->selected)
             list = g_list_prepend(list, GINT_TO_POINTER(i));
     }
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     return g_list_reverse(list);
 }
 
@@ -2161,11 +2150,11 @@
     GList *node = NULL;
     gint i = 0;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     for (node = playlist->entries; node; node = g_list_next(node), i++) {
         PLAYLIST_ENTRY(node->data)->selected = FALSE;
     }
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     playlist_recalc_total_time(playlist);
 }
 
@@ -2175,13 +2164,13 @@
     GList *node;
     gint num = 0;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     for (node = playlist->entries; node; node = g_list_next(node)) {
         PlaylistEntry *entry = node->data;
         if (entry->selected)
             num++;
     }
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     return num;
 }
 
@@ -2189,9 +2178,9 @@
 static void
 playlist_generate_shuffle_list(Playlist *playlist)
 {
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     playlist_generate_shuffle_list_nolock(playlist);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 }
 
 static void
@@ -2200,7 +2189,7 @@
     GList *node;
     gint numsongs;
 
-    REQUIRE_STATIC_LOCK(playlists);
+    REQUIRE_LOCK(playlist->mutex);
 
     if (!cfg.shuffle || !playlist)
         return;
@@ -2230,7 +2219,7 @@
     TitleInput *tuple = NULL;
     gint mtime;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     if ((node = g_list_nth(playlist->entries, pos)))
     {
@@ -2239,7 +2228,7 @@
         path = g_strdup(entry->filename);
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     /* No tuple? Try to set this entry up properly. --nenolod */
     if (entry->tuple == NULL || entry->tuple->mtime == -1 ||
@@ -2275,7 +2264,7 @@
     gchar *path = NULL;
     TitleInput *tuple = NULL;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     if (playlist->entries && playlist->position)
     {
@@ -2285,7 +2274,7 @@
         tuple = playlist->position->tuple;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     if (tuple != NULL)
     {
@@ -2336,7 +2325,7 @@
             cfg.get_info_on_load &&
             playlist_get_info_scan_active) {
 
-            PLAYLIST_LOCK();
+            PLAYLIST_LOCK(playlist->mutex);
             for (node = playlist->entries; node; node = g_list_next(node)) {
                 entry = node->data;
 
@@ -2358,7 +2347,7 @@
                     break;
                 }
             }
-            PLAYLIST_UNLOCK();
+            PLAYLIST_UNLOCK(playlist->mutex);
             
             if (!node) {
                 g_mutex_lock(mutex_scan);
@@ -2378,10 +2367,10 @@
             playlist_get_info_scan_active = FALSE;
             g_mutex_unlock(mutex_scan);
 
-            PLAYLIST_LOCK();
+            PLAYLIST_LOCK(playlist->mutex);
 
             if (!playlist->entries) {
-                PLAYLIST_UNLOCK();
+                PLAYLIST_UNLOCK(playlist->mutex);
             }
             else {
                 for (node = g_list_nth(playlist->entries, playlistwin_get_toprow());
@@ -2410,7 +2399,7 @@
 			// no need for break here since this iteration is very short.
                     }
                 }
-                PLAYLIST_UNLOCK();
+                PLAYLIST_UNLOCK(playlist->mutex);
             }
         } // on_demand
         else if (cfg.get_info_on_demand && 
@@ -2482,7 +2471,7 @@
 {
     GList *node, *next_node;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     for (node = playlist->entries; node; node = next_node) {
         PlaylistEntry *entry = PLAYLIST_ENTRY(node->data);
@@ -2517,7 +2506,7 @@
         playlist->entries = g_list_delete_link(playlist->entries, node);
     }
    
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     
     playlist_generate_shuffle_list(playlist);
     playlistwin_update_list();
@@ -2606,7 +2595,7 @@
         break;
     }
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     for (node = playlist->entries; node; node = next_node) {
         PlaylistEntry *entry = PLAYLIST_ENTRY(node->data);
@@ -2651,7 +2640,7 @@
         }
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlistwin_update_list();
     playlist_recalc_total_time(playlist);
@@ -2664,12 +2653,12 @@
                         gboolean * total_more,
                         gboolean * selection_more)
 {
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     *total_time = playlist->pl_total_time;
     *selection_time = playlist->pl_selection_time;
     *total_more = playlist->pl_total_more;
     *selection_more = playlist->pl_selection_more;
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 }
 
 
@@ -2679,7 +2668,7 @@
     GList *list;
     PlaylistEntry *entry;
 
-    REQUIRE_STATIC_LOCK(playlists);
+    REQUIRE_LOCK(playlist->mutex);
 
     playlist->pl_total_time = 0;
     playlist->pl_selection_time = 0;
@@ -2706,9 +2695,9 @@
 static void
 playlist_recalc_total_time(Playlist *playlist)
 {
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     playlist_recalc_total_time_nolock(playlist);
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 }
 
 gint
@@ -2718,7 +2707,7 @@
     gboolean is_first_search = TRUE;
     gint num_of_entries_found = 0;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     if ( tuple->track_name != NULL )
     {
@@ -2836,7 +2825,7 @@
 
     g_list_free( found_list );
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     playlist_recalc_total_time(playlist);
 
     return num_of_entries_found;
@@ -2847,14 +2836,14 @@
 {
     GList *list;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     for (list = playlist->entries; list; list = g_list_next(list)) {
         PlaylistEntry *entry = list->data;
         entry->selected = set;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     playlist_recalc_total_time(playlist);
 }
 
@@ -2863,14 +2852,14 @@
 {
     GList *list;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     for (list = playlist->entries; list; list = g_list_next(list)) {
         PlaylistEntry *entry = list->data;
         entry->selected = !entry->selected;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     playlist_recalc_total_time(playlist);
 }
 
@@ -2880,7 +2869,7 @@
     GList *list;
     gboolean invert_ok = FALSE;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     if ((list = g_list_nth(playlist->entries, pos))) {
         PlaylistEntry *entry = list->data;
@@ -2888,7 +2877,7 @@
         invert_ok = TRUE;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     playlist_recalc_total_time(playlist);
 
     return invert_ok;
@@ -2904,7 +2893,7 @@
     if (min_pos > max_pos)
         SWAP(min_pos, max_pos);
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     list = g_list_nth(playlist->entries, min_pos);
     for (i = min_pos; i <= max_pos && list; i++) {
@@ -2913,7 +2902,7 @@
         list = g_list_next(list);
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlist_recalc_total_time(playlist);
 }
@@ -2924,7 +2913,7 @@
     GList *node;
     gboolean retval = FALSE;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     for (node = playlist->entries; node; node = g_list_next(node)) {
         PlaylistEntry *entry = node->data;
@@ -2947,7 +2936,7 @@
         }
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlistwin_update_list();
     playlist_recalc_total_time(playlist);
@@ -2960,7 +2949,7 @@
 {
     GList *node;
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
 
     if ((node = g_list_nth(playlist->entries, pos))) {
         PlaylistEntry *entry = node->data;
@@ -2969,7 +2958,7 @@
         playlist_entry_get_info(entry);
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     playlistwin_update_list();
     playlist_recalc_total_time(playlist);
@@ -2987,20 +2976,25 @@
 void
 playlist_set_shuffle(gboolean shuffle)
 {
-    PLAYLIST_LOCK();
+    Playlist *playlist = playlist_get_active();
+    if (!playlist)
+        return;
+
+    PLAYLIST_LOCK(playlist->mutex);
 
     playlist_position_before_jump = NULL;
 
     cfg.shuffle = shuffle;
-    playlist_generate_shuffle_list_nolock(playlist_get_active());
-
-    PLAYLIST_UNLOCK();
+    playlist_generate_shuffle_list_nolock(playlist);
+
+    PLAYLIST_UNLOCK(playlist->mutex);
 }
 
 Playlist *
 playlist_new(void) 
 {
     Playlist *playlist = g_new0(Playlist, 1);
+    playlist->mutex = g_mutex_new();
 
     playlist_set_current_name(playlist, NULL);
     playlist_clear(playlist);
@@ -3008,26 +3002,52 @@
     return playlist;
 }
 
+Playlist *
+playlist_new_from_selected(void)
+{
+#if 0
+ /* !!!!!! TODO !!!!!!! */
+    Playlist *newpl = playlist_new();
+    Playlist *playlist = playlist_get_active();
+    GList *list = playlist_get_selected(playlist);
+
+    PLAYLIST_LOCK(playlist->mutex);
+
+    while ( list != NULL )
+    {
+        PlaylistEntry *entry = g_list_nth_data(playlist->entries, GPOINTER_TO_INT(list->data));
+        if ( entry->filename != NULL ) /* paranoid? oh well... */
+            playlist_add( newpl , entry->filename );
+        list = g_list_next(list);
+    }
+
+    PLAYLIST_UNLOCK(playlist->mutex);
+
+    playlist_recalc_total_time(newpl);
+    playlistwin_update_list();
+#endif
+}
 
 const gchar *
 playlist_get_filename_to_play(Playlist *playlist)
 {
     const gchar *filename = NULL;
-    
-    PLAYLIST_LOCK();
-
-    if (playlist) {
-        if (!playlist->position) {
-            if (cfg.shuffle)
-                playlist->position = playlist->shuffle->data;
-            else
-                playlist->position = playlist->entries->data;
-        }
-
-        filename = playlist->position->filename;
+
+    if (!playlist)
+        return NULL;
+
+    PLAYLIST_LOCK(playlist->mutex);
+
+    if (!playlist->position) {
+        if (cfg.shuffle)
+            playlist->position = playlist->shuffle->data;
+        else
+            playlist->position = playlist->entries->data;
     }
 
-    PLAYLIST_UNLOCK();
+    filename = playlist->position->filename;
+
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return filename;
 }
@@ -3035,18 +3055,19 @@
 PlaylistEntry *
 playlist_get_entry_to_play(Playlist *playlist)
 {
-    PLAYLIST_LOCK();
-
-    if (playlist) {
-        if (!playlist->position) {
-            if (cfg.shuffle)
-                playlist->position = playlist->shuffle->data;
-            else
-                playlist->position = playlist->entries->data;
-        }
+    if (!playlist)
+        return NULL;
+
+    PLAYLIST_LOCK(playlist->mutex);
+
+    if (!playlist->position) {
+        if (cfg.shuffle)
+            playlist->position = playlist->shuffle->data;
+        else
+            playlist->position = playlist->entries->data;
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     return playlist->position;
 }
--- a/audacious/playlist.h	Sat Dec 16 02:35:16 2006 -0800
+++ b/audacious/playlist.h	Sat Dec 16 02:52:03 2006 -0800
@@ -75,6 +75,7 @@
     gulong         pl_selection_time;
     gboolean       pl_total_more;
     gboolean       pl_selection_more;
+    GMutex        *mutex;       /* this is required for multiple playlist */
 } Playlist;
 
 typedef enum {
@@ -140,9 +141,6 @@
 gboolean playlist_save(Playlist *playlist, const gchar * filename);
 gboolean playlist_load(Playlist *playlist, const gchar * filename);
 
-/* returns the current selected *linear* playlist */
-GList *playlist_get(void);
-
 void playlist_start_get_info_thread(void);
 void playlist_stop_get_info_thread();
 void playlist_start_get_info_scan(void);
@@ -196,12 +194,13 @@
 gboolean playlist_set_current_name(Playlist *playlist, const gchar * filename);
 const gchar *playlist_get_current_name(Playlist *playlist);
 Playlist *playlist_new(void);
+Playlist *playlist_new_from_selected(void);
 
 PlaylistFormat playlist_format_get_from_name(const gchar * filename);
 gboolean is_playlist_name(const gchar * filename);
 
-#define PLAYLIST_LOCK()    G_LOCK(playlists)
-#define PLAYLIST_UNLOCK()  G_UNLOCK(playlists)
+#define PLAYLIST_LOCK(m)    g_mutex_lock(m)
+#define PLAYLIST_UNLOCK(m)  g_mutex_unlock(m)
 
 G_LOCK_EXTERN(playlists);
 
--- a/audacious/ui_playlist.c	Sat Dec 16 02:35:16 2006 -0800
+++ b/audacious/ui_playlist.c	Sat Dec 16 02:52:03 2006 -0800
@@ -660,6 +660,27 @@
 }
 
 static void
+playlistwin_select_all(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_select_all(playlist, TRUE);
+    playlistwin_list->pl_prev_selected = 0;
+    playlistwin_list->pl_prev_min = 0;
+    playlistwin_list->pl_prev_max = playlist_get_length(playlist) - 1;
+    playlistwin_update_list();
+}
+
+static void
+playlistwin_select_none(void)
+{
+    playlist_select_all(playlist_get_active(), FALSE);
+    playlistwin_list->pl_prev_selected = -1;
+    playlistwin_list->pl_prev_min = -1;
+    playlistwin_update_list();
+}
+
+static void
 playlistwin_select_search(void)
 {
     Playlist *playlist = playlist_get_active();
@@ -669,6 +690,8 @@
     GtkWidget *searchdlg_entry_album_name, *searchdlg_label_album_name;
     GtkWidget *searchdlg_entry_file_name, *searchdlg_label_file_name;
     GtkWidget *searchdlg_entry_performer, *searchdlg_label_performer;
+    GtkWidget *searchdlg_checkbt_clearprevsel;
+    GtkWidget *searchdlg_checkbt_newplaylist;
     gint result;
 
     /* create dialog */
@@ -701,9 +724,17 @@
     searchdlg_label_file_name = gtk_label_new( _("Filename: ") );
     searchdlg_entry_file_name = gtk_entry_new();
     gtk_misc_set_alignment( GTK_MISC(searchdlg_label_file_name) , 0 , 0.5 );
+    /* some options that control behaviour */
+    searchdlg_checkbt_clearprevsel = gtk_check_button_new_with_label(
+      _("Clear previous selection before searching") );
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel) , TRUE );
+    searchdlg_checkbt_newplaylist = gtk_check_button_new_with_label(
+      _("Create a new playlist with matching entries") );
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist) , FALSE );
     /* place fields in searchdlg_table */
-    searchdlg_table = gtk_table_new( 5 , 2 , FALSE );
+    searchdlg_table = gtk_table_new( 7 , 2 , FALSE );
     gtk_table_set_row_spacing( GTK_TABLE(searchdlg_table) , 0 , 8 );
+    gtk_table_set_row_spacing( GTK_TABLE(searchdlg_table) , 4 , 8 );
     gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_hbox ,
       0 , 2 , 0 , 1 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
     gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_track_name ,
@@ -722,6 +753,10 @@
       0 , 1 , 4 , 5 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 );
     gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_file_name ,
       1 , 2 , 4 , 5 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_clearprevsel ,
+      0 , 2 , 5 , 6 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_newplaylist ,
+      0 , 2 , 6 , 7 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 );
 
     gtk_container_set_border_width( GTK_CONTAINER(searchdlg_table) , 5 );
     gtk_container_add( GTK_CONTAINER(GTK_DIALOG(searchdlg_win)->vbox) , searchdlg_table );
@@ -731,6 +766,7 @@
     {
       case GTK_RESPONSE_ACCEPT:
       {
+         gint matched_entries_num = 0;
          /* create a TitleInput tuple with user search data */
          TitleInput *tuple = g_malloc(sizeof(TitleInput));
          gchar *searchdata = NULL;
@@ -742,8 +778,11 @@
          tuple->performer = ( strcmp(searchdata,"") ) ? g_strdup(searchdata) : NULL;
          searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_file_name) );
          tuple->file_name = ( strcmp(searchdata,"") ) ? g_strdup(searchdata) : NULL;
+         /* check if previous selection should be cleared before searching */
+         if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel)) == TRUE )
+             playlistwin_select_none();
          /* now send this tuple to the real search function */
-         playlist_select_search( playlist , tuple , 0 );
+         matched_entries_num = playlist_select_search( playlist , tuple , 0 );
          /* we do not need the tuple and its data anymore */
          if ( tuple->track_name != NULL ) g_free( tuple->track_name );
          if ( tuple->album_name != NULL )  g_free( tuple->album_name );
@@ -751,6 +790,9 @@
          if ( tuple->file_name != NULL ) g_free( tuple->file_name );
          g_free( tuple );
          playlistwin_update_list();
+         /* check if a new playlist should be created after searching */
+         if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist)) == TRUE )
+             playlist_new_from_selected();
          break;
       }
       default:
@@ -761,27 +803,6 @@
 }
 
 static void
-playlistwin_select_all(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_select_all(playlist, TRUE);
-    playlistwin_list->pl_prev_selected = 0;
-    playlistwin_list->pl_prev_min = 0;
-    playlistwin_list->pl_prev_max = playlist_get_length(playlist) - 1;
-    playlistwin_update_list();
-}
-
-static void
-playlistwin_select_none(void)
-{
-    playlist_select_all(playlist_get_active(), FALSE);
-    playlistwin_list->pl_prev_selected = -1;
-    playlistwin_list->pl_prev_min = -1;
-    playlistwin_update_list();
-}
-
-static void
 playlistwin_inverse_selection(void)
 {
     playlist_select_invert_all(playlist_get_active());
--- a/audacious/widgets/playlist_list.c	Sat Dec 16 02:35:16 2006 -0800
+++ b/audacious/widgets/playlist_list.c	Sat Dec 16 02:52:03 2006 -0800
@@ -244,15 +244,19 @@
 playlist_list_move_up(PlayList_List * pl)
 {
     GList *list;
+    Playlist *playlist = playlist_get_active();
 
-    PLAYLIST_LOCK();
-    if ((list = playlist_get()) == NULL) {
-        PLAYLIST_UNLOCK();
+    if (!playlist)
+        return;
+
+    PLAYLIST_LOCK(playlist->mutex);
+    if ((list = playlist->entries) == NULL) {
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
     if (PLAYLIST_ENTRY(list->data)->selected) {
         /* We are at the top */
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
     while (list) {
@@ -260,7 +264,7 @@
             glist_moveup(list);
         list = g_list_next(list);
     }
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
     if (pl->pl_prev_selected != -1)
         pl->pl_prev_selected--;
     if (pl->pl_prev_min != -1)
@@ -273,17 +277,21 @@
 playlist_list_move_down(PlayList_List * pl)
 {
     GList *list;
+    Playlist *playlist = playlist_get_active();
 
-    PLAYLIST_LOCK();
+    if (!playlist)
+        return;
 
-    if (!(list = g_list_last(playlist_get()))) {
-        PLAYLIST_UNLOCK();
+    PLAYLIST_LOCK(playlist->mutex);
+
+    if (!(list = g_list_last(playlist->entries))) {
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
 
     if (PLAYLIST_ENTRY(list->data)->selected) {
         /* We are at the bottom */
-        PLAYLIST_UNLOCK();
+        PLAYLIST_UNLOCK(playlist->mutex);
         return;
     }
 
@@ -293,7 +301,7 @@
         list = g_list_previous(list);
     }
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     if (pl->pl_prev_selected != -1)
         pl->pl_prev_selected++;
@@ -460,7 +468,7 @@
 
     PangoLayout *layout;
 
-    REQUIRE_STATIC_LOCK(playlists);
+    REQUIRE_LOCK(playlist->mutex);
 
     if (cfg.show_numbers_in_pl) {
         gchar *pos_string = g_strdup_printf(cfg.show_separator_in_pl == TRUE ? "%d" : "%d.", ppos);
@@ -590,7 +598,7 @@
 
     pl->pl_first = CLAMP(pl->pl_first, 0, max_first);
 
-    PLAYLIST_LOCK();
+    PLAYLIST_LOCK(playlist->mutex);
     list = playlist->entries;
     list = g_list_nth(list, pl->pl_first);
 
@@ -612,7 +620,7 @@
     }
 
     /* Reset */
-    list = playlist_get();
+    list = playlist->entries;
     list = g_list_nth(list, pl->pl_first);
 
     for (i = pl->pl_first;
@@ -887,7 +895,7 @@
     gdk_gc_set_clip_origin(gc, 0, 0);
     gdk_gc_set_clip_rectangle(gc, NULL);
 
-    PLAYLIST_UNLOCK();
+    PLAYLIST_UNLOCK(playlist->mutex);
 
     gdk_flush();