1 /*
2 * Copyright (C) 2005 Marc Pavot <marc.pavot@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19
20 #include "servers/ario-server.h"
21 #include <gtk/gtk.h>
22 #include <config.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <limits.h>
27 #include <glib/gi18n.h>
28 #include "lib/ario-conf.h"
29 #include "servers/ario-mpd.h"
30 #include "ario-util.h"
31 #ifdef ENABLE_XMMS2
32 #include "servers/ario-xmms.h"
33 #endif
34 #include "preferences/ario-preferences.h"
35 #include "ario-debug.h"
36 #include "ario-profiles.h"
37
38 #define NORMAL_TIMEOUT 500
39 #define LAZY_TIMEOUT 12000
40
41 static guint ario_server_signals[SERVER_LAST_SIGNAL] = { 0 };
42
43 char * ArioServerItemNames[ARIO_TAG_COUNT] =
44 {
45 N_("Artist"), // ARIO_TAG_ARTIST
46 N_("Album"), // ARIO_TAG_ALBUM
47 N_("Album Artist"), // ARIO_TAG_ALBUM_ARTIST
48 N_("Title"), // ARIO_TAG_TITLE
49 N_("Track"), // ARIO_TAG_TRACK
50 NULL, // ARIO_TAG_NAME
51 N_("Genre"), // ARIO_TAG_GENRE
52 N_("Date"), // ARIO_TAG_DATE
53 N_("Composer"), // ARIO_TAG_COMPOSER
54 N_("Performer"), // ARIO_TAG_PERFORMER
55 NULL, // ARIO_TAG_COMMENT
56 NULL, // ARIO_TAG_DISC
57 N_("Filename"), // ARIO_TAG_FILENAME
58 N_("Any") // ARIO_TAG_ANY
59 };
60
61 G_DEFINE_TYPE (ArioServer, ario_server, G_TYPE_OBJECT)
62
63 static ArioServer *instance = NULL;
64 static ArioServerInterface *interface = NULL;
65
66 static void
ario_server_class_init(ArioServerClass * klass)67 ario_server_class_init (ArioServerClass *klass)
68 {
69 ARIO_LOG_FUNCTION_START;
70 GObjectClass *object_class = G_OBJECT_CLASS (klass);
71
72 /* Object Signals */
73 ario_server_signals[SERVER_SONG_CHANGED] =
74 g_signal_new ("song_changed",
75 G_OBJECT_CLASS_TYPE (object_class),
76 G_SIGNAL_RUN_LAST,
77 G_STRUCT_OFFSET (ArioServerClass, song_changed),
78 NULL, NULL,
79 g_cclosure_marshal_VOID__VOID,
80 G_TYPE_NONE,
81 0);
82
83 ario_server_signals[SERVER_ALBUM_CHANGED] =
84 g_signal_new ("album_changed",
85 G_OBJECT_CLASS_TYPE (object_class),
86 G_SIGNAL_RUN_LAST,
87 G_STRUCT_OFFSET (ArioServerClass, album_changed),
88 NULL, NULL,
89 g_cclosure_marshal_VOID__VOID,
90 G_TYPE_NONE,
91 0);
92
93 ario_server_signals[SERVER_CONNECTIVITY_CHANGED] =
94 g_signal_new ("connectivity_changed",
95 G_OBJECT_CLASS_TYPE (object_class),
96 G_SIGNAL_RUN_LAST,
97 G_STRUCT_OFFSET (ArioServerClass, connectivity_changed),
98 NULL, NULL,
99 g_cclosure_marshal_VOID__VOID,
100 G_TYPE_NONE,
101 0);
102
103 ario_server_signals[SERVER_STATE_CHANGED] =
104 g_signal_new ("state_changed",
105 G_OBJECT_CLASS_TYPE (object_class),
106 G_SIGNAL_RUN_LAST,
107 G_STRUCT_OFFSET (ArioServerClass, state_changed),
108 NULL, NULL,
109 g_cclosure_marshal_VOID__VOID,
110 G_TYPE_NONE,
111 0);
112
113 ario_server_signals[SERVER_VOLUME_CHANGED] =
114 g_signal_new ("volume_changed",
115 G_OBJECT_CLASS_TYPE (object_class),
116 G_SIGNAL_RUN_LAST,
117 G_STRUCT_OFFSET (ArioServerClass, volume_changed),
118 NULL, NULL,
119 g_cclosure_marshal_VOID__INT,
120 G_TYPE_NONE,
121 1,
122 G_TYPE_INT);
123
124 ario_server_signals[SERVER_ELAPSED_CHANGED] =
125 g_signal_new ("elapsed_changed",
126 G_OBJECT_CLASS_TYPE (object_class),
127 G_SIGNAL_RUN_LAST,
128 G_STRUCT_OFFSET (ArioServerClass, elapsed_changed),
129 NULL, NULL,
130 g_cclosure_marshal_VOID__INT,
131 G_TYPE_NONE,
132 1,
133 G_TYPE_INT);
134
135 ario_server_signals[SERVER_PLAYLIST_CHANGED] =
136 g_signal_new ("playlist_changed",
137 G_OBJECT_CLASS_TYPE (object_class),
138 G_SIGNAL_RUN_LAST,
139 G_STRUCT_OFFSET (ArioServerClass, playlist_changed),
140 NULL, NULL,
141 g_cclosure_marshal_VOID__VOID,
142 G_TYPE_NONE,
143 0);
144
145 ario_server_signals[SERVER_CONSUME_CHANGED] =
146 g_signal_new ("consume_changed",
147 G_OBJECT_CLASS_TYPE (object_class),
148 G_SIGNAL_RUN_LAST,
149 G_STRUCT_OFFSET (ArioServerClass, consume_changed),
150 NULL, NULL,
151 g_cclosure_marshal_VOID__VOID,
152 G_TYPE_NONE,
153 0);
154
155 ario_server_signals[SERVER_RANDOM_CHANGED] =
156 g_signal_new ("random_changed",
157 G_OBJECT_CLASS_TYPE (object_class),
158 G_SIGNAL_RUN_LAST,
159 G_STRUCT_OFFSET (ArioServerClass, random_changed),
160 NULL, NULL,
161 g_cclosure_marshal_VOID__VOID,
162 G_TYPE_NONE,
163 0);
164
165 ario_server_signals[SERVER_REPEAT_CHANGED] =
166 g_signal_new ("repeat_changed",
167 G_OBJECT_CLASS_TYPE (object_class),
168 G_SIGNAL_RUN_LAST,
169 G_STRUCT_OFFSET (ArioServerClass, repeat_changed),
170 NULL, NULL,
171 g_cclosure_marshal_VOID__VOID,
172 G_TYPE_NONE,
173 0);
174
175 ario_server_signals[SERVER_UPDATINGDB_CHANGED] =
176 g_signal_new ("updatingdb_changed",
177 G_OBJECT_CLASS_TYPE (object_class),
178 G_SIGNAL_RUN_LAST,
179 G_STRUCT_OFFSET (ArioServerClass, updatingdb_changed),
180 NULL, NULL,
181 g_cclosure_marshal_VOID__VOID,
182 G_TYPE_NONE,
183 0);
184
185 ario_server_signals[SERVER_STOREDPLAYLISTS_CHANGED] =
186 g_signal_new ("storedplaylists_changed",
187 G_OBJECT_CLASS_TYPE (object_class),
188 G_SIGNAL_RUN_LAST,
189 G_STRUCT_OFFSET (ArioServerClass, storedplaylists_changed),
190 NULL, NULL,
191 g_cclosure_marshal_VOID__VOID,
192 G_TYPE_NONE,
193 0);
194 }
195
196 static void
ario_server_init(ArioServer * server)197 ario_server_init (ArioServer *server)
198 {
199 ARIO_LOG_FUNCTION_START;
200 }
201
202 static void
ario_server_reset_interface(void)203 ario_server_reset_interface (void)
204 {
205 ARIO_LOG_FUNCTION_START;
206 static ArioServerType interface_type = -1;
207 ArioServerType new_interface_type;
208
209 /* Get new interface type */
210 new_interface_type = ario_profiles_get_current (ario_profiles_get ())->type;
211
212 /* Same type as before: do nothing */
213 if (new_interface_type == interface_type)
214 return;
215
216 /* Change type */
217 interface_type = new_interface_type;
218
219 /* destroy previous insterface */
220 if (interface) {
221 ario_server_disconnect ();
222 g_object_unref (interface);
223 }
224
225 /* Create new interface */
226 if (interface_type == ArioServerMpd) {
227 /* MPD interface */
228 interface = ARIO_SERVER_INTERFACE (ario_mpd_get_instance (instance));
229 #ifdef ENABLE_XMMS2
230 } else if (interface_type == ArioServerXmms) {
231 /* XMMS2 interface */
232 interface = ARIO_SERVER_INTERFACE (ario_xmms_get_instance (instance));
233 #endif
234 } else {
235 /* Unknown interface */
236 ARIO_LOG_ERROR ("Unknown server type: %d", interface_type);
237 interface = ARIO_SERVER_INTERFACE (ario_mpd_get_instance (instance));
238 }
239 }
240
241 ArioServer *
ario_server_get_instance(void)242 ario_server_get_instance (void)
243 {
244 ARIO_LOG_FUNCTION_START;
245 /* Singleton instanciation if needed */
246 if (!instance) {
247 instance = g_object_new (ARIO_TYPE_SERVER, NULL);
248 }
249 if (!interface) {
250 ario_server_reset_interface ();
251 }
252
253 return instance;
254 }
255
256 gboolean
ario_server_connect(void)257 ario_server_connect (void)
258 {
259 ARIO_LOG_FUNCTION_START;
260
261 /* Make sure we have the right interface type */
262 ario_server_reset_interface ();
263
264 /* check if there is a connection */
265 if (ario_server_is_connected () || interface->connecting)
266 return FALSE;
267
268 interface->connecting = TRUE;
269
270 /* Call virtual method */
271 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->connect ();
272 g_signal_emit (G_OBJECT (instance), ario_server_signals[SERVER_CONNECTIVITY_CHANGED], 0);
273 return FALSE;
274 }
275
276 void
ario_server_disconnect(void)277 ario_server_disconnect (void)
278 {
279 ARIO_LOG_FUNCTION_START;
280 /* Call virtual method */
281 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->disconnect ();
282 g_signal_emit (G_OBJECT (instance), ario_server_signals[SERVER_CONNECTIVITY_CHANGED], 0);
283 }
284
285 void
ario_server_reconnect(void)286 ario_server_reconnect (void)
287 {
288 ARIO_LOG_FUNCTION_START;
289 ario_server_disconnect ();
290 ario_server_connect ();
291 }
292
293 void
ario_server_shutdown(void)294 ario_server_shutdown (void)
295 {
296 ARIO_LOG_FUNCTION_START;
297 g_object_unref (interface);
298 }
299
300 void
ario_server_update_db(const gchar * path)301 ario_server_update_db (const gchar *path)
302 {
303 ARIO_LOG_FUNCTION_START;
304 interface->updatingdb = 1;
305 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->update_db (path);
306 }
307
308 gboolean
ario_server_is_connected(void)309 ario_server_is_connected (void)
310 {
311 // desactivated to make the logs more readable
312 //ARIO_LOG_FUNCTION_START;
313
314 /* Call virtual method */
315 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->is_connected ();
316 }
317
318 GSList *
ario_server_list_tags(const ArioServerTag tag,const ArioServerCriteria * criteria)319 ario_server_list_tags (const ArioServerTag tag,
320 const ArioServerCriteria *criteria)
321 {
322 ARIO_LOG_FUNCTION_START;
323 /* Call virtual method */
324 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->list_tags (tag, criteria);
325 }
326
327 GSList *
ario_server_get_albums(const ArioServerCriteria * criteria)328 ario_server_get_albums (const ArioServerCriteria *criteria)
329 {
330 ARIO_LOG_FUNCTION_START;
331 /* Call virtual method */
332 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_albums (criteria);
333 }
334
335 GSList *
ario_server_get_songs(const ArioServerCriteria * criteria,const gboolean exact)336 ario_server_get_songs (const ArioServerCriteria *criteria,
337 const gboolean exact)
338 {
339 ARIO_LOG_FUNCTION_START;
340 /* Call virtual method */
341 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_songs (criteria, exact);
342 }
343
344 GSList *
ario_server_get_songs_from_playlist(char * playlist)345 ario_server_get_songs_from_playlist (char *playlist)
346 {
347 ARIO_LOG_FUNCTION_START;
348 /* Call virtual method */
349 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_songs_from_playlist (playlist);
350 }
351
352 GSList *
ario_server_get_playlists(void)353 ario_server_get_playlists (void)
354 {
355 ARIO_LOG_FUNCTION_START;
356 /* Call virtual method */
357 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_playlists ();
358 }
359
360 GSList *
ario_server_get_playlist_changes(gint64 playlist_id)361 ario_server_get_playlist_changes (gint64 playlist_id)
362 {
363 ARIO_LOG_FUNCTION_START;
364 /* Call virtual method */
365 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_playlist_changes (playlist_id);
366 }
367
368 gboolean
ario_server_update_status(void)369 ario_server_update_status (void)
370 {
371 /* Call virtual method */
372 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->update_status ();
373 }
374
375 ArioServerSong *
ario_server_get_current_song_on_server(void)376 ario_server_get_current_song_on_server (void)
377 {
378 ARIO_LOG_FUNCTION_START;
379 /* Call virtual method */
380 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_current_song_on_server ();
381 }
382
383 ArioServerSong *
ario_server_get_current_song(void)384 ario_server_get_current_song (void)
385 {
386 ARIO_LOG_FUNCTION_START;
387 if (interface->server_song)
388 return interface->server_song;
389 else
390 return NULL;
391 }
392
393 char *
ario_server_get_current_artist(void)394 ario_server_get_current_artist (void)
395 {
396 ARIO_LOG_FUNCTION_START;
397 if (interface->server_song)
398 return interface->server_song->artist;
399 else
400 return NULL;
401 }
402
403 char *
ario_server_get_current_album(void)404 ario_server_get_current_album (void)
405 {
406 ARIO_LOG_FUNCTION_START;
407 if (interface->server_song)
408 return interface->server_song->album;
409 else
410 return NULL;
411 }
412
413 char *
ario_server_get_current_song_path(void)414 ario_server_get_current_song_path (void)
415 {
416 ARIO_LOG_FUNCTION_START;
417 if (interface->server_song)
418 return interface->server_song->file;
419 else
420 return NULL;
421 }
422
423 int
ario_server_get_current_song_id(void)424 ario_server_get_current_song_id (void)
425 {
426 ARIO_LOG_FUNCTION_START;
427 return interface->song_id;
428 }
429
430 int
ario_server_get_current_state(void)431 ario_server_get_current_state (void)
432 {
433 ARIO_LOG_FUNCTION_START;
434 return interface->state;
435 }
436
437 int
ario_server_get_current_elapsed(void)438 ario_server_get_current_elapsed (void)
439 {
440 ARIO_LOG_FUNCTION_START;
441 return interface->elapsed;
442 }
443
444 int
ario_server_get_current_volume(void)445 ario_server_get_current_volume (void)
446 {
447 ARIO_LOG_FUNCTION_START;
448 return interface->volume;
449 }
450
451 int
ario_server_get_current_total_time(void)452 ario_server_get_current_total_time (void)
453 {
454 ARIO_LOG_FUNCTION_START;
455 if (interface->server_song)
456 return interface->server_song->time;
457 else
458 return 0;
459 }
460
461 gint64
ario_server_get_current_playlist_id(void)462 ario_server_get_current_playlist_id (void)
463 {
464 ARIO_LOG_FUNCTION_START;
465 return interface->playlist_id;
466 }
467
468 int
ario_server_get_current_playlist_length(void)469 ario_server_get_current_playlist_length (void)
470 {
471 ARIO_LOG_FUNCTION_START;
472 return interface->playlist_length;
473 }
474
475 int
ario_server_get_current_playlist_total_time(void)476 ario_server_get_current_playlist_total_time (void)
477 {
478 ARIO_LOG_FUNCTION_START;
479 /* Call virtual method */
480 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_current_playlist_total_time ();
481 }
482
483 int
ario_server_get_crossfadetime(void)484 ario_server_get_crossfadetime (void)
485 {
486 ARIO_LOG_FUNCTION_START;
487 if (ario_server_is_connected ())
488 return interface->crossfade;
489 else
490 return 0;
491 }
492
493 gboolean
ario_server_get_current_consume(void)494 ario_server_get_current_consume (void)
495 {
496 ARIO_LOG_FUNCTION_START;
497 return interface->consume;
498 }
499
500 gboolean
ario_server_get_current_random(void)501 ario_server_get_current_random (void)
502 {
503 ARIO_LOG_FUNCTION_START;
504 return interface->random;
505 }
506
507 gboolean
ario_server_get_current_repeat(void)508 ario_server_get_current_repeat (void)
509 {
510 ARIO_LOG_FUNCTION_START;
511 return interface->repeat;
512 }
513
514 gboolean
ario_server_get_updating(void)515 ario_server_get_updating (void)
516 {
517 ARIO_LOG_FUNCTION_START;
518 return ario_server_is_connected () && interface->updatingdb;
519 }
520
521 unsigned long
ario_server_get_last_update(void)522 ario_server_get_last_update (void)
523 {
524 /* Call virtual method */
525 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_last_update ();
526 }
527
528 gboolean
ario_server_is_paused(void)529 ario_server_is_paused (void)
530 {
531 ARIO_LOG_FUNCTION_START;
532 return (interface->state == ARIO_STATE_PAUSE) || (interface->state == ARIO_STATE_STOP);
533 }
534
535 void
ario_server_do_next(void)536 ario_server_do_next (void)
537 {
538 ARIO_LOG_FUNCTION_START;
539 /* Call virtual method */
540 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->do_next ();
541 }
542
543 void
ario_server_do_prev(void)544 ario_server_do_prev (void)
545 {
546 ARIO_LOG_FUNCTION_START;
547 /* Call virtual method */
548 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->do_prev ();
549 }
550
551 void
ario_server_do_play(void)552 ario_server_do_play (void)
553 {
554 ARIO_LOG_FUNCTION_START;
555 /* Call virtual method */
556 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->do_play ();
557 }
558
559 void
ario_server_do_play_pos(gint id)560 ario_server_do_play_pos (gint id)
561 {
562 ARIO_LOG_FUNCTION_START;
563 /* Call virtual method */
564 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->do_play_pos (id);
565 }
566
567 void
ario_server_do_pause(void)568 ario_server_do_pause (void)
569 {
570 ARIO_LOG_FUNCTION_START;
571 /* Call virtual method */
572 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->do_pause ();
573 }
574
575 void
ario_server_do_stop(void)576 ario_server_do_stop (void)
577 {
578 ARIO_LOG_FUNCTION_START;
579 /* Call virtual method */
580 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->do_stop ();
581 }
582
583 void
ario_server_free_album(ArioServerAlbum * server_album)584 ario_server_free_album (ArioServerAlbum *server_album)
585 {
586 ARIO_LOG_FUNCTION_START;
587 if (server_album) {
588 g_free (server_album->album);
589 g_free (server_album->artist);
590 g_free (server_album->path);
591 g_free (server_album->date);
592 g_free (server_album);
593 }
594 }
595
596 ArioServerAlbum*
ario_server_copy_album(const ArioServerAlbum * server_album)597 ario_server_copy_album (const ArioServerAlbum *server_album)
598 {
599 ARIO_LOG_FUNCTION_START;
600 ArioServerAlbum *ret = NULL;
601
602 if (server_album) {
603 ret = (ArioServerAlbum *) g_malloc (sizeof (ArioServerAlbum));
604 ret->album = g_strdup (server_album->album);
605 ret->artist = g_strdup (server_album->artist);
606 ret->path = g_strdup (server_album->path);
607 ret->date = g_strdup (server_album->date);
608 }
609
610 return ret;
611 }
612
613 void
ario_server_set_current_elapsed(const gint elapsed)614 ario_server_set_current_elapsed (const gint elapsed)
615 {
616 ARIO_LOG_FUNCTION_START;
617 /* Call virtual method */
618 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->set_current_elapsed (elapsed);
619 }
620
621 void
ario_server_set_current_volume(const gint volume)622 ario_server_set_current_volume (const gint volume)
623 {
624 ARIO_LOG_FUNCTION_START;
625 /* Call virtual method */
626 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->set_current_volume (volume);
627 }
628
629 void
ario_server_set_current_consume(const gboolean consume)630 ario_server_set_current_consume (const gboolean consume)
631 {
632 ARIO_LOG_FUNCTION_START;
633 /* Call virtual method */
634 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->set_current_consume (consume);
635 }
636
637 void
ario_server_set_current_random(const gboolean random)638 ario_server_set_current_random (const gboolean random)
639 {
640 ARIO_LOG_FUNCTION_START;
641 /* Call virtual method */
642 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->set_current_random (random);
643 }
644
645 void
ario_server_set_current_repeat(const gboolean repeat)646 ario_server_set_current_repeat (const gboolean repeat)
647 {
648 ARIO_LOG_FUNCTION_START;
649 /* Call virtual method */
650 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->set_current_repeat (repeat);
651 }
652
653 void
ario_server_set_crossfadetime(const int crossfadetime)654 ario_server_set_crossfadetime (const int crossfadetime)
655 {
656 ARIO_LOG_FUNCTION_START;
657 /* Call virtual method */
658 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->set_crossfadetime (crossfadetime);
659 }
660
661 void
ario_server_clear(void)662 ario_server_clear (void)
663 {
664 ARIO_LOG_FUNCTION_START;
665 /* Call virtual method */
666 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->clear ();
667 }
668
669 void
ario_server_shuffle(void)670 ario_server_shuffle (void)
671 {
672 ARIO_LOG_FUNCTION_START;
673 /* Call virtual method */
674 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->shuffle ();
675 }
676
677 void
ario_server_queue_add(const char * path)678 ario_server_queue_add (const char *path)
679 {
680 ARIO_LOG_FUNCTION_START;
681
682 /* Append a queue action to list */
683 ArioServerQueueAction *queue_action = (ArioServerQueueAction *) g_malloc (sizeof (ArioServerQueueAction));
684 queue_action->type = ARIO_SERVER_ACTION_ADD;
685 queue_action->path = path;
686
687 interface->queue = g_slist_append (interface->queue, queue_action);
688 }
689
690 void
ario_server_queue_delete_id(const int id)691 ario_server_queue_delete_id (const int id)
692 {
693 /* Append a queue action to list */
694 ArioServerQueueAction *queue_action = (ArioServerQueueAction *) g_malloc (sizeof (ArioServerQueueAction));
695 queue_action->type = ARIO_SERVER_ACTION_DELETE_ID;
696 queue_action->id = id;
697
698 interface->queue = g_slist_append (interface->queue, queue_action);
699 }
700
701 void
ario_server_queue_delete_pos(const int pos)702 ario_server_queue_delete_pos (const int pos)
703 {
704 ARIO_LOG_FUNCTION_START;
705 /* Append a queue action to list */
706 ArioServerQueueAction *queue_action = (ArioServerQueueAction *) g_malloc (sizeof (ArioServerQueueAction));
707 queue_action->type = ARIO_SERVER_ACTION_DELETE_POS;
708 queue_action->pos = pos;
709
710 interface->queue = g_slist_append (interface->queue, queue_action);
711 }
712
713 void
ario_server_queue_move(const int old_pos,const int new_pos)714 ario_server_queue_move (const int old_pos,
715 const int new_pos)
716 {
717 ARIO_LOG_FUNCTION_START;
718 /* Append a queue action to list */
719 ArioServerQueueAction *queue_action = (ArioServerQueueAction *) g_malloc (sizeof (ArioServerQueueAction));
720 queue_action->type = ARIO_SERVER_ACTION_MOVE;
721 queue_action->old_pos = old_pos;
722 queue_action->new_pos = new_pos;
723
724 interface->queue = g_slist_append (interface->queue, queue_action);
725 }
726
727 void
ario_server_queue_moveid(const int id,const int pos)728 ario_server_queue_moveid (const int id,
729 const int pos)
730 {
731 ARIO_LOG_FUNCTION_START;
732 /* Append a queue action to list */
733 ArioServerQueueAction *queue_action = (ArioServerQueueAction *) g_malloc (sizeof (ArioServerQueueAction));
734 queue_action->type = ARIO_SERVER_ACTION_MOVEID;
735 queue_action->old_pos = id;
736 queue_action->new_pos = pos;
737
738 interface->queue = g_slist_append (interface->queue, queue_action);
739 }
740
741 void
ario_server_queue_commit(void)742 ario_server_queue_commit (void)
743 {
744 ARIO_LOG_FUNCTION_START;
745 /* Call virtual method */
746 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->queue_commit ();
747 }
748
749 void
ario_server_insert_at(const GSList * songs,const gint pos)750 ario_server_insert_at (const GSList *songs,
751 const gint pos)
752 {
753 ARIO_LOG_FUNCTION_START;
754 /* Call virtual method */
755 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->insert_at (songs, pos);
756 }
757
758 int
ario_server_save_playlist(const char * name)759 ario_server_save_playlist (const char *name)
760 {
761 ARIO_LOG_FUNCTION_START;
762 /* Call virtual method */
763 int ret = ARIO_SERVER_INTERFACE_GET_CLASS (interface)->save_playlist (name);
764
765 #ifndef ENABLE_MPDIDLE
766 g_signal_emit (G_OBJECT (instance), ario_server_signals[SERVER_STOREDPLAYLISTS_CHANGED], 0);
767 #endif
768
769 return ret;
770 }
771
772 void
ario_server_delete_playlist(const char * name)773 ario_server_delete_playlist (const char *name)
774 {
775 ARIO_LOG_FUNCTION_START;
776 /* Call virtual method */
777 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->delete_playlist (name);
778
779 #ifndef ENABLE_MPDIDLE
780 g_signal_emit (G_OBJECT (instance), ario_server_signals[SERVER_STOREDPLAYLISTS_CHANGED], 0);
781 #endif
782 }
783
784 GSList *
ario_server_get_outputs(void)785 ario_server_get_outputs (void)
786 {
787 ARIO_LOG_FUNCTION_START;
788 /* Call virtual method */
789 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_outputs ();
790 }
791
792 void
ario_server_enable_output(int id,gboolean enabled)793 ario_server_enable_output (int id,
794 gboolean enabled)
795 {
796 ARIO_LOG_FUNCTION_START;
797 /* Call virtual method */
798 ARIO_SERVER_INTERFACE_GET_CLASS (interface)->enable_output (id, enabled);
799 }
800
801 ArioServerStats *
ario_server_get_stats(void)802 ario_server_get_stats (void)
803 {
804 ARIO_LOG_FUNCTION_START;
805 /* Call virtual method */
806 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_stats ();
807 }
808
809 GList *
ario_server_get_songs_info(GSList * paths)810 ario_server_get_songs_info (GSList *paths)
811 {
812 ARIO_LOG_FUNCTION_START;
813 /* Call virtual method */
814 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->get_songs_info (paths);
815 }
816
817 ArioServerFileList *
ario_server_list_files(const char * path,gboolean recursive)818 ario_server_list_files (const char *path,
819 gboolean recursive)
820 {
821 ARIO_LOG_FUNCTION_START;
822 /* Call virtual method */
823 return ARIO_SERVER_INTERFACE_GET_CLASS (interface)->list_files (path, recursive);
824 }
825
826 void
ario_server_free_file_list(ArioServerFileList * files)827 ario_server_free_file_list (ArioServerFileList *files)
828 {
829 ARIO_LOG_FUNCTION_START;
830 if (files) {
831 g_slist_foreach (files->directories, (GFunc) g_free, NULL);
832 g_slist_free (files->directories);
833 g_slist_foreach (files->songs, (GFunc) ario_server_free_song, NULL);
834 g_slist_free (files->songs);
835 g_free (files);
836 }
837 }
838
839 void
ario_server_criteria_free(ArioServerCriteria * criteria)840 ario_server_criteria_free (ArioServerCriteria *criteria)
841 {
842 ARIO_LOG_FUNCTION_START;
843 GSList *tmp;
844 ArioServerAtomicCriteria *atomic_criteria;
845
846 for (tmp = criteria; tmp; tmp = g_slist_next (tmp)) {
847 atomic_criteria = tmp->data;
848 g_free (atomic_criteria->value);
849 g_free (atomic_criteria);
850 }
851 g_slist_free (criteria);
852 }
853
854 ArioServerCriteria *
ario_server_criteria_copy(const ArioServerCriteria * criteria)855 ario_server_criteria_copy (const ArioServerCriteria *criteria)
856 {
857 ARIO_LOG_FUNCTION_START;
858 ArioServerCriteria *ret = NULL;
859 const GSList *tmp;
860 ArioServerAtomicCriteria *atomic_criteria;
861 ArioServerAtomicCriteria *new_atomic_criteria;
862
863 for (tmp = criteria; tmp; tmp = g_slist_next (tmp)) {
864 atomic_criteria = tmp->data;
865 if (criteria) {
866 new_atomic_criteria = (ArioServerAtomicCriteria *) g_malloc0 (sizeof (ArioServerAtomicCriteria));
867 new_atomic_criteria->tag = atomic_criteria->tag;
868 new_atomic_criteria->value = g_strdup (atomic_criteria->value);
869 ret = g_slist_append (ret, new_atomic_criteria);
870 }
871 }
872 return ret;
873 }
874
875 gchar **
ario_server_get_items_names(void)876 ario_server_get_items_names (void)
877 {
878 return ArioServerItemNames;
879 }
880
881 const gchar*
ario_server_song_get_tag(const ArioServerSong * song,ArioServerTag tag)882 ario_server_song_get_tag (const ArioServerSong *song,
883 ArioServerTag tag)
884 {
885 ARIO_LOG_FUNCTION_START;
886 switch (tag) {
887 case ARIO_TAG_ARTIST: return song->artist;
888 case ARIO_TAG_ALBUM: return song->album;
889 case ARIO_TAG_ALBUM_ARTIST: return song->album_artist;
890 case ARIO_TAG_TITLE: return song->title;
891 case ARIO_TAG_TRACK: return song->track;
892 case ARIO_TAG_NAME: return song->name;
893 case ARIO_TAG_GENRE: return song->genre;
894 case ARIO_TAG_DATE: return song->date;
895 case ARIO_TAG_COMPOSER: return song->composer;
896 case ARIO_TAG_PERFORMER: return song->performer;
897 case ARIO_TAG_COMMENT: return song->comment;
898 case ARIO_TAG_DISC: return song->disc;
899 case ARIO_TAG_FILENAME: return song->file;
900 default: return NULL;
901 }
902 }
903
904 void
ario_server_playlist_add_songs(const GSList * songs,const gint pos,const PlaylistAction action)905 ario_server_playlist_add_songs (const GSList *songs,
906 const gint pos,
907 const PlaylistAction action)
908 {
909 ARIO_LOG_FUNCTION_START;
910 const GSList *tmp;
911 int end;
912 int song_pos = pos;
913
914 /* Clear playlist if needed */
915 if (action == PLAYLIST_REPLACE) {
916 ario_server_clear ();
917 }
918
919 /* Get current song position */
920 if (action == PLAYLIST_ADD_AFTER_PLAYING
921 && (interface->state == ARIO_STATE_PLAY
922 || interface->state == ARIO_STATE_PAUSE)) {
923 song_pos = ario_server_get_current_song()->pos;
924 }
925
926 end = ario_server_get_current_playlist_length ();
927
928 if (song_pos >= 0) {
929 /* Insert songs at a given position */
930 ario_server_insert_at (songs, song_pos);
931 } else {
932 /* For each filename :*/
933 for (tmp = songs; tmp; tmp = g_slist_next (tmp)) {
934 /* Add it in the playlist*/
935 ario_server_queue_add (tmp->data);
936 }
937 /* Commit song additions */
938 ario_server_queue_commit ();
939 }
940
941 /* Start playing if needed */
942 if (action == PLAYLIST_ADD_PLAY || action == PLAYLIST_REPLACE) {
943 ario_server_do_play_pos (end);
944 }
945 }
946
947 void
ario_server_playlist_add_dir(const gchar * dir,const gint pos,const PlaylistAction action)948 ario_server_playlist_add_dir (const gchar *dir,
949 const gint pos,
950 const PlaylistAction action)
951 {
952 ARIO_LOG_FUNCTION_START;
953 GSList *tmp;
954 ArioServerFileList *files;
955 ArioServerSong *song;
956 GSList *char_songs = NULL;
957
958 /* List files in dir */
959 files = ario_server_list_files (dir, TRUE);
960
961 /* For each file */
962 for (tmp = files->songs; tmp; tmp = g_slist_next (tmp)) {
963 song = tmp->data;
964 /* Append file to list */
965 char_songs = g_slist_append (char_songs, song->file);
966 }
967
968 /* Append all files to playlist */
969 ario_server_playlist_add_songs (char_songs, pos, action);
970 g_slist_free (char_songs);
971 ario_server_free_file_list (files);
972 }
973
974 void
ario_server_playlist_add_criterias(const GSList * criterias,const gint pos,const PlaylistAction action,const gint nb_entries)975 ario_server_playlist_add_criterias (const GSList *criterias,
976 const gint pos,
977 const PlaylistAction action,
978 const gint nb_entries)
979 {
980 ARIO_LOG_FUNCTION_START;
981 GSList *filenames = NULL, *tmp_filenames = NULL, *songs = NULL;
982 const GSList *tmp_criteria, *tmp_songs;
983 const ArioServerCriteria *criteria;
984 ArioServerSong *server_song;
985
986 /* For each criteria :*/
987 for (tmp_criteria = criterias; tmp_criteria; tmp_criteria = g_slist_next (tmp_criteria)) {
988 criteria = tmp_criteria->data;
989 songs = ario_server_get_songs (criteria, TRUE);
990
991 /* For each song */
992 for (tmp_songs = songs; tmp_songs; tmp_songs = g_slist_next (tmp_songs)) {
993 /* Append song filename to list */
994 server_song = tmp_songs->data;
995 filenames = g_slist_append (filenames, server_song->file);
996 server_song->file = NULL;
997 }
998
999 g_slist_foreach (songs, (GFunc) ario_server_free_song, NULL);
1000 g_slist_free (songs);
1001 }
1002
1003 /* Need to only add a limited number of songs */
1004 if (nb_entries > 0 && filenames) {
1005 /* Randomly get some songs in list */
1006 tmp_filenames = ario_util_gslist_randomize (&filenames, nb_entries);
1007 g_slist_foreach (filenames, (GFunc) g_free, NULL);
1008 g_slist_free (filenames);
1009
1010 filenames = tmp_filenames;
1011 }
1012
1013 /* Add songs to playlist */
1014 ario_server_playlist_add_songs (filenames,
1015 pos,
1016 action);
1017
1018 g_slist_foreach (filenames, (GFunc) g_free, NULL);
1019 g_slist_free (filenames);
1020 }
1021
1022 void
ario_server_playlist_append_songs(const GSList * songs,const PlaylistAction action)1023 ario_server_playlist_append_songs (const GSList *songs,
1024 const PlaylistAction action)
1025 {
1026 ARIO_LOG_FUNCTION_START;
1027 /* Add songs to playlist */
1028 ario_server_playlist_add_songs (songs, -1, action);
1029 }
1030
1031 void
ario_server_playlist_append_server_songs(const GSList * songs,const PlaylistAction action)1032 ario_server_playlist_append_server_songs (const GSList *songs,
1033 const PlaylistAction action)
1034 {
1035 ARIO_LOG_FUNCTION_START;
1036 const GSList *tmp;
1037 GSList *char_songs = NULL;
1038 ArioServerSong *song;
1039
1040 /* For each song */
1041 for (tmp = songs; tmp; tmp = g_slist_next (tmp)) {
1042 /* Append song filename to list */
1043 song = tmp->data;
1044 char_songs = g_slist_append (char_songs, song->file);
1045 }
1046
1047 /* Add songs to playlist */
1048 ario_server_playlist_add_songs (char_songs, -1, action);
1049 g_slist_free (char_songs);
1050 }
1051
1052 void
ario_server_playlist_append_artists(const GSList * artists,const PlaylistAction action,const gint nb_entries)1053 ario_server_playlist_append_artists (const GSList *artists,
1054 const PlaylistAction action,
1055 const gint nb_entries)
1056 {
1057 ARIO_LOG_FUNCTION_START;
1058 ArioServerAtomicCriteria *atomic_criteria;
1059 ArioServerCriteria *criteria;
1060 GSList *criterias = NULL;
1061 const GSList *tmp;
1062
1063 /* For each artist */
1064 for (tmp = artists; tmp; tmp = g_slist_next (tmp)) {
1065 /* Create a criteria corresponding to artist */
1066 criteria = NULL;
1067 atomic_criteria = (ArioServerAtomicCriteria *) g_malloc0 (sizeof (ArioServerAtomicCriteria));
1068 atomic_criteria->tag = ARIO_TAG_ARTIST;
1069 atomic_criteria->value = g_strdup (tmp->data);
1070
1071 criteria = g_slist_append (criteria, atomic_criteria);
1072 criterias = g_slist_append (criterias, criteria);
1073 }
1074
1075 /* Add songs matching criteria to playlist */
1076 ario_server_playlist_append_criterias (criterias, action, nb_entries);
1077
1078 g_slist_foreach (criterias, (GFunc) ario_server_criteria_free, NULL);
1079 g_slist_free (criterias);
1080 }
1081
1082 void
ario_server_playlist_append_dir(const gchar * dir,const PlaylistAction action)1083 ario_server_playlist_append_dir (const gchar *dir,
1084 const PlaylistAction action)
1085 {
1086 ARIO_LOG_FUNCTION_START;
1087 /* Append all files in dir to playlist */
1088 ario_server_playlist_add_dir (dir, -1, action);
1089 }
1090
1091 void
ario_server_playlist_append_criterias(const GSList * criterias,const PlaylistAction action,const gint nb_entries)1092 ario_server_playlist_append_criterias (const GSList *criterias,
1093 const PlaylistAction action,
1094 const gint nb_entries)
1095 {
1096 ARIO_LOG_FUNCTION_START;
1097 /* Append all songs matching criteria to playlist */
1098 ario_server_playlist_add_criterias (criterias, -1, action, nb_entries);
1099 }
1100
1101 void
ario_server_free_song(ArioServerSong * song)1102 ario_server_free_song (ArioServerSong *song)
1103 {
1104 ARIO_LOG_FUNCTION_START;
1105 if (song) {
1106 g_free (song->file);
1107 g_free (song->artist);
1108 g_free (song->title);
1109 g_free (song->album);
1110 g_free (song->album_artist);
1111 g_free (song->track);
1112 g_free (song->name);
1113 g_free (song->date);
1114 g_free (song->genre);
1115 g_free (song->composer);
1116 g_free (song->performer);
1117 g_free (song->disc);
1118 g_free (song->comment);
1119 g_free (song);
1120 }
1121 }
1122
1123 void
ario_server_free_output(ArioServerOutput * output)1124 ario_server_free_output (ArioServerOutput *output)
1125 {
1126 ARIO_LOG_FUNCTION_START;
1127 if (output) {
1128 g_free (output->name);
1129 g_free (output);
1130 }
1131 }
1132
1133