0c56a7420433f5567473624e40909f2ce5efbb98
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 "support.h"
33 #include "mpdclient.h"
34 #include "utils.h"
35 #include "command.h"
36 #include "options.h"
37 #include "colors.h"
38 #include "strfsong.h"
39 #include "wreadln.h"
40 #include "screen.h"
41 #include "screen_utils.h"
43 #define MAX_SONGNAME_LENGTH 512
45 #define SCREEN_PLAYLIST_ID 0
46 #define SCREEN_BROWSE_ID 1
47 #define SCREEN_HELP_ID 100
48 #define SCREEN_KEYDEF_ID 101
49 #define SCREEN_CLOCK_ID 102
50 #define SCREEN_SEARCH_ID 103
53 /* screens */
54 extern screen_functions_t *get_screen_playlist(void);
55 extern screen_functions_t *get_screen_browse(void);
56 extern screen_functions_t *get_screen_help(void);
57 extern screen_functions_t *get_screen_search(void);
58 extern screen_functions_t *get_screen_keydef(void);
59 extern screen_functions_t *get_screen_clock(void);
61 typedef screen_functions_t * (*screen_get_mode_functions_fn_t) (void);
63 typedef struct
64 {
65 gint id;
66 gchar *name;
67 screen_get_mode_functions_fn_t get_mode_functions;
68 } screen_mode_info_t;
71 static screen_mode_info_t screens[] = {
72 { SCREEN_PLAYLIST_ID, "playlist", get_screen_playlist },
73 { SCREEN_BROWSE_ID, "browse", get_screen_browse },
74 { SCREEN_HELP_ID, "help", get_screen_help },
75 #ifdef ENABLE_SEARCH_SCREEN
76 { SCREEN_SEARCH_ID, "search", get_screen_search },
77 #endif
78 #ifdef ENABLE_KEYDEF_SCREEN
79 { SCREEN_KEYDEF_ID, "keydef", get_screen_keydef },
80 #endif
81 #ifdef ENABLE_CLOCK_SCREEN
82 { SCREEN_CLOCK_ID, "clock", get_screen_clock },
83 #endif
84 { G_MAXINT, NULL, NULL }
85 };
87 static gboolean welcome = TRUE;
88 static screen_t *screen = NULL;
89 static screen_functions_t *mode_fn = NULL;
90 static int seek_id = -1;
91 static int seek_target_time = 0;
93 static gint
94 lookup_mode(gint id)
95 {
96 gint i=0;
98 while( screens[i].name )
99 {
100 if( screens[i].id == id )
101 return i;
102 i++;
103 }
104 return -1;
105 }
107 static void
108 switch_screen_mode(gint id, mpdclient_t *c)
109 {
110 gint new_mode;
112 if( id == screens[screen->mode].id )
113 return;
115 /* close the old mode */
116 if( mode_fn && mode_fn->close )
117 mode_fn->close();
119 /* get functions for the new mode */
120 new_mode = lookup_mode(id);
121 if( new_mode>=0 && screens[new_mode].get_mode_functions )
122 {
123 D("switch_screen(%s)\n", screens[new_mode].name );
124 mode_fn = screens[new_mode].get_mode_functions();
125 screen->mode = new_mode;
126 }
128 screen->painted = 0;
130 /* open the new mode */
131 if( mode_fn && mode_fn->open )
132 mode_fn->open(screen, c);
134 }
136 static void
137 paint_top_window(char *header, mpdclient_t *c, int clear)
138 {
139 char flags[5];
140 static int prev_volume = -1;
141 static int prev_header_len = -1;
142 WINDOW *w = screen->top_window.w;
144 if(prev_header_len!=strlen(header))
145 {
146 prev_header_len = strlen(header);
147 clear = 1;
148 }
150 if(clear)
151 {
152 wmove(w, 0, 0);
153 wclrtoeol(w);
154 }
156 if(prev_volume!=c->status->volume || clear)
157 {
158 char buf[32];
160 if( header[0] )
161 {
162 colors_use(w, COLOR_TITLE_BOLD);
163 mvwaddstr(w, 0, 0, header);
164 }
165 else
166 {
167 colors_use(w, COLOR_TITLE_BOLD);
168 waddstr(w, get_key_names(CMD_SCREEN_HELP, FALSE));
169 colors_use(w, COLOR_TITLE);
170 waddstr(w, _(":Help "));
171 colors_use(w, COLOR_TITLE_BOLD);
172 waddstr(w, get_key_names(CMD_SCREEN_PLAY, FALSE));
173 colors_use(w, COLOR_TITLE);
174 waddstr(w, _(":Playlist "));
175 colors_use(w, COLOR_TITLE_BOLD);
176 waddstr(w, get_key_names(CMD_SCREEN_FILE, FALSE));
177 colors_use(w, COLOR_TITLE);
178 waddstr(w, _(":Browse "));
179 #ifdef ENABLE_SEARCH_SCREEN
180 colors_use(w, COLOR_TITLE_BOLD);
181 waddstr(w, get_key_names(CMD_SCREEN_SEARCH, FALSE));
182 colors_use(w, COLOR_TITLE);
183 waddstr(w, _(":Search "));
184 #endif
185 }
186 if( c->status->volume==MPD_STATUS_NO_VOLUME )
187 {
188 g_snprintf(buf, 32, _("Volume n/a "));
189 }
190 else
191 {
192 g_snprintf(buf, 32, _(" Volume %d%%"), c->status->volume);
193 }
194 colors_use(w, COLOR_TITLE);
195 mvwaddstr(w, 0, screen->top_window.cols-strlen(buf), buf);
197 flags[0] = 0;
198 if( c->status->repeat )
199 g_strlcat(flags, "r", sizeof(flags));
200 if( c->status->random )
201 g_strlcat(flags, "z", sizeof(flags));;
202 if( c->status->crossfade )
203 g_strlcat(flags, "x", sizeof(flags));
204 if( c->status->updatingDb )
205 g_strlcat(flags, "U", sizeof(flags));
206 colors_use(w, COLOR_LINE);
207 mvwhline(w, 1, 0, ACS_HLINE, screen->top_window.cols);
208 if( flags[0] )
209 {
210 wmove(w,1,screen->top_window.cols-strlen(flags)-3);
211 waddch(w, '[');
212 colors_use(w, COLOR_LINE_BOLD);
213 waddstr(w, flags);
214 colors_use(w, COLOR_LINE);
215 waddch(w, ']');
216 }
217 wnoutrefresh(w);
218 }
219 }
221 static void
222 paint_progress_window(mpdclient_t *c)
223 {
224 double p;
225 int width;
226 int elapsedTime = c->status->elapsedTime;
228 if( c->status==NULL || IS_STOPPED(c->status->state) )
229 {
230 mvwhline(screen->progress_window.w, 0, 0, ACS_HLINE,
231 screen->progress_window.cols);
232 wnoutrefresh(screen->progress_window.w);
233 return;
234 }
236 if( c->song && seek_id == c->song->id )
237 elapsedTime = seek_target_time;
239 p = ((double) elapsedTime) / ((double) c->status->totalTime);
241 width = (int) (p * (double) screen->progress_window.cols);
242 mvwhline(screen->progress_window.w,
243 0, 0,
244 ACS_HLINE,
245 screen->progress_window.cols);
246 whline(screen->progress_window.w, '=', width-1);
247 mvwaddch(screen->progress_window.w, 0, width-1, 'O');
248 wnoutrefresh(screen->progress_window.w);
249 }
251 static void
252 paint_status_window(mpdclient_t *c)
253 {
254 WINDOW *w = screen->status_window.w;
255 mpd_Status *status = c->status;
256 mpd_Song *song = c->song;
257 int elapsedTime = c->status->elapsedTime;
258 char *str = NULL;
259 int x = 0;
261 if( time(NULL) - screen->status_timestamp <= SCREEN_STATUS_MESSAGE_TIME )
262 return;
264 wmove(w, 0, 0);
265 wclrtoeol(w);
266 colors_use(w, COLOR_STATUS_BOLD);
268 switch(status->state)
269 {
270 case MPD_STATUS_STATE_PLAY:
271 str = _("Playing:");
272 break;
273 case MPD_STATUS_STATE_PAUSE:
274 str = _("[Paused]");
275 break;
276 case MPD_STATUS_STATE_STOP:
277 default:
278 break;
279 }
281 if( str )
282 {
283 waddstr(w, str);
284 x += strlen(str)+1;
285 }
287 /* create time string */
288 memset(screen->buf, 0, screen->buf_size);
289 if( IS_PLAYING(status->state) || IS_PAUSED(status->state) )
290 {
291 if( status->totalTime > 0 )
292 {
293 if( c->song && seek_id == c->song->id )
294 elapsedTime = seek_target_time;
295 g_snprintf(screen->buf, screen->buf_size,
296 " [%i:%02i/%i:%02i]",
297 elapsedTime/60, elapsedTime%60,
298 status->totalTime/60, status->totalTime%60 );
299 }
300 else
301 {
302 g_snprintf(screen->buf, screen->buf_size,
303 " [%d kbps]", status->bitRate );
304 }
305 }
306 else
307 {
308 time_t timep;
310 time(&timep);
311 strftime(screen->buf, screen->buf_size, "%X ",localtime(&timep));
312 }
314 /* display song */
315 if( (IS_PLAYING(status->state) || IS_PAUSED(status->state)) )
316 {
317 char songname[MAX_SONGNAME_LENGTH];
318 int width = COLS-x-strlen(screen->buf);
320 if( song )
321 strfsong(songname, MAX_SONGNAME_LENGTH, STATUS_FORMAT, song);
322 else
323 songname[0] = '\0';
325 colors_use(w, COLOR_STATUS);
326 /* scroll if the song name is to long */
327 if( strlen(songname) > width )
328 {
329 static scroll_state_t st = { 0, 0 };
330 char *tmp = strscroll(songname, " *** ", width, &st);
332 g_strlcpy(songname, tmp, MAX_SONGNAME_LENGTH);
333 g_free(tmp);
334 }
335 mvwaddnstr(w, 0, x, songname, width);
336 }
338 /* display time string */
339 if( screen->buf[0] )
340 {
341 x = screen->status_window.cols - strlen(screen->buf);
342 colors_use(w, COLOR_STATUS_TIME);
343 mvwaddstr(w, 0, x, screen->buf);
344 }
346 wnoutrefresh(w);
347 }
349 int
350 screen_exit(void)
351 {
352 endwin();
353 if( screen )
354 {
355 gint i;
357 /* close and exit all screens (playlist,browse,help...) */
358 i=0;
359 while( screens[i].get_mode_functions )
360 {
361 screen_functions_t *mode_fn = screens[i].get_mode_functions();
363 if( mode_fn && mode_fn->close )
364 mode_fn->close();
365 if( mode_fn && mode_fn->exit )
366 mode_fn->exit();
368 i++;
369 }
371 string_list_free(screen->find_history);
372 g_free(screen->buf);
373 g_free(screen->findbuf);
375 g_free(screen);
376 screen = NULL;
377 }
378 return 0;
379 }
381 void
382 screen_resize(void)
383 {
384 gint i;
386 D("Resize rows %d->%d, cols %d->%d\n",screen->rows,LINES,screen->cols,COLS);
387 if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
388 {
389 screen_exit();
390 fprintf(stderr, _("Error: Screen to small!\n"));
391 exit(EXIT_FAILURE);
392 }
394 resizeterm(LINES, COLS);
396 screen->cols = COLS;
397 screen->rows = LINES;
399 /* top window */
400 screen->top_window.cols = screen->cols;
401 wresize(screen->top_window.w, 2, screen->cols);
403 /* main window */
404 screen->main_window.cols = screen->cols;
405 screen->main_window.rows = screen->rows-4;
406 wresize(screen->main_window.w, screen->main_window.rows, screen->cols);
407 wclear(screen->main_window.w);
409 /* progress window */
410 screen->progress_window.cols = screen->cols;
411 wresize(screen->progress_window.w, 1, screen->cols);
412 mvwin(screen->progress_window.w, screen->rows-2, 0);
414 /* status window */
415 screen->status_window.cols = screen->cols;
416 wresize(screen->status_window.w, 1, screen->cols);
417 mvwin(screen->status_window.w, screen->rows-1, 0);
419 screen->buf_size = screen->cols;
420 g_free(screen->buf);
421 screen->buf = g_malloc(screen->cols);
423 /* close and exit all screens (playlist,browse,help...) */
424 i=0;
425 while( screens[i].get_mode_functions )
426 {
427 screen_functions_t *mode_fn = screens[i].get_mode_functions();
429 if( mode_fn && mode_fn->resize )
430 mode_fn->resize(screen->main_window.cols, screen->main_window.rows);
432 i++;
433 }
435 /* ? - without this the cursor becomes visible with aterm & Eterm */
436 curs_set(1);
437 curs_set(0);
439 screen->painted = 0;
440 }
442 void
443 screen_status_message(char *msg)
444 {
445 WINDOW *w = screen->status_window.w;
447 wmove(w, 0, 0);
448 wclrtoeol(w);
449 colors_use(w, COLOR_STATUS_ALERT);
450 waddstr(w, msg);
451 wnoutrefresh(w);
452 screen->status_timestamp = time(NULL);
453 }
455 void
456 screen_status_printf(char *format, ...)
457 {
458 char *msg;
459 va_list ap;
461 va_start(ap,format);
462 msg = g_strdup_vprintf(format,ap);
463 va_end(ap);
464 screen_status_message(msg);
465 g_free(msg);
466 }
468 int
469 screen_init(mpdclient_t *c)
470 {
471 gint i;
473 /* initialize the curses library */
474 initscr();
475 /* initialize color support */
476 colors_start();
477 /* tell curses not to do NL->CR/NL on output */
478 nonl();
479 /* use raw mode (ignore interrupt,quit,suspend, and flow control ) */
480 #ifdef ENABLE_RAW_MODE
481 raw();
482 #endif
483 /* don't echo input */
484 noecho();
485 /* set cursor invisible */
486 curs_set(0);
487 /* enable extra keys */
488 keypad(stdscr, TRUE);
489 /* return from getch() without blocking */
490 timeout(SCREEN_TIMEOUT);
491 /* initialize mouse support */
492 #ifdef HAVE_GETMOUSE
493 if( options.enable_mouse )
494 mousemask(ALL_MOUSE_EVENTS, NULL);
495 #endif
497 if( COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS )
498 {
499 fprintf(stderr, _("Error: Screen to small!\n"));
500 exit(EXIT_FAILURE);
501 }
503 screen = g_malloc(sizeof(screen_t));
504 memset(screen, 0, sizeof(screen_t));
505 screen->mode = 0;
506 screen->cols = COLS;
507 screen->rows = LINES;
508 screen->buf = g_malloc(screen->cols);
509 screen->buf_size = screen->cols;
510 screen->findbuf = NULL;
511 screen->painted = 0;
512 screen->start_timestamp = time(NULL);
513 screen->input_timestamp = time(NULL);
514 screen->last_cmd = CMD_NONE;
516 /* create top window */
517 screen->top_window.rows = 2;
518 screen->top_window.cols = screen->cols;
519 screen->top_window.w = newwin(screen->top_window.rows,
520 screen->top_window.cols,
521 0, 0);
522 leaveok(screen->top_window.w, TRUE);
523 keypad(screen->top_window.w, TRUE);
525 /* create main window */
526 screen->main_window.rows = screen->rows-4;
527 screen->main_window.cols = screen->cols;
528 screen->main_window.w = newwin(screen->main_window.rows,
529 screen->main_window.cols,
530 2,
531 0);
533 // leaveok(screen->main_window.w, TRUE); temporary disabled
534 keypad(screen->main_window.w, TRUE);
536 /* create progress window */
537 screen->progress_window.rows = 1;
538 screen->progress_window.cols = screen->cols;
539 screen->progress_window.w = newwin(screen->progress_window.rows,
540 screen->progress_window.cols,
541 screen->rows-2,
542 0);
543 leaveok(screen->progress_window.w, TRUE);
545 /* create status window */
546 screen->status_window.rows = 1;
547 screen->status_window.cols = screen->cols;
548 screen->status_window.w = newwin(screen->status_window.rows,
549 screen->status_window.cols,
550 screen->rows-1,
551 0);
553 leaveok(screen->status_window.w, FALSE);
554 keypad(screen->status_window.w, TRUE);
556 if( options.enable_colors )
557 {
558 /* set background attributes */
559 wbkgd(stdscr, COLOR_PAIR(COLOR_LIST));
560 wbkgd(screen->main_window.w, COLOR_PAIR(COLOR_LIST));
561 wbkgd(screen->top_window.w, COLOR_PAIR(COLOR_TITLE));
562 wbkgd(screen->progress_window.w, COLOR_PAIR(COLOR_PROGRESSBAR));
563 wbkgd(screen->status_window.w, COLOR_PAIR(COLOR_STATUS));
564 colors_use(screen->progress_window.w, COLOR_PROGRESSBAR);
565 }
567 /* initialize screens */
568 i=0;
569 while( screens[i].get_mode_functions )
570 {
571 screen_functions_t *fn = screens[i].get_mode_functions();
573 if( fn && fn->init )
574 fn->init(screen->main_window.w,
575 screen->main_window.cols,
576 screen->main_window.rows);
578 i++;
579 }
581 mode_fn = get_screen_playlist();
582 if( mode_fn && mode_fn->open )
583 mode_fn->open(screen, c);
585 /* initialize wreadln */
586 wrln_wgetch = my_wgetch;
587 wrln_max_history_length = 16;
589 return 0;
590 }
592 void
593 screen_paint(mpdclient_t *c)
594 {
595 char *title = NULL;
597 if( mode_fn && mode_fn->get_title )
598 title = mode_fn->get_title(screen->buf,screen->buf_size);
600 D("screen_paint(%s)\n", title);
601 /* paint the title/header window */
602 if( title )
603 paint_top_window(title, c, 1);
604 else
605 paint_top_window("", c, 1);
607 /* paint the main window */
608 wclear(screen->main_window.w);
609 if( mode_fn && mode_fn->paint )
610 mode_fn->paint(screen, c);
612 paint_progress_window(c);
613 paint_status_window(c);
614 screen->painted = 1;
615 wmove(screen->main_window.w, 0, 0);
616 wnoutrefresh(screen->main_window.w);
618 /* tell curses to update */
619 doupdate();
620 }
622 void
623 screen_update(mpdclient_t *c)
624 {
625 static int repeat = -1;
626 static int random = -1;
627 static int crossfade = -1;
628 static int dbupdate = -1;
629 list_window_t *lw = NULL;
631 if( !screen->painted )
632 return screen_paint(c);
634 /* print a message if mpd status has changed */
635 if( repeat<0 )
636 {
637 repeat = c->status->repeat;
638 random = c->status->random;
639 crossfade = c->status->crossfade;
640 dbupdate = c->status->updatingDb;
641 }
642 if( repeat != c->status->repeat )
643 screen_status_printf(c->status->repeat ?
644 _("Repeat is on") :
645 _("Repeat is off"));
646 if( random != c->status->random )
647 screen_status_printf(c->status->random ?
648 _("Random is on") :
649 _("Random is off"));
651 if( crossfade != c->status->crossfade )
652 screen_status_printf(_("Crossfade %d seconds"), c->status->crossfade);
653 if( dbupdate && dbupdate != c->status->updatingDb )
654 {
655 screen_status_printf(_("Database updated!"));
656 mpdclient_browse_callback(c, BROWSE_DB_UPDATED, NULL);
657 }
659 repeat = c->status->repeat;
660 random = c->status->random;
661 crossfade = c->status->crossfade;
662 dbupdate = c->status->updatingDb;
664 /* update title/header window */
665 if( welcome && screen->last_cmd==CMD_NONE &&
666 time(NULL)-screen->start_timestamp <= SCREEN_WELCOME_TIME)
667 paint_top_window("", c, 0);
668 else if( mode_fn && mode_fn->get_title )
669 {
670 paint_top_window(mode_fn->get_title(screen->buf,screen->buf_size), c, 0);
671 welcome = FALSE;
672 }
673 else
674 paint_top_window("", c, 0);
676 /* update the main window */
677 if( mode_fn && mode_fn->paint )
678 mode_fn->update(screen, c);
680 if( mode_fn && mode_fn->get_lw )
681 lw = mode_fn->get_lw();
683 /* update progress window */
684 paint_progress_window(c);
686 /* update status window */
687 paint_status_window(c);
689 /* move the cursor to the selected row in the main window */
690 if( lw )
691 wmove(screen->main_window.w, LW_ROW(lw), 0);
692 else
693 wmove(screen->main_window.w, 0, 0);
694 wnoutrefresh(screen->main_window.w);
696 /* tell curses to update */
697 doupdate();
698 }
700 void
701 screen_idle(mpdclient_t *c)
702 {
703 if( c->song && seek_id == c->song->id &&
704 (screen->last_cmd == CMD_SEEK_FORWARD ||
705 screen->last_cmd == CMD_SEEK_BACKWARD) )
706 {
707 mpdclient_cmd_seek(c, seek_id, seek_target_time);
708 }
710 screen->last_cmd = CMD_NONE;
711 seek_id = -1;
712 }
714 #ifdef HAVE_GETMOUSE
715 int
716 screen_get_mouse_event(mpdclient_t *c,
717 list_window_t *lw, int lw_length,
718 unsigned long *bstate, int *row)
719 {
720 MEVENT event;
722 /* retreive the mouse event from ncurses */
723 getmouse(&event);
724 D("mouse: id=%d y=%d,x=%d,z=%d\n",event.id,event.y,event.x,event.z);
725 /* calculate the selected row in the list window */
726 *row = event.y - screen->top_window.rows;
727 /* copy button state bits */
728 *bstate = event.bstate;
729 /* if button 2 was pressed switch screen */
730 if( event.bstate & BUTTON2_CLICKED )
731 {
732 screen_cmd(c, CMD_SCREEN_NEXT);
733 return 1;
734 }
735 /* if the even occured above the list window move up */
736 if( *row<0 && lw )
737 {
738 if( event.bstate & BUTTON3_CLICKED )
739 list_window_first(lw);
740 else
741 list_window_previous_page(lw);
742 return 1;
743 }
744 /* if the even occured below the list window move down */
745 if( *row>=lw->rows && lw )
746 {
747 if( event.bstate & BUTTON3_CLICKED )
748 list_window_last(lw, lw_length);
749 else
750 list_window_next_page(lw, lw_length);
751 return 1;
752 }
753 return 0;
754 }
755 #endif
757 void
758 screen_cmd(mpdclient_t *c, command_t cmd)
759 {
760 screen->input_timestamp = time(NULL);
761 screen->last_cmd = cmd;
762 welcome = FALSE;
764 if( mode_fn && mode_fn->cmd && mode_fn->cmd(screen, c, cmd) )
765 return;
767 switch(cmd)
768 {
769 case CMD_PLAY:
770 mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
771 break;
772 case CMD_PAUSE:
773 mpdclient_cmd_pause(c, !IS_PAUSED(c->status->state));
774 break;
775 case CMD_STOP:
776 mpdclient_cmd_stop(c);
777 break;
778 case CMD_SEEK_FORWARD:
779 if( !IS_STOPPED(c->status->state) )
780 {
781 if( c->song && seek_id != c->song->id )
782 {
783 seek_id = c->song->id;
784 seek_target_time = c->status->elapsedTime;
785 }
786 seek_target_time+=options.seek_time;
787 if( seek_target_time < c->status->totalTime )
788 break;
789 seek_target_time = c->status->totalTime;
790 /* seek_target_time=0; */
791 }
792 break;
793 /* fall through... */
794 case CMD_TRACK_NEXT:
795 if( !IS_STOPPED(c->status->state) )
796 mpdclient_cmd_next(c);
797 break;
798 case CMD_SEEK_BACKWARD:
799 if( !IS_STOPPED(c->status->state) )
800 {
801 if( seek_id != c->song->id )
802 {
803 seek_id = c->song->id;
804 seek_target_time = c->status->elapsedTime;
805 }
806 seek_target_time-=options.seek_time;
807 if( seek_target_time < 0 )
808 seek_target_time=0;
809 }
810 break;
811 case CMD_TRACK_PREVIOUS:
812 if( !IS_STOPPED(c->status->state) )
813 mpdclient_cmd_prev(c);
814 break;
815 case CMD_SHUFFLE:
816 if( mpdclient_cmd_shuffle(c) == 0 )
817 screen_status_message(_("Shuffled playlist!"));
818 break;
819 case CMD_CLEAR:
820 if( mpdclient_cmd_clear(c) == 0 )
821 screen_status_message(_("Cleared playlist!"));
822 break;
823 case CMD_REPEAT:
824 mpdclient_cmd_repeat(c, !c->status->repeat);
825 break;
826 case CMD_RANDOM:
827 mpdclient_cmd_random(c, !c->status->random);
828 break;
829 case CMD_CROSSFADE:
830 if( c->status->crossfade )
831 mpdclient_cmd_crossfade(c, 0);
832 else
833 mpdclient_cmd_crossfade(c, options.crossfade_time);
834 break;
835 case CMD_DB_UPDATE:
836 if( !c->status->updatingDb )
837 {
838 if( mpdclient_cmd_db_update_utf8(c,NULL)==0 )
839 screen_status_printf(_("Database update started!"));
840 }
841 else
842 screen_status_printf(_("Database update running..."));
843 break;
844 case CMD_VOLUME_UP:
845 if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume<100 )
846 mpdclient_cmd_volume(c, ++c->status->volume);
847 break;
848 case CMD_VOLUME_DOWN:
849 if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume>0 )
850 mpdclient_cmd_volume(c, --c->status->volume);
851 break;
852 case CMD_TOGGLE_FIND_WRAP:
853 options.find_wrap = !options.find_wrap;
854 screen_status_printf(options.find_wrap ?
855 _("Find mode: Wrapped") :
856 _("Find mode: Normal"));
857 break;
858 case CMD_TOGGLE_AUTOCENTER:
859 options.auto_center = !options.auto_center;
860 screen_status_printf(options.auto_center ?
861 _("Auto center mode: On") :
862 _("Auto center mode: Off"));
863 break;
864 case CMD_SCREEN_UPDATE:
865 screen->painted = 0;
866 break;
867 case CMD_SCREEN_PREVIOUS:
868 if( screen->mode > 0 )
869 switch_screen_mode(screens[screen->mode-1].id, c);
870 else
871 switch_screen_mode(lookup_mode(SCREEN_HELP_ID)-1, c);
872 break;
873 case CMD_SCREEN_NEXT:
874 if( screens[screen->mode+1].id < SCREEN_HELP_ID )
875 switch_screen_mode(screens[screen->mode+1].id, c);
876 else
877 switch_screen_mode(screens[0].id, c);
878 break;
879 case CMD_SCREEN_PLAY:
880 switch_screen_mode(SCREEN_PLAYLIST_ID, c);
881 break;
882 case CMD_SCREEN_FILE:
883 switch_screen_mode(SCREEN_BROWSE_ID, c);
884 break;
885 case CMD_SCREEN_HELP:
886 switch_screen_mode(SCREEN_HELP_ID, c);
887 break;
888 case CMD_SCREEN_SEARCH:
889 switch_screen_mode(SCREEN_SEARCH_ID, c);
890 break;
891 case CMD_SCREEN_KEYDEF:
892 switch_screen_mode(SCREEN_KEYDEF_ID, c);
893 break;
894 case CMD_SCREEN_CLOCK:
895 switch_screen_mode(SCREEN_CLOCK_ID, c);
896 break;
897 case CMD_QUIT:
898 exit(EXIT_SUCCESS);
899 default:
900 break;
901 }
902 }