mirror of
https://github.com/brl/mutter.git
synced 2024-12-25 04:22:05 +00:00
Support window resizing in the SDL 2 winsys
The SDL2 winsys will now set the SDL_WINDOW_RESIZABLE flag on the window before creating it if the resizable property is set on the onscreen. Note that there doesn't appear to be a way in SDL to change the flag later so unlike the other winsyses it will only take affect if it is set before allocating the framebuffer. The winsys now registers a callback for SDL events so that it can report window size changes back to the application. Reviewed-by: Robert Bragg <robert@linux.intel.com> (cherry picked from commit 0dea9aeb897faf029828379b120970477df3c7d5)
This commit is contained in:
parent
11126a1b7e
commit
9f107ab3fb
@ -53,13 +53,19 @@ typedef struct _CoglDisplaySdl2
|
|||||||
{
|
{
|
||||||
SDL_Window *dummy_window;
|
SDL_Window *dummy_window;
|
||||||
SDL_GLContext *context;
|
SDL_GLContext *context;
|
||||||
|
CoglBool pending_resize_notify;
|
||||||
} CoglDisplaySdl2;
|
} CoglDisplaySdl2;
|
||||||
|
|
||||||
typedef struct _CoglOnscreenSdl2
|
typedef struct _CoglOnscreenSdl2
|
||||||
{
|
{
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
|
CoglBool pending_resize_notify;
|
||||||
} CoglOnscreenSdl2;
|
} CoglOnscreenSdl2;
|
||||||
|
|
||||||
|
/* The key used to store a pointer to the CoglOnscreen in an
|
||||||
|
* SDL_Window */
|
||||||
|
#define COGL_SDL_WINDOW_DATA_KEY "cogl-onscreen"
|
||||||
|
|
||||||
static CoglFuncPtr
|
static CoglFuncPtr
|
||||||
_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer,
|
_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer,
|
||||||
const char *name,
|
const char *name,
|
||||||
@ -259,6 +265,47 @@ error:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CoglFilterReturn
|
||||||
|
sdl_event_filter_cb (SDL_Event *event, void *data)
|
||||||
|
{
|
||||||
|
if (event->type == SDL_WINDOWEVENT &&
|
||||||
|
event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
||||||
|
{
|
||||||
|
CoglContext *context = data;
|
||||||
|
CoglDisplay *display = context->display;
|
||||||
|
CoglDisplaySdl2 *sdl_display = display->winsys;
|
||||||
|
float width = event->window.data1;
|
||||||
|
float height = event->window.data2;
|
||||||
|
CoglFramebuffer *framebuffer;
|
||||||
|
CoglOnscreenSdl2 *sdl_onscreen;
|
||||||
|
SDL_Window *window;
|
||||||
|
|
||||||
|
window = SDL_GetWindowFromID (event->window.windowID);
|
||||||
|
|
||||||
|
if (window == NULL)
|
||||||
|
return COGL_FILTER_CONTINUE;
|
||||||
|
|
||||||
|
framebuffer = SDL_GetWindowData (window, COGL_SDL_WINDOW_DATA_KEY);
|
||||||
|
|
||||||
|
if (framebuffer == NULL || framebuffer->context != context)
|
||||||
|
return COGL_FILTER_CONTINUE;
|
||||||
|
|
||||||
|
_cogl_framebuffer_winsys_update_size (framebuffer, width, height);
|
||||||
|
|
||||||
|
sdl_onscreen = COGL_ONSCREEN (framebuffer)->winsys;
|
||||||
|
|
||||||
|
/* We only want to notify that a resize happened when the
|
||||||
|
application calls cogl_context_dispatch so instead of immediately
|
||||||
|
notifying we'll set a flag to remember to notify later */
|
||||||
|
sdl_display->pending_resize_notify = TRUE;
|
||||||
|
sdl_onscreen->pending_resize_notify = TRUE;
|
||||||
|
|
||||||
|
return COGL_FILTER_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return COGL_FILTER_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
_cogl_winsys_context_init (CoglContext *context, CoglError **error)
|
_cogl_winsys_context_init (CoglContext *context, CoglError **error)
|
||||||
{
|
{
|
||||||
@ -278,12 +325,23 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)
|
|||||||
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE,
|
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
|
_cogl_renderer_add_native_filter (renderer,
|
||||||
|
(CoglNativeFilterFunc) sdl_event_filter_cb,
|
||||||
|
context);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_winsys_context_deinit (CoglContext *context)
|
_cogl_winsys_context_deinit (CoglContext *context)
|
||||||
{
|
{
|
||||||
|
CoglRenderer *renderer = context->display->renderer;
|
||||||
|
|
||||||
|
_cogl_renderer_remove_native_filter (renderer,
|
||||||
|
(CoglNativeFilterFunc)
|
||||||
|
sdl_event_filter_cb,
|
||||||
|
context);
|
||||||
|
|
||||||
g_free (context->winsys);
|
g_free (context->winsys);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,15 +405,22 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
|||||||
CoglOnscreenSdl2 *sdl_onscreen;
|
CoglOnscreenSdl2 *sdl_onscreen;
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
SDL_WindowFlags flags;
|
||||||
|
|
||||||
width = cogl_framebuffer_get_width (framebuffer);
|
width = cogl_framebuffer_get_width (framebuffer);
|
||||||
height = cogl_framebuffer_get_height (framebuffer);
|
height = cogl_framebuffer_get_height (framebuffer);
|
||||||
|
|
||||||
|
flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;
|
||||||
|
|
||||||
|
/* The resizable property on SDL window apparently can only be set
|
||||||
|
* on creation */
|
||||||
|
if (onscreen->resizable)
|
||||||
|
flags |= SDL_WINDOW_RESIZABLE;
|
||||||
|
|
||||||
window = SDL_CreateWindow ("" /* title */,
|
window = SDL_CreateWindow ("" /* title */,
|
||||||
0, 0, /* x/y */
|
0, 0, /* x/y */
|
||||||
width, height,
|
width, height,
|
||||||
SDL_WINDOW_OPENGL |
|
flags);
|
||||||
SDL_WINDOW_HIDDEN);
|
|
||||||
|
|
||||||
if (window == NULL)
|
if (window == NULL)
|
||||||
{
|
{
|
||||||
@ -366,6 +431,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_SetWindowData (window, COGL_SDL_WINDOW_DATA_KEY, onscreen);
|
||||||
|
|
||||||
onscreen->winsys = g_slice_new (CoglOnscreenSdl2);
|
onscreen->winsys = g_slice_new (CoglOnscreenSdl2);
|
||||||
sdl_onscreen = onscreen->winsys;
|
sdl_onscreen = onscreen->winsys;
|
||||||
sdl_onscreen->window = window;
|
sdl_onscreen->window = window;
|
||||||
@ -407,6 +474,42 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
|
|||||||
SDL_HideWindow (sdl_onscreen->window);
|
SDL_HideWindow (sdl_onscreen->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
flush_pending_notifications_cb (void *data,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *framebuffer = data;
|
||||||
|
|
||||||
|
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
|
||||||
|
{
|
||||||
|
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
||||||
|
CoglOnscreenSdl2 *sdl_onscreen = onscreen->winsys;
|
||||||
|
|
||||||
|
if (sdl_onscreen->pending_resize_notify)
|
||||||
|
{
|
||||||
|
_cogl_onscreen_notify_resize (onscreen);
|
||||||
|
sdl_onscreen->pending_resize_notify = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_poll_dispatch (CoglContext *context,
|
||||||
|
const CoglPollFD *poll_fds,
|
||||||
|
int n_poll_fds)
|
||||||
|
{
|
||||||
|
CoglDisplay *display = context->display;
|
||||||
|
CoglDisplaySdl2 *sdl_display = display->winsys;
|
||||||
|
|
||||||
|
if (sdl_display->pending_resize_notify)
|
||||||
|
{
|
||||||
|
g_list_foreach (context->framebuffers,
|
||||||
|
flush_pending_notifications_cb,
|
||||||
|
NULL);
|
||||||
|
sdl_display->pending_resize_notify = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const CoglWinsysVtable *
|
const CoglWinsysVtable *
|
||||||
_cogl_winsys_sdl_get_vtable (void)
|
_cogl_winsys_sdl_get_vtable (void)
|
||||||
{
|
{
|
||||||
@ -439,6 +542,8 @@ _cogl_winsys_sdl_get_vtable (void)
|
|||||||
_cogl_winsys_onscreen_update_swap_throttled;
|
_cogl_winsys_onscreen_update_swap_throttled;
|
||||||
vtable.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility;
|
vtable.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility;
|
||||||
|
|
||||||
|
vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
|
||||||
|
|
||||||
vtable_inited = TRUE;
|
vtable_inited = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +99,10 @@ main (int argc, char **argv)
|
|||||||
data.center_y = 0.0f;
|
data.center_y = 0.0f;
|
||||||
data.quit = FALSE;
|
data.quit = FALSE;
|
||||||
|
|
||||||
|
/* In SDL2, setting resizable only works before allocating the
|
||||||
|
* onscreen */
|
||||||
|
cogl_onscreen_set_resizable (onscreen, TRUE);
|
||||||
|
|
||||||
cogl_onscreen_show (onscreen);
|
cogl_onscreen_show (onscreen);
|
||||||
|
|
||||||
data.triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
|
data.triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
|
||||||
|
Loading…
Reference in New Issue
Block a user