Patch #1367059 by _FireFly_: New wps loader. The wps buffer size can be reduced now...
[kugel-rb.git] / apps / gui / gwps.c
blobbd7591fb374b82d1f2c7eebc0e5210b082542169
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"
56 #include "splash.h"
58 #define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
59 #define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps"
60 /* currently only on wps_state is needed */
61 struct wps_state wps_state;
62 struct gui_wps gui_wps[NB_SCREENS];
63 static struct wps_data wps_datas[NB_SCREENS];
65 bool keys_locked = false;
67 /* change the path to the current played track */
68 static void wps_state_update_ctp(const char *path);
70 #ifdef HAVE_LCD_BITMAP
71 static void gui_wps_set_margin(struct gui_wps *gwps)
73 int offset = 0;
74 struct wps_data *data = gwps->data;
75 if(data->wps_sb_tag && data->show_sb_on_wps)
76 offset = STATUSBAR_HEIGHT;
77 else if ( global_settings.statusbar && !data->wps_sb_tag)
78 offset = STATUSBAR_HEIGHT;
79 gwps->display->setmargins(0, offset);
81 #endif
83 long gui_wps_show(void)
85 long button = 0, lastbutton = 0;
86 bool ignore_keyup = true;
87 bool restore = false;
88 long restoretimer = 0; /* timer to delay screen redraw temporarily */
89 bool exit = false;
90 bool update_track = false;
91 unsigned long right_lastclick = 0;
92 unsigned long left_lastclick = 0;
93 int i;
95 wps_state_init();
97 #ifdef HAVE_LCD_CHARCELLS
98 status_set_audio(true);
99 status_set_param(false);
100 #else
101 FOR_NB_SCREENS(i)
103 gui_wps_set_margin(&gui_wps[i]);
105 #endif
107 #ifdef AB_REPEAT_ENABLE
108 ab_repeat_init();
109 ab_reset_markers();
110 #endif
112 if(audio_status() & AUDIO_STATUS_PLAY)
114 wps_state.id3 = audio_current_track();
115 wps_state.nid3 = audio_next_track();
116 if (wps_state.id3) {
117 if (gui_wps_display())
118 return 0;
119 FOR_NB_SCREENS(i)
120 gui_wps_refresh(&gui_wps[i], 0, WPS_REFRESH_ALL);
121 wps_state_update_ctp(wps_state.id3->path);
124 restore = true;
126 while ( 1 )
128 bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false;
130 /* did someone else (i.e power thread) change audio pause mode? */
131 if (wps_state.paused != audio_paused) {
132 wps_state.paused = audio_paused;
134 /* if another thread paused audio, we are probably in car mode,
135 about to shut down. lets save the settings. */
136 if (wps_state.paused) {
137 settings_save();
138 #if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
139 ata_flush();
140 #endif
144 #ifdef HAVE_LCD_BITMAP
145 /* when the peak meter is enabled we want to have a
146 few extra updates to make it look smooth. On the
147 other hand we don't want to waste energy if it
148 isn't displayed */
149 bool pm=false;
150 FOR_NB_SCREENS(i)
152 if(gui_wps[i].data->peak_meter_enabled)
153 pm = true;
156 if (pm) {
157 long next_refresh = current_tick;
158 long next_big_refresh = current_tick + HZ / 5;
159 button = BUTTON_NONE;
160 while (TIME_BEFORE(current_tick, next_big_refresh)) {
161 button = button_get(false);
162 if (button != BUTTON_NONE) {
163 break;
165 peak_meter_peek();
166 sleep(0); /* Sleep until end of current tick. */
168 if (TIME_AFTER(current_tick, next_refresh)) {
169 FOR_NB_SCREENS(i)
171 if(gui_wps[i].data->peak_meter_enabled)
172 gui_wps_refresh(&gui_wps[i], 0,
173 WPS_REFRESH_PEAK_METER);
174 next_refresh += HZ / PEAK_METER_FPS;
181 /* The peak meter is disabled
182 -> no additional screen updates needed */
183 else {
184 button = button_get_w_tmo(HZ/5);
186 #else
187 button = button_get_w_tmo(HZ/5);
188 #endif
190 /* discard first event if it's a button release */
191 if (button && ignore_keyup)
193 ignore_keyup = false;
194 /* Negative events are system events */
195 if (button >= 0 && button & BUTTON_REL )
196 continue;
199 #ifdef WPS_KEYLOCK
200 /* ignore non-remote buttons when keys are locked */
201 if (keys_locked &&
202 ! ((button < 0) ||
203 (button == BUTTON_NONE) ||
204 ((button & WPS_KEYLOCK) == WPS_KEYLOCK) ||
205 (button & BUTTON_REMOTE)
208 if (!(button & BUTTON_REL))
209 display_keylock_text(true);
210 restore = true;
211 button = BUTTON_NONE;
213 #endif
215 /* Exit if audio has stopped playing. This can happen if using the
216 sleep timer with the charger plugged or if starting a recording
217 from F1 */
218 if (!audio_status())
219 exit = true;
221 switch(button)
223 #ifdef WPS_CONTEXT
224 case WPS_CONTEXT:
225 #ifdef WPS_RC_CONTEXT
226 case WPS_RC_CONTEXT:
227 #endif
228 onplay(wps_state.id3->path, TREE_ATTR_MPA, CONTEXT_WPS);
229 #ifdef HAVE_LCD_BITMAP
230 FOR_NB_SCREENS(i)
232 gui_wps_set_margin(&gui_wps[i]);
234 #endif
235 restore = true;
236 break;
237 #endif
239 #ifdef WPS_RC_BROWSE
240 case WPS_RC_BROWSE:
241 #endif
242 case WPS_BROWSE:
243 #ifdef WPS_BROWSE_PRE
244 if ((lastbutton != WPS_BROWSE_PRE)
245 #ifdef WPS_RC_BROWSE_PRE
246 && (lastbutton != WPS_RC_BROWSE_PRE)
247 #endif
249 break;
250 #endif
251 #ifdef HAVE_LCD_CHARCELLS
252 status_set_record(false);
253 status_set_audio(false);
254 #endif
255 FOR_NB_SCREENS(i)
256 gui_wps[i].display->stop_scroll();
258 /* set dir browser to current playing song */
259 if (global_settings.browse_current &&
260 wps_state.current_track_path[0] != '\0')
261 set_current_file(wps_state.current_track_path);
263 return 0;
264 break;
266 /* play/pause */
267 case WPS_PAUSE:
268 #ifdef WPS_PAUSE_PRE
269 if (lastbutton != WPS_PAUSE_PRE)
270 break;
271 #endif
272 #ifdef WPS_RC_PAUSE
273 case WPS_RC_PAUSE:
274 #ifdef WPS_RC_PAUSE_PRE
275 if ((button == WPS_RC_PAUSE) &&
276 (lastbutton != WPS_RC_PAUSE_PRE))
277 break;
278 #endif
279 #endif
280 if ( wps_state.paused )
282 wps_state.paused = false;
283 if ( global_settings.fade_on_stop )
284 fade(1);
285 else
286 audio_resume();
288 else
290 wps_state.paused = true;
291 if ( global_settings.fade_on_stop )
292 fade(0);
293 else
294 audio_pause();
295 settings_save();
296 #if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
297 ata_flush(); /* make sure resume info is saved */
298 #endif
300 break;
302 /* volume up */
303 case WPS_INCVOL:
304 case WPS_INCVOL | BUTTON_REPEAT:
305 #ifdef WPS_RC_INCVOL
306 case WPS_RC_INCVOL:
307 case WPS_RC_INCVOL | BUTTON_REPEAT:
308 #endif
310 global_settings.volume++;
311 bool res = false;
312 setvol();
313 FOR_NB_SCREENS(i)
315 if(update_onvol_change(&gui_wps[i]))
316 res = true;
318 if (res) {
319 restore = true;
320 restoretimer = current_tick + HZ;
323 break;
325 /* volume down */
326 case WPS_DECVOL:
327 case WPS_DECVOL | BUTTON_REPEAT:
328 #ifdef WPS_RC_DECVOL
329 case WPS_RC_DECVOL:
330 case WPS_RC_DECVOL | BUTTON_REPEAT:
331 #endif
333 global_settings.volume--;
334 setvol();
335 bool res = false;
336 FOR_NB_SCREENS(i)
338 if(update_onvol_change(&gui_wps[i]))
339 res = true;
341 if (res) {
342 restore = true;
343 restoretimer = current_tick + HZ;
346 break;
348 /* fast forward / rewind */
349 #ifdef WPS_RC_FFWD
350 case WPS_RC_FFWD:
351 #endif
352 case WPS_FFWD:
353 #ifdef WPS_NEXT_DIR
354 if (current_tick - right_lastclick < HZ)
356 audio_next_dir();
357 right_lastclick = 0;
358 break;
360 #endif
361 #ifdef WPS_RC_REW
362 case WPS_RC_REW:
363 #endif
364 case WPS_REW:
365 #ifdef WPS_PREV_DIR
366 if (current_tick - left_lastclick < HZ)
368 audio_prev_dir();
369 left_lastclick = 0;
370 break;
372 #endif
373 ffwd_rew(button);
374 break;
376 /* prev / restart */
377 case WPS_PREV:
378 #ifdef WPS_PREV_PRE
379 if (lastbutton != WPS_PREV_PRE)
380 break;
381 #endif
382 #ifdef WPS_RC_PREV
383 case WPS_RC_PREV:
384 #ifdef WPS_RC_PREV_PRE
385 if ((button == WPS_RC_PREV) && (lastbutton != WPS_RC_PREV_PRE))
386 break;
387 #endif
388 #endif
389 left_lastclick = current_tick;
390 update_track = true;
392 #ifdef AB_REPEAT_ENABLE
393 /* if we're in A/B repeat mode and the current position
394 is past the A marker, jump back to the A marker... */
395 if ( ab_repeat_mode_enabled()
396 && ab_after_A_marker(wps_state.id3->elapsed) )
398 ab_jump_to_A_marker();
399 break;
401 /* ...otherwise, do it normally */
402 #endif
404 if (!wps_state.id3 || (wps_state.id3->elapsed < 3*1000)) {
405 audio_prev();
407 else {
408 if (!wps_state.paused)
409 audio_pause();
411 audio_ff_rewind(0);
413 if (!wps_state.paused)
414 audio_resume();
416 break;
418 #ifdef WPS_NEXT_DIR
419 #ifdef WPS_RC_NEXT_DIR
420 case WPS_RC_NEXT_DIR:
421 #endif
422 case WPS_NEXT_DIR:
423 audio_next_dir();
424 break;
425 #endif
426 #ifdef WPS_PREV_DIR
427 #ifdef WPS_RC_PREV_DIR
428 case WPS_RC_PREV_DIR:
429 #endif
430 case WPS_PREV_DIR:
431 audio_prev_dir();
432 break;
433 #endif
435 /* next */
436 case WPS_NEXT:
437 #ifdef WPS_NEXT_PRE
438 if (lastbutton != WPS_NEXT_PRE)
439 break;
440 #endif
441 #ifdef WPS_RC_NEXT
442 case WPS_RC_NEXT:
443 #ifdef WPS_RC_NEXT_PRE
444 if ((button == WPS_RC_NEXT) && (lastbutton != WPS_RC_NEXT_PRE))
445 break;
446 #endif
447 #endif
448 right_lastclick = current_tick;
449 update_track = true;
451 #ifdef AB_REPEAT_ENABLE
452 /* if we're in A/B repeat mode and the current position is
453 before the A marker, jump to the A marker... */
454 if ( ab_repeat_mode_enabled()
455 && ab_before_A_marker(wps_state.id3->elapsed) )
457 ab_jump_to_A_marker();
458 break;
460 /* ...otherwise, do it normally */
461 #endif
463 audio_next();
464 break;
466 #ifdef WPS_MENU
467 /* menu key functions */
468 case WPS_MENU:
469 #ifdef WPS_MENU_PRE
470 if (lastbutton != WPS_MENU_PRE)
471 break;
472 #endif
473 #ifdef WPS_RC_MENU
474 case WPS_RC_MENU:
475 #ifdef WPS_RC_MENU_PRE
476 if ((button == WPS_RC_MENU) && (lastbutton != WPS_RC_MENU_PRE))
477 break;
478 #endif
479 #endif
480 FOR_NB_SCREENS(i)
481 gui_wps[i].display->stop_scroll();
483 if (main_menu())
484 return true;
485 #ifdef HAVE_LCD_BITMAP
486 FOR_NB_SCREENS(i)
488 gui_wps_set_margin(&gui_wps[i]);
490 #endif
491 restore = true;
492 break;
493 #endif /* WPS_MENU */
495 #ifdef WPS_KEYLOCK
496 /* key lock */
497 case WPS_KEYLOCK:
498 case WPS_KEYLOCK | BUTTON_REPEAT:
499 keys_locked = !keys_locked;
500 display_keylock_text(keys_locked);
501 restore = true;
502 waitfor_nokey();
503 break;
504 #endif
506 #if (CONFIG_KEYPAD == RECORDER_PAD) || (CONFIG_KEYPAD == IRIVER_H100_PAD) \
507 || (CONFIG_KEYPAD == IRIVER_H300_PAD)
508 /* play settings */
509 case WPS_QUICK:
510 #ifdef WPS_RC_QUICK
511 case WPS_RC_QUICK:
512 #endif
513 if (quick_screen_quick(button))
514 return SYS_USB_CONNECTED;
515 #ifdef HAVE_LCD_BITMAP
516 FOR_NB_SCREENS(i)
518 gui_wps_set_margin(&gui_wps[i]);
520 #endif
521 restore = true;
522 lastbutton = 0;
523 break;
525 /* screen settings */
526 #ifdef BUTTON_F3
527 case BUTTON_F3:
528 if (quick_screen_f3(button))
529 return SYS_USB_CONNECTED;
530 restore = true;
531 break;
532 #endif
534 /* pitch screen */
535 #if CONFIG_KEYPAD == RECORDER_PAD || CONFIG_KEYPAD == IRIVER_H100_PAD \
536 || CONFIG_KEYPAD == IRIVER_H300_PAD
537 case BUTTON_ON | BUTTON_UP:
538 case BUTTON_ON | BUTTON_DOWN:
539 if (2 == pitch_screen())
540 return SYS_USB_CONNECTED;
541 restore = true;
542 break;
543 #endif
544 #endif
546 #ifdef AB_REPEAT_ENABLE
548 #ifdef WPS_AB_SET_A_MARKER
549 /* set A marker for A-B repeat */
550 case WPS_AB_SET_A_MARKER:
551 if (ab_repeat_mode_enabled())
552 ab_set_A_marker(wps_state.id3->elapsed);
553 break;
554 #endif
556 #ifdef WPS_AB_SET_B_MARKER
557 /* set B marker for A-B repeat and jump to A */
558 case WPS_AB_SET_B_MARKER:
559 if (ab_repeat_mode_enabled())
561 ab_set_B_marker(wps_state.id3->elapsed);
562 ab_jump_to_A_marker();
563 update_track = true;
565 break;
566 #endif
568 #ifdef WPS_AB_RESET_AB_MARKERS
569 /* reset A&B markers */
570 case WPS_AB_RESET_AB_MARKERS:
571 if (ab_repeat_mode_enabled())
573 ab_reset_markers();
574 update_track = true;
576 break;
577 #endif
579 #endif /* AB_REPEAT_ENABLE */
581 /* stop and exit wps */
582 #ifdef WPS_EXIT
583 case WPS_EXIT:
584 # ifdef WPS_EXIT_PRE
585 if (lastbutton != WPS_EXIT_PRE)
586 break;
587 # endif
588 exit = true;
589 #ifdef WPS_RC_EXIT
590 case WPS_RC_EXIT:
591 #ifdef WPS_RC_EXIT_PRE
592 if (lastbutton != WPS_RC_EXIT_PRE)
593 break;
594 #endif
595 exit = true;
596 #endif
597 break;
598 #endif
600 #ifdef WPS_ID3
601 case WPS_ID3:
602 browse_id3();
603 restore = true;
604 break;
605 #endif
607 case BUTTON_NONE: /* Timeout */
608 update_track = true;
609 break;
611 case SYS_POWEROFF:
612 bookmark_autobookmark();
613 default_event_handler(SYS_POWEROFF);
614 break;
616 default:
617 if(default_event_handler(button) == SYS_USB_CONNECTED)
618 return SYS_USB_CONNECTED;
619 update_track = true;
620 break;
623 if (update_track)
625 bool update_failed = false;
626 FOR_NB_SCREENS(i)
628 if(update(&gui_wps[i]))
629 update_failed = true;
631 if (update_failed)
633 /* set dir browser to current playing song */
634 if (global_settings.browse_current &&
635 wps_state.current_track_path[0] != '\0')
636 set_current_file(wps_state.current_track_path);
638 return 0;
640 update_track = false;
643 if (exit) {
644 #ifdef HAVE_LCD_CHARCELLS
645 status_set_record(false);
646 status_set_audio(false);
647 #endif
648 if (global_settings.fade_on_stop)
649 fade(0);
651 FOR_NB_SCREENS(i)
652 gui_wps[i].display->stop_scroll();
653 bookmark_autobookmark();
654 audio_stop();
655 #ifdef AB_REPEAT_ENABLE
656 ab_reset_markers();
657 #endif
659 /* Keys can be locked when exiting, so either unlock here
660 or implement key locking in tree.c too */
661 keys_locked=false;
663 /* set dir browser to current playing song */
664 if (global_settings.browse_current &&
665 wps_state.current_track_path[0] != '\0')
666 set_current_file(wps_state.current_track_path);
668 return 0;
671 if ( button )
672 ata_spin();
674 if (restore &&
675 ((restoretimer == 0) ||
676 (restoretimer < current_tick)))
678 restore = false;
679 restoretimer = 0;
680 if (gui_wps_display())
682 /* set dir browser to current playing song */
683 if (global_settings.browse_current &&
684 wps_state.current_track_path[0] != '\0')
685 set_current_file(wps_state.current_track_path);
687 return 0;
690 if (wps_state.id3){
691 FOR_NB_SCREENS(i)
692 gui_wps_refresh(&gui_wps[i], 0, WPS_REFRESH_NON_STATIC);
695 if (button != BUTTON_NONE)
696 lastbutton = button;
698 return 0; /* unreachable - just to reduce compiler warnings */
701 /* needs checking if needed end*/
703 /* wps_data*/
704 /* initial setup of wps_data */
705 void wps_data_init(struct wps_data *wps_data)
707 int i;
708 #ifdef HAVE_LCD_BITMAP
709 for (i = 0; i < MAX_IMAGES; i++) {
710 wps_data->img[i].loaded = false;
711 wps_data->img[i].display = false;
712 wps_data->img[i].always_display = false;
714 wps_data->wps_sb_tag = false;
715 wps_data->show_sb_on_wps = false;
716 #else /* HAVE_LCD_CHARCELLS */
717 for(i = 0; i < 8; i++)
718 wps_data->wps_progress_pat[i] = 0;
719 wps_data->full_line_progressbar = 0;
720 #endif
721 wps_data->format_buffer[0] = '\0';
722 wps_data->wps_loaded = false;
723 wps_data->peak_meter_enabled = false;
726 #ifdef HAVE_LCD_BITMAP
727 /* Clear the WPS image cache */
728 static void wps_clear(struct wps_data *data )
730 int i;
731 /* set images to unloaded and not displayed */
732 for (i = 0; i < MAX_IMAGES; i++) {
733 data->img[i].loaded = false;
734 data->img[i].display = false;
735 data->img[i].always_display = false;
737 data->wps_sb_tag = false;
738 data->show_sb_on_wps = false;
740 #else
741 #define wps_clear(a)
742 #endif
744 static void wps_reset(struct wps_data *data)
746 data->wps_loaded = false;
747 memset(&data->format_buffer, 0, sizeof data->format_buffer);
748 wps_clear(data);
751 /* to setup up the wps-data from a format-buffer (isfile = false)
752 from a (wps-)file (isfile = true)*/
753 bool wps_data_load(struct wps_data *wps_data,
754 const char *buf,
755 bool isfile,
756 bool display)
758 int i, s;
759 int fd;
761 if(!wps_data || !buf)
762 return false;
764 if(!isfile)
766 wps_clear(wps_data);
767 strncpy(wps_data->format_buffer, buf, sizeof(wps_data->format_buffer));
768 wps_data->format_buffer[sizeof(wps_data->format_buffer) - 1] = 0;
769 gui_wps_format(wps_data);
770 return true;
772 else
775 * Hardcode loading WPS_DEFAULTCFG to cause a reset ideally this
776 * wants to be a virtual file. Feel free to modify dirbrowse()
777 * if you're feeling brave.
779 if (! strcmp(buf, WPS_DEFAULTCFG) )
781 wps_reset(wps_data);
782 global_settings.wps_file[0] = 0;
783 return false;
786 #ifdef HAVE_REMOTE_LCD
787 if (! strcmp(buf, RWPS_DEFAULTCFG) )
789 wps_reset(wps_data);
790 global_settings.rwps_file[0] = 0;
791 return false;
793 #endif
795 size_t bmpdirlen;
796 char *bmpdir = strrchr(buf, '.');
797 bmpdirlen = bmpdir - buf;
799 fd = open(buf, O_RDONLY);
801 if (fd >= 0)
803 unsigned int start = 0;
805 wps_reset(wps_data);
806 #ifdef HAVE_LCD_BITMAP
807 wps_data->img_buf_ptr = wps_data->img_buf; /* where in image buffer */
809 wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
810 #endif
811 while( ( read_line(fd, &wps_data->format_buffer[start],
812 sizeof(wps_data->format_buffer)-start) ) > 0 )
814 if(!wps_data_preload_tags(wps_data,
815 &wps_data->format_buffer[start],
816 buf, bmpdirlen))
818 start += strlen(&wps_data->format_buffer[start]);
820 if (start < sizeof(wps_data->format_buffer) - 1)
822 wps_data->format_buffer[start++] = '\n';
823 wps_data->format_buffer[start] = 0;
828 if (start > 0)
830 gui_wps_format(wps_data);
833 close(fd);
835 if ( display ) {
836 bool any_defined_line;
837 int z;
838 FOR_NB_SCREENS(z)
839 screens[z].clear_display();
840 #ifdef HAVE_LCD_BITMAP
841 FOR_NB_SCREENS(z)
842 screens[z].setmargins(0,0);
843 #endif
844 for (s=0; s<WPS_MAX_SUBLINES; s++)
846 any_defined_line = false;
847 for (i=0; i<WPS_MAX_LINES; i++)
849 if (wps_data->format_lines[i][s] &&
850 wps_data->format_lines[i][s][0])
852 FOR_NB_SCREENS(z)
853 screens[z].puts(0, i,
854 wps_data->
855 format_lines[i][s]);
856 any_defined_line = true;
858 else
860 FOR_NB_SCREENS(z)
861 screens[z].puts(0, i, " ");
864 if (any_defined_line)
866 #ifdef HAVE_LCD_BITMAP
867 FOR_NB_SCREENS(z)
868 screens[z].update();
869 #endif
870 sleep(HZ/2);
874 wps_data->wps_loaded = true;
876 return start > 0;
880 return false;
883 /* wps_data end */
885 /* wps_state */
887 void wps_state_init(void)
889 wps_state.ff_rewind = false;
890 wps_state.paused = false;
891 wps_state.id3 = NULL;
892 wps_state.nid3 = NULL;
893 wps_state.current_track_path[0] = '\0';
896 #if 0
897 /* these are obviously not used? */
899 void wps_state_update_ff_rew(bool ff_rew)
901 wps_state.ff_rewind = ff_rew;
904 void wps_state_update_paused(bool paused)
906 wps_state.paused = paused;
908 void wps_state_update_id3_nid3(struct mp3entry *id3, struct mp3entry *nid3)
910 wps_state.id3 = id3;
911 wps_state.nid3 = nid3;
913 #endif
915 static void wps_state_update_ctp(const char *path)
917 memcpy(wps_state.current_track_path, path,
918 sizeof(wps_state.current_track_path));
920 /* wps_state end*/
922 /* initial setup of a wps */
923 void gui_wps_init(struct gui_wps *gui_wps)
925 gui_wps->data = NULL;
926 gui_wps->display = NULL;
927 gui_wps->statusbar = NULL;
928 /* Currently no seperate wps_state needed/possible
929 so use the only aviable ( "global" ) one */
930 gui_wps->state = &wps_state;
933 /* connects a wps with a format-description of the displayed content */
934 void gui_wps_set_data(struct gui_wps *gui_wps, struct wps_data *data)
936 gui_wps->data = data;
939 /* connects a wps with a screen */
940 void gui_wps_set_disp(struct gui_wps *gui_wps, struct screen *display)
942 gui_wps->display = display;
945 void gui_wps_set_statusbar(struct gui_wps *gui_wps, struct gui_statusbar *statusbar)
947 gui_wps->statusbar = statusbar;
949 /* gui_wps end */
951 void gui_sync_wps_screen_init(void)
953 int i;
954 FOR_NB_SCREENS(i)
955 gui_wps_set_disp(&gui_wps[i], &screens[i]);
958 void gui_sync_wps_init(void)
960 int i;
961 FOR_NB_SCREENS(i)
963 wps_data_init(&wps_datas[i]);
964 gui_wps_init(&gui_wps[i]);
965 gui_wps_set_data(&gui_wps[i], &wps_datas[i]);
966 gui_wps_set_statusbar(&gui_wps[i], &statusbars.statusbars[i]);