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