nitpicker: Reworked session interface

This patch changes nitpicker's session interface to use session-local
view handles instead of view capabilities. This enables the batching
of multiple view operations into one atomic update.
This commit is contained in:
Norman Feske 2014-06-06 17:26:53 +02:00
parent 24869bd3ff
commit 91e01411a4
23 changed files with 887 additions and 456 deletions

View File

@ -16,7 +16,6 @@
/* Genode includes */
#include <nitpicker_session/connection.h>
#include <nitpicker_view/client.h>
#include <os/pixel_rgb565.h>
/* Scout includes */
@ -53,19 +52,25 @@ class Scout::Nitpicker_graphics_backend : public Graphics_backend
void *_fb_local_base = { _map_fb_ds() };
Point _position;
Area _view_size;
Nitpicker::View_client _view;
Canvas_base *_canvas[2];
bool _flip_state = { false };
typedef Nitpicker::Session::View_handle View_handle;
Point _position;
Area _view_size;
View_handle _view;
Canvas_base *_canvas[2];
bool _flip_state = { false };
void _update_viewport()
{
_view.viewport(_position.x(), _position.y(),
_view_size.w(), _view_size.h(),
0,
_flip_state ? -_max_size.h() : 0,
true);
typedef Nitpicker::Session::Command Command;
Nitpicker::Rect rect(_position, _view_size);
_nitpicker.enqueue<Command::Geometry>(_view, rect);
Nitpicker::Point offset(0, _flip_state ? -_max_size.h() : 0);
_nitpicker.enqueue<Command::Offset>(_view, offset);
_nitpicker.execute();
}
void _refresh_view(Rect rect)
@ -146,7 +151,9 @@ class Scout::Nitpicker_graphics_backend : public Graphics_backend
void bring_to_front()
{
_view.stack(Nitpicker::View_capability(), true, true);
typedef Nitpicker::Session::Command Command;
_nitpicker.enqueue<Command::To_front>(_view);
_nitpicker.execute();
}
void view_area(Area area)

View File

