From 6d1302f09d1a6958f3cddfd3c6564ee2c0b4813a Mon Sep 17 00:00:00 2001 Message-Id: <6d1302f09d1a6958f3cddfd3c6564ee2c0b4813a.1714126379.git.mdw@distorted.org.uk> From: Mark Wooding Date: Mon, 1 Oct 2007 11:08:05 +0100 Subject: [PATCH] more control state fiddling, starts nicely when server down now Organization: Straylight/Edgeware From: Richard Kettlewell --- disobedience/client.c | 3 --- disobedience/control.c | 25 ++++++++++++------------- disobedience/disobedience.c | 5 ++--- disobedience/disobedience.h | 5 ++--- disobedience/log.c | 28 +++++++++++++--------------- lib/eclient.c | 13 +++++++++++++ 6 files changed, 42 insertions(+), 37 deletions(-) diff --git a/disobedience/client.c b/disobedience/client.c index 869bcf3..ed93d1b 100644 --- a/disobedience/client.c +++ b/disobedience/client.c @@ -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); } diff --git a/disobedience/control.c b/disobedience/control.c index ba5b202..6efadda 100644 --- a/disobedience/control.c +++ b/disobedience/control.c @@ -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 diff --git a/disobedience/disobedience.c b/disobedience/disobedience.c index f4221f8..bb06347 100644 --- a/disobedience/disobedience.c +++ b/disobedience/disobedience.c @@ -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); diff --git a/disobedience/disobedience.h b/disobedience/disobedience.h index 6727ba2..53b4deb 100644 --- a/disobedience/disobedience.h +++ b/disobedience/disobedience.h @@ -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 */ diff --git a/disobedience/log.c b/disobedience/log.c index ccb883a..d5878c9 100644 --- a/disobedience/log.c +++ b/disobedience/log.c @@ -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(); } } diff --git a/lib/eclient.c b/lib/eclient.c index d12cf2b..8efefb6 100644 --- a/lib/eclient.c +++ b/lib/eclient.c @@ -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) -- [mdw]