[prev in list] [next in list] [prev in thread] [next in thread] 

List:       bochs-dev
Subject:    [Bochs-developers] [PATCH 3/3] [QEMU] Add BIOS splash image
From:       Laurent Vivier <Laurent.Vivier () bull ! net>
Date:       2008-12-16 15:20:10
Message-ID: 1229440810-12394-4-git-send-email-Laurent.Vivier () bull ! net
[Download RAW message or body]

This patch adds to qemu the function needed to display a splash image under
BIOS control through the firmware control device.

It adds a "-splash" option allowing to specify the picture file name (a .PNG)
to display. You can enable/disable a fade in, fade out and the bootmenu. The
time to display the image can be also given (in seconds).

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
 qemu/Makefile.target      |    2 +-
 qemu/configure            |   19 +++
 qemu/hw/bootmenu_pixmap.h |  231 +++++++++++++++++++++++++++++++++++++
 qemu/hw/fw_cfg.h          |    1 +
 qemu/hw/pc.c              |  276 ++++++++++++++++++++++++++++++++++++++++++++-
 qemu/sysemu.h             |    1 +
 qemu/vl.c                 |   19 +++
 7 files changed, 545 insertions(+), 4 deletions(-)
 create mode 100644 qemu/hw/bootmenu_pixmap.h

diff --git a/qemu/Makefile.target b/qemu/Makefile.target
index d6a6479..65f0252 100644
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -894,7 +894,7 @@ firmware.o: firmware.c
 endif
 
 $(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a $(DEPLIBS)
-	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) \
$(BRLAPI_LIBS) $(VDE_LIBS) +	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) \
$(COCOA_LIBS) $(PNGLITE_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS)  
 endif # !CONFIG_USER_ONLY
 
diff --git a/qemu/configure b/qemu/configure
index 1f8b9b4..7f20a4b 100755
--- a/qemu/configure
+++ b/qemu/configure
@@ -833,6 +833,19 @@ else
 fi
 
 ##########################################
+# libpnglite check
+
+cat > $TMPC << EOF
+#include <pnglite.h>
+int main(void) { (void)png_init(NULL, NULL); return 0; }
+EOF
+if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $TMPC -lz -lpnglite 2> /dev/null ; then
+    pnglite=yes
+else
+    pnglite=no
+fi
+
+##########################################
 # SDL probe
 
 sdl_too_old=no
@@ -1187,6 +1200,7 @@ echo "SDL support       $sdl"
 if test "$sdl" != "no" ; then
     echo "SDL static link   $sdl_static"
 fi
+echo "pnglite support   $pnglite"
 echo "curses support    $curses"
 echo "mingw32 support   $mingw32"
 echo "Audio drivers     $audio_drv_list"
@@ -1477,6 +1491,11 @@ if test "$cocoa" = "yes" ; then
   echo "#define CONFIG_COCOA 1" >> $config_h
   echo "CONFIG_COCOA=yes" >> $config_mak
 fi
+if test "$pnglite" = "yes" ; then
+  echo "#define CONFIG_PNGLITE 1" >> $config_h
+  echo "CONFIG_PNGLITE=yes" >> $config_mak
+  echo "PNGLITE_LIBS=-lpnglite" >> $config_mak
+fi
 if test "$curses" = "yes" ; then
   echo "#define CONFIG_CURSES 1" >> $config_h
   echo "CONFIG_CURSES=yes" >> $config_mak
