1 /*
2 * (c) 2004 by Kalle Wallin <kaw@linux.se>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
19 #include "screen.h"
20 #include "screen_list.h"
21 #include "screen_utils.h"
22 #include "config.h"
23 #include "i18n.h"
24 #include "hscroll.h"
25 #include "charset.h"
26 #include "mpdclient.h"
27 #include "utils.h"
28 #include "options.h"
29 #include "colors.h"
30 #include "strfsong.h"
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <stdarg.h>
35 #include <string.h>
36 #include <time.h>
37 #include <locale.h>
39 #ifndef NCMPC_MINI
40 /** welcome message time [s] */
41 static const GTime SCREEN_WELCOME_TIME = 10;
42 #endif
44 /** status message time [s] */
45 static const GTime SCREEN_STATUS_MESSAGE_TIME = 3;
47 /* minumum window size */
48 static const int SCREEN_MIN_COLS = 14;
49 static const int SCREEN_MIN_ROWS = 5;
51 /* screens */
53 #ifndef NCMPC_MINI
54 static gboolean welcome = TRUE;
55 #endif
57 struct screen screen;
58 static const struct screen_functions *mode_fn = &screen_playlist;
59 static int seek_id = -1;
60 static int seek_target_time = 0;
62 gboolean
63 screen_is_visible(const struct screen_functions *sf)
64 {
65 return sf == mode_fn;
66 }
68 void
69 screen_switch(const struct screen_functions *sf, struct mpdclient *c)
70 {
71 assert(sf != NULL);
73 if (sf == mode_fn)
74 return;
76 /* close the old mode */
77 if (mode_fn->close != NULL)
78 mode_fn->close();
80 /* get functions for the new mode */
81 mode_fn = sf;
83 /* open the new mode */
84 if (mode_fn->open != NULL)
85 mode_fn->open(c);
87 screen_paint(c);
88 }
90 static int
91 find_configured_screen(const char *name)
92 {
93 unsigned i;
95 for (i = 0; options.screen_list[i] != NULL; ++i)
96 if (strcmp(options.screen_list[i], name) == 0)
97 return i;
99 return -1;
100 }
102 static void
103 screen_next_mode(mpdclient_t *c, int offset)
104 {
105 int max = g_strv_length(options.screen_list);
106 int current, next;
107 const struct screen_functions *sf;
109 /* find current screen */
110 current = find_configured_screen(screen_get_name(mode_fn));
111 next = current + offset;
112 if (next<0)
113 next = max-1;
114 else if (next>=max)
115 next = 0;
117 sf = screen_lookup_name(options.screen_list[next]);
118 if (sf != NULL)
119 screen_switch(sf, c);
120 }
122 #ifndef NCMPC_MINI
123 static void
124 print_hotkey(WINDOW *w, command_t cmd, const char *label)
125 {
126 colors_use(w, COLOR_TITLE_BOLD);
127 waddstr(w, get_key_names(cmd, FALSE));
128 colors_use(w, COLOR_TITLE);
129 waddch(w, ':');
130 waddstr(w, label);
131 waddch(w, ' ');
132 waddch(w, ' ');
133 }
134 #endif
136 static void
137 paint_top_window2(const char *header, mpdclient_t *c)
138 {
139 char flags[5];
140 WINDOW *w = screen.top_window.w;
141 char buf[32];
143 if (header[0]) {
144 colors_use(w, COLOR_TITLE_BOLD);
145 mvwaddstr(w, 0, 0, header);
146 #ifndef NCMPC_MINI
147 } else {
148 #ifdef ENABLE_HELP_SCREEN
149 print_hotkey(w, CMD_SCREEN_HELP, _("Help"));
150 #endif
151 print_hotkey(w, CMD_SCREEN_PLAY, _("Playlist"));
152 print_hotkey(w, CMD_SCREEN_FILE, _("Browse"));
153 #ifdef ENABLE_ARTIST_SCREEN
154 print_hotkey(w, CMD_SCREEN_ARTIST, _("Artist"));
155 #endif
156 #ifdef ENABLE_SEARCH_SCREEN
157 print_hotkey(w, CMD_SCREEN_SEARCH, _("Search"));
158 #endif
159 #ifdef ENABLE_LYRICS_SCREEN
160 print_hotkey(w, CMD_SCREEN_LYRICS, _("Lyrics"));
161 #endif
162 #ifdef ENABLE_OUTPUTS_SCREEN
163 print_hotkey(w, CMD_SCREEN_OUTPUTS, _("Outputs"));
164 #endif
165 #endif
166 }
168 if (c->status == NULL || c->status->volume == MPD_STATUS_NO_VOLUME) {
169 g_snprintf(buf, 32, _("Volume n/a "));
170 } else {
171 g_snprintf(buf, 32, _(" Volume %d%%"), c->status->volume);
172 }
173 colors_use(w, COLOR_TITLE);
174 mvwaddstr(w, 0, screen.top_window.cols - utf8_width(buf), buf);
176 flags[0] = 0;
177 if (c->status != NULL) {
178 if (c->status->repeat)
179 g_strlcat(flags, "r", sizeof(flags));
180 if (c->status->random)
181 g_strlcat(flags, "z", sizeof(flags));;
182 if (c->status->crossfade)
183 g_strlcat(flags, "x", sizeof(flags));
184 if (c->status->updatingDb)
185 g_strlcat(flags, "U", sizeof(flags));
186 }
188 colors_use(w, COLOR_LINE);
189 mvwhline(w, 1, 0, ACS_HLINE, screen.top_window.cols);
190 if (flags[0]) {
191 wmove(w,1,screen.top_window.cols-strlen(flags)-3);
192 waddch(w, '[');
193 colors_use(w, COLOR_LINE_BOLD);
194 waddstr(w, flags);
195 colors_use(w, COLOR_LINE);
196 waddch(w, ']');
197 }
198 wnoutrefresh(w);
199 }
201 static void
202 paint_top_window(const char *header, mpdclient_t *c, int full_repaint)
203 {
204 static int prev_volume = -1;
205 static unsigned prev_header_len = -1;
206 WINDOW *w = screen.top_window.w;
208 if (prev_header_len != utf8_width(header)) {
209 prev_header_len = utf8_width(header);
210 full_repaint = 1;
211 }
213 if (full_repaint) {
214 wmove(w, 0, 0);
215 wclrtoeol(w);
216 }
218 if ((c->status != NULL && prev_volume != c->status->volume) ||
219 full_repaint)
220 paint_top_window2(header, c);
221 }
223 static void
224 paint_progress_window(mpdclient_t *c)
225 {
226 double p;
227 int width;
228 int elapsedTime;
230 if (c->status==NULL || IS_STOPPED(c->status->state)) {
231 mvwhline(screen.progress_window.w, 0, 0, ACS_HLINE,
232 screen.progress_window.cols);
233 wnoutrefresh(screen.progress_window.w);
234 return;
235 }
237 if (c->song && seek_id == c->song->id)
238 elapsedTime = seek_target_time;
239 else
240 elapsedTime = c->status->elapsedTime;
242 p = ((double) elapsedTime) / ((double) c->status->totalTime);
244 width = (int) (p * (double) screen.progress_window.cols);
245 mvwhline(screen.progress_window.w,
246 0, 0,
247 ACS_HLINE,
248 screen.progress_window.cols);
249 whline(screen.progress_window.w, '=', width-1);
250 mvwaddch(screen.progress_window.w, 0, width-1, 'O');
251 wnoutrefresh(screen.progress_window.w);
252 }
254 static void
255 paint_status_window(mpdclient_t *c)
256 {
257 WINDOW *w = screen.status_window.w;
258 mpd_Status *status = c->status;
259 mpd_Song *song = c->song;
260 int elapsedTime = 0;
261 #ifdef NCMPC_MINI
262 static char bitrate[1];
263 #else
264 char bitrate[16];
265 #endif
266 const char *str = NULL;
267 int x = 0;
269 if( time(NULL) - screen.status_timestamp <= SCREEN_STATUS_MESSAGE_TIME )
270 return;
272 wmove(w, 0, 0);
273 wclrtoeol(w);
274 colors_use(w, COLOR_STATUS_BOLD);
276 switch (status == NULL ? MPD_STATUS_STATE_STOP : status->state) {
277 case MPD_STATUS_STATE_PLAY:
278 str = _("Playing:");
279 break;
280 case MPD_STATUS_STATE_PAUSE:
281 str = _("[Paused]");
282 break;
283 case MPD_STATUS_STATE_STOP:
284 default:
285 break;
286 }
288 if (str) {
289 waddstr(w, str);
290 x += utf8_width(str) + 1;
291 }
293 /* create time string */
294 memset(screen.buf, 0, screen.buf_size);
295 if (status != NULL && (IS_PLAYING(status->state) ||
296 IS_PAUSED(status->state))) {
297 if (status->totalTime > 0) {
298 /*checks the conf to see whether to display elapsed or remaining time */
299 if(!strcmp(options.timedisplay_type,"elapsed"))
300 elapsedTime = c->status->elapsedTime;
301 else if(!strcmp(options.timedisplay_type,"remaining"))
302 elapsedTime = (c->status->totalTime - c->status->elapsedTime);
304 if( c->song && seek_id == c->song->id )
305 elapsedTime = seek_target_time;
307 /* display bitrate if visible-bitrate is true */
308 #ifndef NCMPC_MINI
309 if (options.visible_bitrate) {
310 g_snprintf(bitrate, 16,
311 " [%d kbps]", status->bitRate);
312 } else {
313 bitrate[0] = '\0';
314 }
315 #endif
317 /*write out the time, using hours if time over 60 minutes*/
318 if (c->status->totalTime > 3600) {
319 g_snprintf(screen.buf, screen.buf_size,
320 "%s [%i:%02i:%02i/%i:%02i:%02i]",
321 bitrate, elapsedTime/3600, (elapsedTime%3600)/60, elapsedTime%60,
322 status->totalTime/3600, (status->totalTime%3600)/60, status->totalTime%60);
323 } else {
324 g_snprintf(screen.buf, screen.buf_size,
325 "%s [%i:%02i/%i:%02i]",
326 bitrate, elapsedTime/60, elapsedTime%60,
327 status->totalTime/60, status->totalTime%60 );
328 }
329 #ifndef NCMPC_MINI
330 } else {
331 g_snprintf(screen.buf, screen.buf_size,
332 " [%d kbps]", status->bitRate );
333 #endif
334 }
335 #ifndef NCMPC_MINI
336 } else {
337 time_t timep;
339 time(&timep);
340 strftime(screen.buf, screen.buf_size, "%X ",localtime(&timep));
341 #endif
342 }
344 /* display song */
345 if (status != NULL && (IS_PLAYING(status->state) ||
346 IS_PAUSED(status->state))) {
347 char songname[MAX_SONGNAME_LENGTH];
348 #ifndef NCMPC_MINI
349 int width = COLS - x - utf8_width(screen.buf);
350 #endif
352 if (song)
353 strfsong(songname, MAX_SONGNAME_LENGTH,
354 options.status_format, song);
355 else
356 songname[0] = '\0';
358 colors_use(w, COLOR_STATUS);
359 /* scroll if the song name is to long */
360 #ifndef NCMPC_MINI
361 if (options.scroll && utf8_width(songname) > (unsigned)width) {
362 static scroll_state_t st = { 0, 0 };
363 char *tmp = strscroll(songname, options.scroll_sep, width, &st);
365 g_strlcpy(songname, tmp, MAX_SONGNAME_LENGTH);
366 g_free(tmp);
367 }
368 #endif
369 //mvwaddnstr(w, 0, x, songname, width);
370 mvwaddstr(w, 0, x, songname);
371 }
373 /* display time string */
374 if (screen.buf[0]) {
375 x = screen.status_window.cols - strlen(screen.buf);
376 colors_use(w, COLOR_STATUS_TIME);
377 mvwaddstr(w, 0, x, screen.buf);
378 }
380 wnoutrefresh(w);
381 }
383 void
384 screen_exit(void)
385 {
386 if (mode_fn->close != NULL)
387 mode_fn->close();
389 screen_list_exit();
391 string_list_free(screen.find_history);
392 g_free(screen.buf);
393 g_free(screen.findbuf);
394 }
396 void
397 screen_resize(struct mpdclient *c)
398 {
399 if (COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS) {
400 screen_exit();
401 fprintf(stderr, "%s", _("Error: Screen too small"));
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 /* resize all screens */
435 screen_list_resize(screen.main_window.cols, screen.main_window.rows);
437 /* ? - without this the cursor becomes visible with aterm & Eterm */
438 curs_set(1);
439 curs_set(0);
441 screen_paint(c);
442 }
444 void
445 screen_status_message(const char *msg)
446 {
447 WINDOW *w = screen.status_window.w;
449 wmove(w, 0, 0);
450 wclrtoeol(w);
451 colors_use(w, COLOR_STATUS_ALERT);
452 waddstr(w, msg);
453 wnoutrefresh(w);
454 screen.status_timestamp = time(NULL);
455 }
457 void
458 screen_status_printf(const char *format, ...)
459 {
460 char *msg;
461 va_list ap;
463 va_start(ap,format);
464 msg = g_strdup_vprintf(format,ap);
465 va_end(ap);
466 screen_status_message(msg);
467 g_free(msg);
468 }
470 void
471 screen_init(mpdclient_t *c)
472 {
473 if (COLS < SCREEN_MIN_COLS || LINES < SCREEN_MIN_ROWS) {
474 fprintf(stderr, "%s\n", _("Error: Screen too small"));
475 exit(EXIT_FAILURE);
476 }
478 screen.cols = COLS;
479 screen.rows = LINES;
481 screen.buf = g_malloc(screen.cols);
482 screen.buf_size = screen.cols;
483 screen.findbuf = NULL;
484 screen.start_timestamp = time(NULL);
485 screen.last_cmd = CMD_NONE;
487 /* create top window */
488 screen.top_window.rows = 2;
489 screen.top_window.cols = screen.cols;
490 screen.top_window.w = newwin(screen.top_window.rows,
491 screen.top_window.cols,
492 0, 0);
493 leaveok(screen.top_window.w, TRUE);
494 keypad(screen.top_window.w, TRUE);
496 /* create main window */
497 screen.main_window.rows = screen.rows-4;
498 screen.main_window.cols = screen.cols;
499 screen.main_window.w = newwin(screen.main_window.rows,
500 screen.main_window.cols,
501 2,
502 0);
504 // leaveok(screen.main_window.w, TRUE); temporary disabled
505 keypad(screen.main_window.w, TRUE);
507 /* create progress window */
508 screen.progress_window.rows = 1;
509 screen.progress_window.cols = screen.cols;
510 screen.progress_window.w = newwin(screen.progress_window.rows,
511 screen.progress_window.cols,
512 screen.rows-2,
513 0);
514 leaveok(screen.progress_window.w, TRUE);
516 /* create status window */
517 screen.status_window.rows = 1;
518 screen.status_window.cols = screen.cols;
519 screen.status_window.w = newwin(screen.status_window.rows,
520 screen.status_window.cols,
521 screen.rows-1,
522 0);
524 leaveok(screen.status_window.w, FALSE);
525 keypad(screen.status_window.w, TRUE);
527 #ifdef ENABLE_COLORS
528 if (options.enable_colors) {
529 /* set background attributes */
530 wbkgd(stdscr, COLOR_PAIR(COLOR_LIST));
531 wbkgd(screen.main_window.w, COLOR_PAIR(COLOR_LIST));
532 wbkgd(screen.top_window.w, COLOR_PAIR(COLOR_TITLE));
533 wbkgd(screen.progress_window.w, COLOR_PAIR(COLOR_PROGRESSBAR));
534 wbkgd(screen.status_window.w, COLOR_PAIR(COLOR_STATUS));
535 colors_use(screen.progress_window.w, COLOR_PROGRESSBAR);
536 }
537 #endif
539 refresh();
541 /* initialize screens */
542 screen_list_init(screen.main_window.w,
543 screen.main_window.cols, screen.main_window.rows);
545 if (mode_fn->open != NULL)
546 mode_fn->open(c);
547 }
549 void
550 screen_paint(mpdclient_t *c)
551 {
552 const char *title = NULL;
554 if (mode_fn->get_title != NULL)
555 title = mode_fn->get_title(screen.buf, screen.buf_size);
557 /* paint the title/header window */
558 if( title )
559 paint_top_window(title, c, 1);
560 else
561 paint_top_window("", c, 1);
563 /* paint the main window */
564 wclear(screen.main_window.w);
565 if (mode_fn->paint != NULL)
566 mode_fn->paint();
568 paint_progress_window(c);
569 paint_status_window(c);
570 wmove(screen.main_window.w, 0, 0);
571 wnoutrefresh(screen.main_window.w);
573 /* tell curses to update */
574 doupdate();
575 }
577 void
578 screen_update(mpdclient_t *c)
579 {
580 #ifndef NCMPC_MINI
581 static int repeat = -1;
582 static int random_enabled = -1;
583 static int crossfade = -1;
584 static int dbupdate = -1;
586 /* print a message if mpd status has changed */
587 if (c->status != NULL) {
588 if (repeat < 0) {
589 repeat = c->status->repeat;
590 random_enabled = c->status->random;
591 crossfade = c->status->crossfade;
592 dbupdate = c->status->updatingDb;
593 }
595 if (repeat != c->status->repeat)
596 screen_status_printf(c->status->repeat ?
597 _("Repeat is on") :
598 _("Repeat is off"));
600 if (random_enabled != c->status->random)
601 screen_status_printf(c->status->random ?
602 _("Random is on") :
603 _("Random is off"));
605 if (crossfade != c->status->crossfade)
606 screen_status_printf(_("Crossfade %d seconds"), c->status->crossfade);
608 if (dbupdate && dbupdate != c->status->updatingDb) {
609 screen_status_printf(_("Database updated"));
610 mpdclient_browse_callback(c, BROWSE_DB_UPDATED, NULL);
611 }
613 repeat = c->status->repeat;
614 random_enabled = c->status->random;
615 crossfade = c->status->crossfade;
616 dbupdate = c->status->updatingDb;
617 }
619 /* update title/header window */
620 if (welcome && options.welcome_screen_list &&
621 screen.last_cmd==CMD_NONE &&
622 time(NULL)-screen.start_timestamp <= SCREEN_WELCOME_TIME)
623 paint_top_window("", c, 0);
624 else
625 #endif
626 if (mode_fn->get_title != NULL) {
627 paint_top_window(mode_fn->get_title(screen.buf,screen.buf_size), c, 0);
628 #ifndef NCMPC_MINI
629 welcome = FALSE;
630 #endif
631 } else
632 paint_top_window("", c, 0);
634 /* update the main window */
635 if (mode_fn->update != NULL)
636 mode_fn->update(c);
638 /* update progress window */
639 paint_progress_window(c);
641 /* update status window */
642 paint_status_window(c);
644 /* move the cursor to the origin */
645 wmove(screen.main_window.w, 0, 0);
646 wnoutrefresh(screen.main_window.w);
648 /* tell curses to update */
649 doupdate();
650 }
652 void
653 screen_idle(mpdclient_t *c)
654 {
655 if (c->song && seek_id == c->song->id &&
656 (screen.last_cmd == CMD_SEEK_FORWARD ||
657 screen.last_cmd == CMD_SEEK_BACKWARD))
658 mpdclient_cmd_seek(c, seek_id, seek_target_time);
660 screen.last_cmd = CMD_NONE;
661 seek_id = -1;
662 }
664 #ifdef HAVE_GETMOUSE
665 int
666 screen_get_mouse_event(mpdclient_t *c, unsigned long *bstate, int *row)
667 {
668 MEVENT event;
670 /* retreive the mouse event from ncurses */
671 getmouse(&event);
672 /* calculate the selected row in the list window */
673 *row = event.y - screen.top_window.rows;
674 /* copy button state bits */
675 *bstate = event.bstate;
676 /* if button 2 was pressed switch screen */
677 if (event.bstate & BUTTON2_CLICKED) {
678 screen_cmd(c, CMD_SCREEN_NEXT);
679 return 1;
680 }
682 return 0;
683 }
684 #endif
686 static int
687 screen_client_cmd(mpdclient_t *c, command_t cmd)
688 {
689 if (c->connection == NULL || c->status == NULL)
690 return 0;
692 switch(cmd) {
693 /*
694 case CMD_PLAY:
695 mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
696 break;
697 */
698 case CMD_PAUSE:
699 mpdclient_cmd_pause(c, !IS_PAUSED(c->status->state));
700 break;
701 case CMD_STOP:
702 mpdclient_cmd_stop(c);
703 break;
704 case CMD_CROP:
705 mpdclient_cmd_crop(c);
706 break;
707 case CMD_SEEK_FORWARD:
708 if (!IS_STOPPED(c->status->state)) {
709 if (c->song && seek_id != c->song->id) {
710 seek_id = c->song->id;
711 seek_target_time = c->status->elapsedTime;
712 }
713 seek_target_time+=options.seek_time;
714 if (seek_target_time < c->status->totalTime)
715 break;
716 seek_target_time = c->status->totalTime;
717 /* seek_target_time=0; */
718 }
719 break;
720 /* fall through... */
721 case CMD_TRACK_NEXT:
722 if (!IS_STOPPED(c->status->state))
723 mpdclient_cmd_next(c);
724 break;
725 case CMD_SEEK_BACKWARD:
726 if (!IS_STOPPED(c->status->state)) {
727 if (seek_id != c->song->id) {
728 seek_id = c->song->id;
729 seek_target_time = c->status->elapsedTime;
730 }
731 seek_target_time-=options.seek_time;
732 if (seek_target_time < 0)
733 seek_target_time=0;
734 }
735 break;
736 case CMD_TRACK_PREVIOUS:
737 if (!IS_STOPPED(c->status->state))
738 mpdclient_cmd_prev(c);
739 break;
740 case CMD_SHUFFLE:
741 if (mpdclient_cmd_shuffle(c) == 0)
742 screen_status_message(_("Shuffled playlist"));
743 break;
744 case CMD_CLEAR:
745 if (mpdclient_cmd_clear(c) == 0)
746 screen_status_message(_("Cleared playlist"));
747 break;
748 case CMD_REPEAT:
749 mpdclient_cmd_repeat(c, !c->status->repeat);
750 break;
751 case CMD_RANDOM:
752 mpdclient_cmd_random(c, !c->status->random);
753 break;
754 case CMD_CROSSFADE:
755 if (c->status->crossfade)
756 mpdclient_cmd_crossfade(c, 0);
757 else
758 mpdclient_cmd_crossfade(c, options.crossfade_time);
759 break;
760 case CMD_DB_UPDATE:
761 if (!c->status->updatingDb) {
762 if( mpdclient_cmd_db_update(c,NULL)==0 )
763 screen_status_printf(_("Database update started"));
764 } else
765 screen_status_printf(_("Database update running..."));
766 break;
767 case CMD_VOLUME_UP:
768 if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume<100 )
769 mpdclient_cmd_volume(c, ++c->status->volume);
770 break;
771 case CMD_VOLUME_DOWN:
772 if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume>0 )
773 mpdclient_cmd_volume(c, --c->status->volume);
774 break;
776 default:
777 return 0;
778 }
780 return 1;
781 }
783 void
784 screen_cmd(mpdclient_t *c, command_t cmd)
785 {
786 screen.last_cmd = cmd;
787 #ifndef NCMPC_MINI
788 welcome = FALSE;
789 #endif
791 if (mode_fn->cmd != NULL && mode_fn->cmd(c, cmd))
792 return;
794 if (screen_client_cmd(c, cmd))
795 return;
797 switch(cmd) {
798 case CMD_TOGGLE_FIND_WRAP:
799 options.find_wrap = !options.find_wrap;
800 screen_status_printf(options.find_wrap ?
801 _("Find mode: Wrapped") :
802 _("Find mode: Normal"));
803 break;
804 case CMD_TOGGLE_AUTOCENTER:
805 options.auto_center = !options.auto_center;
806 screen_status_printf(options.auto_center ?
807 _("Auto center mode: On") :
808 _("Auto center mode: Off"));
809 break;
810 case CMD_SCREEN_UPDATE:
811 screen_paint(c);
812 break;
813 case CMD_SCREEN_PREVIOUS:
814 screen_next_mode(c, -1);
815 break;
816 case CMD_SCREEN_NEXT:
817 screen_next_mode(c, 1);
818 break;
819 case CMD_SCREEN_PLAY:
820 screen_switch(&screen_playlist, c);
821 break;
822 case CMD_SCREEN_FILE:
823 screen_switch(&screen_browse, c);
824 break;
825 #ifdef ENABLE_HELP_SCREEN
826 case CMD_SCREEN_HELP:
827 screen_switch(&screen_help, c);
828 break;
829 #endif
830 #ifdef ENABLE_SEARCH_SCREEN
831 case CMD_SCREEN_SEARCH:
832 screen_switch(&screen_search, c);
833 break;
834 #endif
835 #ifdef ENABLE_ARTIST_SCREEN
836 case CMD_SCREEN_ARTIST:
837 screen_switch(&screen_artist, c);
838 break;
839 #endif
840 #ifdef ENABLE_KEYDEF_SCREEN
841 case CMD_SCREEN_KEYDEF:
842 screen_switch(&screen_keydef, c);
843 break;
844 #endif
845 #ifdef ENABLE_LYRICS_SCREEN
846 case CMD_SCREEN_LYRICS:
847 screen_switch(&screen_lyrics, c);
848 break;
849 #endif
850 #ifdef ENABLE_OUTPUTS_SCREEN
851 case CMD_SCREEN_OUTPUTS:
852 screen_switch(&screen_outputs, c);
853 break;
854 #endif
855 default:
856 break;
857 }
858 }