summaryrefslogtreecommitdiff
path: root/apps/gui/splash.c
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2005-10-28 00:00:00 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2005-10-28 00:00:00 +0000
commit7da9477bc3401cbd90b2984f625f96f451ecaf6b (patch)
tree8aea2c154ad0f666f57c4752fa541fa539de757c /apps/gui/splash.c
parent3efa91ed03797dd533c0add6db750ade67499587 (diff)
downloadrockbox-7da9477bc3401cbd90b2984f625f96f451ecaf6b.zip
rockbox-7da9477bc3401cbd90b2984f625f96f451ecaf6b.tar.gz
rockbox-7da9477bc3401cbd90b2984f625f96f451ecaf6b.tar.bz2
rockbox-7da9477bc3401cbd90b2984f625f96f451ecaf6b.tar.xz
Initial multi screen support by Kévin Ferrare (Patch #1318081)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7666 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui/splash.c')
-rw-r--r--apps/gui/splash.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
new file mode 100644
index 0000000..a3cbb19
--- /dev/null
+++ b/apps/gui/splash.c
@@ -0,0 +1,216 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) Daniel Stenberg (2002), Kévin FERRARE (2005)
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * 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 "stdio.h"
+#include "kernel.h"
+#include "screen_access.h"
+
+
+#ifdef HAVE_LCD_BITMAP
+
+#define SPACE 3 /* pixels between words */
+#define MAXLETTERS 128 /* 16*8 */
+#define MAXLINES 10
+
+#else
+
+#define SPACE 1 /* one letter space */
+#define MAXLETTERS 22 /* 11 * 2 */
+#define MAXLINES 2
+
+#endif
+
+
+void internal_splash(struct screen * screen,
+ bool center, const char *fmt, va_list ap)
+{
+ char *next;
+ char *store=NULL;
+ int x=0;
+ int y=0;
+ int w, h;
+ unsigned char splash_buf[MAXLETTERS];
+ unsigned char widths[MAXLINES];
+ int line=0;
+ bool first=true;
+#ifdef HAVE_LCD_BITMAP
+ int maxw=0;
+#endif
+
+#ifdef HAVE_LCD_CHARCELLS
+ screen->double_height (false);
+#endif
+ vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap );
+
+ if(center) {
+ /* first a pass to measure sizes */
+ next = strtok_r(splash_buf, " ", &store);
+ while (next) {
+#ifdef HAVE_LCD_BITMAP
+ screen->getstringsize(next, &w, &h);
+#else
+ w = strlen(next);
+ h = 1; /* store height in characters */
+#endif
+ if(!first) {
+ if(x+w> screen->width) {
+ /* Too wide, wrap */
+ y+=h;
+ line++;
+ if((y > (screen->height-h)) || (line > screen->nb_lines))
+ /* STOP */
+ break;
+ x=0;
+ first=true;
+ }
+ }
+ else
+ first = false;
+
+ /* think of it as if the text was written here at position x,y
+ being w pixels/chars wide and h high */
+
+ x += w+SPACE;
+ widths[line]=x-SPACE; /* don't count the trailing space */
+#ifdef HAVE_LCD_BITMAP
+ /* store the widest line */
+ if(widths[line]>maxw)
+ maxw = widths[line];
+#endif
+ next = strtok_r(NULL, " ", &store);
+ }
+
+#ifdef HAVE_LCD_BITMAP
+ /* Start displaying the message at position y. The reason for the
+ added h here is that it isn't added until the end of lines in the
+ loop above and we always break the loop in the middle of a line. */
+ y = (screen->height - (y+h) )/2;
+#else
+ y = 0; /* vertical center on 2 lines would be silly */
+#endif
+ first=true;
+
+ /* Now recreate the string again since the strtok_r() above has ruined
+ the one we already have! Here's room for improvements! */
+ vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap );
+ }
+ va_end( ap );
+
+ if(center)
+ {
+ x = (screen->width-widths[0])/2;
+ if(x < 0)
+ x = 0;
+ }
+
+#ifdef HAVE_LCD_BITMAP
+ /* If we center the display, then just clear the box we need and put
+ a nice little frame and put the text in there! */
+ if(center && (y > 2)) {
+ int xx = (screen->width-maxw)/2 - 2;
+ /* The new graphics routines handle clipping, so no need to check */
+#if LCD_DEPTH > 1
+#ifdef HAVE_LCD_COLOR
+ screen->set_background((struct rgb){LCD_MAX_RED-1, LCD_MAX_GREEN-1,
+ LCD_MAX_BLUE-1});
+#else
+ if(screen->depth>1)
+ screen->set_background(LCD_MAX_LEVEL-1);
+#endif
+#endif
+ screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ screen->fillrect(xx, y-2, maxw+4, screen->height-y*2+4);
+ screen->set_drawmode(DRMODE_SOLID);
+ screen->drawrect(xx, y-2, maxw+4, screen->height-y*2+4);
+ }
+ else
+#endif
+ screen->clear_display();
+ line=0;
+ next = strtok_r(splash_buf, " ", &store);
+ while (next) {
+#ifdef HAVE_LCD_BITMAP
+ screen->getstringsize(next, &w, &h);
+#else
+ w = strlen(next);
+ h = 1;
+#endif
+ if(!first) {
+ if(x+w> screen->width) {
+ /* too wide */
+ y+=h;
+ line++; /* goto next line */
+ first=true;
+ if(y > (screen->height-h))
+ /* STOP */
+ break;
+ if(center) {
+ x = (screen->width-widths[line])/2;
+ if(x < 0)
+ x = 0;
+ }
+ else
+ x=0;
+ }
+ }
+ else
+ first=false;
+#ifdef HAVE_LCD_BITMAP
+ screen->putsxy(x, y, next);
+#else
+ screen->puts(x, y, next);
+#endif
+ x += w+SPACE; /* pixels space! */
+ next = strtok_r(NULL, " ", &store);
+ }
+
+#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1)
+ if(screen->depth > 1)
+ screen->set_background(LCD_WHITE);
+#endif
+#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
+ screen->update();
+#endif
+}
+
+void gui_splash(struct screen * screen, int ticks,
+ bool center, const char *fmt, ...)
+{
+ va_list ap;
+ va_start( ap, fmt );
+ internal_splash(screen, center, fmt, ap);
+ va_end( ap );
+
+ if(ticks)
+ sleep(ticks);
+}
+
+void gui_syncsplash(int ticks, bool center, const char *fmt, ...)
+{
+ va_list ap;
+ int i;
+ va_start( ap, fmt );
+ for(i=0;i<NB_SCREENS;++i)
+ internal_splash(&(screens[i]), center, fmt, ap);
+ va_end( ap );
+
+ if(ticks)
+ sleep(ticks);
+}