diff options
Diffstat (limited to 'apps/gui')
-rw-r--r-- | apps/gui/splash.c | 187 |
1 files changed, 106 insertions, 81 deletions
diff --git a/apps/gui/splash.c b/apps/gui/splash.c index f41d174881..0995968415 100644 --- a/apps/gui/splash.c +++ b/apps/gui/splash.c | |||
@@ -18,105 +18,123 @@ | |||
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | #include "stdarg.h" | 19 | #include "stdarg.h" |
20 | #include "string.h" | 20 | #include "string.h" |
21 | #include "rbunicode.h" | ||
21 | #include "stdio.h" | 22 | #include "stdio.h" |
22 | #include "kernel.h" | 23 | #include "kernel.h" |
23 | #include "screen_access.h" | 24 | #include "screen_access.h" |
24 | 25 | ||
26 | #ifndef MAX | ||
27 | #define MAX(a, b) (((a)>(b))?(a):(b)) | ||
28 | #endif | ||
25 | 29 | ||
26 | #ifdef HAVE_LCD_BITMAP | 30 | #ifdef HAVE_LCD_BITMAP |
27 | 31 | ||
28 | #define MAXLETTERS 128 /* 16*8 */ | 32 | #define MAXLINES (LCD_HEIGHT/6) |
29 | #define MAXLINES 10 | 33 | #define MAXBUFFER 512 |
30 | 34 | ||
31 | #else | 35 | #else /* HAVE_LCD_CHARCELLS */ |
32 | 36 | ||
33 | #define MAXLETTERS 22 /* 11 * 2 */ | 37 | #define MAXLINES 2 |
34 | #define MAXLINES 2 | 38 | #define MAXBUFFER 64 |
35 | 39 | ||
36 | #endif | 40 | #endif |
37 | 41 | ||
38 | static void splash(struct screen * screen, | 42 | static void splash(struct screen * screen, bool center, |
39 | bool center, const char *fmt, va_list ap) | 43 | const char *fmt, va_list ap) |
40 | { | 44 | { |
45 | char splash_buf[MAXBUFFER]; | ||
46 | short widths[MAXLINES]; | ||
47 | char *lines[MAXLINES]; | ||
48 | |||
41 | char *next; | 49 | char *next; |
42 | char *store=NULL; | 50 | char *lastbreak = NULL; |
51 | char *store = NULL; | ||
52 | int line = 0; | ||
43 | int x = 0; | 53 | int x = 0; |
44 | int w, h = 1; | 54 | int y, i; |
45 | unsigned char splash_buf[MAXLETTERS]; | 55 | int space_w, w, h; |
46 | unsigned short widths[MAXLINES]; | ||
47 | unsigned char *text = splash_buf; | ||
48 | int line = 0, i_line = 0; | ||
49 | bool first=true; | ||
50 | #ifdef HAVE_LCD_BITMAP | 56 | #ifdef HAVE_LCD_BITMAP |
51 | int maxw=0; | 57 | int maxw = 0; |
52 | int space; | ||
53 | int y; | ||
54 | screen->getstringsize(" ", &space, &y); | ||
55 | #if LCD_DEPTH > 1 | 58 | #if LCD_DEPTH > 1 |
56 | unsigned prevbg = LCD_DEFAULT_BG; | 59 | unsigned prevbg = 0; |
57 | unsigned prevfg = LCD_DEFAULT_FG; | 60 | unsigned prevfg = 0; |
58 | #endif | 61 | #endif |
59 | #else | 62 | |
60 | screen->double_height (false); /* HAVE_LCD_CHARCELLS */ | 63 | screen->getstringsize(" ", &space_w, &h); |
61 | int space = 1; | 64 | #else /* HAVE_LCD_CHARCELLS */ |
62 | int y = 0; | 65 | |
66 | space_w = h = 1; | ||
67 | screen->double_height (false); | ||
63 | #endif | 68 | #endif |
64 | screen->stop_scroll(); | 69 | y = h; |
65 | vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap ); | 70 | |
66 | va_end( ap ); | 71 | vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap); |
67 | 72 | va_end(ap); | |
68 | /* measure sizes & concatenates tokenise words into lines. */ | 73 | |
74 | /* break splash string into display lines, doing proper word wrap */ | ||
75 | |||
69 | next = strtok_r(splash_buf, " ", &store); | 76 | next = strtok_r(splash_buf, " ", &store); |
70 | while (next) { | 77 | if (!next) |
78 | return; /* nothing to display */ | ||
79 | |||
80 | lines[0] = next; | ||
81 | while (true) | ||
82 | { | ||
71 | #ifdef HAVE_LCD_BITMAP | 83 | #ifdef HAVE_LCD_BITMAP |
72 | screen->getstringsize(next, &w, &h); | 84 | screen->getstringsize(next, &w, NULL); |
73 | #else | 85 | #else |
74 | w = strlen(next); | 86 | w = utf8length(next); |
75 | h = 1; /* store height in characters */ | ||
76 | #endif | 87 | #endif |
77 | if(!first) { | 88 | if (lastbreak) |
78 | if(x + w > screen->width) { /* Too wide, wrap */ | 89 | { |
79 | y += h; | 90 | if (x + (next - lastbreak) * space_w + w > screen->width) |
80 | line++; | 91 | { /* too wide, wrap */ |
92 | widths[line] = x; | ||
93 | #ifdef HAVE_LCD_BITMAP | ||
94 | if (x > maxw) | ||
95 | maxw = x; | ||
96 | #endif | ||
97 | if ((y + h > screen->height) || (line >= (MAXLINES-1))) | ||
98 | break; /* screen full or out of lines */ | ||
81 | x = 0; | 99 | x = 0; |
82 | if((y > (screen->height-h)) || (line > screen->nb_lines)) | 100 | y += h; |
83 | /* STOP */ | 101 | lines[++line] = next; |
84 | break; | ||
85 | } | 102 | } |
86 | else | 103 | else |
87 | next[-1] = ' '; /* re-concatenate string */ | 104 | { |
105 | /* restore & calculate spacing */ | ||
106 | *lastbreak = ' '; | ||
107 | x += (next - lastbreak) * space_w; | ||
108 | } | ||
88 | } | 109 | } |
89 | else | 110 | x += w; |
90 | first = false; | 111 | lastbreak = next + strlen(next); |
91 | 112 | next = strtok_r(NULL, " ", &store); | |
92 | x += w + space; | 113 | if (!next) |
93 | widths[line] = x - space; /* don't count the trailing space */ | 114 | { /* no more words */ |
115 | widths[line] = x; | ||
94 | #ifdef HAVE_LCD_BITMAP | 116 | #ifdef HAVE_LCD_BITMAP |
95 | /* store the widest line */ | 117 | if (x > maxw) |
96 | if(widths[line]>maxw) | 118 | maxw = x; |
97 | maxw = widths[line]; | ||
98 | #endif | 119 | #endif |
99 | next = strtok_r(NULL, " ", &store); | 120 | break; |
121 | } | ||
100 | } | 122 | } |
101 | 123 | ||
102 | if(center) { | 124 | /* prepare screen */ |
103 | #ifdef HAVE_LCD_BITMAP | ||
104 | /* Start displaying the message at position y. */ | ||
105 | y = (screen->height - y)/2; | ||
106 | #else | ||
107 | y = 0; /* vertical center on 2 lines would be silly */ | ||
108 | #endif | ||
109 | } else | ||
110 | y = 0; | ||
111 | 125 | ||
126 | screen->stop_scroll(); | ||
127 | |||
128 | #ifdef HAVE_LCD_BITMAP | ||
112 | /* If we center the display, then just clear the box we need and put | 129 | /* If we center the display, then just clear the box we need and put |
113 | a nice little frame and put the text in there! */ | 130 | a nice little frame and put the text in there! */ |
114 | #ifdef HAVE_LCD_BITMAP | 131 | if (center) |
115 | if(center && (y > 2)) { | 132 | { |
116 | int xx = (screen->width - maxw)/2 - 2; | 133 | y = (screen->height - y) / 2; /* height => y start position */ |
117 | /* The new graphics routines handle clipping, so no need to check */ | 134 | x = (screen->width - maxw) / 2 - 2; |
118 | #if LCD_DEPTH > 1 | 135 | #if LCD_DEPTH > 1 |
119 | if(screen->depth>1) { | 136 | if (screen->depth > 1) |
137 | { | ||
120 | prevbg = screen->get_background(); | 138 | prevbg = screen->get_background(); |
121 | prevfg = screen->get_foreground(); | 139 | prevfg = screen->get_foreground(); |
122 | screen->set_background(LCD_LIGHTGRAY); | 140 | screen->set_background(LCD_LIGHTGRAY); |
@@ -124,33 +142,40 @@ static void splash(struct screen * screen, | |||
124 | } | 142 | } |
125 | #endif | 143 | #endif |
126 | screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | 144 | screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); |
127 | screen->fillrect(xx, y-2, maxw+4, screen->height-y*2+4); | 145 | screen->fillrect(x, y-2, maxw+4, screen->height-y*2+4); |
128 | screen->set_drawmode(DRMODE_SOLID); | 146 | screen->set_drawmode(DRMODE_SOLID); |
129 | screen->drawrect(xx, y-2, maxw+4, screen->height-y*2+4); | 147 | screen->drawrect(x, y-2, maxw+4, screen->height-y*2+4); |
130 | } | 148 | } |
131 | else | 149 | else |
132 | #endif | 150 | { |
151 | y = 0; | ||
152 | x = 0; | ||
133 | screen->clear_display(); | 153 | screen->clear_display(); |
154 | } | ||
155 | #else /* HAVE_LCD_CHARCELLS */ | ||
156 | y = 0; /* vertical center on 2 lines would be silly */ | ||
157 | x = 0; | ||
158 | screen->clear_display(); | ||
159 | #endif | ||
160 | |||
161 | /* print the message to screen */ | ||
162 | |||
163 | for (i = 0; i <= line; i++) | ||
164 | { | ||
165 | if (center) | ||
166 | x = MAX((screen->width - widths[i]) / 2, 0); | ||
134 | 167 | ||
135 | /* print the message to screen */ | ||
136 | while(line-- >= 0) { | ||
137 | if (center) { | ||
138 | x = (screen->width-widths[i_line++])/2; | ||
139 | if(x < 0) | ||
140 | x = 0; | ||
141 | } else | ||
142 | x = 0; | ||
143 | #ifdef HAVE_LCD_BITMAP | 168 | #ifdef HAVE_LCD_BITMAP |
144 | screen->putsxy(x, y, text); | 169 | screen->putsxy(x, y, lines[i]); |
145 | #else | 170 | #else |
146 | screen->puts(x, y, text); | 171 | screen->puts(x, y, lines[i]); |
147 | #endif | 172 | #endif |
148 | text += strlen(text) + 1; | 173 | y += h; |
149 | y +=h; | 174 | } |
150 | } | ||
151 | 175 | ||
152 | #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1) | 176 | #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1) |
153 | if(screen->depth > 1) { | 177 | if (center && (screen->depth > 1)) |
178 | { | ||
154 | screen->set_background(prevbg); | 179 | screen->set_background(prevbg); |
155 | screen->set_foreground(prevfg); | 180 | screen->set_foreground(prevfg); |
156 | } | 181 | } |