mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
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
This commit is contained in:
parent
8bafb9d41b
commit
b44f0554bd
@ -26,65 +26,138 @@
|
||||
#include <cap_session/connection.h>
|
||||
#include <timer_session/timer_session.h>
|
||||
#include <pd_session/client.h>
|
||||
|
||||
#include <init/child.h>
|
||||
|
||||
class Launchpad_child_policy : public Genode::Child_policy,
|
||||
public Genode::Client
|
||||
class Launchpad;
|
||||
|
||||
|
||||
class Launchpad_child : public Genode::Child_policy,
|
||||
public Genode::List<Launchpad_child>::Element,
|
||||
public Genode::Child_service::Wakeup
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Genode::Child_policy::Name Name;
|
||||
|
||||
typedef Genode::Registered<Genode::Child_service> Child_service;
|
||||
typedef Genode::Registered<Genode::Parent_service> Parent_service;
|
||||
|
||||
typedef Genode::Registry<Child_service> Child_services;
|
||||
typedef Genode::Registry<Parent_service> Parent_services;
|
||||
|
||||
private:
|
||||
|
||||
typedef Genode::String<64> Name;
|
||||
Name const _name;
|
||||
|
||||
Genode::Server *_server;
|
||||
Genode::Service_registry *_parent_services;
|
||||
Genode::Service_registry *_child_services;
|
||||
Genode::Dataspace_capability _config_ds;
|
||||
Genode::Rpc_entrypoint *_parent_entrypoint;
|
||||
Init::Child_policy_enforce_labeling _labeling_policy;
|
||||
Init::Child_policy_provide_rom_file _config_policy;
|
||||
Init::Child_policy_provide_rom_file _binary_policy;
|
||||
Genode::Env &_env;
|
||||
|
||||
Genode::Ram_session_capability _ref_ram_cap;
|
||||
Genode::Ram_session_client _ref_ram { _ref_ram_cap };
|
||||
Genode::size_t const _ram_quota;
|
||||
|
||||
Parent_services &_parent_services;
|
||||
Child_services &_child_services;
|
||||
|
||||
Genode::Dataspace_capability _config_ds;
|
||||
|
||||
Genode::Session_requester _session_requester;
|
||||
|
||||
Init::Child_policy_enforce_labeling _labeling_policy { _name.string() };
|
||||
Init::Child_policy_provide_rom_file _config_policy;
|
||||
|
||||
Genode::Child _child;
|
||||
|
||||
/**
|
||||
* Child_service::Wakeup callback
|
||||
*/
|
||||
void wakeup_child_service() override
|
||||
{
|
||||
_session_requester.trigger_update();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static Genode::Service *_find_service(Genode::Registry<T> &services,
|
||||
Genode::Service::Name const &name)
|
||||
{
|
||||
Genode::Service *service = nullptr;
|
||||
services.for_each([&] (T &s) {
|
||||
if (!service && (s.name() == name))
|
||||
service = &s; });
|
||||
return service;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Launchpad_child_policy(const char *name,
|
||||
Genode::Server *server,
|
||||
Genode::Service_registry *parent_services,
|
||||
Genode::Service_registry *child_services,
|
||||
Genode::Dataspace_capability config_ds,
|
||||
Genode::Dataspace_capability binary_ds,
|
||||
Genode::Rpc_entrypoint *parent_entrypoint)
|
||||
Launchpad_child(Genode::Env &env,
|
||||
Genode::Session_label const &label,
|
||||
Name const &elf_name,
|
||||
Genode::size_t ram_quota,
|
||||
Parent_services &parent_services,
|
||||
Child_services &child_services,
|
||||
Genode::Dataspace_capability config_ds)
|
||||
:
|
||||
_name(name),
|
||||
_server(server),
|
||||
_name(label),
|
||||
_env(env), _ref_ram_cap(env.ram_session_cap()), _ram_quota(ram_quota),
|
||||
_parent_services(parent_services),
|
||||
_child_services(child_services),
|
||||
_config_ds(config_ds),
|
||||
_parent_entrypoint(parent_entrypoint),
|
||||
_labeling_policy(_name.string()),
|
||||
_config_policy("config", config_ds, _parent_entrypoint),
|
||||
_binary_policy("binary", binary_ds, _parent_entrypoint)
|
||||
_session_requester(env.ep().rpc_ep(), _env.ram(), _env.rm()),
|
||||
_config_policy("config", config_ds, &_env.ep().rpc_ep()),
|
||||
_child(_env.rm(), _env.ep().rpc_ep(), *this)
|
||||
{ }
|
||||
|
||||
const char *name() const { return _name.string(); }
|
||||
|
||||
Genode::Service *resolve_session_request(const char *service_name,
|
||||
const char *args)
|
||||
~Launchpad_child()
|
||||
{
|
||||
Genode::Service *service;
|
||||
using namespace Genode;
|
||||
|
||||
/* unregister services */
|
||||
_child_services.for_each(
|
||||
[&] (Child_service &service) {
|
||||
if (service.has_id_space(_session_requester.id_space()))
|
||||
Genode::destroy(_child.heap(), &service); });
|
||||
}
|
||||
|
||||
Genode::Allocator &heap() { return _child.heap(); }
|
||||
|
||||
|
||||
/****************************
|
||||
** Child_policy interface **
|
||||
****************************/
|
||||
|
||||
Name name() const override { return _name; }
|
||||
|
||||
Genode::Ram_session &ref_ram() override { return _ref_ram; }
|
||||
|
||||
Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
|
||||
|
||||
void init(Genode::Ram_session &session,
|
||||
Genode::Ram_session_capability cap) override
|
||||
{
|
||||
session.ref_account(_ref_ram_cap);
|
||||
_ref_ram.transfer_quota(cap, _ram_quota);
|
||||
}
|
||||
|
||||
Genode::Id_space<Genode::Parent::Server> &server_id_space() override {
|
||||
return _session_requester.id_space(); }
|
||||
|
||||
Genode::Service &resolve_session_request(Genode::Service::Name const &service_name,
|
||||
Genode::Session_state::Args const &args) override
|
||||
{
|
||||
Genode::Service *service = nullptr;
|
||||
|
||||
/* check for config file request */
|
||||
if ((service = _config_policy.resolve_session_request(service_name, args)))
|
||||
return service;
|
||||
if ((service = _config_policy
|
||||
.resolve_session_request(service_name.string(), args.string())))
|
||||
return *service;
|
||||
|
||||
/* check for binary file request */
|
||||
if ((service = _binary_policy.resolve_session_request(service_name, args)))
|
||||
return service;
|
||||
/* check for "session_requests" ROM request */
|
||||
Genode::Session_label const label(Genode::label_from_args(args.string()));
|
||||
if (service_name == Genode::Rom_session::service_name()
|
||||
&& label.last_element() == Genode::Session_requester::rom_name())
|
||||
return _session_requester.service();
|
||||
|
||||
/* if service is provided by one of our children, use it */
|
||||
if ((service = _child_services->find(service_name)))
|
||||
return service;
|
||||
if ((service = _find_service(_child_services, service_name)))
|
||||
return *service;
|
||||
|
||||
/*
|
||||
* Handle special case of the demo scenario when the user uses
|
||||
@ -100,130 +173,33 @@ class Launchpad_child_policy : public Genode::Child_policy,
|
||||
* interacted, however, would block at the parent interface
|
||||
* until this condition gets satisfied.
|
||||
*/
|
||||
if (Genode::strcmp(service_name, "Input") != 0
|
||||
&& Genode::strcmp(service_name, "Framebuffer") != 0
|
||||
&& (service = _parent_services->find(service_name)))
|
||||
return service;
|
||||
if (service_name != "Input"
|
||||
&& service_name != "Framebuffer"
|
||||
&& ((service = _find_service(_parent_services, service_name))))
|
||||
return *service;
|
||||
|
||||
/* wait for the service to become available */
|
||||
Genode::Client client;
|
||||
return _child_services->wait_for_service(service_name,
|
||||
&client, name());
|
||||
Genode::warning(name(), ": service ", service_name, " not available");
|
||||
throw Genode::Parent::Service_denied();
|
||||
}
|
||||
|
||||
void filter_session_args(const char *service, char *args,
|
||||
Genode::size_t args_len)
|
||||
void filter_session_args(Genode::Service::Name const &service,
|
||||
char *args, Genode::size_t args_len) override
|
||||
{
|
||||
_labeling_policy.filter_session_args(service, args, args_len);
|
||||
_labeling_policy.filter_session_args(service.string(), args, args_len);
|
||||
}
|
||||
|
||||
bool announce_service(const char *service_name,
|
||||
Genode::Root_capability root,
|
||||
Genode::Allocator *alloc,
|
||||
Genode::Server * /*server*/)
|
||||
void announce_service(Genode::Service::Name const &service_name) override
|
||||
{
|
||||
if (_child_services->find(service_name)) {
|
||||
PWRN("%s: service %s is already registered",
|
||||
name(), service_name);
|
||||
return false;
|
||||
if (_find_service(_child_services, service_name)) {
|
||||
Genode::warning(name(), ": service ", service_name, " is already registered");
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX remove potential race between checking for and inserting service */
|
||||
|
||||
_child_services->insert(new (alloc)
|
||||
Genode::Child_service(service_name, root, _server));
|
||||
Genode::printf("%s registered service %s\n", name(), service_name);
|
||||
return true;
|
||||
new (_child.heap())
|
||||
Child_service(_child_services, _session_requester.id_space(),
|
||||
_child.session_factory(), service_name,
|
||||
_child.ram_session_cap(), *this);
|
||||
}
|
||||
|
||||
void unregister_services()
|
||||
{
|
||||
Genode::Service *rs;
|
||||
while ((rs = _child_services->find_by_server(_server)))
|
||||
_child_services->remove(rs);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Launchpad;
|
||||
|
||||
|
||||
class Launchpad_child : public Genode::List<Launchpad_child>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
static Genode::Dataspace_capability _ldso_ds();
|
||||
|
||||
Launchpad *_launchpad;
|
||||
|
||||
/*
|
||||
* Entry point used for serving the parent interface and the
|
||||
* locally provided ROM sessions for the 'config' and 'binary'
|
||||
* files.
|
||||
*/
|
||||
enum { ENTRYPOINT_STACK_SIZE = 12*1024 };
|
||||
Genode::Rpc_entrypoint _entrypoint;
|
||||
|
||||
Genode::Region_map_client _address_space;
|
||||
|
||||
Genode::Rom_session_client _rom;
|
||||
Genode::Pd_session_client _pd;
|
||||
Genode::Ram_session_client _ram;
|
||||
Genode::Cpu_session_client _cpu;
|
||||
|
||||
Genode::Child::Initial_thread _initial_thread;
|
||||
|
||||
Genode::Server _server;
|
||||
|
||||
Launchpad_child_policy _policy;
|
||||
Genode::Child _child;
|
||||
|
||||
public:
|
||||
|
||||
Launchpad_child(const char *name,
|
||||
Genode::Dataspace_capability elf_ds,
|
||||
Genode::Pd_session_capability pd,
|
||||
Genode::Ram_session_capability ram,
|
||||
Genode::Cpu_session_capability cpu,
|
||||
Genode::Rom_session_capability rom,
|
||||
Genode::Cap_session *cap_session,
|
||||
Genode::Service_registry *parent_services,
|
||||
Genode::Service_registry *child_services,
|
||||
Genode::Dataspace_capability config_ds,
|
||||
Launchpad *launchpad)
|
||||
:
|
||||
_launchpad(launchpad),
|
||||
_entrypoint(cap_session, ENTRYPOINT_STACK_SIZE, name, false),
|
||||
_address_space(Genode::Pd_session_client(pd).address_space()),
|
||||
_rom(rom), _pd(pd), _ram(ram), _cpu(cpu),
|
||||
_initial_thread(_cpu, _pd, name), _server(_ram),
|
||||
_policy(name, &_server, parent_services, child_services,
|
||||
config_ds, elf_ds, &_entrypoint),
|
||||
_child(elf_ds, _ldso_ds(), _pd, _pd, _ram, _ram, _cpu,
|
||||
_initial_thread, *Genode::env()->rm_session(),
|
||||
_address_space, _entrypoint, _policy)
|
||||
{
|
||||
_entrypoint.activate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Required to forcefully kill client which blocks on a session
|
||||
* opening quest where the service is not up yet.
|
||||
*/
|
||||
void cancel_blocking() { _entrypoint.cancel_blocking(); }
|
||||
|
||||
Genode::Rom_session_capability rom_session_cap() { return _rom; }
|
||||
Genode::Ram_session_capability ram_session_cap() { return _ram; }
|
||||
Genode::Cpu_session_capability cpu_session_cap() { return _cpu; }
|
||||
|
||||
const char *name() const { return _policy.name(); }
|
||||
|
||||
const Genode::Server *server() const { return &_server; }
|
||||
|
||||
Genode::Allocator *heap() { return _child.heap(); }
|
||||
|
||||
void revoke_server(const Genode::Server *server) {
|
||||
_child.revoke_server(server); }
|
||||
};
|
||||
|
||||
|
||||
@ -231,31 +207,31 @@ class Launchpad
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
Genode::Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
unsigned long _initial_quota;
|
||||
|
||||
Genode::Service_registry _parent_services;
|
||||
Genode::Service_registry _child_services;
|
||||
Launchpad_child::Parent_services _parent_services;
|
||||
Launchpad_child::Child_services _child_services;
|
||||
|
||||
Genode::Lock _children_lock;
|
||||
Genode::List<Launchpad_child> _children;
|
||||
|
||||
bool _child_name_exists(const char *name);
|
||||
void _get_unique_child_name(const char *filename, char *dst, int dst_len);
|
||||
bool _child_name_exists(Launchpad_child::Name const &);
|
||||
|
||||
Launchpad_child::Name _get_unique_child_name(Launchpad_child::Name const &);
|
||||
|
||||
Genode::Sliced_heap _sliced_heap;
|
||||
|
||||
/* cap session for allocating capabilities for parent interfaces */
|
||||
Genode::Cap_connection _cap_session;
|
||||
|
||||
protected:
|
||||
|
||||
int _ypos;
|
||||
|
||||
public:
|
||||
|
||||
Genode::Lock gui_lock;
|
||||
|
||||
Launchpad(unsigned long initial_quota);
|
||||
Launchpad(Genode::Env &env, unsigned long initial_quota);
|
||||
|
||||
unsigned long initial_quota() { return _initial_quota; }
|
||||
|
||||
@ -273,36 +249,26 @@ class Launchpad
|
||||
|
||||
virtual void quota(unsigned long quota) { }
|
||||
|
||||
virtual void add_launcher(const char *filename,
|
||||
virtual void add_launcher(Launchpad_child::Name const &binary_name,
|
||||
unsigned long default_quota,
|
||||
Genode::Dataspace_capability config_ds) { }
|
||||
|
||||
virtual void add_child(const char *unique_name,
|
||||
virtual void add_child(Launchpad_child::Name const &,
|
||||
unsigned long quota,
|
||||
Launchpad_child *launchpad_child,
|
||||
Genode::Allocator *alloc) { }
|
||||
Launchpad_child &,
|
||||
Genode::Allocator &) { }
|
||||
|
||||
virtual void remove_child(const char *name,
|
||||
Genode::Allocator *alloc) { }
|
||||
virtual void remove_child(Launchpad_child::Name const &,
|
||||
Genode::Allocator &) { }
|
||||
|
||||
Launchpad_child *start_child(const char *prg_name, unsigned long quota,
|
||||
Launchpad_child *start_child(Launchpad_child::Name const &binary_name,
|
||||
unsigned long quota,
|
||||
Genode::Dataspace_capability config_ds);
|
||||
|
||||
/**
|
||||
* Exit child and close all its sessions
|
||||
*
|
||||
* \param timer Timer session to use for watchdog
|
||||
* mechanism. When using the default
|
||||
* value, a new timer session gets
|
||||
* created during the 'exit_child'
|
||||
* call.
|
||||
* \param session_close_timeout_ms Timeout in milliseconds until a an
|
||||
* unresponsive service->close call
|
||||
* gets canceled.
|
||||
*/
|
||||
void exit_child(Launchpad_child *child,
|
||||
Timer::Session *timer = 0,
|
||||
int session_close_timeout_ms = 2000);
|
||||
void exit_child(Launchpad_child &child);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__LAUNCHPAD__LAUNCHPAD_H_ */
|
||||
|
@ -181,7 +181,7 @@ class Scout::Element
|
||||
/**
|
||||
* Handle user input or timer event
|
||||
*/
|
||||
void handle_event(Event &ev) { if (_evh) _evh->handle(ev); }
|
||||
void handle_event(Event const &ev) { if (_evh) _evh->handle_event(ev); }
|
||||
|
||||
/**
|
||||
* Request the chapter in which the element lives
|
||||
|
@ -76,7 +76,7 @@ class Scout::Event_handler
|
||||
/**
|
||||
* Handle event
|
||||
*/
|
||||
virtual void handle(Event &e) = 0;
|
||||
virtual void handle_event(Event const &e) = 0;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__SCOUT__EVENT_H_ */
|
||||
|
@ -17,6 +17,7 @@
|
||||
#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>
|
||||
@ -51,150 +52,108 @@ class Scout::Platform
|
||||
{
|
||||
private:
|
||||
|
||||
/*****************
|
||||
** Event queue **
|
||||
*****************/
|
||||
|
||||
class Event_queue
|
||||
Genode::Env &_env;
|
||||
Event_handler *_event_handler = nullptr;
|
||||
|
||||
int _mx = 0, _my = 0;
|
||||
|
||||
void _handle_event(Event const &ev)
|
||||
{
|
||||
private:
|
||||
if (_event_handler)
|
||||
_event_handler->handle_event(ev);
|
||||
}
|
||||
|
||||
static const int queue_size = 1024;
|
||||
|
||||
int _head;
|
||||
int _tail;
|
||||
Genode::Semaphore _sem;
|
||||
Genode::Lock _head_lock; /* synchronize add */
|
||||
/****************************
|
||||
** Timer event processing **
|
||||
****************************/
|
||||
|
||||
Event _queue[queue_size];
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
public:
|
||||
unsigned long _ticks = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Event_queue(): _head(0), _tail(0)
|
||||
{
|
||||
Genode::memset(_queue, 0, sizeof(_queue));
|
||||
}
|
||||
|
||||
void add(Event ev)
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_head_lock);
|
||||
|
||||
if ((_head + 1)%queue_size != _tail) {
|
||||
|
||||
_queue[_head] = ev;
|
||||
_head = (_head + 1)%queue_size;
|
||||
_sem.up();
|
||||
}
|
||||
}
|
||||
|
||||
Event get()
|
||||
{
|
||||
_sem.down();
|
||||
Event ev = _queue[_tail];
|
||||
_tail = (_tail + 1)%queue_size;
|
||||
return ev;
|
||||
}
|
||||
|
||||
int pending() const { return _head != _tail; }
|
||||
|
||||
} _event_queue;
|
||||
|
||||
/******************
|
||||
** Timer thread **
|
||||
******************/
|
||||
|
||||
class Timer_thread : public Genode::Thread_deprecated<4096>
|
||||
void _handle_timer()
|
||||
{
|
||||
private:
|
||||
_ticks = _timer.elapsed_ms();
|
||||
|
||||
Timer::Connection _timer;
|
||||
Input::Session &_input;
|
||||
Input::Event *_ev_buf = { Genode::env()->rm_session()->attach(_input.dataspace()) };
|
||||
Event_queue &_event_queue;
|
||||
int _mx, _my;
|
||||
unsigned long _ticks = { 0 };
|
||||
Event ev;
|
||||
ev.assign(Event::TIMER, _mx, _my, 0);
|
||||
|
||||
void _import_events()
|
||||
{
|
||||
if (_input.pending() == false) return;
|
||||
_handle_event(ev);
|
||||
}
|
||||
|
||||
for (int i = 0, num = _input.flush(); i < num; i++)
|
||||
{
|
||||
Event ev;
|
||||
Input::Event e = _ev_buf[i];
|
||||
Genode::Signal_handler<Platform> _timer_handler {
|
||||
_env.ep(), *this, &Platform::_handle_timer };
|
||||
|
||||
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());
|
||||
_event_queue.add(ev);
|
||||
}
|
||||
|
||||
if (e.type() == Input::Event::MOTION) {
|
||||
_mx = e.ax();
|
||||
_my = e.ay();
|
||||
ev.assign(Event::MOTION, e.ax(), e.ay(), e.code());
|
||||
_event_queue.add(ev);
|
||||
}
|
||||
}
|
||||
/****************************
|
||||
** 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);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Start thread immediately on construction.
|
||||
*/
|
||||
Timer_thread(Input::Session &input, Event_queue &event_queue)
|
||||
: Thread_deprecated("timer"), _input(input), _event_queue(event_queue)
|
||||
{ start(); }
|
||||
|
||||
void entry()
|
||||
{
|
||||
while (1) {
|
||||
Event ev;
|
||||
ev.assign(Event::TIMER, _mx, _my, 0);
|
||||
_event_queue.add(ev);
|
||||
|
||||
_import_events();
|
||||
|
||||
_timer.msleep(10);
|
||||
_ticks += 10;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long ticks() const { return _ticks; }
|
||||
} _timer_thread;
|
||||
Genode::Signal_handler<Platform> _input_handler {
|
||||
_env.ep(), *this, &Platform::_handle_input};
|
||||
|
||||
public:
|
||||
|
||||
Platform(Input::Session &input) : _timer_thread(input, _event_queue) { }
|
||||
Platform(Genode::Env &env, Input::Session &input)
|
||||
: _env(env), _input(input) { }
|
||||
|
||||
/**
|
||||
* Get timer ticks in miilliseconds
|
||||
*/
|
||||
unsigned long timer_ticks() const { return _timer_thread.ticks(); }
|
||||
unsigned long timer_ticks() const { return _ticks; }
|
||||
|
||||
/**
|
||||
* Return true if an event is pending
|
||||
* Register event handler
|
||||
*/
|
||||
bool event_pending() const { return _event_queue.pending(); }
|
||||
void event_handler(Event_handler &handler)
|
||||
{
|
||||
_event_handler = &handler;
|
||||
|
||||
/**
|
||||
* Request event
|
||||
*
|
||||
* \param e destination where to store event information.
|
||||
*
|
||||
* If there is no event pending, this function blocks
|
||||
* until there is an event to deliver.
|
||||
*/
|
||||
Event get_event() { return _event_queue.get(); }
|
||||
_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_ */
|
||||
|
@ -78,7 +78,7 @@ class Scout::User_state : public Parent_element
|
||||
/**
|
||||
* Apply input event to mouse focus state
|
||||
*/
|
||||
void handle_event(Event &ev)
|
||||
void handle_event(Event const &ev)
|
||||
{
|
||||
_key_cnt += ev.type == Event::PRESS ? 1 : 0;
|
||||
_key_cnt -= ev.type == Event::RELEASE ? 1 : 0;
|
||||
|
@ -34,21 +34,34 @@ class Scout::Window : public Parent_element
|
||||
Graphics_backend &_gfx_backend;
|
||||
Rect _dirty;
|
||||
Area _max_size;
|
||||
Point _view_position;
|
||||
int _request_cnt; /* nb of requests since last process */
|
||||
bool const _scout_quirk; /* enable redraw quirk for scout */
|
||||
|
||||
/*
|
||||
* We limit the rate of (expensive) view-position updates to the rate
|
||||
* of 'process_redraw' calls instead of eagerly responding to
|
||||
* individual input events (which trigger calls of 'vpos').
|
||||
*/
|
||||
Point _view_position, _next_view_position = _view_position;
|
||||
|
||||
void _update_view_position()
|
||||
{
|
||||
if (_view_position == _next_view_position) return;
|
||||
|
||||
_view_position = _next_view_position;
|
||||
_gfx_backend.position(_view_position);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Window(Graphics_backend &gfx_backend, Point position, Area size,
|
||||
Area max_size, bool scout_quirk)
|
||||
:
|
||||
_gfx_backend(gfx_backend), _max_size(max_size), _request_cnt(0),
|
||||
_scout_quirk(scout_quirk)
|
||||
_scout_quirk(scout_quirk), _view_position(position)
|
||||
{
|
||||
/* init element attributes */
|
||||
_view_position = position;
|
||||
_size = size;
|
||||
_size = size;
|
||||
}
|
||||
|
||||
virtual ~Window() { }
|
||||
@ -56,8 +69,8 @@ class Scout::Window : public Parent_element
|
||||
/**
|
||||
* Return current window position
|
||||
*/
|
||||
int view_x() const { return _view_position.x(); }
|
||||
int view_y() const { return _view_position.y(); }
|
||||
int view_x() const { return _next_view_position.x(); }
|
||||
int view_y() const { return _next_view_position.y(); }
|
||||
int view_w() const { return _size.w(); }
|
||||
int view_h() const { return _size.h(); }
|
||||
|
||||
@ -71,11 +84,7 @@ class Scout::Window : public Parent_element
|
||||
/**
|
||||
* Move window to new position
|
||||
*/
|
||||
virtual void vpos(int x, int y)
|
||||
{
|
||||
_view_position = Point(x, y);
|
||||
_gfx_backend.position(_view_position);
|
||||
}
|
||||
virtual void vpos(int x, int y) { _next_view_position = Point(x, y); }
|
||||
|
||||
/**
|
||||
* Define vertical scroll offset
|
||||
@ -133,6 +142,8 @@ class Scout::Window : public Parent_element
|
||||
*/
|
||||
void process_redraw()
|
||||
{
|
||||
_update_view_position();
|
||||
|
||||
if (_request_cnt == 0) return;
|
||||
|
||||
/* get actual drawing area (clipped against canvas dimensions) */
|
||||
@ -198,7 +209,7 @@ class Scout::Drag_event_handler : public Event_handler
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &ev)
|
||||
void handle_event(Event const &ev) override
|
||||
{
|
||||
if (ev.type == Event::PRESS) _key_cnt++;
|
||||
if (ev.type == Event::RELEASE) _key_cnt--;
|
||||
|
@ -32,18 +32,18 @@ class Kill_event_handler : public Scout::Event_handler
|
||||
{
|
||||
private:
|
||||
|
||||
Launchpad *_launchpad;
|
||||
Launchpad_child *_launchpad_child;
|
||||
Launchpad &_launchpad;
|
||||
Launchpad_child &_launchpad_child;
|
||||
|
||||
public:
|
||||
|
||||
Kill_event_handler(Launchpad *launchpad, Launchpad_child *launchpad_child):
|
||||
Kill_event_handler(Launchpad &launchpad, Launchpad_child &launchpad_child):
|
||||
_launchpad(launchpad), _launchpad_child(launchpad_child) { }
|
||||
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Scout::Event &ev)
|
||||
void handle_event(Scout::Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
|
||||
@ -53,7 +53,7 @@ class Kill_event_handler : public Scout::Event_handler
|
||||
if (ev.type == Event::RELEASE) key_cnt--;
|
||||
|
||||
if (ev.type == Event::RELEASE && key_cnt == 0)
|
||||
_launchpad->exit_child(_launchpad_child);
|
||||
_launchpad.exit_child(_launchpad_child);
|
||||
}
|
||||
};
|
||||
|
||||
@ -73,7 +73,7 @@ class Child_entry : public Scout::Parent_element,
|
||||
Scout::Block _block;
|
||||
Kbyte_loadbar<PT> _loadbar;
|
||||
|
||||
char _name[_NAME_LEN];
|
||||
Launchpad_child::Name const _name;
|
||||
|
||||
Scout::Fade_icon<PT, _IW, _IH> _kill_icon;
|
||||
Scout::Fade_icon<PT, _IW, _IH> _fold_icon;
|
||||
@ -85,14 +85,14 @@ class Child_entry : public Scout::Parent_element,
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Child_entry(const char *name, int quota_kb, int max_quota_kb,
|
||||
Launchpad *launchpad, Launchpad_child *launchpad_child)
|
||||
Child_entry(Launchpad_child::Name const &name, int quota_kb, int max_quota_kb,
|
||||
Launchpad &launchpad, Launchpad_child &launchpad_child)
|
||||
:
|
||||
_block(Scout::Block::RIGHT), _loadbar(0, &Scout::label_font),
|
||||
_name(name),
|
||||
_kill_event_handler(launchpad, launchpad_child)
|
||||
{
|
||||
Genode::strncpy(_name, name, sizeof(_name));
|
||||
_block.append_plaintext(_name, &Scout::plain_style);
|
||||
_block.append_plaintext(_name.string(), &Scout::plain_style);
|
||||
|
||||
_loadbar.max_value(max_quota_kb);
|
||||
_loadbar.value(quota_kb);
|
||||
@ -118,7 +118,7 @@ class Child_entry : public Scout::Parent_element,
|
||||
/**
|
||||
* Accessors
|
||||
*/
|
||||
const char *name() { return _name; }
|
||||
Launchpad_child::Name name() { return _name; }
|
||||
|
||||
|
||||
/******************************
|
||||
|
@ -22,6 +22,7 @@ class Launch_entry : public Scout::Parent_element, public Loadbar_listener
|
||||
{
|
||||
private:
|
||||
|
||||
Scout::Launcher::Name _prg_name;
|
||||
Scout::Block _block;
|
||||
Kbyte_loadbar<PT> _loadbar;
|
||||
Scout::Launcher_config _config;
|
||||
@ -37,15 +38,16 @@ class Launch_entry : public Scout::Parent_element, public Loadbar_listener
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Launch_entry(const char *prg_name, unsigned long initial_quota,
|
||||
Launch_entry(Scout::Launcher::Name const &prg_name, unsigned long initial_quota,
|
||||
unsigned long max_quota, Launchpad *launchpad,
|
||||
Genode::Dataspace_capability config_ds)
|
||||
:
|
||||
_prg_name(prg_name),
|
||||
_block(Scout::Block::RIGHT), _loadbar(this, &Scout::label_font),
|
||||
_config(config_ds),
|
||||
_launcher(prg_name, launchpad, initial_quota * 1024UL, &_config)
|
||||
{
|
||||
_block.append_launchertext(prg_name, &Scout::link_style, &_launcher);
|
||||
_block.append_launchertext(_prg_name.string(), &Scout::link_style, &_launcher);
|
||||
|
||||
_loadbar.max_value(max_quota);
|
||||
_loadbar.value(initial_quota);
|
||||
|
@ -35,11 +35,12 @@ extern unsigned char TITLEBAR_RGBA[];
|
||||
********************************/
|
||||
|
||||
template <typename PT>
|
||||
Launchpad_window<PT>::Launchpad_window(Graphics_backend &gfx_backend,
|
||||
Launchpad_window<PT>::Launchpad_window(Genode::Env &env,
|
||||
Graphics_backend &gfx_backend,
|
||||
Point position, Area size, Area max_size,
|
||||
unsigned long initial_quota)
|
||||
:
|
||||
Launchpad(initial_quota),
|
||||
Launchpad(env, initial_quota),
|
||||
Window(gfx_backend, position, size, max_size, false),
|
||||
_docview(0),
|
||||
_spacer(1, _TH),
|
||||
|
@ -14,6 +14,9 @@
|
||||
#ifndef _LAUNCHPAD_WINDOW_H_
|
||||
#define _LAUNCHPAD_WINDOW_H_
|
||||
|
||||
#include <base/env.h>
|
||||
#include <dataspace/capability.h>
|
||||
|
||||
#include <scout/platform.h>
|
||||
#include <scout/window.h>
|
||||
|
||||
@ -73,7 +76,8 @@ class Launchpad_window : public Scout::Scrollbar_listener,
|
||||
*
|
||||
* \param initial_quota maximum value of quota displays
|
||||
*/
|
||||
Launchpad_window(Scout::Graphics_backend &gfx_backend,
|
||||
Launchpad_window(Genode::Env &env,
|
||||
Scout::Graphics_backend &gfx_backend,
|
||||
Scout::Point position, Scout::Area size,
|
||||
Scout::Area max_size, unsigned long inital_quota);
|
||||
|
||||
@ -123,39 +127,40 @@ class Launchpad_window : public Scout::Scrollbar_listener,
|
||||
_status_entry.refresh();
|
||||
}
|
||||
|
||||
void add_launcher(const char *filename,
|
||||
void add_launcher(Launchpad_child::Name const &name,
|
||||
unsigned long default_quota,
|
||||
Genode::Dataspace_capability config_ds = Genode::Dataspace_capability())
|
||||
Genode::Dataspace_capability config_ds = Genode::Dataspace_capability()) override
|
||||
{
|
||||
Launch_entry<PT> *le;
|
||||
le = new Launch_entry<PT>(filename, default_quota / 1024,
|
||||
le = new Launch_entry<PT>(name, default_quota / 1024,
|
||||
initial_quota() / 1024,
|
||||
this, config_ds);
|
||||
_launch_section.append(le);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void add_child(const char *unique_name,
|
||||
void add_child(Launchpad_child::Name const &name,
|
||||
unsigned long quota,
|
||||
Launchpad_child *launchpad_child,
|
||||
Genode::Allocator *alloc)
|
||||
Launchpad_child &launchpad_child,
|
||||
Genode::Allocator &alloc) override
|
||||
{
|
||||
Child_entry<PT> *ce;
|
||||
ce = new (alloc) Child_entry<PT>(unique_name, quota / 1024,
|
||||
ce = new (alloc) Child_entry<PT>(name, quota / 1024,
|
||||
initial_quota() / 1024,
|
||||
this, launchpad_child);
|
||||
*this, launchpad_child);
|
||||
_child_entry_list.insert(ce);
|
||||
_kiddy_section.append(ce);
|
||||
format(_size);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void remove_child(const char *name, Genode::Allocator *alloc)
|
||||
void remove_child(Launchpad_child::Name const &name,
|
||||
Genode::Allocator &alloc) override
|
||||
{
|
||||
/* lookup child entry by its name */
|
||||
Child_entry<PT> *ce = _child_entry_list.first();
|
||||
for ( ; ce; ce = ce->Genode::List<Child_entry<PT> >::Element::next())
|
||||
if (Genode::strcmp(ce->name(), name) == 0)
|
||||
if (name == ce->name())
|
||||
break;
|
||||
|
||||
if (!ce) {
|
||||
|
@ -53,7 +53,7 @@ class Loadbar_event_handler : public Scout::Event_handler
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Scout::Event &ev)
|
||||
void handle_event(Scout::Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
using Scout::Event;
|
||||
|
@ -11,6 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
|
||||
#include <scout/platform.h>
|
||||
#include <scout/tick.h>
|
||||
#include <scout/user_state.h>
|
||||
@ -85,15 +87,52 @@ static long read_int_attr_from_config(const char *attr, long default_value)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
struct Main : Scout::Event_handler
|
||||
{
|
||||
Scout::Platform &_pf;
|
||||
Scout::Window &_launchpad;
|
||||
Scout::User_state &_user_state;
|
||||
|
||||
unsigned long _old_time = _pf.timer_ticks();
|
||||
|
||||
Main(Scout::Platform &pf, Scout::Window &launchpad, Scout::User_state &user_state)
|
||||
: _pf(pf), _launchpad(launchpad), _user_state(user_state) { }
|
||||
|
||||
void handle_event(Scout::Event const &event) override
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
Event ev = event;
|
||||
|
||||
if (ev.type != Event::WHEEL)
|
||||
ev.mouse_position = ev.mouse_position - _user_state.view_position();
|
||||
|
||||
_user_state.handle_event(ev);
|
||||
|
||||
if (ev.type == Event::TIMER)
|
||||
Tick::handle(_pf.timer_ticks());
|
||||
|
||||
/* perform periodic redraw */
|
||||
unsigned long const curr_time = _pf.timer_ticks();
|
||||
if (!_pf.event_pending() && ((curr_time - _old_time > 20)
|
||||
|| (curr_time < _old_time))) {
|
||||
_old_time = curr_time;
|
||||
_launchpad.process_redraw();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Component **
|
||||
***************/
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
static Nitpicker::Connection nitpicker;
|
||||
static Platform pf(*nitpicker.input());
|
||||
static Nitpicker::Connection nitpicker(env);
|
||||
static Platform pf(env, *nitpicker.input());
|
||||
|
||||
long initial_x = read_int_attr_from_config("xpos", 550);
|
||||
long initial_y = read_int_attr_from_config("ypos", 150);
|
||||
@ -109,17 +148,13 @@ int main(int argc, char **argv)
|
||||
|
||||
/* create instance of launchpad window */
|
||||
static Launchpad_window<Pixel_rgb565>
|
||||
launchpad(
|
||||
graphics_backend, initial_position, initial_size, max_size,
|
||||
Genode::env()->ram_session()->avail()
|
||||
);
|
||||
launchpad(env, graphics_backend, initial_position, initial_size,
|
||||
max_size, env.ram().avail());
|
||||
|
||||
/* request config file from ROM service */
|
||||
try {
|
||||
launchpad.process_config();
|
||||
} catch (...) { }
|
||||
try { launchpad.process_config(); } catch (...) { }
|
||||
|
||||
Avail_quota_update avail_quota_update(&launchpad);
|
||||
static Avail_quota_update avail_quota_update(&launchpad);
|
||||
|
||||
/* create user state manager */
|
||||
static User_state user_state(&launchpad, &launchpad,
|
||||
@ -129,36 +164,6 @@ int main(int argc, char **argv)
|
||||
launchpad.format(initial_size);
|
||||
launchpad.ypos(0);
|
||||
|
||||
Genode::printf("--- entering main loop ---\n");
|
||||
|
||||
/* enter main loop */
|
||||
unsigned long curr_time, old_time;
|
||||
curr_time = old_time = pf.timer_ticks();
|
||||
for (;;) {
|
||||
Event ev = pf.get_event();
|
||||
|
||||
launchpad.gui_lock.lock();
|
||||
|
||||
if (ev.type != Event::WHEEL)
|
||||
ev.mouse_position = ev.mouse_position - user_state.view_position();
|
||||
|
||||
user_state.handle_event(ev);
|
||||
|
||||
if (ev.type == Event::TIMER)
|
||||
Tick::handle(pf.timer_ticks());
|
||||
|
||||
/* perform periodic redraw */
|
||||
curr_time = pf.timer_ticks();
|
||||
if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) {
|
||||
old_time = curr_time;
|
||||
launchpad.process_redraw();
|
||||
}
|
||||
|
||||
launchpad.gui_lock.unlock();
|
||||
|
||||
if (ev.type == Event::QUIT)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
static Main main(pf, launchpad, user_state);
|
||||
pf.event_handler(main);
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ class Iconbar_event_handler : public Scout::Event_handler
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &ev)
|
||||
void handle_event(Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
|
||||
|
@ -426,7 +426,7 @@ void Verbatim::format_fixed_width(int w)
|
||||
** Link_token **
|
||||
****************/
|
||||
|
||||
void Link_token::handle(Event &e)
|
||||
void Link_token::handle_event(Event const &e)
|
||||
{
|
||||
if (e.type != Event::PRESS) return;
|
||||
|
||||
@ -444,7 +444,7 @@ void Link_token::handle(Event &e)
|
||||
** Launcher_link_token **
|
||||
*************************/
|
||||
|
||||
void Launcher_link_token::handle(Event &e)
|
||||
void Launcher_link_token::handle_event(Event const &e)
|
||||
{
|
||||
if (e.type != Event::PRESS) return;
|
||||
|
||||
|
@ -200,7 +200,7 @@ class Scout::Link_token : public Token, public Link, public Event_handler,
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &e);
|
||||
void handle_event(Event const &) override;
|
||||
|
||||
/**
|
||||
* Tick interface
|
||||
@ -221,9 +221,13 @@ class Launchpad;
|
||||
|
||||
class Scout::Launcher : public Anchor
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Genode::String<64> Name;
|
||||
|
||||
private:
|
||||
|
||||
const char *_prg_name; /* null-terminated name of the program */
|
||||
Name _prg_name;
|
||||
int _active;
|
||||
int _exec_once;
|
||||
Launchpad *_launchpad;
|
||||
@ -232,22 +236,24 @@ class Scout::Launcher : public Anchor
|
||||
|
||||
public:
|
||||
|
||||
static void init(Genode::Env &);
|
||||
|
||||
/**
|
||||
* Constructors
|
||||
*/
|
||||
Launcher(const char *prg_name, int exec_once = 0,
|
||||
Launcher(Name const &prg_name, int exec_once = 0,
|
||||
unsigned long quota = 0, Launcher_config *config = 0) :
|
||||
_prg_name(prg_name), _active(1),
|
||||
_exec_once(exec_once), _quota(quota), _config(config) { }
|
||||
|
||||
Launcher(const char *prg_name, Launchpad *launchpad,
|
||||
Launcher(Name const &prg_name, Launchpad *launchpad,
|
||||
unsigned long quota, Launcher_config *config = 0) :
|
||||
_prg_name(prg_name), _launchpad(launchpad), _quota(quota),
|
||||
_config(config) { }
|
||||
|
||||
int active() { return _active; }
|
||||
|
||||
const char *prg_name() { return _prg_name; }
|
||||
Name prg_name() { return _prg_name; }
|
||||
|
||||
void quota(unsigned long quota) { _quota = quota; }
|
||||
|
||||
@ -280,7 +286,7 @@ class Scout::Launcher_link_token : public Link_token
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &e);
|
||||
void handle_event(Event const &) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,9 +18,6 @@
|
||||
#include <base/snprintf.h>
|
||||
#include "elements.h"
|
||||
|
||||
static Launchpad launchpad(Genode::env()->ram_session()->quota());
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Scout;
|
||||
|
||||
@ -94,10 +91,32 @@ Dataspace_capability Config_registry::config(char const *name)
|
||||
** Launcher interface **
|
||||
************************/
|
||||
|
||||
|
||||
static Launchpad *launchpad_ptr;
|
||||
|
||||
|
||||
static Launchpad &launchpad()
|
||||
{
|
||||
if (!launchpad_ptr) {
|
||||
class Missing_launchpad_init_call { };
|
||||
throw Missing_launchpad_init_call();
|
||||
}
|
||||
|
||||
return *launchpad_ptr;
|
||||
}
|
||||
|
||||
|
||||
void Launcher::init(Genode::Env &env)
|
||||
{
|
||||
static Launchpad launchpad(env, env.ram().avail());
|
||||
launchpad_ptr = &launchpad;
|
||||
}
|
||||
|
||||
|
||||
void Launcher::launch()
|
||||
{
|
||||
static Config_registry config_registry;
|
||||
|
||||
launchpad.start_child(prg_name(), quota(),
|
||||
config_registry.config(prg_name()));
|
||||
launchpad().start_child(prg_name(), quota(),
|
||||
config_registry.config(prg_name().string()));
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
|
||||
#include <scout/platform.h>
|
||||
#include <scout/tick.h>
|
||||
#include <scout/user_state.h>
|
||||
@ -45,20 +47,86 @@ extern unsigned char NAV_PREV_RGBA[];
|
||||
|
||||
static unsigned char *navicons_rgba[] = { NAV_NEXT_RGBA, NAV_PREV_RGBA };
|
||||
static Scout::Generic_icon **navicons[] = { &Scout::Navbar::next_icon,
|
||||
&Scout::Navbar::prev_icon };
|
||||
&Scout::Navbar::prev_icon };
|
||||
|
||||
extern int native_startup(int, char **);
|
||||
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
namespace Scout { struct Main; }
|
||||
|
||||
|
||||
struct Scout::Main : Scout::Event_handler
|
||||
{
|
||||
Scout::Platform &_pf;
|
||||
Scout::Window &_browser;
|
||||
Scout::User_state &_user_state;
|
||||
Scout::Element &_mcursor;
|
||||
|
||||
Scout::Point _mouse_position;
|
||||
|
||||
unsigned long _old_time = _pf.timer_ticks();
|
||||
|
||||
Main(Scout::Platform &pf, Scout::Window &browser,
|
||||
Scout::User_state &user_state, Scout::Element &mcursor)
|
||||
:
|
||||
_pf(pf), _browser(browser), _user_state(user_state), _mcursor(mcursor)
|
||||
{ }
|
||||
|
||||
void handle_event(Scout::Event const &event) override
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
Event ev = event;
|
||||
|
||||
if (event.type != Event::WHEEL) {
|
||||
|
||||
ev.mouse_position = ev.mouse_position - _user_state.view_position();
|
||||
|
||||
/* update mouse cursor */
|
||||
if (Config::mouse_cursor && (ev.mouse_position.x() != _mouse_position.x()
|
||||
|| ev.mouse_position.y() != _mouse_position.y())) {
|
||||
int x1 = min(ev.mouse_position.x(), _mouse_position.x());
|
||||
int y1 = min(ev.mouse_position.y(), _mouse_position.y());
|
||||
int x2 = max(ev.mouse_position.x() + _mcursor.size().w() - 1,
|
||||
_mouse_position.x() + _mcursor.size().w() - 1);
|
||||
int y2 = max(ev.mouse_position.y() + _mcursor.size().h() - 1,
|
||||
_mouse_position.y() + _mcursor.size().h() - 1);
|
||||
|
||||
_mcursor.geometry(Rect(ev.mouse_position, _mcursor.size()));
|
||||
_browser.redraw_area(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||
|
||||
_mouse_position = ev.mouse_position;
|
||||
}
|
||||
}
|
||||
|
||||
_user_state.handle_event(ev);
|
||||
|
||||
if (event.type == Event::TIMER)
|
||||
Tick::handle(_pf.timer_ticks());
|
||||
|
||||
/* perform periodic redraw */
|
||||
unsigned long curr_time = _pf.timer_ticks();
|
||||
if (!_pf.event_pending() && ((curr_time - _old_time > 20)
|
||||
|| (curr_time < _old_time))) {
|
||||
_old_time = curr_time;
|
||||
_browser.process_redraw();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Component **
|
||||
***************/
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
Launcher::init(env);
|
||||
|
||||
static Nitpicker::Connection nitpicker;
|
||||
static Platform pf(*nitpicker.input());
|
||||
static Platform pf(env, *nitpicker.input());
|
||||
|
||||
Area const max_size(530, 620);
|
||||
Point const initial_position(256, 80);
|
||||
@ -92,10 +160,9 @@ int main(int argc, char **argv)
|
||||
);
|
||||
|
||||
/* initialize mouse cursor */
|
||||
Point mouse_position;
|
||||
static Icon<Pixel_rgb565, 32, 32> mcursor;
|
||||
if (Config::mouse_cursor) {
|
||||
mcursor.geometry(Rect(mouse_position, Area(32, 32)));
|
||||
mcursor.geometry(Rect(Point(0, 0), Area(32, 32)));
|
||||
mcursor.rgba(POINTER_RGBA);
|
||||
mcursor.alpha(255);
|
||||
mcursor.findable(0);
|
||||
@ -107,47 +174,7 @@ int main(int argc, char **argv)
|
||||
initial_position.x(), initial_position.y());
|
||||
browser.ypos(0);
|
||||
|
||||
/* enter main loop */
|
||||
unsigned long curr_time, old_time;
|
||||
curr_time = old_time = pf.timer_ticks();
|
||||
for (;;) {
|
||||
Event ev = pf.get_event();
|
||||
static Main main(pf, browser, user_state, mcursor);
|
||||
pf.event_handler(main);
|
||||
|
||||
if (ev.type != Event::WHEEL) {
|
||||
ev.mouse_position = ev.mouse_position - user_state.view_position();
|
||||
|
||||
/* update mouse cursor */
|
||||
if (Config::mouse_cursor && (ev.mouse_position.x() != mouse_position.x()
|
||||
|| ev.mouse_position.y() != mouse_position.y())) {
|
||||
int x1 = min(ev.mouse_position.x(), mouse_position.x());
|
||||
int y1 = min(ev.mouse_position.y(), mouse_position.y());
|
||||
int x2 = max(ev.mouse_position.x() + mcursor.size().w() - 1,
|
||||
mouse_position.x() + mcursor.size().w() - 1);
|
||||
int y2 = max(ev.mouse_position.y() + mcursor.size().h() - 1,
|
||||
mouse_position.y() + mcursor.size().h() - 1);
|
||||
|
||||
mcursor.geometry(Rect(ev.mouse_position, mcursor.size()));
|
||||
browser.redraw_area(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||
|
||||
mouse_position = ev.mouse_position;
|
||||
}
|
||||
}
|
||||
|
||||
user_state.handle_event(ev);
|
||||
|
||||
if (ev.type == Event::TIMER)
|
||||
Tick::handle(pf.timer_ticks());
|
||||
|
||||
/* perform periodic redraw */
|
||||
curr_time = pf.timer_ticks();
|
||||
if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) {
|
||||
old_time = curr_time;
|
||||
browser.process_redraw();
|
||||
}
|
||||
|
||||
if (ev.type == Event::QUIT)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class Linkicon_event_handler : public Event_handler
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &ev)
|
||||
void handle_event(Event const &ev) override
|
||||
{
|
||||
if (ev.type != Event::PRESS || !_navbar) return;
|
||||
|
||||
|
@ -69,7 +69,7 @@ class Arrow_event_handler : public Event_handler, public Tick
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &ev)
|
||||
void handle_event(Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
|
||||
@ -166,7 +166,7 @@ class Slider_event_handler : public Event_handler
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &ev)
|
||||
void handle_event(Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
static int curr_my, orig_my;
|
||||
|
@ -14,16 +14,10 @@
|
||||
*/
|
||||
|
||||
#include <base/env.h>
|
||||
#include <base/child.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/service.h>
|
||||
#include <base/snprintf.h>
|
||||
#include <base/blocking.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <ram_session/connection.h>
|
||||
#include <cpu_session/connection.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <os/config.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <launchpad/launchpad.h>
|
||||
|
||||
using namespace Genode;
|
||||
@ -33,10 +27,11 @@ using namespace Genode;
|
||||
** Launchpad **
|
||||
***************/
|
||||
|
||||
Launchpad::Launchpad(unsigned long initial_quota)
|
||||
Launchpad::Launchpad(Env &env, unsigned long initial_quota)
|
||||
:
|
||||
_env(env),
|
||||
_initial_quota(initial_quota),
|
||||
_sliced_heap(env()->ram_session(), env()->rm_session())
|
||||
_sliced_heap(_env.ram(), _env.rm())
|
||||
{
|
||||
/* names of services provided by the parent */
|
||||
static const char *names[] = {
|
||||
@ -45,25 +40,24 @@ Launchpad::Launchpad(unsigned long initial_quota)
|
||||
"RAM", "RM", "PD", "CPU", "IO_MEM", "IO_PORT", "IRQ", "ROM", "LOG",
|
||||
|
||||
/* services expected to got started by init */
|
||||
"Nitpicker", "Init", "Timer", "PCI", "Block", "Nic", "Rtc",
|
||||
"Nitpicker", "Init", "Timer", "Block", "Nic", "Rtc",
|
||||
|
||||
0 /* null-termination */
|
||||
};
|
||||
for (unsigned i = 0; names[i]; i++)
|
||||
_parent_services.insert(new (env()->heap())
|
||||
Parent_service(names[i]));
|
||||
new (_heap) Launchpad_child::Parent_service(_parent_services, names[i]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a program with the specified name already exists
|
||||
*/
|
||||
bool Launchpad::_child_name_exists(const char *name)
|
||||
bool Launchpad::_child_name_exists(Launchpad_child::Name const &name)
|
||||
{
|
||||
Launchpad_child *c = _children.first();
|
||||
|
||||
for ( ; c; c = c->List<Launchpad_child>::Element::next())
|
||||
if (strcmp(c->name(), name) == 0)
|
||||
if (c->name() == name)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -73,30 +67,23 @@ bool Launchpad::_child_name_exists(const char *name)
|
||||
/**
|
||||
* Create a unique name based on the filename
|
||||
*
|
||||
* If a program with the filename as name already exists, we
|
||||
* add a counting number as suffix.
|
||||
* If a program with the filename as name already exists, we add a counting
|
||||
* number as suffix.
|
||||
*/
|
||||
void Launchpad::_get_unique_child_name(const char *filename, char *dst, int dst_len)
|
||||
Launchpad_child::Name
|
||||
Launchpad::_get_unique_child_name(Launchpad_child::Name const &binary_name)
|
||||
{
|
||||
Lock::Guard lock_guard(_children_lock);
|
||||
|
||||
char buf[64];
|
||||
char suffix[8];
|
||||
suffix[0] = 0;
|
||||
if (!_child_name_exists(binary_name))
|
||||
return binary_name;
|
||||
|
||||
for (int cnt = 1; true; cnt++) {
|
||||
|
||||
/* build program name composed of filename and numeric suffix */
|
||||
snprintf(buf, sizeof(buf), "%s%s", filename, suffix);
|
||||
for (unsigned cnt = 1; ; cnt++) {
|
||||
|
||||
/* if such a program name does not exist yet, we are happy */
|
||||
if (!_child_name_exists(buf)) {
|
||||
strncpy(dst, buf, dst_len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* increase number of suffix */
|
||||
snprintf(suffix, sizeof(suffix), ".%d", cnt + 1);
|
||||
Launchpad_child::Name const unique(binary_name, ".", cnt);
|
||||
if (!_child_name_exists(unique))
|
||||
return unique;
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,370 +101,98 @@ void Launchpad::process_config()
|
||||
* Iterate through all entries of the config file and create
|
||||
* launchpad entries as specified.
|
||||
*/
|
||||
int launcher_cnt = 0;
|
||||
for (unsigned i = 0; i < config_node.num_sub_nodes(); i++) {
|
||||
Xml_node node = config_node.sub_node(i);
|
||||
if (node.has_type("launcher"))
|
||||
config_node.for_each_sub_node("launcher", [&] (Xml_node node) {
|
||||
|
||||
/* catch XML syntax errors within launcher node */
|
||||
try {
|
||||
/* read file name and default quote from launcher node */
|
||||
Xml_node::Attribute filename_attr = node.attribute("name");
|
||||
typedef Launchpad_child::Name Name;
|
||||
Name *name = new (_heap) Name(node.attribute_value("name", Name()));
|
||||
|
||||
enum { MAX_NAME_LEN = 128 };
|
||||
char *filename = (char *)env()->heap()->alloc(MAX_NAME_LEN);
|
||||
if (!filename) {
|
||||
Genode::error("out of memory while processing configuration");
|
||||
return;
|
||||
}
|
||||
filename_attr.value(filename, MAX_NAME_LEN);
|
||||
Xml_node::Attribute ram_quota_attr = node.attribute("ram_quota");
|
||||
Number_of_bytes default_ram_quota = 0;
|
||||
ram_quota_attr.value(&default_ram_quota);
|
||||
Number_of_bytes default_ram_quota =
|
||||
node.attribute_value("ram_quota", Number_of_bytes(0));
|
||||
|
||||
/*
|
||||
* Obtain configuration for the child
|
||||
*/
|
||||
Dataspace_capability config_ds;
|
||||
/*
|
||||
* Obtain configuration for the child
|
||||
*/
|
||||
Dataspace_capability config_ds;
|
||||
|
||||
if (node.has_sub_node("configfile")
|
||||
&& node.sub_node("configfile").has_attribute("name")) {
|
||||
typedef String<128> Rom_name;
|
||||
|
||||
char name[128];
|
||||
node.sub_node("configfile").attribute("name").value(name, sizeof(name));
|
||||
if (node.has_sub_node("configfile")) {
|
||||
|
||||
Rom_connection config_rom(name);
|
||||
config_rom.on_destruction(Rom_connection::KEEP_OPEN);
|
||||
Rom_name const name =
|
||||
node.sub_node("configfile").attribute_value("name", Rom_name());
|
||||
|
||||
config_ds = config_rom.dataspace();
|
||||
}
|
||||
Rom_connection &config_rom = *new (_heap) Rom_connection(name.string());
|
||||
|
||||
if (node.has_sub_node("config")) {
|
||||
|
||||
Xml_node config_node = node.sub_node("config");
|
||||
|
||||
/* allocate dataspace for config */
|
||||
size_t const config_size = config_node.size();
|
||||
config_ds = env()->ram_session()->alloc(config_size);
|
||||
|
||||
/* copy configuration into new dataspace */
|
||||
char * const ptr = env()->rm_session()->attach(config_ds);
|
||||
Genode::memcpy(ptr, config_node.addr(), config_size);
|
||||
env()->rm_session()->detach(ptr);
|
||||
}
|
||||
|
||||
/* add launchpad entry */
|
||||
add_launcher(filename, default_ram_quota, config_ds);
|
||||
launcher_cnt++;
|
||||
|
||||
} catch (...) {
|
||||
Genode::warning("launcher entry ", launcher_cnt + 1, " is malformed");
|
||||
}
|
||||
else {
|
||||
char buf[32];
|
||||
node.type_name(buf, sizeof(buf));
|
||||
Genode::warning("ignoring unsupported tag <", Genode::Cstring(buf), ">");
|
||||
config_ds = config_rom.dataspace();
|
||||
}
|
||||
}
|
||||
|
||||
if (node.has_sub_node("config")) {
|
||||
|
||||
Xml_node config_node = node.sub_node("config");
|
||||
|
||||
/* allocate dataspace for config */
|
||||
size_t const size = config_node.size();
|
||||
config_ds = env()->ram_session()->alloc(size);
|
||||
|
||||
/* copy configuration into new dataspace */
|
||||
Attached_dataspace attached(config_ds);
|
||||
memcpy(attached.local_addr<char>(), config_node.addr(), size);
|
||||
}
|
||||
|
||||
/* add launchpad entry */
|
||||
add_launcher(*name, default_ram_quota, config_ds);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Launchpad_child *Launchpad::start_child(const char *filename,
|
||||
Launchpad_child *Launchpad::start_child(Launchpad_child::Name const &binary_name,
|
||||
unsigned long ram_quota,
|
||||
Genode::Dataspace_capability config_ds)
|
||||
Dataspace_capability config_ds)
|
||||
{
|
||||
Genode::log("starting ", filename, " with quota ", ram_quota);
|
||||
log("starting ", binary_name, " with quota ", ram_quota);
|
||||
|
||||
/* find unique name for new child */
|
||||
char unique_name[64];
|
||||
_get_unique_child_name(filename, unique_name, sizeof(unique_name));
|
||||
Genode::log("using unique child name \"", Cstring(unique_name), "\"");
|
||||
Launchpad_child::Name const unique_name = _get_unique_child_name(binary_name);
|
||||
log("using unique child name \"", unique_name, "\"");
|
||||
|
||||
if (ram_quota > env()->ram_session()->avail()) {
|
||||
Genode::error("child's ram quota is higher than our available quota, using available quota");
|
||||
error("child's ram quota is higher than our available quota, using available quota");
|
||||
ram_quota = env()->ram_session()->avail() - 256*1000;
|
||||
}
|
||||
|
||||
size_t metadata_size = 4096*16 + sizeof(Launchpad_child);
|
||||
|
||||
if (metadata_size > ram_quota) {
|
||||
Genode::error("too low ram_quota to hold child metadata");
|
||||
error("too low ram_quota to hold child metadata");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ram_quota -= metadata_size;
|
||||
|
||||
/* lookup executable elf binary */
|
||||
Dataspace_capability file_cap;
|
||||
Rom_session_capability rom_cap;
|
||||
try {
|
||||
/*
|
||||
* When creating a ROM connection for a non-existing file, the
|
||||
* constructor of 'Rom_connection' throws a 'Parent::Service_denied'
|
||||
* exception.
|
||||
*/
|
||||
Rom_connection rom(prefixed_label(Session_label(Cstring(unique_name)),
|
||||
Session_label(filename)).string());
|
||||
rom.on_destruction(Rom_connection::KEEP_OPEN);
|
||||
rom_cap = rom.cap();
|
||||
file_cap = rom.dataspace();
|
||||
} catch (...) {
|
||||
Genode::error("could not access ROM module \"", filename, "\"");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create ram session for child with some of our own quota */
|
||||
Ram_connection ram;
|
||||
ram.on_destruction(Ram_connection::KEEP_OPEN);
|
||||
ram.ref_account(env()->ram_session_cap());
|
||||
env()->ram_session()->transfer_quota(ram.cap(), ram_quota);
|
||||
|
||||
/* create cpu session for child */
|
||||
Cpu_connection cpu(unique_name);
|
||||
cpu.on_destruction(Cpu_connection::KEEP_OPEN);
|
||||
|
||||
if (!ram.cap().valid() || !cpu.cap().valid()) {
|
||||
if (ram.cap().valid()) {
|
||||
Genode::warning("failed to create CPU session");
|
||||
env()->parent()->close(ram.cap());
|
||||
}
|
||||
if (cpu.cap().valid()) {
|
||||
Genode::warning("failed to create RAM session");
|
||||
env()->parent()->close(cpu.cap());
|
||||
}
|
||||
env()->parent()->close(rom_cap);
|
||||
Genode::log("our quota is ", env()->ram_session()->quota());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Pd_connection pd;
|
||||
pd.on_destruction(Pd_connection::KEEP_OPEN);
|
||||
if (!pd.cap().valid()) {
|
||||
Genode::warning("failed to create PD session");
|
||||
env()->parent()->close(ram.cap());
|
||||
env()->parent()->close(cpu.cap());
|
||||
env()->parent()->close(rom_cap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
Launchpad_child *c = new (&_sliced_heap)
|
||||
Launchpad_child(unique_name, file_cap, pd.cap(), ram.cap(),
|
||||
cpu.cap(), rom_cap,
|
||||
&_cap_session, &_parent_services, &_child_services,
|
||||
config_ds, this);
|
||||
Launchpad_child(_env, unique_name, binary_name, ram_quota,
|
||||
_parent_services, _child_services, config_ds);
|
||||
|
||||
Lock::Guard lock_guard(_children_lock);
|
||||
_children.insert(c);
|
||||
|
||||
add_child(unique_name, ram_quota, c, c->heap());
|
||||
|
||||
add_child(unique_name, ram_quota, *c, c->heap());
|
||||
return c;
|
||||
} catch (Cpu_session::Thread_creation_failed) {
|
||||
Genode::warning("failed to create child - Cpu_session::Thread_creation_failed");
|
||||
} catch (...) {
|
||||
Genode::warning("failed to create child - unknown reason");
|
||||
}
|
||||
|
||||
env()->parent()->close(ram.cap());
|
||||
env()->parent()->close(cpu.cap());
|
||||
env()->parent()->close(rom_cap);
|
||||
} catch (...) {
|
||||
warning("failed to create child - unknown reason"); }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Watchdog-guarded child destruction mechanism
|
||||
*
|
||||
* During the destruction of a child, all sessions of the child are getting
|
||||
* closed. A server, however, may refuse to answer a close call. We detect
|
||||
* this case using a watchdog mechanism, unblock the 'close' call, and
|
||||
* proceed with the closing the other remaining sessions.
|
||||
*/
|
||||
class Child_destructor_thread : Thread_deprecated<2*4096>
|
||||
void Launchpad::exit_child(Launchpad_child &child)
|
||||
{
|
||||
private:
|
||||
|
||||
Launchpad_child *_curr_child; /* currently destructed child */
|
||||
Allocator *_curr_alloc; /* child object'sallocator */
|
||||
Lock _submit_lock; /* only one submission at a time */
|
||||
Lock _activate_lock; /* submission protocol */
|
||||
bool _ready; /* set if submission is completed */
|
||||
int _watchdog_cnt; /* watchdog counter in milliseconds */
|
||||
|
||||
/**
|
||||
* Thread entry function
|
||||
*/
|
||||
void entry() {
|
||||
while (true) {
|
||||
|
||||
/* wait for next submission */
|
||||
_activate_lock.lock();
|
||||
|
||||
/*
|
||||
* Eventually long-taking operation that involves the
|
||||
* closing of all session of the child. This procedure
|
||||
* may need blocking cancellation to proceed in the
|
||||
* case servers are unresponsive.
|
||||
*/
|
||||
try {
|
||||
destroy(_curr_alloc, _curr_child);
|
||||
} catch (Blocking_canceled) {
|
||||
Genode::error("suspicious cancellation");
|
||||
}
|
||||
|
||||
_ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Watchdog timer granularity in milliseconds. This value defined
|
||||
* after how many milliseconds the watchdog is activated.
|
||||
*/
|
||||
enum { WATCHDOG_GRANULARITY_MS = 10 };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Child_destructor_thread() :
|
||||
Thread_deprecated("child_destructor"),
|
||||
_curr_child(0), _curr_alloc(0),
|
||||
_activate_lock(Lock::LOCKED),
|
||||
_ready(true)
|
||||
{
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destruct child, coping with unresponsive servers
|
||||
*
|
||||
* \param alloc Child object's allocator
|
||||
* \param child Child to destruct
|
||||
* \param timeout_ms Maximum destruction time until the destructing
|
||||
* thread gets waken up to give up the close call to
|
||||
* an unreponsive server.
|
||||
*/
|
||||
void submit_for_destruction(Allocator *alloc, Launchpad_child *child,
|
||||
Timer::Session *timer, int timeout_ms)
|
||||
{
|
||||
/* block until destructor thread is ready for new submission */
|
||||
Lock::Guard _lock_guard(_submit_lock);
|
||||
|
||||
/* register submission values */
|
||||
_curr_child = child;
|
||||
_curr_alloc = alloc;
|
||||
_ready = false;
|
||||
_watchdog_cnt = 0;
|
||||
|
||||
/* wake up the destruction thread */
|
||||
_activate_lock.unlock();
|
||||
|
||||
/*
|
||||
* Now, the destruction thread attempts to close all the
|
||||
* child's sessions. Check '_ready' flag periodically.
|
||||
*/
|
||||
while (!_ready) {
|
||||
|
||||
/* give the destruction thread some time to proceed */
|
||||
timer->msleep(WATCHDOG_GRANULARITY_MS);
|
||||
_watchdog_cnt += WATCHDOG_GRANULARITY_MS;
|
||||
|
||||
/* check if we reached the timeout */
|
||||
if (_watchdog_cnt > timeout_ms) {
|
||||
|
||||
/*
|
||||
* The destruction seems to got stuck, let's shake it a
|
||||
* bit to proceed and reset the watchdog counter to give
|
||||
* the next blocking operation a chance to execute.
|
||||
*/
|
||||
child->cancel_blocking();
|
||||
_watchdog_cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Construct a timer session for the watchdog timer on demand
|
||||
*/
|
||||
static Timer::Session *timer_session()
|
||||
{
|
||||
static Timer::Connection timer;
|
||||
return &timer;
|
||||
}
|
||||
|
||||
|
||||
Dataspace_capability Launchpad_child::_ldso_ds()
|
||||
{
|
||||
static bool first_attempt_failed = false;
|
||||
|
||||
if (!first_attempt_failed) {
|
||||
try {
|
||||
static Rom_connection rom("ld.lib.so");
|
||||
static Dataspace_capability ds = rom.dataspace();
|
||||
return ds;
|
||||
} catch (...) { }
|
||||
}
|
||||
|
||||
first_attempt_failed = true;
|
||||
return Dataspace_capability();
|
||||
}
|
||||
|
||||
|
||||
/* construct child-destructor thread early - in case we run out of threads */
|
||||
static Child_destructor_thread child_destructor;
|
||||
|
||||
/**
|
||||
* Destruct Launchpad_child, cope with infinitely blocking server->close calls
|
||||
*
|
||||
* The arguments correspond to the 'Child_destructor_thread::submit_for_destruction'
|
||||
* function.
|
||||
*/
|
||||
static void destruct_child(Allocator *alloc, Launchpad_child *child,
|
||||
Timer::Session *timer, int timeout)
|
||||
{
|
||||
/* if no timer session was provided by our caller, we have create one */
|
||||
if (!timer)
|
||||
timer = timer_session();
|
||||
|
||||
child_destructor.submit_for_destruction(alloc, child, timer, timeout);
|
||||
}
|
||||
|
||||
|
||||
void Launchpad::exit_child(Launchpad_child *child,
|
||||
Timer::Session *timer,
|
||||
int session_close_timeout_ms)
|
||||
{
|
||||
remove_child(child->name(), child->heap());
|
||||
remove_child(child.name(), child.heap());
|
||||
|
||||
Lock::Guard lock_guard(_children_lock);
|
||||
_children.remove(child);
|
||||
_children.remove(&child);
|
||||
|
||||
Ram_session_capability ram_session_cap = child->ram_session_cap();
|
||||
Cpu_session_capability cpu_session_cap = child->cpu_session_cap();
|
||||
Rom_session_capability rom_session_cap = child->rom_session_cap();
|
||||
|
||||
const Genode::Server *server = child->server();
|
||||
destruct_child(&_sliced_heap, child, timer, session_close_timeout_ms);
|
||||
|
||||
env()->parent()->close(cpu_session_cap);
|
||||
env()->parent()->close(rom_session_cap);
|
||||
env()->parent()->close(ram_session_cap);
|
||||
|
||||
/*
|
||||
* The killed child may have provided services to other children.
|
||||
* Since the server is dead by now, we cannot close its sessions
|
||||
* in the cooperative way. Instead, we need to instruct each
|
||||
* other child to forget about session associated with the dead
|
||||
* server. Note that the 'child' pointer points a a no-more
|
||||
* existing object. It is only used to identify the corresponding
|
||||
* session. It must never by de-referenced!
|
||||
*/
|
||||
Launchpad_child *c = _children.first();
|
||||
for ( ; c; c = c->Genode::List<Launchpad_child>::Element::next())
|
||||
c->revoke_server(server);
|
||||
destroy(_sliced_heap, &child);
|
||||
}
|
||||
|
@ -11,10 +11,9 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/signal.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <os/config.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <scout/user_state.h>
|
||||
#include <scout/nitpicker_graphics_backend.h>
|
||||
|
||||
@ -101,12 +100,10 @@ static bool config_decoration = true;
|
||||
/**
|
||||
* Parse configuration
|
||||
*/
|
||||
static void read_config()
|
||||
static void read_config(Genode::Xml_node config_node)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Xml_node config_node = config()->xml_node();
|
||||
|
||||
try {
|
||||
char buf[16];
|
||||
config_node.attribute("animate").value(buf, sizeof(buf));
|
||||
@ -169,42 +166,71 @@ static void read_config()
|
||||
|
||||
struct Input_handler
|
||||
{
|
||||
GENODE_RPC(Rpc_handle_input, void, handle, Scout::Event&);
|
||||
GENODE_RPC(Rpc_handle_input, void, handle_input, Scout::Event const &);
|
||||
GENODE_RPC_INTERFACE(Rpc_handle_input);
|
||||
};
|
||||
|
||||
|
||||
class Input_handler_component : public Genode::Rpc_object<Input_handler,
|
||||
Input_handler_component>
|
||||
class Main : public Scout::Event_handler
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
Scout::Platform &_pf;
|
||||
Scout::User_state &_user_state;
|
||||
Framebuffer_window<Genode::Pixel_rgb565> &_fb_win;
|
||||
Genode::Signal_receiver &_sig_rec;
|
||||
Genode::Attached_rom_dataspace &_config;
|
||||
unsigned long _curr_time, _old_time;
|
||||
|
||||
void _handle_config()
|
||||
{
|
||||
_config.update();
|
||||
|
||||
/* keep the current values by default */
|
||||
config_fb_x = _fb_win.view_x();
|
||||
config_fb_y = _fb_win.view_y();
|
||||
config_fb_width = _fb_win.view_w();
|
||||
config_fb_height = _fb_win.view_h();
|
||||
|
||||
try { read_config(_config.xml()); } catch (...) { }
|
||||
|
||||
_fb_win.name(config_title);
|
||||
_fb_win.config_alpha(config_alpha);
|
||||
_fb_win.config_resize_handle(config_resize_handle);
|
||||
_fb_win.config_decoration(config_decoration);
|
||||
|
||||
/* must get called after 'config_decoration()' */
|
||||
_fb_win.content_geometry(config_fb_x, config_fb_y,
|
||||
config_fb_width, config_fb_height);
|
||||
_user_state.update_view_offset();
|
||||
}
|
||||
|
||||
Genode::Signal_handler<Main> _config_handler;
|
||||
|
||||
public:
|
||||
|
||||
Input_handler_component(Scout::Platform &pf,
|
||||
Scout::User_state &user_state,
|
||||
Framebuffer_window<Genode::Pixel_rgb565> &fb_win,
|
||||
Genode::Signal_receiver &sig_rec)
|
||||
Main(Scout::Platform &pf,
|
||||
Scout::User_state &user_state,
|
||||
Framebuffer_window<Genode::Pixel_rgb565> &fb_win,
|
||||
Genode::Entrypoint &ep,
|
||||
Genode::Attached_rom_dataspace &config)
|
||||
:
|
||||
_pf(pf),
|
||||
_user_state(user_state),
|
||||
_fb_win(fb_win),
|
||||
_sig_rec(sig_rec)
|
||||
_config(config),
|
||||
_config_handler(ep, *this, &Main::_handle_config)
|
||||
{
|
||||
_curr_time = _old_time = _pf.timer_ticks();
|
||||
|
||||
config.sigh(_config_handler);
|
||||
}
|
||||
|
||||
void handle(Scout::Event &ev)
|
||||
void handle_event(Scout::Event const &event) override
|
||||
{
|
||||
using Scout::Event;
|
||||
|
||||
Event ev = event;
|
||||
|
||||
if (ev.type != Event::WHEEL)
|
||||
ev.mouse_position = ev.mouse_position - _user_state.view_position();
|
||||
|
||||
@ -217,30 +243,11 @@ class Input_handler_component : public Genode::Rpc_object<Input_handler,
|
||||
|
||||
if (ev.type == Event::TIMER) {
|
||||
Scout::Tick::handle(_pf.timer_ticks());
|
||||
/* check for configuration changes */
|
||||
if (_sig_rec.pending()) {
|
||||
_sig_rec.wait_for_signal();
|
||||
Genode::config()->reload();
|
||||
/* keep the current values by default */
|
||||
config_fb_x = _fb_win.view_x();
|
||||
config_fb_y = _fb_win.view_y();
|
||||
config_fb_width = _fb_win.view_w();
|
||||
config_fb_height = _fb_win.view_h();
|
||||
try { read_config(); } catch (...) { }
|
||||
_fb_win.name(config_title);
|
||||
_fb_win.config_alpha(config_alpha);
|
||||
_fb_win.config_resize_handle(config_resize_handle);
|
||||
_fb_win.config_decoration(config_decoration);
|
||||
/* must get called after 'config_decoration()' */
|
||||
_fb_win.content_geometry(config_fb_x, config_fb_y,
|
||||
config_fb_width, config_fb_height);
|
||||
_user_state.update_view_offset();
|
||||
}
|
||||
}
|
||||
|
||||
/* perform periodic redraw */
|
||||
_curr_time = _pf.timer_ticks();
|
||||
if (!_pf.event_pending() && ((_curr_time - _old_time > 20) || (_curr_time < _old_time))) {
|
||||
if ((_curr_time - _old_time > 20) || (_curr_time < _old_time)) {
|
||||
_old_time = _curr_time;
|
||||
_fb_win.process_redraw();
|
||||
}
|
||||
@ -248,29 +255,24 @@ class Input_handler_component : public Genode::Rpc_object<Input_handler,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
/***************
|
||||
** Component **
|
||||
***************/
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
try { read_config(); } catch (...) { }
|
||||
static Genode::Attached_rom_dataspace config(env, "config");
|
||||
|
||||
/*
|
||||
* Register signal handler for config changes
|
||||
*/
|
||||
static Genode::Signal_receiver sig_rec;
|
||||
static Genode::Signal_context sig_ctx;
|
||||
|
||||
try { Genode::config()->sigh(sig_rec.manage(&sig_ctx)); } catch (...) { }
|
||||
try { read_config(config.xml()); } catch (...) { }
|
||||
|
||||
/* heuristic for allocating the double-buffer backing store */
|
||||
enum { WINBORDER_WIDTH = 10, WINBORDER_HEIGHT = 40 };
|
||||
|
||||
/* init platform */
|
||||
static Nitpicker::Connection nitpicker;
|
||||
static Platform pf(*nitpicker.input());
|
||||
static Nitpicker::Connection nitpicker(env);
|
||||
static Platform pf(env, *nitpicker.input());
|
||||
|
||||
Area const max_size(config_fb_width + WINBORDER_WIDTH,
|
||||
config_fb_height + WINBORDER_HEIGHT);
|
||||
@ -301,27 +303,9 @@ int main(int argc, char **argv)
|
||||
fb_win.content_geometry(config_fb_x, config_fb_y,
|
||||
config_fb_width, config_fb_height);
|
||||
|
||||
/* initialize server entry point */
|
||||
enum { STACK_SIZE = 2*1024*sizeof(Genode::addr_t) };
|
||||
static Genode::Cap_connection cap;
|
||||
static Genode::Rpc_entrypoint ep(&cap, STACK_SIZE, "liquid_fb_ep");
|
||||
|
||||
/* initialize public services */
|
||||
init_services(ep);
|
||||
init_services(env.ep().rpc_ep());
|
||||
|
||||
/* create local input handler service */
|
||||
static Input_handler_component input_handler(pf, user_state, fb_win,
|
||||
sig_rec);
|
||||
Genode::Capability<Input_handler> input_handler_cap = ep.manage(&input_handler);
|
||||
|
||||
/* enter main loop */
|
||||
for (;;) {
|
||||
Event ev = pf.get_event();
|
||||
input_handler_cap.call<Input_handler::Rpc_handle_input>(ev);
|
||||
|
||||
if (ev.type == Event::QUIT)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
static Main main(pf, user_state, fb_win, env.ep(), config);
|
||||
pf.event_handler(main);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class Window_content : public Scout::Element
|
||||
:
|
||||
_input_session(input_session),_element(element) { }
|
||||
|
||||
void handle(Scout::Event &ev)
|
||||
void handle_event(Scout::Event const &ev) override
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
|
@ -401,7 +401,7 @@ int main(int argc, char **argv)
|
||||
Framebuffer::Mode::RGB565), false);
|
||||
|
||||
/* initialize entry point that serves the root interface */
|
||||
enum { STACK_SIZE = 4096 };
|
||||
enum { STACK_SIZE = 4096*sizeof(long) };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "nitlog_ep");
|
||||
|
||||
|
@ -17,85 +17,53 @@
|
||||
/* Genode includes */
|
||||
#include <base/lock.h>
|
||||
#include <os/slave.h>
|
||||
#include <report_session/report_session.h>
|
||||
#include <rom_session/capability.h>
|
||||
#include <root/client.h>
|
||||
#include <report_session/connection.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
|
||||
class Report_rom_slave : public Genode::Noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
class Policy : public Genode::Slave_policy
|
||||
class Policy : public Genode::Slave::Policy
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Root_capability _report_root_cap;
|
||||
Genode::Root_capability _rom_root_cap;
|
||||
bool _announced;
|
||||
Genode::Lock mutable _lock; /* used to wait for announcement */
|
||||
|
||||
protected:
|
||||
|
||||
char const **_permitted_services() const
|
||||
{
|
||||
static char const *permitted_services[] = {
|
||||
"LOG", "RM", 0 };
|
||||
"CPU", "PD", "RAM", "LOG", 0 };
|
||||
|
||||
return permitted_services;
|
||||
};
|
||||
|
||||
static Name _name() { return "report_rom"; }
|
||||
static Genode::size_t _quota() { return 1024*1024; }
|
||||
|
||||
public:
|
||||
|
||||
Policy(Genode::Rpc_entrypoint &entrypoint,
|
||||
Genode::Ram_session &ram,
|
||||
const char *config)
|
||||
Policy(Genode::Rpc_entrypoint &ep,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Ram_session_capability ram,
|
||||
const char *config)
|
||||
:
|
||||
Slave_policy("report_rom", entrypoint, &ram),
|
||||
_lock(Genode::Lock::LOCKED)
|
||||
Genode::Slave::Policy(_name(), _name(), ep, rm, ram, _quota())
|
||||
{
|
||||
if (config)
|
||||
configure(config);
|
||||
}
|
||||
|
||||
bool announce_service(const char *service_name,
|
||||
Genode::Root_capability root,
|
||||
Genode::Allocator *,
|
||||
Genode::Server *)
|
||||
{
|
||||
if (Genode::strcmp(service_name, "ROM") == 0)
|
||||
_rom_root_cap = root;
|
||||
else if (Genode::strcmp(service_name, "Report") == 0)
|
||||
_report_root_cap = root;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (_rom_root_cap.valid() && _report_root_cap.valid())
|
||||
_lock.unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Genode::Root_capability report_root() const
|
||||
{
|
||||
Genode::Lock::Guard guard(_lock);
|
||||
return _report_root_cap;
|
||||
}
|
||||
|
||||
Genode::Root_capability rom_root() const
|
||||
{
|
||||
Genode::Lock::Guard guard(_lock);
|
||||
return _rom_root_cap;
|
||||
}
|
||||
};
|
||||
|
||||
Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t);
|
||||
Genode::Rpc_entrypoint _ep;
|
||||
Policy _policy;
|
||||
Genode::size_t const _quota = 1024*1024;
|
||||
Genode::Slave _slave;
|
||||
Genode::Root_client _rom_root;
|
||||
Genode::Root_client _report_root;
|
||||
Genode::Child _child;
|
||||
|
||||
public:
|
||||
|
||||
@ -106,64 +74,17 @@ class Report_rom_slave : public Genode::Noncopyable
|
||||
* \param ram RAM session used to allocate the configuration
|
||||
* dataspace
|
||||
*/
|
||||
Report_rom_slave(Genode::Cap_session &cap, Genode::Ram_session &ram,
|
||||
char const *config)
|
||||
Report_rom_slave(Genode::Pd_session &pd,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Ram_session_capability ram,
|
||||
char const *config)
|
||||
:
|
||||
_ep(&cap, _ep_stack_size, "report_rom"),
|
||||
_policy(_ep, ram, config),
|
||||
_slave(_ep, _policy, _quota),
|
||||
_rom_root(_policy.rom_root()),
|
||||
_report_root(_policy.report_root())
|
||||
_ep(&pd, _ep_stack_size, "report_rom"),
|
||||
_policy(_ep, rm, ram, config),
|
||||
_child(rm, _ep, _policy)
|
||||
{ }
|
||||
|
||||
Genode::Rom_session_capability rom_session(char const *label)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
enum { ARGBUF_SIZE = 128 };
|
||||
char argbuf[ARGBUF_SIZE];
|
||||
argbuf[0] = 0;
|
||||
|
||||
/*
|
||||
* Declare ram-quota donation
|
||||
*/
|
||||
enum { SESSION_METADATA = 4*1024 };
|
||||
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA);
|
||||
|
||||
/*
|
||||
* Set session label
|
||||
*/
|
||||
Arg_string::set_arg_string(argbuf, sizeof(argbuf), "label", label);
|
||||
|
||||
Session_capability session_cap = _rom_root.session(argbuf, Affinity());
|
||||
|
||||
return static_cap_cast<Genode::Rom_session>(session_cap);
|
||||
}
|
||||
|
||||
Genode::Capability<Report::Session> report_session(char const *label)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
enum { ARGBUF_SIZE = 128 };
|
||||
char argbuf[ARGBUF_SIZE];
|
||||
argbuf[0] = 0;
|
||||
|
||||
/*
|
||||
* Declare ram-quota donation
|
||||
*/
|
||||
enum { BUFFER_SIZE = 4096, SESSION_METADATA = BUFFER_SIZE + 8*1024 };
|
||||
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA);
|
||||
Arg_string::set_arg(argbuf, sizeof(argbuf), "buffer_size", BUFFER_SIZE);
|
||||
|
||||
/*
|
||||
* Set session label
|
||||
*/
|
||||
Arg_string::set_arg_string(argbuf, sizeof(argbuf), "label", label);
|
||||
|
||||
Session_capability session_cap = _report_root.session(argbuf, Affinity());
|
||||
|
||||
return static_cap_cast<Report::Session>(session_cap);
|
||||
}
|
||||
Genode::Slave::Policy &policy() { return _policy; }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__GEMS__REPORT_ROM_SLAVE_H_ */
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* \brief Utility for implementing a local service with a single session
|
||||
* \author Norman Feske
|
||||
* \date 2014-02-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 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.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__GEMS__SINGLE_SESSION_SERVICE_H_
|
||||
#define _INCLUDE__GEMS__SINGLE_SESSION_SERVICE_H_
|
||||
|
||||
#include <base/service.h>
|
||||
|
||||
struct Single_session_service : Genode::Service
|
||||
{
|
||||
Genode::Session_capability session_cap;
|
||||
|
||||
Single_session_service(char const *service_name,
|
||||
Genode::Session_capability session_cap)
|
||||
:
|
||||
Service(service_name), session_cap(session_cap)
|
||||
{ }
|
||||
|
||||
Genode::Session_capability
|
||||
session(const char *, Genode::Affinity const &) override
|
||||
{
|
||||
return session_cap;
|
||||
}
|
||||
|
||||
void upgrade(Genode::Session_capability, const char *) override { }
|
||||
void close(Genode::Session_capability) override { }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__GEMS__SINGLE_SESSION_SERVICE_H_ */
|
@ -105,12 +105,11 @@ class Launcher::Context_dialog : Input_event_handler, Dialog_generator,
|
||||
|
||||
public:
|
||||
|
||||
Context_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram,
|
||||
Dataspace_capability ldso_ds,
|
||||
Context_dialog(Env &env,
|
||||
Report_rom_slave &report_rom_slave,
|
||||
Response_handler &response_handler)
|
||||
:
|
||||
_dialog(ep, cap, ram, ldso_ds, report_rom_slave,
|
||||
_dialog(env, report_rom_slave,
|
||||
"context_dialog", "context_hover",
|
||||
*this, *this, *this, *this,
|
||||
Fading_dialog::Position(364, 64)),
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/string.h>
|
||||
#include <base/entrypoint.h>
|
||||
#include <os/attached_dataspace.h>
|
||||
#include <nitpicker_session/nitpicker_session.h>
|
||||
#include <input_session/client.h>
|
||||
@ -54,7 +55,7 @@ struct Launcher::Dialog_nitpicker_session : Wrapped_nitpicker_session
|
||||
|
||||
Input_event_handler &_input_event_handler;
|
||||
|
||||
Server::Entrypoint &_ep;
|
||||
Rpc_entrypoint &_session_ep;
|
||||
|
||||
Nitpicker::Session &_nitpicker_session;
|
||||
|
||||
@ -62,36 +63,43 @@ struct Launcher::Dialog_nitpicker_session : Wrapped_nitpicker_session
|
||||
|
||||
Attached_dataspace _nitpicker_input_ds { _nitpicker_input.dataspace() };
|
||||
|
||||
Signal_rpc_member<Dialog_nitpicker_session>
|
||||
_input_dispatcher { _ep, *this, &Dialog_nitpicker_session::_input_handler };
|
||||
Signal_handler<Dialog_nitpicker_session> _input_handler;
|
||||
|
||||
Input::Session_component _input_session;
|
||||
|
||||
Capability<Input::Session> _input_session_cap { _ep.manage(_input_session) };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param input_sigh_ep entrypoint where the input signal handler is
|
||||
* installed ('env.ep')
|
||||
* \param service_ep entrypoint providing the nitpicker session
|
||||
* (slave-specific ep)
|
||||
*/
|
||||
Dialog_nitpicker_session(Nitpicker::Session &nitpicker_session,
|
||||
Server::Entrypoint &ep,
|
||||
Dialog_nitpicker_session(Nitpicker::Session &nitpicker_session,
|
||||
Entrypoint &input_sigh_ep,
|
||||
Rpc_entrypoint &session_ep,
|
||||
Input_event_handler &input_event_handler)
|
||||
:
|
||||
Wrapped_nitpicker_session(nitpicker_session),
|
||||
_input_event_handler(input_event_handler),
|
||||
_ep(ep),
|
||||
_nitpicker_session(nitpicker_session)
|
||||
_session_ep(session_ep),
|
||||
_nitpicker_session(nitpicker_session),
|
||||
_input_handler(input_sigh_ep, *this, &Dialog_nitpicker_session::_handle_input)
|
||||
{
|
||||
_nitpicker_input.sigh(_input_dispatcher);
|
||||
_session_ep.manage(this);
|
||||
_session_ep.manage(&_input_session);
|
||||
_nitpicker_input.sigh(_input_handler);
|
||||
|
||||
_input_session.event_queue().enabled(true);
|
||||
}
|
||||
|
||||
~Dialog_nitpicker_session()
|
||||
{
|
||||
_ep.dissolve(_input_session);
|
||||
_session_ep.dissolve(&_input_session);
|
||||
_session_ep.dissolve(this);
|
||||
}
|
||||
|
||||
void _input_handler(unsigned)
|
||||
void _handle_input()
|
||||
{
|
||||
Input::Event const * const events =
|
||||
_nitpicker_input_ds.local_addr<Input::Event>();
|
||||
@ -116,7 +124,7 @@ struct Launcher::Dialog_nitpicker_session : Wrapped_nitpicker_session
|
||||
|
||||
Input::Session_capability input_session() override
|
||||
{
|
||||
return _input_session_cap;
|
||||
return _input_session.cap();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -54,17 +54,17 @@ class Launcher::Fading_dialog : private Input_event_handler
|
||||
{
|
||||
private:
|
||||
|
||||
Rom_session_capability _dialog_rom;
|
||||
Slave::Connection<Rom_connection> _dialog_rom;
|
||||
|
||||
/* dialog reported locally */
|
||||
Capability<Report::Session> _dialog_report;
|
||||
Slave::Connection<Report::Connection> _dialog_report;
|
||||
|
||||
Rom_session_client _hover_rom;
|
||||
Slave::Connection<Rom_connection> _hover_rom;
|
||||
|
||||
Lazy_volatile_object<Attached_dataspace> _hover_ds;
|
||||
|
||||
/* hovered element reported by menu view */
|
||||
Capability<Report::Session> _hover_report;
|
||||
Slave::Connection<Report::Connection> _hover_report;
|
||||
|
||||
Local_reporter _dialog_reporter { "dialog", _dialog_report };
|
||||
|
||||
@ -100,7 +100,7 @@ class Launcher::Fading_dialog : private Input_event_handler
|
||||
return forward_event;
|
||||
}
|
||||
|
||||
void _handle_hover_update(unsigned)
|
||||
void _handle_hover_update()
|
||||
{
|
||||
try {
|
||||
if (!_hover_ds.constructed() || _hover_rom.update() == false) {
|
||||
@ -129,52 +129,10 @@ class Launcher::Fading_dialog : private Input_event_handler
|
||||
}
|
||||
}
|
||||
|
||||
Signal_rpc_member<Fading_dialog> _hover_update_dispatcher;
|
||||
Signal_handler<Fading_dialog> _hover_update_handler;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Local nitpicker service to be handed out to the menu view slave
|
||||
*/
|
||||
struct Nitpicker_service : Genode::Service
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
Rpc_entrypoint &child_ep;
|
||||
|
||||
/* connection to real nitpicker */
|
||||
Nitpicker::Connection connection { "menu" };
|
||||
|
||||
Dialog_nitpicker_session wrapper_session;
|
||||
|
||||
Capability<Nitpicker::Session> session_cap { child_ep.manage(&wrapper_session) };
|
||||
|
||||
Nitpicker_service(Server::Entrypoint &ep,
|
||||
Rpc_entrypoint &child_ep,
|
||||
Dialog_nitpicker_session::Input_event_handler &ev_handler)
|
||||
:
|
||||
Genode::Service(Nitpicker::Session::service_name()),
|
||||
ep(ep), child_ep(child_ep),
|
||||
wrapper_session(connection, ep, ev_handler)
|
||||
{ }
|
||||
|
||||
/*******************************
|
||||
** Genode::Service interface **
|
||||
*******************************/
|
||||
|
||||
Genode::Session_capability
|
||||
session(const char *, Genode::Affinity const &) override
|
||||
{
|
||||
return session_cap;
|
||||
}
|
||||
|
||||
void upgrade(Genode::Session_capability, const char *args) override
|
||||
{
|
||||
Genode::log("upgrade called args: '", args, "'");
|
||||
}
|
||||
|
||||
void close(Genode::Session_capability) override { }
|
||||
};
|
||||
|
||||
/*
|
||||
* Entrypoint for the fader slave
|
||||
*
|
||||
@ -188,9 +146,21 @@ class Launcher::Fading_dialog : private Input_event_handler
|
||||
size_t const _fader_slave_ep_stack_size = 4*1024*sizeof(addr_t);
|
||||
Rpc_entrypoint _fader_slave_ep;
|
||||
|
||||
Nitpicker_service _nitpicker_service;
|
||||
Nit_fader_slave _nit_fader_slave;
|
||||
Menu_view_slave _menu_view_slave;
|
||||
/*
|
||||
* Provide wrapped nitpicker connection as a service handed out to
|
||||
* the menu-view slave
|
||||
*/
|
||||
typedef Genode::Local_service<Dialog_nitpicker_session> Nitpicker_service;
|
||||
typedef Nitpicker_service::Single_session_factory Nitpicker_factory;
|
||||
|
||||
Nitpicker::Connection _nitpicker_connection;
|
||||
Dialog_nitpicker_session _nitpicker_session;
|
||||
Nitpicker_factory _nitpicker_factory { _nitpicker_session };
|
||||
Nitpicker_service _nitpicker_service { _nitpicker_factory };
|
||||
|
||||
Nit_fader_slave _nit_fader_slave;
|
||||
Slave::Connection<Nitpicker::Connection> _nit_fader_connection;
|
||||
Menu_view_slave _menu_view_slave;
|
||||
|
||||
bool _visible = false;
|
||||
|
||||
@ -198,47 +168,38 @@ class Launcher::Fading_dialog : private Input_event_handler
|
||||
|
||||
typedef Menu_view_slave::Position Position;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param ep main entrypoint, used for managing the local input
|
||||
* session provided (indirectly through the wrapped
|
||||
* nitpicker session) to the menu view
|
||||
* \param cap capability session to be used for creating the
|
||||
* slave entrypoints
|
||||
* \param ram RAM session where to draw the memory for providing
|
||||
* configuration data to the slave processes
|
||||
*/
|
||||
Fading_dialog(Server::Entrypoint &ep,
|
||||
Cap_session &cap,
|
||||
Ram_session &ram,
|
||||
Dataspace_capability ldso_ds,
|
||||
Report_rom_slave &report_rom_slave,
|
||||
char const *dialog_name,
|
||||
char const *hover_name,
|
||||
Input_event_handler &input_event_handler,
|
||||
Hover_handler &hover_handler,
|
||||
Dialog_generator &dialog_generator,
|
||||
Dialog_model &dialog_model,
|
||||
Position initial_position)
|
||||
Fading_dialog(Env &env,
|
||||
Report_rom_slave &report_rom_slave,
|
||||
char const *dialog_name,
|
||||
char const *hover_name,
|
||||
Input_event_handler &input_event_handler,
|
||||
Hover_handler &hover_handler,
|
||||
Dialog_generator &dialog_generator,
|
||||
Dialog_model &dialog_model,
|
||||
Position initial_position)
|
||||
:
|
||||
_dialog_rom(report_rom_slave.rom_session(dialog_name)),
|
||||
_dialog_report(report_rom_slave.report_session(dialog_name)),
|
||||
_hover_rom(report_rom_slave.rom_session(hover_name)),
|
||||
_hover_report(report_rom_slave.report_session(hover_name)),
|
||||
_dialog_rom(report_rom_slave.policy(), Slave::Args("label=", dialog_name)),
|
||||
_dialog_report(report_rom_slave.policy(),
|
||||
Slave::Args("label=", dialog_name, ", buffer_size=4096")),
|
||||
_hover_rom(report_rom_slave.policy(), Slave::Args("label=", hover_name)),
|
||||
_hover_report(report_rom_slave.policy(),
|
||||
Slave::Args("label=", hover_name, ", buffer_size=4096")),
|
||||
_dialog_input_event_handler(input_event_handler),
|
||||
_hover_handler(hover_handler),
|
||||
_dialog_generator(dialog_generator),
|
||||
_dialog_model(dialog_model),
|
||||
_hover_update_dispatcher(ep, *this, &Fading_dialog::_handle_hover_update),
|
||||
_fader_slave_ep(&cap, _fader_slave_ep_stack_size, "nit_fader"),
|
||||
_nitpicker_service(ep, _fader_slave_ep, *this),
|
||||
_nit_fader_slave(_fader_slave_ep, ram, _nitpicker_service, ldso_ds),
|
||||
_menu_view_slave(cap, ram, ldso_ds,
|
||||
_nit_fader_slave.nitpicker_session("menu"),
|
||||
_hover_update_handler(env.ep(), *this, &Fading_dialog::_handle_hover_update),
|
||||
_fader_slave_ep(&env.pd(), _fader_slave_ep_stack_size, "nit_fader"),
|
||||
_nitpicker_connection(env, "menu"),
|
||||
_nitpicker_session(_nitpicker_connection, env.ep(), _fader_slave_ep, *this),
|
||||
_nit_fader_slave(_fader_slave_ep, env.rm(), env.ram_session_cap(),
|
||||
_nitpicker_service),
|
||||
_nit_fader_connection(_nit_fader_slave.policy(), Slave::Args("label=menu")),
|
||||
_menu_view_slave(env.pd(), env.rm(), env.ram_session_cap(),
|
||||
_nit_fader_connection,
|
||||
_dialog_rom, _hover_report, initial_position)
|
||||
{
|
||||
Rom_session_client(_hover_rom).sigh(_hover_update_dispatcher);
|
||||
Rom_session_client(_hover_rom).sigh(_hover_update_handler);
|
||||
}
|
||||
|
||||
void update()
|
||||
|
@ -12,9 +12,7 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/server.h>
|
||||
#include <os/config.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <base/component.h>
|
||||
#include <decorator/xml_utils.h>
|
||||
#include <util/volatile_object.h>
|
||||
#include <os/attached_rom_dataspace.h>
|
||||
@ -23,25 +21,16 @@
|
||||
/* local includes */
|
||||
#include <panel_dialog.h>
|
||||
|
||||
namespace Launcher {
|
||||
|
||||
using namespace Genode;
|
||||
struct Main;
|
||||
}
|
||||
|
||||
namespace Launcher { struct Main; }
|
||||
|
||||
struct Launcher::Main
|
||||
{
|
||||
Server::Entrypoint &_ep;
|
||||
|
||||
Genode::Dataspace_capability _request_ldso_ds()
|
||||
{
|
||||
try {
|
||||
static Genode::Rom_connection rom("ld.lib.so");
|
||||
return rom.dataspace();
|
||||
} catch (...) { }
|
||||
return Genode::Dataspace_capability();
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability _ldso_ds = _request_ldso_ds();
|
||||
|
||||
Genode::Cap_connection _cap;
|
||||
Env &_env;
|
||||
|
||||
char const *_report_rom_config =
|
||||
"<config>"
|
||||
@ -53,35 +42,54 @@ struct Launcher::Main
|
||||
" <policy label=\"context_hover\" report=\"context_hover\"/>"
|
||||
"</config>";
|
||||
|
||||
Report_rom_slave _report_rom_slave = { _cap, *env()->ram_session(), _report_rom_config };
|
||||
Report_rom_slave _report_rom_slave {
|
||||
_env.pd(), _env.rm(), _env.ram_session_cap(), _report_rom_config };
|
||||
|
||||
/**
|
||||
* Nitpicker session used to perform session-control operations on the
|
||||
* subsystem's nitpicker sessions and to receive global keyboard
|
||||
* shortcuts.
|
||||
*/
|
||||
Nitpicker::Connection _nitpicker;
|
||||
Nitpicker::Connection _nitpicker { _env };
|
||||
|
||||
Genode::Signal_rpc_member<Main> _input_dispatcher =
|
||||
{ _ep, *this, &Main::_handle_input };
|
||||
Signal_handler<Main> _input_handler =
|
||||
{ _env.ep(), *this, &Main::_handle_input };
|
||||
|
||||
void _handle_input(unsigned);
|
||||
void _handle_input();
|
||||
|
||||
unsigned _key_cnt = 0;
|
||||
|
||||
Genode::Signal_rpc_member<Main> _exited_child_dispatcher =
|
||||
{ _ep, *this, &Main::_handle_exited_child };
|
||||
Signal_handler<Main> _exited_child_handler =
|
||||
{ _env.ep(), *this, &Main::_handle_exited_child };
|
||||
|
||||
Subsystem_manager _subsystem_manager { _ep, _cap, _exited_child_dispatcher,
|
||||
_ldso_ds };
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
Panel_dialog _panel_dialog { _ep, _cap, *env()->ram_session(), _ldso_ds,
|
||||
*env()->heap(),
|
||||
_report_rom_slave, _subsystem_manager, _nitpicker };
|
||||
static size_t _ram_preservation(Xml_node config)
|
||||
{
|
||||
char const * const node_name = "preservation";
|
||||
|
||||
void _handle_config(unsigned);
|
||||
if (config.has_sub_node(node_name)) {
|
||||
|
||||
void _handle_exited_child(unsigned)
|
||||
Xml_node const node = config.sub_node(node_name);
|
||||
if (node.attribute_value("name", Genode::String<16>()) == "RAM")
|
||||
return node.attribute_value("quantum", Genode::Number_of_bytes());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Subsystem_manager _subsystem_manager { _env.ep(), _env.pd(),
|
||||
_ram_preservation(_config.xml()),
|
||||
_exited_child_handler };
|
||||
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
Panel_dialog _panel_dialog { _env, _heap, _report_rom_slave,
|
||||
_subsystem_manager, _nitpicker };
|
||||
|
||||
void _handle_config();
|
||||
|
||||
void _handle_exited_child()
|
||||
{
|
||||
auto kill_child_fn = [&] (Label const &label) { _panel_dialog.kill(label); };
|
||||
|
||||
@ -92,37 +100,40 @@ struct Launcher::Main
|
||||
|
||||
Genode::Attached_rom_dataspace _focus_rom { "focus" };
|
||||
|
||||
void _handle_focus_update(unsigned);
|
||||
void _handle_focus_update();
|
||||
|
||||
Genode::Signal_rpc_member<Main> _focus_update_dispatcher =
|
||||
{ _ep, *this, &Main::_handle_focus_update };
|
||||
Signal_handler<Main> _focus_update_handler =
|
||||
{ _env.ep(), *this, &Main::_handle_focus_update };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Main(Server::Entrypoint &ep) : _ep(ep)
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
_nitpicker.input()->sigh(_input_dispatcher);
|
||||
_focus_rom.sigh(_focus_update_dispatcher);
|
||||
_nitpicker.input()->sigh(_input_handler);
|
||||
_focus_rom.sigh(_focus_update_handler);
|
||||
|
||||
_handle_config(0);
|
||||
_handle_config();
|
||||
|
||||
_panel_dialog.visible(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Launcher::Main::_handle_config(unsigned)
|
||||
void Launcher::Main::_handle_config()
|
||||
{
|
||||
config()->reload();
|
||||
_config.update();
|
||||
|
||||
_focus_prefix = config()->xml_node().attribute_value("focus_prefix", Label());
|
||||
_focus_prefix = _config.xml().attribute_value("focus_prefix", Label());
|
||||
|
||||
_panel_dialog.update(config()->xml_node());
|
||||
try {
|
||||
_panel_dialog.update(_config.xml()); }
|
||||
catch (Allocator::Out_of_memory) {
|
||||
error("out of memory while applying configuration"); }
|
||||
}
|
||||
|
||||
|
||||
void Launcher::Main::_handle_input(unsigned)
|
||||
void Launcher::Main::_handle_input()
|
||||
{
|
||||
_nitpicker.input()->for_each_event([&] (Input::Event const &e) {
|
||||
if (e.type() == Input::Event::PRESS) _key_cnt++;
|
||||
@ -143,7 +154,7 @@ void Launcher::Main::_handle_input(unsigned)
|
||||
}
|
||||
|
||||
|
||||
void Launcher::Main::_handle_focus_update(unsigned)
|
||||
void Launcher::Main::_handle_focus_update()
|
||||
{
|
||||
try {
|
||||
_focus_rom.update();
|
||||
@ -176,18 +187,4 @@ void Launcher::Main::_handle_focus_update(unsigned)
|
||||
}
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
namespace Server {
|
||||
|
||||
char const *name() { return "desktop_ep"; }
|
||||
|
||||
size_t stack_size() { return 4*1024*sizeof(long); }
|
||||
|
||||
void construct(Entrypoint &ep)
|
||||
{
|
||||
static Launcher::Main desktop(ep);
|
||||
}
|
||||
}
|
||||
void Component::construct(Genode::Env &env) { static Launcher::Main main(env); }
|
||||
|
@ -103,18 +103,14 @@ class Launcher::Menu_dialog : Input_event_handler, Dialog_generator,
|
||||
|
||||
public:
|
||||
|
||||
Menu_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram,
|
||||
Dataspace_capability ldso_ds,
|
||||
Menu_dialog(Env &env,
|
||||
Report_rom_slave &report_rom_slave,
|
||||
Response_handler &response_handler)
|
||||
:
|
||||
_response_handler(response_handler),
|
||||
_dialog(ep, cap, ram, ldso_ds, report_rom_slave,
|
||||
"menu_dialog", "menu_hover",
|
||||
*this, *this, *this, *this,
|
||||
_position)
|
||||
{
|
||||
}
|
||||
_dialog(env, report_rom_slave, "menu_dialog", "menu_hover",
|
||||
*this, *this, *this, *this, _position)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Dialog_generator interface
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <nitpicker_session/nitpicker_session.h>
|
||||
|
||||
/* gems includes */
|
||||
#include <gems/single_session_service.h>
|
||||
#include <os/single_session_service.h>
|
||||
|
||||
/* local includes */
|
||||
#include <types.h>
|
||||
@ -35,16 +35,13 @@ class Launcher::Menu_view_slave
|
||||
|
||||
private:
|
||||
|
||||
class Policy : public Genode::Slave_policy
|
||||
class Policy : public Genode::Slave::Policy
|
||||
{
|
||||
private:
|
||||
|
||||
Lock mutable _nitpicker_root_lock { Lock::LOCKED };
|
||||
Capability<Root> _nitpicker_root_cap;
|
||||
|
||||
Single_session_service _nitpicker_service;
|
||||
Single_session_service _dialog_rom_service;
|
||||
Single_session_service _hover_report_service;
|
||||
Genode::Single_session_service<Nitpicker::Session> _nitpicker;
|
||||
Genode::Single_session_service<Genode::Rom_session> _dialog_rom;
|
||||
Genode::Single_session_service<Report::Session> _hover_report;
|
||||
|
||||
Position _position;
|
||||
|
||||
@ -53,7 +50,7 @@ class Launcher::Menu_view_slave
|
||||
char const **_permitted_services() const
|
||||
{
|
||||
static char const *permitted_services[] = {
|
||||
"ROM", "LOG", "RM", "Timer", 0 };
|
||||
"CPU", "PD", "RAM", "ROM", "LOG", "Timer", 0 };
|
||||
|
||||
return permitted_services;
|
||||
};
|
||||
@ -78,82 +75,70 @@ class Launcher::Menu_view_slave
|
||||
configure(config);
|
||||
}
|
||||
|
||||
static Name _name() { return "menu_view"; }
|
||||
static Genode::size_t _quota() { return 6*1024*1024; }
|
||||
|
||||
public:
|
||||
|
||||
Policy(Genode::Rpc_entrypoint &entrypoint,
|
||||
Genode::Ram_session &ram,
|
||||
Policy(Genode::Rpc_entrypoint &ep,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Ram_session_capability ram,
|
||||
Capability<Nitpicker::Session> nitpicker_session,
|
||||
Capability<Rom_session> dialog_rom_session,
|
||||
Capability<Report::Session> hover_report_session,
|
||||
Position position)
|
||||
:
|
||||
Slave_policy("menu_view", entrypoint, &ram),
|
||||
_nitpicker_service(Nitpicker::Session::service_name(), nitpicker_session),
|
||||
_dialog_rom_service(Rom_session::service_name(), dialog_rom_session),
|
||||
_hover_report_service(Report::Session::service_name(), hover_report_session),
|
||||
Genode::Slave::Policy(_name(), _name(), ep, rm, ram, _quota()),
|
||||
_nitpicker(nitpicker_session),
|
||||
_dialog_rom(dialog_rom_session),
|
||||
_hover_report(hover_report_session),
|
||||
_position(position)
|
||||
{
|
||||
_configure(position);
|
||||
}
|
||||
|
||||
void position(Position pos)
|
||||
void position(Position pos) { _configure(pos); }
|
||||
|
||||
Genode::Service &resolve_session_request(Genode::Service::Name const &service,
|
||||
Genode::Session_state::Args const &args) override
|
||||
{
|
||||
_configure(pos);
|
||||
}
|
||||
if (service == "Nitpicker")
|
||||
return _nitpicker.service();
|
||||
|
||||
Genode::Service *resolve_session_request(const char *service_name,
|
||||
const char *args) override
|
||||
{
|
||||
using Genode::strcmp;
|
||||
Genode::Session_label const label(label_from_args(args.string()));
|
||||
|
||||
if (strcmp(service_name, "Nitpicker") == 0)
|
||||
return &_nitpicker_service;
|
||||
if ((service == "ROM") && (label == "menu_view -> dialog"))
|
||||
return _dialog_rom.service();
|
||||
|
||||
char label[128];
|
||||
Arg_string::find_arg(args, "label").string(label, sizeof(label), "");
|
||||
if ((service == "Report") && (label == "menu_view -> hover"))
|
||||
return _hover_report.service();
|
||||
|
||||
if (strcmp(service_name, "ROM") == 0) {
|
||||
|
||||
if (strcmp(label, "menu_view -> dialog") == 0)
|
||||
return &_dialog_rom_service;
|
||||
}
|
||||
|
||||
if (strcmp(service_name, "Report") == 0) {
|
||||
|
||||
if (strcmp(label, "menu_view -> hover") == 0)
|
||||
return &_hover_report_service;
|
||||
}
|
||||
|
||||
return Genode::Slave_policy::resolve_session_request(service_name, args);
|
||||
return Genode::Slave::Policy::resolve_session_request(service, args);
|
||||
}
|
||||
};
|
||||
|
||||
Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t);
|
||||
Genode::Rpc_entrypoint _ep;
|
||||
Policy _policy;
|
||||
Genode::size_t const _quota = 6*1024*1024;
|
||||
Genode::Slave _slave;
|
||||
Genode::Child _child;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param ep entrypoint used for child thread
|
||||
* \param ram RAM session used to allocate the configuration
|
||||
* dataspace
|
||||
*/
|
||||
Menu_view_slave(Genode::Cap_session &cap, Genode::Ram_session &ram,
|
||||
Genode::Dataspace_capability ldso_ds,
|
||||
Menu_view_slave(Genode::Pd_session &pd,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Ram_session_capability ram,
|
||||
Capability<Nitpicker::Session> nitpicker_session,
|
||||
Capability<Rom_session> dialog_rom_session,
|
||||
Capability<Report::Session> hover_report_session,
|
||||
Position initial_position)
|
||||
:
|
||||
_ep(&cap, _ep_stack_size, "nit_fader"),
|
||||
_policy(_ep, ram, nitpicker_session, dialog_rom_session,
|
||||
_ep(&pd, _ep_stack_size, "nit_fader"),
|
||||
_policy(_ep, rm, ram, nitpicker_session, dialog_rom_session,
|
||||
hover_report_session, initial_position),
|
||||
_slave(_ep, _policy, _quota, env()->ram_session_cap(), ldso_ds)
|
||||
_child(rm, _ep, _policy)
|
||||
{ }
|
||||
|
||||
void position(Position position) { _policy.position(position); }
|
||||
|
@ -28,31 +28,33 @@ class Launcher::Nit_fader_slave
|
||||
{
|
||||
private:
|
||||
|
||||
class Policy : public Slave_policy
|
||||
class Policy : public Slave::Policy
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Service &_nitpicker_service;
|
||||
Lock mutable _nitpicker_root_lock { Lock::LOCKED };
|
||||
Capability<Root> _nitpicker_root_cap;
|
||||
|
||||
protected:
|
||||
|
||||
char const **_permitted_services() const
|
||||
{
|
||||
static char const *permitted_services[] = {
|
||||
"LOG", "RM", "Timer", 0 };
|
||||
"RAM", "CPU", "PD", "LOG", "Timer", 0 };
|
||||
|
||||
return permitted_services;
|
||||
};
|
||||
|
||||
static Name _name() { return "nit_fader"; }
|
||||
static size_t _quota() { return 2*1024*1024; }
|
||||
|
||||
public:
|
||||
|
||||
Policy(Rpc_entrypoint &entrypoint,
|
||||
Ram_session &ram,
|
||||
Genode::Service &nitpicker_service)
|
||||
Policy(Rpc_entrypoint &ep,
|
||||
Region_map &rm,
|
||||
Ram_session_capability ram,
|
||||
Genode::Service &nitpicker_service)
|
||||
:
|
||||
Slave_policy("nit_fader", entrypoint, &ram),
|
||||
Genode::Slave::Policy(_name(), _name(), ep, rm, ram, _quota()),
|
||||
_nitpicker_service(nitpicker_service)
|
||||
{
|
||||
visible(false);
|
||||
@ -66,42 +68,18 @@ class Launcher::Nit_fader_slave
|
||||
configure(config, strlen(config) + 1);
|
||||
}
|
||||
|
||||
bool announce_service(const char *service_name,
|
||||
Root_capability root,
|
||||
Allocator *,
|
||||
Genode::Server *)
|
||||
Genode::Service &resolve_session_request(Genode::Service::Name const &service,
|
||||
Genode::Session_state::Args const &args) override
|
||||
{
|
||||
if (strcmp(service_name, "Nitpicker") == 0)
|
||||
_nitpicker_root_cap = root;
|
||||
else
|
||||
return false;
|
||||
if (service == Nitpicker::Session::service_name())
|
||||
return _nitpicker_service;
|
||||
|
||||
if (_nitpicker_root_cap.valid())
|
||||
_nitpicker_root_lock.unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Genode::Service *resolve_session_request(const char *service_name,
|
||||
const char *args) override
|
||||
{
|
||||
if (Genode::strcmp(service_name, "Nitpicker") == 0)
|
||||
return &_nitpicker_service;
|
||||
|
||||
return Genode::Slave_policy::resolve_session_request(service_name, args);
|
||||
}
|
||||
|
||||
Root_capability nitpicker_root() const
|
||||
{
|
||||
Lock::Guard guard(_nitpicker_root_lock);
|
||||
return _nitpicker_root_cap;
|
||||
return Genode::Slave::Policy::resolve_session_request(service, args);
|
||||
}
|
||||
};
|
||||
|
||||
Policy _policy;
|
||||
size_t const _quota = 2*1024*1024;
|
||||
Slave _slave;
|
||||
Root_client _nitpicker_root;
|
||||
Policy _policy;
|
||||
Child _child;
|
||||
|
||||
public:
|
||||
|
||||
@ -112,38 +90,18 @@ class Launcher::Nit_fader_slave
|
||||
* \param ram RAM session used to allocate the configuration
|
||||
* dataspace
|
||||
*/
|
||||
Nit_fader_slave(Rpc_entrypoint &ep, Ram_session &ram,
|
||||
Genode::Service &nitpicker_service,
|
||||
Genode::Dataspace_capability ldso_ds)
|
||||
Nit_fader_slave(Rpc_entrypoint &ep,
|
||||
Genode::Region_map &rm,
|
||||
Ram_session_capability ram,
|
||||
Genode::Service &nitpicker_service)
|
||||
:
|
||||
_policy(ep, ram, nitpicker_service),
|
||||
_slave(ep, _policy, _quota, env()->ram_session_cap(), ldso_ds),
|
||||
_nitpicker_root(_policy.nitpicker_root())
|
||||
_policy(ep, rm, ram, nitpicker_service),
|
||||
_child(rm, ep, _policy)
|
||||
{
|
||||
visible(false);
|
||||
}
|
||||
|
||||
Capability<Nitpicker::Session> nitpicker_session(char const *label)
|
||||
{
|
||||
enum { ARGBUF_SIZE = 128 };
|
||||
char argbuf[ARGBUF_SIZE];
|
||||
argbuf[0] = 0;
|
||||
|
||||
/*
|
||||
* Declare ram-quota donation
|
||||
*/
|
||||
enum { SESSION_METADATA = 8*1024 };
|
||||
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA);
|
||||
|
||||
/*
|
||||
* Set session label
|
||||
*/
|
||||
Arg_string::set_arg_string(argbuf, sizeof(argbuf), "label", label);
|
||||
|
||||
Session_capability session_cap = _nitpicker_root.session(argbuf, Affinity());
|
||||
|
||||
return static_cap_cast<Nitpicker::Session>(session_cap);
|
||||
}
|
||||
Genode::Slave::Policy &policy() { return _policy; }
|
||||
|
||||
void visible(bool visible)
|
||||
{
|
||||
|
@ -50,6 +50,39 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
|
||||
|
||||
Genode::Allocator &_alloc;
|
||||
|
||||
struct Buffered_xml
|
||||
{
|
||||
Allocator &_alloc;
|
||||
char const * const _ptr; /* pointer to dynamically allocated buffer */
|
||||
Xml_node const _xml; /* referring to buffer of '_ptr' */
|
||||
|
||||
/**
|
||||
* \throw Allocator::Out_of_memory
|
||||
*/
|
||||
static char const *_init_ptr(Allocator &alloc, Xml_node node)
|
||||
{
|
||||
char *ptr = (char *)alloc.alloc(node.size());
|
||||
Genode::memcpy(ptr, node.addr(), node.size());
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \throw Allocator::Out_of_memory
|
||||
*/
|
||||
Buffered_xml(Allocator &alloc, Xml_node node)
|
||||
:
|
||||
_alloc(alloc), _ptr(_init_ptr(alloc, node)), _xml(_ptr, node.size())
|
||||
{ }
|
||||
|
||||
~Buffered_xml() { _alloc.free(const_cast<char *>(_ptr), _xml.size()); }
|
||||
|
||||
Xml_node xml() const { return _xml; }
|
||||
};
|
||||
|
||||
Lazy_volatile_object<Buffered_xml> _config;
|
||||
|
||||
List<Element> _elements;
|
||||
|
||||
Label _focus;
|
||||
@ -135,7 +168,7 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
|
||||
Element *_clicked = nullptr;
|
||||
bool _click_in_progress = false;
|
||||
|
||||
Signal_rpc_member<Panel_dialog> _timer_dispatcher;
|
||||
Signal_handler<Panel_dialog> _timer_handler;
|
||||
|
||||
Label _context_subsystem;
|
||||
Context_dialog _context_dialog;
|
||||
@ -165,9 +198,13 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
|
||||
|
||||
void _start(Label const &label)
|
||||
{
|
||||
if (!_config.constructed()) {
|
||||
warning("attempt to start subsystem without prior configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Xml_node subsystem = _subsystem(config()->xml_node(),
|
||||
label.string());
|
||||
Xml_node subsystem = _subsystem(_config->xml(), label.string());
|
||||
_subsystem_manager.start(subsystem);
|
||||
|
||||
Title const title = subsystem.attribute_value("title", Title());
|
||||
@ -232,7 +269,7 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
|
||||
_context_dialog.visible(true);
|
||||
}
|
||||
|
||||
void _handle_timer(unsigned)
|
||||
void _handle_timer()
|
||||
{
|
||||
if (_click_in_progress && _clicked && _hovered() == _clicked) {
|
||||
_open_context_dialog(_clicked->label);
|
||||
@ -250,26 +287,23 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
|
||||
|
||||
public:
|
||||
|
||||
Panel_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram,
|
||||
Dataspace_capability ldso_ds,
|
||||
Genode::Allocator &alloc,
|
||||
Report_rom_slave &report_rom_slave,
|
||||
Subsystem_manager &subsystem_manager,
|
||||
Panel_dialog(Env &env,
|
||||
Genode::Allocator &alloc,
|
||||
Report_rom_slave &report_rom_slave,
|
||||
Subsystem_manager &subsystem_manager,
|
||||
Nitpicker::Session &nitpicker)
|
||||
:
|
||||
_alloc(alloc),
|
||||
_subsystem_manager(subsystem_manager),
|
||||
_nitpicker(nitpicker),
|
||||
_dialog(ep, cap, ram, ldso_ds, report_rom_slave,
|
||||
"panel_dialog", "panel_hover",
|
||||
*this, *this, *this, *this,
|
||||
_position),
|
||||
_timer_dispatcher(ep, *this, &Panel_dialog::_handle_timer),
|
||||
_context_dialog(ep, cap, ram, ldso_ds, report_rom_slave, *this),
|
||||
_menu_dialog(ep, cap, ram, ldso_ds, report_rom_slave, *this)
|
||||
_dialog(env, report_rom_slave, "panel_dialog", "panel_hover",
|
||||
*this, *this, *this, *this, _position),
|
||||
_timer_handler(env.ep(), *this, &Panel_dialog::_handle_timer),
|
||||
_context_dialog(env, report_rom_slave, *this),
|
||||
_menu_dialog(env, report_rom_slave, *this)
|
||||
{
|
||||
_elements.insert(&_menu_button);
|
||||
_timer.sigh(_timer_dispatcher);
|
||||
_timer.sigh(_timer_handler);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -514,13 +548,17 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
|
||||
_kill(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* \throw Allocator::Out_of_memory
|
||||
*/
|
||||
void update(Xml_node config)
|
||||
{
|
||||
_config.construct(_alloc, config);
|
||||
|
||||
/* populate menu dialog with one item per subsystem */
|
||||
_menu_dialog.update(config);
|
||||
_menu_dialog.update(_config->xml());
|
||||
|
||||
/* evaluate configuration */
|
||||
|
||||
_dialog.update();
|
||||
}
|
||||
|
||||
|
@ -25,28 +25,7 @@ namespace Launcher {
|
||||
|
||||
class Subsystem_manager;
|
||||
using Decorator::string_attribute;
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Utilities **
|
||||
***************/
|
||||
|
||||
/*
|
||||
* XXX copied from 'cli_monitor/main.cc'
|
||||
*/
|
||||
static Genode::size_t ram_preservation_from_config()
|
||||
{
|
||||
Genode::Number_of_bytes ram_preservation = 0;
|
||||
try {
|
||||
Genode::Xml_node node =
|
||||
Genode::config()->xml_node().sub_node("preservation");
|
||||
|
||||
if (node.attribute("name").has_value("RAM"))
|
||||
node.attribute("quantum").value(&ram_preservation);
|
||||
} catch (...) { }
|
||||
|
||||
return ram_preservation;
|
||||
using namespace Genode;
|
||||
}
|
||||
|
||||
|
||||
@ -61,34 +40,15 @@ class Launcher::Subsystem_manager
|
||||
|
||||
private:
|
||||
|
||||
Server::Entrypoint &_ep;
|
||||
Cap_session &_cap;
|
||||
Dataspace_capability _ldso_ds;
|
||||
Entrypoint &_ep;
|
||||
Pd_session &_pd;
|
||||
|
||||
size_t const _ram_preservation;
|
||||
|
||||
struct Child : Child_base, List<Child>::Element
|
||||
{
|
||||
typedef String<128> Binary_name;
|
||||
|
||||
Child(Ram &ram,
|
||||
Label const &label,
|
||||
Binary_name const &binary,
|
||||
Cap_session &cap_session,
|
||||
size_t ram_quota,
|
||||
size_t ram_limit,
|
||||
Signal_context_capability yield_response_sig_cap,
|
||||
Signal_context_capability exit_sig_cap,
|
||||
Dataspace_capability ldso_ds)
|
||||
:
|
||||
Child_base(ram,
|
||||
label.string(),
|
||||
binary.string(),
|
||||
cap_session,
|
||||
ram_quota,
|
||||
ram_limit,
|
||||
yield_response_sig_cap,
|
||||
exit_sig_cap,
|
||||
ldso_ds)
|
||||
{ }
|
||||
template <typename... ARGS>
|
||||
Child(ARGS &&... args) : Child_base(args...) { }
|
||||
};
|
||||
|
||||
List<Child> _children;
|
||||
@ -99,10 +59,10 @@ class Launcher::Subsystem_manager
|
||||
child->try_response_to_resource_request();
|
||||
}
|
||||
|
||||
Genode::Signal_rpc_member<Subsystem_manager> _yield_broadcast_dispatcher =
|
||||
Signal_handler<Subsystem_manager> _yield_broadcast_handler =
|
||||
{ _ep, *this, &Subsystem_manager::_handle_yield_broadcast };
|
||||
|
||||
void _handle_yield_broadcast(unsigned)
|
||||
void _handle_yield_broadcast()
|
||||
{
|
||||
_try_response_to_resource_request();
|
||||
|
||||
@ -129,27 +89,27 @@ class Launcher::Subsystem_manager
|
||||
child->yield(amount, true);
|
||||
}
|
||||
|
||||
Genode::Signal_rpc_member<Subsystem_manager> _resource_avail_dispatcher =
|
||||
Signal_handler<Subsystem_manager> _resource_avail_handler =
|
||||
{ _ep, *this, &Subsystem_manager::_handle_resource_avail };
|
||||
|
||||
void _handle_resource_avail(unsigned)
|
||||
void _handle_resource_avail()
|
||||
{
|
||||
_try_response_to_resource_request();
|
||||
}
|
||||
|
||||
Genode::Signal_rpc_member<Subsystem_manager> _yield_response_dispatcher =
|
||||
Signal_handler<Subsystem_manager> _yield_response_handler =
|
||||
{ _ep, *this, &Subsystem_manager::_handle_yield_response };
|
||||
|
||||
void _handle_yield_response(unsigned)
|
||||
void _handle_yield_response()
|
||||
{
|
||||
_try_response_to_resource_request();
|
||||
}
|
||||
|
||||
Genode::Signal_context_capability _exited_child_sig_cap;
|
||||
|
||||
Ram _ram { ram_preservation_from_config(),
|
||||
_yield_broadcast_dispatcher,
|
||||
_resource_avail_dispatcher };
|
||||
Ram _ram { _ram_preservation,
|
||||
_yield_broadcast_handler,
|
||||
_resource_avail_handler };
|
||||
|
||||
static Child::Binary_name _binary_name(Xml_node subsystem)
|
||||
{
|
||||
@ -187,11 +147,11 @@ class Launcher::Subsystem_manager
|
||||
|
||||
public:
|
||||
|
||||
Subsystem_manager(Server::Entrypoint &ep, Cap_session &cap,
|
||||
Genode::Signal_context_capability exited_child_sig_cap,
|
||||
Dataspace_capability ldso_ds)
|
||||
Subsystem_manager(Genode::Entrypoint &ep, Pd_session &pd,
|
||||
size_t ram_preservation,
|
||||
Genode::Signal_context_capability exited_child_sig_cap)
|
||||
:
|
||||
_ep(ep), _cap(cap), _ldso_ds(ldso_ds),
|
||||
_ep(ep), _pd(pd), _ram_preservation(ram_preservation),
|
||||
_exited_child_sig_cap(exited_child_sig_cap)
|
||||
{ }
|
||||
|
||||
@ -213,10 +173,14 @@ class Launcher::Subsystem_manager
|
||||
|
||||
try {
|
||||
Child *child = new (env()->heap())
|
||||
Child(_ram, label, binary_name.string(), _cap,
|
||||
Child(_ram, label, binary_name.string(),
|
||||
*Genode::env()->pd_session(),
|
||||
*Genode::env()->ram_session(),
|
||||
Genode::env()->ram_session_cap(),
|
||||
*Genode::env()->rm_session(),
|
||||
ram_config.quantum, ram_config.limit,
|
||||
_yield_broadcast_dispatcher,
|
||||
_exited_child_sig_cap, _ldso_ds);
|
||||
_yield_broadcast_handler,
|
||||
_exited_child_sig_cap);
|
||||
|
||||
/* configure child */
|
||||
try {
|
||||
@ -228,8 +192,8 @@ class Launcher::Subsystem_manager
|
||||
|
||||
child->start();
|
||||
|
||||
} catch (Rom_connection::Rom_connection_failed) {
|
||||
Genode::error("binary \"", binary_name, "\" is missing");
|
||||
} catch (Parent::Service_denied) {
|
||||
Genode::error("failed to start ", binary_name);
|
||||
throw Invalid_config();
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
TARGET = launcher
|
||||
SRC_CC = main.cc
|
||||
LIBS = base server config
|
||||
LIBS = base
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
@ -118,7 +118,7 @@ struct Decorator::Main : Window_factory_base
|
||||
* and view_handle operations. Currently, these exceptions will
|
||||
* abort the decorator.
|
||||
*/
|
||||
Genode::env()->parent()->upgrade(nitpicker, "ram_quota=256K");
|
||||
nitpicker.upgrade_ram(256*1024);
|
||||
|
||||
Genode::config()->sigh(config_dispatcher);
|
||||
handle_config(0);
|
||||
|
@ -499,15 +499,11 @@ namespace Terminal {
|
||||
}
|
||||
|
||||
|
||||
extern "C" void wait_for_continue();
|
||||
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
log("--- terminal service started ---");
|
||||
wait_for_continue();
|
||||
|
||||
static Framebuffer::Connection framebuffer;
|
||||
static Input::Connection input;
|
||||
|
@ -737,7 +737,7 @@ int main(int, char **)
|
||||
|
||||
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
|
||||
|
||||
static Registry registry;
|
||||
static ::Registry registry;
|
||||
static Ncurses ncurses;
|
||||
static Status_window status_window(ncurses);
|
||||
static Menu menu(ncurses, registry, status_window);
|
||||
|
@ -352,7 +352,8 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
|
||||
|
||||
void upgrade(const char *args)
|
||||
{
|
||||
Genode::env()->parent()->upgrade(_nitpicker_session, args);
|
||||
size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
|
||||
_nitpicker_session.upgrade_ram(ram_quota);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,7 +40,8 @@ class Wm::Direct_nitpicker_session : public Genode::Rpc_object<Nitpicker::Sessio
|
||||
|
||||
void upgrade(char const *args)
|
||||
{
|
||||
Genode::env()->parent()->upgrade(_session, args);
|
||||
size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
|
||||
_session.upgrade_ram(ram_quota);
|
||||
}
|
||||
|
||||
|
||||
|
@ -737,7 +737,8 @@ class Wm::Nitpicker::Session_component : public Rpc_object<Nitpicker::Session>,
|
||||
|
||||
void upgrade(char const *args)
|
||||
{
|
||||
Genode::env()->parent()->upgrade(_session, args);
|
||||
size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
|
||||
_session.upgrade_ram(ram_quota);
|
||||
}
|
||||
|
||||
void try_to_init_real_child_views()
|
||||
|
24
repos/libports/include/acpica/acpica.h
Normal file
24
repos/libports/include/acpica/acpica.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* \brief Port of ACPICA library
|
||||
* \author Alexander Boettcher
|
||||
* \date 2016-11-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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__ACPICA__ACPICA_H_
|
||||
#define _INCLUDE__ACPICA__ACPICA_H_
|
||||
|
||||
namespace Genode {
|
||||
struct Env;
|
||||
struct Allocator;
|
||||
}
|
||||
|
||||
namespace Acpica { void init(Genode::Env &env, Genode::Allocator &heap); }
|
||||
|
||||
#endif /* _INCLUDE__ACPICA__ACPICA_H_ */
|
2
repos/libports/lib/import/import-acpica.mk
Normal file
2
repos/libports/lib/import/import-acpica.mk
Normal file
@ -0,0 +1,2 @@
|
||||
INC_DIR += $(call select_from_ports,acpica)/src/lib/acpica/source/include
|
||||
CC_OPT += -DACPI_INLINE=inline -Wno-unused-variable
|
@ -3,8 +3,6 @@ REQUIRES := x86
|
||||
ACPICA_DIR := $(call select_from_ports,acpica)/src/lib/acpica
|
||||
ACPICA_COMP := $(ACPICA_DIR)/source/components
|
||||
|
||||
INC_DIR += $(ACPICA_DIR)/source/include
|
||||
|
||||
SRC_C += debugger/dbdisply.c debugger/dbobject.c debugger/dbxface.c
|
||||
SRC_C += $(addprefix disassembler/, $(notdir $(wildcard $(ACPICA_COMP)/disassembler/*.c)))
|
||||
SRC_C += $(addprefix dispatcher/, $(notdir $(wildcard $(ACPICA_COMP)/dispatcher/*.c)))
|
||||
@ -17,10 +15,10 @@ SRC_C += $(addprefix resources/, $(notdir $(wildcard $(ACPICA_COMP)/resources/*.
|
||||
SRC_C += $(addprefix tables/, $(notdir $(wildcard $(ACPICA_COMP)/tables/*.c)))
|
||||
SRC_C += $(addprefix utilities/, $(notdir $(wildcard $(ACPICA_COMP)/utilities/*.c)))
|
||||
|
||||
SRC_CC += osl.cc iomem.cc pci.cc
|
||||
SRC_CC += scan_root.cc
|
||||
SRC_CC += osl.cc iomem.cc pci.cc scan_root.cc env.cc
|
||||
|
||||
include $(REP_DIR)/lib/import/import-acpica.mk
|
||||
|
||||
CC_OPT += -Wno-unused-function -Wno-unused-variable
|
||||
CC_C_OPT += -DACPI_LIBRARY
|
||||
|
||||
vpath %.c $(ACPICA_COMP)
|
||||
|
@ -1 +1 @@
|
||||
a3d820f28b860fdd9fd8c855f0fa2ec0b4beb859
|
||||
cd8c5b5513ba384e52be2cfc54ee4435439b57d2
|
||||
|
@ -103,7 +103,7 @@ append_platform_drv_config
|
||||
|
||||
append_if $use_nic_driver config {
|
||||
<start name="nic_drv">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<resource name="RAM" quantum="6M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
</start>}
|
||||
|
||||
|
@ -145,8 +145,9 @@ proc drivers_start_nodes { feature_arg } {
|
||||
|
||||
append_if [use_audio_drv feature] start_nodes {
|
||||
<start name="audio_drv">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides><service name="Audio_out"/></provides>
|
||||
<config/>
|
||||
</start>
|
||||
}
|
||||
|
||||
@ -177,7 +178,7 @@ proc drivers_start_nodes { feature_arg } {
|
||||
|
||||
append_if [use_nic_drv feature] start_nodes {
|
||||
<start name="nic_drv">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
</start>
|
||||
}
|
||||
|
@ -14,16 +14,19 @@
|
||||
#include <base/component.h>
|
||||
#include <base/log.h>
|
||||
#include <base/signal.h>
|
||||
#include <base/heap.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <io_port_session/connection.h>
|
||||
|
||||
#include <os/attached_rom_dataspace.h>
|
||||
#include <os/config.h>
|
||||
#include <os/reporter.h>
|
||||
|
||||
#include <util/volatile_object.h>
|
||||
#include <util/xml_node.h>
|
||||
|
||||
#include <acpica/acpica.h>
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include "acpi.h"
|
||||
#include "accommon.h"
|
||||
@ -46,7 +49,149 @@ namespace Acpica {
|
||||
#include "ec.h"
|
||||
|
||||
|
||||
static void init_acpica(Acpica::Reportstate *report) {
|
||||
struct Acpica::Statechange
|
||||
{
|
||||
Genode::Signal_handler<Acpica::Statechange> _dispatcher;
|
||||
Genode::Attached_rom_dataspace _system_state;
|
||||
bool _enable_reset;
|
||||
bool _enable_poweroff;
|
||||
|
||||
Statechange(Genode::Entrypoint &ep, bool reset, bool poweroff)
|
||||
:
|
||||
_dispatcher(ep, *this, &Statechange::state_changed),
|
||||
_system_state("system"),
|
||||
_enable_reset(reset), _enable_poweroff(poweroff)
|
||||
{
|
||||
_system_state.sigh(_dispatcher);
|
||||
|
||||
state_changed();
|
||||
}
|
||||
|
||||
void state_changed() {
|
||||
|
||||
_system_state.update();
|
||||
|
||||
if (!_system_state.is_valid()) return;
|
||||
|
||||
Genode::Xml_node system(_system_state.local_addr<char>(),
|
||||
_system_state.size());
|
||||
|
||||
Genode::String<32> state;
|
||||
system.attribute("state").value<32>(&state);
|
||||
|
||||
if (_enable_poweroff && state == "poweroff") {
|
||||
ACPI_STATUS res0 = AcpiEnterSleepStatePrep(5);
|
||||
ACPI_STATUS res1 = AcpiEnterSleepState(5);
|
||||
Genode::error("system poweroff failed - "
|
||||
"res=", Genode::Hex(res0), ",", Genode::Hex(res1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_enable_reset && state == "reset") {
|
||||
ACPI_STATUS res = AE_OK;
|
||||
try {
|
||||
res = AcpiReset();
|
||||
} catch (...) { }
|
||||
|
||||
Genode::uint64_t const space_addr = AcpiGbl_FADT.ResetRegister.Address;
|
||||
Genode::error("system reset failed - "
|
||||
"err=", res, " "
|
||||
"reset=", !!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER), " "
|
||||
"spaceid=", Genode::Hex(AcpiGbl_FADT.ResetRegister.SpaceId), " "
|
||||
"addr=", Genode::Hex(space_addr));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Acpica::Main
|
||||
{
|
||||
Genode::Env &env;
|
||||
Genode::Heap heap { env.ram(), env.rm() };
|
||||
|
||||
Genode::Attached_rom_dataspace config { env, "config" };
|
||||
|
||||
Genode::Signal_handler<Acpica::Main> sci_irq;
|
||||
Genode::Lazy_volatile_object<Genode::Irq_connection> sci_conn;
|
||||
|
||||
Acpica::Reportstate * report = nullptr;
|
||||
|
||||
static struct Irq_handler {
|
||||
UINT32 irq;
|
||||
ACPI_OSD_HANDLER handler;
|
||||
void *context;
|
||||
} irq_handler;
|
||||
|
||||
void init_acpica();
|
||||
|
||||
Main(Genode::Env &env)
|
||||
:
|
||||
env(env),
|
||||
sci_irq(env.ep(), *this, &Main::acpi_irq)
|
||||
{
|
||||
bool const enable_reset = config.xml().attribute_value("reset", false);
|
||||
bool const enable_poweroff = config.xml().attribute_value("poweroff", false);
|
||||
bool const enable_report = config.xml().attribute_value("report", false);
|
||||
bool const enable_ready = config.xml().attribute_value("acpi_ready", false);
|
||||
|
||||
if (enable_report)
|
||||
report = new (heap) Acpica::Reportstate();
|
||||
|
||||
init_acpica();
|
||||
|
||||
if (enable_report)
|
||||
report->enable();
|
||||
|
||||
if (enable_reset || enable_poweroff)
|
||||
new (heap) Acpica::Statechange(env.ep(), enable_reset,
|
||||
enable_poweroff);
|
||||
|
||||
/* setup IRQ */
|
||||
if (!irq_handler.handler) {
|
||||
Genode::warning("no IRQ handling available");
|
||||
return;
|
||||
}
|
||||
|
||||
sci_conn.construct(irq_handler.irq);
|
||||
|
||||
Genode::log("SCI IRQ: ", irq_handler.irq);
|
||||
|
||||
sci_conn->sigh(sci_irq);
|
||||
sci_conn->ack_irq();
|
||||
|
||||
if (!enable_ready)
|
||||
return;
|
||||
|
||||
/* we are ready - signal it via changing system state */
|
||||
static Genode::Reporter _system_rom { "system", "acpi_ready" };
|
||||
_system_rom.enabled(true);
|
||||
Genode::Reporter::Xml_generator xml(_system_rom, [&] () {
|
||||
xml.attribute("state", "acpi_ready");
|
||||
});
|
||||
}
|
||||
|
||||
void acpi_irq()
|
||||
{
|
||||
if (!irq_handler.handler)
|
||||
return;
|
||||
|
||||
UINT32 res = irq_handler.handler(irq_handler.context);
|
||||
|
||||
sci_conn->ack_irq();
|
||||
|
||||
AcpiOsWaitEventsComplete();
|
||||
|
||||
if (report)
|
||||
report->generate_report();
|
||||
|
||||
if (res == ACPI_INTERRUPT_HANDLED)
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Acpica::Main::init_acpica()
|
||||
{
|
||||
Acpica::init(env, heap);
|
||||
|
||||
/* enable debugging: */
|
||||
/* AcpiDbgLevel |= ACPI_LV_IO | ACPI_LV_INTERRUPTS | ACPI_LV_INIT_NAMES; */
|
||||
@ -107,7 +252,7 @@ static void init_acpica(Acpica::Reportstate *report) {
|
||||
}
|
||||
|
||||
/* note: ACPI_EVENT_PMTIMER claimed by nova kernel - not usable by us */
|
||||
Fixed * acpi_fixed = new (Genode::env()->heap()) Fixed(report);
|
||||
Fixed * acpi_fixed = new (heap) Fixed(report);
|
||||
|
||||
status = AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON,
|
||||
Fixed::handle_power_button,
|
||||
@ -144,138 +289,6 @@ static void init_acpica(Acpica::Reportstate *report) {
|
||||
}
|
||||
}
|
||||
|
||||
struct Acpica::Statechange
|
||||
{
|
||||
Genode::Signal_handler<Acpica::Statechange> _dispatcher;
|
||||
Genode::Attached_rom_dataspace _system_state;
|
||||
bool _enable_reset;
|
||||
bool _enable_poweroff;
|
||||
|
||||
Statechange(Genode::Entrypoint &ep, bool reset, bool poweroff)
|
||||
:
|
||||
_dispatcher(ep, *this, &Statechange::state_changed),
|
||||
_system_state("system"),
|
||||
_enable_reset(reset), _enable_poweroff(poweroff)
|
||||
{
|
||||
_system_state.sigh(_dispatcher);
|
||||
|
||||
state_changed();
|
||||
}
|
||||
|
||||
void state_changed() {
|
||||
|
||||
_system_state.update();
|
||||
|
||||
if (!_system_state.is_valid()) return;
|
||||
|
||||
Genode::Xml_node system(_system_state.local_addr<char>(),
|
||||
_system_state.size());
|
||||
|
||||
Genode::String<32> state;
|
||||
system.attribute("state").value<32>(&state);
|
||||
|
||||
if (_enable_poweroff && state == "poweroff") {
|
||||
ACPI_STATUS res0 = AcpiEnterSleepStatePrep(5);
|
||||
ACPI_STATUS res1 = AcpiEnterSleepState(5);
|
||||
Genode::error("system poweroff failed - "
|
||||
"res=", Genode::Hex(res0), ",", Genode::Hex(res1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_enable_reset && state == "reset") {
|
||||
ACPI_STATUS res = AE_OK;
|
||||
try {
|
||||
res = AcpiReset();
|
||||
} catch (...) { }
|
||||
|
||||
Genode::uint64_t const space_addr = AcpiGbl_FADT.ResetRegister.Address;
|
||||
Genode::error("system reset failed - "
|
||||
"err=", res, " "
|
||||
"reset=", !!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER), " "
|
||||
"spaceid=", Genode::Hex(AcpiGbl_FADT.ResetRegister.SpaceId), " "
|
||||
"addr=", Genode::Hex(space_addr));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Acpica::Main {
|
||||
|
||||
Genode::Signal_handler<Acpica::Main> _sci_irq;
|
||||
Genode::Lazy_volatile_object<Genode::Irq_connection> _sci_conn;
|
||||
|
||||
Acpica::Reportstate * _report = nullptr;
|
||||
|
||||
static struct Irq_handler {
|
||||
UINT32 irq;
|
||||
ACPI_OSD_HANDLER handler;
|
||||
void *context;
|
||||
} irq_handler;
|
||||
|
||||
Main(Genode::Env &env)
|
||||
:
|
||||
_sci_irq(env.ep(), *this, &Main::acpi_irq)
|
||||
{
|
||||
bool enable_reset = Genode::config()->xml_node().attribute_value("reset", false);
|
||||
bool enable_poweroff = Genode::config()->xml_node().attribute_value("poweroff", false);
|
||||
bool enable_report = Genode::config()->xml_node().attribute_value("report", false);
|
||||
bool enable_ready = Genode::config()->xml_node().attribute_value("acpi_ready", false);
|
||||
|
||||
if (enable_report)
|
||||
_report = new (Genode::env()->heap()) Acpica::Reportstate();
|
||||
|
||||
init_acpica(_report);
|
||||
|
||||
if (enable_report)
|
||||
_report->enable();
|
||||
|
||||
if (enable_reset || enable_poweroff)
|
||||
new (Genode::env()->heap()) Acpica::Statechange(env.ep(), enable_reset,
|
||||
enable_poweroff);
|
||||
|
||||
/* setup IRQ */
|
||||
if (!irq_handler.handler) {
|
||||
Genode::warning("no IRQ handling available");
|
||||
return;
|
||||
}
|
||||
|
||||
_sci_conn.construct(irq_handler.irq);
|
||||
|
||||
Genode::log("SCI IRQ: ", irq_handler.irq);
|
||||
|
||||
_sci_conn->sigh(_sci_irq);
|
||||
_sci_conn->ack_irq();
|
||||
|
||||
if (!enable_ready)
|
||||
return;
|
||||
|
||||
/* we are ready - signal it via changing system state */
|
||||
const char * system_file = "system";
|
||||
|
||||
static Genode::Reporter _system_rom { "system", "acpi_ready" };
|
||||
_system_rom.enabled(true);
|
||||
Genode::Reporter::Xml_generator xml(_system_rom, [&] () {
|
||||
xml.attribute("state", "acpi_ready");
|
||||
});
|
||||
}
|
||||
|
||||
void acpi_irq()
|
||||
{
|
||||
if (!irq_handler.handler)
|
||||
return;
|
||||
|
||||
UINT32 res = irq_handler.handler(irq_handler.context);
|
||||
|
||||
_sci_conn->ack_irq();
|
||||
|
||||
AcpiOsWaitEventsComplete();
|
||||
|
||||
if (_report)
|
||||
_report->generate_report();
|
||||
|
||||
if (res == ACPI_INTERRUPT_HANDLED)
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
struct Acpica::Main::Irq_handler Acpica::Main::irq_handler;
|
||||
|
||||
|
@ -1,8 +1,3 @@
|
||||
REQUIRES := x86
|
||||
|
||||
LIBS += base acpica config
|
||||
|
||||
CC_OPT += -Wno-unused-function -Wno-unused-variable
|
||||
CC_C_OPT += -DACPI_LIBRARY
|
||||
|
||||
INC_DIR += $(call select_from_ports,acpica)/src/lib/acpica/source/include
|
||||
LIBS += base acpica
|
||||
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* \brief Avplay policy
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-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 _AVPLAY_POLICY_H_
|
||||
#define _AVPLAY_POLICY_H_
|
||||
|
||||
/* Qt includes */
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include <QDomText>
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/slave.h>
|
||||
|
||||
|
||||
class Avplay_policy : public QObject, public Genode::Slave_policy
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
Genode::Service_registry &_input_in;
|
||||
Genode::Service_registry &_framebuffer_in;
|
||||
|
||||
const char *_mediafile;
|
||||
int _sdl_audio_volume;
|
||||
QByteArray _config_byte_array;
|
||||
|
||||
|
||||
const char *_config()
|
||||
{
|
||||
QDomDocument config_doc;
|
||||
|
||||
QDomElement config_node = config_doc.createElement("config");
|
||||
config_doc.appendChild(config_node);
|
||||
|
||||
QDomElement arg0_node = config_doc.createElement("arg");
|
||||
arg0_node.setAttribute("value", "avplay");
|
||||
config_node.appendChild(arg0_node);
|
||||
|
||||
QDomElement arg1_node = config_doc.createElement("arg");
|
||||
arg1_node.setAttribute("value", _mediafile);
|
||||
config_node.appendChild(arg1_node);
|
||||
|
||||
/*
|
||||
* Configure libc of avplay to direct output to LOG and to obtain
|
||||
* the mediafile from ROM.
|
||||
*/
|
||||
QDomElement libc_node = config_doc.createElement("libc");
|
||||
libc_node.setAttribute("stdout", "/dev/log");
|
||||
libc_node.setAttribute("stderr", "/dev/log");
|
||||
QDomElement libc_vfs_node = config_doc.createElement("vfs");
|
||||
QDomElement libc_vfs_dev_node = config_doc.createElement("dir");
|
||||
libc_vfs_dev_node.setAttribute("name", "dev");
|
||||
QDomElement libc_vfs_dev_log_node = config_doc.createElement("log");
|
||||
libc_vfs_dev_node.appendChild(libc_vfs_dev_log_node);
|
||||
libc_vfs_node.appendChild(libc_vfs_dev_node);
|
||||
QDomElement libc_vfs_mediafile_node = config_doc.createElement("rom");
|
||||
libc_vfs_mediafile_node.setAttribute("name", "mediafile");
|
||||
libc_vfs_node.appendChild(libc_vfs_mediafile_node);
|
||||
libc_node.appendChild(libc_vfs_node);
|
||||
config_node.appendChild(libc_node);
|
||||
|
||||
QDomElement sdl_audio_volume_node = config_doc.createElement("sdl_audio_volume");
|
||||
sdl_audio_volume_node.setAttribute("value", QString::number(_sdl_audio_volume));
|
||||
config_node.appendChild(sdl_audio_volume_node);
|
||||
|
||||
_config_byte_array = config_doc.toByteArray(4);
|
||||
|
||||
return _config_byte_array.constData();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
const char **_permitted_services() const
|
||||
{
|
||||
static const char *permitted_services[] = {
|
||||
"LOG", "RM", "ROM", "Timer", "Audio_out", 0 };
|
||||
|
||||
return permitted_services;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Avplay_policy(Genode::Rpc_entrypoint &entrypoint,
|
||||
Genode::Service_registry &input_in,
|
||||
Genode::Service_registry &framebuffer_in,
|
||||
const char *mediafile)
|
||||
: Genode::Slave_policy("avplay", entrypoint, Genode::env()->ram_session()),
|
||||
_input_in(input_in),
|
||||
_framebuffer_in(framebuffer_in),
|
||||
_mediafile(mediafile),
|
||||
_sdl_audio_volume(100)
|
||||
{
|
||||
configure(_config());
|
||||
}
|
||||
|
||||
Genode::Service *resolve_session_request(const char *service_name,
|
||||
const char *args)
|
||||
{
|
||||
if (strcmp(service_name, "Input") == 0)
|
||||
return _input_in.find(service_name);
|
||||
|
||||
if (strcmp(service_name, "Framebuffer") == 0) {
|
||||
Genode::Client client;
|
||||
return _framebuffer_in.wait_for_service(service_name, &client, name());
|
||||
}
|
||||
|
||||
return Slave_policy::resolve_session_request(service_name, args);
|
||||
}
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
void volume_changed(int value)
|
||||
{
|
||||
_sdl_audio_volume = value;
|
||||
configure(_config());
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _AVPLAY_POLICY_H_ */
|
175
repos/libports/src/app/qt5/qt_avplay/avplay_slave.h
Normal file
175
repos/libports/src/app/qt5/qt_avplay/avplay_slave.h
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* \brief Avplay slave
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2016 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 _AVPLAY_SLAVE_H_
|
||||
#define _AVPLAY_SLAVE_H_
|
||||
|
||||
/* Qt includes */
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include <QDomText>
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/component.h>
|
||||
#include <os/slave.h>
|
||||
|
||||
/* local includes */
|
||||
#include "framebuffer_service_factory.h"
|
||||
|
||||
typedef Genode::Local_service<Input::Session_component> Input_service;
|
||||
|
||||
class Avplay_slave : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
class Policy : public Genode::Slave::Policy
|
||||
{
|
||||
private:
|
||||
|
||||
Input_service &_input_service;
|
||||
Framebuffer_service_factory &_framebuffer_service_factory;
|
||||
|
||||
const char *_mediafile;
|
||||
int _sdl_audio_volume;
|
||||
QByteArray _config_byte_array;
|
||||
|
||||
|
||||
const char *_config()
|
||||
{
|
||||
QDomDocument config_doc;
|
||||
|
||||
QDomElement config_node = config_doc.createElement("config");
|
||||
config_doc.appendChild(config_node);
|
||||
|
||||
QDomElement arg0_node = config_doc.createElement("arg");
|
||||
arg0_node.setAttribute("value", "avplay");
|
||||
config_node.appendChild(arg0_node);
|
||||
|
||||
QDomElement arg1_node = config_doc.createElement("arg");
|
||||
arg1_node.setAttribute("value", _mediafile);
|
||||
config_node.appendChild(arg1_node);
|
||||
|
||||
/*
|
||||
* Configure libc of avplay to direct output to LOG and to obtain
|
||||
* the mediafile from ROM.
|
||||
*/
|
||||
QDomElement libc_node = config_doc.createElement("libc");
|
||||
libc_node.setAttribute("stdout", "/dev/log");
|
||||
libc_node.setAttribute("stderr", "/dev/log");
|
||||
QDomElement libc_vfs_node = config_doc.createElement("vfs");
|
||||
QDomElement libc_vfs_dev_node = config_doc.createElement("dir");
|
||||
libc_vfs_dev_node.setAttribute("name", "dev");
|
||||
QDomElement libc_vfs_dev_log_node = config_doc.createElement("log");
|
||||
libc_vfs_dev_node.appendChild(libc_vfs_dev_log_node);
|
||||
libc_vfs_node.appendChild(libc_vfs_dev_node);
|
||||
QDomElement libc_vfs_mediafile_node = config_doc.createElement("rom");
|
||||
libc_vfs_mediafile_node.setAttribute("name", "mediafile");
|
||||
libc_vfs_node.appendChild(libc_vfs_mediafile_node);
|
||||
libc_node.appendChild(libc_vfs_node);
|
||||
config_node.appendChild(libc_node);
|
||||
|
||||
QDomElement sdl_audio_volume_node = config_doc.createElement("sdl_audio_volume");
|
||||
sdl_audio_volume_node.setAttribute("value", QString::number(_sdl_audio_volume));
|
||||
config_node.appendChild(sdl_audio_volume_node);
|
||||
|
||||
_config_byte_array = config_doc.toByteArray(4);
|
||||
|
||||
return _config_byte_array.constData();
|
||||
}
|
||||
|
||||
static Genode::size_t _quota() { return 32*1024*1024; }
|
||||
static Name _name() { return "avplay"; }
|
||||
|
||||
protected:
|
||||
|
||||
const char **_permitted_services() const override
|
||||
{
|
||||
static const char *permitted_services[] = {
|
||||
"CPU", "LOG", "PD", "RAM", "RM", "ROM", "Timer", "Audio_out", 0 };
|
||||
|
||||
return permitted_services;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Policy(Genode::Rpc_entrypoint &entrypoint,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Ram_session_capability ram,
|
||||
Input_service &input_service,
|
||||
Framebuffer_service_factory &framebuffer_service_factory,
|
||||
char const *mediafile)
|
||||
: Genode::Slave::Policy(_name(), _name(), entrypoint, rm, ram,
|
||||
_quota()),
|
||||
_input_service(input_service),
|
||||
_framebuffer_service_factory(framebuffer_service_factory),
|
||||
_mediafile(mediafile),
|
||||
_sdl_audio_volume(100)
|
||||
{
|
||||
configure(_config());
|
||||
}
|
||||
|
||||
Genode::Service &resolve_session_request(Genode::Service::Name const &service_name,
|
||||
Genode::Session_state::Args const &args) override
|
||||
{
|
||||
if (service_name == "Input")
|
||||
return _input_service;
|
||||
|
||||
if (service_name == "Framebuffer")
|
||||
return _framebuffer_service_factory.create(args);
|
||||
|
||||
return Genode::Slave::Policy::resolve_session_request(service_name, args);
|
||||
}
|
||||
|
||||
void volume_changed(int value)
|
||||
{
|
||||
_sdl_audio_volume = value;
|
||||
configure(_config());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t);
|
||||
Genode::Rpc_entrypoint _ep;
|
||||
Policy _policy;
|
||||
Genode::Child _child;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Avplay_slave(Genode::Pd_session &pd,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Ram_session_capability ram,
|
||||
Input_service &input_service,
|
||||
Framebuffer_service_factory &framebuffer_service_factory,
|
||||
char const *mediafile)
|
||||
:
|
||||
_ep(&pd, _ep_stack_size, "avplay_ep"),
|
||||
_policy(_ep, rm, ram, input_service, framebuffer_service_factory, mediafile),
|
||||
_child(rm, _ep, _policy)
|
||||
{ }
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
void volume_changed(int value)
|
||||
{
|
||||
_policy.volume_changed(value);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _AVPLAY_SLAVE_H_ */
|
@ -24,15 +24,15 @@
|
||||
void Control_bar::_rewind()
|
||||
{
|
||||
/* mouse click at horizontal position 0 */
|
||||
_event_queue.add(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0));
|
||||
_event_queue.add(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 0));
|
||||
_input.submit(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0));
|
||||
_input.submit(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
void Control_bar::_pause_resume()
|
||||
{
|
||||
_event_queue.add(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
_event_queue.add(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
_input.submit(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
_input.submit(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
|
||||
_playing = !_playing;
|
||||
if (_playing)
|
||||
@ -51,9 +51,9 @@ void Control_bar::_stop()
|
||||
}
|
||||
|
||||
|
||||
Control_bar::Control_bar(Input::Event_queue &event_queue)
|
||||
Control_bar::Control_bar(Input::Session_component &input)
|
||||
:
|
||||
_event_queue(event_queue), _playing(true)
|
||||
_input(input), _playing(true)
|
||||
{
|
||||
update_style_id(_play_pause_button, "play");
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <qoost/qmember.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/event_queue.h>
|
||||
#include <input/component.h>
|
||||
|
||||
struct Play_pause_button : QPushButton { Q_OBJECT };
|
||||
struct Stop_button : QPushButton { Q_OBJECT };
|
||||
@ -36,7 +36,7 @@ class Control_bar : public Compound_widget<QWidget, QHBoxLayout>
|
||||
|
||||
private:
|
||||
|
||||
Input::Event_queue &_event_queue;
|
||||
Input::Session_component &_input;
|
||||
|
||||
QMember<Play_pause_button> _play_pause_button;
|
||||
QMember<Stop_button> _stop_button;
|
||||
@ -54,7 +54,7 @@ class Control_bar : public Compound_widget<QWidget, QHBoxLayout>
|
||||
|
||||
public:
|
||||
|
||||
Control_bar(Input::Event_queue &event_queue);
|
||||
Control_bar(Input::Session_component &input);
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* \brief Filter framebuffer policy
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-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 _FILTER_FRAMEBUFFER_POLICY_H_
|
||||
#define _FILTER_FRAMEBUFFER_POLICY_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
#include <os/slave.h>
|
||||
|
||||
|
||||
class Filter_framebuffer_policy : public Genode::Slave_policy
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Service_registry &_framebuffer_in;
|
||||
Genode::Service_registry &_framebuffer_out;
|
||||
|
||||
protected:
|
||||
|
||||
const char **_permitted_services() const
|
||||
{
|
||||
static const char *permitted_services[] = {
|
||||
"LOG", "RM", "ROM", "Timer", 0 };
|
||||
|
||||
return permitted_services;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Filter_framebuffer_policy(const char *name,
|
||||
Genode::Rpc_entrypoint &entrypoint,
|
||||
Genode::Service_registry &framebuffer_in,
|
||||
Genode::Service_registry &framebuffer_out)
|
||||
: Genode::Slave_policy(name, entrypoint, Genode::env()->ram_session()),
|
||||
_framebuffer_in(framebuffer_in),
|
||||
_framebuffer_out(framebuffer_out) { }
|
||||
|
||||
Genode::Service *resolve_session_request(const char *service_name,
|
||||
const char *args)
|
||||
{
|
||||
if (strcmp(service_name, "Framebuffer") == 0) {
|
||||
Genode::Client client;
|
||||
return _framebuffer_in.wait_for_service(service_name, &client, name());
|
||||
}
|
||||
|
||||
return Slave_policy::resolve_session_request(service_name, args);
|
||||
}
|
||||
|
||||
bool announce_service(const char *name,
|
||||
Genode::Root_capability root,
|
||||
Genode::Allocator *alloc,
|
||||
Genode::Server *server)
|
||||
{
|
||||
if (strcmp(name, "Framebuffer") == 0) {
|
||||
_framebuffer_out.insert(new (alloc) Genode::Child_service(name, root, server));
|
||||
return true;
|
||||
}
|
||||
|
||||
return Slave_policy::announce_service(name, root, alloc, server);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* _FILTER_FRAMEBUFFER_POLICY_H_ */
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* \brief Filter framebuffer policy
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2016 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 _FILTER_FRAMEBUFFER_SLAVE_H_
|
||||
#define _FILTER_FRAMEBUFFER_SLAVE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
#include <os/slave.h>
|
||||
|
||||
/* local includes */
|
||||
#include "framebuffer_service_factory.h"
|
||||
|
||||
|
||||
class Filter_framebuffer_slave
|
||||
{
|
||||
private:
|
||||
|
||||
class Policy : public Genode::Slave::Policy
|
||||
{
|
||||
private:
|
||||
|
||||
Framebuffer_service_factory &_framebuffer_service_factory;
|
||||
|
||||
protected:
|
||||
|
||||
const char **_permitted_services() const
|
||||
{
|
||||
static const char *permitted_services[] = {
|
||||
"CPU", "LOG", "PD", "RAM", "RM", "ROM", "Timer", 0 };
|
||||
|
||||
return permitted_services;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Policy(Genode::Rpc_entrypoint &entrypoint,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Ram_session_capability ram,
|
||||
Name const &name,
|
||||
size_t quota,
|
||||
Framebuffer_service_factory &framebuffer_service_factory)
|
||||
: Genode::Slave::Policy(name, name, entrypoint, rm, ram, quota),
|
||||
_framebuffer_service_factory(framebuffer_service_factory) { }
|
||||
|
||||
Genode::Service &resolve_session_request(Genode::Service::Name const &service_name,
|
||||
Genode::Session_state::Args const &args) override
|
||||
{
|
||||
if (service_name == "Framebuffer")
|
||||
return _framebuffer_service_factory.create(args);
|
||||
|
||||
return Genode::Slave::Policy::resolve_session_request(service_name, args);
|
||||
}
|
||||
};
|
||||
|
||||
Genode::size_t const _ep_stack_size = 2*1024*sizeof(Genode::addr_t);
|
||||
Genode::Rpc_entrypoint _ep;
|
||||
Policy _policy;
|
||||
Genode::Child _child;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Filter_framebuffer_slave(Genode::Pd_session &pd,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Ram_session_capability ram,
|
||||
Genode::Slave::Policy::Name const &name,
|
||||
size_t quota,
|
||||
Framebuffer_service_factory &framebuffer_service_factory)
|
||||
:
|
||||
_ep(&pd, _ep_stack_size, "filter_framebuffer_ep"),
|
||||
_policy(_ep, rm, ram, name, quota, framebuffer_service_factory),
|
||||
_child(rm, _ep, _policy)
|
||||
{ }
|
||||
|
||||
Genode::Slave::Policy &policy() { return _policy; }
|
||||
};
|
||||
|
||||
#endif /* _FILTER_FRAMEBUFFER_SLAVE_H_ */
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* \brief Framebuffer root
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-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 _FRAMEBUFFER_ROOT_H_
|
||||
#define _FRAMEBUFFER_ROOT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <root/component.h>
|
||||
|
||||
#include "framebuffer_session_component.h"
|
||||
|
||||
namespace Framebuffer {
|
||||
|
||||
/**
|
||||
* Shortcut for single-client root component
|
||||
*/
|
||||
typedef Genode::Root_component<Session_component, Genode::Single_client> Root_component;
|
||||
|
||||
|
||||
class Root : public Root_component
|
||||
{
|
||||
private:
|
||||
|
||||
QNitpickerViewWidget &_nitpicker_view_widget;
|
||||
int _max_width;
|
||||
int _max_height;
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args)
|
||||
{
|
||||
return new (md_alloc())
|
||||
Session_component(args, _nitpicker_view_widget,
|
||||
_max_width, _max_height);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Rpc_entrypoint *session_ep,
|
||||
Genode::Allocator *md_alloc,
|
||||
QNitpickerViewWidget &nitpicker_view_widget,
|
||||
int max_width = 0,
|
||||
int max_height = 0)
|
||||
: Root_component(session_ep, md_alloc),
|
||||
_nitpicker_view_widget(nitpicker_view_widget),
|
||||
_max_width(max_width),
|
||||
_max_height(max_height) { }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _FRAMEBUFFER_ROOT_H_ */
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* \brief Framebuffer service factory
|
||||
* \author Christian Prochaska
|
||||
* \date 2016-11-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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 _FRAMEBUFFER_SERVICE_FACTORY_H_
|
||||
#define _FRAMEBUFFER_SERVICE_FACTORY_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
#include <os/slave.h>
|
||||
#include <framebuffer_session/connection.h>
|
||||
#include <os/single_session_service.h>
|
||||
#include <nitpicker_session/connection.h>
|
||||
|
||||
/* Qt includes */
|
||||
#include <qnitpickerplatformwindow.h>
|
||||
#include <qnitpickerviewwidget/qnitpickerviewwidget.h>
|
||||
|
||||
|
||||
struct Framebuffer_service_factory
|
||||
{
|
||||
virtual Genode::Service &create(Genode::Session_state::Args const &args) = 0;
|
||||
|
||||
typedef Genode::Single_session_service<Framebuffer::Session> Session_service;
|
||||
};
|
||||
|
||||
|
||||
class Nitpicker_framebuffer_service_factory : public Framebuffer_service_factory
|
||||
{
|
||||
private:
|
||||
|
||||
Nitpicker::Connection _nitpicker;
|
||||
|
||||
Session_service _service;
|
||||
|
||||
QNitpickerViewWidget &_nitpicker_view_widget;
|
||||
int _max_width;
|
||||
int _max_height;
|
||||
|
||||
int _limited_size(int requested_size, int max_size)
|
||||
{
|
||||
if (requested_size == 0)
|
||||
return max_size;
|
||||
else
|
||||
return (max_size > 0) ? Genode::min(requested_size, max_size) : requested_size;
|
||||
}
|
||||
|
||||
static inline long _session_arg(Genode::Session_state::Args const &args, const char *key)
|
||||
{
|
||||
return Genode::Arg_string::find_arg(args.string(), key).long_value(0);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Nitpicker_framebuffer_service_factory(Genode::Env &env,
|
||||
QNitpickerViewWidget &nitpicker_view_widget,
|
||||
int max_width = 0,
|
||||
int max_height = 0)
|
||||
: _nitpicker(env),
|
||||
_service(_nitpicker.framebuffer_session()),
|
||||
_nitpicker_view_widget(nitpicker_view_widget),
|
||||
_max_width(max_width), _max_height(max_height)
|
||||
{ }
|
||||
|
||||
Genode::Service &create(Genode::Session_state::Args const &args)
|
||||
{
|
||||
Framebuffer::Mode const
|
||||
mode(_limited_size(_session_arg(args, "fb_width"), _max_width),
|
||||
_limited_size(_session_arg(args, "fb_height"), _max_height),
|
||||
_nitpicker.mode().format());
|
||||
_nitpicker.buffer(mode, false);
|
||||
|
||||
QNitpickerPlatformWindow *platform_window =
|
||||
dynamic_cast<QNitpickerPlatformWindow*>(_nitpicker_view_widget
|
||||
.window()->windowHandle()->handle());
|
||||
|
||||
Nitpicker::Session::View_handle parent_view_handle =
|
||||
_nitpicker.view_handle(platform_window->view_cap());
|
||||
|
||||
Nitpicker::Session::View_handle nitpicker_view_handle =
|
||||
_nitpicker.create_view(parent_view_handle);
|
||||
|
||||
_nitpicker.release_view_handle(parent_view_handle);
|
||||
|
||||
Framebuffer::Session_client framebuffer(_nitpicker.framebuffer_session());
|
||||
|
||||
Framebuffer::Mode framebuffer_mode = framebuffer.mode();
|
||||
_nitpicker_view_widget.setNitpickerView(&_nitpicker,
|
||||
nitpicker_view_handle,
|
||||
0, 0,
|
||||
framebuffer_mode.width(),
|
||||
framebuffer_mode.height());
|
||||
return _service.service();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Filter_framebuffer_service_factory : public Framebuffer_service_factory
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Genode::Slave::Connection<Framebuffer::Connection> Framebuffer_connection;
|
||||
|
||||
Genode::Slave::Policy &_policy;
|
||||
|
||||
Framebuffer_connection *_slave_connection { nullptr };
|
||||
Session_service *_service { nullptr };
|
||||
|
||||
public:
|
||||
|
||||
Filter_framebuffer_service_factory(Genode::Slave::Policy &policy)
|
||||
: _policy(policy)
|
||||
{ }
|
||||
|
||||
~Filter_framebuffer_service_factory()
|
||||
{
|
||||
delete _service;
|
||||
delete _slave_connection;
|
||||
}
|
||||
|
||||
Genode::Service &create(Genode::Session_state::Args const &args)
|
||||
{
|
||||
_slave_connection = new Framebuffer_connection(_policy, args);
|
||||
|
||||
_service = new Session_service(*_slave_connection);
|
||||
|
||||
return _service->service();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* _FRAMEBUFFER_SERVICE_FACTORY_H_ */
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* \brief Framebuffer session component
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <nitpicker_session/client.h>
|
||||
#include <util/arg_string.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
#include "framebuffer_session_component.h"
|
||||
#include <qnitpickerplatformwindow.h>
|
||||
|
||||
namespace Framebuffer {
|
||||
|
||||
|
||||
int Session_component::_limited_size(int requested_size, int max_size)
|
||||
{
|
||||
if (requested_size == 0)
|
||||
return max_size;
|
||||
else
|
||||
return (max_size > 0) ? Genode::min(requested_size, max_size) : requested_size;
|
||||
}
|
||||
|
||||
|
||||
static inline long session_arg(const char *arg, const char *key)
|
||||
{
|
||||
return Genode::Arg_string::find_arg(arg, key).long_value(0);
|
||||
}
|
||||
|
||||
|
||||
Session_component::Session_component(const char *args,
|
||||
QNitpickerViewWidget &nitpicker_view_widget,
|
||||
int max_width,
|
||||
int max_height)
|
||||
:
|
||||
_framebuffer(_nitpicker.framebuffer_session())
|
||||
{
|
||||
Framebuffer::Mode const
|
||||
mode(_limited_size(session_arg(args, "fb_width"), max_width),
|
||||
_limited_size(session_arg(args, "fb_height"), max_height),
|
||||
_nitpicker.mode().format());
|
||||
_nitpicker.buffer(mode, false);
|
||||
|
||||
QNitpickerPlatformWindow *platform_window =
|
||||
dynamic_cast<QNitpickerPlatformWindow*>(nitpicker_view_widget
|
||||
.window()->windowHandle()->handle());
|
||||
|
||||
Nitpicker::Session::View_handle parent_view_handle =
|
||||
_nitpicker.view_handle(platform_window->view_cap());
|
||||
|
||||
Nitpicker::Session::View_handle nitpicker_view_handle =
|
||||
_nitpicker.create_view(parent_view_handle);
|
||||
|
||||
_nitpicker.release_view_handle(parent_view_handle);
|
||||
|
||||
Mode _mode = _framebuffer.mode();
|
||||
nitpicker_view_widget.setNitpickerView(&_nitpicker,
|
||||
nitpicker_view_handle,
|
||||
0, 0,
|
||||
_mode.width(),
|
||||
_mode.height());
|
||||
}
|
||||
|
||||
|
||||
Genode::Dataspace_capability Session_component::dataspace()
|
||||
{
|
||||
return _framebuffer.dataspace();
|
||||
}
|
||||
|
||||
|
||||
Mode Session_component::mode() const
|
||||
{
|
||||
return _framebuffer.mode();
|
||||
}
|
||||
|
||||
|
||||
void Session_component::mode_sigh(Genode::Signal_context_capability sigh_cap)
|
||||
{
|
||||
_framebuffer.mode_sigh(sigh_cap);
|
||||
}
|
||||
|
||||
|
||||
void Session_component::sync_sigh(Genode::Signal_context_capability sigh_cap)
|
||||
{
|
||||
_framebuffer.sync_sigh(sigh_cap);
|
||||
}
|
||||
|
||||
void Session_component::refresh(int x, int y, int w, int h)
|
||||
{
|
||||
_framebuffer.refresh(x, y, w, h);
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* \brief Framebuffer session component
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-04-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-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 _FRAMEBUFFER_SESSION_COMPONENT_H_
|
||||
#define _FRAMEBUFFER_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/rpc_server.h>
|
||||
#include <framebuffer_session/client.h>
|
||||
#include <nitpicker_session/connection.h>
|
||||
|
||||
/* Qt includes */
|
||||
#include <qnitpickerviewwidget/qnitpickerviewwidget.h>
|
||||
|
||||
|
||||
namespace Framebuffer {
|
||||
|
||||
class Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
private:
|
||||
|
||||
Nitpicker::Connection _nitpicker;
|
||||
Session_client _framebuffer;
|
||||
|
||||
int _limited_size(int requested_size, int max_size);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(const char *args,
|
||||
QNitpickerViewWidget &nitpicker_view_widget,
|
||||
int max_width = 0,
|
||||
int max_height = 0);
|
||||
|
||||
Genode::Dataspace_capability dataspace() override;
|
||||
Mode mode() const override;
|
||||
void mode_sigh(Genode::Signal_context_capability) override;
|
||||
void sync_sigh(Genode::Signal_context_capability) override;
|
||||
void refresh(int, int, int, int) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _FRAMEBUFFER_SESSION_COMPONENT_H_ */
|
@ -18,7 +18,7 @@
|
||||
#include "main_window.h"
|
||||
|
||||
/* Genode includes */
|
||||
#include <rom_session/connection.h>
|
||||
#include <base/component.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
|
||||
@ -35,15 +35,18 @@ static inline void load_stylesheet()
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
extern int genode_argc;
|
||||
extern char **genode_argv;
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QApplication app(genode_argc, genode_argv);
|
||||
|
||||
load_stylesheet();
|
||||
|
||||
QMember<Main_window> main_window;
|
||||
QMember<Main_window> main_window(env);
|
||||
|
||||
main_window->show();
|
||||
|
||||
return app.exec();
|
||||
app.exec();
|
||||
}
|
||||
|
@ -12,9 +12,7 @@
|
||||
*/
|
||||
|
||||
/* qt_avplay includes */
|
||||
#include "avplay_policy.h"
|
||||
#include "filter_framebuffer_policy.h"
|
||||
#include "framebuffer_root.h"
|
||||
#include "filter_framebuffer_slave.h"
|
||||
#include "main_window.h"
|
||||
|
||||
|
||||
@ -24,22 +22,19 @@ using namespace Genode;
|
||||
struct Framebuffer_filter
|
||||
{
|
||||
enum { MAX_FILTER_NAME_SIZE = 32 };
|
||||
char name[MAX_FILTER_NAME_SIZE];
|
||||
Genode::Number_of_bytes ram_quota;
|
||||
|
||||
Service_registry *framebuffer_out_registry;
|
||||
Rpc_entrypoint *ep;
|
||||
Filter_framebuffer_policy *policy;
|
||||
Slave *slave;
|
||||
char name[MAX_FILTER_NAME_SIZE];
|
||||
Genode::Number_of_bytes ram_quota;
|
||||
Filter_framebuffer_slave *slave;
|
||||
};
|
||||
|
||||
|
||||
Main_window::Main_window()
|
||||
Main_window::Main_window(Genode::Env &env)
|
||||
:
|
||||
_control_bar(_input_session.event_queue())
|
||||
_env(env),
|
||||
_control_bar(_input_session_component)
|
||||
{
|
||||
_input_registry.insert(&_input_service);
|
||||
_ep.manage(&_input_root);
|
||||
_input_session_component.event_queue().enabled(true);
|
||||
_ep.manage(&_input_session_component);
|
||||
|
||||
/* find out which filtering framebuffer services to start and sort them in reverse order */
|
||||
|
||||
@ -55,49 +50,33 @@ Main_window::Main_window()
|
||||
}
|
||||
} catch (Xml_node::Nonexistent_sub_node) { }
|
||||
|
||||
Framebuffer_service_factory *framebuffer_service_factory =
|
||||
&_nitpicker_framebuffer_service_factory;
|
||||
|
||||
/* start the filtering framebuffer services */
|
||||
|
||||
Service_registry *framebuffer_in_registry = &_nitpicker_framebuffer_registry;
|
||||
|
||||
Q_FOREACH(Framebuffer_filter *framebuffer_filter, framebuffer_filters) {
|
||||
framebuffer_filter->framebuffer_out_registry = new Service_registry;
|
||||
framebuffer_filter->ep = new Rpc_entrypoint(&_cap, STACK_SIZE, "filter_fb_ep");
|
||||
framebuffer_filter->policy = new Filter_framebuffer_policy(framebuffer_filter->name,
|
||||
*framebuffer_filter->ep,
|
||||
*framebuffer_in_registry,
|
||||
*framebuffer_filter->framebuffer_out_registry);
|
||||
framebuffer_filter->slave = new Slave(*framebuffer_filter->ep,
|
||||
*framebuffer_filter->policy,
|
||||
framebuffer_filter->ram_quota);
|
||||
framebuffer_in_registry = framebuffer_filter->framebuffer_out_registry;
|
||||
framebuffer_filter->slave = new Filter_framebuffer_slave(_env.pd(), _env.rm(),
|
||||
_env.ram_session_cap(),
|
||||
framebuffer_filter->name,
|
||||
framebuffer_filter->ram_quota,
|
||||
*framebuffer_service_factory);
|
||||
framebuffer_service_factory =
|
||||
new Filter_framebuffer_service_factory(framebuffer_filter->slave->policy());
|
||||
}
|
||||
|
||||
Rpc_entrypoint *local_framebuffer_ep = framebuffer_filters.isEmpty() ?
|
||||
&_ep :
|
||||
framebuffer_filters.at(0)->ep;
|
||||
|
||||
static Framebuffer::Root framebuffer_root(local_framebuffer_ep, env()->heap(), *_avplay_widget, 640, 480);
|
||||
static Local_service framebuffer_service(Framebuffer::Session::service_name(), &framebuffer_root);
|
||||
_nitpicker_framebuffer_registry.insert(&framebuffer_service);
|
||||
|
||||
/* obtain dynamic linker */
|
||||
|
||||
Dataspace_capability ldso_ds;
|
||||
try {
|
||||
static Rom_connection rom("ld.lib.so");
|
||||
ldso_ds = rom.dataspace();
|
||||
} catch (...) { }
|
||||
|
||||
/* start avplay */
|
||||
|
||||
static Avplay_policy avplay_policy(_ep, _input_registry, *framebuffer_in_registry, _mediafile_name.buf);
|
||||
static Genode::Slave avplay_slave(_ep, avplay_policy, 32*1024*1024,
|
||||
env()->ram_session_cap(), ldso_ds);
|
||||
|
||||
/* add widgets to layout */
|
||||
|
||||
_layout->addWidget(_avplay_widget);
|
||||
_layout->addWidget(_control_bar);
|
||||
|
||||
connect(_control_bar, SIGNAL(volume_changed(int)), &avplay_policy, SLOT(volume_changed(int)));
|
||||
/* start avplay */
|
||||
|
||||
Avplay_slave *avplay_slave = new Avplay_slave(_env.pd(), _env.rm(),
|
||||
_env.ram_session_cap(),
|
||||
_input_service,
|
||||
*framebuffer_service_factory,
|
||||
_mediafile_name.buf);
|
||||
|
||||
connect(_control_bar, SIGNAL(volume_changed(int)), avplay_slave, SLOT(volume_changed(int)));
|
||||
}
|
||||
|
@ -31,8 +31,9 @@
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include "avplay_slave.h"
|
||||
#include "control_bar.h"
|
||||
|
||||
#include "framebuffer_service_factory.h"
|
||||
|
||||
class Main_window : public Compound_widget<QWidget, QVBoxLayout>
|
||||
{
|
||||
@ -56,25 +57,29 @@ class Main_window : public Compound_widget<QWidget, QVBoxLayout>
|
||||
Genode::warning("no <mediafile> config node found, using \"mediafile\"");
|
||||
}
|
||||
}
|
||||
} _mediafile_name;
|
||||
};
|
||||
|
||||
enum { STACK_SIZE = 2*sizeof(Genode::addr_t)*1024 };
|
||||
Genode::Cap_connection _cap;
|
||||
Genode::Rpc_entrypoint _ep { &_cap, STACK_SIZE, "avplay_ep" };
|
||||
Genode::Service_registry _input_registry;
|
||||
Genode::Service_registry _nitpicker_framebuffer_registry;
|
||||
Genode::Env &_env;
|
||||
|
||||
Input::Session_component _input_session;
|
||||
Input::Root_component _input_root { _ep, _input_session };
|
||||
Mediafile_name _mediafile_name;
|
||||
|
||||
Genode::Local_service _input_service { Input::Session::service_name(), &_input_root };
|
||||
QMember<QNitpickerViewWidget> _avplay_widget;
|
||||
QMember<Control_bar> _control_bar;
|
||||
|
||||
QMember<QNitpickerViewWidget> _avplay_widget;
|
||||
QMember<Control_bar> _control_bar;
|
||||
Genode::size_t const _ep_stack_size { 2*sizeof(Genode::addr_t)*1024 };
|
||||
Genode::Rpc_entrypoint _ep { &_env.pd(), _ep_stack_size, "avplay_ep" };
|
||||
|
||||
Nitpicker_framebuffer_service_factory _nitpicker_framebuffer_service_factory { _env,
|
||||
*_avplay_widget,
|
||||
640, 480 };
|
||||
|
||||
Input::Session_component _input_session_component { _env, _env.ram() };
|
||||
Input_service::Single_session_factory _input_factory { _input_session_component };
|
||||
Input_service _input_service { _input_factory };
|
||||
|
||||
public:
|
||||
|
||||
Main_window();
|
||||
Main_window(Genode::Env &env);
|
||||
};
|
||||
|
||||
#endif /* _MAIN_WINDOW_H_ */
|
||||
|
@ -1,11 +1,10 @@
|
||||
TEMPLATE = app
|
||||
TARGET = qt_avplay
|
||||
QT = core gui xml
|
||||
HEADERS = avplay_policy.h \
|
||||
HEADERS = avplay_slave.h \
|
||||
control_bar.h \
|
||||
main_window.h
|
||||
SOURCES = control_bar.cpp \
|
||||
framebuffer_session_component.cc \
|
||||
main.cpp \
|
||||
main_window.cpp
|
||||
RESOURCES = style.qrc
|
||||
|
@ -6,14 +6,15 @@
|
||||
|
||||
#include "child_entry.h"
|
||||
|
||||
Child_entry::Child_entry(const char *name, int quota_kb, int max_quota_kb,
|
||||
Launchpad *launchpad, Launchpad_child *launchpad_child,
|
||||
Child_entry::Child_entry(Launchpad_child::Name const &name, int quota_kb,
|
||||
int max_quota_kb, Launchpad &launchpad,
|
||||
Launchpad_child &launchpad_child,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), _launchpad(launchpad), _launchpad_child(launchpad_child)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
ui.nameLabel->setText(name);
|
||||
ui.nameLabel->setText(name.string());
|
||||
ui.quotaBar->setMaximum(max_quota_kb);
|
||||
ui.quotaBar->setValue(quota_kb);
|
||||
}
|
||||
@ -21,5 +22,5 @@ Child_entry::Child_entry(const char *name, int quota_kb, int max_quota_kb,
|
||||
|
||||
void Child_entry::on_exitButton_clicked()
|
||||
{
|
||||
_launchpad->exit_child(_launchpad_child);
|
||||
_launchpad.exit_child(_launchpad_child);
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ class Child_entry : public QWidget
|
||||
|
||||
Ui::Child_entryClass ui;
|
||||
|
||||
Launchpad *_launchpad;
|
||||
Launchpad_child *_launchpad_child;
|
||||
Launchpad &_launchpad;
|
||||
Launchpad_child &_launchpad_child;
|
||||
|
||||
private slots:
|
||||
|
||||
@ -37,8 +37,9 @@ class Child_entry : public QWidget
|
||||
|
||||
public:
|
||||
|
||||
Child_entry(const char *name, int quota_kb, int max_quota_kb,
|
||||
Launchpad *launchpad, Launchpad_child *launchpad_child,
|
||||
Child_entry(Launchpad_child::Name const &name, int quota_kb,
|
||||
int max_quota_kb, Launchpad &launchpad,
|
||||
Launchpad_child &launchpad_child,
|
||||
QWidget *parent = 0);
|
||||
};
|
||||
|
||||
|
@ -6,19 +6,20 @@
|
||||
|
||||
#include "launch_entry.h"
|
||||
|
||||
Launch_entry::Launch_entry(const char *filename, unsigned long default_quota,
|
||||
Launch_entry::Launch_entry(Launchpad_child::Name const &prg_name,
|
||||
unsigned long default_quota,
|
||||
unsigned long max_quota,
|
||||
Genode::Dataspace_capability config_ds,
|
||||
Launchpad *launchpad,
|
||||
Genode::Dataspace_capability config_ds,
|
||||
QWidget *parent)
|
||||
: QWidget(parent),
|
||||
_filename(filename),
|
||||
_config_ds(config_ds),
|
||||
_launchpad(launchpad)
|
||||
_prg_name(prg_name),
|
||||
_launchpad(launchpad),
|
||||
_config_ds(config_ds)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
ui.launchButton->setText(filename);
|
||||
ui.launchButton->setText(prg_name.string());
|
||||
|
||||
ui.quotaDial->setMaximum(max_quota);
|
||||
ui.quotaDial->setSingleStep(max_quota / 100);
|
||||
@ -28,7 +29,7 @@ Launch_entry::Launch_entry(const char *filename, unsigned long default_quota,
|
||||
|
||||
void Launch_entry::on_launchButton_clicked()
|
||||
{
|
||||
_launchpad->start_child(_filename,
|
||||
_launchpad->start_child(_prg_name,
|
||||
1024 * ui.quotaDial->value(),
|
||||
_config_ds);
|
||||
}
|
||||
|
@ -28,9 +28,9 @@ class Launch_entry : public QWidget
|
||||
|
||||
Ui::Launch_entryClass ui;
|
||||
|
||||
const char *_filename;
|
||||
Genode::Dataspace_capability _config_ds;
|
||||
Launchpad *_launchpad;
|
||||
Launchpad_child::Name const &_prg_name;
|
||||
Launchpad *_launchpad;
|
||||
Genode::Dataspace_capability _config_ds;
|
||||
|
||||
private slots:
|
||||
|
||||
@ -38,11 +38,11 @@ class Launch_entry : public QWidget
|
||||
|
||||
public:
|
||||
|
||||
Launch_entry(const char *filename,
|
||||
Launch_entry(Launchpad_child::Name const &prg_name,
|
||||
unsigned long default_quota,
|
||||
unsigned long max_quota,
|
||||
Genode::Dataspace_capability config_ds,
|
||||
Launchpad *launchpad,
|
||||
Genode::Dataspace_capability config_ds,
|
||||
QWidget *parent = 0);
|
||||
};
|
||||
|
||||
|
@ -12,14 +12,57 @@
|
||||
#include <QApplication>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/component.h>
|
||||
#include <base/env.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
extern int genode_argc;
|
||||
extern char **genode_argv;
|
||||
|
||||
namespace Qt_launchpad_namespace {
|
||||
struct Local_env;
|
||||
using namespace Genode;
|
||||
}
|
||||
|
||||
struct Qt_launchpad_namespace::Local_env : Genode::Env
|
||||
{
|
||||
static QApplication a(argc, argv);
|
||||
Genode::Env &genode_env;
|
||||
|
||||
static Qt_launchpad launchpad(Genode::env()->ram_session()->quota());
|
||||
Genode::Entrypoint local_ep { genode_env,
|
||||
2*1024*sizeof(addr_t),
|
||||
"qt_launchpad_ep" };
|
||||
|
||||
Local_env(Env &genode_env) : genode_env(genode_env) { }
|
||||
|
||||
Parent &parent() { return genode_env.parent(); }
|
||||
Ram_session &ram() { return genode_env.ram(); }
|
||||
Cpu_session &cpu() { return genode_env.cpu(); }
|
||||
Region_map &rm() { return genode_env.rm(); }
|
||||
Pd_session &pd() { return genode_env.pd(); }
|
||||
Entrypoint &ep() { return local_ep; }
|
||||
Ram_session_capability ram_session_cap() { return genode_env.ram_session_cap(); }
|
||||
Cpu_session_capability cpu_session_cap() { return genode_env.cpu_session_cap(); }
|
||||
Pd_session_capability pd_session_cap() { return genode_env.pd_session_cap(); }
|
||||
Id_space<Parent::Client> &id_space() { return genode_env.id_space(); }
|
||||
|
||||
Session_capability session(Parent::Service_name const &service_name,
|
||||
Parent::Client::Id id,
|
||||
Parent::Session_args const &session_args,
|
||||
Affinity const &affinity)
|
||||
{ return genode_env.session(service_name, id, session_args, affinity); }
|
||||
|
||||
void upgrade(Parent::Client::Id id, Parent::Upgrade_args const &args)
|
||||
{ return genode_env.upgrade(id, args); }
|
||||
|
||||
void close(Parent::Client::Id id) { return genode_env.close(id); }
|
||||
};
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
static Qt_launchpad_namespace::Local_env local_env(env);
|
||||
|
||||
static QApplication a(genode_argc, genode_argv);
|
||||
|
||||
static Qt_launchpad launchpad(local_env, env.ram().avail());
|
||||
|
||||
try {
|
||||
launchpad.process_config();
|
||||
@ -30,7 +73,5 @@ int main(int argc, char *argv[])
|
||||
|
||||
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
|
||||
|
||||
int const result = a.exec();
|
||||
|
||||
return result;
|
||||
a.exec();
|
||||
}
|
||||
|
@ -11,8 +11,9 @@
|
||||
#include "launch_entry.h"
|
||||
#include "child_entry.h"
|
||||
|
||||
Qt_launchpad::Qt_launchpad(unsigned long initial_quota, QWidget *parent)
|
||||
: QMainWindow(parent), Launchpad(initial_quota)
|
||||
Qt_launchpad::Qt_launchpad(Genode::Env &env, unsigned long initial_quota,
|
||||
QWidget *parent)
|
||||
: QMainWindow(parent), Launchpad(env, initial_quota)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
@ -72,40 +73,40 @@ void Qt_launchpad::quota(unsigned long quota)
|
||||
}
|
||||
|
||||
|
||||
void Qt_launchpad::add_launcher(const char *filename,
|
||||
void Qt_launchpad::add_launcher(Launchpad_child::Name const &binary_name,
|
||||
unsigned long default_quota,
|
||||
Genode::Dataspace_capability config_ds)
|
||||
{
|
||||
Launch_entry *launch_entry = new Launch_entry(filename,
|
||||
Launch_entry *launch_entry = new Launch_entry(binary_name,
|
||||
default_quota / 1024,
|
||||
initial_quota() / 1024,
|
||||
config_ds,
|
||||
this);
|
||||
this,
|
||||
config_ds);
|
||||
launcherDockWidgetContents->layout()->addWidget(launch_entry);
|
||||
launch_entry->show();
|
||||
launcherDockWidgetContents->adjustSize();
|
||||
}
|
||||
|
||||
|
||||
void Qt_launchpad::add_child(const char *unique_name,
|
||||
void Qt_launchpad::add_child(Launchpad_child::Name const &name,
|
||||
unsigned long quota,
|
||||
Launchpad_child *launchpad_child,
|
||||
Genode::Allocator *alloc)
|
||||
Launchpad_child &launchpad_child,
|
||||
Genode::Allocator &alloc)
|
||||
{
|
||||
Child_entry *child_entry = new Child_entry(unique_name, quota / 1024,
|
||||
Child_entry *child_entry = new Child_entry(name, quota / 1024,
|
||||
initial_quota() / 1024,
|
||||
this, launchpad_child);
|
||||
child_entry->setObjectName(QString(unique_name) + "_child_entry");
|
||||
*this, launchpad_child);
|
||||
child_entry->setObjectName(QString(name.string()) + "_child_entry");
|
||||
childrenDockWidgetContents->layout()->addWidget(child_entry);
|
||||
child_entry->show();
|
||||
childrenDockWidgetContents->adjustSize();
|
||||
}
|
||||
|
||||
|
||||
void Qt_launchpad::remove_child(const char *name, Genode::Allocator *alloc)
|
||||
void Qt_launchpad::remove_child(Launchpad_child::Name const &name, Genode::Allocator &alloc)
|
||||
{
|
||||
Child_entry *child_entry =
|
||||
childrenDockWidgetContents->findChild<Child_entry*>(QString(name) + "_child_entry");
|
||||
childrenDockWidgetContents->findChild<Child_entry*>(QString(name.string()) + "_child_entry");
|
||||
|
||||
if (!child_entry) {
|
||||
PWRN("child entry lookup failed");
|
||||
|
@ -29,20 +29,22 @@ class Qt_launchpad : public QMainWindow, public Launchpad, private Ui::Qt_launch
|
||||
|
||||
public:
|
||||
|
||||
Qt_launchpad(unsigned long initial_quota, QWidget *parent = 0);
|
||||
Qt_launchpad(Genode::Env &env, unsigned long initial_quota,
|
||||
QWidget *parent = 0);
|
||||
|
||||
virtual void quota(unsigned long quota) override;
|
||||
|
||||
virtual void add_launcher(const char *filename,
|
||||
virtual void add_launcher(Launchpad_child::Name const &binary_name,
|
||||
unsigned long default_quota,
|
||||
Genode::Dataspace_capability config_ds) override;
|
||||
|
||||
virtual void add_child(const char *unique_name,
|
||||
virtual void add_child(Launchpad_child::Name const &name,
|
||||
unsigned long quota,
|
||||
Launchpad_child *launchpad_child,
|
||||
Genode::Allocator *alloc) override;
|
||||
Launchpad_child &launchpad_child,
|
||||
Genode::Allocator &alloc) override;
|
||||
|
||||
virtual void remove_child(const char *name, Genode::Allocator *alloc) override;
|
||||
virtual void remove_child(Launchpad_child::Name const &name,
|
||||
Genode::Allocator &alloc) override;
|
||||
};
|
||||
|
||||
#endif /* QT_LAUNCHPAD_H */
|
||||
|
@ -74,3 +74,14 @@
|
||||
|
||||
/*
|
||||
* Make sure that a handler exists. If not, report an error
|
||||
+++ src/lib/acpica/source/include/platform/acgcc.h
|
||||
@@ -44,7 +44,9 @@
|
||||
#ifndef __ACGCC_H__
|
||||
#define __ACGCC_H__
|
||||
|
||||
+#ifndef ACPI_INLINE
|
||||
#define ACPI_INLINE __inline__
|
||||
+#endif
|
||||
|
||||
/* Function name is used for debug output. Non-ANSI, compiler-dependent */
|
||||
|
||||
|
60
repos/libports/src/lib/acpica/env.cc
Normal file
60
repos/libports/src/lib/acpica/env.cc
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* \brief Genode environment for ACPICA library
|
||||
* \author Christian Helmuth
|
||||
* \date 2016-11-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/volatile_object.h>
|
||||
#include <acpica/acpica.h>
|
||||
#include <platform_session/client.h>
|
||||
|
||||
#include "env.h"
|
||||
|
||||
|
||||
namespace Acpica { struct Env; }
|
||||
|
||||
|
||||
struct Acpica::Env
|
||||
{
|
||||
Genode::Env &env;
|
||||
Genode::Allocator &heap;
|
||||
|
||||
Genode::Parent::Service_name announce_for_acpica { "Acpi" };
|
||||
|
||||
Genode::Parent::Client parent_client;
|
||||
|
||||
Genode::Id_space<Genode::Parent::Client>::Element id_space_element {
|
||||
parent_client, env.id_space() };
|
||||
|
||||
Genode::Capability<Platform::Session> cap {
|
||||
Genode::reinterpret_cap_cast<Platform::Session>(
|
||||
env.session(announce_for_acpica,
|
||||
id_space_element.id(),
|
||||
"ram_quota=24K", Genode::Affinity())) };
|
||||
|
||||
Platform::Client platform { cap };
|
||||
|
||||
Env(Genode::Env &env, Genode::Allocator &heap)
|
||||
: env(env), heap(heap) { }
|
||||
};
|
||||
|
||||
static Genode::Lazy_volatile_object<Acpica::Env> instance;
|
||||
|
||||
|
||||
Genode::Allocator & Acpica::heap() { return instance->heap; }
|
||||
Genode::Env & Acpica::env() { return instance->env; }
|
||||
Platform::Client & Acpica::platform() { return instance->platform; }
|
||||
|
||||
|
||||
void Acpica::init(Genode::Env &env, Genode::Allocator &heap)
|
||||
{
|
||||
instance.construct(env, heap);
|
||||
}
|
27
repos/libports/src/lib/acpica/env.h
Normal file
27
repos/libports/src/lib/acpica/env.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* \brief Genode environment for ACPICA library
|
||||
* \author Christian Helmuth
|
||||
* \date 2016-11-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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 _ACPICA__ENV_H_
|
||||
#define _ACPICA__ENV_H_
|
||||
|
||||
#include <base/env.h>
|
||||
#include <base/allocator.h>
|
||||
#include <platform_session/client.h>
|
||||
|
||||
namespace Acpica {
|
||||
Genode::Env & env();
|
||||
Genode::Allocator & heap();
|
||||
Platform::Client & platform();
|
||||
}
|
||||
|
||||
#endif /* _ACPICA__ENV_H_ */
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* \brief I/O memory backend for ACPICA library
|
||||
* \author Alexander Boettcher
|
||||
*
|
||||
* \date 2016-11-14
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -12,12 +12,13 @@
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <base/env.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <rm_session/connection.h>
|
||||
|
||||
#include "env.h"
|
||||
|
||||
extern "C" {
|
||||
#include "acpi.h"
|
||||
#include "acpiosxf.h"
|
||||
@ -31,9 +32,7 @@ extern "C" {
|
||||
return retval; \
|
||||
}
|
||||
|
||||
namespace Acpica {
|
||||
class Io_mem;
|
||||
};
|
||||
namespace Acpica { class Io_mem; };
|
||||
|
||||
class Acpica::Io_mem
|
||||
{
|
||||
@ -77,7 +76,7 @@ class Acpica::Io_mem
|
||||
void invalidate(ACPI_SIZE s)
|
||||
{
|
||||
if (_io_mem && refs())
|
||||
Genode::destroy(Genode::env()->heap(), _io_mem);
|
||||
Genode::destroy(Acpica::heap(), _io_mem);
|
||||
|
||||
ACPI_PHYSICAL_ADDRESS const p = _phys;
|
||||
|
||||
@ -139,7 +138,7 @@ class Acpica::Io_mem
|
||||
io_mem._ref = r;
|
||||
io_mem._virt = 0;
|
||||
|
||||
io_mem._io_mem = new (Genode::env()->heap())
|
||||
io_mem._io_mem = new (Acpica::heap())
|
||||
Genode::Io_mem_connection(io_mem._phys, io_mem._size);
|
||||
|
||||
return &io_mem;
|
||||
@ -152,7 +151,8 @@ class Acpica::Io_mem
|
||||
if (!io_mem)
|
||||
return 0UL;
|
||||
|
||||
io_mem->_virt = Genode::env()->rm_session()->attach(io_mem->_io_mem->dataspace(), io_mem->_size);
|
||||
io_mem->_virt = Acpica::env().rm().attach(io_mem->_io_mem->dataspace(),
|
||||
io_mem->_size);
|
||||
|
||||
return reinterpret_cast<Genode::addr_t>(io_mem->_virt);
|
||||
}
|
||||
@ -160,7 +160,7 @@ class Acpica::Io_mem
|
||||
Genode::addr_t pre_expand(ACPI_PHYSICAL_ADDRESS p, ACPI_SIZE s)
|
||||
{
|
||||
if (_io_mem)
|
||||
Genode::destroy(Genode::env()->heap(), _io_mem);
|
||||
Genode::destroy(Acpica::heap(), _io_mem);
|
||||
|
||||
_io_mem = nullptr;
|
||||
|
||||
@ -174,7 +174,7 @@ class Acpica::Io_mem
|
||||
Genode::addr_t post_expand(ACPI_PHYSICAL_ADDRESS p, ACPI_SIZE s)
|
||||
{
|
||||
if (_io_mem)
|
||||
Genode::destroy(Genode::env()->heap(), _io_mem);
|
||||
Genode::destroy(Acpica::heap(), _io_mem);
|
||||
|
||||
ACPI_SIZE xsize = p + s - _phys;
|
||||
if (!allocate(_phys, xsize, _ref))
|
||||
@ -211,8 +211,7 @@ class Acpica::Io_mem
|
||||
io2._io_mem = io_mem._io_mem;
|
||||
Genode::addr_t virt = reinterpret_cast<Genode::addr_t>(io2._virt);
|
||||
|
||||
Genode::env()->rm_session()->attach_at(io_ds, virt,
|
||||
io2._size, off_phys);
|
||||
Acpica::env().rm().attach_at(io_ds, virt, io2._size, off_phys);
|
||||
});
|
||||
|
||||
/**
|
||||
@ -227,7 +226,7 @@ class Acpica::Io_mem
|
||||
FAIL(0UL);
|
||||
|
||||
/* attach whole memory */
|
||||
io_mem._virt = Genode::env()->rm_session()->attach(io_ds);
|
||||
io_mem._virt = Acpica::env().rm().attach(io_ds);
|
||||
|
||||
return io_mem.to_virt(p);
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* \brief OS specific backend for ACPICA library
|
||||
* \author Alexander Boettcher
|
||||
*
|
||||
* \date 2016-11-14
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -12,17 +12,21 @@
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <base/env.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
#include <io_port_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
#include <acpica/acpica.h>
|
||||
|
||||
#include "env.h"
|
||||
|
||||
extern "C" {
|
||||
#include "acpi.h"
|
||||
#include "acpiosxf.h"
|
||||
}
|
||||
|
||||
|
||||
#define FAIL(retval) \
|
||||
{ \
|
||||
Genode::error(__func__, ":", __LINE__, " called - dead"); \
|
||||
@ -39,21 +43,20 @@ ACPI_STATUS AcpiOsPredefinedOverride (const ACPI_PREDEFINED_NAMES *pre,
|
||||
}
|
||||
|
||||
|
||||
void * AcpiOsAllocate (ACPI_SIZE size) {
|
||||
return Genode::env()->heap()->alloc(size); }
|
||||
void * AcpiOsAllocate (ACPI_SIZE size) { return Acpica::heap().alloc(size); }
|
||||
|
||||
|
||||
void AcpiOsFree (void *ptr)
|
||||
{
|
||||
if (Genode::env()->heap()->need_size_for_free())
|
||||
if (Acpica::heap().need_size_for_free())
|
||||
Genode::warning(__func__, " called - warning - ptr=", ptr);
|
||||
|
||||
Genode::env()->heap()->free(ptr, 0);
|
||||
Acpica::heap().free(ptr, 0);
|
||||
}
|
||||
|
||||
ACPI_STATUS AcpiOsCreateLock (ACPI_SPINLOCK *spin_lock)
|
||||
{
|
||||
*spin_lock = new (Genode::env()->heap()) Genode::Lock();
|
||||
*spin_lock = new (Acpica::heap()) Genode::Lock();
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
@ -80,7 +83,7 @@ void AcpiOsReleaseLock (ACPI_SPINLOCK h, ACPI_CPU_FLAGS flags)
|
||||
ACPI_STATUS AcpiOsCreateSemaphore (UINT32 max, UINT32 initial,
|
||||
ACPI_SEMAPHORE *sem)
|
||||
{
|
||||
*sem = new (Genode::env()->heap()) Genode::Semaphore(initial);
|
||||
*sem = new (Acpica::heap()) Genode::Semaphore(initial);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
@ -200,7 +203,8 @@ ACPI_STATUS AcpiOsWritePort (ACPI_IO_ADDRESS port, UINT32 value, UINT32 width)
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static struct {
|
||||
static struct
|
||||
{
|
||||
ACPI_EXECUTE_TYPE type;
|
||||
ACPI_OSD_EXEC_CALLBACK func;
|
||||
void *context;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* \brief PCI specific backend for ACPICA library
|
||||
* \author Alexander Boettcher
|
||||
*
|
||||
* \date 2016-11-14
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -12,9 +12,8 @@
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <base/env.h>
|
||||
#include <parent/parent.h>
|
||||
#include <platform_session/client.h>
|
||||
|
||||
#include "env.h"
|
||||
|
||||
extern "C" {
|
||||
#include "acpi.h"
|
||||
@ -42,44 +41,12 @@ struct Bdf
|
||||
};
|
||||
|
||||
|
||||
static Platform::Client & platform()
|
||||
{
|
||||
static bool connected = false;
|
||||
|
||||
typedef Genode::Capability<Platform::Session> Platform_session_capability;
|
||||
Platform_session_capability platform_cap;
|
||||
|
||||
if (!connected) {
|
||||
Genode::Parent::Service_name announce_for_acpica("Acpi");
|
||||
Genode::Native_capability cap = Genode::env()->parent()->session(announce_for_acpica, "ram_quota=20K");
|
||||
|
||||
platform_cap = Genode::reinterpret_cap_cast<Platform::Session>(cap);
|
||||
connected = true;
|
||||
}
|
||||
|
||||
static Platform::Client conn(platform_cap);
|
||||
return conn;
|
||||
}
|
||||
|
||||
ACPI_STATUS AcpiOsInitialize (void)
|
||||
{
|
||||
/* acpi_drv uses IOMEM concurrently to us - wait until it is done */
|
||||
Genode::log("wait for platform drv");
|
||||
try {
|
||||
platform();
|
||||
} catch (...) {
|
||||
Genode::error("did not get Platform connection");
|
||||
Genode::Lock lock(Genode::Lock::LOCKED);
|
||||
lock.lock();
|
||||
}
|
||||
Genode::log("wait for platform drv - done");
|
||||
return AE_OK;
|
||||
}
|
||||
ACPI_STATUS AcpiOsInitialize (void) { return AE_OK; }
|
||||
|
||||
ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
|
||||
UINT64 *value, UINT32 width)
|
||||
{
|
||||
Platform::Device_capability cap = platform().first_device();
|
||||
Platform::Device_capability cap = Acpica::platform().first_device();
|
||||
|
||||
while (cap.valid()) {
|
||||
Platform::Device_client client(cap);
|
||||
@ -103,7 +70,7 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
|
||||
break;
|
||||
default:
|
||||
Genode::error(__func__, " : unsupported access size ", width);
|
||||
platform().release_device(client);
|
||||
Acpica::platform().release_device(client);
|
||||
return AE_ERROR;
|
||||
};
|
||||
|
||||
@ -114,13 +81,13 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
|
||||
"width=", width, " -> "
|
||||
"value=", Genode::Hex(*value));
|
||||
|
||||
platform().release_device(client);
|
||||
Acpica::platform().release_device(client);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
cap = platform().next_device(cap);
|
||||
cap = Acpica::platform().next_device(cap);
|
||||
|
||||
platform().release_device(client);
|
||||
Acpica::platform().release_device(client);
|
||||
}
|
||||
|
||||
Genode::error(__func__, " unknown device - segment=", pcidev->Segment, " "
|
||||
@ -134,7 +101,7 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
|
||||
ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
|
||||
UINT64 value, UINT32 width)
|
||||
{
|
||||
Platform::Device_capability cap = platform().first_device();
|
||||
Platform::Device_capability cap = Acpica::platform().first_device();
|
||||
|
||||
while (cap.valid()) {
|
||||
Platform::Device_client client(cap);
|
||||
@ -158,7 +125,7 @@ ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
|
||||
break;
|
||||
default:
|
||||
Genode::error(__func__, " : unsupported access size ", width);
|
||||
platform().release_device(client);
|
||||
Acpica::platform().release_device(client);
|
||||
return AE_ERROR;
|
||||
};
|
||||
|
||||
@ -169,13 +136,13 @@ ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
|
||||
"width=", width, " "
|
||||
"value=", Genode::Hex(value));
|
||||
|
||||
platform().release_device(client);
|
||||
Acpica::platform().release_device(client);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
cap = platform().next_device(cap);
|
||||
cap = Acpica::platform().next_device(cap);
|
||||
|
||||
platform().release_device(client);
|
||||
Acpica::platform().release_device(client);
|
||||
}
|
||||
|
||||
Genode::error(__func__, " unknown device - segment=", pcidev->Segment, " ",
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Lookup code for initial ACPI RSDP pointer
|
||||
* \author Alexander Boettcher
|
||||
* \date 2016-11-14
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -13,6 +14,8 @@
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <os/attached_io_mem_dataspace.h>
|
||||
|
||||
#include "env.h"
|
||||
|
||||
extern "C" {
|
||||
#include "acpi.h"
|
||||
}
|
||||
@ -48,9 +51,11 @@ class Genode::Acpi_table
|
||||
{
|
||||
uint8_t * local = 0;
|
||||
|
||||
Genode::Env &env = Acpica::env();
|
||||
|
||||
/* try BIOS area */
|
||||
{
|
||||
Genode::Attached_io_mem_dataspace io_mem(BIOS_BASE, BIOS_SIZE);
|
||||
Genode::Attached_io_mem_dataspace io_mem(env, BIOS_BASE, BIOS_SIZE);
|
||||
local = _search_rsdp(io_mem.local_addr<uint8_t>());
|
||||
if (local)
|
||||
return BIOS_BASE + (local - io_mem.local_addr<uint8_t>());
|
||||
@ -60,7 +65,7 @@ class Genode::Acpi_table
|
||||
try {
|
||||
unsigned short base = 0;
|
||||
{
|
||||
Genode::Attached_io_mem_dataspace io_mem(0, 0x1000);
|
||||
Genode::Attached_io_mem_dataspace io_mem(env, 0, 0x1000);
|
||||
local = io_mem.local_addr<uint8_t>();
|
||||
if (local)
|
||||
base = (*reinterpret_cast<unsigned short *>(local + 0x40e)) << 4;
|
||||
@ -69,7 +74,7 @@ class Genode::Acpi_table
|
||||
if (!base)
|
||||
return 0;
|
||||
|
||||
Genode::Attached_io_mem_dataspace io_mem(base, 1024);
|
||||
Genode::Attached_io_mem_dataspace io_mem(env, base, 1024);
|
||||
local = _search_rsdp(io_mem.local_addr<uint8_t>());
|
||||
|
||||
if (local)
|
||||
|
@ -50,8 +50,7 @@ const char *config = " \
|
||||
<resource name=\"RAM\" quantum=\"2G\"/> \
|
||||
<configfile name=\"config.plugin\"/> \
|
||||
<route> \
|
||||
<service name=\"ROM\"> \
|
||||
<if-arg key=\"filename\" value=\"config.plugin\" /> \
|
||||
<service name=\"ROM\" label=\"config.plugin\"> \
|
||||
<child name=\"tar_rom\"/> \
|
||||
</service> \
|
||||
<any-service> <parent /> </any-service> \
|
||||
|
@ -28,13 +28,14 @@ class QNitpickerScreen : public QPlatformScreen
|
||||
{
|
||||
private:
|
||||
|
||||
Nitpicker::Connection _nitpicker;
|
||||
QRect _geometry;
|
||||
|
||||
public:
|
||||
|
||||
QNitpickerScreen()
|
||||
{
|
||||
Nitpicker::Connection _nitpicker;
|
||||
|
||||
Framebuffer::Mode const scr_mode = _nitpicker.mode();
|
||||
|
||||
if (scr_mode.format() != Framebuffer::Mode::RGB565)
|
||||
@ -42,8 +43,6 @@ class QNitpickerScreen : public QPlatformScreen
|
||||
|
||||
_geometry.setRect(0, 0, scr_mode.width(),
|
||||
scr_mode.height());
|
||||
|
||||
Genode::env()->parent()->close(_nitpicker.cap());
|
||||
}
|
||||
|
||||
QRect geometry() const { return _geometry; }
|
||||
|
@ -260,7 +260,8 @@ class Child_base : public Genode::Child_policy
|
||||
** Child_policy interface **
|
||||
****************************/
|
||||
|
||||
Name name() const override { return _label.string(); }
|
||||
Name name() const override { return _label; }
|
||||
Binary_name binary_name() const override { return _binary_name; }
|
||||
|
||||
Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
|
||||
Genode::Ram_session &ref_ram() override { return _ref_ram; }
|
||||
|
@ -24,6 +24,10 @@ namespace Framebuffer { class Connection; }
|
||||
class Framebuffer::Connection : public Genode::Connection<Session>,
|
||||
public Session_client
|
||||
{
|
||||
public:
|
||||
|
||||
enum { RAM_QUOTA = 8*1024UL };
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@ -39,7 +43,7 @@ class Framebuffer::Connection : public Genode::Connection<Session>,
|
||||
char argbuf[ARGBUF_SIZE];
|
||||
|
||||
/* donate ram quota for storing server-side meta data */
|
||||
Genode::strncpy(argbuf, "ram_quota=8K", sizeof(argbuf));
|
||||
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", RAM_QUOTA);
|
||||
|
||||
/* set optional session-constructor arguments */
|
||||
if (width)
|
||||
|
@ -23,6 +23,7 @@ namespace Framebuffer {
|
||||
|
||||
struct Mode;
|
||||
struct Session;
|
||||
struct Session_client;
|
||||
}
|
||||
|
||||
|
||||
@ -81,6 +82,8 @@ struct Framebuffer::Session : Genode::Session
|
||||
{
|
||||
static const char *service_name() { return "Framebuffer"; }
|
||||
|
||||
typedef Session_client Client;
|
||||
|
||||
virtual ~Session() { }
|
||||
|
||||
/**
|
||||
|
@ -28,7 +28,7 @@ class Nitpicker::Connection : public Genode::Connection<Session>,
|
||||
{
|
||||
public:
|
||||
|
||||
enum { RAM_QUOTA = 36*1024UL };
|
||||
enum { RAM_QUOTA = 36*1024UL };
|
||||
|
||||
private:
|
||||
|
||||
|
61
repos/os/include/os/single_session_service.h
Normal file
61
repos/os/include/os/single_session_service.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* \brief Utility for implementing a local service with a single session
|
||||
* \author Norman Feske
|
||||
* \date 2014-02-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 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.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__OS__SINGLE_SESSION_SERVICE_H_
|
||||
#define _INCLUDE__OS__SINGLE_SESSION_SERVICE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
|
||||
|
||||
namespace Genode { template <typename> class Single_session_service; }
|
||||
|
||||
|
||||
template <typename SESSION>
|
||||
class Genode::Single_session_service
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Capability<SESSION> Session_capability;
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
* Wrap client object to be compabile with 'Rpc_object::cap' calls
|
||||
*
|
||||
* We hand out the capability via 'cap' method to be compatible with
|
||||
* the interface normally provided by server-side component objects.
|
||||
* The 'Single_session_factory' requests the capability via this
|
||||
* method.
|
||||
*/
|
||||
struct Client : SESSION::Client
|
||||
{
|
||||
Client(Session_capability cap) : SESSION::Client(cap) { }
|
||||
Session_capability cap() const { return *this; }
|
||||
};
|
||||
|
||||
typedef Local_service<Client> Service;
|
||||
typedef typename Service::Single_session_factory Factory;
|
||||
|
||||
Client _client;
|
||||
Factory _factory { _client };
|
||||
Service _service { _factory };
|
||||
|
||||
public:
|
||||
|
||||
Single_session_service(Session_capability cap) : _client(cap) { }
|
||||
|
||||
Service &service() { return _service; }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__OS__SINGLE_SESSION_SERVICE_H_ */
|
@ -25,25 +25,29 @@ struct Child : Child_base, List<Child>::Element
|
||||
Argument argument;
|
||||
|
||||
Child(Ram &ram,
|
||||
char const *label,
|
||||
char const *binary,
|
||||
Genode::Cap_session &cap_session,
|
||||
Name const &label,
|
||||
Binary_name const &binary,
|
||||
Genode::Pd_session &pd_session,
|
||||
Genode::Ram_session &ref_ram,
|
||||
Genode::Ram_session_capability ref_ram_cap,
|
||||
Genode::Region_map &local_rm,
|
||||
Genode::size_t ram_quota,
|
||||
Genode::size_t ram_limit,
|
||||
Genode::Signal_context_capability yield_response_sig_cap,
|
||||
Genode::Signal_context_capability exit_sig_cap,
|
||||
Genode::Dataspace_capability ldso_ds)
|
||||
Genode::Signal_context_capability exit_sig_cap)
|
||||
:
|
||||
Child_base(ram,
|
||||
label,
|
||||
binary,
|
||||
cap_session,
|
||||
pd_session,
|
||||
ref_ram,
|
||||
ref_ram_cap,
|
||||
local_rm,
|
||||
ram_quota,
|
||||
ram_limit,
|
||||
yield_response_sig_cap,
|
||||
exit_sig_cap,
|
||||
ldso_ds),
|
||||
argument(label, "subsystem")
|
||||
exit_sig_cap),
|
||||
argument(label.string(), "subsystem")
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@ class Child_registry : public List<Child>
|
||||
bool _child_name_exists(const char *label)
|
||||
{
|
||||
for (Child *child = first() ; child; child = child->next())
|
||||
if (strcmp(child->name(), label) == 0)
|
||||
if (child->name() == label)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ struct Kill_command : Command
|
||||
|
||||
void _destroy_child(Child *child, Terminal::Session &terminal)
|
||||
{
|
||||
tprintf(terminal, "destroying subsystem '%s'\n", child->name());
|
||||
tprintf(terminal, "destroying subsystem '%s'\n", child->name().string());
|
||||
_children.remove(child);
|
||||
Genode::destroy(Genode::env()->heap(), child);
|
||||
}
|
||||
@ -38,8 +38,8 @@ struct Kill_command : Command
|
||||
|
||||
void _for_each_argument(Argument_fn const &fn) const override
|
||||
{
|
||||
auto child_name_fn = [&] (char const *child_name) {
|
||||
Argument arg(child_name, "");
|
||||
auto child_name_fn = [&] (Child_base::Name const &child_name) {
|
||||
Argument arg(child_name.string(), "");
|
||||
fn(arg);
|
||||
};
|
||||
|
||||
@ -65,7 +65,7 @@ struct Kill_command : Command
|
||||
|
||||
/* lookup child by its unique name */
|
||||
for (Child *child = _children.first(); child; child = child->next()) {
|
||||
if (strcmp(child->name(), label) == 0) {
|
||||
if (child->name() == label) {
|
||||
_destroy_child(child, terminal);
|
||||
return;
|
||||
}
|
||||
|
@ -132,11 +132,12 @@ void Component::construct(Genode::Env &env)
|
||||
commands.insert(new Help_command);
|
||||
Kill_command kill_command(children);
|
||||
commands.insert(&kill_command);
|
||||
commands.insert(new Start_command(ram, cap, children,
|
||||
commands.insert(new Start_command(ram, env.pd(),
|
||||
env.ram(), env.ram_session_cap(),
|
||||
env.rm(), children,
|
||||
subsystem_config_registry,
|
||||
yield_response_sig_cap,
|
||||
exited_child_sig_cap,
|
||||
ldso_ds));
|
||||
exited_child_sig_cap));
|
||||
commands.insert(new Status_command(ram, children));
|
||||
commands.insert(new Yield_command(children));
|
||||
commands.insert(new Ram_command(children));
|
||||
|
@ -40,13 +40,13 @@ struct Ram_command : Command
|
||||
size_t const avail = Genode::env()->ram_session()->avail();
|
||||
if (amount > avail) {
|
||||
tprintf(terminal, "upgrade of '%s' exceeds available quota of ",
|
||||
child.name());
|
||||
child.name().string());
|
||||
tprint_bytes(terminal, avail);
|
||||
tprintf(terminal, "\n");
|
||||
amount = avail;
|
||||
}
|
||||
|
||||
tprintf(terminal, "upgrading quota of '%s' to ", child.name());
|
||||
tprintf(terminal, "upgrading quota of '%s' to ", child.name().string());
|
||||
tprint_bytes(terminal, old_quota + amount);
|
||||
tprintf(terminal, "\n");
|
||||
|
||||
@ -69,7 +69,7 @@ struct Ram_command : Command
|
||||
amount = avail;
|
||||
}
|
||||
|
||||
tprintf(terminal, "depleting quota of '%s' to ", child.name());
|
||||
tprintf(terminal, "depleting quota of '%s' to ", child.name().string());
|
||||
tprint_bytes(terminal, old_quota - amount);
|
||||
tprintf(terminal, "\n");
|
||||
|
||||
@ -82,8 +82,8 @@ struct Ram_command : Command
|
||||
|
||||
void _for_each_argument(Argument_fn const &fn) const override
|
||||
{
|
||||
auto child_name_fn = [&] (char const *child_name) {
|
||||
Argument arg(child_name, "");
|
||||
auto child_name_fn = [&] (Child_base::Name const &child_name) {
|
||||
Argument arg(child_name.string(), "");
|
||||
fn(arg);
|
||||
};
|
||||
|
||||
@ -102,7 +102,7 @@ struct Ram_command : Command
|
||||
/* lookup child by its unique name */
|
||||
Child *child = _children.first();
|
||||
for (; child; child = child->next())
|
||||
if (strcmp(child->name(), label) == 0)
|
||||
if (child->name() == label)
|
||||
break;
|
||||
|
||||
if (!child) {
|
||||
|
@ -28,14 +28,16 @@ class Start_command : public Command
|
||||
typedef Genode::Signal_context_capability Signal_context_capability;
|
||||
typedef Genode::Dataspace_capability Dataspace_capability;
|
||||
|
||||
Ram &_ram;
|
||||
Child_registry &_children;
|
||||
Genode::Cap_session &_cap;
|
||||
Subsystem_config_registry &_subsystem_configs;
|
||||
List<Argument> _arguments;
|
||||
Signal_context_capability _yield_response_sigh_cap;
|
||||
Signal_context_capability _exit_sig_cap;
|
||||
Dataspace_capability _ldso_ds;
|
||||
Ram &_ram;
|
||||
Child_registry &_children;
|
||||
Genode::Pd_session &_pd;
|
||||
Genode::Ram_session &_ref_ram;
|
||||
Genode::Ram_session_capability _ref_ram_cap;
|
||||
Genode::Region_map &_local_rm;
|
||||
Subsystem_config_registry &_subsystem_configs;
|
||||
List<Argument> _arguments;
|
||||
Signal_context_capability _yield_response_sigh_cap;
|
||||
Signal_context_capability _exit_sig_cap;
|
||||
|
||||
void _execute_subsystem(char const *name, Command_line &cmd,
|
||||
Terminal::Session &terminal,
|
||||
@ -107,11 +109,12 @@ class Start_command : public Command
|
||||
Child *child = 0;
|
||||
try {
|
||||
child = new (Genode::env()->heap())
|
||||
Child(_ram, label, binary_name, _cap, ram, ram_limit,
|
||||
_yield_response_sigh_cap, _exit_sig_cap, _ldso_ds);
|
||||
Child(_ram, label, binary_name, _pd, _ref_ram, _ref_ram_cap,
|
||||
_local_rm, ram, ram_limit,
|
||||
_yield_response_sigh_cap, _exit_sig_cap);
|
||||
}
|
||||
catch (Genode::Rom_connection::Rom_connection_failed) {
|
||||
tprintf(terminal, "Error: could not obtain ROM module \"%s\"\n",
|
||||
catch (Genode::Parent::Service_denied) {
|
||||
tprintf(terminal, "Error: could not start child \"%s\"\n",
|
||||
binary_name);
|
||||
return;
|
||||
}
|
||||
@ -146,18 +149,22 @@ class Start_command : public Command
|
||||
|
||||
public:
|
||||
|
||||
Start_command(Ram &ram, Genode::Cap_session &cap, Child_registry &children,
|
||||
Subsystem_config_registry &subsustem_configs,
|
||||
Signal_context_capability yield_response_sigh_cap,
|
||||
Signal_context_capability exit_sig_cap,
|
||||
Dataspace_capability ldso_ds)
|
||||
Start_command(Ram &ram,
|
||||
Genode::Pd_session &pd,
|
||||
Genode::Ram_session &ref_ram,
|
||||
Genode::Ram_session_capability ref_ram_cap,
|
||||
Genode::Region_map &local_rm,
|
||||
Child_registry &children,
|
||||
Subsystem_config_registry &subsustem_configs,
|
||||
Signal_context_capability yield_response_sigh_cap,
|
||||
Signal_context_capability exit_sig_cap)
|
||||
:
|
||||
Command("start", "create new subsystem"),
|
||||
_ram(ram), _children(children), _cap(cap),
|
||||
_ram(ram), _children(children), _pd(pd),
|
||||
_ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap), _local_rm(local_rm),
|
||||
_subsystem_configs(subsustem_configs),
|
||||
_yield_response_sigh_cap(yield_response_sigh_cap),
|
||||
_exit_sig_cap(exit_sig_cap),
|
||||
_ldso_ds(ldso_ds)
|
||||
_exit_sig_cap(exit_sig_cap)
|
||||
{
|
||||
add_parameter(new Parameter("--count", Parameter::NUMBER, "number of instances"));
|
||||
add_parameter(new Parameter("--ram", Parameter::NUMBER, "initial RAM quota"));
|
||||
|
@ -139,7 +139,7 @@ struct Status_command : Command
|
||||
Child_info child_info[num_children];
|
||||
unsigned i = 0;
|
||||
for (Child *c = _children.first(); c && i < num_children; c = c->next(), i++)
|
||||
child_info[i] = Child_info(c->name(), c->ram_status());
|
||||
child_info[i] = Child_info(c->name().string(), c->ram_status());
|
||||
|
||||
/*
|
||||
* Print table
|
||||
|
@ -32,8 +32,8 @@ struct Yield_command : Command
|
||||
|
||||
void _for_each_argument(Argument_fn const &fn) const override
|
||||
{
|
||||
auto child_name_fn = [&] (char const *child_name) {
|
||||
Argument arg(child_name, "");
|
||||
auto child_name_fn = [&] (Child_base::Name const &child_name) {
|
||||
Argument arg(child_name.string(), "");
|
||||
fn(arg);
|
||||
};
|
||||
|
||||
@ -57,7 +57,7 @@ struct Yield_command : Command
|
||||
/* lookup child by its unique name */
|
||||
Child *child = _children.first();
|
||||
for (; child; child = child->next())
|
||||
if (strcmp(child->name(), label) == 0)
|
||||
if (child->name() == label)
|
||||
break;
|
||||
|
||||
if (!child) {
|
||||
@ -67,7 +67,7 @@ struct Yield_command : Command
|
||||
|
||||
child->yield(ram, greedy);
|
||||
|
||||
tprintf(terminal, "requesting '%s' to yield ", child->name());
|
||||
tprintf(terminal, "requesting '%s' to yield ", child->name().string());
|
||||
tprint_bytes(terminal, ram);
|
||||
tprintf(terminal, "\n");
|
||||
}
|
||||
|
@ -115,9 +115,7 @@ namespace L4lx {
|
||||
use_local_addr,
|
||||
local_addr,
|
||||
executable); },
|
||||
[&] () {
|
||||
Genode::env()->parent()->upgrade(Rm_connection::cap(), "ram_quota=8K");
|
||||
});
|
||||
[&] () { Rm_connection::upgrade_ram(8*1024); });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -56,30 +56,4 @@ auto retry(FUNC func, HANDLER handler, unsigned attempts = ~0U) -> decltype(func
|
||||
throw EXC();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Client object for a session that may get its session quota upgraded
|
||||
*/
|
||||
template <typename CLIENT>
|
||||
struct Upgradeable_client : CLIENT
|
||||
{
|
||||
typedef Genode::Capability<typename CLIENT::Rpc_interface> Capability;
|
||||
|
||||
Capability _cap;
|
||||
|
||||
Upgradeable_client(Capability cap) : CLIENT(cap), _cap(cap) { }
|
||||
|
||||
void upgrade_ram(Genode::size_t quota)
|
||||
{
|
||||
Genode::log("upgrading quota donation for "
|
||||
"Env::", CLIENT::Rpc_interface::service_name(), " "
|
||||
"(", quota, " bytes)");
|
||||
|
||||
char buf[128];
|
||||
Genode::snprintf(buf, sizeof(buf), "ram_quota=%ld", quota);
|
||||
|
||||
Genode::env()->parent()->upgrade(_cap, buf);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _PLATFORM_ENV_H_ */
|
||||
|
@ -83,7 +83,7 @@ static void map_kip()
|
||||
using namespace Genode;
|
||||
|
||||
/* Open the KIP special file and keep it open */
|
||||
static Genode::Rom_connection kip_rom("kip");
|
||||
static Genode::Rom_connection kip_rom("l4v2_kip");
|
||||
|
||||
/* Attach and register dataspace */
|
||||
l4lx_kinfo = L4lx::Env::env()->rm()->attach(kip_rom.dataspace(), "KIP");
|
||||
|
@ -40,6 +40,18 @@ struct Noux::Connection : Genode::Connection<Session>, Session_client
|
||||
*/
|
||||
Connection()
|
||||
: Genode::Connection<Session>(session("")), Session_client(cap()) { }
|
||||
|
||||
/**
|
||||
* Remove session ID of the noux session from the ID space.
|
||||
*
|
||||
* This must by done before reinitializing the noux connection in a
|
||||
* freshly forked process. Otherwise, an overwritten 'Noux::Connection'
|
||||
* object would still be referenced by the AVL tree of the the ID space.
|
||||
*/
|
||||
void discard_session_id()
|
||||
{
|
||||
_id_space_element.~Element();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NOUX_SESSION__CONNECTION_H_ */
|
||||
|
@ -38,8 +38,8 @@ class Vmm::Vcpu_dispatcher : public T
|
||||
|
||||
enum { WEIGHT = Genode::Cpu_session::Weight::DEFAULT_WEIGHT };
|
||||
|
||||
Pd_session &_pd;
|
||||
Nova_native_pd_client _native_pd { _pd.native_pd() };
|
||||
Env &_env;
|
||||
Nova_native_pd_client _native_pd { _env.pd().native_pd() };
|
||||
|
||||
/**
|
||||
* Portal entry point entered on virtualization events
|
||||
@ -69,12 +69,12 @@ class Vmm::Vcpu_dispatcher : public T
|
||||
|
||||
unsigned int exit_reason = 0;
|
||||
|
||||
Vcpu_dispatcher(Genode::size_t stack_size, Pd_session &pd,
|
||||
Vcpu_dispatcher(Genode::Env &env, Genode::size_t stack_size,
|
||||
Cpu_session * cpu_session,
|
||||
Genode::Affinity::Location location,
|
||||
const char * name = "vCPU dispatcher")
|
||||
:
|
||||
T(WEIGHT, name, stack_size, location), _pd(pd)
|
||||
T(WEIGHT, name, stack_size, location), _env(env)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -85,13 +85,13 @@ class Vmm::Vcpu_dispatcher : public T
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
Vcpu_dispatcher(Genode::size_t stack_size, Pd_session &pd,
|
||||
Vcpu_dispatcher(Genode::Env &env, Genode::size_t stack_size,
|
||||
Cpu_session * cpu_session,
|
||||
Genode::Affinity::Location location,
|
||||
X attr, void *(*start_routine) (void *), void *arg,
|
||||
const char * name = "vCPU dispatcher")
|
||||
: T(attr, start_routine, arg, stack_size, name, nullptr, location),
|
||||
_pd(pd)
|
||||
_env(env)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -125,11 +125,7 @@ class Vmm::Vcpu_dispatcher : public T
|
||||
},
|
||||
[&] () {
|
||||
Thread::myself()->native_thread().reset_client_rcv_sel();
|
||||
Pd_session_client *client =
|
||||
dynamic_cast<Pd_session_client*>(&_pd);
|
||||
|
||||
if (client)
|
||||
env()->parent()->upgrade(*client, "ram_quota=16K");
|
||||
_env.parent().upgrade(Parent::Env::pd(), "ram_quota=16K");
|
||||
});
|
||||
|
||||
/* revert selector allocation to automatic mode of operation */
|
||||
|
@ -64,6 +64,22 @@ append config {
|
||||
<start name="loader">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides><service name="Loader"/></provides>
|
||||
<config>
|
||||
<policy label="arora">
|
||||
<parent-rom name="ld.lib.so"/>
|
||||
<parent-rom name="init"/>
|
||||
<parent-rom name="tar_rom"/>
|
||||
<parent-rom name="nit_fb"/>
|
||||
<parent-rom name="nitpicker"/>
|
||||
<parent-rom name="pointer"/>
|
||||
<parent-rom name="launchpad"/>
|
||||
<parent-rom name="testnit"/>
|
||||
</policy>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nitpicker"> <child name="wm"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="arora">
|
||||
|
@ -104,7 +104,7 @@ append config {
|
||||
|
||||
append_if $use_nic_driver config {
|
||||
<start name="nic_drv">
|
||||
<resource name="RAM" quantum="5M"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides> <service name="Nic"/> </provides>
|
||||
</start>}
|
||||
|
||||
|
@ -212,7 +212,7 @@ append_platform_drv_config
|
||||
|
||||
append_if $use_nic_session config {
|
||||
<start name="nic_drv" priority="-2">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<route> <any-service><any-child/><parent/></any-service> </route>
|
||||
</start>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user