From e0848da70daa9ac5561146a45241c21c993ed4bb Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 7 Oct 2024 09:15:34 +0900 Subject: [PATCH] key-state.c: generalize set operations --- include/common/set.h | 19 ++++++++++ src/common/meson.build | 1 + src/common/set.c | 44 +++++++++++++++++++++++ src/input/key-state.c | 82 +++++++++++------------------------------- 4 files changed, 84 insertions(+), 62 deletions(-) create mode 100644 include/common/set.h create mode 100644 src/common/set.c diff --git a/include/common/set.h b/include/common/set.h new file mode 100644 index 00000000..6ca5cd85 --- /dev/null +++ b/include/common/set.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_SET_H +#define LABWC_SET_H + +#include +#include + +#define LAB_SET_MAX_SIZE 16 + +struct lab_set { + uint32_t values[LAB_SET_MAX_SIZE]; + int size; +}; + +bool lab_set_contains(struct lab_set *set, uint32_t value); +void lab_set_add(struct lab_set *set, uint32_t value); +void lab_set_remove(struct lab_set *set, uint32_t value); + +#endif /* LABWC_SET_H */ diff --git a/src/common/meson.build b/src/common/meson.build index d9be1d1a..d369df4c 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -16,6 +16,7 @@ labwc_sources += files( 'scaled-font-buffer.c', 'scaled-scene-buffer.c', 'scene-helpers.c', + 'set.c', 'surface-helpers.c', 'spawn.c', 'string-helpers.c', diff --git a/src/common/set.c b/src/common/set.c new file mode 100644 index 00000000..ccaa6c49 --- /dev/null +++ b/src/common/set.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include "common/set.h" + +bool +lab_set_contains(struct lab_set *set, uint32_t value) +{ + for (int i = 0; i < set->size; ++i) { + if (set->values[i] == value) { + return true; + } + } + return false; +} + +void +lab_set_add(struct lab_set *set, uint32_t value) +{ + if (lab_set_contains(set, value)) { + return; + } + if (set->size >= LAB_SET_MAX_SIZE) { + wlr_log(WLR_ERROR, "lab_set size exceeded"); + return; + } + set->values[set->size++] = value; +} + +void +lab_set_remove(struct lab_set *set, uint32_t value) +{ + bool shifting = false; + + for (int i = 0; i < LAB_SET_MAX_SIZE; ++i) { + if (set->values[i] == value) { + --set->size; + shifting = true; + } + if (shifting) { + set->values[i] = i < LAB_SET_MAX_SIZE - 1 + ? set->values[i + 1] : 0; + } + } +} diff --git a/src/input/key-state.c b/src/input/key-state.c index 8ce66ff0..e5bfe3ca 100644 --- a/src/input/key-state.c +++ b/src/input/key-state.c @@ -5,19 +5,13 @@ #include #include #include +#include "common/set.h" #include "input/key-state.h" -#define MAX_PRESSED_KEYS (16) - -struct key_array { - uint32_t keys[MAX_PRESSED_KEYS]; - int nr_keys; -}; - -static struct key_array pressed, pressed_mods, bound, pressed_sent; +static struct lab_set pressed, pressed_mods, bound, pressed_sent; static void -report(struct key_array *array, const char *msg) +report(struct lab_set *key_set, const char *msg) { static char *should_print; static bool has_run; @@ -30,48 +24,12 @@ report(struct key_array *array, const char *msg) return; } printf("%s", msg); - for (int i = 0; i < array->nr_keys; ++i) { - printf("%d,", array->keys[i]); + for (int i = 0; i < key_set->size; ++i) { + printf("%d,", key_set->values[i]); } printf("\n"); } -static bool -key_present(struct key_array *array, uint32_t keycode) -{ - for (int i = 0; i < array->nr_keys; ++i) { - if (array->keys[i] == keycode) { - return true; - } - } - return false; -} - -static void -remove_key(struct key_array *array, uint32_t keycode) -{ - bool shifting = false; - - for (int i = 0; i < MAX_PRESSED_KEYS; ++i) { - if (array->keys[i] == keycode) { - --array->nr_keys; - shifting = true; - } - if (shifting) { - array->keys[i] = i < MAX_PRESSED_KEYS - 1 - ? array->keys[i + 1] : 0; - } - } -} - -static void -add_key(struct key_array *array, uint32_t keycode) -{ - if (!key_present(array, keycode) && array->nr_keys < MAX_PRESSED_KEYS) { - array->keys[array->nr_keys++] = keycode; - } -} - uint32_t * key_state_pressed_sent_keycodes(void) { @@ -80,70 +38,70 @@ key_state_pressed_sent_keycodes(void) /* pressed_sent = pressed - bound */ pressed_sent = pressed; - for (int i = 0; i < bound.nr_keys; ++i) { - remove_key(&pressed_sent, bound.keys[i]); + for (int i = 0; i < bound.size; ++i) { + lab_set_remove(&pressed_sent, bound.values[i]); } report(&pressed_sent, "after - pressed_sent:"); - return pressed_sent.keys; + return pressed_sent.values; } int key_state_nr_pressed_sent_keycodes(void) { - return pressed_sent.nr_keys; + return pressed_sent.size; } void key_state_set_pressed(uint32_t keycode, bool is_pressed, bool is_modifier) { if (is_pressed) { - add_key(&pressed, keycode); + lab_set_add(&pressed, keycode); if (is_modifier) { - add_key(&pressed_mods, keycode); + lab_set_add(&pressed_mods, keycode); } } else { - remove_key(&pressed, keycode); - remove_key(&pressed_mods, keycode); + lab_set_remove(&pressed, keycode); + lab_set_remove(&pressed_mods, keycode); } } void key_state_store_pressed_key_as_bound(uint32_t keycode) { - add_key(&bound, keycode); + lab_set_add(&bound, keycode); /* * Also store any pressed modifiers as bound. This prevents * applications from seeing and handling the release event for * a modifier key that was part of a keybinding (e.g. Firefox * displays its menu bar for a lone Alt press + release). */ - for (int i = 0; i < pressed_mods.nr_keys; ++i) { - add_key(&bound, pressed_mods.keys[i]); + for (int i = 0; i < pressed_mods.size; ++i) { + lab_set_add(&bound, pressed_mods.values[i]); } } bool key_state_corresponding_press_event_was_bound(uint32_t keycode) { - return key_present(&bound, keycode); + return lab_set_contains(&bound, keycode); } void key_state_bound_key_remove(uint32_t keycode) { - remove_key(&bound, keycode); + lab_set_remove(&bound, keycode); } int key_state_nr_bound_keys(void) { - return bound.nr_keys; + return bound.size; } int key_state_nr_pressed_keys(void) { - return pressed.nr_keys; + return pressed.size; }