diff --git a/qemu/hw/bootmenu_pixmap.h b/qemu/hw/bootmenu_pixmap.h
new file mode 100644
index 0000000..a33ddb4
--- /dev/null
+++ b/qemu/hw/bootmenu_pixmap.h
@@ -0,0 +1,231 @@
+/*  GIMP header image file format (INDEXED): /home/vivierl/Desktop/Press F12 for \
boot menu.h  */ +
+#define SPLASH_BOOTMENU_WIDTH 216
+#define SPLASH_BOOTMENU_HEIGHT 16
+
+static char bootmenu_pixmap[] = {
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,
+	0,0,1,1,0,0,0,0,0,1,1,1,1,1,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
+	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,
+	0,1,1,1,0,0,0,0,1,1,0,0,0,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,
+	1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,
+	0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,
+	1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,
+	0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,
+	0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,1,
+	1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,
+	0,1,1,1,1,1,0,0,0,1,1,1,1,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,
+	1,1,0,0,0,1,1,1,1,1,0,0,0,1,1,0,
+	1,1,1,0,0,0,1,1,0,0,1,1,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,1,1,1,1,1,0,0,0,0,1,1,1,0,1,1,
+	0,0,1,1,0,0,0,1,1,0,0,1,1,0,0,0,
+	1,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,
+	0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,
+	0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,
+	0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,1,
+	0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,
+	1,1,0,0,0,1,1,0,0,0,0,1,1,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
+	1,1,1,0,1,1,0,0,0,1,1,0,0,0,1,1,
+	0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,1,1,0,0,0,0,0,0,0,1,1,0,0,1,1,
+	0,0,1,1,1,1,1,1,1,0,0,0,1,1,0,0,
+	0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,
+	0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,
+	0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,
+	0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,
+	1,1,0,0,0,1,1,0,0,0,0,1,1,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,
+	0,1,1,0,1,1,1,1,1,1,1,0,0,0,1,1,
+	0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,
+	0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,
+	0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,
+	0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,
+	0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,
+	1,1,0,0,0,1,1,0,0,0,0,1,1,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,
+	0,1,1,0,1,1,0,0,0,0,0,0,0,0,1,1,
+	0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,
+	0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,
+	0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,
+	0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,
+	1,1,0,0,0,1,1,0,0,0,0,1,1,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,
+	0,1,1,0,1,1,0,0,0,0,0,0,0,0,1,1,
+	0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,
+	0,0,1,1,0,0,0,1,1,0,0,1,1,0,0,0,
+	1,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0,
+	0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,
+	0,0,1,1,0,0,0,0,1,1,0,0,0,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,
+	0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,0,
+	1,1,0,0,0,1,1,0,0,0,0,1,1,0,1,1,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,
+	0,1,1,0,1,1,0,0,0,1,1,0,0,0,1,1,
+	0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,
+	0,0,1,1,0,0,0,0,
+	1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,
+	0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,
+	1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,
+	0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
+	1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,
+	0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
+	1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,
+	0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,
+	0,1,1,0,0,1,1,1,1,1,0,0,0,0,1,1,
+	0,0,1,1,0,0,0,1,1,1,0,1,1,0,0,0,
+	0,0,1,1,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0
+	};
diff --git a/qemu/hw/fw_cfg.h b/qemu/hw/fw_cfg.h
index ef8f378..41fdde8 100644
--- a/qemu/hw/fw_cfg.h
+++ b/qemu/hw/fw_cfg.h
@@ -8,6 +8,7 @@
 #define FW_CFG_NOGRAPHIC        0x04
 #define FW_CFG_NB_CPUS          0x05
 #define FW_CFG_MACHINE_ID       0x06
+#define FW_CFG_SPLASH           (FW_CFG_WRITE_CHANNEL | 0x07)
 #define FW_CFG_MAX_ENTRY        0x10
 
 #define FW_CFG_WRITE_CHANNEL    0x4000
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 3cf5a73..74ba523 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -36,6 +36,9 @@
 #include "virtio-blk.h"
 #include "virtio-balloon.h"
 #include "device-assignment.h"
+#ifdef CONFIG_PNGLITE
+#include <pnglite.h>
+#endif
 
 #include "qemu-kvm.h"
 
@@ -423,7 +426,256 @@ static void bochs_bios_write(void *opaque, uint32_t addr, \
uint32_t val)  }
 }
 
