X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmpdclient.c;h=4a12515752b9037366d99f1662022ea4269289e3;hb=850ad87b588dd6cbb96e5558ee671f2c95cc839d;hp=f67b09133949ff0efcb78eda00b384de699214c9;hpb=75348aad7cbddb9ef736a0ecca9e3ddfb8b75f8d;p=ncmpc.git diff --git a/src/mpdclient.c b/src/mpdclient.c index f67b091..4a12515 100644 --- a/src/mpdclient.c +++ b/src/mpdclient.c @@ -1,30 +1,28 @@ -/* - * $Id$ - * - * (c) 2004 by Kalle Wallin - * +/* ncmpc (Ncurses MPD Client) + * (c) 2004-2009 The Music Player Daemon Project + * Project homepage: http://musicpd.org + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ #include "mpdclient.h" #include "screen_utils.h" #include "config.h" -#include "ncmpc.h" -#include "support.h" #include "options.h" #include "strfsong.h" +#include "utils.h" #include #include @@ -35,38 +33,41 @@ #define ENABLE_FANCY_PLAYLIST_MANAGMENT_CMD_DELETE #define ENABLE_FANCY_PLAYLIST_MANAGMENT_CMD_MOVE #define ENABLE_SONG_ID -#define ENABLE_PLCHANGES +#define ENABLE_PLCHANGES #define BUFSIZE 1024 -#define MPD_ERROR(c) (c==NULL || c->connection==NULL || c->connection->error) - -/* from utils.c */ -extern GList *string_list_free(GList *string_list); - +static bool +MPD_ERROR(const struct mpdclient *client) +{ + return client == NULL || client->connection==NULL || + client->connection->error != MPD_ERROR_SUCCESS; +} /* filelist sorting functions */ static gint -compare_filelistentry_dir(gconstpointer filelist_entry1, +compare_filelistentry(gconstpointer filelist_entry1, gconstpointer filelist_entry2) { const mpd_InfoEntity *e1, *e2; - char *key1, *key2; int n = 0; e1 = ((const filelist_entry_t *)filelist_entry1)->entity; e2 = ((const filelist_entry_t *)filelist_entry2)->entity; - if (e1 && e2 && - e1->type == MPD_INFO_ENTITY_TYPE_DIRECTORY && - e2->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { - key1 = g_utf8_collate_key(e1->info.directory->path,-1); - key2 = g_utf8_collate_key(e2->info.directory->path,-1); - n = strcmp(key1,key2); - g_free(key1); - g_free(key2); + if (e1 && e2 && e1->type == e2->type) { + switch (e1->type) { + case MPD_INFO_ENTITY_TYPE_DIRECTORY: + n = g_utf8_collate(e1->info.directory->path, + e2->info.directory->path); + break; + case MPD_INFO_ENTITY_TYPE_SONG: + break; + case MPD_INFO_ENTITY_TYPE_PLAYLISTFILE: + n = g_utf8_collate(e1->info.playlistFile->path, + e2->info.playlistFile->path); + } } - return n; } @@ -85,8 +86,8 @@ compare_filelistentry_format(gconstpointer filelist_entry1, if (e1 && e2 && e1->type == MPD_INFO_ENTITY_TYPE_SONG && e2->type == MPD_INFO_ENTITY_TYPE_SONG) { - strfsong(key1, BUFSIZE, LIST_FORMAT, e1->info.song); - strfsong(key2, BUFSIZE, LIST_FORMAT, e2->info.song); + strfsong(key1, BUFSIZE, options.list_format, e1->info.song); + strfsong(key2, BUFSIZE, options.list_format, e2->info.song); n = strcmp(key1,key2); } @@ -96,65 +97,50 @@ compare_filelistentry_format(gconstpointer filelist_entry1, /* Error callbacks */ static gint -error_cb(mpdclient_t *c, gint error, gchar *msg) -{ - GList *list = c->error_callbacks; - - if( list==NULL ) - fprintf(stderr, "error [%d]: %s\n", (error & 0xFF), msg); - - while(list) - { - mpdc_error_cb_t cb = list->data; - if( cb ) - cb(c, error, msg); - list=list->next; - } - mpd_clearError(c->connection); - return error; -} - -#ifndef NDEBUG -// Unused ath the moment -/* -#include "strfsong.h" - -static gchar * -get_song_name(mpd_Song *song) +error_cb(mpdclient_t *c, gint error, const gchar *msg) { - static gchar name[256]; + GList *list = c->error_callbacks; - strfsong(name, 256, "[%artist% - ]%title%|%file%", song); - return name; + if (list == NULL) + fprintf(stderr, "error [%d]: %s\n", (error & 0xFF), msg); + + while (list) { + mpdc_error_cb_t cb = list->data; + if (cb) + cb(c, error, msg); + list = list->next; + } + + mpd_clearError(c->connection); + return error; } -*/ -#endif + /****************************************************************************/ /*** mpdclient functions ****************************************************/ /****************************************************************************/ gint -mpdclient_finish_command(mpdclient_t *c) +mpdclient_finish_command(mpdclient_t *c) { - mpd_finishCommand(c->connection); + mpd_finishCommand(c->connection); + + if (c->connection->error) { + gint error = c->connection->error; - if( c->connection->error ) - { - gchar *msg = locale_to_utf8(c->connection->errorStr); - gint error = c->connection->error; - if( error == MPD_ERROR_ACK ) - error = error | (c->connection->errorCode << 8); - if( c->connection->errorCode == MPD_ACK_ERROR_PERMISSION ) - { - if(screen_auth(c) == 0) return 0; + if (error == MPD_ERROR_ACK && + c->connection->errorCode == MPD_ACK_ERROR_PERMISSION && + screen_auth(c) == 0) + return 0; + + if (error == MPD_ERROR_ACK) + error = error | (c->connection->errorCode << 8); + + error_cb(c, error, c->connection->errorStr); + return error; } - error_cb(c, error, msg); - g_free(msg); - return error; - } - return 0; + return 0; } mpdclient_t * @@ -164,6 +150,7 @@ mpdclient_new(void) c = g_malloc0(sizeof(mpdclient_t)); playlist_init(&c->playlist); + c->volume = MPD_STATUS_NO_VOLUME; return c; } @@ -234,6 +221,8 @@ mpdclient_update(mpdclient_t *c) { gint retval = 0; + c->volume = MPD_STATUS_NO_VOLUME; + if (MPD_ERROR(c)) return -1; @@ -241,15 +230,17 @@ mpdclient_update(mpdclient_t *c) if (c->status) mpd_freeStatus(c->status); - /* retreive new status */ + /* retrieve new status */ mpd_sendStatusCommand(c->connection); c->status = mpd_getStatus(c->connection); if ((retval=mpdclient_finish_command(c))) return retval; -#ifndef NDEBUG - if (c->status->error) - D("status> %s\n", c->status->error); -#endif + + if (c->updatingdb && c->updatingdb != c->status->updatingDb) + mpdclient_browse_callback(c, BROWSE_DB_UPDATED, NULL); + + c->updatingdb = c->status->updatingDb; + c->volume = c->status->volume; /* check if the playlist needs an update */ if (c->playlist.id != c->status->playlist) { @@ -280,7 +271,6 @@ mpdclient_cmd_play(mpdclient_t *c, gint idx) #ifdef ENABLE_SONG_ID struct mpd_song *song = playlist_get_song(c, idx); - D("Play id:%d\n", song ? song->id : -1); if (song) mpd_sendPlayIdCommand(c->connection, song->id); else @@ -299,6 +289,41 @@ mpdclient_cmd_pause(mpdclient_t *c, gint value) return mpdclient_finish_command(c); } +gint +mpdclient_cmd_crop(mpdclient_t *c) +{ + gint error; + mpd_Status *status; + bool playing; + int length, current; + + mpd_sendStatusCommand(c->connection); + status = mpd_getStatus(c->connection); + error = mpdclient_finish_command(c); + if (error) + return error; + + playing = status->state == MPD_STATUS_STATE_PLAY || + status->state == MPD_STATUS_STATE_PAUSE; + length = status->playlistLength; + current = status->song; + + mpd_freeStatus(status); + + if (!playing || length < 2) + return 0; + + mpd_sendCommandListBegin( c->connection ); + + while (--length >= 0) + if (length != current) + mpd_sendDeleteCommand(c->connection, length); + + mpd_sendCommandListEnd(c->connection); + + return mpdclient_finish_command(c); +} + gint mpdclient_cmd_stop(mpdclient_t *c) { @@ -322,86 +347,134 @@ mpdclient_cmd_prev(mpdclient_t *c) return mpdclient_finish_command(c); } -gint +gint mpdclient_cmd_seek(mpdclient_t *c, gint id, gint pos) { - D("Seek id:%d\n", id); - mpd_sendSeekIdCommand(c->connection, id, pos); - return mpdclient_finish_command(c); + mpd_sendSeekIdCommand(c->connection, id, pos); + return mpdclient_finish_command(c); } -gint +gint mpdclient_cmd_shuffle(mpdclient_t *c) { - mpd_sendShuffleCommand(c->connection); - c->need_update = TRUE; - return mpdclient_finish_command(c); + mpd_sendShuffleCommand(c->connection); + c->need_update = TRUE; + return mpdclient_finish_command(c); +} + +gint +mpdclient_cmd_shuffle_range(mpdclient_t *c, guint start, guint end) +{ + mpd_sendShuffleRangeCommand(c->connection, start, end); + c->need_update = TRUE; + return mpdclient_finish_command(c); } -gint +gint mpdclient_cmd_clear(mpdclient_t *c) { - gint retval = 0; + gint retval = 0; - mpd_sendClearCommand(c->connection); - retval = mpdclient_finish_command(c); - /* call playlist updated callback */ - mpdclient_playlist_callback(c, PLAYLIST_EVENT_CLEAR, NULL); - c->need_update = TRUE; - return retval; + mpd_sendClearCommand(c->connection); + retval = mpdclient_finish_command(c); + /* call playlist updated callback */ + mpdclient_playlist_callback(c, PLAYLIST_EVENT_CLEAR, NULL); + c->need_update = TRUE; + return retval; } -gint +gint mpdclient_cmd_repeat(mpdclient_t *c, gint value) { - mpd_sendRepeatCommand(c->connection, value); - return mpdclient_finish_command(c); + mpd_sendRepeatCommand(c->connection, value); + return mpdclient_finish_command(c); } -gint +gint mpdclient_cmd_random(mpdclient_t *c, gint value) { - mpd_sendRandomCommand(c->connection, value); - return mpdclient_finish_command(c); + mpd_sendRandomCommand(c->connection, value); + return mpdclient_finish_command(c); +} + +gint +mpdclient_cmd_single(mpdclient_t *c, gint value) +{ + mpd_sendSingleCommand(c->connection, value); + return mpdclient_finish_command(c); } -gint +gint +mpdclient_cmd_consume(mpdclient_t *c, gint value) +{ + mpd_sendConsumeCommand(c->connection, value); + return mpdclient_finish_command(c); +} + +gint mpdclient_cmd_crossfade(mpdclient_t *c, gint value) { - mpd_sendCrossfadeCommand(c->connection, value); - return mpdclient_finish_command(c); + mpd_sendCrossfadeCommand(c->connection, value); + return mpdclient_finish_command(c); } -gint -mpdclient_cmd_db_update_utf8(mpdclient_t *c, gchar *path) +gint +mpdclient_cmd_db_update(mpdclient_t *c, gchar *path) { - mpd_sendUpdateCommand(c->connection, path ? path : ""); - return mpdclient_finish_command(c); + gint ret; + + mpd_sendUpdateCommand(c->connection, path ? path : ""); + ret = mpdclient_finish_command(c); + + if (ret == 0) + /* set updatingDb to make sure the browse callback + gets called even if the update has finished before + status is updated */ + c->updatingdb = 1; + + return ret; } -gint +gint mpdclient_cmd_volume(mpdclient_t *c, gint value) { - mpd_sendSetvolCommand(c->connection, value); - return mpdclient_finish_command(c); + mpd_sendSetvolCommand(c->connection, value); + return mpdclient_finish_command(c); } -gint -mpdclient_cmd_add_path_utf8(mpdclient_t *c, gchar *path_utf8) +gint mpdclient_cmd_volume_up(struct mpdclient *c) { - mpd_sendAddCommand(c->connection, path_utf8); - return mpdclient_finish_command(c); + if (c->status == NULL || c->status->volume == MPD_STATUS_NO_VOLUME) + return 0; + + if (c->volume == MPD_STATUS_NO_VOLUME) + c->volume = c->status->volume; + + if (c->volume >= 100) + return 0; + + return mpdclient_cmd_volume(c, ++c->volume); } -gint -mpdclient_cmd_add_path(mpdclient_t *c, gchar *path) +gint mpdclient_cmd_volume_down(struct mpdclient *c) { - gint retval; - gchar *path_utf8 = locale_to_utf8(path); + if (c->status == NULL || c->status->volume == MPD_STATUS_NO_VOLUME) + return 0; + + if (c->volume == MPD_STATUS_NO_VOLUME) + c->volume = c->status->volume; - retval=mpdclient_cmd_add_path_utf8(c, path_utf8); - g_free(path_utf8); - return retval; + if (c->volume <= 0) + return 0; + + return mpdclient_cmd_volume(c, --c->volume); +} + +gint +mpdclient_cmd_add_path(mpdclient_t *c, gchar *path_utf8) +{ + mpd_sendAddCommand(c->connection, path_utf8); + return mpdclient_finish_command(c); } gint @@ -421,7 +494,7 @@ mpdclient_cmd_add(mpdclient_t *c, struct mpd_song *song) /* add the song to playlist */ playlist_append(&c->playlist, song); - /* increment the playlist id, so we dont retrives a new playlist */ + /* increment the playlist id, so we don't retrieve a new playlist */ c->playlist.id++; /* call playlist updated callback */ @@ -446,7 +519,6 @@ mpdclient_cmd_delete(mpdclient_t *c, gint idx) /* send the delete command to mpd */ #ifdef ENABLE_SONG_ID - D("Delete id:%d\n", song->id); mpd_sendDeleteIdCommand(c->connection, song->id); #else mpd_sendDeleteCommand(c->connection, idx); @@ -455,11 +527,11 @@ mpdclient_cmd_delete(mpdclient_t *c, gint idx) return retval; #ifdef ENABLE_FANCY_PLAYLIST_MANAGMENT_CMD_DELETE - /* increment the playlist id, so we dont retrive a new playlist */ + /* increment the playlist id, so we don't retrieve a new playlist */ c->playlist.id++; /* remove the song from the playlist */ - playlist_remove(&c->playlist, idx); + playlist_remove_reuse(&c->playlist, idx); /* call playlist updated callback */ mpdclient_playlist_callback(c, PLAYLIST_EVENT_DELETE, (gpointer) song); @@ -470,6 +542,8 @@ mpdclient_cmd_delete(mpdclient_t *c, gint idx) c->need_update = TRUE; } + mpd_freeSong(song); + #else c->need_update = TRUE; #endif @@ -492,10 +566,8 @@ mpdclient_cmd_move(mpdclient_t *c, gint old_index, gint new_index) /* send the move command to mpd */ #ifdef ENABLE_SONG_ID - D("Swapping id:%d with id:%d\n", song1->id, song2->id); mpd_sendSwapIdCommand(c->connection, song1->id, song2->id); #else - D("Moving index %d to id:%d\n", old_index, new_index); mpd_sendMoveCommand(c->connection, old_index, new_index); #endif if( (n=mpdclient_finish_command(c)) ) @@ -505,7 +577,7 @@ mpdclient_cmd_move(mpdclient_t *c, gint old_index, gint new_index) /* update the playlist */ playlist_swap(&c->playlist, old_index, new_index); - /* increment the playlist id, so we dont retrives a new playlist */ + /* increment the playlist id, so we don't retrieve a new playlist */ c->playlist.id++; #else @@ -513,142 +585,117 @@ mpdclient_cmd_move(mpdclient_t *c, gint old_index, gint new_index) #endif /* call playlist updated callback */ - D("move> new_index=%d, old_index=%d\n", new_index, old_index); mpdclient_playlist_callback(c, PLAYLIST_EVENT_MOVE, (gpointer) &new_index); return 0; } -gint -mpdclient_cmd_save_playlist_utf8(mpdclient_t *c, gchar *filename_utf8) -{ - gint retval = 0; - - mpd_sendSaveCommand(c->connection, filename_utf8); - if( (retval=mpdclient_finish_command(c)) == 0 ) - mpdclient_browse_callback(c, BROWSE_PLAYLIST_SAVED, NULL); - return retval; -} - -gint -mpdclient_cmd_save_playlist(mpdclient_t *c, gchar *filename) +gint +mpdclient_cmd_save_playlist(mpdclient_t *c, gchar *filename_utf8) { - gint retval = 0; - gchar *filename_utf8 = locale_to_utf8(filename); - - retval = mpdclient_cmd_save_playlist_utf8(c, filename); - g_free(filename_utf8); - return retval; -} + gint retval = 0; -gint -mpdclient_cmd_load_playlist_utf8(mpdclient_t *c, gchar *filename_utf8) -{ - mpd_sendLoadCommand(c->connection, filename_utf8); - c->need_update = TRUE; - return mpdclient_finish_command(c); + mpd_sendSaveCommand(c->connection, filename_utf8); + if ((retval = mpdclient_finish_command(c)) == 0) + mpdclient_browse_callback(c, BROWSE_PLAYLIST_SAVED, NULL); + return retval; } -gint -mpdclient_cmd_delete_playlist_utf8(mpdclient_t *c, gchar *filename_utf8) +gint +mpdclient_cmd_load_playlist(mpdclient_t *c, gchar *filename_utf8) { - gint retval = 0; - - mpd_sendRmCommand(c->connection, filename_utf8); - if( (retval=mpdclient_finish_command(c)) == 0 ) - mpdclient_browse_callback(c, BROWSE_PLAYLIST_DELETED, NULL); - return retval; + mpd_sendLoadCommand(c->connection, filename_utf8); + c->need_update = TRUE; + return mpdclient_finish_command(c); } -gint -mpdclient_cmd_delete_playlist(mpdclient_t *c, gchar *filename) +gint +mpdclient_cmd_delete_playlist(mpdclient_t *c, gchar *filename_utf8) { - gint retval = 0; - gchar *filename_utf8 = locale_to_utf8(filename); + gint retval = 0; - retval = mpdclient_cmd_delete_playlist_utf8(c, filename_utf8); - g_free(filename_utf8); - return retval; + mpd_sendRmCommand(c->connection, filename_utf8); + if ((retval = mpdclient_finish_command(c)) == 0) + mpdclient_browse_callback(c, BROWSE_PLAYLIST_DELETED, NULL); + return retval; } /****************************************************************************/ -/*** Callback managment functions *******************************************/ +/*** Callback management functions ******************************************/ /****************************************************************************/ + static void do_list_callbacks(mpdclient_t *c, GList *list, gint event, gpointer data) { - while(list) - { - mpdc_list_cb_t fn = list->data; + while (list) { + mpdc_list_cb_t fn = list->data; - fn(c, event, data); - list=list->next; - } + fn(c, event, data); + list = list->next; + } } void mpdclient_playlist_callback(mpdclient_t *c, int event, gpointer data) { - do_list_callbacks(c, c->playlist_callbacks, event, data); + do_list_callbacks(c, c->playlist_callbacks, event, data); } void mpdclient_install_playlist_callback(mpdclient_t *c,mpdc_list_cb_t cb) { - c->playlist_callbacks = g_list_append(c->playlist_callbacks, cb); + c->playlist_callbacks = g_list_append(c->playlist_callbacks, cb); } void mpdclient_remove_playlist_callback(mpdclient_t *c, mpdc_list_cb_t cb) { - c->playlist_callbacks = g_list_remove(c->playlist_callbacks, cb); + c->playlist_callbacks = g_list_remove(c->playlist_callbacks, cb); } void mpdclient_browse_callback(mpdclient_t *c, int event, gpointer data) { - do_list_callbacks(c, c->browse_callbacks, event, data); + do_list_callbacks(c, c->browse_callbacks, event, data); } void mpdclient_install_browse_callback(mpdclient_t *c,mpdc_list_cb_t cb) { - c->browse_callbacks = g_list_append(c->browse_callbacks, cb); + c->browse_callbacks = g_list_append(c->browse_callbacks, cb); } void mpdclient_remove_browse_callback(mpdclient_t *c, mpdc_list_cb_t cb) { - c->browse_callbacks = g_list_remove(c->browse_callbacks, cb); + c->browse_callbacks = g_list_remove(c->browse_callbacks, cb); } void mpdclient_install_error_callback(mpdclient_t *c, mpdc_error_cb_t cb) { - c->error_callbacks = g_list_append(c->error_callbacks, cb); + c->error_callbacks = g_list_append(c->error_callbacks, cb); } void mpdclient_remove_error_callback(mpdclient_t *c, mpdc_error_cb_t cb) { - c->error_callbacks = g_list_remove(c->error_callbacks, cb); + c->error_callbacks = g_list_remove(c->error_callbacks, cb); } + /****************************************************************************/ -/*** Playlist managment functions *******************************************/ +/*** Playlist management functions ******************************************/ /****************************************************************************/ - /* update playlist */ gint mpdclient_playlist_update(mpdclient_t *c) { mpd_InfoEntity *entity; - D("mpdclient_playlist_update() [%lld]\n", c->status->playlist); - if (MPD_ERROR(c)) return -1; @@ -664,7 +711,6 @@ mpdclient_playlist_update(mpdclient_t *c) c->playlist.id = c->status->playlist; c->song = NULL; - c->playlist.updated = TRUE; /* call playlist updated callbacks */ mpdclient_playlist_callback(c, PLAYLIST_EVENT_UPDATED, NULL); @@ -680,9 +726,6 @@ mpdclient_playlist_update_changes(mpdclient_t *c) { mpd_InfoEntity *entity; - D("mpdclient_playlist_update_changes() [%lld -> %lld]\n", - c->status->playlist, c->playlist.id); - if (MPD_ERROR(c)) return -1; @@ -693,12 +736,9 @@ mpdclient_playlist_update_changes(mpdclient_t *c) if (song->pos >= 0 && (guint)song->pos < c->playlist.list->len) { /* update song */ - D("updating pos:%d, id=%d - %s\n", - song->pos, song->id, song->file); playlist_replace(&c->playlist, song->pos, song); } else { /* add a new song */ - D("adding song at pos %d\n", song->pos); playlist_append(&c->playlist, song); } @@ -710,13 +750,11 @@ mpdclient_playlist_update_changes(mpdclient_t *c) guint pos = c->playlist.list->len - 1; /* Remove the last playlist entry */ - D("removing song at pos %d\n", pos); playlist_remove(&c->playlist, pos); } c->song = NULL; c->playlist.id = c->status->playlist; - c->playlist.updated = TRUE; mpdclient_playlist_callback(c, PLAYLIST_EVENT_UPDATED, NULL); @@ -736,242 +774,123 @@ mpdclient_playlist_update_changes(mpdclient_t *c) /*** Filelist functions *****************************************************/ /****************************************************************************/ -void -mpdclient_filelist_free(mpdclient_filelist_t *filelist) -{ - GList *list = g_list_first(filelist->list); - - D("mpdclient_filelist_free()\n"); - if (list == NULL) - return; - while (list != NULL) { - filelist_entry_t *entry = list->data; - - if (entry->entity) - mpd_freeInfoEntity(entry->entity); - g_free(entry); - list=list->next; - } - g_list_free(filelist->list); - g_free(filelist->path); - filelist->path = NULL; - filelist->list = NULL; - filelist->length = 0; - g_free(filelist); -} - - mpdclient_filelist_t * mpdclient_filelist_get(mpdclient_t *c, const gchar *path) { mpdclient_filelist_t *filelist; mpd_InfoEntity *entity; - gchar *path_utf8 = locale_to_utf8(path); - gboolean has_dirs_only = TRUE; - D("mpdclient_filelist_get(%s)\n", path); - mpd_sendLsInfoCommand(c->connection, path_utf8); - filelist = g_malloc0(sizeof(mpdclient_filelist_t)); - if (path && path[0] && strcmp(path, "/")) { + mpd_sendLsInfoCommand(c->connection, path); + filelist = filelist_new(path); + if (path && path[0] && strcmp(path, "/")) /* add a dummy entry for ./.. */ - filelist_entry_t *entry = g_malloc0(sizeof(filelist_entry_t)); - entry->entity = NULL; - filelist->list = g_list_append(filelist->list, entry); - filelist->length++; - } + filelist_append(filelist, NULL); while ((entity=mpd_getNextInfoEntity(c->connection))) { - filelist_entry_t *entry = g_malloc0(sizeof(filelist_entry_t)); - - entry->entity = entity; - filelist->list = g_list_append(filelist->list, entry); - filelist->length++; - - if (has_dirs_only && entity->type != MPD_INFO_ENTITY_TYPE_DIRECTORY) { - has_dirs_only = FALSE; - } + filelist_append(filelist, entity); } /* If there's an error, ignore it. We'll return an empty filelist. */ mpdclient_finish_command(c); - g_free(path_utf8); - filelist->path = g_strdup(path); - filelist->updated = TRUE; - - // If there are only directory entities in the filelist, we sort it - if (has_dirs_only) { - D("mpdclient_filelist_get: only dirs; sorting!\n"); - filelist->list = g_list_sort(filelist->list, compare_filelistentry_dir); - } + filelist_sort_dir_play(filelist, compare_filelistentry); return filelist; } mpdclient_filelist_t * -mpdclient_filelist_search_utf8(mpdclient_t *c, - int exact_match, - int table, - gchar *filter_utf8) +mpdclient_filelist_search(mpdclient_t *c, + int exact_match, + int table, + gchar *filter_utf8) { mpdclient_filelist_t *filelist; mpd_InfoEntity *entity; - D("mpdclient_filelist_search(%s)\n", filter_utf8); if (exact_match) mpd_sendFindCommand(c->connection, table, filter_utf8); else mpd_sendSearchCommand(c->connection, table, filter_utf8); - filelist = g_malloc0(sizeof(mpdclient_filelist_t)); + filelist = filelist_new(NULL); - while ((entity=mpd_getNextInfoEntity(c->connection))) { - filelist_entry_t *entry = g_malloc0(sizeof(filelist_entry_t)); - - entry->entity = entity; - filelist->list = g_list_append(filelist->list, entry); - filelist->length++; - } + while ((entity=mpd_getNextInfoEntity(c->connection))) + filelist_append(filelist, entity); if (mpdclient_finish_command(c)) { - mpdclient_filelist_free(filelist); + filelist_free(filelist); return NULL; } - filelist->updated = TRUE; - return filelist; -} - - -mpdclient_filelist_t * -mpdclient_filelist_search(mpdclient_t *c, - int exact_match, - int table, - gchar *_filter) -{ - mpdclient_filelist_t *filelist; - gchar *filter_utf8 = locale_to_utf8(_filter); - - D("mpdclient_filelist_search(%s)\n", _filter); - filelist = mpdclient_filelist_search_utf8(c, exact_match, table, - filter_utf8); - g_free(filter_utf8); - return filelist; } mpdclient_filelist_t * mpdclient_filelist_update(mpdclient_t *c, mpdclient_filelist_t *filelist) { - if( filelist != NULL ) - { - gchar *path = g_strdup(filelist->path); - - mpdclient_filelist_free(filelist); - filelist = mpdclient_filelist_get(c, path); - g_free(path); - return filelist; - } - return NULL; -} - -filelist_entry_t * -mpdclient_filelist_find_song(mpdclient_filelist_t *fl, struct mpd_song *song) -{ - GList *list = g_list_first(fl->list); - - while( list && song) - { - filelist_entry_t *entry = list->data; - mpd_InfoEntity *entity = entry->entity; + if (filelist != NULL) { + gchar *path = g_strdup(filelist->path); - if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG ) - { - struct mpd_song *song2 = entity->info.song; - - if( strcmp(song->file, song2->file) == 0 ) - { - return entry; - } + filelist_free(filelist); + filelist = mpdclient_filelist_get(c, path); + g_free(path); + return filelist; } - list = list->next; - } - return NULL; + return NULL; } int mpdclient_filelist_add_all(mpdclient_t *c, mpdclient_filelist_t *fl) { - GList *list = g_list_first(fl->list); - - if( fl->list==NULL || fl->length<1 ) - return 0; - - mpd_sendCommandListBegin(c->connection); - while( list ) - { - filelist_entry_t *entry = list->data; - mpd_InfoEntity *entity = entry->entity; - - if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG ) - { - struct mpd_song *song = entity->info.song; - - mpd_sendAddCommand(c->connection, song->file); - } - list = list->next; - } - mpd_sendCommandListEnd(c->connection); - return mpdclient_finish_command(c); -} - + guint i; + if (filelist_is_empty(fl)) + return 0; + mpd_sendCommandListBegin(c->connection); + for (i = 0; i < filelist_length(fl); ++i) { + filelist_entry_t *entry = filelist_get(fl, i); + mpd_InfoEntity *entity = entry->entity; + if (entity && entity->type == MPD_INFO_ENTITY_TYPE_SONG) { + struct mpd_song *song = entity->info.song; + mpd_sendAddCommand(c->connection, song->file); + } + } + mpd_sendCommandListEnd(c->connection); + return mpdclient_finish_command(c); +} GList * -mpdclient_get_artists_utf8(mpdclient_t *c) +mpdclient_get_artists(mpdclient_t *c) { - gchar *str = NULL; - GList *list = NULL; + gchar *str = NULL; + GList *list = NULL; + + mpd_sendListCommand(c->connection, MPD_TABLE_ARTIST, NULL); + while ((str = mpd_getNextArtist(c->connection))) + list = g_list_append(list, (gpointer) str); - D("mpdclient_get_artists()\n"); - mpd_sendListCommand(c->connection, MPD_TABLE_ARTIST, NULL); - while( (str=mpd_getNextArtist(c->connection)) ) - { - list = g_list_append(list, (gpointer) str); - } - if( mpdclient_finish_command(c) ) - { - return string_list_free(list); - } + if (mpdclient_finish_command(c)) + return string_list_free(list); - return list; + return list; } GList * -mpdclient_get_albums_utf8(mpdclient_t *c, gchar *artist_utf8) +mpdclient_get_albums(mpdclient_t *c, gchar *artist_utf8) { - gchar *str = NULL; - GList *list = NULL; - - D("mpdclient_get_albums(%s)\n", artist_utf8); - mpd_sendListCommand(c->connection, MPD_TABLE_ALBUM, artist_utf8); - while( (str=mpd_getNextAlbum(c->connection)) ) - { - list = g_list_append(list, (gpointer) str); - } - if( mpdclient_finish_command(c) ) - { - return string_list_free(list); - } - - return list; -} - - + gchar *str = NULL; + GList *list = NULL; + mpd_sendListCommand(c->connection, MPD_TABLE_ALBUM, artist_utf8); + while ((str = mpd_getNextAlbum(c->connection))) + list = g_list_append(list, (gpointer) str); + if (mpdclient_finish_command(c)) + return string_list_free(list); + return list; +}