nitpicker: New signal handling, bg color config

This patch overhauls the signal handling of nitpicker to clear the way
towards dynamic reconfiguration. Furthermore, it moves the
implementation of the global-keys handling and input utilities to
separate files.
This commit is contained in:
Norman Feske
2013-09-07 23:48:40 +02:00
parent 430582c060
commit 602e36394d
7 changed files with 628 additions and 563 deletions

View File

@ -65,3 +65,10 @@ the "launchpad -> testnit" program is running. As soon as testnit gets started
by launchpad, testnit will receive the events. If the order was reversed, by launchpad, testnit will receive the events. If the order was reversed,
launchpad would always receive the events. launchpad would always receive the events.
Background color
----------------
The background color can be defined via the '<background>' config node:
! <background color="#112233" />

View File

@ -0,0 +1,90 @@
/*
* \brief Global keys handling
* \author Norman Feske
* \date 2013-09-07
*/
/*
* Copyright (C) 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.
*/
/* Genode includes */
#include <os/config.h>
/* local includes */
#include "global_keys.h"
Global_keys::Policy *Global_keys::_lookup_policy(char const *key_name)
{
for (unsigned i = 0; i < NUM_POLICIES; i++)
if (Genode::strcmp(key_name, Input::key_name((Input::Keycode)i)) == 0)
return &_policies[i];
return 0;
}
void Global_keys::apply_config(Session_list &session_list)
{
for (unsigned i = 0; i < NUM_POLICIES; i++)
_policies[i].undefine();
using Genode::Xml_node;
try {
Xml_node node = Genode::config()->xml_node().sub_node("global-keys").sub_node("key");
for (; ; node = node.next("key")) {
if (!node.has_attribute("name")) {
PWRN("attribute 'name' missing in <key> config node");
continue;
}
char name[32]; name[0] = 0;
node.attribute("name").value(name, sizeof(name));
Policy * policy = _lookup_policy(name);
if (!policy) {
PWRN("invalid key name \"%s\"", name);
continue;
}
/* if two policies match, give precedence to policy defined first */
if (policy->defined())
continue;
if (node.has_attribute("operation")) {
Xml_node::Attribute operation = node.attribute("operation");
if (operation.has_value("kill")) {
policy->operation_kill();
continue;
} else if (operation.has_value("xray")) {
policy->operation_xray();
continue;
} else {
char buf[32]; buf[0] = 0;
operation.value(buf, sizeof(buf));
PWRN("unknown operation \"%s\" for key %s", buf, name);
}
continue;
}
if (!node.has_attribute("label")) {
PWRN("missing 'label' attribute for key %s", name);
continue;
}
/* assign policy to matching client session */
for (Session *s = session_list.first(); s; s = s->next())
if (node.attribute("label").has_value(s->label()))
policy->client(s);
}
} catch (Xml_node::Nonexistent_sub_node) { }
}

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,13 @@ LIBS = base blit config
SRC_CC = main.cc \ SRC_CC = main.cc \
view_stack.cc \ view_stack.cc \
view.cc \ view.cc \
user_state.cc user_state.cc \
global_keys.cc
SRC_BIN = default.tff SRC_BIN = default.tff
# enable C++11 support
CC_CXX_OPT += -std=gnu++11
INC_DIR = $(PRG_DIR)/../include \ INC_DIR = $(PRG_DIR)/../include \
$(PRG_DIR)/../data $(PRG_DIR)/../data

View File

@ -19,6 +19,8 @@
struct Background : private Texture, Session, View struct Background : private Texture, Session, View
{ {
Color color;
/* /*
* The background uses no texture. Therefore * The background uses no texture. Therefore
* we can pass a null pointer as texture argument * we can pass a null pointer as texture argument
@ -28,7 +30,8 @@ struct Background : private Texture, Session, View
: :
Texture(Area(0, 0)), Session("", *this, 0, BLACK), Texture(Area(0, 0)), Session("", *this, 0, BLACK),
View(*this, View::NOT_STAY_TOP, View::NOT_TRANSPARENT, View(*this, View::NOT_STAY_TOP, View::NOT_TRANSPARENT,
View::BACKGROUND, Rect(Point(0, 0), size)) View::BACKGROUND, Rect(Point(0, 0), size)),
color(25, 37, 50)
{ } { }
@ -49,7 +52,7 @@ struct Background : private Texture, Session, View
void draw(Canvas &canvas, Mode const &mode) const void draw(Canvas &canvas, Mode const &mode) const
{ {
Clip_guard clip_guard(canvas, *this); Clip_guard clip_guard(canvas, *this);
canvas.draw_box(*this, Color(25, 37, 50)); canvas.draw_box(*this, color);
} }
}; };

View File

@ -0,0 +1,98 @@
/*
* \brief Input handling utilities
* \author Norman Feske
* \date 2013-09-07
*/
/*
* Copyright (C) 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 _INPUT_H_
#define _INPUT_H_
/* Genode includes */
#include <input/event.h>
/* local includes */
#include "user_state.h"
/**
* Determine number of events that can be merged into one
*
* \param ev pointer to first event array element to check
* \param max size of the event array
* \return number of events subjected to merge
*/
static unsigned num_consecutive_events(Input::Event const *ev, unsigned max)
{
if (max < 1) return 0;
if (ev->type() != Input::Event::MOTION) return 1;
bool first_is_absolute = ev->is_absolute_motion();
/* iterate until we get a different event type, start at second */
unsigned cnt = 1;
for (ev++ ; cnt < max; cnt++, ev++) {
if (ev->type() != Input::Event::MOTION) break;
if (first_is_absolute != ev->is_absolute_motion()) break;
}
return cnt;
}
/**
* Merge consecutive motion events
*
* \param ev event array to merge
* \param n number of events to merge
* \return merged motion event
*/
static Input::Event merge_motion_events(Input::Event const *ev, unsigned n)
{
Input::Event res;
for (unsigned i = 0; i < n; i++, ev++)
res = Input::Event(Input::Event::MOTION, 0, ev->ax(), ev->ay(),
res.rx() + ev->rx(), res.ry() + ev->ry());
return res;
}
static void import_input_events(Input::Event *ev_buf, unsigned num_ev,
User_state &user_state)
{
/*
* Take events from input event buffer, merge consecutive motion
* events, and pass result to the user state.
*/
for (unsigned src_ev_cnt = 0; src_ev_cnt < num_ev; src_ev_cnt++) {
Input::Event *e = &ev_buf[src_ev_cnt];
Input::Event curr = *e;
if (e->type() == Input::Event::MOTION) {
unsigned n = num_consecutive_events(e, num_ev - src_ev_cnt);
curr = merge_motion_events(e, n);
/* skip merged events */
src_ev_cnt += n - 1;
}
/*
* If subsequential relative motion events are merged to
* a zero-motion event, drop it. Otherwise, it would be
* misinterpreted as absolute event pointing to (0, 0).
*/
if (e->is_relative_motion() && curr.rx() == 0 && curr.ry() == 0)
continue;
/* pass event to user state */
user_state.handle_event(curr);
}
}
#endif /* _INPUT_H_ */

View File

@ -17,6 +17,9 @@
/* Genode includes */ /* Genode includes */
#include <util/list.h> #include <util/list.h>
#include <util/string.h> #include <util/string.h>
#include <nitpicker_gfx/color.h>
#include <nitpicker_gfx/geometry.h>
#include <nitpicker_gfx/canvas.h>
class Texture; class Texture;
class View; class View;