From 64a4713fe6ae51b87554ec8dc921f66b8282b171 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Thu, 8 Oct 2015 17:12:25 +0200 Subject: [PATCH] fb_sdl: check for X11 / prevent invalid-event flood We check for X11 as required platform now and are more verbose on errors. --- .../drivers/framebuffer/spec/sdl/fb_sdl.cc | 24 +++++++++-- .../src/drivers/framebuffer/spec/sdl/input.cc | 43 +++++++++++++++---- 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/repos/os/src/drivers/framebuffer/spec/sdl/fb_sdl.cc b/repos/os/src/drivers/framebuffer/spec/sdl/fb_sdl.cc index 5473c2b62..b058a9435 100644 --- a/repos/os/src/drivers/framebuffer/spec/sdl/fb_sdl.cc +++ b/repos/os/src/drivers/framebuffer/spec/sdl/fb_sdl.cc @@ -1,11 +1,12 @@ /* * \brief SDL-based implementation of the Genode framebuffer * \author Norman Feske + * \author Christian Helmuth * \date 2006-07-10 */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2006-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -119,7 +120,7 @@ class Framebuffer::Session_component : public Genode::Rpc_object /** * Main program */ -extern "C" int main(int, char**) +int main() { using namespace Genode; using namespace Framebuffer; @@ -132,12 +133,27 @@ extern "C" int main(int, char**) */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { - PERR("SDL_Init failed\n"); + PERR("SDL_Init failed (%s)", SDL_GetError()); return -1; } + /* + * We're testing only X11. + */ + static char driver[16] = { 0 }; + SDL_VideoDriverName(driver, sizeof(driver)); + if (::strcmp(driver, "x11") != 0) { + PERR("fb_sdl works on X11 only. Your SDL backend is \"%s\".", driver); + return -2; + } + Genode::size_t bpp = Framebuffer::Mode::bytes_per_pixel(scr_format); screen = SDL_SetVideoMode(scr_width, scr_height, bpp*8, SDL_SWSURFACE); + if (!screen) { + PERR("SDL_SetVideoMode failed (%s)", SDL_GetError()); + return -3; + } + SDL_ShowCursor(0); Genode::printf("creating virtual framebuffer for mode %ldx%ld@%zd\n", @@ -152,7 +168,7 @@ extern "C" int main(int, char**) fb_ds_addr = fb_ds.local_addr(); } catch (...) { PERR("Could not allocate dataspace for virtual frame buffer"); - return -2; + return -4; } /* diff --git a/repos/os/src/drivers/framebuffer/spec/sdl/input.cc b/repos/os/src/drivers/framebuffer/spec/sdl/input.cc index 65e5be90a..d9fa82628 100644 --- a/repos/os/src/drivers/framebuffer/spec/sdl/input.cc +++ b/repos/os/src/drivers/framebuffer/spec/sdl/input.cc @@ -1,11 +1,12 @@ /* * \brief SDL input support * \author Norman Feske + * \author Christian Helmuth * \date 2006-08-16 */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2006-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -138,7 +139,7 @@ static long convert_keycode(int sdl_keycode) }; -Input::Event wait_for_event() +static Input::Event wait_for_sdl_event() { using namespace Input; @@ -166,18 +167,30 @@ Input::Event wait_for_event() case SDL_MOUSEBUTTONUP: switch (event.button.button) { - case SDL_BUTTON_LEFT: keycode = BTN_LEFT; break; - case SDL_BUTTON_RIGHT: keycode = BTN_RIGHT; break; - default: keycode = 0; + case SDL_BUTTON_LEFT: keycode = BTN_LEFT; break; + case SDL_BUTTON_MIDDLE: keycode = BTN_MIDDLE; break; + case SDL_BUTTON_RIGHT: keycode = BTN_RIGHT; break; + default: keycode = 0; } } /* determine event type */ Event::Type type; switch (event.type) { - case SDL_MOUSEMOTION: type = Event::MOTION; break; + case SDL_MOUSEMOTION: + type = Event::MOTION; + break; + case SDL_KEYUP: - case SDL_MOUSEBUTTONUP: type = Event::RELEASE; break; + case SDL_MOUSEBUTTONUP: + if (event.button.button == SDL_BUTTON_WHEELUP + || event.button.button == SDL_BUTTON_WHEELDOWN) + /* ignore */ + return Event(); + + type = Event::RELEASE; + break; + case SDL_KEYDOWN: case SDL_MOUSEBUTTONDOWN: if (event.button.button == SDL_BUTTON_WHEELUP) { @@ -189,8 +202,22 @@ Input::Event wait_for_event() } type = Event::PRESS; break; - default: type = Event::INVALID; + + default: + return Event(); } return Event(type, keycode, mx, my, mx - ox, my - oy); } + +Input::Event wait_for_event() +{ + Input::Event e; + + /* prevent flooding of client with invalid events */ + do { + e = wait_for_sdl_event(); + } while (e.type() == Input::Event::INVALID); + + return e; +}