summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2021-09-16 22:23:54 +0200
committerAki <please@ignore.pl>2021-09-16 22:23:54 +0200
commitf9a9b8550ef8c7ab6c80569525f3218d864b2f3b (patch)
tree34a9c6b7722dab100180fb325425c3e2cbe1f2d0
parentd4f7d26a6179034637cb302b4850c8febd5df01a (diff)
downloadtext-f9a9b8550ef8c7ab6c80569525f3218d864b2f3b.zip
text-f9a9b8550ef8c7ab6c80569525f3218d864b2f3b.tar.gz
text-f9a9b8550ef8c7ab6c80569525f3218d864b2f3b.tar.bz2
Window is now closed only if q is pressed
-rw-r--r--Makefile4
-rw-r--r--text.c54
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 <pango/pangocairo.h>
#include <xcb/xcb.h>
#include <xcb/xcb_util.h>
+#include <xkbcommon/xkbcommon.h>
+#include <xkbcommon/xkbcommon-x11.h>
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;