diff --git a/src/mpdclient.c b/src/mpdclient.c
index f5939e475e03e90cd020684978842b6a1865d1fc..4a12515752b9037366d99f1662022ea4269289e3 100644 (file)
--- a/src/mpdclient.c
+++ b/src/mpdclient.c
/* 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
#include "config.h"
#include "options.h"
#include "strfsong.h"
+#include "utils.h"
#include <stdlib.h>
#include <unistd.h>
#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;
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)
- n = g_utf8_collate(e1->info.directory->path,
- e2->info.directory->path);
-
+ 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;
}
/* Error callbacks */
static gint
-error_cb(mpdclient_t *c, gint error, gchar *msg)
+error_cb(mpdclient_t *c, gint error, const gchar *msg)
{
GList *list = c->error_callbacks;
c = g_malloc0(sizeof(mpdclient_t));
playlist_init(&c->playlist);
+ c->volume = MPD_STATUS_NO_VOLUME;
return c;
}
{
gint retval = 0;
+ c->volume = MPD_STATUS_NO_VOLUME;
+
if (MPD_ERROR(c))
return -1;
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;
+ 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) {
if (playlist_is_empty(&c->playlist))
gint
mpdclient_cmd_crop(mpdclient_t *c)
{
+ gint error;
mpd_Status *status;
- int length;
+ bool playing;
+ int length, current;
mpd_sendStatusCommand(c->connection);
status = mpd_getStatus(c->connection);
- length = status->playlistLength - 1;
+ 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;
- if (length <= 0) {
- mpd_freeStatus(status);
- } else if (status->state == 3 || status->state == 2) {
- /* If playing or paused */
+ mpd_freeStatus(status);
- mpd_sendCommandListBegin( c->connection );
+ if (!playing || length < 2)
+ return 0;
- while (length >= 0) {
- if (length != status->song)
- mpd_sendDeleteCommand(c->connection, length);
+ mpd_sendCommandListBegin( c->connection );
- length--;
- }
+ while (--length >= 0)
+ if (length != current)
+ mpd_sendDeleteCommand(c->connection, length);
- mpd_sendCommandListEnd(c->connection);
- mpd_freeStatus(status);
- } else {
- mpd_freeStatus(status);
- }
+ mpd_sendCommandListEnd(c->connection);
return mpdclient_finish_command(c);
}
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
mpdclient_cmd_clear(mpdclient_t *c)
{
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
+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)
{
gint
mpdclient_cmd_db_update(mpdclient_t *c, gchar *path)
{
+ gint ret;
+
mpd_sendUpdateCommand(c->connection, path ? path : "");
- return mpdclient_finish_command(c);
+ 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
return mpdclient_finish_command(c);
}
+gint mpdclient_cmd_volume_up(struct mpdclient *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_volume_down(struct mpdclient *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 <= 0)
+ return 0;
+
+ return mpdclient_cmd_volume(c, --c->volume);
+}
+
gint
mpdclient_cmd_add_path(mpdclient_t *c, gchar *path_utf8)
{
/* 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 */
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 */
/* 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
/****************************************************************************/
-/*** Callback managment functions *******************************************/
+/*** Callback management functions ******************************************/
/****************************************************************************/
static void
/****************************************************************************/
-/*** Playlist managment functions *******************************************/
+/*** Playlist management functions ******************************************/
/****************************************************************************/
/* update playlist */
{
mpdclient_filelist_t *filelist;
mpd_InfoEntity *entity;
- gboolean has_dirs_only = TRUE;
mpd_sendLsInfoCommand(c->connection, path);
filelist = filelist_new(path);
while ((entity=mpd_getNextInfoEntity(c->connection))) {
filelist_append(filelist, entity);
-
- if (has_dirs_only && entity->type != MPD_INFO_ENTITY_TYPE_DIRECTORY) {
- has_dirs_only = FALSE;
- }
}
/* If there's an error, ignore it. We'll return an empty filelist. */
mpdclient_finish_command(c);
- // If there are only directory entities in the filelist, we sort it
- if (has_dirs_only)
- filelist_sort(filelist, compare_filelistentry_dir);
+ filelist_sort_dir_play(filelist, compare_filelistentry);
return filelist;
}