From f9a9b8550ef8c7ab6c80569525f3218d864b2f3b Mon Sep 17 00:00:00 2001 From: Aki Date: Thu, 16 Sep 2021 22:23:54 +0200 Subject: Window is now closed only if q is pressed --- Makefile | 4 ++-- text.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index d48d49c..20a8b76 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CFLAGS += -Wall -Wextra -Wpedantic -CFLAGS += `pkg-config --cflags cairo pango pangocairo xcb xcb-util` -LDLIBS += -lm `pkg-config --libs cairo pango pangocairo xcb xcb-util` +CFLAGS += `pkg-config --cflags cairo pango pangocairo xcb xcb-util xkbcommon xkbcommon-x11` +LDLIBS += -lm `pkg-config --libs cairo pango pangocairo xcb xcb-util xkbcommon xkbcommon-x11` all: text diff --git a/text.c b/text.c index 9560edd..6e3da86 100644 --- a/text.c +++ b/text.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include enum CommandType { @@ -49,6 +51,14 @@ struct State cairo_surface_t * surface; }; +struct Keyboard +{ + struct xkb_context * ctx; + struct xkb_keymap * keymap; + int32_t device_id; + struct xkb_state * state; +}; + enum Actions { ACTION_REDRAW = 1 << 0, @@ -66,8 +76,9 @@ struct Layout }; int setup(struct State *); +int setup_keyboard(struct State *, struct Keyboard *); void finalize(struct State *, struct Layout *); -int handle(struct State *, xcb_generic_event_t *); +int handle(struct State *, struct Keyboard *, xcb_generic_event_t *); xcb_visualtype_t * find_visual(xcb_screen_t *); PangoAttribute * find_link_under(struct State *, PangoLayout *, PangoAttrList *, int, int); void arrange(struct State *, struct Layout *, union Command[]); @@ -114,12 +125,18 @@ int main(int argc, const char ** argv) dprintf(2, "Could not connect to X server\n"); return 1; } + struct Keyboard keys; + if (-1 == setup_keyboard(&state, &keys)) + { + dprintf(2, "Could not set up XKB\n"); + return 1; + } struct Layout layout = {.desc = NULL, .size = 0, .v = NULL}; arrange(&state, &layout, body); for (;;) { xcb_generic_event_t * e = xcb_wait_for_event(state.c); // TODO: All events first, then flagged actions. - int actions = handle(&state, e); // Obviously, right now this may have at most one action. + int actions = handle(&state, &keys, e); // Obviously, right now this may have at most one action. if (ACTION_CLOSE & actions) break; // TODO: Arranging, rearranging and (obviously) reacting to pointer events are all different things. @@ -163,6 +180,31 @@ int setup(struct State * state) } +int setup_keyboard(struct State * state, struct Keyboard * keys) +{ + unsigned char event; + if (!xkb_x11_setup_xkb_extension( + state->c, + XKB_X11_MIN_MAJOR_XKB_VERSION, + XKB_X11_MIN_MINOR_XKB_VERSION, + XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, NULL, NULL, &event, NULL)) + return -1; + keys->ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (NULL == keys->ctx) + return -1; + keys->device_id = xkb_x11_get_core_keyboard_device_id(state->c); + if (-1 == keys->device_id) + return -1; + keys->keymap = xkb_x11_keymap_new_from_device(keys->ctx, state->c, keys->device_id, XKB_KEYMAP_COMPILE_NO_FLAGS); + if (NULL == keys->keymap) + return -1; + keys->state = xkb_x11_state_new_from_device(keys->keymap, state->c, keys->device_id); + if (NULL == keys->state) + return -1; + return 0; +} + + void finalize(struct State * state, struct Layout * layout) { pango_font_description_free(layout->desc); @@ -175,13 +217,17 @@ void finalize(struct State * state, struct Layout * layout) } -int handle(struct State * state, xcb_generic_event_t * e) +int handle(struct State * state, struct Keyboard * keys, xcb_generic_event_t * e) { int actions = 0; switch (XCB_EVENT_RESPONSE_TYPE(e)) { case XCB_KEY_PRESS: - actions = ACTION_CLOSE; + ; + xcb_key_press_event_t * key = (xcb_key_press_event_t *) e; + xkb_keysym_t sym = xkb_state_key_get_one_sym(keys->state, (xkb_keycode_t) key->detail); + if (XKB_KEY_q == sym) + actions = ACTION_CLOSE; break; case XCB_EXPOSE: actions |= ACTION_REDRAW; -- cgit v1.1