diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-08-17 08:42:24 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-17 08:42:24 -0400 |
commit | 18f153810871d4d39d057bd6ceceda91c4353300 (patch) | |
tree | ea183d8b014878a0887ee2c1c49b2b92c0d21e24 /examples/compositor | |
parent | a616437c83a51e4329f3ea280699073e43da6436 (diff) | |
parent | edbaa7d6ac0bdbe3230b75e7cf7664dbda7207e0 (diff) |
Merge pull request #99 from nyorain/wlr_seat2
wlr_seat
Diffstat (limited to 'examples/compositor')
-rw-r--r-- | examples/compositor/main.c | 84 |
1 files changed, 82 insertions, 2 deletions
diff --git a/examples/compositor/main.c b/examples/compositor/main.c index 8a9de2f9..1fe81046 100644 --- a/examples/compositor/main.c +++ b/examples/compositor/main.c @@ -4,6 +4,8 @@ #include <stdlib.h> #include <time.h> #include <inttypes.h> +#include <unistd.h> +#include <sys/mman.h> #include <wayland-server.h> #include <wlr/backend.h> #include <wlr/backend/session.h> @@ -14,16 +16,26 @@ #include <wlr/types/wlr_surface.h> #include <wlr/types/wlr_wl_shell.h> #include <wlr/types/wlr_xdg_shell_v6.h> +#include <wlr/types/wlr_seat.h> #include <xkbcommon/xkbcommon.h> #include <wlr/util/log.h> #include "shared.h" #include "compositor.h" +// TODO: move to common header? +int os_create_anonymous_file(off_t size); + struct sample_state { struct wlr_renderer *renderer; struct wl_compositor_state compositor; struct wlr_wl_shell *wl_shell; + struct wlr_seat *wl_seat; struct wlr_xdg_shell_v6 *xdg_shell; + struct wl_resource *focus; + struct wl_listener keyboard_bound; + int keymap_fd; + size_t keymap_size; + uint32_t serial; }; /* @@ -33,7 +45,7 @@ static inline int64_t timespec_to_msec(const struct timespec *a) { return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; } -void output_frame_handle_surface(struct sample_state *sample, +static void output_frame_handle_surface(struct sample_state *sample, struct wlr_output *wlr_output, struct timespec *ts, struct wl_resource *_res) { struct wlr_surface *surface = wl_resource_get_user_data(_res); @@ -53,7 +65,7 @@ void output_frame_handle_surface(struct sample_state *sample, } } } -void handle_output_frame(struct output_state *output, struct timespec *ts) { +static void handle_output_frame(struct output_state *output, struct timespec *ts) { struct compositor_state *state = output->compositor; struct sample_state *sample = state->data; struct wlr_output *wlr_output = output->output; @@ -74,11 +86,58 @@ void handle_output_frame(struct output_state *output, struct timespec *ts) { wlr_output_swap_buffers(wlr_output); } +static void handle_keyboard_key(struct keyboard_state *keyboard, uint32_t keycode, + xkb_keysym_t sym, enum wlr_key_state key_state) { + struct compositor_state *state = keyboard->compositor; + struct sample_state *sample = state->data; + + struct wl_resource *res = NULL; + struct wlr_seat_handle *seat_handle = NULL; + wl_list_for_each(res, &sample->compositor.surfaces, link) { + break; + } + + if (res) { + seat_handle = wlr_seat_handle_for_client(sample->wl_seat, + wl_resource_get_client(res)); + } + + if (res != sample->focus && seat_handle && seat_handle->keyboard) { + struct wl_array keys; + wl_array_init(&keys); + wl_keyboard_send_enter(seat_handle->keyboard, ++sample->serial, res, &keys); + sample->focus = res; + } + + if (seat_handle && seat_handle->keyboard) { + uint32_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, + XKB_STATE_MODS_DEPRESSED); + uint32_t latched = xkb_state_serialize_mods(keyboard->xkb_state, + XKB_STATE_MODS_LATCHED); + uint32_t locked = xkb_state_serialize_mods(keyboard->xkb_state, + XKB_STATE_MODS_LOCKED); + uint32_t group = xkb_state_serialize_layout(keyboard->xkb_state, + XKB_STATE_LAYOUT_EFFECTIVE); + wl_keyboard_send_modifiers(seat_handle->keyboard, ++sample->serial, depressed, + latched, locked, group); + wl_keyboard_send_key(seat_handle->keyboard, ++sample->serial, 0, keycode, key_state); + } +} + +static void handle_keyboard_bound(struct wl_listener *listener, void *data) { + struct wlr_seat_handle *handle = data; + struct sample_state *state = wl_container_of(listener, state, keyboard_bound); + + wl_keyboard_send_keymap(handle->keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + state->keymap_fd, state->keymap_size); +} + int main() { struct sample_state state = { 0 }; struct compositor_state compositor = { 0, .data = &state, .output_frame_cb = handle_output_frame, + .keyboard_key_cb = handle_keyboard_key }; compositor_init(&compositor); @@ -92,8 +151,29 @@ int main() { state.wl_shell = wlr_wl_shell_create(compositor.display); state.xdg_shell = wlr_xdg_shell_v6_create(compositor.display); + state.wl_seat = wlr_seat_create(compositor.display, "seat0"); + state.keyboard_bound.notify = handle_keyboard_bound; + wl_signal_add(&state.wl_seat->events.keyboard_bound, &state.keyboard_bound); + wlr_seat_set_capabilities(state.wl_seat, WL_SEAT_CAPABILITY_KEYBOARD + | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); + + struct keyboard_state *kbstate; + wl_list_for_each(kbstate, &compositor.keyboards, link) { + char *keymap = xkb_keymap_get_as_string(kbstate->keymap, + XKB_KEYMAP_FORMAT_TEXT_V1); + state.keymap_size = strlen(keymap); + state.keymap_fd = os_create_anonymous_file(state.keymap_size); + void *ptr = mmap(NULL, state.keymap_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, state.keymap_fd, 0); + strcpy(ptr, keymap); + free(keymap); + break; + } + compositor_run(&compositor); wlr_wl_shell_destroy(state.wl_shell); wlr_xdg_shell_v6_destroy(state.xdg_shell); + close(state.keymap_fd); } |