-static void bochs_bios_init(void)
+#ifdef CONFIG_PNGLITE
+struct logo_header {
+    uint16_t        signature;
+    uint16_t        duration;
+    uint8_t         fadein;
+    uint8_t         fadeout;
+    uint8_t         bootmenu;
+    uint8_t         pad;
+    uint32_t        size;
+};
+
+#define LOGO_HDR_MAGIC	0x66BB
+
+struct splash_info {
+    uint16_t data;
+    DisplayState *ds;
+    int width;
+    int height;
+    struct logo_header *logo;
+};
+
+#define LOGO_CMD_NOP		0x00
+#define LOGO_CMD_SET_OFFSET	0x01
+#define LOGO_CMD_SHOW_BMP	0x02
+#define 	LOGO_SHOW_STEPS	16
+
+#define SPLASH_WIDTH    640
+#define SPLASH_HEIGHT   480
+#define SPLASH_BPP      4
+#define SPLASH_DURATION 2000
+
+#include "bootmenu_pixmap.h"
+
+static void splash_show_info(struct splash_info *info, int step)
+{
+    int i, j;
+    uint8_t *d;
+    int origin_x, origin_y;
+
+    origin_y = ds_get_height(info->ds) - SPLASH_BOOTMENU_HEIGHT;
+    origin_x = (ds_get_width(info->ds) - SPLASH_BOOTMENU_WIDTH) / 2;
+
+    d = ds_get_data(info->ds);
+    d += origin_y * ds_get_linesize(info->ds);
+    d += origin_x * ds_get_bits_per_pixel(info->ds) / 8;
+
+    for (i = 0; i < SPLASH_BOOTMENU_HEIGHT; i++) {
+        for (j = 0; j < SPLASH_BOOTMENU_WIDTH; j++ ) {
+            if (bootmenu_pixmap[i * SPLASH_BOOTMENU_WIDTH + j])
+                switch(ds_get_bits_per_pixel(info->ds)) {
+                case 32:
+                    d[j * 4] = d[j * 4 + 1] = d[j * 4 + 2] =
+                                    255 * step / LOGO_SHOW_STEPS;
+                    break;
+                case 24:
+                    d[j * 3] = d[j * 3 + 1] = d[j * 3 + 2] =
+                                    255 * step / LOGO_SHOW_STEPS;
+                    break;
+            }
+        }
+        d += ds_get_linesize(info->ds);
+    }
+
+    dpy_update(info->ds, origin_x, origin_y,
+               SPLASH_BOOTMENU_WIDTH, SPLASH_BOOTMENU_HEIGHT);
+}
+
+static void splash_show(struct splash_info *info, int step)
+{
+    int i, j;
+    uint8_t *d, *s;
+    int origin_x, origin_y;
+
+    if (ds_get_width(info->ds) < SPLASH_WIDTH ||
+        ds_get_height(info->ds) < SPLASH_HEIGHT ||
+        ds_get_bits_per_pixel(info->ds) < 24)
+	return;
+
+    origin_y = (ds_get_height(info->ds) - info->height) / 2;
+    origin_x = (ds_get_width(info->ds) - info->width) / 2;
+    d = ds_get_data(info->ds);
+    d += origin_y * ds_get_linesize(info->ds);
+    d += origin_x * ds_get_bits_per_pixel(info->ds) / 8;
+    s = (uint8_t*)info->logo + sizeof(struct logo_header);
+    for (i = 0; i < info->height; i++) {
+        for (j = 0; j < info->width; j++ ) {
+	    int r, g, b;
+            b = s[j * SPLASH_BPP + 0];
+            g = s[j * SPLASH_BPP + 1];
+            r = s[j * SPLASH_BPP + 2];
+            r = r * step / LOGO_SHOW_STEPS;
+            g = g * step / LOGO_SHOW_STEPS;
+            b = b * step / LOGO_SHOW_STEPS;
+            switch(ds_get_bits_per_pixel(info->ds)) {
+            case 32:
+                d[j * 4] = r; d[j * 4 + 1] = g; d[j * 4 + 2] = b;
+                break;
+            case 24:
+                d[j * 3] = r; d[j * 3 + 1] = g; d[j * 3] = b;
+                break;
+            }
+        }
+        s += info->width * 4;
+        d += ds_get_linesize(info->ds);
+    }
+
+    if (info->logo->bootmenu)
+        splash_show_info(info, step);
+
+    dpy_update(info->ds, origin_x, origin_y, info->width, info->height);
+}
+
+static void splash_load(struct splash_info *info)
+{
+    int len;
+    png_t png;
+    char buf[128];
+    char file[1024];
+    static const char * const params[] = { "file", "fadein", "fadeout",
+                                           "duration", "bootmenu", NULL };
+
+    if (check_params(buf, sizeof(buf), params, splash_image) < 0) {
+         fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
+                         buf, splash_image);
+         return;
+    }
+
+    if (!get_param_value(file, sizeof(file), "file", splash_image))
+        return;
+
+    /* load splash image */
+
+    png_init(qemu_malloc, qemu_free);
+
+    if (png_open_file(&png, file) != PNG_NO_ERROR)
+        return;
+
+    if (png.bpp != SPLASH_BPP || png.width > SPLASH_WIDTH ||
+        png.height > SPLASH_HEIGHT) {
+        fprintf(stderr, "qemu: splash image %s is greater than %dx%dx%d\n",
+                file, SPLASH_WIDTH, SPLASH_HEIGHT, SPLASH_BPP * 8);
+        return;
+    }
+
+    len = png.width * png.height * png.bpp + sizeof(struct logo_header);
+    info->logo = qemu_malloc(len);
+    if (info->logo == NULL) {
+        png_close_file(&png);
+        fprintf(stderr, "qemu: cannot allocate memory for %s\n", file);
+        return;
+    }
+
+    if (png_get_data(&png,
+                     (uint8_t*)info->logo +
+                     sizeof(struct logo_header)) != PNG_NO_ERROR) {
+        fprintf(stderr, "Cannot load splash screen %s\n", buf);
+        free(info->logo);
+        info->logo = NULL;
+        png_close_file(&png);
+        return;
+    }
+    png_close_file(&png);
+
+    info->width = png.width;
+    info->height = png.height;
+    info->logo->signature = cpu_to_le16(LOGO_HDR_MAGIC);
+    info->logo->size = cpu_to_le32(len);
+
+    info->logo->fadein = 1;
+    if (get_param_value(buf, sizeof(buf), "fadein", splash_image)) {
+        if (!strcmp(buf, "off"))
+            info->logo->fadein = 0;
+        else if (strcmp(buf, "on"))
+            fprintf(stderr, "qemu: '%s' invalid splash option\n", splash_image);
+    }
+
+    info->logo->fadeout = 1;
+    if (get_param_value(buf, sizeof(buf), "fadeout", splash_image)) {
+        if (!strcmp(buf, "off"))
+            info->logo->fadeout = 0;
+        else if (strcmp(buf, "on"))
+            fprintf(stderr, "qemu: '%s' invalid splash option\n", splash_image);
+    }
+
+    info->logo->bootmenu = 1;
+    if (get_param_value(buf, sizeof(buf), "bootmenu", splash_image)) {
+        if (!strcmp(buf, "off"))
+            info->logo->bootmenu = 0;
+        else if (strcmp(buf, "on"))
+            fprintf(stderr, "qemu: '%s' invalid splash option\n", splash_image);
+    }
+
+    info->logo->duration = SPLASH_DURATION;
+    if (get_param_value(buf, sizeof(buf), "duration", splash_image)) {
+        int duration = strtol(buf, NULL, 0);
+        if (duration != 0 || errno != EINVAL)
+            info->logo->duration = duration * 1000;
+    }
+}
+
+/* free splash image */
+
+static void splash_unload(struct splash_info *info)
+{
+    if (info->logo)
+        free(info->logo);
+
+    info->logo = NULL;
+}
+
+static void splash_controller(void *opaque, uint8_t *data)
+{
+    struct splash_info *info = (struct splash_info *)opaque;
+    uint16_t cmd = *(uint16_t*)data;
+
+    switch (cmd & 0x00FF) {
+
+    case LOGO_CMD_NOP:
+        break;
+
+    case LOGO_CMD_SHOW_BMP:
+        cmd >>= 8;
+        if (info->logo == NULL) {
+            splash_load(info);
+            if (info->logo == NULL)
+                break;
+        }
+        splash_show(info, cmd);
+        if (cmd == 0)
+            splash_unload(info);
+        break;
+
+    case LOGO_CMD_SET_OFFSET:
+        if (info->logo == NULL) {
+            splash_load(info);
+            if (info->logo == NULL)
+                break;
+        }
+        cmd >>= 8;
+        if (cmd >= info->logo->size)
+            break;
+        memcpy(&info->data, ((char*)info->logo) + cmd,
+               sizeof(info->data));
+        break;
+
+    }
+}
+#endif /* CONFIG_PNGLITE */
+
+static void bochs_bios_init(DisplayState *ds)
 {
     void *fw_cfg;
 
@@ -441,6 +693,24 @@ static void bochs_bios_init(void)
     fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+
+#ifdef CONFIG_PNGLITE
+    if (!nographic && splash_image) {
+        struct splash_info *splash;
+
+        splash = qemu_mallocz(sizeof(*splash));
+        if (!splash)
+            return;
+
+        splash->ds = ds;
+        splash->logo = NULL;
+
+        if (!fw_cfg_add_callback(fw_cfg, FW_CFG_SPLASH,
+                                 splash_controller, splash,
+                                 &splash->data, sizeof(splash->data)))
+            qemu_free(splash);
+    }
+#endif /* CONFIG_PNGLITE */
 }
 
 /* Generate an initial boot sector which sets state and jump to
@@ -977,8 +1247,6 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
     cpu_register_physical_memory((uint32_t)(-bios_size),
                                  bios_size, bios_offset | IO_MEM_ROM);
 
-    bochs_bios_init();
-
     cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);
     i8259 = i8259_init(cpu_irq[0]);
     ferr_irq = i8259[13];
@@ -1020,6 +1288,8 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
         }
     }
 
+    bochs_bios_init(ds);
+
     rtc_state = rtc_init(0x70, i8259[8]);
 
     qemu_register_boot_set(pc_boot_set, rtc_state);
diff --git a/qemu/sysemu.h b/qemu/sysemu.h
index 5abda5c..ff8669b 100644
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -99,6 +99,7 @@ extern int win2k_install_hack;
 extern int alt_grab;
 extern int usb_enabled;
 extern int smp_cpus;
+extern char *splash_image;
 extern int cursor_hide;
 extern int graphic_rotate;
 extern int no_quit;
diff --git a/qemu/vl.c b/qemu/vl.c
index 7b58605..01aea0f 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -228,6 +228,9 @@ int usb_enabled = 0;
 const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE];
 int assigned_devices_index;
 int smp_cpus = 1;
+#ifdef CONFIG_PNGLITE
+char *splash_image = NULL;
+#endif
 const char *vnc_display;
 int acpi_enabled = 1;
 int fd_bootchk = 1;
@@ -3986,6 +3989,11 @@ static void help(int exitcode)
 #ifdef TARGET_I386
            "-win2k-hack     use it when installing Windows 2000 to avoid a disk full \
bug\n"  #endif
+#ifdef CONFIG_PNGLITE
+           "-splash file=name.png[,fadein=on|off][,fadeout=on|off]\n"
+           "        [,bootmenu=on|off][,duration=seconds]\n"
+           "                display a splash image at BIOS startup\n"
+#endif
            "-usb            enable the USB driver (will be the default soon)\n"
            "-usbdevice name add the host or guest USB device 'name'\n"
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
@@ -4195,6 +4203,9 @@ enum {
     QEMU_OPTION_kernel_kqemu,
     QEMU_OPTION_enable_kvm,
     QEMU_OPTION_win2k_hack,
+#ifdef CONFIG_PNGLITE
+    QEMU_OPTION_splash,
+#endif
     QEMU_OPTION_usb,
     QEMU_OPTION_usbdevice,
     QEMU_OPTION_smp,
@@ -4323,6 +4334,9 @@ static const QEMUOption qemu_options[] = {
 #endif
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
     { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
+#ifdef CONFIG_PNGLITE
+    { "splash", HAS_ARG, QEMU_OPTION_splash },
+#endif
     { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
     { "smp", HAS_ARG, QEMU_OPTION_smp },
     { "vnc", HAS_ARG, QEMU_OPTION_vnc },
@@ -5234,6 +5248,11 @@ int main(int argc, char **argv)
                 win2k_install_hack = 1;
                 break;
 #endif
+#ifdef CONFIG_PNGLITE
+            case QEMU_OPTION_splash:
+                splash_image = optarg;
+                break;
+#endif
 #ifdef USE_KQEMU
             case QEMU_OPTION_no_kqemu:
                 kqemu_allowed = 0;
-- 
1.5.6.5


------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
bochs-developers mailing list
bochs-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bochs-developers


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic