[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/2][v2][QEMU] Add BIOS splash image
From: |
Laurent Vivier |
Subject: |
[Qemu-devel] [PATCH 2/2][v2][QEMU] Add BIOS splash image |
Date: |
Thu, 18 Dec 2008 15:51:37 +0100 |
This patch adds to qemu the functions 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 <address@hidden>
---
qemu/Makefile.target | 5 +-
qemu/configure | 19 +++
qemu/hw/fw_cfg.h | 1 +
qemu/hw/pc.c | 11 ++-
qemu/hw/press_f12.h | 231 +++++++++++++++++++++++++++++++++++++++
qemu/hw/splash.c | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++
qemu/hw/splash.h | 38 +++++++
qemu/qemu-doc.texi | 20 ++++
qemu/sysemu.h | 1 +
qemu/vl.c | 19 +++
10 files changed, 639 insertions(+), 3 deletions(-)
create mode 100644 qemu/hw/press_f12.h
create mode 100644 qemu/hw/splash.c
create mode 100644 qemu/hw/splash.h
Changelog:
v2: make it generic, move splash functions to their own files,
add documentation
diff --git a/qemu/Makefile.target b/qemu/Makefile.target
index 315c3c9..5887bba 100644
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -613,6 +613,9 @@ ifndef CONFIG_USER_ONLY
OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o
OBJS+=fw_cfg.o
+ifdef CONFIG_PNGLITE
+OBJS+=splash.o
+endif
ifdef CONFIG_KVM
OBJS+=kvm.o kvm-all.o
endif
@@ -865,7 +868,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 5f5264f..60523fd 100755
--- a/qemu/configure
+++ b/qemu/configure
@@ -767,6 +767,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
@@ -1145,6 +1158,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"
@@ -1437,6 +1451,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/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 2924b2a..f6979fe 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -36,6 +36,8 @@
#include "virtio-blk.h"
#include "virtio-balloon.h"
#include "device-assignment.h"
+#include "splash.h"
+#include "press_f12.h"
#include "qemu-kvm.h"
@@ -423,7 +425,7 @@ static void bochs_bios_write(void *opaque, uint32_t addr,
uint32_t val)
}
}
-static void bochs_bios_init(void)
+static void *bochs_bios_init(void)
{
void *fw_cfg;
@@ -441,6 +443,8 @@ 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);
+
+ return fw_cfg;
}
/* Generate an initial boot sector which sets state and jump to
@@ -818,6 +822,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
int index;
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
BlockDriverState *fd[MAX_FD];
+ void *fw_cfg;
if (ram_size >= 0xe0000000 ) {
above_4g_mem_size = ram_size - 0xe0000000;
@@ -977,7 +982,7 @@ 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();
+ fw_cfg = bochs_bios_init();
cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);
i8259 = i8259_init(cpu_irq[0]);
@@ -1020,6 +1025,8 @@ static void pc_init1(ram_addr_t ram_size, int
vga_ram_size,
}
}
+ splash_init(fw_cfg, ds, &press_f12_pixmap);
+
rtc_state = rtc_init(0x70, i8259[8]);
qemu_register_boot_set(pc_boot_set, rtc_state);
diff --git a/qemu/hw/press_f12.h b/qemu/hw/press_f12.h
new file mode 100644
index 0000000..0e0fe23
--- /dev/null
+++ b/qemu/hw/press_f12.h
@@ -0,0 +1,231 @@
+static struct splash_pixmap press_f12_pixmap = {
+ .width = 216,
+ .height = 16,
+ .data = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 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/splash.c b/qemu/hw/splash.c
new file mode 100644
index 0000000..0289fb3
--- /dev/null
+++ b/qemu/hw/splash.c
@@ -0,0 +1,297 @@
+/*
+ * QEMU Splash image support
+ *
+ * Copyright (c) 2008 Bull S.A.S., Laurent Vivier <address@hidden>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <pnglite.h>
+
+#include "hw.h"
+#include "fw_cfg.h"
+#include "splash.h"
+#include "console.h"
+#include "sysemu.h"
+
+struct splash_header {
+ uint16_t signature;
+ uint16_t duration;
+ uint8_t fadein;
+ uint8_t fadeout;
+ uint8_t bootmenu;
+ uint8_t pad;
+ uint32_t size;
+};
+
+#define SPLASH_MAGIC 0x66BB
+
+struct splash_info {
+ uint16_t data;
+ DisplayState *ds;
+ struct splash_pixmap *pixmap;
+ int width;
+ int height;
+ struct splash_header *logo;
+};
+
+#define SPLASH_CMD_NOP 0x00
+#define SPLASH_CMD_SET_OFFSET 0x01
+#define SPLASH_CMD_SHOW_BMP 0x02
+#define SPLASH_SHOW_STEPS 16
+
+#define SPLASH_WIDTH 640
+#define SPLASH_HEIGHT 480
+#define SPLASH_BPP 4
+#define SPLASH_DURATION 2000
+
+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) - info->pixmap->height;
+ origin_x = (ds_get_width(info->ds) - info->pixmap->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 < info->pixmap->height; i++) {
+ for (j = 0; j < info->pixmap->width; j++ ) {
+ if (info->pixmap->data[i * info->pixmap->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 / SPLASH_SHOW_STEPS;
+ break;
+ case 24:
+ d[j * 3] = d[j * 3 + 1] = d[j * 3 + 2] =
+ 255 * step / SPLASH_SHOW_STEPS;
+ break;
+ }
+ }
+ d += ds_get_linesize(info->ds);
+ }
+
+ dpy_update(info->ds, origin_x, origin_y,
+ info->pixmap->width, info->pixmap->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 splash_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 / SPLASH_SHOW_STEPS;
+ g = g * step / SPLASH_SHOW_STEPS;
+ b = b * step / SPLASH_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 splash_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 splash_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(SPLASH_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 SPLASH_CMD_NOP:
+ break;
+
+ case SPLASH_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 SPLASH_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;
+
+ }
+}
+
+void splash_init(void *fw_cfg, DisplayState *ds, struct splash_pixmap *pixmap)
+{
+ if (!nographic && splash_image) {
+ struct splash_info *splash;
+
+ splash = qemu_mallocz(sizeof(*splash));
+ if (!splash)
+ return;
+
+ splash->ds = ds;
+ splash->pixmap = pixmap;
+ splash->logo = NULL;
+
+ if (!fw_cfg_add_callback(fw_cfg, FW_CFG_SPLASH,
+ splash_controller, splash,
+ &splash->data, sizeof(splash->data)))
+ qemu_free(splash);
+ }
+}
diff --git a/qemu/hw/splash.h b/qemu/hw/splash.h
new file mode 100644
index 0000000..54f4fc7
--- /dev/null
+++ b/qemu/hw/splash.h
@@ -0,0 +1,38 @@
+/*
+ * QEMU Splash image support
+ *
+ * Copyright (c) 2008 Bull S.A.S., Laurent Vivier <address@hidden>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+struct splash_pixmap {
+ int width, height;
+ char data[];
+};
+
+#ifdef CONFIG_PNGLITE
+void splash_init(void *fw_cfg, DisplayState *ds, struct splash_pixmap *pixmap);
+#else
+static inline void splash_init(void *fw_cfg, DisplayState *ds,
+ struct splash_pixmap *pixmap)
+{
+ return;
+}
+#endif
diff --git a/qemu/qemu-doc.texi b/qemu/qemu-doc.texi
index e004a26..f0adf7c 100644
--- a/qemu/qemu-doc.texi
+++ b/qemu/qemu-doc.texi
@@ -426,6 +426,26 @@ Use it when installing Windows 2000 to avoid a disk full
bug. After
Windows 2000 is installed, you no longer need this option (this option
slows down the IDE transfers).
address@hidden -splash @var{option}[,@var{option}[,@var{option}[,...]]]
+Display a splash image at BIOS startup. This option is available only if
+libpnglite is available on your system and if your BIOS has support for
+splash image.
address@hidden @code
address@hidden address@hidden
+This option defines the image to display at BIOS startup. The file must
+be a PNG file, true color.
address@hidden address@hidden
address@hidden is "on" or "off", to enable or disable a fade in when the image
+is displayed.
address@hidden address@hidden
address@hidden is "on" or "off", to enable or disable a fade out when the image
+is cleared.
address@hidden address@hidden
address@hidden is "on" or "off", to enable or disable the boot menu.
address@hidden address@hidden
+The splash image is displayed @var{duration} seconds.
address@hidden table
+
@item -option-rom @var{file}
Load the contents of @var{file} as an option ROM.
This option is useful to load things like EtherBoot.
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 26d767a..56cc1ac 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -229,6 +229,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;
@@ -3987,6 +3990,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)
@@ -4196,6 +4204,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,
@@ -4324,6 +4335,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 },
@@ -5237,6 +5251,11 @@ int main(int argc, char **argv, char **envp)
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