Skip to content

Commit

Permalink
wayland kb
Browse files Browse the repository at this point in the history
  • Loading branch information
igagis committed Apr 2, 2024
1 parent 1061d9f commit 0add70f
Showing 1 changed file with 181 additions and 7 deletions.
188 changes: 181 additions & 7 deletions src/ruisapp/glue/linux/glue_wayland.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,168 @@ ruis::mouse_button button_number_to_enum(uint32_t number)
}
} // namespace

namespace {
struct keyboard_wrapper {
unsigned num_connected = 0;

wl_keyboard* keyboard = nullptr;

static void wl_keyboard_keymap(void* data, struct wl_keyboard* keyboard, uint32_t format, int32_t fd, uint32_t size)
{
// ASSERT(data)
// auto& self = *static_cast<keyboard_wrapper*>(data);

// struct client_state *client_state = data;
// assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1);

// char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
// assert(map_shm != MAP_FAILED);

// struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_string(
// client_state->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(client_state->xkb_keymap);
// xkb_state_unref(client_state->xkb_state);
// client_state->xkb_keymap = xkb_keymap;
// client_state->xkb_state = xkb_state;
}

static void wl_keyboard_enter(
void* data,
struct wl_keyboard* keyboard,
uint32_t serial,
struct wl_surface* surface,
struct wl_array* keys
)
{
// struct client_state *client_state = data;
// fprintf(stderr, "keyboard enter; keys pressed are:\n");
// uint32_t *key;
// wl_array_for_each(key, keys) {
// char buf[128];
// xkb_keysym_t sym = xkb_state_key_get_one_sym(
// client_state->xkb_state, *key + 8);
// xkb_keysym_get_name(sym, buf, sizeof(buf));
// fprintf(stderr, "sym: %-12s (%d), ", buf, sym);
// xkb_state_key_get_utf8(client_state->xkb_state,
// *key + 8, buf, sizeof(buf));
// fprintf(stderr, "utf8: '%s'\n", buf);
// }
}

static void wl_keyboard_leave(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface)
{
// fprintf(stderr, "keyboard leave\n");
}

static void wl_keyboard_key(
void* data,
struct wl_keyboard* keyboard,
uint32_t serial,
uint32_t time,
uint32_t key,
uint32_t state
)
{
// struct client_state *client_state = data;
// char buf[128];
// uint32_t keycode = key + 8;
// xkb_keysym_t sym = xkb_state_key_get_one_sym(
// client_state->xkb_state, keycode);
// xkb_keysym_get_name(sym, buf, sizeof(buf));
// const char *action =
// state == WL_KEYBOARD_KEY_STATE_PRESSED ? "press" : "release";
// fprintf(stderr, "key %s: sym: %-12s (%d), ", action, buf, sym);
// xkb_state_key_get_utf8(client_state->xkb_state, keycode,
// buf, sizeof(buf));
// fprintf(stderr, "utf8: '%s'\n", buf);
}

static void wl_keyboard_modifiers(
void* data,
struct wl_keyboard* keyboard,
uint32_t serial,
uint32_t mods_depressed,
uint32_t mods_latched,
uint32_t mods_locked,
uint32_t group
)
{
// struct client_state* client_state = data;
// xkb_state_update_mask(client_state->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
}

static void wl_keyboard_repeat_info(void* data, struct wl_keyboard* keyboard, int32_t rate, int32_t delay)
{
// TODO:
}

constexpr static const wl_keyboard_listener listener = {
.keymap = &wl_keyboard_keymap,
.enter = &wl_keyboard_enter,
.leave = &wl_keyboard_leave,
.key = &wl_keyboard_key,
.modifiers = &wl_keyboard_modifiers,
.repeat_info = &wl_keyboard_repeat_info,
};

void connect(wl_seat* seat)
{
++this->num_connected;

if (this->num_connected > 1) {
// already connected
ASSERT(this->keyboard)
return;
}

this->keyboard = wl_seat_get_keyboard(seat);
if (!this->keyboard) {
this->num_connected = 0;
throw std::runtime_error("could not get wayland keyboard interface");
}

if (wl_keyboard_add_listener(this->keyboard, &listener, this) != 0) {
wl_keyboard_release(this->keyboard);
this->num_connected = 0;
throw std::runtime_error("could not add listener to wayland keyboard interface");
}
}

void disconnect() noexcept
{
if (this->num_connected == 0) {
// no keyboards connected
ASSERT(!this->keyboard)
return;
}

ASSERT(this->keyboard)

--this->num_connected;

if (this->num_connected == 0) {
wl_keyboard_release(this->keyboard);
this->keyboard = nullptr;
}
}

keyboard_wrapper() {}

~keyboard_wrapper()
{
if (this->keyboard) {
wl_keyboard_release(this->keyboard);
}
}
};

} // namespace

namespace {

struct window_wrapper;
Expand Down Expand Up @@ -133,7 +295,9 @@ struct window_wrapper : public utki::destructable {
wl_compositor* compositor = nullptr;
xdg_wm_base* wm_base = nullptr;
wl_seat* seat = nullptr;

wl_pointer* pointer = nullptr;
keyboard_wrapper keyboard;

ruis::vector2 cur_pointer_pos{0, 0};

Expand Down Expand Up @@ -283,15 +447,25 @@ struct window_wrapper : public utki::destructable {
wl_pointer_release(self.pointer);
self.pointer = nullptr;
}

bool have_keyboard = capabilities & WL_SEAT_CAPABILITY_KEYBOARD;

if (have_keyboard) {
self.keyboard.connect(self.seat);
} else {
self.keyboard.disconnect();
}
}

constexpr static const wl_seat_listener seat_listener =
{.capabilities = &wl_seat_capabilities, //
.name = [](void* data, struct wl_seat* seat, const char* name) {
LOG([&](auto& o) {
o << "seat name: " << name << std::endl;
})
}};
constexpr static const wl_seat_listener seat_listener = {
.capabilities = &wl_seat_capabilities,
.name =
[](void* data, struct wl_seat* seat, const char* name) {
LOG([&](auto& o) {
o << "seat name: " << name << std::endl;
})
} //
};

static void wl_registry_global(
void* data,
Expand Down

0 comments on commit 0add70f

Please sign in to comment.