aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lyrics.c55
-rw-r--r--src/lyrics.h15
-rw-r--r--src/screen_lyrics.c55
3 files changed, 56 insertions, 69 deletions
diff --git a/src/lyrics.c b/src/lyrics.c
index 917344701..7a6124b69 100644
--- a/src/lyrics.c
+++ b/src/lyrics.c
@@ -32,7 +32,8 @@ static GPtrArray *plugins;
struct lyrics_loader {
char *artist, *title;
- enum lyrics_loader_result result;
+ lyrics_callback_t callback;
+ void *callback_data;
guint next_plugin;
@@ -99,7 +100,7 @@ lyrics_eof(struct lyrics_loader *loader)
lyrics_next_plugin(loader);
} else {
- loader->result = LYRICS_SUCCESS;
+ loader->callback(loader->data, loader->callback_data);
}
}
@@ -112,7 +113,6 @@ lyrics_data(mpd_unused GIOChannel *source,
ssize_t nbytes;
assert(loader != NULL);
- assert(loader->result = LYRICS_BUSY);
assert(loader->fd >= 0);
assert(loader->pid > 0);
assert(source == loader->channel);
@@ -134,6 +134,28 @@ lyrics_data(mpd_unused GIOChannel *source,
return TRUE;
}
+/**
+ * This is a timer callback which calls the lyrics callback "some
+ * timer later". This solves the problem that lyrics_load() may fail
+ * immediately, leaving its return value in an undefined state.
+ * Instead, install a timer which calls the lyrics callback in the
+ * moment after.
+ */
+static gboolean
+lyrics_delayed_fail(gpointer data)
+{
+ struct lyrics_loader *loader = data;
+
+ assert(loader != NULL);
+ assert(loader->fd < 0);
+ assert(loader->pid < 0);
+ assert(loader->data == NULL);
+
+ loader->callback(NULL, loader->callback_data);
+
+ return FALSE;
+}
+
static int
lyrics_start_plugin(struct lyrics_loader *loader, const char *plugin_path)
{
@@ -141,7 +163,6 @@ lyrics_start_plugin(struct lyrics_loader *loader, const char *plugin_path)
pid_t pid;
assert(loader != NULL);
- assert(loader->result == LYRICS_BUSY);
assert(loader->pid < 0);
assert(loader->fd < 0);
assert(loader->data == NULL);
@@ -198,7 +219,7 @@ lyrics_next_plugin(struct lyrics_loader *loader)
if (loader->next_plugin >= plugins->len) {
/* no plugins left */
- loader->result = LYRICS_FAILED;
+ g_timeout_add(0, lyrics_delayed_fail, loader);
return;
}
@@ -206,13 +227,14 @@ lyrics_next_plugin(struct lyrics_loader *loader)
ret = lyrics_start_plugin(loader, plugin_path);
if (ret < 0) {
/* system error */
- loader->result = LYRICS_FAILED;
+ g_timeout_add(0, lyrics_delayed_fail, loader);
return;
}
}
struct lyrics_loader *
-lyrics_load(const char *artist, const char *title)
+lyrics_load(const char *artist, const char *title,
+ lyrics_callback_t callback, void *data)
{
struct lyrics_loader *loader = g_new(struct lyrics_loader, 1);
@@ -224,7 +246,8 @@ lyrics_load(const char *artist, const char *title)
loader->artist = g_strdup(artist);
loader->title = g_strdup(title);
- loader->result = LYRICS_BUSY;
+ loader->callback = callback;
+ loader->data = data;
loader->next_plugin = 0;
loader->pid = -1;
loader->fd = -1;
@@ -254,19 +277,3 @@ lyrics_free(struct lyrics_loader *loader)
if (loader->data != NULL)
g_string_free(loader->data, TRUE);
}
-
-enum lyrics_loader_result
-lyrics_result(struct lyrics_loader *loader)
-{
- return loader->result;
-}
-
-const GString *
-lyrics_get(struct lyrics_loader *loader)
-{
- assert(loader->result == LYRICS_SUCCESS);
- assert(loader->pid < 0);
- assert(loader->data != NULL);
-
- return loader->data;
-}
diff --git a/src/lyrics.h b/src/lyrics.h
index 34380c344..613ccb338 100644
--- a/src/lyrics.h
+++ b/src/lyrics.h
@@ -21,11 +21,7 @@
#include <glib.h>
-enum lyrics_loader_result {
- LYRICS_SUCCESS,
- LYRICS_BUSY,
- LYRICS_FAILED
-};
+typedef void (*lyrics_callback_t)(const GString *result, void *data);
struct lyrics_loader;
@@ -34,15 +30,10 @@ void lyrics_init(void);
void lyrics_deinit(void);
struct lyrics_loader *
-lyrics_load(const char *artist, const char *title);
+lyrics_load(const char *artist, const char *title,
+ lyrics_callback_t callback, void *callback_data);
void
lyrics_free(struct lyrics_loader *loader);
-enum lyrics_loader_result
-lyrics_result(struct lyrics_loader *loader);
-
-const GString *
-lyrics_get(struct lyrics_loader *loader);
-
#endif
diff --git a/src/screen_lyrics.c b/src/screen_lyrics.c
index cfc658939..9b9ea03a2 100644
--- a/src/screen_lyrics.c
+++ b/src/screen_lyrics.c
@@ -76,15 +76,15 @@ screen_lyrics_clear(void)
{
guint i;
- assert(current.loader == NULL ||
- lyrics_result(current.loader) == LYRICS_SUCCESS);
-
for (i = 0; i < current.lines->len; ++i)
g_free(g_ptr_array_index(current.lines, i));
g_ptr_array_set_size(current.lines, 0);
}
+static const char *
+list_callback(unsigned idx, int *highlight, void *data);
+
static void
screen_lyrics_set(const GString *str)
{
@@ -122,32 +122,30 @@ screen_lyrics_set(const GString *str)
if (*p != 0)
g_ptr_array_add(current.lines, g_strdup(p));
+
+ /* paint new data */
+
+ if (get_cur_mode_id() == 104) { /* XXX don't use the literal number */
+ lw->clear = 1;
+ list_window_paint(lw, list_callback, NULL);
+ wrefresh(lw->w);
+
+ /* XXX repaint the screen title */
+ }
}
-static int
-screen_lyrics_poll(void)
+static void
+screen_lyrics_callback(const GString *result, mpd_unused void *data)
{
assert(current.loader != NULL);
- switch (lyrics_result(current.loader)) {
- case LYRICS_BUSY:
- return 0;
-
- case LYRICS_SUCCESS:
- screen_lyrics_set(lyrics_get(current.loader));
- lyrics_free(current.loader);
- current.loader = NULL;
- return 1;
-
- case LYRICS_FAILED:
- lyrics_free(current.loader);
- current.loader = NULL;
+ if (result != NULL)
+ screen_lyrics_set(result);
+ else
screen_status_message (_("No lyrics"));
- return -1;
- }
- assert(0);
- return -1;
+ lyrics_free(current.loader);
+ current.loader = NULL;
}
static void
@@ -168,7 +166,8 @@ screen_lyrics_load(struct mpd_song *song)
strfsong(buffer, sizeof(buffer), "%title%", song);
current.title = g_strdup(buffer);
- current.loader = lyrics_load(current.artist, current.title);
+ current.loader = lyrics_load(current.artist, current.title,
+ screen_lyrics_callback, NULL);
}
static void lyrics_paint(screen_t *screen, mpdclient_t *c);
@@ -246,8 +245,6 @@ lyrics_open(mpd_unused screen_t *screen, mpdclient_t *c)
{
if (c->song != NULL && c->song != current.song)
screen_lyrics_load(c->song);
- else if (current.loader != NULL)
- screen_lyrics_poll();
}
@@ -292,14 +289,6 @@ lyrics_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
return 1;
switch(cmd) {
- case CMD_SELECT:
- /* XXX */
- if (current.loader != NULL) {
- int ret = screen_lyrics_poll();
- if (ret != 0)
- lyrics_paint(NULL, NULL);
- }
- return 1;
case CMD_INTERRUPT:
if (current.loader != NULL) {
screen_lyrics_abort();