@ -16,7 +16,6 @@
/* Genode includes */
#include <nitpicker_session/connection.h>
#include <nitpicker_view/client.h>
#include <framebuffer_session/client.h>
#include <base/printf.h>
#include <base/sleep.h>
@ -241,8 +240,7 @@ int main(int argc, char **argv)
nitpicker.buffer(mode, false);
static Framebuffer::Session_client framebuffer(nitpicker.framebuffer_session());
Nitpicker::View_capability view_cap = nitpicker.create_view();
static Nitpicker::View_client view(view_cap);
Nitpicker::Session::View_handle view_handle = nitpicker.create_view();
if (mode.format() != Framebuffer::Mode::RGB565) {
printf("Error: Color mode %d not supported\n", (int)mode.format());
@ -256,9 +254,14 @@ int main(int argc, char **argv)
convert_png_to_rgb565(png_data, fb, mode.width(), mode.height());
/* display view behind all others */
nitpicker.background(view_cap);
view.viewport(0, 0, mode.width(), mode.height(), 0, 0, false);
view.stack(Nitpicker::View_capability(), false, false);
typedef Nitpicker::Session::Command Command;
nitpicker.enqueue<Command::Background>(view_handle);
Nitpicker::Rect rect(Nitpicker::Point(),
Nitpicker::Area(mode.width(), mode.height()));
nitpicker.enqueue<Command::Geometry>(view_handle, rect);
nitpicker.enqueue<Command::To_back>(view_handle);
nitpicker.execute();
framebuffer.refresh(0, 0, mode.width(), mode.height());
sleep_forever();

View File

@ -21,7 +21,6 @@
#include <cap_session/connection.h>
#include <log_session/log_session.h>
#include <nitpicker_session/connection.h>
#include <nitpicker_view/client.h>
#include <timer_session/connection.h>
#include <input/event.h>
#include <os/pixel_rgb565.h>
@ -343,40 +342,42 @@ class Log_view
{
private:
Nitpicker::View_capability _cap;
Nitpicker::Session_client &_nitpicker;
Nitpicker::Point _pos;
Nitpicker::Area _size;
Nitpicker::Session::View_handle _handle;
int _x, _y, _w, _h;
typedef Nitpicker::Session::Command Command;
public:
Log_view(Nitpicker::Session *nitpicker,
int x, int y, int w, int h)
Log_view(Nitpicker::Session_client &nitpicker, Nitpicker::Rect geometry)
:
_x(x), _y(y), _w(w), _h(h)
_nitpicker(nitpicker),
_pos(geometry.p1()),
_size(geometry.area()),
_handle(nitpicker.create_view())
{
using namespace Nitpicker;
_cap = nitpicker->create_view();
View_client(_cap).viewport(_x, _y, _w, _h, 0, 0, true);
View_client(_cap).stack(Nitpicker::View_capability(), true, true);
move(_pos);
top();
}
void top()
{
Nitpicker::View_client(_cap).stack(Nitpicker::View_capability(), true, true);
_nitpicker.enqueue<Command::To_front>(_handle);
_nitpicker.execute();
}
void move(int x, int y)
void move(Nitpicker::Point pos)
{
_x = x, _y = y;
Nitpicker::View_client(_cap).viewport(_x, _y, _w, _h, 0, 0, true);
_pos = pos;
Nitpicker::Rect rect(_pos, _size);
_nitpicker.enqueue<Command::Geometry>(_handle, rect);
_nitpicker.execute();
}
/**
* Accessors
*/
int x() { return _x; }
int y() { return _y; }
Nitpicker::Point pos() const { return _pos; }
};
@ -424,7 +425,9 @@ int main(int argc, char **argv)
canvas.clip(::Rect(::Point(1, 1), ::Area(log_win_w - 2, log_win_h - 2)));
/* create view for log window */
Log_view log_view(&nitpicker, 20, 20, log_win_w, log_win_h);
Nitpicker::Rect log_view_geometry(Nitpicker::Point(20, 20),
Nitpicker::Area(log_win_w, log_win_h));
Log_view log_view(nitpicker, log_view_geometry);
/* create root interface for service */
static Log_root_component log_root(&ep, &sliced_heap, &log_window);
@ -434,7 +437,8 @@ int main(int argc, char **argv)
/* handle input events */
Input::Event *ev_buf = env()->rm_session()->attach(nitpicker.input()->dataspace());
int omx = 0, omy = 0, key_cnt = 0;
Nitpicker::Point old_mouse_pos;
unsigned key_cnt = 0;
while (1) {
while (!nitpicker.input()->is_pending()) {
@ -450,16 +454,17 @@ int main(int argc, char **argv)
if (ev->type() == Input::Event::PRESS) key_cnt++;
if (ev->type() == Input::Event::RELEASE) key_cnt--;
Nitpicker::Point mouse_pos(ev->ax(), ev->ay());
/* move view */
if (ev->type() == Input::Event::MOTION && key_cnt > 0)
log_view.move(log_view.x() + ev->ax() - omx,
log_view.y() + ev->ay() - omy);
log_view.move(log_view.pos() + mouse_pos - old_mouse_pos);
/* find selected view and bring it to front */
if (ev->type() == Input::Event::PRESS && key_cnt == 1)
log_view.top();
omx = ev->ax(); omy = ev->ay();
old_mouse_pos = mouse_pos;
}
}
return 0;

View File

@ -19,8 +19,7 @@
#include <qwindowsystem_qws.h>
#endif
#include <nitpicker_view/capability.h>
#include <nitpicker_view/client.h>
#include <nitpicker_session/client.h>
class QNitpickerViewWidget : public QWidget
{
@ -38,7 +37,10 @@ private slots:
void destroyed(QObject *obj = 0);
protected:
Nitpicker::View_client *vc;
Nitpicker::Session_client *nitpicker;
Nitpicker::Session::View_handle view_handle;
int orig_w;
int orig_h;
int orig_buf_x;
@ -51,7 +53,9 @@ protected:
public:
QNitpickerViewWidget(QWidget *parent =0);
~QNitpickerViewWidget();
void setNitpickerView(Nitpicker::View_capability view, int buf_x, int buf_y, int w, int h);
void setNitpickerView(Nitpicker::Session_client *nitpicker,
Nitpicker::Session::View_handle view_handle,
int buf_x, int buf_y, int w, int h);
};
#endif // QNITPICKERVIEWWIDGET_H

View File

@ -13,11 +13,12 @@
/* Genode includes */
#include <base/env.h>
#include <nitpicker_view/client.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 {
@ -49,9 +50,22 @@ namespace Framebuffer {
_limited_size(session_arg(args, "fb_height"), max_height),
_nitpicker.mode().format());
_nitpicker.buffer(mode, false);
Nitpicker::View_capability nitpicker_view_cap = _nitpicker.create_view();
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_view_cap,
nitpicker_view_widget.setNitpickerView(&_nitpicker,
nitpicker_view_handle,
0, 0,
_mode.width(),
_mode.height());

View File

@ -20,26 +20,29 @@
QNitpickerViewWidget::QNitpickerViewWidget(QWidget *parent)
: QWidget(parent), vc(0), orig_w(0), orig_h(0), orig_buf_x(0), orig_buf_y(0)
: QWidget(parent), nitpicker(0), orig_w(0), orig_h(0), orig_buf_x(0), orig_buf_y(0)
{
}
void QNitpickerViewWidget::setNitpickerView(Nitpicker::View_capability view, int buf_x, int buf_y, int w, int h)
void QNitpickerViewWidget::setNitpickerView(Nitpicker::Session_client *new_nitpicker,
Nitpicker::Session::View_handle new_view_handle,
int buf_x, int buf_y, int w, int h)
{
orig_buf_x = buf_x;
orig_buf_y = buf_y;
orig_w = w;
orig_h = h;
// PDBG("orig_w = %d, orig_h = %d", orig_w, orig_h);
vc = new Nitpicker::View_client(view);
nitpicker = new_nitpicker;
view_handle = new_view_handle;
setFixedSize(orig_w, orig_h);
}
QNitpickerViewWidget::~QNitpickerViewWidget()
{
delete vc;
}
@ -61,15 +64,27 @@ void QNitpickerViewWidget::hideEvent(QHideEvent *event)
#endif
QWidget::hideEvent(event);
if (vc)
vc->viewport(mapToGlobal(pos()).x(), mapToGlobal(pos()).y(), 0, 0, orig_buf_x, orig_buf_y, 1);
if (nitpicker) {
typedef Nitpicker::Session::Command Command;
Nitpicker::Rect geometry(Nitpicker::Point(mapToGlobal(pos()).x(),
mapToGlobal(pos()).y()),
Nitpicker::Area(0, 0));
nitpicker->enqueue<Command::Geometry>(view_handle, geometry);
Nitpicker::Point offset(orig_buf_x, orig_buf_y);
nitpicker->enqueue<Command::Offset>(view_handle, offset);
nitpicker->execute();
}
}
void QNitpickerViewWidget::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
if (!vc)
if (!nitpicker)
return;
/* mark all sliders as unchecked */
@ -221,19 +236,20 @@ void QNitpickerViewWidget::paintEvent(QPaintEvent *event)
}
}
typedef Nitpicker::Session::Command Command;
/* argument to mapToGlobal() is relative to the Widget's origin
* the plugin view starts at (0, 0)
*/
if (mask().isEmpty()) {
/* PDBG("x0 = %d, y0 = %d, w = %d, h = %d, buf_x = %d, buf_y = %d",
x0, y0, w, h, orig_buf_x + diff_x, orig_buf_y + diff_y); */
vc->viewport(x0,
y0,
/*qMin(width(), w)*/w,
/*qMin(height(), h)*/h,
orig_buf_x + diff_x,
orig_buf_y + diff_y,
false);
// PDBG("x0 = %d, y0 = %d, w = %d, h = %d, buf_x = %d, buf_y = %d",
// x0, y0, w, h, orig_buf_x + diff_x, orig_buf_y + diff_y);
Nitpicker::Rect geometry(Nitpicker::Point(x0, y0),
Nitpicker::Area(w, h));
nitpicker->enqueue<Command::Geometry>(view_handle, geometry);
Nitpicker::Point offset(orig_buf_x + diff_x, orig_buf_y + diff_y);
nitpicker->enqueue<Command::Offset>(view_handle, offset);
} else {
/* PDBG("x = %d, y = %d, w = %d, h = %d, buf_x = %d, buf_y = %d",
mapToGlobal(mask().boundingRect().topLeft()).x(),
@ -241,19 +257,29 @@ void QNitpickerViewWidget::paintEvent(QPaintEvent *event)
mask().boundingRect().width(),
mask().boundingRect().height(),
orig_buf_x + diff_x, orig_buf_y + diff_y); */
vc->viewport(mapToGlobal(mask().boundingRect().topLeft()).x(),
mapToGlobal(mask().boundingRect().topLeft()).y(),
mask().boundingRect().width(),
mask().boundingRect().height(),
orig_buf_x + diff_x,
orig_buf_y + diff_y,
false);
Nitpicker::Rect const
geometry(Nitpicker::Point(mapToGlobal(mask().boundingRect().topLeft()).x(),
mapToGlobal(mask().boundingRect().topLeft()).y()),
Nitpicker::Area(mask().boundingRect().width(),
mask().boundingRect().height()));
nitpicker->enqueue<Command::Geometry>(view_handle, geometry);
Nitpicker::Point offset(orig_buf_x + diff_x, orig_buf_y + diff_y);
nitpicker->enqueue<Command::Offset>(view_handle, offset);
}
/* bring the plugin view to the front of the Qt window */
QNitpickerPlatformWindow *platform_window =
dynamic_cast<QNitpickerPlatformWindow*>(window()->windowHandle()->handle());
vc->stack(platform_window->view_cap(), false, true);
Nitpicker::Session::View_handle neighbor_handle =
nitpicker->view_handle(platform_window->view_cap());
nitpicker->enqueue<Command::To_front>(view_handle, neighbor_handle);
nitpicker->execute();
nitpicker->release_view_handle(neighbor_handle);
}
#if 0
void QNitpickerViewWidget::windowEvent(QWSWindow *window,

View File

@ -13,7 +13,7 @@
/* Genode includes */
#include <nitpicker_view/client.h>
#include <nitpicker_session/client.h>
/* Qt includes */
#include <qpa/qwindowsysteminterface.h>
@ -124,20 +124,29 @@ void QNitpickerPlatformWindow::_process_key_event(Input::Event *ev)
_keyboard_handler.processKeycode(keycode, pressed, false);
}
Nitpicker::View_capability QNitpickerPlatformWindow::_create_view()
Nitpicker::Session::View_handle QNitpickerPlatformWindow::_create_view()
{
if (window()->type() == Qt::Desktop)
return Nitpicker::View_capability();
return Nitpicker::Session::View_handle();
if (window()->type() == Qt::Dialog)
return _nitpicker_session.create_view(Nitpicker::View_capability());
return _nitpicker_session.create_view();
if (window()->transientParent()) {
QNitpickerPlatformWindow *parent_platform_window =
static_cast<QNitpickerPlatformWindow*>(window()->transientParent()->handle());
return _nitpicker_session.create_view(parent_platform_window->view_cap());
Nitpicker::Session::View_handle parent_handle =
_nitpicker_session.view_handle(parent_platform_window->view_cap());
Nitpicker::Session::View_handle result =
_nitpicker_session.create_view(parent_handle);
_nitpicker_session.release_view_handle(parent_handle);
return result;
} else
return _nitpicker_session.create_view(Nitpicker::View_capability());
return _nitpicker_session.create_view();
}
void QNitpickerPlatformWindow::_adjust_and_set_geometry(const QRect &rect)
@ -163,7 +172,7 @@ QNitpickerPlatformWindow::QNitpickerPlatformWindow(QWindow *window, Genode::Rpc_
: QPlatformWindow(window),
_framebuffer_session(_nitpicker_session.framebuffer_session()),
_framebuffer(0),
_view_cap(_create_view()),
_view_handle(_create_view()),
_input_session(_nitpicker_session.input_session()),
_timer(this),
_keyboard_handler("", -1, false, false, ""),
@ -180,10 +189,12 @@ QNitpickerPlatformWindow::QNitpickerPlatformWindow(QWindow *window, Genode::Rpc_
_ev_buf = static_cast<Input::Event *>
(Genode::env()->rm_session()->attach(_input_session.dataspace()));
if (_view_cap.valid()) {
if (_view_handle.valid()) {
/* bring the view to the top */
Nitpicker::View_client(_view_cap).stack(Nitpicker::View_capability(),
true, false);
typedef Nitpicker::Session::Command Command;
_nitpicker_session.enqueue<Command::To_front>(_view_handle);
_nitpicker_session.execute();
}
connect(_timer, SIGNAL(timeout()), this, SLOT(handle_events()));
@ -227,11 +238,12 @@ void QNitpickerPlatformWindow::setGeometry(const QRect &rect)
if (window()->isVisible()) {
QRect g(geometry());
Nitpicker::View_client(_view_cap).viewport(g.x(),
g.y(),
g.width(),
g.height(),
0, 0, true);
typedef Nitpicker::Session::Command Command;
_nitpicker_session.enqueue<Command::Geometry>(_view_handle,
Nitpicker::Rect(Nitpicker::Point(g.x(), g.y()),
Nitpicker::Area(g.width(), g.height())));
_nitpicker_session.execute();
}
if (qnpw_verbose)
@ -257,15 +269,23 @@ void QNitpickerPlatformWindow::setVisible(bool visible)
if (qnpw_verbose)
qDebug() << "QNitpickerPlatformWindow::setVisible(" << visible << ")";
typedef Nitpicker::Session::Command Command;
if (visible) {
QRect g = geometry();
Nitpicker::View_client(_view_cap).viewport(g.x(), g.y(),
g.width(),
g.height(),
0, 0, true);
} else
Nitpicker::View_client(_view_cap).viewport(0, 0, 0, 0, 0, 0,
false);
_nitpicker_session.enqueue<Command::Geometry>(_view_handle,
Nitpicker::Rect(Nitpicker::Point(g.x(), g.y()),
Nitpicker::Area(g.width(), g.height())));
} else {
_nitpicker_session.enqueue<Command::Geometry>(_view_handle,
Nitpicker::Rect(Nitpicker::Point(), Nitpicker::Area(0, 0)));
}
_nitpicker_session.execute();
QPlatformWindow::setVisible(visible);
@ -322,8 +342,12 @@ void QNitpickerPlatformWindow::setWindowTitle(const QString &title)
_title = title.toLocal8Bit();
if (_view_cap.valid())
Nitpicker::View_client(_view_cap).title(_title.constData());
typedef Nitpicker::Session::Command Command;
if (_view_handle.valid()) {
_nitpicker_session.enqueue<Command::Title>(_view_handle, _title.constData());
_nitpicker_session.execute();
}
if (qnpw_verbose)
qDebug() << "QNitpickerPlatformWindow::setWindowTitle() finished";
@ -346,8 +370,9 @@ void QNitpickerPlatformWindow::setWindowIcon(const QIcon &icon)
void QNitpickerPlatformWindow::raise()
{
/* bring the view to the top */
Nitpicker::View_client(_view_cap).stack(Nitpicker::View_capability(),
true, false);
_nitpicker_session.enqueue<Nitpicker::Session::Command::To_front>(_view_handle);
_nitpicker_session.execute();
QPlatformWindow::raise();
}
@ -518,7 +543,8 @@ void QNitpickerPlatformWindow::egl_surface(EGLSurface egl_surface)
Nitpicker::View_capability QNitpickerPlatformWindow::view_cap() const
{
return _view_cap;
QNitpickerPlatformWindow *npw = const_cast<QNitpickerPlatformWindow *>(this);
return npw->_nitpicker_session.view_capability(_view_handle);
}
void QNitpickerPlatformWindow::handle_events()

View File

@ -37,24 +37,24 @@ class QNitpickerPlatformWindow : public QObject, public QPlatformWindow
private:
Nitpicker::Connection _nitpicker_session;
Framebuffer::Session_client _framebuffer_session;
unsigned char *_framebuffer;
Nitpicker::View_capability _view_cap;
Input::Session_client _input_session;
Input::Event *_ev_buf;
QMember<QTimer> _timer;
Qt::MouseButtons _mouse_button_state;
QEvdevKeyboardHandler _keyboard_handler;
QByteArray _title;
bool _resize_handle;
bool _decoration;
EGLSurface _egl_surface;
Nitpicker::Connection _nitpicker_session;
Framebuffer::Session_client _framebuffer_session;
unsigned char *_framebuffer;
Nitpicker::Session::View_handle _view_handle;
Input::Session_client _input_session;
Input::Event *_ev_buf;
QMember<QTimer> _timer;
Qt::MouseButtons _mouse_button_state;
QEvdevKeyboardHandler _keyboard_handler;
QByteArray _title;
bool _resize_handle;
bool _decoration;
EGLSurface _egl_surface;
void _process_mouse_event(Input::Event *ev);
void _process_key_event(Input::Event *ev);
Nitpicker::View_capability _create_view();
Nitpicker::Session::View_handle _create_view();
void _adjust_and_set_geometry(const QRect &rect);
public:

View File

@ -18,7 +18,7 @@
#include <base/rpc.h>
#include <base/rpc_args.h>
#include <dataspace/capability.h>
#include <nitpicker_view/capability.h>
#include <nitpicker_session/client.h>
#include <base/signal.h>
#include <session/session.h>

View File

@ -16,38 +16,91 @@
#include <nitpicker_session/capability.h>
#include <base/rpc_client.h>
#include <os/attached_dataspace.h>
namespace Nitpicker { struct Session_client; }
struct Nitpicker::Session_client : public Genode::Rpc_client<Session>
class Nitpicker::Session_client : public Genode::Rpc_client<Session>
{
explicit Session_client(Session_capability session)
: Rpc_client<Session>(session) { }
private:
Framebuffer::Session_capability framebuffer_session() override {
return call<Rpc_framebuffer_session>(); }
Genode::Attached_dataspace _command_ds;
Input::Session_capability input_session() override {
return call<Rpc_input_session>(); }
Command_buffer &_command_buffer;
View_capability create_view(View_capability parent = View_capability()) override {
return call<Rpc_create_view>(parent); }
public:
void destroy_view(View_capability view) override {
call<Rpc_destroy_view>(view); }
explicit Session_client(Session_capability session)
:
Rpc_client<Session>(session),
_command_ds(command_dataspace()),
_command_buffer(*_command_ds.local_addr<Command_buffer>())
{ }
int background(View_capability view) override {
return call<Rpc_background>(view); }
Framebuffer::Session_capability framebuffer_session() override {
return call<Rpc_framebuffer_session>(); }
Framebuffer::Mode mode() override {
return call<Rpc_mode>(); }
Input::Session_capability input_session() override {
return call<Rpc_input_session>(); }
void buffer(Framebuffer::Mode mode, bool alpha) override {
call<Rpc_buffer>(mode, alpha); }
View_handle create_view(View_handle parent = View_handle()) override {
return call<Rpc_create_view>(parent); }
void focus(Nitpicker::Session_capability session) override {
call<Rpc_focus>(session); }
void destroy_view(View_handle view) override {
call<Rpc_destroy_view>(view); }
View_handle view_handle(View_capability view,
View_handle handle = View_handle()) override
{
return call<Rpc_view_handle>(view, handle);
}
View_capability view_capability(View_handle handle) override {
return call<Rpc_view_capability>(handle); }
void release_view_handle(View_handle handle) override {
call<Rpc_release_view_handle>(handle); }
Genode::Dataspace_capability command_dataspace() override {
return call<Rpc_command_dataspace>(); }
void execute() override
{
call<Rpc_execute>();
_command_buffer.reset();
}
Framebuffer::Mode mode() override {
return call<Rpc_mode>(); }
void buffer(Framebuffer::Mode mode, bool alpha) override {
call<Rpc_buffer>(mode, alpha); }
void focus(Nitpicker::Session_capability session) override {
call<Rpc_focus>(session); }
/**
* Enqueue command to command buffer
*
* The submitted command is not executed immediately. To execute a
* batch of enqueued commands, the 'execute' function must be called.
* Only in the corner case when there is not space left in the command
* buffer, the 'execute' is called to make room in the buffer.
*/
template <typename CMD, typename... ARGS>
void enqueue(ARGS... args)
{
enqueue(Command( CMD { args... } ));
}
void enqueue(Command const &command)
{
if (_command_buffer.is_full())
execute();
_command_buffer.enqueue(command);
}
};
#endif /* _INCLUDE__NITPICKER_SESSION__CLIENT_H_ */

View File

@ -44,7 +44,7 @@ class Nitpicker::Connection : public Genode::Connection<Session>,
* Declare ram-quota donation
*/
using Genode::Arg_string;
enum { SESSION_METADATA = 20*1024 };
enum { SESSION_METADATA = 36*1024 };
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA);
if (stay_top)

View File

@ -17,13 +17,20 @@
#define _INCLUDE__NITPICKER_SESSION__NITPICKER_SESSION_H_
#include <session/session.h>
#include <os/surface.h>
#include <os/handle_registry.h>
#include <framebuffer_session/capability.h>
#include <input_session/capability.h>
#include <nitpicker_view/capability.h>
namespace Nitpicker {
using Genode::size_t;
struct View;
typedef Genode::Capability<View> View_capability;
struct Session;
typedef Genode::Surface_base::Rect Rect;
typedef Genode::Surface_base::Point Point;
typedef Genode::Surface_base::Area Area;
using Genode::Meta::Type_tuple;
}
@ -32,9 +39,144 @@ struct Nitpicker::Session : Genode::Session
static const char *service_name() { return "Nitpicker"; }
/**
* Exception type
* Session-local view handle
*
* When issuing commands to nitpicker via the 'execute' function, views
* are referenced by session-local handles.
*/
typedef Genode::Handle<View> View_handle;
struct Command
{
enum Opcode { OP_GEOMETRY, OP_OFFSET,
OP_TO_FRONT, OP_TO_BACK, OP_BACKGROUND,
OP_TITLE, OP_NOP };
/*
* Argument structures for nitpicker's command interface
*/
struct Nop { static Opcode opcode() { return OP_NOP; } };
struct Geometry
{
static Opcode opcode() { return OP_GEOMETRY; }
View_handle view;
Rect rect;
};
struct Offset
{
static Opcode opcode() { return OP_OFFSET; }
View_handle view;
Point offset;
};
struct To_front
{
static Opcode opcode() { return OP_TO_FRONT; }
View_handle view;
View_handle neighbor;
};
struct To_back
{
static Opcode opcode() { return OP_TO_BACK; }
View_handle view;
View_handle neighbor;
};
struct Background
{
static Opcode opcode() { return OP_BACKGROUND; }
View_handle view;
};
struct Title
{
static Opcode opcode() { return OP_TITLE; }
View_handle view;
Genode::String<64> title;
};
Opcode opcode;
union
{
Nop nop;
Geometry geometry;
Offset offset;
To_front to_front;
To_back to_back;
Background background;
Title title;
};
Command() : opcode(OP_NOP) { }
template <typename ARGS>
Command(ARGS args)
{
opcode = ARGS::opcode();
reinterpret_cast<ARGS &>(nop) = args;
}
};
/**
* Command buffer shared between nitpicker and client
*/
class Command_buffer
{
public:
enum { MAX_COMMANDS = 64 };
private:
unsigned _num = 0;
Command _commands[MAX_COMMANDS];
public:
bool is_full() const { return _num >= MAX_COMMANDS; }
unsigned num() const
{
/* copy out _num value to avoid use-after-check problems */
unsigned const num = _num;
return num <= MAX_COMMANDS ? num : 0;
}
void reset() { _num = 0; }
/**
* Enqueue command
*
* The command will be dropped if the buffer is full. Check for this
* condition by calling 'is_full()' prior calling this function.
*/
void enqueue(Command const &command)
{
if (!is_full())
_commands[_num++] = command;
}
Command get(unsigned i)
{
if (i >= MAX_COMMANDS) return Command(Command::Nop());
return _commands[i];
}
};
/**
* Exception types
*/
struct Out_of_metadata : Genode::Exception { };
struct Invalid_handle : Genode::Exception { };
virtual ~Session() { }
@ -53,24 +195,57 @@ struct Nitpicker::Session : Genode::Session
*
* \param parent parent view
*
* \return capability to a new view
* \throw Invalid_handle
* \return handle for new view
*
* The 'parent' argument allows the client to use the location of an
* existing view as the coordinate origin for the to-be-created view.
* If an invalid capability is specified (default), the view will be a
* If an invalid handle is specified (default), the view will be a
* top-level view.
*/
virtual View_capability create_view(View_capability parent = View_capability()) = 0;
virtual View_handle create_view(View_handle parent = View_handle()) = 0;
/**
* Destroy view
*/
virtual void destroy_view(View_capability view) = 0;
virtual void destroy_view(View_handle) = 0;
/**
* Define view that is used as desktop background
* Return session-local handle for the specified view
*
* The handle returned by this functions can be used to issue commands
* via the 'execute' function.
*
* \param handle designated view handle to be assigned to the imported
* view. By default, a new handle will be allocated.
*
* \throw Out_of_metadata
*/
virtual int background(View_capability view) = 0;
virtual View_handle view_handle(View_capability,
View_handle handle = View_handle()) = 0;
/**
* Request view capability for a given handle
*
* The returned view capability can be used to share the view with another
* session.
*/
virtual View_capability view_capability(View_handle) = 0;
/**
* Release session-local view handle
*/
virtual void release_view_handle(View_handle) = 0;
/**
* Request dataspace used for issuing view commands to nitpicker
*/
virtual Genode::Dataspace_capability command_dataspace() = 0;
/**
* Execution batch of commands contained in the command dataspace
*/
virtual void execute() = 0;
/**
* Return physical screen mode
@ -118,17 +293,40 @@ struct Nitpicker::Session : Genode::Session
GENODE_RPC(Rpc_framebuffer_session, Framebuffer::Session_capability, framebuffer_session);
GENODE_RPC(Rpc_input_session, Input::Session_capability, input_session);
GENODE_RPC(Rpc_create_view, View_capability, create_view, View_capability);
GENODE_RPC(Rpc_destroy_view, void, destroy_view, View_capability);
GENODE_RPC_THROW(Rpc_create_view, View_handle, create_view,
GENODE_TYPE_LIST(Out_of_metadata, Invalid_handle), View_handle);
GENODE_RPC(Rpc_destroy_view, void, destroy_view, View_handle);
GENODE_RPC_THROW(Rpc_view_handle, View_handle, view_handle,
GENODE_TYPE_LIST(Out_of_metadata), View_capability, View_handle);
GENODE_RPC(Rpc_view_capability, View_capability, view_capability, View_handle);
GENODE_RPC(Rpc_release_view_handle, void, release_view_handle, View_handle);
GENODE_RPC(Rpc_command_dataspace, Genode::Dataspace_capability, command_dataspace);
GENODE_RPC(Rpc_execute, void, execute);
GENODE_RPC(Rpc_background, int, background, View_capability);
GENODE_RPC(Rpc_mode, Framebuffer::Mode, mode);
GENODE_RPC(Rpc_focus, void, focus, Genode::Capability<Session>);
GENODE_RPC_THROW(Rpc_buffer, void, buffer, GENODE_TYPE_LIST(Out_of_metadata),
Framebuffer::Mode, bool);
GENODE_RPC_INTERFACE(Rpc_framebuffer_session, Rpc_input_session,
Rpc_create_view, Rpc_destroy_view, Rpc_background,
Rpc_mode, Rpc_buffer, Rpc_focus);
/*
* The 'GENODE_RPC_INTERFACE' declaration is done manually because the
* number of RPC functions exceeds the maxium arguments supported by the
* 'Type_list' template.
*/
typedef Type_tuple<Rpc_framebuffer_session,
Type_tuple<Rpc_input_session,
Type_tuple<Rpc_create_view,
Type_tuple<Rpc_destroy_view,
Type_tuple<Rpc_view_handle,
Type_tuple<Rpc_view_capability,
Type_tuple<Rpc_release_view_handle,
Type_tuple<Rpc_command_dataspace,
Type_tuple<Rpc_execute,
Type_tuple<Rpc_mode,
Type_tuple<Rpc_buffer,
Type_tuple<Rpc_focus,
Genode::Meta::Empty>
> > > > > > > > > > > Rpc_functions;
};
#endif /* _INCLUDE__NITPICKER_SESSION__NITPICKER_SESSION_H_ */

