mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-02 09:18:18 +00:00
Use signals for delivering input events
This patch changes both the Input::Session interface and the skeleton for the server-side implementation of this interface ('input/component.h'). The Input::Session interface offers a new 'sigh' function, which can be called be the client to register a signal handler. The signal handler gets notified on the arrival of new input. This alleviates the need to poll for input events at the client side. The server-side skeleton for implementing input services underwent a redesign to make it more modular and robust. I.e., there are no global functions needed at the server side and the event-queue enable/disable mechanism is implemented at a central place (in the root component) rather than inside each driver. Fixes #46
This commit is contained in:
parent
6c10bfe049
commit
0ed68a56b7
@ -15,7 +15,7 @@
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <input/component.h>
|
||||
#include <input/root.h>
|
||||
#include <os/ring_buffer.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
@ -25,19 +25,27 @@
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/*********************
|
||||
** Input component **
|
||||
*********************/
|
||||
/**
|
||||
* Return singleton instance of input-session component
|
||||
*/
|
||||
static Input::Session_component &input_session()
|
||||
{
|
||||
static Input::Session_component inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
typedef Ring_buffer<Input::Event, 512> Input_ring_buffer;
|
||||
|
||||
static Input_ring_buffer ev_queue;
|
||||
|
||||
namespace Input {
|
||||
|
||||
void event_handling(bool enable) { }
|
||||
bool event_pending() { return !ev_queue.empty(); }
|
||||
Event get_event() { return ev_queue.get(); }
|
||||
/**
|
||||
* Return singleton instance of input-root component
|
||||
*
|
||||
* On the first call (from 'start_input_service'), the 'ep' argument is
|
||||
* specified. All subsequent calls (from 'input_callback') just return the
|
||||
* reference to the singleton instance.
|
||||
*/
|
||||
static Input::Root_component &input_root(Rpc_entrypoint *ep = 0)
|
||||
{
|
||||
static Input::Root_component root(*ep, input_session());
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
@ -58,20 +66,20 @@ static void input_callback(enum input_event_type type,
|
||||
}
|
||||
|
||||
try {
|
||||
ev_queue.add(Input::Event(t, code,
|
||||
absolute_x, absolute_y,
|
||||
relative_x, relative_y));
|
||||
} catch (Input_ring_buffer::Overflow) {
|
||||
input_session().submit(Input::Event(t, code,
|
||||
absolute_x, absolute_y,
|
||||
relative_x, relative_y));
|
||||
} catch (Input::Event_queue::Overflow) {
|
||||
PWRN("input ring buffer overflow");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void start_input_service(void *ep)
|
||||
void start_input_service(void *ep_ptr)
|
||||
{
|
||||
Rpc_entrypoint *e = static_cast<Rpc_entrypoint *>(ep);
|
||||
static Input::Root input_root(e, env()->heap());
|
||||
env()->parent()->announce(e->manage(&input_root));
|
||||
Rpc_entrypoint *ep = static_cast<Rpc_entrypoint *>(ep_ptr);
|
||||
|
||||
env()->parent()->announce(ep->manage(&input_root(ep)));
|
||||
|
||||
genode_input_register(input_callback);
|
||||
}
|
||||
|
@ -11,77 +11,30 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode include */
|
||||
#include <base/env.h>
|
||||
#include <base/semaphore.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <framebuffer_session/framebuffer_session.h>
|
||||
#include <input/component.h>
|
||||
#include <input/root.h>
|
||||
#include <nitpicker_gfx/texture_painter.h>
|
||||
#include <os/pixel_rgb565.h>
|
||||
#include <os/static_root.h>
|
||||
|
||||
/* local includes */
|
||||
#include "services.h"
|
||||
|
||||
|
||||
typedef Genode::Texture<Genode::Pixel_rgb565> Texture_rgb565;
|
||||
|
||||
|
||||
/*****************
|
||||
** Event queue **
|
||||
*****************/
|
||||
|
||||
class Event_queue
|
||||
/**
|
||||
* Return singleton instance of input session component
|
||||
*/
|
||||
Input::Session_component &input_session()
|
||||
{
|
||||
private:
|
||||
|
||||
enum { QUEUE_SIZE = 1024 };
|
||||
|
||||
Input::Event _queue[QUEUE_SIZE];
|
||||
int _head;
|
||||
int _tail;
|
||||
Genode::Semaphore _sem;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Event_queue(): _head(0), _tail(0)
|
||||
{
|
||||
Scout::memset(_queue, 0, sizeof(_queue));
|
||||
}
|
||||
|
||||
void post(Input::Event ev)
|
||||
{
|
||||
if ((_head + 1)%QUEUE_SIZE != _tail) {
|
||||
_queue[_head] = ev;
|
||||
_head = (_head + 1)%QUEUE_SIZE;
|
||||
_sem.up();
|
||||
}
|
||||
}
|
||||
|
||||
Input::Event get()
|
||||
{
|
||||
_sem.down();
|
||||
Input::Event dst_ev = _queue[_tail];
|
||||
_tail = (_tail + 1)%QUEUE_SIZE;
|
||||
return dst_ev;
|
||||
}
|
||||
|
||||
int pending() { return _head != _tail; }
|
||||
|
||||
} _ev_queue;
|
||||
|
||||
|
||||
/***************************
|
||||
** Input service backend **
|
||||
***************************/
|
||||
|
||||
namespace Input {
|
||||
|
||||
void event_handling(bool enable) { }
|
||||
bool event_pending() { return _ev_queue.pending(); }
|
||||
Event get_event() { return _ev_queue.get(); }
|
||||
|
||||
static Input::Session_component inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
@ -93,16 +46,16 @@ class Window_content : public Scout::Element
|
||||
{
|
||||
private:
|
||||
|
||||
Event_queue *_ev_queue;
|
||||
Scout::Point _old_mouse_position;
|
||||
Element *_element;
|
||||
Input::Session_component &_input_session;
|
||||
Scout::Point _old_mouse_position;
|
||||
Element *_element;
|
||||
|
||||
public:
|
||||
|
||||
Content_event_handler(Event_queue *ev_queue,
|
||||
Content_event_handler(Input::Session_component &input_session,
|
||||
Scout::Element *element)
|
||||
:
|
||||
_ev_queue(ev_queue), _element(element) { }
|
||||
_input_session(input_session),_element(element) { }
|
||||
|
||||
void handle(Scout::Event &ev)
|
||||
{
|
||||
@ -123,10 +76,10 @@ class Window_content : public Scout::Element
|
||||
: Input::Event::INVALID;
|
||||
|
||||
if (type != Input::Event::INVALID)
|
||||
_ev_queue->post(Input::Event(type, code, mouse_position.x(),
|
||||
mouse_position.y(),
|
||||
mouse_position.x() - _old_mouse_position.x(),
|
||||
mouse_position.y() - _old_mouse_position.y()));
|
||||
_input_session.submit(Input::Event(type, code, mouse_position.x(),
|
||||
mouse_position.y(),
|
||||
mouse_position.x() - _old_mouse_position.x(),
|
||||
mouse_position.y() - _old_mouse_position.y()));
|
||||
|
||||
_old_mouse_position = mouse_position;
|
||||
}
|
||||
@ -173,9 +126,9 @@ class Window_content : public Scout::Element
|
||||
|
||||
};
|
||||
|
||||
bool _config_alpha;
|
||||
Content_event_handler _ev_handler;
|
||||
Fb_texture *_fb;
|
||||
bool _config_alpha;
|
||||
Content_event_handler _ev_handler;
|
||||
Fb_texture *_fb;
|
||||
|
||||
/**
|
||||
* Size of the framebuffer handed out by the next call of 'dataspace'
|
||||
@ -198,11 +151,12 @@ class Window_content : public Scout::Element
|
||||
|
||||
public:
|
||||
|
||||
Window_content(unsigned fb_w, unsigned fb_h, Event_queue *ev_queue,
|
||||
Window_content(unsigned fb_w, unsigned fb_h,
|
||||
Input::Session_component &input_session,
|
||||
bool config_alpha)
|
||||
:
|
||||
_config_alpha(config_alpha),
|
||||
_ev_handler(ev_queue, this),
|
||||
_ev_handler(input_session, this),
|
||||
_fb(new (Genode::env()->heap()) Fb_texture(fb_w, fb_h, _config_alpha)),
|
||||
_next_size(fb_w, fb_h),
|
||||
_designated_size(_next_size)
|
||||
@ -268,76 +222,52 @@ Scout::Element *window_content() { return _window_content; }
|
||||
** Implementation of the framebuffer service **
|
||||
***********************************************/
|
||||
|
||||
namespace Framebuffer
|
||||
namespace Framebuffer { class Session_component; }
|
||||
|
||||
class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
class Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
private:
|
||||
private:
|
||||
|
||||
Window_content &_window_content;
|
||||
Window_content &_window_content;
|
||||
|
||||
Genode::Signal_context_capability _sync_sigh;
|
||||
Genode::Signal_context_capability _sync_sigh;
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
Session_component(Window_content &window_content)
|
||||
: _window_content(window_content) { }
|
||||
Session_component(Window_content &window_content)
|
||||
: _window_content(window_content) { }
|
||||
|
||||
Genode::Dataspace_capability dataspace() override
|
||||
{
|
||||
_window_content.realloc_framebuffer();
|
||||
return _window_content.fb_ds_cap();
|
||||
}
|
||||
Genode::Dataspace_capability dataspace() override
|
||||
{
|
||||
_window_content.realloc_framebuffer();
|
||||
return _window_content.fb_ds_cap();
|
||||
}
|
||||
|
||||
Mode mode() const override
|
||||
{
|
||||
return Mode(_window_content.mode_size().w(),
|
||||
_window_content.mode_size().h(), Mode::RGB565);
|
||||
}
|
||||
Mode mode() const override
|
||||
{
|
||||
return Mode(_window_content.mode_size().w(),
|
||||
_window_content.mode_size().h(), Mode::RGB565);
|
||||
}
|
||||
|
||||
void mode_sigh(Genode::Signal_context_capability sigh) override {
|
||||
_window_content.mode_sigh(sigh); }
|
||||
void mode_sigh(Genode::Signal_context_capability sigh) override {
|
||||
_window_content.mode_sigh(sigh); }
|
||||
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override {
|
||||
_sync_sigh = sigh; }
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override {
|
||||
_sync_sigh = sigh; }
|
||||
|
||||
void refresh(int x, int y, int w, int h) override
|
||||
{
|
||||
_window_content.redraw_area(x, y, w, h);
|
||||
void refresh(int x, int y, int w, int h) override
|
||||
{
|
||||
_window_content.redraw_area(x, y, w, h);
|
||||
|
||||
if (_sync_sigh.valid())
|
||||
Genode::Signal_transmitter(_sync_sigh).submit();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Root : public Genode::Root_component<Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Window_content &_window_content;
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args) override {
|
||||
return new (md_alloc()) Session_component(_window_content); }
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Rpc_entrypoint *session_ep,
|
||||
Genode::Allocator *md_alloc,
|
||||
Window_content &window_content)
|
||||
:
|
||||
Genode::Root_component<Session_component>(session_ep, md_alloc),
|
||||
_window_content(window_content)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
if (_sync_sigh.valid())
|
||||
Genode::Signal_transmitter(_sync_sigh).submit();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void init_window_content(unsigned fb_w, unsigned fb_h, bool config_alpha)
|
||||
{
|
||||
static Window_content content(fb_w, fb_h, &_ev_queue, config_alpha);
|
||||
static Window_content content(fb_w, fb_h, input_session(), config_alpha);
|
||||
_window_content = &content;
|
||||
}
|
||||
|
||||
@ -346,11 +276,10 @@ void init_services(Genode::Rpc_entrypoint &ep)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/*
|
||||
* Let the entry point serve the framebuffer and input root interfaces
|
||||
*/
|
||||
static Framebuffer::Root fb_root(&ep, env()->heap(), *_window_content);
|
||||
static Input::Root input_root(&ep, env()->heap());
|
||||
static Framebuffer::Session_component fb_session(*_window_content);
|
||||
static Static_root<Framebuffer::Session> fb_root(ep.manage(&fb_session));
|
||||
|
||||
static Input::Root_component input_root(ep, input_session());
|
||||
|
||||
/*
|
||||
* Now, the root interfaces are ready to accept requests.
|
||||
|
@ -110,6 +110,14 @@ namespace Input {
|
||||
* Flush input events
|
||||
*/
|
||||
Genode::size_t flush() { return _client.flush(); }
|
||||
|
||||
/**
|
||||
* Register signal handler for input notifications
|
||||
*/
|
||||
void sigh(Genode::Signal_context_capability sigh)
|
||||
{
|
||||
_client.sigh(sigh);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -183,6 +191,12 @@ namespace Input {
|
||||
}
|
||||
return dst_count;
|
||||
}
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh)
|
||||
{
|
||||
for (Source *e = _sources.first(); e; e = e->next())
|
||||
e->sigh(sigh);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -214,18 +228,23 @@ namespace Input {
|
||||
** Input-session interface **
|
||||
*****************************/
|
||||
|
||||
Genode::Dataspace_capability dataspace() { return _ev_ds.cap(); }
|
||||
Genode::Dataspace_capability dataspace() override { return _ev_ds.cap(); }
|
||||
|
||||
bool is_pending() const
|
||||
bool is_pending() const override
|
||||
{
|
||||
return _source_registry.any_source_has_pending_input();
|
||||
}
|
||||
|
||||
int flush()
|
||||
int flush() override
|
||||
{
|
||||
return _source_registry.flush_sources(_ev_ds.local_addr<Event>(),
|
||||
MAX_EVENTS);
|
||||
}
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_source_registry.sigh(sigh);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -17,22 +17,22 @@
|
||||
/* Qoost includes */
|
||||
#include <qoost/style.h>
|
||||
|
||||
#include "input_service.h"
|
||||
/* local includes */
|
||||
#include "main_window.h"
|
||||
|
||||
|
||||
void Control_bar::_rewind()
|
||||
{
|
||||
/* mouse click at horizontal position 0 */
|
||||
ev_queue.add(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0));
|
||||
ev_queue.add(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 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));
|
||||
}
|
||||
|
||||
|
||||
void Control_bar::_pause_resume()
|
||||
{
|
||||
ev_queue.add(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
ev_queue.add(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
_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));
|
||||
|
||||
_playing = !_playing;
|
||||
if (_playing)
|
||||
@ -51,8 +51,9 @@ void Control_bar::_stop()
|
||||
}
|
||||
|
||||
|
||||
Control_bar::Control_bar()
|
||||
: _playing(true)
|
||||
Control_bar::Control_bar(Input::Event_queue &event_queue)
|
||||
:
|
||||
_event_queue(event_queue), _playing(true)
|
||||
{
|
||||
update_style_id(_play_pause_button, "play");
|
||||
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include <qoost/compound_widget.h>
|
||||
#include <qoost/qmember.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/event_queue.h>
|
||||
|
||||
struct Play_pause_button : QPushButton { Q_OBJECT };
|
||||
struct Stop_button : QPushButton { Q_OBJECT };
|
||||
struct Volume_label : QLabel { Q_OBJECT };
|
||||
@ -33,6 +36,8 @@ class Control_bar : public Compound_widget<QWidget, QHBoxLayout>
|
||||
|
||||
private:
|
||||
|
||||
Input::Event_queue &_event_queue;
|
||||
|
||||
QMember<Play_pause_button> _play_pause_button;
|
||||
QMember<Stop_button> _stop_button;
|
||||
QMember<Volume_label> _volume_label;
|
||||
@ -49,7 +54,7 @@ class Control_bar : public Compound_widget<QWidget, QHBoxLayout>
|
||||
|
||||
public:
|
||||
|
||||
Control_bar();
|
||||
Control_bar(Input::Event_queue &event_queue);
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* \brief Input service
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <input/component.h>
|
||||
|
||||
#include "input_service.h"
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
Event_queue ev_queue;
|
||||
|
||||
|
||||
namespace Input {
|
||||
|
||||
/*
|
||||
* Event handling is disabled on queue creation and will be enabled later if a
|
||||
* session is created.
|
||||
*/
|
||||
void event_handling(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
ev_queue.enable();
|
||||
else
|
||||
ev_queue.disable();
|
||||
}
|
||||
|
||||
bool event_pending() { return !ev_queue.empty(); }
|
||||
Event get_event() { return ev_queue.get(); }
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* \brief Input service
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _INPUT_SERVICE_H_
|
||||
#define _INPUT_SERVICE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/event_queue.h>
|
||||
|
||||
extern Event_queue ev_queue;
|
||||
|
||||
extern void create_input_service();
|
||||
|
||||
#endif /* _INPUT_SERVICE_H_ */
|
@ -17,6 +17,11 @@
|
||||
/* qt_avplay includes */
|
||||
#include "main_window.h"
|
||||
|
||||
/* Genode includes */
|
||||
#include <rom_session/connection.h>
|
||||
#include <base/process.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
|
||||
static inline void load_stylesheet()
|
||||
{
|
||||
@ -37,6 +42,14 @@ int main(int argc, char *argv[])
|
||||
|
||||
load_stylesheet();
|
||||
|
||||
/* look for dynamic linker */
|
||||
try {
|
||||
static Genode::Rom_connection ldso_rom("ld.lib.so");
|
||||
Genode::Process::dynamic_linker(ldso_rom.dataspace());
|
||||
} catch (...) {
|
||||
PERR("ld.lib.so not found");
|
||||
}
|
||||
|
||||
QMember<Main_window> main_window;
|
||||
|
||||
main_window->show();
|
||||
|
@ -11,17 +11,10 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <cap_session/connection.h>
|
||||
#include <input/component.h>
|
||||
#include <os/config.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
/* qt_avplay includes */
|
||||
#include "avplay_policy.h"
|
||||
#include "filter_framebuffer_policy.h"
|
||||
#include "framebuffer_root.h"
|
||||
#include "input_service.h"
|
||||
#include "main_window.h"
|
||||
|
||||
|
||||
@ -30,49 +23,23 @@ using namespace Genode;
|
||||
|
||||
struct Framebuffer_filter
|
||||
{
|
||||
enum { MAX_FILTER_NAME_SIZE = 32 };
|
||||
char name[MAX_FILTER_NAME_SIZE];
|
||||
Genode::Number_of_bytes ram_quota;
|
||||
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;
|
||||
Service_registry *framebuffer_out_registry;
|
||||
Rpc_entrypoint *ep;
|
||||
Filter_framebuffer_policy *policy;
|
||||
Slave *slave;
|
||||
};
|
||||
|
||||
|
||||
Main_window::Main_window()
|
||||
:
|
||||
_control_bar(_input_session.event_queue())
|
||||
{
|
||||
/* look for dynamic linker */
|
||||
|
||||
try {
|
||||
static Rom_connection ldso_rom("ld.lib.so");
|
||||
Process::dynamic_linker(ldso_rom.dataspace());
|
||||
} catch (...) {
|
||||
PERR("ld.lib.so not found");
|
||||
}
|
||||
|
||||
/* get the name of the media file from the config file */
|
||||
enum { MAX_LEN_MEDIAFILE_NAME = 256 };
|
||||
static char mediafile[MAX_LEN_MEDIAFILE_NAME] = "mediafile";
|
||||
try {
|
||||
config()->xml_node().sub_node("mediafile").attribute("name").value(mediafile, sizeof(mediafile));
|
||||
} catch(...) {
|
||||
PWRN("no <mediafile> config node found, using \"mediafile\"");
|
||||
}
|
||||
|
||||
/* create local services */
|
||||
|
||||
enum { STACK_SIZE = 2*sizeof(addr_t)*1024 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint avplay_ep(&cap, STACK_SIZE, "avplay_ep");
|
||||
static Service_registry input_registry;
|
||||
static Service_registry nitpicker_framebuffer_registry;
|
||||
|
||||
static Input::Root input_root(&avplay_ep, env()->heap());
|
||||
static Local_service input_service(Input::Session::service_name(), &input_root);
|
||||
input_registry.insert(&input_service);
|
||||
avplay_ep.manage(&input_root);
|
||||
_input_registry.insert(&_input_service);
|
||||
_ep.manage(&_input_root);
|
||||
|
||||
/* find out which filtering framebuffer services to start and sort them in reverse order */
|
||||
|
||||
@ -90,15 +57,15 @@ Main_window::Main_window()
|
||||
|
||||
/* start the filtering framebuffer services */
|
||||
|
||||
Service_registry *framebuffer_in_registry = &nitpicker_framebuffer_registry;
|
||||
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->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_in_registry,
|
||||
*framebuffer_filter->framebuffer_out_registry);
|
||||
framebuffer_filter->slave = new Slave(*framebuffer_filter->ep,
|
||||
*framebuffer_filter->policy,
|
||||
framebuffer_filter->ram_quota);
|
||||
@ -106,17 +73,17 @@ Main_window::Main_window()
|
||||
}
|
||||
|
||||
Rpc_entrypoint *local_framebuffer_ep = framebuffer_filters.isEmpty() ?
|
||||
&avplay_ep :
|
||||
&_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);
|
||||
_nitpicker_framebuffer_registry.insert(&framebuffer_service);
|
||||
|
||||
/* start avplay */
|
||||
|
||||
static Avplay_policy avplay_policy(avplay_ep, input_registry, *framebuffer_in_registry, mediafile);
|
||||
static Genode::Slave avplay_slave(avplay_ep, avplay_policy, 32*1024*1024);
|
||||
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);
|
||||
|
||||
/* add widgets to layout */
|
||||
|
||||
|
@ -23,6 +23,14 @@
|
||||
#include <qoost/compound_widget.h>
|
||||
#include <qoost/qmember.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <input/root.h>
|
||||
#include <os/config.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include "control_bar.h"
|
||||
|
||||
|
||||
@ -32,6 +40,35 @@ class Main_window : public Compound_widget<QWidget, QVBoxLayout>
|
||||
|
||||
private:
|
||||
|
||||
struct Mediafile_name
|
||||
{
|
||||
/* get the name of the media file from the config file */
|
||||
enum { MAX_LEN_MEDIAFILE_NAME = 256 };
|
||||
char buf[MAX_LEN_MEDIAFILE_NAME];
|
||||
|
||||
Mediafile_name()
|
||||
{
|
||||
Genode::strncpy(buf, "mediafile", sizeof(buf));
|
||||
try {
|
||||
Genode::config()->xml_node().sub_node("mediafile")
|
||||
.attribute("name").value(buf, sizeof(buf));
|
||||
} catch(...) {
|
||||
PWRN("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;
|
||||
|
||||
Input::Session_component _input_session;
|
||||
Input::Root_component _input_root { _ep, _input_session };
|
||||
|
||||
Genode::Local_service _input_service { Input::Session::service_name(), &_input_root };
|
||||
|
||||
QMember<QNitpickerViewWidget> _avplay_widget;
|
||||
QMember<Control_bar> _control_bar;
|
||||
|
||||
|
@ -6,7 +6,6 @@ HEADERS = avplay_policy.h \
|
||||
main_window.h
|
||||
SOURCES = control_bar.cpp \
|
||||
framebuffer_session_component.cc \
|
||||
input_service.cpp \
|
||||
main.cpp \
|
||||
main_window.cpp
|
||||
RESOURCES = style.qrc
|
||||
|
@ -17,100 +17,61 @@
|
||||
#include <base/env.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <os/attached_ram_dataspace.h>
|
||||
#include <os/ring_buffer.h>
|
||||
#include <root/component.h>
|
||||
#include <input_session/input_session.h>
|
||||
#include <input/event.h>
|
||||
#include <input/event_queue.h>
|
||||
|
||||
|
||||
namespace Input {
|
||||
namespace Input { class Session_component; }
|
||||
|
||||
/********************
|
||||
** Input back end **
|
||||
********************/
|
||||
class Input::Session_component : public Genode::Rpc_object<Input::Session>
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Enable/disable input event handling
|
||||
*
|
||||
* \param enable enable (true) or disable (false) back end
|
||||
*
|
||||
* The front end informs the back end about when to start capturing input
|
||||
* events for an open session. Later, the back end may be deactivated on
|
||||
* session destruction.
|
||||
*/
|
||||
void event_handling(bool enable);
|
||||
Genode::Attached_ram_dataspace _ds { Genode::env()->ram_session(),
|
||||
Event_queue::QUEUE_SIZE*sizeof(Input::Event) };
|
||||
|
||||
/**
|
||||
* Check if an event is pending
|
||||
*/
|
||||
bool event_pending();
|
||||
Event_queue _event_queue;
|
||||
|
||||
/**
|
||||
* Wait for an event, Zzz...zz..
|
||||
*/
|
||||
Input::Event get_event();
|
||||
public:
|
||||
|
||||
/**
|
||||
* Return reference to event queue of the session
|
||||
*/
|
||||
Event_queue &event_queue() { return _event_queue; }
|
||||
|
||||
/**
|
||||
* Submit input event to event queue
|
||||
*
|
||||
* \throw Input::Event_queue::Overflow
|
||||
*/
|
||||
void submit(Input::Event event) { _event_queue.add(event); }
|
||||
|
||||
|
||||
/*****************************
|
||||
** Input service front end **
|
||||
*****************************/
|
||||
/******************************
|
||||
** Input::Session interface **
|
||||
******************************/
|
||||
|
||||
class Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
private:
|
||||
Genode::Dataspace_capability dataspace() override { return _ds.cap(); }
|
||||
|
||||
/*
|
||||
* Input event buffer that is shared with the client
|
||||
*/
|
||||
enum { MAX_EVENTS = 1000 };
|
||||
bool is_pending() const override { return !_event_queue.empty(); }
|
||||
|
||||
Genode::Attached_ram_dataspace _ev_ds;
|
||||
int flush() override
|
||||
{
|
||||
Input::Event *dst = _ds.local_addr<Input::Event>();
|
||||
|
||||
unsigned cnt = 0;
|
||||
for (; cnt < Event_queue::QUEUE_SIZE && !_event_queue.empty(); cnt++)
|
||||
*dst++ = _event_queue.get();
|
||||
|
||||
public:
|
||||
return cnt;
|
||||
}
|
||||
|
||||
Session_component()
|
||||
: _ev_ds(Genode::env()->ram_session(), MAX_EVENTS*sizeof(Event)) {
|
||||
event_handling(true); }
|
||||
|
||||
~Session_component() {
|
||||
event_handling(false); }
|
||||
|
||||
Genode::Dataspace_capability dataspace() { return _ev_ds.cap(); }
|
||||
|
||||
bool is_pending() const { return event_pending(); }
|
||||
|
||||
int flush()
|
||||
{
|
||||
/* dump events into event buffer dataspace */
|
||||
int i;
|
||||
Input::Event *ev_ds_buf = _ev_ds.local_addr<Input::Event>();
|
||||
for (i = 0; (i < MAX_EVENTS) && event_pending(); ++i)
|
||||
ev_ds_buf[i] = get_event();
|
||||
|
||||
/* return number of flushed events */
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for single-client root component
|
||||
*/
|
||||
typedef Genode::Root_component<Session_component, Genode::Single_client> Root_component;
|
||||
|
||||
|
||||
class Root : public Root_component
|
||||
{
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args) {
|
||||
return new (md_alloc()) Session_component(); }
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Rpc_entrypoint *session_ep,
|
||||
Genode::Allocator *md_alloc)
|
||||
: Root_component(session_ep, md_alloc) { }
|
||||
};
|
||||
}
|
||||
void sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_event_queue.sigh(sigh);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__INPUT__COMPONENT_H_ */
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2007-2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -14,57 +14,70 @@
|
||||
#ifndef _EVENT_QUEUE_H_
|
||||
#define _EVENT_QUEUE_H_
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <base/signal.h>
|
||||
#include <input/event.h>
|
||||
#include <os/ring_buffer.h>
|
||||
|
||||
/**
|
||||
* Input event queue
|
||||
*
|
||||
* We expect the client to fetch events circa each 10ms. The PS/2 driver queues
|
||||
* up to 255 events, which should be enough. Normally, PS/2 generates not more
|
||||
* than 16Kbit/s, which would correspond to ca. 66 mouse events per 10ms.
|
||||
*/
|
||||
class Event_queue
|
||||
namespace Input { class Event_queue; };
|
||||
|
||||
|
||||
class Input::Event_queue
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Input event queue
|
||||
*
|
||||
* We expect the client to fetch events circa each 10ms. The PS/2 driver
|
||||
* queues up to 255 events, which should be enough. Normally, PS/2
|
||||
* generates not more than 16Kbit/s, which would correspond to ca. 66 mouse
|
||||
* events per 10ms.
|
||||
*/
|
||||
enum { QUEUE_SIZE = 512U };
|
||||
|
||||
private:
|
||||
|
||||
bool _enabled;
|
||||
Ring_buffer<Input::Event, 512> _ev_queue;
|
||||
Ring_buffer<Input::Event, QUEUE_SIZE> _queue;
|
||||
|
||||
bool _enabled = false;
|
||||
|
||||
Genode::Signal_context_capability _sigh;
|
||||
|
||||
public:
|
||||
|
||||
Event_queue() : _enabled(false), _ev_queue() { }
|
||||
typedef typename Ring_buffer<Input::Event, QUEUE_SIZE>::Overflow Overflow;
|
||||
|
||||
void enable() { _enabled = true; }
|
||||
void disable() { _enabled = false; }
|
||||
void enabled(bool enabled) { _enabled = enabled; }
|
||||
|
||||
void add(Input::Event e)
|
||||
bool enabled() const { return _enabled; }
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh) { _sigh = sigh; }
|
||||
|
||||
void submit_signal()
|
||||
{
|
||||
if (!_enabled) return;
|
||||
|
||||
try {
|
||||
_ev_queue.add(e);
|
||||
} catch (Ring_buffer<Input::Event, 512>::Overflow) {
|
||||
PWRN("event buffer overflow");
|
||||
}
|
||||
if (_sigh.valid())
|
||||
Genode::Signal_transmitter(_sigh).submit();
|
||||
}
|
||||
|
||||
Input::Event get()
|
||||
/**
|
||||
* \throw Overflow
|
||||
*/
|
||||
void add(Input::Event ev, bool submit_signal_immediately = true)
|
||||
{
|
||||
if (_enabled)
|
||||
return _ev_queue.get();
|
||||
else
|
||||
return Input::Event();
|
||||
if (!_enabled)
|
||||
return;
|
||||
|
||||
_queue.add(ev);
|
||||
|
||||
if (submit_signal_immediately)
|
||||
submit_signal();
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
if (_enabled)
|
||||
return _ev_queue.empty();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
Input::Event get() { return _queue.get(); }
|
||||
|
||||
bool empty() const { return _queue.empty(); }
|
||||
|
||||
int avail_capacity() const { return _queue.avail_capacity(); }
|
||||
};
|
||||
|
||||
#endif /* _EVENT_QUEUE_H_ */
|
||||
|
70
repos/os/include/input/root.h
Normal file
70
repos/os/include/input/root.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* \brief Input root component
|
||||
* \author Norman Feske
|
||||
* \date 2014-05-31
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _INPUT__ROOT_H_
|
||||
#define _INPUT__ROOT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/static_root.h>
|
||||
#include <input/component.h>
|
||||
|
||||
|
||||
namespace Input { class Root_component; }
|
||||
|
||||
/*
|
||||
* This input root component tracks if the session has been opened. If a client
|
||||
* is connected, the 'Event_queue::enabled' gets enabled. This is useful to
|
||||
* omit the enqueuing of input events into the event queue before any client is
|
||||
* interested in receiving input events. If we would not drop such early input
|
||||
* events, the queue might overflow when input events are generated at boot
|
||||
* times.
|
||||
*/
|
||||
class Input::Root_component : public Genode::Static_root<Input::Session>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Rpc_entrypoint &_ep;
|
||||
Input::Session_component &_session;
|
||||
|
||||
public:
|
||||
|
||||
Root_component(Genode::Rpc_entrypoint &ep, Input::Session_component &session)
|
||||
:
|
||||
Static_root<Input::Session>(ep.manage(&session)),
|
||||
_ep(ep), _session(session)
|
||||
{ }
|
||||
|
||||
~Root_component()
|
||||
{
|
||||
_ep.dissolve(&_session);
|
||||
}
|
||||
|
||||
Genode::Capability<Genode::Session>
|
||||
session(Genode::Root::Session_args const &args,
|
||||
Genode::Affinity const &affinity) override
|
||||
{
|
||||
if (_session.event_queue().enabled())
|
||||
throw Root::Unavailable();
|
||||
|
||||
_session.event_queue().enabled(true);
|
||||
|
||||
return Static_root<Input::Session>::session(args, affinity);
|
||||
}
|
||||
|
||||
void close(Genode::Capability<Session>)
|
||||
{
|
||||
_session.event_queue().enabled(false);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INPUT__ROOT_H_ */
|
@ -24,14 +24,17 @@ namespace Input {
|
||||
explicit Session_client(Session_capability session)
|
||||
: Genode::Rpc_client<Session>(session) { }
|
||||
|
||||
Genode::Dataspace_capability dataspace() {
|
||||
Genode::Dataspace_capability dataspace() override {
|
||||
return call<Rpc_dataspace>(); }
|
||||
|
||||
bool is_pending() const {
|
||||
bool is_pending() const override {
|
||||
return call<Rpc_is_pending>(); }
|
||||
|
||||
int flush() {
|
||||
int flush() override {
|
||||
return call<Rpc_flush>(); }
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh) override {
|
||||
call<Rpc_sigh>(sigh); }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <dataspace/capability.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <session/session.h>
|
||||
#include <base/signal.h>
|
||||
|
||||
namespace Input {
|
||||
|
||||
@ -45,6 +46,11 @@ namespace Input {
|
||||
*/
|
||||
virtual int flush() = 0;
|
||||
|
||||
/**
|
||||
* Register signal handler to be notified on arrival of new input
|
||||
*/
|
||||
virtual void sigh(Genode::Signal_context_capability) = 0;
|
||||
|
||||
|
||||
/*********************
|
||||
** RPC declaration **
|
||||
@ -53,8 +59,9 @@ namespace Input {
|
||||
GENODE_RPC(Rpc_dataspace, Genode::Dataspace_capability, dataspace);
|
||||
GENODE_RPC(Rpc_is_pending, bool, is_pending);
|
||||
GENODE_RPC(Rpc_flush, int, flush);
|
||||
GENODE_RPC(Rpc_sigh, void, sigh, Genode::Signal_context_capability);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_is_pending, Rpc_flush);
|
||||
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_is_pending, Rpc_flush, Rpc_sigh);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,12 @@
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <root/component.h>
|
||||
#include <framebuffer_session/framebuffer_session.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <input/component.h>
|
||||
#include <input/root.h>
|
||||
|
||||
/* local includes */
|
||||
#include <input.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -44,85 +46,63 @@ static void *fb_ds_addr;
|
||||
** Implementation of the framebuffer service **
|
||||
***********************************************/
|
||||
|
||||
namespace Framebuffer {
|
||||
namespace Framebuffer { class Session_component; }
|
||||
|
||||
class Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
private:
|
||||
class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
private:
|
||||
|
||||
Mode _mode;
|
||||
Mode _mode;
|
||||
|
||||
Genode::Signal_context_capability _sync_sigh;
|
||||
Genode::Signal_context_capability _sync_sigh;
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component() : _mode(scr_width, scr_height, Mode::RGB565) { }
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component() : _mode(scr_width, scr_height, Mode::RGB565) { }
|
||||
|
||||
Genode::Dataspace_capability dataspace() override { return fb_ds_cap; }
|
||||
Genode::Dataspace_capability dataspace() override { return fb_ds_cap; }
|
||||
|
||||
Mode mode() const override { return _mode; }
|
||||
Mode mode() const override { return _mode; }
|
||||
|
||||
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_sync_sigh = sigh;
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_sync_sigh = sigh;
|
||||
}
|
||||
|
||||
void refresh(int x, int y, int w, int h) override
|
||||
{
|
||||
/* clip refresh area to screen boundaries */
|
||||
int x1 = Genode::max(x, 0);
|
||||
int y1 = Genode::max(y, 0);
|
||||
int x2 = Genode::min(x + w - 1, scr_width - 1);
|
||||
int y2 = Genode::min(y + h - 1, scr_height - 1);
|
||||
|
||||
if (x1 <= x2 && y1 <= y2) {
|
||||
|
||||
/* copy pixels from shared dataspace to sdl surface */
|
||||
const int start_offset = _mode.bytes_per_pixel()*(y1*scr_width + x1);
|
||||
const int line_len = _mode.bytes_per_pixel()*(x2 - x1 + 1);
|
||||
const int pitch = _mode.bytes_per_pixel()*scr_width;
|
||||
|
||||
char *src = (char *)fb_ds_addr + start_offset;
|
||||
char *dst = (char *)screen->pixels + start_offset;
|
||||
|
||||
for (int i = y1; i <= y2; i++, src += pitch, dst += pitch)
|
||||
Genode::memcpy(dst, src, line_len);
|
||||
|
||||
/* flush pixels in sdl window */
|
||||
SDL_UpdateRect(screen, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||
}
|
||||
|
||||
void refresh(int x, int y, int w, int h) override
|
||||
{
|
||||
/* clip refresh area to screen boundaries */
|
||||
int x1 = Genode::max(x, 0);
|
||||
int y1 = Genode::max(y, 0);
|
||||
int x2 = Genode::min(x + w - 1, scr_width - 1);
|
||||
int y2 = Genode::min(y + h - 1, scr_height - 1);
|
||||
|
||||
if (x1 <= x2 && y1 <= y2) {
|
||||
|
||||
/* copy pixels from shared dataspace to sdl surface */
|
||||
const int start_offset = _mode.bytes_per_pixel()*(y1*scr_width + x1);
|
||||
const int line_len = _mode.bytes_per_pixel()*(x2 - x1 + 1);
|
||||
const int pitch = _mode.bytes_per_pixel()*scr_width;
|
||||
|
||||
char *src = (char *)fb_ds_addr + start_offset;
|
||||
char *dst = (char *)screen->pixels + start_offset;
|
||||
|
||||
for (int i = y1; i <= y2; i++, src += pitch, dst += pitch)
|
||||
Genode::memcpy(dst, src, line_len);
|
||||
|
||||
/* flush pixels in sdl window */
|
||||
SDL_UpdateRect(screen, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||
}
|
||||
|
||||
if (_sync_sigh.valid())
|
||||
Genode::Signal_transmitter(_sync_sigh).submit();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for single-client root component
|
||||
*/
|
||||
typedef Genode::Root_component<Session_component, Genode::Single_client> Root_component;
|
||||
|
||||
|
||||
class Root : public Root_component
|
||||
{
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args) override {
|
||||
return new (md_alloc()) Session_component(); }
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Rpc_entrypoint *session_ep,
|
||||
Genode::Allocator *md_alloc)
|
||||
: Root_component(session_ep, md_alloc) { }
|
||||
};
|
||||
}
|
||||
if (_sync_sigh.valid())
|
||||
Genode::Signal_transmitter(_sync_sigh).submit();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -172,19 +152,21 @@ extern "C" int main(int, char**)
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "fb_ep");
|
||||
|
||||
/*
|
||||
* Let the entry point serve the framebuffer and input root interfaces
|
||||
*/
|
||||
static Framebuffer::Root framebuffer_root(&ep, env()->heap());
|
||||
static Input::Root input_root(&ep, env()->heap());
|
||||
static Input::Session_component input_session;
|
||||
static Input::Root_component input_root(ep, input_session);
|
||||
|
||||
static Framebuffer::Session_component fb_session;
|
||||
static Static_root<Framebuffer::Session> fb_root(ep.manage(&fb_session));
|
||||
|
||||
/*
|
||||
* Now, the root interfaces are ready to accept requests.
|
||||
* This is the right time to tell mummy about our services.
|
||||
*/
|
||||
env()->parent()->announce(ep.manage(&framebuffer_root));
|
||||
env()->parent()->announce(ep.manage(&fb_root));
|
||||
env()->parent()->announce(ep.manage(&input_root));
|
||||
|
||||
sleep_forever();
|
||||
for (;;)
|
||||
input_session.submit(wait_for_event());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -16,12 +16,11 @@
|
||||
|
||||
/* Genode */
|
||||
#include <input/keycodes.h>
|
||||
|
||||
/* Local */
|
||||
#include <input/component.h>
|
||||
|
||||
#include <base/printf.h>
|
||||
|
||||
/* local */
|
||||
#include <input.h>
|
||||
|
||||
/**
|
||||
* Convert SDL keycode to Genode keycode
|
||||
*/
|
||||
@ -139,14 +138,7 @@ static long convert_keycode(int sdl_keycode)
|
||||
};
|
||||
|
||||
|
||||
void Input::event_handling(bool enable) { }
|
||||
bool Input::event_pending() { return SDL_PollEvent(0); }
|
||||
|
||||
|
||||
/**
|
||||
* Wait for an event, Zzz...zz..
|
||||
*/
|
||||
Input::Event Input::get_event()
|
||||
Input::Event wait_for_event()
|
||||
{
|
||||
using namespace Input;
|
||||
|
||||
|
24
repos/os/src/drivers/framebuffer/sdl/input.h
Normal file
24
repos/os/src/drivers/framebuffer/sdl/input.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* \brief SDL input support
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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 _INPUT_H_
|
||||
#define _INPUT_H_
|
||||
|
||||
#include <input/event.h>
|
||||
|
||||
/**
|
||||
* Wait for an event, Zzz...zz..
|
||||
*/
|
||||
Input::Event wait_for_event();
|
||||
|
||||
#endif /* _INPUT_H_ */
|
@ -3,13 +3,4 @@ LIBS = lx_hybrid
|
||||
REQUIRES = linux sdl
|
||||
SRC_CC = fb_sdl.cc input.cc
|
||||
LX_LIBS = sdl
|
||||
|
||||
#
|
||||
# Explicitly add host headers to the include-search location. Even though this
|
||||
# path happens to be added via the 'lx_hybrid' library via the 'HOST_INC_DIR'
|
||||
# variable, we want to give /usr/include preference for resolving 'SDL/*'
|
||||
# headers. Otherwise, if libSDL is prepared in 'libports', the build system
|
||||
# would pull-in the SDL headers from libports.
|
||||
#
|
||||
INC_DIR += /usr/include
|
||||
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
@ -15,6 +15,7 @@
|
||||
/* Genode */
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/signal.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <root/component.h>
|
||||
#include <cap_session/connection.h>
|
||||
@ -41,15 +42,17 @@ namespace Input {
|
||||
{
|
||||
public:
|
||||
|
||||
Dataspace_capability dataspace() { return ev_ds_cap; }
|
||||
Dataspace_capability dataspace() override { return ev_ds_cap; }
|
||||
|
||||
bool is_pending() const { return 0; }
|
||||
bool is_pending() const override { return 0; }
|
||||
|
||||
int flush()
|
||||
int flush() override
|
||||
{
|
||||
/* return number of flushed events */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sigh(Genode::Signal_context_capability) override { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -13,41 +13,21 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode */
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <root/component.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <platform_session/connection.h>
|
||||
#include <input/component.h>
|
||||
#include <input/root.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
static Event_queue ev_queue;
|
||||
|
||||
namespace Input {
|
||||
|
||||
/*
|
||||
* Event handling is disabled on queue creation and will be enabled later if a
|
||||
* session is created.
|
||||
*/
|
||||
void event_handling(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
ev_queue.enable();
|
||||
else
|
||||
ev_queue.disable();
|
||||
}
|
||||
|
||||
bool event_pending() { return !ev_queue.empty(); }
|
||||
Event get_event() { return ev_queue.get(); }
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* initialize server entry point */
|
||||
@ -55,23 +35,25 @@ int main(int argc, char **argv)
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "input_ep");
|
||||
|
||||
static Input::Session_component session;
|
||||
|
||||
Platform::Connection plat_drv;
|
||||
switch (plat_drv.revision()) {
|
||||
case Platform::Session::SMD:
|
||||
plat_drv.enable(Platform::Session::I2C_2);
|
||||
plat_drv.enable(Platform::Session::I2C_3);
|
||||
plat_drv.enable(Platform::Session::BUTTONS);
|
||||
Input::Tablet_driver::factory(ev_queue);
|
||||
Input::Tablet_driver::factory(session.event_queue());
|
||||
break;
|
||||
default:
|
||||
PWRN("No input driver available for this board");
|
||||
}
|
||||
|
||||
/* entry point serving input root interface */
|
||||
static Input::Root input_root(&ep, env()->heap());
|
||||
static Input::Root_component root(ep, session);
|
||||
|
||||
/* tell parent about the service */
|
||||
env()->parent()->announce(ep.manage(&input_root));
|
||||
env()->parent()->announce(ep.manage(&root));
|
||||
|
||||
/* main's done - go to sleep */
|
||||
sleep_forever();
|
||||
|
@ -11,12 +11,15 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <input/component.h>
|
||||
#include <input/root.h>
|
||||
#include <cap_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include "ps2_keyboard.h"
|
||||
#include "ps2_mouse.h"
|
||||
#include "irq_handler.h"
|
||||
@ -24,26 +27,6 @@
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
static Event_queue ev_queue;
|
||||
|
||||
namespace Input {
|
||||
|
||||
/*
|
||||
* Event handling is disabled on queue creation and will be enabled later if a
|
||||
* session is created.
|
||||
*/
|
||||
void event_handling(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
ev_queue.enable();
|
||||
else
|
||||
ev_queue.disable();
|
||||
}
|
||||
|
||||
bool event_pending() { return !ev_queue.empty(); }
|
||||
Event get_event() { return ev_queue.get(); }
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -52,12 +35,6 @@ int main(int argc, char **argv)
|
||||
Serial_interface *kbd = pl050.kbd_interface();
|
||||
Serial_interface *aux = pl050.aux_interface();
|
||||
|
||||
Ps2_mouse ps2_mouse(*aux, ev_queue);
|
||||
Ps2_keyboard ps2_keybd(*kbd, ev_queue, true);
|
||||
|
||||
Irq_handler ps2_mouse_irq(PL050_MOUSE_IRQ, aux, ps2_mouse);
|
||||
Irq_handler ps2_keybd_irq(PL050_KEYBD_IRQ, kbd, ps2_keybd);
|
||||
|
||||
/*
|
||||
* Initialize server entry point
|
||||
*/
|
||||
@ -65,11 +42,19 @@ int main(int argc, char **argv)
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "ps2_ep");
|
||||
|
||||
static Input::Session_component session;
|
||||
static Input::Root_component root(ep, session);
|
||||
|
||||
Ps2_mouse ps2_mouse(*aux, session.event_queue());
|
||||
Ps2_keyboard ps2_keybd(*kbd, session.event_queue(), true);
|
||||
|
||||
Irq_handler ps2_mouse_irq(PL050_MOUSE_IRQ, aux, ps2_mouse);
|
||||
Irq_handler ps2_keybd_irq(PL050_KEYBD_IRQ, kbd, ps2_keybd);
|
||||
|
||||
/*
|
||||
* Let the entry point serve the input root interface
|
||||
*/
|
||||
static Input::Root input_root(&ep, env()->heap());
|
||||
env()->parent()->announce(ep.manage(&input_root));
|
||||
env()->parent()->announce(ep.manage(&root));
|
||||
|
||||
Genode::sleep_forever();
|
||||
return 0;
|
||||
|
@ -30,9 +30,9 @@ class Ps2_keyboard : public Input_driver
|
||||
static const bool verbose = false;
|
||||
static const bool verbose_scan_codes = false;
|
||||
|
||||
Serial_interface &_kbd;
|
||||
Event_queue &_ev_queue;
|
||||
bool _xlate_mode;
|
||||
Serial_interface &_kbd;
|
||||
Input::Event_queue &_ev_queue;
|
||||
bool _xlate_mode;
|
||||
|
||||
/**
|
||||
* Array for tracking the current keyboard state
|
||||
@ -363,7 +363,7 @@ class Ps2_keyboard : public Input_driver
|
||||
* If 'xlate_mode' is true, we do not attempt to manually switch the
|
||||
* keyboard to scan code set 2 but just decode the scan-code set 1.
|
||||
*/
|
||||
Ps2_keyboard(Serial_interface &kbd, Event_queue &ev_queue, bool xlate_mode)
|
||||
Ps2_keyboard(Serial_interface &kbd, Input::Event_queue &ev_queue, bool xlate_mode)
|
||||
:
|
||||
_kbd(kbd), _ev_queue(ev_queue), _xlate_mode(xlate_mode)
|
||||
{
|
||||
|
@ -71,12 +71,12 @@ class Ps2_mouse : public Input_driver
|
||||
|
||||
static const bool verbose = false;
|
||||
|
||||
Serial_interface &_aux;
|
||||
Event_queue &_ev_queue;
|
||||
Serial_interface &_aux;
|
||||
Input::Event_queue &_ev_queue;
|
||||
|
||||
Type _type;
|
||||
Type _type;
|
||||
|
||||
bool _button_state[NUM_BUTTONS];
|
||||
bool _button_state[NUM_BUTTONS];
|
||||
|
||||
unsigned char _packet[MAX_PACKET_LEN];
|
||||
int _packet_len;
|
||||
@ -149,9 +149,10 @@ class Ps2_mouse : public Input_driver
|
||||
|
||||
public:
|
||||
|
||||
Ps2_mouse(Serial_interface &aux, Event_queue &ev_queue)
|
||||
Ps2_mouse(Serial_interface &aux, Input::Event_queue &ev_queue)
|
||||
:
|
||||
_aux(aux), _ev_queue(ev_queue), _type(PS2),
|
||||
_aux(aux),
|
||||
_ev_queue(ev_queue), _type(PS2),
|
||||
_packet_len(PS2_PACKET_LEN), _packet_idx(0)
|
||||
{
|
||||
for (unsigned i = 0; i < NUM_BUTTONS; ++i)
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <input/component.h>
|
||||
#include <input/root.h>
|
||||
#include <cap_session/connection.h>
|
||||
|
||||
#include "i8042.h"
|
||||
@ -24,26 +25,6 @@
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
static Event_queue ev_queue;
|
||||
|
||||
namespace Input {
|
||||
|
||||
/*
|
||||
* Event handling is disabled on queue creation and will be enabled later if a
|
||||
* session is created.
|
||||
*/
|
||||
void event_handling(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
ev_queue.enable();
|
||||
else
|
||||
ev_queue.disable();
|
||||
}
|
||||
|
||||
bool event_pending() { return !ev_queue.empty(); }
|
||||
Event get_event() { return ev_queue.get(); }
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -52,24 +33,23 @@ int main(int argc, char **argv)
|
||||
Serial_interface *kbd = i8042.kbd_interface();
|
||||
Serial_interface *aux = i8042.aux_interface();
|
||||
|
||||
Ps2_mouse ps2_mouse(*aux, ev_queue);
|
||||
Ps2_keyboard ps2_keybd(*kbd, ev_queue, i8042.kbd_xlate());
|
||||
/*
|
||||
* Initialize server entry point
|
||||
*/
|
||||
enum { STACK_SIZE = 4096 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "ps2_ep");
|
||||
|
||||
static Input::Session_component session;
|
||||
static Input::Root_component root(ep, session);
|
||||
|
||||
Ps2_mouse ps2_mouse(*aux, session.event_queue());
|
||||
Ps2_keyboard ps2_keybd(*kbd, session.event_queue(), i8042.kbd_xlate());
|
||||
|
||||
Irq_handler ps2_mouse_irq(12, ps2_mouse);
|
||||
Irq_handler ps2_keybd_irq( 1, ps2_keybd);
|
||||
|
||||
/*
|
||||
* Initialize server entry point
|
||||
*/
|
||||
enum { STACK_SIZE = sizeof(addr_t)*1024 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "ps2_ep");
|
||||
|
||||
/*
|
||||
* Let the entry point serve the input root interface
|
||||
*/
|
||||
static Input::Root input_root(&ep, env()->heap());
|
||||
env()->parent()->announce(ep.manage(&input_root));
|
||||
env()->parent()->announce(ep.manage(&root));
|
||||
|
||||
Genode::sleep_forever();
|
||||
return 0;
|
||||
|
@ -66,11 +66,11 @@ namespace Input {
|
||||
** Input session interface **
|
||||
*****************************/
|
||||
|
||||
Dataspace_capability dataspace() { return _real_input.dataspace(); }
|
||||
Dataspace_capability dataspace() override { return _real_input.dataspace(); }
|
||||
|
||||
bool is_pending() const { return _real_input.is_pending(); }
|
||||
bool is_pending() const override { return _real_input.is_pending(); }
|
||||
|
||||
int flush()
|
||||
int flush() override
|
||||
{
|
||||
/* translate mouse position to child's coordinate system */
|
||||
Transformer::Delta delta = _transformer.delta();
|
||||
@ -97,6 +97,11 @@ namespace Input {
|
||||
|
||||
return num_ev;
|
||||
}
|
||||
|
||||
void sigh(Signal_context_capability sigh) override
|
||||
{
|
||||
_real_input.sigh(sigh);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -82,11 +82,11 @@ namespace Input {
|
||||
** Input session interface **
|
||||
*****************************/
|
||||
|
||||
Genode::Dataspace_capability dataspace() { return _to_input_ds; }
|
||||
Genode::Dataspace_capability dataspace() override { return _to_input_ds; }
|
||||
|
||||
bool is_pending() const { return _from_input->is_pending(); }
|
||||
bool is_pending() const override { return _from_input->is_pending(); }
|
||||
|
||||
int flush()
|
||||
int flush() override
|
||||
{
|
||||
/* flush events at input session */
|
||||
int num_events = _from_input->flush();
|
||||
@ -103,6 +103,11 @@ namespace Input {
|
||||
}
|
||||
return num_events;
|
||||
}
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_from_input->sigh(sigh);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -257,8 +257,19 @@ class Input::Session_component : public Genode::Rpc_object<Session>
|
||||
Event _ev_buf[MAX_EVENTS];
|
||||
unsigned _num_ev = 0;
|
||||
|
||||
Signal_context_capability _sigh;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Wake up client
|
||||
*/
|
||||
void submit_signal()
|
||||
{
|
||||
if (_sigh.valid())
|
||||
Signal_transmitter(_sigh).submit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue event into local event buffer of the input session
|
||||
*/
|
||||
@ -269,6 +280,8 @@ class Input::Session_component : public Genode::Rpc_object<Session>
|
||||
|
||||
/* insert event into local event buffer */
|
||||
_ev_buf[_num_ev++] = *ev;
|
||||
|
||||
submit_signal();
|
||||
}
|
||||
|
||||
|
||||
@ -276,11 +289,11 @@ class Input::Session_component : public Genode::Rpc_object<Session>
|
||||
** Input session interface **
|
||||
*****************************/
|
||||
|
||||
Dataspace_capability dataspace() { return _ev_ram_ds.cap(); }
|
||||
Dataspace_capability dataspace() override { return _ev_ram_ds.cap(); }
|
||||
|
||||
bool is_pending() const { return _num_ev > 0; }
|
||||
bool is_pending() const override { return _num_ev > 0; }
|
||||
|
||||
int flush()
|
||||
int flush() override
|
||||
{
|
||||
unsigned ev_cnt;
|
||||
|
||||
@ -292,6 +305,8 @@ class Input::Session_component : public Genode::Rpc_object<Session>
|
||||
_num_ev = 0;
|
||||
return ev_cnt;
|
||||
}
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh) override { _sigh = sigh; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -54,6 +54,25 @@ class Avplay_policy : public QObject, public Genode::Slave_policy
|
||||
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);
|
||||
|
@ -17,22 +17,22 @@
|
||||
/* Qoost includes */
|
||||
#include <qoost/style.h>
|
||||
|
||||
#include "input_service.h"
|
||||
/* local includes */
|
||||
#include "main_window.h"
|
||||
|
||||
|
||||
void Control_bar::_rewind()
|
||||
{
|
||||
/* mouse click at horizontal position 0 */
|
||||
ev_queue.add(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0));
|
||||
ev_queue.add(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 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));
|
||||
}
|
||||
|
||||
|
||||
void Control_bar::_pause_resume()
|
||||
{
|
||||
ev_queue.add(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
ev_queue.add(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0));
|
||||
_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));
|
||||
|
||||
_playing = !_playing;
|
||||
if (_playing)
|
||||
@ -51,8 +51,9 @@ void Control_bar::_stop()
|
||||
}
|
||||
|
||||
|
||||
Control_bar::Control_bar()
|
||||
: _playing(true)
|
||||
Control_bar::Control_bar(Input::Event_queue &event_queue)
|
||||
:
|
||||
_event_queue(event_queue), _playing(true)
|
||||
{
|
||||
update_style_id(_play_pause_button, "play");
|
||||
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include <qoost/compound_widget.h>
|
||||
#include <qoost/qmember.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/event_queue.h>
|
||||
|
||||
struct Play_pause_button : QPushButton { Q_OBJECT };
|
||||
struct Stop_button : QPushButton { Q_OBJECT };
|
||||
struct Volume_label : QLabel { Q_OBJECT };
|
||||
@ -32,6 +35,8 @@ class Control_bar : public Compound_widget<QWidget, QHBoxLayout>
|
||||
|
||||
private:
|
||||
|
||||
Input::Event_queue &_event_queue;
|
||||
|
||||
QMember<Play_pause_button> _play_pause_button;
|
||||
QMember<Stop_button> _stop_button;
|
||||
QMember<Volume_label> _volume_label;
|
||||
@ -48,7 +53,7 @@ class Control_bar : public Compound_widget<QWidget, QHBoxLayout>
|
||||
|
||||
public:
|
||||
|
||||
Control_bar();
|
||||
Control_bar(Input::Event_queue &event_queue);
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* \brief Input service
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <input/component.h>
|
||||
|
||||
#include "input_service.h"
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
Event_queue ev_queue;
|
||||
|
||||
|
||||
namespace Input {
|
||||
|
||||
/*
|
||||
* Event handling is disabled on queue creation and will be enabled later if a
|
||||
* session is created.
|
||||
*/
|
||||
void event_handling(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
ev_queue.enable();
|
||||
else
|
||||
ev_queue.disable();
|
||||
}
|
||||
|
||||
bool event_pending() { return !ev_queue.empty(); }
|
||||
Event get_event() { return ev_queue.get(); }
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* \brief Input service
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-03-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _INPUT_SERVICE_H_
|
||||
#define _INPUT_SERVICE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/event_queue.h>
|
||||
|
||||
extern Event_queue ev_queue;
|
||||
|
||||
extern void create_input_service();
|
||||
|
||||
#endif /* _INPUT_SERVICE_H_ */
|
@ -17,6 +17,11 @@
|
||||
/* qt_avplay includes */
|
||||
#include "main_window.h"
|
||||
|
||||
/* Genode includes */
|
||||
#include <rom_session/connection.h>
|
||||
#include <base/process.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
|
||||
static inline void load_stylesheet()
|
||||
{
|
||||
@ -37,6 +42,14 @@ int main(int argc, char *argv[])
|
||||
|
||||
load_stylesheet();
|
||||
|
||||
/* look for dynamic linker */
|
||||
try {
|
||||
static Genode::Rom_connection ldso_rom("ld.lib.so");
|
||||
Genode::Process::dynamic_linker(ldso_rom.dataspace());
|
||||
} catch (...) {
|
||||
PERR("ld.lib.so not found");
|
||||
}
|
||||
|
||||
QMember<Main_window> main_window;
|
||||
|
||||
main_window->show();
|
||||
|
@ -11,17 +11,10 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <cap_session/connection.h>
|
||||
#include <input/component.h>
|
||||
#include <os/config.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
/* qt_avplay includes */
|
||||
#include "avplay_policy.h"
|
||||
#include "filter_framebuffer_policy.h"
|
||||
#include "framebuffer_root.h"
|
||||
#include "input_service.h"
|
||||
#include "main_window.h"
|
||||
|
||||
|
||||
@ -30,49 +23,23 @@ using namespace Genode;
|
||||
|
||||
struct Framebuffer_filter
|
||||
{
|
||||
enum { MAX_FILTER_NAME_SIZE = 32 };
|
||||
char name[MAX_FILTER_NAME_SIZE];
|
||||
Genode::Number_of_bytes ram_quota;
|
||||
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;
|
||||
Service_registry *framebuffer_out_registry;
|
||||
Rpc_entrypoint *ep;
|
||||
Filter_framebuffer_policy *policy;
|
||||
Slave *slave;
|
||||
};
|
||||
|
||||
|
||||
Main_window::Main_window()
|
||||
:
|
||||
_control_bar(_input_session.event_queue())
|
||||
{
|
||||
/* look for dynamic linker */
|
||||
|
||||
try {
|
||||
static Rom_connection ldso_rom("ld.lib.so");
|
||||
Process::dynamic_linker(ldso_rom.dataspace());
|
||||
} catch (...) {
|
||||
PERR("ld.lib.so not found");
|
||||
}
|
||||
|
||||
/* get the name of the media file from the config file */
|
||||
enum { MAX_LEN_MEDIAFILE_NAME = 256 };
|
||||
static char mediafile[MAX_LEN_MEDIAFILE_NAME] = "mediafile";
|
||||
try {
|
||||
config()->xml_node().sub_node("mediafile").attribute("name").value(mediafile, sizeof(mediafile));
|
||||
} catch(...) {
|
||||
PWRN("no <mediafile> config node found, using \"mediafile\"");
|
||||
}
|
||||
|
||||
/* create local services */
|
||||
|
||||
enum { STACK_SIZE = 2*sizeof(addr_t)*1024 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint avplay_ep(&cap, STACK_SIZE, "avplay_ep");
|
||||
static Service_registry input_registry;
|
||||
static Service_registry nitpicker_framebuffer_registry;
|
||||
|
||||
static Input::Root input_root(&avplay_ep, env()->heap());
|
||||
static Local_service input_service(Input::Session::service_name(), &input_root);
|
||||
input_registry.insert(&input_service);
|
||||
avplay_ep.manage(&input_root);
|
||||
_input_registry.insert(&_input_service);
|
||||
_ep.manage(&_input_root);
|
||||
|
||||
/* find out which filtering framebuffer services to start and sort them in reverse order */
|
||||
|
||||
@ -90,15 +57,15 @@ Main_window::Main_window()
|
||||
|
||||
/* start the filtering framebuffer services */
|
||||
|
||||
Service_registry *framebuffer_in_registry = &nitpicker_framebuffer_registry;
|
||||
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->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_in_registry,
|
||||
*framebuffer_filter->framebuffer_out_registry);
|
||||
framebuffer_filter->slave = new Slave(*framebuffer_filter->ep,
|
||||
*framebuffer_filter->policy,
|
||||
framebuffer_filter->ram_quota);
|
||||
@ -106,17 +73,17 @@ Main_window::Main_window()
|
||||
}
|
||||
|
||||
Rpc_entrypoint *local_framebuffer_ep = framebuffer_filters.isEmpty() ?
|
||||
&avplay_ep :
|
||||
&_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);
|
||||
_nitpicker_framebuffer_registry.insert(&framebuffer_service);
|
||||
|
||||
/* start avplay */
|
||||
|
||||
static Avplay_policy avplay_policy(avplay_ep, input_registry, *framebuffer_in_registry, mediafile);
|
||||
static Genode::Slave avplay_slave(avplay_ep, avplay_policy, 32*1024*1024);
|
||||
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);
|
||||
|
||||
/* add widgets to layout */
|
||||
|
||||
|
@ -23,6 +23,14 @@
|
||||
#include <qoost/compound_widget.h>
|
||||
#include <qoost/qmember.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <input/root.h>
|
||||
#include <os/config.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include "control_bar.h"
|
||||
|
||||
|
||||
@ -32,6 +40,35 @@ class Main_window : public Compound_widget<QWidget, QVBoxLayout>
|
||||
|
||||
private:
|
||||
|
||||
struct Mediafile_name
|
||||
{
|
||||
/* get the name of the media file from the config file */
|
||||
enum { MAX_LEN_MEDIAFILE_NAME = 256 };
|
||||
char buf[MAX_LEN_MEDIAFILE_NAME];
|
||||
|
||||
Mediafile_name()
|
||||
{
|
||||
Genode::strncpy(buf, "mediafile", sizeof(buf));
|
||||
try {
|
||||
Genode::config()->xml_node().sub_node("mediafile")
|
||||
.attribute("name").value(buf, sizeof(buf));
|
||||
} catch(...) {
|
||||
PWRN("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;
|
||||
|
||||
Input::Session_component _input_session;
|
||||
Input::Root_component _input_root { _ep, _input_session };
|
||||
|
||||
Genode::Local_service _input_service { Input::Session::service_name(), &_input_root };
|
||||
|
||||
QMember<QNitpickerViewWidget> _avplay_widget;
|
||||
QMember<Control_bar> _control_bar;
|
||||
|
||||
|
@ -6,7 +6,6 @@ HEADERS = avplay_policy.h \
|
||||
main_window.h
|
||||
SOURCES = control_bar.cpp \
|
||||
framebuffer_session_component.cc \
|
||||
input_service.cpp \
|
||||
main.cpp \
|
||||
main_window.cpp
|
||||
RESOURCES = style.qrc
|
||||
|
@ -6,4 +6,4 @@ include $(QT4_REP_DIR)/src/app/tmpl/target_defaults.inc
|
||||
|
||||
include $(QT4_REP_DIR)/src/app/tmpl/target_final.inc
|
||||
|
||||
LIBS += qnitpickerviewwidget
|
||||
LIBS += qnitpickerviewwidget qoost
|
||||
|
Loading…
x
Reference in New Issue
Block a user