genode/repos/demo/include/scout/platform.h
Norman Feske b44f0554bd Adapt high-level components to new parent API
This patch adjusts the various users of the 'Child' API to the changes
on the account of the new non-blocking parent interface. It also removes
the use of the no-longer-available 'Connection::KEEP_OPEN' feature.

With the adjustment, we took the opportunity to redesign several
components to fit the non-blocking execution model much better, in
particular the demo applications.

Issue #2120
2016-11-30 13:37:03 +01:00

160 lines
3.3 KiB
C++

/*
* \brief Platform abstraction
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*
* This interface specifies the target-platform-specific functions.
*/
/*
* Copyright (C) 2005-2013 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.
*/
#ifndef _INCLUDE__SCOUT__PLATFORM_H_
#define _INCLUDE__SCOUT__PLATFORM_H_
#include <base/env.h>
#include <base/attached_dataspace.h>
#include <base/semaphore.h>
#include <timer_session/connection.h>
#include <input_session/input_session.h>
#include <input/event.h>
#include <scout/event.h>
#include <scout/canvas.h>
namespace Scout {
typedef Genode::Point<> Point;
typedef Genode::Area<> Area;
typedef Genode::Rect<> Rect;
class Platform;
}
inline void *operator new(__SIZE_TYPE__ size)
{
using Genode::env;
void *addr = env()->heap()->alloc(size);
if (!addr) {
Genode::error("env()->heap() has consumed ", env()->heap()->consumed());
Genode::error("env()->ram_session()->quota = ", env()->ram_session()->quota());
throw Genode::Allocator::Out_of_memory();
}
return addr;
}
class Scout::Platform
{
private:
Genode::Env &_env;
Event_handler *_event_handler = nullptr;
int _mx = 0, _my = 0;
void _handle_event(Event const &ev)
{
if (_event_handler)
_event_handler->handle_event(ev);
}
/****************************
** Timer event processing **
****************************/
Timer::Connection _timer { _env };
unsigned long _ticks = 0;
void _handle_timer()
{
_ticks = _timer.elapsed_ms();
Event ev;
ev.assign(Event::TIMER, _mx, _my, 0);
_handle_event(ev);
}
Genode::Signal_handler<Platform> _timer_handler {
_env.ep(), *this, &Platform::_handle_timer };
/****************************
** Input event processing **
****************************/
Input::Session &_input;
Genode::Attached_dataspace _input_ds { _env.rm(), _input.dataspace() };
Input::Event * const _ev_buf = _input_ds.local_addr<Input::Event>();
bool _event_pending = 0;
void _handle_input()
{
if (_input.pending() == false) return;
for (int i = 0, num = _input.flush(); i < num; i++)
{
Event ev;
Input::Event e = _ev_buf[i];
_event_pending = i + 1 < num;
if (e.type() == Input::Event::RELEASE
|| e.type() == Input::Event::PRESS) {
_mx = e.ax();
_my = e.ay();
ev.assign(e.type() == Input::Event::PRESS ? Event::PRESS : Event::RELEASE,
e.ax(), e.ay(), e.code());
_handle_event(ev);
}
if (e.type() == Input::Event::MOTION) {
_mx = e.ax();
_my = e.ay();
ev.assign(Event::MOTION, e.ax(), e.ay(), e.code());
_handle_event(ev);
}
}
}
Genode::Signal_handler<Platform> _input_handler {
_env.ep(), *this, &Platform::_handle_input};
public:
Platform(Genode::Env &env, Input::Session &input)
: _env(env), _input(input) { }
/**
* Get timer ticks in miilliseconds
*/
unsigned long timer_ticks() const { return _ticks; }
/**
* Register event handler
*/
void event_handler(Event_handler &handler)
{
_event_handler = &handler;
_timer.sigh(_timer_handler);
_timer.trigger_periodic(40*1000);
_input.sigh(_input_handler);
}
bool event_pending() const { return _event_pending; }
};
#endif /* _INCLUDE__SCOUT__PLATFORM_H_ */