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.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
new file mode 100644
index 0000000000..a3cbb198df
--- /dev/null
+++ b/apps/gui/splash.c
@@ -0,0 +1,216 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) Daniel Stenberg (2002), Kévin FERRARE (2005)
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "stdarg.h"
20#include "string.h"
21#include "stdio.h"
22#include "kernel.h"
23#include "screen_access.h"
24
25
26#ifdef HAVE_LCD_BITMAP
27
28#define SPACE 3 /* pixels between words */
29#define MAXLETTERS 128 /* 16*8 */
30#define MAXLINES 10
31
32#else
33
34#define SPACE 1 /* one letter space */
35#define MAXLETTERS 22 /* 11 * 2 */
36#define MAXLINES 2
37
38#endif
39
40
41void internal_splash(struct screen * screen,
42 bool center, const char *fmt, va_list ap)
43{
44 char *next;
45 char *store=NULL;
46 int x=0;
47 int y=0;
48 int w, h;
49 unsigned char splash_buf[MAXLETTERS];
50 unsigned char widths[MAXLINES];
51 int line=0;
52 bool first=true;
53#ifdef HAVE_LCD_BITMAP
54 int maxw=0;
55#endif
56
57#ifdef HAVE_LCD_CHARCELLS
58 screen->double_height (false);
59#endif
60 vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap );
61
62 if(center) {
63 /* first a pass to measure sizes */
64 next = strtok_r(splash_buf, " ", &store);
65 while (next) {
66#ifdef HAVE_LCD_BITMAP
67 screen->getstringsize(next, &w, &h);
68#else
69 w = strlen(next);
70 h = 1; /* store height in characters */
71#endif
72 if(!first) {
73 if(x+w> screen->width) {
74 /* Too wide, wrap */
75 y+=h;
76 line++;
77 if((y > (screen->height-h)) || (line > screen->nb_lines))
78 /* STOP */
79 break;
80 x=0;
81 first=true;
82 }
83 }
84 else
85 first = false;
86
87 /* think of it as if the text was written here at position x,y
88 being w pixels/chars wide and h high */
89
90 x += w+SPACE;
91 widths[line]=x-SPACE; /* don't count the trailing space */
92#ifdef HAVE_LCD_BITMAP
93 /* store the widest line */
94 if(widths[line]>maxw)
95 maxw = widths[line];
96#endif
97 next = strtok_r(NULL, " ", &store);
98 }
99
100#ifdef HAVE_LCD_BITMAP
101 /* Start displaying the message at position y. The reason for the
102 added h here is that it isn't added until the end of lines in the
103 loop above and we always break the loop in the middle of a line. */
104 y = (screen->height - (y+h) )/2;
105#else
106 y = 0; /* vertical center on 2 lines would be silly */
107#endif
108 first=true;
109
110 /* Now recreate the string again since the strtok_r() above has ruined
111 the one we already have! Here's room for improvements! */
112 vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap );
113 }
114 va_end( ap );
115
116 if(center)
117 {
118 x = (screen->width-widths[0])/2;
119 if(x < 0)
120 x = 0;
121 }
122
123#ifdef HAVE_LCD_BITMAP
124 /* If we center the display, then just clear the box we need and put
125 a nice little frame and put the text in there! */
126 if(center && (y > 2)) {
127 int xx = (screen->width-maxw)/2 - 2;
128 /* The new graphics routines handle clipping, so no need to check */
129#if LCD_DEPTH > 1
130#ifdef HAVE_LCD_COLOR
131 screen->set_background((struct rgb){LCD_MAX_RED-1, LCD_MAX_GREEN-1,
132 LCD_MAX_BLUE-1});
133#else
134 if(screen->depth>1)
135 screen->set_background(LCD_MAX_LEVEL-1);
136#endif
137#endif
138 screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
139 screen->fillrect(xx, y-2, maxw+4, screen->height-y*2+4);
140 screen->set_drawmode(DRMODE_SOLID);
141 screen->drawrect(xx, y-2, maxw+4, screen->height-y*2+4);
142 }
143 else
144#endif
145 screen->clear_display();
146 line=0;
147 next = strtok_r(splash_buf, " ", &store);
148 while (next) {
149#ifdef HAVE_LCD_BITMAP
150 screen->getstringsize(next, &w, &h);
151#else
152 w = strlen(next);
153 h = 1;
154#endif
155 if(!first) {
156 if(x+w> screen->width) {
157 /* too wide */
158 y+=h;
159 line++; /* goto next line */
160 first=true;
161 if(y > (screen->height-h))
162 /* STOP */
163 break;
164 if(center) {
165 x = (screen->width-widths[line])/2;
166 if(x < 0)
167 x = 0;
168 }
169 else
170 x=0;
171 }
172 }
173 else
174 first=false;
175#ifdef HAVE_LCD_BITMAP
176 screen->putsxy(x, y, next);
177#else
178 screen->puts(x, y, next);
179#endif
180 x += w+SPACE; /* pixels space! */
181 next = strtok_r(NULL, " ", &store);
182 }
183
184#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1)
185 if(screen->depth > 1)
186 screen->set_background(LCD_WHITE);
187#endif
188#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
189 screen->update();
190#endif
191}
192
193void gui_splash(struct screen * screen, int ticks,
194 bool center, const char *fmt, ...)
195{
196 va_list ap;
197 va_start( ap, fmt );
198 internal_splash(screen, center, fmt, ap);
199 va_end( ap );
200
201 if(ticks)
202 sleep(ticks);
203}
204
205void gui_syncsplash(int ticks, bool center, const char *fmt, ...)
206{
207 va_list ap;
208 int i;
209 va_start( ap, fmt );
210 for(i=0;i<NB_SCREENS;++i)
211 internal_splash(&(screens[i]), center, fmt, ap);
212 va_end( ap );
213
214 if(ticks)
215 sleep(ticks);
216}