fb_sdl: update to use sdl2

Following the official migration guide of SDL [1], the
fb_sdl framebuffer driver was update from SDL1 to SDL2.

The sdl2 port in world/src/lib/sdl2 is used.

Since SDL1 is in maintenance mode [2], support for other
display servers than X11 will never be implemented. In
particular, support for Wayland is missing from SDL1.

Fortunately, a port of sdl2 is maintained in genode-world.

As SDL2 is actively developed, it will provide support for
modern hardware architectures, and has mature support for
Wayland [3].

[1]: https://wiki.libsdl.org/SDL2/MigrationGuide
[2]: https://wiki.debian.org/Wayland#SDL1_.28unsupported.29
[3]: https://wiki.debian.org/Wayland#SDL2_.28supported_since_2.0.2.2B-.29

Issue #4993
This commit is contained in:
Robin Eklind 2023-09-07 18:18:02 +02:00 committed by Christian Helmuth
parent 5abd2dddb8
commit 9799adda79
3 changed files with 77 additions and 44 deletions

View File

@ -114,12 +114,12 @@ static inline Input::Keycode convert_keycode(int sdl_keycode)
case SDLK_F15: return KEY_F15;
/* special keys */
case SDLK_PRINT: return KEY_PRINT;
case SDLK_SCROLLOCK: return KEY_SCROLLLOCK;
case SDLK_PRINTSCREEN: return KEY_PRINT;
case SDLK_SCROLLLOCK: return KEY_SCROLLLOCK;
case SDLK_MENU: return KEY_MENU;
/* key state modifier keys */
case SDLK_NUMLOCK: return KEY_NUMLOCK;
case SDLK_NUMLOCKCLEAR: return KEY_NUMLOCK;
case SDLK_CAPSLOCK: return KEY_CAPSLOCK;
case SDLK_RSHIFT: return KEY_RIGHTSHIFT;
case SDLK_LSHIFT: return KEY_LEFTSHIFT;
@ -127,8 +127,8 @@ static inline Input::Keycode convert_keycode(int sdl_keycode)
case SDLK_LCTRL: return KEY_LEFTCTRL;
case SDLK_RALT: return KEY_RIGHTALT;
case SDLK_LALT: return KEY_LEFTALT;
case SDLK_RMETA: return KEY_RIGHTMETA;
case SDLK_LMETA: return KEY_LEFTMETA;
case SDLK_RGUI: return KEY_RIGHTMETA;
case SDLK_LGUI: return KEY_LEFTMETA;
default: return KEY_UNKNOWN;
}

View File

