From 8f763f1bcd527d7f2bb27a3bf3677571c8ffd2d9 Mon Sep 17 00:00:00 2001 Message-Id: <8f763f1bcd527d7f2bb27a3bf3677571c8ffd2d9.1714153687.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sun, 30 Sep 2007 18:31:50 +0100 Subject: [PATCH] _eclient_state is more general than _eclient_connected Organization: Straylight/Edgeware From: Richard Kettlewell --- disobedience/choose.c | 7 ++++--- disobedience/control.c | 2 +- disobedience/disobedience.c | 2 +- disobedience/menu.c | 2 +- disobedience/queue.c | 9 +++++---- lib/eclient.c | 39 +++++++++++++++++-------------------- lib/eclient.h | 22 +++++++++++++++++++-- 7 files changed, 50 insertions(+), 33 deletions(-) diff --git a/disobedience/choose.c b/disobedience/choose.c index 6db9422..cc9f3ac 100644 --- a/disobedience/choose.c +++ b/disobedience/choose.c @@ -937,7 +937,8 @@ static void activate_properties(GtkMenuItem attribute((unused)) *menuitem, } static gboolean sensitive_play(struct choosenode attribute((unused)) *cn) { - return !!files_selected && disorder_eclient_connected(client); + return (!!files_selected + && (disorder_eclient_state(client) & DISORDER_CONNECTED)); } #if 0 @@ -947,13 +948,13 @@ static gboolean sensitive_remove(struct choosenode attribute((unused)) *cn) { #endif static gboolean sensitive_properties(struct choosenode attribute((unused)) *cn) { - return !!files_selected && disorder_eclient_connected(client); + return !!files_selected && (disorder_eclient_state(client) & DISORDER_CONNECTED); } /* Main menu plumbing ------------------------------------------------------ */ static int choose_properties_sensitive(GtkWidget attribute((unused)) *w) { - return !!files_selected && disorder_eclient_connected(client); + return !!files_selected && (disorder_eclient_state(client) & DISORDER_CONNECTED); } static int choose_selectall_sensitive(GtkWidget attribute((unused)) *w) { diff --git a/disobedience/control.c b/disobedience/control.c index f65c78c..fb42801 100644 --- a/disobedience/control.c +++ b/disobedience/control.c @@ -186,7 +186,7 @@ void control_update(void) { static void update_icon(GtkWidget *button, int visible, int usable) { /* If the connection is down nothing is ever usable */ - if(!disorder_eclient_connected(client)) + if(!(disorder_eclient_state(client) & DISORDER_CONNECTED)) usable = 0; (visible ? gtk_widget_show : gtk_widget_hide)(button); /* Only both updating usability if the button is visible */ diff --git a/disobedience/disobedience.c b/disobedience/disobedience.c index 3c3fae6..0e7805b 100644 --- a/disobedience/disobedience.c +++ b/disobedience/disobedience.c @@ -389,7 +389,7 @@ static void nop_completed(void attribute((unused)) *v) { * currently connected then no NOP is sent. */ static gboolean maybe_send_nop(gpointer attribute((unused)) data) { - if(!nop_in_flight && disorder_eclient_connected(client)) { + if(!nop_in_flight && (disorder_eclient_state(client) & DISORDER_CONNECTED)) { nop_in_flight = 1; disorder_eclient_nop(client, nop_completed, 0); } diff --git a/disobedience/menu.c b/disobedience/menu.c index 4569385..3347a51 100644 --- a/disobedience/menu.c +++ b/disobedience/menu.c @@ -62,7 +62,7 @@ void menu_update(int page) { assert(t != 0); gtk_widget_set_sensitive(properties_widget, (t->properties_sensitive(tab) - && disorder_eclient_connected(client))); + && (disorder_eclient_state(client) & DISORDER_CONNECTED))); gtk_widget_set_sensitive(selectall_widget, t->selectall_sensitive(tab)); } diff --git a/disobedience/queue.c b/disobedience/queue.c index e4c3862..6ef558d 100644 --- a/disobedience/queue.c +++ b/disobedience/queue.c @@ -1097,7 +1097,7 @@ static int scratch_sensitive(struct queuelike attribute((unused)) *ql, struct queue_entry attribute((unused)) *q) { /* We can scratch if the playing track is selected */ return (playing_track - && disorder_eclient_connected(client) + && (disorder_eclient_state(client) & DISORDER_CONNECTED) && selection_selected(ql->selection, playing_track->id)); } @@ -1112,7 +1112,7 @@ static int remove_sensitive(struct queuelike *ql, struct queue_entry *q) { /* We can remove if we're hovering over a particular track or any non-playing * tracks are selected */ - return (disorder_eclient_connected(client) + return ((disorder_eclient_state(client) & DISORDER_CONNECTED) && ((q && q != playing_track) || count_selected_nonplaying(ql))); @@ -1139,7 +1139,7 @@ static int properties_sensitive(struct queuelike *ql, struct queue_entry attribute((unused)) *q) { /* "Properties" is sensitive if at least something is selected */ return (hash_count(ql->selection) > 0 - && disorder_eclient_connected(client)); + && (disorder_eclient_state(client) & DISORDER_CONNECTED)); } static void properties_activate(GtkMenuItem attribute((unused)) *menuitem, @@ -1269,7 +1269,8 @@ void recent_update(void) { /* Main menu plumbing ------------------------------------------------------ */ static int queue_properties_sensitive(GtkWidget *w) { - return !!queue_count_selected(g_object_get_data(G_OBJECT(w), "queue")); + return (!!queue_count_selected(g_object_get_data(G_OBJECT(w), "queue")) + && (disorder_eclient_state(client) & DISORDER_CONNECTED)); } static int queue_selectall_sensitive(GtkWidget *w) { diff --git a/lib/eclient.c b/lib/eclient.c index 6bbb530..d0cf661 100644 --- a/lib/eclient.c +++ b/lib/eclient.c @@ -127,7 +127,7 @@ struct disorder_eclient { struct vector vec; /**< @brief body */ const disorder_eclient_log_callbacks *log_callbacks; /**< @brief log callbacks */ void *log_v; /**< @brief user data */ - unsigned long statebits; /**< @brief current state */ + unsigned long statebits; /**< @brief latest state */ }; /* Forward declarations ******************************************************/ @@ -240,6 +240,7 @@ void disorder_eclient_close(disorder_eclient *c) { xclose(c->fd); c->fd = -1; c->state = state_disconnected; + c->statebits = 0; } c->output.nvec = 0; c->input.nvec = 0; @@ -250,25 +251,9 @@ void disorder_eclient_close(disorder_eclient *c) { op->sent = 0; } -/** @brief Return true if @c c is connected - * - * By connected it is meant that commands have a reasonable chance of being - * processed soon, not merely that a TCP connection exists - for instance if - * the client is still authenticating then that does not count as connected. - */ -int disorder_eclient_connected(const disorder_eclient *c) { - switch(c->state) { - case state_disconnected: - case state_connecting: - case state_connected: - return 0; - case state_idle: - case state_cmdresponse: - case state_body: - case state_log: - return 1; - } - assert(!"reached"); +/** @brief Return current state */ +unsigned long disorder_eclient_state(const disorder_eclient *c) { + return c->statebits | (c->state > state_connected ? DISORDER_CONNECTED : 0); } /* Error reporting ***********************************************************/ @@ -1215,13 +1200,19 @@ static void logline(disorder_eclient *c, const char *line) { static void logentry_completed(disorder_eclient *c, int attribute((unused)) nvec, char **vec) { if(!c->log_callbacks->completed) return; + c->state &= ~DISORDER_PLAYING; c->log_callbacks->completed(c->log_v, vec[0]); + if(c->log_callbacks->state) + c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED); } static void logentry_failed(disorder_eclient *c, int attribute((unused)) nvec, char **vec) { if(!c->log_callbacks->failed)return; + c->state &= ~DISORDER_PLAYING; c->log_callbacks->failed(c->log_v, vec[0], vec[1]); + if(c->log_callbacks->state) + c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED); } static void logentry_moved(disorder_eclient *c, @@ -1233,7 +1224,10 @@ static void logentry_moved(disorder_eclient *c, static void logentry_playing(disorder_eclient *c, int attribute((unused)) nvec, char **vec) { if(!c->log_callbacks->playing) return; + c->state |= DISORDER_PLAYING; c->log_callbacks->playing(c->log_v, vec[0], vec[1]); + if(c->log_callbacks->state) + c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED); } static void logentry_queue(disorder_eclient *c, @@ -1273,7 +1267,10 @@ static void logentry_removed(disorder_eclient *c, static void logentry_scratched(disorder_eclient *c, int attribute((unused)) nvec, char **vec) { if(!c->log_callbacks->scratched) return; + c->state &= ~DISORDER_PLAYING; c->log_callbacks->scratched(c->log_v, vec[0], vec[1]); + if(c->log_callbacks->state) + c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED); } static const struct { @@ -1300,7 +1297,7 @@ static void logentry_state(disorder_eclient *c, break; } if(!c->log_callbacks->state) return; - c->log_callbacks->state(c->log_v, c->statebits); + c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED); } static void logentry_volume(disorder_eclient *c, diff --git a/lib/eclient.h b/lib/eclient.h index d898ca8..6fdb386 100644 --- a/lib/eclient.h +++ b/lib/eclient.h @@ -106,9 +106,27 @@ typedef struct disorder_eclient_log_callbacks { /** @brief Random play is enabled */ #define DISORDER_RANDOM_ENABLED 0x00000002 -/** @brief Track is paused */ +/** @brief Track is paused + * + * This is only meaningful if @ref DISORDER_PLAYING is set + */ #define DISORDER_TRACK_PAUSED 0x00000004 +/** @brief Track is playing + * + * This can be set even if the current track is paused (in which case @ref + * DISORDER_TRACK_PAUSED) will also be set. + */ +#define DISORDER_PLAYING 0x00000008 + +/** @brief Connected to server + * + * By connected it is meant that commands have a reasonable chance of being + * processed soon, not merely that a TCP connection exists - for instance if + * the client is still authenticating then that does not count as connected. + */ +#define DISORDER_CONNECTED 0x00000010 + struct queue_entry; struct kvp; struct sink; @@ -142,7 +160,7 @@ disorder_eclient *disorder_eclient_new(const disorder_eclient_callbacks *cb, void disorder_eclient_close(disorder_eclient *c); /* Close C */ -int disorder_eclient_connected(const disorder_eclient *c); +unsigned long disorder_eclient_state(const disorder_eclient *c); void disorder_eclient_polled(disorder_eclient *c, unsigned mode); /* Should be called when c's FD is readable and/or writable, and in any case -- [mdw]