View File

@ -1,25 +0,0 @@
/*
* \brief Nitpicker view capability type
* \author Norman Feske
* \date 2008-08-16
*/
/*
* Copyright (C) 2008-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__NITPICKER_VIEW__CAPABILITY_H_
#define _INCLUDE__NITPICKER_VIEW__CAPABILITY_H_
#include <base/capability.h>
namespace Nitpicker {
class View;
typedef Genode::Capability<View> View_capability;
}
#endif /* _INCLUDE__NITPICKER_VIEW__CAPABILITY_H_ */

View File

@ -1,39 +0,0 @@
/*
* \brief Client-side nitpicker view interface
* \author Norman Feske
* \date 2006-08-23
*/
/*
* 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 _INCLUDE__NITPICKER_VIEW__CLIENT_H_
#define _INCLUDE__NITPICKER_VIEW__CLIENT_H_
#include <nitpicker_view/nitpicker_view.h>
#include <base/rpc_client.h>
namespace Nitpicker {
struct View_client : public Genode::Rpc_client<View>
{
explicit View_client(View_capability view)
: Genode::Rpc_client<View>(view) { }
int viewport(int x, int y, int w, int h,
int buf_x, int buf_y, bool redraw) {
return call<Rpc_viewport>(x, y, w, h, buf_x, buf_y, redraw); }
int stack(View_capability neighbor, bool behind, bool redraw) {
return call<Rpc_stack>(neighbor, behind, redraw); }
int title(Title const &title) {
return call<Rpc_title>(title); }
};
}
#endif /* _INCLUDE__NITPICKER_VIEW__CLIENT_H_ */

