commit 210aa3d51d8dcc1e36c73d3404e032937271e0d6
parent 71f3528512ae0666e68994bd70dccb933bed55f8
Author: lumidify <nobody@lumidify.org>
Date: Wed, 1 May 2024 21:24:44 +0200
Restructure configuration parsing for keybindings
It's still really ugly.
Diffstat:
M | Makefile | | | 1 | - |
M | src/ltk/config.c | | | 158 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- |
M | src/ltk/config.h | | | 40 | ++++++++++++++++++++++++++-------------- |
M | src/ltk/entry.c | | | 209 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | src/ltk/entry.h | | | 16 | +++++++++------- |
D | src/ltk/keys.h | | | 78 | ------------------------------------------------------------------------------ |
M | src/ltk/ltk.c | | | 66 | ++---------------------------------------------------------------- |
A | src/ltk/sort_search.h | | | 76 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | src/ltk/window.c | | | 155 | +++++++++++++++++++++++++++++++------------------------------------------------ |
M | src/ltk/window.h | | | 17 | +++++++++-------- |
10 files changed, 416 insertions(+), 400 deletions(-)
diff --git a/Makefile b/Makefile
@@ -117,7 +117,6 @@ HDR_LTK = \
src/ltk/label.h \
src/ltk/config.h \
src/ltk/array.h \
- src/ltk/keys.h \
src/ltk/clipboard_xlib.h \
src/ltk/clipboard.h \
src/ltk/txtbuf.h \
diff --git a/src/ltk/config.c b/src/ltk/config.c
@@ -21,10 +21,122 @@
#include <limits.h>
#include "util.h"
-#include "keys.h"
#include "memory.h"
#include "config.h"
+#include "sort_search.h"
+
+#include "entry.h"
+#include "window.h"
+
+GEN_SORT_SEARCH_HELPERS(keybinding, ltk_keybinding_cb, text)
+//GEN_SORT_SEARCH_HELPERS(theme, ltk_theme_parseinfo, key)
+LTK_ARRAY_INIT_IMPL(keypress, ltk_keypress_cfg)
+LTK_ARRAY_INIT_IMPL(keyrelease, ltk_keyrelease_cfg)
+
+static struct {
+ const char *name;
+ void (*get_parseinfo)(
+ ltk_keybinding_cb **press_cbs_ret, size_t *press_len_ret,
+ ltk_keybinding_cb **release_cbs_ret, size_t *release_len_ret,
+ ltk_array(keypress) **presses_ret, ltk_array(keyrelease) **releases_ret
+ );
+} keybinding_handlers[] = {
+ {"entry", <k_entry_get_keybinding_parseinfo},
+ {"window", <k_window_get_keybinding_parseinfo},
+};
+
+static int
+register_keypress(ltk_array(keypress) *bindings, ltk_keybinding_cb *arr, size_t arrlen, const char *func_name, size_t func_len, ltk_keypress_binding b) {
+ ltk_keybinding_cb *cb = keybinding_get_entry(arr, arrlen, func_name, func_len);
+ if (!cb)
+ return 1;
+ ltk_keypress_cfg cfg = {b, *cb};
+ ltk_array_append(keypress, bindings, cfg);
+ return 0;
+}
+
+static int
+register_keyrelease(ltk_array(keyrelease) *bindings, ltk_keybinding_cb *arr, size_t arrlen, const char *func_name, size_t func_len, ltk_keyrelease_binding b) {
+ ltk_keybinding_cb *cb = keybinding_get_entry(arr, arrlen, func_name, func_len);
+ if (!cb)
+ return 1;
+ ltk_keyrelease_cfg cfg = {b, *cb};
+ ltk_array_append(keyrelease, bindings, cfg);
+ return 0;
+}
+
+static int
+handle_keypress_binding(const char *widget_name, size_t wlen, const char *name, size_t nlen, ltk_keypress_binding b) {
+ ltk_keybinding_cb *press_cbs = NULL, *release_cbs = NULL;
+ size_t press_len = 0, release_len = 0;
+ ltk_array(keypress) *presses = NULL;
+ ltk_array(keyrelease) *releases = NULL;
+ for (size_t i = 0; i < LENGTH(keybinding_handlers); i++) {
+ if (str_array_equal(keybinding_handlers[i].name, widget_name, wlen)) {
+ keybinding_handlers[i].get_parseinfo(
+ &press_cbs, &press_len, &release_cbs, &release_len, &presses, &releases
+ );
+ if (!press_cbs || !presses)
+ return 1;
+ return register_keypress(presses, press_cbs, press_len, name, nlen, b);
+ }
+ }
+ return 1;
+}
+
+static int
+handle_keyrelease_binding(const char *widget_name, size_t wlen, const char *name, size_t nlen, ltk_keyrelease_binding b) {
+ ltk_keybinding_cb *press_cbs = NULL, *release_cbs = NULL;
+ size_t press_len = 0, release_len = 0;
+ ltk_array(keypress) *presses = NULL;
+ ltk_array(keyrelease) *releases = NULL;
+ for (size_t i = 0; i < LENGTH(keybinding_handlers); i++) {
+ if (str_array_equal(keybinding_handlers[i].name, widget_name, wlen)) {
+ keybinding_handlers[i].get_parseinfo(
+ &press_cbs, &press_len, &release_cbs, &release_len, &presses, &releases
+ );
+ if (!release_cbs || !releases)
+ return 1;
+ return register_keyrelease(releases, release_cbs, release_len, name, nlen, b);
+ }
+ }
+ return 1;
+}
+
+static void
+sort_keybindings(void) {
+ ltk_keybinding_cb *press_cbs = NULL, *release_cbs = NULL;
+ size_t press_len = 0, release_len = 0;
+ ltk_array(keypress) *presses = NULL;
+ ltk_array(keyrelease) *releases = NULL;
+ for (size_t i = 0; i < LENGTH(keybinding_handlers); i++) {
+ keybinding_handlers[i].get_parseinfo(
+ &press_cbs, &press_len, &release_cbs, &release_len, &presses, &releases
+ );
+ if (press_cbs)
+ keybinding_sort(press_cbs, press_len);
+ if (release_cbs)
+ keybinding_sort(release_cbs, release_len);
+ }
+}
+
+static void
+destroy_keypress_cfg(ltk_keypress_cfg cfg) {
+ ltk_free(cfg.b.text);
+ ltk_free(cfg.b.rawtext);
+}
+
+void
+ltk_keypress_bindings_destroy(ltk_array(keypress) *arr) {
+ ltk_array_destroy_deep(keypress, arr, &destroy_keypress_cfg);
+}
+
+void
+ltk_keyrelease_bindings_destroy(ltk_array(keyrelease) *arr) {
+ ltk_array_destroy(keyrelease, arr);
+}
+static void sort_keysyms(void);
static int parse_keysym(char *text, size_t len, ltk_keysym *sym_ret);
ltk_config *global_config = NULL;
@@ -361,8 +473,6 @@ parse_keybinding(
struct token *tok,
char *widget,
size_t len,
- keypress_binding_handler press_handler,
- keyrelease_binding_handler release_handler,
char **errstr) {
char *msg = NULL;
*tok = next_token(s);
@@ -379,7 +489,7 @@ parse_keybinding(
size_t nlen;
if (parse_keypress_binding(s, tok, &b, &name, &nlen, errstr))
return 1;
- if (press_handler(widget, len, name, nlen, b)) {
+ if (handle_keypress_binding(widget, len, name, nlen, b)) {
msg = "Invalid key binding";
goto error;
}
@@ -395,7 +505,7 @@ parse_keybinding(
msg = "Text and rawtext may only be specified for keypress bindings";
goto error;
}
- if (release_handler(widget, len, name, nlen, (ltk_keyrelease_binding){b.sym, b.mods, b.flags})) {
+ if (handle_keyrelease_binding(widget, len, name, nlen, (ltk_keyrelease_binding){b.sym, b.mods, b.flags})) {
msg = "Invalid key binding";
goto error;
}
@@ -502,8 +612,6 @@ load_from_text(
const char *filename,
char *file_contents,
size_t len,
- keypress_binding_handler press_handler,
- keyrelease_binding_handler release_handler,
char **errstr) {
ltk_config *config = ltk_malloc(sizeof(ltk_config));
config->mappings = NULL;
@@ -629,7 +737,7 @@ load_from_text(
char *widget = secttok.text + strlen("key-binding:");
size_t len = secttok.len - strlen("key-binding:");
while (1) {
- if ((ret = parse_keybinding(&s, &tok, widget, len, press_handler, release_handler, errstr)) > 0) {
+ if ((ret = parse_keybinding(&s, &tok, widget, len, errstr)) > 0) {
goto errornomsg;
} else if (ret < 0) {
start_of_line = 1;
@@ -715,19 +823,17 @@ errornomsg:
}
int
-ltk_config_parsefile(
- const char *filename,
- keypress_binding_handler press_handler,
- keyrelease_binding_handler release_handler,
- char **errstr) {
+ltk_config_parsefile(const char *filename, char **errstr) {
unsigned long len = 0;
char *ferrstr = NULL;
+ sort_keysyms();
+ sort_keybindings();
char *file_contents = ltk_read_file(filename, &len, &ferrstr);
if (!file_contents) {
*errstr = ltk_print_fmt("Unable to open file \"%s\": %s", filename, ferrstr);
return 1;
}
- int ret = load_from_text(filename, file_contents, len, press_handler, release_handler, errstr);
+ int ret = load_from_text(filename, file_contents, len, errstr);
ltk_free(file_contents);
return ret;
}
@@ -750,22 +856,15 @@ const char *default_config = "[general]\n"
/* FIXME: improve this configuration */
int
-ltk_config_load_default(
- keypress_binding_handler press_handler,
- keyrelease_binding_handler release_handler,
- char **errstr) {
+ltk_config_load_default(char **errstr) {
+ sort_keysyms();
+ sort_keybindings();
char *config_copied = ltk_strdup(default_config);
- int ret = load_from_text("<default config>", config_copied, strlen(config_copied), press_handler, release_handler, errstr);
+ int ret = load_from_text("<default config>", config_copied, strlen(config_copied), errstr);
ltk_free(config_copied);
return ret;
}
-void
-ltk_keypress_binding_destroy(ltk_keypress_binding b) {
- ltk_free(b.text);
- ltk_free(b.rawtext);
-}
-
/* FIXME: which additional ones are needed here? */
static struct keysym_mapping {
char *name;
@@ -859,11 +958,16 @@ static struct keysym_mapping {
{"undo", LTK_KEY_UNDO},
};
-GEN_CB_MAP_HELPERS(keysym_map, struct keysym_mapping, name)
+GEN_SORT_SEARCH_HELPERS(keysym, struct keysym_mapping, name)
+
+static void
+sort_keysyms(void) {
+ keysym_sort(keysym_map, LENGTH(keysym_map));
+}
static int
parse_keysym(char *keysym_str, size_t len, ltk_keysym *sym) {
- struct keysym_mapping *km = keysym_map_get_entry(keysym_str, len);
+ struct keysym_mapping *km = keysym_get_entry(keysym_map, LENGTH(keysym_map), keysym_str, len);
if (!km)
return 1;
*sym = km->keysym;
diff --git a/src/ltk/config.h b/src/ltk/config.h
@@ -19,6 +19,8 @@
#include <stddef.h>
+#include "array.h"
+#include "widget.h"
#include "eventdefs.h"
typedef enum{
@@ -66,24 +68,34 @@ typedef struct {
ltk_general_config general;
} ltk_config;
-typedef int (*keypress_binding_handler)(const char *widget_name, size_t wlen, const char *name, size_t nlen, ltk_keypress_binding b);
-typedef int (*keyrelease_binding_handler)(const char *widget_name, size_t wlen, const char *name, size_t nlen, ltk_keyrelease_binding b);
+typedef int (*ltk_keybinding_func)(ltk_widget *, ltk_key_event *);
+
+typedef struct {
+ char *text;
+ ltk_keybinding_func func;
+} ltk_keybinding_cb;
+
+typedef struct {
+ ltk_keypress_binding b;
+ ltk_keybinding_cb cb;
+} ltk_keypress_cfg;
+
+typedef struct {
+ ltk_keyrelease_binding b;
+ ltk_keybinding_cb cb;
+} ltk_keyrelease_cfg;
+
+LTK_ARRAY_INIT_DECL(keypress, ltk_keypress_cfg)
+LTK_ARRAY_INIT_DECL(keyrelease, ltk_keyrelease_cfg)
void ltk_config_cleanup(void);
ltk_config *ltk_config_get(void);
int ltk_config_get_language_index(char *lang, size_t *idx_ret);
ltk_language_mapping *ltk_config_get_language_mapping(size_t idx);
-int ltk_config_parsefile(
- const char *filename,
- keypress_binding_handler press_handler,
- keyrelease_binding_handler release_handler,
- char **errstr
-);
-int ltk_config_load_default(
- keypress_binding_handler press_handler,
- keyrelease_binding_handler release_handler,
- char **errstr
-);
-void ltk_keypress_binding_destroy(ltk_keypress_binding b);
+int ltk_config_parsefile(const char *filename, char **errstr);
+int ltk_config_load_default(char **errstr);
+
+void ltk_keypress_bindings_destroy(ltk_array(keypress) *arr);
+void ltk_keyrelease_bindings_destroy(ltk_array(keyrelease) *arr);
#endif /* LTK_CONFIG_H */
diff --git a/src/ltk/entry.c b/src/ltk/entry.c
@@ -31,7 +31,6 @@
#include "event.h"
#include "eventdefs.h"
#include "graphics.h"
-#include "keys.h"
#include "ltk.h"
#include "memory.h"
#include "rect.h"
@@ -40,6 +39,7 @@
#include "txtbuf.h"
#include "util.h"
#include "widget.h"
+#include "config.h"
#define MAX_ENTRY_BORDER_WIDTH 10000
#define MAX_ENTRY_PADDING 50000
@@ -63,31 +63,27 @@ typedef void (*cb_func)(ltk_entry *, ltk_key_event *);
/* FIXME: configure mouse actions, e.g. select-word-under-pointer, move-cursor-to-pointer */
-static void cursor_to_beginning(ltk_entry *entry, ltk_key_event *event);
-static void cursor_to_end(ltk_entry *entry, ltk_key_event *event);
-static void cursor_left(ltk_entry *entry, ltk_key_event *event);
-static void cursor_right(ltk_entry *entry, ltk_key_event *event);
-static void expand_selection_left(ltk_entry *entry, ltk_key_event *event);
-static void expand_selection_right(ltk_entry *entry, ltk_key_event *event);
-static void selection_to_primary(ltk_entry *entry, ltk_key_event *event);
-static void selection_to_clipboard(ltk_entry *entry, ltk_key_event *event);
-static void switch_selection_side(ltk_entry *entry, ltk_key_event *event);
-static void paste_primary(ltk_entry *entry, ltk_key_event *event);
-static void paste_clipboard(ltk_entry *entry, ltk_key_event *event);
-static void select_all(ltk_entry *entry, ltk_key_event *event);
-static void delete_char_backwards(ltk_entry *entry, ltk_key_event *event);
-static void delete_char_forwards(ltk_entry *entry, ltk_key_event *event);
-static void edit_external(ltk_entry *entry, ltk_key_event *event);
+static int cursor_to_beginning(ltk_widget *self, ltk_key_event *event);
+static int cursor_to_end(ltk_widget *self, ltk_key_event *event);
+static int cursor_left(ltk_widget *self, ltk_key_event *event);
+static int cursor_right(ltk_widget *self, ltk_key_event *event);
+static int expand_selection_left(ltk_widget *self, ltk_key_event *event);
+static int expand_selection_right(ltk_widget *self, ltk_key_event *event);
+static int selection_to_primary(ltk_widget *self, ltk_key_event *event);
+static int selection_to_clipboard(ltk_widget *self, ltk_key_event *event);
+static int switch_selection_side(ltk_widget *self, ltk_key_event *event);
+static int paste_primary(ltk_widget *self, ltk_key_event *event);
+static int paste_clipboard(ltk_widget *self, ltk_key_event *event);
+static int select_all(ltk_widget *self, ltk_key_event *event);
+static int delete_char_backwards(ltk_widget *self, ltk_key_event *event);
+static int delete_char_forwards(ltk_widget *self, ltk_key_event *event);
+static int edit_external(ltk_widget *self, ltk_key_event *event);
+
static void recalc_ideal_size(ltk_entry *entry);
static void ensure_cursor_shown(ltk_entry *entry);
static void insert_text(ltk_entry *entry, char *text, size_t len, int move_cursor);
-struct key_cb {
- char *text;
- cb_func func;
-};
-
-static struct key_cb cb_map[] = {
+static ltk_keybinding_cb cb_map[] = {
{"cursor-left", &cursor_left},
{"cursor-right", &cursor_right},
{"cursor-to-beginning", &cursor_to_beginning},
@@ -105,61 +101,29 @@ static struct key_cb cb_map[] = {
{"switch-selection-side", &switch_selection_side},
};
-struct keypress_cfg {
- ltk_keypress_binding b;
- struct key_cb cb;
-};
-
-struct keyrelease_cfg {
- ltk_keyrelease_binding b;
- struct key_cb cb;
-};
-
-LTK_ARRAY_INIT_DECL_STATIC(keypress, struct keypress_cfg)
-LTK_ARRAY_INIT_IMPL_STATIC(keypress, struct keypress_cfg)
-LTK_ARRAY_INIT_DECL_STATIC(keyrelease, struct keyrelease_cfg)
-LTK_ARRAY_INIT_IMPL_STATIC(keyrelease, struct keyrelease_cfg)
-
+/* FIXME: also support keyreleases */
static ltk_array(keypress) *keypresses = NULL;
-static ltk_array(keyrelease) *keyreleases = NULL;
-GEN_CB_MAP_HELPERS(cb_map, struct key_cb, text)
-
-int
-ltk_entry_register_keypress(const char *func_name, size_t func_len, ltk_keypress_binding b) {
+void
+ltk_entry_get_keybinding_parseinfo(
+ ltk_keybinding_cb **press_cbs_ret, size_t *press_len_ret,
+ ltk_keybinding_cb **release_cbs_ret, size_t *release_len_ret,
+ ltk_array(keypress) **presses_ret, ltk_array(keyrelease) **releases_ret
+) {
+ *press_cbs_ret = cb_map;
+ *press_len_ret = LENGTH(cb_map);
+ *release_cbs_ret = NULL;
+ *release_len_ret = 0;
if (!keypresses)
keypresses = ltk_array_create(keypress, 1);
- struct key_cb *cb = cb_map_get_entry(func_name, func_len);
- if (!cb)
- return 1;
- struct keypress_cfg cfg = {b, *cb};
- ltk_array_append(keypress, keypresses, cfg);
- return 0;
-}
-
-int
-ltk_entry_register_keyrelease(const char *func_name, size_t func_len, ltk_keyrelease_binding b) {
- if (!keyreleases)
- keyreleases = ltk_array_create(keyrelease, 1);
- struct key_cb *cb = cb_map_get_entry(func_name, func_len);
- if (!cb)
- return 1;
- struct keyrelease_cfg cfg = {b, *cb};
- ltk_array_append(keyrelease, keyreleases, cfg);
- return 0;
-}
-
-static void
-destroy_keypress_cfg(struct keypress_cfg cfg) {
- ltk_keypress_binding_destroy(cfg.b);
+ *presses_ret = keypresses;
+ *releases_ret = NULL;
}
void
ltk_entry_cleanup(void) {
- ltk_array_destroy_deep(keypress, keypresses, &destroy_keypress_cfg);
- ltk_array_destroy(keyrelease, keyreleases);
+ ltk_keypress_bindings_destroy(keypresses);
keypresses = NULL;
- keyreleases = NULL;
}
static struct ltk_widget_vtable vtable = {
@@ -335,42 +299,50 @@ wipe_selection(ltk_entry *entry) {
set_selection(entry, 0, 0);
}
-static void
-cursor_to_beginning(ltk_entry *entry, ltk_key_event *event) {
+static int
+cursor_to_beginning(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
wipe_selection(entry);
entry->pos = 0;
ensure_cursor_shown(entry);
+ return 0;
}
-static void
-cursor_to_end(ltk_entry *entry, ltk_key_event *event) {
+static int
+cursor_to_end(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
wipe_selection(entry);
entry->pos = entry->len;
ensure_cursor_shown(entry);
+ return 0;
}
-static void
-cursor_left(ltk_entry *entry, ltk_key_event *event) {
+static int
+cursor_left(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
if (entry->sel_start != entry->sel_end)
entry->pos = entry->sel_start;
else
entry->pos = ltk_text_line_move_cursor_visually(entry->tl, entry->pos, -1, NULL);
wipe_selection(entry);
ensure_cursor_shown(entry);
+ return 0;
}
-static void
-cursor_right(ltk_entry *entry, ltk_key_event *event) {
+static int
+cursor_right(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
if (entry->sel_start != entry->sel_end)
entry->pos = entry->sel_end;
else
entry->pos = ltk_text_line_move_cursor_visually(entry->tl, entry->pos, 1, NULL);
wipe_selection(entry);
ensure_cursor_shown(entry);
+ return 0;
}
static void
@@ -392,64 +364,79 @@ expand_selection(ltk_entry *entry, int dir) {
entry->pos = new;
wipe_selection(entry);
}
- selection_to_primary(entry, NULL);
+ selection_to_primary(LTK_CAST_WIDGET(entry), NULL);
}
/* FIXME: different programs have different behaviors when they set the selection */
/* FIXME: sometimes, it might be more useful to wipe the selection when sel_end == sel_start */
-static void
-selection_to_primary(ltk_entry *entry, ltk_key_event *event) {
+static int
+selection_to_primary(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
if (entry->sel_end == entry->sel_start)
- return;
+ return 0;
txtbuf *primary = ltk_clipboard_get_primary_buffer(ltk_get_clipboard());
txtbuf_clear(primary);
txtbuf_appendn(primary, entry->text + entry->sel_start, entry->sel_end - entry->sel_start);
ltk_clipboard_set_primary_selection_owner(ltk_get_clipboard());
+ return 0;
}
-static void
-selection_to_clipboard(ltk_entry *entry, ltk_key_event *event) {
+static int
+selection_to_clipboard(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
if (entry->sel_end == entry->sel_start)
- return;
+ return 0;
txtbuf *clip = ltk_clipboard_get_clipboard_buffer(ltk_get_clipboard());
txtbuf_clear(clip);
txtbuf_appendn(clip, entry->text + entry->sel_start, entry->sel_end - entry->sel_start);
ltk_clipboard_set_clipboard_selection_owner(ltk_get_clipboard());
+ return 0;
}
-static void
-switch_selection_side(ltk_entry *entry, ltk_key_event *event) {
+
+static int
+switch_selection_side(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
entry->sel_side = !entry->sel_side;
+ return 0;
}
-static void
-paste_primary(ltk_entry *entry, ltk_key_event *event) {
+static int
+paste_primary(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
txtbuf *buf = ltk_clipboard_get_primary_text(ltk_get_clipboard());
if (buf)
insert_text(entry, buf->text, buf->len, 1);
+ return 0;
}
-static void
-paste_clipboard(ltk_entry *entry, ltk_key_event *event) {
+static int
+paste_clipboard(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
txtbuf *buf = ltk_clipboard_get_clipboard_text(ltk_get_clipboard());
if (buf)
insert_text(entry, buf->text, buf->len, 1);
+ return 0;
}
-static void
-expand_selection_left(ltk_entry *entry, ltk_key_event *event) {
+static int
+expand_selection_left(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
expand_selection(entry, -1);
+ return 0;
}
-static void
-expand_selection_right(ltk_entry *entry, ltk_key_event *event) {
+static int
+expand_selection_right(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
expand_selection(entry, 1);
+ return 0;
}
static void
@@ -466,35 +453,41 @@ delete_text(ltk_entry *entry, size_t start, size_t end) {
ltk_window_invalidate_widget_rect(entry->widget.window, &entry->widget);
}
-static void
-delete_char_backwards(ltk_entry *entry, ltk_key_event *event) {
+static int
+delete_char_backwards(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
if (entry->sel_start != entry->sel_end) {
delete_text(entry, entry->sel_start, entry->sel_end);
} else {
size_t new = prev_utf8(entry->text, entry->pos);
delete_text(entry, new, entry->pos);
}
+ return 0;
}
-static void
-delete_char_forwards(ltk_entry *entry, ltk_key_event *event) {
+static int
+delete_char_forwards(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
if (entry->sel_start != entry->sel_end) {
delete_text(entry, entry->sel_start, entry->sel_end);
} else {
size_t new = next_utf8(entry->text, entry->len, entry->pos);
delete_text(entry, entry->pos, new);
}
+ return 0;
}
-static void
-select_all(ltk_entry *entry, ltk_key_event *event) {
+static int
+select_all(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
set_selection(entry, 0, entry->len);
if (entry->len)
- selection_to_primary(entry, NULL);
+ selection_to_primary(LTK_CAST_WIDGET(entry), NULL);
entry->sel_side = 0;
+ return 0;
}
static void
@@ -579,9 +572,10 @@ ltk_entry_cmd_return(ltk_widget *self, char *text, size_t len) {
insert_text(e, text, len, 0);
}
-static void
-edit_external(ltk_entry *entry, ltk_key_event *event) {
+static int
+edit_external(ltk_widget *self, ltk_key_event *event) {
(void)event;
+ ltk_entry *entry = LTK_CAST_ENTRY(self);
ltk_config *config = ltk_config_get();
/* FIXME: allow arguments to key mappings - this would allow to have different key mappings
for different editors instead of just one command */
@@ -592,8 +586,11 @@ edit_external(ltk_entry *entry, ltk_key_event *event) {
/* FIXME: change interface to not require length of cmd */
ltk_call_cmd(LTK_CAST_WIDGET(entry), config->general.line_editor, strlen(config->general.line_editor), entry->text, entry->len);
}
+ return 0;
}
+/* FIXME: return values of callbacks are currently ignored - could this be used for anything useful? */
+/* -> maybe if multiple bindings are configured for the same key? */
static int
ltk_entry_key_press(ltk_widget *self, ltk_key_event *event) {
ltk_entry *entry = LTK_CAST_ENTRY(self);
@@ -607,7 +604,7 @@ ltk_entry_key_press(ltk_widget *self, ltk_key_event *event) {
(b.mods == (event->modmask & ~LTK_MOD_SHIFT) &&
((b.text && event->mapped && !strcmp(b.text, event->mapped)) ||
(b.rawtext && event->text && !strcmp(b.rawtext, event->text))))) {
- ltk_array_get(keypresses, i).cb.func(entry, event);
+ ltk_array_get(keypresses, i).cb.func(LTK_CAST_WIDGET(entry), event);
self->dirty = 1;
ltk_window_invalidate_widget_rect(self->window, self);
return 1;
@@ -641,7 +638,7 @@ ltk_entry_mouse_press(ltk_widget *self, ltk_button_event *event) {
}
if (event->button == LTK_BUTTONL) {
if (event->type == LTK_3BUTTONPRESS_EVENT) {
- select_all(e, NULL);
+ select_all(LTK_CAST_WIDGET(e), NULL);
} else if (event->type == LTK_2BUTTONPRESS_EVENT) {
/* FIXME: use proper unicode stuff */
/* Note: If pango is used to determine what a word is, maybe at least
@@ -695,7 +692,7 @@ ltk_entry_mouse_press(ltk_widget *self, ltk_button_event *event) {
(see behavior in ledit) */
wipe_selection(e);
e->pos = xy_to_pos(e, event->x, event->y, 1);
- paste_primary(e, NULL);
+ paste_primary(LTK_CAST_WIDGET(e), NULL);
}
return 0;
}
@@ -705,7 +702,7 @@ ltk_entry_mouse_release(ltk_widget *self, ltk_button_event *event) {
ltk_entry *e = LTK_CAST_ENTRY(self);
if (event->button == LTK_BUTTONL) {
e->selecting = 0;
- selection_to_primary(e, NULL);
+ selection_to_primary(LTK_CAST_WIDGET(e), NULL);
}
return 0;
}
diff --git a/src/ltk/entry.h b/src/ltk/entry.h
@@ -38,15 +38,17 @@ typedef struct {
char selecting;
} ltk_entry;
+ltk_entry *ltk_entry_create(ltk_window *window, char *text);
+
+/* FIXME: these should be private to ltk */
+void ltk_entry_cleanup(void);
+void ltk_entry_get_keybinding_parseinfo(
+ ltk_keybinding_cb **press_cbs_ret, size_t *press_len_ret,
+ ltk_keybinding_cb **release_cbs_ret, size_t *release_len_ret,
+ ltk_array(keypress) **presses_ret, ltk_array(keyrelease) **releases_ret
+);
int ltk_entry_ini_handler(ltk_renderdata *data, const char *prop, const char *value);
int ltk_entry_fill_theme_defaults(ltk_renderdata *data);
void ltk_entry_uninitialize_theme(ltk_renderdata *data);
-/* FIXME: document that pointers inside binding are taken over! */
-int ltk_entry_register_keypress(const char *func_name, size_t func_len, ltk_keypress_binding b);
-int ltk_entry_register_keyrelease(const char *func_name, size_t func_len, ltk_keyrelease_binding b);
-void ltk_entry_cleanup(void);
-
-ltk_entry *ltk_entry_create(ltk_window *window, char *text);
-
#endif /* LTK_ENTRY_H */
diff --git a/src/ltk/keys.h b/src/ltk/keys.h
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2023-2024 lumidify <nobody@lumidify.org>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef LTK_KEYS_H
-#define LTK_KEYS_H
-
-#include <stddef.h>
-
-#include "util.h"
-
-/* FIXME: replace with proper string type */
-struct ltk_search_cmp_helper {
- const char *text;
- size_t len;
-};
-
-/* FIXME: documentation */
-#define GEN_CB_MAP_HELPERS(name, typename, cmp_entry) \
- \
-static int name##_sorted = 0; \
- \
-/* \
- * IMPORTANT: The text passed to *_get_entry may not be nul-terminated, \
- * so ltk_search_cmp_helper has to be used for the bsearch comparison \
- * helper. \
- */ \
- \
-static int \
-name##_search_helper(const void *keyv, const void *entryv) { \
- struct ltk_search_cmp_helper *key = (struct ltk_search_cmp_helper *)keyv; \
- typename *entry = (typename *)entryv; \
- int ret = strncmp(key->text, entry->cmp_entry, key->len); \
- if (ret == 0) { \
- if (entry->cmp_entry[key->len] == '\0') \
- return 0; \
- else \
- return -1; \
- } \
- return ret; \
-} \
- \
-static int \
-name##_sort_helper(const void *entry1v, const void *entry2v) { \
- typename *entry1 = (typename *)entry1v; \
- typename *entry2 = (typename *)entry2v; \
- return strcmp(entry1->cmp_entry, entry2->cmp_entry); \
-} \
- \
-static typename * \
-name##_get_entry(const char *text, size_t len) { \
- /* just in case */ \
- if (!name##_sorted) { \
- qsort( \
- name, LENGTH(name), \
- sizeof(name[0]), &name##_sort_helper); \
- name##_sorted = 1; \
- } \
- struct ltk_search_cmp_helper tmp = {.len = len, .text = text}; \
- return bsearch( \
- &tmp, name, LENGTH(name), \
- sizeof(name[0]), &name##_search_helper \
- ); \
-}
-
-#endif /* LTK_KEYS_H */
diff --git a/src/ltk/ltk.c b/src/ltk/ltk.c
@@ -90,8 +90,6 @@ static void ltk_handle_event(ltk_event *event);
static void ltk_load_theme(const char *path);
static void ltk_uninitialize_theme(void);
static int ltk_ini_handler(void *renderdata, const char *widget, const char *prop, const char *value);
-static int handle_keypress_binding(const char *widget_name, size_t wlen, const char *name, size_t nlen, ltk_keypress_binding b);
-static int handle_keyrelease_binding(const char *widget_name, size_t wlen, const char *name, size_t nlen, ltk_keyrelease_binding b);
static short running = 1;
@@ -100,8 +98,6 @@ typedef struct {
int (*ini_handler)(ltk_renderdata *, const char *, const char *);
int (*fill_theme_defaults)(ltk_renderdata *);
void (*uninitialize_theme)(ltk_renderdata *);
- int (*register_keypress)(const char *, size_t, ltk_keypress_binding);
- int (*register_keyrelease)(const char *, size_t, ltk_keyrelease_binding);
void (*cleanup)(void);
} ltk_widget_funcs;
@@ -112,8 +108,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = NULL,
.fill_theme_defaults = NULL,
.uninitialize_theme = NULL,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
},
{
@@ -121,8 +115,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = <k_button_ini_handler,
.fill_theme_defaults = <k_button_fill_theme_defaults,
.uninitialize_theme = <k_button_uninitialize_theme,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
},
{
@@ -130,8 +122,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = <k_entry_ini_handler,
.fill_theme_defaults = <k_entry_fill_theme_defaults,
.uninitialize_theme = <k_entry_uninitialize_theme,
- .register_keypress = <k_entry_register_keypress,
- .register_keyrelease = <k_entry_register_keyrelease,
.cleanup = <k_entry_cleanup,
},
{
@@ -139,8 +129,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = NULL,
.fill_theme_defaults = NULL,
.uninitialize_theme = NULL,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
},
{
@@ -148,8 +136,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = <k_label_ini_handler,
.fill_theme_defaults = <k_label_fill_theme_defaults,
.uninitialize_theme = <k_label_uninitialize_theme,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
},
{
@@ -158,8 +144,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = NULL,
.fill_theme_defaults = NULL,
.uninitialize_theme = NULL,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
},
{
@@ -167,8 +151,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = <k_menu_ini_handler,
.fill_theme_defaults = <k_menu_fill_theme_defaults,
.uninitialize_theme = <k_menu_uninitialize_theme,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
},
{
@@ -176,8 +158,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = <k_menuentry_ini_handler,
.fill_theme_defaults = <k_menuentry_fill_theme_defaults,
.uninitialize_theme = <k_menuentry_uninitialize_theme,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
},
{
@@ -185,8 +165,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = <k_submenu_ini_handler,
.fill_theme_defaults = <k_submenu_fill_theme_defaults,
.uninitialize_theme = <k_submenu_uninitialize_theme,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
},
{
@@ -194,8 +172,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = <k_submenuentry_ini_handler,
.fill_theme_defaults = <k_submenuentry_fill_theme_defaults,
.uninitialize_theme = <k_submenuentry_uninitialize_theme,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
/*
This "widget" is only needed to have separate styles for regular
@@ -213,18 +189,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = <k_scrollbar_ini_handler,
.fill_theme_defaults = <k_scrollbar_fill_theme_defaults,
.uninitialize_theme = <k_scrollbar_uninitialize_theme,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
- .cleanup = NULL,
- },
- {
- /* Handler for general widget key bindings. */
- .name = "widget",
- .ini_handler = NULL,
- .fill_theme_defaults = NULL,
- .uninitialize_theme = NULL,
- .register_keypress = NULL,
- .register_keyrelease = NULL,
.cleanup = NULL,
},
{
@@ -233,8 +197,6 @@ static ltk_widget_funcs widget_funcs[] = {
.ini_handler = <k_window_ini_handler,
.fill_theme_defaults = <k_window_fill_theme_defaults,
.uninitialize_theme = <k_window_uninitialize_theme,
- .register_keypress = <k_window_register_keypress,
- .register_keyrelease = <k_window_register_keyrelease,
.cleanup = <k_window_cleanup,
}
};
@@ -259,12 +221,12 @@ ltk_init(void) {
char *config_path = ltk_strcat_useful(ltk_dir, "/ltk.cfg");
char *theme_path;
char *errstr = NULL;
- if (ltk_config_parsefile(config_path, &handle_keypress_binding, &handle_keyrelease_binding, &errstr)) {
+ if (ltk_config_parsefile(config_path, &errstr)) {
if (errstr) {
ltk_warn("Unable to load config: %s\n", errstr);
ltk_free0(errstr);
}
- if (ltk_config_load_default(&handle_keypress_binding, &handle_keyrelease_binding, &errstr)) {
+ if (ltk_config_load_default(&errstr)) {
/* FIXME: I guess errstr isn't freed here, but whatever */
/* FIXME: return error instead of dying */
ltk_fatal("Unable to load default config: %s\n", errstr);
@@ -588,30 +550,6 @@ ltk_uninitialize_theme(void) {
}
}
-static int
-handle_keypress_binding(const char *widget_name, size_t wlen, const char *name, size_t nlen, ltk_keypress_binding b) {
- for (size_t i = 0; i < LENGTH(widget_funcs); i++) {
- if (str_array_equal(widget_funcs[i].name, widget_name, wlen)) {
- if (!widget_funcs[i].register_keypress)
- return 1;
- return widget_funcs[i].register_keypress(name, nlen, b);
- }
- }
- return 1;
-}
-
-static int
-handle_keyrelease_binding(const char *widget_name, size_t wlen, const char *name, size_t nlen, ltk_keyrelease_binding b) {
- for (size_t i = 0; i < LENGTH(widget_funcs); i++) {
- if (str_array_equal(widget_funcs[i].name, widget_name, wlen)) {
- if (!widget_funcs[i].register_keyrelease)
- return 1;
- return widget_funcs[i].register_keyrelease(name, nlen, b);
- }
- }
- return 1;
-}
-
int
ltk_call_cmd(ltk_widget *caller, const char *cmd, size_t cmdlen, const char *text, size_t textlen) {
/* FIXME: support environment variable $TMPDIR */
diff --git a/src/ltk/sort_search.h b/src/ltk/sort_search.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2024 lumidify <nobody@lumidify.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef LTK_SORT_SEARCH_H
+#define LTK_SORT_SEARCH_H
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+struct ltk_search_cmp_helper {
+ const char *text;
+ size_t len;
+};
+
+/* FIXME: documentation */
+#define GEN_SORT_SEARCH_HELPERS(name, typename, cmp_entry) \
+ \
+/* \
+ * IMPORTANT: The text passed to *_get_entry may not be nul-terminated, \
+ * so ltk_search_cmp_helper has to be used for the bsearch comparison \
+ * helper. \
+ */ \
+ \
+static int \
+name##_search_helper(const void *keyv, const void *entryv) { \
+ struct ltk_search_cmp_helper *key = (struct ltk_search_cmp_helper *)keyv; \
+ typename *entry = (typename *)entryv; \
+ int ret = strncmp(key->text, entry->cmp_entry, key->len); \
+ if (ret == 0) { \
+ if (entry->cmp_entry[key->len] == '\0') \
+ return 0; \
+ else \
+ return -1; \
+ } \
+ return ret; \
+} \
+ \
+static int \
+name##_sort_helper(const void *entry1v, const void *entry2v) { \
+ typename *entry1 = (typename *)entry1v; \
+ typename *entry2 = (typename *)entry2v; \
+ return strcmp(entry1->cmp_entry, entry2->cmp_entry); \
+} \
+ \
+static void \
+name##_sort(typename *arr, size_t arrlen) { \
+ qsort( \
+ arr, arrlen, \
+ sizeof(typename), &name##_sort_helper \
+ ); \
+} \
+ \
+static typename * \
+name##_get_entry(typename *arr, size_t arrlen, const char *text, size_t len) { \
+ struct ltk_search_cmp_helper tmp = {.text = text, .len = len}; \
+ return bsearch( \
+ &tmp, arr, arrlen, \
+ sizeof(typename), &name##_search_helper \
+ ); \
+}
+
+#endif /* LTK_SORT_SEARCH_H */
diff --git a/src/ltk/window.c b/src/ltk/window.c
@@ -21,12 +21,12 @@
#include "ltk.h"
#include "util.h"
-#include "keys.h"
#include "array.h"
#include "theme.h"
#include "widget.h"
#include "window.h"
#include "memory.h"
+#include "config.h"
#include "eventdefs.h"
#define MAX_WINDOW_FONT_SIZE 20000
@@ -67,24 +67,19 @@ static struct ltk_widget_vtable vtable = {
.invalid_signal = LTK_WINDOW_SIGNAL_INVALID,
};
-static int cb_focus_active(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_unfocus_active(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_move_prev(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_move_next(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_move_left(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_move_right(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_move_up(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_move_down(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_set_pressed(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_unset_pressed(ltk_window *window, ltk_key_event *event, int handled);
-static int cb_remove_popups(ltk_window *window, ltk_key_event *event, int handled);
-
-struct key_cb {
- char *func_name;
- int (*callback)(ltk_window *, ltk_key_event *, int handled);
-};
-
-static struct key_cb cb_map[] = {
+static int cb_focus_active(ltk_widget *self, ltk_key_event *event);
+static int cb_unfocus_active(ltk_widget *self, ltk_key_event *event);
+static int cb_move_prev(ltk_widget *self, ltk_key_event *event);
+static int cb_move_next(ltk_widget *self, ltk_key_event *event);
+static int cb_move_left(ltk_widget *self, ltk_key_event *event);
+static int cb_move_right(ltk_widget *self, ltk_key_event *event);
+static int cb_move_up(ltk_widget *self, ltk_key_event *event);
+static int cb_move_down(ltk_widget *self, ltk_key_event *event);
+static int cb_set_pressed(ltk_widget *self, ltk_key_event *event);
+static int cb_unset_pressed(ltk_widget *self, ltk_key_event *event);
+static int cb_remove_popups(ltk_widget *self, ltk_key_event *event);
+
+static ltk_keybinding_cb cb_map[] = {
{"focus-active", &cb_focus_active},
{"move-down", &cb_move_down},
{"move-left", &cb_move_left},
@@ -98,25 +93,26 @@ static struct key_cb cb_map[] = {
{"unset-pressed", &cb_unset_pressed},
};
-struct keypress_cfg {
- ltk_keypress_binding b;
- struct key_cb cb;
-};
-
-struct keyrelease_cfg {
- ltk_keyrelease_binding b;
- struct key_cb cb;
-};
-
-LTK_ARRAY_INIT_DECL_STATIC(keypress, struct keypress_cfg)
-LTK_ARRAY_INIT_IMPL_STATIC(keypress, struct keypress_cfg)
-LTK_ARRAY_INIT_DECL_STATIC(keyrelease, struct keyrelease_cfg)
-LTK_ARRAY_INIT_IMPL_STATIC(keyrelease, struct keyrelease_cfg)
-
static ltk_array(keypress) *keypresses = NULL;
static ltk_array(keyrelease) *keyreleases = NULL;
-GEN_CB_MAP_HELPERS(cb_map, struct key_cb, func_name)
+void
+ltk_window_get_keybinding_parseinfo(
+ ltk_keybinding_cb **press_cbs_ret, size_t *press_len_ret,
+ ltk_keybinding_cb **release_cbs_ret, size_t *release_len_ret,
+ ltk_array(keypress) **presses_ret, ltk_array(keyrelease) **releases_ret
+) {
+ *press_cbs_ret = cb_map;
+ *press_len_ret = LENGTH(cb_map);
+ *release_cbs_ret = cb_map;
+ *release_len_ret = LENGTH(cb_map);
+ if (!keypresses)
+ keypresses = ltk_array_create(keypress, 1);
+ if (!keyreleases)
+ keyreleases = ltk_array_create(keyrelease, 1);
+ *presses_ret = keypresses;
+ *releases_ret = keyreleases;
+}
/* needed for passing keyboard events down the hierarchy */
static ltk_widget **widget_stack = NULL;
@@ -153,44 +149,13 @@ ltk_window_get_theme(void) {
return &theme;
}
-/* FIXME: most of this is duplicated code */
-
-int
-ltk_window_register_keypress(const char *func_name, size_t func_len, ltk_keypress_binding b) {
- if (!keypresses)
- keypresses = ltk_array_create(keypress, 1);
- struct key_cb *cb = cb_map_get_entry(func_name, func_len);
- if (!cb)
- return 1;
- struct keypress_cfg cfg = {b, *cb};
- ltk_array_append(keypress, keypresses, cfg);
- return 0;
-}
-
-int
-ltk_window_register_keyrelease(const char *func_name, size_t func_len, ltk_keyrelease_binding b) {
- if (!keyreleases)
- keyreleases = ltk_array_create(keyrelease, 1);
- struct key_cb *cb = cb_map_get_entry(func_name, func_len);
- if (!cb)
- return 1;
- struct keyrelease_cfg cfg = {b, *cb};
- ltk_array_append(keyrelease, keyreleases, cfg);
- return 0;
-}
-
-static void
-destroy_keypress_cfg(struct keypress_cfg cfg) {
- ltk_keypress_binding_destroy(cfg.b);
-}
-
void
ltk_window_cleanup(void) {
- ltk_array_destroy_deep(keypress, keypresses, &destroy_keypress_cfg);
- ltk_array_destroy(keyrelease, keyreleases);
- free(widget_stack);
+ ltk_keypress_bindings_destroy(keypresses);
+ ltk_keyrelease_bindings_destroy(keyreleases);
keypresses = NULL;
keyreleases = NULL;
+ ltk_free(widget_stack);
widget_stack = NULL;
}
@@ -244,13 +209,13 @@ ltk_window_key_press_event(ltk_widget *self, ltk_key_event *event) {
continue;
} else if (b->text) {
if (event->mapped && !strcmp(b->text, event->mapped))
- handled |= ltk_array_get(keypresses, i).cb.callback(window, event, handled);
+ handled |= ltk_array_get(keypresses, i).cb.func(LTK_CAST_WIDGET(window), event);
} else if (b->rawtext) {
if (event->text && !strcmp(b->text, event->text))
- handled |= ltk_array_get(keypresses, i).cb.callback(window, event, handled);
+ handled |= ltk_array_get(keypresses, i).cb.func(LTK_CAST_WIDGET(window), event);
} else if (b->sym != LTK_KEY_NONE) {
if (event->sym == b->sym)
- handled |= ltk_array_get(keypresses, i).cb.callback(window, event, handled);
+ handled |= ltk_array_get(keypresses, i).cb.func(LTK_CAST_WIDGET(window), event);
}
}
return 1;
@@ -280,7 +245,7 @@ ltk_window_key_release_event(ltk_widget *self, ltk_key_event *event) {
if (b->mods != event->modmask || (!(b->flags & LTK_KEY_BINDING_RUN_ALWAYS) && handled)) {
continue;
} else if (b->sym != LTK_KEY_NONE && event->sym == b->sym) {
- handled |= ltk_array_get(keyreleases, i).cb.callback(window, event, handled);
+ handled |= ltk_array_get(keyreleases, i).cb.func(LTK_CAST_WIDGET(window), event);
}
}
return 1;
@@ -1226,9 +1191,9 @@ gen_widget_stack(ltk_widget *bottom) {
widget type, but what if the program using ltk wants to catch keyboard events even if the widget
doesn't do that by default? */
static int
-cb_focus_active(ltk_window *window, ltk_key_event *event, int handled) {
+cb_focus_active(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
if (window->active_widget && !(window->active_widget->state & LTK_FOCUSED)) {
/* FIXME: maybe also set widgets above in hierarchy? */
ltk_widget_state old_state = window->active_widget->state;
@@ -1240,9 +1205,9 @@ cb_focus_active(ltk_window *window, ltk_key_event *event, int handled) {
}
static int
-cb_unfocus_active(ltk_window *window, ltk_key_event *event, int handled) {
+cb_unfocus_active(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
if (window->active_widget && (window->active_widget->state & LTK_FOCUSED) && (window->active_widget->vtable->flags & LTK_NEEDS_KEYBOARD)) {
ltk_widget_state old_state = window->active_widget->state;
window->active_widget->state &= ~LTK_FOCUSED;
@@ -1253,51 +1218,51 @@ cb_unfocus_active(ltk_window *window, ltk_key_event *event, int handled) {
}
static int
-cb_move_prev(ltk_window *window, ltk_key_event *event, int handled) {
+cb_move_prev(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
return prev_child(window);
}
static int
-cb_move_next(ltk_window *window, ltk_key_event *event, int handled) {
+cb_move_next(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
return next_child(window);
}
static int
-cb_move_left(ltk_window *window, ltk_key_event *event, int handled) {
+cb_move_left(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
return left_top_child(window, 1);
}
static int
-cb_move_right(ltk_window *window, ltk_key_event *event, int handled) {
+cb_move_right(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
return right_bottom_child(window, 1);
}
static int
-cb_move_up(ltk_window *window, ltk_key_event *event, int handled) {
+cb_move_up(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
return left_top_child(window, 0);
}
static int
-cb_move_down(ltk_window *window, ltk_key_event *event, int handled) {
+cb_move_down(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
return right_bottom_child(window, 0);
}
static int
-cb_set_pressed(ltk_window *window, ltk_key_event *event, int handled) {
+cb_set_pressed(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
if (window->active_widget && (window->active_widget->state & LTK_FOCUSED)) {
/* FIXME: only set pressed if needs keyboard? */
ltk_window_set_pressed_widget(window, window->active_widget, 0);
@@ -1307,9 +1272,9 @@ cb_set_pressed(ltk_window *window, ltk_key_event *event, int handled) {
}
static int
-cb_unset_pressed(ltk_window *window, ltk_key_event *event, int handled) {
+cb_unset_pressed(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
if (window->pressed_widget) {
ltk_window_set_pressed_widget(window, NULL, 1);
return 1;
@@ -1318,9 +1283,9 @@ cb_unset_pressed(ltk_window *window, ltk_key_event *event, int handled) {
}
static int
-cb_remove_popups(ltk_window *window, ltk_key_event *event, int handled) {
+cb_remove_popups(ltk_widget *self, ltk_key_event *event) {
(void)event;
- (void)handled;
+ ltk_window *window = LTK_CAST_WINDOW(self);
if (window->popups_num > 0) {
ltk_window_unregister_all_popups(window);
return 1;
diff --git a/src/ltk/window.h b/src/ltk/window.h
@@ -61,11 +61,6 @@ typedef struct ltk_window {
char popups_locked;
} ltk_window;
-int ltk_window_fill_theme_defaults(ltk_renderdata *data);
-int ltk_window_ini_handler(ltk_renderdata *data, const char *prop, const char *value);
-void ltk_window_uninitialize_theme(ltk_renderdata *data);
-ltk_window_theme *ltk_window_get_theme(void);
-
/* FIXME: should be private to ltk */
ltk_window *ltk_window_create_intern(ltk_renderdata *data, const char *title, int x, int y, unsigned int w, unsigned int h);
void ltk_window_destroy_intern(ltk_window *window);
@@ -90,9 +85,15 @@ void ltk_window_unregister_popup(ltk_window *window, ltk_widget *popup);
void ltk_window_unregister_all_popups(ltk_window *window);
/* FIXME: these should be private to ltk */
-/* FIXME: document that pointers inside binding are taken over! */
-int ltk_window_register_keypress(const char *func_name, size_t func_len, ltk_keypress_binding b);
-int ltk_window_register_keyrelease(const char *func_name, size_t func_len, ltk_keyrelease_binding b);
void ltk_window_cleanup(void);
+void ltk_window_get_keybinding_parseinfo(
+ ltk_keybinding_cb **press_cbs_ret, size_t *press_len_ret,
+ ltk_keybinding_cb **release_cbs_ret, size_t *release_len_ret,
+ ltk_array(keypress) **presses_ret, ltk_array(keyrelease) **releases_ret
+);
+int ltk_window_fill_theme_defaults(ltk_renderdata *data);
+int ltk_window_ini_handler(ltk_renderdata *data, const char *prop, const char *value);
+void ltk_window_uninitialize_theme(ltk_renderdata *data);
+ltk_window_theme *ltk_window_get_theme(void);
#endif /* LTK_WINDOW_H */