xref: /kvmtool/ui/sdl.c (revision 3f838fece38e6c217fc6cc3a459f9c3a3ca66dab)
1 #include "kvm/sdl.h"
2 
3 #include "kvm/framebuffer.h"
4 #include "kvm/util.h"
5 
6 #include <SDL/SDL.h>
7 #include <pthread.h>
8 
9 #define FRAME_RATE		25
10 
11 static void sdl__write(struct framebuffer *fb, u64 addr, u8 *data, u32 len)
12 {
13 	memcpy(&fb->mem[addr - fb->mem_addr], data, len);
14 }
15 
16 static void *sdl__thread(void *p)
17 {
18 	Uint32 rmask, gmask, bmask, amask;
19 	struct framebuffer *fb = p;
20 	SDL_Surface *guest_screen;
21 	SDL_Surface *screen;
22 	SDL_Event ev;
23 	Uint32 flags;
24 
25 	if (SDL_Init(SDL_INIT_VIDEO) != 0)
26 		die("Unable to initialize SDL");
27 
28 	rmask = 0x000000ff;
29 	gmask = 0x0000ff00;
30 	bmask = 0x00ff0000;
31 	amask = 0x00000000;
32 
33 	guest_screen = SDL_CreateRGBSurfaceFrom(fb->mem, fb->width, fb->height, fb->depth, fb->width * fb->depth / 8, rmask, gmask, bmask, amask);
34 	if (!guest_screen)
35 		die("Unable to create SDL RBG surface");
36 
37 	flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
38 
39 	screen = SDL_SetVideoMode(fb->width, fb->height, fb->depth, flags);
40 	if (!screen)
41 		die("Unable to set SDL video mode");
42 
43 	for (;;) {
44 		SDL_BlitSurface(guest_screen, NULL, screen, NULL);
45 		SDL_UpdateRect(screen, 0, 0, 0, 0);
46 		while (SDL_PollEvent(&ev)) {
47 			switch (ev.type) {
48 			case SDL_QUIT:
49 				goto exit;
50 			}
51 		}
52 		SDL_Delay(1000 / FRAME_RATE);
53 	}
54 exit:
55 	return NULL;
56 }
57 
58 static int sdl__start(struct framebuffer *fb)
59 {
60 	pthread_t thread;
61 
62 	if (pthread_create(&thread, NULL, sdl__thread, fb) != 0)
63 		return -1;
64 
65 	return 0;
66 }
67 
68 static struct fb_target_operations sdl_ops = {
69 	.start			= sdl__start,
70 	.write			= sdl__write,
71 };
72 
73 void sdl__init(struct framebuffer *fb)
74 {
75 	fb__attach(fb, &sdl_ops);
76 }
77