@ -22,7 +22,8 @@
/* Linux includes */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#include <SDL/SDL.h>
#pragma GCC diagnostic ignored "-Wtype-limits"
#include <SDL2/SDL.h>
#pragma GCC diagnostic pop
/* local includes */
@ -37,7 +38,10 @@ namespace Fb_sdl {
/* fatal exceptions */
struct Sdl_init_failed : Genode::Exception { };
struct Sdl_videodriver_not_supported : Genode::Exception { };
struct Sdl_setvideomode_failed : Genode::Exception { };
struct Sdl_createwindow_failed : Genode::Exception { };
struct Sdl_createrenderer_failed : Genode::Exception { };
struct Sdl_creatergbsurface_failed : Genode::Exception { };
struct Sdl_createtexture_failed : Genode::Exception { };
struct Fb_sdl::Main
@ -65,17 +69,6 @@ struct Fb_sdl::Main
throw Sdl_init_failed();
}
/*
* We're testing only X11.
*/
char driver[16] = { 0 };
SDL_VideoDriverName(driver, sizeof(driver));
if (::strcmp(driver, "x11") != 0) {
error("fb_sdl works on X11 only. "
"Your SDL backend is ", Genode::Cstring(driver), ".");
throw Sdl_videodriver_not_supported();
}
SDL_ShowCursor(0);
}
@ -85,25 +78,62 @@ struct Fb_sdl::Main
{
Area const size;
SDL_Renderer &_sdl_renderer = _init_sdl_renderer();
SDL_Surface &_sdl_surface = _init_sdl_surface();
SDL_Texture &_sdl_texture = _init_sdl_texture();
SDL_Renderer &_init_sdl_renderer()
{
unsigned const window_flags = 0;
SDL_Window *window_ptr = SDL_CreateWindow("fb_sdl", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, size.w(), size.h(), window_flags);
if (!window_ptr) {
error("SDL_CreateWindow failed (", Genode::Cstring(SDL_GetError()), ")");
throw Sdl_createwindow_failed();
}
SDL_SetWindowResizable(window_ptr, SDL_TRUE);
int const index = -1;
unsigned const renderer_flags = SDL_RENDERER_SOFTWARE;
SDL_Renderer *renderer_ptr = SDL_CreateRenderer(window_ptr, index, renderer_flags);
if (!renderer_ptr) {
error("SDL_CreateRenderer failed (", Genode::Cstring(SDL_GetError()), ")");
throw Sdl_createrenderer_failed();
}
return *renderer_ptr;
}
SDL_Surface &_init_sdl_surface()
{
unsigned const bpp = 32;
unsigned const flags = SDL_SWSURFACE | SDL_RESIZABLE;
SDL_Surface *surface_ptr = nullptr;
if (SDL_VideoModeOK(size.w(), size.h(), bpp, flags))
surface_ptr = SDL_SetVideoMode(size.w(), size.h(), bpp, flags);
unsigned const flags = 0;
unsigned const bpp = 32;
unsigned const red_mask = 0x00FF0000;
unsigned const green_mask = 0x0000FF00;
unsigned const blue_mask = 0x000000FF;
unsigned const alpha_mask = 0xFF000000;
SDL_Surface *surface_ptr = SDL_CreateRGBSurface(flags, size.w(), size.h(), bpp, red_mask, green_mask, blue_mask, alpha_mask);
if (!surface_ptr) {
error("SDL_SetVideoMode failed (", Genode::Cstring(SDL_GetError()), ")");
throw Sdl_setvideomode_failed();
error("SDL_CreateRGBSurface failed (", Genode::Cstring(SDL_GetError()), ")");
throw Sdl_creatergbsurface_failed();
}
return *surface_ptr;
}
SDL_Texture &_init_sdl_texture()
{
SDL_Texture *texture_ptr = SDL_CreateTexture(&_sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, size.w(), size.h());
if (!texture_ptr) {
error("SDL_CreateTexture failed (", Genode::Cstring(SDL_GetError()), ")");
throw Sdl_createtexture_failed();
}
return *texture_ptr;
}
Sdl_screen(Area size) : size(size) { }
template <typename FN>
@ -113,9 +143,12 @@ struct Fb_sdl::Main
fn(surface);
}
void flush(Capture::Rect rect)
void flush()
{
SDL_UpdateRect(&_sdl_surface, rect.x1(), rect.y1(), rect.w(), rect.h());
SDL_UpdateTexture(&_sdl_texture, nullptr, _sdl_surface.pixels, _sdl_surface.pitch);
SDL_RenderClear(&_sdl_renderer);
SDL_RenderCopy(&_sdl_renderer, &_sdl_texture, nullptr, nullptr);
SDL_RenderPresent(&_sdl_renderer);
}
};
@ -151,8 +184,7 @@ struct Fb_sdl::Main
});
/* flush pixels in SDL window */
affected.for_each_rect([&] (Capture::Rect const rect) {
_sdl_screen->flush(rect); });
_sdl_screen->flush();
}
void _handle_timer()
@ -185,14 +217,16 @@ void Fb_sdl::Main::_handle_sdl_event(Event_batch &batch, SDL_Event const &event)
{
using namespace Input;
if (event.type == SDL_VIDEORESIZE) {
if (event.type == SDL_WINDOWEVENT_RESIZED) {
if (event.resize.w < 0 || event.resize.h < 0) {
int w = event.window.data1;
int h = event.window.data2;
if (w < 0 || h < 0) {
warning("attempt to resize to negative size");
return;
}
_resize(Area((unsigned)event.resize.w, (unsigned)event.resize.h));
_resize(Area((unsigned)w, (unsigned)h));
return;
}
@ -234,10 +268,6 @@ void Fb_sdl::Main::_handle_sdl_event(Event_batch &batch, SDL_Event const &event)
case SDL_KEYUP:
case SDL_MOUSEBUTTONUP:
if (event.button.button == SDL_BUTTON_WHEELUP
|| event.button.button == SDL_BUTTON_WHEELDOWN)
/* ignore */
return;
batch.submit(Release{keycode});
return;
@ -245,12 +275,15 @@ void Fb_sdl::Main::_handle_sdl_event(Event_batch &batch, SDL_Event const &event)
case SDL_KEYDOWN:
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_WHEELUP)
batch.submit(Press{keycode});
return;
case SDL_MOUSEWHEEL:
if (event.wheel.y > 0)
batch.submit(Wheel{0, 1});
else if (event.button.button == SDL_BUTTON_WHEELDOWN)
else if (event.wheel.y < 0)
batch.submit(Wheel{0, -1});
else
batch.submit(Press{keycode});
return;
default:

View File

@ -2,5 +2,5 @@ TARGET = fb_sdl
LIBS = lx_hybrid blit
REQUIRES = linux
SRC_CC = main.cc
LX_LIBS = sdl
INC_DIR += $(PRG_DIR)
LX_LIBS = sdl2
INC_DIR += $(PRG_DIR) /usr/include/SDL2