3237ae4a4f
I'm currently running up against the limitations of the lcd_draw functions I want these functions to be able to be used on any size buffer not just buffers with a stride matching the underlying device [DONE] allow the framebuffer to be decoupled from the device framebuffer [DONE need examples] allow for some simple blit like transformations [DONE] remove the device framebuffer from the plugin api [DONE}ditto remote framebuffer [DONE] remove _viewport_get_framebuffer you can call struct *vp = lcd_set_viewport(NULL) and vp->buffer->fb_ptr while remote lcds may compile (and work in the sim) its not been tested on targets [FIXED] backdrops need work to be screen agnostic [FIXED] screen statusbar is not being combined into the main viewport correctly yet [FIXED] screen elements are displayed incorrectly after switch to void* [FIXED] core didn't restore proper viewport on splash etc. [NEEDS TESTING] remote lcd garbled data [FIXED] osd lib garbled screen on bmp_part [FIXED] grey_set_vp needs to return old viewport like lcd_set_viewport [FIXED] Viewport update now handles viewports with differing buffers/strides by copying to the main buffer [FIXED] splash on top of WPS leaves old framebuffer data (doesn't redraw) [UPDATE] refined this a bit more to have clear_viewport set the clean bit and have skin_render do its own screen clear scrolling viewports no longer trigger wps refresh also fixed a bug where guisyncyesno was displaying and then disappearing [ADDED!] New LCD macros that allow you to create properly size frame buffers in you desired size without wasting bytes (LCD_ and LCD_REMOTE_) LCD_STRIDE(w, h) same as STRIDE_MAIN LCD_FBSTRIDE(w, h) returns target specific stride for a buffer W x H LCD_NBELEMS(w, h) returns the number of fb_data sized elemenst needed for a buffer W x H LCD_NATIVE_STRIDE(s) conversion between rockbox native vertical and lcd native stride (2bitH) test_viewports.c has an example of usage [FIXED!!] 2bit targets don't respect non-native strides [FIXED] Few define snags Change-Id: I0d04c3834e464eca84a5a715743a297a0cefd0af
191 lines
5.2 KiB
C
191 lines
5.2 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) Daniel Stenberg (2002)
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
#include "stdarg.h"
|
|
#include "string.h"
|
|
#include "rbunicode.h"
|
|
#include "stdio.h"
|
|
#include "kernel.h"
|
|
#include "screen_access.h"
|
|
#include "lang.h"
|
|
#include "settings.h"
|
|
#include "talk.h"
|
|
#include "splash.h"
|
|
#include "viewport.h"
|
|
#include "strtok_r.h"
|
|
|
|
#define MAXLINES (LCD_HEIGHT/6)
|
|
#define MAXBUFFER 512
|
|
#define RECT_SPACING 2
|
|
#define SPLASH_MEMORY_INTERVAL (HZ)
|
|
|
|
static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
|
|
{
|
|
char splash_buf[MAXBUFFER];
|
|
char *lines[MAXLINES];
|
|
|
|
char *next;
|
|
char *lastbreak = NULL;
|
|
char *store = NULL;
|
|
int line = 0;
|
|
int x = 0;
|
|
int y, i;
|
|
int space_w, w, h;
|
|
struct viewport vp;
|
|
int width, height;
|
|
int maxw = 0;
|
|
|
|
viewport_set_defaults(&vp, screen->screen_type);
|
|
struct viewport *last_vp = screen->set_viewport(&vp);
|
|
|
|
screen->getstringsize(" ", &space_w, &h);
|
|
y = h;
|
|
|
|
vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
|
|
va_end(ap);
|
|
|
|
/* break splash string into display lines, doing proper word wrap */
|
|
|
|
next = strtok_r(splash_buf, " ", &store);
|
|
if (!next)
|
|
goto end; /* nothing to display */
|
|
|
|
lines[0] = next;
|
|
while (true)
|
|
{
|
|
screen->getstringsize(next, &w, NULL);
|
|
if (lastbreak)
|
|
{
|
|
if (x + (next - lastbreak) * space_w + w
|
|
> vp.width - RECT_SPACING*2)
|
|
{ /* too wide, wrap */
|
|
if (x > maxw)
|
|
maxw = x;
|
|
if ((y + h > vp.height) || (line >= (MAXLINES-1)))
|
|
break; /* screen full or out of lines */
|
|
x = 0;
|
|
y += h;
|
|
lines[++line] = next;
|
|
}
|
|
else
|
|
{
|
|
/* restore & calculate spacing */
|
|
*lastbreak = ' ';
|
|
x += (next - lastbreak) * space_w;
|
|
}
|
|
}
|
|
x += w;
|
|
lastbreak = next + strlen(next);
|
|
next = strtok_r(NULL, " ", &store);
|
|
if (!next)
|
|
{ /* no more words */
|
|
if (x > maxw)
|
|
maxw = x;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* prepare viewport
|
|
* First boundaries, then the grey filling, then the black border and finally
|
|
* the text*/
|
|
|
|
screen->scroll_stop();
|
|
|
|
width = maxw + 2*RECT_SPACING;
|
|
height = y + 2*RECT_SPACING;
|
|
|
|
if (width > vp.width)
|
|
width = vp.width;
|
|
if (height > vp.height)
|
|
height = vp.height;
|
|
|
|
vp.x += (vp.width - width) / 2;
|
|
vp.y += (vp.height - height) / 2;
|
|
vp.width = width;
|
|
vp.height = height;
|
|
|
|
vp.flags |= VP_FLAG_ALIGN_CENTER;
|
|
#if LCD_DEPTH > 1
|
|
if (screen->depth > 1)
|
|
{
|
|
vp.drawmode = DRMODE_FG;
|
|
/* can't do vp.fg_pattern here, since set_foreground does a bit more on
|
|
* greyscale */
|
|
screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
|
|
}
|
|
else
|
|
#endif
|
|
vp.drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID);
|
|
|
|
screen->fill_viewport();
|
|
|
|
#if LCD_DEPTH > 1
|
|
if (screen->depth > 1)
|
|
/* can't do vp.fg_pattern here, since set_foreground does a bit more on
|
|
* greyscale */
|
|
screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
|
|
else
|
|
#endif
|
|
vp.drawmode = DRMODE_SOLID;
|
|
|
|
screen->draw_border_viewport();
|
|
|
|
/* prepare putting the text */
|
|
y = RECT_SPACING;
|
|
|
|
/* print the message to screen */
|
|
for (i = 0; i <= line; i++, y+=h)
|
|
{
|
|
screen->putsxy(0, y, lines[i]);
|
|
}
|
|
screen->update_viewport();
|
|
end:
|
|
screen->set_viewport(last_vp);
|
|
}
|
|
|
|
void splashf(int ticks, const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
/* If fmt is a lang ID then get the corresponding string (which
|
|
still might contain % place holders). */
|
|
fmt = P2STR((unsigned char *)fmt);
|
|
FOR_NB_SCREENS(i)
|
|
{
|
|
va_start(ap, fmt);
|
|
splash_internal(&(screens[i]), fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
if (ticks)
|
|
sleep(ticks);
|
|
}
|
|
|
|
void splash(int ticks, const char *str)
|
|
{
|
|
#if !defined(SIMULATOR)
|
|
long id;
|
|
/* fmt may be a so called virtual pointer. See settings.h. */
|
|
if((id = P2ID((const unsigned char*)str)) >= 0)
|
|
/* If fmt specifies a voicefont ID, and voice menus are
|
|
enabled, then speak it. */
|
|
cond_talk_ids_fq(id);
|
|
#endif
|
|
splashf(ticks, "%s", P2STR((const unsigned char*)str));
|
|
}
|