chiark / gitweb /
more control state fiddling, starts nicely when server down now
authorRichard Kettlewell <rjk@greenend.org.uk>
Mon, 1 Oct 2007 10:08:05 +0000 (11:08 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Mon, 1 Oct 2007 10:08:05 +0000 (11:08 +0100)
disobedience/client.c
disobedience/control.c
disobedience/disobedience.c
disobedience/disobedience.h
disobedience/log.c
lib/eclient.c

index 869bcf3..ed93d1b 100644 (file)
@@ -110,8 +110,6 @@ static void gtkclient_poll(void *u,
 static void gtkclient_comms_error(void attribute((unused)) *u,
                                  const char *msg) {
   D(("gtkclient_comms_error %s", msg));
-  /* Control buttons might have become unusable */
-  control_update();
   menu_update(-1);
   gtk_label_set_text(GTK_LABEL(report_label), msg);
 }
@@ -137,7 +135,6 @@ static void gtkclient_report(void attribute((unused)) *u,
   if(!msg)
     /* We're idle - clear the report line */
     gtk_label_set_text(GTK_LABEL(report_label), "");
-  control_update();
   menu_update(-1);
 }
 
index ba5b202..6efadda 100644 (file)
@@ -51,8 +51,6 @@ static void volume_adjusted(GtkAdjustment *a, gpointer user_data);
 static gchar *format_volume(GtkScale *scale, gdouble value);
 static gchar *format_balance(GtkScale *scale, gdouble value);
 
-static void control_monitor(void *u);
-
 /* Control bar ------------------------------------------------------------- */
 
 static int suppress_set_volume;
@@ -87,6 +85,15 @@ static struct icon {
 
 GtkAdjustment *volume_adj, *balance_adj;
 
+/** @brief Called whenever last_state changes in any way */
+static void control_monitor(void attribute((unused)) *u) {
+  int n;
+
+  D(("control_monitor"));
+  for(n = 0; n < NICONS; ++n)
+    icons[n].update(&icons[n]);
+}
+
 /* Create the control bar */
 GtkWidget *control_widget(void) {
   GtkWidget *hbox = gtk_hbox_new(FALSE, 1), *vbox;
@@ -158,12 +165,11 @@ GtkWidget *control_widget(void) {
   return hbox;
 }
 
-/** @brief Update the control bar after some kind of state change */
-void control_update(void) {
+/** @brief Update the volume control when it changes */
+void volume_update(void) {
   double l, r;
 
-  D(("control_update"));
-  /*control_monitor(0, disorder_eclient_state(client));*/
+  D(("volume_update"));
   l = volume_l / 100.0;
   r = volume_r / 100.0;
   ++suppress_set_volume;
@@ -172,13 +178,6 @@ void control_update(void) {
   --suppress_set_volume;
 }
 
-static void control_monitor(void attribute((unused)) *u) {
-  int n;
-
-  for(n = 0; n < NICONS; ++n)
-    icons[n].update(&icons[n]);
-}
-
 /** @brief Update the state of one of the control icons
  * @param icon Target icon
  * @param visible True if this version of the button should be visible
index f4221f8..bb06347 100644 (file)
@@ -337,7 +337,6 @@ int main(int argc, char **argv) {
   if(!(client = gtkclient())
      || !(logclient = gtkclient()))
     return 1;                           /* already reported an error */
-  disorder_eclient_log(logclient, &log_callbacks, 0);
   /* periodic operations (e.g. expiring the cache) */
 #if MDEBUG || MTRACK
   g_timeout_add(5000/*milliseconds*/, periodic, 0);
@@ -352,14 +351,14 @@ int main(int argc, char **argv) {
   /* reset styles now everything has its name */
   gtk_rc_reset_styles(gtk_settings_get_for_screen(gdk_screen_get_default()));
   gtk_widget_show_all(toplevel);
-  /* set initial control button visibility/usability */
-  control_update();
   /* issue a NOP every so often */
   g_timeout_add_full(G_PRIORITY_LOW,
                      1000/*interval, ms*/,
                      maybe_send_nop,
                      0/*data*/,
                      0/*notify*/);
+  /* Start monitoring the log */
+  disorder_eclient_log(logclient, &log_callbacks, 0);
   D(("enter main loop"));
   MTAG("misc");
   g_main_loop_run(mainloop);
index 6727ba2..53b4deb 100644 (file)
@@ -138,9 +138,8 @@ void menu_update(int page);
 GtkWidget *control_widget(void);
 /* Make the controls widget */
 
-void control_update(void);
-/* Called whenever we think the control widget needs changing */
-
+void volume_update(void);
+/* Called whenever we think the volume control has changed */
 
 /* Queue/Recent */
 
index ccb883a..d5878c9 100644 (file)
@@ -64,27 +64,20 @@ void all_update(void) {
   playing_update();
   queue_update();
   recent_update();
-  control_update();
+  volume_update();
 }
 
 static void log_connected(void attribute((unused)) *v) {
-  struct callbackdata *cbd;
-
   /* Don't know what we might have missed while disconnected so update
    * everything.  We get this at startup too and this is how we do the initial
    * state fetch. */
   all_update();
-  /* Re-get the volume */
-  cbd = xmalloc(sizeof *cbd);
-  cbd->onerror = 0;
-  disorder_eclient_volume(client, log_volume, -1, -1, cbd);
 }
 
 static void log_completed(void attribute((unused)) *v,
                           const char attribute((unused)) *track) {
   playing = 0;
   playing_update();
-  control_update();
 }
 
 static void log_failed(void attribute((unused)) *v,
@@ -92,7 +85,6 @@ static void log_failed(void attribute((unused)) *v,
                        const char attribute((unused)) *status) {
   playing = 0;
   playing_update();
-  control_update();
 }
 
 static void log_moved(void attribute((unused)) *v,
@@ -105,7 +97,6 @@ static void log_playing(void attribute((unused)) *v,
                         const char attribute((unused)) *user) {
   playing = 1;
   playing_update();
-  control_update();
   /* we get a log_removed() anyway so we don't need to update_queue() from
    * here */
 }
@@ -136,15 +127,22 @@ static void log_scratched(void attribute((unused)) *v,
                           const char attribute((unused)) *user) {
   playing = 0;
   playing_update();
-  control_update();
 }
 
 static void log_state(void attribute((unused)) *v,
                       unsigned long state) {
   const struct monitor *m;
-  const unsigned long changes = state ^ last_state;
-
-  D(("log_state %s", disorder_eclient_interpret_state(state)));
+  unsigned long changes = state ^ last_state;
+  static int first = 1;
+  
+  if(first) {
+    changes = -1UL;
+    first = 0;
+  }
+  D(("log_state old=%s new=%s changed=%s",
+     disorder_eclient_interpret_state(last_state),
+     disorder_eclient_interpret_state(state),
+     disorder_eclient_interpret_state(changes)));
   last_state = state;
   /* Tell anything that cares about the state change */
   for(m = monitors; m; m = m->next) {
@@ -162,7 +160,7 @@ static void log_volume(void attribute((unused)) *v,
   if(volume_l != l || volume_r != r) {
     volume_l = l;
     volume_r = r;
-    control_update();
+    volume_update();
   }
 }
 
index d12cf2b..8efefb6 100644 (file)
@@ -249,6 +249,9 @@ void disorder_eclient_close(disorder_eclient *c) {
   /* We'll need to resend all operations */
   for(op = c->ops; op; op = op->next)
     op->sent = 0;
+  /* Drop our use a hint that we're disconnected */
+  if(c->log_callbacks && c->log_callbacks->state)
+    c->log_callbacks->state(c->log_v, c->statebits);
 }
 
 /** @brief Return current state */
@@ -488,6 +491,8 @@ static void maybe_connected(disorder_eclient *c) {
     c->state = state_connected;
     byte_xasprintf(&r, "connected to %s", c->ident);
     c->callbacks->report(c->u, r);
+    /* If this is a log client we expect to get a bunch of updates from the
+     * server straight away */
   }
 }
 
@@ -1146,6 +1151,9 @@ int disorder_eclient_nop(disorder_eclient *c,
  * Once a client is being used for logging it cannot be used for anything else.
  * There is magic in authuser_opcallback() to re-submit the @c log command
  * after reconnection.
+ *
+ * NB that the @c state callback may be called from within this function,
+ * i.e. not solely later on from the event loop callback.
  */
 int disorder_eclient_log(disorder_eclient *c,
                          const disorder_eclient_log_callbacks *callbacks,
@@ -1153,6 +1161,9 @@ int disorder_eclient_log(disorder_eclient *c,
   if(c->log_callbacks) return -1;
   c->log_callbacks = callbacks;
   c->log_v = v;
+  /* Repoort initial state */
+  if(c->log_callbacks->state)
+    c->log_callbacks->state(c->log_v, c->statebits);
   stash_command(c, 0/*queuejump*/, log_opcallback, 0/*completed*/, v,
                 "log", (char *)0);
   return 0;
@@ -1331,6 +1342,8 @@ char *disorder_eclient_interpret_state(unsigned long statebits) {
 #define NBITS (sizeof bits / sizeof *bits)
 
   dynstr_init(d);
+  if(!statebits)
+    dynstr_append(d, '0');
   for(n = 0; n < NBITS; ++n)
     if(statebits & bits[n].bit) {
       if(d->nvec)