54664e58e9bdb8c6a5ccc78a7ec0f4f0a505d5ff
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 "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)
34 {
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;
44 }
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;
51 }
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.
56 */
57 static gboolean
58 seek_timer(gpointer data)
59 {
60 struct mpdclient *c = data;
62 seek_source_id = 0;
63 commit_seek(c);
64 mpdclient_put_connection(c);
65 return false;
66 }
68 static void
69 schedule_seek_timer(struct mpdclient *c)
70 {
71 assert(seek_source_id == 0);
73 seek_source_id = g_timeout_add(500, seek_timer, c);
74 }
76 void
77 cancel_seek_timer(void)
78 {
79 if (seek_source_id != 0) {
80 g_source_remove(seek_source_id);
81 seek_source_id = 0;
82 }
83 }
85 bool
86 handle_player_command(struct mpdclient *c, command_t cmd)
87 {
88 struct mpd_connection *connection;
89 const struct mpd_song *song;
91 if (!mpdclient_is_connected(c) || c->status == NULL)
92 return false;
94 cancel_seek_timer();
96 switch(cmd) {
97 /*
98 case CMD_PLAY:
99 mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
100 break;
101 */
102 case CMD_PAUSE:
103 connection = mpdclient_get_connection(c);
104 if (connection == NULL)
105 break;
107 if (!mpd_run_pause(connection,
108 mpd_status_get_state(c->status) != MPD_STATE_PAUSE))
109 mpdclient_handle_error(c);
110 break;
111 case CMD_STOP:
112 connection = mpdclient_get_connection(c);
113 if (connection == NULL)
114 break;
116 if (!mpd_run_stop(connection))
117 mpdclient_handle_error(c);
118 break;
119 case CMD_CROP:
120 mpdclient_cmd_crop(c);
121 break;
122 case CMD_SEEK_FORWARD:
123 song = mpdclient_get_current_song(c);
124 if (song != NULL) {
125 if (seek_id != (int)mpd_song_get_id(song)) {
126 seek_id = mpd_song_get_id(song);
127 seek_target_time = mpd_status_get_elapsed_time(c->status);
128 }
129 seek_target_time+=options.seek_time;
130 if (seek_target_time > (int)mpd_status_get_total_time(c->status))
131 seek_target_time = mpd_status_get_total_time(c->status);
132 schedule_seek_timer(c);
133 }
134 break;
135 case CMD_TRACK_NEXT:
136 connection = mpdclient_get_connection(c);
137 if (connection == NULL)
138 break;
140 if (!mpd_run_next(connection))
141 mpdclient_handle_error(c);
142 break;
143 case CMD_SEEK_BACKWARD:
144 song = mpdclient_get_current_song(c);
145 if (song != NULL) {
146 if (seek_id != (int)mpd_song_get_id(song)) {
147 seek_id = mpd_song_get_id(c->song);
148 seek_target_time = mpd_status_get_elapsed_time(c->status);
149 }
150 seek_target_time-=options.seek_time;
151 if (seek_target_time < 0)
152 seek_target_time=0;
153 schedule_seek_timer(c);
154 }
155 break;
156 case CMD_TRACK_PREVIOUS:
157 connection = mpdclient_get_connection(c);
158 if (connection == NULL)
159 break;
161 if (!mpd_run_previous(connection))
162 mpdclient_handle_error(c);
163 break;
164 case CMD_SHUFFLE:
165 connection = mpdclient_get_connection(c);
166 if (connection == NULL)
167 break;
169 if (mpd_run_shuffle(connection))
170 screen_status_message(_("Shuffled playlist"));
171 else
172 mpdclient_handle_error(c);
173 break;
174 case CMD_CLEAR:
175 connection = mpdclient_get_connection(c);
176 if (connection == NULL)
177 break;
179 if (mpdclient_cmd_clear(c))
180 screen_status_message(_("Cleared playlist"));
181 break;
182 case CMD_REPEAT:
183 connection = mpdclient_get_connection(c);
184 if (connection == NULL)
185 break;
187 if (!mpd_run_repeat(connection,
188 !mpd_status_get_repeat(c->status)))
189 mpdclient_handle_error(c);
190 break;
191 case CMD_RANDOM:
192 connection = mpdclient_get_connection(c);
193 if (connection == NULL)
194 break;
196 if (!mpd_run_random(connection,
197 !mpd_status_get_random(c->status)))
198 mpdclient_handle_error(c);
199 break;
200 case CMD_SINGLE:
201 connection = mpdclient_get_connection(c);
202 if (connection == NULL)
203 break;
205 if (!mpd_run_single(connection,
206 !mpd_status_get_single(c->status)))
207 mpdclient_handle_error(c);
208 break;
209 case CMD_CONSUME:
210 connection = mpdclient_get_connection(c);
211 if (connection == NULL)
212 break;
214 if (!mpd_run_consume(connection,
215 !mpd_status_get_consume(c->status)))
216 mpdclient_handle_error(c);
217 break;
218 case CMD_CROSSFADE:
219 connection = mpdclient_get_connection(c);
220 if (connection == NULL)
221 break;
223 if (!mpd_run_crossfade(connection,
224 mpd_status_get_crossfade(c->status) > 0
225 ? 0 : options.crossfade_time))
226 mpdclient_handle_error(c);
227 break;
228 case CMD_DB_UPDATE:
229 screen_database_update(c, NULL);
230 break;
231 case CMD_VOLUME_UP:
232 mpdclient_cmd_volume_up(c);
233 break;
234 case CMD_VOLUME_DOWN:
235 mpdclient_cmd_volume_down(c);
236 break;
238 default:
239 return false;
240 }
242 return true;
243 }