summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-bitmap-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-bitmap-common.c')
-rw-r--r--firmware/drivers/lcd-bitmap-common.c69
1 files changed, 39 insertions, 30 deletions
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index a71f5b2862..22430d4e50 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -316,15 +316,19 @@ static struct scrollinfo* find_scrolling_line(int x, int y)
316 316
317void LCDFN(scroll_fn)(struct scrollinfo* s) 317void LCDFN(scroll_fn)(struct scrollinfo* s)
318{ 318{
319 /* with line == NULL when scrolling stops. This scroller
320 * maintains no userdata so there is nothing left to do */
321 if (!s->line)
322 return;
319 /* Fill with background/backdrop to clear area. 323 /* Fill with background/backdrop to clear area.
320 * cannot use clear_viewport_rect() since stops scrolling as well */ 324 * cannot use clear_viewport_rect() since would stop scrolling as well */
321 LCDFN(set_drawmode)(DRMODE_SOLID|DRMODE_INVERSEVID); 325 LCDFN(set_drawmode)(DRMODE_SOLID|DRMODE_INVERSEVID);
322 LCDFN(fillrect)(s->x, s->y, s->width, s->height); 326 LCDFN(fillrect)(s->x, s->y, s->width, s->height);
323 LCDFN(set_drawmode)(DRMODE_SOLID); 327 LCDFN(set_drawmode)(DRMODE_SOLID);
324 LCDFN(putsxyofs)(s->x, s->y, s->offset, s->line); 328 LCDFN(putsxyofs)(s->x, s->y, s->offset, s->line);
325} 329}
326 330
327static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, 331static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
328 int x_offset, 332 int x_offset,
329 bool linebased, 333 bool linebased,
330 void (*scroll_func)(struct scrollinfo *), 334 void (*scroll_func)(struct scrollinfo *),
@@ -336,7 +340,7 @@ static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
336 bool restart; 340 bool restart;
337 341
338 if (!string) 342 if (!string)
339 return; 343 return false;
340 344
341 /* prepare rectangle for scrolling. x and y must be calculated early 345 /* prepare rectangle for scrolling. x and y must be calculated early
342 * for find_scrolling_line() to work */ 346 * for find_scrolling_line() to work */
@@ -347,32 +351,25 @@ static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
347 width = current_vp->width - x; 351 width = current_vp->width - x;
348 352
349 if (y >= current_vp->height) 353 if (y >= current_vp->height)
350 return; 354 return false;
351 355
352 s = find_scrolling_line(x, y); 356 s = find_scrolling_line(x, y);
353 restart = !s; 357 restart = !s;
354 358
355 if (restart) {
356 /* remove any previously scrolling line at the same location */
357 LCDFN(scroll_stop_viewport_rect)(current_vp, x, y, width, height);
358 LCDFN(putsxyofs)(x, y, x_offset, string);
359
360 if (LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES))
361 return;
362 }
363
364 /* get width (pixeks) of the string */ 359 /* get width (pixeks) of the string */
365 LCDFN(getstringsize)(string, &w, &h); 360 LCDFN(getstringsize)(string, &w, &h);
366 361
367 /* check if scrolling is actually necessary (consider the actual start 362 /* Remove any previously scrolling line at the same location. If
368 * of the line) */ 363 * the string width is too small to scroll the scrolling line is
369 if (width >= w) 364 * cleared as well */
370 return; 365 if (w < width || restart) {
371 366 LCDFN(scroll_stop_viewport_rect)(current_vp, x, y, width, height);
372 if (restart) { 367 LCDFN(putsxyofs)(x, y, x_offset, string);
373 /* prepare scroll line */ 368 /* nothing to scroll, or out of scrolling lines. Either way, get out */
369 if (w < width || LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES))
370 return false;
371 /* else restarting: prepare scroll line */
374 s = &LCDFN(scroll_info).scroll[LCDFN(scroll_info).lines]; 372 s = &LCDFN(scroll_info).scroll[LCDFN(scroll_info).lines];
375 s->start_tick = current_tick + LCDFN(scroll_info).delay;
376 } 373 }
377 374
378 /* copy contents to the line buffer */ 375 /* copy contents to the line buffer */
@@ -385,9 +382,6 @@ static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
385 else 382 else
386 s->bidir = false; 383 s->bidir = false;
387 384
388 s->scroll_func = scroll_func;
389 s->userdata = data;
390
391 if (restart) { 385 if (restart) {
392 s->offset = x_offset; 386 s->offset = x_offset;
393 s->backward = false; 387 s->backward = false;
@@ -397,26 +391,41 @@ static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
397 s->width = width; 391 s->width = width;
398 s->height = height; 392 s->height = height;
399 s->vp = current_vp; 393 s->vp = current_vp;
394 s->start_tick = current_tick + LCDFN(scroll_info).delay;
400 LCDFN(scroll_info).lines++; 395 LCDFN(scroll_info).lines++;
401 } else { 396 } else {
402 /* if only the text was updated render immediately */ 397 /* not restarting, however we are about to assign new userdata;
403 LCDFN(scroll_now(s)); 398 * therefore tell the scroller that it can release the previous userdata */
399 s->line = NULL;
400 s->scroll_func(s);
404 } 401 }
402
403 s->scroll_func = scroll_func;
404 s->userdata = data;
405
406 /* if only the text was updated render immediately */
407 if (!restart)
408 LCDFN(scroll_now(s));
409
410 return true;
405} 411}
406 412
407void LCDFN(putsxy_scroll_func)(int x, int y, const unsigned char *string, 413bool LCDFN(putsxy_scroll_func)(int x, int y, const unsigned char *string,
408 void (*scroll_func)(struct scrollinfo *), 414 void (*scroll_func)(struct scrollinfo *),
409 void *data, int x_offset) 415 void *data, int x_offset)
410{ 416{
417 bool retval = false;
411 if (!scroll_func) 418 if (!scroll_func)
412 LCDFN(putsxyofs)(x, y, x_offset, string); 419 LCDFN(putsxyofs)(x, y, x_offset, string);
413 else 420 else
414 LCDFN(puts_scroll_worker)(x, y, string, x_offset, false, scroll_func, data); 421 retval = LCDFN(puts_scroll_worker)(x, y, string, x_offset, false, scroll_func, data);
422
423 return retval;
415} 424}
416 425
417void LCDFN(puts_scroll)(int x, int y, const unsigned char *string) 426bool LCDFN(puts_scroll)(int x, int y, const unsigned char *string)
418{ 427{
419 LCDFN(puts_scroll_worker)(x, y, string, 0, true, LCDFN(scroll_fn), NULL); 428 return LCDFN(puts_scroll_worker)(x, y, string, 0, true, LCDFN(scroll_fn), NULL);
420} 429}
421 430
422#if !defined(HAVE_LCD_COLOR) || !defined(MAIN_LCD) 431#if !defined(HAVE_LCD_COLOR) || !defined(MAIN_LCD)