diff options
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | conf.c | 263 | ||||
-rw-r--r-- | conf.h | 3 | ||||
-rw-r--r-- | configure.ac | 11 | ||||
-rw-r--r-- | doc/ncmpcrc | 39 | ||||
-rw-r--r-- | main.c | 11 | ||||
-rw-r--r-- | options.c | 28 | ||||
-rw-r--r-- | options.h | 18 | ||||
-rw-r--r-- | screen.c | 62 | ||||
-rw-r--r-- | screen.h | 11 | ||||
-rw-r--r-- | screen_file.c | 12 | ||||
-rw-r--r-- | screen_utils.c | 28 | ||||
-rw-r--r-- | screen_utils.h | 3 | ||||
-rw-r--r-- | support.c | 28 | ||||
-rw-r--r-- | support.h | 1 |
15 files changed, 481 insertions, 43 deletions
diff --git a/Makefile.am b/Makefile.am index 96e6b1dd0..1e980df6d 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) @@ -0,0 +1,263 @@ +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <ncurses.h> + +#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<MAX_LINE_LENGTH && line[i-1]!='\n' ); + + + /* remove trailing whitespace */ + line[i] = '\0'; + i--; + while( i>=0 && IS_WHITESPACE(line[i]) ) + { + line[i] = '\0'; + i--; + } + len = i+1; + + if( len>0 ) + { + i = 0; + /* skip whitespace */ + while( i<len && IS_WHITESPACE(line[i]) ) + i++; + + /* continue if this line is not a comment */ + if( line[i] != COMMENT_TOKEN ) + { + /* get the name part */ + j=0; + while( i<len && line[i]!='=' && !IS_WHITESPACE(line[i]) ) + { + name[j++] = line[i++]; + } + name[j] = '\0'; + + /* skip '=' and whitespace */ + while( i<len && (line[i]=='=' || IS_WHITESPACE(line[i])) ) + i++; + + /* get the value part */ + j=0; + while( i<len ) + { + value[j++] = line[i++]; + } + value[j] = '\0'; + + match_found = 0; + + /* enable colors */ + if( !strcasecmp(CONF_ENABLE_COLORS, name) ) + { + options->enable_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; +} + + + + + + @@ -0,0 +1,3 @@ + +int read_rc_file(char *filename, options_t *options); + diff --git a/configure.ac b/configure.ac index 501e00e88..531cc3b29 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 000000000..98d34c699 --- /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 +# + + @@ -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() ) @@ -1,19 +1,15 @@ -/* - * $Id: options.c,v 1.7 2004/03/17 11:34:36 kalle Exp $ - * - */ - #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <ncurses.h> #include <popt.h> #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; } @@ -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); + + @@ -1,8 +1,3 @@ -/* - * $Id: screen.c,v 1.10 2004/03/17 14:50:12 kalle Exp $ - * - */ - #include <stdlib.h> #include <unistd.h> #include <stdarg.h> @@ -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( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS ) { fprintf(stderr, "Error: Screen to small!\n"); @@ -338,9 +354,22 @@ screen_init(void) screen->status_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) } +; @@ -3,16 +3,27 @@ #include <ncurses.h> #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 809ae3faf..69ec85808 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 49bd6692a..648291f03 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 70091f5c8..a03c36d47 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); @@ -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) @@ -3,6 +3,7 @@ #include <libgen.h> #endif +char *concat_path(char *p1, char *p2); #ifndef HAVE_BASENAME char *basename(char *path); |