mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 16:35:28 +00:00
nitpicker: Use server skeleton library
This commit is contained in:
parent
518a71ccf5
commit
f371aef346
@ -15,13 +15,11 @@
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <os/attached_ram_dataspace.h>
|
||||
#include <input/event.h>
|
||||
#include <input/keycodes.h>
|
||||
#include <root/component.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <input_session/connection.h>
|
||||
#include <input_session/input_session.h>
|
||||
@ -31,7 +29,7 @@
|
||||
#include <nitpicker_gfx/pixel_rgb565.h>
|
||||
#include <nitpicker_gfx/string.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <os/signal_rpc_dispatcher.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include "input.h"
|
||||
@ -45,9 +43,13 @@ namespace Input { using namespace Genode; }
|
||||
namespace Input { class Session_component; }
|
||||
namespace Framebuffer { using namespace Genode; }
|
||||
namespace Framebuffer { class Session_component; }
|
||||
namespace Nitpicker { using namespace Genode; }
|
||||
namespace Nitpicker { class Session_component; }
|
||||
namespace Nitpicker { template <typename> class Root; }
|
||||
|
||||
namespace Nitpicker {
|
||||
using namespace Genode;
|
||||
class Session_component;
|
||||
template <typename> class Root;
|
||||
struct Main;
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
@ -646,117 +648,68 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
|
||||
};
|
||||
|
||||
|
||||
void wait_and_dispatch_one_signal(Genode::Signal_receiver &sig_rec)
|
||||
struct Nitpicker::Main
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/*
|
||||
* We call the signal dispatcher outside of the scope of 'Signal'
|
||||
* object because we block the RPC interface in the input handler
|
||||
* when the kill mode gets actived. While kill mode is active, we
|
||||
* do not serve incoming RPC requests but we need to stay responsive
|
||||
* to user input. Hence, we wait for signals in the input dispatcher
|
||||
* in this case. An already existing 'Signal' object would lock the
|
||||
* signal receiver and thereby prevent this nested way of signal
|
||||
* handling.
|
||||
*/
|
||||
Signal_dispatcher_base *dispatcher = 0;
|
||||
unsigned num = 0;
|
||||
|
||||
{
|
||||
Signal sig = sig_rec.wait_for_signal();
|
||||
dispatcher = dynamic_cast<Signal_dispatcher_base *>(sig.context());
|
||||
num = sig.num();
|
||||
}
|
||||
|
||||
if (dispatcher)
|
||||
dispatcher->dispatch(num);
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
** Main program **
|
||||
******************/
|
||||
|
||||
typedef Pixel_rgb565 PT; /* physical pixel type */
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
using namespace Genode;
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
/*
|
||||
* Sessions to the required external services
|
||||
*/
|
||||
static Framebuffer::Connection framebuffer;
|
||||
static Input::Connection input;
|
||||
static Cap_connection cap;
|
||||
Framebuffer::Connection framebuffer;
|
||||
Input::Connection input;
|
||||
|
||||
static Input::Event * const ev_buf =
|
||||
Input::Event * const ev_buf =
|
||||
env()->rm_session()->attach(input.dataspace());
|
||||
|
||||
/*
|
||||
* Initialize server entry point
|
||||
*/
|
||||
enum { STACK_SIZE = 16*1024 };
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "nitpicker_ep");
|
||||
|
||||
/*
|
||||
* Initialize framebuffer
|
||||
*/
|
||||
Framebuffer::Mode const mode = framebuffer.mode();
|
||||
|
||||
PINF("framebuffer is %dx%d@%d\n",
|
||||
mode.width(), mode.height(), mode.format());
|
||||
|
||||
Dataspace_capability fb_ds_cap = framebuffer.dataspace();
|
||||
if (!fb_ds_cap.valid()) {
|
||||
PERR("Could not request dataspace for frame buffer");
|
||||
return -2;
|
||||
}
|
||||
|
||||
typedef Pixel_rgb565 PT; /* physical pixel type */
|
||||
|
||||
void *fb_base = env()->rm_session()->attach(fb_ds_cap);
|
||||
Screen<PT> screen((PT *)fb_base, Area(mode.width(), mode.height()));
|
||||
|
||||
Screen<PT> screen = { (PT *)fb_base, Area(mode.width(), mode.height()) };
|
||||
|
||||
/*
|
||||
* Menu bar
|
||||
*/
|
||||
enum { MENUBAR_HEIGHT = 16 };
|
||||
|
||||
PT *menubar_pixels = (PT *)env()->heap()->alloc(sizeof(PT)*mode.width()*16);
|
||||
Chunky_menubar<PT> menubar(menubar_pixels, Area(mode.width(), MENUBAR_HEIGHT));
|
||||
|
||||
static Global_keys global_keys;
|
||||
Chunky_menubar<PT> menubar = { menubar_pixels, Area(mode.width(), MENUBAR_HEIGHT) };
|
||||
|
||||
static Session_list session_list;
|
||||
/*
|
||||
* User-input policy
|
||||
*/
|
||||
Global_keys global_keys;
|
||||
|
||||
static User_state user_state(global_keys, screen, menubar);
|
||||
Session_list session_list;
|
||||
|
||||
User_state user_state = { global_keys, screen, menubar };
|
||||
|
||||
/*
|
||||
* Create view stack with default elements
|
||||
*/
|
||||
Area mouse_size(big_mouse.w, big_mouse.h);
|
||||
Mouse_cursor<PT> mouse_cursor((PT *)&big_mouse.pixels[0][0],
|
||||
mouse_size, user_state);
|
||||
Area mouse_size { big_mouse.w, big_mouse.h };
|
||||
Mouse_cursor<PT> mouse_cursor { (PT *)&big_mouse.pixels[0][0],
|
||||
mouse_size, user_state };
|
||||
|
||||
menubar.state(user_state, "", "", BLACK);
|
||||
|
||||
Background background(screen.size());
|
||||
|
||||
user_state.default_background(background);
|
||||
user_state.stack(mouse_cursor);
|
||||
user_state.stack(menubar);
|
||||
user_state.stack(background);
|
||||
Background background = { screen.size() };
|
||||
|
||||
/*
|
||||
* Initialize Nitpicker root interface
|
||||
*/
|
||||
Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
|
||||
|
||||
static Nitpicker::Root<PT> np_root(session_list, global_keys,
|
||||
ep, Area(mode.width(), mode.height()),
|
||||
user_state, sliced_heap,
|
||||
screen, framebuffer,
|
||||
MENUBAR_HEIGHT);
|
||||
|
||||
static Signal_receiver sig_rec;
|
||||
Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() };
|
||||
|
||||
Root<PT> np_root = { session_list, global_keys, ep.rpc_ep(),
|
||||
Area(mode.width(), mode.height()),
|
||||
user_state, sliced_heap, screen,
|
||||
framebuffer, MENUBAR_HEIGHT };
|
||||
/*
|
||||
* Configuration-update dispatcher, executed in the context of the RPC
|
||||
* entrypoint.
|
||||
@ -764,30 +717,46 @@ int main(int argc, char **argv)
|
||||
* In addition to installing the signal dispatcher, we trigger first signal
|
||||
* manually to turn the initial configuration into effect.
|
||||
*/
|
||||
static auto config_func = [&](unsigned)
|
||||
{
|
||||
config()->reload();
|
||||
global_keys.apply_config(session_list);
|
||||
try {
|
||||
config()->xml_node().sub_node("background")
|
||||
.attribute("color").value(&background.color);
|
||||
} catch (...) { }
|
||||
user_state.update_all_views();
|
||||
};
|
||||
void handle_config(unsigned);
|
||||
|
||||
auto config_dispatcher = signal_rpc_dispatcher(config_func);
|
||||
Signal_rpc_member<Main> config_dispatcher = { *this, &Main::handle_config };
|
||||
|
||||
Signal_context_capability config_sigh = config_dispatcher.manage(sig_rec, ep);
|
||||
Signal_context_capability config_sigh = ep.manage(config_dispatcher);
|
||||
|
||||
config()->sigh(config_sigh);
|
||||
/**
|
||||
* Signal handler invoked on the reception of user input
|
||||
*/
|
||||
void handle_input(unsigned);
|
||||
|
||||
Signal_transmitter(config_sigh).submit();
|
||||
Signal_rpc_member<Main> input_dispatcher = { *this, &Main::handle_input };
|
||||
|
||||
/*
|
||||
* Input dispatcher, executed in the contect of the RPC entrypoint
|
||||
* Dispatch input on periodic timer signals every 10 milliseconds
|
||||
*/
|
||||
static auto input_func = [&](unsigned num)
|
||||
Timer::Connection timer;
|
||||
|
||||
Main(Server::Entrypoint &ep) : ep(ep)
|
||||
{
|
||||
menubar.state(user_state, "", "", BLACK);
|
||||
|
||||
user_state.default_background(background);
|
||||
user_state.stack(mouse_cursor);
|
||||
user_state.stack(menubar);
|
||||
user_state.stack(background);
|
||||
|
||||
config()->sigh(config_sigh);
|
||||
Signal_transmitter(config_sigh).submit();
|
||||
|
||||
timer.sigh(ep.manage(input_dispatcher));
|
||||
timer.trigger_periodic(10*1000);
|
||||
|
||||
env()->parent()->announce(ep.manage(np_root));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Nitpicker::Main::handle_input(unsigned)
|
||||
{
|
||||
/*
|
||||
* If kill mode is already active, we got recursively called from
|
||||
* within this 'input_func' (via 'wait_and_dispatch_one_signal').
|
||||
@ -829,24 +798,36 @@ int main(int argc, char **argv)
|
||||
* check for 'user_state.kill()' at the beginning of the handler.
|
||||
*/
|
||||
if (user_state.kill())
|
||||
wait_and_dispatch_one_signal(sig_rec);
|
||||
Server::wait_and_dispatch_one_signal();
|
||||
|
||||
} while (user_state.kill());
|
||||
};
|
||||
|
||||
auto input_dispatcher = signal_rpc_dispatcher(input_func);
|
||||
|
||||
/*
|
||||
* Dispatch input on periodic timer signals every 10 milliseconds
|
||||
*/
|
||||
static Timer::Connection timer;
|
||||
timer.sigh(input_dispatcher.manage(sig_rec, ep));
|
||||
timer.trigger_periodic(10*1000);
|
||||
|
||||
env()->parent()->announce(ep.manage(&np_root));
|
||||
|
||||
for (;;)
|
||||
wait_and_dispatch_one_signal(sig_rec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Nitpicker::Main::handle_config(unsigned)
|
||||
{
|
||||
config()->reload();
|
||||
global_keys.apply_config(session_list);
|
||||
try {
|
||||
config()->xml_node().sub_node("background")
|
||||
.attribute("color").value(&background.color);
|
||||
} catch (...) { }
|
||||
user_state.update_all_views();
|
||||
}
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
namespace Server {
|
||||
|
||||
char const *name() { return "nitpicker_ep"; }
|
||||
|
||||
size_t stack_size() { return 4*1024*sizeof(long); }
|
||||
|
||||
void construct(Entrypoint &ep)
|
||||
{
|
||||
static Nitpicker::Main nitpicker(ep);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
TARGET = nitpicker
|
||||
LIBS = base blit config
|
||||
LIBS = base blit config server
|
||||
SRC_CC = main.cc \
|
||||
view_stack.cc \
|
||||
view.cc \
|
||||
|
Loading…
x
Reference in New Issue
Block a user