From d29c431edce6c0cd18fc5c4ecf31417c2569ae4a Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 11 Nov 2014 10:13:08 +0100 Subject: sdl: move version logic from source code to makefile Compile sdl.c / sdl2.c depending on CONFIG_SDLABI instead of compiling both and have version #ifdefs in the source code. Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- ui/Makefile.objs | 7 ++++++- ui/sdl.c | 3 --- ui/sdl2.c | 3 --- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ui/Makefile.objs b/ui/Makefile.objs index 801cba2675..b25e85f68e 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -16,7 +16,12 @@ common-obj-$(CONFIG_CURSES) += curses.o common-obj-$(CONFIG_VNC) += $(vnc-obj-y) common-obj-$(CONFIG_GTK) += gtk.o x_keymap.o -sdl.mo-objs := sdl.o sdl_zoom.o sdl2.o +ifeq ($(CONFIG_SDLABI),1.2) +sdl.mo-objs := sdl.o sdl_zoom.o +endif +ifeq ($(CONFIG_SDLABI),2.0) +sdl.mo-objs := sdl2.o +endif sdl.mo-cflags := $(SDL_CFLAGS) gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) diff --git a/ui/sdl.c b/ui/sdl.c index 94c1d9dc3a..3e9d81076b 100644 --- a/ui/sdl.c +++ b/ui/sdl.c @@ -26,8 +26,6 @@ #undef WIN32_LEAN_AND_MEAN #include - -#if SDL_MAJOR_VERSION == 1 #include #include "qemu-common.h" @@ -958,4 +956,3 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) atexit(sdl_cleanup); } -#endif diff --git a/ui/sdl2.c b/ui/sdl2.c index 1ad74baafc..45f23b15e0 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -27,8 +27,6 @@ #undef WIN32_LEAN_AND_MEAN #include - -#if SDL_MAJOR_VERSION == 2 #include #include "qemu-common.h" @@ -912,4 +910,3 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) atexit(sdl_cleanup); } -#endif -- cgit v1.2.1 From 5d0fe65078bcd6949372a49b125dded981856197 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 11 Nov 2014 10:21:24 +0100 Subject: sdl2: rename sdl2_state to sdl2_console, move to header file Create sdl2.h header file, in preparation for sdl2 code splitup. Populate it with sdl2_console struct (renamed from sdl2_state). Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- include/ui/sdl2.h | 16 ++++++++++++++ ui/sdl2.c | 63 ++++++++++++++++++++++++------------------------------- 2 files changed, 43 insertions(+), 36 deletions(-) create mode 100644 include/ui/sdl2.h diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h new file mode 100644 index 0000000000..3ad5d7d6e0 --- /dev/null +++ b/include/ui/sdl2.h @@ -0,0 +1,16 @@ +#ifndef SDL2_H +#define SDL2_H + +struct sdl2_console { + DisplayChangeListener dcl; + DisplaySurface *surface; + SDL_Texture *texture; + SDL_Window *real_window; + SDL_Renderer *real_renderer; + int idx; + int last_vm_running; /* per console for caption reasons */ + int x, y; + int hidden; +}; + +#endif /* SDL2_H */ diff --git a/ui/sdl2.c b/ui/sdl2.c index 45f23b15e0..375e1a3df4 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -32,22 +32,13 @@ #include "qemu-common.h" #include "ui/console.h" #include "ui/input.h" +#include "ui/sdl2.h" #include "sysemu/sysemu.h" #include "sdl2-keymap.h" static int sdl2_num_outputs; -static struct sdl2_state { - DisplayChangeListener dcl; - DisplaySurface *surface; - SDL_Texture *texture; - SDL_Window *real_window; - SDL_Renderer *real_renderer; - int idx; - int last_vm_running; /* per console for caption reasons */ - int x, y; - int hidden; -} *sdl2_console; +static struct sdl2_console *sdl2_console; static SDL_Surface *guest_sprite_surface; static int gui_grab; /* if true, all keyboard/mouse events are grabbed */ @@ -71,9 +62,9 @@ static SDL_Cursor *guest_sprite; static int scaling_active; static Notifier mouse_mode_notifier; -static void sdl_update_caption(struct sdl2_state *scon); +static void sdl_update_caption(struct sdl2_console *scon); -static struct sdl2_state *get_scon_from_window(uint32_t window_id) +static struct sdl2_console *get_scon_from_window(uint32_t window_id) { int i; for (i = 0; i < sdl2_num_outputs; i++) { @@ -87,7 +78,7 @@ static struct sdl2_state *get_scon_from_window(uint32_t window_id) static void sdl_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { - struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl); + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); SDL_Rect rect; DisplaySurface *surf = qemu_console_surface(dcl->con); @@ -109,7 +100,7 @@ static void sdl_update(DisplayChangeListener *dcl, SDL_RenderPresent(scon->real_renderer); } -static void do_sdl_resize(struct sdl2_state *scon, int width, int height, +static void do_sdl_resize(struct sdl2_console *scon, int width, int height, int bpp) { int flags; @@ -149,7 +140,7 @@ static void do_sdl_resize(struct sdl2_state *scon, int width, int height, static void sdl_switch(DisplayChangeListener *dcl, DisplaySurface *new_surface) { - struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl); + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); int format = 0; int idx = scon->idx; DisplaySurface *old_surface = scon->surface; @@ -191,7 +182,7 @@ static void sdl_switch(DisplayChangeListener *dcl, } } -static void reset_keys(struct sdl2_state *scon) +static void reset_keys(struct sdl2_console *scon) { QemuConsole *con = scon ? scon->dcl.con : NULL; int i; @@ -205,7 +196,7 @@ static void reset_keys(struct sdl2_state *scon) } } -static void sdl_process_key(struct sdl2_state *scon, +static void sdl_process_key(struct sdl2_console *scon, SDL_KeyboardEvent *ev) { int qcode = sdl2_scancode_to_qcode[ev->keysym.scancode]; @@ -257,7 +248,7 @@ static void sdl_process_key(struct sdl2_state *scon, } } -static void sdl_update_caption(struct sdl2_state *scon) +static void sdl_update_caption(struct sdl2_console *scon) { char win_title[1024]; char icon_title[1024]; @@ -321,7 +312,7 @@ static void sdl_show_cursor(void) } } -static void sdl_grab_start(struct sdl2_state *scon) +static void sdl_grab_start(struct sdl2_console *scon) { QemuConsole *con = scon ? scon->dcl.con : NULL; @@ -349,7 +340,7 @@ static void sdl_grab_start(struct sdl2_state *scon) sdl_update_caption(scon); } -static void sdl_grab_end(struct sdl2_state *scon) +static void sdl_grab_end(struct sdl2_console *scon) { SDL_SetWindowGrab(scon->real_window, SDL_FALSE); gui_grab = 0; @@ -357,7 +348,7 @@ static void sdl_grab_end(struct sdl2_state *scon) sdl_update_caption(scon); } -static void absolute_mouse_grab(struct sdl2_state *scon) +static void absolute_mouse_grab(struct sdl2_console *scon) { int mouse_x, mouse_y; int scr_w, scr_h; @@ -384,7 +375,7 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data) } } -static void sdl_send_mouse_event(struct sdl2_state *scon, int dx, int dy, +static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy, int x, int y, int state) { static uint32_t bmap[INPUT_BUTTON_MAX] = { @@ -407,7 +398,7 @@ static void sdl_send_mouse_event(struct sdl2_state *scon, int dx, int dy, int i; for (i = 0; i < sdl2_num_outputs; i++) { - struct sdl2_state *thiscon = &sdl2_console[i]; + struct sdl2_console *thiscon = &sdl2_console[i]; if (thiscon->real_window && thiscon->surface) { SDL_GetWindowSize(thiscon->real_window, &scr_w, &scr_h); cur_off_x = thiscon->x; @@ -441,14 +432,14 @@ static void sdl_send_mouse_event(struct sdl2_state *scon, int dx, int dy, qemu_input_event_sync(); } -static void sdl_scale(struct sdl2_state *scon, int width, int height) +static void sdl_scale(struct sdl2_console *scon, int width, int height) { int bpp = 0; do_sdl_resize(scon, width, height, bpp); scaling_active = 1; } -static void toggle_full_screen(struct sdl2_state *scon) +static void toggle_full_screen(struct sdl2_console *scon) { int width = surface_width(scon->surface); int height = surface_height(scon->surface); @@ -482,7 +473,7 @@ static void toggle_full_screen(struct sdl2_state *scon) static void handle_keydown(SDL_Event *ev) { int mod_state, win; - struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); + struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); if (alt_grab) { mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) == @@ -560,7 +551,7 @@ static void handle_keydown(SDL_Event *ev) static void handle_keyup(SDL_Event *ev) { int mod_state; - struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); + struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); if (!alt_grab) { mod_state = (ev->key.keysym.mod & gui_grab_code); @@ -590,7 +581,7 @@ static void handle_keyup(SDL_Event *ev) static void handle_textinput(SDL_Event *ev) { - struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); + struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); QemuConsole *con = scon ? scon->dcl.con : NULL; if (qemu_console_is_graphic(con)) { @@ -602,7 +593,7 @@ static void handle_textinput(SDL_Event *ev) static void handle_mousemotion(SDL_Event *ev) { int max_x, max_y; - struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); + struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); if (qemu_input_is_absolute() || absolute_enabled) { int scr_w, scr_h; @@ -629,7 +620,7 @@ static void handle_mousebutton(SDL_Event *ev) { int buttonstate = SDL_GetMouseState(NULL, NULL); SDL_MouseButtonEvent *bev; - struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); + struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); bev = &ev->button; if (!gui_grab && !qemu_input_is_absolute()) { @@ -649,7 +640,7 @@ static void handle_mousebutton(SDL_Event *ev) static void handle_mousewheel(SDL_Event *ev) { - struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); + struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); SDL_MouseWheelEvent *wev = &ev->wheel; InputButton btn; @@ -670,7 +661,7 @@ static void handle_mousewheel(SDL_Event *ev) static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) { int w, h; - struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); + struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); switch (ev->window.event) { case SDL_WINDOWEVENT_RESIZED: @@ -717,7 +708,7 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) static void sdl_refresh(DisplayChangeListener *dcl) { - struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl); + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); SDL_Event ev1, *ev = &ev1; if (scon->last_vm_running != runstate_is_running()) { @@ -766,7 +757,7 @@ static void sdl_refresh(DisplayChangeListener *dcl) static void sdl_mouse_warp(DisplayChangeListener *dcl, int x, int y, int on) { - struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl); + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); if (on) { if (!guest_cursor) { sdl_show_cursor(); @@ -871,7 +862,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) } } sdl2_num_outputs = i; - sdl2_console = g_new0(struct sdl2_state, sdl2_num_outputs); + sdl2_console = g_new0(struct sdl2_console, sdl2_num_outputs); for (i = 0; i < sdl2_num_outputs; i++) { QemuConsole *con = qemu_console_lookup_by_index(i); if (!qemu_console_is_graphic(con)) { -- cgit v1.2.1 From 8fc1a3f58f180089284c7d5c8e67b584930d19fe Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 11 Nov 2014 10:58:19 +0100 Subject: sdl2: move keyboard input code to new sdl2-input.c Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- include/ui/sdl2.h | 4 +++ ui/Makefile.objs | 2 +- ui/sdl2-input.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ui/sdl2.c | 75 ++------------------------------------ 4 files changed, 114 insertions(+), 73 deletions(-) create mode 100644 ui/sdl2-input.c diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index 3ad5d7d6e0..77d800e18f 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -13,4 +13,8 @@ struct sdl2_console { int hidden; }; +void sdl2_reset_keys(struct sdl2_console *scon); +void sdl2_process_key(struct sdl2_console *scon, + SDL_KeyboardEvent *ev); + #endif /* SDL2_H */ diff --git a/ui/Makefile.objs b/ui/Makefile.objs index b25e85f68e..011c5bb4d4 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -20,7 +20,7 @@ ifeq ($(CONFIG_SDLABI),1.2) sdl.mo-objs := sdl.o sdl_zoom.o endif ifeq ($(CONFIG_SDLABI),2.0) -sdl.mo-objs := sdl2.o +sdl.mo-objs := sdl2.o sdl2-input.o endif sdl.mo-cflags := $(SDL_CFLAGS) diff --git a/ui/sdl2-input.c b/ui/sdl2-input.c new file mode 100644 index 0000000000..a1973fc2e0 --- /dev/null +++ b/ui/sdl2-input.c @@ -0,0 +1,106 @@ +/* + * QEMU SDL display driver + * + * Copyright (c) 2003 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* Ported SDL 1.2 code to 2.0 by Dave Airlie. */ + +/* Avoid compiler warning because macro is redefined in SDL_syswm.h. */ +#undef WIN32_LEAN_AND_MEAN + +#include +#include + +#include "qemu-common.h" +#include "ui/console.h" +#include "ui/input.h" +#include "ui/sdl2.h" +#include "sysemu/sysemu.h" + +#include "sdl2-keymap.h" + +static uint8_t modifiers_state[SDL_NUM_SCANCODES]; + +void sdl2_reset_keys(struct sdl2_console *scon) +{ + QemuConsole *con = scon ? scon->dcl.con : NULL; + int i; + + for (i = 0; i < SDL_NUM_SCANCODES; i++) { + if (modifiers_state[i]) { + int qcode = sdl2_scancode_to_qcode[i]; + qemu_input_event_send_key_qcode(con, qcode, false); + modifiers_state[i] = 0; + } + } +} + +void sdl2_process_key(struct sdl2_console *scon, + SDL_KeyboardEvent *ev) +{ + int qcode = sdl2_scancode_to_qcode[ev->keysym.scancode]; + QemuConsole *con = scon ? scon->dcl.con : NULL; + + if (!qemu_console_is_graphic(con)) { + if (ev->type == SDL_KEYDOWN) { + switch (ev->keysym.scancode) { + case SDL_SCANCODE_RETURN: + kbd_put_keysym_console(con, '\n'); + break; + case SDL_SCANCODE_BACKSPACE: + kbd_put_keysym_console(con, QEMU_KEY_BACKSPACE); + break; + default: + kbd_put_qcode_console(con, qcode); + break; + } + } + return; + } + + switch (ev->keysym.scancode) { +#if 0 + case SDL_SCANCODE_NUMLOCKCLEAR: + case SDL_SCANCODE_CAPSLOCK: + /* SDL does not send the key up event, so we generate it */ + qemu_input_event_send_key_qcode(con, qcode, true); + qemu_input_event_send_key_qcode(con, qcode, false); + return; +#endif + case SDL_SCANCODE_LCTRL: + case SDL_SCANCODE_LSHIFT: + case SDL_SCANCODE_LALT: + case SDL_SCANCODE_LGUI: + case SDL_SCANCODE_RCTRL: + case SDL_SCANCODE_RSHIFT: + case SDL_SCANCODE_RALT: + case SDL_SCANCODE_RGUI: + if (ev->type == SDL_KEYUP) { + modifiers_state[ev->keysym.scancode] = 0; + } else { + modifiers_state[ev->keysym.scancode] = 1; + } + /* fall though */ + default: + qemu_input_event_send_key_qcode(con, qcode, + ev->type == SDL_KEYDOWN); + } +} diff --git a/ui/sdl2.c b/ui/sdl2.c index 375e1a3df4..b8d592fba1 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -35,8 +35,6 @@ #include "ui/sdl2.h" #include "sysemu/sysemu.h" -#include "sdl2-keymap.h" - static int sdl2_num_outputs; static struct sdl2_console *sdl2_console; @@ -52,7 +50,6 @@ static int gui_noframe; static int gui_key_modifier_pressed; static int gui_keysym; static int gui_grab_code = KMOD_LALT | KMOD_LCTRL; -static uint8_t modifiers_state[SDL_NUM_SCANCODES]; static SDL_Cursor *sdl_cursor_normal; static SDL_Cursor *sdl_cursor_hidden; static int absolute_enabled; @@ -182,72 +179,6 @@ static void sdl_switch(DisplayChangeListener *dcl, } } -static void reset_keys(struct sdl2_console *scon) -{ - QemuConsole *con = scon ? scon->dcl.con : NULL; - int i; - - for (i = 0; i < 256; i++) { - if (modifiers_state[i]) { - int qcode = sdl2_scancode_to_qcode[i]; - qemu_input_event_send_key_qcode(con, qcode, false); - modifiers_state[i] = 0; - } - } -} - -static void sdl_process_key(struct sdl2_console *scon, - SDL_KeyboardEvent *ev) -{ - int qcode = sdl2_scancode_to_qcode[ev->keysym.scancode]; - QemuConsole *con = scon ? scon->dcl.con : NULL; - - if (!qemu_console_is_graphic(con)) { - if (ev->type == SDL_KEYDOWN) { - switch (ev->keysym.scancode) { - case SDL_SCANCODE_RETURN: - kbd_put_keysym_console(con, '\n'); - break; - case SDL_SCANCODE_BACKSPACE: - kbd_put_keysym_console(con, QEMU_KEY_BACKSPACE); - break; - default: - kbd_put_qcode_console(con, qcode); - break; - } - } - return; - } - - switch (ev->keysym.scancode) { -#if 0 - case SDL_SCANCODE_NUMLOCKCLEAR: - case SDL_SCANCODE_CAPSLOCK: - /* SDL does not send the key up event, so we generate it */ - qemu_input_event_send_key_qcode(con, qcode, true); - qemu_input_event_send_key_qcode(con, qcode, false); - return; -#endif - case SDL_SCANCODE_LCTRL: - case SDL_SCANCODE_LSHIFT: - case SDL_SCANCODE_LALT: - case SDL_SCANCODE_LGUI: - case SDL_SCANCODE_RCTRL: - case SDL_SCANCODE_RSHIFT: - case SDL_SCANCODE_RALT: - case SDL_SCANCODE_RGUI: - if (ev->type == SDL_KEYUP) { - modifiers_state[ev->keysym.scancode] = 0; - } else { - modifiers_state[ev->keysym.scancode] = 1; - } - /* fall though */ - default: - qemu_input_event_send_key_qcode(con, qcode, - ev->type == SDL_KEYDOWN); - } -} - static void sdl_update_caption(struct sdl2_console *scon) { char win_title[1024]; @@ -544,7 +475,7 @@ static void handle_keydown(SDL_Event *ev) } } if (!gui_keysym) { - sdl_process_key(scon, &ev->key); + sdl2_process_key(scon, &ev->key); } } @@ -569,13 +500,13 @@ static void handle_keyup(SDL_Event *ev) } /* SDL does not send back all the modifiers key, so we must * correct it. */ - reset_keys(scon); + sdl2_reset_keys(scon); return; } gui_keysym = 0; } if (!gui_keysym) { - sdl_process_key(scon, &ev->key); + sdl2_process_key(scon, &ev->key); } } -- cgit v1.2.1 From 44f017d03e72484d47a2aefcbf452af0a9915fbc Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 11 Nov 2014 12:02:50 +0100 Subject: sdl2: turn on keyboard grabs Makes quite some keys actually go to the guest instead of being captured by the host window manager. Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- ui/sdl2.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/sdl2.c b/ui/sdl2.c index b8d592fba1..9b66017e71 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -189,11 +189,11 @@ static void sdl_update_caption(struct sdl2_console *scon) status = " [Stopped]"; } else if (gui_grab) { if (alt_grab) { - status = " - Press Ctrl-Alt-Shift to exit mouse grab"; + status = " - Press Ctrl-Alt-Shift to exit grab"; } else if (ctrl_grab) { - status = " - Press Right-Ctrl to exit mouse grab"; + status = " - Press Right-Ctrl to exit grab"; } else { - status = " - Press Ctrl-Alt to exit mouse grab"; + status = " - Press Ctrl-Alt to exit grab"; } } @@ -785,6 +785,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) SDL_GetError()); exit(1); } + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); for (i = 0;; i++) { QemuConsole *con = qemu_console_lookup_by_index(i); -- cgit v1.2.1 From f1ddebd8651c023409d3505f83416f65ce088961 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 11 Nov 2014 11:09:26 +0100 Subject: sdl2: move sdl_update to new sdl2-2d.c Create new sdl2-2d file for 2d display rendering. Move over sdl_update code, and rename to sdl2_2d_update. Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- include/ui/sdl2.h | 3 +++ ui/Makefile.objs | 2 +- ui/sdl2-2d.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ ui/sdl2.c | 35 +++++-------------------------- 4 files changed, 70 insertions(+), 31 deletions(-) create mode 100644 ui/sdl2-2d.c diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index 77d800e18f..84c27f03fa 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -17,4 +17,7 @@ void sdl2_reset_keys(struct sdl2_console *scon); void sdl2_process_key(struct sdl2_console *scon, SDL_KeyboardEvent *ev); +void sdl2_2d_update(DisplayChangeListener *dcl, + int x, int y, int w, int h); + #endif /* SDL2_H */ diff --git a/ui/Makefile.objs b/ui/Makefile.objs index 011c5bb4d4..13b5cfbe41 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -20,7 +20,7 @@ ifeq ($(CONFIG_SDLABI),1.2) sdl.mo-objs := sdl.o sdl_zoom.o endif ifeq ($(CONFIG_SDLABI),2.0) -sdl.mo-objs := sdl2.o sdl2-input.o +sdl.mo-objs := sdl2.o sdl2-input.o sdl2-2d.o endif sdl.mo-cflags := $(SDL_CFLAGS) diff --git a/ui/sdl2-2d.c b/ui/sdl2-2d.c new file mode 100644 index 0000000000..7b0039b080 --- /dev/null +++ b/ui/sdl2-2d.c @@ -0,0 +1,61 @@ +/* + * QEMU SDL display driver + * + * Copyright (c) 2003 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* Ported SDL 1.2 code to 2.0 by Dave Airlie. */ + +/* Avoid compiler warning because macro is redefined in SDL_syswm.h. */ +#undef WIN32_LEAN_AND_MEAN + +#include +#include + +#include "qemu-common.h" +#include "ui/console.h" +#include "ui/input.h" +#include "ui/sdl2.h" +#include "sysemu/sysemu.h" + +void sdl2_2d_update(DisplayChangeListener *dcl, + int x, int y, int w, int h) +{ + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); + DisplaySurface *surf = qemu_console_surface(dcl->con); + SDL_Rect rect; + + if (!surf) { + return; + } + if (!scon->texture) { + return; + } + + rect.x = x; + rect.y = y; + rect.w = w; + rect.h = h; + + SDL_UpdateTexture(scon->texture, NULL, surface_data(surf), + surface_stride(surf)); + SDL_RenderCopy(scon->real_renderer, scon->texture, &rect, &rect); + SDL_RenderPresent(scon->real_renderer); +} diff --git a/ui/sdl2.c b/ui/sdl2.c index 9b66017e71..47a757ad88 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -72,31 +72,6 @@ static struct sdl2_console *get_scon_from_window(uint32_t window_id) return NULL; } -static void sdl_update(DisplayChangeListener *dcl, - int x, int y, int w, int h) -{ - struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); - SDL_Rect rect; - DisplaySurface *surf = qemu_console_surface(dcl->con); - - if (!surf) { - return; - } - if (!scon->texture) { - return; - } - - rect.x = x; - rect.y = y; - rect.w = w; - rect.h = h; - - SDL_UpdateTexture(scon->texture, NULL, surface_data(surf), - surface_stride(surf)); - SDL_RenderCopy(scon->real_renderer, scon->texture, &rect, &rect); - SDL_RenderPresent(scon->real_renderer); -} - static void do_sdl_resize(struct sdl2_console *scon, int width, int height, int bpp) { @@ -609,7 +584,7 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) break; case SDL_WINDOWEVENT_EXPOSED: SDL_GetWindowSize(SDL_GetWindowFromID(ev->window.windowID), &w, &h); - sdl_update(dcl, 0, 0, w, h); + sdl2_2d_update(dcl, 0, 0, w, h); break; case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_ENTER: @@ -746,9 +721,9 @@ static void sdl_cleanup(void) SDL_QuitSubSystem(SDL_INIT_VIDEO); } -static const DisplayChangeListenerOps dcl_ops = { - .dpy_name = "sdl", - .dpy_gfx_update = sdl_update, +static const DisplayChangeListenerOps dcl_2d_ops = { + .dpy_name = "sdl2-2d", + .dpy_gfx_update = sdl2_2d_update, .dpy_gfx_switch = sdl_switch, .dpy_refresh = sdl_refresh, .dpy_mouse_set = sdl_mouse_warp, @@ -800,7 +775,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) if (!qemu_console_is_graphic(con)) { sdl2_console[i].hidden = true; } - sdl2_console[i].dcl.ops = &dcl_ops; + sdl2_console[i].dcl.ops = &dcl_2d_ops; sdl2_console[i].dcl.con = con; register_displaychangelistener(&sdl2_console[i].dcl); sdl2_console[i].idx = i; -- cgit v1.2.1 From 46522a82236ea0cf9011b89896d2d8f8ddaf2443 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 11 Nov 2014 13:12:02 +0100 Subject: sdl2: overhaul window size handling Split do_sdl_resize function (which does alot more than just resizing) into three: sdl2_window_{create,destroy,resize}. Fix SDL_Renderer handling: must be guest display size not host window size, and SDL2 will magically handle all scaling for us. Make fullscreen actually enter fullscreen mode and simplify the code. There is no need to store the original window size, the window manager will do that for us. Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- ui/sdl2.c | 172 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 79 insertions(+), 93 deletions(-) diff --git a/ui/sdl2.c b/ui/sdl2.c index 47a757ad88..59b67a6b3c 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -41,9 +41,6 @@ static struct sdl2_console *sdl2_console; static SDL_Surface *guest_sprite_surface; static int gui_grab; /* if true, all keyboard/mouse events are grabbed */ -static bool gui_saved_scaling; -static int gui_saved_width; -static int gui_saved_height; static int gui_saved_grab; static int gui_fullscreen; static int gui_noframe; @@ -56,7 +53,6 @@ static int absolute_enabled; static int guest_cursor; static int guest_x, guest_y; static SDL_Cursor *guest_sprite; -static int scaling_active; static Notifier mouse_mode_notifier; static void sdl_update_caption(struct sdl2_console *scon); @@ -72,86 +68,96 @@ static struct sdl2_console *get_scon_from_window(uint32_t window_id) return NULL; } -static void do_sdl_resize(struct sdl2_console *scon, int width, int height, - int bpp) +static void sdl2_window_create(struct sdl2_console *scon) { - int flags; + int flags = 0; - if (scon->real_window && scon->real_renderer) { - if (width && height) { - SDL_RenderSetLogicalSize(scon->real_renderer, width, height); - SDL_SetWindowSize(scon->real_window, width, height); - } else { - SDL_DestroyRenderer(scon->real_renderer); - SDL_DestroyWindow(scon->real_window); - scon->real_renderer = NULL; - scon->real_window = NULL; - } + if (!scon->surface) { + return; + } + assert(!scon->real_window); + + if (gui_fullscreen) { + flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } else { - if (!width || !height) { - return; - } - flags = 0; - if (gui_fullscreen) { - flags |= SDL_WINDOW_FULLSCREEN; - } else { - flags |= SDL_WINDOW_RESIZABLE; - } - if (scon->hidden) { - flags |= SDL_WINDOW_HIDDEN; - } + flags |= SDL_WINDOW_RESIZABLE; + } + if (scon->hidden) { + flags |= SDL_WINDOW_HIDDEN; + } - scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - width, height, flags); - scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0); - sdl_update_caption(scon); + scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + surface_width(scon->surface), + surface_height(scon->surface), + flags); + scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0); + sdl_update_caption(scon); +} + +static void sdl2_window_destroy(struct sdl2_console *scon) +{ + if (!scon->real_window) { + return; } + + SDL_DestroyRenderer(scon->real_renderer); + scon->real_renderer = NULL; + SDL_DestroyWindow(scon->real_window); + scon->real_window = NULL; +} + +static void sdl2_window_resize(struct sdl2_console *scon) +{ + if (!scon->real_window) { + return; + } + + SDL_SetWindowSize(scon->real_window, + surface_width(scon->surface), + surface_height(scon->surface)); } static void sdl_switch(DisplayChangeListener *dcl, DisplaySurface *new_surface) { struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); - int format = 0; - int idx = scon->idx; DisplaySurface *old_surface = scon->surface; + int format = 0; - /* temporary hack: allows to call sdl_switch to handle scaling changes */ - if (new_surface) { - scon->surface = new_surface; - } + scon->surface = new_surface; - if (!new_surface && idx > 0) { - scon->surface = NULL; + if (scon->texture) { + SDL_DestroyTexture(scon->texture); + scon->texture = NULL; } - if (new_surface == NULL) { - do_sdl_resize(scon, 0, 0, 0); - } else { - do_sdl_resize(scon, surface_width(scon->surface), - surface_height(scon->surface), 0); + if (!new_surface) { + sdl2_window_destroy(scon); + return; } - if (old_surface && scon->texture) { - SDL_DestroyTexture(scon->texture); - scon->texture = NULL; + if (!scon->real_window) { + sdl2_window_create(scon); + } else if (old_surface && + ((surface_width(old_surface) != surface_width(new_surface)) || + (surface_height(old_surface) != surface_height(new_surface)))) { + sdl2_window_resize(scon); } - if (new_surface) { - if (!scon->texture) { - if (surface_bits_per_pixel(scon->surface) == 16) { - format = SDL_PIXELFORMAT_RGB565; - } else if (surface_bits_per_pixel(scon->surface) == 32) { - format = SDL_PIXELFORMAT_ARGB8888; - } + SDL_RenderSetLogicalSize(scon->real_renderer, + surface_width(new_surface), + surface_height(new_surface)); - scon->texture = SDL_CreateTexture(scon->real_renderer, format, - SDL_TEXTUREACCESS_STREAMING, - surface_width(new_surface), - surface_height(new_surface)); - } + if (surface_bits_per_pixel(scon->surface) == 16) { + format = SDL_PIXELFORMAT_RGB565; + } else if (surface_bits_per_pixel(scon->surface) == 32) { + format = SDL_PIXELFORMAT_ARGB8888; } + scon->texture = SDL_CreateTexture(scon->real_renderer, format, + SDL_TEXTUREACCESS_STREAMING, + surface_width(new_surface), + surface_height(new_surface)); } static void sdl_update_caption(struct sdl2_console *scon) @@ -338,39 +344,19 @@ static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy, qemu_input_event_sync(); } -static void sdl_scale(struct sdl2_console *scon, int width, int height) -{ - int bpp = 0; - do_sdl_resize(scon, width, height, bpp); - scaling_active = 1; -} - static void toggle_full_screen(struct sdl2_console *scon) { - int width = surface_width(scon->surface); - int height = surface_height(scon->surface); - int bpp = surface_bits_per_pixel(scon->surface); - gui_fullscreen = !gui_fullscreen; if (gui_fullscreen) { - SDL_GetWindowSize(scon->real_window, - &gui_saved_width, &gui_saved_height); - gui_saved_scaling = scaling_active; - - do_sdl_resize(scon, width, height, bpp); - scaling_active = 0; - + SDL_SetWindowFullscreen(scon->real_window, + SDL_WINDOW_FULLSCREEN_DESKTOP); gui_saved_grab = gui_grab; sdl_grab_start(scon); } else { - if (gui_saved_scaling) { - sdl_scale(scon, gui_saved_width, gui_saved_height); - } else { - do_sdl_resize(scon, width, height, 0); - } if (!gui_saved_grab) { sdl_grab_end(scon); } + SDL_SetWindowFullscreen(scon->real_window, 0); } graphic_hw_invalidate(scon->dcl.con); graphic_hw_update(scon->dcl.con); @@ -419,14 +405,13 @@ static void handle_keydown(SDL_Event *ev) gui_keysym = 1; break; case SDL_SCANCODE_U: - if (scaling_active) { - scaling_active = 0; - sdl_switch(&scon->dcl, NULL); - graphic_hw_invalidate(scon->dcl.con); - graphic_hw_update(scon->dcl.con); - } + sdl2_window_destroy(scon); + sdl2_window_create(scon); + graphic_hw_invalidate(scon->dcl.con); + graphic_hw_update(scon->dcl.con); gui_keysym = 1; break; +#if 0 case SDL_SCANCODE_KP_PLUS: case SDL_SCANCODE_KP_MINUS: if (!gui_fullscreen) { @@ -439,12 +424,14 @@ static void handle_keydown(SDL_Event *ev) 160); height = (surface_height(scon->surface) * width) / surface_width(scon->surface); - + fprintf(stderr, "%s: scale to %dx%d\n", + __func__, width, height); sdl_scale(scon, width, height); graphic_hw_invalidate(NULL); graphic_hw_update(NULL); gui_keysym = 1; } +#endif default: break; } @@ -571,7 +558,6 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) switch (ev->window.event) { case SDL_WINDOWEVENT_RESIZED: - sdl_scale(scon, ev->window.data1, ev->window.data2); { QemuUIInfo info; memset(&info, 0, sizeof(info)); -- cgit v1.2.1 From 2c3056f182e16038c8b0663f68b3b5105899fb75 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 11 Nov 2014 13:22:49 +0100 Subject: sdl2: move sdl_switch to sdl2-2d.c Move sdl_switch to sdl2-2d.c file, rename to sdl2_2d_switch. Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- include/ui/sdl2.h | 6 ++++++ ui/sdl2-2d.c | 42 ++++++++++++++++++++++++++++++++++++++++++ ui/sdl2.c | 50 ++++---------------------------------------------- 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index 84c27f03fa..fd6bfdd46d 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -13,11 +13,17 @@ struct sdl2_console { int hidden; }; +void sdl2_window_create(struct sdl2_console *scon); +void sdl2_window_destroy(struct sdl2_console *scon); +void sdl2_window_resize(struct sdl2_console *scon); + void sdl2_reset_keys(struct sdl2_console *scon); void sdl2_process_key(struct sdl2_console *scon, SDL_KeyboardEvent *ev); void sdl2_2d_update(DisplayChangeListener *dcl, int x, int y, int w, int h); +void sdl2_2d_switch(DisplayChangeListener *dcl, + DisplaySurface *new_surface); #endif /* SDL2_H */ diff --git a/ui/sdl2-2d.c b/ui/sdl2-2d.c index 7b0039b080..29ada53552 100644 --- a/ui/sdl2-2d.c +++ b/ui/sdl2-2d.c @@ -59,3 +59,45 @@ void sdl2_2d_update(DisplayChangeListener *dcl, SDL_RenderCopy(scon->real_renderer, scon->texture, &rect, &rect); SDL_RenderPresent(scon->real_renderer); } + +void sdl2_2d_switch(DisplayChangeListener *dcl, + DisplaySurface *new_surface) +{ + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); + DisplaySurface *old_surface = scon->surface; + int format = 0; + + scon->surface = new_surface; + + if (scon->texture) { + SDL_DestroyTexture(scon->texture); + scon->texture = NULL; + } + + if (!new_surface) { + sdl2_window_destroy(scon); + return; + } + + if (!scon->real_window) { + sdl2_window_create(scon); + } else if (old_surface && + ((surface_width(old_surface) != surface_width(new_surface)) || + (surface_height(old_surface) != surface_height(new_surface)))) { + sdl2_window_resize(scon); + } + + SDL_RenderSetLogicalSize(scon->real_renderer, + surface_width(new_surface), + surface_height(new_surface)); + + if (surface_bits_per_pixel(scon->surface) == 16) { + format = SDL_PIXELFORMAT_RGB565; + } else if (surface_bits_per_pixel(scon->surface) == 32) { + format = SDL_PIXELFORMAT_ARGB8888; + } + scon->texture = SDL_CreateTexture(scon->real_renderer, format, + SDL_TEXTUREACCESS_STREAMING, + surface_width(new_surface), + surface_height(new_surface)); +} diff --git a/ui/sdl2.c b/ui/sdl2.c index 59b67a6b3c..eff9cb3661 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -68,7 +68,7 @@ static struct sdl2_console *get_scon_from_window(uint32_t window_id) return NULL; } -static void sdl2_window_create(struct sdl2_console *scon) +void sdl2_window_create(struct sdl2_console *scon) { int flags = 0; @@ -95,7 +95,7 @@ static void sdl2_window_create(struct sdl2_console *scon) sdl_update_caption(scon); } -static void sdl2_window_destroy(struct sdl2_console *scon) +void sdl2_window_destroy(struct sdl2_console *scon) { if (!scon->real_window) { return; @@ -107,7 +107,7 @@ static void sdl2_window_destroy(struct sdl2_console *scon) scon->real_window = NULL; } -static void sdl2_window_resize(struct sdl2_console *scon) +void sdl2_window_resize(struct sdl2_console *scon) { if (!scon->real_window) { return; @@ -118,48 +118,6 @@ static void sdl2_window_resize(struct sdl2_console *scon) surface_height(scon->surface)); } -static void sdl_switch(DisplayChangeListener *dcl, - DisplaySurface *new_surface) -{ - struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); - DisplaySurface *old_surface = scon->surface; - int format = 0; - - scon->surface = new_surface; - - if (scon->texture) { - SDL_DestroyTexture(scon->texture); - scon->texture = NULL; - } - - if (!new_surface) { - sdl2_window_destroy(scon); - return; - } - - if (!scon->real_window) { - sdl2_window_create(scon); - } else if (old_surface && - ((surface_width(old_surface) != surface_width(new_surface)) || - (surface_height(old_surface) != surface_height(new_surface)))) { - sdl2_window_resize(scon); - } - - SDL_RenderSetLogicalSize(scon->real_renderer, - surface_width(new_surface), - surface_height(new_surface)); - - if (surface_bits_per_pixel(scon->surface) == 16) { - format = SDL_PIXELFORMAT_RGB565; - } else if (surface_bits_per_pixel(scon->surface) == 32) { - format = SDL_PIXELFORMAT_ARGB8888; - } - scon->texture = SDL_CreateTexture(scon->real_renderer, format, - SDL_TEXTUREACCESS_STREAMING, - surface_width(new_surface), - surface_height(new_surface)); -} - static void sdl_update_caption(struct sdl2_console *scon) { char win_title[1024]; @@ -710,7 +668,7 @@ static void sdl_cleanup(void) static const DisplayChangeListenerOps dcl_2d_ops = { .dpy_name = "sdl2-2d", .dpy_gfx_update = sdl2_2d_update, - .dpy_gfx_switch = sdl_switch, + .dpy_gfx_switch = sdl2_2d_switch, .dpy_refresh = sdl_refresh, .dpy_mouse_set = sdl_mouse_warp, .dpy_cursor_define = sdl_mouse_define, -- cgit v1.2.1 From 0d01b7ce617b5f511c852ad770fd7fdce6bf353d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 11 Nov 2014 13:31:08 +0100 Subject: sdl2: add+use sdl2_2d_redraw function. Add a new sdl2_2d_redraw function for a complete screen refresh, so we can stop using graphic_hw_invalidate for that. There is no need to bother console / gfx emulation code if we are just going to re-blit the screen after window resizes. Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- include/ui/sdl2.h | 1 + ui/sdl2-2d.c | 11 +++++++++++ ui/sdl2.c | 17 ++++++----------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index fd6bfdd46d..d0ce0b0f9c 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -25,5 +25,6 @@ void sdl2_2d_update(DisplayChangeListener *dcl, int x, int y, int w, int h); void sdl2_2d_switch(DisplayChangeListener *dcl, DisplaySurface *new_surface); +void sdl2_2d_redraw(struct sdl2_console *scon); #endif /* SDL2_H */ diff --git a/ui/sdl2-2d.c b/ui/sdl2-2d.c index 29ada53552..40a552c7cb 100644 --- a/ui/sdl2-2d.c +++ b/ui/sdl2-2d.c @@ -100,4 +100,15 @@ void sdl2_2d_switch(DisplayChangeListener *dcl, SDL_TEXTUREACCESS_STREAMING, surface_width(new_surface), surface_height(new_surface)); + sdl2_2d_redraw(scon); +} + +void sdl2_2d_redraw(struct sdl2_console *scon) +{ + if (!scon->surface) { + return; + } + sdl2_2d_update(&scon->dcl, 0, 0, + surface_width(scon->surface), + surface_height(scon->surface)); } diff --git a/ui/sdl2.c b/ui/sdl2.c index eff9cb3661..064f18a02b 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -316,8 +316,7 @@ static void toggle_full_screen(struct sdl2_console *scon) } SDL_SetWindowFullscreen(scon->real_window, 0); } - graphic_hw_invalidate(scon->dcl.con); - graphic_hw_update(scon->dcl.con); + sdl2_2d_redraw(scon); } static void handle_keydown(SDL_Event *ev) @@ -365,8 +364,8 @@ static void handle_keydown(SDL_Event *ev) case SDL_SCANCODE_U: sdl2_window_destroy(scon); sdl2_window_create(scon); - graphic_hw_invalidate(scon->dcl.con); - graphic_hw_update(scon->dcl.con); + /* re-create texture */ + sdl2_2d_switch(&scon->dcl, scon->surface); gui_keysym = 1; break; #if 0 @@ -385,8 +384,7 @@ static void handle_keydown(SDL_Event *ev) fprintf(stderr, "%s: scale to %dx%d\n", __func__, width, height); sdl_scale(scon, width, height); - graphic_hw_invalidate(NULL); - graphic_hw_update(NULL); + sdl2_2d_redraw(scon); gui_keysym = 1; } #endif @@ -511,7 +509,6 @@ static void handle_mousewheel(SDL_Event *ev) static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) { - int w, h; struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); switch (ev->window.event) { @@ -523,12 +520,10 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) info.height = ev->window.data2; dpy_set_ui_info(scon->dcl.con, &info); } - graphic_hw_invalidate(scon->dcl.con); - graphic_hw_update(scon->dcl.con); + sdl2_2d_redraw(scon); break; case SDL_WINDOWEVENT_EXPOSED: - SDL_GetWindowSize(SDL_GetWindowFromID(ev->window.windowID), &w, &h); - sdl2_2d_update(dcl, 0, 0, w, h); + sdl2_2d_redraw(scon); break; case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_ENTER: -- cgit v1.2.1 From 63ed4907cb4cfacf1f875f938037af9c75afa453 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 12 Nov 2014 08:01:27 +0100 Subject: sdl2: factor out sdl2_poll_events Create a new function to poll and handle sdl2 events, which is then just called from the refresh timer. Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- include/ui/sdl2.h | 1 + ui/sdl2.c | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index d0ce0b0f9c..bda60f8b93 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -16,6 +16,7 @@ struct sdl2_console { void sdl2_window_create(struct sdl2_console *scon); void sdl2_window_destroy(struct sdl2_console *scon); void sdl2_window_resize(struct sdl2_console *scon); +void sdl2_poll_events(struct sdl2_console *scon); void sdl2_reset_keys(struct sdl2_console *scon); void sdl2_process_key(struct sdl2_console *scon, diff --git a/ui/sdl2.c b/ui/sdl2.c index 064f18a02b..2fdf8df608 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -507,10 +507,8 @@ static void handle_mousewheel(SDL_Event *ev) qemu_input_event_sync(); } -static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) +static void handle_windowevent(struct sdl2_console *scon, SDL_Event *ev) { - struct sdl2_console *scon = get_scon_from_window(ev->key.windowID); - switch (ev->window.event) { case SDL_WINDOWEVENT_RESIZED: { @@ -537,10 +535,10 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) } break; case SDL_WINDOWEVENT_RESTORED: - update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT); + update_displaychangelistener(&scon->dcl, GUI_REFRESH_INTERVAL_DEFAULT); break; case SDL_WINDOWEVENT_MINIMIZED: - update_displaychangelistener(dcl, 500); + update_displaychangelistener(&scon->dcl, 500); break; case SDL_WINDOWEVENT_CLOSE: if (!no_quit) { @@ -551,9 +549,8 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) } } -static void sdl_refresh(DisplayChangeListener *dcl) +void sdl2_poll_events(struct sdl2_console *scon) { - struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); SDL_Event ev1, *ev = &ev1; if (scon->last_vm_running != runstate_is_running()) { @@ -561,8 +558,6 @@ static void sdl_refresh(DisplayChangeListener *dcl) sdl_update_caption(scon); } - graphic_hw_update(dcl->con); - while (SDL_PollEvent(ev)) { switch (ev->type) { case SDL_KEYDOWN: @@ -591,7 +586,7 @@ static void sdl_refresh(DisplayChangeListener *dcl) handle_mousewheel(ev); break; case SDL_WINDOWEVENT: - handle_windowevent(dcl, ev); + handle_windowevent(scon, ev); break; default: break; @@ -599,6 +594,14 @@ static void sdl_refresh(DisplayChangeListener *dcl) } } +static void sdl_refresh(DisplayChangeListener *dcl) +{ + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); + + graphic_hw_update(dcl->con); + sdl2_poll_events(scon); +} + static void sdl_mouse_warp(DisplayChangeListener *dcl, int x, int y, int on) { -- cgit v1.2.1 From 62959ffe45bdd7bb069e529686a8c152518812fc Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 12 Nov 2014 08:03:34 +0100 Subject: sdl2: move sdl2_2d_refresh to sdl2-2d.c Now that common event handling code is split off, we can move over sdl_refresh to sdl2-2d.c, and rename it to sdl2_2d_refresh. Signed-off-by: Gerd Hoffmann Reviewed-by: Max Reitz --- include/ui/sdl2.h | 1 + ui/sdl2-2d.c | 8 ++++++++ ui/sdl2.c | 10 +--------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index bda60f8b93..f56c596e31 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -26,6 +26,7 @@ void sdl2_2d_update(DisplayChangeListener *dcl, int x, int y, int w, int h); void sdl2_2d_switch(DisplayChangeListener *dcl, DisplaySurface *new_surface); +void sdl2_2d_refresh(DisplayChangeListener *dcl); void sdl2_2d_redraw(struct sdl2_console *scon); #endif /* SDL2_H */ diff --git a/ui/sdl2-2d.c b/ui/sdl2-2d.c index 40a552c7cb..9264817e76 100644 --- a/ui/sdl2-2d.c +++ b/ui/sdl2-2d.c @@ -103,6 +103,14 @@ void sdl2_2d_switch(DisplayChangeListener *dcl, sdl2_2d_redraw(scon); } +void sdl2_2d_refresh(DisplayChangeListener *dcl) +{ + struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); + + graphic_hw_update(dcl->con); + sdl2_poll_events(scon); +} + void sdl2_2d_redraw(struct sdl2_console *scon) { if (!scon->surface) { diff --git a/ui/sdl2.c b/ui/sdl2.c index 2fdf8df608..64ce2065fc 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -594,14 +594,6 @@ void sdl2_poll_events(struct sdl2_console *scon) } } -static void sdl_refresh(DisplayChangeListener *dcl) -{ - struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl); - - graphic_hw_update(dcl->con); - sdl2_poll_events(scon); -} - static void sdl_mouse_warp(DisplayChangeListener *dcl, int x, int y, int on) { @@ -667,7 +659,7 @@ static const DisplayChangeListenerOps dcl_2d_ops = { .dpy_name = "sdl2-2d", .dpy_gfx_update = sdl2_2d_update, .dpy_gfx_switch = sdl2_2d_switch, - .dpy_refresh = sdl_refresh, + .dpy_refresh = sdl2_2d_refresh, .dpy_mouse_set = sdl_mouse_warp, .dpy_cursor_define = sdl_mouse_define, }; -- cgit v1.2.1 From 1dfc5c8808e8b523c8ef70859921ab5ecd09cd67 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 12 Dec 2014 10:52:51 +0100 Subject: sdl2: Use correct sdl2_console for window events SDL_PollEvent() polls events for all windows; therefore, sdl2_poll_events() will poll the events for all windows and not only for the one identified by the given sdl2_console. This should be considered in handle_windowevent(): The window affected by the event is not necessarily the one identified by the sdl2_console object given to sdl2_poll_events(), but the one identified by ev->window.windowID. Signed-off-by: Max Reitz Signed-off-by: Gerd Hoffmann --- ui/sdl2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/sdl2.c b/ui/sdl2.c index 64ce2065fc..04bbcc78ee 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -507,8 +507,10 @@ static void handle_mousewheel(SDL_Event *ev) qemu_input_event_sync(); } -static void handle_windowevent(struct sdl2_console *scon, SDL_Event *ev) +static void handle_windowevent(SDL_Event *ev) { + struct sdl2_console *scon = get_scon_from_window(ev->window.windowID); + switch (ev->window.event) { case SDL_WINDOWEVENT_RESIZED: { @@ -586,7 +588,7 @@ void sdl2_poll_events(struct sdl2_console *scon) handle_mousewheel(ev); break; case SDL_WINDOWEVENT: - handle_windowevent(scon, ev); + handle_windowevent(ev); break; default: break; -- cgit v1.2.1 From d3f3a0f453ea590be529079ae214c200bb5ecc1a Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 12 Dec 2014 10:52:52 +0100 Subject: sdl2: Work around SDL2 SDL_ShowWindow() bug Apparently it is possible for X to send an event to a hidden SDL2 window, leading to SDL2 believing it is now shown. SDL2 will pass the SDL_WINDOWEVENT_SHOWN message to the application without actually showing the window; the problem is that the next SDL_ShowWindow() will be a no-op because SDL2 assumes the window is already shown. The correct way to react to SDL_WINDOWEVENT_SHOWN would be to clear scon->hidden (analogous for SDL_WINDOWEVENT_HIDDEN). However, due to the window not actually being shown, this will somehow not be correct after all. Therefore, just hide the window on SDL_WINDOWEVENT_SHOWN if it is supposed to be hidden (and analogous for SDL_WINDOWEVENT_HIDDEN). Signed-off-by: Max Reitz Signed-off-by: Gerd Hoffmann --- ui/sdl2.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ui/sdl2.c b/ui/sdl2.c index 04bbcc78ee..1ae2781624 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -548,6 +548,16 @@ static void handle_windowevent(SDL_Event *ev) qemu_system_shutdown_request(); } break; + case SDL_WINDOWEVENT_SHOWN: + if (scon->hidden) { + SDL_HideWindow(scon->real_window); + } + break; + case SDL_WINDOWEVENT_HIDDEN: + if (!scon->hidden) { + SDL_ShowWindow(scon->real_window); + } + break; } } -- cgit v1.2.1