summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2010-09-14 11:56:50 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2010-09-14 11:56:50 +0000
commit9928e3418f67fe6d2f82292ddbddcf56ae20b8f6 (patch)
tree397b13a537a476feb77b7d052250b98055924aec
parent0928cdf074c8991f470fa0d96e6d4f828998b643 (diff)
downloadrockbox-9928e3418f67fe6d2f82292ddbddcf56ae20b8f6.tar.gz
rockbox-9928e3418f67fe6d2f82292ddbddcf56ae20b8f6.zip
Another major skin backend update/hopefully bugfix:
Skins are now more self contained in the skin manager which in the future might allow on demand skin loading (i.e smaller skin buffers) Skin backdrops are also managed more intelegently (fixes a bug where you can get a crazy backdrop loaded if a .sbs fails to load) the rockbox_default rescue theme is now called rockbox_failsafe to better express what it actually is. This commit hopefully/maybe fixes the heavily reported data aborts, so please check if you are getting them git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28073 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/SOURCES2
-rw-r--r--apps/gui/skin_engine/skin_backdrops.c164
-rw-r--r--apps/gui/skin_engine/skin_display.c31
-rw-r--r--apps/gui/skin_engine/skin_engine.h24
-rw-r--r--apps/gui/skin_engine/skin_parser.c42
-rw-r--r--apps/gui/skin_engine/skin_render.c3
-rw-r--r--apps/gui/skin_engine/skin_tokens.c16
-rw-r--r--apps/gui/skin_engine/wps_internals.h20
-rw-r--r--apps/gui/statusbar-skinned.c120
-rw-r--r--apps/gui/statusbar-skinned.h5
-rw-r--r--apps/gui/theme_settings.c117
-rw-r--r--apps/gui/viewport.c3
-rw-r--r--apps/gui/wps.c271
-rw-r--r--apps/main.c4
-rw-r--r--apps/menus/theme_menu.c3
-rw-r--r--apps/onplay.c7
-rw-r--r--apps/radio/radio.c6
-rw-r--r--apps/radio/radio.h4
-rw-r--r--apps/radio/radio_skin.c73
-rwxr-xr-xtools/buildzip.pl43
-rw-r--r--wps/WPSLIST17
21 files changed, 415 insertions, 560 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 9bc8859746..2a13b6245d 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -89,12 +89,12 @@ gui/statusbar.c
89#ifdef HAVE_LCD_BITMAP 89#ifdef HAVE_LCD_BITMAP
90gui/statusbar-skinned.c 90gui/statusbar-skinned.c
91#endif 91#endif
92gui/theme_settings.c
93gui/yesno.c 92gui/yesno.c
94gui/viewport.c 93gui/viewport.c
95 94
96gui/skin_engine/skin_backdrops.c 95gui/skin_engine/skin_backdrops.c
97gui/skin_engine/skin_display.c 96gui/skin_engine/skin_display.c
97gui/skin_engine/skin_engine.c
98#ifdef HAVE_LCD_BITMAP 98#ifdef HAVE_LCD_BITMAP
99gui/skin_engine/skin_fonts.c 99gui/skin_engine/skin_fonts.c
100#endif 100#endif
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c
index 9ceee0cd05..f5b72a9652 100644
--- a/apps/gui/skin_engine/skin_backdrops.c
+++ b/apps/gui/skin_engine/skin_backdrops.c
@@ -30,88 +30,164 @@
30 30
31#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 31#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
32 32
33#define NB_BDROPS SKINNABLE_SCREENS_COUNT*NB_SCREENS
33static struct skin_backdrop { 34static struct skin_backdrop {
34 char name[MAX_PATH]; 35 char name[MAX_PATH];
35 char *buffer; 36 char *buffer;
36 enum screen_type screen; 37 enum screen_type screen;
37} backdrops[SKINNABLE_SCREENS_COUNT*NB_SCREENS]; 38} backdrops[NB_BDROPS];
39
40#define NB_BDROPS SKINNABLE_SCREENS_COUNT*NB_SCREENS
38 41
39void skin_backdrop_init(void) 42void skin_backdrop_init(void)
40{ 43{
41 int i; 44 int i;
42 for(i=0;i<SKINNABLE_SCREENS_COUNT*NB_SCREENS;i++) 45 for (i=0; i<NB_BDROPS; i++)
43 { 46 {
44 backdrops[i].name[0] = '\0'; 47 backdrops[i].name[0] = '\0';
45 backdrops[i].buffer = NULL; 48 backdrops[i].buffer = NULL;
46 } 49 }
47} 50}
48 51
49/* load a backdrop into the skin buffer. 52int skin_backdrop_assign(char* backdrop, char *bmpdir,
50 * reuse buffers if the file is already loaded */ 53 enum screen_type screen)
51char* skin_backdrop_load(char* backdrop, char *bmpdir, enum screen_type screen)
52{ 54{
53 int i;
54 struct skin_backdrop *bdrop = NULL;
55 char dir[MAX_PATH]; 55 char dir[MAX_PATH];
56 char filename[MAX_PATH]; 56 char filename[MAX_PATH];
57 size_t buf_size; 57 int i, free = -1;
58 bool loaded = false; 58 if (!backdrop)
59#if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1) 59 return -1;
60 if (screen == SCREEN_REMOTE)
61 buf_size = REMOTE_LCD_BACKDROP_BYTES;
62 else
63#endif
64 buf_size = LCD_BACKDROP_BYTES;
65
66 if (backdrop[0] == '-') 60 if (backdrop[0] == '-')
67 { 61 {
62 filename[0] = '-';
63 filename[1] = '\0';
64 filename[2] = '\0'; /* we check this later to see if we actually have an
65 image to load. != '\0' means display the image */
68#if NB_SCREENS > 1 66#if NB_SCREENS > 1
69 if (screen == SCREEN_REMOTE) 67 if (screen == SCREEN_REMOTE)
70 { 68 {
71 return NULL; /* remotes don't have a backdrop setting (yet!) */ 69 filename[0] = '\0';
72 } 70 }
73 else
74#endif 71#endif
75 {
76 char settings_bdrop = global_settings.backdrop_file[0];
77 if (settings_bdrop == '\0' || settings_bdrop == '-')
78 {
79 return NULL; /* backdrop setting not set */
80 }
81 snprintf(filename, sizeof(filename), "%s/%s.bmp",
82 get_user_file_path(BACKDROP_DIR, 0, dir, sizeof(dir)),
83 global_settings.backdrop_file);
84 }
85 } 72 }
86 else 73 else
87 { 74 {
88 const char *bd_dir = get_user_file_path(bmpdir, 0, dir, sizeof(dir)); 75 const char *bd_dir = get_user_file_path(bmpdir, 0, dir, sizeof(dir));
89 get_image_filename(backdrop, bd_dir, filename, sizeof(filename)); 76 get_image_filename(backdrop, bd_dir, filename, sizeof(filename));
90 } 77 }
91 78 for (i=0; i<NB_BDROPS; i++)
92 for(i=0;i<SKINNABLE_SCREENS_COUNT*NB_SCREENS;i++)
93 { 79 {
80 if (!backdrops[i].name[0] && free < 0)
81 free = i;
94 if (!strcmp(backdrops[i].name, filename) && backdrops[i].screen == screen) 82 if (!strcmp(backdrops[i].name, filename) && backdrops[i].screen == screen)
95 { 83 {
96 return backdrops[i].buffer; 84 break;
85 }
86 }
87 if (i < NB_BDROPS)
88 return i;
89 else if (free >= 0)
90 {
91 strlcpy(backdrops[free].name, filename,
92 sizeof (backdrops[free].name));
93 backdrops[free].buffer = NULL;
94 backdrops[free].screen = screen;
95 return free;
96 }
97 return -1;
98}
99
100bool skin_backdrops_preload(void)
101{
102 bool retval = true;
103 int i;
104 char *filename;
105 for (i=0; i<NB_BDROPS; i++)
106 {
107 if (backdrops[i].name[0] && !backdrops[i].buffer)
108 {
109 size_t buf_size;
110 bool loaded = false;
111 enum screen_type screen = backdrops[i].screen;
112#if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
113 if (screen == SCREEN_REMOTE)
114 buf_size = REMOTE_LCD_BACKDROP_BYTES;
115 else
116#endif
117 buf_size = LCD_BACKDROP_BYTES;
118
119 filename = backdrops[i].name;
120 if (screen == SCREEN_MAIN && global_settings.backdrop_file[0] &&
121 global_settings.backdrop_file[0] != '-' && filename[0] == '-')
122 {
123 char dir[MAX_PATH];
124 char* temp = filename+2; /* slightly hacky to get a buffer */
125 size_t size = sizeof(backdrops[i].name) - 2;
126 snprintf(temp, size, "%s/%s.bmp",
127 get_user_file_path(BACKDROP_DIR, 0, dir, sizeof(dir)),
128 global_settings.backdrop_file);
129 filename = temp;
130 }
131 if (*filename && *filename != '-')
132 {
133 backdrops[i].buffer = (char*)skin_buffer_alloc(buf_size);
134 loaded = backdrops[i].buffer &&
135 screens[screen].backdrop_load(filename, backdrops[i].buffer);
136 if (!loaded)
137 retval = false;
138 }
139 if (backdrops[i].name[0] == '-' && loaded)
140 backdrops[i].name[2] = '.';
97 } 141 }
98 else if (!bdrop && backdrops[i].buffer == NULL) 142 }
143 return retval;
144}
145
146void skin_backdrop_show(int backdrop_id)
147{
148 if (backdrop_id < 0)
149 return;
150 enum screen_type screen = backdrops[backdrop_id].screen;
151 if (backdrops[backdrop_id].name[0] == '-' &&
152 backdrops[backdrop_id].name[2] == '\0')
153 return;
154 if (backdrops[backdrop_id].buffer)
155 screens[screen].backdrop_show(backdrops[backdrop_id].buffer);
156}
157
158void skin_backdrop_unload(int backdrop_id)
159{
160 backdrops[backdrop_id].buffer = NULL;
161}
162
163void skin_backdrop_load_setting(void)
164{
165 int i;
166 char filename[MAX_PATH], dir[MAX_PATH];
167 for(i=0;i<SKINNABLE_SCREENS_COUNT*NB_SCREENS;i++)
168 {
169 if (backdrops[i].name[0] == '-' && backdrops[i].screen == SCREEN_MAIN)
99 { 170 {
100 bdrop = &backdrops[i]; 171 if (global_settings.backdrop_file[0] &&
172 global_settings.backdrop_file[0] != '-')
173 {
174 if (!backdrops[i].buffer)
175 backdrops[i].buffer = (char*)skin_buffer_alloc(LCD_BACKDROP_BYTES);
176 snprintf(filename, sizeof filename, "%s/%s.bmp",
177 get_user_file_path(BACKDROP_DIR, 0, dir, sizeof(dir)),
178 global_settings.backdrop_file);
179 bool loaded = backdrops[i].buffer &&
180 screens[SCREEN_MAIN].backdrop_load(filename,
181 backdrops[i].buffer);
182 backdrops[i].name[2] = loaded ? '.' : '\0';
183 return;
184 }
185 else
186 backdrops[i].name[2] = '\0';
101 } 187 }
102 } 188 }
103 if (!bdrop)
104 return NULL; /* too many backdrops loaded */
105
106 bdrop->buffer = (char*)skin_buffer_alloc(buf_size);
107 if (!bdrop->buffer)
108 return NULL;
109 loaded = screens[screen].backdrop_load(filename, bdrop->buffer);
110 bdrop->screen = screen;
111 strlcpy(bdrop->name, filename, sizeof(bdrop->name));
112
113 return loaded ? bdrop->buffer : NULL;
114} 189}
190
115#else 191#else
116 192
117void skin_backdrop_init(void) 193void skin_backdrop_init(void)
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index d76b57976d..f001640cde 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -74,18 +74,21 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode);
74 74
75/* update a skinned screen, update_type is WPS_REFRESH_* values. 75/* update a skinned screen, update_type is WPS_REFRESH_* values.
76 * Usually it should only be WPS_REFRESH_NON_STATIC 76 * Usually it should only be WPS_REFRESH_NON_STATIC
77 * A full update will be done if required (state.do_full_update == true) 77 * A full update will be done if required (skin_do_full_update() == true)
78 */ 78 */
79void skin_update(struct gui_wps *gwps, unsigned int update_type) 79void skin_update(enum skinnable_screens skin, enum screen_type screen,
80 unsigned int update_type)
80{ 81{
82 struct gui_wps *gwps = skin_get_gwps(skin, screen);
81 /* This maybe shouldnt be here, 83 /* This maybe shouldnt be here,
82 * This is also safe for skined screen which dont use the id3 */ 84 * This is also safe for skined screen which dont use the id3 */
83 struct mp3entry *id3 = gwps->state->id3; 85 struct mp3entry *id3 = skin_get_global_state()->id3;
84 bool cuesheet_update = (id3 != NULL ? cuesheet_subtrack_changed(id3) : false); 86 bool cuesheet_update = (id3 != NULL ? cuesheet_subtrack_changed(id3) : false);
85 gwps->sync_data->do_full_update |= cuesheet_update; 87 if (cuesheet_update)
88 skin_request_full_update(skin);
86 89
87 skin_render(gwps, gwps->sync_data->do_full_update ? 90 skin_render(gwps, skin_do_full_update(skin, screen) ?
88 SKIN_REFRESH_ALL : update_type); 91 SKIN_REFRESH_ALL : update_type);
89} 92}
90 93
91#ifdef HAVE_LCD_BITMAP 94#ifdef HAVE_LCD_BITMAP
@@ -126,7 +129,7 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
126{ 129{
127 struct screen *display = gwps->display; 130 struct screen *display = gwps->display;
128 struct viewport *vp = pb->vp; 131 struct viewport *vp = pb->vp;
129 struct wps_state *state = gwps->state; 132 struct wps_state *state = skin_get_global_state();
130 struct mp3entry *id3 = state->id3; 133 struct mp3entry *id3 = state->id3;
131 int y = pb->y, height = pb->height; 134 int y = pb->y, height = pb->height;
132 unsigned long length, end; 135 unsigned long length, end;
@@ -729,11 +732,10 @@ bool skin_has_sbs(enum screen_type screen, struct wps_data *data)
729 732
730/* do the button loop as often as required for the peak meters to update 733/* do the button loop as often as required for the peak meters to update
731 * with a good refresh rate. 734 * with a good refresh rate.
732 * gwps is really gwps[NB_SCREENS]! don't wrap this if FOR_NB_SCREENS()
733 */ 735 */
734int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout) 736int skin_wait_for_action(enum skinnable_screens skin, int context, int timeout)
735{ 737{
736 (void)gwps; /* silence charcell warning */ 738 (void)skin; /* silence charcell warning */
737 int button = ACTION_NONE; 739 int button = ACTION_NONE;
738#ifdef HAVE_LCD_BITMAP 740#ifdef HAVE_LCD_BITMAP
739 int i; 741 int i;
@@ -744,7 +746,7 @@ int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout)
744 bool pm=false; 746 bool pm=false;
745 FOR_NB_SCREENS(i) 747 FOR_NB_SCREENS(i)
746 { 748 {
747 if(gwps[i].data->peak_meter_enabled) 749 if(skin_get_gwps(skin, i)->data->peak_meter_enabled)
748 pm = true; 750 pm = true;
749 } 751 }
750 752
@@ -763,8 +765,8 @@ int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout)
763 if (TIME_AFTER(current_tick, next_refresh)) { 765 if (TIME_AFTER(current_tick, next_refresh)) {
764 FOR_NB_SCREENS(i) 766 FOR_NB_SCREENS(i)
765 { 767 {
766 if(gwps[i].data->peak_meter_enabled) 768 if(skin_get_gwps(skin, i)->data->peak_meter_enabled)
767 skin_update(&gwps[i], SKIN_REFRESH_PEAK_METER); 769 skin_update(skin, i, SKIN_REFRESH_PEAK_METER);
768 next_refresh += HZ / PEAK_METER_FPS; 770 next_refresh += HZ / PEAK_METER_FPS;
769 } 771 }
770 } 772 }
@@ -781,3 +783,6 @@ int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout)
781 } 783 }
782 return button; 784 return button;
783} 785}
786
787
788
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h
index 6beedd90a2..ef4297d0ce 100644
--- a/apps/gui/skin_engine/skin_engine.h
+++ b/apps/gui/skin_engine/skin_engine.h
@@ -73,7 +73,8 @@ void skin_disarm_touchregions(struct wps_data *data);
73#endif 73#endif
74 74
75/* Do a update_type update of the skinned screen */ 75/* Do a update_type update of the skinned screen */
76void skin_update(struct gui_wps *gwps, unsigned int update_type); 76void skin_update(enum skinnable_screens skin, enum screen_type screen,
77 unsigned int update_type);
77 78
78/* 79/*
79 * setup up the skin-data from a format-buffer (isfile = false) 80 * setup up the skin-data from a format-buffer (isfile = false)
@@ -92,13 +93,28 @@ bool skin_has_sbs(enum screen_type screen, struct wps_data *data);
92 * reuse buffers if the file is already loaded */ 93 * reuse buffers if the file is already loaded */
93char* skin_backdrop_load(char* backdrop, char *bmpdir, enum screen_type screen); 94char* skin_backdrop_load(char* backdrop, char *bmpdir, enum screen_type screen);
94void skin_backdrop_init(void); 95void skin_backdrop_init(void);
95 96int skin_backdrop_assign(char* backdrop, char *bmpdir,
97 enum screen_type screen);
98bool skin_backdrops_preload(void);
99void skin_backdrop_show(int backdrop_id);
100void skin_backdrop_load_setting(void);
101void skin_backdrop_unload(int backdrop_id);
96 102
97/* do the button loop as often as required for the peak meters to update 103/* do the button loop as often as required for the peak meters to update
98 * with a good refresh rate. 104 * with a good refresh rate.
99 * gwps is really gwps[NB_SCREENS]! don't wrap this in FOR_NB_SCREENS() 105 * gwps is really gwps[NB_SCREENS]! don't wrap this in FOR_NB_SCREENS()
100 */ 106 */
101int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout); 107int skin_wait_for_action(enum skinnable_screens skin, int context, int timeout);
102#endif 108
109void skin_load(enum skinnable_screens skin, enum screen_type screen,
110 const char *buf, bool isfile);
111struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen);
112struct wps_state *skin_get_global_state(void);
113void gui_sync_skin_init(void);
114
115
116bool skin_do_full_update(enum skinnable_screens skin, enum screen_type screen);
117void skin_request_full_update(enum skinnable_screens skin);
103 118
119#endif /* !PLUGIN */
104#endif 120#endif
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index a6d4c798dc..2534bf9104 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -447,26 +447,27 @@ static int parse_image_special(struct skin_element *element,
447{ 447{
448 (void)wps_data; /* kill warning */ 448 (void)wps_data; /* kill warning */
449 (void)token; 449 (void)token;
450 bool error = false;
451 450
452#if LCD_DEPTH > 1 451#if LCD_DEPTH > 1
452 char *filename;
453 if (token->type == SKIN_TOKEN_IMAGE_BACKDROP) 453 if (token->type == SKIN_TOKEN_IMAGE_BACKDROP)
454 { 454 {
455 char *filename = element->params[0].data.text; 455 if (isdefault(&element->params[0]))
456 /* format: %X|filename.bmp| or %Xd */
457 if (!strcmp(filename, "d"))
458 { 456 {
459 wps_data->backdrop = NULL; 457 filename = "-";
460 return 0;
461 } 458 }
462 else if (!error) 459 else
463 { 460 {
464 wps_data->backdrop = filename; 461 filename = element->params[0].data.text;
462 /* format: %X(filename.bmp) or %X(d) */
463 if (!strcmp(filename, "d"))
464 filename = NULL;
465 } 465 }
466 wps_data->backdrop = filename;
466 } 467 }
467#endif 468#endif
468 /* Skip the rest of the line */ 469
469 return error ? WPS_ERROR_INVALID_PARAM : 0; 470 return 0;
470} 471}
471#endif 472#endif
472 473
@@ -1010,6 +1011,8 @@ static void skin_data_reset(struct wps_data *wps_data)
1010 wps_data->progressbars = NULL; 1011 wps_data->progressbars = NULL;
1011#endif 1012#endif
1012#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 1013#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
1014 if (wps_data->backdrop_id >= 0)
1015 skin_backdrop_unload(wps_data->backdrop_id);
1013 wps_data->backdrop = NULL; 1016 wps_data->backdrop = NULL;
1014#endif 1017#endif
1015#ifdef HAVE_TOUCHSCREEN 1018#ifdef HAVE_TOUCHSCREEN
@@ -1128,23 +1131,7 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
1128 } 1131 }
1129 1132
1130#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 1133#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
1131 /* Backdrop load scheme: 1134 wps_data->backdrop_id = skin_backdrop_assign(wps_data->backdrop, bmpdir, curr_screen);
1132 * 1) %X|filename|
1133 * 2) load the backdrop from settings
1134 */
1135 if (wps_data->backdrop)
1136 {
1137 if (screens[curr_screen].depth == 1)
1138 {
1139 wps_data->backdrop = NULL;
1140 return retval;
1141 }
1142 bool needed = wps_data->backdrop[0] != '-';
1143 wps_data->backdrop = skin_backdrop_load(wps_data->backdrop,
1144 bmpdir, curr_screen);
1145 if (!wps_data->backdrop && needed)
1146 retval = false;
1147 }
1148#endif /* has backdrop support */ 1135#endif /* has backdrop support */
1149 return retval; 1136 return retval;
1150} 1137}
@@ -1575,6 +1562,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
1575 } 1562 }
1576#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 1563#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
1577 wps_data->backdrop = "-"; 1564 wps_data->backdrop = "-";
1565 wps_data->backdrop_id = -1;
1578#endif 1566#endif
1579 /* parse the skin source */ 1567 /* parse the skin source */
1580 skin_buffer_save_position(); 1568 skin_buffer_save_position();
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 9f392f144f..4fbd550c72 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -749,7 +749,8 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
749 else 749 else
750#endif 750#endif
751 { 751 {
752 struct cuesheet *cue = gwps->state->id3 ? gwps->state->id3->cuesheet:NULL; 752 struct cuesheet *cue = skin_get_global_state()->id3 ?
753 skin_get_global_state()->id3->cuesheet : NULL;
753 cur_pos = playlist_get_display_index(); 754 cur_pos = playlist_get_display_index();
754 max = playlist_amount()+1; 755 max = playlist_amount()+1;
755 if (cue) 756 if (cue)
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 3de6630a51..0e98c2d42f 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -515,18 +515,18 @@ const char *get_radio_token(struct wps_token *token, int preset_offset,
515} 515}
516#endif 516#endif
517 517
518static struct mp3entry* get_mp3entry_from_offset(struct gui_wps *gwps, 518static struct mp3entry* get_mp3entry_from_offset(int offset, char **filename)
519 int offset, char **filename)
520{ 519{
521 struct mp3entry* pid3 = NULL; 520 struct mp3entry* pid3 = NULL;
522 struct cuesheet *cue = gwps->state->id3 ? gwps->state->id3->cuesheet:NULL; 521 struct wps_state *state = skin_get_global_state();
522 struct cuesheet *cue = state->id3 ? state->id3->cuesheet : NULL;
523 const char *fname = NULL; 523 const char *fname = NULL;
524 if (cue && cue->curr_track_idx + offset < cue->track_count) 524 if (cue && cue->curr_track_idx + offset < cue->track_count)
525 pid3 = gwps->state->id3; 525 pid3 = state->id3;
526 else if (offset == 0) 526 else if (offset == 0)
527 pid3 = gwps->state->id3; 527 pid3 = state->id3;
528 else if (offset == 1) 528 else if (offset == 1)
529 pid3 = gwps->state->nid3; 529 pid3 = state->nid3;
530 else 530 else
531 { 531 {
532 static char filename_buf[MAX_PATH + 1]; 532 static char filename_buf[MAX_PATH + 1];
@@ -568,7 +568,7 @@ const char *get_token_value(struct gui_wps *gwps,
568 return NULL; 568 return NULL;
569 569
570 struct wps_data *data = gwps->data; 570 struct wps_data *data = gwps->data;
571 struct wps_state *state = gwps->state; 571 struct wps_state *state = skin_get_global_state();
572 struct mp3entry *id3; /* Think very carefully about using this. 572 struct mp3entry *id3; /* Think very carefully about using this.
573 maybe get_id3_token() is the better place? */ 573 maybe get_id3_token() is the better place? */
574 const char *out_text = NULL; 574 const char *out_text = NULL;
@@ -577,7 +577,7 @@ const char *get_token_value(struct gui_wps *gwps,
577 if (!data || !state) 577 if (!data || !state)
578 return NULL; 578 return NULL;
579 579
580 id3 = get_mp3entry_from_offset(gwps, token->next? 1: offset, &filename); 580 id3 = get_mp3entry_from_offset(token->next? 1: offset, &filename);
581 if (id3) 581 if (id3)
582 filename = id3->path; 582 filename = id3->path;
583 583
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index 0767f50279..5c3d953fdb 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -266,7 +266,10 @@ struct wps_data
266 struct skin_token_list *progressbars; 266 struct skin_token_list *progressbars;
267#endif 267#endif
268#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 268#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
269 char *backdrop; 269 struct {
270 char *backdrop;
271 int backdrop_id;
272 };
270#endif 273#endif
271 274
272#ifdef HAVE_TOUCHSCREEN 275#ifdef HAVE_TOUCHSCREEN
@@ -305,18 +308,6 @@ struct wps_state
305 bool is_fading; 308 bool is_fading;
306}; 309};
307 310
308/* Holds data for all screens in a skin. */
309struct wps_sync_data
310{
311 /* suitable for the viewportmanager, possibly only temporary here
312 * needs to be same for all screens! can't be split up for screens
313 * due to what viewportmanager_set_statusbar() accepts
314 * (FIXME?) */
315 int statusbars;
316 /* indicates whether the skin needs a full update for all screens */
317 bool do_full_update;
318};
319
320/* change the ff/rew-status 311/* change the ff/rew-status
321 if ff_rew = true then we are in skipping mode 312 if ff_rew = true then we are in skipping mode
322 else we are in normal mode */ 313 else we are in normal mode */
@@ -334,9 +325,6 @@ struct gui_wps
334{ 325{
335 struct screen *display; 326 struct screen *display;
336 struct wps_data *data; 327 struct wps_data *data;
337 struct wps_state *state;
338 /* must point to the same struct for all screens */
339 struct wps_sync_data *sync_data;
340}; 328};
341 329
342/* gui_wps end */ 330/* gui_wps end */
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index e22ab28f13..2139bd698a 100644
--- a/apps/gui/statusbar-skinned.c
+++ b/apps/gui/statusbar-skinned.c
@@ -40,13 +40,6 @@
40#include "icon.h" 40#include "icon.h"
41#include "option_select.h" 41#include "option_select.h"
42 42
43
44/* currently only one wps_state is needed */
45extern struct wps_state wps_state; /* from wps.c */
46static struct gui_wps sb_skin[NB_SCREENS] = {{ .data = NULL }};
47static struct wps_data sb_skin_data[NB_SCREENS] = {{ .wps_loaded = 0 }};
48static struct wps_sync_data sb_skin_sync_data = { .do_full_update = false };
49
50/* initial setup of wps_data */ 43/* initial setup of wps_data */
51static int update_delay = DEFAULT_UPDATE_DELAY; 44static int update_delay = DEFAULT_UPDATE_DELAY;
52static int set_title_worker(char* title, enum themable_icons icon, 45static int set_title_worker(char* title, enum themable_icons icon,
@@ -102,26 +95,26 @@ static int set_title_worker(char* title, enum themable_icons icon,
102 95
103bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen) 96bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen)
104{ 97{
105 bool retval = set_title_worker(title, icon, &sb_skin_data[screen], 98 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
106 sb_skin_data[screen].tree) > 0; 99 bool retval = data->wps_loaded &&
100 set_title_worker(title, icon, data, data->tree) > 0;
107 return retval; 101 return retval;
108} 102}
109 103
110 104int sb_preproccess(enum screen_type screen, struct wps_data *data)
111void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile)
112{ 105{
113 struct wps_data *data = sb_skin[screen].data; 106 (void)data;
114
115 int success;
116 /* We need to disable the theme here or else viewport_set_defaults() 107 /* We need to disable the theme here or else viewport_set_defaults()
117 * (which is called in the viewport tag parser) will crash because 108 * (which is called in the viewport tag parser) will crash because
118 * the theme is enabled but sb_set_info_vp() isnt set untill after the sbs 109 * the theme is enabled but sb_set_info_vp() isnt set untill after the sbs
119 * is parsed. This only affects the default viewport which is ignored 110 * is parsed. This only affects the default viewport which is ignored
120 * int he sbs anyway */ 111 * int he sbs anyway */
121 viewportmanager_theme_enable(screen, false, NULL); 112 viewportmanager_theme_enable(screen, false, NULL);
122 success = buf && skin_data_load(screen, data, buf, isfile); 113 return 1;
123 114}
124 if (success) 115int sb_postproccess(enum screen_type screen, struct wps_data *data)
116{
117 if (data->wps_loaded)
125 { 118 {
126 /* hide the sb's default viewport because it has nasty effect with stuff 119 /* hide the sb's default viewport because it has nasty effect with stuff
127 * not part of the statusbar, 120 * not part of the statusbar,
@@ -133,18 +126,17 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile)
133 { 126 {
134 if (!next_vp) 127 if (!next_vp)
135 { /* no second viewport, let parsing fail */ 128 { /* no second viewport, let parsing fail */
136 success = false; 129 return 0;
137 } 130 }
138 /* hide this viewport, forever */ 131 /* hide this viewport, forever */
139 vp->hidden_flags = VP_NEVER_VISIBLE; 132 vp->hidden_flags = VP_NEVER_VISIBLE;
140 } 133 }
141 sb_set_info_vp(screen, VP_DEFAULT_LABEL); 134 sb_set_info_vp(screen, VP_DEFAULT_LABEL);
142 } 135 }
143
144 if (!success && isfile)
145 sb_create_from_settings(screen);
146 viewportmanager_theme_undo(screen, false); 136 viewportmanager_theme_undo(screen, false);
137 return 1;
147} 138}
139
148static char *infovp_label[NB_SCREENS]; 140static char *infovp_label[NB_SCREENS];
149static char *oldinfovp_label[NB_SCREENS]; 141static char *oldinfovp_label[NB_SCREENS];
150void sb_set_info_vp(enum screen_type screen, char *label) 142void sb_set_info_vp(enum screen_type screen, char *label)
@@ -154,6 +146,7 @@ void sb_set_info_vp(enum screen_type screen, char *label)
154 146
155struct viewport *sb_skin_get_info_vp(enum screen_type screen) 147struct viewport *sb_skin_get_info_vp(enum screen_type screen)
156{ 148{
149 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
157 if (oldinfovp_label[screen] && 150 if (oldinfovp_label[screen] &&
158 strcmp(oldinfovp_label[screen], infovp_label[screen])) 151 strcmp(oldinfovp_label[screen], infovp_label[screen]))
159 { 152 {
@@ -162,48 +155,26 @@ struct viewport *sb_skin_get_info_vp(enum screen_type screen)
162 viewportmanager_theme_enable(screen, false, NULL); 155 viewportmanager_theme_enable(screen, false, NULL);
163 viewportmanager_theme_undo(screen, true); 156 viewportmanager_theme_undo(screen, true);
164 } 157 }
165 return &find_viewport(infovp_label[screen], true, sb_skin[screen].data)->vp; 158 return &find_viewport(infovp_label[screen], true, data)->vp;
166} 159}
167 160
168#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) 161#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
169char* sb_get_backdrop(enum screen_type screen) 162int sb_get_backdrop(enum screen_type screen)
170{
171 return sb_skin[screen].data->backdrop;
172}
173
174bool sb_set_backdrop(enum screen_type screen, char* filename)
175{ 163{
176 if (!filename) 164 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
177 { 165 if (data->wps_loaded)
178 sb_skin[screen].data->backdrop = NULL; 166 return data->backdrop_id;
179 return true; 167 else
180 } 168 return -1;
181 else if (!sb_skin[screen].data->backdrop)
182 {
183 /* need to make room on the buffer */
184 size_t buf_size;
185#if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
186 if (screen == SCREEN_REMOTE)
187 buf_size = REMOTE_LCD_BACKDROP_BYTES;
188 else
189#endif
190 buf_size = LCD_BACKDROP_BYTES;
191 sb_skin[screen].data->backdrop = (char*)skin_buffer_alloc(buf_size);
192 if (!sb_skin[screen].data->backdrop)
193 return false;
194 }
195
196 if (!screens[screen].backdrop_load(filename, sb_skin[screen].data->backdrop))
197 sb_skin[screen].data->backdrop = NULL;
198 return sb_skin[screen].data->backdrop != NULL;
199} 169}
200 170
201#endif 171#endif
202void sb_skin_update(enum screen_type screen, bool force) 172void sb_skin_update(enum screen_type screen, bool force)
203{ 173{
174 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
204 static long next_update[NB_SCREENS] = {0}; 175 static long next_update[NB_SCREENS] = {0};
205 int i = screen; 176 int i = screen;
206 if (!sb_skin_data[screen].wps_loaded) 177 if (!data->wps_loaded)
207 return; 178 return;
208 if (TIME_AFTER(current_tick, next_update[i]) || force) 179 if (TIME_AFTER(current_tick, next_update[i]) || force)
209 { 180 {
@@ -213,24 +184,9 @@ void sb_skin_update(enum screen_type screen, bool force)
213 if (lcd_active() || (i != SCREEN_MAIN)) 184 if (lcd_active() || (i != SCREEN_MAIN))
214#endif 185#endif
215 { 186 {
216 bool full_update = sb_skin[i].sync_data->do_full_update; 187 bool full_update = skin_do_full_update(CUSTOM_STATUSBAR, screen);
217#if NB_SCREENS > 1 188 skin_update(CUSTOM_STATUSBAR, screen, force ||
218 if (i==SCREEN_MAIN && sb_skin[i].sync_data->do_full_update) 189 full_update ? SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
219 {
220 sb_skin[i].sync_data->do_full_update = false;
221 /* we need to make sure the remote gets a full update
222 * next time it is drawn also. so quick n dirty hack */
223 next_update[SCREEN_REMOTE] = 0;
224 }
225 else if (next_update[SCREEN_REMOTE] == 0)
226 {
227 full_update = true;
228 }
229#else
230 sb_skin[i].sync_data->do_full_update = false;
231#endif
232 skin_update(&sb_skin[i], force || full_update?
233 SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
234 } 190 }
235 next_update[i] = current_tick + update_delay; /* don't update too often */ 191 next_update[i] = current_tick + update_delay; /* don't update too often */
236 } 192 }
@@ -241,7 +197,7 @@ void do_sbs_update_callback(void *param)
241 (void)param; 197 (void)param;
242 /* the WPS handles changing the actual id3 data in the id3 pointers 198 /* the WPS handles changing the actual id3 data in the id3 pointers
243 * we imported, we just want a full update */ 199 * we imported, we just want a full update */
244 sb_skin_sync_data.do_full_update = true; 200 skin_request_full_update(CUSTOM_STATUSBAR);
245 /* force timeout in wps main loop, so that the update is instantly */ 201 /* force timeout in wps main loop, so that the update is instantly */
246 queue_post(&button_queue, BUTTON_NONE, 0); 202 queue_post(&button_queue, BUTTON_NONE, 0);
247} 203}
@@ -257,9 +213,10 @@ void sb_skin_set_update_delay(int delay)
257 * - ui viewport 213 * - ui viewport
258 * - backdrop 214 * - backdrop
259 */ 215 */
260void sb_create_from_settings(enum screen_type screen) 216char* sb_create_from_settings(enum screen_type screen)
261{ 217{
262 char buf[128], *ptr, *ptr2; 218 static char buf[128];
219 char *ptr, *ptr2;
263 int len, remaining = sizeof(buf); 220 int len, remaining = sizeof(buf);
264 int bar_position = statusbar_position(screen); 221 int bar_position = statusbar_position(screen);
265 ptr = buf; 222 ptr = buf;
@@ -329,7 +286,7 @@ void sb_create_from_settings(enum screen_type screen)
329 len = snprintf(ptr, remaining, "%%ax%%Vi(-,0,%d,-,%d,1)\n", 286 len = snprintf(ptr, remaining, "%%ax%%Vi(-,0,%d,-,%d,1)\n",
330 y, height); 287 y, height);
331 } 288 }
332 sb_skin_data_load(screen, buf, false); 289 return buf;
333} 290}
334 291
335void sb_skin_init(void) 292void sb_skin_init(void)
@@ -338,16 +295,6 @@ void sb_skin_init(void)
338 FOR_NB_SCREENS(i) 295 FOR_NB_SCREENS(i)
339 { 296 {
340 oldinfovp_label[i] = NULL; 297 oldinfovp_label[i] = NULL;
341#ifdef HAVE_ALBUMART
342 sb_skin_data[i].albumart = NULL;
343 sb_skin_data[i].playback_aa_slot = -1;
344#endif
345 sb_skin[i].data = &sb_skin_data[i];
346 sb_skin[i].display = &screens[i];
347 /* Currently no seperate wps_state needed/possible
348 so use the only available ( "global" ) one */
349 sb_skin[i].state = &wps_state;
350 sb_skin[i].sync_data = &sb_skin_sync_data;
351 } 298 }
352} 299}
353 300
@@ -367,9 +314,10 @@ int sb_touch_to_button(int context)
367 return ACTION_TOUCHSCREEN; 314 return ACTION_TOUCHSCREEN;
368 315
369 if (last_context != context) 316 if (last_context != context)
370 skin_disarm_touchregions(&sb_skin_data[SCREEN_MAIN]); 317 skin_disarm_touchregions(skin_get_gwps(CUSTOM_STATUSBAR, SCREEN_MAIN)->data);
371 last_context = context; 318 last_context = context;
372 button = skin_get_touchaction(&sb_skin_data[SCREEN_MAIN], &offset, &region); 319 button = skin_get_touchaction(skin_get_gwps(CUSTOM_STATUSBAR, SCREEN_MAIN)->data,
320 &offset, &region);
373 321
374 switch (button) 322 switch (button)
375 { 323 {
diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h
index 893d48941d..02a3a7159e 100644
--- a/apps/gui/statusbar-skinned.h
+++ b/apps/gui/statusbar-skinned.h
@@ -34,7 +34,7 @@
34 34
35void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile); 35void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile);
36 36
37void sb_create_from_settings(enum screen_type screen); 37char* sb_create_from_settings(enum screen_type screen);
38void sb_skin_init(void) INIT_ATTR; 38void sb_skin_init(void) INIT_ATTR;
39void sb_set_info_vp(enum screen_type screen, char *label); 39void sb_set_info_vp(enum screen_type screen, char *label);
40struct viewport *sb_skin_get_info_vp(enum screen_type screen); 40struct viewport *sb_skin_get_info_vp(enum screen_type screen);
@@ -49,8 +49,7 @@ int sb_touch_to_button(int context);
49#endif 49#endif
50 50
51#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) 51#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
52char* sb_get_backdrop(enum screen_type screen); 52int sb_get_backdrop(enum screen_type screen);
53bool sb_set_backdrop(enum screen_type screen, char* filename);
54#endif 53#endif
55 54
56#else /* CHARCELL */ 55#else /* CHARCELL */
diff --git a/apps/gui/theme_settings.c b/apps/gui/theme_settings.c
deleted file mode 100644
index a975c218cd..0000000000
--- a/apps/gui/theme_settings.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Stuart Martin
11 * RTC config saving code (C) 2002 by hessu@hes.iki.fi
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include <stdio.h>
23#include <stddef.h>
24#include <stdlib.h>
25#include <limits.h>
26#include "inttypes.h"
27#include "config.h"
28#include "action.h"
29#include "crc32.h"
30#include "settings.h"
31#include "wps.h"
32#include "file.h"
33#include "buffer.h"
34#if CONFIG_TUNER
35#include "radio.h"
36#endif
37#include "skin_engine/skin_engine.h"
38#include "skin_buffer.h"
39#include "statusbar-skinned.h"
40#include "bootchart.h"
41
42static char *skin_buffer = NULL;
43void theme_init_buffer(void)
44{
45 skin_buffer = buffer_alloc(SKIN_BUFFER_SIZE);
46}
47
48
49/* call this after loading a .wps/.rwps or other skin files, so that the
50 * skin buffer is reset properly
51 */
52struct skin_load_setting {
53 char* setting;
54 char* suffix;
55 void (*loadfunc)(enum screen_type screen, const char *buf, bool isfile);
56};
57
58static const struct skin_load_setting skins[] = {
59 /* This determins the load order. *sbs must be loaded before any other
60 * skin on that screen */
61#ifdef HAVE_LCD_BITMAP
62 { global_settings.sbs_file, "sbs", sb_skin_data_load},
63#endif
64 { global_settings.wps_file, "wps", wps_data_load},
65#if CONFIG_TUNER
66 { global_settings.fms_file, "fms", fms_data_load},
67#endif
68#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
69 { global_settings.rsbs_file, "rsbs", sb_skin_data_load},
70 { global_settings.rwps_file, "rwps", wps_data_load},
71#if CONFIG_TUNER
72 { global_settings.rfms_file, "rfms", fms_data_load},
73#endif
74#endif
75};
76
77void settings_apply_skins(void)
78{
79 char buf[MAX_PATH];
80 /* re-initialize the skin buffer before we start reloading skins */
81 enum screen_type screen = SCREEN_MAIN;
82 unsigned int i;
83
84 skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE);
85#ifdef HAVE_LCD_BITMAP
86 skin_backdrop_init();
87 skin_font_init();
88#endif
89#if CONFIG_TUNER
90 fms_skin_init();
91#endif
92 for (i=0; i<ARRAYLEN(skins); i++)
93 {
94#ifdef HAVE_REMOTE_LCD
95 screen = skins[i].suffix[0] == 'r' ? SCREEN_REMOTE : SCREEN_MAIN;
96#endif
97 CHART2(">skin load ", skins[i].suffix);
98 if (skins[i].setting[0] && skins[i].setting[0] != '-')
99 {
100 char path[MAX_PATH];
101 snprintf(buf, sizeof buf, "%s/%s.%s",
102 get_user_file_path(WPS_DIR, false, path, sizeof(path)),
103 skins[i].setting, skins[i].suffix);
104 skins[i].loadfunc(screen, buf, true);
105 }
106 else
107 {
108 skins[i].loadfunc(screen, NULL, true);
109 }
110 CHART2("<skin load ", skins[i].suffix);
111 }
112 viewportmanager_theme_changed(THEME_STATUSBAR);
113#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
114 FOR_NB_SCREENS(i)
115 screens[i].backdrop_show(sb_get_backdrop(i));
116#endif
117}
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
index 2b1cc9eb05..45094e421a 100644
--- a/apps/gui/viewport.c
+++ b/apps/gui/viewport.c
@@ -56,6 +56,7 @@
56#include "language.h" 56#include "language.h"
57#endif 57#endif
58#include "statusbar-skinned.h" 58#include "statusbar-skinned.h"
59#include "skin_engine/skin_engine.h"
59#include "debug.h" 60#include "debug.h"
60 61
61#define VPSTACK_DEPTH 16 62#define VPSTACK_DEPTH 16
@@ -118,7 +119,7 @@ static void toggle_theme(enum screen_type screen, bool force)
118 /* remove the left overs from the previous screen. 119 /* remove the left overs from the previous screen.
119 * could cause a tiny flicker. Redo your screen code if that happens */ 120 * could cause a tiny flicker. Redo your screen code if that happens */
120#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 121#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
121 screens[screen].backdrop_show(sb_get_backdrop(screen)); 122 skin_backdrop_show(sb_get_backdrop(screen));
122#endif 123#endif
123 if (LIKELY(after_boot[screen]) && (!was_enabled[screen] || force)) 124 if (LIKELY(after_boot[screen]) && (!was_enabled[screen] || force))
124 { 125 {
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 1489ff0026..a5fe304d21 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -74,12 +74,6 @@
74 /* 3% of 30min file == 54s step size */ 74 /* 3% of 30min file == 54s step size */
75#define MIN_FF_REWIND_STEP 500 75#define MIN_FF_REWIND_STEP 500
76 76
77/* currently only one wps_state is needed, initialize to 0 */
78 struct wps_state wps_state = { .id3 = NULL };
79static struct gui_wps gui_wps[NB_SCREENS] = {{ .data = NULL }};
80static struct wps_data wps_datas[NB_SCREENS] = {{ .wps_loaded = 0 }};
81static struct wps_sync_data wps_sync_data = { .do_full_update = false };
82
83/* initial setup of wps_data */ 77/* initial setup of wps_data */
84static void wps_state_init(void); 78static void wps_state_init(void);
85static void track_changed_callback(void *param); 79static void track_changed_callback(void *param);
@@ -94,35 +88,9 @@ static void nextid3available_callback(void* param);
94#define DEFAULT_WPS(screen) (WPS_DEFAULTCFG) 88#define DEFAULT_WPS(screen) (WPS_DEFAULTCFG)
95#endif 89#endif
96 90
97void wps_data_load(enum screen_type screen, const char *buf, bool isfile) 91char* wps_default_skin(enum screen_type screen)
98{ 92{
99 bool loaded_ok; 93 static char *skin_buf[NB_SCREENS] = {
100
101#ifndef __PCTOOL__
102 /*
103 * Hardcode loading WPS_DEFAULTCFG to cause a reset ideally this
104 * wants to be a virtual file. Feel free to modify dirbrowse()
105 * if you're feeling brave.
106 */
107
108 if (buf && ! strcmp(buf, DEFAULT_WPS(screen)) )
109 {
110#ifdef HAVE_REMOTE_LCD
111 if (screen == SCREEN_REMOTE)
112 global_settings.rwps_file[0] = '\0';
113 else
114#endif
115 global_settings.wps_file[0] = '\0';
116 buf = NULL;
117 }
118
119#endif /* __PCTOOL__ */
120
121 loaded_ok = buf && skin_data_load(screen, gui_wps[screen].data, buf, isfile);
122
123 if (!loaded_ok) /* load the hardcoded default */
124 {
125 char *skin_buf[NB_SCREENS] = {
126#ifdef HAVE_LCD_BITMAP 94#ifdef HAVE_LCD_BITMAP
127#if LCD_DEPTH > 1 95#if LCD_DEPTH > 1
128 "%X(d)\n" 96 "%X(d)\n"
@@ -148,8 +116,7 @@ void wps_data_load(enum screen_type screen, const char *buf, bool isfile)
148 "%pb\n", 116 "%pb\n",
149#endif 117#endif
150 }; 118 };
151 skin_data_load(screen, gui_wps[screen].data, skin_buf[screen], false); 119 return skin_buf[screen];
152 }
153} 120}
154 121
155void fade(bool fade_in, bool updatewps) 122void fade(bool fade_in, bool updatewps)
@@ -158,7 +125,7 @@ void fade(bool fade_in, bool updatewps)
158 int fp_min_vol = sound_min(SOUND_VOLUME) << 8; 125 int fp_min_vol = sound_min(SOUND_VOLUME) << 8;
159 int fp_step = (fp_global_vol - fp_min_vol) / 30; 126 int fp_step = (fp_global_vol - fp_min_vol) / 30;
160 int i; 127 int i;
161 wps_state.is_fading = !fade_in; 128 skin_get_global_state()->is_fading = !fade_in;
162 if (fade_in) { 129 if (fade_in) {
163 /* fade in */ 130 /* fade in */
164 int fp_volume = fp_min_vol; 131 int fp_volume = fp_min_vol;
@@ -175,7 +142,7 @@ void fade(bool fade_in, bool updatewps)
175 if (updatewps) 142 if (updatewps)
176 { 143 {
177 FOR_NB_SCREENS(i) 144 FOR_NB_SCREENS(i)
178 skin_update(&gui_wps[i], SKIN_REFRESH_NON_STATIC); 145 skin_update(WPS, i, SKIN_REFRESH_NON_STATIC);
179 } 146 }
180 sleep(1); 147 sleep(1);
181 } 148 }
@@ -191,12 +158,12 @@ void fade(bool fade_in, bool updatewps)
191 if (updatewps) 158 if (updatewps)
192 { 159 {
193 FOR_NB_SCREENS(i) 160 FOR_NB_SCREENS(i)
194 skin_update(&gui_wps[i], SKIN_REFRESH_NON_STATIC); 161 skin_update(WPS, i, SKIN_REFRESH_NON_STATIC);
195 } 162 }
196 sleep(1); 163 sleep(1);
197 } 164 }
198 audio_pause(); 165 audio_pause();
199 wps_state.is_fading = false; 166 skin_get_global_state()->is_fading = false;
200#if CONFIG_CODEC != SWCODEC 167#if CONFIG_CODEC != SWCODEC
201#ifndef SIMULATOR 168#ifndef SIMULATOR
202 /* let audio thread run and wait for the mas to run out of data */ 169 /* let audio thread run and wait for the mas to run out of data */
@@ -210,9 +177,9 @@ void fade(bool fade_in, bool updatewps)
210 } 177 }
211} 178}
212 179
213static bool update_onvol_change(struct gui_wps * gwps) 180static bool update_onvol_change(enum screen_type screen)
214{ 181{
215 skin_update(gwps, SKIN_REFRESH_NON_STATIC); 182 skin_update(WPS, screen, SKIN_REFRESH_NON_STATIC);
216 183
217#ifdef HAVE_LCD_CHARCELLS 184#ifdef HAVE_LCD_CHARCELLS
218 splashf(0, "Vol: %3d dB", 185 splashf(0, "Vol: %3d dB",
@@ -250,16 +217,16 @@ static int skintouch_to_wps(struct wps_data *data)
250 return ACTION_WPS_HOTKEY; 217 return ACTION_WPS_HOTKEY;
251#endif 218#endif
252 case WPS_TOUCHREGION_SCROLLBAR: 219 case WPS_TOUCHREGION_SCROLLBAR:
253 wps_state.id3->elapsed = wps_state.id3->length*offset/100; 220 skin_get_global_state()->id3->elapsed = skin_get_global_state()->id3->length*offset/100;
254 if (!wps_state.paused) 221 if (!skin_get_global_state()->paused)
255#if (CONFIG_CODEC == SWCODEC) 222#if (CONFIG_CODEC == SWCODEC)
256 audio_pre_ff_rewind(); 223 audio_pre_ff_rewind();
257#else 224#else
258 audio_pause(); 225 audio_pause();
259#endif 226#endif
260 audio_ff_rewind(wps_state.id3->elapsed); 227 audio_ff_rewind(skin_get_global_state()->id3->elapsed);
261#if (CONFIG_CODEC != SWCODEC) 228#if (CONFIG_CODEC != SWCODEC)
262 if (!wps_state.paused) 229 if (!skin_get_global_state()->paused)
263 audio_resume(); 230 audio_resume();
264#endif 231#endif
265 return ACTION_TOUCHSCREEN; 232 return ACTION_TOUCHSCREEN;
@@ -307,20 +274,20 @@ bool ffwd_rew(int button)
307 case ACTION_WPS_SEEKFWD: 274 case ACTION_WPS_SEEKFWD:
308 direction = 1; 275 direction = 1;
309 case ACTION_WPS_SEEKBACK: 276 case ACTION_WPS_SEEKBACK:
310 if (wps_state.ff_rewind) 277 if (skin_get_global_state()->ff_rewind)
311 { 278 {
312 if (direction == 1) 279 if (direction == 1)
313 { 280 {
314 /* fast forwarding, calc max step relative to end */ 281 /* fast forwarding, calc max step relative to end */
315 max_step = (wps_state.id3->length - 282 max_step = (skin_get_global_state()->id3->length -
316 (wps_state.id3->elapsed + 283 (skin_get_global_state()->id3->elapsed +
317 ff_rewind_count)) * 284 ff_rewind_count)) *
318 FF_REWIND_MAX_PERCENT / 100; 285 FF_REWIND_MAX_PERCENT / 100;
319 } 286 }
320 else 287 else
321 { 288 {
322 /* rewinding, calc max step relative to start */ 289 /* rewinding, calc max step relative to start */
323 max_step = (wps_state.id3->elapsed + ff_rewind_count) * 290 max_step = (skin_get_global_state()->id3->elapsed + ff_rewind_count) *
324 FF_REWIND_MAX_PERCENT / 100; 291 FF_REWIND_MAX_PERCENT / 100;
325 } 292 }
326 293
@@ -337,9 +304,9 @@ bool ffwd_rew(int button)
337 else 304 else
338 { 305 {
339 if ( (audio_status() & AUDIO_STATUS_PLAY) && 306 if ( (audio_status() & AUDIO_STATUS_PLAY) &&
340 wps_state.id3 && wps_state.id3->length ) 307 skin_get_global_state()->id3 && skin_get_global_state()->id3->length )
341 { 308 {
342 if (!wps_state.paused) 309 if (!skin_get_global_state()->paused)
343#if (CONFIG_CODEC == SWCODEC) 310#if (CONFIG_CODEC == SWCODEC)
344 audio_pre_ff_rewind(); 311 audio_pre_ff_rewind();
345#else 312#else
@@ -347,14 +314,14 @@ bool ffwd_rew(int button)
347#endif 314#endif
348#if CONFIG_KEYPAD == PLAYER_PAD 315#if CONFIG_KEYPAD == PLAYER_PAD
349 FOR_NB_SCREENS(i) 316 FOR_NB_SCREENS(i)
350 gui_wps[i].display->stop_scroll(); 317 skin_get_gwps(WPS, i)->display->stop_scroll();
351#endif 318#endif
352 if (direction > 0) 319 if (direction > 0)
353 status_set_ffmode(STATUS_FASTFORWARD); 320 status_set_ffmode(STATUS_FASTFORWARD);
354 else 321 else
355 status_set_ffmode(STATUS_FASTBACKWARD); 322 status_set_ffmode(STATUS_FASTBACKWARD);
356 323
357 wps_state.ff_rewind = true; 324 skin_get_global_state()->ff_rewind = true;
358 325
359 step = 1000 * global_settings.ff_rewind_min_step; 326 step = 1000 * global_settings.ff_rewind_min_step;
360 } 327 }
@@ -363,23 +330,23 @@ bool ffwd_rew(int button)
363 } 330 }
364 331
365 if (direction > 0) { 332 if (direction > 0) {
366 if ((wps_state.id3->elapsed + ff_rewind_count) > 333 if ((skin_get_global_state()->id3->elapsed + ff_rewind_count) >
367 wps_state.id3->length) 334 skin_get_global_state()->id3->length)
368 ff_rewind_count = wps_state.id3->length - 335 ff_rewind_count = skin_get_global_state()->id3->length -
369 wps_state.id3->elapsed; 336 skin_get_global_state()->id3->elapsed;
370 } 337 }
371 else { 338 else {
372 if ((int)(wps_state.id3->elapsed + ff_rewind_count) < 0) 339 if ((int)(skin_get_global_state()->id3->elapsed + ff_rewind_count) < 0)
373 ff_rewind_count = -wps_state.id3->elapsed; 340 ff_rewind_count = -skin_get_global_state()->id3->elapsed;
374 } 341 }
375 342
376 /* set the wps state ff_rewind_count so the progess info 343 /* set the wps state ff_rewind_count so the progess info
377 displays corectly */ 344 displays corectly */
378 wps_state.ff_rewind_count = (wps_state.wps_time_countup == false)? 345 skin_get_global_state()->ff_rewind_count = (skin_get_global_state()->wps_time_countup == false)?
379 ff_rewind_count:-ff_rewind_count; 346 ff_rewind_count:-ff_rewind_count;
380 FOR_NB_SCREENS(i) 347 FOR_NB_SCREENS(i)
381 { 348 {
382 skin_update(&gui_wps[i], 349 skin_update(WPS, i,
383 SKIN_REFRESH_PLAYER_PROGRESS | 350 SKIN_REFRESH_PLAYER_PROGRESS |
384 SKIN_REFRESH_DYNAMIC); 351 SKIN_REFRESH_DYNAMIC);
385 } 352 }
@@ -387,18 +354,18 @@ bool ffwd_rew(int button)
387 break; 354 break;
388 355
389 case ACTION_WPS_STOPSEEK: 356 case ACTION_WPS_STOPSEEK:
390 wps_state.id3->elapsed = wps_state.id3->elapsed+ff_rewind_count; 357 skin_get_global_state()->id3->elapsed = skin_get_global_state()->id3->elapsed+ff_rewind_count;
391 audio_ff_rewind(wps_state.id3->elapsed); 358 audio_ff_rewind(skin_get_global_state()->id3->elapsed);
392 wps_state.ff_rewind_count = 0; 359 skin_get_global_state()->ff_rewind_count = 0;
393 wps_state.ff_rewind = false; 360 skin_get_global_state()->ff_rewind = false;
394 status_set_ffmode(0); 361 status_set_ffmode(0);
395#if (CONFIG_CODEC != SWCODEC) 362#if (CONFIG_CODEC != SWCODEC)
396 if (!wps_state.paused) 363 if (!skin_get_global_state()->paused)
397 audio_resume(); 364 audio_resume();
398#endif 365#endif
399#ifdef HAVE_LCD_CHARCELLS 366#ifdef HAVE_LCD_CHARCELLS
400 FOR_NB_SCREENS(i) 367 FOR_NB_SCREENS(i)
401 skin_update(&gui_wps[i], SKIN_REFRESH_ALL); 368 skin_update(WPS, i, SKIN_REFRESH_ALL);
402#endif 369#endif
403 exit = true; 370 exit = true;
404 break; 371 break;
@@ -416,7 +383,7 @@ bool ffwd_rew(int button)
416 button = get_action(CONTEXT_WPS|ALLOW_SOFTLOCK,TIMEOUT_BLOCK); 383 button = get_action(CONTEXT_WPS|ALLOW_SOFTLOCK,TIMEOUT_BLOCK);
417#ifdef HAVE_TOUCHSCREEN 384#ifdef HAVE_TOUCHSCREEN
418 if (button == ACTION_TOUCHSCREEN) 385 if (button == ACTION_TOUCHSCREEN)
419 button = skintouch_to_wps(gui_wps[SCREEN_MAIN].data); 386 button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data);
420 if (button != ACTION_WPS_SEEKFWD && 387 if (button != ACTION_WPS_SEEKFWD &&
421 button != ACTION_WPS_SEEKBACK) 388 button != ACTION_WPS_SEEKBACK)
422 button = ACTION_WPS_STOPSEEK; 389 button = ACTION_WPS_STOPSEEK;
@@ -431,7 +398,7 @@ void display_keylock_text(bool locked)
431{ 398{
432 int i; 399 int i;
433 FOR_NB_SCREENS(i) 400 FOR_NB_SCREENS(i)
434 gui_wps[i].display->stop_scroll(); 401 skin_get_gwps(WPS, i)->display->stop_scroll();
435 402
436 splash(HZ, locked ? ID2P(LANG_KEYLOCK_ON) : ID2P(LANG_KEYLOCK_OFF)); 403 splash(HZ, locked ? ID2P(LANG_KEYLOCK_ON) : ID2P(LANG_KEYLOCK_OFF));
437} 404}
@@ -497,20 +464,21 @@ static void change_dir(int direction)
497 464
498static void prev_track(unsigned long skip_thresh) 465static void prev_track(unsigned long skip_thresh)
499{ 466{
500 if (wps_state.id3->elapsed < skip_thresh) 467 struct wps_state *state = skin_get_global_state();
468 if (state->id3->elapsed < skip_thresh)
501 { 469 {
502 audio_prev(); 470 audio_prev();
503 return; 471 return;
504 } 472 }
505 else 473 else
506 { 474 {
507 if (wps_state.id3->cuesheet) 475 if (state->id3->cuesheet)
508 { 476 {
509 curr_cuesheet_skip(wps_state.id3->cuesheet, -1, wps_state.id3->elapsed); 477 curr_cuesheet_skip(state->id3->cuesheet, -1, state->id3->elapsed);
510 return; 478 return;
511 } 479 }
512 480
513 if (!wps_state.paused) 481 if (!state->paused)
514#if (CONFIG_CODEC == SWCODEC) 482#if (CONFIG_CODEC == SWCODEC)
515 audio_pre_ff_rewind(); 483 audio_pre_ff_rewind();
516#else 484#else
@@ -520,7 +488,7 @@ static void prev_track(unsigned long skip_thresh)
520 audio_ff_rewind(0); 488 audio_ff_rewind(0);
521 489
522#if (CONFIG_CODEC != SWCODEC) 490#if (CONFIG_CODEC != SWCODEC)
523 if (!wps_state.paused) 491 if (!state->paused)
524 audio_resume(); 492 audio_resume();
525#endif 493#endif
526 } 494 }
@@ -528,10 +496,11 @@ static void prev_track(unsigned long skip_thresh)
528 496
529static void next_track(void) 497static void next_track(void)
530{ 498{
499 struct wps_state *state = skin_get_global_state();
531 /* take care of if we're playing a cuesheet */ 500 /* take care of if we're playing a cuesheet */
532 if (wps_state.id3->cuesheet) 501 if (state->id3->cuesheet)
533 { 502 {
534 if (curr_cuesheet_skip(wps_state.id3->cuesheet, 1, wps_state.id3->elapsed)) 503 if (curr_cuesheet_skip(state->id3->cuesheet, 1, state->id3->elapsed))
535 { 504 {
536 /* if the result was false, then we really want 505 /* if the result was false, then we really want
537 to skip to the next track */ 506 to skip to the next track */
@@ -544,9 +513,10 @@ static void next_track(void)
544 513
545static void play_hop(int direction) 514static void play_hop(int direction)
546{ 515{
516 struct wps_state *state = skin_get_global_state();
547 long step = global_settings.skip_length*1000; 517 long step = global_settings.skip_length*1000;
548 long elapsed = wps_state.id3->elapsed; 518 long elapsed = state->id3->elapsed;
549 long remaining = wps_state.id3->length - elapsed; 519 long remaining = state->id3->length - elapsed;
550 520
551 if (step < 0) 521 if (step < 0)
552 { 522 {
@@ -590,7 +560,7 @@ static void play_hop(int direction)
590 { 560 {
591 elapsed += step * direction; 561 elapsed += step * direction;
592 } 562 }
593 if((audio_status() & AUDIO_STATUS_PLAY) && !wps_state.paused) 563 if((audio_status() & AUDIO_STATUS_PLAY) && !state->paused)
594 { 564 {
595#if (CONFIG_CODEC == SWCODEC) 565#if (CONFIG_CODEC == SWCODEC)
596 audio_pre_ff_rewind(); 566 audio_pre_ff_rewind();
@@ -598,9 +568,9 @@ static void play_hop(int direction)
598 audio_pause(); 568 audio_pause();
599#endif 569#endif
600 } 570 }
601 audio_ff_rewind(wps_state.id3->elapsed = elapsed); 571 audio_ff_rewind(state->id3->elapsed = elapsed);
602#if (CONFIG_CODEC != SWCODEC) 572#if (CONFIG_CODEC != SWCODEC)
603 if (!wps_state.paused) 573 if (!state->paused)
604 audio_resume(); 574 audio_resume();
605#endif 575#endif
606} 576}
@@ -615,7 +585,7 @@ static void play_hop(int direction)
615static void wps_lcd_activation_hook(void *param) 585static void wps_lcd_activation_hook(void *param)
616{ 586{
617 (void)param; 587 (void)param;
618 wps_sync_data.do_full_update = true; 588 skin_request_full_update(WPS);
619 /* force timeout in wps main loop, so that the update is instantly */ 589 /* force timeout in wps main loop, so that the update is instantly */
620 queue_post(&button_queue, BUTTON_NONE, 0); 590 queue_post(&button_queue, BUTTON_NONE, 0);
621} 591}
@@ -627,11 +597,11 @@ static void gwps_leave_wps(void)
627 597
628 FOR_NB_SCREENS(i) 598 FOR_NB_SCREENS(i)
629 { 599 {
630 gui_wps[i].display->stop_scroll(); 600 skin_get_gwps(WPS, i)->display->stop_scroll();
631#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 601#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
632 gui_wps[i].display->backdrop_show(sb_get_backdrop(i)); 602 skin_backdrop_show(sb_get_backdrop(i));
633#endif 603#endif
634 viewportmanager_theme_undo(i, skin_has_sbs(i, gui_wps[i].data)); 604 viewportmanager_theme_undo(i, skin_has_sbs(i, skin_get_gwps(WPS, i)->data));
635 605
636 } 606 }
637 607
@@ -651,12 +621,14 @@ static void gwps_leave_wps(void)
651static void gwps_enter_wps(void) 621static void gwps_enter_wps(void)
652{ 622{
653 int i; 623 int i;
624 struct gui_wps *gwps;
625 struct screen *display;
654 FOR_NB_SCREENS(i) 626 FOR_NB_SCREENS(i)
655 { 627 {
656 struct gui_wps *gwps = &gui_wps[i]; 628 gwps = skin_get_gwps(WPS, i);
657 struct screen *display = gwps->display; 629 display = gwps->display;
658 display->stop_scroll(); 630 display->stop_scroll();
659 viewportmanager_theme_enable(i, skin_has_sbs(i, gui_wps[i].data), NULL); 631 viewportmanager_theme_enable(i, skin_has_sbs(i, skin_get_gwps(WPS, i)->data), NULL);
660 632
661 /* Update the values in the first (default) viewport - in case the user 633 /* Update the values in the first (default) viewport - in case the user
662 has modified the statusbar or colour settings */ 634 has modified the statusbar or colour settings */
@@ -675,15 +647,16 @@ static void gwps_enter_wps(void)
675#endif 647#endif
676 /* make the backdrop actually take effect */ 648 /* make the backdrop actually take effect */
677#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 649#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
678 display->backdrop_show(gwps->data->backdrop); 650 skin_backdrop_show(gwps->data->backdrop_id);
679#endif 651#endif
680 display->clear_display(); 652 display->clear_display();
681 skin_update(gwps, SKIN_REFRESH_ALL); 653 skin_update(WPS, i, SKIN_REFRESH_ALL);
682 654
683 } 655 }
684#ifdef HAVE_TOUCHSCREEN 656#ifdef HAVE_TOUCHSCREEN
685 skin_disarm_touchregions(gui_wps[SCREEN_MAIN].data); 657 gwps = skin_get_gwps(WPS, SCREEN_MAIN);
686 if (!gui_wps[SCREEN_MAIN].data->touchregions) 658 skin_disarm_touchregions(gwps->data);
659 if (!gwps->data->touchregions)
687 touchscreen_set_mode(TOUCHSCREEN_BUTTON); 660 touchscreen_set_mode(TOUCHSCREEN_BUTTON);
688#endif 661#endif
689 /* force statusbar/skin update since we just cleared the whole screen */ 662 /* force statusbar/skin update since we just cleared the whole screen */
@@ -710,6 +683,7 @@ long gui_wps_show(void)
710 bool vol_changed = false; 683 bool vol_changed = false;
711 int i; 684 int i;
712 long last_left = 0, last_right = 0; 685 long last_left = 0, last_right = 0;
686 struct wps_state *state = skin_get_global_state();
713 687
714#ifdef HAVE_LCD_CHARCELLS 688#ifdef HAVE_LCD_CHARCELLS
715 status_set_audio(true); 689 status_set_audio(true);
@@ -727,19 +701,19 @@ long gui_wps_show(void)
727 bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false; 701 bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false;
728 702
729 /* did someone else (i.e power thread) change audio pause mode? */ 703 /* did someone else (i.e power thread) change audio pause mode? */
730 if (wps_state.paused != audio_paused) { 704 if (state->paused != audio_paused) {
731 wps_state.paused = audio_paused; 705 state->paused = audio_paused;
732 706
733 /* if another thread paused audio, we are probably in car mode, 707 /* if another thread paused audio, we are probably in car mode,
734 about to shut down. lets save the settings. */ 708 about to shut down. lets save the settings. */
735 if (wps_state.paused) { 709 if (state->paused) {
736 settings_save(); 710 settings_save();
737#if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF) 711#if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
738 call_storage_idle_notifys(true); 712 call_storage_idle_notifys(true);
739#endif 713#endif
740 } 714 }
741 } 715 }
742 button = skin_wait_for_action(gui_wps, CONTEXT_WPS|ALLOW_SOFTLOCK, 716 button = skin_wait_for_action(WPS, CONTEXT_WPS|ALLOW_SOFTLOCK,
743 restore ? 1 : HZ/5); 717 restore ? 1 : HZ/5);
744 718
745 /* Exit if audio has stopped playing. This happens e.g. at end of 719 /* Exit if audio has stopped playing. This happens e.g. at end of
@@ -748,7 +722,7 @@ long gui_wps_show(void)
748 exit = true; 722 exit = true;
749#ifdef HAVE_TOUCHSCREEN 723#ifdef HAVE_TOUCHSCREEN
750 if (button == ACTION_TOUCHSCREEN) 724 if (button == ACTION_TOUCHSCREEN)
751 button = skintouch_to_wps(gui_wps[SCREEN_MAIN].data); 725 button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data);
752#endif 726#endif
753/* The iPods/X5/M5 use a single button for the A-B mode markers, 727/* The iPods/X5/M5 use a single button for the A-B mode markers,
754 defined as ACTION_WPSAB_SINGLE in their config files. */ 728 defined as ACTION_WPSAB_SINGLE in their config files. */
@@ -786,7 +760,7 @@ long gui_wps_show(void)
786 { 760 {
787 bool hotkey = button == ACTION_WPS_HOTKEY; 761 bool hotkey = button == ACTION_WPS_HOTKEY;
788 gwps_leave_wps(); 762 gwps_leave_wps();
789 int retval = onplay(wps_state.id3->path, 763 int retval = onplay(state->id3->path,
790 FILE_ATTR_AUDIO, CONTEXT_WPS, hotkey); 764 FILE_ATTR_AUDIO, CONTEXT_WPS, hotkey);
791 /* if music is stopped in the context menu we want to exit the wps */ 765 /* if music is stopped in the context menu we want to exit the wps */
792 if (retval == ONPLAY_MAINMENU 766 if (retval == ONPLAY_MAINMENU
@@ -815,9 +789,9 @@ long gui_wps_show(void)
815 case ACTION_WPS_PLAY: 789 case ACTION_WPS_PLAY:
816 if (global_settings.party_mode) 790 if (global_settings.party_mode)
817 break; 791 break;
818 if ( wps_state.paused ) 792 if ( state->paused )
819 { 793 {
820 wps_state.paused = false; 794 state->paused = false;
821 if ( global_settings.fade_on_stop ) 795 if ( global_settings.fade_on_stop )
822 fade(true, true); 796 fade(true, true);
823 else 797 else
@@ -825,7 +799,7 @@ long gui_wps_show(void)
825 } 799 }
826 else 800 else
827 { 801 {
828 wps_state.paused = true; 802 state->paused = true;
829 if ( global_settings.fade_on_stop ) 803 if ( global_settings.fade_on_stop )
830 fade(false, true); 804 fade(false, true);
831 else 805 else
@@ -852,7 +826,7 @@ long gui_wps_show(void)
852 break; 826 break;
853 if (current_tick -last_right < HZ) 827 if (current_tick -last_right < HZ)
854 { 828 {
855 if (wps_state.id3->cuesheet) 829 if (state->id3->cuesheet)
856 { 830 {
857 audio_next(); 831 audio_next();
858 } 832 }
@@ -872,9 +846,9 @@ long gui_wps_show(void)
872 break; 846 break;
873 if (current_tick -last_left < HZ) 847 if (current_tick -last_left < HZ)
874 { 848 {
875 if (wps_state.id3->cuesheet) 849 if (state->id3->cuesheet)
876 { 850 {
877 if (!wps_state.paused) 851 if (!state->paused)
878#if (CONFIG_CODEC == SWCODEC) 852#if (CONFIG_CODEC == SWCODEC)
879 audio_pre_ff_rewind(); 853 audio_pre_ff_rewind();
880#else 854#else
@@ -902,7 +876,7 @@ long gui_wps_show(void)
902 is past the A marker, jump back to the A marker... */ 876 is past the A marker, jump back to the A marker... */
903 if ( ab_repeat_mode_enabled() ) 877 if ( ab_repeat_mode_enabled() )
904 { 878 {
905 if ( ab_after_A_marker(wps_state.id3->elapsed) ) 879 if ( ab_after_A_marker(state->id3->elapsed) )
906 { 880 {
907 ab_jump_to_A_marker(); 881 ab_jump_to_A_marker();
908 break; 882 break;
@@ -925,7 +899,7 @@ long gui_wps_show(void)
925 before the A marker, jump to the A marker... */ 899 before the A marker, jump to the A marker... */
926 if ( ab_repeat_mode_enabled() ) 900 if ( ab_repeat_mode_enabled() )
927 { 901 {
928 if ( ab_before_A_marker(wps_state.id3->elapsed) ) 902 if ( ab_before_A_marker(state->id3->elapsed) )
929 { 903 {
930 ab_jump_to_A_marker(); 904 ab_jump_to_A_marker();
931 break; 905 break;
@@ -944,7 +918,7 @@ long gui_wps_show(void)
944#if defined(AB_REPEAT_ENABLE) 918#if defined(AB_REPEAT_ENABLE)
945 if (ab_repeat_mode_enabled()) 919 if (ab_repeat_mode_enabled())
946 { 920 {
947 ab_set_B_marker(wps_state.id3->elapsed); 921 ab_set_B_marker(state->id3->elapsed);
948 ab_jump_to_A_marker(); 922 ab_jump_to_A_marker();
949 } 923 }
950 else 924 else
@@ -958,7 +932,7 @@ long gui_wps_show(void)
958 break; 932 break;
959#if defined(AB_REPEAT_ENABLE) 933#if defined(AB_REPEAT_ENABLE)
960 if (ab_repeat_mode_enabled()) 934 if (ab_repeat_mode_enabled())
961 ab_set_A_marker(wps_state.id3->elapsed); 935 ab_set_A_marker(state->id3->elapsed);
962 else 936 else
963#endif 937#endif
964 { 938 {
@@ -1060,7 +1034,7 @@ long gui_wps_show(void)
1060 /* this case is used by the softlock feature 1034 /* this case is used by the softlock feature
1061 * it requests a full update here */ 1035 * it requests a full update here */
1062 case ACTION_REDRAW: 1036 case ACTION_REDRAW:
1063 wps_sync_data.do_full_update = true; 1037 skin_request_full_update(WPS);
1064 break; 1038 break;
1065 case ACTION_NONE: /* Timeout, do a partial update */ 1039 case ACTION_NONE: /* Timeout, do a partial update */
1066 update = true; 1040 update = true;
@@ -1095,7 +1069,7 @@ long gui_wps_show(void)
1095 setvol(); 1069 setvol();
1096 FOR_NB_SCREENS(i) 1070 FOR_NB_SCREENS(i)
1097 { 1071 {
1098 if(update_onvol_change(&gui_wps[i])) 1072 if(update_onvol_change(i))
1099 res = true; 1073 res = true;
1100 } 1074 }
1101 if (res) { 1075 if (res) {
@@ -1117,15 +1091,15 @@ long gui_wps_show(void)
1117 /* we remove the update delay since it's not very usable in the wps, 1091 /* we remove the update delay since it's not very usable in the wps,
1118 * e.g. during volume changing or ffwd/rewind */ 1092 * e.g. during volume changing or ffwd/rewind */
1119 sb_skin_set_update_delay(0); 1093 sb_skin_set_update_delay(0);
1120 wps_sync_data.do_full_update = update = false; 1094 skin_request_full_update(WPS);
1095 update = true;
1121 gwps_enter_wps(); 1096 gwps_enter_wps();
1122 } 1097 }
1123 else if (wps_sync_data.do_full_update || update) 1098 else
1124 { 1099 {
1125#if defined(HAVE_BACKLIGHT) || defined(HAVE_REMOTE_LCD) 1100#if defined(HAVE_BACKLIGHT) || defined(HAVE_REMOTE_LCD)
1126 gwps_caption_backlight(&wps_state); 1101 gwps_caption_backlight(state);
1127#endif 1102#endif
1128 bool full_update = wps_sync_data.do_full_update;
1129 FOR_NB_SCREENS(i) 1103 FOR_NB_SCREENS(i)
1130 { 1104 {
1131#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) 1105#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
@@ -1134,17 +1108,12 @@ long gui_wps_show(void)
1134 if (lcd_active() || (i != SCREEN_MAIN)) 1108 if (lcd_active() || (i != SCREEN_MAIN))
1135#endif 1109#endif
1136 { 1110 {
1137#if NB_SCREENS > 1 1111 bool full_update = skin_do_full_update(WPS, i);
1138 if (i==SCREEN_MAIN && wps_sync_data.do_full_update) 1112 if (update || full_update)
1139 { 1113 {
1140 wps_sync_data.do_full_update = false; 1114 skin_update(WPS, i, full_update ?
1141 }
1142
1143#else
1144 wps_sync_data.do_full_update = false;
1145#endif
1146 skin_update(&gui_wps[i], full_update ?
1147 SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC); 1115 SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
1116 }
1148 } 1117 }
1149 } 1118 }
1150 update = false; 1119 update = false;
@@ -1183,72 +1152,54 @@ long gui_wps_show(void)
1183/* this is called from the playback thread so NO DRAWING! */ 1152/* this is called from the playback thread so NO DRAWING! */
1184static void track_changed_callback(void *param) 1153static void track_changed_callback(void *param)
1185{ 1154{
1186 wps_state.id3 = (struct mp3entry*)param; 1155 struct wps_state *state = skin_get_global_state();
1187 wps_state.nid3 = audio_next_track(); 1156 state->id3 = (struct mp3entry*)param;
1188 if (wps_state.id3->cuesheet) 1157 state->nid3 = audio_next_track();
1158 if (state->id3->cuesheet)
1189 { 1159 {
1190 cue_find_current_track(wps_state.id3->cuesheet, wps_state.id3->elapsed); 1160 cue_find_current_track(state->id3->cuesheet, state->id3->elapsed);
1191 } 1161 }
1192 wps_sync_data.do_full_update = true; 1162 skin_request_full_update(WPS);
1193} 1163}
1194static void nextid3available_callback(void* param) 1164static void nextid3available_callback(void* param)
1195{ 1165{
1196 (void)param; 1166 (void)param;
1197 wps_state.nid3 = audio_next_track(); 1167 skin_get_global_state()->nid3 = audio_next_track();
1198 wps_sync_data.do_full_update = true; 1168 skin_request_full_update(WPS);
1199} 1169}
1200 1170
1201 1171
1202static void wps_state_init(void) 1172static void wps_state_init(void)
1203{ 1173{
1204 wps_state.ff_rewind = false; 1174 struct wps_state *state = skin_get_global_state();
1205 wps_state.paused = false; 1175 state->ff_rewind = false;
1176 state->paused = false;
1206 if(audio_status() & AUDIO_STATUS_PLAY) 1177 if(audio_status() & AUDIO_STATUS_PLAY)
1207 { 1178 {
1208 wps_state.id3 = audio_current_track(); 1179 state->id3 = audio_current_track();
1209 wps_state.nid3 = audio_next_track(); 1180 state->nid3 = audio_next_track();
1210 } 1181 }
1211 else 1182 else
1212 { 1183 {
1213 wps_state.id3 = NULL; 1184 state->id3 = NULL;
1214 wps_state.nid3 = NULL; 1185 state->nid3 = NULL;
1215 } 1186 }
1216 /* We'll be updating due to restore initialized with true */ 1187 /* We'll be updating due to restore initialized with true */
1217 wps_sync_data.do_full_update = false; 1188 skin_request_full_update(WPS);
1218 /* add the WPS track event callbacks */ 1189 /* add the WPS track event callbacks */
1219 add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback); 1190 add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback);
1220 add_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, false, nextid3available_callback); 1191 add_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, false, nextid3available_callback);
1221} 1192}
1222 1193
1223 1194
1224void gui_sync_wps_init(void)
1225{
1226 int i;
1227 FOR_NB_SCREENS(i)
1228 {
1229#ifdef HAVE_ALBUMART
1230 wps_datas[i].albumart = NULL;
1231 wps_datas[i].playback_aa_slot = -1;
1232#endif
1233 gui_wps[i].data = &wps_datas[i];
1234 gui_wps[i].display = &screens[i];
1235 /* Currently no seperate wps_state needed/possible
1236 so use the only available ( "global" ) one */
1237 gui_wps[i].state = &wps_state;
1238 /* must point to the same struct for both screens */
1239 gui_wps[i].sync_data = &wps_sync_data;
1240 }
1241}
1242
1243
1244#ifdef IPOD_ACCESSORY_PROTOCOL 1195#ifdef IPOD_ACCESSORY_PROTOCOL
1245bool is_wps_fading(void) 1196bool is_wps_fading(void)
1246{ 1197{
1247 return wps_state.is_fading; 1198 return skin_get_global_state()->is_fading;
1248} 1199}
1249 1200
1250int wps_get_ff_rewind_count(void) 1201int wps_get_ff_rewind_count(void)
1251{ 1202{
1252 return wps_state.ff_rewind_count; 1203 return skin_get_global_state()->ff_rewind_count;
1253} 1204}
1254#endif 1205#endif
diff --git a/apps/main.c b/apps/main.c
index 5f2c9e5a58..4c05b4342c 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -358,7 +358,7 @@ static void init(void)
358 /* Keep the order of this 3 (viewportmanager handles statusbars) 358 /* Keep the order of this 3 (viewportmanager handles statusbars)
359 * Must be done before any code uses the multi-screen API */ 359 * Must be done before any code uses the multi-screen API */
360 gui_syncstatusbar_init(&statusbars); 360 gui_syncstatusbar_init(&statusbars);
361 gui_sync_wps_init(); 361 gui_sync_skin_init();
362 sb_skin_init(); 362 sb_skin_init();
363 viewportmanager_init(); 363 viewportmanager_init();
364 364
@@ -510,7 +510,7 @@ static void init(void)
510 sb_skin_init(); 510 sb_skin_init();
511 CHART("<sb_skin_init"); 511 CHART("<sb_skin_init");
512 CHART(">gui_sync_wps_init"); 512 CHART(">gui_sync_wps_init");
513 gui_sync_wps_init(); 513 gui_sync_skin_init();
514 CHART("<gui_sync_wps_init"); 514 CHART("<gui_sync_wps_init");
515 CHART(">viewportmanager_init"); 515 CHART(">viewportmanager_init");
516 viewportmanager_init(); 516 viewportmanager_init();
diff --git a/apps/menus/theme_menu.c b/apps/menus/theme_menu.c
index c6553728a1..1676719123 100644
--- a/apps/menus/theme_menu.c
+++ b/apps/menus/theme_menu.c
@@ -40,6 +40,7 @@
40#include "appevents.h" 40#include "appevents.h"
41#include "viewport.h" 41#include "viewport.h"
42#include "statusbar-skinned.h" 42#include "statusbar-skinned.h"
43#include "skin_engine/skin_engine.h"
43 44
44#if LCD_DEPTH > 1 45#if LCD_DEPTH > 1
45/** 46/**
@@ -49,7 +50,7 @@ static int clear_main_backdrop(void)
49{ 50{
50 global_settings.backdrop_file[0] = '-'; 51 global_settings.backdrop_file[0] = '-';
51 global_settings.backdrop_file[1] = '\0'; 52 global_settings.backdrop_file[1] = '\0';
52 sb_set_backdrop(SCREEN_MAIN, NULL); 53 skin_backdrop_load_setting();
53 viewportmanager_theme_enable(SCREEN_MAIN, false, NULL); 54 viewportmanager_theme_enable(SCREEN_MAIN, false, NULL);
54 viewportmanager_theme_undo(SCREEN_MAIN, true); 55 viewportmanager_theme_undo(SCREEN_MAIN, true);
55 settings_save(); 56 settings_save();
diff --git a/apps/onplay.c b/apps/onplay.c
index f5b8476492..92864f5f16 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -1017,7 +1017,7 @@ MENUITEM_FUNCTION(add_to_faves_item, MENU_FUNC_USEPARAM, ID2P(LANG_ADD_TO_FAVES)
1017#if LCD_DEPTH > 1 1017#if LCD_DEPTH > 1
1018static bool set_backdrop(void) 1018static bool set_backdrop(void)
1019{ 1019{
1020 /* load the image */ 1020 /* load the image
1021 if(sb_set_backdrop(SCREEN_MAIN, selected_file)) { 1021 if(sb_set_backdrop(SCREEN_MAIN, selected_file)) {
1022 splash(HZ, str(LANG_BACKDROP_LOADED)); 1022 splash(HZ, str(LANG_BACKDROP_LOADED));
1023 set_file(selected_file, (char *)global_settings.backdrop_file, 1023 set_file(selected_file, (char *)global_settings.backdrop_file,
@@ -1026,7 +1026,10 @@ static bool set_backdrop(void)
1026 } else { 1026 } else {
1027 splash(HZ, str(LANG_BACKDROP_FAILED)); 1027 splash(HZ, str(LANG_BACKDROP_FAILED));
1028 return false; 1028 return false;
1029 } 1029 }*/
1030 set_file(selected_file, (char *)global_settings.backdrop_file,
1031 MAX_FILENAME);
1032 skin_backdrop_load_setting();
1030 return true; 1033 return true;
1031} 1034}
1032MENUITEM_FUNCTION(set_backdrop_item, 0, ID2P(LANG_SET_AS_BACKDROP), 1035MENUITEM_FUNCTION(set_backdrop_item, 0, ID2P(LANG_SET_AS_BACKDROP),
diff --git a/apps/radio/radio.c b/apps/radio/radio.c
index 74bdb4bc75..e5badb10a8 100644
--- a/apps/radio/radio.c
+++ b/apps/radio/radio.c
@@ -422,7 +422,7 @@ int radio_screen(void)
422 { 422 {
423 radio_load_presets(global_settings.fmr_file); 423 radio_load_presets(global_settings.fmr_file);
424 } 424 }
425 fms_get(SCREEN_MAIN)->state->id3 = NULL; 425 skin_get_global_state()->id3 = NULL;
426#ifdef HAVE_ALBUMART 426#ifdef HAVE_ALBUMART
427 radioart_init(true); 427 radioart_init(true);
428#endif 428#endif
@@ -469,7 +469,7 @@ int radio_screen(void)
469#endif 469#endif
470 fms_fix_displays(FMS_ENTER); 470 fms_fix_displays(FMS_ENTER);
471 FOR_NB_SCREENS(i) 471 FOR_NB_SCREENS(i)
472 skin_update(fms_get(i), SKIN_REFRESH_ALL); 472 skin_update(FM_SCREEN, i, SKIN_REFRESH_ALL);
473 473
474 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN))) 474 if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
475 presets_scan(NULL); 475 presets_scan(NULL);
@@ -800,7 +800,7 @@ int radio_screen(void)
800 { 800 {
801#endif 801#endif
802 FOR_NB_SCREENS(i) 802 FOR_NB_SCREENS(i)
803 skin_update(fms_get(i), update_type); 803 skin_update(FM_SCREEN, i, update_type);
804 } 804 }
805 } 805 }
806 update_type = 0; 806 update_type = 0;
diff --git a/apps/radio/radio.h b/apps/radio/radio.h
index 7c263ce218..daeaee9ca7 100644
--- a/apps/radio/radio.h
+++ b/apps/radio/radio.h
@@ -50,10 +50,6 @@ int radio_current_preset(void);
50int radio_preset_count(void); 50int radio_preset_count(void);
51const struct fmstation *radio_get_preset(int preset); 51const struct fmstation *radio_get_preset(int preset);
52 52
53/* skin functions */
54void fms_data_load(enum screen_type screen, const char *buf, bool isfile);
55void fms_skin_init(void);
56
57/* callbacks for the radio settings */ 53/* callbacks for the radio settings */
58void set_radio_region(int region); 54void set_radio_region(int region);
59void toggle_mono_mode(bool mono); 55void toggle_mono_mode(bool mono);
diff --git a/apps/radio/radio_skin.c b/apps/radio/radio_skin.c
index 28bd784ad4..0217c83f92 100644
--- a/apps/radio/radio_skin.c
+++ b/apps/radio/radio_skin.c
@@ -33,45 +33,37 @@
33#include "option_select.h" 33#include "option_select.h"
34 34
35 35
36extern struct wps_state wps_state; /* from wps.c */ 36char* default_radio_skin(enum screen_type screen)
37static struct gui_wps fms_skin[NB_SCREENS] = {{ .data = NULL }};
38static struct wps_data fms_skin_data[NB_SCREENS] = {{ .wps_loaded = 0 }};
39static struct wps_sync_data fms_skin_sync_data = { .do_full_update = false };
40
41void fms_data_load(enum screen_type screen, const char *buf, bool isfile)
42{ 37{
43 struct wps_data *data = fms_skin[screen].data; 38 (void)screen;
44 int success; 39 static char default_fms[] =
45 success = buf && skin_data_load(screen, data, buf, isfile); 40 "%s%?Ti<%Ti. |>%?Tn<%Tn|%Tf>\n"
46 41 "%Sx(Station:) %tf MHz\n"
47 if (!success ) /* load the default */ 42 "%?St(force fm mono)<%Sx(Force Mono)|%?ts<%Sx(Stereo)|%Sx(Mono)>>\n"
48 { 43 "%Sx(Mode:) %?tm<%Sx(Scan)|%Sx(Preset)>\n"
49 const char default_fms[] = "%s%?Ti<%Ti. |>%?Tn<%Tn|%Tf>\n"
50 "%Sx(Station:) %tf MHz\n"
51 "%?St(force fm mono)<%Sx(Force Mono)|%?ts<%Sx(Stereo)|%Sx(Mono)>>\n"
52 "%Sx(Mode:) %?tm<%Sx(Scan)|%Sx(Preset)>\n"
53#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR) 44#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
54 "%?Rr<%Sx(Time:) %Rh:%Rn:%Rs|%?St(prerecording time)<%pm|%Sx(Prerecord Time) %Rs>>\n" 45 "%?Rr<%Sx(Time:) %Rh:%Rn:%Rs|%?St(prerecording time)<%pm|%Sx(Prerecord Time) %Rs>>\n"
55#endif 46#endif
56 "%pb\n" 47 "%pb\n"
57#ifdef HAVE_RDS_CAP 48#ifdef HAVE_RDS_CAP
58 "\n%s%ty\n" 49 "\n%s%ty\n"
59 "%s%tz\n" 50 "%s%tz\n"
60#endif 51#endif
61 ; 52 ;
62 skin_data_load(screen, data, default_fms, false); 53 return default_fms;
63 }
64} 54}
55
65void fms_fix_displays(enum fms_exiting toggle_state) 56void fms_fix_displays(enum fms_exiting toggle_state)
66{ 57{
67 int i; 58 int i;
68 FOR_NB_SCREENS(i) 59 FOR_NB_SCREENS(i)
69 { 60 {
61 struct wps_data *data = skin_get_gwps(FM_SCREEN, i)->data;
70 if (toggle_state == FMS_ENTER) 62 if (toggle_state == FMS_ENTER)
71 { 63 {
72 viewportmanager_theme_enable(i, skin_has_sbs(i, fms_skin[i].data), NULL); 64 viewportmanager_theme_enable(i, skin_has_sbs(i, data), NULL);
73#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 65#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
74 screens[i].backdrop_show(fms_skin[i].data->backdrop); 66 skin_backdrop_show(data->backdrop_id);
75#endif 67#endif
76 screens[i].clear_display(); 68 screens[i].clear_display();
77 /* force statusbar/skin update since we just cleared the whole screen */ 69 /* force statusbar/skin update since we just cleared the whole screen */
@@ -81,46 +73,29 @@ void fms_fix_displays(enum fms_exiting toggle_state)
81 { 73 {
82 screens[i].stop_scroll(); 74 screens[i].stop_scroll();
83#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 75#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
84 screens[i].backdrop_show(sb_get_backdrop(i)); 76 skin_backdrop_show(sb_get_backdrop(i));
85#endif 77#endif
86 viewportmanager_theme_undo(i, skin_has_sbs(i, fms_skin[i].data)); 78 viewportmanager_theme_undo(i, skin_has_sbs(i, data));
87 } 79 }
88 } 80 }
89#ifdef HAVE_TOUCHSCREEN 81#ifdef HAVE_TOUCHSCREEN
90 if (!fms_skin[SCREEN_MAIN].data->touchregions) 82 if (i==SCREEN_MAIN && !data->touchregions)
91 touchscreen_set_mode(toggle_state == FMS_ENTER ? 83 touchscreen_set_mode(toggle_state == FMS_ENTER ?
92 TOUCHSCREEN_BUTTON : global_settings.touch_mode); 84 TOUCHSCREEN_BUTTON : global_settings.touch_mode);
93#endif 85#endif
94} 86}
95 87
96 88
97void fms_skin_init(void)
98{
99 int i;
100 FOR_NB_SCREENS(i)
101 {
102#ifdef HAVE_ALBUMART
103 fms_skin_data[i].albumart = NULL;
104 fms_skin_data[i].playback_aa_slot = -1;
105#endif
106 fms_skin[i].data = &fms_skin_data[i];
107 fms_skin[i].display = &screens[i];
108 /* Currently no seperate wps_state needed/possible
109 so use the only available ( "global" ) one */
110 fms_skin[i].state = &wps_state;
111 fms_skin[i].sync_data = &fms_skin_sync_data;
112 }
113}
114
115int fms_do_button_loop(bool update_screen) 89int fms_do_button_loop(bool update_screen)
116{ 90{
117 int button = skin_wait_for_action(fms_skin, CONTEXT_FM, 91 int button = skin_wait_for_action(FM_SCREEN, CONTEXT_FM,
118 update_screen ? TIMEOUT_NOBLOCK : HZ/5); 92 update_screen ? TIMEOUT_NOBLOCK : HZ/5);
119#ifdef HAVE_TOUCHSCREEN 93#ifdef HAVE_TOUCHSCREEN
120 struct touchregion *region; 94 struct touchregion *region;
121 int offset; 95 int offset;
122 if (button == ACTION_TOUCHSCREEN) 96 if (button == ACTION_TOUCHSCREEN)
123 button = skin_get_touchaction(&fms_skin_data[SCREEN_MAIN], &offset, &region); 97 button = skin_get_touchaction(skin_get_gwps(FM_SCREEN, SCREEN_MAIN)->data,
98 &offset, &region)
124 switch (button) 99 switch (button)
125 { 100 {
126 case ACTION_WPS_STOP: 101 case ACTION_WPS_STOP:
@@ -152,5 +127,5 @@ int fms_do_button_loop(bool update_screen)
152 127
153struct gui_wps *fms_get(enum screen_type screen) 128struct gui_wps *fms_get(enum screen_type screen)
154{ 129{
155 return &fms_skin[screen]; 130 return skin_get_gwps(FM_SCREEN, screen);
156} 131}
diff --git a/tools/buildzip.pl b/tools/buildzip.pl
index e0b0bbb5de..e299d7c02a 100755
--- a/tools/buildzip.pl
+++ b/tools/buildzip.pl
@@ -305,6 +305,47 @@ sub filesize {
305 return $size; 305 return $size;
306} 306}
307 307
308sub create_failsafefiles {
309 my ($dir) = @_;
310 my $text = "# Dummy file to allow Rockbox to reset to the default skin config.
311# Do not edit this file. It's never actually loaded by Rockbox.";
312 open (FOO, ">$dir/wps/rockbox_failsafe.wps");
313 print FOO $text;
314 close(FOO);
315 open (FOO, ">$dir/wps/rockbox_failsafe.rwps");
316 print FOO $text;
317 close(FOO);
318 open (FOO, ">$dir/wps/rockbox_failsafe.sbs");
319 print FOO $text;
320 close(FOO);
321 open (FOO, ">$dir/wps/rockbox_failsafe.rsbs");
322 print FOO $text;
323 close(FOO);
324 open (FOO, ">$dir/wps/rockbox_failsafe.fms");
325 print FOO $text;
326 close(FOO);
327 open (FOO, ">$dir/wps/rockbox_failsafe.rfms");
328 print FOO $text;
329 close(FOO);
330 open (FOO, ">$dir/themes/rockbox_failsafe.cfg");
331 print FOO <<STOP
332# This config has been autogenerated to reload the failsafe setup
333wps: $dir/wps/rockbox_failsafe.wps
334rwps: $dir/wps/rockbox_failsafe.rwps
335sbs: $dir/wps/rockbox_failsafe.sbs
336rsbs: $dir/wps/rockbox_failsafe.rsbs
337fms: $dir/wps/rockbox_failsafe.fms
338rfms: $dir/wps/rockbox_failsafe.rfms
339statusbar: top
340font: 08-Schumacher-Clean.fnt
341foreground color: 000000
342background color: B6C6E5
343selector type: bar (inverse)
344STOP
345;
346 close(FOO);
347}
348
308sub buildzip { 349sub buildzip {
309 my ($image, $fonts)=@_; 350 my ($image, $fonts)=@_;
310 my $libdir = $install; 351 my $libdir = $install;
@@ -508,6 +549,7 @@ STOP
508 "$temp_dir/rocks/demos/pictureflow_splash.bmp"); 549 "$temp_dir/rocks/demos/pictureflow_splash.bmp");
509 550
510 } 551 }
552 create_failsafefiles($temp_dir);
511 553
512 if($image) { 554 if($image) {
513 # image is blank when this is a simulator 555 # image is blank when this is a simulator
@@ -572,7 +614,6 @@ STOP
572 } else { 614 } else {
573 copy("$ROOT/wps/classic_statusbar.112x64x1.sbs", "$temp_dir/wps/classic_statusbar.sbs"); 615 copy("$ROOT/wps/classic_statusbar.112x64x1.sbs", "$temp_dir/wps/classic_statusbar.sbs");
574 } 616 }
575 system("touch $temp_dir/wps/rockbox_none.sbs");
576 if ($remote_depth != $depth) { 617 if ($remote_depth != $depth) {
577 copy("$ROOT/wps/classic_statusbar.mono.sbs", "$temp_dir/wps/classic_statusbar.rsbs"); 618 copy("$ROOT/wps/classic_statusbar.mono.sbs", "$temp_dir/wps/classic_statusbar.rsbs");
578 } else { 619 } else {
diff --git a/wps/WPSLIST b/wps/WPSLIST
index e382368fa1..362df12609 100644
--- a/wps/WPSLIST
+++ b/wps/WPSLIST
@@ -42,23 +42,6 @@ selector type: bar (inverse)
42</wps> 42</wps>
43 43
44<wps> 44<wps>
45Name: rockbox_default.wps
46RWPS: rockbox_default.rwps
47SBS:
48RSBS:
49Author: Rockbox team
50Font: 08-Schumacher-Clean.fnt
51Font.11x2x1:
52Statusbar: on
53Foreground Color: 000000
54Background Color: B6C6E5
55backdrop:
56iconset:
57viewers iconset:
58selector type: bar (inverse)
59</wps>
60
61<wps>
62Name: boxes.wps 45Name: boxes.wps
63rwps: boxes.rwps 46rwps: boxes.rwps
64SBS: 47SBS: