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