From 268b0823860274d6079c5dd307770a0769d404ef Mon Sep 17 00:00:00 2001 From: Kalle Wallin Date: Thu, 25 Mar 2004 11:44:59 +0000 Subject: [PATCH] Added support for a configuration file ~/.ncmpcrc and color support. git-svn-id: https://svn.musicpd.org/ncmpc/trunk@473 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- Makefile.am | 6 +- conf.c | 263 +++++++++++++++++++++++++++++++++++++++++++++++++ conf.h | 3 + configure.ac | 11 --- doc/ncmpcrc | 39 ++++++++ main.c | 11 ++- options.c | 28 ++++-- options.h | 18 +++- screen.c | 62 +++++++++--- screen.h | 11 +++ screen_file.c | 12 ++- screen_utils.c | 28 ++++++ screen_utils.h | 3 + support.c | 28 ++++++ support.h | 1 + 15 files changed, 481 insertions(+), 43 deletions(-) create mode 100644 conf.c create mode 100644 conf.h create mode 100644 doc/ncmpcrc diff --git a/Makefile.am b/Makefile.am index 96e6b1d..1e980df 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,11 +9,11 @@ docdir = $(prefix)/share/doc/$(PACKAGE) doc_DATA = AUTHORS README ChangeLog EXTRA_DIST = COPYING $(pkgdata_DATA) $(man_MANS) $(doc_DATA) -ncmpc_headers = libmpdclient.h mpc.h options.h command.h screen.h \ +ncmpc_headers = libmpdclient.h mpc.h options.h conf.h command.h screen.h \ screen_utils.h screen_play.h screen_file.h screen_search.h \ - screen_help.h list_window.h support.h + screen_help.h list_window.h support.h -ncmpc_SOURCES = libmpdclient.c main.c mpc.c options.c command.c \ +ncmpc_SOURCES = libmpdclient.c main.c mpc.c options.c conf.c command.c \ screen.c screen_utils.c screen_play.c screen_file.c \ screen_search.c screen_help.c \ list_window.c support.c $(ncmpc_headers) diff --git a/conf.c b/conf.c new file mode 100644 index 0000000..1ea1fd9 --- /dev/null +++ b/conf.c @@ -0,0 +1,263 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "options.h" +#include "support.h" +#include "conf.h" + +#ifdef DEBUG +#define D(x) x +#else +#define D(x) +#endif + +#define RCFILE "." PACKAGE "rc" + +#define MAX_LINE_LENGTH 1024 +#define COMMENT_TOKEN '#' + +/* configuration field names */ +#define CONF_ENABLE_COLORS "enable_colors" +#define CONF_COLOR_BACKGROUND "background_color" +#define CONF_COLOR_TITLE "title_color" +#define CONF_COLOR_LINE "line_color" +#define CONF_COLOR_LIST "list_color" +#define CONF_COLOR_PROGRESS "progress_color" +#define CONF_COLOR_STATUS "status_color" +#define CONF_COLOR_ALERT "alert_color" + + +#define IS_WHITESPACE(c) (c==' ' || c=='\t' || c=='\r' || c=='\n') + + +static int +str2bool(char *str) +{ + if( !strcasecmp(str,"no") || !strcasecmp(str,"false") || + !strcasecmp(str,"off") || !strcasecmp(str,"0") ) + return 0; + return 1; +} + +static int +str2color(char *str) +{ + if( !strcasecmp(str,"black") ) + return COLOR_BLACK; + else if( !strcasecmp(str,"red") ) + return COLOR_RED; + else if( !strcasecmp(str,"green") ) + return COLOR_GREEN; + else if( !strcasecmp(str,"yellow") ) + return COLOR_YELLOW; + else if( !strcasecmp(str,"blue") ) + return COLOR_BLUE; + else if( !strcasecmp(str,"magenta") ) + return COLOR_MAGENTA; + else if( !strcasecmp(str,"cyan") ) + return COLOR_CYAN; + else if( !strcasecmp(str,"white") ) + return COLOR_WHITE; +#if 0 + else if( !strcasecmp(str,"grey") ) + return COLOR_BLACK | A_BOLD; + else if( !strcasecmp(str,"brightred") ) + return COLOR_RED | A_BOLD; + else if( !strcasecmp(str,"brightgreen") ) + return COLOR_GREEN | A_BOLD; + else if( !strcasecmp(str,"brightyellow") ) + return COLOR_YELLOW | A_BOLD; + else if( !strcasecmp(str,"brightblue") ) + return COLOR_BLUE | A_BOLD; + else if( !strcasecmp(str,"brightmagenta") ) + return COLOR_MAGENTA | A_BOLD; + else if( !strcasecmp(str,"brightcyan") ) + return COLOR_CYAN | A_BOLD; + else if( !strcasecmp(str,"brightwhite") ) + return COLOR_WHITE | A_BOLD; +#endif + fprintf(stderr,"Warning: unknown color %s\n", str); + return -1; +} + +int +read_rc_file(char *filename, options_t *options) +{ + int fd; + int quit = 0; + int color = -1; + int free_filename = 0; + + if( filename==NULL ) + { + filename = concat_path(getenv("HOME"), RCFILE); + free_filename = 1; + } + + D(printf("\n--Reading configuration file %s\n", filename)); + if( (fd=open(filename,O_RDONLY)) <0 ) + { + D(perror(filename)); + if( free_filename ) + free(filename); + return -1; + } + + while( !quit ) + { + int i,j; + int len; + int match_found; + char line[MAX_LINE_LENGTH]; + char name[MAX_LINE_LENGTH]; + char value[MAX_LINE_LENGTH]; + + line[0] = '\0'; + value[0] = '\0'; + + i = 0; + /* read a line ending with '\n' */ + do { + len = read( fd, &line[i], 1 ); + if( len == 1 ) + i++; + else + quit = 1; + } while( !quit && i=0 && IS_WHITESPACE(line[i]) ) + { + line[i] = '\0'; + i--; + } + len = i+1; + + if( len>0 ) + { + i = 0; + /* skip whitespace */ + while( ienable_colors = str2bool(value); + match_found = 1; + } + /* background color */ + else if( !strcasecmp(CONF_COLOR_BACKGROUND, name) ) + { + if( (color=str2color(value)) >= 0 ) + options->bg_color = color; + match_found = 1; + } + /* color - top (title) window */ + else if( !strcasecmp(CONF_COLOR_TITLE, name) ) + { + if( (color=str2color(value)) >= 0 ) + options->title_color = color; + match_found = 1; + } + /* color - line (title) window */ + else if( !strcasecmp(CONF_COLOR_LINE, name) ) + { + if( (color=str2color(value)) >= 0 ) + options->line_color = color; + match_found = 1; + } + /* color - list window */ + else if( !strcasecmp(CONF_COLOR_LIST, name) ) + { + if( (color=str2color(value)) >= 0 ) + options->list_color = color; + match_found = 1; + } + /* color - progress bar */ + else if( !strcasecmp(CONF_COLOR_PROGRESS, name) ) + { + if( (color=str2color(value)) >= 0 ) + options->progress_color = color; + match_found = 1; + } + /* color - status window */ + else if( !strcasecmp(CONF_COLOR_STATUS, name) ) + { + if( (color=str2color(value)) >= 0 ) + options->status_color = color; + match_found = 1; + } + /* color - alerts */ + else if( !strcasecmp(CONF_COLOR_ALERT, name) ) + { + if( (color=str2color(value)) >= 0 ) + options->alert_color = color; + match_found = 1; + } + + + if( !match_found ) + fprintf(stderr, + "Unknown configuration parameter: %s\n", + name); +#ifdef DEBUG + printf( " %s = %s %s\n", + name, + value, + match_found ? "" : "- UNKNOWN SETTING!" ); +#endif + + } + } + } + + D(printf( "--\n\n" )); + + if( free_filename ) + free(filename); + + return 0; +} + + + + + + diff --git a/conf.h b/conf.h new file mode 100644 index 0000000..ee7656e --- /dev/null +++ b/conf.h @@ -0,0 +1,3 @@ + +int read_rc_file(char *filename, options_t *options); + diff --git a/configure.ac b/configure.ac index 501e00e..531cc3b 100644 --- a/configure.ac +++ b/configure.ac @@ -79,17 +79,6 @@ if test "$enable_debug" = yes; then CFLAGS="$CFLAGS -g -DDEBUG" fi -dnl Enable -AC_ARG_ENABLE(colors, - [ --enable-colors Enable colors [default=no]], - , - enable_colors=no) - -if test "$enable_colors" = yes; then - CFLAGS="$CFLAGS -DENABLE_COLORS" -fi - - dnl Default charset AC_ARG_WITH(default-charset, [ --with-default-charset=ARG Default charset (ISO-8859-1)], diff --git a/doc/ncmpcrc b/doc/ncmpcrc new file mode 100644 index 0000000..98d34c6 --- /dev/null +++ b/doc/ncmpcrc @@ -0,0 +1,39 @@ +# +# Configuration file for ncmpc (~/.ncmpcrc) +# + + +# +# Color configuration +# +# colors: black,red,green,yellow,blue,magenta,cyan,white +# + +# enable/disable colors +enable_colors = yes + +# background color +#background_color = blue + +# text colors +#title_color = white +#line_color = green +#list_color = yellow +#progress_color = green +#status_color = white +#alert_color = yellow + + +# +# Key bindings - NOT IMPLEMENTED +# +# key_up = 13 + + +# +# Key names - NOT IMPLEMENTED +# +#key_name 13 Enter +# + + diff --git a/main.c b/main.c index c2c29b3..0e36133 100644 --- a/main.c +++ b/main.c @@ -11,6 +11,8 @@ #include "options.h" #include "command.h" #include "screen.h" +#include "conf.h" + static mpd_client_t *mpc = NULL; @@ -42,9 +44,14 @@ main(int argc, const char *argv[]) struct sigaction act; int counter, connected; + /* initialize options */ + options = options_init(); + + /* read configuration */ + read_rc_file(NULL, options); + /* parse command line options */ - options_init(); - options = options_parse(argc, argv); + options_parse(argc, argv); /* initialize local charset */ if( charset_init() ) diff --git a/options.c b/options.c index 9685ce3..8f684a1 100644 --- a/options.c +++ b/options.c @@ -1,19 +1,15 @@ -/* - * $Id: options.c,v 1.7 2004/03/17 11:34:36 kalle Exp $ - * - */ - #include #include #include #include +#include #include #include "config.h" #include "options.h" #include "command.h" -static options_t options; +options_t options; static struct poptOption optionsTable[] = { #ifdef DEBUG @@ -21,6 +17,8 @@ static struct poptOption optionsTable[] = { #endif { "version", 'V', 0, 0, 'V', "Display version information." }, { "keys", 'k', 0, 0, 'k', "Display key bindings." }, + { "colors", 'c', 0, 0, 'c', "Enable colors." }, + { "no-colors", 'C', 0, 0, 'C', "Disable colors." }, { "exit", 'e', 0, 0, 'e', "Exit on connection errors." }, { "port", 'p', POPT_ARG_INT, &options.port, 0, "Connect to server on port [" DEFAULT_PORT_STR "].", "PORT" }, @@ -55,6 +53,12 @@ options_parse( int argc, const char **argv) options.debug = 1; break; #endif + case 'c': + options.enable_colors = 1; + break; + case 'C': + options.enable_colors = 0; + break; case 'V': printf("Version " VERSION "\n"); exit(EXIT_SUCCESS); @@ -87,7 +91,7 @@ options_parse( int argc, const char **argv) return &options; } -void +options_t * options_init( void ) { char *value; @@ -102,6 +106,16 @@ options_init( void ) else options.port = DEFAULT_PORT; options.reconnect = 1; + + options.bg_color = COLOR_BLACK; + options.title_color = COLOR_BLUE; + options.line_color = COLOR_GREEN; + options.list_color = COLOR_YELLOW; + options.progress_color = COLOR_GREEN; + options.status_color = COLOR_RED; + options.alert_color = COLOR_MAGENTA;; + + return &options; } diff --git a/options.h b/options.h index 49af199..a8ac179 100644 --- a/options.h +++ b/options.h @@ -2,6 +2,8 @@ #define MPD_HOST_ENV "MPD_HOST" #define MPD_PORT_ENV "MPD_PORT" +#define NCMPCRC_ENV "NCMPCRC" + typedef struct { @@ -10,9 +12,21 @@ typedef struct int reconnect; int debug; + int enable_colors; + int bg_color; + int title_color; + int line_color; + int list_color; + int progress_color; + int status_color; + int alert_color; + } options_t; -void options_init(void); +extern options_t options; + +options_t *options_init(void); options_t *options_parse(int argc, const char **argv); -options_t *get_options(void); + + diff --git a/screen.c b/screen.c index 3012fa3..8626951 100644 --- a/screen.c +++ b/screen.c @@ -1,8 +1,3 @@ -/* - * $Id: screen.c,v 1.10 2004/03/17 14:50:12 kalle Exp $ - * - */ - #include #include #include @@ -14,11 +9,13 @@ #include "libmpdclient.h" #include "mpc.h" #include "command.h" +#include "options.h" #include "screen.h" #include "screen_play.h" #include "screen_file.h" #include "screen_help.h" #include "screen_search.h" +#include "screen_utils.h" #define STATUS_MESSAGE_TIMEOUT 3 #define STATUS_LINE_MAX_SIZE 512 @@ -83,7 +80,7 @@ paint_top_window(char *header, int volume, int clear) char buf[12]; wattron(w, A_BOLD); - mvwaddstr(w, 0, 0, header ); + mvwaddstr(w, 0, 0, header); wattroff(w, A_BOLD); if( volume==MPD_STATUS_NO_VOLUME ) { @@ -95,8 +92,14 @@ paint_top_window(char *header, int volume, int clear) } mvwaddstr(w, 0, screen->top_window.cols-12, buf); + if( options.enable_colors ) + wattron(w, LINE_COLORS); + mvwhline(w, 1, 0, ACS_HLINE, screen->top_window.cols); + if( options.enable_colors ) + wattroff(w, LINE_COLORS); + wrefresh(w); } } @@ -118,14 +121,11 @@ paint_progress_window(mpd_client_t *c) p = ((double) c->status->elapsedTime) / ((double) c->status->totalTime); width = (int) (p * (double) screen->progress_window.cols); - mvwhline(screen->progress_window.w, 0, 0, ACS_HLINE, screen->progress_window.cols); - whline(screen->progress_window.w, '=', width-1); - mvwaddch(screen->progress_window.w, 0, width-1, 'O'); wrefresh(screen->progress_window.w); } @@ -152,27 +152,32 @@ paint_status_window(mpd_client_t *c) wattroff(w, A_BOLD); break; case MPD_STATUS_STATE_PLAY: + wattron(w, A_BOLD); waddstr(w, "Playing:"); + wattroff(w, A_BOLD); break; case MPD_STATUS_STATE_PAUSE: wattron(w, A_BOLD); - waddstr(w, "Paused:"); + waddstr(w, "[Paused]"); wattroff(w, A_BOLD); break; default: - waddstr(w, "Warning: Music Player Daemon in unknown state!"); + my_waddstr(w, + "Warning: Music Player Daemon in unknown state!", + ALERT_COLORS); break; } x += 10; - if( IS_PLAYING(status->state) && song ) + if( (IS_PLAYING(status->state) || IS_PAUSED(status->state)) && song ) { + // my_mvwaddstr(w, 0, x, mpc_get_song_name(song), COLOR_PAIR(2)); mvwaddstr(w, 0, x, mpc_get_song_name(song)); } /* time */ - if( IS_PLAYING(status->state) ) + if( IS_PLAYING(status->state) || IS_PAUSED(status->state) ) { x = screen->status_window.cols - strlen(screen->buf); @@ -180,6 +185,7 @@ paint_status_window(mpd_client_t *c) " [%i:%02i/%i:%02i] ", status->elapsedTime/60, status->elapsedTime%60, status->totalTime/60, status->totalTime%60 ); + //my_mvwaddstr(w, 0, x, screen->buf, COLOR_PAIR(1)); mvwaddstr(w, 0, x, screen->buf); } @@ -239,7 +245,7 @@ screen_status_message(char *msg) wmove(w, 0, 0); wclrtoeol(w); wattron(w, A_BOLD); - waddstr(w, msg); + my_waddstr(w, msg, ALERT_COLORS); wattroff(w, A_BOLD); wrefresh(w); screen->status_timestamp = time(NULL); @@ -263,7 +269,18 @@ screen_init(void) /* initialize the curses library */ initscr(); start_color(); - use_default_colors(); + if( options.enable_colors ) + { + init_pair(1, options.title_color, options.bg_color); + init_pair(2, options.line_color, options.bg_color); + init_pair(3, options.list_color, options.bg_color); + init_pair(4, options.progress_color, options.bg_color); + init_pair(5, options.status_color, options.bg_color); + init_pair(6, options.alert_color, options.bg_color); + } + else + use_default_colors(); + /* tell curses not to do NL->CR/NL on output */ nonl(); /* take input chars one at a time, no wait for \n */ @@ -277,7 +294,6 @@ screen_init(void) keypad(stdscr, TRUE); timeout(100); /*void wtimeout(WINDOW *win, int delay);*/ - if( COLSstatus_window.cols, screen->rows-1, 0); + leaveok(screen->status_window.w, FALSE); keypad(screen->status_window.w, TRUE); + if( options.enable_colors ) + { + /* set background attributes */ + wbkgd(screen->main_window.w, LIST_COLORS); + wbkgd(screen->top_window.w, TITLE_COLORS); + wbkgd(screen->playlist->w, LIST_COLORS); + wbkgd(screen->filelist->w, LIST_COLORS); + wbkgd(screen->helplist->w, LIST_COLORS); + wbkgd(screen->progress_window.w, PROGRESS_COLORS); + wbkgd(screen->status_window.w, STATUS_COLORS); + } + return 0; } @@ -541,3 +570,4 @@ screen_cmd(mpd_client_t *c, command_t cmd) } +; diff --git a/screen.h b/screen.h index 7b667d8..78ca39c 100644 --- a/screen.h +++ b/screen.h @@ -3,16 +3,27 @@ #include #include "list_window.h" +/* top window headers */ #define TOP_HEADER_PREFIX "Music Player Client - " #define TOP_HEADER_PLAY TOP_HEADER_PREFIX "Playlist" #define TOP_HEADER_FILE TOP_HEADER_PREFIX "Browse" #define TOP_HEADER_HELP TOP_HEADER_PREFIX "Help " #define TOP_HEADER_SEARCH TOP_HEADER_PREFIX "Search " +/* colors */ +#define TITLE_COLORS COLOR_PAIR(1) +#define LINE_COLORS COLOR_PAIR(2) +#define LIST_COLORS COLOR_PAIR(3) +#define PROGRESS_COLORS COLOR_PAIR(4) +#define STATUS_COLORS COLOR_PAIR(5) +#define ALERT_COLORS COLOR_PAIR(6) + +/* minumum window size */ #define SCREEN_MIN_COLS 14 #define SCREEN_MIN_ROWS 5 #define IS_PLAYING(s) (s==MPD_STATUS_STATE_PLAY) +#define IS_PAUSED(s) (s==MPD_STATUS_STATE_PAUSE) typedef enum { diff --git a/screen_file.c b/screen_file.c index 809ae3f..69ec858 100644 --- a/screen_file.c +++ b/screen_file.c @@ -47,8 +47,16 @@ list_callback(int index, int *highlight, void *data) mpd_Song *song = entity->info.song; return mpc_get_song_name(song); } - - return NULL; + else if( entity->type==MPD_INFO_ENTITY_TYPE_PLAYLISTFILE ) + { + mpd_PlaylistFile *plf = entity->info.playlistFile; + char *filename = utf8_to_locale(basename(plf->path)); + + snprintf(buf, BUFSIZE, "%s*", filename); + free(filename); + return buf; + } + return "Error: Unknow entry!"; } static void diff --git a/screen_utils.c b/screen_utils.c index 49bd669..648291f 100644 --- a/screen_utils.c +++ b/screen_utils.c @@ -8,6 +8,7 @@ #include "mpc.h" #include "support.h" #include "command.h" +#include "options.h" #include "screen.h" char * @@ -33,3 +34,30 @@ screen_readln(WINDOW *w, char *prompt) return line; } +int +my_waddstr(WINDOW *w, const char *text, int color) +{ + int ret; + + if( options.enable_colors ) + wattron(w, color); + ret = waddstr(w, text); + if( options.enable_colors ) + wattroff(w, color); + + return ret; +} + +int +my_mvwaddstr(WINDOW *w, int x, int y, const char *text, int color) +{ + int ret; + + if( options.enable_colors ) + wattron(w, color); + ret = mvwaddstr(w, x, y, text); + if( options.enable_colors ) + wattroff(w, color); + + return ret; +} diff --git a/screen_utils.h b/screen_utils.h index 70091f5..a03c36d 100644 --- a/screen_utils.h +++ b/screen_utils.h @@ -1,2 +1,5 @@ char *screen_readln(WINDOW *w, char *prompt); + +int my_waddstr(WINDOW *, const char *, int); +int my_mvwaddstr(WINDOW *, int, int, const char *, int); diff --git a/support.c b/support.c index 28297e4..d7c196a 100644 --- a/support.c +++ b/support.c @@ -68,6 +68,34 @@ lowerstr(char *str) return str; } + +char * +concat_path(char *p1, char *p2) +{ + size_t size; + char *path; + char append_slash = 0; + + size = strlen(p1); + if( size==0 || p1[size-1]!='/' ) + { + size++; + append_slash = 1; + } + size += strlen(p2); + size++; + + path = calloc(size, sizeof(char)); + strncpy(path, p1, size); + if( append_slash ) + strncat(path, "/", size); + strncat(path, p2, size); + + return path; +} + + + #ifndef HAVE_BASENAME char * basename(char *path) diff --git a/support.h b/support.h index da5ac5e..9e1a1b8 100644 --- a/support.h +++ b/support.h @@ -3,6 +3,7 @@ #include #endif +char *concat_path(char *p1, char *p2); #ifndef HAVE_BASENAME char *basename(char *path); -- 2.30.2