Added 'Party Mode': Unstoppable playback
[kugel-rb.git] / apps / gui / gwps.c
blob2ec1c4dcc703df94ea43a3773e789c6f0e5fc357
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Jerome Kuptz
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
23 #include "system.h"
24 #include "file.h"
25 #include "lcd.h"
26 #include "font.h"
27 #include "backlight.h"
28 #include "button.h"
29 #include "kernel.h"
30 #include "tree.h"
31 #include "debug.h"
32 #include "sprintf.h"
33 #include "settings.h"
34 #include "gwps.h"
35 #include "gwps-common.h"
36 #include "audio.h"
37 #include "usb.h"
38 #include "status.h"
39 #include "main_menu.h"
40 #include "ata.h"
41 #include "screens.h"
42 #include "playlist.h"
43 #ifdef HAVE_LCD_BITMAP
44 #include "icons.h"
45 #include "peakmeter.h"
46 #endif
47 #include "action.h"
48 #include "lang.h"
49 #include "bookmark.h"
50 #include "misc.h"
51 #include "sound.h"
52 #include "onplay.h"
53 #include "abrepeat.h"
54 #include "playback.h"
55 #include "splash.h"
56 #ifdef HAVE_LCD_COLOR
57 #include "backdrop.h"
58 #endif
60 #define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
61 #define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps"
62 /* currently only on wps_state is needed */
63 struct wps_state wps_state;
64 struct gui_wps gui_wps[NB_SCREENS];
65 static struct wps_data wps_datas[NB_SCREENS];
67 bool keys_locked = false;
69 /* change the path to the current played track */
70 static void wps_state_update_ctp(const char *path);
72 #ifdef HAVE_LCD_BITMAP
73 static void gui_wps_set_margin(struct gui_wps *gwps)
75 int offset = 0;
76 struct wps_data *data = gwps->data;
77 if(data->wps_sb_tag && data->show_sb_on_wps)
78 offset = STATUSBAR_HEIGHT;
79 else if ( global_settings.statusbar && !data->wps_sb_tag)
80 offset = STATUSBAR_HEIGHT;
81 gwps->display->setmargins(0, offset);
83 #endif
85 long gui_wps_show(void)
87 long button = 0, lastbutton = 0;
88 bool ignore_keyup = true;
89 bool restore = false;
90 long restoretimer = 0; /* timer to delay screen redraw temporarily */
91 bool exit = false;
92 bool update_track = false;
93 unsigned long right_lastclick = 0;
94 unsigned long left_lastclick = 0;
95 int i;
97 wps_state_init();
99 #ifdef HAVE_LCD_CHARCELLS
100 status_set_audio(true);
101 status_set_param(false);
102 #else
103 FOR_NB_SCREENS(i)
105 gui_wps_set_margin(&gui_wps[i]);
107 #ifdef HAVE_LCD_COLOR
108 gui_wps[SCREEN_MAIN].data->old_backdrop = lcd_get_backdrop();
109 if (gui_wps[SCREEN_MAIN].data->has_backdrop) {
110 lcd_set_backdrop(&wps_backdrop[0][0]);
112 #endif
113 #endif
115 #ifdef AB_REPEAT_ENABLE
116 ab_repeat_init();
117 ab_reset_markers();
118 #endif
120 if(audio_status() & AUDIO_STATUS_PLAY)
122 wps_state.id3 = audio_current_track();
123 wps_state.nid3 = audio_next_track();
124 if (wps_state.id3) {
125 if (gui_wps_display())
126 return 0;
127 FOR_NB_SCREENS(i)
128 gui_wps_refresh(&gui_wps[i], 0, WPS_REFRESH_ALL);
129 wps_state_update_ctp(wps_state.id3->path);
132 restore = true;
134 while ( 1 )
136 bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false;
138 /* did someone else (i.e power thread) change audio pause mode? */
139 if (wps_state.paused != audio_paused) {
140 wps_state.paused = audio_paused;
142 /* if another thread paused audio, we are probably in car mode,
143 about to shut down. lets save the settings. */
144 if (wps_state.paused) {
145 settings_save();
146 #if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
147 ata_flush();
148 #endif
152 #ifdef HAVE_LCD_BITMAP
153 /* when the peak meter is enabled we want to have a
154 few extra updates to make it look smooth. On the
155 other hand we don't want to waste energy if it
156 isn't displayed */
157 bool pm=false;
158 FOR_NB_SCREENS(i)
160 if(gui_wps[i].data->peak_meter_enabled)
161 pm = true;
164 if (pm) {
165 long next_refresh = current_tick;
166 long next_big_refresh = current_tick + HZ / 5;
167 button = BUTTON_NONE;
168 while (TIME_BEFORE(current_tick, next_big_refresh)) {
169 button = button_get(false);
170 if (button != BUTTON_NONE) {
171 break;
173 peak_meter_peek();
174 sleep(0); /* Sleep until end of current tick. */
176 if (TIME_AFTER(current_tick, next_refresh)) {
177 FOR_NB_SCREENS(i)
179 if(gui_wps[i].data->peak_meter_enabled)
180 gui_wps_refresh(&gui_wps[i], 0,
181 WPS_REFRESH_PEAK_METER);
182 next_refresh += HZ / PEAK_METER_FPS;
189 /* The peak meter is disabled
190 -> no additional screen updates needed */
191 else {
192 button = button_get_w_tmo(HZ/5);
194 #else
195 button = button_get_w_tmo(HZ/5);
196 #endif
198 /* discard first event if it's a button release */
199 if (button && ignore_keyup)
201 ignore_keyup = false;
202 /* Negative events are system events */
203 if (button >= 0 && button & BUTTON_REL )
204 continue;
207 #ifdef WPS_KEYLOCK
208 /* ignore non-remote buttons when keys are locked */
209 if (keys_locked &&
210 ! ((button < 0) ||
211 (button == BUTTON_NONE) ||
212 ((button & WPS_KEYLOCK) == WPS_KEYLOCK) ||
213 (button & BUTTON_REMOTE)
216 if (!(button & BUTTON_REL))
217 display_keylock_text(true);
218 restore = true;
219 button = BUTTON_NONE;
221 #endif
223 /* Exit if audio has stopped playing. This can happen if using the
224 sleep timer with the charger plugged or if starting a recording
225 from F1 */
226 if (!audio_status())
227 exit = true;
229 switch(button)
231 #ifdef WPS_CONTEXT
232 case WPS_CONTEXT:
233 #ifdef WPS_RC_CONTEXT
234 case WPS_RC_CONTEXT:
235 #endif
236 #ifdef HAVE_LCD_COLOR
237 lcd_set_backdrop(gui_wps[SCREEN_MAIN].data->old_backdrop);
238 #endif
239 onplay(wps_state.id3->path, TREE_ATTR_MPA, CONTEXT_WPS);
240 #ifdef HAVE_LCD_COLOR
241 if (gui_wps[SCREEN_MAIN].data->has_backdrop)
242 lcd_set_backdrop(&wps_backdrop[0][0]);
243 #endif
244 #ifdef HAVE_LCD_BITMAP
245 FOR_NB_SCREENS(i)
247 gui_wps_set_margin(&gui_wps[i]);
249 #endif
250 restore = true;
251 break;
252 #endif
254 #ifdef WPS_RC_BROWSE
255 case WPS_RC_BROWSE:
256 #endif
257 case WPS_BROWSE:
258 #ifdef WPS_BROWSE_PRE
259 if ((lastbutton != WPS_BROWSE_PRE)
260 #ifdef WPS_RC_BROWSE_PRE
261 && (lastbutton != WPS_RC_BROWSE_PRE)
262 #endif
264 break;
265 #endif
266 #ifdef HAVE_LCD_CHARCELLS
267 status_set_record(false);
268 status_set_audio(false);
269 #endif
270 FOR_NB_SCREENS(i)
271 gui_wps[i].display->stop_scroll();
273 /* set dir browser to current playing song */
274 if (global_settings.browse_current &&
275 wps_state.current_track_path[0] != '\0')
276 set_current_file(wps_state.current_track_path);
278 return 0;
279 break;
281 /* play/pause */
282 case WPS_PAUSE:
283 #ifdef WPS_PAUSE_PRE
284 if (lastbutton != WPS_PAUSE_PRE)
285 break;
286 #endif
287 #ifdef WPS_RC_PAUSE
288 case WPS_RC_PAUSE:
289 if (global_settings.party_mode)
290 break;
291 #ifdef WPS_RC_PAUSE_PRE
292 if ((button == WPS_RC_PAUSE) &&
293 (lastbutton != WPS_RC_PAUSE_PRE))
294 break;
295 #endif
296 #endif
297 if ( wps_state.paused )
299 wps_state.paused = false;
300 if ( global_settings.fade_on_stop )
301 fade(1);
302 else
303 audio_resume();
305 else
307 wps_state.paused = true;
308 if ( global_settings.fade_on_stop )
309 fade(0);
310 else
311 audio_pause();
312 settings_save();
313 #if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
314 ata_flush(); /* make sure resume info is saved */
315 #endif
317 break;
319 /* volume up */
320 case WPS_INCVOL:
321 case WPS_INCVOL | BUTTON_REPEAT:
322 #ifdef WPS_RC_INCVOL
323 case WPS_RC_INCVOL:
324 case WPS_RC_INCVOL | BUTTON_REPEAT:
325 #endif
327 global_settings.volume++;
328 bool res = false;
329 setvol();
330 FOR_NB_SCREENS(i)
332 if(update_onvol_change(&gui_wps[i]))
333 res = true;
335 if (res) {
336 restore = true;
337 restoretimer = current_tick + HZ;
340 break;
342 /* volume down */
343 case WPS_DECVOL:
344 case WPS_DECVOL | BUTTON_REPEAT:
345 #ifdef WPS_RC_DECVOL
346 case WPS_RC_DECVOL:
347 case WPS_RC_DECVOL | BUTTON_REPEAT:
348 #endif
350 global_settings.volume--;
351 setvol();
352 bool res = false;
353 FOR_NB_SCREENS(i)
355 if(update_onvol_change(&gui_wps[i]))
356 res = true;
358 if (res) {
359 restore = true;
360 restoretimer = current_tick + HZ;
363 break;
365 /* fast forward / rewind */
366 #ifdef WPS_RC_FFWD
367 case WPS_RC_FFWD:
368 #endif
369 case WPS_FFWD:
370 if (global_settings.party_mode)
371 break;
372 #ifdef WPS_NEXT_DIR
373 if (current_tick - right_lastclick < HZ)
375 audio_next_dir();
376 right_lastclick = 0;
377 break;
379 #endif
380 #ifdef WPS_RC_REW
381 case WPS_RC_REW:
382 #endif
383 case WPS_REW:
384 if (global_settings.party_mode)
385 break;
386 #ifdef WPS_PREV_DIR
387 if (current_tick - left_lastclick < HZ)
389 audio_prev_dir();
390 left_lastclick = 0;
391 break;
393 #endif
394 ffwd_rew(button);
395 break;
397 /* prev / restart */
398 case WPS_PREV:
399 #ifdef WPS_PREV_PRE
400 if (lastbutton != WPS_PREV_PRE)
401 break;
402 #endif
403 #ifdef WPS_RC_PREV
404 case WPS_RC_PREV:
405 if (global_settings.party_mode)
406 break;
407 #ifdef WPS_RC_PREV_PRE
408 if ((button == WPS_RC_PREV) && (lastbutton != WPS_RC_PREV_PRE))
409 break;
410 #endif
411 #endif
412 left_lastclick = current_tick;
413 update_track = true;
415 #ifdef AB_REPEAT_ENABLE
416 /* if we're in A/B repeat mode and the current position
417 is past the A marker, jump back to the A marker... */
418 if ( ab_repeat_mode_enabled() )
420 if ( ab_after_A_marker(wps_state.id3->elapsed) )
422 ab_jump_to_A_marker();
423 break;
424 #if (AB_REPEAT_ENABLE == 2)
425 } else {
426 ab_reset_markers();
427 #endif
430 /* ...otherwise, do it normally */
431 #endif
433 if (!wps_state.id3 || (wps_state.id3->elapsed < 3*1000)) {
434 audio_prev();
436 else {
437 if (!wps_state.paused)
438 audio_pause();
440 audio_ff_rewind(0);
442 if (!wps_state.paused)
443 audio_resume();
445 break;
447 #ifdef WPS_NEXT_DIR
448 #ifdef WPS_RC_NEXT_DIR
449 case WPS_RC_NEXT_DIR:
450 #endif
451 case WPS_NEXT_DIR:
452 if (global_settings.party_mode)
453 break;
454 #if defined(AB_REPEAT_ENABLE) && defined(WPS_AB_SHARE_DIR_BUTTONS)
455 if (ab_repeat_mode_enabled())
457 ab_set_B_marker(wps_state.id3->elapsed);
458 ab_jump_to_A_marker();
459 update_track = true;
461 else
462 #endif
464 audio_next_dir();
466 break;
467 #endif
468 #ifdef WPS_PREV_DIR
469 #ifdef WPS_RC_PREV_DIR
470 case WPS_RC_PREV_DIR:
471 #endif
472 case WPS_PREV_DIR:
473 if (global_settings.party_mode)
474 break;
475 #if defined(AB_REPEAT_ENABLE) && defined(WPS_AB_SHARE_DIR_BUTTONS)
476 if (ab_repeat_mode_enabled())
477 ab_set_A_marker(wps_state.id3->elapsed);
478 else
479 #endif
481 audio_prev_dir();
483 break;
484 #endif
486 /* next */
487 case WPS_NEXT:
488 #ifdef WPS_NEXT_PRE
489 if (lastbutton != WPS_NEXT_PRE)
490 break;
491 #endif
492 #ifdef WPS_RC_NEXT
493 case WPS_RC_NEXT:
494 if (global_settings.party_mode)
495 break;
496 #ifdef WPS_RC_NEXT_PRE
497 if ((button == WPS_RC_NEXT) && (lastbutton != WPS_RC_NEXT_PRE))
498 break;
499 #endif
500 #endif
501 right_lastclick = current_tick;
502 update_track = true;
504 #ifdef AB_REPEAT_ENABLE
505 /* if we're in A/B repeat mode and the current position is
506 before the A marker, jump to the A marker... */
507 if ( ab_repeat_mode_enabled() )
509 if ( ab_before_A_marker(wps_state.id3->elapsed) )
511 ab_jump_to_A_marker();
512 break;
513 #if (AB_REPEAT_ENABLE == 2)
514 } else {
515 ab_reset_markers();
516 #endif
519 /* ...otherwise, do it normally */
520 #endif
522 audio_next();
523 break;
525 #ifdef WPS_MENU
526 /* menu key functions */
527 case WPS_MENU:
528 #ifdef WPS_MENU_PRE
529 if (lastbutton != WPS_MENU_PRE)
530 break;
531 #endif
532 #ifdef WPS_RC_MENU
533 case WPS_RC_MENU:
534 #ifdef WPS_RC_MENU_PRE
535 if ((button == WPS_RC_MENU) && (lastbutton != WPS_RC_MENU_PRE))
536 break;
537 #endif
538 #endif
539 FOR_NB_SCREENS(i)
540 gui_wps[i].display->stop_scroll();
542 #ifdef HAVE_LCD_COLOR
543 lcd_set_backdrop(gui_wps[SCREEN_MAIN].data->old_backdrop);
544 #endif
545 if (main_menu())
546 return true;
547 #ifdef HAVE_LCD_COLOR
548 if (gui_wps[SCREEN_MAIN].data->has_backdrop)
549 lcd_set_backdrop(&wps_backdrop[0][0]);
550 #endif
551 #ifdef HAVE_LCD_BITMAP
552 FOR_NB_SCREENS(i)
554 gui_wps_set_margin(&gui_wps[i]);
556 #endif
557 restore = true;
558 break;
559 #endif /* WPS_MENU */
561 #ifdef WPS_KEYLOCK
562 /* key lock */
563 case WPS_KEYLOCK:
564 case WPS_KEYLOCK | BUTTON_REPEAT:
565 keys_locked = !keys_locked;
566 display_keylock_text(keys_locked);
567 restore = true;
568 waitfor_nokey();
569 break;
570 #endif
572 #if (CONFIG_KEYPAD == RECORDER_PAD) || (CONFIG_KEYPAD == IRIVER_H100_PAD) \
573 || (CONFIG_KEYPAD == IRIVER_H300_PAD)
574 /* play settings */
575 case WPS_QUICK:
576 #ifdef WPS_RC_QUICK
577 case WPS_RC_QUICK:
578 #endif
579 #ifdef HAVE_LCD_COLOR
580 lcd_set_backdrop(gui_wps[SCREEN_MAIN].data->old_backdrop);
581 #endif
582 if (quick_screen_quick(button))
583 return SYS_USB_CONNECTED;
584 #ifdef HAVE_LCD_COLOR
585 if (gui_wps[SCREEN_MAIN].data->has_backdrop)
586 lcd_set_backdrop(&wps_backdrop[0][0]);
587 #endif
588 #ifdef HAVE_LCD_BITMAP
589 FOR_NB_SCREENS(i)
591 gui_wps_set_margin(&gui_wps[i]);
593 #endif
594 restore = true;
595 lastbutton = 0;
596 break;
598 /* screen settings */
599 #ifdef BUTTON_F3
600 case BUTTON_F3:
601 if (quick_screen_f3(button))
602 return SYS_USB_CONNECTED;
603 restore = true;
604 break;
605 #endif
607 /* pitch screen */
608 #if CONFIG_KEYPAD == RECORDER_PAD || CONFIG_KEYPAD == IRIVER_H100_PAD \
609 || CONFIG_KEYPAD == IRIVER_H300_PAD
610 case BUTTON_ON | BUTTON_UP:
611 case BUTTON_ON | BUTTON_DOWN:
612 #if CONFIG_KEYPAD == IRIVER_H100_PAD || CONFIG_KEYPAD == IRIVER_H300_PAD
613 case BUTTON_ON | BUTTON_OFF:
614 #endif
615 #ifdef HAVE_LCD_COLOR
616 lcd_set_backdrop(gui_wps[SCREEN_MAIN].data->old_backdrop);
617 #endif
618 if (2 == pitch_screen())
619 return SYS_USB_CONNECTED;
620 #ifdef HAVE_LCD_COLOR
621 if (gui_wps[SCREEN_MAIN].data->has_backdrop)
622 lcd_set_backdrop(&wps_backdrop[0][0]);
623 #endif
624 restore = true;
625 break;
626 #endif
627 #endif
629 #ifdef AB_REPEAT_ENABLE
631 #ifdef WPS_AB_SINGLE
632 case WPS_AB_SINGLE:
633 #ifdef WPS_AB_SINGLE_PRE
634 if (lastbutton != WPS_AB_SINGLE_PRE)
635 break;
636 #endif
637 /* If we are using the menu option to enable ab_repeat mode, don't do anything
638 * when it's disabled */
639 #if (AB_REPEAT_ENABLE == 1)
640 if (!ab_repeat_mode_enabled())
641 break;
642 #endif
643 if (ab_A_marker_set()) {
644 update_track = true;
645 if (ab_B_marker_set()) {
646 ab_reset_markers();
647 break;
649 ab_set_B_marker(wps_state.id3->elapsed);
650 ab_jump_to_A_marker();
651 break;
653 ab_set_A_marker(wps_state.id3->elapsed);
654 break;
655 #endif
658 #ifdef WPS_AB_SET_A_MARKER
659 /* set A marker for A-B repeat */
660 case WPS_AB_SET_A_MARKER:
661 if (ab_repeat_mode_enabled())
662 ab_set_A_marker(wps_state.id3->elapsed);
663 break;
664 #endif
666 #ifdef WPS_AB_SET_B_MARKER
667 /* set B marker for A-B repeat and jump to A */
668 case WPS_AB_SET_B_MARKER:
669 if (ab_repeat_mode_enabled())
671 ab_set_B_marker(wps_state.id3->elapsed);
672 ab_jump_to_A_marker();
673 update_track = true;
675 break;
676 #endif
678 #ifdef WPS_AB_RESET_AB_MARKERS
679 /* reset A&B markers */
680 case WPS_AB_RESET_AB_MARKERS:
681 if (ab_repeat_mode_enabled())
683 ab_reset_markers();
684 update_track = true;
686 break;
687 #endif
689 #endif /* AB_REPEAT_ENABLE */
691 /* stop and exit wps */
692 #ifdef WPS_EXIT
693 case WPS_EXIT:
694 # ifdef WPS_EXIT_PRE
695 if (lastbutton != WPS_EXIT_PRE)
696 break;
697 # endif
698 if (global_settings.party_mode)
699 break;
700 exit = true;
701 #ifdef WPS_RC_EXIT
702 case WPS_RC_EXIT:
703 #ifdef WPS_RC_EXIT_PRE
704 if (lastbutton != WPS_RC_EXIT_PRE)
705 break;
706 #endif
707 if (global_settings.party_mode)
708 break;
709 exit = true;
710 #endif
711 break;
712 #endif
714 #ifdef WPS_ID3
715 case WPS_ID3:
716 browse_id3();
717 restore = true;
718 break;
719 #endif
721 case BUTTON_NONE: /* Timeout */
722 update_track = true;
723 break;
725 case SYS_POWEROFF:
726 bookmark_autobookmark();
727 default_event_handler(SYS_POWEROFF);
728 break;
730 default:
731 if(default_event_handler(button) == SYS_USB_CONNECTED)
732 return SYS_USB_CONNECTED;
733 update_track = true;
734 break;
737 if (update_track)
739 bool update_failed = false;
740 FOR_NB_SCREENS(i)
742 if(update(&gui_wps[i]))
743 update_failed = true;
745 if (update_failed)
747 /* set dir browser to current playing song */
748 if (global_settings.browse_current &&
749 wps_state.current_track_path[0] != '\0')
750 set_current_file(wps_state.current_track_path);
752 return 0;
754 update_track = false;
757 if (exit) {
758 #ifdef HAVE_LCD_CHARCELLS
759 status_set_record(false);
760 status_set_audio(false);
761 #endif
762 if (global_settings.fade_on_stop)
763 fade(0);
765 FOR_NB_SCREENS(i)
766 gui_wps[i].display->stop_scroll();
767 bookmark_autobookmark();
768 audio_stop();
769 #ifdef AB_REPEAT_ENABLE
770 ab_reset_markers();
771 #endif
773 /* Keys can be locked when exiting, so either unlock here
774 or implement key locking in tree.c too */
775 keys_locked=false;
777 /* set dir browser to current playing song */
778 if (global_settings.browse_current &&
779 wps_state.current_track_path[0] != '\0')
780 set_current_file(wps_state.current_track_path);
782 return 0;
785 if ( button )
786 ata_spin();
788 if (restore &&
789 ((restoretimer == 0) ||
790 (restoretimer < current_tick)))
792 restore = false;
793 restoretimer = 0;
794 if (gui_wps_display())
796 /* set dir browser to current playing song */
797 if (global_settings.browse_current &&
798 wps_state.current_track_path[0] != '\0')
799 set_current_file(wps_state.current_track_path);
801 return 0;
804 if (wps_state.id3){
805 FOR_NB_SCREENS(i)
806 gui_wps_refresh(&gui_wps[i], 0, WPS_REFRESH_NON_STATIC);
809 if (button != BUTTON_NONE)
810 lastbutton = button;
812 return 0; /* unreachable - just to reduce compiler warnings */
815 /* needs checking if needed end*/
817 /* wps_data*/
818 #ifdef HAVE_LCD_BITMAP
819 /* Clear the WPS image cache */
820 static void wps_clear(struct wps_data *data )
822 int i;
823 /* set images to unloaded and not displayed */
824 for (i = 0; i < MAX_IMAGES; i++) {
825 data->img[i].loaded = false;
826 data->img[i].display = false;
827 data->img[i].always_display = false;
829 data->wps_sb_tag = false;
830 data->show_sb_on_wps = false;
831 data->progressbar.have_bitmap_pb=false;
833 #else
834 #define wps_clear(a)
835 #endif
837 /* initial setup of wps_data */
838 void wps_data_init(struct wps_data *wps_data)
840 #ifdef HAVE_LCD_BITMAP
841 wps_clear(wps_data);
842 #else /* HAVE_LCD_CHARCELLS */
844 int i;
845 for(i = 0; i < 8; i++)
846 wps_data->wps_progress_pat[i] = 0;
847 wps_data->full_line_progressbar = 0;
849 #endif
850 wps_data->format_buffer[0] = '\0';
851 wps_data->wps_loaded = false;
852 wps_data->peak_meter_enabled = false;
853 #ifdef HAVE_LCD_COLOR
854 wps_data->has_backdrop = false;
855 #endif
858 static void wps_reset(struct wps_data *data)
860 data->wps_loaded = false;
861 memset(&data->format_buffer, 0, sizeof data->format_buffer);
862 wps_data_init(data);
865 /* to setup up the wps-data from a format-buffer (isfile = false)
866 from a (wps-)file (isfile = true)*/
867 bool wps_data_load(struct wps_data *wps_data,
868 const char *buf,
869 bool isfile)
871 int fd;
873 if(!wps_data || !buf)
874 return false;
876 if(!isfile)
878 wps_clear(wps_data);
879 strncpy(wps_data->format_buffer, buf, sizeof(wps_data->format_buffer));
880 wps_data->format_buffer[sizeof(wps_data->format_buffer) - 1] = 0;
881 gui_wps_format(wps_data);
882 return true;
884 else
887 * Hardcode loading WPS_DEFAULTCFG to cause a reset ideally this
888 * wants to be a virtual file. Feel free to modify dirbrowse()
889 * if you're feeling brave.
891 if (! strcmp(buf, WPS_DEFAULTCFG) )
893 wps_reset(wps_data);
894 global_settings.wps_file[0] = 0;
895 return false;
898 #ifdef HAVE_REMOTE_LCD
899 if (! strcmp(buf, RWPS_DEFAULTCFG) )
901 wps_reset(wps_data);
902 global_settings.rwps_file[0] = 0;
903 return false;
905 #endif
907 size_t bmpdirlen;
908 char *bmpdir = strrchr(buf, '.');
909 bmpdirlen = bmpdir - buf;
911 fd = open(buf, O_RDONLY);
913 if (fd >= 0)
915 unsigned int start = 0;
917 wps_reset(wps_data);
918 #ifdef HAVE_LCD_BITMAP
919 wps_data->img_buf_ptr = wps_data->img_buf; /* where in image buffer */
921 wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
922 #endif
923 while( ( read_line(fd, &wps_data->format_buffer[start],
924 sizeof(wps_data->format_buffer)-start) ) > 0 )
926 if(!wps_data_preload_tags(wps_data,
927 &wps_data->format_buffer[start],
928 buf, bmpdirlen))
930 start += strlen(&wps_data->format_buffer[start]);
932 if (start < sizeof(wps_data->format_buffer) - 1)
934 wps_data->format_buffer[start++] = '\n';
935 wps_data->format_buffer[start] = 0;
940 if (start > 0)
942 gui_wps_format(wps_data);
945 close(fd);
947 wps_data->wps_loaded = true;
949 return start > 0;
953 return false;
956 /* wps_data end */
958 /* wps_state */
960 void wps_state_init(void)
962 wps_state.ff_rewind = false;
963 wps_state.paused = false;
964 wps_state.id3 = NULL;
965 wps_state.nid3 = NULL;
966 wps_state.current_track_path[0] = '\0';
969 #if 0
970 /* these are obviously not used? */
972 void wps_state_update_ff_rew(bool ff_rew)
974 wps_state.ff_rewind = ff_rew;
977 void wps_state_update_paused(bool paused)
979 wps_state.paused = paused;
981 void wps_state_update_id3_nid3(struct mp3entry *id3, struct mp3entry *nid3)
983 wps_state.id3 = id3;
984 wps_state.nid3 = nid3;
986 #endif
988 static void wps_state_update_ctp(const char *path)
990 memcpy(wps_state.current_track_path, path,
991 sizeof(wps_state.current_track_path));
993 /* wps_state end*/
995 /* initial setup of a wps */
996 void gui_wps_init(struct gui_wps *gui_wps)
998 gui_wps->data = NULL;
999 gui_wps->display = NULL;
1000 gui_wps->statusbar = NULL;
1001 /* Currently no seperate wps_state needed/possible
1002 so use the only aviable ( "global" ) one */
1003 gui_wps->state = &wps_state;
1006 /* connects a wps with a format-description of the displayed content */
1007 void gui_wps_set_data(struct gui_wps *gui_wps, struct wps_data *data)
1009 gui_wps->data = data;
1012 /* connects a wps with a screen */
1013 void gui_wps_set_disp(struct gui_wps *gui_wps, struct screen *display)
1015 gui_wps->display = display;
1018 void gui_wps_set_statusbar(struct gui_wps *gui_wps, struct gui_statusbar *statusbar)
1020 gui_wps->statusbar = statusbar;
1022 /* gui_wps end */
1024 void gui_sync_wps_screen_init(void)
1026 int i;
1027 FOR_NB_SCREENS(i)
1028 gui_wps_set_disp(&gui_wps[i], &screens[i]);
1031 void gui_sync_wps_init(void)
1033 int i;
1034 FOR_NB_SCREENS(i)
1036 wps_data_init(&wps_datas[i]);
1037 gui_wps_init(&gui_wps[i]);
1038 gui_wps_set_data(&gui_wps[i], &wps_datas[i]);
1039 gui_wps_set_statusbar(&gui_wps[i], &statusbars.statusbars[i]);