fc3962188552f9ec179047a75c78c8296949b8ea
[kugel-rb.git] / apps / gui / splash.c
blobfc3962188552f9ec179047a75c78c8296949b8ea
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) Daniel Stenberg (2002)
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "stdarg.h"
22 #include "string.h"
23 #include "rbunicode.h"
24 #include "stdio.h"
25 #include "kernel.h"
26 #include "screen_access.h"
27 #include "lang.h"
28 #include "settings.h"
29 #include "talk.h"
30 #include "splash.h"
31 #include "viewport.h"
33 #ifdef HAVE_LCD_BITMAP
35 #define MAXLINES (LCD_HEIGHT/6)
36 #define MAXBUFFER 512
37 #define RECT_SPACING 2
38 #define SPLASH_MEMORY_INTERVAL (HZ)
40 #else /* HAVE_LCD_CHARCELLS */
42 #define MAXLINES 2
43 #define MAXBUFFER 64
44 #define RECT_SPACING 0
46 #endif
49 static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
51 char splash_buf[MAXBUFFER];
52 char *lines[MAXLINES];
54 char *next;
55 char *lastbreak = NULL;
56 char *store = NULL;
57 int line = 0;
58 int x = 0;
59 int y, i;
60 int space_w, w, h;
61 struct viewport vp;
62 #ifdef HAVE_LCD_BITMAP
63 int width, height;
64 int maxw = 0;
66 viewport_set_defaults(&vp, screen->screen_type);
67 screen->set_viewport(&vp);
69 screen->getstringsize(" ", &space_w, &h);
70 #else /* HAVE_LCD_CHARCELLS */
71 vp.width = screen->lcdwidth;
72 vp.height = screen->lcdheight;
74 space_w = h = 1;
75 screen->double_height (false);
76 #endif
77 y = h;
79 vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
80 va_end(ap);
82 /* break splash string into display lines, doing proper word wrap */
84 next = strtok_r(splash_buf, " ", &store);
85 if (!next)
86 goto end; /* nothing to display */
88 lines[0] = next;
89 while (true)
91 #ifdef HAVE_LCD_BITMAP
92 screen->getstringsize(next, &w, NULL);
93 #else
94 w = utf8length(next);
95 #endif
96 if (lastbreak)
98 if (x + (next - lastbreak) * space_w + w
99 > vp.width - RECT_SPACING*2)
100 { /* too wide, wrap */
101 #ifdef HAVE_LCD_BITMAP
102 if (x > maxw)
103 maxw = x;
104 #endif
105 if ((y + h > vp.height) || (line >= (MAXLINES-1)))
106 break; /* screen full or out of lines */
107 x = 0;
108 y += h;
109 lines[++line] = next;
111 else
113 /* restore & calculate spacing */
114 *lastbreak = ' ';
115 x += (next - lastbreak) * space_w;
118 x += w;
119 lastbreak = next + strlen(next);
120 next = strtok_r(NULL, " ", &store);
121 if (!next)
122 { /* no more words */
123 #ifdef HAVE_LCD_BITMAP
124 if (x > maxw)
125 maxw = x;
126 #endif
127 break;
131 /* prepare viewport
132 * First boundaries, then the grey filling, then the black border and finally
133 * the text*/
135 screen->stop_scroll();
137 #ifdef HAVE_LCD_BITMAP
139 vp.y = (vp.height - vp.y - y) / 2 - RECT_SPACING; /* height => y start position */
140 vp.x += (vp.width - maxw) / 2 - RECT_SPACING;
141 width = maxw + 2*RECT_SPACING;
142 height = y + 2*RECT_SPACING;
144 if (vp.y < 0)
145 vp.y = 0;
146 if (vp.x < 0)
147 vp.x = 0;
148 if (width > vp.width)
149 width = vp.width;
150 if (height > vp.height)
151 height = vp.height;
152 vp.width = width;
153 vp.height = height;
155 vp.flags |= VP_FLAG_ALIGN_CENTER;
156 #if LCD_DEPTH > 1
157 if (screen->depth > 1)
159 vp.drawmode = DRMODE_FG;
160 /* can't do vp.fg_pattern here, since set_foreground does a bit more on
161 * greyscale */
162 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
164 else
165 #endif
166 vp.drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID);
168 screen->fillrect(0, 0, vp.width, vp.height);
170 #if LCD_DEPTH > 1
171 if (screen->depth > 1)
172 /* can't do vp.fg_pattern here, since set_foreground does a bit more on
173 * greyscale */
174 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
175 else
176 #endif
177 vp.drawmode = DRMODE_SOLID;
179 screen->drawrect(0, 0, vp.width, vp.height);
181 /* prepare putting the text */
182 y = RECT_SPACING;
183 #else /* HAVE_LCD_CHARCELLS */
184 y = 0; /* vertical centering on 2 lines would be silly */
185 screen->clear_display();
186 #endif
188 /* print the message to screen */
189 for (i = 0; i <= line; i++, y+=h)
191 #ifdef HAVE_LCD_BITMAP
192 screen->putsxy(0, y, lines[i]);
193 #else
194 screen->puts(0, y, lines[i]);
195 #endif
197 screen->update_viewport();
198 end:
199 screen->set_viewport(NULL);
202 void splashf(int ticks, const char *fmt, ...)
204 va_list ap;
205 int i;
207 /* If fmt is a lang ID then get the corresponding string (which
208 still might contain % place holders). */
209 fmt = P2STR((unsigned char *)fmt);
210 FOR_NB_SCREENS(i)
212 va_start(ap, fmt);
213 splash_internal(&(screens[i]), fmt, ap);
214 va_end(ap);
216 if (ticks)
217 sleep(ticks);
220 void splash(int ticks, const char *str)
222 #if !defined(SIMULATOR) || CONFIG_CODEC == SWCODEC
223 long id;
224 /* fmt may be a so called virtual pointer. See settings.h. */
225 if((id = P2ID((const unsigned char*)str)) >= 0)
226 /* If fmt specifies a voicefont ID, and voice menus are
227 enabled, then speak it. */
228 cond_talk_ids_fq(id);
229 #endif
230 splashf(ticks, "%s", P2STR((const unsigned char*)str));