1 /* libmpdclient
2 (c) 2003-2019 The Music Player Daemon Project
3 This project's homepage is: http://www.musicpd.org
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <mpd/player.h>
30 #include <mpd/send.h>
31 #include <mpd/song.h>
32 #include <mpd/response.h>
33 #include "isend.h"
34 #include "run.h"
35
36 #include <limits.h>
37 #include <stdio.h>
38
39 bool
mpd_send_current_song(struct mpd_connection * connection)40 mpd_send_current_song(struct mpd_connection *connection)
41 {
42 return mpd_send_command(connection, "currentsong", NULL);
43 }
44
45 struct mpd_song *
mpd_run_current_song(struct mpd_connection * connection)46 mpd_run_current_song(struct mpd_connection *connection)
47 {
48 struct mpd_song *song;
49
50 if (!mpd_run_check(connection) || !mpd_send_current_song(connection))
51 return NULL;
52
53 song = mpd_recv_song(connection);
54 if (song == NULL)
55 return NULL;
56
57 if (!mpd_response_finish(connection)) {
58 mpd_song_free(song);
59 return NULL;
60 }
61
62 return song;
63 }
64
65 bool
mpd_send_play(struct mpd_connection * connection)66 mpd_send_play(struct mpd_connection *connection)
67 {
68 return mpd_send_command(connection, "play", NULL);
69 }
70
71 bool
mpd_run_play(struct mpd_connection * connection)72 mpd_run_play(struct mpd_connection *connection)
73 {
74 return mpd_run_check(connection) && mpd_send_play(connection) &&
75 mpd_response_finish(connection);
76 }
77
78 bool
mpd_send_play_pos(struct mpd_connection * connection,unsigned song_pos)79 mpd_send_play_pos(struct mpd_connection *connection, unsigned song_pos)
80 {
81 return mpd_send_int_command(connection, "play", song_pos);
82 }
83
84 bool
mpd_run_play_pos(struct mpd_connection * connection,unsigned song_pos)85 mpd_run_play_pos(struct mpd_connection *connection, unsigned song_pos)
86 {
87 return mpd_run_check(connection) &&
88 mpd_send_play_pos(connection, song_pos) &&
89 mpd_response_finish(connection);
90 }
91
92 bool
mpd_send_play_id(struct mpd_connection * connection,unsigned song_id)93 mpd_send_play_id(struct mpd_connection *connection, unsigned song_id)
94 {
95 return mpd_send_int_command(connection, "playid", song_id);
96 }
97
98 bool
mpd_run_play_id(struct mpd_connection * connection,unsigned song_id)99 mpd_run_play_id(struct mpd_connection *connection, unsigned song_id)
100 {
101 return mpd_run_check(connection) &&
102 mpd_send_play_id(connection, song_id) &&
103 mpd_response_finish(connection);
104 }
105
106 bool
mpd_send_stop(struct mpd_connection * connection)107 mpd_send_stop(struct mpd_connection *connection)
108 {
109 return mpd_send_command(connection, "stop", NULL);
110 }
111
112 bool
mpd_run_stop(struct mpd_connection * connection)113 mpd_run_stop(struct mpd_connection *connection)
114 {
115 return mpd_run_check(connection) && mpd_send_stop(connection) &&
116 mpd_response_finish(connection);
117 }
118
119 bool
mpd_send_toggle_pause(struct mpd_connection * connection)120 mpd_send_toggle_pause(struct mpd_connection *connection)
121 {
122 return mpd_send_command(connection, "pause", NULL);
123 }
124
125 bool
mpd_run_toggle_pause(struct mpd_connection * connection)126 mpd_run_toggle_pause(struct mpd_connection *connection)
127 {
128 return mpd_run_check(connection) &&
129 mpd_send_toggle_pause(connection) &&
130 mpd_response_finish(connection);
131 }
132
133 bool
mpd_send_pause(struct mpd_connection * connection,bool mode)134 mpd_send_pause(struct mpd_connection *connection, bool mode)
135 {
136 return mpd_send_int_command(connection, "pause", mode);
137 }
138
139 bool
mpd_run_pause(struct mpd_connection * connection,bool mode)140 mpd_run_pause(struct mpd_connection *connection, bool mode)
141 {
142 return mpd_run_check(connection) && mpd_send_pause(connection, mode) &&
143 mpd_response_finish(connection);
144 }
145
146 bool
mpd_send_next(struct mpd_connection * connection)147 mpd_send_next(struct mpd_connection *connection)
148 {
149 return mpd_send_command(connection, "next", NULL);
150 }
151
152 bool
mpd_run_next(struct mpd_connection * connection)153 mpd_run_next(struct mpd_connection *connection)
154 {
155 return mpd_run_check(connection) && mpd_send_next(connection) &&
156 mpd_response_finish(connection);
157 }
158
159 bool
mpd_send_previous(struct mpd_connection * connection)160 mpd_send_previous(struct mpd_connection *connection)
161 {
162 return mpd_send_command(connection, "previous", NULL);
163 }
164
165 bool
mpd_run_previous(struct mpd_connection * connection)166 mpd_run_previous(struct mpd_connection *connection)
167 {
168 return mpd_run_check(connection) && mpd_send_previous(connection) &&
169 mpd_response_finish(connection);
170 }
171
172 bool
mpd_send_seek_pos(struct mpd_connection * connection,unsigned song_pos,unsigned t)173 mpd_send_seek_pos(struct mpd_connection *connection,
174 unsigned song_pos, unsigned t)
175 {
176 return mpd_send_int2_command(connection, "seek", song_pos, t);
177 }
178
179 bool
mpd_run_seek_pos(struct mpd_connection * connection,unsigned song_pos,unsigned t)180 mpd_run_seek_pos(struct mpd_connection *connection,
181 unsigned song_pos, unsigned t)
182 {
183 return mpd_run_check(connection) &&
184 mpd_send_seek_pos(connection, song_pos, t) &&
185 mpd_response_finish(connection);
186 }
187
188 bool
mpd_send_seek_id(struct mpd_connection * connection,unsigned song_id,unsigned t)189 mpd_send_seek_id(struct mpd_connection *connection,
190 unsigned song_id, unsigned t)
191 {
192 return mpd_send_int2_command(connection, "seekid", song_id, t);
193 }
194
195 bool
mpd_run_seek_id(struct mpd_connection * connection,unsigned song_id,unsigned t)196 mpd_run_seek_id(struct mpd_connection *connection,
197 unsigned song_id, unsigned t)
198 {
199 return mpd_run_check(connection) &&
200 mpd_send_seek_id(connection, song_id, t) &&
201 mpd_response_finish(connection);
202 }
203
204 bool
mpd_send_seek_id_float(struct mpd_connection * connection,unsigned song_id,float t)205 mpd_send_seek_id_float(struct mpd_connection *connection,
206 unsigned song_id, float t)
207 {
208 return mpd_send_u_f_command(connection, "seekid", song_id, t);
209 }
210
211 bool
mpd_run_seek_id_float(struct mpd_connection * connection,unsigned song_id,float t)212 mpd_run_seek_id_float(struct mpd_connection *connection,
213 unsigned song_id, float t)
214 {
215 return mpd_run_check(connection) &&
216 mpd_send_seek_id_float(connection, song_id, t) &&
217 mpd_response_finish(connection);
218 }
219
220 bool
mpd_send_seek_current(struct mpd_connection * connection,float t,bool relative)221 mpd_send_seek_current(struct mpd_connection *connection,
222 float t, bool relative)
223 {
224 char ts[32];
225 if (relative)
226 snprintf(ts, sizeof(ts), "%+.3f", t);
227 else
228 snprintf(ts, sizeof(ts), "%.3f", t);
229
230 return mpd_send_command(connection, "seekcur", ts, NULL);
231 }
232
233 bool
mpd_run_seek_current(struct mpd_connection * connection,float t,bool relative)234 mpd_run_seek_current(struct mpd_connection *connection,
235 float t, bool relative)
236 {
237 return mpd_run_check(connection) &&
238 mpd_send_seek_current(connection, t, relative) &&
239 mpd_response_finish(connection);
240 }
241
242 bool
mpd_send_repeat(struct mpd_connection * connection,bool mode)243 mpd_send_repeat(struct mpd_connection *connection, bool mode)
244 {
245 return mpd_send_int_command(connection, "repeat", mode);
246 }
247
248 bool
mpd_run_repeat(struct mpd_connection * connection,bool mode)249 mpd_run_repeat(struct mpd_connection *connection, bool mode)
250 {
251 return mpd_run_check(connection) &&
252 mpd_send_repeat(connection, mode) &&
253 mpd_response_finish(connection);
254 }
255
256 bool
mpd_send_random(struct mpd_connection * connection,bool mode)257 mpd_send_random(struct mpd_connection *connection, bool mode)
258 {
259 return mpd_send_int_command(connection, "random", mode);
260 }
261
262 bool
mpd_run_random(struct mpd_connection * connection,bool mode)263 mpd_run_random(struct mpd_connection *connection, bool mode)
264 {
265 return mpd_run_check(connection) &&
266 mpd_send_random(connection, mode) &&
267 mpd_response_finish(connection);
268 }
269
270 static const char *
single_state_to_string(enum mpd_single_state state)271 single_state_to_string(enum mpd_single_state state)
272 {
273 switch (state) {
274 case MPD_SINGLE_OFF:
275 return "0";
276 case MPD_SINGLE_ON:
277 return "1";
278 case MPD_SINGLE_ONESHOT:
279 return "oneshot";
280 case MPD_SINGLE_UNKNOWN:
281 return NULL;
282 }
283 return NULL;
284 }
285 bool
mpd_send_single_state(struct mpd_connection * connection,enum mpd_single_state state)286 mpd_send_single_state(struct mpd_connection *connection,
287 enum mpd_single_state state)
288 {
289 const char *state_str = single_state_to_string(state);
290 if (state_str == NULL)
291 return false;
292
293 return mpd_send_command(connection, "single", state_str, NULL);
294 }
295
296 bool
mpd_run_single_state(struct mpd_connection * connection,enum mpd_single_state state)297 mpd_run_single_state(struct mpd_connection *connection,
298 enum mpd_single_state state)
299 {
300 return mpd_run_check(connection) &&
301 mpd_send_single_state(connection, state) &&
302 mpd_response_finish(connection);
303 }
304
305 bool
mpd_send_single(struct mpd_connection * connection,bool mode)306 mpd_send_single(struct mpd_connection *connection, bool mode)
307 {
308 return mpd_send_int_command(connection, "single", mode);
309 }
310
311 bool
mpd_run_single(struct mpd_connection * connection,bool mode)312 mpd_run_single(struct mpd_connection *connection, bool mode)
313 {
314 return mpd_run_check(connection) &&
315 mpd_send_single(connection, mode) &&
316 mpd_response_finish(connection);
317 }
318
319 bool
mpd_send_consume(struct mpd_connection * connection,bool mode)320 mpd_send_consume(struct mpd_connection *connection, bool mode)
321 {
322 return mpd_send_int_command(connection, "consume", mode);
323 }
324
325 bool
mpd_run_consume(struct mpd_connection * connection,bool mode)326 mpd_run_consume(struct mpd_connection *connection, bool mode)
327 {
328 return mpd_run_check(connection) &&
329 mpd_send_consume(connection, mode) &&
330 mpd_response_finish(connection);
331 }
332
333 bool
mpd_send_crossfade(struct mpd_connection * connection,unsigned seconds)334 mpd_send_crossfade(struct mpd_connection *connection, unsigned seconds)
335 {
336 return mpd_send_int_command(connection, "crossfade", seconds);
337 }
338
339 bool
mpd_run_crossfade(struct mpd_connection * connection,unsigned seconds)340 mpd_run_crossfade(struct mpd_connection *connection, unsigned seconds)
341 {
342 return mpd_run_check(connection) &&
343 mpd_send_crossfade(connection, seconds) &&
344 mpd_response_finish(connection);
345 }
346
347 bool
mpd_send_mixrampdb(struct mpd_connection * connection,float db)348 mpd_send_mixrampdb(struct mpd_connection *connection, float db)
349 {
350 return mpd_send_float_command(connection, "mixrampdb", db);
351 }
352
353 bool
mpd_run_mixrampdb(struct mpd_connection * connection,float db)354 mpd_run_mixrampdb(struct mpd_connection *connection, float db)
355 {
356 return mpd_run_check(connection) &&
357 mpd_send_mixrampdb(connection, db) &&
358 mpd_response_finish(connection);
359 }
360
361 bool
mpd_send_mixrampdelay(struct mpd_connection * connection,float seconds)362 mpd_send_mixrampdelay(struct mpd_connection *connection, float seconds)
363 {
364 return mpd_send_float_command(connection, "mixrampdelay", seconds);
365 }
366
367 bool
mpd_run_mixrampdelay(struct mpd_connection * connection,float seconds)368 mpd_run_mixrampdelay(struct mpd_connection *connection, float seconds)
369 {
370 return mpd_run_check(connection) &&
371 mpd_send_mixrampdelay(connection, seconds) &&
372 mpd_response_finish(connection);
373 }
374
375 bool
mpd_send_clearerror(struct mpd_connection * connection)376 mpd_send_clearerror(struct mpd_connection *connection)
377 {
378 return mpd_send_command(connection, "clearerror", NULL);
379 }
380
381 bool
mpd_run_clearerror(struct mpd_connection * connection)382 mpd_run_clearerror(struct mpd_connection *connection)
383 {
384 return mpd_run_check(connection) && mpd_send_clearerror(connection) &&
385 mpd_response_finish(connection);
386 }
387