Code

Crossfade time can now be definied in the rc file (crossfade-time)
[ncmpc.git] / src / screen.c
index 4059ac24fbb4168c438d24689529b1f99b707fd4..eacc78f88ee7011e14c1dcc7ed7e082d0f2c515f 100644 (file)
@@ -1,5 +1,7 @@
 /* 
- * (c) 2004 by Kalle Wallin (kaw@linux.se)
+ * $Id$
+ *
+ * (c) 2004 by Kalle Wallin <kaw@linux.se>
  *
  * 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
 #include <stdarg.h>
 #include <string.h>
 #include <time.h>
-//#include <signal.h>
 #include <locale.h>
 #include <glib.h>
 #include <ncurses.h>
 
 #include "config.h"
-#include "libmpdclient.h"
-#include "mpc.h"
+#include "ncmpc.h"
+#include "support.h"
+#include "mpdclient.h"
 #include "command.h"
 #include "options.h"
 #include "colors.h"
+#include "strfsong.h"
+#include "wreadln.h"
 #include "screen.h"
-#include "screen_play.h"
-#include "screen_file.h"
-#include "screen_help.h"
-#include "screen_search.h"
 #include "screen_utils.h"
 
-#undef  ENABLE_STATUS_LINE_CLOCK
+#define ENABLE_STATUS_LINE_CLOCK
 #define ENABLE_SCROLLING
 
-#define DEFAULT_CROSSFADE_TIME 10
-
 #define STATUS_MESSAGE_TIMEOUT 3
 #define STATUS_LINE_MAX_SIZE   512
 
+#define SCREEN_PLAYLIST_ID     0
+#define SCREEN_BROWSE_ID       1
+#define SCREEN_HELP_ID         100
+#define SCREEN_KEYDEF_ID       101
+#define SCREEN_CLOCK_ID        102
+
+/* 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);
+
 #ifdef ENABLE_KEYDEF_SCREEN
 extern screen_functions_t *get_screen_keydef(void);
 #endif
+#ifdef ENABLE_CLOCK_SCREEN
+extern screen_functions_t *get_screen_clock(void);
+#endif
+
+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 },
+  { SCREEN_HELP_ID,     "help",     get_screen_help },
+#ifdef ENABLE_KEYDEF_SCREEN
+  { SCREEN_KEYDEF_ID,   "keydef",   get_screen_keydef },
+#endif
+#ifdef ENABLE_CLOCK_SCREEN
+  { SCREEN_CLOCK_ID,    "clock",    get_screen_clock },
+#endif
+  { -1, NULL,      NULL }
+};
 
+static gboolean welcome = TRUE;
 static screen_t *screen = NULL;
 static screen_functions_t *mode_fn = NULL;
+static int seek_id = -1;
+static int seek_target_time = 0;
+
+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, mpd_client_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 */
@@ -65,37 +119,23 @@ switch_screen_mode(screen_mode_t new_mode, mpd_client_t *c)
     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_file();
-      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
-    default:
-      break;
+      mode_fn = screens[new_mode].get_mode_functions();
+      screen->mode = new_mode;
     }
 
- screen->mode = new_mode;
- screen->painted = 0;
-
- /* open the new mode */
- if( mode_fn && mode_fn->open )
-   mode_fn->open(screen, c);
+  screen->painted = 0;
+  
+  /* open the new mode */
+  if( mode_fn && mode_fn->open )
+    mode_fn->open(screen, c);
 
 }
 
 static void
-paint_top_window(char *header, mpd_client_t *c, int clear)
+paint_top_window(char *header, mpdclient_t *c, int clear)
 {
   char flags[4];
   static int prev_volume = -1;
@@ -128,23 +168,23 @@ paint_top_window(char *header, mpd_client_t *c, int clear)
          colors_use(w, COLOR_TITLE_BOLD);
          waddstr(w, get_key_names(CMD_SCREEN_HELP, FALSE));
          colors_use(w, COLOR_TITLE);
-         waddstr(w, ":Help  ");
+         waddstr(w, _(":Help  "));
          colors_use(w, COLOR_TITLE_BOLD);
          waddstr(w, get_key_names(CMD_SCREEN_PLAY, FALSE));
          colors_use(w, COLOR_TITLE);
-         waddstr(w, ":Playlist  ");
+         waddstr(w, _(":Playlist  "));
          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"));
        }
       if( c->status->volume==MPD_STATUS_NO_VOLUME )
        {
-         snprintf(buf, 32, "Volume n/a ");
+         snprintf(buf, 32, _("Volume n/a "));
        }
       else
        {
-         snprintf(buf, 32, " Volume %d%%", c->status->volume); 
+         snprintf(buf, 32, _(" Volume %d%%"), c->status->volume); 
        }
       colors_use(w, COLOR_TITLE);
       mvwaddstr(w, 0, screen->top_window.cols-strlen(buf), buf);
@@ -174,7 +214,7 @@ paint_top_window(char *header, mpd_client_t *c, int clear)
 }
 
 static void
-paint_progress_window(mpd_client_t *c)
+paint_progress_window(mpdclient_t *c)
 {
   double p;
   int width;
@@ -188,8 +228,8 @@ paint_progress_window(mpd_client_t *c)
       return;
     }
 
-  if( c->seek_song_id == c->song_id )
-    elapsedTime = c->seek_target_time;
+  if( c->song && seek_id == c->song->id )
+    elapsedTime = seek_target_time;
 
   p = ((double) elapsedTime) / ((double) c->status->totalTime);
   
@@ -203,53 +243,14 @@ paint_progress_window(mpd_client_t *c)
   wnoutrefresh(screen->progress_window.w);
 }
 
-#ifdef ENABLE_SCROLLING
-static char *
-scroll_string(char *str, char *sep, int width)
-{
-  static int offset = 0;
-  static time_t t = 0;
-  char *tmp, *buf;
-  size_t len;
-
-  if( offset==0 )
-    {
-      offset++;
-      return g_strdup(str);
-    }
-  /* create a buffer containing the string and the separator */
-  tmp = g_malloc(strlen(str)+strlen(sep)+1);
-  strcpy(tmp, str);
-  strcat(tmp, sep);
-  len = strlen(tmp);
-
-  if( offset >= len )
-   offset = 0;
-  
-  /* create the new scrolled string */
-  buf = g_malloc(width+1);
-  strncpy(buf, tmp+offset, width);
-  if( strlen(buf) < width )
-    strncat(buf, tmp, width-strlen(buf));
-
-  if( time(NULL)-t >= 1 )
-    {
-      t = time(NULL);
-      offset++;
-    }
-  g_free(tmp);
-  return buf;
-}
-#endif
-
 static void 
-paint_status_window(mpd_client_t *c)
+paint_status_window(mpdclient_t *c)
 {
   WINDOW *w = screen->status_window.w;
   mpd_Status *status = c->status;
   mpd_Song *song   = c->song;
   int elapsedTime = c->status->elapsedTime;
+  char *str = NULL;
   int x = 0;
 
   if( time(NULL) - screen->status_timestamp <= STATUS_MESSAGE_TIMEOUT )
@@ -262,19 +263,22 @@ paint_status_window(mpd_client_t *c)
   
   switch(status->state)
     {
-    case MPD_STATUS_STATE_STOP:
-      waddstr(w, "Stopped! ");
-      break;
     case MPD_STATUS_STATE_PLAY:
-      waddstr(w, "Playing:");
+      str = _("Playing:");
       break;
     case MPD_STATUS_STATE_PAUSE:
-      waddstr(w, "[Paused]");
+      str = _("[Paused]");
       break;
+    case MPD_STATUS_STATE_STOP:
     default:
       break;
     }
-  x += 9;
+
+  if( str )
+    {
+      waddstr(w, str);
+      x += strlen(str)+1;
+    }
 
   /* create time string */
   memset(screen->buf, 0, screen->buf_size);
@@ -282,8 +286,8 @@ paint_status_window(mpd_client_t *c)
     {
       if( status->totalTime > 0 )
        {
-         if( c->seek_song_id == c->song_id )
-           elapsedTime = c->seek_target_time;
+         if( c->song && seek_id == c->song->id )
+           elapsedTime = seek_target_time;
          snprintf(screen->buf, screen->buf_size, 
                   " [%i:%02i/%i:%02i]",
                   elapsedTime/60, elapsedTime%60,
@@ -294,29 +298,36 @@ paint_status_window(mpd_client_t *c)
          snprintf(screen->buf, screen->buf_size,  " [%d kbps]", status->bitRate );
        }
     }
+#ifdef ENABLE_STATUS_LINE_CLOCK
   else
     {
       time_t timep;
 
       time(&timep);
-      /* Note: setlocale(LC_TIME,"") should be used first */
-      //strftime(screen->buf, screen->buf_size, "%X ",  localtime(&timep));
-      strftime(screen->buf, screen->buf_size, " %k:%M",  localtime(&timep));
+      strftime(screen->buf, screen->buf_size, "%X ",localtime(&timep));
     }
+#endif
 
   /* display song */
-  if( (IS_PLAYING(status->state) || IS_PAUSED(status->state)) &&  song )
+  if( (IS_PLAYING(status->state) || IS_PAUSED(status->state)) )
     {
-      char *songname = mpc_get_song_name(song);
+      char songname[STATUS_LINE_MAX_SIZE];
       int width = COLS-x-strlen(screen->buf);
 
+      if( song )
+       strfsong(songname, STATUS_LINE_MAX_SIZE, STATUS_FORMAT, song);
+      else
+       songname[0] = '\0';
+
       colors_use(w, COLOR_STATUS);
 #ifdef ENABLE_SCROLLING
       if( strlen(songname) > width )
        {
-         char *tmp = scroll_string(songname, " *** ", width);
+         static  scroll_state_t st = { 0, 0 };
+         char *tmp = strscroll(songname, " *** ", width, &st);
+
          strcpy(songname, tmp);
-         g_free(tmp);
+         g_free(tmp);    
        }
 #endif
       mvwaddnstr(w, 0, x, songname, width);
@@ -330,24 +341,23 @@ paint_status_window(mpd_client_t *c)
       mvwaddstr(w, 0, x, screen->buf);
     }
 
-#ifdef ENABLE_STATUS_LINE_CLOCK
-  else if( c->status->state == MPD_STATUS_STATE_STOP )
-    {
-      time_t timep;
-
-      /* Note: setlocale(LC_TIME,"") should be used first */
-      time(&timep);
-      strftime(screen->buf, screen->buf_size, "%X ",  localtime(&timep));
-      x = screen->status_window.cols - strlen(screen->buf) ;
-      colors_use(w, COLOR_STATUS_TIME);
-      mvwaddstr(w, 0, x, screen->buf);
-    }
-#endif
-
   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)
@@ -355,24 +365,26 @@ 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;
-       }
-      g_list_free(screen->screen_list);
 
+         i++;
+       }
+     
+      screen_free_string_list(screen->find_history);
       g_free(screen->buf);
       g_free(screen->findbuf);
+      
       g_free(screen);
       screen = NULL;
     }
@@ -382,18 +394,13 @@ screen_exit(void)
 void
 screen_resize(void)
 {
-  GList *list;
+  gint i;
 
-#ifdef DEBUG
-  fprintf(stderr, "Resize rows %d->%d, cols %d->%d\n",
-         screen->rows, LINES,
-         screen->cols, COLS);
-#endif
-      
+  D("Resize rows %d->%d, cols %d->%d\n",screen->rows,LINES,screen->cols,COLS);
   if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
     {
       screen_exit();
-      fprintf(stderr, "Error: Screen to small!\n");
+      fprintf(stderr, _("Error: Screen to small!\n"));
       exit(EXIT_FAILURE);
     }
 
@@ -426,15 +433,16 @@ screen_resize(void)
   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 */
@@ -470,9 +478,9 @@ screen_status_printf(char *format, ...)
 }
 
 int
-screen_init(void)
+screen_init(mpdclient_t *c)
 {
-  GList *list;
+  gint i;
 
   /* initialize the curses library */
   initscr();
@@ -480,26 +488,33 @@ screen_init(void)
   colors_start();
   /* tell curses not to do NL->CR/NL on output */
   nonl();          
-  /* take input chars one at a time, no wait for \n */  
-  cbreak();       
+  /*  use raw mode (ignore interrupt,quit,suspend, and flow control ) */
+#ifdef ENABLE_RAW_MODE
+  raw();
+#endif
   /* don't echo input */
   noecho();    
   /* set cursor invisible */     
   curs_set(0);     
-  /* return from getch() without blocking */
-  //  nodelay(stdscr, TRUE); 
+  /* enable extra keys */
   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 )
     {
-      fprintf(stderr, "Error: Screen to small!\n");
+      fprintf(stderr, _("Error: Screen to small!\n"));
       exit(EXIT_FAILURE);
     }
 
   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);
@@ -562,46 +577,42 @@ screen_init(void)
     }
 
   /* 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_file());
-  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
-
-  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++;
     }
 
   mode_fn = get_screen_playlist();
+  if( mode_fn && mode_fn->open )
+    mode_fn->open(screen, c);
+
+  /* initialize wreadln */
+  wrln_wgetch = my_wgetch;
+  wrln_max_history_length = 16;
 
   return 0;
 }
 
 void 
-screen_paint(mpd_client_t *c)
+screen_paint(mpdclient_t *c)
 {
+  D("screen_paint()\n");
   /* paint the title/header window */
   if( mode_fn && mode_fn->get_title )
-    paint_top_window(mode_fn->get_title(), c, 1);
+    paint_top_window(mode_fn->get_title(screen->buf,screen->buf_size), 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);
   
@@ -616,13 +627,12 @@ screen_paint(mpd_client_t *c)
 }
 
 void 
-screen_update(mpd_client_t *c)
+screen_update(mpdclient_t *c)
 {
   static int repeat = -1;
   static int random = -1;
   static int crossfade = -1;
   static int dbupdate = -1;
-  static int welcome = 1;
   list_window_t *lw = NULL;
 
   if( !screen->painted )
@@ -637,15 +647,21 @@ screen_update(mpd_client_t *c)
       dbupdate = c->status->updatingDb;
     }
   if( repeat != c->status->repeat )
-    screen_status_printf("Repeat is %s", 
-                        c->status->repeat  ? "On" : "Off");
+    screen_status_printf(c->status->repeat ? 
+                        _("Repeat is on") :
+                        _("Repeat is off"));
   if( random != c->status->random )
-    screen_status_printf("Random is %s", 
-                        c->status->random ? "On" : "Off");
+    screen_status_printf(c->status->random ?
+                        _("Random is on") :
+                        _("Random is off"));
+                        
   if( crossfade != c->status->crossfade )
-    screen_status_printf("Crossfade %d seconds", c->status->crossfade);
+    screen_status_printf(_("Crossfade %d seconds"), c->status->crossfade);
   if( dbupdate && dbupdate != c->status->updatingDb )
-    screen_status_printf("Database updated!");
+    {
+      screen_status_printf(_("Database updated!"));
+      mpdclient_browse_callback(c, BROWSE_DB_UPDATED, NULL);
+    }
 
   repeat = c->status->repeat;
   random = c->status->random;
@@ -658,8 +674,8 @@ screen_update(mpd_client_t *c)
     paint_top_window("", c, 0);
   else if( mode_fn && mode_fn->get_title )
     {
-      paint_top_window(mode_fn->get_title(), c, 0);
-      welcome = 0;
+      paint_top_window(mode_fn->get_title(screen->buf,screen->buf_size), c, 0);
+      welcome = FALSE;
     }
   else
     paint_top_window("", c, 0);
@@ -689,30 +705,68 @@ screen_update(mpd_client_t *c)
 }
 
 void
-screen_idle(mpd_client_t *c)
+screen_idle(mpdclient_t *c)
 {
-  if( c->seek_song_id ==  c->song_id &&
+  if( c->song && seek_id ==  c->song->id &&
       (screen->last_cmd == CMD_SEEK_FORWARD || 
        screen->last_cmd == CMD_SEEK_BACKWARD) )
     {
-      mpd_sendSeekCommand(c->connection, 
-                         c->seek_song_id, 
-                         c->seek_target_time);
-      mpd_finishCommand(c->connection);
+      mpdclient_cmd_seek(c, seek_id, seek_target_time);
     }
 
   screen->last_cmd = CMD_NONE;
-  c->seek_song_id = -1;
+  seek_id = -1;
 }
 
-void 
-screen_cmd(mpd_client_t *c, command_t cmd)
+#ifdef HAVE_GETMOUSE
+int
+screen_get_mouse_event(mpdclient_t *c,
+                      list_window_t *lw, int lw_length, 
+                      unsigned long *bstate, int *row)
 {
-  int n = 0;
-  screen_mode_t new_mode = screen->mode;
+  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->input_timestamp = time(NULL);
   screen->last_cmd = cmd;
+  welcome = FALSE;
 
   if( mode_fn && mode_fn->cmd && mode_fn->cmd(screen, c, cmd) )
     return;
@@ -720,161 +774,135 @@ screen_cmd(mpd_client_t *c, command_t cmd)
   switch(cmd)
     {
     case CMD_PLAY:
-      mpd_sendPlayCommand(c->connection, play_get_selected());
-      mpd_finishCommand(c->connection);
+      mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
       break;
     case CMD_PAUSE:
-      mpd_sendPauseCommand(c->connection);
-      mpd_finishCommand(c->connection);
+      mpdclient_cmd_pause(c, !IS_PAUSED(c->status->state));
       break;
     case CMD_STOP:
-      mpd_sendStopCommand(c->connection);
-      mpd_finishCommand(c->connection);
+      mpdclient_cmd_stop(c);
       break;
     case CMD_SEEK_FORWARD:
       if( !IS_STOPPED(c->status->state) )
        {
-         if( c->seek_song_id != c->song_id )
+         if( c->song && seek_id != c->song->id )
            {
-             c->seek_song_id = c->song_id;
-             c->seek_target_time = c->status->elapsedTime;
+             seek_id = c->song->id;
+             seek_target_time = c->status->elapsedTime;
            }
-         c->seek_target_time++;
-         if( c->seek_target_time < c->status->totalTime )
+         seek_target_time++;
+         if( seek_target_time < c->status->totalTime )
            break;
-         c->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) )
-       {
-         mpd_sendNextCommand(c->connection);
-         mpd_finishCommand(c->connection);
-       }
+       mpdclient_cmd_next(c);
       break;
     case CMD_SEEK_BACKWARD:
       if( !IS_STOPPED(c->status->state) )
        {
-         if( c->seek_song_id != c->song_id )
+         if( seek_id != c->song->id )
            {
-             c->seek_song_id = c->song_id;
-             c->seek_target_time = c->status->elapsedTime;
+             seek_id = c->song->id;
+             seek_target_time = c->status->elapsedTime;
            }
-         c->seek_target_time--;
-         if( c->seek_target_time < 0 )
-           c->seek_target_time=0;
+         seek_target_time--;
+         if( seek_target_time < 0 )
+           seek_target_time=0;
        }
       break;
     case CMD_TRACK_PREVIOUS:
       if( !IS_STOPPED(c->status->state) )
-       {
-         mpd_sendPrevCommand(c->connection);
-         mpd_finishCommand(c->connection);
-       }
+       mpdclient_cmd_prev(c);
       break;   
     case CMD_SHUFFLE:
-      mpd_sendShuffleCommand(c->connection);
-      mpd_finishCommand(c->connection);
-      screen_status_message("Shuffled playlist!");
+      if( mpdclient_cmd_shuffle(c) == 0 )
+       screen_status_message(_("Shuffled playlist!"));
       break;
     case CMD_CLEAR:
-      mpd_sendClearCommand(c->connection);
-      mpd_finishCommand(c->connection);
-      file_clear_highlights(c);
-      screen_status_message("Cleared playlist!");
+      if( mpdclient_cmd_clear(c) == 0 )
+       screen_status_message(_("Cleared playlist!"));
       break;
     case CMD_REPEAT:
-      n = !c->status->repeat;
-      mpd_sendRepeatCommand(c->connection, n);
-      mpd_finishCommand(c->connection);
+      mpdclient_cmd_repeat(c, !c->status->repeat);
       break;
     case CMD_RANDOM:
-      n = !c->status->random;
-      mpd_sendRandomCommand(c->connection, n);
-      mpd_finishCommand(c->connection);
+      mpdclient_cmd_random(c, !c->status->random);
       break;
     case CMD_CROSSFADE:
-      if( c->status->crossfade )
-       n = 0;
+      if(  c->status->crossfade )
+       mpdclient_cmd_crossfade(c, 0);
       else
-       n = DEFAULT_CROSSFADE_TIME;
-      mpd_sendCrossfadeCommand(c->connection, n);
-      mpd_finishCommand(c->connection);
+       mpdclient_cmd_crossfade(c, options.crossfade_time);     
       break;
     case CMD_DB_UPDATE:
       if( !c->status->updatingDb )
        {
-         mpd_sendUpdateCommand(c->connection);
-         n = mpd_getUpdateId(c->connection);
-         mpd_finishCommand(c->connection);
-         if( !mpc_error(c) )
-           screen_status_printf("Database update started [%d]", n);
+         if( mpdclient_cmd_db_update_utf8(c,NULL)==0 )
+           screen_status_printf(_("Database update started!"));
        }
       else
-       screen_status_printf("Database update running...");
+       screen_status_printf(_("Database update running..."));
       break;
     case CMD_VOLUME_UP:
       if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume<100 )
-       {
-         c->status->volume=c->status->volume+1;
-         mpd_sendSetvolCommand(c->connection, c->status->volume  );
-         mpd_finishCommand(c->connection);
-       }
+       mpdclient_cmd_volume(c, ++c->status->volume);
       break;
     case CMD_VOLUME_DOWN:
       if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume>0 )
-       {
-         c->status->volume=c->status->volume-1;
-         mpd_sendSetvolCommand(c->connection, c->status->volume  );
-         mpd_finishCommand(c->connection);
-       }
+       mpdclient_cmd_volume(c, --c->status->volume);
       break;
     case CMD_TOGGLE_FIND_WRAP:
       options.find_wrap = !options.find_wrap;
-      screen_status_printf("Find mode: %s", 
-                          options.find_wrap ? "Wrapped" : "Normal");
+      screen_status_printf(options.find_wrap ? 
+                          _("Find mode: Wrapped") :
+                          _("Find mode: Normal"));
       break;
     case CMD_TOGGLE_AUTOCENTER:
       options.auto_center = !options.auto_center;
-      screen_status_printf("Auto center mode: %s", 
-                          options.auto_center ? "On" : "Off");
+      screen_status_printf(options.auto_center ?
+                          _("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;
+      if( screen->mode > 0 )
+       switch_screen_mode(screens[screen->mode-1].id, c);
       else
-       new_mode = SCREEN_HELP_WINDOW-1;
-      switch_screen_mode(new_mode, c);
+       switch_screen_mode(lookup_mode(SCREEN_HELP_ID)-1, c);
       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);
+      if( screens[screen->mode+1].id < SCREEN_HELP_ID )
+       switch_screen_mode(screens[screen->mode+1].id, c);
+      else
+       switch_screen_mode(screens[0].id, c);
       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);
-      break;
-    case CMD_SCREEN_SEARCH:
-      switch_screen_mode(SCREEN_SEARCH_WINDOW, c);
+      switch_screen_mode(SCREEN_BROWSE_ID, c);
       break;
     case CMD_SCREEN_HELP:
-      switch_screen_mode(SCREEN_HELP_WINDOW, c);
+      switch_screen_mode(SCREEN_HELP_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;
+    case CMD_SCREEN_CLOCK:
+      switch_screen_mode(SCREEN_CLOCK_ID, c);
       break;
-#endif
     case CMD_QUIT:
       exit(EXIT_SUCCESS);
     default:
       break;
     }
-
 }