wio

a wayland wm stylised after plan9 rio - forked from git.sr.ht/~srcmpwn/wio
git clone git://src.gearsix.net/wio
Log | Files | Refs | Atom | Submodules | README | LICENSE

commit 2e46c9d760a6541606eec145a2b9ba9e7af1b351
parent 4be707fd105b05c22fb0f8791c1a0728fea93739
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 10 Jan 2019 21:28:02 -0500

Add basic input rigging

Diffstat:
Minclude/server.h | 33+++++++++++++++++++++++++++++++++
Ainput.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmain.c | 32+++++++++++++++++++++++++++++++-
Mmeson.build | 7+++++--
Moutput.c | 3+--
5 files changed, 170 insertions(+), 5 deletions(-)

diff --git a/include/server.h b/include/server.h @@ -3,28 +3,61 @@ #include <wayland-server.h> #include <wlr/backend.h> #include <wlr/render/wlr_renderer.h> +#include <wlr/types/wlr_cursor.h> +#include <wlr/types/wlr_seat.h> +#include <wlr/types/wlr_keyboard.h> #include <wlr/types/wlr_output.h> +#include <wlr/types/wlr_output_layout.h> +#include <wlr/types/wlr_pointer.h> +#include <wlr/types/wlr_xcursor_manager.h> struct wio_server { struct wl_display *wl_display; struct wlr_backend *backend; + struct wlr_cursor *cursor; + struct wlr_output_layout *output_layout; struct wlr_renderer *renderer; + struct wlr_seat *seat; + struct wlr_xcursor_manager *cursor_mgr; struct wl_list outputs; + struct wl_list inputs; + struct wl_list pointers; + struct wl_list keyboards; struct wl_listener new_output; struct wl_listener new_input; + struct wl_listener cursor_motion; + struct wl_listener cursor_motion_absolute; + struct wl_listener cursor_button; + struct wl_listener cursor_axis; }; struct wio_output { struct wl_list link; + struct wio_server *server; struct wlr_output *wlr_output; struct wl_listener frame; }; +struct wio_keyboard { + struct wl_list link; + + struct wio_server *server; + struct wlr_input_device *device; + + struct wl_listener modifiers; + struct wl_listener key; +}; + void server_new_output(struct wl_listener *listener, void *data); +void server_new_input(struct wl_listener *listener, void *data); +void server_cursor_motion(struct wl_listener *listener, void *data); +void server_cursor_motion_absolute(struct wl_listener *listener, void *data); +void server_cursor_button(struct wl_listener *listener, void *data); +void server_cursor_axis(struct wl_listener *listener, void *data); #endif diff --git a/input.c b/input.c @@ -0,0 +1,100 @@ +#include <stdlib.h> +#include <wlr/types/wlr_cursor.h> +#include <wlr/types/wlr_seat.h> +#include <wlr/types/wlr_input_device.h> +#include <wlr/types/wlr_keyboard.h> +#include <wlr/types/wlr_pointer.h> +#include <xkbcommon/xkbcommon.h> +#include "server.h" + +static void server_new_keyboard( + struct wio_server *server, struct wlr_input_device *device) { + struct wio_keyboard *keyboard = calloc(1, sizeof(struct wio_keyboard)); + keyboard->server = server; + keyboard->device = device; + + struct xkb_rule_names rules = { 0 }; + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); + xkb_context_unref(context); + wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); + + //keyboard->modifiers.notify = keyboard_handle_modifiers; + //wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); + //keyboard->key.notify = keyboard_handle_key; + //wl_signal_add(&device->keyboard->events.key, &keyboard->key); + + wlr_seat_set_keyboard(server->seat, device); + wl_list_insert(&server->keyboards, &keyboard->link); +} + +static void server_new_pointer( + struct wio_server *server, struct wlr_input_device *device) { + wlr_cursor_attach_input_device(server->cursor, device); +} + +void server_new_input(struct wl_listener *listener, void *data) { + struct wio_server *server = wl_container_of(listener, server, new_input); + struct wlr_input_device *device = data; + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + server_new_keyboard(server, device); + break; + case WLR_INPUT_DEVICE_POINTER: + server_new_pointer(server, device); + break; + default: + break; + } + uint32_t caps = WL_SEAT_CAPABILITY_POINTER; + if (!wl_list_empty(&server->keyboards)) { + caps |= WL_SEAT_CAPABILITY_KEYBOARD; + } + wlr_seat_set_capabilities(server->seat, caps); +} + +static void process_cursor_motion(struct wio_server *server, uint32_t time) { + // TODO: Resize/move/passthrough/etc + wlr_xcursor_manager_set_cursor_image( + server->cursor_mgr, "left_ptr", server->cursor); +} + +void server_cursor_motion(struct wl_listener *listener, void *data) { + struct wio_server *server = + wl_container_of(listener, server, cursor_motion); + struct wlr_event_pointer_motion *event = data; + wlr_cursor_move(server->cursor, event->device, + event->delta_x, event->delta_y); + process_cursor_motion(server, event->time_msec); +} + +void server_cursor_motion_absolute( + struct wl_listener *listener, void *data) { + struct wio_server *server = + wl_container_of(listener, server, cursor_motion_absolute); + struct wlr_event_pointer_motion_absolute *event = data; + wlr_cursor_warp_absolute(server->cursor, event->device, event->x, event->y); + process_cursor_motion(server, event->time_msec); +} + +void server_cursor_button(struct wl_listener *listener, void *data) { + struct wio_server *server = + wl_container_of(listener, server, cursor_button); + struct wlr_event_pointer_button *event = data; + // TODO: Internal button processing (e.g. resize, menus, etc) + // TODO: Bring client under the cursor to the front when pressed + wlr_seat_pointer_notify_button(server->seat, + event->time_msec, event->button, event->state); +} + +void server_cursor_axis(struct wl_listener *listener, void *data) { + struct wio_server *server = wl_container_of(listener, server, cursor_axis); + struct wlr_event_pointer_axis *event = data; + wlr_seat_pointer_notify_axis(server->seat, + event->time_msec, event->orientation, event->delta, + event->delta_discrete, event->source); +} diff --git a/main.c b/main.c @@ -3,9 +3,11 @@ #include <time.h> #include <wayland-server.h> #include <wlr/backend.h> +#include <wlr/render/wlr_renderer.h> #include <wlr/types/wlr_compositor.h> #include <wlr/types/wlr_data_device.h> -#include <wlr/render/wlr_renderer.h> +#include <wlr/types/wlr_seat.h> +#include <wlr/types/wlr_xcursor_manager.h> #include <wlr/util/log.h> #include "server.h" @@ -26,6 +28,34 @@ int main(int argc, char **argv) { server.new_output.notify = server_new_output; wl_signal_add(&server.backend->events.new_output, &server.new_output); + server.output_layout = wlr_output_layout_create(); + + server.cursor = wlr_cursor_create(); + wlr_cursor_attach_output_layout(server.cursor, server.output_layout); + server.cursor_mgr = wlr_xcursor_manager_create(NULL, 24); + wlr_xcursor_manager_load(server.cursor_mgr, 1); + + server.cursor_motion.notify = server_cursor_motion; + wl_signal_add(&server.cursor->events.motion, &server.cursor_motion); + server.cursor_motion_absolute.notify = server_cursor_motion_absolute; + wl_signal_add(&server.cursor->events.motion_absolute, + &server.cursor_motion_absolute); + server.cursor_button.notify = server_cursor_button; + wl_signal_add(&server.cursor->events.button, &server.cursor_button); + server.cursor_axis.notify = server_cursor_axis; + wl_signal_add(&server.cursor->events.axis, &server.cursor_axis); + + wl_list_init(&server.inputs); + server.new_input.notify = server_new_input; + wl_signal_add(&server.backend->events.new_input, &server.new_input); + + server.seat = wlr_seat_create(server.wl_display, "seat0"); + //server.request_cursor.notify = seat_request_cursor; // TODO + //wl_signal_add(&server.seat->events.request_set_cursor, + // &server.request_cursor); + wl_list_init(&server.keyboards); + wl_list_init(&server.pointers); + const char *socket = wl_display_add_socket_auto(server.wl_display); if (!socket) { wlr_backend_destroy(server.backend); diff --git a/meson.build b/meson.build @@ -24,6 +24,7 @@ add_project_arguments( wlroots = dependency('wlroots', fallback: ['wlroots', 'wlroots']) wayland_server = dependency('wayland-server') wayland_protos = dependency('wayland-protocols') +xkbcommon = dependency('xkbcommon') wio_inc = include_directories('include') @@ -31,6 +32,7 @@ subdir('protocols') wio_sources = files( 'main.c', + 'input.c', 'output.c', ) @@ -39,9 +41,10 @@ executable( wio_sources, include_directories: [wio_inc], dependencies: [ - wlroots, - wayland_server, server_protos, + wayland_server, + wlroots, + xkbcommon, ], install: true ) diff --git a/output.c b/output.c @@ -46,7 +46,6 @@ void server_new_output(struct wl_listener *listener, void *data) { wl_signal_add(&wlr_output->events.frame, &output->frame); wl_list_insert(&server->outputs, &output->link); - // TODO - //wlr_output_layout_add_auto(server->output_layout, wlr_output); + wlr_output_layout_add_auto(server->output_layout, wlr_output); wlr_output_create_global(wlr_output); }