# HG changeset patch # User Paul Boddie # Date 1526679711 -7200 # Node ID c5af0606a3d10a9a4116f5b724f25311cf3bb28d # Parent 951e3acf12cecf8b0c49f7b6b5f87c86c2c6469b Introduced an event loop class that knows about handlers and event types. Tidied up the handler mechanism, eliminating the superfluous private data, since the event details are meant to take the place of such data. Changed the example to use separate handlers depending on the presentation mode. diff -r 951e3acf12ce -r c5af0606a3d1 pkg/devices/input/include/input-event-loop.h --- a/pkg/devices/input/include/input-event-loop.h Fri May 18 22:34:51 2018 +0200 +++ b/pkg/devices/input/include/input-event-loop.h Fri May 18 23:41:51 2018 +0200 @@ -29,20 +29,10 @@ #include #include -typedef L4Re::Event_buffer::Event Event_type; - /* Input event loop abstraction. */ -class Input_event_loop : public Event_loop +class Input_event_loop : public Event_handler_loop { - /* Handler function type. */ - - typedef void (*Event_handler)(Event_type &, void *); - - /* External handler function. */ - - Event_handler _handler; - /* Event buffer and notification interrupt capability. */ L4Re::Event_buffer _event_buffer; @@ -52,22 +42,21 @@ L4::Cap _irq; public: - /* Initialise the event loop with an event handler function and private data, - an event buffer, a notification interrupt, and a thread priority. */ + /* Initialise the event loop with an event buffer, a notification interrupt, + and a thread priority. */ - explicit Input_event_loop(Event_handler handler, void *priv, - L4Re::Event_buffer event_buffer, + explicit Input_event_loop(L4Re::Event_buffer event_buffer, L4::Cap irq, int priority=0x20) - : _handler(handler), Event_loop(priv, priority), _event_buffer(event_buffer), _irq(irq) + : Event_handler_loop(priority), _event_buffer(event_buffer), _irq(irq) { } - /* Event handler method. */ + /* Event handler method, dispatching to the provided handler. */ virtual void handle(); - /* Initiation function. */ + /* Start the loop, dispatching to the handle method. */ virtual void start(l4_umword_t label=0xDF00); }; diff -r 951e3acf12ce -r c5af0606a3d1 pkg/devices/input/src/client/input-event-loop.cc --- a/pkg/devices/input/src/client/input-event-loop.cc Fri May 18 22:34:51 2018 +0200 +++ b/pkg/devices/input/src/client/input-event-loop.cc Fri May 18 23:41:51 2018 +0200 @@ -28,13 +28,13 @@ void Input_event_loop::handle() { - L4Re::Event_buffer::Event *event; + Event_type *event; if (!l4_error(_irq->receive())) { while ((event = _event_buffer.next())) { - _handler(*event, _priv); + _handler(*event); event->free(); } } diff -r 951e3acf12ce -r c5af0606a3d1 pkg/devices/util/include/event-loop.h --- a/pkg/devices/util/include/event-loop.h Fri May 18 22:34:51 2018 +0200 +++ b/pkg/devices/util/include/event-loop.h Fri May 18 23:41:51 2018 +0200 @@ -31,21 +31,16 @@ class Event_loop { protected: - /* Private data for the handler. */ - - void *_priv; - /* Thread properties. */ int _priority; pthread_t _pthread; public: - /* Initialise the event loop with an event handler function and private data, - plus thread priority. */ + /* Initialise the event loop with a thread priority. */ - explicit Event_loop(void *priv, int priority=0x20) - : _priv(priv), _priority(priority) + explicit Event_loop(int priority=0x20) + : _priority(priority) { } @@ -62,4 +57,40 @@ virtual void start(); }; + + +/* Event loop with handler. */ + +template +class Event_handler_loop : public Event_loop +{ +protected: + /* Event type. */ + + typedef T Event_type; + + /* Handler function type. */ + + typedef void (*Event_handler)(Event_type &); + + /* External handler function. */ + + Event_handler _handler; + +public: + /* Initialise the event loop with a thread priority. */ + + explicit Event_handler_loop(int priority=0x20) + : Event_loop(priority) + { + } + + /* Attach a handler to the loop. */ + + virtual void attach(Event_handler handler) + { + _handler = handler; + } +}; + #endif diff -r 951e3acf12ce -r c5af0606a3d1 pkg/landfall-examples/input_event_client/input_event_client.cc --- a/pkg/landfall-examples/input_event_client/input_event_client.cc Fri May 18 22:34:51 2018 +0200 +++ b/pkg/landfall-examples/input_event_client/input_event_client.cc Fri May 18 23:41:51 2018 +0200 @@ -51,6 +51,7 @@ #include #include + #include #include #include @@ -141,7 +142,7 @@ static uint8_t row = 0; static uint32_t text_x = 0, text_y = 0, next_y = 0; -static void handler(L4Re::Event_buffer::Event &event, void *priv) +static void show_key_code(L4Re::Event_buffer::Event &event) { uint32_t colsize = view_info.width / 10, rowsize = view_info.height / 20; @@ -150,26 +151,28 @@ /* Convert the key code into a bit pattern. */ - if (!priv) - { - for (column = 0, mask = (1 << 9); column < 10; column++, mask >>= 1) - _screen->draw_box(Rect(Point(column * colsize, row * rowsize), - Area(colsize, rowsize)), - event.payload.code & mask ? ( - event.payload.value ? Rgb32::Color(0, 255, 0) - : Rgb32::Color(255, 0, 0)) - : Rgb32::Color(0, 0, 0)); + for (column = 0, mask = (1 << 9); column < 10; column++, mask >>= 1) + _screen->draw_box(Rect(Point(column * colsize, row * rowsize), + Area(colsize, rowsize)), + event.payload.code & mask ? ( + event.payload.value ? Rgb32::Color(0, 255, 0) + : Rgb32::Color(255, 0, 0)) + : Rgb32::Color(0, 0, 0)); + + /* Advance to the next row, wrapping around. */ - /* Advance to the next row, wrapping around. */ + row = (row + 1) % 20; - row = (row + 1) % 20; - } + /* Refresh the display. */ - /* Or produce a string. */ + l4re_util_video_goos_fb_refresh(&gfb, 0, 0, view_info.width, view_info.height); +} - else if (event.payload.value) +static void show_key_label(L4Re::Event_buffer::Event &event) +{ + if (event.payload.value) { - const char *s = ((const char *(*)(int)) priv)(event.payload.code); + const char *s = key_to_string(event.payload.code); Rgba32::Color col; if (!s) @@ -226,12 +229,6 @@ -/* Event buffer memory. */ - -static void *evmem = 0; - - - /* Arguments: [ chars ] */ int main(int argc, char *argv[]) @@ -272,11 +269,12 @@ L4::Cap mem = L4Re::Util::cap_alloc.alloc(); if (!mem.is_valid()) return 1; - if (event_server->get_buffer(mem)) return 1; /* Attach the event buffer to this task. */ + void *evmem = 0; + if (L4Re::Env::env()->rm()->attach(&evmem, mem->size(), L4Re::Rm::Search_addr, L4::Ipc::make_cap_rw(mem))) return 1; @@ -292,16 +290,18 @@ if (event_server->bind(0, irq)) return 1; - /* Private data for the handler function. */ + /* Create an event handler. */ - void *priv = 0; + Input_event_loop loop(event_buffer, irq); + + /* Attach the handler function. */ if ((argc > 1) && (!strcmp(argv[1], "chars"))) - priv = (void *) key_to_string; + loop.attach(show_key_label); + else + loop.attach(show_key_code); - /* Create an event handler and wait for events. */ - - Input_event_loop loop(handler, priv, event_buffer, irq); + /* Wait for events. */ loop.start(); l4_sleep_forever();