Merge tag 'v3.13-final' into maemo-port
[maemo-rb.git] / apps / gui / splash.c
blobad6625fec6de2de7c40c7917f5ffb03125c69aaf
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"
32 #include "strtok_r.h"
34 #ifdef HAVE_LCD_BITMAP
36 #define MAXLINES (LCD_HEIGHT/6)
37 #define MAXBUFFER 512
38 #define RECT_SPACING 2
39 #define SPLASH_MEMORY_INTERVAL (HZ)
41 #else /* HAVE_LCD_CHARCELLS */
43 #define MAXLINES 2
44 #define MAXBUFFER 64
45 #define RECT_SPACING 0
47 #endif
50 static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
52 char splash_buf[MAXBUFFER];
53 char *lines[MAXLINES];
55 char *next;
56 char *lastbreak = NULL;
57 char *store = NULL;
58 int line = 0;
59 int x = 0;
60 int y, i;
61 int space_w, w, h;
62 struct viewport vp;
63 #ifdef HAVE_LCD_BITMAP
64 int width, height;
65 int maxw = 0;
67 viewport_set_defaults(&vp, screen->screen_type);
68 screen->set_viewport(&vp);
70 screen->getstringsize(" ", &space_w, &h);
71 #else /* HAVE_LCD_CHARCELLS */
72 vp.width = screen->lcdwidth;
73 vp.height = screen->lcdheight;
75 space_w = h = 1;
76 screen->double_height (false);
77 #endif
78 y = h;
80 vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
81 va_end(ap);
83 /* break splash string into display lines, doing proper word wrap */
85 next = strtok_r(splash_buf, " ", &store);
86 if (!next)
87 goto end; /* nothing to display */
89 lines[0] = next;
90 while (true)
92 #ifdef HAVE_LCD_BITMAP
93 screen->getstringsize(next, &w, NULL);
94 #else
95 w = utf8length(next);
96 #endif
97 if (lastbreak)
99 if (x + (next - lastbreak) * space_w + w
100 > vp.width - RECT_SPACING*2)
101 { /* too wide, wrap */
102 #ifdef HAVE_LCD_BITMAP
103 if (x > maxw)
104 maxw = x;
105 #endif
106 if ((y + h > vp.height) || (line >= (MAXLINES-1)))
107 break; /* screen full or out of lines */
108 x = 0;
109 y += h;
110 lines[++line] = next;
112 else
114 /* restore & calculate spacing */
115 *lastbreak = ' ';
116 x += (next - lastbreak) * space_w;
119 x += w;
120 lastbreak = next + strlen(next);
121 next = strtok_r(NULL, " ", &store);
122 if (!next)
123 { /* no more words */
124 #ifdef HAVE_LCD_BITMAP
125 if (x > maxw)
126 maxw = x;
127 #endif
128 break;
132 /* prepare viewport
133 * First boundaries, then the grey filling, then the black border and finally
134 * the text*/
136 screen->stop_scroll();
138 #ifdef HAVE_LCD_BITMAP
140 width = maxw + 2*RECT_SPACING;
141 height = y + 2*RECT_SPACING;
143 if (width > vp.width)
144 width = vp.width;
145 if (height > vp.height)
146 height = vp.height;
148 vp.x += (vp.width - width) / 2;
149 vp.y += (vp.height - height) / 2;
150 vp.width = width;
151 vp.height = height;
153 vp.flags |= VP_FLAG_ALIGN_CENTER;
154 #if LCD_DEPTH > 1
155 if (screen->depth > 1)
157 vp.drawmode = DRMODE_FG;
158 /* can't do vp.fg_pattern here, since set_foreground does a bit more on
159 * greyscale */
160 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
162 else
163 #endif
164 vp.drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID);
166 screen->fill_viewport();
168 #if LCD_DEPTH > 1
169 if (screen->depth > 1)
170 /* can't do vp.fg_pattern here, since set_foreground does a bit more on
171 * greyscale */
172 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
173 else
174 #endif
175 vp.drawmode = DRMODE_SOLID;
177 screen->draw_border_viewport();
179 /* prepare putting the text */
180 y = RECT_SPACING;
181 #else /* HAVE_LCD_CHARCELLS */
182 y = 0; /* vertical centering on 2 lines would be silly */
183 screen->clear_display();
184 #endif
186 /* print the message to screen */
187 for (i = 0; i <= line; i++, y+=h)
189 #ifdef HAVE_LCD_BITMAP
190 screen->putsxy(0, y, lines[i]);
191 #else
192 screen->puts(0, y, lines[i]);
193 #endif
195 screen->update_viewport();
196 end:
197 screen->set_viewport(NULL);
200 void splashf(int ticks, const char *fmt, ...)
202 va_list ap;
204 /* If fmt is a lang ID then get the corresponding string (which
205 still might contain % place holders). */
206 fmt = P2STR((unsigned char *)fmt);
207 FOR_NB_SCREENS(i)
209 va_start(ap, fmt);
210 splash_internal(&(screens[i]), fmt, ap);
211 va_end(ap);
213 if (ticks)
214 sleep(ticks);
217 void splash(int ticks, const char *str)
219 #if !defined(SIMULATOR) || CONFIG_CODEC == SWCODEC
220 long id;
221 /* fmt may be a so called virtual pointer. See settings.h. */
222 if((id = P2ID((const unsigned char*)str)) >= 0)
223 /* If fmt specifies a voicefont ID, and voice menus are
224 enabled, then speak it. */
225 cond_talk_ids_fq(id);
226 #endif
227 splashf(ticks, "%s", P2STR((const unsigned char*)str));