X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/53fa91bb028fc115847700f9f3640f1b107c4592..439c12ca8967200d8762a83c02434ea0c319c5ed:/disobedience/queue.c diff --git a/disobedience/queue.c b/disobedience/queue.c index 7240417..e2c06a4 100644 --- a/disobedience/queue.c +++ b/disobedience/queue.c @@ -94,6 +94,15 @@ static GtkWidget *column_length(const struct queuelike *ql, const struct queue_entry *q, const char *data); static int draggable_row(const struct queue_entry *q); +static void recent_changed(const char *event, + void *eventdata, + void *callbackdata); +static void added_changed(const char *event, + void *eventdata, + void *callbackdata); +static void queue_changed(const char *event, + void *eventdata, + void *callbackdata); static const struct tabtype tabtype_queue; /* forward */ @@ -272,37 +281,33 @@ static void namepart_completed_or_failed(void) { } } -/** @brief Called when A namepart lookup has completed */ +/** @brief Called when a namepart lookup has completed */ static void namepart_completed(void *v, const char *error, const char *value) { if(error) { gtk_label_set_text(GTK_LABEL(report_label), error); } else { - cache_put(&cachetype_string, v, value); + const char *key = v; + + cache_put(&cachetype_string, key, value); ++namepart_completions_deferred; } namepart_completed_or_failed(); } /** @brief Called when a length lookup has completed */ -static void length_completed(void *v, long l) { - struct callbackdata *cbd = v; - long *value; - - D(("namepart_completed")); - value = xmalloc(sizeof *value); - *value = l; - cache_put(&cachetype_integer, cbd->u.key, value); - ++namepart_completions_deferred; - namepart_completed_or_failed(); -} - -/** @brief Called when a length or namepart lookup has failed */ -static void namepart_protocol_error( - struct callbackdata attribute((unused)) *cbd, - int attribute((unused)) code, - const char *msg) { - D(("namepart_protocol_error")); - gtk_label_set_text(GTK_LABEL(report_label), msg); +static void length_completed(void *v, const char *error, long l) { + if(error) + gtk_label_set_text(GTK_LABEL(report_label), error); + else { + const char *key = v; + long *value; + + D(("namepart_completed")); + value = xmalloc(sizeof *value); + *value = l; + cache_put(&cachetype_integer, key, value); + ++namepart_completions_deferred; + } namepart_completed_or_failed(); } @@ -360,7 +365,6 @@ void namepart_update(const char *track, static long getlength(const char *track) { char *key; const long *value; - struct callbackdata *cbd; static const long bogus = -1; D(("getlength %s", track)); @@ -370,10 +374,7 @@ static long getlength(const char *track) { D(("deferring..."));; cache_put(&cachetype_integer, key, value = &bogus); ++namepart_lookups_outstanding; - cbd = xmalloc(sizeof *cbd); - cbd->onerror = namepart_protocol_error; - cbd->u.key = key; - disorder_eclient_length(client, length_completed, track, cbd); + disorder_eclient_length(client, length_completed, track, key); } return *value; } @@ -1049,32 +1050,40 @@ static void redisplay_queue(struct queuelike *ql) { } /** @brief Called with new queue/recent contents */ -static void queuelike_completed(void *v, struct queue_entry *q) { - struct callbackdata *cbd = v; - struct queuelike *ql = cbd->u.ql; - - D(("queuelike_complete")); - /* Install the new queue */ - update_queue(ql, ql->fixup ? ql->fixup(q) : q); - /* Update the display */ - redisplay_queue(ql); - if(ql->notify) - ql->notify(); - /* Update sensitivity of main menu items */ - menu_update(-1); +static void queuelike_completed(void *v, + const char *error, + struct queue_entry *q) { + if(error) + popup_protocol_error(0, error); + else { + struct queuelike *const ql = v; + + D(("queuelike_complete")); + /* Install the new queue */ + update_queue(ql, ql->fixup ? ql->fixup(q) : q); + /* Update the display */ + redisplay_queue(ql); + if(ql->notify) + ql->notify(); + /* Update sensitivity of main menu items */ + menu_update(-1); + } } /** @brief Called with a new currently playing track */ static void playing_completed(void attribute((unused)) *v, + const char *error, struct queue_entry *q) { - struct callbackdata cbd; - D(("playing_completed")); - playing_track = q; - /* Record when we got the playing track data so we know how old the 'sofar' - * field is */ - time(&last_playing); - cbd.u.ql = &ql_queue; - queuelike_completed(&cbd, actual_queue); + if(error) + popup_protocol_error(0, error); + else { + D(("playing_completed")); + playing_track = q; + /* Record when we got the playing track data so we know how old the 'sofar' + * field is */ + time(&last_playing); + queuelike_completed(&ql_queue, 0, actual_queue); + } } /** @brief Called when the queue is scrolled */ @@ -1375,7 +1384,9 @@ GtkWidget *queue_widget(void) { g_timeout_add(1000/*ms*/, adjust_sofar, 0); /* Arrange a callback whenever the playing state changes */ register_monitor(playing_update, 0, DISORDER_PLAYING|DISORDER_TRACK_PAUSED); - register_reset(queue_update); + event_register("queue-changed", + queue_changed, + 0); /* We pass choose_update() as our notify function since the choose screen * marks tracks that are playing/in the queue. */ return queuelike(&ql_queue, fixup_queue, choose_update, queue_menu, @@ -1387,15 +1398,12 @@ GtkWidget *queue_widget(void) { * Called when a track is added to the queue, removed from the queue (by user * cmmand or because it is to be played) or moved within the queue */ -void queue_update(void) { - struct callbackdata *cbd; - - D(("queue_update")); - cbd = xmalloc(sizeof *cbd); - cbd->onerror = 0; - cbd->u.ql = &ql_queue; +void queue_changed(const char attribute((unused)) *event, + void attribute((unused)) *eventdata, + void attribute((unused)) *callbackdata) { + D(("queue_changed")); gtk_label_set_text(GTK_LABEL(report_label), "updating queue"); - disorder_eclient_queue(client, queuelike_completed, cbd); + disorder_eclient_queue(client, queuelike_completed, &ql_queue); } /* Recently played tracks -------------------------------------------------- */ @@ -1431,7 +1439,9 @@ static struct queue_menuitem recent_menu[] = { /** @brief Create the recently-played list */ GtkWidget *recent_widget(void) { D(("recent_widget")); - register_reset(recent_update); + event_register("recent-changed", + recent_changed, + 0); return queuelike(&ql_recent, fixup_recent, 0, recent_menu, maincolumns, NMAINCOLUMNS); } @@ -1440,15 +1450,12 @@ GtkWidget *recent_widget(void) { * * Called whenever a track is added to it or removed from it. */ -void recent_update(void) { - struct callbackdata *cbd; - - D(("recent_update")); - cbd = xmalloc(sizeof *cbd); - cbd->onerror = 0; - cbd->u.ql = &ql_recent; +static void recent_changed(const char attribute((unused)) *event, + void attribute((unused)) *eventdata, + void attribute((unused)) *callbackdata) { + D(("recent_changed")); gtk_label_set_text(GTK_LABEL(report_label), "updating recently played list"); - disorder_eclient_recent(client, queuelike_completed, cbd); + disorder_eclient_recent(client, queuelike_completed, &ql_recent); } /* Newly added tracks ------------------------------------------------------ */ @@ -1465,7 +1472,7 @@ static struct queue_menuitem added_menu[] = { /** @brief Create the newly-added list */ GtkWidget *added_widget(void) { D(("added_widget")); - register_reset(added_update); + event_register("added-changed", added_changed, 0); return queuelike(&ql_added, 0/*fixup*/, 0/*notify*/, added_menu, addedcolumns, NADDEDCOLUMNS); } @@ -1476,34 +1483,40 @@ GtkWidget *added_widget(void) { * disobedience/queue.c requires @ref queue_entry structures with a valid and * unique @c id field. This function fakes it. */ -static void new_completed(void *v, int nvec, char **vec) { - struct queue_entry *q, *qh, *qlast = 0, **qq = &qh; - int n; - - for(n = 0; n < nvec; ++n) { - q = xmalloc(sizeof *q); - q->prev = qlast; - q->track = vec[n]; - q->id = vec[n]; - *qq = q; - qq = &q->next; - qlast = q; +static void new_completed(void *v, + const char *error, + int nvec, char **vec) { + if(error) + popup_protocol_error(0, error); + else { + struct queuelist *ql = v; + /* Convert the vector result to a queue linked list */ + struct queue_entry *q, *qh, *qlast = 0, **qq = &qh; + int n; + + for(n = 0; n < nvec; ++n) { + q = xmalloc(sizeof *q); + q->prev = qlast; + q->track = vec[n]; + q->id = vec[n]; + *qq = q; + qq = &q->next; + qlast = q; + } + *qq = 0; + queuelike_completed(ql, 0, qh); } - *qq = 0; - queuelike_completed(v, qh); } /** @brief Update the newly-added list */ -void added_update(void) { - struct callbackdata *cbd; - D(("added_updae")); +static void added_changed(const char attribute((unused)) *event, + void attribute((unused)) *eventdata, + void attribute((unused)) *callbackdata) { + D(("added_changed")); - cbd = xmalloc(sizeof *cbd); - cbd->onerror = 0; - cbd->u.ql = &ql_added; gtk_label_set_text(GTK_LABEL(report_label), "updating newly added track list"); - disorder_eclient_new_tracks(client, new_completed, 0/*all*/, cbd); + disorder_eclient_new_tracks(client, new_completed, 0/*all*/, &ql_added); } /* Main menu plumbing ------------------------------------------------------ */