View File

@ -1,77 +0,0 @@
/*
* \brief Nitpicker view interface
* \author Norman Feske
* \date 2006-08-10
*/
/*
* 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 _INCLUDE__NITPICKER_VIEW__NITPICKER_VIEW_H_
#define _INCLUDE__NITPICKER_VIEW__NITPICKER_VIEW_H_
#include <nitpicker_session/nitpicker_session.h>
#include <nitpicker_view/capability.h>
#include <base/rpc.h>
#include <base/rpc_args.h>
namespace Nitpicker {
struct View
{
virtual ~View() { }
/**
* Define position and viewport
*
* Both attributes are handled in one function to enable atomic
* updates of position and viewport. This is the common case for
* moving an overlay window.
*/
virtual int viewport(int x, int y, int w, int h,
int buf_x, int buf_y, bool redraw = true) = 0;
/**
* Reposition view in view stack
*
* \param neighbor neighbor view
* \param behind insert view in front (true) or
* behind (false) the specified neighbor
* \param redraw redraw affected screen region
*
* To insert a view at the top of the view stack, specify
* neighbor = invalid and behind = true. To insert a view at the
* bottom of the view stack, specify neighbor = invalid and
* behind = false.
*/
virtual int stack(View_capability neighbor = View_capability(),
bool behind = true, bool redraw = true) = 0;
/**
* String type used as argument for the 'title' function
*/
typedef Genode::Rpc_in_buffer<64> Title;
/**
* Assign new view title
*/
virtual int title(Title const &title) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_viewport, int, viewport, int, int, int, int, int, int, bool);
GENODE_RPC(Rpc_stack, int, stack, View_capability, bool, bool);
GENODE_RPC(Rpc_title, int, title, Title const &);
GENODE_RPC_INTERFACE(Rpc_viewport, Rpc_stack, Rpc_title);
};
}
#endif /* _INCLUDE__NITPICKER_VIEW__NITPICKER_VIEW_H_ */

