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:
parent
24869bd3ff
commit
91e01411a4
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <nitpicker_session/connection.h>
|
#include <nitpicker_session/connection.h>
|
||||||
#include <nitpicker_view/client.h>
|
|
||||||
#include <os/pixel_rgb565.h>
|
#include <os/pixel_rgb565.h>
|
||||||
|
|
||||||
/* Scout includes */
|
/* Scout includes */
|
||||||
|
@ -53,19 +52,25 @@ class Scout::Nitpicker_graphics_backend : public Graphics_backend
|
||||||
|
|
||||||
void *_fb_local_base = { _map_fb_ds() };
|
void *_fb_local_base = { _map_fb_ds() };
|
||||||
|
|
||||||
Point _position;
|
typedef Nitpicker::Session::View_handle View_handle;
|
||||||
Area _view_size;
|
|
||||||
Nitpicker::View_client _view;
|
Point _position;
|
||||||
Canvas_base *_canvas[2];
|
Area _view_size;
|
||||||
bool _flip_state = { false };
|
View_handle _view;
|
||||||
|
Canvas_base *_canvas[2];
|
||||||
|
bool _flip_state = { false };
|
||||||
|
|
||||||
void _update_viewport()
|
void _update_viewport()
|
||||||
{
|
{
|
||||||
_view.viewport(_position.x(), _position.y(),
|
typedef Nitpicker::Session::Command Command;
|
||||||
_view_size.w(), _view_size.h(),
|
|
||||||
0,
|
Nitpicker::Rect rect(_position, _view_size);
|
||||||
_flip_state ? -_max_size.h() : 0,
|
_nitpicker.enqueue<Command::Geometry>(_view, rect);
|
||||||
true);
|
|
||||||
|
Nitpicker::Point offset(0, _flip_state ? -_max_size.h() : 0);
|
||||||
|
_nitpicker.enqueue<Command::Offset>(_view, offset);
|
||||||
|
|
||||||
|
_nitpicker.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _refresh_view(Rect rect)
|
void _refresh_view(Rect rect)
|
||||||
|
@ -146,7 +151,9 @@ class Scout::Nitpicker_graphics_backend : public Graphics_backend
|
||||||
|
|
||||||
void bring_to_front()
|
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)
|
void view_area(Area area)
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <nitpicker_session/connection.h>
|
#include <nitpicker_session/connection.h>
|
||||||
#include <nitpicker_view/client.h>
|
|
||||||
#include <framebuffer_session/client.h>
|
#include <framebuffer_session/client.h>
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
|
@ -241,8 +240,7 @@ int main(int argc, char **argv)
|
||||||
nitpicker.buffer(mode, false);
|
nitpicker.buffer(mode, false);
|
||||||
|
|
||||||
static Framebuffer::Session_client framebuffer(nitpicker.framebuffer_session());
|
static Framebuffer::Session_client framebuffer(nitpicker.framebuffer_session());
|
||||||
Nitpicker::View_capability view_cap = nitpicker.create_view();
|
Nitpicker::Session::View_handle view_handle = nitpicker.create_view();
|
||||||
static Nitpicker::View_client view(view_cap);
|
|
||||||
|
|
||||||
if (mode.format() != Framebuffer::Mode::RGB565) {
|
if (mode.format() != Framebuffer::Mode::RGB565) {
|
||||||
printf("Error: Color mode %d not supported\n", (int)mode.format());
|
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());
|
convert_png_to_rgb565(png_data, fb, mode.width(), mode.height());
|
||||||
|
|
||||||
/* display view behind all others */
|
/* display view behind all others */
|
||||||
nitpicker.background(view_cap);
|
typedef Nitpicker::Session::Command Command;
|
||||||
view.viewport(0, 0, mode.width(), mode.height(), 0, 0, false);
|
nitpicker.enqueue<Command::Background>(view_handle);
|
||||||
view.stack(Nitpicker::View_capability(), false, false);
|
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());
|
framebuffer.refresh(0, 0, mode.width(), mode.height());
|
||||||
|
|
||||||
sleep_forever();
|
sleep_forever();
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <cap_session/connection.h>
|
#include <cap_session/connection.h>
|
||||||
#include <log_session/log_session.h>
|
#include <log_session/log_session.h>
|
||||||
#include <nitpicker_session/connection.h>
|
#include <nitpicker_session/connection.h>
|
||||||
#include <nitpicker_view/client.h>
|
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
#include <input/event.h>
|
#include <input/event.h>
|
||||||
#include <os/pixel_rgb565.h>
|
#include <os/pixel_rgb565.h>
|
||||||
|
@ -343,40 +342,42 @@ class Log_view
|
||||||
{
|
{
|
||||||
private:
|
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:
|
public:
|
||||||
|
|
||||||
Log_view(Nitpicker::Session *nitpicker,
|
Log_view(Nitpicker::Session_client &nitpicker, Nitpicker::Rect geometry)
|
||||||
int x, int y, int w, int h)
|
|
||||||
:
|
:
|
||||||
_x(x), _y(y), _w(w), _h(h)
|
_nitpicker(nitpicker),
|
||||||
|
_pos(geometry.p1()),
|
||||||
|
_size(geometry.area()),
|
||||||
|
_handle(nitpicker.create_view())
|
||||||
{
|
{
|
||||||
using namespace Nitpicker;
|
move(_pos);
|
||||||
|
top();
|
||||||
_cap = nitpicker->create_view();
|
|
||||||
View_client(_cap).viewport(_x, _y, _w, _h, 0, 0, true);
|
|
||||||
View_client(_cap).stack(Nitpicker::View_capability(), true, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void 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;
|
_pos = pos;
|
||||||
Nitpicker::View_client(_cap).viewport(_x, _y, _w, _h, 0, 0, true);
|
|
||||||
|
Nitpicker::Rect rect(_pos, _size);
|
||||||
|
_nitpicker.enqueue<Command::Geometry>(_handle, rect);
|
||||||
|
_nitpicker.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
Nitpicker::Point pos() const { return _pos; }
|
||||||
* Accessors
|
|
||||||
*/
|
|
||||||
int x() { return _x; }
|
|
||||||
int y() { return _y; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)));
|
canvas.clip(::Rect(::Point(1, 1), ::Area(log_win_w - 2, log_win_h - 2)));
|
||||||
|
|
||||||
/* create view for log window */
|
/* 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 */
|
/* create root interface for service */
|
||||||
static Log_root_component log_root(&ep, &sliced_heap, &log_window);
|
static Log_root_component log_root(&ep, &sliced_heap, &log_window);
|
||||||
|
@ -434,7 +437,8 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
/* handle input events */
|
/* handle input events */
|
||||||
Input::Event *ev_buf = env()->rm_session()->attach(nitpicker.input()->dataspace());
|
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 (1) {
|
||||||
|
|
||||||
while (!nitpicker.input()->is_pending()) {
|
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::PRESS) key_cnt++;
|
||||||
if (ev->type() == Input::Event::RELEASE) key_cnt--;
|
if (ev->type() == Input::Event::RELEASE) key_cnt--;
|
||||||
|
|
||||||
|
Nitpicker::Point mouse_pos(ev->ax(), ev->ay());
|
||||||
|
|
||||||
/* move view */
|
/* move view */
|
||||||
if (ev->type() == Input::Event::MOTION && key_cnt > 0)
|
if (ev->type() == Input::Event::MOTION && key_cnt > 0)
|
||||||
log_view.move(log_view.x() + ev->ax() - omx,
|
log_view.move(log_view.pos() + mouse_pos - old_mouse_pos);
|
||||||
log_view.y() + ev->ay() - omy);
|
|
||||||
|
|
||||||
/* find selected view and bring it to front */
|
/* find selected view and bring it to front */
|
||||||
if (ev->type() == Input::Event::PRESS && key_cnt == 1)
|
if (ev->type() == Input::Event::PRESS && key_cnt == 1)
|
||||||
log_view.top();
|
log_view.top();
|
||||||
|
|
||||||
omx = ev->ax(); omy = ev->ay();
|
old_mouse_pos = mouse_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
#include <qwindowsystem_qws.h>
|
#include <qwindowsystem_qws.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <nitpicker_view/capability.h>
|
#include <nitpicker_session/client.h>
|
||||||
#include <nitpicker_view/client.h>
|
|
||||||
|
|
||||||
class QNitpickerViewWidget : public QWidget
|
class QNitpickerViewWidget : public QWidget
|
||||||
{
|
{
|
||||||
|
@ -38,7 +37,10 @@ private slots:
|
||||||
void destroyed(QObject *obj = 0);
|
void destroyed(QObject *obj = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Nitpicker::View_client *vc;
|
|
||||||
|
Nitpicker::Session_client *nitpicker;
|
||||||
|
Nitpicker::Session::View_handle view_handle;
|
||||||
|
|
||||||
int orig_w;
|
int orig_w;
|
||||||
int orig_h;
|
int orig_h;
|
||||||
int orig_buf_x;
|
int orig_buf_x;
|
||||||
|
@ -51,7 +53,9 @@ protected:
|
||||||
public:
|
public:
|
||||||
QNitpickerViewWidget(QWidget *parent =0);
|
QNitpickerViewWidget(QWidget *parent =0);
|
||||||
~QNitpickerViewWidget();
|
~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
|
#endif // QNITPICKERVIEWWIDGET_H
|
||||||
|
|
|
@ -13,11 +13,12 @@
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
#include <nitpicker_view/client.h>
|
#include <nitpicker_session/client.h>
|
||||||
#include <util/arg_string.h>
|
#include <util/arg_string.h>
|
||||||
#include <util/misc_math.h>
|
#include <util/misc_math.h>
|
||||||
|
|
||||||
#include "framebuffer_session_component.h"
|
#include "framebuffer_session_component.h"
|
||||||
|
#include <qnitpickerplatformwindow.h>
|
||||||
|
|
||||||
namespace Framebuffer {
|
namespace Framebuffer {
|
||||||
|
|
||||||
|
@ -49,9 +50,22 @@ namespace Framebuffer {
|
||||||
_limited_size(session_arg(args, "fb_height"), max_height),
|
_limited_size(session_arg(args, "fb_height"), max_height),
|
||||||
_nitpicker.mode().format());
|
_nitpicker.mode().format());
|
||||||
_nitpicker.buffer(mode, false);
|
_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();
|
Mode _mode = _framebuffer.mode();
|
||||||
nitpicker_view_widget.setNitpickerView(nitpicker_view_cap,
|
nitpicker_view_widget.setNitpickerView(&_nitpicker,
|
||||||
|
nitpicker_view_handle,
|
||||||
0, 0,
|
0, 0,
|
||||||
_mode.width(),
|
_mode.width(),
|
||||||
_mode.height());
|
_mode.height());
|
||||||
|
|
|
@ -20,26 +20,29 @@
|
||||||
|
|
||||||
|
|
||||||
QNitpickerViewWidget::QNitpickerViewWidget(QWidget *parent)
|
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_x = buf_x;
|
||||||
orig_buf_y = buf_y;
|
orig_buf_y = buf_y;
|
||||||
orig_w = w;
|
orig_w = w;
|
||||||
orig_h = h;
|
orig_h = h;
|
||||||
// PDBG("orig_w = %d, orig_h = %d", orig_w, orig_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);
|
setFixedSize(orig_w, orig_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QNitpickerViewWidget::~QNitpickerViewWidget()
|
QNitpickerViewWidget::~QNitpickerViewWidget()
|
||||||
{
|
{
|
||||||
delete vc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,15 +64,27 @@ void QNitpickerViewWidget::hideEvent(QHideEvent *event)
|
||||||
#endif
|
#endif
|
||||||
QWidget::hideEvent(event);
|
QWidget::hideEvent(event);
|
||||||
|
|
||||||
if (vc)
|
if (nitpicker) {
|
||||||
vc->viewport(mapToGlobal(pos()).x(), mapToGlobal(pos()).y(), 0, 0, orig_buf_x, orig_buf_y, 1);
|
|
||||||
|
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)
|
void QNitpickerViewWidget::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::paintEvent(event);
|
QWidget::paintEvent(event);
|
||||||
|
|
||||||
if (!vc)
|
if (!nitpicker)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* mark all sliders as unchecked */
|
/* 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
|
/* argument to mapToGlobal() is relative to the Widget's origin
|
||||||
* the plugin view starts at (0, 0)
|
* the plugin view starts at (0, 0)
|
||||||
*/
|
*/
|
||||||
if (mask().isEmpty()) {
|
if (mask().isEmpty()) {
|
||||||
/* PDBG("x0 = %d, y0 = %d, w = %d, h = %d, buf_x = %d, buf_y = %d",
|
// 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); */
|
// x0, y0, w, h, orig_buf_x + diff_x, orig_buf_y + diff_y);
|
||||||
vc->viewport(x0,
|
|
||||||
y0,
|
Nitpicker::Rect geometry(Nitpicker::Point(x0, y0),
|
||||||
/*qMin(width(), w)*/w,
|
Nitpicker::Area(w, h));
|
||||||
/*qMin(height(), h)*/h,
|
nitpicker->enqueue<Command::Geometry>(view_handle, geometry);
|
||||||
orig_buf_x + diff_x,
|
Nitpicker::Point offset(orig_buf_x + diff_x, orig_buf_y + diff_y);
|
||||||
orig_buf_y + diff_y,
|
nitpicker->enqueue<Command::Offset>(view_handle, offset);
|
||||||
false);
|
|
||||||
} else {
|
} else {
|
||||||
/* PDBG("x = %d, y = %d, w = %d, h = %d, buf_x = %d, buf_y = %d",
|
/* PDBG("x = %d, y = %d, w = %d, h = %d, buf_x = %d, buf_y = %d",
|
||||||
mapToGlobal(mask().boundingRect().topLeft()).x(),
|
mapToGlobal(mask().boundingRect().topLeft()).x(),
|
||||||
|
@ -241,19 +257,29 @@ void QNitpickerViewWidget::paintEvent(QPaintEvent *event)
|
||||||
mask().boundingRect().width(),
|
mask().boundingRect().width(),
|
||||||
mask().boundingRect().height(),
|
mask().boundingRect().height(),
|
||||||
orig_buf_x + diff_x, orig_buf_y + diff_y); */
|
orig_buf_x + diff_x, orig_buf_y + diff_y); */
|
||||||
vc->viewport(mapToGlobal(mask().boundingRect().topLeft()).x(),
|
|
||||||
mapToGlobal(mask().boundingRect().topLeft()).y(),
|
Nitpicker::Rect const
|
||||||
mask().boundingRect().width(),
|
geometry(Nitpicker::Point(mapToGlobal(mask().boundingRect().topLeft()).x(),
|
||||||
mask().boundingRect().height(),
|
mapToGlobal(mask().boundingRect().topLeft()).y()),
|
||||||
orig_buf_x + diff_x,
|
Nitpicker::Area(mask().boundingRect().width(),
|
||||||
orig_buf_y + diff_y,
|
mask().boundingRect().height()));
|
||||||
false);
|
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 */
|
/* bring the plugin view to the front of the Qt window */
|
||||||
QNitpickerPlatformWindow *platform_window =
|
QNitpickerPlatformWindow *platform_window =
|
||||||
dynamic_cast<QNitpickerPlatformWindow*>(window()->windowHandle()->handle());
|
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
|
#if 0
|
||||||
void QNitpickerViewWidget::windowEvent(QWSWindow *window,
|
void QNitpickerViewWidget::windowEvent(QWSWindow *window,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <nitpicker_view/client.h>
|
#include <nitpicker_session/client.h>
|
||||||
|
|
||||||
/* Qt includes */
|
/* Qt includes */
|
||||||
#include <qpa/qwindowsysteminterface.h>
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
@ -124,20 +124,29 @@ void QNitpickerPlatformWindow::_process_key_event(Input::Event *ev)
|
||||||
_keyboard_handler.processKeycode(keycode, pressed, false);
|
_keyboard_handler.processKeycode(keycode, pressed, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Nitpicker::View_capability QNitpickerPlatformWindow::_create_view()
|
Nitpicker::Session::View_handle QNitpickerPlatformWindow::_create_view()
|
||||||
{
|
{
|
||||||
if (window()->type() == Qt::Desktop)
|
if (window()->type() == Qt::Desktop)
|
||||||
return Nitpicker::View_capability();
|
return Nitpicker::Session::View_handle();
|
||||||
|
|
||||||
if (window()->type() == Qt::Dialog)
|
if (window()->type() == Qt::Dialog)
|
||||||
return _nitpicker_session.create_view(Nitpicker::View_capability());
|
return _nitpicker_session.create_view();
|
||||||
|
|
||||||
if (window()->transientParent()) {
|
if (window()->transientParent()) {
|
||||||
QNitpickerPlatformWindow *parent_platform_window =
|
QNitpickerPlatformWindow *parent_platform_window =
|
||||||
static_cast<QNitpickerPlatformWindow*>(window()->transientParent()->handle());
|
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
|
} else
|
||||||
return _nitpicker_session.create_view(Nitpicker::View_capability());
|
return _nitpicker_session.create_view();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QNitpickerPlatformWindow::_adjust_and_set_geometry(const QRect &rect)
|
void QNitpickerPlatformWindow::_adjust_and_set_geometry(const QRect &rect)
|
||||||
|
@ -163,7 +172,7 @@ QNitpickerPlatformWindow::QNitpickerPlatformWindow(QWindow *window, Genode::Rpc_
|
||||||
: QPlatformWindow(window),
|
: QPlatformWindow(window),
|
||||||
_framebuffer_session(_nitpicker_session.framebuffer_session()),
|
_framebuffer_session(_nitpicker_session.framebuffer_session()),
|
||||||
_framebuffer(0),
|
_framebuffer(0),
|
||||||
_view_cap(_create_view()),
|
_view_handle(_create_view()),
|
||||||
_input_session(_nitpicker_session.input_session()),
|
_input_session(_nitpicker_session.input_session()),
|
||||||
_timer(this),
|
_timer(this),
|
||||||
_keyboard_handler("", -1, false, false, ""),
|
_keyboard_handler("", -1, false, false, ""),
|
||||||
|
@ -180,10 +189,12 @@ QNitpickerPlatformWindow::QNitpickerPlatformWindow(QWindow *window, Genode::Rpc_
|
||||||
_ev_buf = static_cast<Input::Event *>
|
_ev_buf = static_cast<Input::Event *>
|
||||||
(Genode::env()->rm_session()->attach(_input_session.dataspace()));
|
(Genode::env()->rm_session()->attach(_input_session.dataspace()));
|
||||||
|
|
||||||
if (_view_cap.valid()) {
|
if (_view_handle.valid()) {
|
||||||
|
|
||||||
/* bring the view to the top */
|
/* bring the view to the top */
|
||||||
Nitpicker::View_client(_view_cap).stack(Nitpicker::View_capability(),
|
typedef Nitpicker::Session::Command Command;
|
||||||
true, false);
|
_nitpicker_session.enqueue<Command::To_front>(_view_handle);
|
||||||
|
_nitpicker_session.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(_timer, SIGNAL(timeout()), this, SLOT(handle_events()));
|
connect(_timer, SIGNAL(timeout()), this, SLOT(handle_events()));
|
||||||
|
@ -227,11 +238,12 @@ void QNitpickerPlatformWindow::setGeometry(const QRect &rect)
|
||||||
|
|
||||||
if (window()->isVisible()) {
|
if (window()->isVisible()) {
|
||||||
QRect g(geometry());
|
QRect g(geometry());
|
||||||
Nitpicker::View_client(_view_cap).viewport(g.x(),
|
|
||||||
g.y(),
|
typedef Nitpicker::Session::Command Command;
|
||||||
g.width(),
|
_nitpicker_session.enqueue<Command::Geometry>(_view_handle,
|
||||||
g.height(),
|
Nitpicker::Rect(Nitpicker::Point(g.x(), g.y()),
|
||||||
0, 0, true);
|
Nitpicker::Area(g.width(), g.height())));
|
||||||
|
_nitpicker_session.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qnpw_verbose)
|
if (qnpw_verbose)
|
||||||
|
@ -257,15 +269,23 @@ void QNitpickerPlatformWindow::setVisible(bool visible)
|
||||||
if (qnpw_verbose)
|
if (qnpw_verbose)
|
||||||
qDebug() << "QNitpickerPlatformWindow::setVisible(" << visible << ")";
|
qDebug() << "QNitpickerPlatformWindow::setVisible(" << visible << ")";
|
||||||
|
|
||||||
|
typedef Nitpicker::Session::Command Command;
|
||||||
|
|
||||||
if (visible) {
|
if (visible) {
|
||||||
QRect g = geometry();
|
QRect g = geometry();
|
||||||
Nitpicker::View_client(_view_cap).viewport(g.x(), g.y(),
|
|
||||||
g.width(),
|
_nitpicker_session.enqueue<Command::Geometry>(_view_handle,
|
||||||
g.height(),
|
Nitpicker::Rect(Nitpicker::Point(g.x(), g.y()),
|
||||||
0, 0, true);
|
Nitpicker::Area(g.width(), g.height())));
|
||||||
} else
|
} 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(), Nitpicker::Area(0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
_nitpicker_session.execute();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QPlatformWindow::setVisible(visible);
|
QPlatformWindow::setVisible(visible);
|
||||||
|
|
||||||
|
@ -322,8 +342,12 @@ void QNitpickerPlatformWindow::setWindowTitle(const QString &title)
|
||||||
|
|
||||||
_title = title.toLocal8Bit();
|
_title = title.toLocal8Bit();
|
||||||
|
|
||||||
if (_view_cap.valid())
|
typedef Nitpicker::Session::Command Command;
|
||||||
Nitpicker::View_client(_view_cap).title(_title.constData());
|
|
||||||
|
if (_view_handle.valid()) {
|
||||||
|
_nitpicker_session.enqueue<Command::Title>(_view_handle, _title.constData());
|
||||||
|
_nitpicker_session.execute();
|
||||||
|
}
|
||||||
|
|
||||||
if (qnpw_verbose)
|
if (qnpw_verbose)
|
||||||
qDebug() << "QNitpickerPlatformWindow::setWindowTitle() finished";
|
qDebug() << "QNitpickerPlatformWindow::setWindowTitle() finished";
|
||||||
|
@ -346,8 +370,9 @@ void QNitpickerPlatformWindow::setWindowIcon(const QIcon &icon)
|
||||||
void QNitpickerPlatformWindow::raise()
|
void QNitpickerPlatformWindow::raise()
|
||||||
{
|
{
|
||||||
/* bring the view to the top */
|
/* bring the view to the top */
|
||||||
Nitpicker::View_client(_view_cap).stack(Nitpicker::View_capability(),
|
_nitpicker_session.enqueue<Nitpicker::Session::Command::To_front>(_view_handle);
|
||||||
true, false);
|
_nitpicker_session.execute();
|
||||||
|
|
||||||
QPlatformWindow::raise();
|
QPlatformWindow::raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +543,8 @@ void QNitpickerPlatformWindow::egl_surface(EGLSurface egl_surface)
|
||||||
|
|
||||||
Nitpicker::View_capability QNitpickerPlatformWindow::view_cap() const
|
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()
|
void QNitpickerPlatformWindow::handle_events()
|
||||||
|
|
|
@ -37,24 +37,24 @@ class QNitpickerPlatformWindow : public QObject, public QPlatformWindow
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Nitpicker::Connection _nitpicker_session;
|
Nitpicker::Connection _nitpicker_session;
|
||||||
Framebuffer::Session_client _framebuffer_session;
|
Framebuffer::Session_client _framebuffer_session;
|
||||||
unsigned char *_framebuffer;
|
unsigned char *_framebuffer;
|
||||||
Nitpicker::View_capability _view_cap;
|
Nitpicker::Session::View_handle _view_handle;
|
||||||
Input::Session_client _input_session;
|
Input::Session_client _input_session;
|
||||||
Input::Event *_ev_buf;
|
Input::Event *_ev_buf;
|
||||||
QMember<QTimer> _timer;
|
QMember<QTimer> _timer;
|
||||||
Qt::MouseButtons _mouse_button_state;
|
Qt::MouseButtons _mouse_button_state;
|
||||||
QEvdevKeyboardHandler _keyboard_handler;
|
QEvdevKeyboardHandler _keyboard_handler;
|
||||||
QByteArray _title;
|
QByteArray _title;
|
||||||
bool _resize_handle;
|
bool _resize_handle;
|
||||||
bool _decoration;
|
bool _decoration;
|
||||||
EGLSurface _egl_surface;
|
EGLSurface _egl_surface;
|
||||||
|
|
||||||
void _process_mouse_event(Input::Event *ev);
|
void _process_mouse_event(Input::Event *ev);
|
||||||
void _process_key_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);
|
void _adjust_and_set_geometry(const QRect &rect);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <base/rpc.h>
|
#include <base/rpc.h>
|
||||||
#include <base/rpc_args.h>
|
#include <base/rpc_args.h>
|
||||||
#include <dataspace/capability.h>
|
#include <dataspace/capability.h>
|
||||||
#include <nitpicker_view/capability.h>
|
#include <nitpicker_session/client.h>
|
||||||
#include <base/signal.h>
|
#include <base/signal.h>
|
||||||
#include <session/session.h>
|
#include <session/session.h>
|
||||||
|
|
||||||
|
|
|
@ -16,38 +16,91 @@
|
||||||
|
|
||||||
#include <nitpicker_session/capability.h>
|
#include <nitpicker_session/capability.h>
|
||||||
#include <base/rpc_client.h>
|
#include <base/rpc_client.h>
|
||||||
|
#include <os/attached_dataspace.h>
|
||||||
|
|
||||||
namespace Nitpicker { struct Session_client; }
|
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)
|
private:
|
||||||
: Rpc_client<Session>(session) { }
|
|
||||||
|
|
||||||
Framebuffer::Session_capability framebuffer_session() override {
|
Genode::Attached_dataspace _command_ds;
|
||||||
return call<Rpc_framebuffer_session>(); }
|
|
||||||
|
|
||||||
Input::Session_capability input_session() override {
|
Command_buffer &_command_buffer;
|
||||||
return call<Rpc_input_session>(); }
|
|
||||||
|
|
||||||
View_capability create_view(View_capability parent = View_capability()) override {
|
public:
|
||||||
return call<Rpc_create_view>(parent); }
|
|
||||||
|
|
||||||
void destroy_view(View_capability view) override {
|
explicit Session_client(Session_capability session)
|
||||||
call<Rpc_destroy_view>(view); }
|
:
|
||||||
|
Rpc_client<Session>(session),
|
||||||
|
_command_ds(command_dataspace()),
|
||||||
|
_command_buffer(*_command_ds.local_addr<Command_buffer>())
|
||||||
|
{ }
|
||||||
|
|
||||||
int background(View_capability view) override {
|
Framebuffer::Session_capability framebuffer_session() override {
|
||||||
return call<Rpc_background>(view); }
|
return call<Rpc_framebuffer_session>(); }
|
||||||
|
|
||||||
Framebuffer::Mode mode() override {
|
Input::Session_capability input_session() override {
|
||||||
return call<Rpc_mode>(); }
|
return call<Rpc_input_session>(); }
|
||||||
|
|
||||||
void buffer(Framebuffer::Mode mode, bool alpha) override {
|
View_handle create_view(View_handle parent = View_handle()) override {
|
||||||
call<Rpc_buffer>(mode, alpha); }
|
return call<Rpc_create_view>(parent); }
|
||||||
|
|
||||||
void focus(Nitpicker::Session_capability session) override {
|
void destroy_view(View_handle view) override {
|
||||||
call<Rpc_focus>(session); }
|
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_ */
|
#endif /* _INCLUDE__NITPICKER_SESSION__CLIENT_H_ */
|
||||||
|
|
|
@ -44,7 +44,7 @@ class Nitpicker::Connection : public Genode::Connection<Session>,
|
||||||
* Declare ram-quota donation
|
* Declare ram-quota donation
|
||||||
*/
|
*/
|
||||||
using Genode::Arg_string;
|
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);
|
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA);
|
||||||
|
|
||||||
if (stay_top)
|
if (stay_top)
|
||||||
|
|
|
@ -17,13 +17,20 @@
|
||||||
#define _INCLUDE__NITPICKER_SESSION__NITPICKER_SESSION_H_
|
#define _INCLUDE__NITPICKER_SESSION__NITPICKER_SESSION_H_
|
||||||
|
|
||||||
#include <session/session.h>
|
#include <session/session.h>
|
||||||
|
#include <os/surface.h>
|
||||||
|
#include <os/handle_registry.h>
|
||||||
#include <framebuffer_session/capability.h>
|
#include <framebuffer_session/capability.h>
|
||||||
#include <input_session/capability.h>
|
#include <input_session/capability.h>
|
||||||
#include <nitpicker_view/capability.h>
|
|
||||||
|
|
||||||
namespace Nitpicker {
|
namespace Nitpicker {
|
||||||
using Genode::size_t;
|
using Genode::size_t;
|
||||||
|
struct View;
|
||||||
|
typedef Genode::Capability<View> View_capability;
|
||||||
struct Session;
|
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"; }
|
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 Out_of_metadata : Genode::Exception { };
|
||||||
|
struct Invalid_handle : Genode::Exception { };
|
||||||
|
|
||||||
virtual ~Session() { }
|
virtual ~Session() { }
|
||||||
|
|
||||||
|
@ -53,24 +195,57 @@ struct Nitpicker::Session : Genode::Session
|
||||||
*
|
*
|
||||||
* \param parent parent view
|
* \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
|
* The 'parent' argument allows the client to use the location of an
|
||||||
* existing view as the coordinate origin for the to-be-created view.
|
* 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.
|
* 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
|
* 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
|
* 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_framebuffer_session, Framebuffer::Session_capability, framebuffer_session);
|
||||||
GENODE_RPC(Rpc_input_session, Input::Session_capability, input_session);
|
GENODE_RPC(Rpc_input_session, Input::Session_capability, input_session);
|
||||||
GENODE_RPC(Rpc_create_view, View_capability, create_view, View_capability);
|
GENODE_RPC_THROW(Rpc_create_view, View_handle, create_view,
|
||||||
GENODE_RPC(Rpc_destroy_view, void, destroy_view, View_capability);
|
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_background, int, background, View_capability);
|
||||||
GENODE_RPC(Rpc_mode, Framebuffer::Mode, mode);
|
GENODE_RPC(Rpc_mode, Framebuffer::Mode, mode);
|
||||||
GENODE_RPC(Rpc_focus, void, focus, Genode::Capability<Session>);
|
GENODE_RPC(Rpc_focus, void, focus, Genode::Capability<Session>);
|
||||||
GENODE_RPC_THROW(Rpc_buffer, void, buffer, GENODE_TYPE_LIST(Out_of_metadata),
|
GENODE_RPC_THROW(Rpc_buffer, void, buffer, GENODE_TYPE_LIST(Out_of_metadata),
|
||||||
Framebuffer::Mode, bool);
|
Framebuffer::Mode, bool);
|
||||||
|
|
||||||
GENODE_RPC_INTERFACE(Rpc_framebuffer_session, Rpc_input_session,
|
/*
|
||||||
Rpc_create_view, Rpc_destroy_view, Rpc_background,
|
* The 'GENODE_RPC_INTERFACE' declaration is done manually because the
|
||||||
Rpc_mode, Rpc_buffer, Rpc_focus);
|
* 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_ */
|
#endif /* _INCLUDE__NITPICKER_SESSION__NITPICKER_SESSION_H_ */
|
||||||
|
|
|
@ -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_ */
|
|
|
@ -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_ */
|
|
|
@ -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_ */
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <nitpicker_view/client.h>
|
|
||||||
#include <cap_session/connection.h>
|
#include <cap_session/connection.h>
|
||||||
#include <nitpicker_session/connection.h>
|
#include <nitpicker_session/connection.h>
|
||||||
#include <dataspace/client.h>
|
#include <dataspace/client.h>
|
||||||
|
@ -176,9 +175,13 @@ int main(int argc, char **argv)
|
||||||
/*
|
/*
|
||||||
* Create Nitpicker view and bring it to front
|
* Create Nitpicker view and bring it to front
|
||||||
*/
|
*/
|
||||||
Nitpicker::View_client view(nitpicker.create_view());
|
Nitpicker::Session::View_handle view = nitpicker.create_view();
|
||||||
view.viewport(view_x, view_y, view_w, view_h, 0, 0, false);
|
typedef Nitpicker::Session::Command Command;
|
||||||
view.stack(Nitpicker::View_capability(), true, true);
|
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
|
* Initialize server entry point
|
||||||
|
@ -243,7 +246,11 @@ int main(int argc, char **argv)
|
||||||
try {
|
try {
|
||||||
config()->reload();
|
config()->reload();
|
||||||
cfg = Config_args();
|
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 (...) {
|
} catch (...) {
|
||||||
PERR("Error while reloading config");
|
PERR("Error while reloading config");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
#include <input_session/connection.h>
|
#include <input_session/connection.h>
|
||||||
#include <input_session/input_session.h>
|
#include <input_session/input_session.h>
|
||||||
#include <nitpicker_view/nitpicker_view.h>
|
|
||||||
#include <nitpicker_session/nitpicker_session.h>
|
#include <nitpicker_session/nitpicker_session.h>
|
||||||
#include <framebuffer_session/connection.h>
|
#include <framebuffer_session/connection.h>
|
||||||
#include <util/color.h>
|
#include <util/color.h>
|
||||||
|
@ -43,13 +42,13 @@
|
||||||
|
|
||||||
namespace Input { class Session_component; }
|
namespace Input { class Session_component; }
|
||||||
namespace Framebuffer { class Session_component; }
|
namespace Framebuffer { class Session_component; }
|
||||||
|
|
||||||
namespace Nitpicker {
|
namespace Nitpicker {
|
||||||
class Session_component;
|
class Session_component;
|
||||||
template <typename> class Root;
|
template <typename> class Root;
|
||||||
struct Main;
|
struct Main;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
using Genode::size_t;
|
using Genode::size_t;
|
||||||
using Genode::Allocator;
|
using Genode::Allocator;
|
||||||
using Genode::Rpc_entrypoint;
|
using Genode::Rpc_entrypoint;
|
||||||
|
@ -67,6 +66,8 @@ using Genode::Signal_context_capability;
|
||||||
using Genode::Signal_rpc_member;
|
using Genode::Signal_rpc_member;
|
||||||
using Genode::Attached_ram_dataspace;
|
using Genode::Attached_ram_dataspace;
|
||||||
using Genode::Attached_dataspace;
|
using Genode::Attached_dataspace;
|
||||||
|
using Genode::Weak_ptr;
|
||||||
|
using Genode::Locked_ptr;
|
||||||
|
|
||||||
|
|
||||||
Framebuffer::Session *tmp_fb;
|
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 **
|
** Implementation of Nitpicker service **
|
||||||
*****************************************/
|
*****************************************/
|
||||||
|
@ -438,7 +377,9 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Genode::Allocator_guard _buffer_alloc;
|
typedef ::View View;
|
||||||
|
|
||||||
|
Genode::Allocator_guard _session_alloc;
|
||||||
|
|
||||||
Framebuffer::Session &_framebuffer;
|
Framebuffer::Session &_framebuffer;
|
||||||
|
|
||||||
|
@ -458,7 +399,9 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
|
|
||||||
Mode &_mode;
|
Mode &_mode;
|
||||||
|
|
||||||
List<View_component> _view_list;
|
List<Session_view_list_elem> _view_list;
|
||||||
|
|
||||||
|
Genode::Tslab<View, 4000> _view_alloc { &_session_alloc };
|
||||||
|
|
||||||
/* capabilities for sub sessions */
|
/* capabilities for sub sessions */
|
||||||
Framebuffer::Session_capability _framebuffer_session_cap;
|
Framebuffer::Session_capability _framebuffer_session_cap;
|
||||||
|
@ -469,6 +412,15 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
/* size of currently allocated virtual framebuffer, in bytes */
|
/* size of currently allocated virtual framebuffer, in bytes */
|
||||||
size_t _buffer_size = 0;
|
size_t _buffer_size = 0;
|
||||||
|
|
||||||
|
Attached_ram_dataspace _command_ds { env()->ram_session(),
|
||||||
|
sizeof(Command_buffer) };
|
||||||
|
|
||||||
|
Command_buffer &_command_buffer = *_command_ds.local_addr<Command_buffer>();
|
||||||
|
|
||||||
|
typedef Genode::Handle_registry<View_handle, View> View_handle_registry;
|
||||||
|
|
||||||
|
View_handle_registry _view_handle_registry;
|
||||||
|
|
||||||
void _release_buffer()
|
void _release_buffer()
|
||||||
{
|
{
|
||||||
if (!::Session::texture())
|
if (!::Session::texture())
|
||||||
|
@ -483,12 +435,30 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
::Session::texture(0, false);
|
::Session::texture(0, false);
|
||||||
::Session::input_mask(0);
|
::Session::input_mask(0);
|
||||||
|
|
||||||
destroy(&_buffer_alloc, const_cast<Chunky_dataspace_texture<PT> *>(cdt));
|
destroy(&_session_alloc, const_cast<Chunky_dataspace_texture<PT> *>(cdt));
|
||||||
|
|
||||||
_buffer_alloc.upgrade(_buffer_size);
|
_session_alloc.upgrade(_buffer_size);
|
||||||
_buffer_size = 0;
|
_buffer_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for performing sanity checks in OP_TO_FRONT and OP_TO_BACK
|
||||||
|
*
|
||||||
|
* We have to check for the equality of both the specified view and
|
||||||
|
* neighbor. If both arguments refer to the same view, the creation of
|
||||||
|
* locked pointers for both views would result in a deadlock.
|
||||||
|
*/
|
||||||
|
bool _views_are_equal(View_handle v1, View_handle v2)
|
||||||
|
{
|
||||||
|
if (!v1.valid() || !v2.valid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Weak_ptr<View> v1_ptr = _view_handle_registry.lookup(v1);
|
||||||
|
Weak_ptr<View> v2_ptr = _view_handle_registry.lookup(v2);
|
||||||
|
|
||||||
|
return v1_ptr == v2_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool _focus_change_permitted() const
|
bool _focus_change_permitted() const
|
||||||
{
|
{
|
||||||
::Session * const focused_session = _mode.focused_session();
|
::Session * const focused_session = _mode.focused_session();
|
||||||
|
@ -521,6 +491,137 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
return strcmp(focused_label, caller_label, Genode::strlen(caller_label)) == 0;
|
return strcmp(focused_label, caller_label, Genode::strlen(caller_label)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _execute_command(Command const &command)
|
||||||
|
{
|
||||||
|
switch (command.opcode) {
|
||||||
|
|
||||||
|
case Command::OP_GEOMETRY:
|
||||||
|
{
|
||||||
|
Locked_ptr<View> view(_view_handle_registry.lookup(command.geometry.view));
|
||||||
|
if (!view.is_valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Point pos = command.geometry.rect.p1();
|
||||||
|
|
||||||
|
/* transpose y position of top-level views by vertical session offset */
|
||||||
|
if (view->top_level())
|
||||||
|
pos = pos + Point(0, v_offset());
|
||||||
|
|
||||||
|
if (view.is_valid())
|
||||||
|
_view_stack.geometry(*view, Rect(pos, command.geometry.rect.area()));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_OFFSET:
|
||||||
|
{
|
||||||
|
Locked_ptr<View> view(_view_handle_registry.lookup(command.geometry.view));
|
||||||
|
|
||||||
|
if (view.is_valid())
|
||||||
|
_view_stack.buffer_offset(*view, command.offset.offset);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_TO_FRONT:
|
||||||
|
{
|
||||||
|
if (_views_are_equal(command.to_front.view, command.to_front.neighbor))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Locked_ptr<View> view(_view_handle_registry.lookup(command.to_front.view));
|
||||||
|
if (!view.is_valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* bring to front if no neighbor is specified */
|
||||||
|
if (!command.to_front.neighbor.valid()) {
|
||||||
|
_view_stack.stack(*view, nullptr, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stack view relative to neighbor */
|
||||||
|
Locked_ptr<View> neighbor(_view_handle_registry.lookup(command.to_front.neighbor));
|
||||||
|
if (neighbor.is_valid())
|
||||||
|
_view_stack.stack(*view, &(*neighbor), false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_TO_BACK:
|
||||||
|
{
|
||||||
|
if (_views_are_equal(command.to_front.view, command.to_front.neighbor))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Locked_ptr<View> view(_view_handle_registry.lookup(command.to_back.view));
|
||||||
|
if (!view.is_valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* bring to front if no neighbor is specified */
|
||||||
|
if (!command.to_front.neighbor.valid()) {
|
||||||
|
_view_stack.stack(*view, nullptr, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stack view relative to neighbor */
|
||||||
|
Locked_ptr<View> neighbor(_view_handle_registry.lookup(command.to_back.neighbor));
|
||||||
|
if (neighbor.is_valid())
|
||||||
|
_view_stack.stack(*view, &(*neighbor), true);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_BACKGROUND:
|
||||||
|
{
|
||||||
|
if (_provides_default_bg) {
|
||||||
|
Locked_ptr<View> view(_view_handle_registry.lookup(command.to_front.view));
|
||||||
|
if (!view.is_valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
view->background(true);
|
||||||
|
_view_stack.default_background(*view);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* revert old background view to normal mode */
|
||||||
|
if (::Session::background())
|
||||||
|
::Session::background()->background(false);
|
||||||
|
|
||||||
|
/* assign session background */
|
||||||
|
Locked_ptr<View> view(_view_handle_registry.lookup(command.to_front.view));
|
||||||
|
if (!view.is_valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
::Session::background(&(*view));
|
||||||
|
|
||||||
|
/* switch background view to background mode */
|
||||||
|
if (::Session::background())
|
||||||
|
view->background(true);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_TITLE:
|
||||||
|
{
|
||||||
|
Locked_ptr<View> view(_view_handle_registry.lookup(command.title.view));
|
||||||
|
|
||||||
|
if (view.is_valid())
|
||||||
|
_view_stack.title(*view, command.title.title.string());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_NOP:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _destroy_view(View &view)
|
||||||
|
{
|
||||||
|
_view_stack.remove_view(view);
|
||||||
|
_ep.dissolve(&view);
|
||||||
|
_view_list.remove(&view);
|
||||||
|
destroy(_view_alloc, &view);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -534,19 +635,20 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
int v_offset,
|
int v_offset,
|
||||||
bool provides_default_bg,
|
bool provides_default_bg,
|
||||||
bool stay_top,
|
bool stay_top,
|
||||||
Allocator &buffer_alloc,
|
Allocator &session_alloc,
|
||||||
size_t ram_quota)
|
size_t ram_quota)
|
||||||
:
|
:
|
||||||
::Session(label, v_offset, stay_top),
|
::Session(label, v_offset, stay_top),
|
||||||
_buffer_alloc(&buffer_alloc, ram_quota),
|
_session_alloc(&session_alloc, ram_quota),
|
||||||
_framebuffer(framebuffer),
|
_framebuffer(framebuffer),
|
||||||
_framebuffer_session_component(view_stack, *this, framebuffer, *this),
|
_framebuffer_session_component(view_stack, *this, framebuffer, *this),
|
||||||
_ep(ep), _view_stack(view_stack), _mode(mode),
|
_ep(ep), _view_stack(view_stack), _mode(mode),
|
||||||
_framebuffer_session_cap(_ep.manage(&_framebuffer_session_component)),
|
_framebuffer_session_cap(_ep.manage(&_framebuffer_session_component)),
|
||||||
_input_session_cap(_ep.manage(&_input_session_component)),
|
_input_session_cap(_ep.manage(&_input_session_component)),
|
||||||
_provides_default_bg(provides_default_bg)
|
_provides_default_bg(provides_default_bg),
|
||||||
|
_view_handle_registry(_session_alloc)
|
||||||
{
|
{
|
||||||
_buffer_alloc.upgrade(ram_quota);
|
_session_alloc.upgrade(ram_quota);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -557,13 +659,18 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
_ep.dissolve(&_framebuffer_session_component);
|
_ep.dissolve(&_framebuffer_session_component);
|
||||||
_ep.dissolve(&_input_session_component);
|
_ep.dissolve(&_input_session_component);
|
||||||
|
|
||||||
while (View_component *vc = _view_list.first())
|
destroy_all_views();
|
||||||
destroy_view(vc->cap());
|
|
||||||
|
|
||||||
_release_buffer();
|
_release_buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void upgrade_ram_quota(size_t ram_quota) { _buffer_alloc.upgrade(ram_quota); }
|
void destroy_all_views()
|
||||||
|
{
|
||||||
|
while (Session_view_list_elem *v = _view_list.first())
|
||||||
|
_destroy_view(*static_cast<View *>(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
void upgrade_ram_quota(size_t ram_quota) { _session_alloc.upgrade(ram_quota); }
|
||||||
|
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
|
@ -601,61 +708,112 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
Input::Session_capability input_session() override {
|
Input::Session_capability input_session() override {
|
||||||
return _input_session_cap; }
|
return _input_session_cap; }
|
||||||
|
|
||||||
View_capability create_view(View_capability parent_cap) override
|
View_handle create_view(View_handle parent_handle) override
|
||||||
{
|
{
|
||||||
/* lookup parent view */
|
View *view = nullptr;
|
||||||
View_component *parent_view =
|
|
||||||
dynamic_cast<View_component *>(_ep.lookup_and_lock(parent_cap));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: Do not allocate View meta data from Heap!
|
* Create child view
|
||||||
* Use a heap partition!
|
|
||||||
*/
|
*/
|
||||||
View_component *view = new (env()->heap())
|
if (parent_handle.valid()) {
|
||||||
View_component(*this, _view_stack, _ep,
|
|
||||||
parent_view ? &parent_view->view() : 0);
|
|
||||||
|
|
||||||
if (parent_view)
|
try {
|
||||||
parent_view->view().add_child(&view->view());
|
Locked_ptr<View> parent(_view_handle_registry.lookup(parent_handle));
|
||||||
|
if (!parent.is_valid())
|
||||||
|
return View_handle();
|
||||||
|
|
||||||
if (parent_view)
|
view = new (_view_alloc)
|
||||||
parent_view->release();
|
View(*this,
|
||||||
|
stay_top() ? View::STAY_TOP : View::NOT_STAY_TOP,
|
||||||
|
View::NOT_TRANSPARENT, View::NOT_BACKGROUND,
|
||||||
|
&(*parent));
|
||||||
|
|
||||||
_view_list.insert(view);
|
parent->add_child(*view);
|
||||||
return _ep.manage(view);
|
}
|
||||||
}
|
catch (View_handle_registry::Lookup_failed) {
|
||||||
|
return View_handle(); }
|
||||||
void destroy_view(View_capability view_cap) override
|
catch (Genode::Allocator::Out_of_memory) {
|
||||||
{
|
throw Nitpicker::Session::Out_of_metadata(); }
|
||||||
View_component *vc = dynamic_cast<View_component *>(_ep.lookup_and_lock(view_cap));
|
|
||||||
if (!vc) return;
|
|
||||||
|
|
||||||
_view_stack.remove_view(vc->view());
|
|
||||||
_ep.dissolve(vc);
|
|
||||||
_view_list.remove(vc);
|
|
||||||
destroy(env()->heap(), vc);
|
|
||||||
}
|
|
||||||
|
|
||||||
int background(View_capability view_cap) override
|
|
||||||
{
|
|
||||||
if (_provides_default_bg) {
|
|
||||||
Object_pool<View_component>::Guard vc(_ep.lookup_and_lock(view_cap));
|
|
||||||
vc->view().background(true);
|
|
||||||
_view_stack.default_background(vc->view());
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* revert old background view to normal mode */
|
/*
|
||||||
if (::Session::background()) ::Session::background()->background(false);
|
* Create top-level view
|
||||||
|
*/
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
view = new (_view_alloc)
|
||||||
|
View(*this,
|
||||||
|
stay_top() ? View::STAY_TOP : View::NOT_STAY_TOP,
|
||||||
|
View::NOT_TRANSPARENT, View::NOT_BACKGROUND,
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
catch (Genode::Allocator::Out_of_memory) {
|
||||||
|
throw Nitpicker::Session::Out_of_metadata(); }
|
||||||
|
}
|
||||||
|
|
||||||
/* assign session background */
|
_view_list.insert(view);
|
||||||
Object_pool<View_component>::Guard vc(_ep.lookup_and_lock(view_cap));
|
_ep.manage(view);
|
||||||
::Session::background(&vc->view());
|
|
||||||
|
|
||||||
/* switch background view to background mode */
|
return _view_handle_registry.alloc(*view);
|
||||||
if (::Session::background()) vc->view().background(true);
|
}
|
||||||
|
|
||||||
return 0;
|
void destroy_view(View_handle handle) override
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Locked_ptr<View> view(_view_handle_registry.lookup(handle));
|
||||||
|
if (view.is_valid())
|
||||||
|
_destroy_view(*view);
|
||||||
|
}
|
||||||
|
catch (View_handle_registry::Lookup_failed) { }
|
||||||
|
|
||||||
|
_view_handle_registry.free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
View_handle view_handle(View_capability view_cap, View_handle handle) override
|
||||||
|
{
|
||||||
|
View *view = dynamic_cast<View *>(_ep.lookup_and_lock(view_cap));
|
||||||
|
if (!view) return View_handle();
|
||||||
|
|
||||||
|
Object_pool<Rpc_object_base>::Guard guard(view);
|
||||||
|
|
||||||
|
return _view_handle_registry.alloc(*view, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
View_capability view_capability(View_handle handle) override
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Locked_ptr<View> view(_view_handle_registry.lookup(handle));
|
||||||
|
return view.is_valid() ? view->cap() : View_capability();
|
||||||
|
}
|
||||||
|
catch (View_handle_registry::Lookup_failed) {
|
||||||
|
return View_capability();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_view_handle(View_handle handle) override
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
_view_handle_registry.free(handle); }
|
||||||
|
|
||||||
|
catch (View_handle_registry::Lookup_failed) {
|
||||||
|
PWRN("view lookup failed while releasing view handle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Genode::Dataspace_capability command_dataspace() override
|
||||||
|
{
|
||||||
|
return _command_ds.cap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute() override
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < _command_buffer.num(); i++) {
|
||||||
|
try {
|
||||||
|
_execute_command(_command_buffer.get(i)); }
|
||||||
|
catch (View_handle_registry::Lookup_failed) {
|
||||||
|
PWRN("view lookup failed during command execution"); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer::Mode mode() override
|
Framebuffer::Mode mode() override
|
||||||
|
@ -671,7 +829,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
void buffer(Framebuffer::Mode mode, bool use_alpha) override
|
void buffer(Framebuffer::Mode mode, bool use_alpha) override
|
||||||
{
|
{
|
||||||
/* check if the session quota suffices for the specified mode */
|
/* check if the session quota suffices for the specified mode */
|
||||||
if (_buffer_alloc.quota() < ram_quota(mode, use_alpha))
|
if (_session_alloc.quota() < ram_quota(mode, use_alpha))
|
||||||
throw Nitpicker::Session::Out_of_metadata();
|
throw Nitpicker::Session::Out_of_metadata();
|
||||||
|
|
||||||
_framebuffer_session_component.notify_mode_change(mode, use_alpha);
|
_framebuffer_session_component.notify_mode_change(mode, use_alpha);
|
||||||
|
@ -716,10 +874,10 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||||
Chunky_dataspace_texture<PT>::calc_num_bytes(size, use_alpha);
|
Chunky_dataspace_texture<PT>::calc_num_bytes(size, use_alpha);
|
||||||
|
|
||||||
Chunky_dataspace_texture<PT> * const texture =
|
Chunky_dataspace_texture<PT> * const texture =
|
||||||
new (&_buffer_alloc) Chunky_dataspace_texture<PT>(size, use_alpha);
|
new (&_session_alloc) Chunky_dataspace_texture<PT>(size, use_alpha);
|
||||||
|
|
||||||
if (!_buffer_alloc.withdraw(_buffer_size)) {
|
if (!_session_alloc.withdraw(_buffer_size)) {
|
||||||
destroy(&_buffer_alloc, texture);
|
destroy(&_session_alloc, texture);
|
||||||
_buffer_size = 0;
|
_buffer_size = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -756,7 +914,8 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
|
||||||
|
|
||||||
bool const stay_top = Arg_string::find_arg(args, "stay_top").bool_value(false);
|
bool const stay_top = Arg_string::find_arg(args, "stay_top").bool_value(false);
|
||||||
|
|
||||||
size_t const required_quota = Input::Session_component::ev_ds_size();
|
size_t const required_quota = Input::Session_component::ev_ds_size()
|
||||||
|
+ Genode::align_addr(sizeof(Session::Command_buffer), 12);
|
||||||
|
|
||||||
if (ram_quota < required_quota) {
|
if (ram_quota < required_quota) {
|
||||||
PWRN("Insufficient dontated ram_quota (%zd bytes), require %zd bytes",
|
PWRN("Insufficient dontated ram_quota (%zd bytes), require %zd bytes",
|
||||||
|
@ -791,6 +950,8 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
|
||||||
{
|
{
|
||||||
_session_list.remove(session);
|
_session_list.remove(session);
|
||||||
_global_keys.apply_config(_session_list);
|
_global_keys.apply_config(_session_list);
|
||||||
|
|
||||||
|
session->destroy_all_views();
|
||||||
_mode.forget(*session);
|
_mode.forget(*session);
|
||||||
|
|
||||||
destroy(md_alloc(), session);
|
destroy(md_alloc(), session);
|
||||||
|
@ -988,8 +1149,7 @@ void Nitpicker::Main::handle_input(unsigned)
|
||||||
|
|
||||||
/* update mouse cursor */
|
/* update mouse cursor */
|
||||||
if (old_mouse_pos != new_mouse_pos)
|
if (old_mouse_pos != new_mouse_pos)
|
||||||
user_state.viewport(mouse_cursor,
|
user_state.geometry(mouse_cursor, Rect(new_mouse_pos, mouse_size));
|
||||||
Rect(new_mouse_pos, mouse_size), Point());
|
|
||||||
|
|
||||||
/* perform redraw and flush pixels to the framebuffer */
|
/* perform redraw and flush pixels to the framebuffer */
|
||||||
user_state.draw(fb_screen->screen).flush([&] (Rect const &rect) {
|
user_state.draw(fb_screen->screen).flush([&] (Rect const &rect) {
|
||||||
|
|
|
@ -93,7 +93,7 @@ void User_state::handle_event(Input::Event ev)
|
||||||
if (type == Event::RELEASE && Mode::drag()) Mode::dec_key_cnt();
|
if (type == Event::RELEASE && Mode::drag()) Mode::dec_key_cnt();
|
||||||
|
|
||||||
View const * const pointed_view = find_view(_mouse_pos);
|
View const * const pointed_view = find_view(_mouse_pos);
|
||||||
Session * const pointed_session = pointed_view ? &pointed_view->session() : 0;
|
::Session * const pointed_session = pointed_view ? &pointed_view->session() : 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deliver a leave event if pointed-to session changed
|
* Deliver a leave event if pointed-to session changed
|
||||||
|
@ -175,7 +175,7 @@ void User_state::handle_event(Input::Event ev)
|
||||||
* to the global receiver. To reflect that change, we need to update
|
* to the global receiver. To reflect that change, we need to update
|
||||||
* the whole screen.
|
* the whole screen.
|
||||||
*/
|
*/
|
||||||
Session * const global_receiver = _global_keys.global_receiver(keycode);
|
::Session * const global_receiver = _global_keys.global_receiver(keycode);
|
||||||
if (global_receiver) {
|
if (global_receiver) {
|
||||||
_global_key_sequence = true;
|
_global_key_sequence = true;
|
||||||
_input_receiver = global_receiver;
|
_input_receiver = global_receiver;
|
||||||
|
@ -252,7 +252,7 @@ void User_state::handle_event(Input::Event ev)
|
||||||
** Mode interface **
|
** Mode interface **
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
void User_state::forget(Session const &session)
|
void User_state::forget(::Session const &session)
|
||||||
{
|
{
|
||||||
Mode::forget(session);
|
Mode::forget(session);
|
||||||
|
|
||||||
|
@ -260,10 +260,13 @@ void User_state::forget(Session const &session)
|
||||||
View * const pointed_view = find_view(_mouse_pos);
|
View * const pointed_view = find_view(_mouse_pos);
|
||||||
_pointed_session = pointed_view ? &pointed_view->session() : nullptr;
|
_pointed_session = pointed_view ? &pointed_view->session() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_input_receiver == &session)
|
||||||
|
_input_receiver = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void User_state::focused_session(Session *session)
|
void User_state::focused_session(::Session *session)
|
||||||
{
|
{
|
||||||
Mode::focused_session(session);
|
Mode::focused_session(session);
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,14 @@
|
||||||
#ifndef _VIEW_H_
|
#ifndef _VIEW_H_
|
||||||
#define _VIEW_H_
|
#define _VIEW_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
#include <util/list.h>
|
#include <util/list.h>
|
||||||
#include <util/dirty_rect.h>
|
#include <util/dirty_rect.h>
|
||||||
|
#include <base/weak_ptr.h>
|
||||||
|
#include <base/rpc_server.h>
|
||||||
|
|
||||||
|
/* local includes */
|
||||||
#include "mode.h"
|
#include "mode.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
|
||||||
|
@ -31,14 +35,19 @@ typedef Genode::Dirty_rect<Rect, 3> Dirty_rect;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For each buffer, there is a list of views that belong to
|
* For each buffer, there is a list of views that belong to this buffer.
|
||||||
* this buffer. This list is called Same_buffer_list.
|
|
||||||
*/
|
*/
|
||||||
struct Same_buffer_list_elem : Genode::List<Same_buffer_list_elem>::Element { };
|
struct Same_buffer_list_elem : Genode::List<Same_buffer_list_elem>::Element { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The view stack holds a list of all visible view in stacking order.
|
||||||
|
*/
|
||||||
struct View_stack_elem : Genode::List<View_stack_elem>::Element { };
|
struct View_stack_elem : Genode::List<View_stack_elem>::Element { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each session maintains a list of views owned by the session.
|
||||||
|
*/
|
||||||
|
struct Session_view_list_elem : Genode::List<Session_view_list_elem>::Element { };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a view has a parent, it is a list element of its parent view
|
* If a view has a parent, it is a list element of its parent view
|
||||||
|
@ -46,9 +55,22 @@ struct View_stack_elem : Genode::List<View_stack_elem>::Element { };
|
||||||
struct View_parent_elem : Genode::List<View_parent_elem>::Element { };
|
struct View_parent_elem : Genode::List<View_parent_elem>::Element { };
|
||||||
|
|
||||||
|
|
||||||
|
namespace Nitpicker { class View; }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use view capabilities as mere tokens to pass views between sessions.
|
||||||
|
* There is no RPC interface associated with a view.
|
||||||
|
*/
|
||||||
|
struct Nitpicker::View { GENODE_RPC_INTERFACE(); };
|
||||||
|
|
||||||
|
|
||||||
class View : public Same_buffer_list_elem,
|
class View : public Same_buffer_list_elem,
|
||||||
|
public Session_view_list_elem,
|
||||||
public View_stack_elem,
|
public View_stack_elem,
|
||||||
public View_parent_elem
|
public View_parent_elem,
|
||||||
|
public Genode::Weak_object<View>,
|
||||||
|
public Genode::Rpc_object<Nitpicker::View>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -86,11 +108,13 @@ class View : public Same_buffer_list_elem,
|
||||||
{
|
{
|
||||||
/* break link to our parent */
|
/* break link to our parent */
|
||||||
if (_parent)
|
if (_parent)
|
||||||
_parent->remove_child(this);
|
_parent->remove_child(*this);
|
||||||
|
|
||||||
/* break links to our children */
|
/* break links to our children */
|
||||||
while (View_parent_elem *e = _children.first())
|
while (View_parent_elem *e = _children.first()) {
|
||||||
static_cast<View *>(e)->dissolve_from_parent();
|
static_cast<View *>(e)->dissolve_from_parent();
|
||||||
|
_children.remove(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,9 +149,9 @@ class View : public Same_buffer_list_elem,
|
||||||
|
|
||||||
void geometry(Rect geometry) { _geometry = geometry; }
|
void geometry(Rect geometry) { _geometry = geometry; }
|
||||||
|
|
||||||
void add_child(View const *child) { _children.insert(child); }
|
void add_child(View const &child) { _children.insert(&child); }
|
||||||
|
|
||||||
void remove_child(View const *child) { _children.remove(child); }
|
void remove_child(View const &child) { _children.remove(&child); }
|
||||||
|
|
||||||
template <typename FN>
|
template <typename FN>
|
||||||
void for_each_child(FN const &fn) const {
|
void for_each_child(FN const &fn) const {
|
||||||
|
|
|
@ -237,14 +237,13 @@ void View_stack::refresh_view(View const &view, Rect const rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void View_stack::viewport(View &view, Rect const rect, Point const buffer_off)
|
void View_stack::geometry(View &view, Rect const rect)
|
||||||
{
|
{
|
||||||
Rect const old_outline = _outline(view);
|
Rect const old_outline = _outline(view);
|
||||||
|
|
||||||
refresh_view(view, Rect(Point(), _size));
|
refresh_view(view, Rect(Point(), _size));
|
||||||
|
|
||||||
view.geometry(Rect(rect));
|
view.geometry(Rect(rect));
|
||||||
view.buffer_off(buffer_off);
|
|
||||||
|
|
||||||
refresh_view(view, Rect(Point(), _size));
|
refresh_view(view, Rect(Point(), _size));
|
||||||
|
|
||||||
|
@ -256,6 +255,14 @@ void View_stack::viewport(View &view, Rect const rect, Point const buffer_off)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void View_stack::buffer_offset(View &view, Point const buffer_off)
|
||||||
|
{
|
||||||
|
view.buffer_off(buffer_off);
|
||||||
|
|
||||||
|
refresh_view(view, Rect(Point(), _size));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void View_stack::stack(View const &view, View const *neighbor, bool behind)
|
void View_stack::stack(View const &view, View const *neighbor, bool behind)
|
||||||
{
|
{
|
||||||
_views.remove(&view);
|
_views.remove(&view);
|
||||||
|
@ -291,6 +298,8 @@ View *View_stack::find_view(Point p)
|
||||||
|
|
||||||
void View_stack::remove_view(View const &view, bool redraw)
|
void View_stack::remove_view(View const &view, bool redraw)
|
||||||
{
|
{
|
||||||
|
view.for_each_child([&] (View const &child) { remove_view(child); });
|
||||||
|
|
||||||
/* remember geometry of view to remove */
|
/* remember geometry of view to remove */
|
||||||
Rect rect = _outline(view);
|
Rect rect = _outline(view);
|
||||||
|
|
||||||
|
|
|
@ -162,12 +162,18 @@ class View_stack
|
||||||
void refresh_view(View const &view, Rect);
|
void refresh_view(View const &view, Rect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define position and viewport
|
* Define view geometry
|
||||||
|
*
|
||||||
|
* \param rect new geometry of view on screen
|
||||||
|
*/
|
||||||
|
void geometry(View &view, Rect rect);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define buffer offset of view
|
||||||
*
|
*
|
||||||
* \param pos position of view on screen
|
|
||||||
* \param buffer_off view offset of displayed buffer
|
* \param buffer_off view offset of displayed buffer
|
||||||
*/
|
*/
|
||||||
void viewport(View &view, Rect pos, Point buffer_off);
|
void buffer_offset(View &view, Point buffer_off);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert view at specified position in view stack
|
* Insert view at specified position in view stack
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <loader_session/connection.h>
|
#include <loader_session/connection.h>
|
||||||
#include <nitpicker_view/client.h>
|
#include <nitpicker_session/client.h>
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
@ -36,16 +36,23 @@ int main(int argc, char **argv)
|
||||||
Loader::Session::View_geometry geometry = loader.view_geometry();
|
Loader::Session::View_geometry geometry = loader.view_geometry();
|
||||||
Nitpicker::View_capability view_cap = loader.view();
|
Nitpicker::View_capability view_cap = loader.view();
|
||||||
|
|
||||||
Nitpicker::View_client view(view_cap);
|
static Nitpicker_connection nitpicker;
|
||||||
view.stack(Nitpicker::View_capability(), true, false);
|
|
||||||
|
Nitpicker::Session::View_handle view_handle = nitpicker.view_handle(view_cap);
|
||||||
|
|
||||||
|
nitpicker.enqueue<Nitpicker::Session::Command::To_front>(view_handle);
|
||||||
|
nitpicker.execute();
|
||||||
|
|
||||||
Timer::Connection timer;
|
Timer::Connection timer;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
|
||||||
for (unsigned i = 0; i < 10; i++) {
|
for (unsigned i = 0; i < 10; i++) {
|
||||||
view.viewport(50*i, 50*i, geometry.width, geometry.height,
|
|
||||||
geometry.buf_x, geometry.buf_y, true);
|
Nitpicker::Rect rect(Nitpicker::Point(50*i, 50*i),
|
||||||
|
Nitpicker::Area(geometry.width, geometry.height));
|
||||||
|
nitpicker.enqueue<Nitpicker::Session::Command::Geometry>(rect);
|
||||||
|
|
||||||
timer.msleep(1000);
|
timer.msleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <nitpicker_session/connection.h>
|
#include <nitpicker_session/connection.h>
|
||||||
#include <nitpicker_view/client.h>
|
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
#include <input/event.h>
|
#include <input/event.h>
|
||||||
|
|
||||||
|
@ -26,34 +25,53 @@ class Test_view : public List<Test_view>::Element
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Nitpicker::View_capability _cap;
|
typedef Nitpicker::Session::View_handle View_handle;
|
||||||
int _x, _y, _w, _h;
|
typedef Nitpicker::Session::Command Command;
|
||||||
const char *_title;
|
|
||||||
Test_view const *_parent_view;
|
Nitpicker::Session_client &_nitpicker;
|
||||||
|
View_handle _handle;
|
||||||
|
int _x, _y, _w, _h;
|
||||||
|
const char *_title;
|
||||||
|
Test_view *_parent_view;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Test_view(Nitpicker::Session *nitpicker,
|
Test_view(Nitpicker::Session_client *nitpicker,
|
||||||
int x, int y, int w, int h,
|
int x, int y, int w, int h,
|
||||||
const char *title,
|
const char *title,
|
||||||
Test_view *parent_view = 0)
|
Test_view *parent_view = 0)
|
||||||
:
|
:
|
||||||
|
_nitpicker(*nitpicker),
|
||||||
_x(x), _y(y), _w(w), _h(h), _title(title), _parent_view(parent_view)
|
_x(x), _y(y), _w(w), _h(h), _title(title), _parent_view(parent_view)
|
||||||
{
|
{
|
||||||
using namespace Nitpicker;
|
using namespace Nitpicker;
|
||||||
|
|
||||||
View_capability parent_cap = parent_view ? parent_view->_cap
|
View_handle parent_handle;
|
||||||
: View_capability();
|
|
||||||
|
|
||||||
_cap = nitpicker->create_view(parent_cap);
|
if (_parent_view)
|
||||||
View_client(_cap).viewport(_x, _y, _w, _h, 0, 0, true);
|
parent_handle = _nitpicker.view_handle(_parent_view->view_cap());
|
||||||
View_client(_cap).stack(Nitpicker::View_capability(), true, true);
|
|
||||||
View_client(_cap).title(_title);
|
_handle = _nitpicker.create_view(parent_handle);
|
||||||
|
|
||||||
|
if (parent_handle.valid())
|
||||||
|
_nitpicker.release_view_handle(parent_handle);
|
||||||
|
|
||||||
|
Nitpicker::Rect rect(Nitpicker::Point(_x, _y), Nitpicker::Area(_w, _h));
|
||||||
|
_nitpicker.enqueue<Command::Geometry>(_handle, rect);
|
||||||
|
_nitpicker.enqueue<Command::To_front>(_handle);
|
||||||
|
_nitpicker.enqueue<Command::Title>(_handle, _title);
|
||||||
|
_nitpicker.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
Nitpicker::View_capability view_cap()
|
||||||
|
{
|
||||||
|
return _nitpicker.view_capability(_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void top()
|
void top()
|
||||||
{
|
{
|
||||||
Nitpicker::View_client(_cap).stack(Nitpicker::View_capability(), true, true);
|
_nitpicker.enqueue<Command::To_front>(_handle);
|
||||||
|
_nitpicker.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,7 +87,9 @@ class Test_view : public List<Test_view>::Element
|
||||||
_x = _parent_view ? x - _parent_view->x() : x;
|
_x = _parent_view ? x - _parent_view->x() : x;
|
||||||
_y = _parent_view ? y - _parent_view->y() : y;
|
_y = _parent_view ? y - _parent_view->y() : y;
|
||||||
|
|
||||||
Nitpicker::View_client(_cap).viewport(_x, _y, _w, _h, 0, 0, true);
|
Nitpicker::Rect rect(Nitpicker::Point(_x, _y), Nitpicker::Area(_w, _h));
|
||||||
|
_nitpicker.enqueue<Command::Geometry>(_handle, rect);
|
||||||
|
_nitpicker.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue