void queue_prev(gboolean notif) { int n, p; int len = g_queue_get_length(&g_queue); g_debug("Switching to previous track."); if (g_shuffle) { /* Possible cases: g_repeat, g_current_track == -1, g_shuffle_first == -1 */ if (g_current_track == -1) { if (g_shuffle_first == -1) { /* Pick a random track */ n = g_random_int_range(0, len); /* Set the next one to be the first shuffle track... */ p = g_queue_index(&g_shuffle_queue, GINT_TO_POINTER(n)); if (p == -1) g_error("Can't find last track in shuffle queue"); p = (p+1) % len; g_shuffle_first = GPOINTER_TO_INT(g_queue_peek_nth(&g_shuffle_queue, p)); } else { /* Find the track that comes just before the first shuffle track */ p = g_queue_index(&g_shuffle_queue, GINT_TO_POINTER(g_shuffle_first)); if (p == -1) g_error("Can't find first track in shuffle queue"); p = (p-1) % len; n = GPOINTER_TO_INT(g_queue_peek_nth(&g_shuffle_queue, p)); } } else { if (g_shuffle_first == -1) { g_warning("g_shuffle_first == -1 in goto_prev()"); g_shuffle_first = g_current_track; } /* Is this the first track in non-repeat mode? */ if ((g_current_track == g_shuffle_first) && !g_repeat) { n = -1; } else { /* Find the index of the current track in the shuffle queue */ p = g_queue_index(&g_shuffle_queue, GINT_TO_POINTER(g_current_track)); if (p == -1) g_error("Can't find current track in shufflequeue"); /* Find the previous track in the shuffle queue */ p = (p+len-1) % len; n = GPOINTER_TO_INT(g_queue_peek_nth(&g_shuffle_queue, p)); } } } else { n = g_current_track - 1; if (g_repeat) n %= len; } queue_goto(FALSE, n, FALSE); if (notif) queue_notify(); }
/*************************** *** Move into the queue *** ***************************/ void queue_next(gboolean notif) { int n, p; int len = g_queue_get_length(&g_queue); g_debug("Switching to next track (current track: %d).", g_current_track); if (g_repeat && len == 1) { /* Easy case: replay the same track */ queue_seek(0); if (notif) queue_notify(); return; } if (g_shuffle) { /* Possible cases: g_repeat, g_current_track == -1, g_shuffle_first == -1 */ if (g_current_track == -1) { if (g_shuffle_first == -1) { /* Pick a random track */ n = g_random_int_range(0, len); g_shuffle_first = n; } else { n = g_shuffle_first; } } else { if (g_shuffle_first == -1) { g_warning("g_shuffle_first == -1 in goto_next()"); g_shuffle_first = g_current_track; } /* Find the index of the current track in the shuffle queue */ p = g_queue_index(&g_shuffle_queue, GINT_TO_POINTER(g_current_track)); if (p == -1) g_error("Can't find current track in shuffle queue"); /* Find the next track in the shuffle queue */ p = (p+1) % len; n = GPOINTER_TO_INT(g_queue_peek_nth(&g_shuffle_queue, p)); if ((n == g_shuffle_first) && !g_repeat) n = -1; } } else { n = g_current_track + 1; if (g_repeat) n %= len; } queue_goto(FALSE, n, FALSE); if (notif) queue_notify(); }
/* Restore state */ static gboolean really_restore_state(gpointer data) { saved_state* s = (saved_state*) data; sp_track* tr; /* Check if all tracks are loaded */ size_t i; for (i=0; i < s->tracks->len; i++) { tr = g_array_index(s->tracks, sp_track*, i); if (!sp_track_is_loaded(tr)) return TRUE; } /* All tracks are loaded: restore them */ g_debug("savestate: restoring saved state..."); queue_clear(FALSE); for (i=0; i < s->tracks->len; i++) { tr = g_array_index(s->tracks, sp_track*, i); if (track_available(tr)) queue_add_track(FALSE, tr); else { g_info("savestate: track %zu is no longer available", i); if (s->cur_track == i) { s->cur_track = -1; s->qs = STOPPED; } else if (s->cur_track > i) s->cur_track -= 1; } sp_track_release(tr); } queue_set_repeat(FALSE, s->repeat); queue_set_shuffle(FALSE, s->shuffle); if (s->cur_track >= 0) queue_goto(FALSE, s->cur_track, TRUE); if (s->qs == PLAYING) queue_play(FALSE); /* Done! */ queue_notify(); g_array_free(s->tracks, TRUE); g_free(s); g_debug("savestate: state restored!"); return FALSE; }