X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fplayer_command.c;h=1a06bfabcb1b9b1bf465f883b9a02fd927bffba4;hb=HEAD;hp=29967957ab0e364db7284b49b26211cfa9131ba2;hpb=e9e1ac46382355c1eb77dde720d026f25e62a329;p=ncmpc.git diff --git a/src/player_command.c b/src/player_command.c index 2996795..1a06bfa 100644 --- a/src/player_command.c +++ b/src/player_command.c @@ -1,17 +1,17 @@ /* ncmpc (Ncurses MPD Client) - * (c) 2004-2009 The Music Player Daemon Project + * (c) 2004-2017 The Music Player Daemon Project * Project homepage: http://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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. @@ -20,103 +20,217 @@ #include "player_command.h" #include "mpdclient.h" #include "options.h" -#include "screen.h" #include "i18n.h" - -#define IS_PLAYING(s) (s==MPD_STATE_PLAY) -#define IS_PAUSED(s) (s==MPD_STATE_PAUSE) -#define IS_STOPPED(s) (!(IS_PLAYING(s) | IS_PAUSED(s))) +#include "screen_client.h" +#include "screen_status.h" int seek_id = -1; -int seek_target_time = 0; +int seek_target_time; + +static guint seek_source_id; + +static void +commit_seek(struct mpdclient *c) +{ + if (seek_id < 0) + return; + + struct mpd_connection *connection = mpdclient_get_connection(c); + if (connection == NULL) { + seek_id = -1; + return; + } + + if (c->song != NULL && (unsigned)seek_id == mpd_song_get_id(c->song)) + if (!mpd_run_seek_id(connection, seek_id, seek_target_time)) + mpdclient_handle_error(c); + + seek_id = -1; +} + +/** + * This timer is invoked after seeking when the user hasn't typed a + * key for 500ms. It is used to do the real seeking. + */ +static gboolean +seek_timer(gpointer data) +{ + struct mpdclient *c = data; + + seek_source_id = 0; + commit_seek(c); + return false; +} -int +static void +schedule_seek_timer(struct mpdclient *c) +{ + assert(seek_source_id == 0); + + seek_source_id = g_timeout_add(500, seek_timer, c); +} + +void +cancel_seek_timer(void) +{ + if (seek_source_id != 0) { + g_source_remove(seek_source_id); + seek_source_id = 0; + } +} + +static bool +setup_seek(struct mpdclient *c) +{ + if (!mpdclient_is_playing(c)) + return false; + + if (seek_id != (int)mpd_status_get_song_id(c->status)) { + seek_id = mpd_status_get_song_id(c->status); + seek_target_time = mpd_status_get_elapsed_time(c->status); + } + + schedule_seek_timer(c); + + return true; +} + +bool handle_player_command(struct mpdclient *c, command_t cmd) { - if (c->connection == NULL || c->status == NULL) - return 0; + if (!mpdclient_is_connected(c) || c->status == NULL) + return false; + + cancel_seek_timer(); switch(cmd) { + struct mpd_connection *connection; + /* case CMD_PLAY: mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING); break; */ case CMD_PAUSE: - mpdclient_cmd_pause(c, !IS_PAUSED(mpd_status_get_state(c->status))); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (!mpd_run_pause(connection, + mpd_status_get_state(c->status) != MPD_STATE_PAUSE)) + mpdclient_handle_error(c); break; case CMD_STOP: - mpdclient_cmd_stop(c); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (!mpd_run_stop(connection)) + mpdclient_handle_error(c); break; case CMD_CROP: mpdclient_cmd_crop(c); break; case CMD_SEEK_FORWARD: - if (!IS_STOPPED(mpd_status_get_state(c->status))) { - if (c->song != NULL && - seek_id != (int)mpd_song_get_id(c->song)) { - seek_id = mpd_song_get_id(c->song); - seek_target_time = mpd_status_get_elapsed_time(c->status); - } - seek_target_time+=options.seek_time; - if (seek_target_time < (int)mpd_status_get_total_time(c->status)) - break; + if (!setup_seek(c)) + break; + + seek_target_time += options.seek_time; + if (seek_target_time > (int)mpd_status_get_total_time(c->status)) seek_target_time = mpd_status_get_total_time(c->status); - /* seek_target_time=0; */ - } break; - /* fall through... */ + case CMD_TRACK_NEXT: - if (!IS_STOPPED(mpd_status_get_state(c->status))) - mpdclient_cmd_next(c); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (!mpd_run_next(connection)) + mpdclient_handle_error(c); break; case CMD_SEEK_BACKWARD: - if (!IS_STOPPED(mpd_status_get_state(c->status))) { - if (seek_id != (int)mpd_song_get_id(c->song)) { - seek_id = mpd_song_get_id(c->song); - seek_target_time = mpd_status_get_elapsed_time(c->status); - } - seek_target_time-=options.seek_time; - if (seek_target_time < 0) - seek_target_time=0; - } + if (!setup_seek(c)) + break; + + seek_target_time -= options.seek_time; + if (seek_target_time < 0) + seek_target_time = 0; break; + case CMD_TRACK_PREVIOUS: - if (!IS_STOPPED(mpd_status_get_state(c->status))) - mpdclient_cmd_prev(c); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (!mpd_run_previous(connection)) + mpdclient_handle_error(c); break; case CMD_SHUFFLE: - if (mpdclient_cmd_shuffle(c) == 0) - screen_status_message(_("Shuffled playlist")); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (mpd_run_shuffle(connection)) + screen_status_message(_("Shuffled queue")); + else + mpdclient_handle_error(c); break; case CMD_CLEAR: - if (mpdclient_cmd_clear(c) == 0) - screen_status_message(_("Cleared playlist")); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (mpdclient_cmd_clear(c)) + screen_status_message(_("Cleared queue")); break; case CMD_REPEAT: - mpdclient_cmd_repeat(c, !mpd_status_get_repeat(c->status)); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (!mpd_run_repeat(connection, + !mpd_status_get_repeat(c->status))) + mpdclient_handle_error(c); break; case CMD_RANDOM: - mpdclient_cmd_random(c, !mpd_status_get_random(c->status)); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (!mpd_run_random(connection, + !mpd_status_get_random(c->status))) + mpdclient_handle_error(c); break; case CMD_SINGLE: - mpdclient_cmd_single(c, !mpd_status_get_single(c->status)); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (!mpd_run_single(connection, + !mpd_status_get_single(c->status))) + mpdclient_handle_error(c); break; case CMD_CONSUME: - mpdclient_cmd_consume(c, !mpd_status_get_consume(c->status)); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (!mpd_run_consume(connection, + !mpd_status_get_consume(c->status))) + mpdclient_handle_error(c); break; case CMD_CROSSFADE: - if (mpd_status_get_crossfade(c->status)) - mpdclient_cmd_crossfade(c, 0); - else - mpdclient_cmd_crossfade(c, options.crossfade_time); + connection = mpdclient_get_connection(c); + if (connection == NULL) + break; + + if (!mpd_run_crossfade(connection, + mpd_status_get_crossfade(c->status) > 0 + ? 0 : options.crossfade_time)) + mpdclient_handle_error(c); break; case CMD_DB_UPDATE: - if (!mpd_status_get_update_id(c->status)) { - if( mpdclient_cmd_db_update(c,NULL)==0 ) - screen_status_printf(_("Database update started")); - } else - screen_status_printf(_("Database update running...")); + screen_database_update(c, NULL); break; case CMD_VOLUME_UP: mpdclient_cmd_volume_up(c); @@ -126,8 +240,8 @@ handle_player_command(struct mpdclient *c, command_t cmd) break; default: - return 0; + return false; } - return 1; + return true; }