po: update Ukrainian translation
[ncmpc.git] / src / player_command.c
blob2455c83e58cdb74b5645730c0a91590c5c0e073b
1 /* ncmpc (Ncurses MPD Client)
2 * (c) 2004-2010 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.
20 #include "player_command.h"
21 #include "mpdclient.h"
22 #include "options.h"
23 #include "i18n.h"
24 #include "screen_client.h"
25 #include "screen_message.h"
27 int seek_id = -1;
28 int seek_target_time;
30 static guint seek_source_id;
32 static void
33 commit_seek(struct mpdclient *c)
35 struct mpd_connection *connection;
37 if (seek_id < 0)
38 return;
40 connection = mpdclient_get_connection(c);
41 if (connection == NULL) {
42 seek_id = -1;
43 return;
46 if (c->song != NULL && (unsigned)seek_id == mpd_song_get_id(c->song))
47 if (!mpd_run_seek_id(connection, seek_id, seek_target_time))
48 mpdclient_handle_error(c);
50 seek_id = -1;
53 /**
54 * This timer is invoked after seeking when the user hasn't typed a
55 * key for 500ms. It is used to do the real seeking.
57 static gboolean
58 seek_timer(gpointer data)
60 struct mpdclient *c = data;
62 seek_source_id = 0;
63 commit_seek(c);
64 mpdclient_put_connection(c);
65 return false;
68 static void
69 schedule_seek_timer(struct mpdclient *c)
71 assert(seek_source_id == 0);
73 seek_source_id = g_timeout_add(500, seek_timer, c);
76 void
77 cancel_seek_timer(void)
79 if (seek_source_id != 0) {
80 g_source_remove(seek_source_id);
81 seek_source_id = 0;
85 static bool
86 setup_seek(struct mpdclient *c)
88 if (!mpdclient_is_playing(c))
89 return false;
91 if (seek_id != (int)mpd_status_get_song_id(c->status)) {
92 seek_id = mpd_status_get_song_id(c->status);
93 seek_target_time = mpd_status_get_elapsed_time(c->status);
96 schedule_seek_timer(c);
98 return true;
101 bool
102 handle_player_command(struct mpdclient *c, command_t cmd)
104 struct mpd_connection *connection;
106 if (!mpdclient_is_connected(c) || c->status == NULL)
107 return false;
109 cancel_seek_timer();
111 switch(cmd) {
113 case CMD_PLAY:
114 mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
115 break;
117 case CMD_PAUSE:
118 connection = mpdclient_get_connection(c);
119 if (connection == NULL)
120 break;
122 if (!mpd_run_pause(connection,
123 mpd_status_get_state(c->status) != MPD_STATE_PAUSE))
124 mpdclient_handle_error(c);
125 break;
126 case CMD_STOP:
127 connection = mpdclient_get_connection(c);
128 if (connection == NULL)
129 break;
131 if (!mpd_run_stop(connection))
132 mpdclient_handle_error(c);
133 break;
134 case CMD_CROP:
135 mpdclient_cmd_crop(c);
136 break;
137 case CMD_SEEK_FORWARD:
138 if (!setup_seek(c))
139 break;
141 seek_target_time += options.seek_time;
142 if (seek_target_time > (int)mpd_status_get_total_time(c->status))
143 seek_target_time = mpd_status_get_total_time(c->status);
144 break;
146 case CMD_TRACK_NEXT:
147 connection = mpdclient_get_connection(c);
148 if (connection == NULL)
149 break;
151 if (!mpd_run_next(connection))
152 mpdclient_handle_error(c);
153 break;
154 case CMD_SEEK_BACKWARD:
155 if (!setup_seek(c))
156 break;
158 seek_target_time -= options.seek_time;
159 if (seek_target_time < 0)
160 seek_target_time = 0;
161 break;
163 case CMD_TRACK_PREVIOUS:
164 connection = mpdclient_get_connection(c);
165 if (connection == NULL)
166 break;
168 if (!mpd_run_previous(connection))
169 mpdclient_handle_error(c);
170 break;
171 case CMD_SHUFFLE:
172 connection = mpdclient_get_connection(c);
173 if (connection == NULL)
174 break;
176 if (mpd_run_shuffle(connection))
177 screen_status_message(_("Shuffled playlist"));
178 else
179 mpdclient_handle_error(c);
180 break;
181 case CMD_CLEAR:
182 connection = mpdclient_get_connection(c);
183 if (connection == NULL)
184 break;
186 if (mpdclient_cmd_clear(c))
187 screen_status_message(_("Cleared playlist"));
188 break;
189 case CMD_REPEAT:
190 connection = mpdclient_get_connection(c);
191 if (connection == NULL)
192 break;
194 if (!mpd_run_repeat(connection,
195 !mpd_status_get_repeat(c->status)))
196 mpdclient_handle_error(c);
197 break;
198 case CMD_RANDOM:
199 connection = mpdclient_get_connection(c);
200 if (connection == NULL)
201 break;
203 if (!mpd_run_random(connection,
204 !mpd_status_get_random(c->status)))
205 mpdclient_handle_error(c);
206 break;
207 case CMD_SINGLE:
208 connection = mpdclient_get_connection(c);
209 if (connection == NULL)
210 break;
212 if (!mpd_run_single(connection,
213 !mpd_status_get_single(c->status)))
214 mpdclient_handle_error(c);
215 break;
216 case CMD_CONSUME:
217 connection = mpdclient_get_connection(c);
218 if (connection == NULL)
219 break;
221 if (!mpd_run_consume(connection,
222 !mpd_status_get_consume(c->status)))
223 mpdclient_handle_error(c);
224 break;
225 case CMD_CROSSFADE:
226 connection = mpdclient_get_connection(c);
227 if (connection == NULL)
228 break;
230 if (!mpd_run_crossfade(connection,
231 mpd_status_get_crossfade(c->status) > 0
232 ? 0 : options.crossfade_time))
233 mpdclient_handle_error(c);
234 break;
235 case CMD_DB_UPDATE:
236 screen_database_update(c, NULL);
237 break;
238 case CMD_VOLUME_UP:
239 mpdclient_cmd_volume_up(c);
240 break;
241 case CMD_VOLUME_DOWN:
242 mpdclient_cmd_volume_down(c);
243 break;
245 default:
246 return false;
249 return true;