#include "kvm/builtin-debug.h"
#include <linux/types.h>
+#include <linux/err.h>
#include <sys/utsname.h>
#include <sys/types.h>
if (vnc || sdl) {
if (vidmode == -1)
vidmode = 0x312;
- } else
+ } else {
vidmode = 0;
+ }
memset(real_cmdline, 0, sizeof(real_cmdline));
kvm__arch_set_cmdline(real_cmdline, vnc || sdl);
pci_shmem__init(kvm);
- if (vnc || sdl)
+ if (vnc || sdl) {
fb = vesa__init(kvm);
+ if (IS_ERR(fb)) {
+ pr_err("vesa__init() failed with error %ld\n", PTR_ERR(fb));
+ goto fail;
+ }
+ }
- if (vnc) {
- if (fb)
- vnc__init(fb);
+ if (vnc && fb) {
+ r = vnc__init(fb);
+ if (r < 0) {
+ pr_err("vnc__init() failed with error %d\n", r);
+ goto fail;
+ }
}
- if (sdl) {
- if (fb)
- sdl__init(fb);
+ if (sdl && fb) {
+ sdl__init(fb);
+ if (r < 0) {
+ pr_err("sdl__init() failed with error %d\n", r);
+ goto fail;
+ }
}
- fb__start();
+ r = fb__start();
+ if (r < 0) {
+ pr_err("fb__init() failed with error %d\n", r);
+ goto fail;
+ }
/* Device init all done; firmware init must
* come after this (it may set up device trees etc.)
#include <linux/list.h>
#include <stdlib.h>
#include <sys/mman.h>
+#include <errno.h>
static LIST_HEAD(framebuffers);
int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops)
{
if (fb->nr_targets >= FB_MAX_TARGETS)
- return -1;
+ return -ENOSPC;
fb->targets[fb->nr_targets++] = ops;
struct framebuffer *fb;
list_for_each_entry(fb, &framebuffers, node) {
+ u32 i;
+
+ for (i = 0; i < fb->nr_targets; i++)
+ if (fb->targets[i]->stop)
+ fb->targets[i]->stop(fb);
+
munmap(fb->mem, fb->mem_size);
}
}
#include "kvm/irq.h"
#include "kvm/kvm.h"
#include "kvm/pci.h"
+
#include <linux/byteorder.h>
#include <sys/mman.h>
-
+#include <linux/err.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <inttypes.h>
u16 vesa_base_addr;
u8 dev, line, pin;
char *mem;
+ int r;
- if (irq__register_device(PCI_DEVICE_ID_VESA, &dev, &pin, &line) < 0)
- return NULL;
+ r = irq__register_device(PCI_DEVICE_ID_VESA, &dev, &pin, &line);
+ if (r < 0)
+ return ERR_PTR(r);
vesa_pci_device.irq_pin = pin;
vesa_pci_device.irq_line = line;
mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
if (mem == MAP_FAILED)
- return NULL;
+ ERR_PTR(-errno);
kvm__register_mem(kvm, VESA_MEM_ADDR, VESA_MEM_SIZE, mem);
struct fb_target_operations {
int (*start)(struct framebuffer *fb);
+ int (*stop)(struct framebuffer *fb);
};
#define FB_MAX_TARGETS 2
struct framebuffer;
#ifdef CONFIG_HAS_SDL
-void sdl__init(struct framebuffer *fb);
+int sdl__init(struct framebuffer *fb);
+int sdl__exit(struct framebuffer *fb);
#else
static inline void sdl__init(struct framebuffer *fb)
{
die("SDL support not compiled in. (install the SDL-dev[el] package)");
}
+static inline void sdl__exit(struct framebuffer *fb)
+{
+ die("SDL support not compiled in. (install the SDL-dev[el] package)");
+}
#endif
#endif /* KVM__SDL_H */
struct framebuffer;
#ifdef CONFIG_HAS_VNCSERVER
-void vnc__init(struct framebuffer *fb);
+int vnc__init(struct framebuffer *fb);
+int vnc__exit(struct framebuffer *fb);
#else
-static inline void vnc__init(struct framebuffer *fb)
+static inline int vnc__init(struct framebuffer *fb)
{
+ return 0;
+}
+static inline int vnc__exit(struct framebuffer *fb)
+{
+ return 0;
}
#endif
[118] = DEFINE_ESC(0x70), /* <ins> */
[119] = DEFINE_ESC(0x71), /* <delete> */
};
+static bool running, done;
static const struct set2_scancode *to_code(u8 scancode)
{
SDL_EnableKeyRepeat(200, 50);
- for (;;) {
+ while (running) {
SDL_BlitSurface(guest_screen, NULL, screen, NULL);
SDL_Flip(screen);
SDL_Delay(1000 / FRAME_RATE);
}
+
+ if (running == false && done == false) {
+ done = true;
+ return NULL;
+ }
exit:
kvm_cpu__reboot();
{
pthread_t thread;
+ running = true;
+
if (pthread_create(&thread, NULL, sdl__thread, fb) != 0)
return -1;
return 0;
}
+static int sdl__stop(struct framebuffer *fb)
+{
+ running = false;
+ while (done == false)
+ sleep(0);
+
+ return 0;
+}
+
static struct fb_target_operations sdl_ops = {
- .start = sdl__start,
+ .start = sdl__start,
+ .start = sdl__stop,
};
-void sdl__init(struct framebuffer *fb)
+int sdl__init(struct framebuffer *fb)
+{
+ return fb__attach(fb, &sdl_ops);
+}
+
+int sdl__exit(struct framebuffer *fb)
{
- fb__attach(fb, &sdl_ops);
+ return sdl__stop(fb);
}
0x1a,
};
+static rfbScreenInfoPtr server;
static char num[10] = {
0x45, 0x16, 0x1e, 0x26, 0x2e, 0x23, 0x36, 0x3d, 0x3e, 0x46,
};
char argv[1][1] = {{0}};
int argc = 1;
- rfbScreenInfoPtr server;
-
server = rfbGetScreen(&argc, (char **) argv, fb->width, fb->height, 8, 3, 4);
server->frameBuffer = fb->mem;
server->alwaysShared = TRUE;
return 0;
}
+static int vnc__stop(struct framebuffer *fb)
+{
+ rfbShutdownServer(server, TRUE);
+
+ return 0;
+}
+
static struct fb_target_operations vnc_ops = {
- .start = vnc__start,
+ .start = vnc__start,
+ .stop = vnc__stop,
};
-void vnc__init(struct framebuffer *fb)
+int vnc__init(struct framebuffer *fb)
{
- fb__attach(fb, &vnc_ops);
+ return fb__attach(fb, &vnc_ops);
}
+
+int vnc__exit(struct framebuffer *fb)
+{
+ return vnc__stop(fb);
+}
\ No newline at end of file