2011-12-22 15:19:25 +00:00
|
|
|
/*
|
|
|
|
* \brief Nitpicker test program
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2006-08-23
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 20:44:47 +00:00
|
|
|
* Copyright (C) 2006-2013 Genode Labs GmbH
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <base/env.h>
|
|
|
|
#include <util/list.h>
|
|
|
|
#include <base/sleep.h>
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
#include <base/log.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
#include <nitpicker_session/connection.h>
|
|
|
|
#include <timer_session/connection.h>
|
|
|
|
#include <input/event.h>
|
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
class Test_view : public List<Test_view>::Element
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
2014-06-06 15:26:53 +00:00
|
|
|
typedef Nitpicker::Session::View_handle View_handle;
|
|
|
|
typedef Nitpicker::Session::Command Command;
|
|
|
|
|
|
|
|
Nitpicker::Session_client &_nitpicker;
|
|
|
|
View_handle _handle;
|
|
|
|
int _x, _y, _w, _h;
|
|
|
|
const char *_title;
|
|
|
|
Test_view *_parent_view;
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2014-06-06 15:26:53 +00:00
|
|
|
Test_view(Nitpicker::Session_client *nitpicker,
|
2011-12-22 15:19:25 +00:00
|
|
|
int x, int y, int w, int h,
|
2014-02-14 09:36:04 +00:00
|
|
|
const char *title,
|
|
|
|
Test_view *parent_view = 0)
|
2011-12-22 15:19:25 +00:00
|
|
|
:
|
2014-06-06 15:26:53 +00:00
|
|
|
_nitpicker(*nitpicker),
|
2014-02-14 09:36:04 +00:00
|
|
|
_x(x), _y(y), _w(w), _h(h), _title(title), _parent_view(parent_view)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
|
|
|
using namespace Nitpicker;
|
|
|
|
|
2014-06-06 15:26:53 +00:00
|
|
|
View_handle parent_handle;
|
|
|
|
|
|
|
|
if (_parent_view)
|
|
|
|
parent_handle = _nitpicker.view_handle(_parent_view->view_cap());
|
|
|
|
|
|
|
|
_handle = _nitpicker.create_view(parent_handle);
|
|
|
|
|
|
|
|
if (parent_handle.valid())
|
|
|
|
_nitpicker.release_view_handle(parent_handle);
|
2014-02-14 09:36:04 +00:00
|
|
|
|
2014-06-06 15:26:53 +00:00
|
|
|
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);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void top()
|
|
|
|
{
|
2014-06-06 15:26:53 +00:00
|
|
|
_nitpicker.enqueue<Command::To_front>(_handle);
|
|
|
|
_nitpicker.execute();
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
2014-02-14 09:36:04 +00:00
|
|
|
/**
|
|
|
|
* Move view to absolute position
|
|
|
|
*/
|
2011-12-22 15:19:25 +00:00
|
|
|
void move(int x, int y)
|
|
|
|
{
|
2014-02-14 09:36:04 +00:00
|
|
|
/*
|
|
|
|
* If the view uses a parent view as corrdinate origin, we need to
|
|
|
|
* transform the absolute coordinates to parent-relative
|
|
|
|
* coordinates.
|
|
|
|
*/
|
|
|
|
_x = _parent_view ? x - _parent_view->x() : x;
|
|
|
|
_y = _parent_view ? y - _parent_view->y() : y;
|
|
|
|
|
2014-06-06 15:26:53 +00:00
|
|
|
Nitpicker::Rect rect(Nitpicker::Point(_x, _y), Nitpicker::Area(_w, _h));
|
|
|
|
_nitpicker.enqueue<Command::Geometry>(_handle, rect);
|
|
|
|
_nitpicker.execute();
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Accessors
|
|
|
|
*/
|
2014-02-14 09:36:04 +00:00
|
|
|
const char *title() const { return _title; }
|
|
|
|
int x() const { return _parent_view ? _parent_view->x() + _x : _x; }
|
|
|
|
int y() const { return _parent_view ? _parent_view->y() + _y : _y; }
|
|
|
|
int w() const { return _w; }
|
|
|
|
int h() const { return _h; }
|
2011-12-22 15:19:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class Test_view_stack : public List<Test_view>
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
|
|
|
unsigned char *_input_mask;
|
|
|
|
unsigned _input_mask_w;
|
|
|
|
public:
|
|
|
|
|
|
|
|
Test_view_stack(unsigned char *input_mask, unsigned input_mask_w)
|
|
|
|
: _input_mask(input_mask), _input_mask_w(input_mask_w) { }
|
|
|
|
|
|
|
|
Test_view *find(int x, int y)
|
|
|
|
{
|
|
|
|
for (Test_view *tv = first(); tv; tv = tv->next()) {
|
2014-02-14 09:36:04 +00:00
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
if (x < tv->x() || x >= tv->x() + tv->w()
|
|
|
|
|| y < tv->y() || y >= tv->y() + tv->h())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!_input_mask)
|
|
|
|
return tv;
|
|
|
|
|
|
|
|
if (_input_mask[(y - tv->y())*_input_mask_w + (x - tv->x())])
|
|
|
|
return tv;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void top(Test_view *tv)
|
|
|
|
{
|
|
|
|
remove(tv);
|
|
|
|
tv->top();
|
|
|
|
insert(tv);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Init sessions to the required external services
|
|
|
|
*/
|
|
|
|
enum { CONFIG_ALPHA = false };
|
2013-10-14 19:31:14 +00:00
|
|
|
static Nitpicker::Connection nitpicker;
|
2011-12-22 15:19:25 +00:00
|
|
|
static Timer::Connection timer;
|
|
|
|
|
2013-10-14 19:31:14 +00:00
|
|
|
Framebuffer::Mode const mode(256, 256, Framebuffer::Mode::RGB565);
|
|
|
|
nitpicker.buffer(mode, false);
|
|
|
|
|
2012-01-18 13:57:08 +00:00
|
|
|
int const scr_w = mode.width(), scr_h = mode.height();
|
2011-12-22 15:19:25 +00:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
log("screen is ", mode);
|
2011-12-22 15:19:25 +00:00
|
|
|
if (!scr_w || !scr_h) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error("got invalid screen - sleeping forever");
|
2011-12-22 15:19:25 +00:00
|
|
|
sleep_forever();
|
|
|
|
}
|
|
|
|
|
|
|
|
short *pixels = env()->rm_session()->attach(nitpicker.framebuffer()->dataspace());
|
|
|
|
unsigned char *alpha = (unsigned char *)&pixels[scr_w*scr_h];
|
|
|
|
unsigned char *input_mask = CONFIG_ALPHA ? alpha + scr_w*scr_h : 0;
|
|
|
|
|
|
|
|
Input::Event *ev_buf = (env()->rm_session()->attach(nitpicker.input()->dataspace()));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Paint some crap into pixel buffer, fill alpha channel and input-mask buffer
|
|
|
|
*
|
|
|
|
* Input should refer to the view if the alpha value is more than 50%.
|
|
|
|
*/
|
|
|
|
for (int i = 0; i < scr_h; i++)
|
|
|
|
for (int j = 0; j < scr_w; j++) {
|
|
|
|
pixels[i*scr_w + j] = (i/8)*32*64 + (j/4)*32 + i*j/256;
|
|
|
|
if (CONFIG_ALPHA) {
|
|
|
|
alpha[i*scr_w + j] = (i*2) ^ (j*2);
|
|
|
|
input_mask[i*scr_w + j] = alpha[i*scr_w + j] > 127;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create views to display the buffer
|
|
|
|
*/
|
|
|
|
Test_view_stack tvs(input_mask, scr_w);
|
|
|
|
|
2014-02-14 09:36:04 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* View 'v1' is used as coordinate origin of 'v2' and 'v3'.
|
|
|
|
*/
|
|
|
|
static Test_view v1(&nitpicker, 150, 100, 230, 200, "Eins");
|
|
|
|
static Test_view v2(&nitpicker, 20, 20, 230, 210, "Zwei", &v1);
|
|
|
|
static Test_view v3(&nitpicker, 40, 40, 230, 220, "Drei", &v1);
|
|
|
|
|
|
|
|
tvs.insert(&v1);
|
|
|
|
tvs.insert(&v2);
|
|
|
|
tvs.insert(&v3);
|
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Handle input events
|
|
|
|
*/
|
|
|
|
int omx = 0, omy = 0, key_cnt = 0;
|
|
|
|
Test_view *tv = 0;
|
|
|
|
while (1) {
|
|
|
|
|
2016-05-11 16:21:47 +00:00
|
|
|
while (!nitpicker.input()->pending()) timer.msleep(20);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
for (int i = 0, num_ev = nitpicker.input()->flush(); i < num_ev; i++) {
|
|
|
|
|
|
|
|
Input::Event *ev = &ev_buf[i];
|
|
|
|
|
|
|
|
if (ev->type() == Input::Event::PRESS) key_cnt++;
|
|
|
|
if (ev->type() == Input::Event::RELEASE) key_cnt--;
|
|
|
|
|
|
|
|
/* move selected view */
|
|
|
|
if (ev->type() == Input::Event::MOTION && key_cnt > 0 && tv)
|
|
|
|
tv->move(tv->x() + ev->ax() - omx, tv->y() + ev->ay() - omy);
|
|
|
|
|
|
|
|
/* find selected view and bring it to front */
|
|
|
|
if (ev->type() == Input::Event::PRESS && key_cnt == 1) {
|
|
|
|
|
|
|
|
tv = tvs.find(ev->ax(), ev->ay());
|
|
|
|
|
|
|
|
if (tv)
|
|
|
|
tvs.top(tv);
|
|
|
|
}
|
|
|
|
|
|
|
|
omx = ev->ax(); omy = ev->ay();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|