diff options
Diffstat (limited to 'src/playlist_state.c')
-rw-r--r-- | src/playlist_state.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/playlist_state.c b/src/playlist_state.c new file mode 100644 index 000000000..7541a353f --- /dev/null +++ b/src/playlist_state.c @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Saving and loading the playlist to/from the state file. + * + */ + +#include "playlist_state.h" +#include "playlist.h" +#include "player_control.h" +#include "queue_save.h" +#include "path.h" + +#include <string.h> +#include <stdlib.h> + +#define PLAYLIST_STATE_FILE_STATE "state: " +#define PLAYLIST_STATE_FILE_RANDOM "random: " +#define PLAYLIST_STATE_FILE_REPEAT "repeat: " +#define PLAYLIST_STATE_FILE_CURRENT "current: " +#define PLAYLIST_STATE_FILE_TIME "time: " +#define PLAYLIST_STATE_FILE_CROSSFADE "crossfade: " +#define PLAYLIST_STATE_FILE_PLAYLIST_BEGIN "playlist_begin" +#define PLAYLIST_STATE_FILE_PLAYLIST_END "playlist_end" + +#define PLAYLIST_STATE_FILE_STATE_PLAY "play" +#define PLAYLIST_STATE_FILE_STATE_PAUSE "pause" +#define PLAYLIST_STATE_FILE_STATE_STOP "stop" + +#define PLAYLIST_BUFFER_SIZE 2*MPD_PATH_MAX + +void +playlist_state_save(FILE *fp, const struct playlist *playlist) +{ + fprintf(fp, "%s", PLAYLIST_STATE_FILE_STATE); + + if (playlist->playing) { + switch (getPlayerState()) { + case PLAYER_STATE_PAUSE: + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_PAUSE); + break; + default: + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_PLAY); + } + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CURRENT, + queue_order_to_position(&playlist->queue, + playlist->current)); + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_TIME, + getPlayerElapsedTime()); + } else + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_STOP); + + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_RANDOM, + playlist->queue.random); + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_REPEAT, + playlist->queue.repeat); + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CROSSFADE, + (int)(getPlayerCrossFade())); + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN); + queue_save(fp, &playlist->queue); + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_END); +} + +static void +playlist_state_load(FILE *fp, struct playlist *playlist, + char *buffer, + int state, int current, int seek_time) +{ + int song; + + if (!fgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) { + g_warning("No playlist in state file"); + return; + } + + while (!g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_PLAYLIST_END)) { + g_strchomp(buffer); + + song = queue_load_song(&playlist->queue, buffer); + if (song >= 0 && song == current) { + if (state != PLAYER_STATE_STOP) { + playPlaylist(queue_length(&playlist->queue) - 1); + } + if (state == PLAYER_STATE_PAUSE) { + playerPause(); + } + if (state != PLAYER_STATE_STOP) { + seekSongInPlaylist(queue_length(&playlist->queue) - 1, + seek_time); + } + } + + if (!fgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) { + g_warning("'%s' not found in state file", + PLAYLIST_STATE_FILE_PLAYLIST_END); + break; + } + } +} + +void +playlist_state_restore(FILE *fp, struct playlist *playlist) +{ + int current = -1; + int seek_time = 0; + int state = PLAYER_STATE_STOP; + char buffer[PLAYLIST_BUFFER_SIZE]; + bool random_mode = false; + + while (fgets(buffer, sizeof(buffer), fp)) { + g_strchomp(buffer); + + if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_STATE)) { + if (strcmp(&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]), + PLAYLIST_STATE_FILE_STATE_PLAY) == 0) { + state = PLAYER_STATE_PLAY; + } else + if (strcmp + (&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]), + PLAYLIST_STATE_FILE_STATE_PAUSE) + == 0) { + state = PLAYER_STATE_PAUSE; + } + } else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_TIME)) { + seek_time = + atoi(&(buffer[strlen(PLAYLIST_STATE_FILE_TIME)])); + } else + if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_REPEAT)) { + if (strcmp + (&(buffer[strlen(PLAYLIST_STATE_FILE_REPEAT)]), + "1") == 0) { + setPlaylistRepeatStatus(true); + } else + setPlaylistRepeatStatus(false); + } else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_CROSSFADE)) { + setPlayerCrossFade(atoi + (& + (buffer + [strlen + (PLAYLIST_STATE_FILE_CROSSFADE)]))); + } else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_RANDOM)) { + random_mode = + strcmp(buffer + strlen(PLAYLIST_STATE_FILE_RANDOM), + "1") == 0; + } else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_CURRENT)) { + current = atoi(&(buffer + [strlen + (PLAYLIST_STATE_FILE_CURRENT)])); + } else if (g_str_has_prefix(buffer, + PLAYLIST_STATE_FILE_PLAYLIST_BEGIN)) { + if (state == PLAYER_STATE_STOP) + current = -1; + playlist_state_load(fp, playlist, buffer, state, + current, seek_time); + } + } + + setPlaylistRandomStatus(random_mode); +} |