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
57 static screen_t *screen = NULL;
58 static screen_functions_t *mode_fn = NULL;
60 static void
61 switch_screen_mode(screen_mode_t new_mode, mpd_client_t *c)
62 {
63 if( new_mode == screen->mode )
64 return;
66 /* close the old mode */
67 if( mode_fn && mode_fn->close )
68 mode_fn->close();
70 /* get functions for the new mode */
71 switch(new_mode)
72 {
73 case SCREEN_PLAY_WINDOW:
74 mode_fn = get_screen_playlist();
75 break;
76 case SCREEN_FILE_WINDOW:
77 mode_fn = get_screen_file();
78 break;
79 case SCREEN_HELP_WINDOW:
80 mode_fn = get_screen_help();
81 break;
82 #ifdef ENABLE_KEYDEF_SCREEN
83 case SCREEN_KEYDEF_WINDOW:
84 mode_fn = get_screen_keydef();
85 break;
86 #endif
87 default:
88 break;
89 }
91 screen->mode = new_mode;
92 screen->painted = 0;
94 /* open the new mode */
95 if( mode_fn && mode_fn->open )
96 mode_fn->open(screen, c);
98 }
100 static void
101 paint_top_window(char *header, mpd_client_t *c, int clear)
102 {
103 char flags[4];
104 static int prev_volume = -1;
105 static int prev_header_len = -1;
106 WINDOW *w = screen->top_window.w;
108 if(prev_header_len!=strlen(header))
109 {
110 prev_header_len = strlen(header);
111 clear = 1;
112 }
114 if(clear)
115 {
116 wmove(w, 0, 0);
117 wclrtoeol(w);
118 }
120 if(prev_volume!=c->status->volume || clear)
121 {
122 char buf[32];
124 if( header[0] )
125 {
126 colors_use(w, COLOR_TITLE_BOLD);
127 mvwaddstr(w, 0, 0, header);
128 }
129 else
130 {
131 colors_use(w, COLOR_TITLE_BOLD);
132 waddstr(w, get_key_names(CMD_SCREEN_HELP, FALSE));
133 colors_use(w, COLOR_TITLE);
134 waddstr(w, _(":Help "));
135 colors_use(w, COLOR_TITLE_BOLD);
136 waddstr(w, get_key_names(CMD_SCREEN_PLAY, FALSE));
137 colors_use(w, COLOR_TITLE);
138 waddstr(w, _(":Playlist "));
139 colors_use(w, COLOR_TITLE_BOLD);
140 waddstr(w, get_key_names(CMD_SCREEN_FILE, FALSE));
141 colors_use(w, COLOR_TITLE);
142 waddstr(w, _(":Browse"));
143 }
144 if( c->status->volume==MPD_STATUS_NO_VOLUME )
145 {
146 snprintf(buf, 32, _("Volume n/a "));
147 }
148 else
149 {
150 snprintf(buf, 32, _(" Volume %d%%"), c->status->volume);
151 }
152 colors_use(w, COLOR_TITLE);
153 mvwaddstr(w, 0, screen->top_window.cols-strlen(buf), buf);
155 flags[0] = 0;
156 if( c->status->repeat )
157 strcat(flags, "r");
158 if( c->status->random )
159 strcat(flags, "z");
160 if( c->status->crossfade )
161 strcat(flags, "x");
162 if( c->status->updatingDb )
163 strcat(flags, "U");
164 colors_use(w, COLOR_LINE);
165 mvwhline(w, 1, 0, ACS_HLINE, screen->top_window.cols);
166 if( flags[0] )
167 {
168 wmove(w,1,screen->top_window.cols-strlen(flags)-3);
169 waddch(w, '[');
170 colors_use(w, COLOR_LINE_BOLD);
171 waddstr(w, flags);
172 colors_use(w, COLOR_LINE);
173 waddch(w, ']');
174 }
175 wnoutrefresh(w);
176 }
177 }
179 static void
180 paint_progress_window(mpd_client_t *c)
181 {
182 double p;
183 int width;
184 int elapsedTime = c->status->elapsedTime;
186 if( c->status==NULL || IS_STOPPED(c->status->state) )
187 {
188 mvwhline(screen->progress_window.w, 0, 0, ACS_HLINE,
189 screen->progress_window.cols);
190 wnoutrefresh(screen->progress_window.w);
191 return;
192 }
194 if( c->seek_song_id == c->song_id )
195 elapsedTime = c->seek_target_time;
197 p = ((double) elapsedTime) / ((double) c->status->totalTime);
199 width = (int) (p * (double) screen->progress_window.cols);
200 mvwhline(screen->progress_window.w,
201 0, 0,
202 ACS_HLINE,
203 screen->progress_window.cols);
204 whline(screen->progress_window.w, '=', width-1);
205 mvwaddch(screen->progress_window.w, 0, width-1, 'O');
206 wnoutrefresh(screen->progress_window.w);
207 }
209 #ifdef ENABLE_SCROLLING
210 static char *
211 scroll_string(char *str, char *sep, int width)
212 {
213 static int offset = 0;
214 static time_t t = 0;
215 char *tmp, *buf;
216 size_t len;
218 if( offset==0 )
219 {
220 offset++;
221 return g_strdup(str);
222 }
224 /* create a buffer containing the string and the separator */
225 tmp = g_malloc(strlen(str)+strlen(sep)+1);
226 strcpy(tmp, str);
227 strcat(tmp, sep);
228 len = strlen(tmp);
230 if( offset >= len )
231 offset = 0;
233 /* create the new scrolled string */
234 buf = g_malloc(width+1);
235 strncpy(buf, tmp+offset, width);
236 if( strlen(buf) < width )
237 strncat(buf, tmp, width-strlen(buf));
239 if( time(NULL)-t >= 1 )
240 {
241 t = time(NULL);
242 offset++;
243 }
244 g_free(tmp);
245 return buf;
246 }
247 #endif
249 static void
250 paint_status_window(mpd_client_t *c)
251 {
252 WINDOW *w = screen->status_window.w;
253 mpd_Status *status = c->status;
254 mpd_Song *song = c->song;
255 int elapsedTime = c->status->elapsedTime;
256 int x = 0;
258 if( time(NULL) - screen->status_timestamp <= STATUS_MESSAGE_TIMEOUT )
259 return;
262 wmove(w, 0, 0);
263 wclrtoeol(w);
264 colors_use(w, COLOR_STATUS_BOLD);
266 switch(status->state)
267 {
268 case MPD_STATUS_STATE_STOP:
269 waddstr(w, _("Stopped! "));
270 break;
271 case MPD_STATUS_STATE_PLAY:
272 waddstr(w, _("Playing:"));
273 break;
274 case MPD_STATUS_STATE_PAUSE:
275 waddstr(w, _("[Paused]"));
276 break;
277 default:
278 break;
279 }
280 x += 9;
282 /* create time string */
283 memset(screen->buf, 0, screen->buf_size);
284 if( IS_PLAYING(status->state) || IS_PAUSED(status->state) )
285 {
286 if( status->totalTime > 0 )
287 {
288 if( c->seek_song_id == c->song_id )
289 elapsedTime = c->seek_target_time;
290 snprintf(screen->buf, screen->buf_size,
291 " [%i:%02i/%i:%02i]",
292 elapsedTime/60, elapsedTime%60,
293 status->totalTime/60, status->totalTime%60 );
294 }
295 else
296 {
297 snprintf(screen->buf, screen->buf_size, " [%d kbps]", status->bitRate );
298 }
299 }
300 #ifdef ENABLE_STATUS_LINE_CLOCK
301 else
302 {
303 time_t timep;
305 time(&timep);
306 /* Note: setlocale(LC_TIME,"") should be used first */
307 //strftime(screen->buf, screen->buf_size, "%x - %X ",localtime(&timep));
308 strftime(screen->buf, screen->buf_size, "%X ",localtime(&timep));
309 }
310 #endif
312 /* display song */
313 if( (IS_PLAYING(status->state) || IS_PAUSED(status->state)) && song )
314 {
315 char *songname = mpc_get_song_name(song);
316 int width = COLS-x-strlen(screen->buf);
318 colors_use(w, COLOR_STATUS);
319 #ifdef ENABLE_SCROLLING
320 if( strlen(songname) > width )
321 {
322 char *tmp = scroll_string(songname, " *** ", width);
323 strcpy(songname, tmp);
324 g_free(tmp);
325 }
326 #endif
327 mvwaddnstr(w, 0, x, songname, width);
328 }
330 /* distplay time string */
331 if( screen->buf[0] )
332 {
333 x = screen->status_window.cols - strlen(screen->buf);
334 colors_use(w, COLOR_STATUS_TIME);
335 mvwaddstr(w, 0, x, screen->buf);
336 }
338 wnoutrefresh(w);
339 }
341 GList *
342 screen_free_string_list(GList *list)
343 {
344 GList *l = g_list_first(list);
346 while(l)
347 {
348 g_free(l->data);
349 l->data = NULL;
350 l=l->next;
351 }
352 g_list_free(list);
353 return NULL;
354 }
356 int
357 screen_exit(void)
358 {
359 endwin();
360 if( screen )
361 {
362 GList *list = g_list_first(screen->screen_list);
364 /* close and exit all screens (playlist,browse,help...) */
365 while( list )
366 {
367 screen_functions_t *mode_fn = list->data;
369 if( mode_fn && mode_fn->close )
370 mode_fn->close();
371 if( mode_fn && mode_fn->exit )
372 mode_fn->exit();
373 list->data = NULL;
374 list=list->next;
375 }
376 g_list_free(screen->screen_list);
377 screen_free_string_list(screen->find_history);
378 g_free(screen->buf);
379 g_free(screen->findbuf);
381 g_free(screen);
382 screen = NULL;
383 }
384 return 0;
385 }
387 void
388 screen_resize(void)
389 {
390 GList *list;
392 #ifdef DEBUG
393 fprintf(stderr, "Resize rows %d->%d, cols %d->%d\n",
394 screen->rows, LINES,
395 screen->cols, COLS);
396 #endif
398 if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
399 {
400 screen_exit();
401 fprintf(stderr, _("Error: Screen to small!\n"));
402 exit(EXIT_FAILURE);
403 }
405 resizeterm(LINES, COLS);
407 screen->cols = COLS;
408 screen->rows = LINES;
410 /* top window */
411 screen->top_window.cols = screen->cols;
412 wresize(screen->top_window.w, 2, screen->cols);
414 /* main window */
415 screen->main_window.cols = screen->cols;
416 screen->main_window.rows = screen->rows-4;
417 wresize(screen->main_window.w, screen->main_window.rows, screen->cols);
418 wclear(screen->main_window.w);
420 /* progress window */
421 screen->progress_window.cols = screen->cols;
422 wresize(screen->progress_window.w, 1, screen->cols);
423 mvwin(screen->progress_window.w, screen->rows-2, 0);
425 /* status window */
426 screen->status_window.cols = screen->cols;
427 wresize(screen->status_window.w, 1, screen->cols);
428 mvwin(screen->status_window.w, screen->rows-1, 0);
430 screen->buf_size = screen->cols;
431 g_free(screen->buf);
432 screen->buf = g_malloc(screen->cols);
434 list = g_list_first(screen->screen_list);
435 while( list )
436 {
437 screen_functions_t *mode_fn = list->data;
439 if( mode_fn && mode_fn->resize )
440 mode_fn->resize(screen->main_window.cols, screen->main_window.rows);
442 list=list->next;
443 }
445 /* ? - without this the cursor becomes visible with aterm & Eterm */
446 curs_set(1);
447 curs_set(0);
449 screen->painted = 0;
450 }
452 void
453 screen_status_message(char *msg)
454 {
455 WINDOW *w = screen->status_window.w;
457 wmove(w, 0, 0);
458 wclrtoeol(w);
459 colors_use(w, COLOR_STATUS_ALERT);
460 waddstr(w, msg);
461 wnoutrefresh(w);
462 screen->status_timestamp = time(NULL);
463 }
465 void
466 screen_status_printf(char *format, ...)
467 {
468 char buffer[STATUS_LINE_MAX_SIZE];
469 va_list ap;
471 va_start(ap,format);
472 vsnprintf(buffer,sizeof(buffer),format,ap);
473 va_end(ap);
474 screen_status_message(buffer);
475 }
477 int
478 screen_init(void)
479 {
480 GList *list;
482 /* initialize the curses library */
483 initscr();
484 /* initialize color support */
485 colors_start();
486 /* tell curses not to do NL->CR/NL on output */
487 nonl();
488 /* take input chars one at a time, no wait for \n */
489 cbreak();
490 /* don't echo input */
491 noecho();
492 /* set cursor invisible */
493 curs_set(0);
494 /* enable extra keys */
495 keypad(stdscr, TRUE);
496 /* return from getch() without blocking */
497 timeout(SCREEN_TIMEOUT);
499 if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
500 {
501 fprintf(stderr, _("Error: Screen to small!\n"));
502 exit(EXIT_FAILURE);
503 }
505 screen = g_malloc(sizeof(screen_t));
506 memset(screen, 0, sizeof(screen_t));
507 screen->mode = SCREEN_PLAY_WINDOW;
508 screen->cols = COLS;
509 screen->rows = LINES;
510 screen->buf = g_malloc(screen->cols);
511 screen->buf_size = screen->cols;
512 screen->findbuf = NULL;
513 screen->painted = 0;
514 screen->start_timestamp = time(NULL);
515 screen->input_timestamp = time(NULL);
516 screen->last_cmd = CMD_NONE;
518 /* create top window */
519 screen->top_window.rows = 2;
520 screen->top_window.cols = screen->cols;
521 screen->top_window.w = newwin(screen->top_window.rows,
522 screen->top_window.cols,
523 0, 0);
524 leaveok(screen->top_window.w, TRUE);
525 keypad(screen->top_window.w, TRUE);
527 /* create main window */
528 screen->main_window.rows = screen->rows-4;
529 screen->main_window.cols = screen->cols;
530 screen->main_window.w = newwin(screen->main_window.rows,
531 screen->main_window.cols,
532 2,
533 0);
535 // leaveok(screen->main_window.w, TRUE); temporary disabled
536 keypad(screen->main_window.w, TRUE);
538 /* create progress window */
539 screen->progress_window.rows = 1;
540 screen->progress_window.cols = screen->cols;
541 screen->progress_window.w = newwin(screen->progress_window.rows,
542 screen->progress_window.cols,
543 screen->rows-2,
544 0);
545 leaveok(screen->progress_window.w, TRUE);
547 /* create status window */
548 screen->status_window.rows = 1;
549 screen->status_window.cols = screen->cols;
550 screen->status_window.w = newwin(screen->status_window.rows,
551 screen->status_window.cols,
552 screen->rows-1,
553 0);
555 leaveok(screen->status_window.w, FALSE);
556 keypad(screen->status_window.w, TRUE);
558 if( options.enable_colors )
559 {
560 /* set background attributes */
561 wbkgd(stdscr, COLOR_PAIR(COLOR_LIST));
562 wbkgd(screen->main_window.w, COLOR_PAIR(COLOR_LIST));
563 wbkgd(screen->top_window.w, COLOR_PAIR(COLOR_TITLE));
564 wbkgd(screen->progress_window.w, COLOR_PAIR(COLOR_PROGRESSBAR));
565 wbkgd(screen->status_window.w, COLOR_PAIR(COLOR_STATUS));
566 colors_use(screen->progress_window.w, COLOR_PROGRESSBAR);
567 }
569 /* initialize screens */
570 screen->screen_list = NULL;
571 screen->screen_list = g_list_append(screen->screen_list,
572 (gpointer) get_screen_playlist());
573 screen->screen_list = g_list_append(screen->screen_list,
574 (gpointer) get_screen_file());
575 screen->screen_list = g_list_append(screen->screen_list,
576 (gpointer) get_screen_help());
577 #ifdef ENABLE_KEYDEF_SCREEN
578 screen->screen_list = g_list_append(screen->screen_list,
579 (gpointer) get_screen_keydef());
580 #endif
582 list = screen->screen_list;
583 while( list )
584 {
585 screen_functions_t *fn = list->data;
587 if( fn && fn->init )
588 fn->init(screen->main_window.w,
589 screen->main_window.cols,
590 screen->main_window.rows);
592 list = list->next;
593 }
595 mode_fn = get_screen_playlist();
597 /* initialize wreadln */
598 wrln_resize_callback = screen_resize;
600 return 0;
601 }
603 void
604 screen_paint(mpd_client_t *c)
605 {
606 /* paint the title/header window */
607 if( mode_fn && mode_fn->get_title )
608 paint_top_window(mode_fn->get_title(), c, 1);
609 else
610 paint_top_window("", c, 1);
612 /* paint the main window */
613 if( mode_fn && mode_fn->paint )
614 mode_fn->paint(screen, c);
616 paint_progress_window(c);
617 paint_status_window(c);
618 screen->painted = 1;
619 wmove(screen->main_window.w, 0, 0);
620 wnoutrefresh(screen->main_window.w);
622 /* tell curses to update */
623 doupdate();
624 }
626 void
627 screen_update(mpd_client_t *c)
628 {
629 static int repeat = -1;
630 static int random = -1;
631 static int crossfade = -1;
632 static int dbupdate = -1;
633 static int welcome = 1;
634 list_window_t *lw = NULL;
636 if( !screen->painted )
637 return screen_paint(c);
639 /* print a message if mpd status has changed */
640 if( repeat<0 )
641 {
642 repeat = c->status->repeat;
643 random = c->status->random;
644 crossfade = c->status->crossfade;
645 dbupdate = c->status->updatingDb;
646 }
647 if( repeat != c->status->repeat )
648 screen_status_printf(c->status->repeat ?
649 _("Repeat is on") :
650 _("Repeat is off"));
651 if( random != c->status->random )
652 screen_status_printf(c->status->random ?
653 _("Random is on") :
654 _("Random is off"));
656 if( crossfade != c->status->crossfade )
657 screen_status_printf(_("Crossfade %d seconds"), c->status->crossfade);
658 if( dbupdate && dbupdate != c->status->updatingDb )
659 screen_status_printf(_("Database updated!"));
661 repeat = c->status->repeat;
662 random = c->status->random;
663 crossfade = c->status->crossfade;
664 dbupdate = c->status->updatingDb;
666 /* update title/header window */
667 if( welcome && screen->last_cmd==CMD_NONE &&
668 time(NULL)-screen->start_timestamp <= SCREEN_WELCOME_TIME)
669 paint_top_window("", c, 0);
670 else if( mode_fn && mode_fn->get_title )
671 {
672 paint_top_window(mode_fn->get_title(), c, 0);
673 welcome = 0;
674 }
675 else
676 paint_top_window("", c, 0);
678 /* update the main window */
679 if( mode_fn && mode_fn->paint )
680 mode_fn->update(screen, c);
682 if( mode_fn && mode_fn->get_lw )
683 lw = mode_fn->get_lw();
685 /* update progress window */
686 paint_progress_window(c);
688 /* update status window */
689 paint_status_window(c);
691 /* move the cursor to the selected row in the main window */
692 if( lw )
693 wmove(screen->main_window.w, LW_ROW(lw), 0);
694 else
695 wmove(screen->main_window.w, 0, 0);
696 wnoutrefresh(screen->main_window.w);
698 /* tell curses to update */
699 doupdate();
700 }
702 void
703 screen_idle(mpd_client_t *c)
704 {
705 if( c->seek_song_id == c->song_id &&
706 (screen->last_cmd == CMD_SEEK_FORWARD ||
707 screen->last_cmd == CMD_SEEK_BACKWARD) )
708 {
709 mpd_sendSeekCommand(c->connection,
710 c->seek_song_id,
711 c->seek_target_time);
712 mpd_finishCommand(c->connection);
713 }
715 screen->last_cmd = CMD_NONE;
716 c->seek_song_id = -1;
717 }
719 void
720 screen_cmd(mpd_client_t *c, command_t cmd)
721 {
722 int n = 0;
723 screen_mode_t new_mode = screen->mode;
725 screen->input_timestamp = time(NULL);
726 screen->last_cmd = cmd;
728 if( mode_fn && mode_fn->cmd && mode_fn->cmd(screen, c, cmd) )
729 return;
731 switch(cmd)
732 {
733 case CMD_PLAY:
734 if( screen->mode == SCREEN_PLAY_WINDOW )
735 n = play_get_selected();
736 else
737 n = -1;
738 mpd_sendPlayCommand(c->connection, n);
739 mpd_finishCommand(c->connection);
740 break;
741 case CMD_PAUSE:
742 mpd_sendPauseCommand(c->connection);
743 mpd_finishCommand(c->connection);
744 break;
745 case CMD_STOP:
746 mpd_sendStopCommand(c->connection);
747 mpd_finishCommand(c->connection);
748 break;
749 case CMD_SEEK_FORWARD:
750 if( !IS_STOPPED(c->status->state) )
751 {
752 if( c->seek_song_id != c->song_id )
753 {
754 c->seek_song_id = c->song_id;
755 c->seek_target_time = c->status->elapsedTime;
756 }
757 c->seek_target_time++;
758 if( c->seek_target_time < c->status->totalTime )
759 break;
760 c->seek_target_time=0;
761 }
762 /* fall through... */
763 case CMD_TRACK_NEXT:
764 if( !IS_STOPPED(c->status->state) )
765 {
766 mpd_sendNextCommand(c->connection);
767 mpd_finishCommand(c->connection);
768 }
769 break;
770 case CMD_SEEK_BACKWARD:
771 if( !IS_STOPPED(c->status->state) )
772 {
773 if( c->seek_song_id != c->song_id )
774 {
775 c->seek_song_id = c->song_id;
776 c->seek_target_time = c->status->elapsedTime;
777 }
778 c->seek_target_time--;
779 if( c->seek_target_time < 0 )
780 c->seek_target_time=0;
781 }
782 break;
783 case CMD_TRACK_PREVIOUS:
784 if( !IS_STOPPED(c->status->state) )
785 {
786 mpd_sendPrevCommand(c->connection);
787 mpd_finishCommand(c->connection);
788 }
789 break;
790 case CMD_SHUFFLE:
791 mpd_sendShuffleCommand(c->connection);
792 mpd_finishCommand(c->connection);
793 screen_status_message(_("Shuffled playlist!"));
794 break;
795 case CMD_CLEAR:
796 mpd_sendClearCommand(c->connection);
797 mpd_finishCommand(c->connection);
798 file_clear_highlights(c);
799 screen_status_message(_("Cleared playlist!"));
800 break;
801 case CMD_REPEAT:
802 n = !c->status->repeat;
803 mpd_sendRepeatCommand(c->connection, n);
804 mpd_finishCommand(c->connection);
805 break;
806 case CMD_RANDOM:
807 n = !c->status->random;
808 mpd_sendRandomCommand(c->connection, n);
809 mpd_finishCommand(c->connection);
810 break;
811 case CMD_CROSSFADE:
812 if( c->status->crossfade )
813 n = 0;
814 else
815 n = DEFAULT_CROSSFADE_TIME;
816 mpd_sendCrossfadeCommand(c->connection, n);
817 mpd_finishCommand(c->connection);
818 break;
819 case CMD_DB_UPDATE:
820 if( !c->status->updatingDb )
821 {
822 mpd_sendUpdateCommand(c->connection);
823 n = mpd_getUpdateId(c->connection);
824 mpd_finishCommand(c->connection);
825 if( !mpc_error(c) )
826 screen_status_printf(_("Database update started [%d]"), n);
827 }
828 else
829 screen_status_printf(_("Database update running..."));
830 break;
831 case CMD_VOLUME_UP:
832 if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume<100 )
833 {
834 c->status->volume=c->status->volume+1;
835 mpd_sendSetvolCommand(c->connection, c->status->volume );
836 mpd_finishCommand(c->connection);
837 }
838 break;
839 case CMD_VOLUME_DOWN:
840 if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume>0 )
841 {
842 c->status->volume=c->status->volume-1;
843 mpd_sendSetvolCommand(c->connection, c->status->volume );
844 mpd_finishCommand(c->connection);
845 }
846 break;
847 case CMD_TOGGLE_FIND_WRAP:
848 options.find_wrap = !options.find_wrap;
849 screen_status_printf(options.find_wrap ?
850 _("Find mode: Wrapped") :
851 _("Find mode: Normal"));
852 break;
853 case CMD_TOGGLE_AUTOCENTER:
854 options.auto_center = !options.auto_center;
855 screen_status_printf(options.auto_center ?
856 _("Auto center mode: On") :
857 _("Auto center mode: Off"));
858 break;
859 case CMD_SCREEN_PREVIOUS:
860 if( screen->mode > SCREEN_PLAY_WINDOW )
861 new_mode = screen->mode - 1;
862 else
863 new_mode = SCREEN_HELP_WINDOW-1;
864 switch_screen_mode(new_mode, c);
865 break;
866 case CMD_SCREEN_NEXT:
867 new_mode = screen->mode + 1;
868 if( new_mode >= SCREEN_HELP_WINDOW )
869 new_mode = SCREEN_PLAY_WINDOW;
870 switch_screen_mode(new_mode, c);
871 break;
872 case CMD_SCREEN_PLAY:
873 switch_screen_mode(SCREEN_PLAY_WINDOW, c);
874 break;
875 case CMD_SCREEN_FILE:
876 switch_screen_mode(SCREEN_FILE_WINDOW, c);
877 break;
878 case CMD_SCREEN_SEARCH:
879 switch_screen_mode(SCREEN_SEARCH_WINDOW, c);
880 break;
881 case CMD_SCREEN_HELP:
882 switch_screen_mode(SCREEN_HELP_WINDOW, c);
883 break;
884 #ifdef ENABLE_KEYDEF_SCREEN
885 case CMD_SCREEN_KEYDEF:
886 switch_screen_mode(SCREEN_KEYDEF_WINDOW, c);
887 break;
888 #endif
889 case CMD_QUIT:
890 exit(EXIT_SUCCESS);
891 default:
892 break;
893 }
895 }