View File

@ -13,7 +13,6 @@
/* Genode includes */
#include <base/sleep.h>
#include <nitpicker_view/client.h>
#include <cap_session/connection.h>
#include <nitpicker_session/connection.h>
#include <dataspace/client.h>
@ -176,9 +175,13 @@ int main(int argc, char **argv)
/*
* Create Nitpicker view and bring it to front
*/
Nitpicker::View_client view(nitpicker.create_view());
view.viewport(view_x, view_y, view_w, view_h, 0, 0, false);
view.stack(Nitpicker::View_capability(), true, true);
Nitpicker::Session::View_handle view = nitpicker.create_view();
typedef Nitpicker::Session::Command Command;
Nitpicker::Rect geometry(Nitpicker::Point(view_x, view_y),
Nitpicker::Area(view_w, view_h));
nitpicker.enqueue<Command::Geometry>(view, geometry);
nitpicker.enqueue<Command::To_front>(view);
nitpicker.execute();
/*
* Initialize server entry point
@ -243,7 +246,11 @@ int main(int argc, char **argv)
try {
config()->reload();
cfg = Config_args();
view.viewport(cfg.xpos, cfg.ypos, cfg.width, cfg.height, 0, 0, true);
Nitpicker::Rect geometry(Nitpicker::Point(cfg.xpos, cfg.ypos),
Nitpicker::Area(cfg.width, cfg.height));
nitpicker.enqueue<Command::Geometry>(view, geometry);
nitpicker.execute();
} catch (...) {
PERR("Error while reloading config");
}

View File

@ -24,7 +24,6 @@
#include <timer_session/connection.h>
#include <input_session/connection.h>
#include <input_session/input_session.h>
#include <nitpicker_view/nitpicker_view.h>
#include <nitpicker_session/nitpicker_session.h>
#include <framebuffer_session/connection.h>
#include <util/color.h>
@ -43,13 +42,13 @@
namespace Input { class Session_component; }
namespace Framebuffer { class Session_component; }
namespace Nitpicker {
class Session_component;
template <typename> class Root;
struct Main;
}
using Genode::size_t;
using Genode::Allocator;
using Genode::Rpc_entrypoint;
@ -67,6 +66,8 @@ using Genode::Signal_context_capability;
using Genode::Signal_rpc_member;
using Genode::Attached_ram_dataspace;
using Genode::Attached_dataspace;
using Genode::Weak_ptr;
using Genode::Locked_ptr;
Framebuffer::Session *tmp_fb;
@ -366,68 +367,6 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
};
class View_component : public Genode::List<View_component>::Element,
public Genode::Rpc_object<Nitpicker::View>
{
private:
typedef Genode::Rpc_entrypoint Rpc_entrypoint;
View_stack &_view_stack;
::View _view;
Rpc_entrypoint &_ep;
public:
/**
* Constructor
*/
View_component(::Session &session, View_stack &view_stack,
Rpc_entrypoint &ep, ::View *parent_view):
_view_stack(view_stack),
_view(session,
session.stay_top() ? ::View::STAY_TOP : ::View::NOT_STAY_TOP,
::View::NOT_TRANSPARENT, ::View::NOT_BACKGROUND, parent_view),
_ep(ep)
{ }
::View &view() { return _view; }
/******************************
** Nitpicker view interface **
******************************/
int viewport(int x, int y, int w, int h,
int buf_x, int buf_y, bool) override
{
/* transpose y position of top-level views by vertical session offset */
if (_view.top_level())
y += _view.session().v_offset();
_view_stack.viewport(_view, Rect(Point(x, y), Area(w, h)),
Point(buf_x, buf_y));
return 0;
}
int stack(Nitpicker::View_capability neighbor_cap, bool behind, bool) override
{
Object_pool<View_component>::Guard nvc(_ep.lookup_and_lock(neighbor_cap));
::View *neighbor_view = nvc ? &nvc->view() : 0;
_view_stack.stack(_view, neighbor_view, behind);
return 0;
}
int title(Title const &title) override
{
_view_stack.title(_view, title.string());
return 0;
}
};
/*****************************************
** Implementation of Nitpicker service **
*****************************************/
@ -438,7 +377,9 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
{
private:
Genode::Allocator_guard _buffer_alloc;
typedef ::View View;
Genode::Allocator_guard _session_alloc;
Framebuffer::Session &_framebuffer;
@ -458,7 +399,9 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,