* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "vl.h"
+#include "qemu-common.h"
+#include "console.h"
+#include "sysemu.h"
#include <SDL.h>
#include <signal.h>
#endif
-static SDL_Surface *screen;
+static DisplayChangeListener *dcl;
+static SDL_Surface *real_screen;
+static SDL_Surface *guest_screen = NULL;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
static int last_vm_running;
static int gui_saved_grab;
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
{
+ SDL_Rect rec;
+ rec.x = x;
+ rec.y = y;
+ rec.w = w;
+ rec.h = h;
// printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
- SDL_UpdateRect(screen, x, y, w, h);
+
+ SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
+ SDL_UpdateRect(real_screen, x, y, w, h);
+}
+
+static void sdl_setdata(DisplayState *ds)
+{
+ SDL_Rect rec;
+ rec.x = 0;
+ rec.y = 0;
+ rec.w = real_screen->w;
+ rec.h = real_screen->h;
+
+ if (guest_screen != NULL) SDL_FreeSurface(guest_screen);
+
+ guest_screen = SDL_CreateRGBSurfaceFrom(ds_get_data(ds), ds_get_width(ds), ds_get_height(ds),
+ ds_get_bits_per_pixel(ds), ds_get_linesize(ds),
+ ds->surface->pf.rmask, ds->surface->pf.gmask,
+ ds->surface->pf.bmask, ds->surface->pf.amask);
}
-static void sdl_resize(DisplayState *ds, int w, int h)
+static void sdl_resize(DisplayState *ds)
{
int flags;
if (gui_noframe)
flags |= SDL_NOFRAME;
- width = w;
- height = h;
-
- again:
- screen = SDL_SetVideoMode(w, h, 0, flags);
- if (!screen) {
+ width = ds_get_width(ds);
+ height = ds_get_height(ds);
+ real_screen = SDL_SetVideoMode(width, height, 0, flags);
+ if (!real_screen) {
fprintf(stderr, "Could not open SDL display\n");
exit(1);
}
- if (!screen->pixels && (flags & SDL_HWSURFACE) && (flags & SDL_FULLSCREEN)) {
- flags &= ~SDL_HWSURFACE;
- goto again;
- }
- if (!screen->pixels) {
- fprintf(stderr, "Could not open SDL display\n");
- exit(1);
- }
- ds->data = screen->pixels;
- ds->linesize = screen->pitch;
- ds->depth = screen->format->BitsPerPixel;
- if (screen->format->Bshift > screen->format->Rshift) {
- ds->bgr = 1;
- } else {
- ds->bgr = 0;
- }
- ds->width = w;
- ds->height = h;
+ sdl_setdata(ds);
}
/* generic keyboard conversion */
{
if (guest_cursor) {
SDL_SetCursor(guest_sprite);
- SDL_WarpMouse(guest_x, guest_y);
+ if (!kbd_mouse_is_absolute() && !absolute_enabled)
+ SDL_WarpMouse(guest_x, guest_y);
} else
sdl_hide_cursor();
- SDL_WM_GrabInput(SDL_GRAB_ON);
- /* dummy read to avoid moving the mouse */
- SDL_GetRelativeMouseState(NULL, NULL);
- gui_grab = 1;
- sdl_update_caption();
+
+ if (SDL_WM_GrabInput(SDL_GRAB_ON) == SDL_GRAB_ON) {
+ gui_grab = 1;
+ sdl_update_caption();
+ } else
+ sdl_show_cursor();
}
static void sdl_grab_end(void)
sdl_update_caption();
}
-static void sdl_send_mouse_event(int dz)
+static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state)
{
- int dx, dy, state, buttons;
- state = SDL_GetRelativeMouseState(&dx, &dy);
+ int buttons;
buttons = 0;
if (state & SDL_BUTTON(SDL_BUTTON_LEFT))
buttons |= MOUSE_EVENT_LBUTTON;
absolute_enabled = 1;
}
- SDL_GetMouseState(&dx, &dy);
- dx = dx * 0x7FFF / width;
- dy = dy * 0x7FFF / height;
+ dx = x * 0x7FFF / (width - 1);
+ dy = y * 0x7FFF / (height - 1);
} else if (absolute_enabled) {
sdl_show_cursor();
absolute_enabled = 0;
} else if (guest_cursor) {
- SDL_GetMouseState(&dx, &dy);
- dx -= guest_x;
- dy -= guest_y;
- guest_x += dx;
- guest_y += dy;
+ x -= guest_x;
+ y -= guest_y;
+ guest_x += x;
+ guest_y += y;
+ dx = x;
+ dy = y;
}
kbd_mouse_event(dx, dy, dz, buttons);
static void toggle_full_screen(DisplayState *ds)
{
gui_fullscreen = !gui_fullscreen;
- sdl_resize(ds, screen->w, screen->h);
+ sdl_resize(ds);
if (gui_fullscreen) {
gui_saved_grab = gui_grab;
sdl_grab_start();
{
SDL_Event ev1, *ev = &ev1;
int mod_state;
+ int buttonstate = SDL_GetMouseState(NULL, NULL);
if (last_vm_running != vm_running) {
last_vm_running = vm_running;
}
vga_hw_update();
+ SDL_EnableUNICODE(!is_graphic_console());
while (SDL_PollEvent(ev)) {
switch (ev->type) {
case SDL_VIDEOEXPOSE:
- sdl_update(ds, 0, 0, screen->w, screen->h);
+ sdl_update(ds, 0, 0, real_screen->w, real_screen->h);
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
sdl_process_key(&ev->key);
break;
case SDL_QUIT:
- if (!no_quit) {
+ if (!no_quit)
qemu_system_shutdown_request();
- vm_start(); /* In case we're paused */
- }
break;
case SDL_MOUSEMOTION:
if (gui_grab || kbd_mouse_is_absolute() ||
absolute_enabled) {
- sdl_send_mouse_event(0);
+ sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0,
+ ev->motion.x, ev->motion.y, ev->motion.state);
}
break;
case SDL_MOUSEBUTTONDOWN:
SDL_MouseButtonEvent *bev = &ev->button;
if (!gui_grab && !kbd_mouse_is_absolute()) {
if (ev->type == SDL_MOUSEBUTTONDOWN &&
- (bev->state & SDL_BUTTON_LMASK)) {
+ (bev->button == SDL_BUTTON_LEFT)) {
/* start grabbing all events */
sdl_grab_start();
}
} else {
int dz;
dz = 0;
+ if (ev->type == SDL_MOUSEBUTTONDOWN) {
+ buttonstate |= SDL_BUTTON(bev->button);
+ } else {
+ buttonstate &= ~SDL_BUTTON(bev->button);
+ }
#ifdef SDL_BUTTON_WHEELUP
if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) {
dz = -1;
dz = 1;
}
#endif
- sdl_send_mouse_event(dz);
+ sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, buttonstate);
}
}
break;
!ev->active.gain && !gui_fullscreen_initial_grab) {
sdl_grab_end();
}
+ if (ev->active.state & SDL_APPACTIVE) {
+ if (ev->active.gain) {
+ /* Back to default interval */
+ dcl->gui_timer_interval = 0;
+ dcl->idle = 0;
+ } else {
+ /* Sleeping interval */
+ dcl->gui_timer_interval = 500;
+ dcl->idle = 1;
+ }
+ }
break;
default:
break;
static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
{
SDL_Rect dst = { x, y, w, h };
- SDL_FillRect(screen, &dst, c);
+ SDL_FillRect(real_screen, &dst, c);
}
static void sdl_mouse_warp(int x, int y, int on)
sdl_show_cursor();
if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) {
SDL_SetCursor(guest_sprite);
- SDL_WarpMouse(x, y);
+ if (!kbd_mouse_is_absolute() && !absolute_enabled)
+ SDL_WarpMouse(x, y);
}
} else if (gui_grab)
sdl_hide_cursor();
fprintf(stderr, "Could not initialize SDL - exiting\n");
exit(1);
}
-#ifndef _WIN32
- /* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
-#endif
- ds->dpy_update = sdl_update;
- ds->dpy_resize = sdl_resize;
- ds->dpy_refresh = sdl_refresh;
- ds->dpy_fill = sdl_fill;
+ dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+ dcl->dpy_update = sdl_update;
+ dcl->dpy_resize = sdl_resize;
+ dcl->dpy_refresh = sdl_refresh;
+ dcl->dpy_setdata = sdl_setdata;
+ dcl->dpy_fill = sdl_fill;
ds->mouse_set = sdl_mouse_warp;
ds->cursor_define = sdl_mouse_define;
+ register_displaychangelistener(ds, dcl);
- sdl_resize(ds, 640, 400);
sdl_update_caption();
SDL_EnableKeyRepeat(250, 50);
- SDL_EnableUNICODE(1);
gui_grab = 0;
sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);