From 53021f8ed428a1a023769339e6162bfebbe4c7a2 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 2 Nov 2017 20:13:10 -0400 Subject: [PATCH 01/21] rootston: break up input.h --- include/rootston/input.h | 52 ---------------------------------- include/rootston/keyboard.h | 22 ++++++++++++++ include/rootston/pointer.h | 16 +++++++++++ include/rootston/tablet_tool.h | 20 +++++++++++++ include/rootston/touch.h | 22 ++++++++++++++ rootston/config.c | 1 + rootston/cursor.c | 4 +++ rootston/input.c | 4 +++ rootston/keyboard.c | 1 + rootston/pointer.c | 1 + rootston/tablet_tool.c | 1 + rootston/touch.c | 1 + 12 files changed, 93 insertions(+), 52 deletions(-) create mode 100644 include/rootston/keyboard.h create mode 100644 include/rootston/pointer.h create mode 100644 include/rootston/tablet_tool.h create mode 100644 include/rootston/touch.h diff --git a/include/rootston/input.h b/include/rootston/input.h index 20b73c8a..6d07de43 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -1,6 +1,5 @@ #ifndef _ROOTSTON_INPUT_H #define _ROOTSTON_INPUT_H -#include #include #include #include @@ -10,41 +9,6 @@ #include "rootston/view.h" #include "rootston/server.h" -#define ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP 32 - -struct roots_keyboard { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_listener key; - struct wl_listener modifiers; - struct wl_list link; - - xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; -}; - -struct roots_pointer { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -struct roots_touch { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -// TODO: tablet pad -struct roots_tablet_tool { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_listener axis; - struct wl_listener proximity; - struct wl_listener tip; - struct wl_listener button; - struct wl_list link; -}; - enum roots_cursor_mode { ROOTS_CURSOR_PASSTHROUGH = 0, ROOTS_CURSOR_MOVE = 1, @@ -77,13 +41,6 @@ struct roots_drag_icon { struct wl_listener surface_commit; }; -struct roots_touch_point { - struct roots_touch *device; - int32_t slot; - double x, y; - struct wl_list link; -}; - struct roots_input { struct roots_config *config; struct roots_server *server; @@ -138,15 +95,6 @@ struct roots_input *input_create(struct roots_server *server, struct roots_config *config); void input_destroy(struct roots_input *input); -void pointer_add(struct wlr_input_device *device, struct roots_input *input); -void pointer_remove(struct wlr_input_device *device, struct roots_input *input); -void keyboard_add(struct wlr_input_device *device, struct roots_input *input); -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); -void touch_add(struct wlr_input_device *device, struct roots_input *input); -void touch_remove(struct wlr_input_device *device, struct roots_input *input); -void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input); -void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input); - void cursor_initialize(struct roots_input *input); void cursor_load_config(struct roots_config *config, struct wlr_cursor *cursor, diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h new file mode 100644 index 00000000..33017b56 --- /dev/null +++ b/include/rootston/keyboard.h @@ -0,0 +1,22 @@ +#ifndef _ROOTSTON_KEYBOARD_H +#define _ROOTSTON_KEYBOARD_H + +#include +#include "rootston/input.h" + +#define ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP 32 + +struct roots_keyboard { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_listener key; + struct wl_listener modifiers; + struct wl_list link; + + xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; +}; + +void keyboard_add(struct wlr_input_device *device, struct roots_input *input); +void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/include/rootston/pointer.h b/include/rootston/pointer.h new file mode 100644 index 00000000..b3fc8c3a --- /dev/null +++ b/include/rootston/pointer.h @@ -0,0 +1,16 @@ +#ifndef _ROOTSTON_POINTER_H +#define _ROOTSTON_POINTER_H + +#include +#include + +struct roots_pointer { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_list link; +}; + +void pointer_add(struct wlr_input_device *device, struct roots_input *input); +void pointer_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/include/rootston/tablet_tool.h b/include/rootston/tablet_tool.h new file mode 100644 index 00000000..72ebf6d8 --- /dev/null +++ b/include/rootston/tablet_tool.h @@ -0,0 +1,20 @@ +#ifndef _ROOTSTON_TABLET_TOOL_H +#define _ROOTSTON_TABLET_TOOL_H + +#include +#include "rootston/input.h" + +struct roots_tablet_tool { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_listener axis; + struct wl_listener proximity; + struct wl_listener tip; + struct wl_listener button; + struct wl_list link; +}; + +void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input); +void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/include/rootston/touch.h b/include/rootston/touch.h new file mode 100644 index 00000000..1624c3ad --- /dev/null +++ b/include/rootston/touch.h @@ -0,0 +1,22 @@ +#ifndef _ROOTSTON_TOUCH_H +#define _ROOTSTON_TOUCH_H + +#include + +struct roots_touch { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_list link; +}; + +struct roots_touch_point { + struct roots_touch *device; + int32_t slot; + double x, y; + struct wl_list link; +}; + +void touch_add(struct wlr_input_device *device, struct roots_input *input); +void touch_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/rootston/config.c b/rootston/config.c index dc7a4b1d..a3ae78be 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -13,6 +13,7 @@ #include #include "rootston/config.h" #include "rootston/input.h" +#include "rootston/keyboard.h" #include "rootston/ini.h" static void usage(const char *name, int ret) { diff --git a/rootston/cursor.c b/rootston/cursor.c index 31001a9f..61dcae7a 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -18,6 +18,10 @@ #include "rootston/input.h" #include "rootston/desktop.h" #include "rootston/view.h" +#include "rootston/keyboard.h" +#include "rootston/pointer.h" +#include "rootston/tablet_tool.h" +#include "rootston/touch.h" const struct roots_input_event *get_input_event(struct roots_input *input, uint32_t serial) { diff --git a/rootston/input.c b/rootston/input.c index 5d367a5e..c8d46a69 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -8,6 +8,10 @@ #include "rootston/server.h" #include "rootston/config.h" #include "rootston/input.h" +#include "rootston/tablet_tool.h" +#include "rootston/keyboard.h" +#include "rootston/pointer.h" +#include "rootston/touch.h" static const char *device_type(enum wlr_input_device_type type) { switch (type) { diff --git a/rootston/keyboard.c b/rootston/keyboard.c index e174b731..9458a05c 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -10,6 +10,7 @@ #include #include #include "rootston/input.h" +#include "rootston/keyboard.h" static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, xkb_keysym_t keysym) { diff --git a/rootston/pointer.c b/rootston/pointer.c index 299ecdfc..cb099264 100644 --- a/rootston/pointer.c +++ b/rootston/pointer.c @@ -3,6 +3,7 @@ #include #include #include "rootston/input.h" +#include "rootston/pointer.h" void pointer_add(struct wlr_input_device *device, struct roots_input *input) { struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1); diff --git a/rootston/tablet_tool.c b/rootston/tablet_tool.c index a612e683..3327115d 100644 --- a/rootston/tablet_tool.c +++ b/rootston/tablet_tool.c @@ -4,6 +4,7 @@ #include #include #include "rootston/input.h" +#include "rootston/tablet_tool.h" void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input) { struct roots_tablet_tool *tool = calloc(sizeof(struct roots_tablet_tool), 1); diff --git a/rootston/touch.c b/rootston/touch.c index f6d9b11a..069853ab 100644 --- a/rootston/touch.c +++ b/rootston/touch.c @@ -3,6 +3,7 @@ #include #include #include "rootston/input.h" +#include "rootston/touch.h" // TODO: we'll likely want touch events to both control the cursor *and* be // submitted directly to the seat. From 447c561d1588226fd6aeb6668c7adb352cb77725 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 06:08:37 -0400 Subject: [PATCH 02/21] rootston: seat config by device --- include/rootston/config.h | 1 + rootston/config.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/include/rootston/config.h b/include/rootston/config.h index 75c04619..58fb1a1c 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -19,6 +19,7 @@ struct device_config { char *name; char *mapped_output; struct wlr_box *mapped_box; + char *seat; struct wl_list link; }; diff --git a/rootston/config.c b/rootston/config.c index a3ae78be..815040bf 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -289,6 +289,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, if (!found) { dc = calloc(1, sizeof(struct device_config)); dc->name = strdup(device_name); + dc->seat = strdup("seat0"); wl_list_insert(&config->devices, &dc->link); } @@ -298,6 +299,9 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else if (strcmp(name, "geometry") == 0) { free(dc->mapped_box); dc->mapped_box = parse_geometry(value); + } else if (strcmp(name, "seat") == 0) { + free(dc->seat); + dc->seat = strdup(value); } else { wlr_log(L_ERROR, "got unknown device config: %s", name); } @@ -387,6 +391,7 @@ void roots_config_destroy(struct roots_config *config) { struct device_config *dc, *dtmp = NULL; wl_list_for_each_safe(dc, dtmp, &config->devices, link) { free(dc->name); + free(dc->seat); free(dc->mapped_output); free(dc->mapped_box); free(dc); From 9bd0f47efd9a0c851d1715f3b9427b5f51b6d8a3 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 06:18:20 -0400 Subject: [PATCH 03/21] rootston: refactor keyboard --- include/rootston/keyboard.h | 10 ++++++++-- rootston/input.c | 4 ++-- rootston/keyboard.c | 35 ++++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 33017b56..f4acc0aa 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -16,7 +16,13 @@ struct roots_keyboard { xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; -void keyboard_add(struct wlr_input_device *device, struct roots_input *input); -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, + struct roots_input *input); +void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input); + +void roots_keyboard_handle_key(struct roots_keyboard *keyboard, + struct wlr_event_keyboard_key *event); + +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); #endif diff --git a/rootston/input.c b/rootston/input.c index c8d46a69..2f50c708 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -36,7 +36,7 @@ static void input_add_notify(struct wl_listener *listener, void *data) { device->vendor, device->product, device_type(device->type)); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - keyboard_add(device, input); + roots_keyboard_create(device, input); break; case WLR_INPUT_DEVICE_POINTER: pointer_add(device, input); @@ -57,7 +57,7 @@ static void input_remove_notify(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, input_remove); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - keyboard_remove(device, input); + roots_keyboard_destroy(device, input); break; case WLR_INPUT_DEVICE_POINTER: pointer_remove(device, input); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 9458a05c..ece95245 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -123,10 +123,8 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } -static void keyboard_key_notify(struct wl_listener *listener, void *data) { - struct wlr_event_keyboard_key *event = data; - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); - +void roots_keyboard_handle_key(struct roots_keyboard *keyboard, + struct wlr_event_keyboard_key *event) { uint32_t keycode = event->keycode + 8; const xkb_keysym_t *syms; int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, @@ -149,9 +147,13 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { } } -static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); +static void handle_keyboard_key(struct wl_listener *listener, void *data) { + struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); + struct wlr_event_keyboard_key *event = data; + roots_keyboard_handle_key(keyboard, event); +} + +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { struct wlr_seat *seat = r_keyboard->input->wl_seat; struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; wlr_seat_set_keyboard(seat, r_keyboard->device); @@ -160,7 +162,12 @@ static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) keyboard->modifiers.latched, keyboard->modifiers.locked, keyboard->modifiers.group); +} +static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { + struct roots_keyboard *r_keyboard = + wl_container_of(listener, r_keyboard, modifiers); + roots_keyboard_handle_modifiers(r_keyboard); } static void keyboard_config_merge(struct keyboard_config *config, @@ -185,19 +192,19 @@ static void keyboard_config_merge(struct keyboard_config *config, } } -void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); if (keyboard == NULL) { - return; + return NULL; } device->data = keyboard; keyboard->device = device; keyboard->input = input; - keyboard->key.notify = keyboard_key_notify; + keyboard->key.notify = handle_keyboard_key; wl_signal_add(&device->keyboard->events.key, &keyboard->key); - keyboard->modifiers.notify = keyboard_modifiers_notify; + keyboard->modifiers.notify = handle_keyboard_modifiers; wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); wl_list_insert(&input->keyboards, &keyboard->link); @@ -226,14 +233,16 @@ void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (context == NULL) { wlr_log(L_ERROR, "Cannot create XKB context"); - return; + return NULL; } wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); xkb_context_unref(context); + + return keyboard; } -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input) { +void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; wl_list_remove(&keyboard->key.link); wl_list_remove(&keyboard->modifiers.link); From 5354fe8729b8c52f8f3ff63f23f932c49bf8c880 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 09:01:34 -0400 Subject: [PATCH 04/21] move keyboard to seat --- backend/libinput/keyboard.c | 1 + backend/wayland/wl_seat.c | 12 ++++- backend/x11/backend.c | 1 + include/rootston/input.h | 1 + include/rootston/keyboard.h | 15 ++++-- include/rootston/seat.h | 26 +++++++++++ include/wlr/interfaces/wlr_keyboard.h | 3 +- include/wlr/types/wlr_keyboard.h | 11 +++++ rootston/input.c | 33 +++++++++++++- rootston/keyboard.c | 38 +++++---------- rootston/meson.build | 1 + rootston/seat.c | 66 +++++++++++++++++++++++++++ types/wlr_keyboard.c | 11 ++--- 13 files changed, 176 insertions(+), 43 deletions(-) create mode 100644 include/rootston/seat.h create mode 100644 rootston/seat.c diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 065d8ead..9a24c791 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -54,6 +54,7 @@ void handle_keyboard_key(struct libinput_event *event, struct libinput_event_keyboard *kbevent = libinput_event_get_keyboard_event(event); struct wlr_event_keyboard_key wlr_event = { 0 }; + wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent)); wlr_event.keycode = libinput_event_keyboard_get_key(kbevent); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index deed215e..146296ae 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -151,6 +151,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, assert(dev && dev->keyboard); struct wlr_event_keyboard_key wlr_event; + wlr_event.device = dev; wlr_event.keycode = key; wlr_event.state = state; wlr_event.time_msec = time; @@ -162,8 +163,15 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar uint32_t mods_locked, uint32_t group) { struct wlr_input_device *dev = data; assert(dev && dev->keyboard); - wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, - mods_locked, group); + struct wlr_event_keyboard_modifiers wlr_event; + wlr_event.device = dev; + wlr_event.keyboard = dev->keyboard; + wlr_event.mods_depressed = mods_depressed; + wlr_event.mods_latched = mods_latched; + wlr_event.mods_locked = mods_locked; + wlr_event.group = group; + + wlr_keyboard_notify_modifiers(dev->keyboard, &wlr_event); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 97b0dd8c..f76b314e 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -50,6 +50,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e case XCB_KEY_RELEASE: { xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; struct wlr_event_keyboard_key key = { + .device = &x11->keyboard_dev, .time_msec = ev->time, .keycode = ev->detail - 8, .state = event->response_type == XCB_KEY_PRESS ? diff --git a/include/rootston/input.h b/include/rootston/input.h index 6d07de43..7b1358f8 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -67,6 +67,7 @@ struct roots_input { struct wl_list pointers; struct wl_list touch; struct wl_list tablet_tools; + struct wl_list seats; struct wl_listener input_add; struct wl_listener input_remove; diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index f4acc0aa..cb639ba1 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -8,21 +8,28 @@ struct roots_keyboard { struct roots_input *input; + struct roots_seat *seat; struct wlr_input_device *device; - struct wl_listener key; - struct wl_listener modifiers; + struct wl_list seat_link; + // XXX temporary struct wl_list link; + struct wl_listener keyboard_key; + struct wl_listener keyboard_modifiers; + xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input); -void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input); + +void roots_keyboard_destroy(struct wlr_input_device *device, + struct roots_input *input); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, + struct wlr_event_keyboard_modifiers *event); #endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h new file mode 100644 index 00000000..f6db63cc --- /dev/null +++ b/include/rootston/seat.h @@ -0,0 +1,26 @@ +#ifndef _ROOTSTON_SEAT_H +#define _ROOTSTON_SEAT_H + +#include + +#include "rootston/input.h" +#include "rootston/keyboard.h" + +struct roots_seat { + struct roots_input *input; + struct wlr_seat *seat; + struct wl_list keyboards; + struct wl_list link; +}; + +struct roots_seat *roots_seat_create(struct roots_input *input, char *name); + +void roots_seat_destroy(struct roots_seat *seat); + +void roots_seat_add_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard); + +void roots_seat_remove_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard); + +#endif diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 570f5721..5848416d 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -14,7 +14,6 @@ void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); + struct wlr_event_keyboard_modifiers *event); #endif diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index af837ff5..c42cea9c 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -63,12 +63,23 @@ enum wlr_key_state { }; struct wlr_event_keyboard_key { + struct wlr_input_device *device; + struct wlr_keyboard *keyboard; uint32_t time_msec; uint32_t keycode; bool update_state; enum wlr_key_state state; }; +struct wlr_event_keyboard_modifiers { + struct wlr_input_device *device; + struct wlr_keyboard *keyboard; + uint32_t mods_depressed; + uint32_t mods_latched; + uint32_t mods_locked; + uint32_t group; +}; + void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); diff --git a/rootston/input.c b/rootston/input.c index 2f50c708..51a64720 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -12,6 +12,7 @@ #include "rootston/keyboard.h" #include "rootston/pointer.h" #include "rootston/touch.h" +#include "rootston/seat.h" static const char *device_type(enum wlr_input_device_type type) { switch (type) { @@ -29,15 +30,42 @@ static const char *device_type(enum wlr_input_device_type type) { return NULL; } +static struct roots_seat *input_get_seat(struct roots_input *input, char *name) { + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &input->seats, link) { + if (strcmp(seat->seat->name, name) == 0) { + return seat; + } + } + + seat = roots_seat_create(input, name); + return seat; +} + static void input_add_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; struct roots_input *input = wl_container_of(listener, input, input_add); + + char *seat_name = "seat0"; + struct device_config *dc = config_get_device(input->config, device); + if (dc) { + seat_name = dc->seat; + } + + struct roots_seat *seat = input_get_seat(input, seat_name); + if (!seat) { + wlr_log(L_ERROR, "could not create roots seat"); + return; + } + wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s", device->name, device->vendor, device->product, device_type(device->type)); switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - roots_keyboard_create(device, input); + case WLR_INPUT_DEVICE_KEYBOARD: { + struct roots_keyboard *keyboard = roots_keyboard_create(device, input); + roots_seat_add_keyboard(seat, keyboard); break; + } case WLR_INPUT_DEVICE_POINTER: pointer_add(device, input); break; @@ -123,6 +151,7 @@ struct roots_input *input_create(struct roots_server *server, wl_list_init(&input->pointers); wl_list_init(&input->touch); wl_list_init(&input->tablet_tools); + wl_list_init(&input->seats); input->input_add.notify = input_add_notify; wl_signal_add(&server->backend->events.input_add, &input->input_add); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index ece95245..0865f551 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -10,6 +10,7 @@ #include #include #include "rootston/input.h" +#include "rootston/seat.h" #include "rootston/keyboard.h" static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, @@ -85,8 +86,8 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, } if (keysym == XKB_KEY_Escape) { - wlr_seat_pointer_end_grab(keyboard->input->wl_seat); - wlr_seat_keyboard_end_grab(keyboard->input->wl_seat); + wlr_seat_pointer_end_grab(keyboard->seat->seat); + wlr_seat_keyboard_end_grab(keyboard->seat->seat); } uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); @@ -141,20 +142,15 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, } if (!handled) { - wlr_seat_set_keyboard(keyboard->input->wl_seat, keyboard->device); - wlr_seat_keyboard_notify_key(keyboard->input->wl_seat, event->time_msec, + wlr_seat_set_keyboard(keyboard->seat->seat, keyboard->device); + wlr_seat_keyboard_notify_key(keyboard->seat->seat, event->time_msec, event->keycode, event->state); } } -static void handle_keyboard_key(struct wl_listener *listener, void *data) { - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); - struct wlr_event_keyboard_key *event = data; - roots_keyboard_handle_key(keyboard, event); -} - -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { - struct wlr_seat *seat = r_keyboard->input->wl_seat; +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, + struct wlr_event_keyboard_modifiers *event) { + struct wlr_seat *seat = r_keyboard->seat->seat; struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; wlr_seat_set_keyboard(seat, r_keyboard->device); wlr_seat_keyboard_notify_modifiers(seat, @@ -164,12 +160,6 @@ void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { keyboard->modifiers.group); } -static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); - roots_keyboard_handle_modifiers(r_keyboard); -} - static void keyboard_config_merge(struct keyboard_config *config, struct keyboard_config *fallback) { if (fallback == NULL) { @@ -192,7 +182,8 @@ static void keyboard_config_merge(struct keyboard_config *config, } } -struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input) { +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, + struct roots_input *input) { struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); if (keyboard == NULL) { return NULL; @@ -201,12 +192,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, st keyboard->device = device; keyboard->input = input; - keyboard->key.notify = handle_keyboard_key; - wl_signal_add(&device->keyboard->events.key, &keyboard->key); - - keyboard->modifiers.notify = handle_keyboard_modifiers; - wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); - + // XXX temporary wl_list_insert(&input->keyboards, &keyboard->link); struct keyboard_config config; @@ -244,8 +230,6 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, st void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; - wl_list_remove(&keyboard->key.link); - wl_list_remove(&keyboard->modifiers.link); wl_list_remove(&keyboard->link); free(keyboard); } diff --git a/rootston/meson.build b/rootston/meson.build index d84422d8..0367e43f 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -8,6 +8,7 @@ sources = [ 'main.c', 'output.c', 'pointer.c', + 'seat.c', 'tablet_tool.c', 'touch.c', 'xcursor.c', diff --git a/rootston/seat.c b/rootston/seat.c new file mode 100644 index 00000000..2103e0d2 --- /dev/null +++ b/rootston/seat.c @@ -0,0 +1,66 @@ +#include +#include + +#include "rootston/input.h" +#include "rootston/seat.h" +#include "rootston/keyboard.h" + +static void handle_keyboard_key(struct wl_listener *listener, void *data) { + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, keyboard_key); + struct wlr_event_keyboard_key *event = data; + roots_keyboard_handle_key(keyboard, event); +} + +static void handle_keyboard_modifiers(struct wl_listener *listener, + void *data) { + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, keyboard_modifiers); + struct wlr_event_keyboard_modifiers *event = data; + roots_keyboard_handle_modifiers(keyboard, event); +} + +struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { + struct roots_seat *seat = calloc(1, sizeof(struct roots_seat)); + if (!seat) { + return NULL; + } + + seat->seat = wlr_seat_create(input->server->wl_display, name); + wlr_seat_set_capabilities(seat->seat, + WL_SEAT_CAPABILITY_KEYBOARD | + WL_SEAT_CAPABILITY_POINTER | + WL_SEAT_CAPABILITY_TOUCH); + seat->input = input; + wl_list_insert(&input->seats, &seat->link); + wl_list_init(&seat->keyboards); + + return seat; +} + +void roots_seat_destroy(struct roots_seat *seat) { + // TODO +} + +void roots_seat_add_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard) { + if (keyboard->seat) { + roots_seat_remove_keyboard(keyboard->seat, keyboard); + } + keyboard->seat = seat; + wl_list_insert(&seat->keyboards, &keyboard->seat_link); + + keyboard->keyboard_key.notify = handle_keyboard_key; + wl_signal_add(&keyboard->device->keyboard->events.key, + &keyboard->keyboard_key); + + keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; + wl_signal_add(&keyboard->device->keyboard->events.modifiers, + &keyboard->keyboard_modifiers); +} + +void roots_seat_remove_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard) { + // TODO +} + diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index c27264ef..c2fd9e0c 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -41,19 +41,18 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { keyboard->modifiers.latched = latched; keyboard->modifiers.locked = locked; keyboard->modifiers.group = group; - - wl_signal_emit(&keyboard->events.modifiers, keyboard); } void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { + struct wlr_event_keyboard_modifiers *event) { if (!keyboard->xkb_state) { return; } - xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, - mods_locked, 0, 0, group); + xkb_state_update_mask(keyboard->xkb_state, event->mods_depressed, + event->mods_latched, event->mods_locked, 0, 0, event->group); keyboard_modifier_update(keyboard); + + wl_signal_emit(&keyboard->events.modifiers, event); } void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, From 704f0f158a669689b78311cde35a736057f983b4 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 4 Nov 2017 13:12:35 -0400 Subject: [PATCH 05/21] rootston: move device init to seat --- include/rootston/pointer.h | 16 --- include/rootston/seat.h | 54 +++++++- include/rootston/tablet_tool.h | 20 --- include/rootston/touch.h | 22 --- rootston/cursor.c | 4 +- rootston/input.c | 44 +----- rootston/meson.build | 3 - rootston/pointer.c | 24 ---- rootston/seat.c | 241 ++++++++++++++++++++++++++++++++- rootston/tablet_tool.c | 25 ---- rootston/touch.c | 27 ---- 11 files changed, 292 insertions(+), 188 deletions(-) delete mode 100644 include/rootston/pointer.h delete mode 100644 include/rootston/tablet_tool.h delete mode 100644 include/rootston/touch.h delete mode 100644 rootston/pointer.c delete mode 100644 rootston/tablet_tool.c delete mode 100644 rootston/touch.c diff --git a/include/rootston/pointer.h b/include/rootston/pointer.h deleted file mode 100644 index b3fc8c3a..00000000 --- a/include/rootston/pointer.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _ROOTSTON_POINTER_H -#define _ROOTSTON_POINTER_H - -#include -#include - -struct roots_pointer { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -void pointer_add(struct wlr_input_device *device, struct roots_input *input); -void pointer_remove(struct wlr_input_device *device, struct roots_input *input); - -#endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h index f6db63cc..e4130e5a 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -9,7 +9,53 @@ struct roots_seat { struct roots_input *input; struct wlr_seat *seat; + struct wlr_cursor *cursor; + struct wl_list link; + struct wl_list keyboards; + struct wl_list pointers; + struct wl_list touch; + struct wl_list tablet_tools; + + struct wl_listener cursor_motion; + struct wl_listener cursor_motion_absolute; + struct wl_listener cursor_button; + struct wl_listener cursor_axis; + + struct wl_listener cursor_touch_down; + struct wl_listener cursor_touch_up; + struct wl_listener cursor_touch_motion; + + struct wl_listener cursor_tool_axis; + struct wl_listener cursor_tool_tip; +}; + +struct roots_pointer { + struct roots_seat *seat; + struct wlr_input_device *device; + struct wl_list link; +}; + +struct roots_touch { + struct roots_seat *seat; + struct wlr_input_device *device; + struct wl_list link; +}; + +struct roots_touch_point { + struct roots_touch *device; + int32_t slot; + double x, y; + struct wl_list link; +}; + +struct roots_tablet_tool { + struct roots_seat *seat; + struct wlr_input_device *device; + struct wl_listener axis; + struct wl_listener proximity; + struct wl_listener tip; + struct wl_listener button; struct wl_list link; }; @@ -17,10 +63,10 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name); void roots_seat_destroy(struct roots_seat *seat); -void roots_seat_add_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard); +void roots_seat_add_device(struct roots_seat *seat, + struct wlr_input_device *device); -void roots_seat_remove_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard); +void roots_seat_remove_device(struct roots_seat *seat, + struct wlr_input_device *device); #endif diff --git a/include/rootston/tablet_tool.h b/include/rootston/tablet_tool.h deleted file mode 100644 index 72ebf6d8..00000000 --- a/include/rootston/tablet_tool.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _ROOTSTON_TABLET_TOOL_H -#define _ROOTSTON_TABLET_TOOL_H - -#include -#include "rootston/input.h" - -struct roots_tablet_tool { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_listener axis; - struct wl_listener proximity; - struct wl_listener tip; - struct wl_listener button; - struct wl_list link; -}; - -void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input); -void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input); - -#endif diff --git a/include/rootston/touch.h b/include/rootston/touch.h deleted file mode 100644 index 1624c3ad..00000000 --- a/include/rootston/touch.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _ROOTSTON_TOUCH_H -#define _ROOTSTON_TOUCH_H - -#include - -struct roots_touch { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -struct roots_touch_point { - struct roots_touch *device; - int32_t slot; - double x, y; - struct wl_list link; -}; - -void touch_add(struct wlr_input_device *device, struct roots_input *input); -void touch_remove(struct wlr_input_device *device, struct roots_input *input); - -#endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 61dcae7a..9028c5bb 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -19,9 +19,7 @@ #include "rootston/desktop.h" #include "rootston/view.h" #include "rootston/keyboard.h" -#include "rootston/pointer.h" -#include "rootston/tablet_tool.h" -#include "rootston/touch.h" +#include "rootston/seat.h" const struct roots_input_event *get_input_event(struct roots_input *input, uint32_t serial) { diff --git a/rootston/input.c b/rootston/input.c index 51a64720..4a567763 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -8,10 +8,7 @@ #include "rootston/server.h" #include "rootston/config.h" #include "rootston/input.h" -#include "rootston/tablet_tool.h" #include "rootston/keyboard.h" -#include "rootston/pointer.h" -#include "rootston/touch.h" #include "rootston/seat.h" static const char *device_type(enum wlr_input_device_type type) { @@ -60,44 +57,17 @@ static void input_add_notify(struct wl_listener *listener, void *data) { wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s", device->name, device->vendor, device->product, device_type(device->type)); - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: { - struct roots_keyboard *keyboard = roots_keyboard_create(device, input); - roots_seat_add_keyboard(seat, keyboard); - break; - } - case WLR_INPUT_DEVICE_POINTER: - pointer_add(device, input); - break; - case WLR_INPUT_DEVICE_TOUCH: - touch_add(device, input); - break; - case WLR_INPUT_DEVICE_TABLET_TOOL: - tablet_tool_add(device, input); - break; - default: - break; - } + + roots_seat_add_device(seat, device); } static void input_remove_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; - struct roots_input *input = wl_container_of(listener, input, input_remove); - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - roots_keyboard_destroy(device, input); - break; - case WLR_INPUT_DEVICE_POINTER: - pointer_remove(device, input); - break; - case WLR_INPUT_DEVICE_TOUCH: - touch_remove(device, input); - break; - case WLR_INPUT_DEVICE_TABLET_TOOL: - tablet_tool_remove(device, input); - break; - default: - break; + struct roots_input *input = wl_container_of(listener, input, input_add); + + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_remove_device(seat, device); } } diff --git a/rootston/meson.build b/rootston/meson.build index 0367e43f..9c543c4f 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -7,10 +7,7 @@ sources = [ 'keyboard.c', 'main.c', 'output.c', - 'pointer.c', 'seat.c', - 'tablet_tool.c', - 'touch.c', 'xcursor.c', 'xdg_shell_v6.c', 'wl_shell.c', diff --git a/rootston/pointer.c b/rootston/pointer.c deleted file mode 100644 index cb099264..00000000 --- a/rootston/pointer.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include "rootston/input.h" -#include "rootston/pointer.h" - -void pointer_add(struct wlr_input_device *device, struct roots_input *input) { - struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1); - device->data = pointer; - pointer->device = device; - pointer->input = input; - wl_list_insert(&input->pointers, &pointer->link); - wlr_cursor_attach_input_device(input->cursor, device); - cursor_load_config(input->server->config, input->cursor, - input, input->server->desktop); -} - -void pointer_remove(struct wlr_input_device *device, struct roots_input *input) { - struct roots_pointer *pointer = device->data; - wlr_cursor_detach_input_device(input->cursor, device); - wl_list_remove(&pointer->link); - free(pointer); -} diff --git a/rootston/seat.c b/rootston/seat.c index 2103e0d2..c8f689bc 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1,5 +1,8 @@ #include #include +#include + +#include #include "rootston/input.h" #include "rootston/seat.h" @@ -20,18 +23,175 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, roots_keyboard_handle_modifiers(keyboard, event); } +static void handle_cursor_motion(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_cursor_button(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_cursor_axis(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_touch_down(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_touch_up(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_touch_motion(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_tool_axis(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_tool_tip(struct wl_listener *listener, void *data) { + // TODO +} + +static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { + struct wlr_cursor *cursor = seat->cursor; + struct roots_config *config = seat->input->config; + + wlr_cursor_map_input_to_output(cursor, device, NULL); + struct device_config *dconfig; + if ((dconfig = config_get_device(config, device))) { + wlr_cursor_map_input_to_region(cursor, device, dconfig->mapped_box); + } +} + +static void seat_set_device_output_mappings(struct roots_seat *seat, + struct wlr_input_device *device, struct wlr_output *output) { + struct wlr_cursor *cursor = seat->cursor; + struct roots_config *config = seat->input->config; + struct device_config *dconfig; + dconfig = config_get_device(config, device); + if (dconfig && dconfig->mapped_output && + strcmp(dconfig->mapped_output, output->name) == 0) { + wlr_cursor_map_input_to_output(cursor, device, output); + } +} + +static void roots_seat_configure_cursor(struct roots_seat *seat) { + struct roots_config *config = seat->input->config; + struct roots_desktop *desktop = seat->input->server->desktop; + struct wlr_cursor *cursor = seat->cursor; + + struct roots_pointer *pointer; + struct roots_touch *touch; + struct roots_tablet_tool *tablet_tool; + struct roots_output *output; + + // reset mappings + wlr_cursor_map_to_output(cursor, NULL); + wl_list_for_each(pointer, &seat->pointers, link) { + seat_reset_device_mappings(seat, pointer->device); + } + wl_list_for_each(touch, &seat->touch, link) { + seat_reset_device_mappings(seat, touch->device); + } + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + seat_reset_device_mappings(seat, tablet_tool->device); + } + + // configure device to output mappings + const char *mapped_output = config->cursor.mapped_output; + wl_list_for_each(output, &desktop->outputs, link) { + if (mapped_output && strcmp(mapped_output, output->wlr_output->name) == 0) { + wlr_cursor_map_to_output(cursor, output->wlr_output); + } + + wl_list_for_each(pointer, &seat->pointers, link) { + seat_set_device_output_mappings(seat, pointer->device, output->wlr_output); + } + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + seat_set_device_output_mappings(seat, tablet_tool->device, output->wlr_output); + } + wl_list_for_each(touch, &seat->touch, link) { + seat_set_device_output_mappings(seat, touch->device, output->wlr_output); + } + } +} + +static void roots_seat_init_cursor(struct roots_seat *seat) { + struct wlr_cursor *cursor = wlr_cursor_create(); + if (!cursor) { + return; + } + seat->cursor = cursor; + + // add output layout and configure + struct roots_desktop *desktop = seat->input->server->desktop; + wlr_cursor_attach_output_layout(cursor, desktop->layout); + roots_seat_configure_cursor(seat); + // TODO configure cursor by seat + + // add input signals + wl_signal_add(&cursor->events.motion, &seat->cursor_motion); + seat->cursor_motion.notify = handle_cursor_motion; + + wl_signal_add(&cursor->events.motion_absolute, + &seat->cursor_motion_absolute); + seat->cursor_motion_absolute.notify = handle_cursor_motion_absolute; + + wl_signal_add(&cursor->events.button, &seat->cursor_button); + seat->cursor_button.notify = handle_cursor_button; + + wl_signal_add(&cursor->events.axis, &seat->cursor_axis); + seat->cursor_axis.notify = handle_cursor_axis; + + wl_signal_add(&cursor->events.touch_down, &seat->cursor_touch_down); + seat->cursor_touch_down.notify = handle_touch_down; + + wl_signal_add(&cursor->events.touch_up, &seat->cursor_touch_up); + seat->cursor_touch_up.notify = handle_touch_up; + + wl_signal_add(&cursor->events.touch_motion, &seat->cursor_touch_motion); + seat->cursor_touch_motion.notify = handle_touch_motion; + + wl_signal_add(&cursor->events.tablet_tool_axis, &seat->cursor_tool_axis); + seat->cursor_tool_axis.notify = handle_tool_axis; + + wl_signal_add(&cursor->events.tablet_tool_tip, &seat->cursor_tool_tip); + seat->cursor_tool_tip.notify = handle_tool_tip; +} + struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { struct roots_seat *seat = calloc(1, sizeof(struct roots_seat)); if (!seat) { return NULL; } + roots_seat_init_cursor(seat); + if (!seat->cursor) { + free(seat); + return NULL; + } + seat->seat = wlr_seat_create(input->server->wl_display, name); + if (!seat->seat) { + free(seat); + wlr_cursor_destroy(seat->cursor); + return NULL; + } + wlr_seat_set_capabilities(seat->seat, WL_SEAT_CAPABILITY_KEYBOARD | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); + seat->input = input; + wl_list_insert(&input->seats, &seat->link); wl_list_init(&seat->keyboards); @@ -42,12 +202,10 @@ void roots_seat_destroy(struct roots_seat *seat) { // TODO } -void roots_seat_add_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard) { - if (keyboard->seat) { - roots_seat_remove_keyboard(keyboard->seat, keyboard); - } +static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; + wl_list_insert(&seat->keyboards, &keyboard->seat_link); keyboard->keyboard_key.notify = handle_keyboard_key; @@ -59,8 +217,77 @@ void roots_seat_add_keyboard(struct roots_seat *seat, &keyboard->keyboard_modifiers); } -void roots_seat_remove_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard) { +static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1); + if (!pointer) { + wlr_log(L_ERROR, "could not allocate pointer for seat"); + return; + } + + device->data = pointer; + pointer->device = device; + pointer->seat = seat; + wl_list_insert(&seat->pointers, &pointer->link); + wlr_cursor_attach_input_device(seat->cursor, device); + roots_seat_configure_cursor(seat); +} + +static void seat_add_touch(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_touch *touch = calloc(sizeof(struct roots_touch), 1); + if (!touch) { + wlr_log(L_ERROR, "could not allocate touch for seat"); + return; + } + + device->data = touch; + touch->device = device; + touch->seat = seat; + wl_list_insert(&seat->touch, &touch->link); + wlr_cursor_attach_input_device(seat->cursor, device); + roots_seat_configure_cursor(seat); +} + +static void seat_add_tablet_pad(struct roots_seat *seat, struct wlr_input_device *device) { // TODO } +static void seat_add_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_tablet_tool *tablet_tool = calloc(sizeof(struct roots_tablet_tool), 1); + if (!tablet_tool) { + wlr_log(L_ERROR, "could not allocate tablet_tool for seat"); + return; + } + + device->data = tablet_tool; + tablet_tool->device = device; + tablet_tool->seat = seat; + wl_list_insert(&seat->tablet_tools, &tablet_tool->link); + wlr_cursor_attach_input_device(seat->cursor, device); + roots_seat_configure_cursor(seat); +} + +void roots_seat_add_device(struct roots_seat *seat, + struct wlr_input_device *device) { + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + seat_add_keyboard(seat, device); + break; + case WLR_INPUT_DEVICE_POINTER: + seat_add_pointer(seat, device); + break; + case WLR_INPUT_DEVICE_TOUCH: + seat_add_touch(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_PAD: + seat_add_tablet_pad(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_TOOL: + seat_add_tablet_tool(seat, device); + break; + } +} + +void roots_seat_remove_device(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} diff --git a/rootston/tablet_tool.c b/rootston/tablet_tool.c deleted file mode 100644 index 3327115d..00000000 --- a/rootston/tablet_tool.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include -#include -#include "rootston/input.h" -#include "rootston/tablet_tool.h" - -void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input) { - struct roots_tablet_tool *tool = calloc(sizeof(struct roots_tablet_tool), 1); - device->data = tool; - tool->device = device; - tool->input = input; - wl_list_insert(&input->tablet_tools, &tool->link); - wlr_cursor_attach_input_device(input->cursor, device); - cursor_load_config(input->server->config, input->cursor, - input, input->server->desktop); -} - -void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input) { - struct roots_tablet_tool *tablet_tool = device->data; - wlr_cursor_detach_input_device(input->cursor, device); - wl_list_remove(&tablet_tool->link); - free(tablet_tool); -} diff --git a/rootston/touch.c b/rootston/touch.c deleted file mode 100644 index 069853ab..00000000 --- a/rootston/touch.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include "rootston/input.h" -#include "rootston/touch.h" - -// TODO: we'll likely want touch events to both control the cursor *and* be -// submitted directly to the seat. - -void touch_add(struct wlr_input_device *device, struct roots_input *input) { - struct roots_touch *touch = calloc(sizeof(struct roots_touch), 1); - device->data = touch; - touch->device = device; - touch->input = input; - wl_list_insert(&input->touch, &touch->link); - wlr_cursor_attach_input_device(input->cursor, device); - cursor_load_config(input->server->config, input->cursor, - input, input->server->desktop); -} - -void touch_remove(struct wlr_input_device *device, struct roots_input *input) { - struct roots_touch *touch = device->data; - wlr_cursor_detach_input_device(input->cursor, device); - wl_list_remove(&touch->link); - free(touch); -} From 2280928bb2859b8a5e71e81b99a396ff7a3f9efa Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 5 Nov 2017 09:20:11 -0500 Subject: [PATCH 06/21] rootston: roots_cursor --- include/rootston/cursor.h | 54 +++++++++++++++++ include/rootston/seat.h | 14 +---- rootston/meson.build | 1 + rootston/roots_cursor.c | 65 +++++++++++++++++++++ rootston/seat.c | 118 +++++++++++++++++++++++--------------- 5 files changed, 194 insertions(+), 58 deletions(-) create mode 100644 include/rootston/cursor.h create mode 100644 rootston/roots_cursor.c diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h new file mode 100644 index 00000000..8a8d33f2 --- /dev/null +++ b/include/rootston/cursor.h @@ -0,0 +1,54 @@ +#ifndef _ROOTSTON_CURSOR_H +#define _ROOTSTON_CURSOR_H + +#include "rootston/seat.h" + +struct roots_cursor { + struct roots_seat *seat; + struct wlr_cursor *cursor; + + struct wl_listener motion; + struct wl_listener motion_absolute; + struct wl_listener button; + struct wl_listener axis; + + struct wl_listener touch_down; + struct wl_listener touch_up; + struct wl_listener touch_motion; + + struct wl_listener tool_axis; + struct wl_listener tool_tip; +}; + +struct roots_cursor *roots_cursor_create(struct roots_seat *seat); + +void roots_cursor_destroy(struct roots_cursor *cursor); + +void roots_cursor_handle_motion(struct roots_cursor *cursor, + struct wlr_event_pointer_motion *event); + +void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, + struct wlr_event_pointer_motion_absolute *event); + +void roots_cursor_handle_button(struct roots_cursor *cursor, + struct wlr_event_pointer_button *event); + +void roots_cursor_handle_axis(struct roots_cursor *cursor, + struct wlr_event_pointer_axis *event); + +void roots_cursor_handle_touch_down(struct roots_cursor *cursor, + struct wlr_event_touch_down *event); + +void roots_cursor_handle_touch_up(struct roots_cursor *cursor, + struct wlr_event_touch_up *event); + +void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, + struct wlr_event_touch_motion *event); + +void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_axis *event); + +void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_tip *event); + +#endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h index e4130e5a..b7c8b477 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -9,25 +9,13 @@ struct roots_seat { struct roots_input *input; struct wlr_seat *seat; - struct wlr_cursor *cursor; + struct roots_cursor *cursor; struct wl_list link; struct wl_list keyboards; struct wl_list pointers; struct wl_list touch; struct wl_list tablet_tools; - - struct wl_listener cursor_motion; - struct wl_listener cursor_motion_absolute; - struct wl_listener cursor_button; - struct wl_listener cursor_axis; - - struct wl_listener cursor_touch_down; - struct wl_listener cursor_touch_up; - struct wl_listener cursor_touch_motion; - - struct wl_listener cursor_tool_axis; - struct wl_listener cursor_tool_tip; }; struct roots_pointer { diff --git a/rootston/meson.build b/rootston/meson.build index 9c543c4f..baed5330 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,6 +1,7 @@ sources = [ 'config.c', 'cursor.c', + 'roots_cursor.c', 'desktop.c', 'ini.c', 'input.c', diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c new file mode 100644 index 00000000..72eff996 --- /dev/null +++ b/rootston/roots_cursor.c @@ -0,0 +1,65 @@ +#include +#include +#include "rootston/cursor.h" + +struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { + struct roots_cursor *cursor = calloc(1, sizeof(struct roots_cursor)); + if (!cursor) { + return NULL; + } + cursor->cursor = wlr_cursor_create(); + if (!cursor->cursor) { + return NULL; + } + + return cursor; +} + +void roots_cursor_destroy(struct roots_cursor *cursor) { + // TODO +} + +void roots_cursor_handle_motion(struct roots_cursor *cursor, + struct wlr_event_pointer_motion *event) { + wlr_log(L_DEBUG, "TODO: cursor handle motion"); +} + +void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, + struct wlr_event_pointer_motion_absolute *event) { + wlr_log(L_DEBUG, "TODO: cursor handle motion absolute"); +} + +void roots_cursor_handle_button(struct roots_cursor *cursor, + struct wlr_event_pointer_button *event) { + wlr_log(L_DEBUG, "TODO: cursor handle button"); +} + +void roots_cursor_handle_axis(struct roots_cursor *cursor, + struct wlr_event_pointer_axis *event) { + wlr_log(L_DEBUG, "TODO: cursor handle axis"); +} + +void roots_cursor_handle_touch_down(struct roots_cursor *cursor, + struct wlr_event_touch_down *event) { + wlr_log(L_DEBUG, "TODO: cursor handle touch down"); +} + +void roots_cursor_handle_touch_up(struct roots_cursor *cursor, + struct wlr_event_touch_up *event) { + wlr_log(L_DEBUG, "TODO: cursor handle touch up"); +} + +void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, + struct wlr_event_touch_motion *event) { + wlr_log(L_DEBUG, "TODO: cursor handle touch motion"); +} + +void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_axis *event) { + wlr_log(L_DEBUG, "TODO: cursor handle tool axis"); +} + +void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_tip *event) { + wlr_log(L_DEBUG, "TODO: cursor handle tool tip"); +} diff --git a/rootston/seat.c b/rootston/seat.c index c8f689bc..957843ec 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -7,6 +7,7 @@ #include "rootston/input.h" #include "rootston/seat.h" #include "rootston/keyboard.h" +#include "rootston/cursor.h" static void handle_keyboard_key(struct wl_listener *listener, void *data) { struct roots_keyboard *keyboard = @@ -24,43 +25,70 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, } static void handle_cursor_motion(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, motion); + struct wlr_event_pointer_motion *event = data; + roots_cursor_handle_motion(cursor, event); } static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, motion_absolute); + struct wlr_event_pointer_motion_absolute *event = data; + roots_cursor_handle_motion_absolute(cursor, event); } static void handle_cursor_button(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, button); + struct wlr_event_pointer_button *event = data; + roots_cursor_handle_button(cursor, event); } static void handle_cursor_axis(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, axis); + struct wlr_event_pointer_axis *event = data; + roots_cursor_handle_axis(cursor, event); } static void handle_touch_down(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, touch_down); + struct wlr_event_touch_down *event = data; + roots_cursor_handle_touch_down(cursor, event); } static void handle_touch_up(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, touch_up); + struct wlr_event_touch_up *event = data; + roots_cursor_handle_touch_up(cursor, event); } static void handle_touch_motion(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, touch_motion); + struct wlr_event_touch_motion *event = data; + roots_cursor_handle_touch_motion(cursor, event); } static void handle_tool_axis(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, tool_axis); + struct wlr_event_tablet_tool_axis *event = data; + roots_cursor_handle_tool_axis(cursor, event); } static void handle_tool_tip(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, tool_tip); + struct wlr_event_tablet_tool_tip *event = data; + roots_cursor_handle_tool_tip(cursor, event); } static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { - struct wlr_cursor *cursor = seat->cursor; + struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; wlr_cursor_map_input_to_output(cursor, device, NULL); @@ -72,7 +100,7 @@ static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input static void seat_set_device_output_mappings(struct roots_seat *seat, struct wlr_input_device *device, struct wlr_output *output) { - struct wlr_cursor *cursor = seat->cursor; + struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; struct device_config *dconfig; dconfig = config_get_device(config, device); @@ -85,7 +113,7 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, static void roots_seat_configure_cursor(struct roots_seat *seat) { struct roots_config *config = seat->input->config; struct roots_desktop *desktop = seat->input->server->desktop; - struct wlr_cursor *cursor = seat->cursor; + struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_pointer *pointer; struct roots_touch *touch; @@ -124,46 +152,42 @@ static void roots_seat_configure_cursor(struct roots_seat *seat) { } static void roots_seat_init_cursor(struct roots_seat *seat) { - struct wlr_cursor *cursor = wlr_cursor_create(); - if (!cursor) { + seat->cursor = roots_cursor_create(seat); + if (!seat->cursor) { return; } - seat->cursor = cursor; - - // add output layout and configure + struct wlr_cursor *wlr_cursor = seat->cursor->cursor; struct roots_desktop *desktop = seat->input->server->desktop; - wlr_cursor_attach_output_layout(cursor, desktop->layout); - roots_seat_configure_cursor(seat); - // TODO configure cursor by seat + wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); // add input signals - wl_signal_add(&cursor->events.motion, &seat->cursor_motion); - seat->cursor_motion.notify = handle_cursor_motion; + wl_signal_add(&wlr_cursor->events.motion, &seat->cursor->motion); + seat->cursor->motion.notify = handle_cursor_motion; - wl_signal_add(&cursor->events.motion_absolute, - &seat->cursor_motion_absolute); - seat->cursor_motion_absolute.notify = handle_cursor_motion_absolute; + wl_signal_add(&wlr_cursor->events.motion_absolute, + &seat->cursor->motion_absolute); + seat->cursor->motion_absolute.notify = handle_cursor_motion_absolute; - wl_signal_add(&cursor->events.button, &seat->cursor_button); - seat->cursor_button.notify = handle_cursor_button; + wl_signal_add(&wlr_cursor->events.button, &seat->cursor->button); + seat->cursor->button.notify = handle_cursor_button; - wl_signal_add(&cursor->events.axis, &seat->cursor_axis); - seat->cursor_axis.notify = handle_cursor_axis; + wl_signal_add(&wlr_cursor->events.axis, &seat->cursor->axis); + seat->cursor->axis.notify = handle_cursor_axis; - wl_signal_add(&cursor->events.touch_down, &seat->cursor_touch_down); - seat->cursor_touch_down.notify = handle_touch_down; + wl_signal_add(&wlr_cursor->events.touch_down, &seat->cursor->touch_down); + seat->cursor->touch_down.notify = handle_touch_down; - wl_signal_add(&cursor->events.touch_up, &seat->cursor_touch_up); - seat->cursor_touch_up.notify = handle_touch_up; + wl_signal_add(&wlr_cursor->events.touch_up, &seat->cursor->touch_up); + seat->cursor->touch_up.notify = handle_touch_up; - wl_signal_add(&cursor->events.touch_motion, &seat->cursor_touch_motion); - seat->cursor_touch_motion.notify = handle_touch_motion; + wl_signal_add(&wlr_cursor->events.touch_motion, &seat->cursor->touch_motion); + seat->cursor->touch_motion.notify = handle_touch_motion; - wl_signal_add(&cursor->events.tablet_tool_axis, &seat->cursor_tool_axis); - seat->cursor_tool_axis.notify = handle_tool_axis; + wl_signal_add(&wlr_cursor->events.tablet_tool_axis, &seat->cursor->tool_axis); + seat->cursor->tool_axis.notify = handle_tool_axis; - wl_signal_add(&cursor->events.tablet_tool_tip, &seat->cursor_tool_tip); - seat->cursor_tool_tip.notify = handle_tool_tip; + wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &seat->cursor->tool_tip); + seat->cursor->tool_tip.notify = handle_tool_tip; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { @@ -172,6 +196,8 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { return NULL; } + seat->input = input; + roots_seat_init_cursor(seat); if (!seat->cursor) { free(seat); @@ -181,7 +207,7 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { seat->seat = wlr_seat_create(input->server->wl_display, name); if (!seat->seat) { free(seat); - wlr_cursor_destroy(seat->cursor); + roots_cursor_destroy(seat->cursor); return NULL; } @@ -190,10 +216,12 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - seat->input = input; - wl_list_insert(&input->seats, &seat->link); + wl_list_init(&seat->keyboards); + wl_list_init(&seat->pointers); + wl_list_init(&seat->touch); + wl_list_init(&seat->tablet_tools); return seat; } @@ -228,7 +256,7 @@ static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *d pointer->device = device; pointer->seat = seat; wl_list_insert(&seat->pointers, &pointer->link); - wlr_cursor_attach_input_device(seat->cursor, device); + wlr_cursor_attach_input_device(seat->cursor->cursor, device); roots_seat_configure_cursor(seat); } @@ -243,7 +271,7 @@ static void seat_add_touch(struct roots_seat *seat, struct wlr_input_device *dev touch->device = device; touch->seat = seat; wl_list_insert(&seat->touch, &touch->link); - wlr_cursor_attach_input_device(seat->cursor, device); + wlr_cursor_attach_input_device(seat->cursor->cursor, device); roots_seat_configure_cursor(seat); } @@ -262,7 +290,7 @@ static void seat_add_tablet_tool(struct roots_seat *seat, struct wlr_input_devic tablet_tool->device = device; tablet_tool->seat = seat; wl_list_insert(&seat->tablet_tools, &tablet_tool->link); - wlr_cursor_attach_input_device(seat->cursor, device); + wlr_cursor_attach_input_device(seat->cursor->cursor, device); roots_seat_configure_cursor(seat); } From 09c60924235805d07b7915ba879685545a3442aa Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 15:56:11 -0500 Subject: [PATCH 07/21] multiseat: somewhat working --- include/rootston/cursor.h | 35 ++++ include/rootston/input.h | 54 +----- include/rootston/keyboard.h | 1 + include/rootston/seat.h | 30 ++++ include/wlr/types/wlr_wl_shell.h | 4 +- include/wlr/types/wlr_xdg_shell_v6.h | 6 +- rootston/desktop.c | 36 ++-- rootston/input.c | 62 ++----- rootston/keyboard.c | 26 ++- rootston/meson.build | 2 +- rootston/output.c | 32 ++-- rootston/roots_cursor.c | 239 ++++++++++++++++++++++++++- rootston/seat.c | 134 ++++++++++++++- rootston/wl_shell.c | 13 +- rootston/xdg_shell_v6.c | 14 +- rootston/xwayland.c | 32 +--- types/wlr_wl_shell.c | 8 +- types/wlr_xdg_shell_v6.c | 12 +- 18 files changed, 521 insertions(+), 219 deletions(-) diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 8a8d33f2..18d5f720 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -3,10 +3,45 @@ #include "rootston/seat.h" +enum roots_cursor_mode { + ROOTS_CURSOR_PASSTHROUGH = 0, + ROOTS_CURSOR_MOVE = 1, + ROOTS_CURSOR_RESIZE = 2, + ROOTS_CURSOR_ROTATE = 3, +}; + +enum roots_cursor_resize_edge { + ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, + ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, + ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, + ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, +}; + +struct roots_input_event { + uint32_t serial; + struct wlr_cursor *cursor; + struct wlr_input_device *device; +}; + struct roots_cursor { struct roots_seat *seat; struct wlr_cursor *cursor; + enum roots_cursor_mode mode; + + // state from input (review if this is necessary) + struct wlr_xcursor_theme *xcursor_theme; + struct wlr_seat *wl_seat; + struct wl_client *cursor_client; + int offs_x, offs_y; + int view_x, view_y, view_width, view_height; + float view_rotation; + uint32_t resize_edges; + // Ring buffer of input events that could trigger move/resize/rotate + int input_events_idx; + struct wl_list touch_points; + struct roots_input_event input_events[16]; + struct wl_listener motion; struct wl_listener motion_absolute; struct wl_listener button; diff --git a/include/rootston/input.h b/include/rootston/input.h index 7b1358f8..7463ba3a 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -5,64 +5,15 @@ #include #include #include +#include "rootston/cursor.h" #include "rootston/config.h" #include "rootston/view.h" #include "rootston/server.h" -enum roots_cursor_mode { - ROOTS_CURSOR_PASSTHROUGH = 0, - ROOTS_CURSOR_MOVE = 1, - ROOTS_CURSOR_RESIZE = 2, - ROOTS_CURSOR_ROTATE = 3, -}; - -enum roots_cursor_resize_edge { - ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, - ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, - ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, - ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, -}; - -struct roots_input_event { - uint32_t serial; - struct wlr_cursor *cursor; - struct wlr_input_device *device; -}; - -struct roots_drag_icon { - struct wlr_surface *surface; - struct wl_list link; // roots_input::drag_icons - bool mapped; - - int32_t sx; - int32_t sy; - - struct wl_listener surface_destroy; - struct wl_listener surface_commit; -}; - struct roots_input { struct roots_config *config; struct roots_server *server; - // TODO: multiseat, multicursor - struct wlr_cursor *cursor; - struct wlr_xcursor_theme *xcursor_theme; - struct wlr_seat *wl_seat; - struct wl_list drag_icons; - struct wl_client *cursor_client; - - enum roots_cursor_mode mode; - struct roots_view *active_view; - int offs_x, offs_y; - int view_x, view_y, view_width, view_height; - float view_rotation; - uint32_t resize_edges; - - // Ring buffer of input events that could trigger move/resize/rotate - int input_events_idx; - struct roots_input_event input_events[16]; - struct wl_list keyboards; struct wl_list pointers; struct wl_list touch; @@ -117,4 +68,7 @@ struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, struct roots_view *view); +struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, + struct wlr_seat *seat); + #endif diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index cb639ba1..e3caf8fb 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -10,6 +10,7 @@ struct roots_keyboard { struct roots_input *input; struct roots_seat *seat; struct wlr_input_device *device; + struct keyboard_config *config; struct wl_list seat_link; // XXX temporary struct wl_list link; diff --git a/include/rootston/seat.h b/include/rootston/seat.h index b7c8b477..b5593651 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -6,11 +6,26 @@ #include "rootston/input.h" #include "rootston/keyboard.h" +struct roots_drag_icon { + struct wlr_surface *surface; + struct wl_list link; // roots_seat::drag_icons + bool mapped; + + int32_t sx; + int32_t sy; + + struct wl_listener surface_destroy; + struct wl_listener surface_commit; +}; + struct roots_seat { struct roots_input *input; struct wlr_seat *seat; struct roots_cursor *cursor; struct wl_list link; + struct wl_list drag_icons; + + struct roots_view *focus; struct wl_list keyboards; struct wl_list pointers; @@ -57,4 +72,19 @@ void roots_seat_add_device(struct roots_seat *seat, void roots_seat_remove_device(struct roots_seat *seat, struct wlr_input_device *device); +void roots_seat_configure_cursor(struct roots_seat *seat); + +void roots_seat_configure_xcursor(struct roots_seat *seat); + +bool roots_seat_has_meta_pressed(struct roots_seat *seat); + +void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, + uint32_t edges); + +void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view); + #endif diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index 4e814817..ab3b4b10 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -93,14 +93,14 @@ struct wlr_wl_shell_surface { struct wlr_wl_shell_surface_move_event { struct wl_client *client; struct wlr_wl_shell_surface *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_wl_shell_surface_resize_event { struct wl_client *client; struct wlr_wl_shell_surface *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; enum wl_shell_surface_resize edges; }; diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index b0de41e2..e17393f6 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -138,14 +138,14 @@ struct wlr_xdg_surface_v6 { struct wlr_xdg_toplevel_v6_move_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_xdg_toplevel_v6_resize_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; uint32_t edges; }; @@ -153,7 +153,7 @@ struct wlr_xdg_toplevel_v6_resize_event { struct wlr_xdg_toplevel_v6_show_window_menu_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; uint32_t x; uint32_t y; diff --git a/rootston/desktop.c b/rootston/desktop.c index 29f78ac7..e752e639 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -14,15 +14,19 @@ #include #include #include "rootston/server.h" -#include "rootston/server.h" +#include "rootston/seat.h" +// TODO replace me with a signal void view_destroy(struct roots_view *view) { struct roots_desktop *desktop = view->desktop; struct roots_input *input = desktop->server->input; - if (input->active_view == view) { - input->active_view = NULL; - input->mode = ROOTS_CURSOR_PASSTHROUGH; + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + if (seat->focus == view) { + seat->focus = NULL; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + } } for (size_t i = 0; i < desktop->views->length; ++i) { @@ -89,15 +93,9 @@ bool view_center(struct roots_view *view) { view_get_size(view, &size); struct roots_desktop *desktop = view->desktop; - struct wlr_cursor *cursor = desktop->server->input->cursor; struct wlr_output *output = - wlr_output_layout_output_at(desktop->layout, cursor->x, cursor->y); - - if (!output) { - output = wlr_output_layout_get_center_output(desktop->layout); - } - + wlr_output_layout_get_center_output(desktop->layout); if (!output) { // empty layout return false; @@ -121,19 +119,15 @@ void view_setup(struct roots_view *view) { view_center(view); struct roots_input *input = view->desktop->server->input; - set_view_focus(input, view->desktop, view); + // TODO what seat gets focus? the one with the last input event? + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_focus_view(seat, view); + } } void view_teardown(struct roots_view *view) { - struct wlr_list *views = view->desktop->views; - if (views->length < 2 || views->items[views->length-1] != view) { - return; - } - - struct roots_view *prev_view = views->items[views->length-2]; - struct roots_input *input = prev_view->desktop->server->input; - set_view_focus(input, prev_view->desktop, prev_view); - wlr_seat_keyboard_notify_enter(input->wl_seat, prev_view->wlr_surface); + // TODO replace me with a signal } struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, diff --git a/rootston/input.c b/rootston/input.c index 4a567763..8e45d6d3 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -84,43 +84,6 @@ struct roots_input *input_create(struct roots_server *server, input->config = config; input->server = server; - input->xcursor_theme = wlr_xcursor_theme_load("default", 16); - if (input->xcursor_theme == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor theme"); - free(input); - return NULL; - } - - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - if (xcursor == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor from theme"); - wlr_xcursor_theme_destroy(input->xcursor_theme); - free(input); - return NULL; - } - - if (server->desktop->xwayland != NULL) { - struct wlr_xcursor_image *xcursor_image = xcursor->images[0]; - wlr_xwayland_set_cursor(server->desktop->xwayland, - xcursor_image->buffer, xcursor_image->width, xcursor_image->width, - xcursor_image->height, xcursor_image->hotspot_x, - xcursor_image->hotspot_y); - } - - input->wl_seat = wlr_seat_create(server->wl_display, "seat0"); - if (input->wl_seat == NULL) { - wlr_log(L_ERROR, "Cannot create seat"); - wlr_xcursor_theme_destroy(input->xcursor_theme); - free(input); - return NULL; - } - wlr_seat_set_capabilities(input->wl_seat, WL_SEAT_CAPABILITY_KEYBOARD - | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - - wl_list_init(&input->keyboards); - wl_list_init(&input->pointers); - wl_list_init(&input->touch); - wl_list_init(&input->tablet_tools); wl_list_init(&input->seats); input->input_add.notify = input_add_notify; @@ -128,23 +91,20 @@ struct roots_input *input_create(struct roots_server *server, input->input_remove.notify = input_remove_notify; wl_signal_add(&server->backend->events.input_remove, &input->input_remove); - input->cursor = wlr_cursor_create(); - cursor_initialize(input); - - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); - - wlr_cursor_attach_output_layout(input->cursor, server->desktop->layout); - wlr_cursor_map_to_region(input->cursor, config->cursor.mapped_box); - cursor_load_config(config, input->cursor, - input, server->desktop); - - wl_list_init(&input->drag_icons); - return input; } void input_destroy(struct roots_input *input) { // TODO } + +struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, + struct wlr_seat *wlr_seat) { + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &input->seats, link) { + if (seat->seat == wlr_seat) { + return seat; + } + } + return seat; +} diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 0865f551..ef5eb8ab 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -39,7 +39,7 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, } else if (strcmp(command, "next_window") == 0) { if (server->desktop->views->length > 0) { struct roots_view *view = server->desktop->views->items[0]; - set_view_focus(keyboard->input, server->desktop, view); + roots_seat_focus_view(keyboard->seat, view); } } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { const char *shell_cmd = command + strlen(exec_prefix); @@ -192,13 +192,9 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->device = device; keyboard->input = input; - // XXX temporary - wl_list_insert(&input->keyboards, &keyboard->link); - - struct keyboard_config config; - memset(&config, 0, sizeof(config)); - keyboard_config_merge(&config, config_get_keyboard(input->config, device)); - keyboard_config_merge(&config, config_get_keyboard(input->config, NULL)); + struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + keyboard_config_merge(config, config_get_keyboard(input->config, device)); + keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); struct keyboard_config env_config = { .rules = getenv("XKB_DEFAULT_RULES"), @@ -207,15 +203,16 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, .variant = getenv("XKB_DEFAULT_VARIANT"), .options = getenv("XKB_DEFAULT_OPTIONS"), }; - keyboard_config_merge(&config, &env_config); + keyboard_config_merge(config, &env_config); + keyboard->config = config; struct xkb_rule_names rules; memset(&rules, 0, sizeof(rules)); - rules.rules = config.rules; - rules.model = config.model; - rules.layout = config.layout; - rules.variant = config.variant; - rules.options = config.options; + rules.rules = config->rules; + rules.model = config->model; + rules.layout = config->layout; + rules.variant = config->variant; + rules.options = config->options; struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (context == NULL) { wlr_log(L_ERROR, "Cannot create XKB context"); @@ -231,5 +228,6 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; wl_list_remove(&keyboard->link); + free(keyboard->config); free(keyboard); } diff --git a/rootston/meson.build b/rootston/meson.build index baed5330..062f56fc 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,6 +1,6 @@ sources = [ 'config.c', - 'cursor.c', + #'cursor.c', 'roots_cursor.c', 'desktop.c', 'ini.c', diff --git a/rootston/output.c b/rootston/output.c index baa7b6cc..329c29be 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -151,15 +151,18 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { } struct roots_drag_icon *drag_icon = NULL; - wl_list_for_each(drag_icon, &server->input->drag_icons, link) { - if (!drag_icon->mapped) { - continue; + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &server->input->seats, link) { + wl_list_for_each(drag_icon, &seat->drag_icons, link) { + if (!drag_icon->mapped) { + continue; + } + struct wlr_surface *icon = drag_icon->surface; + struct wlr_cursor *cursor = seat->cursor->cursor; + double icon_x = cursor->x + drag_icon->sx; + double icon_y = cursor->y + drag_icon->sy; + render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0); } - struct wlr_surface *icon = drag_icon->surface; - struct wlr_cursor *cursor = server->input->cursor; - double icon_x = cursor->x + drag_icon->sx; - double icon_y = cursor->y + drag_icon->sy; - render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0); } wlr_renderer_end(server->renderer); @@ -224,14 +227,11 @@ void output_add_notify(struct wl_listener *listener, void *data) { wlr_output_layout_add_auto(desktop->layout, wlr_output); } - cursor_load_config(config, input->cursor, input, desktop); - - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); - - wlr_cursor_warp(input->cursor, NULL, input->cursor->x, input->cursor->y); + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_configure_cursor(seat); + roots_seat_configure_xcursor(seat); + } } void output_remove_notify(struct wl_listener *listener, void *data) { diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 72eff996..92c0cc9e 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -1,4 +1,11 @@ +#define _XOPEN_SOURCE 700 #include +#include +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif #include #include "rootston/cursor.h" @@ -19,47 +26,261 @@ void roots_cursor_destroy(struct roots_cursor *cursor) { // TODO } +static void cursor_set_xcursor_image(struct roots_cursor *cursor, + struct wlr_xcursor_image *image) { + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); +} + +static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { + struct roots_desktop *desktop = cursor->seat->input->server->desktop; + struct roots_seat *seat = cursor->seat; + struct roots_view *view; + struct wlr_surface *surface; + double sx, sy; + switch (cursor->mode) { + case ROOTS_CURSOR_PASSTHROUGH: + view = view_at(desktop, cursor->cursor->x, cursor->cursor->y, + &surface, &sx, &sy); + bool set_compositor_cursor = !view && cursor->cursor_client; + if (view) { + struct wl_client *view_client = + wl_resource_get_client(view->wlr_surface->resource); + set_compositor_cursor = view_client != cursor->cursor_client; + } + if (set_compositor_cursor) { + struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); + cursor_set_xcursor_image(cursor, xcursor->images[0]); + cursor->cursor_client = NULL; + } + if (view) { + wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); + } else { + wlr_seat_pointer_clear_focus(seat->seat); + } + break; + case ROOTS_CURSOR_MOVE: + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + view_move(seat->focus, cursor->view_x + dx, + cursor->view_y + dy); + } + break; + case ROOTS_CURSOR_RESIZE: + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + double active_x = seat->focus->x; + double active_y = seat->focus->y; + int width = cursor->view_width; + int height = cursor->view_height; + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { + active_y = cursor->view_y + dy; + height -= dy; + if (height < 0) { + active_y += height; + } + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { + height += dy; + } + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { + active_x = cursor->view_x + dx; + width -= dx; + if (width < 0) { + active_x += width; + } + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { + width += dx; + } + + if (width < 0) { + width = 0; + } + if (height < 0) { + height = 0; + } + + if (active_x != seat->focus->x || + active_y != seat->focus->y) { + view_move_resize(seat->focus, active_x, active_y, + width, height); + } else { + view_resize(seat->focus, width, height); + } + } + break; + case ROOTS_CURSOR_ROTATE: + if (seat->focus) { + struct roots_view *view = seat->focus; + int ox = view->x + view->wlr_surface->current->width/2, + oy = view->y + view->wlr_surface->current->height/2; + int ux = cursor->offs_x - ox, + uy = cursor->offs_y - oy; + int vx = cursor->cursor->x - ox, + vy = cursor->cursor->y - oy; + float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); + int steps = 12; + angle = round(angle/M_PI*steps) / (steps/M_PI); + view->rotation = cursor->view_rotation + angle; + } + break; + } + +} + +static void roots_cursor_press_button(struct roots_cursor *cursor, + struct wlr_input_device *device, uint32_t time, uint32_t button, + uint32_t state) { + struct roots_seat *seat = cursor->seat; + struct roots_desktop *desktop = seat->input->server->desktop; + struct wlr_surface *surface; + double sx, sy; + struct roots_view *view = view_at(desktop, + cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); + + if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { + // TODO + roots_seat_focus_view(seat, view); + + uint32_t edges; + switch (button) { + case BTN_LEFT: + // TODO + roots_seat_begin_move(seat, view); + break; + case BTN_RIGHT: + edges = 0; + if (sx < view->wlr_surface->current->width/2) { + edges |= ROOTS_CURSOR_RESIZE_EDGE_LEFT; + } else { + edges |= ROOTS_CURSOR_RESIZE_EDGE_RIGHT; + } + if (sy < view->wlr_surface->current->height/2) { + edges |= ROOTS_CURSOR_RESIZE_EDGE_TOP; + } else { + edges |= ROOTS_CURSOR_RESIZE_EDGE_BOTTOM; + } + roots_seat_begin_resize(seat, view, edges); + break; + case BTN_MIDDLE: + roots_seat_begin_rotate(seat, view); + break; + } + return; + } + + // TODO + uint32_t serial = + wlr_seat_pointer_notify_button(seat->seat, time, button, state); + + int i; + switch (state) { + case WLR_BUTTON_RELEASED: + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + roots_cursor_update_position(cursor, time); + break; + case WLR_BUTTON_PRESSED: + // TODO + i = cursor->input_events_idx; + cursor->input_events[i].serial = serial; + cursor->input_events[i].cursor = cursor->cursor; + cursor->input_events[i].device = device; + cursor->input_events_idx = (i + 1) + % (sizeof(cursor->input_events) / sizeof(cursor->input_events[0])); + roots_seat_focus_view(seat, view); + break; + } +} + void roots_cursor_handle_motion(struct roots_cursor *cursor, struct wlr_event_pointer_motion *event) { - wlr_log(L_DEBUG, "TODO: cursor handle motion"); + wlr_cursor_move(cursor->cursor, event->device, + event->delta_x, event->delta_y); + roots_cursor_update_position(cursor, event->time_msec); } void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, struct wlr_event_pointer_motion_absolute *event) { - wlr_log(L_DEBUG, "TODO: cursor handle motion absolute"); + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); + roots_cursor_update_position(cursor, event->time_msec); } void roots_cursor_handle_button(struct roots_cursor *cursor, struct wlr_event_pointer_button *event) { - wlr_log(L_DEBUG, "TODO: cursor handle button"); + roots_cursor_press_button(cursor, event->device, event->time_msec, + event->button, event->state); } void roots_cursor_handle_axis(struct roots_cursor *cursor, struct wlr_event_pointer_axis *event) { - wlr_log(L_DEBUG, "TODO: cursor handle axis"); + wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, + event->orientation, event->delta); } void roots_cursor_handle_touch_down(struct roots_cursor *cursor, struct wlr_event_touch_down *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch down"); + struct roots_touch_point *point = + calloc(1, sizeof(struct roots_touch_point)); + if (!point) { + wlr_log(L_ERROR, "could not allocate memory for touch point"); + return; + } + + point->device = event->device->data; + point->slot = event->slot; + point->x = event->x_mm / event->width_mm; + point->y = event->y_mm / event->height_mm; + wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + wl_list_insert(&cursor->touch_points, &point->link); + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, 1); } void roots_cursor_handle_touch_up(struct roots_cursor *cursor, struct wlr_event_touch_up *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch up"); + struct roots_touch_point *point; + wl_list_for_each(point, &cursor->touch_points, link) { + if (point->slot == event->slot) { + wl_list_remove(&point->link); + free(point); + break; + } + } + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, 0); } void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, struct wlr_event_touch_motion *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch motion"); + struct roots_touch_point *point; + wl_list_for_each(point, &cursor->touch_points, link) { + if (point->slot == event->slot) { + point->x = event->x_mm / event->width_mm; + point->y = event->y_mm / event->height_mm; + wlr_cursor_warp_absolute(cursor->cursor, event->device, + point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + break; + } + } } void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, struct wlr_event_tablet_tool_axis *event) { - wlr_log(L_DEBUG, "TODO: cursor handle tool axis"); + if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && + (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); + roots_cursor_update_position(cursor, event->time_msec); + } } void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, struct wlr_event_tablet_tool_tip *event) { - wlr_log(L_DEBUG, "TODO: cursor handle tool tip"); + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, event->state); } diff --git a/rootston/seat.c b/rootston/seat.c index 957843ec..ec7709fa 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -110,7 +111,7 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, } } -static void roots_seat_configure_cursor(struct roots_seat *seat) { +void roots_seat_configure_cursor(struct roots_seat *seat) { struct roots_config *config = seat->input->config; struct roots_desktop *desktop = seat->input->server->desktop; struct wlr_cursor *cursor = seat->cursor->cursor; @@ -156,10 +157,44 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { if (!seat->cursor) { return; } + seat->cursor->seat = seat; struct wlr_cursor *wlr_cursor = seat->cursor->cursor; struct roots_desktop *desktop = seat->input->server->desktop; wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); + seat->cursor->xcursor_theme = wlr_xcursor_theme_load("default", 16); + if (seat->cursor->xcursor_theme == NULL) { + wlr_log(L_ERROR, "Cannot load xcursor theme"); + roots_cursor_destroy(seat->cursor); + seat->cursor = NULL; + return; + } + + struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + if (xcursor == NULL) { + wlr_log(L_ERROR, "Cannot load xcursor from theme"); + wlr_xcursor_theme_destroy(seat->cursor->xcursor_theme); + roots_cursor_destroy(seat->cursor); + seat->cursor = NULL; + return; + } + + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + // XXX: xwayland will always have the theme of the last created seat + if (seat->input->server->desktop->xwayland != NULL) { + wlr_xwayland_set_cursor(seat->input->server->desktop->xwayland, + image->buffer, image->width, image->width, + image->height, image->hotspot_x, + image->hotspot_y); + } + + wl_list_init(&seat->cursor->touch_points); + + roots_seat_configure_cursor(seat); + // add input signals wl_signal_add(&wlr_cursor->events.motion, &seat->cursor->motion); seat->cursor->motion.notify = handle_cursor_motion; @@ -196,6 +231,12 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { return NULL; } + wl_list_init(&seat->keyboards); + wl_list_init(&seat->pointers); + wl_list_init(&seat->touch); + wl_list_init(&seat->tablet_tools); + wl_list_init(&seat->drag_icons); + seat->input = input; roots_seat_init_cursor(seat); @@ -218,11 +259,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { wl_list_insert(&input->seats, &seat->link); - wl_list_init(&seat->keyboards); - wl_list_init(&seat->pointers); - wl_list_init(&seat->touch); - wl_list_init(&seat->tablet_tools); - return seat; } @@ -231,6 +267,7 @@ void roots_seat_destroy(struct roots_seat *seat) { } static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { + assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; @@ -319,3 +356,88 @@ void roots_seat_remove_device(struct roots_seat *seat, struct wlr_input_device *device) { // TODO } + +void roots_seat_configure_xcursor(struct roots_seat *seat) { + struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, + seat->cursor->cursor->y); +} + +bool roots_seat_has_meta_pressed(struct roots_seat *seat) { + struct roots_keyboard *keyboard; + wl_list_for_each(keyboard, &seat->keyboards, seat_link) { + if (!keyboard->config->meta_key) { + continue; + } + + uint32_t modifiers = + wlr_keyboard_get_modifiers(keyboard->device->keyboard); + if ((modifiers ^ keyboard->config->meta_key) == 0) { + return true; + } + } + + return false; +} + +void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { + struct roots_desktop *desktop = seat->input->server->desktop; + if (seat->focus == view) { + return; + } + seat->focus = view; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + if (!view) { + return; + } + + if (view->type == ROOTS_XWAYLAND_VIEW && + view->xwayland_surface->override_redirect) { + return; + } + + size_t index = 0; + for (size_t i = 0; i < desktop->views->length; ++i) { + struct roots_view *_view = desktop->views->items[i]; + if (_view != view) { + view_activate(_view, false); + } else { + index = i; + } + } + view_activate(view, true); + // TODO: list_swap + wlr_list_del(desktop->views, index); + wlr_list_add(desktop->views, view); + wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); +} + +void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { + struct roots_cursor *cursor = seat->cursor; + cursor->mode = ROOTS_CURSOR_MOVE; + cursor->offs_x = cursor->cursor->x; + cursor->offs_y = cursor->cursor->y; + cursor->view_x = view->x; + cursor->view_y = view->y; + wlr_seat_pointer_clear_focus(seat->seat); + + struct wlr_xcursor *xcursor = get_move_xcursor(seat->cursor->xcursor_theme); + if (xcursor != NULL) { + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + } +} + +void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, + uint32_t edges) { + // TODO +} + +void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { + // TODO +} diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index e38eb697..81b9e640 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -29,11 +29,11 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_move_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, event->cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -42,11 +42,12 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_resize_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + // TODO verify input event + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, event->cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_surface_commit(struct wl_listener *listener, void *data) { diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ca33c582..4a694349 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -98,11 +98,12 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_view *view = roots_xdg_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_xdg_toplevel_v6_move_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + // TODO verify event serial + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, event->cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -111,11 +112,12 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_view *view = roots_xdg_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_xdg_toplevel_v6_resize_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + // TODO verify event serial + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, event->cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_commit(struct wl_listener *listener, void *data) { diff --git a/rootston/xwayland.c b/rootston/xwayland.c index e3fc1c84..b53b98a9 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -114,22 +114,8 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { // seat based on seat pointer focus, but interactive moving and resizing is not // yet seat aware. Even then, we can only guess because X11 events don't give us // enough wayland info to know for sure. -static struct wlr_cursor *guess_cursor_for_view(struct roots_view *view) { - struct roots_input *input = view->desktop->server->input; - size_t len = sizeof(input->input_events) / sizeof(*input->input_events); - for (size_t i = 0; i < len; i++) { - struct wlr_cursor *cursor = input->input_events[i].cursor; - if (cursor) { - int width = view->xwayland_surface->surface->current->width; - int height = view->xwayland_surface->surface->current->height; - if (cursor->x > view->x && cursor->y > view->y && - cursor->x < view->x + width && - cursor->y < view->y + height) { - return cursor; - } - } - } - +static struct roots_seat *guess_seat_for_view(struct roots_view *view) { + // TODO return NULL; } @@ -137,28 +123,26 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, request_move); struct roots_view *view = roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_cursor *cursor = guess_cursor_for_view(view); + struct roots_seat *seat = guess_seat_for_view(view); - if (!cursor || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, request_resize); struct roots_view *view = roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_cursor *cursor = guess_cursor_for_view(view); + struct roots_seat *seat = guess_seat_for_view(view); struct wlr_xwayland_resize_event *e = data; - if (!cursor || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_map_notify(struct wl_listener *listener, void *data) { diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index fe61075e..ce32d186 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -110,7 +110,7 @@ static void shell_surface_protocol_move(struct wl_client *client, uint32_t serial) { wlr_log(L_DEBUG, "got shell surface move"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); struct wlr_wl_shell_surface_move_event *event = @@ -121,7 +121,7 @@ static void shell_surface_protocol_move(struct wl_client *client, } event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; wl_signal_emit(&surface->events.request_move, event); @@ -177,7 +177,7 @@ static void shell_surface_protocol_resize(struct wl_client *client, uint32_t serial, enum wl_shell_surface_resize edges) { wlr_log(L_DEBUG, "got shell surface resize"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); struct wlr_wl_shell_surface_resize_event *event = @@ -188,7 +188,7 @@ static void shell_surface_protocol_resize(struct wl_client *client, } event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->edges = edges; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc45bc17..0c41b66f 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -557,7 +557,7 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -576,7 +576,7 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->x = x; event->y = y; @@ -590,7 +590,7 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -609,7 +609,7 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; wl_signal_emit(&surface->events.request_move, event); @@ -621,7 +621,7 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, uint32_t edges) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -640,7 +640,7 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->edges = edges; From 5ac05b0c475aae86e0a9356dc68d59a5f4004d5e Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 16:24:21 -0500 Subject: [PATCH 08/21] rootston: input remove stubs --- rootston/input.c | 2 +- rootston/seat.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/rootston/input.c b/rootston/input.c index 8e45d6d3..08cde4a1 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -63,7 +63,7 @@ static void input_add_notify(struct wl_listener *listener, void *data) { static void input_remove_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; - struct roots_input *input = wl_container_of(listener, input, input_add); + struct roots_input *input = wl_container_of(listener, input, input_remove); struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { diff --git a/rootston/seat.c b/rootston/seat.c index ec7709fa..3a009a51 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -352,11 +352,52 @@ void roots_seat_add_device(struct roots_seat *seat, } } -void roots_seat_remove_device(struct roots_seat *seat, +static void seat_remove_keyboard(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} + +static void seat_remove_pointer(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} + +static void seat_remove_touch(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} + +static void seat_remove_tablet_pad(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} + +static void seat_remove_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) { // TODO } +void roots_seat_remove_device(struct roots_seat *seat, + struct wlr_input_device *device) { + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + seat_remove_keyboard(seat, device); + break; + case WLR_INPUT_DEVICE_POINTER: + seat_remove_pointer(seat, device); + break; + case WLR_INPUT_DEVICE_TOUCH: + seat_remove_touch(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_PAD: + seat_remove_tablet_pad(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_TOOL: + seat_remove_tablet_tool(seat, device); + break; + } +} + void roots_seat_configure_xcursor(struct roots_seat *seat) { struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); struct wlr_xcursor_image *image = xcursor->images[0]; From fc6c3310e812afdc7c9754894e9e09c2fca20046 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 16:32:14 -0500 Subject: [PATCH 09/21] rootston: log seat name --- rootston/input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rootston/input.c b/rootston/input.c index 08cde4a1..92148b65 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -55,8 +55,8 @@ static void input_add_notify(struct wl_listener *listener, void *data) { return; } - wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s", device->name, - device->vendor, device->product, device_type(device->type)); + wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s seat:%s", device->name, + device->vendor, device->product, device_type(device->type), seat_name); roots_seat_add_device(seat, device); } From 86b86f07143132a399f28c13c6e86db027bb0486 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 16:42:04 -0500 Subject: [PATCH 10/21] rootston: multiple activated views --- rootston/seat.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/rootston/seat.c b/rootston/seat.c index 3a009a51..9a725dfa 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -430,12 +430,35 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { if (seat->focus == view) { return; } - seat->focus = view; - seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + + // unfocus the old view if it is not focused by some other seat + // TODO probably should be an input function + if (seat->focus) { + bool has_other_focus = false; + struct roots_seat *iter_seat; + wl_list_for_each(iter_seat, &seat->input->seats, link) { + if (iter_seat == seat) { + continue; + } + if (iter_seat->focus == seat->focus) { + has_other_focus = true; + break; + } + } + + if (!has_other_focus) { + view_activate(seat->focus, false); + } + } + if (!view) { + seat->focus = NULL; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; return; } + seat->focus = view; + if (view->type == ROOTS_XWAYLAND_VIEW && view->xwayland_surface->override_redirect) { return; @@ -444,12 +467,12 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { size_t index = 0; for (size_t i = 0; i < desktop->views->length; ++i) { struct roots_view *_view = desktop->views->items[i]; - if (_view != view) { - view_activate(_view, false); - } else { + if (_view == view) { index = i; + break; } } + view_activate(view, true); // TODO: list_swap wlr_list_del(desktop->views, index); From fc09f904624a8f3a4fc7577ba19137a3700c7a45 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 08:19:23 -0500 Subject: [PATCH 11/21] rootston: guess seat for xwayland moveresize --- rootston/xwayland.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/rootston/xwayland.c b/rootston/xwayland.c index b53b98a9..92ba5e60 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -110,12 +110,16 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { xwayland_surface, event->x, event->y, event->width, event->height); } -// XXX Needs deep refactoring to get this better. We need to select the correct -// seat based on seat pointer focus, but interactive moving and resizing is not -// yet seat aware. Even then, we can only guess because X11 events don't give us -// enough wayland info to know for sure. static struct roots_seat *guess_seat_for_view(struct roots_view *view) { - // TODO + // the best we can do is to pick the first seat that has the surface focused + // for the pointer + struct roots_input *input = view->desktop->server->input; + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + if (seat->seat->pointer_state.focused_surface == view->wlr_surface) { + return seat; + } + } return NULL; } From eb3c367c63adbef67bfe76bfc57f3eba25d0c149 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 08:35:27 -0500 Subject: [PATCH 12/21] rootston: seat resize and rotate --- rootston/seat.c | 40 ++++++++++++++++++++++++++++++++++++---- rootston/xdg_shell_v6.c | 1 + 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/rootston/seat.c b/rootston/seat.c index 9a725dfa..7fcffc29 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -480,6 +480,12 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); } +static void seat_set_xcursor_image(struct roots_seat *seat, struct + wlr_xcursor_image *image) { + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); +} + void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { struct roots_cursor *cursor = seat->cursor; cursor->mode = ROOTS_CURSOR_MOVE; @@ -492,16 +498,42 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { struct wlr_xcursor *xcursor = get_move_xcursor(seat->cursor->xcursor_theme); if (xcursor != NULL) { struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + seat_set_xcursor_image(seat, image); } } void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, uint32_t edges) { - // TODO + struct roots_cursor *cursor = seat->cursor; + cursor->mode = ROOTS_CURSOR_RESIZE; + cursor->offs_x = cursor->cursor->x; + cursor->offs_y = cursor->cursor->y; + cursor->view_x = view->x; + cursor->view_y = view->y; + struct wlr_box size; + view_get_size(view, &size); + cursor->view_width = size.width; + cursor->view_height = size.height; + cursor->resize_edges = edges; + wlr_seat_pointer_clear_focus(seat->seat); + + struct wlr_xcursor *xcursor = get_resize_xcursor(cursor->xcursor_theme, edges); + if (xcursor != NULL) { + seat_set_xcursor_image(seat, xcursor->images[0]); + } + } void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { - // TODO + struct roots_cursor *cursor = seat->cursor; + cursor->mode = ROOTS_CURSOR_ROTATE; + cursor->offs_x = cursor->cursor->x; + cursor->offs_y = cursor->cursor->y; + cursor->view_rotation = view->rotation; + wlr_seat_pointer_clear_focus(seat->seat); + + struct wlr_xcursor *xcursor = get_rotate_xcursor(cursor->xcursor_theme); + if (xcursor != NULL) { + seat_set_xcursor_image(seat, xcursor->images[0]); + } } diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 4a694349..ed952e18 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -114,6 +114,7 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct wlr_xdg_toplevel_v6_resize_event *e = data; // TODO verify event serial struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + assert(seat); if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } From a00b7f1e9bb992734f2498e597a86f1ca29b1d59 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 09:04:33 -0500 Subject: [PATCH 13/21] rootston: remove devices from seat --- include/rootston/keyboard.h | 5 +---- rootston/keyboard.c | 3 +-- rootston/seat.c | 42 +++++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index e3caf8fb..4dd70a65 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -11,8 +11,6 @@ struct roots_keyboard { struct roots_seat *seat; struct wlr_input_device *device; struct keyboard_config *config; - struct wl_list seat_link; - // XXX temporary struct wl_list link; struct wl_listener keyboard_key; @@ -24,8 +22,7 @@ struct roots_keyboard { struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input); -void roots_keyboard_destroy(struct wlr_input_device *device, - struct roots_input *input); +void roots_keyboard_destroy(struct roots_keyboard *keyboard); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index ef5eb8ab..a770f00f 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -225,8 +225,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, return keyboard; } -void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { - struct roots_keyboard *keyboard = device->data; +void roots_keyboard_destroy(struct roots_keyboard *keyboard) { wl_list_remove(&keyboard->link); free(keyboard->config); free(keyboard); diff --git a/rootston/seat.c b/rootston/seat.c index 7fcffc29..e860c093 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -271,7 +271,7 @@ static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device * struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; - wl_list_insert(&seat->keyboards, &keyboard->seat_link); + wl_list_insert(&seat->keyboards, &keyboard->link); keyboard->keyboard_key.notify = handle_keyboard_key; wl_signal_add(&keyboard->device->keyboard->events.key, @@ -354,17 +354,39 @@ void roots_seat_add_device(struct roots_seat *seat, static void seat_remove_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_keyboard *keyboard; + wl_list_for_each(keyboard, &seat->keyboards, link) { + if (keyboard->device == device) { + roots_keyboard_destroy(keyboard); + return; + } + } } static void seat_remove_pointer(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_pointer *pointer; + wl_list_for_each(pointer, &seat->pointers, link) { + if (pointer->device == device) { + wl_list_remove(&pointer->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(pointer); + return; + } + } } static void seat_remove_touch(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_touch *touch; + wl_list_for_each(touch, &seat->touch, link) { + if (touch->device == device) { + wl_list_remove(&touch->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(touch); + return; + } + } } static void seat_remove_tablet_pad(struct roots_seat *seat, @@ -374,7 +396,15 @@ static void seat_remove_tablet_pad(struct roots_seat *seat, static void seat_remove_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_tablet_tool *tablet_tool; + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + if (tablet_tool->device == device) { + wl_list_remove(&tablet_tool->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(tablet_tool); + return; + } + } } void roots_seat_remove_device(struct roots_seat *seat, @@ -410,7 +440,7 @@ void roots_seat_configure_xcursor(struct roots_seat *seat) { bool roots_seat_has_meta_pressed(struct roots_seat *seat) { struct roots_keyboard *keyboard; - wl_list_for_each(keyboard, &seat->keyboards, seat_link) { + wl_list_for_each(keyboard, &seat->keyboards, link) { if (!keyboard->config->meta_key) { continue; } From 992f931ae9319999f338298d8e0538f13ee388d7 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 14:53:08 -0500 Subject: [PATCH 14/21] rootston: cleanup for multiseat --- include/rootston/input.h | 42 +------------------------------------- include/rootston/xcursor.h | 15 ++++++++++++++ rootston/roots_cursor.c | 5 +---- rootston/seat.c | 1 + rootston/xcursor.c | 16 +++++++-------- 5 files changed, 26 insertions(+), 53 deletions(-) create mode 100644 include/rootston/xcursor.h diff --git a/include/rootston/input.h b/include/rootston/input.h index 7463ba3a..e073a59d 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -4,7 +4,6 @@ #include #include #include -#include #include "rootston/cursor.h" #include "rootston/config.h" #include "rootston/view.h" @@ -14,30 +13,12 @@ struct roots_input { struct roots_config *config; struct roots_server *server; - struct wl_list keyboards; - struct wl_list pointers; - struct wl_list touch; - struct wl_list tablet_tools; - struct wl_list seats; - struct wl_listener input_add; struct wl_listener input_remove; - struct wl_listener cursor_motion; - struct wl_listener cursor_motion_absolute; - struct wl_listener cursor_button; - struct wl_listener cursor_axis; - - struct wl_listener cursor_touch_down; - struct wl_listener cursor_touch_up; - struct wl_listener cursor_touch_motion; - - struct wl_listener cursor_tool_axis; - struct wl_listener cursor_tool_tip; + struct wl_list seats; struct wl_listener pointer_grab_begin; - struct wl_list touch_points; - struct wl_listener pointer_grab_end; struct wl_listener request_set_cursor; @@ -47,27 +28,6 @@ struct roots_input *input_create(struct roots_server *server, struct roots_config *config); void input_destroy(struct roots_input *input); -void cursor_initialize(struct roots_input *input); -void cursor_load_config(struct roots_config *config, - struct wlr_cursor *cursor, - struct roots_input *input, - struct roots_desktop *desktop); -const struct roots_input_event *get_input_event(struct roots_input *input, - uint32_t serial); -void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view); -void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view, uint32_t edges); - -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme); -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme); -struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, - uint32_t edges); -struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); - -void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, - struct roots_view *view); - struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, struct wlr_seat *seat); diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h new file mode 100644 index 00000000..c96e50ef --- /dev/null +++ b/include/rootston/xcursor.h @@ -0,0 +1,15 @@ +#ifndef _ROOTSTON_XCURSOR_H +#define _ROOTSTON_XCURSOR_H + +#include + +struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme); + +struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme); + +struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, + uint32_t edges); + +struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); + +#endif diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 92c0cc9e..833551d1 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -7,6 +7,7 @@ #include #endif #include +#include "rootston/xcursor.h" #include "rootston/cursor.h" struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { @@ -141,13 +142,11 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { - // TODO roots_seat_focus_view(seat, view); uint32_t edges; switch (button) { case BTN_LEFT: - // TODO roots_seat_begin_move(seat, view); break; case BTN_RIGHT: @@ -171,7 +170,6 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, return; } - // TODO uint32_t serial = wlr_seat_pointer_notify_button(seat->seat, time, button, state); @@ -182,7 +180,6 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, roots_cursor_update_position(cursor, time); break; case WLR_BUTTON_PRESSED: - // TODO i = cursor->input_events_idx; cursor->input_events[i].serial = serial; cursor->input_events[i].cursor = cursor->cursor; diff --git a/rootston/seat.c b/rootston/seat.c index e860c093..b4d7887e 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -5,6 +5,7 @@ #include +#include "rootston/xcursor.h" #include "rootston/input.h" #include "rootston/seat.h" #include "rootston/keyboard.h" diff --git a/rootston/xcursor.c b/rootston/xcursor.c index 43cbfc51..8697cdc3 100644 --- a/rootston/xcursor.c +++ b/rootston/xcursor.c @@ -1,14 +1,6 @@ #include #include "rootston/input.h" -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); -} - -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "grabbing"); -} - static const char *get_resize_xcursor_name(uint32_t edges) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { @@ -32,6 +24,14 @@ static const char *get_resize_xcursor_name(uint32_t edges) { return "se-resize"; // fallback } +struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { + return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); +} + +struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { + return wlr_xcursor_theme_get_cursor(theme, "grabbing"); +} + struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, uint32_t edges) { return wlr_xcursor_theme_get_cursor(theme, get_resize_xcursor_name(edges)); From 428bf18ec70a29d6e3d778ab3baf175a3cead0af Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 15:23:56 -0500 Subject: [PATCH 15/21] rootston: request set cursor --- include/rootston/cursor.h | 8 ++++++++ include/rootston/input.h | 5 ----- rootston/roots_cursor.c | 21 +++++++++++++++++++++ rootston/seat.c | 23 ++++++++++++++++++----- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 18d5f720..3bc8c08b 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -53,6 +53,11 @@ struct roots_cursor { struct wl_listener tool_axis; struct wl_listener tool_tip; + + struct wl_listener pointer_grab_begin; + struct wl_listener pointer_grab_end; + + struct wl_listener request_set_cursor; }; struct roots_cursor *roots_cursor_create(struct roots_seat *seat); @@ -86,4 +91,7 @@ void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, struct wlr_event_tablet_tool_tip *event); +void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, + struct wlr_seat_pointer_request_set_cursor_event *event); + #endif diff --git a/include/rootston/input.h b/include/rootston/input.h index e073a59d..ea0bbeb6 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -17,11 +17,6 @@ struct roots_input { struct wl_listener input_remove; struct wl_list seats; - - struct wl_listener pointer_grab_begin; - struct wl_listener pointer_grab_end; - - struct wl_listener request_set_cursor; }; struct roots_input *input_create(struct roots_server *server, diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 833551d1..c44b0e7f 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -281,3 +281,24 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, roots_cursor_press_button(cursor, event->device, event->time_msec, BTN_LEFT, event->state); } + +void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, + struct wlr_seat_pointer_request_set_cursor_event *event) { + struct wlr_surface *focused_surface = + event->seat_client->seat->pointer_state.focused_surface; + bool has_focused = focused_surface != NULL && focused_surface->resource != NULL; + struct wl_client *focused_client = NULL; + if (has_focused) { + focused_client = wl_resource_get_client(focused_surface->resource); + } + if (event->seat_client->client != focused_client || + cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { + wlr_log(L_DEBUG, "Denying request to set cursor from unfocused client"); + return; + } + + wlr_log(L_DEBUG, "Setting client cursor"); + wlr_cursor_set_surface(cursor->cursor, event->surface, event->hotspot_x, + event->hotspot_y); + cursor->cursor_client = event->seat_client->client; +} diff --git a/rootston/seat.c b/rootston/seat.c index b4d7887e..12f12a69 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -89,6 +89,14 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { roots_cursor_handle_tool_tip(cursor, event); } +static void handle_request_set_cursor(struct wl_listener *listener, + void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, request_set_cursor); + struct wlr_seat_pointer_request_set_cursor_event *event = data; + roots_cursor_handle_request_set_cursor(cursor, event); +} + static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; @@ -224,6 +232,10 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &seat->cursor->tool_tip); seat->cursor->tool_tip.notify = handle_tool_tip; + + wl_signal_add(&seat->seat->events.request_set_cursor, + &seat->cursor->request_set_cursor); + seat->cursor->request_set_cursor.notify = handle_request_set_cursor; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { @@ -240,16 +252,17 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { seat->input = input; - roots_seat_init_cursor(seat); - if (!seat->cursor) { + seat->seat = wlr_seat_create(input->server->wl_display, name); + if (!seat->seat) { free(seat); + roots_cursor_destroy(seat->cursor); return NULL; } - seat->seat = wlr_seat_create(input->server->wl_display, name); - if (!seat->seat) { + roots_seat_init_cursor(seat); + if (!seat->cursor) { + wlr_seat_destroy(seat->seat); free(seat); - roots_cursor_destroy(seat->cursor); return NULL; } From 06642859f1d6c1e88056a606dac7376fb59e9205 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 15:35:47 -0500 Subject: [PATCH 16/21] rootston: drag icons --- include/rootston/cursor.h | 6 ++++ rootston/roots_cursor.c | 62 +++++++++++++++++++++++++++++++++++++++ rootston/seat.c | 24 +++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 3bc8c08b..c0dbc010 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -94,4 +94,10 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, struct wlr_seat_pointer_request_set_cursor_event *event); +void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab); + +void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab); + #endif diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index c44b0e7f..c8abe098 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -302,3 +302,65 @@ void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, event->hotspot_y); cursor->cursor_client = event->seat_client->client; } + +static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { + struct roots_drag_icon *drag_icon = + wl_container_of(listener, drag_icon, surface_commit); + drag_icon->sx += drag_icon->surface->current->sx; + drag_icon->sy += drag_icon->surface->current->sy; +} + +static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { + struct roots_drag_icon *drag_icon = + wl_container_of(listener, drag_icon, surface_destroy); + wl_list_remove(&drag_icon->link); + wl_list_remove(&drag_icon->surface_destroy.link); + wl_list_remove(&drag_icon->surface_commit.link); + free(drag_icon); +} + +void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { + struct roots_seat *seat = cursor->seat; + if (grab->interface == &wlr_data_device_pointer_drag_interface) { + struct wlr_drag *drag = grab->data; + if (drag->icon) { + struct roots_drag_icon *iter_icon; + wl_list_for_each(iter_icon, &seat->drag_icons, link) { + if (iter_icon->surface == drag->icon) { + // already in the list + return; + } + } + + struct roots_drag_icon *drag_icon = + calloc(1, sizeof(struct roots_drag_icon)); + drag_icon->mapped = true; + drag_icon->surface = drag->icon; + wl_list_insert(&seat->drag_icons, &drag_icon->link); + + wl_signal_add(&drag->icon->events.destroy, + &drag_icon->surface_destroy); + drag_icon->surface_destroy.notify = handle_drag_icon_destroy; + + wl_signal_add(&drag->icon->events.commit, + &drag_icon->surface_commit); + drag_icon->surface_commit.notify = handle_drag_icon_commit; + } + } +} + +void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { + if (grab->interface == &wlr_data_device_pointer_drag_interface) { + struct wlr_drag *drag = grab->data; + struct roots_drag_icon *icon; + wl_list_for_each(icon, &cursor->seat->drag_icons, link) { + if (icon->surface == drag->icon) { + icon->mapped = false; + } + } + } + + roots_cursor_update_position(cursor, 0); +} diff --git a/rootston/seat.c b/rootston/seat.c index 12f12a69..ce8ad10b 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -97,6 +97,22 @@ static void handle_request_set_cursor(struct wl_listener *listener, roots_cursor_handle_request_set_cursor(cursor, event); } +static void handle_pointer_grab_begin(struct wl_listener *listener, + void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, pointer_grab_begin); + struct wlr_seat_pointer_grab *grab = data; + roots_cursor_handle_pointer_grab_begin(cursor, grab); +} + +static void handle_pointer_grab_end(struct wl_listener *listener, + void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, pointer_grab_end); + struct wlr_seat_pointer_grab *grab = data; + roots_cursor_handle_pointer_grab_end(cursor, grab); +} + static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; @@ -236,6 +252,14 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wl_signal_add(&seat->seat->events.request_set_cursor, &seat->cursor->request_set_cursor); seat->cursor->request_set_cursor.notify = handle_request_set_cursor; + + wl_signal_add(&seat->seat->events.pointer_grab_begin, + &seat->cursor->pointer_grab_begin); + seat->cursor->pointer_grab_begin.notify = handle_pointer_grab_begin; + + wl_signal_add(&seat->seat->events.pointer_grab_end, + &seat->cursor->pointer_grab_end); + seat->cursor->pointer_grab_end.notify = handle_pointer_grab_end; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { From c680ace5e8209d573e7ce2d676bbf5fe1b4ff894 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 20:25:02 -0500 Subject: [PATCH 17/21] rootston: remove old cursor implementation --- rootston/cursor.c | 578 ++++++++++++---------------------------- rootston/meson.build | 3 +- rootston/roots_cursor.c | 366 ------------------------- 3 files changed, 171 insertions(+), 776 deletions(-) delete mode 100644 rootston/roots_cursor.c diff --git a/rootston/cursor.c b/rootston/cursor.c index 64277464..c8abe098 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -1,152 +1,98 @@ #define _XOPEN_SOURCE 700 #include -#include -#include -#include #include -#include #ifdef __linux__ #include #elif __FreeBSD__ #include #endif -#include -#include #include -#include -#include "rootston/config.h" -#include "rootston/input.h" -#include "rootston/desktop.h" -#include "rootston/view.h" -#include "rootston/keyboard.h" -#include "rootston/seat.h" - -const struct roots_input_event *get_input_event(struct roots_input *input, - uint32_t serial) { - size_t len = sizeof(input->input_events) / sizeof(*input->input_events); - for (size_t i = 0; i < len; ++i) { - if (input->input_events[i].cursor - && input->input_events[i].serial == serial) { - return &input->input_events[i]; - } - } - return NULL; -} - -static void cursor_set_xcursor_image(struct roots_input *input, - struct wlr_xcursor_image *image) { - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); -} +#include "rootston/xcursor.h" +#include "rootston/cursor.h" -void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view) { - input->mode = ROOTS_CURSOR_MOVE; - input->offs_x = cursor->x; - input->offs_y = cursor->y; - input->view_x = view->x; - input->view_y = view->y; - wlr_seat_pointer_clear_focus(input->wl_seat); - - struct wlr_xcursor *xcursor = get_move_xcursor(input->xcursor_theme); - if (xcursor != NULL) { - cursor_set_xcursor_image(input, xcursor->images[0]); +struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { + struct roots_cursor *cursor = calloc(1, sizeof(struct roots_cursor)); + if (!cursor) { + return NULL; + } + cursor->cursor = wlr_cursor_create(); + if (!cursor->cursor) { + return NULL; } + + return cursor; } -void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view, uint32_t edges) { - input->mode = ROOTS_CURSOR_RESIZE; - input->offs_x = cursor->x; - input->offs_y = cursor->y; - input->view_x = view->x; - input->view_y = view->y; - struct wlr_box size; - view_get_size(view, &size); - input->view_width = size.width; - input->view_height = size.height; - input->resize_edges = edges; - wlr_seat_pointer_clear_focus(input->wl_seat); - - struct wlr_xcursor *xcursor = get_resize_xcursor(input->xcursor_theme, edges); - if (xcursor != NULL) { - cursor_set_xcursor_image(input, xcursor->images[0]); - } +void roots_cursor_destroy(struct roots_cursor *cursor) { + // TODO } -void view_begin_rotate(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view) { - input->mode = ROOTS_CURSOR_ROTATE; - input->offs_x = cursor->x; - input->offs_y = cursor->y; - input->view_rotation = view->rotation; - wlr_seat_pointer_clear_focus(input->wl_seat); - - struct wlr_xcursor *xcursor = get_rotate_xcursor(input->xcursor_theme); - if (xcursor != NULL) { - cursor_set_xcursor_image(input, xcursor->images[0]); - } +static void cursor_set_xcursor_image(struct roots_cursor *cursor, + struct wlr_xcursor_image *image) { + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); } -void cursor_update_position(struct roots_input *input, uint32_t time) { - struct roots_desktop *desktop = input->server->desktop; +static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { + struct roots_desktop *desktop = cursor->seat->input->server->desktop; + struct roots_seat *seat = cursor->seat; struct roots_view *view; struct wlr_surface *surface; double sx, sy; - switch (input->mode) { + switch (cursor->mode) { case ROOTS_CURSOR_PASSTHROUGH: - view = view_at(desktop, input->cursor->x, input->cursor->y, + view = view_at(desktop, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); - bool set_compositor_cursor = !view && input->cursor_client; + bool set_compositor_cursor = !view && cursor->cursor_client; if (view) { struct wl_client *view_client = wl_resource_get_client(view->wlr_surface->resource); - set_compositor_cursor = view_client != input->cursor_client; + set_compositor_cursor = view_client != cursor->cursor_client; } if (set_compositor_cursor) { - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - cursor_set_xcursor_image(input, xcursor->images[0]); - input->cursor_client = NULL; + struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); + cursor_set_xcursor_image(cursor, xcursor->images[0]); + cursor->cursor_client = NULL; } if (view) { - wlr_seat_pointer_notify_enter(input->wl_seat, surface, sx, sy); - wlr_seat_pointer_notify_motion(input->wl_seat, time, sx, sy); + wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); } else { - wlr_seat_pointer_clear_focus(input->wl_seat); + wlr_seat_pointer_clear_focus(seat->seat); } break; case ROOTS_CURSOR_MOVE: - if (input->active_view) { - double dx = input->cursor->x - input->offs_x; - double dy = input->cursor->y - input->offs_y; - view_move(input->active_view, input->view_x + dx, - input->view_y + dy); + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + view_move(seat->focus, cursor->view_x + dx, + cursor->view_y + dy); } break; case ROOTS_CURSOR_RESIZE: - if (input->active_view) { - double dx = input->cursor->x - input->offs_x; - double dy = input->cursor->y - input->offs_y; - double active_x = input->active_view->x; - double active_y = input->active_view->y; - int width = input->view_width; - int height = input->view_height; - if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { - active_y = input->view_y + dy; + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + double active_x = seat->focus->x; + double active_y = seat->focus->y; + int width = cursor->view_width; + int height = cursor->view_height; + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { + active_y = cursor->view_y + dy; height -= dy; if (height < 0) { active_y += height; } - } else if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { height += dy; } - if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { - active_x = input->view_x + dx; + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { + active_x = cursor->view_x + dx; width -= dx; if (width < 0) { active_x += width; } - } else if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { width += dx; } @@ -157,132 +103,51 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { height = 0; } - if (active_x != input->active_view->x || - active_y != input->active_view->y) { - view_move_resize(input->active_view, active_x, active_y, + if (active_x != seat->focus->x || + active_y != seat->focus->y) { + view_move_resize(seat->focus, active_x, active_y, width, height); } else { - view_resize(input->active_view, width, height); + view_resize(seat->focus, width, height); } } break; case ROOTS_CURSOR_ROTATE: - if (input->active_view) { - struct roots_view *view = input->active_view; + if (seat->focus) { + struct roots_view *view = seat->focus; int ox = view->x + view->wlr_surface->current->width/2, oy = view->y + view->wlr_surface->current->height/2; - int ux = input->offs_x - ox, - uy = input->offs_y - oy; - int vx = input->cursor->x - ox, - vy = input->cursor->y - oy; + int ux = cursor->offs_x - ox, + uy = cursor->offs_y - oy; + int vx = cursor->cursor->x - ox, + vy = cursor->cursor->y - oy; float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); int steps = 12; angle = round(angle/M_PI*steps) / (steps/M_PI); - view->rotation = input->view_rotation + angle; + view->rotation = cursor->view_rotation + angle; } break; } -} - -void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, - struct roots_view *view) { - if (input->active_view == view) { - return; - } - input->active_view = view; - input->mode = ROOTS_CURSOR_PASSTHROUGH; - if (!view) { - return; - } - - if (view->type == ROOTS_XWAYLAND_VIEW && - view->xwayland_surface->override_redirect) { - return; - } - - size_t index = 0; - for (size_t i = 0; i < desktop->views->length; ++i) { - struct roots_view *_view = desktop->views->items[i]; - if (_view != view) { - view_activate(_view, false); - } else { - index = i; - } - } - view_activate(view, true); - // TODO: list_swap - wlr_list_del(desktop->views, index); - wlr_list_add(desktop->views, view); - wlr_seat_keyboard_notify_enter(input->wl_seat, view->wlr_surface); -} - -static void handle_cursor_motion(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, cursor_motion); - struct wlr_event_pointer_motion *event = data; - wlr_cursor_move(input->cursor, event->device, - event->delta_x, event->delta_y); - cursor_update_position(input, event->time_msec); -} - -static void handle_cursor_motion_absolute(struct wl_listener *listener, - void *data) { - struct roots_input *input = wl_container_of(listener, - input, cursor_motion_absolute); - struct wlr_event_pointer_motion_absolute *event = data; - wlr_cursor_warp_absolute(input->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); - cursor_update_position(input, event->time_msec); -} - -static void handle_cursor_axis(struct wl_listener *listener, void *data) { - struct roots_input *input = - wl_container_of(listener, input, cursor_axis); - struct wlr_event_pointer_axis *event = data; - wlr_seat_pointer_notify_axis(input->wl_seat, event->time_msec, - event->orientation, event->delta); -} - -static bool is_meta_pressed(struct roots_input *input, - struct wlr_input_device *device) { - uint32_t meta_key = 0; - struct keyboard_config *config; - if ((config = config_get_keyboard(input->server->config, device))) { - meta_key = config->meta_key; - } else if (!meta_key && (config = config_get_keyboard(input->server->config, - NULL))) { - meta_key = config->meta_key; - } - if (meta_key == 0) { - return false; - } - struct roots_keyboard *keyboard; - wl_list_for_each(keyboard, &input->keyboards, link) { - uint32_t modifiers = - wlr_keyboard_get_modifiers(keyboard->device->keyboard); - if ((modifiers ^ meta_key) == 0) { - return true; - } - } - return false; } -static void do_cursor_button_press(struct roots_input *input, - struct wlr_cursor *cursor, struct wlr_input_device *device, - uint32_t time, uint32_t button, uint32_t state) { - struct roots_desktop *desktop = input->server->desktop; +static void roots_cursor_press_button(struct roots_cursor *cursor, + struct wlr_input_device *device, uint32_t time, uint32_t button, + uint32_t state) { + struct roots_seat *seat = cursor->seat; + struct roots_desktop *desktop = seat->input->server->desktop; struct wlr_surface *surface; double sx, sy; struct roots_view *view = view_at(desktop, - input->cursor->x, input->cursor->y, &surface, &sx, &sy); + cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); - if (state == WLR_BUTTON_PRESSED && view && is_meta_pressed(input, device)) { - set_view_focus(input, desktop, view); + if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { + roots_seat_focus_view(seat, view); uint32_t edges; switch (button) { case BTN_LEFT: - view_begin_move(input, cursor, view); + roots_seat_begin_move(seat, view); break; case BTN_RIGHT: edges = 0; @@ -296,117 +161,146 @@ static void do_cursor_button_press(struct roots_input *input, } else { edges |= ROOTS_CURSOR_RESIZE_EDGE_BOTTOM; } - view_begin_resize(input, cursor, view, edges); + roots_seat_begin_resize(seat, view, edges); break; case BTN_MIDDLE: - view_begin_rotate(input, cursor, view); + roots_seat_begin_rotate(seat, view); break; } return; } - uint32_t serial = wlr_seat_pointer_notify_button(input->wl_seat, time, button, - state); + uint32_t serial = + wlr_seat_pointer_notify_button(seat->seat, time, button, state); int i; switch (state) { case WLR_BUTTON_RELEASED: - set_view_focus(input, desktop, NULL); - cursor_update_position(input, time); + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + roots_cursor_update_position(cursor, time); break; case WLR_BUTTON_PRESSED: - i = input->input_events_idx; - input->input_events[i].serial = serial; - input->input_events[i].cursor = cursor; - input->input_events[i].device = device; - input->input_events_idx = (i + 1) - % (sizeof(input->input_events) / sizeof(input->input_events[0])); - set_view_focus(input, desktop, view); + i = cursor->input_events_idx; + cursor->input_events[i].serial = serial; + cursor->input_events[i].cursor = cursor->cursor; + cursor->input_events[i].device = device; + cursor->input_events_idx = (i + 1) + % (sizeof(cursor->input_events) / sizeof(cursor->input_events[0])); + roots_seat_focus_view(seat, view); break; } } -static void handle_cursor_button(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, cursor_button); - struct wlr_event_pointer_button *event = data; - do_cursor_button_press(input, input->cursor, event->device, - event->time_msec, event->button, event->state); +void roots_cursor_handle_motion(struct roots_cursor *cursor, + struct wlr_event_pointer_motion *event) { + wlr_cursor_move(cursor->cursor, event->device, + event->delta_x, event->delta_y); + roots_cursor_update_position(cursor, event->time_msec); +} + +void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, + struct wlr_event_pointer_motion_absolute *event) { + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); + roots_cursor_update_position(cursor, event->time_msec); +} + +void roots_cursor_handle_button(struct roots_cursor *cursor, + struct wlr_event_pointer_button *event) { + roots_cursor_press_button(cursor, event->device, event->time_msec, + event->button, event->state); } -static void handle_touch_down(struct wl_listener *listener, void *data) { - struct wlr_event_touch_down *event = data; - struct roots_input *input = - wl_container_of(listener, input, cursor_touch_down); +void roots_cursor_handle_axis(struct roots_cursor *cursor, + struct wlr_event_pointer_axis *event) { + wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, + event->orientation, event->delta); +} + +void roots_cursor_handle_touch_down(struct roots_cursor *cursor, + struct wlr_event_touch_down *event) { struct roots_touch_point *point = calloc(1, sizeof(struct roots_touch_point)); + if (!point) { + wlr_log(L_ERROR, "could not allocate memory for touch point"); + return; + } + point->device = event->device->data; point->slot = event->slot; point->x = event->x_mm / event->width_mm; point->y = event->y_mm / event->height_mm; - wlr_cursor_warp_absolute(input->cursor, event->device, point->x, point->y); - cursor_update_position(input, event->time_msec); - wl_list_insert(&input->touch_points, &point->link); - do_cursor_button_press(input, input->cursor, event->device, + wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + wl_list_insert(&cursor->touch_points, &point->link); + roots_cursor_press_button(cursor, event->device, event->time_msec, BTN_LEFT, 1); } -static void handle_touch_up(struct wl_listener *listener, void *data) { - struct wlr_event_touch_up *event = data; - struct roots_input *input = - wl_container_of(listener, input, cursor_touch_up); +void roots_cursor_handle_touch_up(struct roots_cursor *cursor, + struct wlr_event_touch_up *event) { struct roots_touch_point *point; - wl_list_for_each(point, &input->touch_points, link) { + wl_list_for_each(point, &cursor->touch_points, link) { if (point->slot == event->slot) { wl_list_remove(&point->link); + free(point); break; } } - do_cursor_button_press(input, input->cursor, event->device, + roots_cursor_press_button(cursor, event->device, event->time_msec, BTN_LEFT, 0); } -static void handle_touch_motion(struct wl_listener *listener, void *data) { - struct wlr_event_touch_motion *event = data; - struct roots_input *input = - wl_container_of(listener, input, cursor_touch_motion); +void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, + struct wlr_event_touch_motion *event) { struct roots_touch_point *point; - wl_list_for_each(point, &input->touch_points, link) { + wl_list_for_each(point, &cursor->touch_points, link) { if (point->slot == event->slot) { point->x = event->x_mm / event->width_mm; point->y = event->y_mm / event->height_mm; - wlr_cursor_warp_absolute(input->cursor, event->device, + wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); - cursor_update_position(input, event->time_msec); + roots_cursor_update_position(cursor, event->time_msec); break; } } } -static void handle_tool_axis(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, cursor_tool_axis); - struct wlr_event_tablet_tool_axis *event = data; +void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_axis *event) { if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - wlr_cursor_warp_absolute(input->cursor, event->device, + wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x_mm / event->width_mm, event->y_mm / event->height_mm); - cursor_update_position(input, event->time_msec); + roots_cursor_update_position(cursor, event->time_msec); } } -static void handle_tool_tip(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, cursor_tool_tip); - struct wlr_event_tablet_tool_tip *event = data; - do_cursor_button_press(input, input->cursor, event->device, +void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_tip *event) { + roots_cursor_press_button(cursor, event->device, event->time_msec, BTN_LEFT, event->state); } -static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { - struct roots_drag_icon *drag_icon = - wl_container_of(listener, drag_icon, surface_destroy); - wl_list_remove(&drag_icon->link); - wl_list_remove(&drag_icon->surface_destroy.link); - wl_list_remove(&drag_icon->surface_commit.link); - free(drag_icon); +void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, + struct wlr_seat_pointer_request_set_cursor_event *event) { + struct wlr_surface *focused_surface = + event->seat_client->seat->pointer_state.focused_surface; + bool has_focused = focused_surface != NULL && focused_surface->resource != NULL; + struct wl_client *focused_client = NULL; + if (has_focused) { + focused_client = wl_resource_get_client(focused_surface->resource); + } + if (event->seat_client->client != focused_client || + cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { + wlr_log(L_DEBUG, "Denying request to set cursor from unfocused client"); + return; + } + + wlr_log(L_DEBUG, "Setting client cursor"); + wlr_cursor_set_surface(cursor->cursor, event->surface, event->hotspot_x, + event->hotspot_y); + cursor->cursor_client = event->seat_client->client; } static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { @@ -416,17 +310,23 @@ static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { drag_icon->sy += drag_icon->surface->current->sy; } -static void handle_pointer_grab_begin(struct wl_listener *listener, - void *data) { - struct roots_input *input = - wl_container_of(listener, input, pointer_grab_begin); - struct wlr_seat_pointer_grab *grab = data; +static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { + struct roots_drag_icon *drag_icon = + wl_container_of(listener, drag_icon, surface_destroy); + wl_list_remove(&drag_icon->link); + wl_list_remove(&drag_icon->surface_destroy.link); + wl_list_remove(&drag_icon->surface_commit.link); + free(drag_icon); +} +void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { + struct roots_seat *seat = cursor->seat; if (grab->interface == &wlr_data_device_pointer_drag_interface) { struct wlr_drag *drag = grab->data; if (drag->icon) { struct roots_drag_icon *iter_icon; - wl_list_for_each(iter_icon, &input->drag_icons, link) { + wl_list_for_each(iter_icon, &seat->drag_icons, link) { if (iter_icon->surface == drag->icon) { // already in the list return; @@ -437,7 +337,7 @@ static void handle_pointer_grab_begin(struct wl_listener *listener, calloc(1, sizeof(struct roots_drag_icon)); drag_icon->mapped = true; drag_icon->surface = drag->icon; - wl_list_insert(&input->drag_icons, &drag_icon->link); + wl_list_insert(&seat->drag_icons, &drag_icon->link); wl_signal_add(&drag->icon->events.destroy, &drag_icon->surface_destroy); @@ -450,155 +350,17 @@ static void handle_pointer_grab_begin(struct wl_listener *listener, } } -static void handle_pointer_grab_end(struct wl_listener *listener, void *data) { - struct roots_input *input = - wl_container_of(listener, input, pointer_grab_end); - struct wlr_seat_pointer_grab *grab = data; - +void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { if (grab->interface == &wlr_data_device_pointer_drag_interface) { struct wlr_drag *drag = grab->data; struct roots_drag_icon *icon; - wl_list_for_each(icon, &input->drag_icons, link) { + wl_list_for_each(icon, &cursor->seat->drag_icons, link) { if (icon->surface == drag->icon) { icon->mapped = false; } } } - cursor_update_position(input, 0); -} - -static void handle_request_set_cursor(struct wl_listener *listener, - void *data) { - struct roots_input *input = wl_container_of(listener, input, - request_set_cursor); - struct wlr_seat_pointer_request_set_cursor_event *event = data; - - struct wlr_surface *focused_surface = - event->seat_client->seat->pointer_state.focused_surface; - bool ok = focused_surface != NULL && focused_surface->resource != NULL; - if (ok) { - struct wl_client *focused_client = - wl_resource_get_client(focused_surface->resource); - ok = event->seat_client->client == focused_client; - } - if (!ok || input->mode != ROOTS_CURSOR_PASSTHROUGH) { - wlr_log(L_DEBUG, "Denying request to set cursor from unfocused client"); - return; - } - - wlr_log(L_DEBUG, "Setting client cursor"); - wlr_cursor_set_surface(input->cursor, event->surface, event->hotspot_x, - event->hotspot_y); - input->cursor_client = event->seat_client->client; -} - -void cursor_initialize(struct roots_input *input) { - struct wlr_cursor *cursor = input->cursor; - - // TODO: Does this belong here - wl_list_init(&input->touch_points); - - wl_signal_add(&cursor->events.motion, &input->cursor_motion); - input->cursor_motion.notify = handle_cursor_motion; - - wl_signal_add(&cursor->events.motion_absolute, - &input->cursor_motion_absolute); - input->cursor_motion_absolute.notify = handle_cursor_motion_absolute; - - wl_signal_add(&cursor->events.button, &input->cursor_button); - input->cursor_button.notify = handle_cursor_button; - - wl_signal_add(&cursor->events.axis, &input->cursor_axis); - input->cursor_axis.notify = handle_cursor_axis; - - wl_signal_add(&cursor->events.touch_down, &input->cursor_touch_down); - input->cursor_touch_down.notify = handle_touch_down; - - wl_signal_add(&cursor->events.touch_up, &input->cursor_touch_up); - input->cursor_touch_up.notify = handle_touch_up; - - wl_signal_add(&cursor->events.touch_motion, &input->cursor_touch_motion); - input->cursor_touch_motion.notify = handle_touch_motion; - - wl_signal_add(&cursor->events.tablet_tool_axis, &input->cursor_tool_axis); - input->cursor_tool_axis.notify = handle_tool_axis; - - wl_signal_add(&cursor->events.tablet_tool_tip, &input->cursor_tool_tip); - input->cursor_tool_tip.notify = handle_tool_tip; - - wl_signal_add(&input->wl_seat->events.pointer_grab_end, &input->pointer_grab_end); - input->pointer_grab_end.notify = handle_pointer_grab_end; - - wl_signal_add(&input->wl_seat->events.pointer_grab_begin, &input->pointer_grab_begin); - input->pointer_grab_begin.notify = handle_pointer_grab_begin; - - wl_list_init(&input->request_set_cursor.link); - - wl_signal_add(&input->wl_seat->events.request_set_cursor, - &input->request_set_cursor); - input->request_set_cursor.notify = handle_request_set_cursor; -} - -static void reset_device_mappings(struct roots_config *config, - struct wlr_cursor *cursor, struct wlr_input_device *device) { - wlr_cursor_map_input_to_output(cursor, device, NULL); - struct device_config *dconfig; - if ((dconfig = config_get_device(config, device))) { - wlr_cursor_map_input_to_region(cursor, device, dconfig->mapped_box); - } -} - -static void set_device_output_mappings(struct roots_config *config, - struct wlr_cursor *cursor, struct wlr_output *output, - struct wlr_input_device *device) { - struct device_config *dconfig; - dconfig = config_get_device(config, device); - if (dconfig && dconfig->mapped_output && - strcmp(dconfig->mapped_output, output->name) == 0) { - wlr_cursor_map_input_to_output(cursor, device, output); - } -} - -void cursor_load_config(struct roots_config *config, - struct wlr_cursor *cursor, - struct roots_input *input, - struct roots_desktop *desktop) { - struct roots_pointer *pointer; - struct roots_touch *touch; - struct roots_tablet_tool *tablet_tool; - struct roots_output *output; - - // reset mappings - wlr_cursor_map_to_output(cursor, NULL); - wl_list_for_each(pointer, &input->pointers, link) { - reset_device_mappings(config, cursor, pointer->device); - } - wl_list_for_each(touch, &input->touch, link) { - reset_device_mappings(config, cursor, touch->device); - } - wl_list_for_each(tablet_tool, &input->tablet_tools, link) { - reset_device_mappings(config, cursor, tablet_tool->device); - } - - // configure device to output mappings - const char *mapped_output = config->cursor.mapped_output; - wl_list_for_each(output, &desktop->outputs, link) { - if (mapped_output && strcmp(mapped_output, output->wlr_output->name) == 0) { - wlr_cursor_map_to_output(cursor, output->wlr_output); - } - - wl_list_for_each(pointer, &input->pointers, link) { - set_device_output_mappings(config, cursor, output->wlr_output, - pointer->device); - } - wl_list_for_each(tablet_tool, &input->tablet_tools, link) { - set_device_output_mappings(config, cursor, output->wlr_output, - tablet_tool->device); - } - wl_list_for_each(touch, &input->touch, link) { - set_device_output_mappings(config, cursor, output->wlr_output, - touch->device); - } - } + roots_cursor_update_position(cursor, 0); } diff --git a/rootston/meson.build b/rootston/meson.build index 062f56fc..9c543c4f 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,7 +1,6 @@ sources = [ 'config.c', - #'cursor.c', - 'roots_cursor.c', + 'cursor.c', 'desktop.c', 'ini.c', 'input.c', diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c deleted file mode 100644 index c8abe098..00000000 --- a/rootston/roots_cursor.c +++ /dev/null @@ -1,366 +0,0 @@ -#define _XOPEN_SOURCE 700 -#include -#include -#ifdef __linux__ -#include -#elif __FreeBSD__ -#include -#endif -#include -#include "rootston/xcursor.h" -#include "rootston/cursor.h" - -struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { - struct roots_cursor *cursor = calloc(1, sizeof(struct roots_cursor)); - if (!cursor) { - return NULL; - } - cursor->cursor = wlr_cursor_create(); - if (!cursor->cursor) { - return NULL; - } - - return cursor; -} - -void roots_cursor_destroy(struct roots_cursor *cursor) { - // TODO -} - -static void cursor_set_xcursor_image(struct roots_cursor *cursor, - struct wlr_xcursor_image *image) { - wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); -} - -static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { - struct roots_desktop *desktop = cursor->seat->input->server->desktop; - struct roots_seat *seat = cursor->seat; - struct roots_view *view; - struct wlr_surface *surface; - double sx, sy; - switch (cursor->mode) { - case ROOTS_CURSOR_PASSTHROUGH: - view = view_at(desktop, cursor->cursor->x, cursor->cursor->y, - &surface, &sx, &sy); - bool set_compositor_cursor = !view && cursor->cursor_client; - if (view) { - struct wl_client *view_client = - wl_resource_get_client(view->wlr_surface->resource); - set_compositor_cursor = view_client != cursor->cursor_client; - } - if (set_compositor_cursor) { - struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); - cursor_set_xcursor_image(cursor, xcursor->images[0]); - cursor->cursor_client = NULL; - } - if (view) { - wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); - wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); - } else { - wlr_seat_pointer_clear_focus(seat->seat); - } - break; - case ROOTS_CURSOR_MOVE: - if (seat->focus) { - double dx = cursor->cursor->x - cursor->offs_x; - double dy = cursor->cursor->y - cursor->offs_y; - view_move(seat->focus, cursor->view_x + dx, - cursor->view_y + dy); - } - break; - case ROOTS_CURSOR_RESIZE: - if (seat->focus) { - double dx = cursor->cursor->x - cursor->offs_x; - double dy = cursor->cursor->y - cursor->offs_y; - double active_x = seat->focus->x; - double active_y = seat->focus->y; - int width = cursor->view_width; - int height = cursor->view_height; - if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { - active_y = cursor->view_y + dy; - height -= dy; - if (height < 0) { - active_y += height; - } - } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { - height += dy; - } - if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { - active_x = cursor->view_x + dx; - width -= dx; - if (width < 0) { - active_x += width; - } - } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { - width += dx; - } - - if (width < 0) { - width = 0; - } - if (height < 0) { - height = 0; - } - - if (active_x != seat->focus->x || - active_y != seat->focus->y) { - view_move_resize(seat->focus, active_x, active_y, - width, height); - } else { - view_resize(seat->focus, width, height); - } - } - break; - case ROOTS_CURSOR_ROTATE: - if (seat->focus) { - struct roots_view *view = seat->focus; - int ox = view->x + view->wlr_surface->current->width/2, - oy = view->y + view->wlr_surface->current->height/2; - int ux = cursor->offs_x - ox, - uy = cursor->offs_y - oy; - int vx = cursor->cursor->x - ox, - vy = cursor->cursor->y - oy; - float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); - int steps = 12; - angle = round(angle/M_PI*steps) / (steps/M_PI); - view->rotation = cursor->view_rotation + angle; - } - break; - } - -} - -static void roots_cursor_press_button(struct roots_cursor *cursor, - struct wlr_input_device *device, uint32_t time, uint32_t button, - uint32_t state) { - struct roots_seat *seat = cursor->seat; - struct roots_desktop *desktop = seat->input->server->desktop; - struct wlr_surface *surface; - double sx, sy; - struct roots_view *view = view_at(desktop, - cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); - - if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { - roots_seat_focus_view(seat, view); - - uint32_t edges; - switch (button) { - case BTN_LEFT: - roots_seat_begin_move(seat, view); - break; - case BTN_RIGHT: - edges = 0; - if (sx < view->wlr_surface->current->width/2) { - edges |= ROOTS_CURSOR_RESIZE_EDGE_LEFT; - } else { - edges |= ROOTS_CURSOR_RESIZE_EDGE_RIGHT; - } - if (sy < view->wlr_surface->current->height/2) { - edges |= ROOTS_CURSOR_RESIZE_EDGE_TOP; - } else { - edges |= ROOTS_CURSOR_RESIZE_EDGE_BOTTOM; - } - roots_seat_begin_resize(seat, view, edges); - break; - case BTN_MIDDLE: - roots_seat_begin_rotate(seat, view); - break; - } - return; - } - - uint32_t serial = - wlr_seat_pointer_notify_button(seat->seat, time, button, state); - - int i; - switch (state) { - case WLR_BUTTON_RELEASED: - seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; - roots_cursor_update_position(cursor, time); - break; - case WLR_BUTTON_PRESSED: - i = cursor->input_events_idx; - cursor->input_events[i].serial = serial; - cursor->input_events[i].cursor = cursor->cursor; - cursor->input_events[i].device = device; - cursor->input_events_idx = (i + 1) - % (sizeof(cursor->input_events) / sizeof(cursor->input_events[0])); - roots_seat_focus_view(seat, view); - break; - } -} - -void roots_cursor_handle_motion(struct roots_cursor *cursor, - struct wlr_event_pointer_motion *event) { - wlr_cursor_move(cursor->cursor, event->device, - event->delta_x, event->delta_y); - roots_cursor_update_position(cursor, event->time_msec); -} - -void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, - struct wlr_event_pointer_motion_absolute *event) { - wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); - roots_cursor_update_position(cursor, event->time_msec); -} - -void roots_cursor_handle_button(struct roots_cursor *cursor, - struct wlr_event_pointer_button *event) { - roots_cursor_press_button(cursor, event->device, event->time_msec, - event->button, event->state); -} - -void roots_cursor_handle_axis(struct roots_cursor *cursor, - struct wlr_event_pointer_axis *event) { - wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, - event->orientation, event->delta); -} - -void roots_cursor_handle_touch_down(struct roots_cursor *cursor, - struct wlr_event_touch_down *event) { - struct roots_touch_point *point = - calloc(1, sizeof(struct roots_touch_point)); - if (!point) { - wlr_log(L_ERROR, "could not allocate memory for touch point"); - return; - } - - point->device = event->device->data; - point->slot = event->slot; - point->x = event->x_mm / event->width_mm; - point->y = event->y_mm / event->height_mm; - wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); - roots_cursor_update_position(cursor, event->time_msec); - wl_list_insert(&cursor->touch_points, &point->link); - roots_cursor_press_button(cursor, event->device, - event->time_msec, BTN_LEFT, 1); -} - -void roots_cursor_handle_touch_up(struct roots_cursor *cursor, - struct wlr_event_touch_up *event) { - struct roots_touch_point *point; - wl_list_for_each(point, &cursor->touch_points, link) { - if (point->slot == event->slot) { - wl_list_remove(&point->link); - free(point); - break; - } - } - roots_cursor_press_button(cursor, event->device, - event->time_msec, BTN_LEFT, 0); -} - -void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, - struct wlr_event_touch_motion *event) { - struct roots_touch_point *point; - wl_list_for_each(point, &cursor->touch_points, link) { - if (point->slot == event->slot) { - point->x = event->x_mm / event->width_mm; - point->y = event->y_mm / event->height_mm; - wlr_cursor_warp_absolute(cursor->cursor, event->device, - point->x, point->y); - roots_cursor_update_position(cursor, event->time_msec); - break; - } - } -} - -void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, - struct wlr_event_tablet_tool_axis *event) { - if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && - (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); - roots_cursor_update_position(cursor, event->time_msec); - } -} - -void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, - struct wlr_event_tablet_tool_tip *event) { - roots_cursor_press_button(cursor, event->device, - event->time_msec, BTN_LEFT, event->state); -} - -void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, - struct wlr_seat_pointer_request_set_cursor_event *event) { - struct wlr_surface *focused_surface = - event->seat_client->seat->pointer_state.focused_surface; - bool has_focused = focused_surface != NULL && focused_surface->resource != NULL; - struct wl_client *focused_client = NULL; - if (has_focused) { - focused_client = wl_resource_get_client(focused_surface->resource); - } - if (event->seat_client->client != focused_client || - cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { - wlr_log(L_DEBUG, "Denying request to set cursor from unfocused client"); - return; - } - - wlr_log(L_DEBUG, "Setting client cursor"); - wlr_cursor_set_surface(cursor->cursor, event->surface, event->hotspot_x, - event->hotspot_y); - cursor->cursor_client = event->seat_client->client; -} - -static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { - struct roots_drag_icon *drag_icon = - wl_container_of(listener, drag_icon, surface_commit); - drag_icon->sx += drag_icon->surface->current->sx; - drag_icon->sy += drag_icon->surface->current->sy; -} - -static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { - struct roots_drag_icon *drag_icon = - wl_container_of(listener, drag_icon, surface_destroy); - wl_list_remove(&drag_icon->link); - wl_list_remove(&drag_icon->surface_destroy.link); - wl_list_remove(&drag_icon->surface_commit.link); - free(drag_icon); -} - -void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, - struct wlr_seat_pointer_grab *grab) { - struct roots_seat *seat = cursor->seat; - if (grab->interface == &wlr_data_device_pointer_drag_interface) { - struct wlr_drag *drag = grab->data; - if (drag->icon) { - struct roots_drag_icon *iter_icon; - wl_list_for_each(iter_icon, &seat->drag_icons, link) { - if (iter_icon->surface == drag->icon) { - // already in the list - return; - } - } - - struct roots_drag_icon *drag_icon = - calloc(1, sizeof(struct roots_drag_icon)); - drag_icon->mapped = true; - drag_icon->surface = drag->icon; - wl_list_insert(&seat->drag_icons, &drag_icon->link); - - wl_signal_add(&drag->icon->events.destroy, - &drag_icon->surface_destroy); - drag_icon->surface_destroy.notify = handle_drag_icon_destroy; - - wl_signal_add(&drag->icon->events.commit, - &drag_icon->surface_commit); - drag_icon->surface_commit.notify = handle_drag_icon_commit; - } - } -} - -void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, - struct wlr_seat_pointer_grab *grab) { - if (grab->interface == &wlr_data_device_pointer_drag_interface) { - struct wlr_drag *drag = grab->data; - struct roots_drag_icon *icon; - wl_list_for_each(icon, &cursor->seat->drag_icons, link) { - if (icon->surface == drag->icon) { - icon->mapped = false; - } - } - } - - roots_cursor_update_position(cursor, 0); -} From 739361aa70d61cbc9e062d6a90df09f258a1bbcb Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 17:29:28 -0500 Subject: [PATCH 18/21] wlr-keyboard: take out modifiers event struct (for now) --- backend/libinput/keyboard.c | 1 - backend/wayland/wl_seat.c | 12 ++---------- backend/x11/backend.c | 1 - include/rootston/keyboard.h | 3 +-- include/wlr/interfaces/wlr_keyboard.h | 3 ++- include/wlr/types/wlr_keyboard.h | 11 ----------- rootston/keyboard.c | 3 +-- rootston/seat.c | 3 +-- types/wlr_keyboard.c | 11 ++++++----- 9 files changed, 13 insertions(+), 35 deletions(-) diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 9a24c791..065d8ead 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -54,7 +54,6 @@ void handle_keyboard_key(struct libinput_event *event, struct libinput_event_keyboard *kbevent = libinput_event_get_keyboard_event(event); struct wlr_event_keyboard_key wlr_event = { 0 }; - wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent)); wlr_event.keycode = libinput_event_keyboard_get_key(kbevent); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 74eaf9bd..a2da8df5 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -151,7 +151,6 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, assert(dev && dev->keyboard); struct wlr_event_keyboard_key wlr_event; - wlr_event.device = dev; wlr_event.keycode = key; wlr_event.state = state; wlr_event.time_msec = time; @@ -163,15 +162,8 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar uint32_t mods_locked, uint32_t group) { struct wlr_input_device *dev = data; assert(dev && dev->keyboard); - struct wlr_event_keyboard_modifiers wlr_event; - wlr_event.device = dev; - wlr_event.keyboard = dev->keyboard; - wlr_event.mods_depressed = mods_depressed; - wlr_event.mods_latched = mods_latched; - wlr_event.mods_locked = mods_locked; - wlr_event.group = group; - - wlr_keyboard_notify_modifiers(dev->keyboard, &wlr_event); + wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, + mods_locked, group); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index f76b314e..97b0dd8c 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -50,7 +50,6 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e case XCB_KEY_RELEASE: { xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; struct wlr_event_keyboard_key key = { - .device = &x11->keyboard_dev, .time_msec = ev->time, .keycode = ev->detail - 8, .state = event->response_type == XCB_KEY_PRESS ? diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 4dd70a65..51977f08 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -27,7 +27,6 @@ void roots_keyboard_destroy(struct roots_keyboard *keyboard); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, - struct wlr_event_keyboard_modifiers *event); +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); #endif diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 5848416d..570f5721 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -14,6 +14,7 @@ void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - struct wlr_event_keyboard_modifiers *event); + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group); #endif diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 4bd5b9b6..e2d50b03 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -66,23 +66,12 @@ enum wlr_key_state { }; struct wlr_event_keyboard_key { - struct wlr_input_device *device; - struct wlr_keyboard *keyboard; uint32_t time_msec; uint32_t keycode; bool update_state; enum wlr_key_state state; }; -struct wlr_event_keyboard_modifiers { - struct wlr_input_device *device; - struct wlr_keyboard *keyboard; - uint32_t mods_depressed; - uint32_t mods_latched; - uint32_t mods_locked; - uint32_t group; -}; - void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 9692ea7d..da75b44f 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -204,8 +204,7 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, } } -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, - struct wlr_event_keyboard_modifiers *event) { +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { struct wlr_seat *seat = r_keyboard->seat->seat; wlr_seat_set_keyboard(seat, r_keyboard->device); wlr_seat_keyboard_notify_modifiers(seat); diff --git a/rootston/seat.c b/rootston/seat.c index ce8ad10b..97d5c7e4 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -22,8 +22,7 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, keyboard_modifiers); - struct wlr_event_keyboard_modifiers *event = data; - roots_keyboard_handle_modifiers(keyboard, event); + roots_keyboard_handle_modifiers(keyboard); } static void handle_cursor_motion(struct wl_listener *listener, void *data) { diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index a301c6e0..98ebeed5 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -41,6 +41,8 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { keyboard->modifiers.latched = latched; keyboard->modifiers.locked = locked; keyboard->modifiers.group = group; + + wl_signal_emit(&keyboard->events.modifiers, keyboard); } static void keyboard_key_update(struct wlr_keyboard *keyboard, @@ -68,15 +70,14 @@ static void keyboard_key_update(struct wlr_keyboard *keyboard, } void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - struct wlr_event_keyboard_modifiers *event) { + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) { if (!keyboard->xkb_state) { return; } - xkb_state_update_mask(keyboard->xkb_state, event->mods_depressed, - event->mods_latched, event->mods_locked, 0, 0, event->group); + xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, + mods_locked, 0, 0, group); keyboard_modifier_update(keyboard); - - wl_signal_emit(&keyboard->events.modifiers, event); } void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, From d6513cef5dc3f2c20e1bf11ff6a468b60ce35aca Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 17:47:59 -0500 Subject: [PATCH 19/21] rootston: add missing properties to kb config merge --- rootston/keyboard.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rootston/keyboard.c b/rootston/keyboard.c index da75b44f..72567eef 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -230,6 +230,12 @@ static void keyboard_config_merge(struct keyboard_config *config, if (config->options == NULL) { config->options = fallback->options; } + if (config->meta_key == 0) { + config->meta_key = fallback->meta_key; + } + if (config->name == NULL) { + config->name = fallback->name; + } } struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, From 1472dbda74dea5387a4d0e531b641734131dc705 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 18:32:54 -0500 Subject: [PATCH 20/21] rootston: roots_keyboard null check --- rootston/keyboard.c | 4 ++++ rootston/seat.c | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 72567eef..bb748550 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -249,6 +249,10 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->input = input; struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + if (config == NULL) { + free(keyboard); + return NULL; + } keyboard_config_merge(config, config_get_keyboard(input->config, device)); keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); diff --git a/rootston/seat.c b/rootston/seat.c index 97d5c7e4..72e94aec 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -306,6 +306,11 @@ void roots_seat_destroy(struct roots_seat *seat) { static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); + if (keyboard == NULL) { + wlr_log(L_ERROR, "could not allocate keyboard for seat"); + return; + } + keyboard->seat = seat; wl_list_insert(&seat->keyboards, &keyboard->link); From 27a3a810ab372ca699bb9da1ce506816432b39f6 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 10 Nov 2017 08:27:45 -0500 Subject: [PATCH 21/21] rootston: fix multiseat focus --- include/rootston/input.h | 2 ++ rootston/input.c | 14 ++++++++++++++ rootston/seat.c | 35 ++++++++++------------------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/include/rootston/input.h b/include/rootston/input.h index ea0bbeb6..0af48577 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -26,4 +26,6 @@ void input_destroy(struct roots_input *input); struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, struct wlr_seat *seat); +bool input_view_has_focus(struct roots_input *input, struct roots_view *view); + #endif diff --git a/rootston/input.c b/rootston/input.c index 92148b65..e96565e0 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -108,3 +108,17 @@ struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, } return seat; } + +bool input_view_has_focus(struct roots_input *input, struct roots_view *view) { + if (!view) { + return false; + } + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + if (seat->focus == view) { + return true; + } + } + + return false; +} diff --git a/rootston/seat.c b/rootston/seat.c index 72e94aec..3dcd7f2f 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -503,36 +503,21 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { return; } - // unfocus the old view if it is not focused by some other seat - // TODO probably should be an input function - if (seat->focus) { - bool has_other_focus = false; - struct roots_seat *iter_seat; - wl_list_for_each(iter_seat, &seat->input->seats, link) { - if (iter_seat == seat) { - continue; - } - if (iter_seat->focus == seat->focus) { - has_other_focus = true; - break; - } - } - - if (!has_other_focus) { - view_activate(seat->focus, false); - } - } - - if (!view) { - seat->focus = NULL; - seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + if (view && view->type == ROOTS_XWAYLAND_VIEW && + view->xwayland_surface->override_redirect) { return; } + struct roots_view *prev_focus = seat->focus; seat->focus = view; - if (view->type == ROOTS_XWAYLAND_VIEW && - view->xwayland_surface->override_redirect) { + // unfocus the old view if it is not focused by some other seat + if (prev_focus && !input_view_has_focus(seat->input, prev_focus)) { + view_activate(prev_focus, false); + } + + if (!seat->focus) { + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; return; }