genode/repos/os/src/server/loader/nitpicker.h

312 lines
7.4 KiB
C++

/*
* \brief Virtualized nitpicker session interface exposed to the subsystem
* \author Christian Prochaska
* \author Norman Feske
* \date 2009-10-05
*/
/*
* Copyright (C) 2009-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 _NITPICKER_H_
#define _NITPICKER_H_
/* Genode includes */
#include <util/arg_string.h>
#include <util/misc_math.h>
#include <base/signal.h>
#include <nitpicker_session/connection.h>
#include <nitpicker_session/nitpicker_session.h>
#include <nitpicker_view/client.h>
/* local includes */
#include <input.h>
namespace Nitpicker {
using namespace Genode;
/**
* View interface provided to the loader client
*/
class Loader_view_component : public Rpc_object<View>
{
private:
View_client _view; /* wrapped view */
int _x, _y, _buf_x, _buf_y;
public:
/**
* Constructor
*/
Loader_view_component(View_capability view_cap)
:
_view(view_cap), _x(0), _y(0), _buf_x(0), _buf_y(0)
{ }
int x() const { return _x; }
int y() const { return _y; }
int buf_x() const { return _buf_x; }
int buf_y() const { return _buf_y; }
/******************************
** Nitpicker view interface **
******************************/
int viewport(int x, int y, int w, int h,
int buf_x, int buf_y, bool redraw)
{
_x = x, _y = y, _buf_x = buf_x, _buf_y = buf_y;
return _view.viewport(x, y, w, h, buf_x, buf_y, redraw);
}
int stack(View_capability neighbor_cap, bool behind, bool redraw)
{
return _view.stack(neighbor_cap, behind, redraw);
}
int title(Title const &title)
{
return _view.title(title.string());
}
};
/**
* View interface exposed to the subsystem
*/
class View_component : public Rpc_object<View>
{
private:
View_client _view; /* wrapped view */
Signal_context_capability _sigh;
bool _viewport_initialized;
int _x, _y, _w, _h, _buf_x, _buf_y;
public:
/**
* Constructor
*/
View_component(View_capability view_cap,
Signal_context_capability sigh)
:
_view(view_cap), _sigh(sigh), _viewport_initialized(false),
_x(0), _y(0), _w(0), _h(0), _buf_x(0), _buf_y(0)
{ }
int x() const { return _x; }
int y() const { return _y; }
int w() const { return _w; }
int h() const { return _h; }
int buf_x() const { return _buf_x; }
int buf_y() const { return _buf_y; }
/******************************
** Nitpicker view interface **
******************************/
int viewport(int x, int y, int w, int h,
int buf_x, int buf_y, bool redraw)
{
_x = x; _y = y; _w = w; _h = h;
_buf_x = buf_x; _buf_y = buf_y;
if (_viewport_initialized)
return 0;
_viewport_initialized = true;
/* hide the view and let the application set the viewport */
int result = _view.viewport(0, 0, 0, 0, 0, 0, true);
/* signal readyness of the view */
if (_sigh.valid())
Signal_transmitter(_sigh).submit();
return result;
}
int stack(View_capability neighbor_cap, bool behind, bool redraw)
{
/*
* Only one child view is supported, so the stack request can
* be ignored.
*/
return 0;
}
int title(Title const &title)
{
return _view.title(title.string());
}
};
class Session_component : public Rpc_object<Session>,
public Input::Transformer
{
private:
Rpc_entrypoint &_ep;
int _max_width;
int _max_height;
Nitpicker::Connection _nitpicker;
View_capability _nitpicker_view;
View_component _proxy_view;
View_capability _proxy_view_cap;
Loader_view_component _loader_view;
View_capability _loader_view_cap;
Input::Session_component _proxy_input;
Input::Session_capability _proxy_input_cap;
static long _session_arg(const char *arg, const char *key) {
return Arg_string::find_arg(arg, key).long_value(0); }
public:
/**
* Constructor
*/
Session_component(Rpc_entrypoint &ep,
int max_width,
int max_height,
Nitpicker::View_capability parent_view,
Signal_context_capability view_ready_sigh,
const char *args)
:
_ep(ep),
_max_width(max_width),
_max_height(max_height),
/* create Nitpicker view */
_nitpicker_view(_nitpicker.create_view(parent_view)),
/* create proxy view component for the child */
_proxy_view(_nitpicker_view, view_ready_sigh),
_proxy_view_cap(_ep.manage(&_proxy_view)),
/* create view component accessed by the loader client */
_loader_view(_nitpicker_view),
_loader_view_cap(_ep.manage(&_loader_view)),
_proxy_input(_nitpicker.input_session(), *this),
_proxy_input_cap(_ep.manage(&_proxy_input))
{ }
/*********************************
** Nitpicker session interface **
*********************************/
Framebuffer::Session_capability framebuffer_session()
{
return _nitpicker.framebuffer_session();
}
Input::Session_capability input_session()
{
return _proxy_input_cap;
}
View_capability create_view(View_capability)
{
return _proxy_view_cap;
}
void destroy_view(View_capability view)
{
_nitpicker.destroy_view(_nitpicker_view);
}
int background(View_capability view)
{
/* not forwarding to real nitpicker session */
return 0;
}
Framebuffer::Mode mode()
{
int mode_width = (_max_width > -1) ?
_max_width :
_nitpicker.mode().width();
int mode_height = (_max_height > -1) ?
_max_height :
_nitpicker.mode().height();
return Framebuffer::Mode(mode_width, mode_height,
_nitpicker.mode().format());
}
void buffer(Framebuffer::Mode mode, bool use_alpha)
{
_nitpicker.buffer(mode, use_alpha);
}
/**********************************
** Input::Transformer interface **
**********************************/
Input::Transformer::Delta delta()
{
/* translate mouse position to child's coordinate system */
Input::Transformer::Delta result = {
_loader_view.x() + _loader_view.buf_x() +
_proxy_view.x() + _proxy_view.buf_x(),
_loader_view.y() + _loader_view.buf_y() +
_proxy_view.y() + _proxy_view.buf_y() };
return result;
}
/**
* Return the client-specific wrapper view for the Nitpicker view
* showing the child content
*/
View_capability loader_view() { return _loader_view_cap; }
/**
* Return geometry of loader view
*/
Loader::Session::View_geometry loader_view_geometry()
{
int view_width = (_max_width > -1) ?
min(_proxy_view.w(), _max_width) :
_proxy_view.w();
int view_height = (_max_height > -1) ?
min(_proxy_view.h(), _max_height) :
_proxy_view.h();
Loader::Session::View_geometry result(
view_width,
view_height,
_proxy_view.buf_x(),
_proxy_view.buf_y());
return result;
}
};
}
#endif /* _NITPICKER_H_ */