X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/ae2883471b8975417a8d15464b433e8b4e41e97e..935fc175597b2f1588a8030e0b8df07973b1c1db:/sdl.c diff --git a/sdl.c b/sdl.c index 36fb07f22a..0072680f4c 100644 --- a/sdl.c +++ b/sdl.c @@ -57,6 +57,7 @@ static SDL_Cursor *guest_sprite = NULL; static uint8_t allocator; static SDL_PixelFormat host_format; static int scaling_active = 0; +static Notifier mouse_mode_notifier; static void sdl_update(DisplayState *ds, int x, int y, int w, int h) { @@ -112,7 +113,8 @@ static void do_sdl_resize(int new_width, int new_height, int bpp) height = new_height; real_screen = SDL_SetVideoMode(width, height, bpp, flags); if (!real_screen) { - fprintf(stderr, "Could not open SDL display\n"); + fprintf(stderr, "Could not open SDL display (%dx%dx%d): %s\n", width, + height, bpp, SDL_GetError()); exit(1); } } @@ -248,7 +250,7 @@ static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev) if (keysym == 92 && ev->keysym.scancode == 133) { keysym = 0xa5; } - return keysym2scancode(kbd_layout, keysym); + return keysym2scancode(kbd_layout, keysym) & SCANCODE_KEYMASK; } /* specific keyboard conversions from scan codes */ @@ -343,9 +345,9 @@ static void reset_keys(void) int i; for(i = 0; i < 256; i++) { if (modifiers_state[i]) { - if (i & 0x80) - kbd_put_keycode(0xe0); - kbd_put_keycode(i | 0x80); + if (i & SCANCODE_GREY) + kbd_put_keycode(SCANCODE_EMUL0); + kbd_put_keycode(i | SCANCODE_UP); modifiers_state[i] = 0; } } @@ -359,7 +361,7 @@ static void sdl_process_key(SDL_KeyboardEvent *ev) /* specific case */ v = 0; if (ev->type == SDL_KEYUP) - v |= 0x80; + v |= SCANCODE_UP; kbd_put_keycode(0xe1); kbd_put_keycode(0x1d | v); kbd_put_keycode(0x45 | v); @@ -392,39 +394,45 @@ static void sdl_process_key(SDL_KeyboardEvent *ev) case 0x3a: /* caps lock */ /* SDL does not send the key up event, so we generate it */ kbd_put_keycode(keycode); - kbd_put_keycode(keycode | 0x80); + kbd_put_keycode(keycode | SCANCODE_UP); return; } /* now send the key code */ - if (keycode & 0x80) - kbd_put_keycode(0xe0); + if (keycode & SCANCODE_GREY) + kbd_put_keycode(SCANCODE_EMUL0); if (ev->type == SDL_KEYUP) - kbd_put_keycode(keycode | 0x80); + kbd_put_keycode(keycode | SCANCODE_UP); else - kbd_put_keycode(keycode & 0x7f); + kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK); } static void sdl_update_caption(void) { - char buf[1024]; + char win_title[1024]; + char icon_title[1024]; const char *status = ""; if (!vm_running) status = " [Stopped]"; else if (gui_grab) { - if (!alt_grab) - status = " - Press Ctrl-Alt to exit grab"; + if (alt_grab) + status = " - Press Ctrl-Alt-Shift to exit mouse grab"; + else if (ctrl_grab) + status = " - Press Right-Ctrl to exit mouse grab"; else - status = " - Press Ctrl-Alt-Shift to exit grab"; + status = " - Press Ctrl-Alt to exit mouse grab"; } - if (qemu_name) - snprintf(buf, sizeof(buf), "QEMU (%s)%s", qemu_name, status); - else - snprintf(buf, sizeof(buf), "QEMU%s", status); + if (qemu_name) { + snprintf(win_title, sizeof(win_title), "QEMU (%s)%s", qemu_name, status); + snprintf(icon_title, sizeof(icon_title), "QEMU (%s)", qemu_name); + } else { + snprintf(win_title, sizeof(win_title), "QEMU%s", status); + snprintf(icon_title, sizeof(icon_title), "QEMU"); + } - SDL_WM_SetCaption(buf, "QEMU"); + SDL_WM_SetCaption(win_title, icon_title); } static void sdl_hide_cursor(void) @@ -479,6 +487,22 @@ static void sdl_grab_end(void) sdl_update_caption(); } +static void sdl_mouse_mode_change(Notifier *notify) +{ + if (kbd_mouse_is_absolute()) { + if (!absolute_enabled) { + sdl_hide_cursor(); + if (gui_grab) { + sdl_grab_end(); + } + absolute_enabled = 1; + } + } else if (absolute_enabled) { + sdl_show_cursor(); + absolute_enabled = 0; + } +} + static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state) { int buttons; @@ -491,19 +515,8 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state buttons |= MOUSE_EVENT_MBUTTON; if (kbd_mouse_is_absolute()) { - if (!absolute_enabled) { - sdl_hide_cursor(); - if (gui_grab) { - sdl_grab_end(); - } - absolute_enabled = 1; - } - dx = x * 0x7FFF / (width - 1); dy = y * 0x7FFF / (height - 1); - } else if (absolute_enabled) { - sdl_show_cursor(); - absolute_enabled = 0; } else if (guest_cursor) { x -= guest_x; y -= guest_y; @@ -519,6 +532,7 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state static void toggle_full_screen(DisplayState *ds) { gui_fullscreen = !gui_fullscreen; + do_sdl_resize(real_screen->w, real_screen->h, real_screen->format->BitsPerPixel); if (gui_fullscreen) { scaling_active = 0; gui_saved_grab = gui_grab; @@ -553,12 +567,14 @@ static void sdl_refresh(DisplayState *ds) case SDL_KEYDOWN: case SDL_KEYUP: if (ev->type == SDL_KEYDOWN) { - if (!alt_grab) { - mod_state = (SDL_GetModState() & gui_grab_code) == - gui_grab_code; - } else { + if (alt_grab) { mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) == (gui_grab_code | KMOD_LSHIFT); + } else if (ctrl_grab) { + mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL; + } else { + mod_state = (SDL_GetModState() & gui_grab_code) == + gui_grab_code; } gui_key_modifier_pressed = mod_state; if (gui_key_modifier_pressed) { @@ -569,6 +585,12 @@ static void sdl_refresh(DisplayState *ds) toggle_full_screen(ds); gui_keysym = 1; break; + case 0x16: /* 'u' key on US keyboard */ + scaling_active = 0; + sdl_resize(ds); + vga_hw_invalidate(); + vga_hw_update(); + break; case 0x02 ... 0x0a: /* '1' to '9' keys */ /* Reset the modifiers sent to the current console */ reset_keys(); @@ -756,46 +778,23 @@ static void sdl_mouse_warp(int x, int y, int on) guest_x = x, guest_y = y; } -static void sdl_mouse_define(int width, int height, int bpp, - int hot_x, int hot_y, - uint8_t *image, uint8_t *mask) +static void sdl_mouse_define(QEMUCursor *c) { - uint8_t sprite[256], *line; - int x, y, dst, bypl, src = 0; + uint8_t *image, *mask; + int bpl; + if (guest_sprite) SDL_FreeCursor(guest_sprite); - memset(sprite, 0, 256); - bypl = ((width * bpp + 31) >> 5) << 2; - for (y = 0, dst = 0; y < height; y ++, image += bypl) { - line = image; - for (x = 0; x < width; x ++, dst ++) { - switch (bpp) { - case 24: - src = *(line ++); src |= *(line ++); src |= *(line ++); - break; - case 16: - case 15: - src = *(line ++); src |= *(line ++); - break; - case 8: - src = *(line ++); - break; - case 4: - src = 0xf & (line[x >> 1] >> ((x & 1)) << 2); - break; - case 2: - src = 3 & (line[x >> 2] >> ((x & 3)) << 1); - break; - case 1: - src = 1 & (line[x >> 3] >> (x & 7)); - break; - } - if (!src) - sprite[dst >> 3] |= (1 << (~dst & 7)) & mask[dst >> 3]; - } - } - guest_sprite = SDL_CreateCursor(sprite, mask, width, height, hot_x, hot_y); + bpl = cursor_get_mono_bpl(c); + image = qemu_mallocz(bpl * c->height); + mask = qemu_mallocz(bpl * c->height); + cursor_get_mono_image(c, 0x000000, image); + cursor_get_mono_mask(c, 0, mask); + guest_sprite = SDL_CreateCursor(image, mask, c->width, c->height, + c->hot_x, c->hot_y); + qemu_free(image); + qemu_free(mask); if (guest_cursor && (gui_grab || kbd_mouse_is_absolute() || absolute_enabled)) @@ -830,9 +829,14 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) if (no_frame) gui_noframe = 1; + if (!full_screen) { + setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0); + } + flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE; if (SDL_Init (flags)) { - fprintf(stderr, "Could not initialize SDL - exiting\n"); + fprintf(stderr, "Could not initialize SDL(%s) - exiting\n", + SDL_GetError()); exit(1); } vi = SDL_GetVideoInfo(); @@ -853,13 +857,12 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) da->resize_displaysurface = sdl_resize_displaysurface; da->free_displaysurface = sdl_free_displaysurface; if (register_displayallocator(ds, da) == da) { - DisplaySurface *surf; - surf = sdl_create_displaysurface(ds_get_width(ds), ds_get_height(ds)); - defaultallocator_free_displaysurface(ds->surface); - ds->surface = surf; dpy_resize(ds); } + mouse_mode_notifier.notify = sdl_mouse_mode_change; + qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier); + sdl_update_caption(); SDL_EnableKeyRepeat(250, 50); gui_grab = 0;