void playlist_prev(void) { GList *plist_pos_list; gboolean restart_playing = FALSE; PL_LOCK(); if (!playlist) { PL_UNLOCK(); return; } plist_pos_list = find_playlist_position_list(); if (!cfg.repeat && !g_list_previous(plist_pos_list)) { PL_UNLOCK(); return; } if (get_input_playing()) { /* We need to stop before changing playlist_position */ PL_UNLOCK(); input_stop(); PL_LOCK(); restart_playing = TRUE; } plist_pos_list = find_playlist_position_list(); if (g_list_previous(plist_pos_list)) playlist_position = plist_pos_list->prev->data; else if (cfg.repeat) { GList *node; playlist_position = NULL; __playlist_generate_shuffle_list(); if (cfg.shuffle) node = g_list_last(shuffle_list); else node = g_list_last(playlist); if (node) playlist_position = node->data; } PL_UNLOCK(); playlist_check_pos_current(); if (restart_playing) playlist_play(); else { mainwin_set_info_text(); playlistwin_update_list(); } }
void playlist_list_move_up(PlayList_List *pl) { GList *list; PL_LOCK(); if ((list = get_playlist()) == NULL) { PL_UNLOCK(); return; } if (((PlaylistEntry *) list->data)->selected) { /* We are at the top */ PL_UNLOCK(); return; } while (list) { if (((PlaylistEntry *) list->data)->selected) glist_moveup(list); list = g_list_next(list); } PL_UNLOCK(); if (pl->pl_prev_selected != -1) pl->pl_prev_selected--; if (pl->pl_prev_min != -1) pl->pl_prev_min--; if (pl->pl_prev_max != -1) pl->pl_prev_max--; }
void playlist_list_move_down(PlayList_List *pl) { GList *list; PL_LOCK(); if ((list = g_list_last(get_playlist())) == NULL) { PL_UNLOCK(); return; } if (((PlaylistEntry *) list->data)->selected) { /* We are at the bottom */ PL_UNLOCK(); return; } while (list) { if (((PlaylistEntry *) list->data)->selected) glist_movedown(list); list = g_list_previous(list); } PL_UNLOCK(); if (pl->pl_prev_selected != -1) pl->pl_prev_selected++; if (pl->pl_prev_min != -1) pl->pl_prev_min++; if (pl->pl_prev_max != -1) pl->pl_prev_max++; }
int destroySourceFile(SourceFile sf) { DEBUG(MSG_SRCFILE, Sdprintf("Destroying source file %s\n", PL_atom_chars(sf->name))); clearSourceAdmin(sf); PL_LOCK(L_SRCFILE); if ( sf->magic == SF_MAGIC ) { SourceFile f; sf->magic = SF_MAGIC_DESTROYING; f = deleteHTable(GD->files.table, (void*)sf->name); assert(f); PL_unregister_atom(sf->name); putSourceFileArray(sf->index, NULL); if ( GD->files.no_hole_before > sf->index ) GD->files.no_hole_before = sf->index; } PL_UNLOCK(L_SRCFILE); unallocSourceFile(sf); return TRUE; }
void playlist_delete_filenames(GList *filenames) { GList *node, *fnode; gboolean set_info_text = FALSE, restart_playing = FALSE; PL_LOCK(); for (fnode = filenames; fnode; fnode = g_list_next(fnode)) { node = playlist; while (node) { GList *next = g_list_next(node); PlaylistEntry *entry = node->data; if (!strcmp(entry->filename, fnode->data)) playlist_delete_node(node, &set_info_text, &restart_playing); node = next; } } PL_UNLOCK(); playlistwin_update_list(); if (restart_playing) { if (playlist_position) playlist_play(); else mainwin_clear_song_info(); } else if (set_info_text) mainwin_set_info_text(); }
void PL_register_blob_type(PL_blob_t *type) { PL_LOCK(L_MISC); /* cannot use L_ATOM */ if ( !type->registered ) { if ( !GD->atoms.types ) { GD->atoms.types = type; } else { PL_blob_t *t = GD->atoms.types; while(t->next) t = t->next; t->next = type; type->rank = t->rank+1; } type->registered = TRUE; if ( !type->atom_name ) type->atom_name = PL_new_atom(type->name); if ( true(type, PL_BLOB_TEXT) ) { if ( true(type, PL_BLOB_WCHAR) ) type->padding = sizeof(pl_wchar_t); else type->padding = sizeof(char); } } PL_UNLOCK(L_MISC); }
void playlist_delete(gboolean crop) { gboolean restart_playing = FALSE, set_info_text = FALSE; GList *node, *next; PlaylistEntry *entry; PL_LOCK(); node = playlist; while (node) { entry = node->data; next = g_list_next(node); if ((entry->selected && !crop) || (!entry->selected && crop)) playlist_delete_node(node, &set_info_text, &restart_playing); node = next; } PL_UNLOCK(); playlistwin_update_list(); if (restart_playing) { if (playlist_position) playlist_play(); else mainwin_clear_song_info(); } else if (set_info_text) mainwin_set_info_text(); }
void * topOfSegStack(segstack *stack) { again: if ( stack->top >= stack->base + stack->unit_size ) { return stack->top - stack->unit_size; } else { segchunk *chunk = stack->last; if ( chunk ) { if ( chunk->previous ) { PL_LOCK(L_AGC); /* See comment */ stack->last = chunk->previous; stack->last->next = NULL; if ( chunk->allocated ) PL_free(chunk); chunk = stack->last; stack->base = chunk->data; stack->max = addPointer(chunk, chunk->size); stack->top = chunk->top; PL_UNLOCK(L_AGC); goto again; } } return NULL; } }
char * playlist_get_filename(int pos) { char *ret; PlaylistEntry *entry; GList *node; PL_LOCK(); if (!playlist) { PL_UNLOCK(); return NULL; } node = g_list_nth(playlist, pos); if (!node) { PL_UNLOCK(); return NULL; } entry = node->data; ret = g_strdup(entry->filename); PL_UNLOCK(); return ret; }
void playlist_set_shuffle(gboolean shuffle) { PL_LOCK(); cfg.shuffle = shuffle; __playlist_generate_shuffle_list(); PL_UNLOCK(); }
void PL_register_blob_type(PL_blob_t *type) { PL_LOCK(L_MISC); /* cannot use L_ATOM */ if ( !type->registered ) { if ( !GD->atoms.types ) { GD->atoms.types = type; type->atom_name = ATOM_text; /* avoid deadlock */ type->registered = TRUE; } else { PL_blob_t *t = GD->atoms.types; while(t->next) t = t->next; t->next = type; type->rank = t->rank+1; type->registered = TRUE; type->atom_name = PL_new_atom(type->name); } } PL_UNLOCK(L_MISC); }
gboolean playlist_read_info_selection(void) { GList *node; gboolean retval = FALSE; PL_LOCK(); for (node = get_playlist(); node; node = node->next) { PlaylistEntry *entry = node->data; if (entry->selected) { retval = TRUE; if (entry->title) g_free(entry->title); entry->title = NULL; entry->length = -1; if (!playlist_get_info_entry(entry)) { if (g_list_index(get_playlist(), entry) == -1) /* Entry disapeared while we looked it up. Restart. */ node = get_playlist(); } } } PL_UNLOCK(); playlistwin_update_list(); return retval; }
static gboolean playlist_get_info_entry(PlaylistEntry *entry) { /* * Caller need to hold playlist mutex. * Note that this function temporarily drops the playlist mutex. * If it returns false, the entry might no longer be valid. */ char *temp_filename, *temp_title; int temp_length; temp_filename = g_strdup(entry->filename); temp_title = NULL; temp_length = -1; /* We don't want to lock the playlist while reading info */ PL_UNLOCK(); input_get_song_info(temp_filename, &temp_title, &temp_length); PL_LOCK(); g_free(temp_filename); if (!temp_title && temp_length == -1) return FALSE; /* Make sure entry is still around */ if (g_list_index(get_playlist(), entry) == -1) return FALSE; /* entry is still around */ entry->title = temp_title; entry->length = temp_length; return TRUE; }
void playlist_get_total_time(gulong *total_time, gulong *selection_time, gboolean *total_more, gboolean *selection_more) { GList *list; PlaylistEntry *entry; *total_time = 0; *selection_time = 0; *total_more = FALSE; *selection_more = FALSE; PL_LOCK(); list = get_playlist(); while (list) { entry = list->data; if (entry->length != -1) *total_time += entry->length / 1000; else *total_more = TRUE; if (entry->selected) { if (entry->length != -1) *selection_time += entry->length / 1000; else *selection_more = TRUE; } list = g_list_next(list); } PL_UNLOCK(); }
void playlist_delete_index(glong index) { gboolean restart_playing = FALSE, set_info_text = FALSE; GList *node; PL_LOCK(); if (!playlist) { PL_UNLOCK(); return; } node = g_list_nth(playlist, index); if(!node) { PL_UNLOCK(); return; } playlist_delete_node(node, &set_info_text, &restart_playing); PL_UNLOCK(); playlistwin_update_list(); if (restart_playing) { if (playlist_position) playlist_play(); else mainwin_clear_song_info(); } else if (set_info_text) mainwin_set_info_text(); }
int playlist_get_songtime(int pos) { int retval = -1; PlaylistEntry *entry; GList *node; PL_LOCK(); if (!playlist) { PL_UNLOCK(); return -1; } node = g_list_nth(playlist, pos); if (!node) { PL_UNLOCK(); return -1; } entry = node->data; if (entry->title == NULL && entry->length == -1) { if (playlist_get_info_entry(entry)) retval = entry->length; PL_UNLOCK(); } else { retval = entry->length; PL_UNLOCK(); } return retval; }
void playlist_check_pos_current(void) { int pos, row, bottom; PL_LOCK(); if (!playlist || !playlist_position || !playlistwin_list) { PL_UNLOCK(); return; } pos = g_list_index(playlist, playlist_position); if (playlistwin_item_visible(pos)) { PL_UNLOCK(); return; } bottom = MAX(0, __get_playlist_length() - playlistwin_list->pl_num_visible); row = CLAMP(pos - playlistwin_list->pl_num_visible / 2, 0, bottom); PL_UNLOCK(); playlistwin_set_toprow(row); }
void playlist_set_position(int pos) { GList *node; gboolean restart_playing = FALSE; PL_LOCK(); if (!playlist) { PL_UNLOCK(); return; } node = g_list_nth(playlist, pos); if (!node) { PL_UNLOCK(); return; } if (get_input_playing()) { /* We need to stop before changing playlist_position */ PL_UNLOCK(); input_stop(); PL_LOCK(); restart_playing = TRUE; } playlist_position = node->data; PL_UNLOCK(); playlist_check_pos_current(); if (restart_playing) playlist_play(); else { mainwin_set_info_text(); playlistwin_update_list(); } /* * Regenerate the shuffle list when the user set a position * manually */ playlist_generate_shuffle_list(); }
void playlist_random(void) { PL_LOCK(); playlist = playlist_shuffle_list(playlist); PL_UNLOCK(); }
void playlist_clear_queue(void) { PL_LOCK(); g_list_free(queued_list); queued_list = NULL; PL_UNLOCK(); playlistwin_update_list(); }
char *playlist_get_info_text(void) { char *text, *tmp, *numbers, *length; const gchar *title; PL_LOCK(); if (!playlist_position) { PL_UNLOCK(); return NULL; } if (playlist_position->title) title = playlist_position->title; else title = xmms_g_basename(playlist_position->filename); /* * If the user don't want numbers in the playlist, don't * display them in other parts of XMMS */ if (cfg.show_numbers_in_pl) numbers = g_strdup_printf("%d. ", __get_playlist_position() + 1); else numbers = g_strdup(""); if (playlist_position->length != -1) length = g_strdup_printf(" (%d:%-2.2d)", playlist_position->length / 60000, (playlist_position->length / 1000) % 60); else length = g_strdup(""); text = g_strdup_printf("%s%s%s", numbers, title, length); g_free(numbers); g_free(length); PL_UNLOCK(); if (cfg.convert_underscore) while ((tmp = strchr(text, '_')) != NULL) *tmp = ' '; if (cfg.convert_twenty) while ((tmp = strstr(text, "%20")) != NULL) { char *tmp2; tmp2 = tmp + 3; *(tmp++) = ' '; while (*tmp2) *(tmp++) = *(tmp2++); *tmp = '\0'; } return text; }
int get_playlist_length(void) { int retval; PL_LOCK(); retval = __get_playlist_length(); PL_UNLOCK(); return retval; }
int get_playlist_position(void) { int retval; PL_LOCK(); retval = __get_playlist_position(); PL_UNLOCK(); return retval; }
SourceFile lookupSourceFile(atom_t name, int create) { SourceFile sf; PL_LOCK(L_SRCFILE); sf = lookupSourceFile_unlocked(name, create); PL_UNLOCK(L_SRCFILE); return sf; }
int playlist_get_current_length(void) { int retval = 0; PL_LOCK(); if (playlist && playlist_position) retval = playlist_position->length; PL_UNLOCK(); return retval; }
gint get_playlist_queue_length(void) { gint qlength; PL_LOCK(); qlength = g_list_length(queued_list); PL_UNLOCK(); return qlength; }
void playlist_queue_remove(int pos) { void *entry; PL_LOCK(); entry = g_list_nth_data(playlist, pos); queued_list = g_list_remove(queued_list, entry); PL_UNLOCK(); playlistwin_update_list(); }
void playlist_queue_position(int pos) { void *entry; PL_LOCK(); entry = g_list_nth_data(playlist, pos); playlist_queue_toggle(entry); PL_UNLOCK(); playlistwin_update_list(); }
gboolean playlist_is_position_selected(int pos) { PlaylistEntry *entry; gboolean selected; PL_LOCK(); entry = g_list_nth_data(playlist, pos); selected = entry && entry->selected; PL_UNLOCK(); return selected; }
gboolean playlist_is_position_queued(int pos) { PlaylistEntry *entry; GList *temp; PL_LOCK(); entry = g_list_nth_data(playlist, pos); temp = g_list_find(queued_list, entry); PL_UNLOCK(); return temp != NULL; }