Stable: 2.5.2
Development: 2.6-alpha3
I've made a small patch to display the lyrics of the file who is currently read. They are fetch from a file on the disk in the same directory and with the name but without extension. It looks like the help screen because it is (almost) the same code. You called it by pressing L.
Please post remarks and excuse me english (it's not my mother tongue).
Here is the patch :
Index: moc/interface.c
===================================================================
--- moc/interface.c (revision 2093)
+++ moc/interface.c (working copy)
@@ -56,6 +56,7 @@
#include "decoder.h"
#include "themes.h"
#include "softmixer.h"
+#include "lyrics.h"
#define INTERFACE_LOG "mocp_client_log"
@@ -2953,6 +2954,8 @@
{
if (iface_in_help())
iface_handle_help_key (k);
+ if (iface_in_lyrics())
+ iface_handle_lyrics_key (k);
else if (iface_in_entry())
entry_key (k);
else if (iface_in_theme_menu())
@@ -3044,6 +3047,9 @@
case KEY_CMD_HELP:
iface_switch_to_help ();
break;
+ case KEY_CMD_LYRICS:
+ iface_switch_to_lyrics ();
+ break;
case KEY_CMD_HIDE_MESSAGE:
iface_disable_message ();
break;
@@ -3347,6 +3353,7 @@
windows_end ();
keys_cleanup ();
+ lyrics_cleanup ();
plist_free (dir_plist);
plist_free (playlist);
Index: moc/keys.c
===================================================================
--- moc/keys.c (revision 2093)
+++ moc/keys.c (working copy)
@@ -736,6 +736,14 @@
{ KEY_F(10), -1 },
1
},
+ {
+ KEY_CMD_LYRICS,
+ "show_lyrics",
+ "Display lyrics of the current song (if available)",
+ CON_MENU,
+ { 'L', -1 },
+ 1
+ },
{
KEY_CMD_TOGGLE_PLAYLIST_FULL_PATHS,
"playlist_full_paths",
Index: moc/keys.h
===================================================================
--- moc/keys.h (revision 2093)
+++ moc/keys.h (working copy)
@@ -89,6 +89,7 @@
KEY_CMD_EXEC10,
KEY_CMD_TOGGLE_PLAYLIST_FULL_PATHS,
KEY_CMD_TOGGLE_SOFTMIXER,
+ KEY_CMD_LYRICS,
KEY_CMD_WRONG
};
Index: moc/interface_elements.c
===================================================================
--- moc/interface_elements.c (revision 2093)
+++ moc/interface_elements.c (working copy)
@@ -56,6 +56,7 @@
#include "protocol.h"
#include "interface.h"
#include "utf8.h"
+#include "lyrics.h"
#define STARTUP_MESSAGE "Welcome to " PACKAGE_STRING "!"
#define HISTORY_SIZE 50
@@ -128,8 +129,11 @@
char *curr_file; /* currently played file. */
int in_help; /* are we displaying help screen? */
+ int in_lyrics; /* are we displaying lyrics screen? */
int too_small; /* is the terminal window too small to display mocp? */
int help_screen_top; /* first visible line of the help screen. */
+ int lyrics_screen_top; /* first visible line of the lyrics screen. */
+ int lyrics_nb_lines; /* line number of the current lyrics file. */
struct side_menu menus[3];
char *layout_fmt;
@@ -871,8 +875,11 @@
w->curr_file = NULL;
w->in_help = 0;
+ w->in_lyrics = 0;
w->too_small = 0;
w->help_screen_top = 0;
+ w->lyrics_screen_top = 0;
+ w->lyrics_nb_lines = 0;
w->layout_fmt = xstrdup (layout_fmt);
res = parse_layout (&l, layout_fmt);
@@ -1626,12 +1633,52 @@
}
}
-static void main_win_draw (const struct main_win *w)
+static void main_win_draw_lyrics_screen (struct main_win *w)
{
int i;
+ int max_lines;
+ int lyrics_lines;
+ char **lyrics;
+ assert (w != NULL);
+ assert (w->in_lyrics);
+
+ max_lines = w->lyrics_screen_top + LINES - 6;
+
+ lyrics = get_lyrics_text (w->win, w->curr_file, &lyrics_lines);
+ w->lyrics_nb_lines = lyrics_lines;
+
+ werase (w->win);
+ wbkgd (w->win, get_color(CLR_BACKGROUND));
+
+ wmove (w->win, 0, 0);
+ if (w->lyrics_screen_top != 0) {
+ wattrset (w->win, get_color(CLR_MESSAGE));
+ xmvwaddstr (w->win, 0, COLS/2 - (sizeof("...MORE...")-1)/2,
+ "...MORE...");
+ }
+ wmove (w->win, 1, 0);
+ wattrset (w->win, get_color(CLR_LEGEND));
+ for (i = w->lyrics_screen_top; i < max_lines && i < lyrics_lines; i++) {
+ xwaddstr (w->win, lyrics);
+ /* TODO supprimer ce \n
+ waddch (w->win, '\n');*/
+ }
+ if (i != lyrics_lines) {
+ wattrset (w->win, get_color(CLR_MESSAGE));
+ xmvwaddstr (w->win, LINES-5,
+ COLS/2 - (sizeof("...MORE...")-1)/2,
+ "...MORE...");
+ }
+}
+static void main_win_draw (struct main_win *w)
+{
+ int i;
+
if (w->in_help)
main_win_draw_help_screen (w);
+ else if (w->in_lyrics)
+ main_win_draw_lyrics_screen (w);
else if (w->too_small)
main_win_draw_too_small_screen (w);
else {
@@ -1740,6 +1787,14 @@
main_win_draw (w);
}
+static void main_win_switch_to_lyrics (struct main_win *w)
+{
+ assert (w != NULL);
+
+ w->in_lyrics = 1;
+ main_win_draw (w);
+}
+
static void main_win_create_themes_menu (struct main_win *w)
{
struct window_params p;
@@ -1791,6 +1846,13 @@
return w->in_help;
}
+static int main_win_in_lyrics (const struct main_win *w)
+{
+ assert (w != NULL);
+
+ return w->in_lyrics;
+}
+
static int main_win_in_plist_menu (const struct main_win *w)
{
assert (w != NULL);
@@ -1985,6 +2047,31 @@
main_win_draw (w);
}
+static void main_win_handle_lyrics_key (struct main_win *w,
+ const struct iface_key *k)
+{
+ assert (w != NULL);
+ assert (w->in_lyrics);
+
+ if ((k->type == IFACE_KEY_FUNCTION && (
+ k->key.func == KEY_DOWN
+ || k->key.func == KEY_NPAGE))
+ || (k->key.ucs == '\n')) {
+ if (w->lyrics_screen_top + LINES - 5 <= w->lyrics_nb_lines)
+ w->lyrics_screen_top++;
+ }
+ else {
+ if (k->type == IFACE_KEY_FUNCTION && (k->key.func == KEY_UP
+ || k->key.func == KEY_PPAGE)) {
+ if (w->lyrics_screen_top > 0)
+ w->lyrics_screen_top--;
+ }
+ else if (k->key.func != KEY_RESIZE)
+ w->in_lyrics = 0;
+ }
+
+ main_win_draw (w);
+}
static void main_win_swap_plist_items (struct main_win *w, const char *file1,
const char *file2)
{
@@ -3648,6 +3735,23 @@
iface_refresh_screen ();
}
+int iface_in_lyrics ()
+{
+ return main_win_in_lyrics (&main_win);
+}
+
+void iface_switch_to_lyrics ()
+{
+ main_win_switch_to_lyrics (&main_win);
+ iface_refresh_screen ();
+}
+
+void iface_handle_lyrics_key (const struct iface_key *k)
+{
+ main_win_handle_lyrics_key (&main_win, k);
+ iface_refresh_screen ();
+}
+
void iface_toggle_layout ()
{
static int curr_layout = 1;
Index: moc/interface_elements.h
===================================================================
--- moc/interface_elements.h (revision 2093)
+++ moc/interface_elements.h (working copy)
@@ -100,6 +100,9 @@
int iface_in_help ();
void iface_switch_to_help ();
void iface_handle_help_key (const struct iface_key *k);
+int iface_in_lyrics ();
+void iface_switch_to_lyrics ();
+void iface_handle_lyrics_key (const struct iface_key *k);
void iface_toggle_layout ();
void iface_swap_plist_items (const char *file1, const char *file2);
void iface_make_visible (const enum iface_menu menu, const char *file);
Index: moc/lyrics.c
===================================================================
--- moc/lyrics.c (revision 0)
+++ moc/lyrics.c (revision 0)
@@ -0,0 +1,103 @@
+/*
+ * MOC - music on console
+ * Copyright (C) 2004-2005 Damian Pietras
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "lyrics.h"
+#include "common.h"
+#include "files.h"
+
+#define LYRICS_LINE_NUMBER 128
+static char *lyrics[LYRICS_LINE_NUMBER];
+const unsigned short LINE_SIZE = 128;
+
+void lyrics_remove_prefix (const char *filename, char *new_name)
+{
+ unsigned short last_dot_pos = 0, i = 0;
+ for (i = 0; i < strlen(filename); i++) {
+ if (filename == '.')
+ last_dot_pos = i;
+ }
+ strncpy(new_name, filename, last_dot_pos);
+ new_name[last_dot_pos] = '\0';
+}
+
+void lyrics_cleanup ()
+{
+ unsigned int i;
+ for (i = 0; i < LYRICS_LINE_NUMBER; i++)
+ free (lyrics);
+}
+
+char **get_lyrics_text (const WINDOW *w, const char *filename, int *num)
+{
+ char *lyrics_filename;
+ char *lyrics_line;
+ FILE *lyrics_file = NULL;
+ unsigned short i = 0;
+ int x, y, space;
+
+ getmaxyx(w,x,y);
+ if (y > LINE_SIZE)
+ y = LINE_SIZE;
+
+ if (filename == NULL) {
+ lyrics[0] = xmalloc (sizeof(char) * 20);
+ strncpy (lyrics[0], "No file reading", 20);
+ *num = 1;
+ return lyrics;
+ }
+ else if (is_url(filename)) {
+ lyrics[0] = xmalloc (sizeof(char) * 30);
+ strncpy (lyrics[0], "URL lyrics is not supported", 30);
+ *num = 1;
+ return lyrics;
+ }
+ else {
+ lyrics_filename = xmalloc (sizeof(char) * 128);
+ lyrics_remove_prefix (filename, lyrics_filename);
+ }
+
+ lyrics_file = fopen (lyrics_filename, "r");
+ if (lyrics_file != NULL) {
+ lyrics_line = xmalloc (sizeof(char) * LINE_SIZE);
+ while (fgets(lyrics_line, y, lyrics_file) != NULL) {
+ lyrics = xmalloc (sizeof(char) * LINE_SIZE);
+ if (strlen(lyrics_line) < (y-1)) {
+ space = (y-strlen(lyrics_line))/2;
+ memset(lyrics, ' ', space);
+ strcat(lyrics, lyrics_line);
+ }
+ else {
+ strncpy (lyrics, lyrics_line, y-1);
+ lyrics[y] = '\0';
+ }
+ i++;
+ }
+ *num = i;
+ fclose (lyrics_file);
+ free (lyrics_line);
+ free (lyrics_filename);
+ return lyrics;
+ }
+ else {
+ lyrics[0] = xmalloc (sizeof(char) * 80);
+ strncpy (lyrics[0], "No lyrics found !", 79);
+ *num = 1;
+ free (lyrics_filename);
+ return lyrics;
+ }
+ free (lyrics_filename);
+ abort ();
+ return lyrics;
+}
+
Index: moc/lyrics.h
===================================================================
--- moc/lyrics.h (revision 0)
+++ moc/lyrics.h (revision 0)
@@ -0,0 +1,18 @@
+#ifndef LYRICS_H
+#define LYRICS_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#ifdef HAVE_NCURSESW_H
+# include
+#elif HAVE_NCURSES_H
+# include
+#elif HAVE_CURSES_H
+# include
+#endif
+
+void lyrics_cleanup ();
+char **get_lyrics_text (const WINDOW*, const char*, int*);
+
+#endif
Index: moc/Makefile.am
===================================================================
--- moc/Makefile.am (revision 2093)
+++ moc/Makefile.am (working copy)
@@ -56,7 +56,9 @@
utf8.c \
utf8.h \
softmixer.c \
- softmixer.h
+ softmixer.h \
+ lyrics.h \
+ lyrics.c
EXTRA_mocp_SOURCES = gnugetopt.h \
getopt.c \
getopt1.c \
daper
Sun, 2008-07-13 06:52
Permalink
Thanks for the patch. I have
Thanks for the patch. I have few questions/suggestions:
- Lyrics are expected to be in the same place where the played file is, but in a file without an extension?
- lyrics_remove_prefix() can be simplified using strrchr().
- I don't think you free memory in a proper way: lyrics_cleanup() calls free() for every lyrics line, but doesn't check if it was actually used (doesn't check if it's NULL). Loading a new lyric calls malloc() for every line but the previously loaded lyric's lines are not free()ed.
daureg
Mon, 2008-07-14 18:33
Permalink
Thanks for suggestions
, it's quite strange.
Here is the new patch:
daper
Tue, 2008-07-22 06:42
Permalink
Sorry for the late response,
Sorry for the late response, I have not much time for MOC.
Doesn't it behave strange because of this?
You are using strcat() to append to a string that is not null-terminated. After memset there should be
lyrics[i][space] = '\0'
. If it works, I'll apply the patch.daureg
Sun, 2008-07-27 21:29
Permalink
It seems I'm also late
You were right, it works with null-terminated string (after too python, string handling is a pain in C). I've also add some lines to load lyrics every time a new file is read.
The patch is here : http://geraudsoft.info/tmp/lyrics.patch
daper
Mon, 2008-07-28 18:01
Permalink
Works for me :) I'll include
Works for me :) I'll include the patch, but I need your full name (to be put in the changelog and Copyright in the lyrics.c file).
daureg
Sat, 2008-08-02 13:05
Permalink
My name
Thanks. My name is Géraud Le Falher.
daper
Sun, 2008-08-03 18:19
Permalink
Thanks, patch applied.
Thanks, patch applied.