}
/** @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 */
* 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;
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 -------------------------------------------------- */
* 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;
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 ------------------------------------------------------ */
* 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) {
+static void new_completed(void attribute((unused)) *v, int nvec, char **vec) {
struct queue_entry *q, *qh, *qlast = 0, **qq = &qh;
int n;
qlast = q;
}
*qq = 0;
- queuelike_completed(v, qh);
+ queuelike_completed(&ql_added, 0, qh);
}
/** @brief Update the newly-added list */
void added_update(void) {
struct callbackdata *cbd;
- D(("added_updae"));
+ D(("added_update"));
cbd = xmalloc(sizeof *cbd);
cbd->onerror = 0;
/* for commands that expect a queue dump */
static void queue_response_opcallback(disorder_eclient *c,
struct operation *op) {
+ disorder_eclient_queue_response *const completed
+ = (disorder_eclient_queue_response *)op->completed;
int n;
+ int parse_failed = 0;
struct queue_entry *q, *qh = 0, **qtail = &qh, *qlast = 0;
D(("queue_response_callback"));
*qtail = q;
qtail = &q->next;
qlast = q;
- }
+ } else
+ parse_failed = 1;
}
- if(op->completed)
- ((disorder_eclient_queue_response *)op->completed)(op->v, qh);
+ /* Currently we pass the partial queue to the callback along with the
+ * error. This might not be very useful in practice... */
+ if(parse_failed)
+ completed(op->v, "cannot parse result", qh);
+ else
+ completed(op->v, 0, qh);
} else
- /* TODO don't use protocol_error here */
- protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+ completed(op->v, errorstring(c), 0);
}
/* for 'playing' */
static void playing_response_opcallback(disorder_eclient *c,
struct operation *op) {
+ disorder_eclient_queue_response *const completed
+ = (disorder_eclient_queue_response *)op->completed;
struct queue_entry *q;
D(("playing_response_callback"));
case 2:
if(queue_unmarshall(q = xmalloc(sizeof *q), c->line + 4,
eclient_queue_error, c))
- return;
+ completed(op->v, "cannot parse result", 0);
+ else
+ completed(op->v, 0, q);
break;
case 9:
- q = 0;
+ completed(op->v, 0, 0);
break;
default:
- /* TODO don't use protocol_error here */
- protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
- return;
+ completed(op->v, errorstring(c), 0);
+ break;
}
- if(op->completed)
- ((disorder_eclient_queue_response *)op->completed)(op->v, q);
} else
- /* TODO don't use protocol_error here */
- protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+ completed(op->v, errorstring(c), 0);
}
/* for commands that expect a list of some sort */
const char *error,
int l, int r);
-typedef void disorder_eclient_queue_response(void *v, struct queue_entry *q);
-/* completion callback for queue/recent listing */
+/** @brief Queue request completion callback
+ * @param v User data
+ * @param error Error string or NULL on success
+ * @param q Head of queue data list
+ *
+ * @p error will be NULL on success. In this case @p q be the (head of the)
+ * result.
+ *
+ * @p error will be non-NULL on failure. In this case @p q may be NULL but
+ * MIGHT also be some subset of the queue. For consistent behavior it should
+ * be ignored in the error case.
+ */
+typedef void disorder_eclient_queue_response(void *v,
+ const char *error,
+ struct queue_entry *q);
typedef void disorder_eclient_list_response(void *v, int nvec, char **vec);
/* completion callback for file listing etc */