mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-07 20:00:23 +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/env.h>
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <base/rpc_server.h>
|
|
||||||
#include <os/attached_ram_dataspace.h>
|
#include <os/attached_ram_dataspace.h>
|
||||||
#include <input/event.h>
|
#include <input/event.h>
|
||||||
#include <input/keycodes.h>
|
#include <input/keycodes.h>
|
||||||
#include <root/component.h>
|
#include <root/component.h>
|
||||||
#include <dataspace/client.h>
|
#include <dataspace/client.h>
|
||||||
#include <cap_session/connection.h>
|
|
||||||
#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>
|
||||||
@ -31,7 +29,7 @@
|
|||||||
#include <nitpicker_gfx/pixel_rgb565.h>
|
#include <nitpicker_gfx/pixel_rgb565.h>
|
||||||
#include <nitpicker_gfx/string.h>
|
#include <nitpicker_gfx/string.h>
|
||||||
#include <os/session_policy.h>
|
#include <os/session_policy.h>
|
||||||
#include <os/signal_rpc_dispatcher.h>
|
#include <os/server.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
@ -45,9 +43,13 @@ namespace Input { using namespace Genode; }
|
|||||||
namespace Input { class Session_component; }
|
namespace Input { class Session_component; }
|
||||||
namespace Framebuffer { using namespace Genode; }
|
namespace Framebuffer { using namespace Genode; }
|
||||||
namespace Framebuffer { class Session_component; }
|
namespace Framebuffer { class Session_component; }
|
||||||
namespace Nitpicker { using namespace Genode; }
|
|
||||||
namespace Nitpicker { class Session_component; }
|
namespace Nitpicker {
|
||||||
namespace Nitpicker { template <typename> class Root; }
|
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;
|
Server::Entrypoint &ep;
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sessions to the required external services
|
* Sessions to the required external services
|
||||||
*/
|
*/
|
||||||
static Framebuffer::Connection framebuffer;
|
Framebuffer::Connection framebuffer;
|
||||||
static Input::Connection input;
|
Input::Connection input;
|
||||||
static Cap_connection cap;
|
|
||||||
|
|
||||||
static Input::Event * const ev_buf =
|
Input::Event * const ev_buf =
|
||||||
env()->rm_session()->attach(input.dataspace());
|
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
|
* Initialize framebuffer
|
||||||
*/
|
*/
|
||||||
Framebuffer::Mode const mode = framebuffer.mode();
|
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();
|
Dataspace_capability fb_ds_cap = framebuffer.dataspace();
|
||||||
if (!fb_ds_cap.valid()) {
|
|
||||||
PERR("Could not request dataspace for frame buffer");
|
typedef Pixel_rgb565 PT; /* physical pixel type */
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *fb_base = env()->rm_session()->attach(fb_ds_cap);
|
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 };
|
enum { MENUBAR_HEIGHT = 16 };
|
||||||
|
|
||||||
PT *menubar_pixels = (PT *)env()->heap()->alloc(sizeof(PT)*mode.width()*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
|
* Create view stack with default elements
|
||||||
*/
|
*/
|
||||||
Area mouse_size(big_mouse.w, big_mouse.h);
|
Area mouse_size { big_mouse.w, big_mouse.h };
|
||||||
Mouse_cursor<PT> mouse_cursor((PT *)&big_mouse.pixels[0][0],
|
Mouse_cursor<PT> mouse_cursor { (PT *)&big_mouse.pixels[0][0],
|
||||||
mouse_size, user_state);
|
mouse_size, user_state };
|
||||||
|
|
||||||
menubar.state(user_state, "", "", BLACK);
|
Background background = { screen.size() };
|
||||||
|
|
||||||
Background background(screen.size());
|
|
||||||
|
|
||||||
user_state.default_background(background);
|
|
||||||
user_state.stack(mouse_cursor);
|
|
||||||
user_state.stack(menubar);
|
|
||||||
user_state.stack(background);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize Nitpicker root interface
|
* Initialize Nitpicker root interface
|
||||||
*/
|
*/
|
||||||
Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
|
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;
|
|
||||||
|
|
||||||
|
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
|
* Configuration-update dispatcher, executed in the context of the RPC
|
||||||
* entrypoint.
|
* entrypoint.
|
||||||
@ -764,29 +717,45 @@ int main(int argc, char **argv)
|
|||||||
* In addition to installing the signal dispatcher, we trigger first signal
|
* In addition to installing the signal dispatcher, we trigger first signal
|
||||||
* manually to turn the initial configuration into effect.
|
* manually to turn the initial configuration into effect.
|
||||||
*/
|
*/
|
||||||
static auto config_func = [&](unsigned)
|
void 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();
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
* If kill mode is already active, we got recursively called from
|
||||||
@ -829,24 +798,36 @@ int main(int argc, char **argv)
|
|||||||
* check for 'user_state.kill()' at the beginning of the handler.
|
* check for 'user_state.kill()' at the beginning of the handler.
|
||||||
*/
|
*/
|
||||||
if (user_state.kill())
|
if (user_state.kill())
|
||||||
wait_and_dispatch_one_signal(sig_rec);
|
Server::wait_and_dispatch_one_signal();
|
||||||
|
|
||||||
} while (user_state.kill());
|
} while (user_state.kill());
|
||||||
};
|
}
|
||||||
|
|
||||||
auto input_dispatcher = signal_rpc_dispatcher(input_func);
|
|
||||||
|
void Nitpicker::Main::handle_config(unsigned)
|
||||||
/*
|
{
|
||||||
* Dispatch input on periodic timer signals every 10 milliseconds
|
config()->reload();
|
||||||
*/
|
global_keys.apply_config(session_list);
|
||||||
static Timer::Connection timer;
|
try {
|
||||||
timer.sigh(input_dispatcher.manage(sig_rec, ep));
|
config()->xml_node().sub_node("background")
|
||||||
timer.trigger_periodic(10*1000);
|
.attribute("color").value(&background.color);
|
||||||
|
} catch (...) { }
|
||||||
env()->parent()->announce(ep.manage(&np_root));
|
user_state.update_all_views();
|
||||||
|
}
|
||||||
for (;;)
|
|
||||||
wait_and_dispatch_one_signal(sig_rec);
|
|
||||||
|
/************
|
||||||
return 0;
|
** 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
|
TARGET = nitpicker
|
||||||
LIBS = base blit config
|
LIBS = base blit config server
|
||||||
SRC_CC = main.cc \
|
SRC_CC = main.cc \
|
||||||
view_stack.cc \
|
view_stack.cc \
|
||||||
view.cc \
|
view.cc \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user