This patch adds support for SDL based framebuffer. Use the '--sdl' command line option to enable the feature.
Cc: Cyrill Gorcunov <gorcu...@gmail.com> Cc: Ingo Molnar <mi...@elte.hu> Cc: John Floren <j...@jfloren.net> Cc: Sasha Levin <levinsasha...@gmail.com> Signed-off-by: Pekka Enberg <penb...@kernel.org> --- tools/kvm/Makefile | 8 ++++ tools/kvm/config/feature-tests.mak | 10 +++++ tools/kvm/include/kvm/sdl.h | 14 +++++++ tools/kvm/kvm-run.c | 17 +++++++-- tools/kvm/ui/sdl.c | 71 ++++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 tools/kvm/include/kvm/sdl.h create mode 100644 tools/kvm/ui/sdl.c diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 17c795b..55949aa 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -71,6 +71,14 @@ ifeq ($(has_vncserver),y) LIBS += -lvncserver endif +FLAGS_SDL=$(CFLAGS) -lSDL +has_SDL := $(call try-cc,$(SOURCE_SDL),$(FLAGS_SDL)) +ifeq ($(has_SDL),y) + OBJS += ui/sdl.o + CFLAGS += -DCONFIG_HAS_SDL + LIBS += -lSDL +endif + DEPS := $(patsubst %.o,%.d,$(OBJS)) # Exclude BIOS object files from header dependencies. diff --git a/tools/kvm/config/feature-tests.mak b/tools/kvm/config/feature-tests.mak index 0801b54..bfd10ca 100644 --- a/tools/kvm/config/feature-tests.mak +++ b/tools/kvm/config/feature-tests.mak @@ -136,3 +136,13 @@ int main(void) return 0; } endef + +define SOURCE_SDL +#include <SDL/SDL.h> + +int main(void) +{ + SDL_Init(SDL_INIT_VIDEO); + return 0; +} +endef diff --git a/tools/kvm/include/kvm/sdl.h b/tools/kvm/include/kvm/sdl.h new file mode 100644 index 0000000..7057770 --- /dev/null +++ b/tools/kvm/include/kvm/sdl.h @@ -0,0 +1,14 @@ +#ifndef KVM__SDL_H +#define KVM__SDL_H + +struct framebuffer; + +#ifdef CONFIG_HAS_SDL +void sdl__init(struct framebuffer *fb); +#else +static inline void sdl__init(struct framebuffer *fb) +{ +} +#endif + +#endif /* KVM__SDL_H */ diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c index e6e180b..8398287 100644 --- a/tools/kvm/kvm-run.c +++ b/tools/kvm/kvm-run.c @@ -32,6 +32,7 @@ #include <kvm/ioeventfd.h> #include <kvm/i8042.h> #include <kvm/vnc.h> +#include <kvm/sdl.h> #include <kvm/framebuffer.h> /* header files for gitish interface */ @@ -72,6 +73,7 @@ static const char *virtio_9p_dir; static bool single_step; static bool readonly_image[MAX_DISK_IMAGES]; static bool vnc; +static bool sdl; extern bool ioport_debug; extern int active_console; @@ -117,6 +119,7 @@ static const struct option options[] = { OPT_STRING('\0', "virtio-9p", &virtio_9p_dir, "root dir", "Enable 9p over virtio"), OPT_BOOLEAN('\0', "vnc", &vnc, "Enable VNC framebuffer"), + OPT_BOOLEAN('\0', "sdl", &sdl, "Enable SDL framebuffer"), OPT_GROUP("Kernel options:"), OPT_STRING('k', "kernel", &kernel_filename, "kernel", @@ -538,7 +541,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) memset(real_cmdline, 0, sizeof(real_cmdline)); strcpy(real_cmdline, "notsc noapic noacpi pci=conf1"); - if (vnc) { + if (vnc || sdl) { strcat(real_cmdline, " video=vesafb console=tty0"); vidmode = 0x312; } else { @@ -630,13 +633,19 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) kvm__init_ram(kvm); + if (vnc || sdl) + fb = vesa__init(kvm); + if (vnc) { kbd__init(kvm); - fb = vesa__init(kvm); + if (fb) + vnc__init(fb); } - if (fb) - vnc__init(fb); + if (sdl) { + if (fb) + sdl__init(fb); + } fb__start(); diff --git a/tools/kvm/ui/sdl.c b/tools/kvm/ui/sdl.c new file mode 100644 index 0000000..8bc3f68 --- /dev/null +++ b/tools/kvm/ui/sdl.c @@ -0,0 +1,71 @@ +#include "kvm/sdl.h" + +#include "kvm/framebuffer.h" +#include "kvm/util.h" + +#include <SDL/SDL.h> +#include <pthread.h> + +static void sdl__write(struct framebuffer *fb, u64 addr, u8 *data, u32 len) +{ + memcpy(&fb->mem[addr - fb->mem_addr], data, len); +} + +static void *sdl__thread(void *p) +{ + Uint32 rmask, gmask, bmask, amask; + struct framebuffer *fb = p; + SDL_Surface *guest_screen; + SDL_Surface *screen; + SDL_Event ev; + + if (SDL_Init(SDL_INIT_VIDEO) != 0) + die("Unable to initialize SDL"); + + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0x00000000; + + guest_screen = SDL_CreateRGBSurfaceFrom(fb->mem, fb->width, fb->height, fb->depth, fb->width * fb->depth / 8, rmask, gmask, bmask, amask); + if (!guest_screen) + die("Unable to create SDL RBG surface"); + + screen = SDL_SetVideoMode(fb->width, fb->height, fb->depth, SDL_SWSURFACE); + if (!screen) + die("Unable to set SDL video mode"); + + for (;;) { + SDL_BlitSurface(guest_screen, NULL, screen, NULL); + SDL_Flip(screen); + + while (SDL_PollEvent(&ev)) { + switch (ev.type) { + case SDL_QUIT: + goto exit; + } + } + } +exit: + return NULL; +} + +static int sdl__start(struct framebuffer *fb) +{ + pthread_t thread; + + if (pthread_create(&thread, NULL, sdl__thread, fb) != 0) + return -1; + + return 0; +} + +static struct fb_target_operations sdl_ops = { + .start = sdl__start, + .write = sdl__write, +}; + +void sdl__init(struct framebuffer *fb) +{ + fb__attach(fb, &sdl_ops); +} -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html