chiark / gitweb /
_eclient_state is more general than _eclient_connected
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 30 Sep 2007 17:31:50 +0000 (18:31 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 30 Sep 2007 17:31:50 +0000 (18:31 +0100)
disobedience/choose.c
disobedience/control.c
disobedience/disobedience.c
disobedience/menu.c
disobedience/queue.c
lib/eclient.c
lib/eclient.h

index 6db94229d1aea68e852f06b3de96fd11a5fe1795..cc9f3acdc94efef4419b59370af14ae7d05eeda3 100644 (file)
@@ -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) {
index f65c78ca10bad6b1f2f51214ba4938feab0373ff..fb428013ca768d75ae3656b9c2bca28f60ea40be 100644 (file)
@@ -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 */
index 3c3fae6b6346f669e4d2890694c6fd1f7e3a1209..0e7805b7730506adbc4c28101b28a30b8593ac42 100644 (file)
@@ -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);
   }
index 45693853cb92be39efd68c5d2e69636b52435ccb..3347a51304a4f7806409deef0ea26f71418a9522 100644 (file)
@@ -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));
 }
index e4c38629f5b2dbab445a4aefaf282f69be61934e..6ef558db87f8212e96411def14d1a279b6905b12 100644 (file)
@@ -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) {
index 6bbb530b0800c5bfb54c15cd23e69f634d4e9da4..d0cf661841210c6534e4fadf0634b7103cbe8383 100644 (file)
@@ -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,
index d898ca8ee51203bf3aa7bec6d2376f5e19ce005a..6fdb3869c35de665a835d1c19382799442085189 100644 (file)
@@ -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