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