mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-23 12:35:41 +00:00
app/acpi_event: update coding style
Remove exceptions, replace pointer lookup by with_ pattern, use Xml_node::attribute_value, constness, naming of signal handlers Issue #5245
This commit is contained in:
parent
8a0689d832
commit
dcddeccccc
@ -82,303 +82,213 @@ class Transform::Keys : public Avl_node<Transform::Keys>
|
||||
return diff;
|
||||
}
|
||||
|
||||
static Keys * find_by(Avl_tree<Keys> &map, uint64_t acpi_code)
|
||||
static auto with_key(Avl_tree<Keys> &map, uint64_t acpi_code, auto const &fn)
|
||||
{
|
||||
Keys * head = map.first();
|
||||
if (!head)
|
||||
return head;
|
||||
if (!map.first())
|
||||
return;
|
||||
|
||||
return head->_find_by_acpi_value(acpi_code);
|
||||
Keys * const key_ptr = map.first()->_find_by_acpi_value(acpi_code);
|
||||
if (key_ptr)
|
||||
fn(*key_ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Transform::Main
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
enum {
|
||||
ACPI_POWER_BUTTON, ACPI_LID_OPEN, ACPI_LID_CLOSED,
|
||||
ACPI_AC_ONLINE, ACPI_AC_OFFLINE, ACPI_BATTERY
|
||||
};
|
||||
|
||||
Heap _heap;
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
Attached_rom_dataspace _config;
|
||||
Attached_rom_dataspace _acpi_ac;
|
||||
Attached_rom_dataspace _acpi_battery;
|
||||
Attached_rom_dataspace _acpi_ec;
|
||||
Attached_rom_dataspace _acpi_fixed;
|
||||
Attached_rom_dataspace _acpi_lid;
|
||||
Attached_rom_dataspace _acpi_hid;
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
Signal_handler<Main> _dispatch_acpi_ac;
|
||||
Signal_handler<Main> _dispatch_acpi_battery;
|
||||
Signal_handler<Main> _dispatch_acpi_ec;
|
||||
Signal_handler<Main> _dispatch_acpi_fixed;
|
||||
Signal_handler<Main> _dispatch_acpi_lid;
|
||||
Signal_handler<Main> _dispatch_acpi_hid;
|
||||
Attached_rom_dataspace
|
||||
_acpi_ac { _env, "acpi_ac" },
|
||||
_acpi_battery { _env, "acpi_battery" },
|
||||
_acpi_ec { _env, "acpi_ec" },
|
||||
_acpi_fixed { _env, "acpi_fixed" },
|
||||
_acpi_lid { _env, "acpi_lid" },
|
||||
_acpi_hid { _env, "acpi_hid" };
|
||||
|
||||
Event::Connection _event;
|
||||
Signal_handler<Main>
|
||||
_acpi_ac_handler { _env.ep(), *this, &Main::_handle_acpi_ac },
|
||||
_acpi_battery_handler { _env.ep(), *this, &Main::_handle_acpi_battery },
|
||||
_acpi_ec_handler { _env.ep(), *this, &Main::_handle_acpi_ec },
|
||||
_acpi_fixed_handler { _env.ep(), *this, &Main::_handle_acpi_fixed },
|
||||
_acpi_lid_handler { _env.ep(), *this, &Main::_handle_acpi_lid },
|
||||
_acpi_hid_handler { _env.ep(), *this, &Main::_handle_acpi_hid };
|
||||
|
||||
Event::Connection _event { _env };
|
||||
|
||||
Avl_tree<Keys> _map_ec { };
|
||||
Avl_tree<Keys> _map_hid { };
|
||||
Avl_tree<Keys> _map_special { };
|
||||
|
||||
Main(Env &env)
|
||||
:
|
||||
_heap(env.ram(), env.rm()),
|
||||
_config(env, "config"),
|
||||
_acpi_ac(env, "acpi_ac"),
|
||||
_acpi_battery(env, "acpi_battery"),
|
||||
_acpi_ec(env, "acpi_ec"),
|
||||
_acpi_fixed(env, "acpi_fixed"),
|
||||
_acpi_lid(env, "acpi_lid"),
|
||||
_acpi_hid(env, "acpi_hid"),
|
||||
_dispatch_acpi_ac(env.ep(), *this, &Main::check_acpi_ac),
|
||||
_dispatch_acpi_battery(env.ep(), *this, &Main::check_acpi_battery),
|
||||
_dispatch_acpi_ec(env.ep(), *this, &Main::check_acpi_ec),
|
||||
_dispatch_acpi_fixed(env.ep(), *this, &Main::check_acpi_fixed),
|
||||
_dispatch_acpi_lid(env.ep(), *this, &Main::check_acpi_lid),
|
||||
_dispatch_acpi_hid(env.ep(), *this, &Main::check_acpi_hid),
|
||||
_event(env)
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
Xml_node config(_config.local_addr<char>(), _config.size());
|
||||
config.for_each_sub_node("map", [&] (Xml_node map_node) {
|
||||
try {
|
||||
uint64_t acpi_value = 0;
|
||||
String<8> acpi_type;
|
||||
String<8> acpi_value_string;
|
||||
Input::Key_name to_key;
|
||||
_config.xml().for_each_sub_node("map", [&] (Xml_node const &map_node) {
|
||||
|
||||
String<16> key_type("PRESS_RELEASE");
|
||||
Keys::Type press_release = Keys::Type::PRESS_RELEASE;
|
||||
auto const acpi_type = map_node.attribute_value("acpi", String<8>());
|
||||
auto const to_key = map_node.attribute_value("to_key", Input::Key_name());
|
||||
auto const value_string = map_node.attribute_value("value", String<8>());
|
||||
auto const key_type = map_node.attribute_value("as", String<16>("PRESS_RELEASE"));
|
||||
|
||||
map_node.attribute("acpi").value(acpi_type);
|
||||
map_node.attribute("to_key").value(to_key);
|
||||
try {
|
||||
map_node.attribute("as").value(key_type);
|
||||
if (key_type == "PRESS")
|
||||
press_release = Keys::Type::PRESS;
|
||||
else if (key_type == "RELEASE")
|
||||
press_release = Keys::Type::RELEASE;
|
||||
else if (key_type != "PRESS_RELEASE")
|
||||
throw 0;
|
||||
} catch (Xml_node::Nonexistent_attribute) { }
|
||||
auto press_release = [&] () -> Keys::Type
|
||||
{
|
||||
if (key_type == "PRESS") return Keys::Type::PRESS;
|
||||
if (key_type == "RELEASE") return Keys::Type::RELEASE;
|
||||
warning("unsupported 'as' attribute value \"", key_type, "\"");
|
||||
return Keys::Type::PRESS_RELEASE;
|
||||
};
|
||||
|
||||
if (acpi_type == "lid" || acpi_type == "ac") {
|
||||
map_node.attribute("value").value(acpi_value_string);
|
||||
auto acpi_value = [&] () -> uint64_t
|
||||
{
|
||||
if (acpi_type == "lid") {
|
||||
if (value_string == "OPEN") return ACPI_LID_OPEN;
|
||||
if (value_string == "CLOSED") return ACPI_LID_CLOSED;
|
||||
warning("unsupported lid value \"", value_string, "\"");
|
||||
}
|
||||
if (acpi_type == "ac") {
|
||||
if (value_string == "ONLINE") return ACPI_AC_ONLINE;
|
||||
if (value_string == "OFFLINE") return ACPI_AC_OFFLINE;
|
||||
warning("unsupported ac value \"", value_string, "\"");
|
||||
}
|
||||
return map_node.attribute_value("value", uint64_t(0));
|
||||
};
|
||||
|
||||
if (acpi_type == "lid") {
|
||||
if (acpi_value_string == "OPEN")
|
||||
acpi_value = ACPI_LID_OPEN;
|
||||
else if (acpi_value_string == "CLOSED")
|
||||
acpi_value = ACPI_LID_CLOSED;
|
||||
else throw 1;
|
||||
} else
|
||||
if (acpi_type == "ac") {
|
||||
if (acpi_value_string == "ONLINE")
|
||||
acpi_value = ACPI_AC_ONLINE;
|
||||
else if (acpi_value_string == "OFFLINE")
|
||||
acpi_value = ACPI_AC_OFFLINE;
|
||||
else throw 2;
|
||||
} else
|
||||
throw 3;
|
||||
} else
|
||||
map_node.attribute("value").value(acpi_value);
|
||||
|
||||
Input::Keycode key_code = Input::key_code(to_key);
|
||||
|
||||
if (key_code == Input::Keycode::KEY_UNKNOWN)
|
||||
throw 4;
|
||||
|
||||
if (acpi_type == "ec")
|
||||
_map_ec.insert(new (_heap) Keys(key_code, acpi_value,
|
||||
press_release));
|
||||
else if (acpi_type == "fixed")
|
||||
_map_special.insert(new (_heap) Keys(key_code,
|
||||
ACPI_POWER_BUTTON,
|
||||
press_release));
|
||||
else if (acpi_type == "lid" || acpi_type == "ac")
|
||||
_map_special.insert(new (_heap) Keys(key_code, acpi_value,
|
||||
press_release));
|
||||
else if (acpi_type == "battery")
|
||||
_map_special.insert(new (_heap) Keys(key_code,
|
||||
ACPI_BATTERY,
|
||||
press_release));
|
||||
else if (acpi_type == "hid")
|
||||
_map_hid.insert(new (_heap) Keys(key_code, acpi_value,
|
||||
press_release));
|
||||
else
|
||||
throw 5;
|
||||
} catch (...) {
|
||||
|
||||
/* abort on malformed configuration */
|
||||
error("map item '", map_node, "' Aborting...");
|
||||
env.parent().exit(1);
|
||||
Input::Keycode const key_code = Input::key_code(to_key);
|
||||
if (key_code == Input::Keycode::KEY_UNKNOWN) {
|
||||
warning("unsupported 'to_key' attribute value \"", to_key, "\"");
|
||||
return;
|
||||
}
|
||||
|
||||
if (acpi_type == "ec")
|
||||
_map_ec.insert(new (_heap) Keys(key_code, acpi_value(),
|
||||
press_release()));
|
||||
else if (acpi_type == "fixed")
|
||||
_map_special.insert(new (_heap) Keys(key_code,
|
||||
ACPI_POWER_BUTTON,
|
||||
press_release()));
|
||||
else if (acpi_type == "lid" || acpi_type == "ac")
|
||||
_map_special.insert(new (_heap) Keys(key_code, acpi_value(),
|
||||
press_release()));
|
||||
else if (acpi_type == "battery")
|
||||
_map_special.insert(new (_heap) Keys(key_code,
|
||||
ACPI_BATTERY,
|
||||
press_release()));
|
||||
else if (acpi_type == "hid")
|
||||
_map_hid.insert(new (_heap) Keys(key_code, acpi_value(),
|
||||
press_release()));
|
||||
else
|
||||
warning("unsupported 'acpi' attribute value \"", acpi_type, "\"");
|
||||
});
|
||||
|
||||
_acpi_ac.sigh(_dispatch_acpi_ac);
|
||||
_acpi_battery.sigh(_dispatch_acpi_battery);
|
||||
_acpi_ec.sigh(_dispatch_acpi_ec);
|
||||
_acpi_fixed.sigh(_dispatch_acpi_fixed);
|
||||
_acpi_lid.sigh(_dispatch_acpi_lid);
|
||||
_acpi_hid.sigh(_dispatch_acpi_hid);
|
||||
_acpi_ac .sigh(_acpi_ac_handler);
|
||||
_acpi_battery.sigh(_acpi_battery_handler);
|
||||
_acpi_ec .sigh(_acpi_ec_handler);
|
||||
_acpi_fixed .sigh(_acpi_fixed_handler);
|
||||
_acpi_lid .sigh(_acpi_lid_handler);
|
||||
_acpi_hid .sigh(_acpi_hid_handler);
|
||||
|
||||
/* check for initial valid ACPI data */
|
||||
check_acpi_ac();
|
||||
check_acpi_battery();
|
||||
check_acpi_ec();
|
||||
check_acpi_fixed();
|
||||
check_acpi_lid();
|
||||
check_acpi_hid();
|
||||
_handle_acpi_ac();
|
||||
_handle_acpi_battery();
|
||||
_handle_acpi_ec();
|
||||
_handle_acpi_fixed();
|
||||
_handle_acpi_lid();
|
||||
_handle_acpi_hid();
|
||||
}
|
||||
|
||||
void submit_input(Keys &key)
|
||||
{
|
||||
_event.with_batch([&] (Event::Session_client::Batch &batch) {
|
||||
|
||||
if (key.type() == Keys::Type::PRESS_RELEASE ||
|
||||
key.type() == Keys::Type::PRESS)
|
||||
batch.submit(Input::Press{key.key_code()});
|
||||
|
||||
if (key.type() == Keys::Type::PRESS_RELEASE ||
|
||||
key.type() == Keys::Type::RELEASE)
|
||||
batch.submit(Input::Release{key.key_code()});
|
||||
});
|
||||
}
|
||||
|
||||
void _check_acpi(Attached_rom_dataspace &rom, Avl_tree<Keys> &map,
|
||||
char const * const name)
|
||||
{
|
||||
rom.update();
|
||||
|
||||
if (!rom.valid()) return;
|
||||
|
||||
Xml_node event(rom.local_addr<char>(), rom.size());
|
||||
|
||||
event.for_each_sub_node(name, [&] (Xml_node const &node) {
|
||||
rom.xml().for_each_sub_node(name, [&] (Xml_node const &node) {
|
||||
node.for_each_sub_node("data", [&] (Xml_node const &data_node) {
|
||||
try {
|
||||
uint64_t acpi_value = 0;
|
||||
uint64_t acpi_count = 0;
|
||||
uint64_t const value = data_node.attribute_value("value", 0ULL);
|
||||
uint64_t const count = data_node.attribute_value("count", 0ULL);
|
||||
|
||||
data_node.attribute("value").value(acpi_value);
|
||||
data_node.attribute("count").value(acpi_count);
|
||||
|
||||
Keys * key = Keys::find_by(map, acpi_value);
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
if (!key->update_count(acpi_count))
|
||||
return;
|
||||
|
||||
submit_input(key);
|
||||
} catch (...) { /* be robust - ignore ill-formated ACPI data */ }
|
||||
Keys::with_key(map, value, [&] (Keys &key) {
|
||||
if (key.update_count(count))
|
||||
submit_input(key); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void check_acpi_ec() { _check_acpi(_acpi_ec, _map_ec, "ec"); }
|
||||
|
||||
void check_acpi_hid() { _check_acpi(_acpi_hid, _map_hid, "hid"); }
|
||||
|
||||
void submit_input(Keys * key)
|
||||
void _check_acpi(Xml_node const &xml_node, const char * const sub_name,
|
||||
unsigned const state_o, unsigned const state_c)
|
||||
{
|
||||
_event.with_batch([&] (Event::Session_client::Batch &batch) {
|
||||
xml_node.for_each_sub_node(sub_name, [&] (Xml_node const &node) {
|
||||
uint64_t const value = node.attribute_value("value", 0ULL);
|
||||
uint64_t const count = node.attribute_value("count", 0ULL);
|
||||
|
||||
if (!key)
|
||||
uint64_t const STATE_C = 0, STATE_O = 1;
|
||||
|
||||
if (value != STATE_O && value != STATE_C)
|
||||
return;
|
||||
|
||||
if (key->type() == Keys::Type::PRESS_RELEASE ||
|
||||
key->type() == Keys::Type::PRESS)
|
||||
batch.submit(Input::Press{key->key_code()});
|
||||
unsigned const state = (value == STATE_O) ? state_o : state_c;
|
||||
|
||||
if (key->type() == Keys::Type::PRESS_RELEASE ||
|
||||
key->type() == Keys::Type::RELEASE)
|
||||
batch.submit(Input::Release{key->key_code()});
|
||||
Keys::with_key(_map_special, state, [&] (Keys &key) {
|
||||
if (key.update_count(count))
|
||||
submit_input(key); });
|
||||
});
|
||||
}
|
||||
|
||||
void check_acpi_fixed()
|
||||
void _handle_acpi_ec() { _check_acpi(_acpi_ec, _map_ec, "ec"); }
|
||||
|
||||
void _handle_acpi_hid() { _check_acpi(_acpi_hid, _map_hid, "hid"); }
|
||||
|
||||
void _handle_acpi_fixed()
|
||||
{
|
||||
_acpi_fixed.update();
|
||||
Keys::with_key(_map_special, ACPI_POWER_BUTTON, [&] (Keys &key) {
|
||||
_acpi_fixed.xml().for_each_sub_node("power_button", [&] (Xml_node const &pw) {
|
||||
bool const pressed = pw.attribute_value("value", false);
|
||||
uint64_t const count = pw.attribute_value("count", 0UL);
|
||||
|
||||
if (!_acpi_fixed.valid()) return;
|
||||
|
||||
Xml_node fixed_event(_acpi_fixed.local_addr<char>(), _acpi_fixed.size());
|
||||
|
||||
fixed_event.for_each_sub_node("power_button", [&] (Xml_node pw_node) {
|
||||
try {
|
||||
bool pressed = false;
|
||||
uint64_t acpi_count = 0;
|
||||
|
||||
pw_node.attribute("value").value(pressed);
|
||||
pw_node.attribute("count").value(acpi_count);
|
||||
|
||||
Keys * key = Keys::find_by(_map_special, ACPI_POWER_BUTTON);
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
if (!key->update_count(acpi_count) && pressed)
|
||||
return;
|
||||
|
||||
submit_input(key);
|
||||
} catch (...) { /* be robust - ignore ill-formated ACPI data */ }
|
||||
if (key.update_count(count) && pressed)
|
||||
submit_input(key);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void check_acpi_battery()
|
||||
void _handle_acpi_battery()
|
||||
{
|
||||
_acpi_battery.update();
|
||||
|
||||
if (!_acpi_battery.valid()) return;
|
||||
|
||||
/* make use of it if we need to ... */
|
||||
Xml_node battery_node(_acpi_battery.local_addr<char>(),
|
||||
_acpi_battery.size());
|
||||
|
||||
submit_input(Keys::find_by(_map_special, ACPI_BATTERY));
|
||||
Keys::with_key(_map_special, ACPI_BATTERY, [&] (Keys &key) {
|
||||
submit_input(key); });
|
||||
}
|
||||
|
||||
void check_acpi_ac()
|
||||
void _handle_acpi_ac()
|
||||
{
|
||||
_acpi_ac.update();
|
||||
|
||||
if (!_acpi_ac.valid()) return;
|
||||
|
||||
Xml_node ac_node(_acpi_ac.local_addr<char>(), _acpi_ac.size());
|
||||
|
||||
_check_acpi(ac_node, "ac", ACPI_AC_ONLINE, ACPI_AC_OFFLINE);
|
||||
_check_acpi(_acpi_ac.xml(), "ac", ACPI_AC_ONLINE, ACPI_AC_OFFLINE);
|
||||
}
|
||||
|
||||
void check_acpi_lid()
|
||||
void _handle_acpi_lid()
|
||||
{
|
||||
_acpi_lid.update();
|
||||
|
||||
if (!_acpi_lid.valid()) return;
|
||||
|
||||
Xml_node lid_node(_acpi_lid.local_addr<char>(), _acpi_lid.size());
|
||||
|
||||
_check_acpi(lid_node, "lid", ACPI_LID_OPEN, ACPI_LID_CLOSED);
|
||||
}
|
||||
|
||||
void _check_acpi(Xml_node &xml_node, const char * sub_name,
|
||||
const unsigned state_o, const unsigned state_c)
|
||||
{
|
||||
xml_node.for_each_sub_node(sub_name, [&] (Xml_node node) {
|
||||
try {
|
||||
uint64_t acpi_value = 0;
|
||||
uint64_t acpi_count = 0;
|
||||
|
||||
node.attribute("value").value(acpi_value);
|
||||
node.attribute("count").value(acpi_count);
|
||||
|
||||
enum { STATE_C = 0, STATE_O = 1 };
|
||||
|
||||
Keys * key = nullptr;
|
||||
if (acpi_value == STATE_O)
|
||||
key = Keys::find_by(_map_special, state_o);
|
||||
if (acpi_value == STATE_C)
|
||||
key = Keys::find_by(_map_special, state_c);
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
if (!key->update_count(acpi_count))
|
||||
return;
|
||||
|
||||
if (acpi_value == STATE_C)
|
||||
submit_input(key);
|
||||
|
||||
if (acpi_value == STATE_O)
|
||||
submit_input(key);
|
||||
} catch (...) { /* be robust - ignore ill-formated ACPI data */ }
|
||||
});
|
||||
_check_acpi(_acpi_lid.xml(), "lid", ACPI_LID_OPEN, ACPI_LID_CLOSED);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user