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 */
}
}
-/** @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();
}
static long getlength(const char *track) {
char *key;
const long *value;
- struct callbackdata *cbd;
static const long bogus = -1;
D(("getlength %s", 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;
}
return q;
}
+static void move_completed(void attribute((unused)) *v,
+ const char *error) {
+ if(error)
+ popup_protocol_error(0, error);
+}
+
/** @brief Called when data is dropped */
static gboolean queue_drag_drop(GtkWidget attribute((unused)) *widget,
GdkDragContext *drag_context,
if(q != playing_track && selection_selected(ql->selection, q->id))
vector_append(&vec, (char *)q->id);
disorder_eclient_moveafter(client, id, vec.nvec, (const char **)vec.vec,
- 0/*completed*/, 0/*v*/);
+ move_completed, 0/*v*/);
gtk_drag_finish(drag_context, TRUE, TRUE, when);
/* Destroy dropzones */
remove_drag_targets(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 */
&& selection_selected(ql->selection, playing_track->id));
}
+/** @brief Called when disorder_eclient_scratch completes */
+static void scratch_completed(void attribute((unused)) *v,
+ const char *error) {
+ if(error)
+ popup_protocol_error(0, error);
+}
+
/** @brief Scratch the playing track */
static void scratch_activate(GtkMenuItem attribute((unused)) *menuitem,
gpointer attribute((unused)) user_data) {
if(playing_track)
- disorder_eclient_scratch(client, playing_track->id, 0, 0);
+ disorder_eclient_scratch(client, playing_track->id, scratch_completed, 0);
}
/** @brief Determine whether the remove option should be sensitive */
|| count_selected_nonplaying(ql)));
}
+static void remove_completed(void attribute((unused)) *v,
+ const char *error) {
+ if(error)
+ popup_protocol_error(0, error);
+}
+
/** @brief Remove selected track(s) */
static void remove_activate(GtkMenuItem attribute((unused)) *menuitem,
gpointer user_data) {
/* Remove selected tracks */
for(q = ql->q; q; q = q->next)
if(selection_selected(ql->selection, q->id) && q != playing_track)
- disorder_eclient_remove(client, q->id, 0, 0);
+ disorder_eclient_remove(client, q->id, move_completed, 0);
} else if(q)
/* Remove just the hovered track */
- disorder_eclient_remove(client, q->id, 0, 0);
+ disorder_eclient_remove(client, q->id, remove_completed, 0);
}
/** @brief Determine whether the properties menu option should be sensitive */
/* Play selected tracks */
for(q = ql->q; q; q = q->next)
if(selection_selected(ql->selection, q->id))
- disorder_eclient_play(client, q->track, 0, 0);
+ disorder_eclient_play(client, q->track, play_completed, 0);
} else if(q)
/* Nothing is selected, so play the hovered track */
- disorder_eclient_play(client, q->track, 0, 0);
+ disorder_eclient_play(client, q->track, play_completed, 0);
}
/* The queue --------------------------------------------------------------- */
* We monitor pause/resume as well as whether the track is playing in order to
* keep the time played so far up to date correctly. See playing_completed().
*/
-static void playing_update(void attribute((unused)) *v) {
- D(("playing_update"));
+static void playing_changed(const char attribute((unused)) *event,
+ void attribute((unused)) *evendata,
+ void attribute((unused)) *callbackdata) {
+ D(("playing_changed"));
gtk_label_set_text(GTK_LABEL(report_label), "updating playing track");
disorder_eclient_playing(client, playing_completed, 0);
}
/* Arrange periodic update of the so-far played field */
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("playing-changed", playing_changed, 0);
+ event_register("pause-changed", playing_changed, 0);
+ 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,
* 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 -------------------------------------------------- */
/** @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);
}
*
* 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 ------------------------------------------------------ */
/** @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);
}
* 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 ------------------------------------------------------ */