*/
/* 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 <SDL.h>
-#include <SDL_syswm.h>
-
#include "qemu-common.h"
#include "ui/console.h"
#include "ui/input.h"
return NULL;
}
-static void sdl2_window_create(struct sdl2_console *scon)
+void sdl2_window_create(struct sdl2_console *scon)
{
int flags = 0;
surface_height(scon->surface),
flags);
scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0);
+ if (scon->opengl) {
+ scon->winctx = SDL_GL_GetCurrentContext();
+ }
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;
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;
surface_height(scon->surface));
}
-static void sdl_switch(DisplayChangeListener *dcl,
- DisplaySurface *new_surface)
+static void sdl2_redraw(struct sdl2_console *scon)
{
- 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->opengl) {
+#ifdef CONFIG_OPENGL
+ sdl2_gl_redraw(scon);
+#endif
+ } else {
+ sdl2_2d_redraw(scon);
}
-
- 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)
}
SDL_SetWindowFullscreen(scon->real_window, 0);
}
- graphic_hw_invalidate(scon->dcl.con);
- graphic_hw_update(scon->dcl.con);
+ sdl2_redraw(scon);
}
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);
+ if (!scon->opengl) {
+ /* re-create scon->texture */
+ sdl2_2d_switch(&scon->dcl, scon->surface);
+ }
gui_keysym = 1;
break;
#if 0
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_redraw(scon);
gui_keysym = 1;
}
#endif
qemu_input_event_sync();
}
-static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev)
+static void handle_windowevent(SDL_Event *ev)
{
- int w, h;
- struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
+ struct sdl2_console *scon = get_scon_from_window(ev->window.windowID);
+
+ if (!scon) {
+ return;
+ }
switch (ev->window.event) {
case SDL_WINDOWEVENT_RESIZED:
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_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_redraw(scon);
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
case SDL_WINDOWEVENT_ENTER:
}
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) {
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;
}
}
-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()) {
sdl_update_caption(scon);
}
- graphic_hw_update(dcl->con);
-
while (SDL_PollEvent(ev)) {
switch (ev->type) {
case SDL_KEYDOWN:
handle_mousewheel(ev);
break;
case SDL_WINDOWEVENT:
- handle_windowevent(dcl, ev);
+ handle_windowevent(ev);
break;
default:
break;
}
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,
- .dpy_cursor_define = sdl_mouse_define,
+ .dpy_name = "sdl2-2d",
+ .dpy_gfx_update = sdl2_2d_update,
+ .dpy_gfx_switch = sdl2_2d_switch,
+ .dpy_gfx_check_format = sdl2_2d_check_format,
+ .dpy_refresh = sdl2_2d_refresh,
+ .dpy_mouse_set = sdl_mouse_warp,
+ .dpy_cursor_define = sdl_mouse_define,
};
+#ifdef CONFIG_OPENGL
+static const DisplayChangeListenerOps dcl_gl_ops = {
+ .dpy_name = "sdl2-gl",
+ .dpy_gfx_update = sdl2_gl_update,
+ .dpy_gfx_switch = sdl2_gl_switch,
+ .dpy_gfx_check_format = console_gl_check_format,
+ .dpy_refresh = sdl2_gl_refresh,
+ .dpy_mouse_set = sdl_mouse_warp,
+ .dpy_cursor_define = sdl_mouse_define,
+};
+#endif
+
+void sdl_display_early_init(int opengl)
+{
+ switch (opengl) {
+ case -1: /* default */
+ case 0: /* off */
+ break;
+ case 1: /* on */
+#ifdef CONFIG_OPENGL
+ display_opengl = 1;
+#endif
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
{
int flags;
if (!qemu_console_is_graphic(con)) {
sdl2_console[i].hidden = true;
}
+ sdl2_console[i].idx = i;
+#ifdef CONFIG_OPENGL
+ sdl2_console[i].opengl = display_opengl;
+ sdl2_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops;
+#else
+ sdl2_console[i].opengl = 0;
sdl2_console[i].dcl.ops = &dcl_2d_ops;
+#endif
sdl2_console[i].dcl.con = con;
register_displaychangelistener(&sdl2_console[i].dcl);
- sdl2_console[i].idx = i;
}
/* Load a 32x32x4 image. White pixels are transparent. */