From 4e9eb9796031db814f1015347730d7b6237d45be Mon Sep 17 00:00:00 2001 From: Phireh Date: Wed, 4 Dec 2024 13:17:08 +0100 Subject: [PATCH] Baby steps towards input handling --- input.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ wayland.c | 71 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 input.h diff --git a/input.h b/input.h new file mode 100644 index 0000000..39a3af3 --- /dev/null +++ b/input.h @@ -0,0 +1,80 @@ +#ifndef INPUT_H +#define INPUT_H + +// NOTE: KEY_STATE_RELEASED does not imply KEY_STATE_UNPRESSED, which can be funky. Maybe give this another look? +typedef enum { + KEY_STATE_UNPRESSED = 0, + KEY_STATE_RELEASED = 1, + KEY_STATE_PRESSED = 1 << 1, + KEY_STATE_HELD = 1 << 2 +} key_state_t; + +typedef enum { + KEYBOARD_STATE_UNPLUGGED = 0, + KEYBOARD_STATE_UNFOCUSED = 1, + KEYBOARD_STATE_FOCUSED = 1 << 1, + KEYBOARD_STATE_IME = 1 << 2 +} keyboard_state_t; + +typedef enum { + MOUSE_STATE_UNPLUGGED = 0, + MOUSE_STATE_UNFOCUSED = 1, + MOUSE_STATE_FOCUSED = 1 << 1 +} mouse_state_t; + +typedef enum { + MOUSE_KEY_LEFT = 0, + MOUSE_KEY_RIGHT = 1, + MOUSE_KEY_MIDDLE = 2, + MOUSE_KEY_SIDE = 3, + MOUSE_KEY_EXTRA = 4, + MOUSE_KEY_FORWARD = 5, + MOUSE_KEY_BACK = 6, + MOUSE_KEY_TASK = 7, + MOUSE_KEY_EXTRA_0 = 8, + MOUSE_KEY_EXTRA_1 = 9, + MOUSE_KEY_EXTRA_2 = 10, + MOUSE_KEY_EXTRA_3 = 11, + MOUSE_KEY_EXTRA_4 = 12, + MOUSE_KEY_EXTRA_5 = 13, + MOUSE_KEY_EXTRA_6 = 14, + MOUSE_KEY_EXTRA_7 = 15, + MOUSE_KEY_EXTRA_8 = 16, + MOUSE_KEY_EXTRA_9 = 17, + MOUSE_KEY_TOTAL = 18 +} mouse_keysym_t; + +#define IME_STR_MAX 200 // TODO: check if this limit is sensible + +typedef struct { + uint8_t keyboard_state; // mostly used to check if we are using the IME + uint8_t keys[256]; // the state of the full keyboard + uint8_t mouse_state; + int32_t mouse_x; + int32_t mouse_y; + uint8_t mouse_keys[MOUSE_KEY_TOTAL]; + uint32_t modifiers; // TODO: Decide on a format for keyboard mod keys + uint8_t ime_str[IME_STR_MAX]; // the final string coming from the IME for text input fields as utf8 +} input_t; + +int32_t is_key_down(input_t *i, uint8_t key) +{ + return i->keys[key] & KEY_STATE_PRESSED; +} + +int32_t is_key_pressed(input_t *i, uint8_t key) +{ + return i->keys[key] & KEY_STATE_PRESSED && !(i->keys[key] & KEY_STATE_HELD); +} + +int32_t is_key_held(input_t *i, uint8_t key) +{ + return i->keys[key] & KEY_STATE_HELD; +} + +int32_t is_key_released(input_t *i, uint8_t key) +{ + return i->keys[key] & KEY_STATE_RELEASED; +} + +#endif diff --git a/wayland.c b/wayland.c index 71fd878..ac1c76b 100644 --- a/wayland.c +++ b/wayland.c @@ -1,17 +1,25 @@ +// stdlib #include -#include -#include -#include -#include -#include #include #include #include -#include #include -// Generated header using wayland-scanner +// wayland +#include +#include +// OGL +#include +#include +// X11 +#include +// linux +#include +#include +// generated header using wayland-scanner #include "xdg-shell-client-protocol.h" #include "zwp-text-input-unstable-v3-protocol.h" +// common headers for platform layer and application layer +#include "input.h" struct wl_compositor *compositor = NULL; struct wl_registry *registry = NULL; @@ -39,6 +47,7 @@ struct xkb_keymap *xkb_keymap = NULL; /* Misc. global state */ EGLBoolean errcode = 0; bool running = true; +input_t user_input = {}; char *egl_s(int code) { @@ -106,11 +115,21 @@ void zwp_text_input_v3_leave_callback(void *data, struct zwp_text_input_v3 *text void zwp_text_input_v3_preedit_string_callback(void *data, struct zwp_text_input_v3 *text_input, const char *text, int32_t cursor_begin, int32_t cursor_end) { fprintf(stdout, "ZWP text input v3 preedit string callback with text %s\n", text); + user_input.keyboard_state &= KEYBOARD_STATE_IME; } void zwp_text_input_v3_commit_string_callback(void *data, struct zwp_text_input_v3 *text_input, const char *text) { fprintf(stdout, "ZWP text input v3 commit string callback with text %s\n", text); + user_input.keyboard_state &= ~KEYBOARD_STATE_IME; + + const char *s = text; + int i = 0; + for (; i < IME_STR_MAX - 1 && s; ++i) + user_input.ime_str[i] = *s++; + + user_input.ime_str[i] = '\0'; + fprintf(stdout, "Copied string %s\n", text); } void zwp_text_input_v3_delete_surrounding_text_callback(void *data, struct zwp_text_input_v3 *text_input, uint32_t before_length, uint32_t after_length) @@ -181,11 +200,13 @@ void keymap_callback(void *data, struct wl_keyboard *kb, uint format, int fd, ui void enter_callback(void *data, struct wl_keyboard* kb, uint serial, struct wl_surface* surface, struct wl_array *keys) { fprintf(stdout, "KBMAP with serial %d entered surface\n", serial); + user_input.keyboard_state = KEYBOARD_STATE_UNFOCUSED; } void leave_callback(void *data, struct wl_keyboard* kb, uint serial, struct wl_surface* surface) { fprintf(stdout, "KBMAP with serial %d left surface\n", serial); + user_input.keyboard_state = KEYBOARD_STATE_FOCUSED; } void key_callback(void *data, struct wl_keyboard *kb, uint serial, uint time, uint key, uint state) @@ -211,12 +232,15 @@ void key_callback(void *data, struct wl_keyboard *kb, uint serial, uint time, ui char keyutf8[128]; xkb_state_key_get_utf8(xkb_state, key, keyutf8, sizeof(keyutf8)); fprintf(stdout, "%s key %d layout %d (KEYSYM %s) (UTF8 %s)\n", (state == WL_KEYBOARD_KEY_STATE_PRESSED ? "Pressed" : "Released"), key, layout, keyname, keyutf8); + // TODO: Test this + user_input.keys[key] = (state == WL_KEYBOARD_KEY_STATE_PRESSED ? KEY_STATE_PRESSED : KEY_STATE_RELEASED); } void modifier_callback(void *data, struct wl_keyboard *kb, uint serial, uint mods_depressed, uint mods_latched, uint mods_locked, uint group) { fprintf(stdout, "Keyboard modifier keys changed\n"); xkb_state_update_mask(xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); + user_input.modifiers = (mods_depressed | mods_latched | mods_locked); } void repeat_info_callback(void *data, struct wl_keyboard *kb, int rate, int delay) @@ -227,21 +251,49 @@ void repeat_info_callback(void *data, struct wl_keyboard *kb, int rate, int dela void pointer_enter_callback(void *data, struct wl_pointer *pointer, uint serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y) { //fprintf(stdout, "Pointer entered WL surface on coordinates %d %d\n", x, y); + user_input.mouse_state = MOUSE_STATE_FOCUSED; } void pointer_leave_callback(void *data, struct wl_pointer *pointer, uint serial, struct wl_surface *surface) { //fprintf(stdout, "Pointer left WL surface\n"); + user_input.mouse_state = MOUSE_STATE_UNFOCUSED; } void pointer_motion_callback(void *data, struct wl_pointer *pointer, uint time, wl_fixed_t x, wl_fixed_t y) { //fprintf(stdout, "Pointer moved to %d %d\n", x, y); + user_input.mouse_x = x; + user_input.mouse_y = y; } void pointer_button_callback(void *data, struct wl_pointer *pointer, uint serial, uint time, uint button, uint state) { - //fprintf(stdout, "Pointer button %d changed state\n", button); + fprintf(stdout, "Pointer button %d changed state\n", button); + mouse_keysym_t idx = 0; + switch (button) + { + case BTN_LEFT: idx = MOUSE_KEY_LEFT; break; + case BTN_RIGHT: idx = MOUSE_KEY_RIGHT; break; + case BTN_MIDDLE: idx = MOUSE_KEY_MIDDLE; break; + case BTN_SIDE: idx = MOUSE_KEY_SIDE; break; + case BTN_EXTRA: idx = MOUSE_KEY_EXTRA; break; + case BTN_FORWARD: idx = MOUSE_KEY_FORWARD; break; + case BTN_TASK: idx = MOUSE_KEY_TASK; break; + case BTN_0: idx = MOUSE_KEY_EXTRA_0; break; + case BTN_1: idx = MOUSE_KEY_EXTRA_1; break; + case BTN_2: idx = MOUSE_KEY_EXTRA_2; break; + case BTN_3: idx = MOUSE_KEY_EXTRA_3; break; + case BTN_4: idx = MOUSE_KEY_EXTRA_4; break; + case BTN_5: idx = MOUSE_KEY_EXTRA_5; break; + case BTN_6: idx = MOUSE_KEY_EXTRA_6; break; + case BTN_7: idx = MOUSE_KEY_EXTRA_7; break; + case BTN_8: idx = MOUSE_KEY_EXTRA_8; break; + case BTN_9: idx = MOUSE_KEY_EXTRA_9; break; + default: + fprintf(stderr, "Unknown wayland button identifier: 0x%x\n", button); + } + user_input.mouse_keys[idx] = (state == WL_POINTER_BUTTON_STATE_PRESSED) ? KEY_STATE_PRESSED : KEY_STATE_RELEASED; } void pointer_axis_callback(void *data, struct wl_pointer *pointer, uint time, uint axis, wl_fixed_t value) @@ -323,7 +375,10 @@ int main() if (xdg_wm_base_add_listener(wm_base, &xdg_wm_base_listener, NULL)) fprintf(stderr, "Could not set XDG WM base listener\n"); if (!(wl_keyboard = wl_seat_get_keyboard(wl_seat))) + { fprintf(stderr, "Could not get XKB keyboard\n"); + user_input.keyboard_state = KEYBOARD_STATE_UNPLUGGED; + } if (!(wl_pointer = wl_seat_get_pointer(wl_seat))) fprintf(stderr, "Could not get WL pointer\n");