Code

mpdclient: added function mpdclient_get_current_song()
[ncmpc.git] / src / player_command.c
1 /* ncmpc (Ncurses MPD Client)
2  * (c) 2004-2009 The Music Player Daemon Project
3  * Project homepage: http://musicpd.org
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
20 #include "player_command.h"
21 #include "mpdclient.h"
22 #include "options.h"
23 #include "screen.h"
24 #include "i18n.h"
25 #include "screen_client.h"
27 #define IS_PAUSED(s) (s==MPD_STATE_PAUSE)
29 int seek_id = -1;
30 int seek_target_time;
32 static guint seek_source_id;
34 static void
35 commit_seek(struct mpdclient *c)
36 {
37         if (seek_id < 0)
38                 return;
40         if (c->song != NULL && (unsigned)seek_id == mpd_song_get_id(c->song))
41                 if (!mpd_run_seek_id(c->connection, seek_id, seek_target_time))
42                         mpdclient_handle_error(c);
44         seek_id = -1;
45 }
47 /**
48  * This timer is invoked after seeking when the user hasn't typed a
49  * key for 500ms.  It is used to do the real seeking.
50  */
51 static gboolean
52 seek_timer(gpointer data)
53 {
54         struct mpdclient *c = data;
56         seek_source_id = 0;
57         commit_seek(c);
58         return false;
59 }
61 static void
62 schedule_seek_timer(struct mpdclient *c)
63 {
64         assert(seek_source_id == 0);
66         seek_source_id = g_timeout_add(500, seek_timer, c);
67 }
69 void
70 cancel_seek_timer(void)
71 {
72         if (seek_source_id != 0) {
73                 g_source_remove(seek_source_id);
74                 seek_source_id = 0;
75         }
76 }
78 bool
79 handle_player_command(struct mpdclient *c, command_t cmd)
80 {
81         const struct mpd_song *song;
83         if (c->connection == NULL || c->status == NULL)
84                 return false;
86         cancel_seek_timer();
88         switch(cmd) {
89                 /*
90         case CMD_PLAY:
91                 mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
92                 break;
93                 */
94         case CMD_PAUSE:
95                 if (!mpd_run_pause(c->connection,
96                                    !IS_PAUSED(mpd_status_get_state(c->status))))
97                         mpdclient_handle_error(c);
98                 break;
99         case CMD_STOP:
100                 if (!mpd_run_stop(c->connection))
101                         mpdclient_handle_error(c);
102                 break;
103         case CMD_CROP:
104                 mpdclient_cmd_crop(c);
105                 break;
106         case CMD_SEEK_FORWARD:
107                 song = mpdclient_get_current_song(c);
108                 if (song != NULL) {
109                         if (seek_id != (int)mpd_song_get_id(song)) {
110                                 seek_id = mpd_song_get_id(song);
111                                 seek_target_time = mpd_status_get_elapsed_time(c->status);
112                         }
113                         seek_target_time+=options.seek_time;
114                         if (seek_target_time > (int)mpd_status_get_total_time(c->status))
115                                 seek_target_time = mpd_status_get_total_time(c->status);
116                         schedule_seek_timer(c);
117                 }
118                 break;
119                 /* fall through... */
120         case CMD_TRACK_NEXT:
121                 if (!mpd_run_next(c->connection))
122                         mpdclient_handle_error(c);
123                 break;
124         case CMD_SEEK_BACKWARD:
125                 song = mpdclient_get_current_song(c);
126                 if (song != NULL) {
127                         if (seek_id != (int)mpd_song_get_id(song)) {
128                                 seek_id = mpd_song_get_id(c->song);
129                                 seek_target_time = mpd_status_get_elapsed_time(c->status);
130                         }
131                         seek_target_time-=options.seek_time;
132                         if (seek_target_time < 0)
133                                 seek_target_time=0;
134                         schedule_seek_timer(c);
135                 }
136                 break;
137         case CMD_TRACK_PREVIOUS:
138                 if (!mpd_run_previous(c->connection))
139                         mpdclient_handle_error(c);
140                 break;
141         case CMD_SHUFFLE:
142                 if (mpd_run_shuffle(c->connection))
143                         screen_status_message(_("Shuffled playlist"));
144                 else
145                         mpdclient_handle_error(c);
146                 break;
147         case CMD_CLEAR:
148                 if (mpdclient_cmd_clear(c) == 0)
149                         screen_status_message(_("Cleared playlist"));
150                 break;
151         case CMD_REPEAT:
152                 if (!mpd_run_repeat(c->connection,
153                                     !mpd_status_get_repeat(c->status)))
154                         mpdclient_handle_error(c);
155                 break;
156         case CMD_RANDOM:
157                 if (!mpd_run_random(c->connection,
158                                     !mpd_status_get_random(c->status)))
159                         mpdclient_handle_error(c);
160                 break;
161         case CMD_SINGLE:
162                 if (!mpd_run_single(c->connection,
163                                     !mpd_status_get_single(c->status)))
164                         mpdclient_handle_error(c);
165                 break;
166         case CMD_CONSUME:
167                 if (!mpd_run_consume(c->connection,
168                                      !mpd_status_get_consume(c->status)))
169                         mpdclient_handle_error(c);
170                 break;
171         case CMD_CROSSFADE:
172                 if (!mpd_run_crossfade(c->connection,
173                                        mpd_status_get_crossfade(c->status) > 0
174                                        ? 0 : options.crossfade_time))
175                         mpdclient_handle_error(c);
176                 break;
177         case CMD_DB_UPDATE:
178                 screen_database_update(c, NULL);
179                 break;
180         case CMD_VOLUME_UP:
181                 mpdclient_cmd_volume_up(c);
182                 break;
183         case CMD_VOLUME_DOWN:
184                 mpdclient_cmd_volume_down(c);
185                 break;
187         default:
188                 return false;
189         }
191         return true;