From patchwork Fri Jun 3 15:59:39 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pekka Enberg X-Patchwork-Id: 847662 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p53FxkQI001729 for ; Fri, 3 Jun 2011 16:00:31 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753607Ab1FCP7n (ORCPT ); Fri, 3 Jun 2011 11:59:43 -0400 Received: from filtteri2.pp.htv.fi ([213.243.153.185]:38283 "EHLO filtteri2.pp.htv.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752855Ab1FCP7m (ORCPT ); Fri, 3 Jun 2011 11:59:42 -0400 Received: from localhost (localhost [127.0.0.1]) by filtteri2.pp.htv.fi (Postfix) with ESMTP id CA5201DF130; Fri, 3 Jun 2011 18:59:40 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at pp.htv.fi Received: from smtp6.welho.com ([213.243.153.40]) by localhost (filtteri2.pp.htv.fi [213.243.153.185]) (amavisd-new, port 10024) with ESMTP id 03u7KVpIKRMK; Fri, 3 Jun 2011 18:59:40 +0300 (EEST) Received: from localhost.localdomain (cs181148025.pp.htv.fi [82.181.148.25]) by smtp6.welho.com (Postfix) with ESMTP id 6B4915BC007; Fri, 3 Jun 2011 18:59:40 +0300 (EEST) From: Pekka Enberg To: kvm@vger.kernel.org Cc: Pekka Enberg , Cyrill Gorcunov , Ingo Molnar , John Floren , Sasha Levin Subject: [PATCH 3/3] kvm tools, ui: Add support for SDL framebuffer output target Date: Fri, 3 Jun 2011 18:59:39 +0300 Message-Id: <1307116779-572-3-git-send-email-penberg@kernel.org> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1307116779-572-1-git-send-email-penberg@kernel.org> References: <1307116779-572-1-git-send-email-penberg@kernel.org> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 03 Jun 2011 16:00:32 +0000 (UTC) This patch adds support for SDL based framebuffer. Use the '--sdl' command line option to enable the feature. Cc: Cyrill Gorcunov Cc: Ingo Molnar Cc: John Floren Cc: Sasha Levin Signed-off-by: Pekka Enberg Signed-off-by: John Floren Signed-off-by: Sasha Levin Signed-off-by: Pekka Enberg --- 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 + +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 #include #include +#include #include /* 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 +#include + +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); +}