Code

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