Use signals for delivering input events

This patch changes both the Input::Session interface and the skeleton
for the server-side implementation of this interface
('input/component.h').

The Input::Session interface offers a new 'sigh' function, which can be
called be the client to register a signal handler. The signal handler
gets notified on the arrival of new input. This alleviates the need to
poll for input events at the client side.

The server-side skeleton for implementing input services underwent a
redesign to make it more modular and robust. I.e., there are no
global functions needed at the server side and the event-queue
enable/disable mechanism is implemented at a central place (in the root
component) rather than inside each driver.

Fixes #46
This commit is contained in:
Norman Feske
2014-05-07 10:33:20 +02:00
committed by Christian Helmuth
parent 6c10bfe049
commit 0ed68a56b7
39 changed files with 643 additions and 733 deletions

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (C) 2007-2013 Genode Labs GmbH
* Copyright (C) 2007-2014 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.
@ -14,57 +14,70 @@
#ifndef _EVENT_QUEUE_H_
#define _EVENT_QUEUE_H_
#include <base/printf.h>
#include <base/signal.h>
#include <input/event.h>
#include <os/ring_buffer.h>
/**
* Input event queue
*
* We expect the client to fetch events circa each 10ms. The PS/2 driver queues
* up to 255 events, which should be enough. Normally, PS/2 generates not more
* than 16Kbit/s, which would correspond to ca. 66 mouse events per 10ms.
*/
class Event_queue
namespace Input { class Event_queue; };
class Input::Event_queue
{
public:
/**
* Input event queue
*
* We expect the client to fetch events circa each 10ms. The PS/2 driver
* queues up to 255 events, which should be enough. Normally, PS/2
* generates not more than 16Kbit/s, which would correspond to ca. 66 mouse
* events per 10ms.
*/
enum { QUEUE_SIZE = 512U };
private:
bool _enabled;
Ring_buffer<Input::Event, 512> _ev_queue;
Ring_buffer<Input::Event, QUEUE_SIZE> _queue;
bool _enabled = false;
Genode::Signal_context_capability _sigh;
public:
Event_queue() : _enabled(false), _ev_queue() { }
typedef typename Ring_buffer<Input::Event, QUEUE_SIZE>::Overflow Overflow;
void enable() { _enabled = true; }
void disable() { _enabled = false; }
void enabled(bool enabled) { _enabled = enabled; }
void add(Input::Event e)
bool enabled() const { return _enabled; }
void sigh(Genode::Signal_context_capability sigh) { _sigh = sigh; }
void submit_signal()
{
if (!_enabled) return;
try {
_ev_queue.add(e);
} catch (Ring_buffer<Input::Event, 512>::Overflow) {
PWRN("event buffer overflow");
}
if (_sigh.valid())
Genode::Signal_transmitter(_sigh).submit();
}
Input::Event get()
/**
* \throw Overflow
*/
void add(Input::Event ev, bool submit_signal_immediately = true)
{
if (_enabled)
return _ev_queue.get();
else
return Input::Event();
if (!_enabled)
return;
_queue.add(ev);
if (submit_signal_immediately)
submit_signal();
}
bool empty()
{
if (_enabled)
return _ev_queue.empty();
else
return true;
}
Input::Event get() { return _queue.get(); }
bool empty() const { return _queue.empty(); }
int avail_capacity() const { return _queue.avail_capacity(); }
};
#endif /* _EVENT_QUEUE_H_ */