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 "charset.h"
25 #include "mpdclient.h"
26 #include "utils.h"
27 #include "options.h"
28 #include "colors.h"
29 #include "strfsong.h"
31 #ifndef NCMPC_MINI
32 #include "hscroll.h"
33 #endif
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <stdarg.h>
38 #include <string.h>
39 #include <time.h>
40 #include <locale.h>
42 #ifndef NCMPC_MINI
43 /** welcome message time [s] */
44 static const GTime SCREEN_WELCOME_TIME = 10;
45 #endif
47 /** status message time [s] */
48 static const GTime SCREEN_STATUS_MESSAGE_TIME = 3;
50 /* minumum window size */
51 static const int SCREEN_MIN_COLS = 14;
52 static const int SCREEN_MIN_ROWS = 5;
54 /* screens */
56 #ifndef NCMPC_MINI
57 static gboolean welcome = TRUE;
58 #endif
60 struct screen screen;
61 static const struct screen_functions *mode_fn = &screen_playlist;
62 static int seek_id = -1;
63 static int seek_target_time = 0;
65 gboolean
66 screen_is_visible(const struct screen_functions *sf)
67 {
68 return sf == mode_fn;
69 }
71 void
72 screen_switch(const struct screen_functions *sf, struct mpdclient *c)
73 {
74 assert(sf != NULL);
76 if (sf == mode_fn)
77 return;
79 /* close the old mode */
80 if (mode_fn->close != NULL)
81 mode_fn->close();
83 /* get functions for the new mode */
84 mode_fn = sf;
86 /* open the new mode */
87 if (mode_fn->open != NULL)
88 mode_fn->open(c);
90 screen_paint(c);
91 }
93 static int
94 find_configured_screen(const char *name)
95 {
96 unsigned i;
98 for (i = 0; options.screen_list[i] != NULL; ++i)
99 if (strcmp(options.screen_list[i], name) == 0)
100 return i;
102 return -1;
103 }
105 static void
106 screen_next_mode(mpdclient_t *c, int offset)
107 {
108 int max = g_strv_length(options.screen_list);
109 int current, next;
110 const struct screen_functions *sf;
112 /* find current screen */
113 current = find_configured_screen(screen_get_name(mode_fn));
114 next = current + offset;
115 if (next<0)
116 next = max-1;
117 else if (next>=max)
118 next = 0;
120 sf = screen_lookup_name(options.screen_list[next]);
121 if (sf != NULL)
122 screen_switch(sf, c);
123 }
125 #ifndef NCMPC_MINI
126 static void
127 print_hotkey(WINDOW *w, command_t cmd, const char *label)
128 {
129 colors_use(w, COLOR_TITLE_BOLD);
130 waddstr(w, get_key_names(cmd, FALSE));
131 colors_use(w, COLOR_TITLE);
132 waddch(w, ':');
133 waddstr(w, label);
134 waddch(w, ' ');
135 waddch(w, ' ');
136 }
137 #endif
139 static void
140 paint_top_window2(const char *header, mpdclient_t *c)
141 {
142 char flags[5];
143 WINDOW *w = screen.top_window.w;
144 char buf[32];
146 if (header[0]) {
147 colors_use(w, COLOR_TITLE_BOLD);
148 mvwaddstr(w, 0, 0, header);
149 #ifndef NCMPC_MINI
150 } else {
151 #ifdef ENABLE_HELP_SCREEN
152 print_hotkey(w, CMD_SCREEN_HELP, _("Help"));
153 #endif
154 print_hotkey(w, CMD_SCREEN_PLAY, _("Playlist"));
155 print_hotkey(w, CMD_SCREEN_FILE, _("Browse"));
156 #ifdef ENABLE_ARTIST_SCREEN
157 print_hotkey(w, CMD_SCREEN_ARTIST, _("Artist"));
158 #endif
159 #ifdef ENABLE_SEARCH_SCREEN
160 print_hotkey(w, CMD_SCREEN_SEARCH, _("Search"));
161 #endif
162 #ifdef ENABLE_LYRICS_SCREEN
163 print_hotkey(w, CMD_SCREEN_LYRICS, _("Lyrics"));
164 #endif
165 #ifdef ENABLE_OUTPUTS_SCREEN
166 print_hotkey(w, CMD_SCREEN_OUTPUTS, _("Outputs"));
167 #endif
168 #endif
169 }
171 if (c->status == NULL || c->status->volume == MPD_STATUS_NO_VOLUME) {
172 g_snprintf(buf, 32, _("Volume n/a "));
173 } else {
174 g_snprintf(buf, 32, _(" Volume %d%%"), c->status->volume);
175 }
176 colors_use(w, COLOR_TITLE);
177 mvwaddstr(w, 0, screen.top_window.cols - utf8_width(buf), buf);
179 flags[0] = 0;
180 if (c->status != NULL) {
181 if (c->status->repeat)
182 g_strlcat(flags, "r", sizeof(flags));
183 if (c->status->random)
184 g_strlcat(flags, "z", sizeof(flags));;
185 if (c->status->crossfade)
186 g_strlcat(flags, "x", sizeof(flags));
187 if (c->status->updatingDb)
188 g_strlcat(flags, "U", sizeof(flags));
189 }
191 colors_use(w, COLOR_LINE);
192 mvwhline(w, 1, 0, ACS_HLINE, screen.top_window.cols);
193 if (flags[0]) {
194 wmove(w,1,screen.top_window.cols-strlen(flags)-3);
195 waddch(w, '[');
196 colors_use(w, COLOR_LINE_BOLD);
197 waddstr(w, flags);
198 colors_use(w, COLOR_LINE);
199 waddch(w, ']');
200 }
201 wnoutrefresh(w);
202 }
204 static void
205 paint_top_window(const char *header, mpdclient_t *c, int full_repaint)
206 {
207 static int prev_volume = -1;
208 static unsigned prev_header_len = -1;
209 WINDOW *w = screen.top_window.w;
211 if (prev_header_len != utf8_width(header)) {
212 prev_header_len = utf8_width(header);
213 full_repaint = 1;
214 }
216 if (full_repaint) {
217 wmove(w, 0, 0);
218 wclrtoeol(w);
219 }
221 if ((c->status != NULL && prev_volume != c->status->volume) ||
222 full_repaint)
223 paint_top_window2(header, c);
224 }
226 static void
227 paint_progress_window(mpdclient_t *c)
228 {
229 double p;
230 int width;
231 int elapsedTime;
233 if (c->status==NULL || IS_STOPPED(c->status->state)) {
234 mvwhline(screen.progress_window.w, 0, 0, ACS_HLINE,
235 screen.progress_window.cols);
236 wnoutrefresh(screen.progress_window.w);
237 return;
238 }
240 if (c->song && seek_id == c->song->id)
241 elapsedTime = seek_target_time;
242 else
243 elapsedTime = c->status->elapsedTime;
245 p = ((double) elapsedTime) / ((double) c->status->totalTime);
247 width = (int) (p * (double) screen.progress_window.cols);
248 mvwhline(screen.progress_window.w,
249 0, 0,
250 ACS_HLINE,
251 screen.progress_window.cols);
252 whline(screen.progress_window.w, '=', width-1);
253 mvwaddch(screen.progress_window.w, 0, width-1, 'O');
254 wnoutrefresh(screen.progress_window.w);
255 }
257 static void
258 paint_status_window(mpdclient_t *c)
259 {
260 WINDOW *w = screen.status_window.w;
261 mpd_Status *status = c->status;
262 mpd_Song *song = c->song;
263 int elapsedTime = 0;
264 #ifdef NCMPC_MINI
265 static char bitrate[1];
266 #else
267 char bitrate[16];
268 #endif
269 const char *str = NULL;
270 int x = 0;
272 if( time(NULL) - screen.status_timestamp <= SCREEN_STATUS_MESSAGE_TIME )
273 return;
275 wmove(w, 0, 0);
276 wclrtoeol(w);
277 colors_use(w, COLOR_STATUS_BOLD);
279 switch (status == NULL ? MPD_STATUS_STATE_STOP : status->state) {
280 case MPD_STATUS_STATE_PLAY:
281 str = _("Playing:");
282 break;
283 case MPD_STATUS_STATE_PAUSE:
284 str = _("[Paused]");
285 break;
286 case MPD_STATUS_STATE_STOP:
287 default:
288 break;
289 }
291 if (str) {
292 waddstr(w, str);
293 x += utf8_width(str) + 1;
294 }
296 /* create time string */
297 memset(screen.buf, 0, screen.buf_size);
298 if (status != NULL && (IS_PLAYING(status->state) ||
299 IS_PAUSED(status->state))) {
300 if (status->totalTime > 0) {
301 /*checks the conf to see whether to display elapsed or remaining time */
302 if(!strcmp(options.timedisplay_type,"elapsed"))
303 elapsedTime = c->status->elapsedTime;
304 else if(!strcmp(options.timedisplay_type,"remaining"))
305 elapsedTime = (c->status->totalTime - c->status->elapsedTime);
307 if( c->song && seek_id == c->song->id )
308 elapsedTime = seek_target_time;
310 /* display bitrate if visible-bitrate is true */
311 #ifndef NCMPC_MINI
312 if (options.visible_bitrate) {
313 g_snprintf(bitrate, 16,
314 " [%d kbps]", status->bitRate);
315 } else {
316 bitrate[0] = '\0';
317 }
318 #endif
320 /*write out the time, using hours if time over 60 minutes*/
321 if (c->status->totalTime > 3600) {
322 g_snprintf(screen.buf, screen.buf_size,
323 "%s [%i:%02i:%02i/%i:%02i:%02i]",
324 bitrate, elapsedTime/3600, (elapsedTime%3600)/60, elapsedTime%60,
325 status->totalTime/3600, (status->totalTime%3600)/60, status->totalTime%60);
326 } else {
327 g_snprintf(screen.buf, screen.buf_size,
328 "%s [%i:%02i/%i:%02i]",
329 bitrate, elapsedTime/60, elapsedTime%60,
330 status->totalTime/60, status->totalTime%60 );
331 }
332 #ifndef NCMPC_MINI
333 } else {
334 g_snprintf(screen.buf, screen.buf_size,
335 " [%d kbps]", status->bitRate );
336 #endif
337 }
338 #ifndef NCMPC_MINI
339 } else {
340 time_t timep;
342 time(&timep);
343 strftime(screen.buf, screen.buf_size, "%X ",localtime(&timep));
344 #endif
345 }
347 /* display song */
348 if (status != NULL && (IS_PLAYING(status->state) ||
349 IS_PAUSED(status->state))) {
350 char songname[MAX_SONGNAME_LENGTH];
351 #ifndef NCMPC_MINI
352 int width = COLS - x - utf8_width(screen.buf);
353 #endif
355 if (song)
356 strfsong(songname, MAX_SONGNAME_LENGTH,
357 options.status_format, song);
358 else
359 songname[0] = '\0';
361 colors_use(w, COLOR_STATUS);
362 /* scroll if the song name is to long */
363 #ifndef NCMPC_MINI
364 if (options.scroll && utf8_width(songname) > (unsigned)width) {
365 static scroll_state_t st = { 0, 0 };
366 char *tmp = strscroll(songname, options.scroll_sep, width, &st);
368 g_strlcpy(songname, tmp, MAX_SONGNAME_LENGTH);
369 g_free(tmp);
370 }
371 #endif
372 //mvwaddnstr(w, 0, x, songname, width);
373 mvwaddstr(w, 0, x, songname);
374 }
376 /* display time string */
377 if (screen.buf[0]) {
378 x = screen.status_window.cols - strlen(screen.buf);
379 colors_use(w, COLOR_STATUS_TIME);
380 mvwaddstr(w, 0, x, screen.buf);
381 }
383 wnoutrefresh(w);
384 }
386 void
387 screen_exit(void)
388 {
389 if (mode_fn->close != NULL)
390 mode_fn->close();
392 screen_list_exit();
394 string_list_free(screen.find_history);
395 g_free(screen.buf);
396 g_free(screen.findbuf);
397 }
399 void
400 screen_resize(struct mpdclient *c)
401 {
402 if (COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS) {
403 screen_exit();
404 fprintf(stderr, "%s", _("Error: Screen too small"));
405 exit(EXIT_FAILURE);
406 }
408 resizeterm(LINES, COLS);
410 screen.cols = COLS;
411 screen.rows = LINES;
413 /* top window */
414 screen.top_window.cols = screen.cols;
415 wresize(screen.top_window.w, 2, screen.cols);
417 /* main window */
418 screen.main_window.cols = screen.cols;
419 screen.main_window.rows = screen.rows-4;
420 wresize(screen.main_window.w, screen.main_window.rows, screen.cols);
421 wclear(screen.main_window.w);
423 /* progress window */
424 screen.progress_window.cols = screen.cols;
425 wresize(screen.progress_window.w, 1, screen.cols);
426 mvwin(screen.progress_window.w, screen.rows-2, 0);
428 /* status window */
429 screen.status_window.cols = screen.cols;
430 wresize(screen.status_window.w, 1, screen.cols);
431 mvwin(screen.status_window.w, screen.rows-1, 0);
433 screen.buf_size = screen.cols;
434 g_free(screen.buf);
435 screen.buf = g_malloc(screen.cols);
437 /* resize all screens */
438 screen_list_resize(screen.main_window.cols, screen.main_window.rows);
440 /* ? - without this the cursor becomes visible with aterm & Eterm */
441 curs_set(1);
442 curs_set(0);
444 screen_paint(c);
445 }
447 void
448 screen_status_message(const char *msg)
449 {
450 WINDOW *w = screen.status_window.w;
452 wmove(w, 0, 0);
453 wclrtoeol(w);
454 colors_use(w, COLOR_STATUS_ALERT);
455 waddstr(w, msg);
456 wnoutrefresh(w);
457 screen.status_timestamp = time(NULL);
458 }
460 void
461 screen_status_printf(const char *format, ...)
462 {
463 char *msg;
464 va_list ap;
466 va_start(ap,format);
467 msg = g_strdup_vprintf(format,ap);
468 va_end(ap);
469 screen_status_message(msg);
470 g_free(msg);
471 }
473 void
474 screen_init(mpdclient_t *c)
475 {
476 if (COLS < SCREEN_MIN_COLS || LINES < SCREEN_MIN_ROWS) {
477 fprintf(stderr, "%s\n", _("Error: Screen too small"));
478 exit(EXIT_FAILURE);
479 }
481 screen.cols = COLS;
482 screen.rows = LINES;
484 screen.buf = g_malloc(screen.cols);
485 screen.buf_size = screen.cols;
486 screen.findbuf = NULL;
487 screen.start_timestamp = time(NULL);
488 screen.last_cmd = CMD_NONE;
490 /* create top window */
491 screen.top_window.rows = 2;
492 screen.top_window.cols = screen.cols;
493 screen.top_window.w = newwin(screen.top_window.rows,
494 screen.top_window.cols,
495 0, 0);
496 leaveok(screen.top_window.w, TRUE);
497 keypad(screen.top_window.w, TRUE);
499 /* create main window */
500 screen.main_window.rows = screen.rows-4;
501 screen.main_window.cols = screen.cols;
502 screen.main_window.w = newwin(screen.main_window.rows,
503 screen.main_window.cols,
504 2,
505 0);
507 // leaveok(screen.main_window.w, TRUE); temporary disabled
508 keypad(screen.main_window.w, TRUE);
510 /* create progress window */
511 screen.progress_window.rows = 1;
512 screen.progress_window.cols = screen.cols;
513 screen.progress_window.w = newwin(screen.progress_window.rows,
514 screen.progress_window.cols,
515 screen.rows-2,
516 0);
517 leaveok(screen.progress_window.w, TRUE);
519 /* create status window */
520 screen.status_window.rows = 1;
521 screen.status_window.cols = screen.cols;
522 screen.status_window.w = newwin(screen.status_window.rows,
523 screen.status_window.cols,
524 screen.rows-1,
525 0);
527 leaveok(screen.status_window.w, FALSE);
528 keypad(screen.status_window.w, TRUE);
530 #ifdef ENABLE_COLORS
531 if (options.enable_colors) {
532 /* set background attributes */
533 wbkgd(stdscr, COLOR_PAIR(COLOR_LIST));
534 wbkgd(screen.main_window.w, COLOR_PAIR(COLOR_LIST));
535 wbkgd(screen.top_window.w, COLOR_PAIR(COLOR_TITLE));
536 wbkgd(screen.progress_window.w, COLOR_PAIR(COLOR_PROGRESSBAR));
537 wbkgd(screen.status_window.w, COLOR_PAIR(COLOR_STATUS));
538 colors_use(screen.progress_window.w, COLOR_PROGRESSBAR);
539 }
540 #endif
542 refresh();
544 /* initialize screens */
545 screen_list_init(screen.main_window.w,
546 screen.main_window.cols, screen.main_window.rows);
548 if (mode_fn->open != NULL)
549 mode_fn->open(c);
550 }
552 void
553 screen_paint(mpdclient_t *c)
554 {
555 const char *title = NULL;
557 if (mode_fn->get_title != NULL)
558 title = mode_fn->get_title(screen.buf, screen.buf_size);
560 /* paint the title/header window */
561 if( title )
562 paint_top_window(title, c, 1);
563 else
564 paint_top_window("", c, 1);
566 /* paint the main window */
567 wclear(screen.main_window.w);
568 if (mode_fn->paint != NULL)
569 mode_fn->paint();
571 paint_progress_window(c);
572 paint_status_window(c);
573 wmove(screen.main_window.w, 0, 0);
574 wnoutrefresh(screen.main_window.w);
576 /* tell curses to update */
577 doupdate();
578 }
580 void
581 screen_update(mpdclient_t *c)
582 {
583 #ifndef NCMPC_MINI
584 static int repeat = -1;
585 static int random_enabled = -1;
586 static int crossfade = -1;
587 static int dbupdate = -1;
589 /* print a message if mpd status has changed */
590 if (c->status != NULL) {
591 if (repeat < 0) {
592 repeat = c->status->repeat;
593 random_enabled = c->status->random;
594 crossfade = c->status->crossfade;
595 dbupdate = c->status->updatingDb;
596 }
598 if (repeat != c->status->repeat)
599 screen_status_printf(c->status->repeat ?
600 _("Repeat is on") :
601 _("Repeat is off"));
603 if (random_enabled != c->status->random)
604 screen_status_printf(c->status->random ?
605 _("Random is on") :
606 _("Random is off"));
608 if (crossfade != c->status->crossfade)
609 screen_status_printf(_("Crossfade %d seconds"), c->status->crossfade);
611 if (dbupdate && dbupdate != c->status->updatingDb) {
612 screen_status_printf(_("Database updated"));
613 mpdclient_browse_callback(c, BROWSE_DB_UPDATED, NULL);
614 }
616 repeat = c->status->repeat;
617 random_enabled = c->status->random;
618 crossfade = c->status->crossfade;
619 dbupdate = c->status->updatingDb;
620 }
622 /* update title/header window */
623 if (welcome && options.welcome_screen_list &&
624 screen.last_cmd==CMD_NONE &&
625 time(NULL)-screen.start_timestamp <= SCREEN_WELCOME_TIME)
626 paint_top_window("", c, 0);
627 else
628 #endif
629 if (mode_fn->get_title != NULL) {
630 paint_top_window(mode_fn->get_title(screen.buf,screen.buf_size), c, 0);
631 #ifndef NCMPC_MINI
632 welcome = FALSE;
633 #endif
634 } else
635 paint_top_window("", c, 0);
637 /* update the main window */
638 if (mode_fn->update != NULL)
639 mode_fn->update(c);
641 /* update progress window */
642 paint_progress_window(c);
644 /* update status window */
645 paint_status_window(c);
647 /* move the cursor to the origin */
648 wmove(screen.main_window.w, 0, 0);
649 wnoutrefresh(screen.main_window.w);
651 /* tell curses to update */
652 doupdate();
653 }
655 void
656 screen_idle(mpdclient_t *c)
657 {
658 if (c->song && seek_id == c->song->id &&
659 (screen.last_cmd == CMD_SEEK_FORWARD ||
660 screen.last_cmd == CMD_SEEK_BACKWARD))
661 mpdclient_cmd_seek(c, seek_id, seek_target_time);
663 screen.last_cmd = CMD_NONE;
664 seek_id = -1;
665 }
667 #ifdef HAVE_GETMOUSE
668 int
669 screen_get_mouse_event(mpdclient_t *c, unsigned long *bstate, int *row)
670 {
671 MEVENT event;
673 /* retreive the mouse event from ncurses */
674 getmouse(&event);
675 /* calculate the selected row in the list window */
676 *row = event.y - screen.top_window.rows;
677 /* copy button state bits */
678 *bstate = event.bstate;
679 /* if button 2 was pressed switch screen */
680 if (event.bstate & BUTTON2_CLICKED) {
681 screen_cmd(c, CMD_SCREEN_NEXT);
682 return 1;
683 }
685 return 0;
686 }
687 #endif
689 static int
690 screen_client_cmd(mpdclient_t *c, command_t cmd)
691 {
692 if (c->connection == NULL || c->status == NULL)
693 return 0;
695 switch(cmd) {
696 /*
697 case CMD_PLAY:
698 mpdclient_cmd_play(c, MPD_PLAY_AT_BEGINNING);
699 break;
700 */
701 case CMD_PAUSE:
702 mpdclient_cmd_pause(c, !IS_PAUSED(c->status->state));
703 break;
704 case CMD_STOP:
705 mpdclient_cmd_stop(c);
706 break;
707 case CMD_CROP:
708 mpdclient_cmd_crop(c);
709 break;
710 case CMD_SEEK_FORWARD:
711 if (!IS_STOPPED(c->status->state)) {
712 if (c->song && seek_id != c->song->id) {
713 seek_id = c->song->id;
714 seek_target_time = c->status->elapsedTime;
715 }
716 seek_target_time+=options.seek_time;
717 if (seek_target_time < c->status->totalTime)
718 break;
719 seek_target_time = c->status->totalTime;
720 /* seek_target_time=0; */
721 }
722 break;
723 /* fall through... */
724 case CMD_TRACK_NEXT:
725 if (!IS_STOPPED(c->status->state))
726 mpdclient_cmd_next(c);
727 break;
728 case CMD_SEEK_BACKWARD:
729 if (!IS_STOPPED(c->status->state)) {
730 if (seek_id != c->song->id) {
731 seek_id = c->song->id;
732 seek_target_time = c->status->elapsedTime;
733 }
734 seek_target_time-=options.seek_time;
735 if (seek_target_time < 0)
736 seek_target_time=0;
737 }
738 break;
739 case CMD_TRACK_PREVIOUS:
740 if (!IS_STOPPED(c->status->state))
741 mpdclient_cmd_prev(c);
742 break;
743 case CMD_SHUFFLE:
744 if (mpdclient_cmd_shuffle(c) == 0)
745 screen_status_message(_("Shuffled playlist"));
746 break;
747 case CMD_CLEAR:
748 if (mpdclient_cmd_clear(c) == 0)
749 screen_status_message(_("Cleared playlist"));
750 break;
751 case CMD_REPEAT:
752 mpdclient_cmd_repeat(c, !c->status->repeat);
753 break;
754 case CMD_RANDOM:
755 mpdclient_cmd_random(c, !c->status->random);
756 break;
757 case CMD_CROSSFADE:
758 if (c->status->crossfade)
759 mpdclient_cmd_crossfade(c, 0);
760 else
761 mpdclient_cmd_crossfade(c, options.crossfade_time);
762 break;
763 case CMD_DB_UPDATE:
764 if (!c->status->updatingDb) {
765 if( mpdclient_cmd_db_update(c,NULL)==0 )
766 screen_status_printf(_("Database update started"));
767 } else
768 screen_status_printf(_("Database update running..."));
769 break;
770 case CMD_VOLUME_UP:
771 if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume<100 )
772 mpdclient_cmd_volume(c, ++c->status->volume);
773 break;
774 case CMD_VOLUME_DOWN:
775 if( c->status->volume!=MPD_STATUS_NO_VOLUME && c->status->volume>0 )
776 mpdclient_cmd_volume(c, --c->status->volume);
777 break;
779 default:
780 return 0;
781 }
783 return 1;
784 }
786 void
787 screen_cmd(mpdclient_t *c, command_t cmd)
788 {
789 screen.last_cmd = cmd;
790 #ifndef NCMPC_MINI
791 welcome = FALSE;
792 #endif
794 if (mode_fn->cmd != NULL && mode_fn->cmd(c, cmd))
795 return;
797 if (screen_client_cmd(c, cmd))
798 return;
800 switch(cmd) {
801 case CMD_TOGGLE_FIND_WRAP:
802 options.find_wrap = !options.find_wrap;
803 screen_status_printf(options.find_wrap ?
804 _("Find mode: Wrapped") :
805 _("Find mode: Normal"));
806 break;
807 case CMD_TOGGLE_AUTOCENTER:
808 options.auto_center = !options.auto_center;
809 screen_status_printf(options.auto_center ?
810 _("Auto center mode: On") :
811 _("Auto center mode: Off"));
812 break;
813 case CMD_SCREEN_UPDATE:
814 screen_paint(c);
815 break;
816 case CMD_SCREEN_PREVIOUS:
817 screen_next_mode(c, -1);
818 break;
819 case CMD_SCREEN_NEXT:
820 screen_next_mode(c, 1);
821 break;
822 case CMD_SCREEN_PLAY:
823 screen_switch(&screen_playlist, c);
824 break;
825 case CMD_SCREEN_FILE:
826 screen_switch(&screen_browse, c);
827 break;
828 #ifdef ENABLE_HELP_SCREEN
829 case CMD_SCREEN_HELP:
830 screen_switch(&screen_help, c);
831 break;
832 #endif
833 #ifdef ENABLE_SEARCH_SCREEN
834 case CMD_SCREEN_SEARCH:
835 screen_switch(&screen_search, c);
836 break;
837 #endif
838 #ifdef ENABLE_ARTIST_SCREEN
839 case CMD_SCREEN_ARTIST:
840 screen_switch(&screen_artist, c);
841 break;
842 #endif
843 #ifdef ENABLE_KEYDEF_SCREEN
844 case CMD_SCREEN_KEYDEF:
845 screen_switch(&screen_keydef, c);
846 break;
847 #endif
848 #ifdef ENABLE_LYRICS_SCREEN
849 case CMD_SCREEN_LYRICS:
850 screen_switch(&screen_lyrics, c);
851 break;
852 #endif
853 #ifdef ENABLE_OUTPUTS_SCREEN
854 case CMD_SCREEN_OUTPUTS:
855 screen_switch(&screen_outputs, c);
856 break;
857 #endif
858 default:
859 break;
860 }
861 }