60 static void xmms_playlist_client_move (
xmms_playlist_t *playlist,
const gchar *plname, gint32 pos, gint32 newpos,
xmms_error_t *err);
64 static void xmms_playlist_client_insert_url (
xmms_playlist_t *playlist,
const gchar *plname, gint32 pos,
const gchar *url,
xmms_error_t *error);
68 static void xmms_playlist_client_rinsert (
xmms_playlist_t *playlist,
const gchar *plname, gint32 pos,
const gchar *path,
xmms_error_t *error);
73 static const gchar *xmms_playlist_canonical_name (
xmms_playlist_t *playlist,
const gchar *plname);
74 static gint xmms_playlist_coll_get_currpos (
xmmsv_coll_t *plcoll);
75 static gint xmms_playlist_coll_get_size (
xmmsv_coll_t *plcoll);
80 static void xmms_playlist_current_pos_msg_send (
xmms_playlist_t *playlist, GTree *dict);
81 static GTree * xmms_playlist_current_pos_msg_new (
xmms_playlist_t *playlist, guint32 pos,
const gchar *plname);
104 #define XMMS_PLAYLIST_CHANGED_MSG(type, id, name) xmms_playlist_changed_msg_send (playlist, xmms_playlist_changed_msg_new (playlist, type, id, name))
105 #define XMMS_PLAYLIST_CURRPOS_MSG(pos, name) xmms_playlist_current_pos_msg_send (playlist, xmms_playlist_current_pos_msg_new (playlist, pos, name))
118 struct xmms_playlist_St {
131 gboolean update_flag;
145 g_mutex_lock (playlist->mutex);
146 playlist->repeat_all = !!value;
147 g_mutex_unlock (playlist->mutex);
159 g_mutex_lock (playlist->mutex);
160 playlist->repeat_one = !!value;
161 g_mutex_unlock (playlist->mutex);
166 on_playlist_updated (
xmms_object_t *
object,
const gchar *plname)
172 if (playlist->update_flag) {
176 plcoll = xmms_playlist_get_coll (playlist, plname, NULL);
177 if (plcoll == NULL) {
183 xmms_playlist_update_queue (playlist, plname, plcoll);
187 xmms_playlist_update_partyshuffle (playlist, plname, plcoll);
199 XMMS_DBG (
"PLAYLIST: updated pos!");
206 const gchar *plname = NULL;
209 XMMS_DBG (
"PLAYLIST: updated chg!");
212 if (pl_val != NULL) {
216 XMMS_DBG (
"PLAYLIST: updated_chg, NULL playlist!");
217 g_assert_not_reached ();
220 on_playlist_updated (
object, plname);
224 xmms_playlist_update_queue (
xmms_playlist_t *playlist,
const gchar *plname,
227 gint history, currpos;
229 XMMS_DBG (
"PLAYLIST: update-queue!");
235 playlist->update_flag = TRUE;
236 currpos = xmms_playlist_coll_get_currpos (coll);
237 while (currpos > history) {
238 xmms_playlist_remove_unlocked (playlist, plname, coll, 0, NULL);
239 currpos = xmms_playlist_coll_get_currpos (coll);
241 playlist->update_flag = FALSE;
248 gint history, upcoming, currpos, size;
252 XMMS_DBG (
"PLAYLIST: update-partyshuffle!");
262 playlist->update_flag = TRUE;
263 currpos = xmms_playlist_coll_get_currpos (coll);
264 while (currpos > history) {
265 xmms_playlist_remove_unlocked (playlist, plname, coll, 0, NULL);
266 currpos = xmms_playlist_coll_get_currpos (coll);
270 XMMS_DBG (
"Cannot find party shuffle operand!");
275 currpos = xmms_playlist_coll_get_currpos (coll);
276 size = xmms_playlist_coll_get_size (coll);
277 while (size < currpos + 1 + upcoming) {
280 if (randentry == 0) {
286 currpos = xmms_playlist_coll_get_currpos (coll);
287 size = xmms_playlist_coll_get_size (coll);
289 playlist->update_flag = FALSE;
303 ret->mutex = g_mutex_new ();
315 on_playlist_r_one_changed, ret);
319 on_playlist_r_all_changed, ret);
322 ret->update_flag = FALSE;
326 on_playlist_updated_chg, ret);
330 on_playlist_updated_pos, ret);
431 xmms_error_reset (&err);
434 if (plcoll == NULL) {
436 }
else if ((size = xmms_playlist_coll_get_size (plcoll)) == 0) {
438 xmms_playlist_client_load (buffer, jumplist, &err);
440 ret = xmms_playlist_advance_do (playlist);
447 }
else if (!playlist->repeat_one) {
448 currpos = xmms_playlist_coll_get_currpos (plcoll);
451 if (currpos == size && !playlist->repeat_all &&
457 xmms_playlist_client_load (buffer, jumplist, &err);
459 ret = xmms_playlist_advance_do (playlist);
464 newpos = currpos%size;
467 ret = (currpos != size) || playlist->repeat_all;
487 g_return_val_if_fail (playlist, FALSE);
489 g_mutex_lock (playlist->mutex);
490 ret = xmms_playlist_advance_do (playlist);
491 g_mutex_unlock (playlist->mutex);
507 g_return_val_if_fail (playlist, 0);
509 g_mutex_lock (playlist->mutex);
512 if (plcoll == NULL) {
514 g_mutex_unlock (playlist->mutex);
518 currpos = xmms_playlist_coll_get_currpos (plcoll);
519 size = xmms_playlist_coll_get_size (plcoll);
521 if (currpos == -1 && (size > 0)) {
527 if (currpos < size) {
530 ent = idlist[currpos];
535 g_mutex_unlock (playlist->mutex);
546 xmms_playlist_client_current_pos (
xmms_playlist_t *playlist,
const gchar *plname,
553 g_return_val_if_fail (playlist, 0);
555 g_mutex_lock (playlist->mutex);
557 plcoll = xmms_playlist_get_coll (playlist, plname, err);
558 if (plcoll == NULL) {
559 g_mutex_unlock (playlist->mutex);
564 pos = xmms_playlist_coll_get_currpos (plcoll);
569 g_mutex_unlock (playlist->mutex);
571 dict = xmms_playlist_current_pos_msg_new (playlist, pos, plname);
586 g_return_val_if_fail (playlist, 0);
588 g_mutex_lock (playlist->mutex);
591 if (active_coll != NULL) {
600 name = g_strdup (alias);
606 g_mutex_unlock (playlist->mutex);
623 if (active_coll == NULL) {
628 plcoll = xmms_playlist_get_coll (playlist, name, err);
629 if (plcoll == NULL) {
634 if (active_coll == plcoll) {
635 XMMS_DBG (
"Not loading %s playlist, already active!", name);
639 XMMS_DBG (
"Loading new playlist! %s", name);
667 xmms_playlist_client_shuffle (
xmms_playlist_t *playlist,
const gchar *plname,
674 g_return_if_fail (playlist);
676 g_mutex_lock (playlist->mutex);
678 plcoll = xmms_playlist_get_coll (playlist, plname, err);
679 if (plcoll == NULL) {
681 g_mutex_unlock (playlist->mutex);
685 currpos = xmms_playlist_coll_get_currpos (plcoll);
686 len = xmms_playlist_coll_get_size (plcoll);
690 swap_entries (plcoll, 0, currpos);
696 for (i = currpos + 1; i < len; i++) {
697 j = g_random_int_range (i, len);
700 swap_entries (plcoll, i, j);
709 g_mutex_unlock (playlist->mutex);
713 xmms_playlist_remove_unlocked (
xmms_playlist_t *playlist,
const gchar *plname,
719 g_return_val_if_fail (playlist, FALSE);
721 currpos = xmms_playlist_coll_get_currpos (plcoll);
729 g_tree_insert (dict, (gpointer)
"position",
xmmsv_new_int (pos));
735 if (currpos != -1 && pos <= currpos) {
747 } playlist_remove_info_t;
750 remove_from_playlist (gpointer key, gpointer value, gpointer udata)
752 playlist_remove_info_t *rminfo = (playlist_remove_info_t *) udata;
757 size = xmms_playlist_coll_get_size (plcoll);
758 for (i = 0; i < size; i++) {
760 XMMS_DBG (
"removing entry on pos %d in %s", i, (gchar *)key);
761 xmms_playlist_remove_unlocked (rminfo->pls, (gchar *)key, plcoll, i, NULL);
781 playlist_remove_info_t rminfo;
782 g_return_val_if_fail (playlist, FALSE);
784 g_mutex_lock (playlist->mutex);
786 rminfo.pls = playlist;
787 rminfo.entry = entry;
791 remove_from_playlist, &rminfo);
793 g_mutex_unlock (playlist->mutex);
803 xmms_playlist_client_remove (
xmms_playlist_t *playlist,
const gchar *plname,
806 gboolean ret = FALSE;
809 g_return_if_fail (playlist);
811 g_mutex_lock (playlist->mutex);
812 plcoll = xmms_playlist_get_coll (playlist, plname, err);
813 if (plcoll != NULL) {
814 ret = xmms_playlist_remove_unlocked (playlist, plname, plcoll, pos, err);
816 g_mutex_unlock (playlist->mutex);
825 xmms_playlist_client_move (
xmms_playlist_t *playlist,
const gchar *plname, gint32 pos,
831 gint64 ipos, inewpos;
834 g_return_if_fail (playlist);
836 XMMS_DBG (
"Moving %d, to %d", pos, newpos);
838 g_mutex_lock (playlist->mutex);
840 plcoll = xmms_playlist_get_coll (playlist, plname, err);
841 if (plcoll == NULL) {
843 g_mutex_unlock (playlist->mutex);
847 currpos = xmms_playlist_coll_get_currpos (plcoll);
848 size = xmms_playlist_coll_get_size (plcoll);
850 if (size == 0 || newpos > (size - 1)) {
852 "Cannot move entry outside playlist");
853 g_mutex_unlock (playlist->mutex);
859 g_mutex_unlock (playlist->mutex);
866 if (inewpos <= currpos && ipos > currpos)
868 else if (inewpos >= currpos && ipos < currpos)
870 else if (ipos == currpos)
878 g_tree_insert (dict, (gpointer)
"position",
xmmsv_new_int (pos));
879 g_tree_insert (dict, (gpointer)
"newposition",
xmmsv_new_int (newpos));
884 g_mutex_unlock (playlist->mutex);
903 xmms_playlist_client_insert_url (
xmms_playlist_t *playlist,
const gchar *plname,
916 xmms_playlist_client_insert_id (playlist, plname, pos, entry, err);
931 xmms_playlist_client_rinsert (
xmms_playlist_t *playlist,
const gchar *plname, gint32 pos,
950 xmms_playlist_client_insert_id (
xmms_playlist_t *playlist,
const gchar *plname,
956 "That is not a valid medialib id!");
963 xmms_playlist_client_insert_collection (
xmms_playlist_t *playlist,
const gchar *plname,
975 xmms_playlist_client_insert_id (playlist, plname, pos,
id, err);
978 res = g_list_delete_link (res, res);
1000 g_mutex_lock (playlist->mutex);
1002 plcoll = xmms_playlist_get_coll (playlist, plname, err);
1003 if (plcoll == NULL) {
1005 g_mutex_unlock (playlist->mutex);
1009 len = xmms_playlist_coll_get_size (plcoll);
1012 "Could not insert entry outside of playlist!");
1013 g_mutex_unlock (playlist->mutex);
1020 g_tree_insert (dict, (gpointer)
"position",
xmmsv_new_int (pos));
1024 currpos = xmms_playlist_coll_get_currpos (plcoll);
1025 if (pos <= currpos) {
1031 g_mutex_unlock (playlist->mutex);
1046 xmms_playlist_client_add_url (
xmms_playlist_t *playlist,
const gchar *plname,
1072 xmms_playlist_client_radd (
xmms_playlist_t *playlist,
const gchar *plname,
1095 xmms_playlist_client_add_id (
xmms_playlist_t *playlist,
const gchar *plname,
1100 "That is not a valid medialib id!");
1108 xmms_playlist_client_add_idlist (
xmms_playlist_t *playlist,
const gchar *plname,
1116 "Idlist contains invalid medialib id!");
1128 xmms_playlist_client_add_collection (
xmms_playlist_t *playlist,
const gchar *plname,
1143 res = g_list_delete_link (res, res);
1159 g_mutex_lock (playlist->mutex);
1161 plcoll = xmms_playlist_get_coll (playlist, plname, err);
1162 if (plcoll != NULL) {
1166 g_mutex_unlock (playlist->mutex);
1175 const gchar *plname,
1183 prev_size = xmms_playlist_coll_get_size (plcoll);
1188 g_tree_insert (dict, (gpointer)
"position",
xmmsv_new_int (prev_size));
1194 xmms_playlist_client_clear (
xmms_playlist_t *playlist,
const gchar *plname,
1199 g_return_if_fail (playlist);
1201 g_mutex_lock (playlist->mutex);
1203 plcoll = xmms_playlist_get_coll (playlist, plname, err);
1204 if (plcoll == NULL) {
1205 g_mutex_unlock (playlist->mutex);
1213 g_mutex_unlock (playlist->mutex);
1226 xmms_playlist_set_current_position_do (
xmms_playlist_t *playlist, guint32 pos,
1235 g_return_val_if_fail (playlist, FALSE);
1238 if (plcoll == NULL) {
1242 size = xmms_playlist_coll_get_size (plcoll);
1250 xmms_playlist_client_load (playlist, jumplist, err);
1256 if (plcoll == NULL) {
1259 }
else if (pos < size) {
1265 "Can't set pos outside the current playlist!");
1276 xmms_playlist_client_set_current_position (
xmms_playlist_t *playlist, gint32 pos,
1280 g_return_val_if_fail (playlist, FALSE);
1282 g_mutex_lock (playlist->mutex);
1283 mid = xmms_playlist_set_current_position_do (playlist, pos, err);
1284 g_mutex_unlock (playlist->mutex);
1290 xmms_playlist_client_set_current_position_rel (
xmms_playlist_t *playlist, gint32 pos,
1293 gint currpos, newpos;
1297 g_return_val_if_fail (playlist, FALSE);
1299 g_mutex_lock (playlist->mutex);
1302 if (plcoll != NULL) {
1303 currpos = xmms_playlist_coll_get_currpos (plcoll);
1305 if (playlist->repeat_all) {
1312 mid = xmms_playlist_set_current_position_do (playlist, newpos, err);
1314 if (currpos + pos >= 0) {
1315 mid = xmms_playlist_set_current_position_do (playlist,
1320 "Can't set pos outside the current playlist!");
1325 g_mutex_unlock (playlist->mutex);
1344 xmms_playlist_entry_compare (gconstpointer a, gconstpointer b, gpointer user_data)
1347 xmmsv_t *val1, *val2, *properties, *propval;
1349 sortdata_t *data1 = (sortdata_t *) a;
1350 sortdata_t *data2 = (sortdata_t *) b;
1352 const gchar *propstr, *str1, *str2;
1354 properties = (
xmmsv_t *) user_data;
1361 if (propstr[0] ==
'-') {
1384 res = g_utf8_collate (str1, str2);
1406 XMMS_DBG (
"Types in compare function differ to much");
1420 xmms_playlist_sorted_free (gpointer data, gpointer userdata)
1423 sortdata_t *sorted = (sortdata_t *) data;
1425 for (n = sorted->val; n; n = n->next) {
1430 g_list_free (sorted->val);
1439 xmms_playlist_sorted_unwind (gpointer data, gpointer userdata)
1442 sortdata_t *sorted = (sortdata_t *) data;
1447 if (sorted->current) {
1452 xmms_playlist_sorted_free (sorted, NULL);
1466 xmms_playlist_client_sort (
xmms_playlist_t *playlist,
const gchar *plname,
1470 GList *tmp = NULL, *n;
1475 gboolean list_changed = FALSE;
1481 g_return_if_fail (playlist);
1482 g_return_if_fail (properties);
1484 g_mutex_lock (playlist->mutex);
1486 plcoll = xmms_playlist_get_coll (playlist, plname, err);
1487 if (plcoll == NULL) {
1489 g_mutex_unlock (playlist->mutex);
1496 "invalid list of properties to sort by!");
1497 g_mutex_unlock (playlist->mutex);
1503 "empty list of properties to sort by!");
1504 g_mutex_unlock (playlist->mutex);
1511 XMMS_DBG (
"Sorting on %s (and maybe more)", str);
1513 currpos = xmms_playlist_coll_get_currpos (plcoll);
1514 size = xmms_playlist_coll_get_size (plcoll);
1518 g_mutex_unlock (playlist->mutex);
1525 for (i = 0; i < size; i++) {
1526 data = g_new (sortdata_t, 1);
1550 casefold = g_utf8_casefold (str, strlen (str));
1557 data->val = g_list_prepend (data->val, val);
1559 data->val = g_list_reverse (data->val);
1561 data->current = (currpos == i);
1563 tmp = g_list_prepend (tmp, data);
1568 tmp = g_list_reverse (tmp);
1569 tmp = g_list_sort_with_data (tmp, xmms_playlist_entry_compare, properties);
1572 for (i = 0, n = tmp; n; i++, n = g_list_next (n)) {
1573 if (((sortdata_t*)n->data)->position != i) {
1574 list_changed = TRUE;
1579 if (!list_changed) {
1580 g_list_foreach (tmp, xmms_playlist_sorted_free, NULL);
1582 g_mutex_unlock (playlist->mutex);
1587 g_list_foreach (tmp, xmms_playlist_sorted_unwind, plcoll);
1594 g_mutex_unlock (playlist->mutex);
1600 xmms_playlist_client_list_entries (
xmms_playlist_t *playlist,
const gchar *plname,
1603 GList *entries = NULL;
1608 g_return_val_if_fail (playlist, NULL);
1610 g_mutex_lock (playlist->mutex);
1612 plcoll = xmms_playlist_get_coll (playlist, plname, err);
1613 if (plcoll == NULL) {
1614 g_mutex_unlock (playlist->mutex);
1620 for (i = 0; idlist[i] != 0; i++) {
1621 entries = g_list_prepend (entries,
xmmsv_new_int (idlist[i]));
1624 g_mutex_unlock (playlist->mutex);
1626 entries = g_list_reverse (entries);
1635 g_return_val_if_fail (playlist, NULL);
1637 return playlist->mediainfordr;
1653 g_return_if_fail (playlist);
1655 g_mutex_free (playlist->mutex);
1672 xmms_playlist_get_coll (
xmms_playlist_t *playlist,
const gchar *plname,
1679 if (coll == NULL && error != NULL) {
1690 static const gchar *
1691 xmms_playlist_canonical_name (
xmms_playlist_t *playlist,
const gchar *plname)
1693 const gchar *fullname;
1735 guint32
id,
const gchar *plname)
1740 dict = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
1743 g_tree_insert (dict, (gpointer)
"type",
xmmsv_new_int (type));
1749 tmp = xmms_playlist_canonical_name (playlist, plname);
1757 guint32 pos,
const gchar *plname)
1762 dict = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
1765 g_tree_insert (dict, (gpointer)
"position",
xmmsv_new_int (pos));
1767 tmp = xmms_playlist_canonical_name (playlist, plname);
1779 const gchar *plname;
1781 g_return_if_fail (playlist);
1782 g_return_if_fail (dict);
1785 type_val = g_tree_lookup (dict,
"type");
1786 pl_val = g_tree_lookup (dict,
"name");
1798 g_tree_destroy (dict);
1805 g_return_if_fail (playlist);
1807 g_return_if_fail (dict);
1814 g_tree_destroy (dict);