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);
108 }
110 static void
111 paint_top_window(char *header, mpd_client_t *c, int clear)
112 {
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 }
187 }
189 static void
190 paint_progress_window(mpd_client_t *c)
191 {
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);
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);
217 }
219 #ifdef ENABLE_SCROLLING
220 static char *
221 scroll_string(char *str, char *sep, int width)
222 {
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 }
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;
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;
256 }
257 #endif
259 static void
260 paint_status_window(mpd_client_t *c)
261 {
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;
272 wmove(w, 0, 0);
273 wclrtoeol(w);
274 colors_use(w, COLOR_STATUS_BOLD);
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);
349 }
351 GList *
352 screen_free_string_list(GList *list)
353 {
354 GList *l = g_list_first(list);
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;
364 }
366 int
367 screen_exit(void)
368 {
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);
391 g_free(screen);
392 screen = NULL;
393 }
394 return 0;
395 }
397 void
398 screen_resize(void)
399 {
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
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;
460 }
462 void
463 screen_status_message(char *msg)
464 {
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);
473 }
475 void
476 screen_status_printf(char *format, ...)
477 {
478 char buffer[STATUS_LINE_MAX_SIZE];
479 va_list ap;
481 va_start(ap,format);
482 vsnprintf(buffer,sizeof(buffer),format,ap);
483 va_end(ap);
484 screen_status_message(buffer);
485 }
487 int
488 screen_init(void)
489 {
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);
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;
601 if( fn && fn->init )
602 fn->init(screen->main_window.w,
603 screen->main_window.cols,
604 screen->main_window.rows);
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;
616 }
618 void
619 screen_paint(mpd_client_t *c)
620 {
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);
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();
639 }
641 void
642 screen_update(mpd_client_t *c)
643 {
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"));
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();
715 }
717 void
718 screen_idle(mpd_client_t *c)
719 {
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;
732 }
734 void
735 screen_cmd(mpd_client_t *c, command_t cmd)
736 {
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 }
914 }