commit 2e46c9d760a6541606eec145a2b9ba9e7af1b351
parent 4be707fd105b05c22fb0f8791c1a0728fea93739
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 10 Jan 2019 21:28:02 -0500
Add basic input rigging
Diffstat:
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);
}