diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2020-07-19 19:38:45 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2020-07-24 21:20:13 +0000 |
commit | 0c4f89370d05056faa789aa9cabcccc4e509fb9f (patch) | |
tree | 6ddf7fff0a47564db41d39927ea1acbdb03e74ee /firmware/drivers/lcd-charcell.c | |
parent | 092c340a2062fa98b7387fc5fd63578ddae7d0b6 (diff) | |
download | rockbox-0c4f89370d05056faa789aa9cabcccc4e509fb9f.tar.gz rockbox-0c4f89370d05056faa789aa9cabcccc4e509fb9f.zip |
[2/4] get rid of HAVE_LCD_CHARCELLS
HAVE_LCD_BITMAP is now redundant.
lcd_bitmap is always-on in features.txt so manual and lang strings
don't have to change
Change-Id: I08eeb20de48099ffc2dc23782711af368c2ec794
Diffstat (limited to 'firmware/drivers/lcd-charcell.c')
-rw-r--r-- | firmware/drivers/lcd-charcell.c | 599 |
1 files changed, 0 insertions, 599 deletions
diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c deleted file mode 100644 index b1f0021ff7..0000000000 --- a/firmware/drivers/lcd-charcell.c +++ /dev/null | |||
@@ -1,599 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Jens Arnold | ||
11 | * Based on the work of Alan Korr, Kjell Ericson and others | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include "config.h" | ||
25 | #include "hwcompat.h" | ||
26 | #include "stdarg.h" | ||
27 | #include "lcd.h" | ||
28 | #include "kernel.h" | ||
29 | #include "thread.h" | ||
30 | #include "string-extra.h" | ||
31 | #include <stdlib.h> | ||
32 | #include "debug.h" | ||
33 | #include "file.h" | ||
34 | #include "system.h" | ||
35 | #include "lcd-charcell.h" | ||
36 | #include "rbunicode.h" | ||
37 | #include "scroll_engine.h" | ||
38 | |||
39 | /** definitions **/ | ||
40 | |||
41 | #define VARIABLE_XCHARS 16 /* number of software user-definable characters */ | ||
42 | /* There must be mappings for this many characters in the 0xe000 unicode range | ||
43 | * in lcd-charset-<target>.c */ | ||
44 | |||
45 | #define NO_PATTERN (-1) | ||
46 | |||
47 | static int find_xchar(unsigned long ucs); | ||
48 | |||
49 | /** globals **/ | ||
50 | |||
51 | unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH]; /* The "frame"buffer */ | ||
52 | static unsigned char lcd_substbuffer[LCD_HEIGHT][LCD_WIDTH]; | ||
53 | struct pattern_info lcd_patterns[MAX_HW_PATTERNS]; | ||
54 | struct cursor_info lcd_cursor; | ||
55 | |||
56 | static unsigned char xfont_variable[VARIABLE_XCHARS][HW_PATTERN_SIZE]; | ||
57 | static bool xfont_variable_locked[VARIABLE_XCHARS]; | ||
58 | static int xspace; /* stores xhcar id of ' ' - often needed */ | ||
59 | |||
60 | static struct viewport default_vp = | ||
61 | { | ||
62 | .x = 0, | ||
63 | .y = 0, | ||
64 | .width = LCD_WIDTH, | ||
65 | .height = LCD_HEIGHT, | ||
66 | }; | ||
67 | |||
68 | static struct viewport* current_vp = &default_vp; | ||
69 | |||
70 | /* LCD init */ | ||
71 | void lcd_init (void) | ||
72 | { | ||
73 | lcd_init_device(); | ||
74 | lcd_charset_init(); | ||
75 | memset(lcd_patterns, 0, sizeof(lcd_patterns)); | ||
76 | xspace = find_xchar(' '); | ||
77 | memset(lcd_charbuffer, xchar_info[xspace].hw_char, sizeof(lcd_charbuffer)); | ||
78 | scroll_init(); | ||
79 | } | ||
80 | |||
81 | /* Viewports */ | ||
82 | |||
83 | void lcd_set_viewport(struct viewport* vp) | ||
84 | { | ||
85 | if (vp == NULL) | ||
86 | current_vp = &default_vp; | ||
87 | else | ||
88 | current_vp = vp; | ||
89 | |||
90 | #if defined(SIMULATOR) | ||
91 | /* Force the viewport to be within bounds. If this happens it should | ||
92 | * be considered an error - the viewport will not draw as it might be | ||
93 | * expected. | ||
94 | */ | ||
95 | if((unsigned) current_vp->x > (unsigned) LCD_WIDTH | ||
96 | || (unsigned) current_vp->y > (unsigned) LCD_HEIGHT | ||
97 | || current_vp->x + current_vp->width > LCD_WIDTH | ||
98 | || current_vp->y + current_vp->height > LCD_HEIGHT) | ||
99 | { | ||
100 | #if !defined(HAVE_VIEWPORT_CLIP) | ||
101 | DEBUGF("ERROR: " | ||
102 | #else | ||
103 | DEBUGF("NOTE: " | ||
104 | #endif | ||
105 | "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", | ||
106 | current_vp->x, current_vp->y, | ||
107 | current_vp->width, current_vp->height); | ||
108 | } | ||
109 | |||
110 | #endif | ||
111 | } | ||
112 | |||
113 | struct viewport *lcd_get_viewport(bool *is_default) | ||
114 | { | ||
115 | *is_default = (current_vp == &default_vp); | ||
116 | return current_vp; | ||
117 | } | ||
118 | |||
119 | void lcd_update_viewport(void) | ||
120 | { | ||
121 | lcd_update(); | ||
122 | } | ||
123 | |||
124 | void lcd_update_viewport_rect(int x, int y, int width, int height) | ||
125 | { | ||
126 | (void) x; | ||
127 | (void) y; | ||
128 | (void) width; | ||
129 | (void) height; | ||
130 | lcd_update(); | ||
131 | } | ||
132 | |||
133 | /** parameter handling **/ | ||
134 | |||
135 | int lcd_getwidth(void) | ||
136 | { | ||
137 | return current_vp->width; | ||
138 | } | ||
139 | |||
140 | int lcd_getheight(void) | ||
141 | { | ||
142 | return current_vp->height; | ||
143 | } | ||
144 | |||
145 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | ||
146 | { | ||
147 | int width = utf8length(str); | ||
148 | |||
149 | if (w) | ||
150 | *w = width; | ||
151 | if (h) | ||
152 | *h = 1; | ||
153 | |||
154 | return width; | ||
155 | } | ||
156 | |||
157 | /** low-level functions **/ | ||
158 | |||
159 | static int find_xchar(unsigned long ucs) | ||
160 | { | ||
161 | int low = 0; | ||
162 | int high = xchar_info_size - 1; | ||
163 | |||
164 | do | ||
165 | { | ||
166 | int probe = (low + high) >> 1; | ||
167 | |||
168 | if (xchar_info[probe].ucs < ucs) | ||
169 | low = probe + 1; | ||
170 | else if (xchar_info[probe].ucs > ucs) | ||
171 | high = probe - 1; | ||
172 | else | ||
173 | return probe; | ||
174 | } | ||
175 | while (low <= high); | ||
176 | |||
177 | /* Not found: return index of no-char symbol (last symbol, hardcoded). */ | ||
178 | return xchar_info_size - 1; | ||
179 | } | ||
180 | |||
181 | static int glyph_to_pat(unsigned glyph) | ||
182 | { | ||
183 | int i; | ||
184 | |||
185 | for (i = 0; i < lcd_pattern_count; i++) | ||
186 | if (lcd_patterns[i].glyph == glyph) | ||
187 | return i; | ||
188 | |||
189 | return NO_PATTERN; | ||
190 | } | ||
191 | |||
192 | static void lcd_free_pat(int pat) | ||
193 | { | ||
194 | int x, y; | ||
195 | |||
196 | if (pat != NO_PATTERN) | ||
197 | { | ||
198 | for (x = 0; x < LCD_WIDTH; x++) | ||
199 | for (y = 0; y < LCD_HEIGHT; y++) | ||
200 | if (pat == lcd_charbuffer[y][x]) | ||
201 | lcd_charbuffer[y][x] = lcd_substbuffer[y][x]; | ||
202 | |||
203 | if (lcd_cursor.enabled && pat == lcd_cursor.hw_char) | ||
204 | lcd_cursor.hw_char = lcd_cursor.subst_char; | ||
205 | |||
206 | lcd_patterns[pat].count = 0; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | static int lcd_get_free_pat(int xchar) | ||
211 | { | ||
212 | static int last_used_pat = 0; | ||
213 | |||
214 | int pat = last_used_pat; /* start from last used pattern */ | ||
215 | int least_pat = pat; /* pattern with least priority */ | ||
216 | int least_priority = lcd_patterns[pat].priority; | ||
217 | int i; | ||
218 | |||
219 | for (i = 0; i < lcd_pattern_count; i++) | ||
220 | { | ||
221 | if (++pat >= lcd_pattern_count) /* Keep 'pat' within limits */ | ||
222 | pat = 0; | ||
223 | |||
224 | if (lcd_patterns[pat].count == 0) | ||
225 | { | ||
226 | last_used_pat = pat; | ||
227 | return pat; | ||
228 | } | ||
229 | if (lcd_patterns[pat].priority < least_priority) | ||
230 | { | ||
231 | least_priority = lcd_patterns[pat].priority; | ||
232 | least_pat = pat; | ||
233 | } | ||
234 | } | ||
235 | if (xchar_info[xchar].priority > least_priority) /* prioritized char */ | ||
236 | { | ||
237 | lcd_free_pat(least_pat); | ||
238 | last_used_pat = least_pat; | ||
239 | return least_pat; | ||
240 | } | ||
241 | return NO_PATTERN; | ||
242 | } | ||
243 | |||
244 | static const unsigned char *glyph_to_pattern(unsigned glyph) | ||
245 | { | ||
246 | if (glyph & 0x8000) | ||
247 | return xfont_variable[glyph & 0x7fff]; | ||
248 | else | ||
249 | return xfont_fixed[glyph]; | ||
250 | } | ||
251 | |||
252 | static int map_xchar(int xchar, unsigned char *substitute) | ||
253 | { | ||
254 | int pat; | ||
255 | unsigned glyph; | ||
256 | |||
257 | if (xchar_info[xchar].priority > 0) /* soft char */ | ||
258 | { | ||
259 | glyph = xchar_info[xchar].glyph; | ||
260 | pat = glyph_to_pat(glyph); | ||
261 | |||
262 | if (pat == NO_PATTERN) /* not yet mapped */ | ||
263 | { | ||
264 | pat = lcd_get_free_pat(xchar); /* try to map */ | ||
265 | |||
266 | if (pat == NO_PATTERN) /* failed: just use substitute */ | ||
267 | return xchar_info[xchar].hw_char; | ||
268 | else | ||
269 | { /* define pattern */ | ||
270 | lcd_patterns[pat].priority = xchar_info[xchar].priority; | ||
271 | lcd_patterns[pat].glyph = glyph; | ||
272 | memcpy(lcd_patterns[pat].pattern, glyph_to_pattern(glyph), | ||
273 | HW_PATTERN_SIZE); | ||
274 | } | ||
275 | } | ||
276 | lcd_patterns[pat].count++; /* increase reference count */ | ||
277 | *substitute = xchar_info[xchar].hw_char; | ||
278 | return pat; | ||
279 | } | ||
280 | else /* hardware char */ | ||
281 | return xchar_info[xchar].hw_char; | ||
282 | } | ||
283 | |||
284 | static void lcd_putxchar(int x, int y, int xchar) | ||
285 | { | ||
286 | int lcd_char; | ||
287 | |||
288 | /* Adjust for viewport */ | ||
289 | x += current_vp->x; | ||
290 | y += current_vp->y; | ||
291 | |||
292 | #if defined(HAVE_VIEWPORT_CLIP) | ||
293 | if((unsigned)x > (unsigned)LCD_WIDTH || (unsigned)y > (unsigned)LCD_HEIGHT) | ||
294 | return; | ||
295 | #endif | ||
296 | |||
297 | lcd_char = lcd_charbuffer[y][x]; | ||
298 | |||
299 | if (lcd_char < lcd_pattern_count) /* old char was soft */ | ||
300 | lcd_patterns[lcd_char].count--; /* decrease old reference count */ | ||
301 | |||
302 | lcd_charbuffer[y][x] = map_xchar(xchar, &lcd_substbuffer[y][x]); | ||
303 | } | ||
304 | |||
305 | /** user-definable pattern handling **/ | ||
306 | |||
307 | unsigned long lcd_get_locked_pattern(void) | ||
308 | { | ||
309 | int i = 0; | ||
310 | |||
311 | for (i = 0; i < VARIABLE_XCHARS; i++) | ||
312 | { | ||
313 | if (!xfont_variable_locked[i]) | ||
314 | { | ||
315 | xfont_variable_locked[i] = true; | ||
316 | return 0xe000 + i; /* hard-coded */ | ||
317 | } | ||
318 | } | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | void lcd_unlock_pattern(unsigned long ucs) | ||
323 | { | ||
324 | int xchar = find_xchar(ucs); | ||
325 | unsigned glyph = xchar_info[xchar].glyph; | ||
326 | |||
327 | if (glyph & 0x8000) /* variable extended char */ | ||
328 | { | ||
329 | lcd_free_pat(glyph_to_pat(glyph)); | ||
330 | xfont_variable_locked[glyph & 0x7fff] = false; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | void lcd_define_pattern(unsigned long ucs, const char *pattern) | ||
335 | { | ||
336 | int xchar = find_xchar(ucs); | ||
337 | unsigned glyph = xchar_info[xchar].glyph; | ||
338 | int pat; | ||
339 | |||
340 | if (glyph & 0x8000) /* variable extended char */ | ||
341 | { | ||
342 | memcpy(xfont_variable[glyph & 0x7fff], pattern, HW_PATTERN_SIZE); | ||
343 | pat = glyph_to_pat(glyph); | ||
344 | if (pat != NO_PATTERN) | ||
345 | memcpy(lcd_patterns[pat].pattern, pattern, HW_PATTERN_SIZE); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | /** output functions **/ | ||
350 | |||
351 | /* Clear the whole display */ | ||
352 | void lcd_clear_display(void) | ||
353 | { | ||
354 | int x, y; | ||
355 | struct viewport* old_vp = current_vp; | ||
356 | |||
357 | lcd_scroll_stop(); | ||
358 | lcd_remove_cursor(); | ||
359 | |||
360 | /* Set the default viewport - required for lcd_putxchar */ | ||
361 | current_vp = &default_vp; | ||
362 | |||
363 | for (x = 0; x < LCD_WIDTH; x++) | ||
364 | for (y = 0; y < LCD_HEIGHT; y++) | ||
365 | lcd_putxchar(x, y, xspace); | ||
366 | |||
367 | current_vp = old_vp; | ||
368 | } | ||
369 | |||
370 | /* Clear the current viewport */ | ||
371 | void lcd_clear_viewport(void) | ||
372 | { | ||
373 | int x, y; | ||
374 | |||
375 | if (current_vp == &default_vp) | ||
376 | { | ||
377 | lcd_clear_display(); | ||
378 | } | ||
379 | else | ||
380 | { | ||
381 | /* Remove the cursor if it is within the current viewport */ | ||
382 | if (lcd_cursor.enabled && | ||
383 | (lcd_cursor.x >= current_vp->x) && | ||
384 | (lcd_cursor.x <= current_vp->x + current_vp->width) && | ||
385 | (lcd_cursor.y >= current_vp->y) && | ||
386 | (lcd_cursor.y <= current_vp->y + current_vp->height)) | ||
387 | { | ||
388 | lcd_remove_cursor(); | ||
389 | } | ||
390 | |||
391 | for (x = 0; x < current_vp->width; x++) | ||
392 | for (y = 0; y < current_vp->height; y++) | ||
393 | lcd_putxchar(x, y, xspace); | ||
394 | |||
395 | lcd_scroll_stop_viewport(current_vp); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | /* Put an unicode character at the given position */ | ||
400 | void lcd_putc(int x, int y, unsigned long ucs) | ||
401 | { | ||
402 | if ((unsigned)x >= (unsigned)current_vp->width || | ||
403 | (unsigned)y >= (unsigned)current_vp->height) | ||
404 | return; | ||
405 | |||
406 | lcd_putxchar(x, y, find_xchar(ucs)); | ||
407 | } | ||
408 | |||
409 | /* Show cursor (alternating with existing character) at the given position */ | ||
410 | void lcd_put_cursor(int x, int y, unsigned long cursor_ucs) | ||
411 | { | ||
412 | if ((unsigned)x >= (unsigned)current_vp->width || | ||
413 | (unsigned)y >= (unsigned)current_vp->height || | ||
414 | lcd_cursor.enabled) | ||
415 | return; | ||
416 | |||
417 | lcd_cursor.enabled = true; | ||
418 | lcd_cursor.visible = false; | ||
419 | lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs), &lcd_cursor.subst_char); | ||
420 | lcd_cursor.x = current_vp->x + x; | ||
421 | lcd_cursor.y = current_vp->y + y; | ||
422 | lcd_cursor.downcount = 0; | ||
423 | lcd_cursor.divider = MAX((HZ/2) / lcd_scroll_info.ticks, 1); | ||
424 | } | ||
425 | |||
426 | /* Remove the cursor */ | ||
427 | void lcd_remove_cursor(void) | ||
428 | { | ||
429 | if (lcd_cursor.enabled) | ||
430 | { | ||
431 | if (lcd_cursor.hw_char < lcd_pattern_count) /* soft char, unmap */ | ||
432 | lcd_patterns[lcd_cursor.hw_char].count--; | ||
433 | |||
434 | lcd_cursor.enabled = lcd_cursor.visible = false; | ||
435 | } | ||
436 | } | ||
437 | |||
438 | /* Put a string at a given position, skipping first ofs chars */ | ||
439 | static int lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | ||
440 | { | ||
441 | unsigned short ucs; | ||
442 | const unsigned char *utf8 = str; | ||
443 | |||
444 | while (*utf8 && x < current_vp->width) | ||
445 | { | ||
446 | utf8 = utf8decode(utf8, &ucs); | ||
447 | |||
448 | if (ofs > 0) | ||
449 | { | ||
450 | ofs--; | ||
451 | continue; | ||
452 | } | ||
453 | lcd_putxchar(x++, y, find_xchar(ucs)); | ||
454 | } | ||
455 | return x; | ||
456 | } | ||
457 | |||
458 | /* Put a string at a given position */ | ||
459 | void lcd_putsxy(int x, int y, const unsigned char *str) | ||
460 | { | ||
461 | if ((unsigned)y >= (unsigned)current_vp->height) | ||
462 | return; | ||
463 | |||
464 | lcd_putsxyofs(x, y, 0, str); | ||
465 | } | ||
466 | |||
467 | /* Formatting version of lcd_putsxy */ | ||
468 | void lcd_putsxyf(int x, int y, const unsigned char *fmt, ...) | ||
469 | { | ||
470 | va_list ap; | ||
471 | char buf[256]; | ||
472 | va_start(ap, fmt); | ||
473 | vsnprintf(buf, sizeof (buf), fmt, ap); | ||
474 | va_end(ap); | ||
475 | lcd_putsxy(x, y, buf); | ||
476 | } | ||
477 | |||
478 | /*** Line oriented text output ***/ | ||
479 | |||
480 | /* Put a string at a given char position, skipping first offset chars */ | ||
481 | void lcd_putsofs(int x, int y, const unsigned char *str, int offset) | ||
482 | { | ||
483 | if ((unsigned)y >= (unsigned)current_vp->height) | ||
484 | return; | ||
485 | |||
486 | /* make sure scrolling is turned off on the line we are updating */ | ||
487 | lcd_scroll_stop_viewport_rect(current_vp, x, y, current_vp->width - x, 1); | ||
488 | |||
489 | x = lcd_putsxyofs(x, y, offset, str); | ||
490 | while (x < current_vp->width) | ||
491 | lcd_putxchar(x++, y, xspace); | ||
492 | } | ||
493 | |||
494 | |||
495 | /* Put a string at a given char position */ | ||
496 | void lcd_puts(int x, int y, const unsigned char *str) | ||
497 | { | ||
498 | lcd_putsofs(x, y, str, 0); | ||
499 | } | ||
500 | |||
501 | /* Formatting version of lcd_puts */ | ||
502 | void lcd_putsf(int x, int y, const unsigned char *fmt, ...) | ||
503 | { | ||
504 | va_list ap; | ||
505 | char buf[256]; | ||
506 | va_start(ap, fmt); | ||
507 | vsnprintf(buf, sizeof (buf), fmt, ap); | ||
508 | va_end(ap); | ||
509 | lcd_puts(x, y, buf); | ||
510 | } | ||
511 | |||
512 | /** scrolling **/ | ||
513 | |||
514 | bool lcd_puts_scroll_worker(int x, int y, const unsigned char *string, | ||
515 | int offset, | ||
516 | void (*scroll_func)(struct scrollinfo *), void *data) | ||
517 | { | ||
518 | struct scrollinfo* s; | ||
519 | int len; | ||
520 | |||
521 | if ((unsigned)y >= (unsigned)current_vp->height) | ||
522 | return false; | ||
523 | |||
524 | /* remove any previously scrolling line at the same location */ | ||
525 | lcd_scroll_stop_viewport_rect(current_vp, x, y, current_vp->width - x, 1); | ||
526 | |||
527 | if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) | ||
528 | return false; | ||
529 | |||
530 | s = &lcd_scroll_info.scroll[lcd_scroll_info.lines]; | ||
531 | |||
532 | s->start_tick = current_tick + lcd_scroll_info.delay; | ||
533 | |||
534 | lcd_putsofs(x, y, string, offset); | ||
535 | len = utf8length(string); | ||
536 | |||
537 | if (current_vp->width - x >= len) | ||
538 | return false; | ||
539 | /* prepare scroll line */ | ||
540 | strlcpy(s->linebuffer, string, sizeof s->linebuffer); | ||
541 | |||
542 | /* scroll bidirectional or forward only depending on the string width */ | ||
543 | if (lcd_scroll_info.bidir_limit) | ||
544 | { | ||
545 | s->bidir = len < (current_vp->width) * | ||
546 | (100 + lcd_scroll_info.bidir_limit) / 100; | ||
547 | } | ||
548 | else | ||
549 | s->bidir = false; | ||
550 | |||
551 | s->scroll_func = scroll_func; | ||
552 | s->userdata = data; | ||
553 | |||
554 | s->vp = current_vp; | ||
555 | s->x = x; | ||
556 | s->y = y; | ||
557 | s->height = 1; | ||
558 | s->width = current_vp->width - x; | ||
559 | s->offset = offset; | ||
560 | s->backward = false; | ||
561 | lcd_scroll_info.lines++; | ||
562 | |||
563 | return true; | ||
564 | } | ||
565 | |||
566 | bool lcd_putsxy_scroll_func(int x, int y, const unsigned char *string, | ||
567 | void (*scroll_func)(struct scrollinfo *), | ||
568 | void *data, int x_offset) | ||
569 | { | ||
570 | bool retval = false; | ||
571 | if (!scroll_func) | ||
572 | lcd_putsxyofs(x, y, x_offset, string); | ||
573 | else | ||
574 | retval = lcd_puts_scroll_worker(x, y, string, x_offset, scroll_func, data); | ||
575 | |||
576 | return retval; | ||
577 | } | ||
578 | |||
579 | static void lcd_scroll_fn(struct scrollinfo* s) | ||
580 | { | ||
581 | /* with line == NULL when scrolling stops. This scroller | ||
582 | * maintains no userdata so there is nothing left to do */ | ||
583 | if (!s->line) | ||
584 | return; | ||
585 | lcd_putsxyofs(s->x, s->y, s->offset, s->line); | ||
586 | if (lcd_cursor.enabled) | ||
587 | { | ||
588 | if (--lcd_cursor.downcount <= 0) | ||
589 | { | ||
590 | lcd_cursor.downcount = lcd_cursor.divider; | ||
591 | lcd_cursor.visible = !lcd_cursor.visible; | ||
592 | } | ||
593 | } | ||
594 | } | ||
595 | |||
596 | bool lcd_puts_scroll(int x, int y, const unsigned char *string) | ||
597 | { | ||
598 | return lcd_puts_scroll_worker(x, y, string, 0, lcd_scroll_fn, NULL); | ||
599 | } | ||