* combine i2c_ack and i2c_outb
[kugel-rb.git] / apps / gui / splash.c
blob034e4a591288b195bc302740f8746d47826d4305
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"
32 #ifndef MAX
33 #define MAX(a, b) (((a)>(b))?(a):(b))
34 #endif
36 #ifdef HAVE_LCD_BITMAP
38 #define MAXLINES (LCD_HEIGHT/6)
39 #define MAXBUFFER 512
41 #else /* HAVE_LCD_CHARCELLS */
43 #define MAXLINES 2
44 #define MAXBUFFER 64
46 #endif
48 static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
50 char splash_buf[MAXBUFFER];
51 short widths[MAXLINES];
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 #ifdef HAVE_LCD_BITMAP
62 int maxw = 0;
63 #if LCD_DEPTH > 1
64 unsigned prevfg = 0;
65 #endif
67 screen->getstringsize(" ", &space_w, &h);
68 #else /* HAVE_LCD_CHARCELLS */
70 space_w = h = 1;
71 screen->double_height (false);
72 #endif
73 y = h;
75 vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
76 va_end(ap);
78 /* break splash string into display lines, doing proper word wrap */
80 next = strtok_r(splash_buf, " ", &store);
81 if (!next)
82 return; /* nothing to display */
84 lines[0] = next;
85 while (true)
87 #ifdef HAVE_LCD_BITMAP
88 screen->getstringsize(next, &w, NULL);
89 #else
90 w = utf8length(next);
91 #endif
92 if (lastbreak)
94 if (x + (next - lastbreak) * space_w + w > screen->lcdwidth)
95 { /* too wide, wrap */
96 widths[line] = x;
97 #ifdef HAVE_LCD_BITMAP
98 if (x > maxw)
99 maxw = x;
100 #endif
101 if ((y + h > screen->lcdheight) || (line >= (MAXLINES-1)))
102 break; /* screen full or out of lines */
103 x = 0;
104 y += h;
105 lines[++line] = next;
107 else
109 /* restore & calculate spacing */
110 *lastbreak = ' ';
111 x += (next - lastbreak) * space_w;
114 x += w;
115 lastbreak = next + strlen(next);
116 next = strtok_r(NULL, " ", &store);
117 if (!next)
118 { /* no more words */
119 widths[line] = x;
120 #ifdef HAVE_LCD_BITMAP
121 if (x > maxw)
122 maxw = x;
123 #endif
124 break;
128 /* prepare screen */
130 screen->stop_scroll();
132 #ifdef HAVE_LCD_BITMAP
133 /* If we center the display, then just clear the box we need and put
134 a nice little frame and put the text in there! */
135 y = (screen->lcdheight - y) / 2; /* height => y start position */
136 x = (screen->lcdwidth - maxw) / 2 - 2;
138 #if LCD_DEPTH > 1
139 if (screen->depth > 1)
141 prevfg = screen->get_foreground();
142 screen->set_drawmode(DRMODE_FG);
143 screen->set_foreground(
144 SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
146 else
147 #endif
148 screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
150 screen->fillrect(x, y-2, maxw+4, screen->lcdheight-y*2+4);
152 #if LCD_DEPTH > 1
153 if (screen->depth > 1)
154 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
155 else
156 #endif
157 screen->set_drawmode(DRMODE_SOLID);
159 screen->drawrect(x, y-2, maxw+4, screen->lcdheight-y*2+4);
160 #else /* HAVE_LCD_CHARCELLS */
161 y = 0; /* vertical centering on 2 lines would be silly */
162 x = 0;
163 screen->clear_display();
164 #endif
166 /* print the message to screen */
168 for (i = 0; i <= line; i++)
170 x = MAX((screen->lcdwidth - widths[i]) / 2, 0);
172 #ifdef HAVE_LCD_BITMAP
173 screen->putsxy(x, y, lines[i]);
174 #else
175 screen->puts(x, y, lines[i]);
176 #endif
177 y += h;
180 #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1)
181 if (screen->depth > 1)
183 screen->set_foreground(prevfg);
184 screen->set_drawmode(DRMODE_SOLID);
186 #endif
187 screen->update();
190 void splashf(int ticks, const char *fmt, ...)
192 va_list ap;
193 int i;
195 /* If fmt is a lang ID then get the corresponding string (which
196 still might contain % place holders). */
197 fmt = P2STR((unsigned char *)fmt);
198 FOR_NB_SCREENS(i)
200 va_start(ap, fmt);
201 screens[i].set_viewport(NULL);
202 splash_internal(&(screens[i]), fmt, ap);
203 va_end(ap);
206 if(ticks)
207 sleep(ticks);
210 void splash(int ticks, const char *str)
212 #if !defined(SIMULATOR) || CONFIG_CODEC == SWCODEC
213 long id;
214 /* fmt may be a so called virtual pointer. See settings.h. */
215 if((id = P2ID((const unsigned char*)str)) >= 0)
216 /* If fmt specifies a voicefont ID, and voice menus are
217 enabled, then speak it. */
218 cond_talk_ids_fq(id);
219 #endif
220 splashf(ticks, "%s", P2STR((const unsigned char*)str));