summaryrefslogtreecommitdiff
path: root/apps/gui/splash.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/splash.c')
-rw-r--r--apps/gui/splash.c112
1 files changed, 82 insertions, 30 deletions
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
index b85e4693aa..bf9647cff1 100644
--- a/apps/gui/splash.c
+++ b/apps/gui/splash.c
@@ -30,17 +30,18 @@
30#include "splash.h" 30#include "splash.h"
31#include "viewport.h" 31#include "viewport.h"
32#include "strtok_r.h" 32#include "strtok_r.h"
33#include "scrollbar.h"
33 34
34#define MAXLINES (LCD_HEIGHT/6) 35#define MAXLINES (LCD_HEIGHT/6)
35#define MAXBUFFER 512 36#define MAXBUFFER 512
36#define RECT_SPACING 2 37#define RECT_SPACING 2
37#define SPLASH_MEMORY_INTERVAL (HZ) 38#define SPLASH_MEMORY_INTERVAL (HZ)
38 39
39static void splash_internal(struct screen * screen, const char *fmt, va_list ap) 40static bool splash_internal(struct screen * screen, const char *fmt, va_list ap,
41 struct viewport *vp, int addl_lines)
40{ 42{
41 char splash_buf[MAXBUFFER]; 43 char splash_buf[MAXBUFFER];
42 char *lines[MAXLINES]; 44 char *lines[MAXLINES];
43
44 char *next; 45 char *next;
45 char *lastbreak = NULL; 46 char *lastbreak = NULL;
46 char *store = NULL; 47 char *store = NULL;
@@ -48,15 +49,12 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
48 int x = 0; 49 int x = 0;
49 int y, i; 50 int y, i;
50 int space_w, w, h; 51 int space_w, w, h;
51 struct viewport vp; 52
52 int width, height; 53 int width, height;
53 int maxw = 0; 54 int maxw = 0;
54 55
55 viewport_set_defaults(&vp, screen->screen_type);
56 struct viewport *last_vp = screen->set_viewport(&vp);
57
58 screen->getstringsize(" ", &space_w, &h); 56 screen->getstringsize(" ", &space_w, &h);
59 y = h; 57 y = h + (addl_lines * h);
60 58
61 vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap); 59 vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
62 va_end(ap); 60 va_end(ap);
@@ -65,7 +63,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
65 63
66 next = strtok_r(splash_buf, " ", &store); 64 next = strtok_r(splash_buf, " ", &store);
67 if (!next) 65 if (!next)
68 goto end; /* nothing to display */ 66 return false; /* nothing to display */
69 67
70 lines[0] = next; 68 lines[0] = next;
71 while (true) 69 while (true)
@@ -73,12 +71,13 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
73 screen->getstringsize(next, &w, NULL); 71 screen->getstringsize(next, &w, NULL);
74 if (lastbreak) 72 if (lastbreak)
75 { 73 {
76 if (x + (next - lastbreak) * space_w + w 74 int next_w = (next - lastbreak) * space_w;
77 > vp.width - RECT_SPACING*2) 75
76 if (x + next_w + w > vp->width - RECT_SPACING*2)
78 { /* too wide, wrap */ 77 { /* too wide, wrap */
79 if (x > maxw) 78 if (x > maxw)
80 maxw = x; 79 maxw = x;
81 if ((y + h > vp.height) || (line >= (MAXLINES-1))) 80 if ((y + h > vp->height) || (line >= (MAXLINES-1)))
82 break; /* screen full or out of lines */ 81 break; /* screen full or out of lines */
83 x = 0; 82 x = 0;
84 y += h; 83 y += h;
@@ -88,7 +87,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
88 { 87 {
89 /* restore & calculate spacing */ 88 /* restore & calculate spacing */
90 *lastbreak = ' '; 89 *lastbreak = ' ';
91 x += (next - lastbreak) * space_w; 90 x += next_w;
92 } 91 }
93 } 92 }
94 x += w; 93 x += w;
@@ -111,39 +110,39 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
111 width = maxw + 2*RECT_SPACING; 110 width = maxw + 2*RECT_SPACING;
112 height = y + 2*RECT_SPACING; 111 height = y + 2*RECT_SPACING;
113 112
114 if (width > vp.width) 113 if (width > vp->width)
115 width = vp.width; 114 width = vp->width;
116 if (height > vp.height) 115 if (height > vp->height)
117 height = vp.height; 116 height = vp->height;
118 117
119 vp.x += (vp.width - width) / 2; 118 vp->x += (vp->width - width) / 2;
120 vp.y += (vp.height - height) / 2; 119 vp->y += (vp->height - height) / 2;
121 vp.width = width; 120 vp->width = width;
122 vp.height = height; 121 vp->height = height;
123 122
124 vp.flags |= VP_FLAG_ALIGN_CENTER; 123 vp->flags |= VP_FLAG_ALIGN_CENTER;
125#if LCD_DEPTH > 1 124#if LCD_DEPTH > 1
126 if (screen->depth > 1) 125 if (screen->depth > 1)
127 { 126 {
128 vp.drawmode = DRMODE_FG; 127 vp->drawmode = DRMODE_FG;
129 /* can't do vp.fg_pattern here, since set_foreground does a bit more on 128 /* can't do vp->fg_pattern here, since set_foreground does a bit more on
130 * greyscale */ 129 * greyscale */
131 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY)); 130 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
132 } 131 }
133 else 132 else
134#endif 133#endif
135 vp.drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); 134 vp->drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID);
136 135
137 screen->fill_viewport(); 136 screen->fill_viewport();
138 137
139#if LCD_DEPTH > 1 138#if LCD_DEPTH > 1
140 if (screen->depth > 1) 139 if (screen->depth > 1)
141 /* can't do vp.fg_pattern here, since set_foreground does a bit more on 140 /* can't do vp->fg_pattern here, since set_foreground does a bit more on
142 * greyscale */ 141 * greyscale */
143 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK)); 142 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
144 else 143 else
145#endif 144#endif
146 vp.drawmode = DRMODE_SOLID; 145 vp->drawmode = DRMODE_SOLID;
147 146
148 screen->draw_border_viewport(); 147 screen->draw_border_viewport();
149 148
@@ -155,9 +154,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
155 { 154 {
156 screen->putsxy(0, y, lines[i]); 155 screen->putsxy(0, y, lines[i]);
157 } 156 }
158 screen->update_viewport(); 157 return true; /* needs update */
159end:
160 screen->set_viewport(last_vp);
161} 158}
162 159
163void splashf(int ticks, const char *fmt, ...) 160void splashf(int ticks, const char *fmt, ...)
@@ -169,9 +166,17 @@ void splashf(int ticks, const char *fmt, ...)
169 fmt = P2STR((unsigned char *)fmt); 166 fmt = P2STR((unsigned char *)fmt);
170 FOR_NB_SCREENS(i) 167 FOR_NB_SCREENS(i)
171 { 168 {
169 struct screen * screen = &(screens[i]);
170 struct viewport vp;
171 viewport_set_defaults(&vp, screen->screen_type);
172 struct viewport *last_vp = screen->set_viewport(&vp);
173
172 va_start(ap, fmt); 174 va_start(ap, fmt);
173 splash_internal(&(screens[i]), fmt, ap); 175 if (splash_internal(screen, fmt, ap, &vp, 0))
176 screen->update_viewport();
174 va_end(ap); 177 va_end(ap);
178
179 screen->set_viewport(last_vp);
175 } 180 }
176 if (ticks) 181 if (ticks)
177 sleep(ticks); 182 sleep(ticks);
@@ -189,3 +194,50 @@ void splash(int ticks, const char *str)
189#endif 194#endif
190 splashf(ticks, "%s", P2STR((const unsigned char*)str)); 195 splashf(ticks, "%s", P2STR((const unsigned char*)str));
191} 196}
197
198/* splash a progress meter */
199void splash_progress(int current, int total, const char *fmt, ...)
200{
201 int vp_flag = VP_FLAG_VP_DIRTY;
202 /* progress update tick */
203 static long next_tick = 0;
204 long now = current_tick;
205
206 if (current < total)
207 {
208 if(TIME_BEFORE(now, next_tick))
209 return;
210 /* limit to 20fps */
211 next_tick = now + HZ/20;
212 vp_flag = 0; /* don't mark vp dirty to prevent flashing */
213 }
214
215 va_list ap;
216
217 /* If fmt is a lang ID then get the corresponding string (which
218 still might contain % place holders). */
219 fmt = P2STR((unsigned char *)fmt);
220 FOR_NB_SCREENS(i)
221 {
222 struct screen * screen = &(screens[i]);
223 struct viewport vp;
224 viewport_set_defaults(&vp, screen->screen_type);
225 struct viewport *last_vp = screen->set_viewport_ex(&vp, vp_flag);
226
227 va_start(ap, fmt);
228 if (splash_internal(screen, fmt, ap, &vp, 1))
229 {
230 int size = screen->getcharheight();
231 int y = vp.height - size - RECT_SPACING;
232 int w = vp.width - RECT_SPACING * 2;
233
234 gui_scrollbar_draw(screen, RECT_SPACING, y, w, size,
235 total, 0, current, HORIZONTAL | FOREGROUND);
236
237 screen->update_viewport();
238 }
239 va_end(ap);
240
241 screen->set_viewport(last_vp);
242 }
243}