Code

i18n - ncmpc is now bilingual (sv)
[ncmpc.git] / src / screen.c
1 /* 
2  * (c) 2004 by Kalle Wallin (kaw@linux.se)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  *
17  */
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <stdarg.h>
22 #include <string.h>
23 #include <time.h>
24 #include <locale.h>
25 #include <glib.h>
26 #include <ncurses.h>
28 #include "config.h"
29 #include "ncmpc.h"
30 #include "libmpdclient.h"
31 #include "mpc.h"
32 #include "command.h"
33 #include "options.h"
34 #include "colors.h"
35 #include "screen.h"
36 #include "screen_play.h"
37 #include "screen_file.h"
38 #include "screen_help.h"
39 #include "screen_search.h"
40 #include "screen_utils.h"
42 #undef  ENABLE_STATUS_LINE_CLOCK
43 #define ENABLE_SCROLLING
45 #define DEFAULT_CROSSFADE_TIME 10
47 #define STATUS_MESSAGE_TIMEOUT 3
48 #define STATUS_LINE_MAX_SIZE   512
50 #ifdef ENABLE_KEYDEF_SCREEN
51 extern screen_functions_t *get_screen_keydef(void);
52 #endif
54 static screen_t *screen = NULL;
55 static screen_functions_t *mode_fn = NULL;
57 static void
58 switch_screen_mode(screen_mode_t new_mode, mpd_client_t *c)
59 {
60   if( new_mode == screen->mode )
61     return;
63   /* close the old mode */
64   if( mode_fn && mode_fn->close )
65     mode_fn->close();
67   /* get functions for the new mode */
68   switch(new_mode)
69     {
70     case SCREEN_PLAY_WINDOW:
71       mode_fn = get_screen_playlist();
72       break;
73     case SCREEN_FILE_WINDOW:
74       mode_fn = get_screen_file();
75       break;
76     case SCREEN_HELP_WINDOW:
77       mode_fn = get_screen_help();
78       break;
79 #ifdef ENABLE_KEYDEF_SCREEN
80     case SCREEN_KEYDEF_WINDOW:
81       mode_fn = get_screen_keydef();
82       break;
83 #endif
84     default:
85       break;
86     }
88  screen->mode = new_mode;
89  screen->painted = 0;
91  /* open the new mode */
92  if( mode_fn && mode_fn->open )
93    mode_fn->open(screen, c);
95 }
97 static void
98 paint_top_window(char *header, mpd_client_t *c, int clear)
99 {
100   char flags[4];
101   static int prev_volume = -1;
102   static int prev_header_len = -1;
103   WINDOW *w = screen->top_window.w;
105   if(prev_header_len!=strlen(header))
106     {
107       prev_header_len = strlen(header);
108       clear = 1;
109     }
111   if(clear)
112     {
113       wmove(w, 0, 0);
114       wclrtoeol(w);
115     }
117   if(prev_volume!=c->status->volume || clear)
118     {
119       char buf[32];
121       if( header[0] )
122         {
123           colors_use(w, COLOR_TITLE_BOLD);
124           mvwaddstr(w, 0, 0, header);
125         }
126       else
127         {
128           colors_use(w, COLOR_TITLE_BOLD);
129           waddstr(w, get_key_names(CMD_SCREEN_HELP, FALSE));
130           colors_use(w, COLOR_TITLE);
131           waddstr(w, _(":Help  "));
132           colors_use(w, COLOR_TITLE_BOLD);
133           waddstr(w, get_key_names(CMD_SCREEN_PLAY, FALSE));
134           colors_use(w, COLOR_TITLE);
135           waddstr(w, _(":Playlist  "));
136           colors_use(w, COLOR_TITLE_BOLD);
137           waddstr(w, get_key_names(CMD_SCREEN_FILE, FALSE));
138           colors_use(w, COLOR_TITLE);
139           waddstr(w, _(":Browse"));
140         }
141       if( c->status->volume==MPD_STATUS_NO_VOLUME )
142         {
143           snprintf(buf, 32, _("Volume n/a "));
144         }
145       else
146         {
147           snprintf(buf, 32, _(" Volume %d%%"), c->status->volume); 
148         }
149       colors_use(w, COLOR_TITLE);
150       mvwaddstr(w, 0, screen->top_window.cols-strlen(buf), buf);
152       flags[0] = 0;
153       if( c->status->repeat )
154         strcat(flags, "r");
155       if( c->status->random )
156         strcat(flags, "z");
157       if( c->status->crossfade )
158         strcat(flags, "x");
159       if( c->status->updatingDb )
160         strcat(flags, "U");
161       colors_use(w, COLOR_LINE);
162       mvwhline(w, 1, 0, ACS_HLINE, screen->top_window.cols);
163       if( flags[0] )
164         {
165           wmove(w,1,screen->top_window.cols-strlen(flags)-3);
166           waddch(w, '[');
167           colors_use(w, COLOR_LINE_BOLD);
168           waddstr(w, flags);
169           colors_use(w, COLOR_LINE);
170           waddch(w, ']');
171         }
172       wnoutrefresh(w);
173     }
176 static void
177 paint_progress_window(mpd_client_t *c)
179   double p;
180   int width;
181   int elapsedTime = c->status->elapsedTime;
183   if( c->status==NULL || IS_STOPPED(c->status->state) )
184     {
185       mvwhline(screen->progress_window.w, 0, 0, ACS_HLINE, 
186                screen->progress_window.cols);
187       wnoutrefresh(screen->progress_window.w);
188       return;
189     }
191   if( c->seek_song_id == c->song_id )
192     elapsedTime = c->seek_target_time;
194   p = ((double) elapsedTime) / ((double) c->status->totalTime);
195   
196   width = (int) (p * (double) screen->progress_window.cols);
197   mvwhline(screen->progress_window.w, 
198            0, 0,
199            ACS_HLINE, 
200            screen->progress_window.cols);
201   whline(screen->progress_window.w, '=', width-1);
202   mvwaddch(screen->progress_window.w, 0, width-1, 'O');
203   wnoutrefresh(screen->progress_window.w);
206 #ifdef ENABLE_SCROLLING
207 static char *
208 scroll_string(char *str, char *sep, int width)
210   static int offset = 0;
211   static time_t t = 0;
212   char *tmp, *buf;
213   size_t len;
215   if( offset==0 )
216     {
217       offset++;
218       return g_strdup(str);
219     }
220  
221   /* create a buffer containing the string and the separator */
222   tmp = g_malloc(strlen(str)+strlen(sep)+1);
223   strcpy(tmp, str);
224   strcat(tmp, sep);
225   len = strlen(tmp);
227   if( offset >= len )
228    offset = 0;
229   
230   /* create the new scrolled string */
231   buf = g_malloc(width+1);
232   strncpy(buf, tmp+offset, width);
233   if( strlen(buf) < width )
234     strncat(buf, tmp, width-strlen(buf));
236   if( time(NULL)-t >= 1 )
237     {
238       t = time(NULL);
239       offset++;
240     }
241   g_free(tmp);
242   return buf;
244 #endif
246 static void 
247 paint_status_window(mpd_client_t *c)
249   WINDOW *w = screen->status_window.w;
250   mpd_Status *status = c->status;
251   mpd_Song *song   = c->song;
252   int elapsedTime = c->status->elapsedTime;
253   int x = 0;
255   if( time(NULL) - screen->status_timestamp <= STATUS_MESSAGE_TIMEOUT )
256     return;
257   
258   
259   wmove(w, 0, 0);
260   wclrtoeol(w);
261   colors_use(w, COLOR_STATUS_BOLD);
262   
263   switch(status->state)
264     {
265     case MPD_STATUS_STATE_STOP:
266       waddstr(w, _("Stopped! "));
267       break;
268     case MPD_STATUS_STATE_PLAY:
269       waddstr(w, _("Playing:"));
270       break;
271     case MPD_STATUS_STATE_PAUSE:
272       waddstr(w, _("[Paused]"));
273       break;
274     default:
275       break;
276     }
277   x += 9;
279   /* create time string */
280   memset(screen->buf, 0, screen->buf_size);
281   if( IS_PLAYING(status->state) || IS_PAUSED(status->state) )
282     {
283       if( status->totalTime > 0 )
284         {
285           if( c->seek_song_id == c->song_id )
286             elapsedTime = c->seek_target_time;
287           snprintf(screen->buf, screen->buf_size, 
288                    " [%i:%02i/%i:%02i]",
289                    elapsedTime/60, elapsedTime%60,
290                    status->totalTime/60,   status->totalTime%60 );
291         }
292       else
293         {
294           snprintf(screen->buf, screen->buf_size,  " [%d kbps]", status->bitRate );
295         }
296     }
297   else
298     {
299       time_t timep;
301       time(&timep);
302       /* Note: setlocale(LC_TIME,"") should be used first */
303       //strftime(screen->buf, screen->buf_size, "%X ",  localtime(&timep));
304       strftime(screen->buf, screen->buf_size, " %k:%M",  localtime(&timep));
305     }
307   /* display song */
308   if( (IS_PLAYING(status->state) || IS_PAUSED(status->state)) &&  song )
309     {
310       char *songname = mpc_get_song_name(song);
311       int width = COLS-x-strlen(screen->buf);
313       colors_use(w, COLOR_STATUS);
314 #ifdef ENABLE_SCROLLING
315       if( strlen(songname) > width )
316         {
317           char *tmp = scroll_string(songname, " *** ", width);
318           strcpy(songname, tmp);
319           g_free(tmp);
320         }
321 #endif
322       mvwaddnstr(w, 0, x, songname, width);
323     } 
325   /* distplay time string */
326   if( screen->buf[0] )
327     {
328       x = screen->status_window.cols - strlen(screen->buf);
329       colors_use(w, COLOR_STATUS_TIME);
330       mvwaddstr(w, 0, x, screen->buf);
331     }
333   wnoutrefresh(w);
338 int
339 screen_exit(void)
341   endwin();
342   if( screen )
343     {
344       GList *list = g_list_first(screen->screen_list);
346       /* close and exit all screens (playlist,browse,help...) */
347       while( list )
348         {
349           screen_functions_t *mode_fn = list->data;
351           if( mode_fn && mode_fn->close )
352             mode_fn->close();
353           if( mode_fn && mode_fn->exit )
354             mode_fn->exit();
355           list->data = NULL;
356           list=list->next;
357         }
358       g_list_free(screen->screen_list);
360       g_free(screen->buf);
361       g_free(screen->findbuf);
362       g_free(screen);
363       screen = NULL;
364     }
365   return 0;
368 void
369 screen_resize(void)
371   GList *list;
373 #ifdef DEBUG
374   fprintf(stderr, "Resize rows %d->%d, cols %d->%d\n",
375           screen->rows, LINES,
376           screen->cols, COLS);
377 #endif
378       
379   if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
380     {
381       screen_exit();
382       fprintf(stderr, _("Error: Screen to small!\n"));
383       exit(EXIT_FAILURE);
384     }
386   resizeterm(LINES, COLS);
388   screen->cols = COLS;
389   screen->rows = LINES;
391   /* top window */
392   screen->top_window.cols = screen->cols;
393   wresize(screen->top_window.w, 2, screen->cols);
395   /* main window */
396   screen->main_window.cols = screen->cols;
397   screen->main_window.rows = screen->rows-4;
398   wresize(screen->main_window.w, screen->main_window.rows, screen->cols);
399   wclear(screen->main_window.w);
401   /* progress window */
402   screen->progress_window.cols = screen->cols;
403   wresize(screen->progress_window.w, 1, screen->cols);
404   mvwin(screen->progress_window.w, screen->rows-2, 0);
406   /* status window */
407   screen->status_window.cols = screen->cols;
408   wresize(screen->status_window.w, 1, screen->cols);
409   mvwin(screen->status_window.w, screen->rows-1, 0);
411   screen->buf_size = screen->cols;
412   g_free(screen->buf);
413   screen->buf = g_malloc(screen->cols);
415   list = g_list_first(screen->screen_list);
416   while( list )
417     {
418       screen_functions_t *mode_fn = list->data;
420       if( mode_fn && mode_fn->resize )
421         mode_fn->resize(screen->main_window.cols, screen->main_window.rows);
423       list=list->next;
424     }
426   /* ? - without this the cursor becomes visible with aterm & Eterm */
427   curs_set(1);
428   curs_set(0);     
430   screen->painted = 0;
433 void 
434 screen_status_message(char *msg)
436   WINDOW *w = screen->status_window.w;
438   wmove(w, 0, 0);
439   wclrtoeol(w);
440   colors_use(w, COLOR_STATUS_ALERT);
441   waddstr(w, msg);
442   wnoutrefresh(w);
443   screen->status_timestamp = time(NULL);
446 void 
447 screen_status_printf(char *format, ...)
449   char buffer[STATUS_LINE_MAX_SIZE];
450   va_list ap;
451   
452   va_start(ap,format);
453   vsnprintf(buffer,sizeof(buffer),format,ap);
454   va_end(ap);
455   screen_status_message(buffer);
458 int
459 screen_init(void)
461   GList *list;
463   /* initialize the curses library */
464   initscr();
465   /* initialize color support */
466   colors_start();
467   /* tell curses not to do NL->CR/NL on output */
468   nonl();          
469   /* take input chars one at a time, no wait for \n */  
470   cbreak();       
471   /* don't echo input */
472   noecho();    
473   /* set cursor invisible */     
474   curs_set(0);     
475   /* return from getch() without blocking */
476   //  nodelay(stdscr, TRUE); 
477   keypad(stdscr, TRUE);  
478   timeout(SCREEN_TIMEOUT);
480   if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
481     {
482       fprintf(stderr, _("Error: Screen to small!\n"));
483       exit(EXIT_FAILURE);
484     }
486   screen = g_malloc(sizeof(screen_t));
487   memset(screen, 0, sizeof(screen_t));
488   screen->mode = SCREEN_PLAY_WINDOW;
489   screen->cols = COLS;
490   screen->rows = LINES;
491   screen->buf  = g_malloc(screen->cols);
492   screen->buf_size = screen->cols;
493   screen->findbuf = NULL;
494   screen->painted = 0;
495   screen->start_timestamp = time(NULL);
496   screen->input_timestamp = time(NULL);
497   screen->last_cmd = CMD_NONE;
499   /* create top window */
500   screen->top_window.rows = 2;
501   screen->top_window.cols = screen->cols;
502   screen->top_window.w = newwin(screen->top_window.rows, 
503                                   screen->top_window.cols,
504                                   0, 0);
505   leaveok(screen->top_window.w, TRUE);
506   keypad(screen->top_window.w, TRUE);  
508   /* create main window */
509   screen->main_window.rows = screen->rows-4;
510   screen->main_window.cols = screen->cols;
511   screen->main_window.w = newwin(screen->main_window.rows, 
512                                  screen->main_window.cols,
513                                  2, 
514                                  0);
516   //  leaveok(screen->main_window.w, TRUE); temporary disabled
517   keypad(screen->main_window.w, TRUE);  
519   /* create progress window */
520   screen->progress_window.rows = 1;
521   screen->progress_window.cols = screen->cols;
522   screen->progress_window.w = newwin(screen->progress_window.rows, 
523                                      screen->progress_window.cols,
524                                      screen->rows-2, 
525                                      0);
526   leaveok(screen->progress_window.w, TRUE);
527   
528   /* create status window */
529   screen->status_window.rows = 1;
530   screen->status_window.cols = screen->cols;
531   screen->status_window.w = newwin(screen->status_window.rows, 
532                                    screen->status_window.cols,
533                                    screen->rows-1, 
534                                    0);
536   leaveok(screen->status_window.w, FALSE);
537   keypad(screen->status_window.w, TRUE);  
539   if( options.enable_colors )
540     {
541       /* set background attributes */
542       wbkgd(stdscr, COLOR_PAIR(COLOR_LIST)); 
543       wbkgd(screen->main_window.w,     COLOR_PAIR(COLOR_LIST));
544       wbkgd(screen->top_window.w,      COLOR_PAIR(COLOR_TITLE));
545       wbkgd(screen->progress_window.w, COLOR_PAIR(COLOR_PROGRESSBAR));
546       wbkgd(screen->status_window.w,   COLOR_PAIR(COLOR_STATUS));
547       colors_use(screen->progress_window.w, COLOR_PROGRESSBAR);
548     }
550   /* initialize screens */
551   screen->screen_list = NULL;
552   screen->screen_list = g_list_append(screen->screen_list, 
553                                       (gpointer) get_screen_playlist());
554   screen->screen_list = g_list_append(screen->screen_list, 
555                                       (gpointer) get_screen_file());
556   screen->screen_list = g_list_append(screen->screen_list, 
557                                       (gpointer) get_screen_help());
558 #ifdef ENABLE_KEYDEF_SCREEN
559   screen->screen_list = g_list_append(screen->screen_list, 
560                                       (gpointer) get_screen_keydef());
561 #endif
563   list = screen->screen_list;
564   while( list )
565     {
566       screen_functions_t *fn = list->data;
567       
568       if( fn && fn->init )
569         fn->init(screen->main_window.w, 
570                  screen->main_window.cols,
571                  screen->main_window.rows);
572       
573       list = list->next;
574     }
576   mode_fn = get_screen_playlist();
578   return 0;
581 void 
582 screen_paint(mpd_client_t *c)
584   /* paint the title/header window */
585   if( mode_fn && mode_fn->get_title )
586     paint_top_window(mode_fn->get_title(), c, 1);
587   else
588     paint_top_window("", c, 1);
590   /* paint the main window */
591   if( mode_fn && mode_fn->paint )
592     mode_fn->paint(screen, c);
593   
594   paint_progress_window(c);
595   paint_status_window(c);
596   screen->painted = 1;
597   wmove(screen->main_window.w, 0, 0);  
598   wnoutrefresh(screen->main_window.w);
600   /* tell curses to update */
601   doupdate();
604 void 
605 screen_update(mpd_client_t *c)
607   static int repeat = -1;
608   static int random = -1;
609   static int crossfade = -1;
610   static int dbupdate = -1;
611   static int welcome = 1;
612   list_window_t *lw = NULL;
614   if( !screen->painted )
615     return screen_paint(c);
617   /* print a message if mpd status has changed */
618   if( repeat<0 )
619     {
620       repeat = c->status->repeat;
621       random = c->status->random;
622       crossfade = c->status->crossfade;
623       dbupdate = c->status->updatingDb;
624     }
625   if( repeat != c->status->repeat )
626     screen_status_printf(c->status->repeat ? 
627                          _("Repeat is on") :
628                          _("Repeat is off"));
629   if( random != c->status->random )
630     screen_status_printf(c->status->random ?
631                          _("Random is on") :
632                          _("Random is off"));
633                          
634   if( crossfade != c->status->crossfade )
635     screen_status_printf(_("Crossfade %d seconds"), c->status->crossfade);
636   if( dbupdate && dbupdate != c->status->updatingDb )
637     screen_status_printf(_("Database updated!"));
639   repeat = c->status->repeat;
640   random = c->status->random;
641   crossfade = c->status->crossfade;
642   dbupdate = c->status->updatingDb;
644   /* update title/header window */
645   if( welcome && screen->last_cmd==CMD_NONE &&
646       time(NULL)-screen->start_timestamp <= SCREEN_WELCOME_TIME)
647     paint_top_window("", c, 0);
648   else if( mode_fn && mode_fn->get_title )
649     {
650       paint_top_window(mode_fn->get_title(), c, 0);
651       welcome = 0;
652     }
653   else
654     paint_top_window("", c, 0);
656   /* update the main window */
657   if( mode_fn && mode_fn->paint )
658     mode_fn->update(screen, c);
660   if( mode_fn && mode_fn->get_lw )
661     lw = mode_fn->get_lw();
663   /* update progress window */
664   paint_progress_window(c);
666   /* update status window */
667   paint_status_window(c);
669   /* move the cursor to the selected row in the main window */
670   if( lw )
671     wmove(screen->main_window.w, LW_ROW(lw), 0);   
672   else
673     wmove(screen->main_window.w, 0, 0);   
674   wnoutrefresh(screen->main_window.w);
676   /* tell curses to update */
677   doupdate();
680 void
681 screen_idle(mpd_client_t *c)
683   if( c->seek_song_id ==  c->song_id &&
684       (screen->last_cmd == CMD_SEEK_FORWARD || 
685        screen->last_cmd == CMD_SEEK_BACKWARD) )
686     {
687       mpd_sendSeekCommand(c->connection, 
688                           c->seek_song_id, 
689                           c->seek_target_time);
690       mpd_finishCommand(c->connection);
691     }
693   screen->last_cmd = CMD_NONE;
694   c->seek_song_id = -1;
697 void 
698 screen_cmd(mpd_client_t *c, command_t cmd)
700   int n = 0;
701   screen_mode_t new_mode = screen->mode;
703   screen->input_timestamp = time(NULL);
704   screen->last_cmd = cmd;
706   if( mode_fn && mode_fn->cmd && mode_fn->cmd(screen, c, cmd) )
707     return;
709   switch(cmd)
710     {
711     case CMD_PLAY:
712       if( screen->mode == SCREEN_PLAY_WINDOW )
713         n = play_get_selected();
714       else
715         n = -1;
716       mpd_sendPlayCommand(c->connection, n);
717       mpd_finishCommand(c->connection);
718       break;
719     case CMD_PAUSE:
720       mpd_sendPauseCommand(c->connection);
721       mpd_finishCommand(c->connection);
722       break;
723     case CMD_STOP:
724       mpd_sendStopCommand(c->connection);
725       mpd_finishCommand(c->connection);
726       break;
727     case CMD_SEEK_FORWARD:
728       if( !IS_STOPPED(c->status->state) )
729         {
730           if( c->seek_song_id != c->song_id )
731             {
732               c->seek_song_id = c->song_id;
733               c->seek_target_time = c->status->elapsedTime;
734             }
735           c->seek_target_time++;
736           if( c->seek_target_time < c->status->totalTime )
737             break;
738           c->seek_target_time=0;
739         }
740       /* fall through... */
741     case CMD_TRACK_NEXT:
742       if( !IS_STOPPED(c->status->state) )
743         {
744           mpd_sendNextCommand(c->connection);
745           mpd_finishCommand(c->connection);
746         }
747       break;
748     case CMD_SEEK_BACKWARD:
749       if( !IS_STOPPED(c->status->state) )
750         {
751           if( c->seek_song_id != c->song_id )
752             {
753               c->seek_song_id = c->song_id;
754               c->seek_target_time = c->status->elapsedTime;
755             }
756           c->seek_target_time--;
757           if( c->seek_target_time < 0 )
758             c->seek_target_time=0;
759         }
760       break;
761     case CMD_TRACK_PREVIOUS:
762       if( !IS_STOPPED(c->status->state) )
763         {
764           mpd_sendPrevCommand(c->connection);
765           mpd_finishCommand(c->connection);
766         }
767       break;   
768     case CMD_SHUFFLE:
769       mpd_sendShuffleCommand(c->connection);
770       mpd_finishCommand(c->connection);
771       screen_status_message(_("Shuffled playlist!"));
772       break;
773     case CMD_CLEAR:
774       mpd_sendClearCommand(c->connection);
775       mpd_finishCommand(c->connection);
776       file_clear_highlights(c);
777       screen_status_message(_("Cleared playlist!"));
778       break;
779     case CMD_REPEAT:
780       n = !c->status->repeat;
781       mpd_sendRepeatCommand(c->connection, n);
782       mpd_finishCommand(c->connection);
783       break;
784     case CMD_RANDOM:
785       n = !c->status->random;
786       mpd_sendRandomCommand(c->connection, n);
787       mpd_finishCommand(c->connection);
788       break;
789     case CMD_CROSSFADE:
790       if( c->status->crossfade )
791         n = 0;
792       else
793         n = DEFAULT_CROSSFADE_TIME;
794       mpd_sendCrossfadeCommand(c->connection, n);
795       mpd_finishCommand(c->connection);
796       break;
797     case CMD_DB_UPDATE:
798       if( !c->status->updatingDb )
799         {
800           mpd_sendUpdateCommand(c->connection);
801           n = mpd_getUpdateId(c->connection);
802           mpd_finishCommand(c->connection);
803           if( !mpc_error(c) )
804             screen_status_printf(_("Database update started [%d]"), n);
805         }
806       else
807         screen_status_printf(_("Database update running..."));
808       break;
809     case CMD_VOLUME_UP:
810       if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume<100 )
811         {
812           c->status->volume=c->status->volume+1;
813           mpd_sendSetvolCommand(c->connection, c->status->volume  );
814           mpd_finishCommand(c->connection);
815         }
816       break;
817     case CMD_VOLUME_DOWN:
818       if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume>0 )
819         {
820           c->status->volume=c->status->volume-1;
821           mpd_sendSetvolCommand(c->connection, c->status->volume  );
822           mpd_finishCommand(c->connection);
823         }
824       break;
825     case CMD_TOGGLE_FIND_WRAP:
826       options.find_wrap = !options.find_wrap;
827       screen_status_printf(options.find_wrap ? 
828                            _("Find mode: Wrapped") :
829                            _("Find mode: Normal"));
830       break;
831     case CMD_TOGGLE_AUTOCENTER:
832       options.auto_center = !options.auto_center;
833       screen_status_printf(options.auto_center ?
834                            _("Auto center mode: On") :
835                            _("Auto center mode: Off"));
836       break;
837     case CMD_SCREEN_PREVIOUS:
838       if( screen->mode > SCREEN_PLAY_WINDOW )
839         new_mode = screen->mode - 1;
840       else
841         new_mode = SCREEN_HELP_WINDOW-1;
842       switch_screen_mode(new_mode, c);
843       break;
844     case CMD_SCREEN_NEXT:
845       new_mode = screen->mode + 1;
846       if( new_mode >= SCREEN_HELP_WINDOW )
847         new_mode = SCREEN_PLAY_WINDOW;
848       switch_screen_mode(new_mode, c);
849       break;
850     case CMD_SCREEN_PLAY:
851       switch_screen_mode(SCREEN_PLAY_WINDOW, c);
852       break;
853     case CMD_SCREEN_FILE:
854       switch_screen_mode(SCREEN_FILE_WINDOW, c);
855       break;
856     case CMD_SCREEN_SEARCH:
857       switch_screen_mode(SCREEN_SEARCH_WINDOW, c);
858       break;
859     case CMD_SCREEN_HELP:
860       switch_screen_mode(SCREEN_HELP_WINDOW, c);
861       break;
862 #ifdef ENABLE_KEYDEF_SCREEN 
863     case CMD_SCREEN_KEYDEF:
864       switch_screen_mode(SCREEN_KEYDEF_WINDOW, c);
865       break;
866 #endif
867     case CMD_QUIT:
868       exit(EXIT_SUCCESS);
869     default:
870       break;
871     }