diff options
Diffstat (limited to 'apps/gui/splash.c')
-rw-r--r-- | apps/gui/splash.c | 216 |
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 | |||
41 | void 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 | |||
193 | void 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 | |||
205 | void 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 | } | ||