From f76eaa53f25e0f4a7313a90156260e03118ad4c1 Mon Sep 17 00:00:00 2001 From: Vftdan Date: Sun, 18 Aug 2024 13:32:20 +0200 Subject: [PATCH] Add "modify_predicate" node type Change "enabled" and "inverted" predicate flags when received events satisfy other predicates --- Makefile | 2 +- config.cfg | 45 +++++++++++++++++ nodes/modify_predicate.c | 102 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 nodes/modify_predicate.c diff --git a/Makefile b/Makefile index a09cef6..00dc0bd 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ CPPFLAGS += $(shell pkg-config --cflags $(DEPS)) LDLIBS += $(shell pkg-config --libs $(DEPS)) INTERP ?= MAIN = main -OBJS = main.o events.o processing.o graph.o config.o event_code_names.o hash_table.o module_registry.o event_predicate.o nodes/getchar.o nodes/print.o nodes/evdev.o nodes/tee.o nodes/router.o nodes/modifiers.o +OBJS = main.o events.o processing.o graph.o config.o event_code_names.o hash_table.o module_registry.o event_predicate.o nodes/getchar.o nodes/print.o nodes/evdev.o nodes/tee.o nodes/router.o nodes/modifiers.o nodes/modify_predicate.o all: $(MAIN) diff --git a/config.cfg b/config.cfg index 6f7ebcd..b874a90 100644 --- a/config.cfg +++ b/config.cfg @@ -23,6 +23,31 @@ predicates = { } ); }; + btn_touch_event = { + type = "and"; + args = ( + "key_event", + { + type = "code_minor"; + min = "button_event.TOUCH"; + max = "button_event.TOUCH"; + } + ); + }; + payload_zero = { + type = "payload"; + min = 0; + max = 0; + }; + payload_one = { + type = "payload"; + min = 1; + max = 1; + }; + touch_held = { + type = "accept"; + inverted = 1; + }; }; nodes = { @@ -63,6 +88,20 @@ nodes = { modifiers = ["my_modifier"]; }; }; + update_touch_held = { + type = "modify_predicate"; + options = { + target = "touch_held"; + uninvert_on = {type: "and", args: ["btn_touch_event", "payload_one"]}; + invert_on = {type: "and", args: ["btn_touch_event", "payload_zero"]}; + }; + }; + while_touch_held = { + type = "router"; + options = { + predicates = ["touch_held"]; + }; + }; }; channels = ({ @@ -79,7 +118,13 @@ channels = ({ to: ("print", 0); }, { from: ("select_key_events", 1); + to: ("while_touch_held", 0); +}, { + from: ("while_touch_held", 0); to: ("print", 1); +}, { + from: ("clickpad", 1); + to: ("update_touch_held", 0); }); // vim: ft=libconfig diff --git a/nodes/modify_predicate.c b/nodes/modify_predicate.c new file mode 100644 index 0000000..8884716 --- /dev/null +++ b/nodes/modify_predicate.c @@ -0,0 +1,102 @@ +#include "../graph.h" +#include "../module_registry.h" + +typedef struct { + GraphNode as_GraphNode; + EventPredicateHandle target; + EventPredicateHandle enable_on, disable_on, invert_on, uninvert_on; +} ModifyPredicateGraphNode; + +static bool +handle_event(EventPositionBase * self, EventNode * event) +{ + ModifyPredicateGraphNode *node = DOWNCAST(ModifyPredicateGraphNode, GraphNode, DOWNCAST(GraphNode, EventPositionBase, self)); + bool + should_enable = false, + should_disable = false, + should_invert = false, + should_uninvert = false; + EventPredicateHandle target = node->target; + EventPredicate target_state = event_predicate_get(target); + + if (target_state.enabled) { + should_disable = event_predicate_apply(node->disable_on, event) == EVPREDRES_ACCEPTED; + } else { + should_enable = event_predicate_apply(node->enable_on, event) == EVPREDRES_ACCEPTED; + } + if (target_state.inverted) { + should_uninvert = event_predicate_apply(node->uninvert_on, event) == EVPREDRES_ACCEPTED; + } else { + should_invert = event_predicate_apply(node->invert_on, event) == EVPREDRES_ACCEPTED; + } + + if (should_enable) { + event_predicate_set_enabled(target, true); + } + if (should_disable) { + event_predicate_set_enabled(target, false); + } + if (should_invert) { + event_predicate_set_inverted(target, true); + } + if (should_uninvert) { + event_predicate_set_inverted(target, false); + } + + event_destroy(event); + return true; +} + +static GraphNode * +create(GraphNodeSpecification * spec, GraphNodeConfig * config, InitializationEnvironment * env) +{ + (void) config; + (void) env; + ModifyPredicateGraphNode * node = T_ALLOC(1, ModifyPredicateGraphNode); + if (!node) { + return NULL; + } + + EventPredicateHandle target = env_resolve_event_predicate(env, config_setting_get_member(config->options, "target")); + if (target < 0) { + free(node); + return NULL; + } + + *node = (ModifyPredicateGraphNode) { + .as_GraphNode = { + .as_EventPositionBase = { + .handle_event = &handle_event, + .waiting_new_event = false, + }, + .specification = spec, + .inputs = EMPTY_GRAPH_CHANNEL_LIST, + .outputs = EMPTY_GRAPH_CHANNEL_LIST, + }, + .target = target, + .enable_on = env_resolve_event_predicate(env, config_setting_get_member(config->options, "enable_on")), + .disable_on = env_resolve_event_predicate(env, config_setting_get_member(config->options, "disable_on")), + .invert_on = env_resolve_event_predicate(env, config_setting_get_member(config->options, "invert_on")), + .uninvert_on = env_resolve_event_predicate(env, config_setting_get_member(config->options, "uninvert_on")), + }; + return &node->as_GraphNode; +} + +static void destroy +(GraphNodeSpecification * self, GraphNode * target) +{ + (void) self; + free(target); +} + +GraphNodeSpecification nodespec_modify_predicate = (GraphNodeSpecification) { + .create = &create, + .destroy = &destroy, + .register_io = NULL, + .name = "modify_predicate", +}; + +MODULE_CONSTRUCTOR(init) +{ + register_graph_node_specification(&nodespec_modify_predicate); +}