diff --git a/src/mpdclient.c b/src/mpdclient.c
index c1c4a31e6143cfb9ae200d3514d23e61c524c64e..73bb85f337c5679092e07e7526066fa36861676b 100644 (file)
--- a/src/mpdclient.c
+++ b/src/mpdclient.c
#include <assert.h>
+static gboolean
+mpdclient_enter_idle_callback(gpointer user_data)
+{
+ struct mpdclient *c = user_data;
+ assert(c->enter_idle_source_id != 0);
+ assert(c->source != NULL);
+ assert(!c->idle);
+
+ c->enter_idle_source_id = 0;
+ c->idle = mpd_glib_enter(c->source);
+ return false;
+}
+
+static void
+mpdclient_schedule_enter_idle(struct mpdclient *c)
+{
+ assert(c != NULL);
+ assert(c->source != NULL);
+
+ if (c->enter_idle_source_id == 0)
+ /* automatically re-enter MPD "idle" mode */
+ c->enter_idle_source_id =
+ g_idle_add(mpdclient_enter_idle_callback, c);
+}
+
+static void
+mpdclient_cancel_enter_idle(struct mpdclient *c)
+{
+ if (c->enter_idle_source_id != 0) {
+ g_source_remove(c->enter_idle_source_id);
+ c->enter_idle_source_id = 0;
+ }
+}
+
static void
mpdclient_invoke_error_callback(enum mpd_error error,
const char *message)
g_free(allocated);
}
+static void
+mpdclient_invoke_error_callback1(struct mpdclient *c)
+{
+ assert(c != NULL);
+ assert(c->connection != NULL);
+
+ struct mpd_connection *connection = c->connection;
+
+ enum mpd_error error = mpd_connection_get_error(connection);
+ assert(error != MPD_ERROR_SUCCESS);
+
+ mpdclient_invoke_error_callback(error,
+ mpd_connection_get_error_message(connection));
+}
+
static void
mpdclient_gidle_callback(enum mpd_error error,
gcc_unused enum mpd_server_error server_error,
c->events = 0;
- mpdclient_put_connection(c);
+ if (c->source != NULL)
+ mpdclient_schedule_enter_idle(c);
}
/****************************************************************************/
mpdclient_invoke_error_callback(error,
mpd_connection_get_error_message(c->connection));
- if (!mpd_connection_clear_error(c->connection))
+ if (!mpd_connection_clear_error(c->connection)) {
mpdclient_disconnect(c);
+ mpdclient_lost_callback();
+ }
return false;
}
void
mpdclient_disconnect(struct mpdclient *c)
{
+ mpdclient_cancel_enter_idle(c);
+
if (c->source != NULL) {
mpd_glib_free(c->source);
c->source = NULL;
g_error("Out of memory");
if (mpd_connection_get_error(c->connection) != MPD_ERROR_SUCCESS) {
- mpdclient_handle_error(c);
+ mpdclient_invoke_error_callback1(c);
mpdclient_disconnect(c);
mpdclient_failed_callback();
return false;
/* send password */
if (c->password != NULL &&
!mpd_run_password(c->connection, c->password)) {
- mpdclient_handle_error(c);
+ mpdclient_invoke_error_callback1(c);
mpdclient_disconnect(c);
mpdclient_failed_callback();
return false;
c->source = mpd_glib_new(c->connection,
mpdclient_gidle_callback, c);
+ mpdclient_schedule_enter_idle(c);
++c->connection_id;
if (c->source != NULL && c->idle) {
c->idle = false;
mpd_glib_leave(c->source);
+
+ mpdclient_schedule_enter_idle(c);
}
return c->connection;
}
-void
-mpdclient_put_connection(struct mpdclient *c)
-{
- assert(c->source == NULL || c->connection != NULL);
-
- if (c->source != NULL && !c->idle) {
- c->idle = mpd_glib_enter(c->source);
- }
-}
-
static struct mpd_status *
mpdclient_recv_status(struct mpdclient *c)
{
bool
mpdclient_cmd_volume_up(struct mpdclient *c)
{
+ if (c->volume < 0 || c->volume >= 100)
+ return true;
+
struct mpd_connection *connection = mpdclient_get_connection(c);
if (connection == NULL)
return false;
- if (c->status == NULL ||
- mpd_status_get_volume(c->status) == -1)
- return true;
-
- if (c->volume < 0)
- c->volume = mpd_status_get_volume(c->status);
-
- if (c->volume >= 100)
- return true;
-
return mpdclient_cmd_volume(c, ++c->volume);
}
bool
mpdclient_cmd_volume_down(struct mpdclient *c)
{
+ if (c->volume <= 0)
+ return true;
+
struct mpd_connection *connection = mpdclient_get_connection(c);
if (connection == NULL)
return false;
- if (c->status == NULL || mpd_status_get_volume(c->status) < 0)
- return true;
-
- if (c->volume < 0)
- c->volume = mpd_status_get_volume(c->status);
-
- if (c->volume <= 0)
- return true;
-
return mpdclient_cmd_volume(c, --c->volume);
}