comparison src/audacious/playlist.c @ 3479:26910525cec8 trunk

merge
author Kieran Clancy <clancy.kieran+audacious@gmail.com>
date Mon, 10 Sep 2007 14:18:18 +0930
parents 481a4a88d3ec 440877c9360e
children 6f8005df972f
comparison
equal deleted inserted replaced
3478:481a4a88d3ec 3479:26910525cec8
43 #include <sys/types.h> 43 #include <sys/types.h>
44 #include <sys/stat.h> 44 #include <sys/stat.h>
45 #include <sys/errno.h> 45 #include <sys/errno.h>
46 46
47 #if defined(USE_REGEX_ONIGURUMA) 47 #if defined(USE_REGEX_ONIGURUMA)
48 #include <onigposix.h> 48 # include <onigposix.h>
49 #elif defined(USE_REGEX_PCRE) 49 #elif defined(USE_REGEX_PCRE)
50 #include <pcreposix.h> 50 # include <pcreposix.h>
51 #else 51 #else
52 #include <regex.h> 52 # include <regex.h>
53 #endif 53 #endif
54 54
55 #include "input.h" 55 #include "input.h"
56 #include "main.h" 56 #include "main.h"
57 #include "ui_main.h" 57 #include "ui_main.h"
100 * up. Hince the boolean below. 100 * up. Hince the boolean below.
101 * 101 *
102 * January 7, 2006, William Pitcock <nenolod@nenolod.net> 102 * January 7, 2006, William Pitcock <nenolod@nenolod.net>
103 */ 103 */
104 104
105 G_LOCK_DEFINE(playlist_get_info_going);
106 105
107 //static gchar *playlist_current_name = NULL; 106 //static gchar *playlist_current_name = NULL;
108 107
109 static gboolean playlist_get_info_scan_active = FALSE; 108 static gboolean playlist_get_info_scan_active = FALSE;
109 GStaticRWLock playlist_get_info_rwlock = G_STATIC_RW_LOCK_INIT;
110 static gboolean playlist_get_info_going = FALSE; 110 static gboolean playlist_get_info_going = FALSE;
111 static GThread *playlist_get_info_thread; 111 static GThread *playlist_get_info_thread;
112 112
113 static gint path_compare(const gchar * a, const gchar * b); 113 static gint path_compare(const gchar * a, const gchar * b);
114 static gint playlist_compare_path(PlaylistEntry * a, PlaylistEntry * b); 114 static gint playlist_compare_path(PlaylistEntry * a, PlaylistEntry * b);
439 playlist->queue = g_list_remove_link(playlist->queue, playlist->queue); 439 playlist->queue = g_list_remove_link(playlist->queue, playlist->queue);
440 g_list_free_1(tmp); 440 g_list_free_1(tmp);
441 } 441 }
442 442
443 void 443 void
444 playlist_clear(Playlist *playlist) 444 playlist_clear_only(Playlist *playlist)
445 { 445 {
446 if (!playlist) 446 PLAYLIST_LOCK(playlist);
447 return;
448
449 PLAYLIST_LOCK( playlist->mutex );
450 447
451 g_list_foreach(playlist->entries, (GFunc) playlist_entry_free, NULL); 448 g_list_foreach(playlist->entries, (GFunc) playlist_entry_free, NULL);
452 g_list_free(playlist->entries); 449 g_list_free(playlist->entries);
453 playlist->position = NULL; 450 playlist->position = NULL;
454 playlist->entries = NULL; 451 playlist->entries = NULL;
455 playlist->tail = NULL; 452 playlist->tail = NULL;
456 playlist->attribute = PLAYLIST_PLAIN; 453 playlist->attribute = PLAYLIST_PLAIN;
457 454
458 PLAYLIST_UNLOCK( playlist->mutex ); 455 PLAYLIST_UNLOCK(playlist);
459 456 }
457
458 void
459 playlist_clear(Playlist *playlist)
460 {
461 if (!playlist)
462 return;
463
464 playlist_clear_only(playlist);
460 playlist_generate_shuffle_list(playlist); 465 playlist_generate_shuffle_list(playlist);
461 playlistwin_update_list(playlist); 466 playlistwin_update_list(playlist);
462 playlist_recalc_total_time(playlist); 467 playlist_recalc_total_time(playlist);
463 playlist_manager_update(); 468 playlist_manager_update();
464 } 469 }
482 487
483 if (playing_song == node) { 488 if (playing_song == node) {
484 *set_info_text = TRUE; 489 *set_info_text = TRUE;
485 490
486 if (playback_get_playing()) { 491 if (playback_get_playing()) {
487 PLAYLIST_UNLOCK(playlist->mutex); 492 PLAYLIST_UNLOCK(playlist);
488 ip_data.stop = TRUE; 493 ip_data.stop = TRUE;
489 playback_stop(); 494 playback_stop();
490 ip_data.stop = FALSE; 495 ip_data.stop = FALSE;
491 PLAYLIST_LOCK(playlist->mutex); 496 PLAYLIST_LOCK(playlist);
492 *restart_playing = TRUE; 497 *restart_playing = TRUE;
493 } 498 }
494 499
495 playing_song = find_playlist_position_list(playlist); 500 playing_song = find_playlist_position_list(playlist);
496 501
528 GList *node; 533 GList *node;
529 534
530 if (!playlist) 535 if (!playlist)
531 return; 536 return;
532 537
533 PLAYLIST_LOCK(playlist->mutex); 538 PLAYLIST_LOCK(playlist);
534 539
535 node = g_list_nth(playlist->entries, pos); 540 node = g_list_nth(playlist->entries, pos);
536 541
537 if (!node) { 542 if (!node) {
538 PLAYLIST_UNLOCK(playlist->mutex); 543 PLAYLIST_UNLOCK(playlist);
539 return; 544 return;
540 } 545 }
541 546
542 playlist_delete_node(playlist, node, &set_info_text, &restart_playing); 547 playlist_delete_node(playlist, node, &set_info_text, &restart_playing);
543 548
544 PLAYLIST_UNLOCK(playlist->mutex); 549 PLAYLIST_UNLOCK(playlist);
545 550
546 playlist_recalc_total_time(playlist); 551 playlist_recalc_total_time(playlist);
547 552
548 playlistwin_update_list(playlist); 553 playlistwin_update_list(playlist);
549 if (restart_playing) { 554 if (restart_playing) {
561 playlist_delete_filenames(Playlist * playlist, GList * filenames) 566 playlist_delete_filenames(Playlist * playlist, GList * filenames)
562 { 567 {
563 GList *node, *fnode; 568 GList *node, *fnode;
564 gboolean set_info_text = FALSE, restart_playing = FALSE; 569 gboolean set_info_text = FALSE, restart_playing = FALSE;
565 570
566 PLAYLIST_LOCK(playlist->mutex); 571 PLAYLIST_LOCK(playlist);
567 572
568 for (fnode = filenames; fnode; fnode = g_list_next(fnode)) { 573 for (fnode = filenames; fnode; fnode = g_list_next(fnode)) {
569 node = playlist->entries; 574 node = playlist->entries;
570 575
571 while (node) { 576 while (node) {
577 582
578 node = next; 583 node = next;
579 } 584 }
580 } 585 }
581 586
582 PLAYLIST_UNLOCK(playlist->mutex); 587 PLAYLIST_UNLOCK(playlist);
583 588
584 playlist_recalc_total_time(playlist); 589 playlist_recalc_total_time(playlist);
585 playlistwin_update_list(playlist); 590 playlistwin_update_list(playlist);
586 591
587 if (restart_playing) { 592 if (restart_playing) {
602 GList *node, *next_node; 607 GList *node, *next_node;
603 PlaylistEntry *entry; 608 PlaylistEntry *entry;
604 609
605 g_return_if_fail(playlist != NULL); 610 g_return_if_fail(playlist != NULL);
606 611
607 PLAYLIST_LOCK(playlist->mutex); 612 PLAYLIST_LOCK(playlist);
608 613
609 node = playlist->entries; 614 node = playlist->entries;
610 615
611 while (node) { 616 while (node) {
612 entry = PLAYLIST_ENTRY(node->data); 617 entry = PLAYLIST_ENTRY(node->data);
618 } 623 }
619 624
620 node = next_node; 625 node = next_node;
621 } 626 }
622 627
623 PLAYLIST_UNLOCK(playlist->mutex); 628 PLAYLIST_UNLOCK(playlist);
624 629
625 playlist_recalc_total_time(playlist); 630 playlist_recalc_total_time(playlist);
626 631
627 if (restart_playing) { 632 if (restart_playing) {
628 if (playlist->position) 633 if (playlist->position)
644 gint len, 649 gint len,
645 InputPlugin * dec) 650 InputPlugin * dec)
646 { 651 {
647 g_return_if_fail(filename != NULL); 652 g_return_if_fail(filename != NULL);
648 653
649 PLAYLIST_LOCK( playlist->mutex ); 654 PLAYLIST_LOCK(playlist);
650 playlist->entries = g_list_insert(playlist->entries, 655 playlist->entries = g_list_insert(playlist->entries,
651 playlist_entry_new(filename, title, len, dec), 656 playlist_entry_new(filename, title, len, dec),
652 pos); 657 pos);
653 PLAYLIST_UNLOCK( playlist->mutex ); 658 PLAYLIST_UNLOCK(playlist);
654 659
655 g_mutex_lock(mutex_scan); 660 g_mutex_lock(mutex_scan);
656 playlist_get_info_scan_active = TRUE; 661 playlist_get_info_scan_active = TRUE;
657 g_mutex_unlock(mutex_scan); 662 g_mutex_unlock(mutex_scan);
658 g_cond_signal(cond_scan); 663 g_cond_signal(cond_scan);
672 677
673 entry = playlist_entry_new(filename, tuple ? tuple_get_string(tuple, "title") : NULL, tuple ? tuple_get_int(tuple, "length") : -1, dec); 678 entry = playlist_entry_new(filename, tuple ? tuple_get_string(tuple, "title") : NULL, tuple ? tuple_get_int(tuple, "length") : -1, dec);
674 if(!playlist->tail) 679 if(!playlist->tail)
675 playlist->tail = g_list_last(playlist->entries); 680 playlist->tail = g_list_last(playlist->entries);
676 681
677 PLAYLIST_LOCK( playlist->mutex ); 682 PLAYLIST_LOCK(playlist);
683
678 if(pos == -1) { // the common case 684 if(pos == -1) { // the common case
679 GList *element; 685 GList *element;
680 element = g_list_alloc(); 686 element = g_list_alloc();
681 element->data = entry; 687 element->data = entry;
682 element->prev = playlist->tail; // NULL is allowed here. 688 element->prev = playlist->tail; // NULL is allowed here.
694 } 700 }
695 else { 701 else {
696 playlist->entries = g_list_insert(playlist->entries, entry, pos); 702 playlist->entries = g_list_insert(playlist->entries, entry, pos);
697 } 703 }
698 704
699 PLAYLIST_UNLOCK( playlist->mutex ); 705 PLAYLIST_UNLOCK(playlist);
706
700 if (tuple != NULL) { 707 if (tuple != NULL) {
701 const gchar *formatter = tuple_get_string(tuple, "formatter"); 708 const gchar *formatter = tuple_get_string(tuple, "formatter");
702 entry->title = tuple_formatter_make_title_string(tuple, formatter ? 709 entry->title = tuple_formatter_make_title_string(tuple, formatter ?
703 formatter : get_gentitle_format()); 710 formatter : get_gentitle_format());
704 entry->length = tuple_get_int(tuple, "length"); 711 entry->length = tuple_get_int(tuple, "length");
1026 } 1033 }
1027 } 1034 }
1028 1035
1029 g_free(decoded); 1036 g_free(decoded);
1030 1037
1031 PLAYLIST_LOCK(playlist->mutex); 1038 PLAYLIST_LOCK(playlist);
1032 node = g_list_nth(playlist->entries, pos); 1039 node = g_list_nth(playlist->entries, pos);
1033 PLAYLIST_UNLOCK(playlist->mutex); 1040 PLAYLIST_UNLOCK(playlist);
1034 1041
1035 entries += i; 1042 entries += i;
1036 1043
1037 if (pos >= 0) 1044 if (pos >= 0)
1038 pos += i; 1045 pos += i;
1120 gint pos, row, bottom; 1127 gint pos, row, bottom;
1121 1128
1122 if (!playlist) 1129 if (!playlist)
1123 return; 1130 return;
1124 1131
1125 PLAYLIST_LOCK(playlist->mutex); 1132 PLAYLIST_LOCK(playlist);
1126 if (!playlist->position || !playlistwin_list) { 1133 if (!playlist->position || !playlistwin_list) {
1127 PLAYLIST_UNLOCK(playlist->mutex); 1134 PLAYLIST_UNLOCK(playlist);
1128 return; 1135 return;
1129 } 1136 }
1130 1137
1131 pos = g_list_index(playlist->entries, playlist->position); 1138 pos = g_list_index(playlist->entries, playlist->position);
1132 1139
1133 if (playlistwin_item_visible(pos)) { 1140 if (playlistwin_item_visible(pos)) {
1134 PLAYLIST_UNLOCK(playlist->mutex); 1141 PLAYLIST_UNLOCK(playlist);
1135 return; 1142 return;
1136 } 1143 }
1137 1144
1138 bottom = MAX(0, playlist_get_length(playlist) - 1145 bottom = MAX(0, playlist_get_length(playlist) -
1139 UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible); 1146 UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible);
1140 row = CLAMP(pos - UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible / 2, 0, bottom); 1147 row = CLAMP(pos - UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible / 2, 0, bottom);
1141 PLAYLIST_UNLOCK(playlist->mutex); 1148 PLAYLIST_UNLOCK(playlist);
1142 playlistwin_set_toprow(row); 1149 playlistwin_set_toprow(row);
1143 g_cond_signal(cond_scan); 1150 g_cond_signal(cond_scan);
1144 } 1151 }
1145 1152
1146 void 1153 void
1149 GList *plist_pos_list; 1156 GList *plist_pos_list;
1150 gboolean restart_playing = FALSE; 1157 gboolean restart_playing = FALSE;
1151 if (!playlist_get_length(playlist)) 1158 if (!playlist_get_length(playlist))
1152 return; 1159 return;
1153 1160
1154 PLAYLIST_LOCK(playlist->mutex); 1161 PLAYLIST_LOCK(playlist);
1155 1162
1156 if ((playlist_position_before_jump != NULL) && playlist->queue == NULL) 1163 if ((playlist_position_before_jump != NULL) && playlist->queue == NULL)
1157 { 1164 {
1158 playlist->position = playlist_position_before_jump; 1165 playlist->position = playlist_position_before_jump;
1159 playlist_position_before_jump = NULL; 1166 playlist_position_before_jump = NULL;
1160 } 1167 }
1161 1168
1162 plist_pos_list = find_playlist_position_list(playlist); 1169 plist_pos_list = find_playlist_position_list(playlist);
1163 1170
1164 if (!cfg.repeat && !g_list_next(plist_pos_list) && playlist->queue == NULL) { 1171 if (!cfg.repeat && !g_list_next(plist_pos_list) && playlist->queue == NULL) {
1165 PLAYLIST_UNLOCK(playlist->mutex); 1172 PLAYLIST_UNLOCK(playlist);
1166 return; 1173 return;
1167 } 1174 }
1168 1175
1169 if (playback_get_playing()) { 1176 if (playback_get_playing()) {
1170 /* We need to stop before changing playlist_position */ 1177 /* We need to stop before changing playlist_position */
1171 PLAYLIST_UNLOCK(playlist->mutex); 1178 PLAYLIST_UNLOCK(playlist);
1172 ip_data.stop = TRUE; 1179 ip_data.stop = TRUE;
1173 playback_stop(); 1180 playback_stop();
1174 ip_data.stop = FALSE; 1181 ip_data.stop = FALSE;
1175 PLAYLIST_LOCK(playlist->mutex); 1182 PLAYLIST_LOCK(playlist);
1176 restart_playing = TRUE; 1183 restart_playing = TRUE;
1177 } 1184 }
1178 1185
1179 plist_pos_list = find_playlist_position_list(playlist); 1186 plist_pos_list = find_playlist_position_list(playlist);
1180 if (playlist->queue != NULL) 1187 if (playlist->queue != NULL)
1187 if (cfg.shuffle) 1194 if (cfg.shuffle)
1188 playlist->position = playlist->shuffle->data; 1195 playlist->position = playlist->shuffle->data;
1189 else 1196 else
1190 playlist->position = playlist->entries->data; 1197 playlist->position = playlist->entries->data;
1191 } 1198 }
1192 PLAYLIST_UNLOCK(playlist->mutex); 1199 PLAYLIST_UNLOCK(playlist);
1193 playlist_check_pos_current(playlist); 1200 playlist_check_pos_current(playlist);
1194 1201
1195 if (restart_playing) 1202 if (restart_playing)
1196 playback_initiate(); 1203 playback_initiate();
1197 1204
1205 gboolean restart_playing = FALSE; 1212 gboolean restart_playing = FALSE;
1206 1213
1207 if (!playlist_get_length(playlist)) 1214 if (!playlist_get_length(playlist))
1208 return; 1215 return;
1209 1216
1210 PLAYLIST_LOCK(playlist->mutex); 1217 PLAYLIST_LOCK(playlist);
1211 1218
1212 if ((playlist_position_before_jump != NULL) && playlist->queue == NULL) 1219 if ((playlist_position_before_jump != NULL) && playlist->queue == NULL)
1213 { 1220 {
1214 playlist->position = playlist_position_before_jump; 1221 playlist->position = playlist_position_before_jump;
1215 playlist_position_before_jump = NULL; 1222 playlist_position_before_jump = NULL;
1216 } 1223 }
1217 1224
1218 plist_pos_list = find_playlist_position_list(playlist); 1225 plist_pos_list = find_playlist_position_list(playlist);
1219 1226
1220 if (!cfg.repeat && !g_list_previous(plist_pos_list)) { 1227 if (!cfg.repeat && !g_list_previous(plist_pos_list)) {
1221 PLAYLIST_UNLOCK(playlist->mutex); 1228 PLAYLIST_UNLOCK(playlist);
1222 return; 1229 return;
1223 } 1230 }
1224 1231
1225 if (playback_get_playing()) { 1232 if (playback_get_playing()) {
1226 /* We need to stop before changing playlist_position */ 1233 /* We need to stop before changing playlist_position */
1227 PLAYLIST_UNLOCK(playlist->mutex); 1234 PLAYLIST_UNLOCK(playlist);
1228 ip_data.stop = TRUE; 1235 ip_data.stop = TRUE;
1229 playback_stop(); 1236 playback_stop();
1230 ip_data.stop = FALSE; 1237 ip_data.stop = FALSE;
1231 PLAYLIST_LOCK(playlist->mutex); 1238 PLAYLIST_LOCK(playlist);
1232 restart_playing = TRUE; 1239 restart_playing = TRUE;
1233 } 1240 }
1234 1241
1235 plist_pos_list = find_playlist_position_list(playlist); 1242 plist_pos_list = find_playlist_position_list(playlist);
1236 if (g_list_previous(plist_pos_list)) { 1243 if (g_list_previous(plist_pos_list)) {
1246 node = g_list_last(playlist->entries); 1253 node = g_list_last(playlist->entries);
1247 if (node) 1254 if (node)
1248 playlist->position = node->data; 1255 playlist->position = node->data;
1249 } 1256 }
1250 1257
1251 PLAYLIST_UNLOCK(playlist->mutex); 1258 PLAYLIST_UNLOCK(playlist);
1252 1259
1253 playlist_check_pos_current(playlist); 1260 playlist_check_pos_current(playlist);
1254 1261
1255 if (restart_playing) 1262 if (restart_playing)
1256 playback_initiate(); 1263 playback_initiate();
1262 playlist_queue(Playlist *playlist) 1269 playlist_queue(Playlist *playlist)
1263 { 1270 {
1264 GList *list = playlist_get_selected(playlist); 1271 GList *list = playlist_get_selected(playlist);
1265 GList *it = list; 1272 GList *it = list;
1266 1273
1267 PLAYLIST_LOCK(playlist->mutex); 1274 PLAYLIST_LOCK(playlist);
1268 1275
1269 if ((cfg.shuffle) && (playlist_position_before_jump == NULL)) 1276 if ((cfg.shuffle) && (playlist_position_before_jump == NULL))
1270 { 1277 {
1271 /* Shuffling and this is our first manual jump. */ 1278 /* Shuffling and this is our first manual jump. */
1272 playlist_position_before_jump = playlist->position; 1279 playlist_position_before_jump = playlist->position;
1288 it = next; 1295 it = next;
1289 } 1296 }
1290 1297
1291 playlist->queue = g_list_concat(playlist->queue, list); 1298 playlist->queue = g_list_concat(playlist->queue, list);
1292 1299
1293 PLAYLIST_UNLOCK(playlist->mutex); 1300 PLAYLIST_UNLOCK(playlist);
1294 1301
1295 playlist_recalc_total_time(playlist); 1302 playlist_recalc_total_time(playlist);
1296 playlistwin_update_list(playlist); 1303 playlistwin_update_list(playlist);
1297 } 1304 }
1298 1305
1300 playlist_queue_position(Playlist *playlist, guint pos) 1307 playlist_queue_position(Playlist *playlist, guint pos)
1301 { 1308 {
1302 GList *tmp; 1309 GList *tmp;
1303 PlaylistEntry *entry; 1310 PlaylistEntry *entry;
1304 1311
1305 PLAYLIST_LOCK(playlist->mutex); 1312 PLAYLIST_LOCK(playlist);
1306 1313
1307 if ((cfg.shuffle) && (playlist_position_before_jump == NULL)) 1314 if ((cfg.shuffle) && (playlist_position_before_jump == NULL))
1308 { 1315 {
1309 /* Shuffling and this is our first manual jump. */ 1316 /* Shuffling and this is our first manual jump. */
1310 playlist_position_before_jump = playlist->position; 1317 playlist_position_before_jump = playlist->position;
1315 playlist->queue = g_list_remove_link(playlist->queue, tmp); 1322 playlist->queue = g_list_remove_link(playlist->queue, tmp);
1316 g_list_free_1(tmp); 1323 g_list_free_1(tmp);
1317 } 1324 }
1318 else 1325 else
1319 playlist->queue = g_list_append(playlist->queue, entry); 1326 playlist->queue = g_list_append(playlist->queue, entry);
1320 PLAYLIST_UNLOCK(playlist->mutex); 1327 PLAYLIST_UNLOCK(playlist);
1321 1328
1322 playlist_recalc_total_time(playlist); 1329 playlist_recalc_total_time(playlist);
1323 playlistwin_update_list(playlist); 1330 playlistwin_update_list(playlist);
1324 } 1331 }
1325 1332
1327 playlist_is_position_queued(Playlist *playlist, guint pos) 1334 playlist_is_position_queued(Playlist *playlist, guint pos)
1328 { 1335 {
1329 PlaylistEntry *entry; 1336 PlaylistEntry *entry;
1330 GList *tmp; 1337 GList *tmp;
1331 1338
1332 PLAYLIST_LOCK(playlist->mutex); 1339 PLAYLIST_LOCK(playlist);
1333 entry = g_list_nth_data(playlist->entries, pos); 1340 entry = g_list_nth_data(playlist->entries, pos);
1334 tmp = g_list_find(playlist->queue, entry); 1341 tmp = g_list_find(playlist->queue, entry);
1335 PLAYLIST_UNLOCK(playlist->mutex); 1342 PLAYLIST_UNLOCK(playlist);
1336 1343
1337 return tmp != NULL; 1344 return tmp != NULL;
1338 } 1345 }
1339 1346
1340 gint 1347 gint
1341 playlist_get_queue_position_number(Playlist *playlist, guint pos) 1348 playlist_get_queue_position_number(Playlist *playlist, guint pos)
1342 { 1349 {
1343 PlaylistEntry *entry; 1350 PlaylistEntry *entry;
1344 gint tmp; 1351 gint tmp;
1345 1352
1346 PLAYLIST_LOCK(playlist->mutex); 1353 PLAYLIST_LOCK(playlist);
1347 entry = g_list_nth_data(playlist->entries, pos); 1354 entry = g_list_nth_data(playlist->entries, pos);
1348 tmp = g_list_index(playlist->queue, entry); 1355 tmp = g_list_index(playlist->queue, entry);
1349 PLAYLIST_UNLOCK(playlist->mutex); 1356 PLAYLIST_UNLOCK(playlist);
1350 1357
1351 return tmp; 1358 return tmp;
1352 } 1359 }
1353 1360
1354 gint 1361 gint
1355 playlist_get_queue_qposition_number(Playlist *playlist, guint pos) 1362 playlist_get_queue_qposition_number(Playlist *playlist, guint pos)
1356 { 1363 {
1357 PlaylistEntry *entry; 1364 PlaylistEntry *entry;
1358 gint tmp; 1365 gint tmp;
1359 1366
1360 PLAYLIST_LOCK(playlist->mutex); 1367 PLAYLIST_LOCK(playlist);
1361 entry = g_list_nth_data(playlist->queue, pos); 1368 entry = g_list_nth_data(playlist->queue, pos);
1362 tmp = g_list_index(playlist->entries, entry); 1369 tmp = g_list_index(playlist->entries, entry);
1363 PLAYLIST_UNLOCK(playlist->mutex); 1370 PLAYLIST_UNLOCK(playlist);
1364 1371
1365 return tmp; 1372 return tmp;
1366 } 1373 }
1367 1374
1368 void 1375 void
1369 playlist_clear_queue(Playlist *playlist) 1376 playlist_clear_queue(Playlist *playlist)
1370 { 1377 {
1371 PLAYLIST_LOCK(playlist->mutex); 1378 PLAYLIST_LOCK(playlist);
1372 g_list_free(playlist->queue); 1379 g_list_free(playlist->queue);
1373 playlist->queue = NULL; 1380 playlist->queue = NULL;
1374 PLAYLIST_UNLOCK(playlist->mutex); 1381 PLAYLIST_UNLOCK(playlist);
1375 1382
1376 playlist_recalc_total_time(playlist); 1383 playlist_recalc_total_time(playlist);
1377 playlistwin_update_list(playlist); 1384 playlistwin_update_list(playlist);
1378 } 1385 }
1379 1386
1380 void 1387 void
1381 playlist_queue_remove(Playlist *playlist, guint pos) 1388 playlist_queue_remove(Playlist *playlist, guint pos)
1382 { 1389 {
1383 void *entry; 1390 void *entry;
1384 1391
1385 PLAYLIST_LOCK(playlist->mutex); 1392 PLAYLIST_LOCK(playlist);
1386 entry = g_list_nth_data(playlist->entries, pos); 1393 entry = g_list_nth_data(playlist->entries, pos);
1387 playlist->queue = g_list_remove(playlist->queue, entry); 1394 playlist->queue = g_list_remove(playlist->queue, entry);
1388 PLAYLIST_UNLOCK(playlist->mutex); 1395 PLAYLIST_UNLOCK(playlist);
1389 1396
1390 playlistwin_update_list(playlist); 1397 playlistwin_update_list(playlist);
1391 } 1398 }
1392 1399
1393 gint 1400 gint
1403 gboolean restart_playing = FALSE; 1410 gboolean restart_playing = FALSE;
1404 1411
1405 if (!playlist) 1412 if (!playlist)
1406 return; 1413 return;
1407 1414
1408 PLAYLIST_LOCK(playlist->mutex); 1415 PLAYLIST_LOCK(playlist);
1409 1416
1410 node = g_list_nth(playlist->entries, pos); 1417 node = g_list_nth(playlist->entries, pos);
1411 if (!node) { 1418 if (!node) {
1412 PLAYLIST_UNLOCK(playlist->mutex); 1419 PLAYLIST_UNLOCK(playlist);
1413 return; 1420 return;
1414 } 1421 }
1415 1422
1416 if (playback_get_playing()) { 1423 if (playback_get_playing()) {
1417 /* We need to stop before changing playlist_position */ 1424 /* We need to stop before changing playlist_position */
1418 PLAYLIST_UNLOCK(playlist->mutex); 1425 PLAYLIST_UNLOCK(playlist);
1419 ip_data.stop = TRUE; 1426 ip_data.stop = TRUE;
1420 playback_stop(); 1427 playback_stop();
1421 ip_data.stop = FALSE; 1428 ip_data.stop = FALSE;
1422 PLAYLIST_LOCK(playlist->mutex); 1429 PLAYLIST_LOCK(playlist);
1423 restart_playing = TRUE; 1430 restart_playing = TRUE;
1424 } 1431 }
1425 1432
1426 if ((cfg.shuffle) && (playlist_position_before_jump == NULL)) 1433 if ((cfg.shuffle) && (playlist_position_before_jump == NULL))
1427 { 1434 {
1428 /* Shuffling and this is our first manual jump. */ 1435 /* Shuffling and this is our first manual jump. */
1429 playlist_position_before_jump = playlist->position; 1436 playlist_position_before_jump = playlist->position;
1430 } 1437 }
1431 1438
1432 playlist->position = node->data; 1439 playlist->position = node->data;
1433 PLAYLIST_UNLOCK(playlist->mutex); 1440 PLAYLIST_UNLOCK(playlist);
1434 playlist_check_pos_current(playlist); 1441 playlist_check_pos_current(playlist);
1435 1442
1436 if (restart_playing) 1443 if (restart_playing)
1437 playback_initiate(); 1444 playback_initiate();
1438 else 1445 else
1450 if ((cfg.no_playlist_advance && !cfg.repeat) || cfg.stopaftersong) 1457 if ((cfg.no_playlist_advance && !cfg.repeat) || cfg.stopaftersong)
1451 ip_data.stop = FALSE; 1458 ip_data.stop = FALSE;
1452 1459
1453 hook_call("playback end", playlist->position); 1460 hook_call("playback end", playlist->position);
1454 1461
1455 PLAYLIST_LOCK(playlist->mutex); 1462 PLAYLIST_LOCK(playlist);
1456 1463
1457 if ((playlist_position_before_jump != NULL) && playlist->queue == NULL) 1464 if ((playlist_position_before_jump != NULL) && playlist->queue == NULL)
1458 { 1465 {
1459 playlist->position = playlist_position_before_jump; 1466 playlist->position = playlist_position_before_jump;
1460 playlist_position_before_jump = NULL; 1467 playlist_position_before_jump = NULL;
1461 } 1468 }
1462 1469
1463 plist_pos_list = find_playlist_position_list(playlist); 1470 plist_pos_list = find_playlist_position_list(playlist);
1464 1471
1465 if (cfg.no_playlist_advance) { 1472 if (cfg.no_playlist_advance) {
1466 PLAYLIST_UNLOCK(playlist->mutex); 1473 PLAYLIST_UNLOCK(playlist);
1467 mainwin_clear_song_info(); 1474 mainwin_clear_song_info();
1468 if (cfg.repeat) 1475 if (cfg.repeat)
1469 playback_initiate(); 1476 playback_initiate();
1470 return; 1477 return;
1471 } 1478 }
1472 1479
1473 if (cfg.stopaftersong) { 1480 if (cfg.stopaftersong) {
1474 PLAYLIST_UNLOCK(playlist->mutex); 1481 PLAYLIST_UNLOCK(playlist);
1475 mainwin_clear_song_info(); 1482 mainwin_clear_song_info();
1476 mainwin_set_stopaftersong(FALSE); 1483 mainwin_set_stopaftersong(FALSE);
1477 return; 1484 return;
1478 } 1485 }
1479 1486
1487 } 1494 }
1488 else if (playlist->entries != NULL) 1495 else if (playlist->entries != NULL)
1489 playlist->position = playlist->entries->data; 1496 playlist->position = playlist->entries->data;
1490 1497
1491 if (!cfg.repeat) { 1498 if (!cfg.repeat) {
1492 PLAYLIST_UNLOCK(playlist->mutex); 1499 PLAYLIST_UNLOCK(playlist);
1493 hook_call("playlist end reached", playlist->position); 1500 hook_call("playlist end reached", playlist->position);
1494 mainwin_clear_song_info(); 1501 mainwin_clear_song_info();
1495 return; 1502 return;
1496 } 1503 }
1497 } 1504 }
1498 else 1505 else
1499 playlist->position = g_list_next(plist_pos_list)->data; 1506 playlist->position = g_list_next(plist_pos_list)->data;
1500 1507
1501 PLAYLIST_UNLOCK(playlist->mutex); 1508 PLAYLIST_UNLOCK(playlist);
1502 1509
1503 playlist_check_pos_current(playlist); 1510 playlist_check_pos_current(playlist);
1504 playback_initiate(); 1511 playback_initiate();
1505 playlistwin_update_list(playlist); 1512 playlistwin_update_list(playlist);
1506 } 1513 }
1508 gint 1515 gint
1509 playlist_queue_get_length(Playlist *playlist) 1516 playlist_queue_get_length(Playlist *playlist)
1510 { 1517 {
1511 gint length; 1518 gint length;
1512 1519
1513 PLAYLIST_LOCK(playlist->mutex); 1520 PLAYLIST_LOCK(playlist);
1514 length = g_list_length(playlist->queue); 1521 length = g_list_length(playlist->queue);
1515 PLAYLIST_UNLOCK(playlist->mutex); 1522 PLAYLIST_UNLOCK(playlist);
1516 1523
1517 return length; 1524 return length;
1518 } 1525 }
1519 1526
1520 gint 1527 gint
1528 { 1535 {
1529 gchar *text, *title, *numbers, *length; 1536 gchar *text, *title, *numbers, *length;
1530 1537
1531 g_return_val_if_fail(playlist != NULL, NULL); 1538 g_return_val_if_fail(playlist != NULL, NULL);
1532 1539
1533 PLAYLIST_LOCK(playlist->mutex); 1540 PLAYLIST_LOCK(playlist);
1534 if (!playlist->position) { 1541 if (!playlist->position) {
1535 PLAYLIST_UNLOCK(playlist->mutex); 1542 PLAYLIST_UNLOCK(playlist);
1536 return NULL; 1543 return NULL;
1537 } 1544 }
1538 1545
1539 /* FIXME: there should not be a need to do additional conversion, 1546 /* FIXME: there should not be a need to do additional conversion,
1540 * if playlist is properly maintained */ 1547 * if playlist is properly maintained */
1566 playlist->position->length / 60000, 1573 playlist->position->length / 60000,
1567 (playlist->position->length / 1000) % 60); 1574 (playlist->position->length / 1000) % 60);
1568 else 1575 else
1569 length = g_strdup(""); 1576 length = g_strdup("");
1570 1577
1571 PLAYLIST_UNLOCK(playlist->mutex); 1578 PLAYLIST_UNLOCK(playlist);
1572 1579
1573 text = convert_title_text(g_strconcat(numbers, title, length, NULL)); 1580 text = convert_title_text(g_strconcat(numbers, title, length, NULL));
1574 1581
1575 g_free(numbers); 1582 g_free(numbers);
1576 g_free(title); 1583 g_free(title);
1832 gint 1839 gint
1833 playlist_get_position(Playlist *playlist) 1840 playlist_get_position(Playlist *playlist)
1834 { 1841 {
1835 gint pos; 1842 gint pos;
1836 1843
1837 PLAYLIST_LOCK(playlist->mutex); 1844 PLAYLIST_LOCK(playlist);
1838 pos = playlist_get_position_nolock(playlist); 1845 pos = playlist_get_position_nolock(playlist);
1839 PLAYLIST_UNLOCK(playlist->mutex); 1846 PLAYLIST_UNLOCK(playlist);
1840 1847
1841 return pos; 1848 return pos;
1842 } 1849 }
1843 1850
1844 gchar * 1851 gchar *
1849 GList *node; 1856 GList *node;
1850 1857
1851 if (!playlist) 1858 if (!playlist)
1852 return NULL; 1859 return NULL;
1853 1860
1854 PLAYLIST_LOCK(playlist->mutex); 1861 PLAYLIST_LOCK(playlist);
1855 node = g_list_nth(playlist->entries, pos); 1862 node = g_list_nth(playlist->entries, pos);
1856 if (!node) { 1863 if (!node) {
1857 PLAYLIST_UNLOCK(playlist->mutex); 1864 PLAYLIST_UNLOCK(playlist);
1858 return NULL; 1865 return NULL;
1859 } 1866 }
1860 entry = node->data; 1867 entry = node->data;
1861 1868
1862 filename = g_strdup(entry->filename); 1869 filename = g_strdup(entry->filename);
1863 PLAYLIST_UNLOCK(playlist->mutex); 1870 PLAYLIST_UNLOCK(playlist);
1864 1871
1865 return filename; 1872 return filename;
1866 } 1873 }
1867 1874
1868 gchar * 1875 gchar *
1874 time_t mtime; 1881 time_t mtime;
1875 1882
1876 if (!playlist) 1883 if (!playlist)
1877 return NULL; 1884 return NULL;
1878 1885
1879 PLAYLIST_LOCK(playlist->mutex); 1886 PLAYLIST_LOCK(playlist);
1880 1887
1881 if (!(node = g_list_nth(playlist->entries, pos))) { 1888 if (!(node = g_list_nth(playlist->entries, pos))) {
1882 PLAYLIST_UNLOCK(playlist->mutex); 1889 PLAYLIST_UNLOCK(playlist);
1883 return NULL; 1890 return NULL;
1884 } 1891 }
1885 1892
1886 entry = node->data; 1893 entry = node->data;
1887 1894
1899 } 1906 }
1900 else { 1907 else {
1901 title = entry->title; 1908 title = entry->title;
1902 } 1909 }
1903 1910
1904 PLAYLIST_UNLOCK(playlist->mutex); 1911 PLAYLIST_UNLOCK(playlist);
1905 1912
1906 if (!title) { 1913 if (!title) {
1907 gchar *realfn = NULL; 1914 gchar *realfn = NULL;
1908 realfn = g_filename_from_uri(entry->filename, NULL, NULL); 1915 realfn = g_filename_from_uri(entry->filename, NULL, NULL);
1909 title = g_path_get_basename(realfn ? realfn : entry->filename); 1916 title = g_path_get_basename(realfn ? realfn : entry->filename);
2229 2236
2230 void 2237 void
2231 playlist_sort(Playlist *playlist, PlaylistSortType type) 2238 playlist_sort(Playlist *playlist, PlaylistSortType type)
2232 { 2239 {
2233 playlist_remove_dead_files(playlist); 2240 playlist_remove_dead_files(playlist);
2234 PLAYLIST_LOCK(playlist->mutex); 2241 PLAYLIST_LOCK(playlist);
2235 playlist->entries = 2242 playlist->entries =
2236 g_list_sort(playlist->entries, 2243 g_list_sort(playlist->entries,
2237 (GCompareFunc) playlist_compare_func_table[type]); 2244 (GCompareFunc) playlist_compare_func_table[type]);
2238 PLAYLIST_UNLOCK(playlist->mutex); 2245 PLAYLIST_UNLOCK(playlist);
2239 } 2246 }
2240 2247
2241 static GList * 2248 static GList *
2242 playlist_sort_selected_generic(GList * list, GCompareFunc cmpfunc) 2249 playlist_sort_selected_generic(GList * list, GCompareFunc cmpfunc)
2243 { 2250 {
2288 } 2295 }
2289 2296
2290 void 2297 void
2291 playlist_sort_selected(Playlist *playlist, PlaylistSortType type) 2298 playlist_sort_selected(Playlist *playlist, PlaylistSortType type)
2292 { 2299 {
2293 PLAYLIST_LOCK(playlist->mutex); 2300 PLAYLIST_LOCK(playlist);
2294 playlist->entries = playlist_sort_selected_generic(playlist->entries, (GCompareFunc) 2301 playlist->entries = playlist_sort_selected_generic(playlist->entries, (GCompareFunc)
2295 playlist_compare_func_table 2302 playlist_compare_func_table
2296 [type]); 2303 [type]);
2297 PLAYLIST_UNLOCK(playlist->mutex); 2304 PLAYLIST_UNLOCK(playlist);
2298 } 2305 }
2299 2306
2300 void 2307 void
2301 playlist_reverse(Playlist *playlist) 2308 playlist_reverse(Playlist *playlist)
2302 { 2309 {
2303 PLAYLIST_LOCK(playlist->mutex); 2310 PLAYLIST_LOCK(playlist);
2304 playlist->entries = g_list_reverse(playlist->entries); 2311 playlist->entries = g_list_reverse(playlist->entries);
2305 PLAYLIST_UNLOCK(playlist->mutex); 2312 PLAYLIST_UNLOCK(playlist);
2306 } 2313 }
2307 2314
2308 static GList * 2315 static GList *
2309 playlist_shuffle_list(Playlist *playlist, GList * list) 2316 playlist_shuffle_list(Playlist *playlist, GList * list)
2310 { 2317 {
2350 } 2357 }
2351 2358
2352 void 2359 void
2353 playlist_random(Playlist *playlist) 2360 playlist_random(Playlist *playlist)
2354 { 2361 {
2355 PLAYLIST_LOCK(playlist->mutex); 2362 PLAYLIST_LOCK(playlist);
2356 playlist->entries = playlist_shuffle_list(playlist, playlist->entries); 2363 playlist->entries = playlist_shuffle_list(playlist, playlist->entries);
2357 PLAYLIST_UNLOCK(playlist->mutex); 2364 PLAYLIST_UNLOCK(playlist);
2358 } 2365 }
2359 2366
2360 GList * 2367 GList *
2361 playlist_get_selected(Playlist *playlist) 2368 playlist_get_selected(Playlist *playlist)
2362 { 2369 {
2363 GList *node, *list = NULL; 2370 GList *node, *list = NULL;
2364 gint i = 0; 2371 gint i = 0;
2365 2372
2366 PLAYLIST_LOCK(playlist->mutex); 2373 PLAYLIST_LOCK(playlist);
2367 for (node = playlist->entries; node; node = g_list_next(node), i++) { 2374 for (node = playlist->entries; node; node = g_list_next(node), i++) {
2368 PlaylistEntry *entry = node->data; 2375 PlaylistEntry *entry = node->data;
2369 if (entry->selected) 2376 if (entry->selected)
2370 list = g_list_prepend(list, GINT_TO_POINTER(i)); 2377 list = g_list_prepend(list, GINT_TO_POINTER(i));
2371 } 2378 }
2372 PLAYLIST_UNLOCK(playlist->mutex); 2379 PLAYLIST_UNLOCK(playlist);
2373 return g_list_reverse(list); 2380 return g_list_reverse(list);
2374 } 2381 }
2375 2382
2376 void 2383 void
2377 playlist_clear_selected(Playlist *playlist) 2384 playlist_clear_selected(Playlist *playlist)
2378 { 2385 {
2379 GList *node = NULL; 2386 GList *node = NULL;
2380 gint i = 0; 2387 gint i = 0;
2381 2388
2382 PLAYLIST_LOCK(playlist->mutex); 2389 PLAYLIST_LOCK(playlist);
2383 for (node = playlist->entries; node; node = g_list_next(node), i++) { 2390 for (node = playlist->entries; node; node = g_list_next(node), i++) {
2384 PLAYLIST_ENTRY(node->data)->selected = FALSE; 2391 PLAYLIST_ENTRY(node->data)->selected = FALSE;
2385 } 2392 }
2386 PLAYLIST_UNLOCK(playlist->mutex); 2393 PLAYLIST_UNLOCK(playlist);
2387 playlist_recalc_total_time(playlist); 2394 playlist_recalc_total_time(playlist);
2388 playlist_manager_update(); 2395 playlist_manager_update();
2389 } 2396 }
2390 2397
2391 gint 2398 gint
2392 playlist_get_num_selected(Playlist *playlist) 2399 playlist_get_num_selected(Playlist *playlist)
2393 { 2400 {
2394 GList *node; 2401 GList *node;
2395 gint num = 0; 2402 gint num = 0;
2396 2403
2397 PLAYLIST_LOCK(playlist->mutex); 2404 PLAYLIST_LOCK(playlist);
2398 for (node = playlist->entries; node; node = g_list_next(node)) { 2405 for (node = playlist->entries; node; node = g_list_next(node)) {
2399 PlaylistEntry *entry = node->data; 2406 PlaylistEntry *entry = node->data;
2400 if (entry->selected) 2407 if (entry->selected)
2401 num++; 2408 num++;
2402 } 2409 }
2403 PLAYLIST_UNLOCK(playlist->mutex); 2410 PLAYLIST_UNLOCK(playlist);
2404 return num; 2411 return num;
2405 } 2412 }
2406 2413
2407 2414
2408 static void 2415 static void
2409 playlist_generate_shuffle_list(Playlist *playlist) 2416 playlist_generate_shuffle_list(Playlist *playlist)
2410 { 2417 {
2411 PLAYLIST_LOCK(playlist->mutex); 2418 PLAYLIST_LOCK(playlist);
2412 playlist_generate_shuffle_list_nolock(playlist); 2419 playlist_generate_shuffle_list_nolock(playlist);
2413 PLAYLIST_UNLOCK(playlist->mutex); 2420 PLAYLIST_UNLOCK(playlist);
2414 } 2421 }
2415 2422
2416 static void 2423 static void
2417 playlist_generate_shuffle_list_nolock(Playlist *playlist) 2424 playlist_generate_shuffle_list_nolock(Playlist *playlist)
2418 { 2425 {
2448 PlaylistEntry *entry = NULL; 2455 PlaylistEntry *entry = NULL;
2449 Tuple *tuple = NULL; 2456 Tuple *tuple = NULL;
2450 ProbeResult *pr = NULL; 2457 ProbeResult *pr = NULL;
2451 time_t mtime; 2458 time_t mtime;
2452 2459
2453 PLAYLIST_LOCK(playlist->mutex); 2460 PLAYLIST_LOCK(playlist);
2454 2461
2455 if ((node = g_list_nth(playlist->entries, pos))) 2462 if ((node = g_list_nth(playlist->entries, pos)))
2456 { 2463 {
2457 entry = node->data; 2464 entry = node->data;
2458 tuple = entry->tuple; 2465 tuple = entry->tuple;
2459 path = g_strdup(entry->filename); 2466 path = g_strdup(entry->filename);
2460 } 2467 }
2461 2468
2462 PLAYLIST_UNLOCK(playlist->mutex); 2469 PLAYLIST_UNLOCK(playlist);
2463 2470
2464 if (entry->tuple) 2471 if (entry->tuple)
2465 mtime = tuple_get_int(entry->tuple, "mtime"); 2472 mtime = tuple_get_int(entry->tuple, "mtime");
2466 else 2473 else
2467 mtime = 0; 2474 mtime = 0;
2506 playlist_fileinfo_current(Playlist *playlist) 2513 playlist_fileinfo_current(Playlist *playlist)
2507 { 2514 {
2508 gchar *path = NULL; 2515 gchar *path = NULL;
2509 Tuple *tuple = NULL; 2516 Tuple *tuple = NULL;
2510 2517
2511 PLAYLIST_LOCK(playlist->mutex); 2518 PLAYLIST_LOCK(playlist);
2512 2519
2513 if (playlist->entries && playlist->position) 2520 if (playlist->entries && playlist->position)
2514 { 2521 {
2515 path = g_strdup(playlist->position->filename); 2522 path = g_strdup(playlist->position->filename);
2516 if (( playlist->position->tuple == NULL ) || ( playlist->position->decoder == NULL )) 2523 if (( playlist->position->tuple == NULL ) || ( playlist->position->decoder == NULL ))
2517 playlist_entry_get_info(playlist->position); 2524 playlist_entry_get_info(playlist->position);
2518 tuple = playlist->position->tuple; 2525 tuple = playlist->position->tuple;
2519 } 2526 }
2520 2527
2521 PLAYLIST_UNLOCK(playlist->mutex); 2528 PLAYLIST_UNLOCK(playlist);
2522 2529
2523 if (tuple != NULL) 2530 if (tuple != NULL)
2524 { 2531 {
2525 if (playlist->position->decoder != NULL && playlist->position->decoder->file_info_box == NULL) 2532 if (playlist->position->decoder != NULL && playlist->position->decoder->file_info_box == NULL)
2526 fileinfo_show_for_tuple(tuple); 2533 fileinfo_show_for_tuple(tuple);
2544 static gboolean 2551 static gboolean
2545 playlist_get_info_is_going(void) 2552 playlist_get_info_is_going(void)
2546 { 2553 {
2547 gboolean result; 2554 gboolean result;
2548 2555
2549 G_LOCK(playlist_get_info_going); 2556 g_static_rw_lock_reader_lock(&playlist_get_info_rwlock);
2550 result = playlist_get_info_going; 2557 result = playlist_get_info_going;
2551 G_UNLOCK(playlist_get_info_going); 2558 g_static_rw_lock_reader_unlock(&playlist_get_info_rwlock);
2552 2559
2553 return result; 2560 return result;
2554 } 2561 }
2562
2563
2564 static gboolean
2565 playlist_get_info_scanning(void)
2566 {
2567 gboolean result;
2568
2569 g_mutex_lock(mutex_scan);
2570 result = playlist_get_info_scan_active;
2571 g_mutex_unlock(mutex_scan);
2572
2573 return result;
2574 }
2575
2555 2576
2556 static gboolean 2577 static gboolean
2557 playlist_request_win_update(gpointer unused) 2578 playlist_request_win_update(gpointer unused)
2558 { 2579 {
2559 Playlist *playlist = playlist_get_active(); 2580 Playlist *playlist = playlist_get_active();
2560 playlistwin_update_list(playlist); 2581 playlistwin_update_list(playlist);
2561 return FALSE; /* to be called only once */ 2582 return FALSE; /* to be called only once */
2562 } 2583 }
2563 2584
2585
2564 static gpointer 2586 static gpointer
2565 playlist_get_info_func(gpointer arg) 2587 playlist_get_info_func(gpointer arg)
2566 { 2588 {
2567 GList *node; 2589 GList *node;
2568 gboolean update_playlistwin = FALSE; 2590 gboolean update_playlistwin = FALSE;
2570 while (playlist_get_info_is_going()) { 2592 while (playlist_get_info_is_going()) {
2571 PlaylistEntry *entry; 2593 PlaylistEntry *entry;
2572 Playlist *playlist = playlist_get_active(); 2594 Playlist *playlist = playlist_get_active();
2573 2595
2574 // on_load 2596 // on_load
2575 if (cfg.use_pl_metadata && 2597 if (cfg.use_pl_metadata && cfg.get_info_on_load &&
2576 cfg.get_info_on_load && 2598 playlist_get_info_scanning()) {
2577 playlist_get_info_scan_active) {
2578 2599
2579 for (node = playlist->entries; node; node = g_list_next(node)) { 2600 for (node = playlist->entries; node; node = g_list_next(node)) {
2580 entry = node->data; 2601 entry = node->data;
2581 2602
2582 if(playlist->attribute & PLAYLIST_STATIC || 2603 if(playlist->attribute & PLAYLIST_STATIC ||
2638 update_playlistwin = TRUE; 2659 update_playlistwin = TRUE;
2639 // no need for break here since this iteration is very short. 2660 // no need for break here since this iteration is very short.
2640 } 2661 }
2641 } 2662 }
2642 } // on_demand 2663 } // on_demand
2643 else if (cfg.get_info_on_demand && 2664 else if (cfg.get_info_on_demand &&
2644 (!cfg.playlist_visible || cfg.playlist_shaded 2665 (!cfg.playlist_visible || cfg.playlist_shaded || !cfg.use_pl_metadata))
2645 || !cfg.use_pl_metadata))
2646 { 2666 {
2647 g_mutex_lock(mutex_scan); 2667 g_mutex_lock(mutex_scan);
2648 playlist_get_info_scan_active = FALSE; 2668 playlist_get_info_scan_active = FALSE;
2649 g_mutex_unlock(mutex_scan); 2669 g_mutex_unlock(mutex_scan);
2650 } 2670 }
2661 instead, schedule a playlist update in the main loop --giacomo */ 2681 instead, schedule a playlist update in the main loop --giacomo */
2662 g_idle_add_full(G_PRIORITY_HIGH_IDLE, playlist_request_win_update, NULL, NULL); 2682 g_idle_add_full(G_PRIORITY_HIGH_IDLE, playlist_request_win_update, NULL, NULL);
2663 update_playlistwin = FALSE; 2683 update_playlistwin = FALSE;
2664 } 2684 }
2665 2685
2666 if (playlist_get_info_scan_active) { 2686 if (playlist_get_info_scanning()) {
2667 continue; 2687 continue;
2668 } 2688 }
2669 2689
2670 g_mutex_lock(mutex_scan); 2690 g_mutex_lock(mutex_scan);
2671 g_cond_wait(cond_scan, mutex_scan); 2691 g_cond_wait(cond_scan, mutex_scan);
2678 } 2698 }
2679 2699
2680 void 2700 void
2681 playlist_start_get_info_thread(void) 2701 playlist_start_get_info_thread(void)
2682 { 2702 {
2683 G_LOCK(playlist_get_info_going); 2703 g_static_rw_lock_writer_lock(&playlist_get_info_rwlock);
2684 playlist_get_info_going = TRUE; 2704 playlist_get_info_going = TRUE;
2685 G_UNLOCK(playlist_get_info_going); 2705 g_static_rw_lock_writer_unlock(&playlist_get_info_rwlock);
2686 2706
2687 playlist_get_info_thread = g_thread_create(playlist_get_info_func, 2707 playlist_get_info_thread = g_thread_create(playlist_get_info_func,
2688 NULL, TRUE, NULL); 2708 NULL, TRUE, NULL);
2689 } 2709 }
2690 2710
2691 void 2711 void
2692 playlist_stop_get_info_thread(void) 2712 playlist_stop_get_info_thread(void)
2693 { 2713 {
2694 G_LOCK(playlist_get_info_going); 2714 g_static_rw_lock_writer_lock(&playlist_get_info_rwlock);
2695 playlist_get_info_going = FALSE; 2715 playlist_get_info_going = FALSE;
2696 G_UNLOCK(playlist_get_info_going); 2716 g_static_rw_lock_writer_unlock(&playlist_get_info_rwlock);
2697 2717
2698 g_cond_broadcast(cond_scan); 2718 g_cond_broadcast(cond_scan);
2699 g_thread_join(playlist_get_info_thread); 2719 g_thread_join(playlist_get_info_thread);
2700 } 2720 }
2701 2721
2703 playlist_start_get_info_scan(void) 2723 playlist_start_get_info_scan(void)
2704 { 2724 {
2705 g_mutex_lock(mutex_scan); 2725 g_mutex_lock(mutex_scan);
2706 playlist_get_info_scan_active = TRUE; 2726 playlist_get_info_scan_active = TRUE;
2707 g_mutex_unlock(mutex_scan); 2727 g_mutex_unlock(mutex_scan);
2728
2708 g_cond_signal(cond_scan); 2729 g_cond_signal(cond_scan);
2709 } 2730 }
2710 2731
2711 void 2732 void
2712 playlist_remove_dead_files(Playlist *playlist) 2733 playlist_remove_dead_files(Playlist *playlist)
2713 { 2734 {
2714 GList *node, *next_node; 2735 GList *node, *next_node;
2715 2736
2716 PLAYLIST_LOCK(playlist->mutex); 2737 PLAYLIST_LOCK(playlist);
2717 2738
2718 for (node = playlist->entries; node; node = next_node) { 2739 for (node = playlist->entries; node; node = next_node) {
2719 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); 2740 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data);
2720 next_node = g_list_next(node); 2741 next_node = g_list_next(node);
2721 2742
2746 2767
2747 playlist_entry_free(entry); 2768 playlist_entry_free(entry);
2748 playlist->entries = g_list_delete_link(playlist->entries, node); 2769 playlist->entries = g_list_delete_link(playlist->entries, node);
2749 } 2770 }
2750 2771
2751 PLAYLIST_UNLOCK(playlist->mutex); 2772 PLAYLIST_UNLOCK(playlist);
2752 2773
2753 playlist_generate_shuffle_list(playlist); 2774 playlist_generate_shuffle_list(playlist);
2754 playlistwin_update_list(playlist); 2775 playlistwin_update_list(playlist);
2755 playlist_recalc_total_time(playlist); 2776 playlist_recalc_total_time(playlist);
2756 playlist_manager_update(); 2777 playlist_manager_update();
2836 default: 2857 default:
2837 dups_compare_func = playlist_dupscmp_filename; 2858 dups_compare_func = playlist_dupscmp_filename;
2838 break; 2859 break;
2839 } 2860 }
2840 2861
2841 PLAYLIST_LOCK(playlist->mutex); 2862 PLAYLIST_LOCK(playlist);
2842 2863
2843 for (node = playlist->entries; node; node = next_node) { 2864 for (node = playlist->entries; node; node = next_node) {
2844 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data); 2865 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data);
2845 next_node = g_list_next(node); 2866 next_node = g_list_next(node);
2846 2867
2881 playlist->entries = g_list_delete_link(playlist->entries, node_cmp); 2902 playlist->entries = g_list_delete_link(playlist->entries, node_cmp);
2882 } 2903 }
2883 } 2904 }
2884 } 2905 }
2885 2906
2886 PLAYLIST_UNLOCK(playlist->mutex); 2907 PLAYLIST_UNLOCK(playlist);
2887 2908
2888 playlistwin_update_list(playlist); 2909 playlistwin_update_list(playlist);
2889 playlist_recalc_total_time(playlist); 2910 playlist_recalc_total_time(playlist);
2890 2911
2891 playlist_manager_update(); 2912 playlist_manager_update();
2896 gulong * total_time, 2917 gulong * total_time,
2897 gulong * selection_time, 2918 gulong * selection_time,
2898 gboolean * total_more, 2919 gboolean * total_more,
2899 gboolean * selection_more) 2920 gboolean * selection_more)
2900 { 2921 {
2901 PLAYLIST_LOCK(playlist->mutex); 2922 PLAYLIST_LOCK(playlist);
2902 *total_time = playlist->pl_total_time; 2923 *total_time = playlist->pl_total_time;
2903 *selection_time = playlist->pl_selection_time; 2924 *selection_time = playlist->pl_selection_time;
2904 *total_more = playlist->pl_total_more; 2925 *total_more = playlist->pl_total_more;
2905 *selection_more = playlist->pl_selection_more; 2926 *selection_more = playlist->pl_selection_more;
2906 PLAYLIST_UNLOCK(playlist->mutex); 2927 PLAYLIST_UNLOCK(playlist);
2907 } 2928 }
2908 2929
2909 2930
2910 static void 2931 static void
2911 playlist_recalc_total_time_nolock(Playlist *playlist) 2932 playlist_recalc_total_time_nolock(Playlist *playlist)
2938 } 2959 }
2939 2960
2940 static void 2961 static void
2941 playlist_recalc_total_time(Playlist *playlist) 2962 playlist_recalc_total_time(Playlist *playlist)
2942 { 2963 {
2943 PLAYLIST_LOCK(playlist->mutex); 2964 PLAYLIST_LOCK(playlist);
2944 playlist_recalc_total_time_nolock(playlist); 2965 playlist_recalc_total_time_nolock(playlist);
2945 PLAYLIST_UNLOCK(playlist->mutex); 2966 PLAYLIST_UNLOCK(playlist);
2946 } 2967 }
2947 2968
2948 gint 2969 gint
2949 playlist_select_search( Playlist *playlist , Tuple *tuple , gint action ) 2970 playlist_select_search( Playlist *playlist , Tuple *tuple , gint action )
2950 { 2971 {
2956 /* set encoding for Oniguruma regex to UTF-8 */ 2977 /* set encoding for Oniguruma regex to UTF-8 */
2957 reg_set_encoding( REG_POSIX_ENCODING_UTF8 ); 2978 reg_set_encoding( REG_POSIX_ENCODING_UTF8 );
2958 onig_set_default_syntax( ONIG_SYNTAX_POSIX_BASIC ); 2979 onig_set_default_syntax( ONIG_SYNTAX_POSIX_BASIC );
2959 #endif 2980 #endif
2960 2981
2961 PLAYLIST_LOCK(playlist->mutex); 2982 PLAYLIST_LOCK(playlist);
2962 2983
2963 if ( tuple_get_string(tuple, "title") != NULL ) 2984 if ( tuple_get_string(tuple, "title") != NULL )
2964 { 2985 {
2965 /* match by track_name */ 2986 /* match by track_name */
2966 const gchar *regex_pattern = tuple_get_string(tuple, "title"); 2987 const gchar *regex_pattern = tuple_get_string(tuple, "title");
3094 num_of_entries_found++; 3115 num_of_entries_found++;
3095 } 3116 }
3096 3117
3097 g_list_free( found_list ); 3118 g_list_free( found_list );
3098 3119
3099 PLAYLIST_UNLOCK(playlist->mutex); 3120 PLAYLIST_UNLOCK(playlist);
3100 playlist_recalc_total_time(playlist); 3121 playlist_recalc_total_time(playlist);
3101 3122
3102 return num_of_entries_found; 3123 return num_of_entries_found;
3103 } 3124 }
3104 3125
3105 void 3126 void
3106 playlist_select_all(Playlist *playlist, gboolean set) 3127 playlist_select_all(Playlist *playlist, gboolean set)
3107 { 3128 {
3108 GList *list; 3129 GList *list;
3109 3130
3110 PLAYLIST_LOCK(playlist->mutex); 3131 PLAYLIST_LOCK(playlist);
3111 3132
3112 for (list = playlist->entries; list; list = g_list_next(list)) { 3133 for (list = playlist->entries; list; list = g_list_next(list)) {
3113 PlaylistEntry *entry = list->data; 3134 PlaylistEntry *entry = list->data;
3114 entry->selected = set; 3135 entry->selected = set;
3115 } 3136 }
3116 3137
3117 PLAYLIST_UNLOCK(playlist->mutex); 3138 PLAYLIST_UNLOCK(playlist);
3118 playlist_recalc_total_time(playlist); 3139 playlist_recalc_total_time(playlist);
3119 } 3140 }
3120 3141
3121 void 3142 void
3122 playlist_select_invert_all(Playlist *playlist) 3143 playlist_select_invert_all(Playlist *playlist)
3123 { 3144 {
3124 GList *list; 3145 GList *list;
3125 3146
3126 PLAYLIST_LOCK(playlist->mutex); 3147 PLAYLIST_LOCK(playlist);
3127 3148
3128 for (list = playlist->entries; list; list = g_list_next(list)) { 3149 for (list = playlist->entries; list; list = g_list_next(list)) {
3129 PlaylistEntry *entry = list->data; 3150 PlaylistEntry *entry = list->data;
3130 entry->selected = !entry->selected; 3151 entry->selected = !entry->selected;
3131 } 3152 }
3132 3153
3133 PLAYLIST_UNLOCK(playlist->mutex); 3154 PLAYLIST_UNLOCK(playlist);
3134 playlist_recalc_total_time(playlist); 3155 playlist_recalc_total_time(playlist);
3135 } 3156 }
3136 3157
3137 gboolean 3158 gboolean
3138 playlist_select_invert(Playlist *playlist, guint pos) 3159 playlist_select_invert(Playlist *playlist, guint pos)
3139 { 3160 {
3140 GList *list; 3161 GList *list;
3141 gboolean invert_ok = FALSE; 3162 gboolean invert_ok = FALSE;
3142 3163
3143 PLAYLIST_LOCK(playlist->mutex); 3164 PLAYLIST_LOCK(playlist);
3144 3165
3145 if ((list = g_list_nth(playlist->entries, pos))) { 3166 if ((list = g_list_nth(playlist->entries, pos))) {
3146 PlaylistEntry *entry = list->data; 3167 PlaylistEntry *entry = list->data;
3147 entry->selected = !entry->selected; 3168 entry->selected = !entry->selected;
3148 invert_ok = TRUE; 3169 invert_ok = TRUE;
3149 } 3170 }
3150 3171
3151 PLAYLIST_UNLOCK(playlist->mutex); 3172 PLAYLIST_UNLOCK(playlist);
3152 playlist_recalc_total_time(playlist); 3173 playlist_recalc_total_time(playlist);
3153 3174
3154 return invert_ok; 3175 return invert_ok;
3155 } 3176 }
3156 3177
3162 gint i; 3183 gint i;
3163 3184
3164 if (min_pos > max_pos) 3185 if (min_pos > max_pos)
3165 SWAP(min_pos, max_pos); 3186 SWAP(min_pos, max_pos);
3166 3187
3167 PLAYLIST_LOCK(playlist->mutex); 3188 PLAYLIST_LOCK(playlist);
3168 3189
3169 list = g_list_nth(playlist->entries, min_pos); 3190 list = g_list_nth(playlist->entries, min_pos);
3170 for (i = min_pos; i <= max_pos && list; i++) { 3191 for (i = min_pos; i <= max_pos && list; i++) {
3171 PlaylistEntry *entry = list->data; 3192 PlaylistEntry *entry = list->data;
3172 entry->selected = select; 3193 entry->selected = select;
3173 list = g_list_next(list); 3194 list = g_list_next(list);
3174 } 3195 }
3175 3196
3176 PLAYLIST_UNLOCK(playlist->mutex); 3197 PLAYLIST_UNLOCK(playlist);
3177 3198
3178 playlist_recalc_total_time(playlist); 3199 playlist_recalc_total_time(playlist);
3179 } 3200 }
3180 3201
3181 gboolean 3202 gboolean
3182 playlist_read_info_selection(Playlist *playlist) 3203 playlist_read_info_selection(Playlist *playlist)
3183 { 3204 {
3184 GList *node; 3205 GList *node;
3185 gboolean retval = FALSE; 3206 gboolean retval = FALSE;
3186 3207
3187 PLAYLIST_LOCK(playlist->mutex); 3208 PLAYLIST_LOCK(playlist);
3188 3209
3189 for (node = playlist->entries; node; node = g_list_next(node)) { 3210 for (node = playlist->entries; node; node = g_list_next(node)) {
3190 PlaylistEntry *entry = node->data; 3211 PlaylistEntry *entry = node->data;
3191 if (!entry->selected) 3212 if (!entry->selected)
3192 continue; 3213 continue;
3205 /* Entry disappeared while we looked it up. Restart. */ 3226 /* Entry disappeared while we looked it up. Restart. */
3206 node = playlist->entries; 3227 node = playlist->entries;
3207 } 3228 }
3208 } 3229 }
3209 3230
3210 PLAYLIST_UNLOCK(playlist->mutex); 3231 PLAYLIST_UNLOCK(playlist);
3211 3232
3212 playlistwin_update_list(playlist); 3233 playlistwin_update_list(playlist);
3213 playlist_recalc_total_time(playlist); 3234 playlist_recalc_total_time(playlist);
3214 3235
3215 return retval; 3236 return retval;
3218 void 3239 void
3219 playlist_read_info(Playlist *playlist, guint pos) 3240 playlist_read_info(Playlist *playlist, guint pos)
3220 { 3241 {
3221 GList *node; 3242 GList *node;
3222 3243
3223 PLAYLIST_LOCK(playlist->mutex); 3244 PLAYLIST_LOCK(playlist);
3224 3245
3225 if ((node = g_list_nth(playlist->entries, pos))) { 3246 if ((node = g_list_nth(playlist->entries, pos))) {
3226 PlaylistEntry *entry = node->data; 3247 PlaylistEntry *entry = node->data;
3227 str_replace_in(&entry->title, NULL); 3248 str_replace_in(&entry->title, NULL);
3228 entry->length = -1; 3249 entry->length = -1;
3229 playlist_entry_get_info(entry); 3250 playlist_entry_get_info(entry);
3230 } 3251 }
3231 3252
3232 PLAYLIST_UNLOCK(playlist->mutex); 3253 PLAYLIST_UNLOCK(playlist);
3233 3254
3234 playlistwin_update_list(playlist); 3255 playlistwin_update_list(playlist);
3235 playlist_recalc_total_time(playlist); 3256 playlist_recalc_total_time(playlist);
3236 } 3257 }
3237 3258
3252 { 3273 {
3253 Playlist *playlist = playlist_get_active(); 3274 Playlist *playlist = playlist_get_active();
3254 if (!playlist) 3275 if (!playlist)
3255 return; 3276 return;
3256 3277
3257 PLAYLIST_LOCK(playlist->mutex); 3278 PLAYLIST_LOCK(playlist);
3258 3279
3259 playlist_position_before_jump = NULL; 3280 playlist_position_before_jump = NULL;
3260 3281
3261 cfg.shuffle = shuffle; 3282 cfg.shuffle = shuffle;
3262 playlist_generate_shuffle_list_nolock(playlist); 3283 playlist_generate_shuffle_list_nolock(playlist);
3263 3284
3264 PLAYLIST_UNLOCK(playlist->mutex); 3285 PLAYLIST_UNLOCK(playlist);
3265 } 3286 }
3266 3287
3267 Playlist * 3288 Playlist *
3268 playlist_new(void) 3289 playlist_new(void)
3269 { 3290 {
3278 } 3299 }
3279 3300
3280 void 3301 void
3281 playlist_free(Playlist *playlist) 3302 playlist_free(Playlist *playlist)
3282 { 3303 {
3304 if (!playlist)
3305 return;
3306
3283 g_mutex_free( playlist->mutex ); 3307 g_mutex_free( playlist->mutex );
3284 g_free( playlist ); 3308 g_free( playlist );
3285 return;
3286 } 3309 }
3287 3310
3288 Playlist * 3311 Playlist *
3289 playlist_new_from_selected(void) 3312 playlist_new_from_selected(void)
3290 { 3313 {
3292 Playlist *playlist = playlist_get_active(); 3315 Playlist *playlist = playlist_get_active();
3293 GList *list = playlist_get_selected(playlist); 3316 GList *list = playlist_get_selected(playlist);
3294 3317
3295 playlist_add_playlist( newpl ); 3318 playlist_add_playlist( newpl );
3296 3319
3297 PLAYLIST_LOCK(playlist->mutex); 3320 PLAYLIST_LOCK(playlist);
3298 3321
3299 while ( list != NULL ) 3322 while ( list != NULL )
3300 { 3323 {
3301 PlaylistEntry *entry = g_list_nth_data(playlist->entries, GPOINTER_TO_INT(list->data)); 3324 PlaylistEntry *entry = g_list_nth_data(playlist->entries, GPOINTER_TO_INT(list->data));
3302 if ( entry->filename != NULL ) /* paranoid? oh well... */ 3325 if ( entry->filename != NULL ) /* paranoid? oh well... */
3303 playlist_add( newpl , entry->filename ); 3326 playlist_add( newpl , entry->filename );
3304 list = g_list_next(list); 3327 list = g_list_next(list);
3305 } 3328 }
3306 3329
3307 PLAYLIST_UNLOCK(playlist->mutex); 3330 PLAYLIST_UNLOCK(playlist);
3308 3331
3309 playlist_recalc_total_time(newpl); 3332 playlist_recalc_total_time(newpl);
3310 playlistwin_update_list(playlist); 3333 playlistwin_update_list(playlist);
3311 3334
3312 return newpl; 3335 return newpl;
3318 const gchar *filename = NULL; 3341 const gchar *filename = NULL;
3319 3342
3320 if (!playlist) 3343 if (!playlist)
3321 return NULL; 3344 return NULL;
3322 3345
3323 PLAYLIST_LOCK(playlist->mutex); 3346 PLAYLIST_LOCK(playlist);
3324 3347
3325 if (!playlist->position) { 3348 if (!playlist->position) {
3326 if (cfg.shuffle) 3349 if (cfg.shuffle)
3327 playlist->position = playlist->shuffle->data; 3350 playlist->position = playlist->shuffle->data;
3328 else 3351 else
3329 playlist->position = playlist->entries->data; 3352 playlist->position = playlist->entries->data;
3330 } 3353 }
3331 3354
3332 filename = playlist->position->filename; 3355 filename = playlist->position->filename;
3333 3356
3334 PLAYLIST_UNLOCK(playlist->mutex); 3357 PLAYLIST_UNLOCK(playlist);
3335 3358
3336 return filename; 3359 return filename;
3337 } 3360 }
3338 3361
3339 PlaylistEntry * 3362 PlaylistEntry *
3340 playlist_get_entry_to_play(Playlist *playlist) 3363 playlist_get_entry_to_play(Playlist *playlist)
3341 { 3364 {
3342 if (!playlist) 3365 if (!playlist)
3343 return NULL; 3366 return NULL;
3344 3367
3345 PLAYLIST_LOCK(playlist->mutex); 3368 PLAYLIST_LOCK(playlist);
3346 3369
3347 if (!playlist->position) { 3370 if (!playlist->position) {
3348 if (cfg.shuffle) 3371 if (cfg.shuffle)
3349 playlist->position = playlist->shuffle->data; 3372 playlist->position = playlist->shuffle->data;
3350 else 3373 else
3351 playlist->position = playlist->entries->data; 3374 playlist->position = playlist->entries->data;
3352 } 3375 }
3353 3376
3354 PLAYLIST_UNLOCK(playlist->mutex); 3377 PLAYLIST_UNLOCK(playlist);
3355 3378
3356 return playlist->position; 3379 return playlist->position;
3357 } 3380 }
3358 3381
3359 gboolean 3382 gboolean