X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fscreen_lyrics.c;h=30a89a163973ddaf8f29143bf2bd5c88fdea20f1;hb=299a27c8dee0e7eeab3448ed7cdfe1ac7c97ebaf;hp=4417d138596a9dad125e3b56c9fb8c6c89b80ae7;hpb=0b3bcb6c7f1bb4a633896b8a9936e498570ef8e1;p=ncmpc.git diff --git a/src/screen_lyrics.c b/src/screen_lyrics.c index 4417d13..30a89a1 100644 --- a/src/screen_lyrics.c +++ b/src/screen_lyrics.c @@ -1,8 +1,6 @@ -/* - * $Id: screen_lyrics.c 3355 2006-09-1 17:44:04Z tradiaz $ - * +/* * (c) 2006 by Kalle Wallin - * Tue Aug 1 23:17:38 2006 + * Copyright (C) 2008 Max Kellermann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,175 +17,233 @@ * */ -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#ifndef DISABLE_LYRICS_SCREEN #include -#include "ncmpc.h" +#include "i18n.h" #include "options.h" #include "mpdclient.h" #include "command.h" #include "screen.h" #include "screen_utils.h" -#include "easy_download.h" #include "strfsong.h" -#include "src_lyrics.h" +#include "lyrics.h" +#include "charset.h" +#include "gcc.h" + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +static list_window_t *lw = NULL; + +static const struct mpd_song *next_song; + +static struct { + struct mpd_song *song; -int src_selection; + char *artist, *title; -static void lyrics_paint(screen_t *screen, mpdclient_t *c); + struct lyrics_loader *loader; -FILE *create_lyr_file(char *artist, char *title) + GPtrArray *lines; +} current; + +static void +screen_lyrics_abort(void) { - char path[1024]; + if (current.loader != NULL) { + lyrics_free(current.loader); + current.loader = NULL; + } - snprintf(path, 1024, "%s/.lyrics", - getenv("HOME")); - if(g_access(path, W_OK) != 0) if(mkdir(path, S_IRWXU) != 0) return NULL; + if (current.artist != NULL) { + g_free(current.artist); + current.artist = NULL; + } - snprintf(path, 1024, "%s/.lyrics/%s", - getenv("HOME"), artist); - if(g_access(path, W_OK) != 0) if(mkdir(path, S_IRWXU) != 0) return NULL; + if (current.title != NULL) { + g_free(current.title); + current.artist = NULL; + } - snprintf(path, 1024, "%s/.lyrics/%s/%s.lyric", - getenv("HOME"), artist, title); + if (current.song != NULL) { + mpd_freeSong(current.song); + current.song = NULL; + } +} - return fopen(path, "w"); +static void +screen_lyrics_clear(void) +{ + guint i; + + 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 void +lyrics_paint(void); + +/** + * Repaint and update the screen. + */ +static void +lyrics_repaint(void) +{ + lyrics_paint(); + wrefresh(lw->w); } +/** + * Repaint and update the screen, if it is currently active. + */ +static void +lyrics_repaint_if_active(void) +{ + if (screen_is_visible(&screen_lyrics)) { + lyrics_repaint(); + + /* XXX repaint the screen title */ + } +} -int store_lyr_hd() +static void +screen_lyrics_set(const GString *str) { - char artist[512]; - char title[512]; - static char path[1024]; - FILE *lyr_file; + const char *p, *eol, *next; - get_text_line(&lyr_text, 0, artist, 512); - get_text_line(&lyr_text, 1, title, 512); - artist[strlen(artist)-1] = '\0'; - title[strlen(title)-1] = '\0'; + screen_lyrics_clear(); - snprintf(path, 1024, "%s/.lyrics/%s/%s.lyric", - getenv("HOME"), artist, title); - lyr_file = create_lyr_file(artist, title); - if (lyr_file == NULL) - return -1; + p = str->str; + while ((eol = strchr(p, '\n')) != NULL) { + char *line; + + next = eol + 1; + + /* strip whitespace at end */ + + while (eol > p && (unsigned char)eol[-1] <= 0x20) + --eol; + + /* create copy and append it to current.lines*/ - int i; - char line_buf[1024]; + line = g_malloc(eol - p + 1); + memcpy(line, p, eol - p); + line[eol - p] = 0; - for (i = 3; i <= lyr_text.text->len; i++) { - if(get_text_line(&lyr_text, i, line_buf, 1024) == -1); - fputs(line_buf, lyr_file); + g_ptr_array_add(current.lines, line); + + /* reset control characters */ + + for (eol = line + (eol - p); line < eol; ++line) + if ((unsigned char)*line < 0x20) + *line = ' '; + + p = next; } - fclose(lyr_file); - return 0; -} + if (*p != 0) + g_ptr_array_add(current.lines, g_strdup(p)); + /* paint new data */ + + lyrics_repaint_if_active(); +} -void check_repaint() +static void +screen_lyrics_callback(const GString *result, mpd_unused void *data) { - if(screen_get_id("lyrics") == get_cur_mode_id())lyrics_paint(NULL, NULL); + assert(current.loader != NULL); + + if (result != NULL) + screen_lyrics_set(result); + else + screen_status_message (_("No lyrics")); + + lyrics_free(current.loader); + current.loader = NULL; } +static void +screen_lyrics_load(const struct mpd_song *song) +{ + char buffer[MAX_SONGNAME_LENGTH]; + + assert(song != NULL); + + screen_lyrics_abort(); + screen_lyrics_clear(); + + current.song = mpd_songDup(song); + + strfsong(buffer, sizeof(buffer), "%artist%", song); + current.artist = g_strdup(buffer); -gpointer get_lyr(void *c) + strfsong(buffer, sizeof(buffer), "%title%", song); + current.title = g_strdup(buffer); + + current.loader = lyrics_load(current.artist, current.title, + screen_lyrics_callback, NULL); +} + +static FILE *create_lyr_file(const char *artist, const char *title) { - mpd_Status *status = ((retrieval_spec*)c)->client->status; - mpd_Song *cur = ((retrieval_spec*)c)->client->song; - //mpdclient_update((mpdclient_t*)c); + char path[1024]; - if(!(IS_PAUSED(status->state)||IS_PLAYING(status->state))) { - formed_text_init(&lyr_text); - return NULL; - } + snprintf(path, 1024, "%s/.lyrics", + getenv("HOME")); + mkdir(path, S_IRWXU); + snprintf(path, 1024, "%s/.lyrics/%s - %s.txt", + getenv("HOME"), artist, title); - char artist[MAX_SONGNAME_LENGTH]; - char title[MAX_SONGNAME_LENGTH]; - lock=2; - result = 0; + return fopen(path, "w"); +} - formed_text_init(&lyr_text); +static int store_lyr_hd(void) +{ + FILE *lyr_file; + unsigned i; - strfsong(artist, MAX_SONGNAME_LENGTH, "%artist%", cur); - strfsong(title, MAX_SONGNAME_LENGTH, "%title%", cur); + lyr_file = create_lyr_file(current.artist, current.title); + if (lyr_file == NULL) + return -1; - //write header.. - formed_text_init(&lyr_text); - add_text_line(&lyr_text, artist, 0); - add_text_line(&lyr_text, title, 0); - add_text_line(&lyr_text, "", 0); - add_text_line(&lyr_text, "", 0); + for (i = 0; i < current.lines->len; ++i) + fprintf(lyr_file, "%s\n", + (const char*)g_ptr_array_index(current.lines, i)); - if (((retrieval_spec*)c)->way != -1) /*till it'S of use*/ { - if(get_lyr_by_src (src_selection, artist, title) != 0) { - lock=0; - return NULL; - } - } - /*else{ - if(get_lyr_hd(artist, title) != 0) - { - if(get_lyr_hd(artist, title) != 0) return NULL; - } - else result |= 1; - }*/ - //return NULL; - lw->start = 0; - check_repaint(); - lock = 1; - return &lyr_text; + fclose(lyr_file); + return 0; } static const char * -list_callback(int index, int *highlight, void *data) +list_callback(unsigned idx, mpd_unused int *highlight, mpd_unused void *data) { - static char buf[512]; - - //i think i'ts fine to write it into the 1st line... - if ((index == lyr_text.lines->len && lyr_text.lines->len > 4) || - ((lyr_text.lines->len == 0 || lyr_text.lines->len == 4) && - index == 0)) { - *highlight=3; - src_lyr* selected = g_array_index(src_lyr_stack, src_lyr*, src_selection); - if (selected != NULL) - return selected->description; - return ""; - } + static char buffer[256]; + char *value; - if (index < 2 && lyr_text.lines->len > 4) - *highlight=3; - else if(index >= lyr_text.lines->len || - (index < 4 && index != 0 && lyr_text.lines->len < 5)) { - return ""; - } + if (idx >= current.lines->len) + return NULL; + + value = utf8_to_locale(g_ptr_array_index(current.lines, idx)); + g_strlcpy(buffer, value, sizeof(buffer)); + free(value); - get_text_line(&lyr_text, index, buf, 512); - return buf; + return buffer; } static void -lyrics_init(WINDOW *w, int cols, int rows) +lyrics_screen_init(WINDOW *w, int cols, int rows) { + current.lines = g_ptr_array_new(); lw = list_window_init(w, cols, rows); lw->flags = LW_HIDE_CURSOR; - //lyr_text.lines = g_array_new(FALSE, TRUE, 4); - formed_text_init(&lyr_text); - if (!g_thread_supported()) - g_thread_init(NULL); } static void @@ -201,171 +257,119 @@ static void lyrics_exit(void) { list_window_free(lw); -} + screen_lyrics_abort(); + screen_lyrics_clear(); -static const char * -lyrics_title(char *str, size_t size) -{ - static GString *msg; - if (msg == NULL) - msg = g_string_new (""); - else g_string_erase (msg, 0, -1); - - g_string_append (msg, "Lyrics ["); - - if (src_selection > src_lyr_stack->len - 1) - g_string_append (msg, "No plugin available"); - else { - src_lyr* selected = g_array_index (src_lyr_stack, src_lyr*, src_selection); - if (selected != NULL) - g_string_append (msg, selected->name); - else - g_string_append (msg, "NONE"); - } + g_ptr_array_free(current.lines, TRUE); + current.lines = NULL; +} - if(lyr_text.lines->len == 4) { - if(lock == 1) { - if(!(result & 1)) { - g_string_append (msg, " - "); - if(!(result & 2)) g_string_append (msg, _("No access")); - else if(!(result & 4)||!(result & 16)) g_string_append (msg, _("Not found")); - } - } - if(lock == 2) { - g_string_append (msg, " - "); - g_string_append (msg, _("retrieving")); - } - } +static void +lyrics_open(mpdclient_t *c) +{ + if (next_song == NULL) + next_song = c->song; - g_string_append_c (msg, ']'); + if (next_song != NULL && + (current.song == NULL || + strcmp(next_song->file, current.song->file) != 0)) + screen_lyrics_load(next_song); - return msg->str; + next_song = NULL; } -static void -lyrics_paint(screen_t *screen, mpdclient_t *c) + +static const char * +lyrics_title(char *str, size_t size) { - lw->clear = 1; - list_window_paint(lw, list_callback, NULL); - wrefresh(lw->w); + if (current.loader != NULL) { + snprintf(str, size, "%s (%s)", + _("Lyrics"), _("loading...")); + return str; + } else if (current.artist != NULL && current.title != NULL && + current.lines->len > 0) { + snprintf(str, size, "%s: %s - %s", + _("Lyrics"), + current.artist, current.title); + return str; + } else + return _("Lyrics"); } - static void -lyrics_update(screen_t *screen, mpdclient_t *c) +lyrics_paint(void) { - if( lw->repaint ) { - list_window_paint(lw, list_callback, NULL); - wrefresh(lw->w); - lw->repaint = 0; - } + list_window_paint(lw, list_callback, NULL); } - static int -lyrics_cmd(screen_t *screen, mpdclient_t *c, command_t cmd) +lyrics_cmd(mpdclient_t *c, command_t cmd) { - static retrieval_spec spec; + if (list_window_scroll_cmd(lw, current.lines->len, cmd)) { + lyrics_repaint(); + return 1; + } - lw->repaint=1; switch(cmd) { - case CMD_LIST_NEXT: - if( lw->start+lw->rows < lyr_text.lines->len+1 ) - lw->start++; - return 1; - case CMD_LIST_PREVIOUS: - if( lw->start >0 ) - lw->start--; - return 1; - case CMD_LIST_FIRST: - lw->start = 0; - return 1; - case CMD_LIST_LAST: - lw->start = lyrics_text_rows-lw->rows; - if( lw->start<0 ) - lw->start = 0; - return 1; - case CMD_LIST_NEXT_PAGE: - lw->start = lw->start + lw->rows-1; - if( lw->start+lw->rows >= lyr_text.lines->len+1 ) - lw->start = lyr_text.lines->len-lw->rows+1; - if( lw->start<0 ) - lw->start = 0; - return 1; - case CMD_LIST_PREVIOUS_PAGE: - lw->start = lw->start - lw->rows; - if( lw->start<0 ) - lw->start = 0; - return 1; - case CMD_SELECT: - spec.client = c; - spec.way = 0; - g_thread_create(get_lyr, &spec, FALSE, NULL); - return 1; case CMD_INTERRUPT: - if(lock > 1) lock = 4; + if (current.loader != NULL) { + screen_lyrics_abort(); + screen_lyrics_clear(); + } return 1; case CMD_ADD: - if(lock > 0 && lock != 4) { - if(store_lyr_hd() == 0) - screen_status_message (_("Lyrics saved!")); - } + if (current.loader == NULL && current.artist != NULL && + current.title != NULL && store_lyr_hd() == 0) + screen_status_message (_("Lyrics saved!")); return 1; case CMD_LYRICS_UPDATE: - spec.client = c; - spec.way = 1; - g_thread_create(get_lyr, &spec, FALSE, NULL); - return 1; - case CMD_SEARCH_MODE: - //while (0==0) fprintf (stderr, "%i", src_lyr_stack->len); - if (src_selection == src_lyr_stack->len - 1) - src_selection = -1; - src_selection++; + if (c->song != NULL) { + screen_lyrics_load(c->song); + lyrics_repaint(); + } return 1; + + case CMD_LOCATE: + if (current.song != NULL) { + screen_file_goto_song(c, current.song); + return true; + } + + return false; + default: break; } lw->selected = lw->start+lw->rows; - if (screen_find(screen, - lw, lyrics_text_rows, + if (screen_find(lw, current.lines->len, cmd, list_callback, NULL)) { /* center the row */ - lw->start = lw->selected - (lw->rows / 2); - if (lw->start + lw->rows > lyrics_text_rows) - lw->start = lyrics_text_rows - lw->rows; - if (lw->start < 0) - lw->start = 0; + list_window_center(lw, current.lines->len, lw->selected); + lyrics_repaint(); return 1; } return 0; } -static list_window_t * -lyrics_lw(void) +const struct screen_functions screen_lyrics = { + .init = lyrics_screen_init, + .exit = lyrics_exit, + .open = lyrics_open, + .close = NULL, + .resize = lyrics_resize, + .paint = lyrics_paint, + .cmd = lyrics_cmd, + .get_title = lyrics_title, +}; + +void +screen_lyrics_switch(struct mpdclient *c, const struct mpd_song *song) { - return lw; -} + assert(song != NULL); -screen_functions_t * -get_screen_lyrics(void) -{ - static screen_functions_t functions; - - memset(&functions, 0, sizeof(screen_functions_t)); - functions.init = lyrics_init; - functions.exit = lyrics_exit; - functions.open = NULL; - functions.close = NULL; - functions.resize = lyrics_resize; - functions.paint = lyrics_paint; - functions.update = lyrics_update; - functions.cmd = lyrics_cmd; - functions.get_lw = lyrics_lw; - functions.get_title = lyrics_title; - - return &functions; + next_song = song; + screen_switch(&screen_lyrics, c); } -#endif /* ENABLE_LYRICS_SCREEN */