mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-08-26 16:28:12 +00:00
kvm tools, ui: Add support for SDL framebuffer output target
This patch adds support for SDL based framebuffer. Use the '--sdl' command line option to enable the feature. Acked-by: Ingo Molnar <mingo@elte.hu> Cc: Cyrill Gorcunov <gorcunov@gmail.com> Cc: John Floren <john@jfloren.net> Cc: Sasha Levin <levinsasha928@gmail.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
committed by
Will Deacon
parent
aba1efa5fb
commit
3f838fece3
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef KVM__SDL_H
|
||||
#define KVM__SDL_H
|
||||
|
||||
#include "kvm/util.h"
|
||||
|
||||
struct framebuffer;
|
||||
|
||||
#ifdef CONFIG_HAS_SDL
|
||||
void sdl__init(struct framebuffer *fb);
|
||||
#else
|
||||
static inline void sdl__init(struct framebuffer *fb)
|
||||
{
|
||||
die("SDL support not compiled in. (install the SDL-dev[el] package)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KVM__SDL_H */
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "kvm/sdl.h"
|
||||
|
||||
#include "kvm/framebuffer.h"
|
||||
#include "kvm/util.h"
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define FRAME_RATE 25
|
||||
|
||||
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;
|
||||
Uint32 flags;
|
||||
|
||||
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");
|
||||
|
||||
flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
|
||||
|
||||
screen = SDL_SetVideoMode(fb->width, fb->height, fb->depth, flags);
|
||||
if (!screen)
|
||||
die("Unable to set SDL video mode");
|
||||
|
||||
for (;;) {
|
||||
SDL_BlitSurface(guest_screen, NULL, screen, NULL);
|
||||
SDL_UpdateRect(screen, 0, 0, 0, 0);
|
||||
while (SDL_PollEvent(&ev)) {
|
||||
switch (ev.type) {
|
||||
case SDL_QUIT:
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
SDL_Delay(1000 / FRAME_RATE);
|
||||
}
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user