diff --git a/src/screen.c b/src/screen.c
index 76d04fa2241cbc48fdff03a543475fddf555ae74..72bdaff36247abf03e1d211db075b38d2fbace58 100644 (file)
--- a/src/screen.c
+++ b/src/screen.c
#include "ncmpc.h"
#include "support.h"
#include "mpdclient.h"
+#include "utils.h"
#include "command.h"
#include "options.h"
#include "colors.h"
#include "screen.h"
#include "screen_utils.h"
-#define ENABLE_STATUS_LINE_CLOCK
-#define ENABLE_SCROLLING
+#define MAX_SONGNAME_LENGTH 512
+
+#define SCREEN_PLAYLIST_ID 0
+#define SCREEN_BROWSE_ID 1
+#define SCREEN_ARTIST_ID 2
+#define SCREEN_HELP_ID 100
+#define SCREEN_KEYDEF_ID 101
+#define SCREEN_CLOCK_ID 102
+#define SCREEN_SEARCH_ID 103
-#define CROSSFADE_TIME 10
-#define STATUS_MESSAGE_TIMEOUT 3
-#define STATUS_LINE_MAX_SIZE 512
/* screens */
extern screen_functions_t *get_screen_playlist(void);
extern screen_functions_t *get_screen_browse(void);
extern screen_functions_t *get_screen_help(void);
+extern screen_functions_t *get_screen_search(void);
+extern screen_functions_t *get_screen_artist(void);
+extern screen_functions_t *get_screen_keydef(void);
+extern screen_functions_t *get_screen_clock(void);
+
+typedef screen_functions_t * (*screen_get_mode_functions_fn_t) (void);
+
+typedef struct
+{
+ gint id;
+ gchar *name;
+ screen_get_mode_functions_fn_t get_mode_functions;
+} screen_mode_info_t;
+
+static screen_mode_info_t screens[] = {
+ { SCREEN_PLAYLIST_ID, "playlist", get_screen_playlist },
+ { SCREEN_BROWSE_ID, "browse", get_screen_browse },
+#ifdef ENABLE_ARTIST_SCREEN
+ { SCREEN_ARTIST_ID, "artist", get_screen_artist },
+#endif
+ { SCREEN_HELP_ID, "help", get_screen_help },
+#ifdef ENABLE_SEARCH_SCREEN
+ { SCREEN_SEARCH_ID, "search", get_screen_search },
+#endif
#ifdef ENABLE_KEYDEF_SCREEN
-extern screen_functions_t *get_screen_keydef(void);
+ { SCREEN_KEYDEF_ID, "keydef", get_screen_keydef },
#endif
#ifdef ENABLE_CLOCK_SCREEN
-extern screen_functions_t *get_screen_clock(void);
+ { SCREEN_CLOCK_ID, "clock", get_screen_clock },
#endif
+ { G_MAXINT, NULL, NULL }
+};
static gboolean welcome = TRUE;
static screen_t *screen = NULL;
static int seek_id = -1;
static int seek_target_time = 0;
+gint
+screen_get_id(char *name)
+{
+ gint i=0;
+
+ while( screens[i].name )
+ {
+ if( strcmp(name, screens[i].name) == 0 )
+ return screens[i].id;
+ i++;
+ }
+ return -1;
+}
+
+static gint
+lookup_mode(gint id)
+{
+ gint i=0;
+
+ while( screens[i].name )
+ {
+ if( screens[i].id == id )
+ return i;
+ i++;
+ }
+ return -1;
+}
static void
-switch_screen_mode(screen_mode_t new_mode, mpdclient_t *c)
+switch_screen_mode(gint id, mpdclient_t *c)
{
- if( new_mode == screen->mode )
+ gint new_mode;
+
+ if( id == screens[screen->mode].id )
return;
/* close the old mode */
mode_fn->close();
/* get functions for the new mode */
- switch(new_mode)
+ new_mode = lookup_mode(id);
+ if( new_mode>=0 && screens[new_mode].get_mode_functions )
{
- case SCREEN_PLAY_WINDOW:
- mode_fn = get_screen_playlist();
- break;
- case SCREEN_FILE_WINDOW:
- mode_fn = get_screen_browse();
- break;
- case SCREEN_HELP_WINDOW:
- mode_fn = get_screen_help();
- break;
-#ifdef ENABLE_KEYDEF_SCREEN
- case SCREEN_KEYDEF_WINDOW:
- mode_fn = get_screen_keydef();
- break;
-#endif
-#ifdef ENABLE_CLOCK_SCREEN
- case SCREEN_CLOCK_WINDOW:
- mode_fn = get_screen_clock();
- break;
-#endif
-
- default:
- break;
+ D("switch_screen(%s)\n", screens[new_mode].name );
+ mode_fn = screens[new_mode].get_mode_functions();
+ screen->mode = new_mode;
}
- screen->mode = new_mode;
- screen->painted = 0;
+ screen->painted = 0;
+
+ /* open the new mode */
+ if( mode_fn && mode_fn->open )
+ mode_fn->open(screen, c);
- /* open the new mode */
- if( mode_fn && mode_fn->open )
- mode_fn->open(screen, c);
+}
+static void
+screen_next_mode(mpdclient_t *c, int offset)
+{
+ int max = g_strv_length(options.screen_list);
+ int current, next;
+ int i;
+
+ /* find current screen */
+ current = -1;
+ i = 0;
+ while( options.screen_list[i] )
+ {
+ if( strcmp(options.screen_list[i], screens[screen->mode].name) == 0 )
+ current = i;
+ i++;
+ }
+ next = current + offset;
+ if( next<0 )
+ next = max-1;
+ else if( next>=max )
+ next = 0;
+
+ D("current mode: %d:%d next:%d\n", current, max, next);
+ switch_screen_mode(screen_get_id(options.screen_list[next]), c);
}
static void
paint_top_window(char *header, mpdclient_t *c, int clear)
{
- char flags[4];
+ char flags[5];
static int prev_volume = -1;
static int prev_header_len = -1;
WINDOW *w = screen->top_window.w;
colors_use(w, COLOR_TITLE_BOLD);
waddstr(w, get_key_names(CMD_SCREEN_FILE, FALSE));
colors_use(w, COLOR_TITLE);
- waddstr(w, _(":Browse"));
+ waddstr(w, _(":Browse "));
+#ifdef ENABLE_ARTIST_SCREEN
+ colors_use(w, COLOR_TITLE_BOLD);
+ waddstr(w, get_key_names(CMD_SCREEN_ARTIST, FALSE));
+ colors_use(w, COLOR_TITLE);
+ waddstr(w, _(":Artist "));
+#endif
+#ifdef ENABLE_SEARCH_SCREEN
+ colors_use(w, COLOR_TITLE_BOLD);
+ waddstr(w, get_key_names(CMD_SCREEN_SEARCH, FALSE));
+ colors_use(w, COLOR_TITLE);
+ waddstr(w, _(":Search "));
+#endif
}
if( c->status->volume==MPD_STATUS_NO_VOLUME )
{
- snprintf(buf, 32, _("Volume n/a "));
+ g_snprintf(buf, 32, _("Volume n/a "));
}
else
{
- snprintf(buf, 32, _(" Volume %d%%"), c->status->volume);
+ g_snprintf(buf, 32, _(" Volume %d%%"), c->status->volume);
}
colors_use(w, COLOR_TITLE);
mvwaddstr(w, 0, screen->top_window.cols-strlen(buf), buf);
flags[0] = 0;
if( c->status->repeat )
- strcat(flags, "r");
+ g_strlcat(flags, "r", sizeof(flags));
if( c->status->random )
- strcat(flags, "z");
+ g_strlcat(flags, "z", sizeof(flags));;
if( c->status->crossfade )
- strcat(flags, "x");
+ g_strlcat(flags, "x", sizeof(flags));
if( c->status->updatingDb )
- strcat(flags, "U");
+ g_strlcat(flags, "U", sizeof(flags));
colors_use(w, COLOR_LINE);
mvwhline(w, 1, 0, ACS_HLINE, screen->top_window.cols);
if( flags[0] )
WINDOW *w = screen->status_window.w;
mpd_Status *status = c->status;
mpd_Song *song = c->song;
- int elapsedTime = c->status->elapsedTime;
+ int elapsedTime = 0;
char *str = NULL;
+ char *timestr = NULL;
int x = 0;
- if( time(NULL) - screen->status_timestamp <= STATUS_MESSAGE_TIMEOUT )
+ if( time(NULL) - screen->status_timestamp <= SCREEN_STATUS_MESSAGE_TIME )
return;
-
-
+
wmove(w, 0, 0);
wclrtoeol(w);
colors_use(w, COLOR_STATUS_BOLD);
if( IS_PLAYING(status->state) || IS_PAUSED(status->state) )
{
if( status->totalTime > 0 )
- {
- if( seek_id == c->song->id )
+ {
+
+ /*checks the conf to see whether to display elapsed or remaining time */
+ if(!strcmp(options.timedisplay_type,"elapsed"))
+ {
+ timestr= " [%i:%02i/%i:%02i]";
+ elapsedTime = c->status->elapsedTime;
+ }
+ else if(!strcmp(options.timedisplay_type,"remaining"))
+ {
+ timestr= " [-%i:%02i/%i:%02i]";
+ elapsedTime = (c->status->totalTime - c->status->elapsedTime);
+ }
+ if( c->song && seek_id == c->song->id )
elapsedTime = seek_target_time;
- snprintf(screen->buf, screen->buf_size,
- " [%i:%02i/%i:%02i]",
+ /*write out the time*/
+ g_snprintf(screen->buf, screen->buf_size,
+ timestr,
elapsedTime/60, elapsedTime%60,
status->totalTime/60, status->totalTime%60 );
}
else
{
- snprintf(screen->buf, screen->buf_size, " [%d kbps]", status->bitRate );
+ g_snprintf(screen->buf, screen->buf_size,
+ " [%d kbps]", status->bitRate );
}
}
-#ifdef ENABLE_STATUS_LINE_CLOCK
else
{
time_t timep;
time(&timep);
strftime(screen->buf, screen->buf_size, "%X ",localtime(&timep));
}
-#endif
/* display song */
if( (IS_PLAYING(status->state) || IS_PAUSED(status->state)) )
{
- char songname[STATUS_LINE_MAX_SIZE];
+ char songname[MAX_SONGNAME_LENGTH];
int width = COLS-x-strlen(screen->buf);
if( song )
- strfsong(songname, STATUS_LINE_MAX_SIZE, STATUS_FORMAT, song);
+ strfsong(songname, MAX_SONGNAME_LENGTH, STATUS_FORMAT, song);
else
songname[0] = '\0';
colors_use(w, COLOR_STATUS);
-#ifdef ENABLE_SCROLLING
+ /* scroll if the song name is to long */
if( strlen(songname) > width )
{
static scroll_state_t st = { 0, 0 };
char *tmp = strscroll(songname, " *** ", width, &st);
- strcpy(songname, tmp);
+ g_strlcpy(songname, tmp, MAX_SONGNAME_LENGTH);
g_free(tmp);
}
-#endif
mvwaddnstr(w, 0, x, songname, width);
}
- /* distplay time string */
+ /* display time string */
if( screen->buf[0] )
{
x = screen->status_window.cols - strlen(screen->buf);
wnoutrefresh(w);
}
-GList *
-screen_free_string_list(GList *list)
-{
- GList *l = g_list_first(list);
-
- while(l)
- {
- g_free(l->data);
- l->data = NULL;
- l=l->next;
- }
- g_list_free(list);
- return NULL;
-}
-
int
screen_exit(void)
{
endwin();
if( screen )
{
- GList *list = g_list_first(screen->screen_list);
+ gint i;
/* close and exit all screens (playlist,browse,help...) */
- while( list )
+ i=0;
+ while( screens[i].get_mode_functions )
{
- screen_functions_t *mode_fn = list->data;
+ screen_functions_t *mode_fn = screens[i].get_mode_functions();
if( mode_fn && mode_fn->close )
mode_fn->close();
if( mode_fn && mode_fn->exit )
mode_fn->exit();
- list->data = NULL;
- list=list->next;
+
+ i++;
}
- g_list_free(screen->screen_list);
- screen_free_string_list(screen->find_history);
+
+ string_list_free(screen->find_history);
g_free(screen->buf);
g_free(screen->findbuf);
void
screen_resize(void)
{
- GList *list;
+ gint i;
D("Resize rows %d->%d, cols %d->%d\n",screen->rows,LINES,screen->cols,COLS);
if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
g_free(screen->buf);
screen->buf = g_malloc(screen->cols);
- list = g_list_first(screen->screen_list);
- while( list )
+ /* close and exit all screens (playlist,browse,help...) */
+ i=0;
+ while( screens[i].get_mode_functions )
{
- screen_functions_t *mode_fn = list->data;
+ screen_functions_t *mode_fn = screens[i].get_mode_functions();
if( mode_fn && mode_fn->resize )
mode_fn->resize(screen->main_window.cols, screen->main_window.rows);
- list=list->next;
+ i++;
}
/* ? - without this the cursor becomes visible with aterm & Eterm */
void
screen_status_printf(char *format, ...)
{
- char buffer[STATUS_LINE_MAX_SIZE];
+ char *msg;
va_list ap;
va_start(ap,format);
- vsnprintf(buffer,sizeof(buffer),format,ap);
+ msg = g_strdup_vprintf(format,ap);
va_end(ap);
- screen_status_message(buffer);
+ screen_status_message(msg);
+ g_free(msg);
}
int
screen_init(mpdclient_t *c)
{
- GList *list;
+ gint i;
/* initialize the curses library */
initscr();
/* tell curses not to do NL->CR/NL on output */
nonl();
/* use raw mode (ignore interrupt,quit,suspend, and flow control ) */
+#ifdef ENABLE_RAW_MODE
raw();
+#endif
/* don't echo input */
noecho();
/* set cursor invisible */
keypad(stdscr, TRUE);
/* return from getch() without blocking */
timeout(SCREEN_TIMEOUT);
-
+ /* initialize mouse support */
+#ifdef HAVE_GETMOUSE
+ if( options.enable_mouse )
+ mousemask(ALL_MOUSE_EVENTS, NULL);
+#endif
if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
{
screen = g_malloc(sizeof(screen_t));
memset(screen, 0, sizeof(screen_t));
- screen->mode = SCREEN_PLAY_WINDOW;
+ screen->mode = 0;
screen->cols = COLS;
screen->rows = LINES;
screen->buf = g_malloc(screen->cols);
}
/* initialize screens */
- screen->screen_list = NULL;
- screen->screen_list = g_list_append(screen->screen_list,
- (gpointer) get_screen_playlist());
- screen->screen_list = g_list_append(screen->screen_list,
- (gpointer) get_screen_browse());
- screen->screen_list = g_list_append(screen->screen_list,
- (gpointer) get_screen_help());
-#ifdef ENABLE_KEYDEF_SCREEN
- screen->screen_list = g_list_append(screen->screen_list,
- (gpointer) get_screen_keydef());
-#endif
-#ifdef ENABLE_CLOCK_SCREEN
- screen->screen_list = g_list_append(screen->screen_list,
- (gpointer) get_screen_clock());
-#endif
-
- list = screen->screen_list;
- while( list )
+ i=0;
+ while( screens[i].get_mode_functions )
{
- screen_functions_t *fn = list->data;
-
+ screen_functions_t *fn = screens[i].get_mode_functions();
+
if( fn && fn->init )
fn->init(screen->main_window.w,
screen->main_window.cols,
screen->main_window.rows);
-
- list = list->next;
+
+ i++;
}
+#if 0
+ /* broken */
+ mode_fn = NULL;
+ switch_screen_mode(screen_get_id(options.screen_list[0]), c);
+#else
mode_fn = get_screen_playlist();
+#endif
+
if( mode_fn && mode_fn->open )
mode_fn->open(screen, c);
/* initialize wreadln */
- wrln_resize_callback = screen_resize;
+ wrln_wgetch = my_wgetch;
wrln_max_history_length = 16;
return 0;
void
screen_paint(mpdclient_t *c)
{
- /* paint the title/header window */
+ char *title = NULL;
+
if( mode_fn && mode_fn->get_title )
- paint_top_window(mode_fn->get_title(screen->buf,screen->buf_size), c, 1);
+ title = mode_fn->get_title(screen->buf,screen->buf_size);
+
+ D("screen_paint(%s)\n", title);
+ /* paint the title/header window */
+ if( title )
+ paint_top_window(title, c, 1);
else
paint_top_window("", c, 1);
/* paint the main window */
+ wclear(screen->main_window.w);
if( mode_fn && mode_fn->paint )
mode_fn->paint(screen, c);
seek_id = -1;
}
+#ifdef HAVE_GETMOUSE
+int
+screen_get_mouse_event(mpdclient_t *c,
+ list_window_t *lw, int lw_length,
+ unsigned long *bstate, int *row)
+{
+ MEVENT event;
+
+ /* retreive the mouse event from ncurses */
+ getmouse(&event);
+ D("mouse: id=%d y=%d,x=%d,z=%d\n",event.id,event.y,event.x,event.z);
+ /* calculate the selected row in the list window */
+ *row = event.y - screen->top_window.rows;
+ /* copy button state bits */
+ *bstate = event.bstate;
+ /* if button 2 was pressed switch screen */
+ if( event.bstate & BUTTON2_CLICKED )
+ {
+ screen_cmd(c, CMD_SCREEN_NEXT);
+ return 1;
+ }
+ /* if the even occured above the list window move up */
+ if( *row<0 && lw )
+ {
+ if( event.bstate & BUTTON3_CLICKED )
+ list_window_first(lw);
+ else
+ list_window_previous_page(lw);
+ return 1;
+ }
+ /* if the even occured below the list window move down */
+ if( *row>=lw->rows && lw )
+ {
+ if( event.bstate & BUTTON3_CLICKED )
+ list_window_last(lw, lw_length);
+ else
+ list_window_next_page(lw, lw_length);
+ return 1;
+ }
+ return 0;
+}
+#endif
+
void
screen_cmd(mpdclient_t *c, command_t cmd)
{
- screen_mode_t new_mode = screen->mode;
-
screen->input_timestamp = time(NULL);
screen->last_cmd = cmd;
welcome = FALSE;
seek_id = c->song->id;
seek_target_time = c->status->elapsedTime;
}
- seek_target_time++;
+ seek_target_time+=options.seek_time;
if( seek_target_time < c->status->totalTime )
break;
- seek_target_time=0;
+ seek_target_time = c->status->totalTime;
+ /* seek_target_time=0; */
}
+ break;
/* fall through... */
case CMD_TRACK_NEXT:
if( !IS_STOPPED(c->status->state) )
seek_id = c->song->id;
seek_target_time = c->status->elapsedTime;
}
- seek_target_time--;
+ seek_target_time-=options.seek_time;
if( seek_target_time < 0 )
seek_target_time=0;
}
mpdclient_cmd_random(c, !c->status->random);
break;
case CMD_CROSSFADE:
- mpdclient_cmd_crossfade(c, c->status->crossfade ? 0 : CROSSFADE_TIME);
+ if( c->status->crossfade )
+ mpdclient_cmd_crossfade(c, 0);
+ else
+ mpdclient_cmd_crossfade(c, options.crossfade_time);
break;
case CMD_DB_UPDATE:
if( !c->status->updatingDb )
{
- if( mpdclient_cmd_db_update(c)==0 )
+ if( mpdclient_cmd_db_update_utf8(c,NULL)==0 )
screen_status_printf(_("Database update started!"));
}
else
_("Auto center mode: On") :
_("Auto center mode: Off"));
break;
+ case CMD_SCREEN_UPDATE:
+ screen->painted = 0;
+ break;
case CMD_SCREEN_PREVIOUS:
- if( screen->mode > SCREEN_PLAY_WINDOW )
- new_mode = screen->mode - 1;
- else
- new_mode = SCREEN_HELP_WINDOW-1;
- switch_screen_mode(new_mode, c);
+ screen_next_mode(c, -1);
break;
case CMD_SCREEN_NEXT:
- new_mode = screen->mode + 1;
- if( new_mode >= SCREEN_HELP_WINDOW )
- new_mode = SCREEN_PLAY_WINDOW;
- switch_screen_mode(new_mode, c);
+ screen_next_mode(c, 1);
break;
case CMD_SCREEN_PLAY:
- switch_screen_mode(SCREEN_PLAY_WINDOW, c);
+ switch_screen_mode(SCREEN_PLAYLIST_ID, c);
break;
case CMD_SCREEN_FILE:
- switch_screen_mode(SCREEN_FILE_WINDOW, c);
+ switch_screen_mode(SCREEN_BROWSE_ID, c);
+ break;
+ case CMD_SCREEN_HELP:
+ switch_screen_mode(SCREEN_HELP_ID, c);
break;
case CMD_SCREEN_SEARCH:
- switch_screen_mode(SCREEN_SEARCH_WINDOW, c);
+ switch_screen_mode(SCREEN_SEARCH_ID, c);
break;
- case CMD_SCREEN_HELP:
- switch_screen_mode(SCREEN_HELP_WINDOW, c);
+ case CMD_SCREEN_ARTIST:
+ switch_screen_mode(SCREEN_ARTIST_ID, c);
break;
-#ifdef ENABLE_KEYDEF_SCREEN
case CMD_SCREEN_KEYDEF:
- switch_screen_mode(SCREEN_KEYDEF_WINDOW, c);
+ switch_screen_mode(SCREEN_KEYDEF_ID, c);
break;
-#endif
-#ifdef ENABLE_CLOCK_SCREEN
case CMD_SCREEN_CLOCK:
- switch_screen_mode(SCREEN_CLOCK_WINDOW, c);
+ switch_screen_mode(SCREEN_CLOCK_ID, c);
break;
-#endif
case CMD_QUIT:
exit(EXIT_SUCCESS);
default: