Skip to content

Commit

Permalink
SDL2: preliminary window resizing support
Browse files Browse the repository at this point in the history
This commit introduces preliminary support for resizing a window.
How and if it works depends to some degree on the program using
the SDL2 library itself. It works well for the currently tested
ports like chocolate-doom and yquake2 (software renderer).
On the other hand program using an OpenGL context via SDL2 still
have issues resizing the window (EGL errors).

As an additional feature the commit adds support for setting the
initial window geometry via the '<initial>' node, e.g.:

! <initial width="800" height="600"/>

This prevents overly large windows because the actual screen size
is propagated by nitpicker.

Fixes genodelabs#368.
  • Loading branch information
cnuke committed May 7, 2024
1 parent f427822 commit 745d4ae
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
18 changes: 10 additions & 8 deletions src/lib/sdl2/video/SDL_genode_fb_events.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,34 +105,36 @@ extern "C" {

Genode::Mutex::Guard guard(event_mutex);

SDL_Window * const window = SDL_GetMouseFocus();

if (video_events.resize_pending) {
video_events.resize_pending = false;

int const width = video_events.width;
int const height = video_events.height;

#if 0
bool const quit = width == 0 && height == 0;

if (!quit)
SDL_PrivateResize(width, height);
if (!quit) {
/* might force clients to call SDL_GetWindowSurface that,
* according to the documentation, may not be done when using
* 3D or render APIs. So see how that goes...
*/
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height);
}
else {
/* at least try to quit w/o other event handling */
if (SDL_PrivateQuit())
if (SDL_SendQuit())
return;
else
Genode::warning("could not deliver requested SDL_QUIT event");
}
#else
printf("XXX resize pending XXX\n");
#endif
}

if (!input->pending())
return;

SDL_MouseID const mouse_id = 0;
SDL_Window * const window = SDL_GetMouseFocus();

input->for_each_event([&] (Input::Event const &curr) {

Expand Down
29 changes: 28 additions & 1 deletion src/lib/sdl2/video/SDL_genode_fb_video.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

/* Genode includes */
#include <base/attached_ram_dataspace.h>
#include <base/attached_rom_dataspace.h>
#include <base/env.h>
#include <base/log.h>
#include <gui_session/connection.h>
Expand Down Expand Up @@ -84,6 +85,8 @@ void Genode_GLES_DeleteContext(_THIS, SDL_GLContext context);
Gui::Connection &_gui;
Gui::Session::View_handle _view { _gui.create_view() };

Genode::Attached_rom_dataspace _config_rom { _env, "config" };

void _handle_mode_change()
{
Genode::Mutex::Guard guard(event_mutex);
Expand All @@ -95,7 +98,10 @@ void Genode_GLES_DeleteContext(_THIS, SDL_GLContext context);
video_events.height = mode.area.h();
}

Genode::Signal_handler<Sdl_framebuffer> _mode_handler {
/* XXX not being an Io_signal_handler prevents receiving of the
* signal...
*/
Genode::Io_signal_handler<Sdl_framebuffer> _mode_handler {
_env.ep(), *this, &Sdl_framebuffer::_handle_mode_change };

Sdl_framebuffer(Genode::Env &env, Gui::Connection &gui)
Expand All @@ -117,6 +123,21 @@ void Genode_GLES_DeleteContext(_THIS, SDL_GLContext context);
_gui.destroy_view(_view);
}

Gui::Area initial_mode_area()
{
_config_rom.update();
if (!_config_rom.valid())
return Gui::Area();

Gui::Area area { };

_config_rom.xml().with_optional_sub_node("initial",
[&] (Genode::Xml_node const &initial) {
area = Gui::Area::from_xml(initial); });

return area;
}

/************************************
** Framebuffer::Session Interface **
************************************/
Expand Down Expand Up @@ -221,6 +242,7 @@ void Genode_GLES_DeleteContext(_THIS, SDL_GLContext context);
/* get dimensions */
int w, h;
SDL_GetWindowSize(window, &w, &h);
SDL_SetWindowResizable(window, (SDL_bool)true);

/* allocate and attach memory for framebuffer */
if (drv.fb_mem.constructed())
Expand Down Expand Up @@ -318,6 +340,10 @@ void Genode_GLES_DeleteContext(_THIS, SDL_GLContext context);
/* Get the framebuffer size and mode infos */
drv.scr_mode = drv.framebuffer->mode();

Gui::Area const initial = drv.framebuffer->initial_mode_area();
if (initial.valid())
drv.scr_mode.area = initial;

/* set mode specific values */
device->displays = (SDL_VideoDisplay *)(SDL_calloc(1, sizeof(*device->displays)));
if (!device->displays)
Expand Down Expand Up @@ -382,6 +408,7 @@ void Genode_GLES_DeleteContext(_THIS, SDL_GLContext context);

/* set name and user data */
SDL_SetWindowData(window, surface_name, surface);
SDL_SetWindowResizable(window, (SDL_bool)true);

#if defined(SDL_VIDEO_OPENGL_EGL)
if (window->flags & SDL_WINDOW_OPENGL) {
Expand Down

0 comments on commit 745d4ae

Please sign in to comment.