untested keyboard support
This commit is contained in:
parent
cb09986053
commit
36ed559da1
2 changed files with 108 additions and 19 deletions
|
|
@ -44,6 +44,8 @@ struct _MwLLWaylandTopLevel {
|
|||
struct xdg_surface_listener xdg_surface_listener;
|
||||
|
||||
struct xkb_context* xkb_context;
|
||||
struct xkb_keymap* xkb_keymap;
|
||||
struct xkb_state* xkb_state;
|
||||
|
||||
MwBool compositor_created;
|
||||
MwBool xdg_wm_base_created;
|
||||
|
|
|
|||
|
|
@ -16,13 +16,12 @@
|
|||
#else
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
callback todo:
|
||||
void (*key)(MwLL handle, void* data);
|
||||
void (*key_released)(MwLL handle, void* data);
|
||||
void (*focus_in)(MwLL handle, void* data);
|
||||
void (*focus_out)(MwLL handle, void* data);
|
||||
*/
|
||||
* GENERAL TODO:
|
||||
* comment the file lmao
|
||||
* make sure MwLLDestroy is finished (+ handle dropdown bug that results from it)
|
||||
*/
|
||||
|
||||
static void timed_redraw(MwLL handle, MwU32 time, int cooldown, MwU64* cooldown_timer);
|
||||
|
||||
|
|
@ -50,9 +49,11 @@ static void protocol_removed(void* data,
|
|||
|
||||
static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 serial,
|
||||
struct wl_surface* surface, wl_fixed_t surface_x,
|
||||
wl_fixed_t surface_y) {};
|
||||
wl_fixed_t surface_y) {
|
||||
};
|
||||
static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial,
|
||||
struct wl_surface* surface) {};
|
||||
struct wl_surface* surface) {
|
||||
};
|
||||
static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time,
|
||||
wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
||||
MwLL self = data;
|
||||
|
|
@ -103,6 +104,102 @@ struct wl_pointer_listener pointer_listener = {
|
|||
.axis = pointer_axis,
|
||||
};
|
||||
|
||||
static void keyboard_keymap(void* data,
|
||||
struct wl_keyboard* wl_keyboard,
|
||||
uint32_t format,
|
||||
int32_t fd,
|
||||
uint32_t size) {
|
||||
MwLL self = data;
|
||||
if(self->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
struct _MwLLWaylandTopLevel* wayland = self->wayland.toplevel;
|
||||
assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1);
|
||||
|
||||
char* map_shm = (char*)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
assert(map_shm != MAP_FAILED);
|
||||
|
||||
struct xkb_keymap* xkb_keymap = xkb_keymap_new_from_string(
|
||||
wayland->xkb_context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
munmap(map_shm, size);
|
||||
close(fd);
|
||||
|
||||
struct xkb_state* xkb_state = xkb_state_new(xkb_keymap);
|
||||
xkb_keymap_unref(wayland->xkb_keymap);
|
||||
xkb_state_unref(wayland->xkb_state);
|
||||
|
||||
wayland->xkb_keymap = xkb_keymap;
|
||||
wayland->xkb_state = xkb_state;
|
||||
}
|
||||
};
|
||||
static void keyboard_enter(void* data,
|
||||
struct wl_keyboard* wl_keyboard,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface,
|
||||
struct wl_array* keys) {
|
||||
MwLL self = data;
|
||||
MwLLDispatch(self, focus_in, NULL);
|
||||
};
|
||||
static void keyboard_leave(void* data,
|
||||
struct wl_keyboard* wl_keyboard,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface) {
|
||||
MwLL self = data;
|
||||
MwLLDispatch(self, focus_out, NULL);
|
||||
};
|
||||
static void keyboard_key(void* data,
|
||||
struct wl_keyboard* wl_keyboard,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state) {
|
||||
MwLL self = data;
|
||||
if(self->wayland.type == MWLL_WAYLAND_TOPLEVEL) {
|
||||
struct _MwLLWaylandTopLevel* wayland = self->wayland.toplevel;
|
||||
xkb_layout_index_t layout;
|
||||
xkb_level_index_t level;
|
||||
const xkb_keysym_t* syms_out;
|
||||
MwU32 keycode = key + 8;
|
||||
MwU64 syms_num;
|
||||
int i;
|
||||
|
||||
if(!wayland->xkb_keymap) {
|
||||
return;
|
||||
}
|
||||
|
||||
layout = xkb_state_key_get_layout(wayland->xkb_state, keycode);
|
||||
level =
|
||||
xkb_keymap_num_levels_for_key(wayland->xkb_keymap, keycode, layout) - 1;
|
||||
syms_num = xkb_keymap_key_get_syms_by_level(wayland->xkb_keymap, keycode, layout, level, &syms_out);
|
||||
if(syms_out == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < syms_num; i++) {
|
||||
int sym = syms_out[i];
|
||||
if(state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
MwLLDispatch(self, key, &sym);
|
||||
} else {
|
||||
MwLLDispatch(self, key_released, &sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static void keyboard_modifiers(void* data,
|
||||
struct wl_keyboard* wl_keyboard,
|
||||
uint32_t serial,
|
||||
uint32_t mods_depressed,
|
||||
uint32_t mods_latched,
|
||||
uint32_t mods_locked,
|
||||
uint32_t group) {};
|
||||
|
||||
struct wl_keyboard_listener keyboard_listener = {
|
||||
.keymap = keyboard_keymap,
|
||||
.enter = keyboard_enter,
|
||||
.leave = keyboard_leave,
|
||||
.key = keyboard_key,
|
||||
.modifiers = keyboard_modifiers,
|
||||
};
|
||||
|
||||
static void
|
||||
wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) {};
|
||||
static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
|
||||
|
|
@ -110,7 +207,7 @@ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
|
|||
MwLL self = data;
|
||||
if(capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
|
||||
struct wl_keyboard* keyboard = wl_seat_get_keyboard(wl_seat);
|
||||
// wl_keyboard_add_listener(keyboard, const struct wl_keyboard_listener* listener, data);
|
||||
wl_keyboard_add_listener(keyboard, &keyboard_listener, data);
|
||||
}
|
||||
if(capabilities & WL_SEAT_CAPABILITY_POINTER && !self->wayland.pointer) {
|
||||
self->wayland.pointer = wl_seat_get_pointer(wl_seat);
|
||||
|
|
@ -490,16 +587,6 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Check that all globals we require are available
|
||||
if(
|
||||
r->wayland.compositor == NULL ||
|
||||
WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context == NULL) {
|
||||
|
||||
printf("no xdg_wm_base support\n");
|
||||
raise(SIGTRAP);
|
||||
return;
|
||||
}
|
||||
|
||||
r->wayland.toplevel->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
// Create a wl_surface, a xdg_surface and a xdg_toplevel
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue