diff options
Diffstat (limited to 'sway/input')
-rw-r--r-- | sway/input/cursor.c | 8 | ||||
-rw-r--r-- | sway/input/input-manager.c | 139 | ||||
-rw-r--r-- | sway/input/keyboard.c | 51 | ||||
-rw-r--r-- | sway/input/seat.c | 163 |
4 files changed, 244 insertions, 117 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 217c2ddb..3aa2d1bc 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -24,7 +24,7 @@ static void cursor_update_position(struct sway_cursor *cursor) { static void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time) { - struct wlr_seat *seat = cursor->seat->seat; + struct wlr_seat *seat = cursor->seat->wlr_seat; struct wlr_surface *surface = NULL; double sx, sy; swayc_t *swayc = @@ -72,7 +72,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { sway_seat_set_focus(cursor->seat, swayc); } - wlr_seat_pointer_notify_button(cursor->seat->seat, event->time_msec, + wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, event->time_msec, event->button, event->state); } @@ -80,7 +80,7 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) { struct sway_cursor *cursor = wl_container_of(listener, cursor, axis); struct wlr_event_pointer_axis *event = data; - wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, + wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec, event->orientation, event->delta); } @@ -173,7 +173,7 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) { wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &cursor->tool_tip); cursor->tool_tip.notify = handle_tool_tip; - wl_signal_add(&seat->seat->events.request_set_cursor, + wl_signal_add(&seat->wlr_seat->events.request_set_cursor, &cursor->request_set_cursor); cursor->request_set_cursor.notify = handle_request_set_cursor; diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index b07a733e..1950b6d9 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -18,12 +18,13 @@ static const char *default_seat = "seat0"; struct sway_input_manager *input_manager; struct input_config *current_input_config = NULL; +struct seat_config *current_seat_config = NULL; static struct sway_seat *input_manager_get_seat( struct sway_input_manager *input, const char *seat_name) { struct sway_seat *seat = NULL; wl_list_for_each(seat, &input->seats, link) { - if (strcmp(seat->seat->name, seat_name) == 0) { + if (strcmp(seat->wlr_seat->name, seat_name) == 0) { return seat; } } @@ -58,56 +59,88 @@ static char *get_device_identifier(struct wlr_input_device *device) { return identifier; } -static struct sway_input_device *input_sway_device_from_wlr(struct sway_input_manager *input, - struct wlr_input_device *device) { - struct sway_input_device *sway_device = NULL; - wl_list_for_each(sway_device, &input->devices, link) { - if (sway_device->wlr_device == device) { - return sway_device; +static struct sway_input_device *input_sway_device_from_wlr( + struct sway_input_manager *input, struct wlr_input_device *device) { + struct sway_input_device *input_device = NULL; + wl_list_for_each(input_device, &input->devices, link) { + if (input_device->wlr_device == device) { + return input_device; } } return NULL; } -static struct sway_input_device *input_sway_device_from_config(struct sway_input_manager *input, - struct input_config *config) { - struct sway_input_device *sway_device = NULL; - wl_list_for_each(sway_device, &input->devices, link) { - if (strcmp(sway_device->identifier, config->identifier) == 0) { - return sway_device; +static struct sway_input_device *input_sway_device_from_config( + struct sway_input_manager *input, struct input_config *config) { + struct sway_input_device *input_device = NULL; + wl_list_for_each(input_device, &input->devices, link) { + if (strcmp(input_device->identifier, config->identifier) == 0) { + return input_device; } } return NULL; } +static struct sway_input_device *input_sway_device_from_identifier( + struct sway_input_manager *input, char *identifier) { + struct sway_input_device *input_device = NULL; + wl_list_for_each(input_device, &input->devices, link) { + if (strcmp(input_device->identifier, identifier) == 0) { + return input_device; + } + } + return NULL; +} + +static bool input_has_seat_configuration(struct sway_input_manager *input) { + struct sway_seat *seat = NULL; + wl_list_for_each(seat, &input->seats, link) { + if (seat->config) { + return true; + } + } + + return false; +} + static void input_add_notify(struct wl_listener *listener, void *data) { struct sway_input_manager *input = wl_container_of(listener, input, input_add); struct wlr_input_device *device = data; - struct sway_input_device *sway_device = + struct sway_input_device *input_device = calloc(1, sizeof(struct sway_input_device)); - if (!sway_assert(sway_device, "could not allocate input device")) { + if (!sway_assert(input_device, "could not allocate input device")) { return; } - sway_device->wlr_device = device; - sway_device->identifier = get_device_identifier(device); - wl_list_insert(&input->devices, &sway_device->link); + input_device->wlr_device = device; + input_device->identifier = get_device_identifier(device); + wl_list_insert(&input->devices, &input_device->link); // find config for (int i = 0; i < config->input_configs->length; ++i) { struct input_config *input_config = config->input_configs->items[i]; - if (strcmp(input_config->identifier, sway_device->identifier) == 0) { - sway_device->config = input_config; + if (strcmp(input_config->identifier, input_device->identifier) == 0) { + input_device->config = input_config; break; } } - const char *seat_name = - (sway_device->config ? sway_device->config->seat : default_seat); - struct sway_seat *seat = input_manager_get_seat(input, seat_name); - sway_seat_add_device(seat, sway_device); + struct sway_seat *seat = NULL; + if (!input_has_seat_configuration(input)) { + seat = input_manager_get_seat(input, default_seat); + sway_seat_add_device(seat, input_device); + return; + } + + wl_list_for_each(seat, &input->seats, link) { + if (seat->config && + (seat_config_get_attachment(seat->config, input_device->identifier) || + seat_config_get_attachment(seat->config, "*"))) { + sway_seat_add_device(seat, input_device); + } + } } static void input_remove_notify(struct wl_listener *listener, void *data) { @@ -115,21 +148,21 @@ static void input_remove_notify(struct wl_listener *listener, void *data) { wl_container_of(listener, input, input_remove); struct wlr_input_device *device = data; - struct sway_input_device *sway_device = + struct sway_input_device *input_device = input_sway_device_from_wlr(input, device); - if (!sway_assert(sway_device, "could not find sway device")) { + if (!sway_assert(input_device, "could not find sway device")) { return; } struct sway_seat *seat = NULL; wl_list_for_each(seat, &input->seats, link) { - sway_seat_remove_device(seat, sway_device); + sway_seat_remove_device(seat, input_device); } - wl_list_remove(&sway_device->link); - free(sway_device->identifier); - free(sway_device); + wl_list_remove(&input_device->link); + free(input_device->identifier); + free(input_device); } struct sway_input_manager *sway_input_manager_create( @@ -139,7 +172,6 @@ struct sway_input_manager *sway_input_manager_create( if (!input) { return NULL; } - // XXX probably don't need the full server input->server = server; wl_list_init(&input->devices); @@ -177,22 +209,53 @@ void sway_input_manager_set_focus(struct sway_input_manager *input, } } -void sway_input_manager_apply_config(struct sway_input_manager *input, +void sway_input_manager_apply_input_config(struct sway_input_manager *input, struct input_config *input_config) { - struct sway_input_device *sway_device = + struct sway_input_device *input_device = input_sway_device_from_config(input, input_config); - if (!sway_device) { + if (!input_device) { return; } + input_device->config = input_config; struct sway_seat *seat = NULL; wl_list_for_each(seat, &input->seats, link) { - sway_seat_remove_device(seat, sway_device); + sway_seat_configure_device(seat, input_device); + } +} + +void sway_input_manager_apply_seat_config(struct sway_input_manager *input, + struct seat_config *seat_config) { + struct sway_seat *seat = input_manager_get_seat(input, seat_config->name); + // the old config is invalid so clear it + sway_seat_set_config(seat, NULL); + + // clear devices + struct sway_input_device *input_device = NULL; + wl_list_for_each(input_device, &input->devices, link) { + sway_seat_remove_device(seat, input_device); + } + + if (seat_config_get_attachment(seat_config, "*")) { + wl_list_for_each(input_device, &input->devices, link) { + sway_seat_add_device(seat, input_device); + } + } else { + for (int i = 0; i < seat_config->attachments->length; ++i) { + struct seat_attachment_config *attachment = + seat_config->attachments->items[i]; + + struct sway_input_device *device = + input_sway_device_from_identifier(input, + attachment->identifier); + + if (device) { + sway_seat_add_device(seat, device); + } + } } - const char *seat_name = (input_config->seat ? input_config->seat : default_seat); - seat = input_manager_get_seat(input, seat_name); - sway_seat_add_device(seat, sway_device); + sway_seat_set_config(seat, seat_config); } void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 6a792c65..53db3270 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -5,32 +5,46 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { struct sway_keyboard *keyboard = wl_container_of(listener, keyboard, keyboard_key); + struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat; + struct wlr_input_device *wlr_device = + keyboard->seat_device->input_device->wlr_device; struct wlr_event_keyboard_key *event = data; - wlr_seat_set_keyboard(keyboard->seat->seat, keyboard->device->wlr_device); - wlr_seat_keyboard_notify_key(keyboard->seat->seat, event->time_msec, - event->keycode, event->state); + wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap); + wlr_seat_set_keyboard(wlr_seat, wlr_device); + wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,event->keycode, + event->state); } static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { struct sway_keyboard *keyboard = wl_container_of(listener, keyboard, keyboard_modifiers); - wlr_seat_set_keyboard(keyboard->seat->seat, keyboard->device->wlr_device); - wlr_seat_keyboard_notify_modifiers(keyboard->seat->seat); + struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat; + struct wlr_input_device *wlr_device = + keyboard->seat_device->input_device->wlr_device; + wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap); + wlr_seat_set_keyboard(wlr_seat, wlr_device); + wlr_seat_keyboard_notify_modifiers(wlr_seat); } struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, - struct sway_input_device *device) { + struct sway_seat_device *device) { struct sway_keyboard *keyboard = calloc(1, sizeof(struct sway_keyboard)); if (!sway_assert(keyboard, "could not allocate sway keyboard")) { return NULL; } - keyboard->device = device; - keyboard->seat = seat; + keyboard->seat_device = device; + device->keyboard = keyboard; - // TODO keyboard config + wl_list_init(&keyboard->keyboard_key.link); + wl_list_init(&keyboard->keyboard_modifiers.link); + + return keyboard; +} + +void sway_keyboard_configure(struct sway_keyboard *keyboard) { struct xkb_rule_names rules; memset(&rules, 0, sizeof(rules)); rules.rules = getenv("XKB_DEFAULT_RULES"); @@ -38,27 +52,32 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, rules.layout = getenv("XKB_DEFAULT_LAYOUT"); rules.variant = getenv("XKB_DEFAULT_VARIANT"); rules.options = getenv("XKB_DEFAULT_OPTIONS"); + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (!sway_assert(context, "cannot create XKB context")) { - return NULL; + return; } - wlr_keyboard_set_keymap(device->wlr_device->keyboard, - xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); + keyboard->keymap = + xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + wlr_keyboard_set_keymap(keyboard->seat_device->input_device->wlr_device->keyboard, keyboard->keymap); xkb_context_unref(context); - wl_signal_add(&device->wlr_device->keyboard->events.key, + wl_list_remove(&keyboard->keyboard_key.link); + wl_signal_add( + &keyboard->seat_device->input_device->wlr_device->keyboard->events.key, &keyboard->keyboard_key); keyboard->keyboard_key.notify = handle_keyboard_key; - wl_signal_add(&device->wlr_device->keyboard->events.modifiers, + wl_list_remove(&keyboard->keyboard_modifiers.link); + wl_signal_add( + &keyboard->seat_device->input_device->wlr_device->keyboard->events.modifiers, &keyboard->keyboard_modifiers); keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; - - return keyboard; } void sway_keyboard_destroy(struct sway_keyboard *keyboard) { + xkb_keymap_unref(keyboard->keymap); wl_list_remove(&keyboard->keyboard_key.link); wl_list_remove(&keyboard->keyboard_modifiers.link); wl_list_remove(&keyboard->link); diff --git a/sway/input/seat.c b/sway/input/seat.c index 80c6424f..1b25419b 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -9,6 +9,18 @@ #include "sway/view.h" #include "log.h" +static void seat_device_destroy(struct sway_seat_device *seat_device) { + if (!seat_device) { + return; + } + + sway_keyboard_destroy(seat_device->keyboard); + wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor, + seat_device->input_device->wlr_device); + wl_list_remove(&seat_device->link); + free(seat_device); +} + struct sway_seat *sway_seat_create(struct sway_input_manager *input, const char *seat_name) { struct sway_seat *seat = calloc(1, sizeof(struct sway_seat)); @@ -16,22 +28,22 @@ struct sway_seat *sway_seat_create(struct sway_input_manager *input, return NULL; } - seat->seat = wlr_seat_create(input->server->wl_display, seat_name); - if (!sway_assert(seat->seat, "could not allocate seat")) { + seat->wlr_seat = wlr_seat_create(input->server->wl_display, seat_name); + if (!sway_assert(seat->wlr_seat, "could not allocate seat")) { return NULL; } seat->cursor = sway_cursor_create(seat); if (!seat->cursor) { - wlr_seat_destroy(seat->seat); + wlr_seat_destroy(seat->wlr_seat); free(seat); return NULL; } seat->input = input; - seat->devices = create_list(); + wl_list_init(&seat->devices); - wlr_seat_set_capabilities(seat->seat, + wlr_seat_set_capabilities(seat->wlr_seat, WL_SEAT_CAPABILITY_KEYBOARD | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); @@ -43,88 +55,94 @@ struct sway_seat *sway_seat_create(struct sway_input_manager *input, return seat; } -static void seat_add_pointer(struct sway_seat *seat, - struct sway_input_device *sway_device) { +static void seat_configure_pointer(struct sway_seat *seat, + struct sway_seat_device *sway_device) { // TODO pointer configuration wlr_cursor_attach_input_device(seat->cursor->cursor, - sway_device->wlr_device); + sway_device->input_device->wlr_device); } -static void seat_add_keyboard(struct sway_seat *seat, - struct sway_input_device *device) { - // TODO keyboard configuration - sway_keyboard_create(seat, device); - wlr_seat_set_keyboard(seat->seat, device->wlr_device); +static void seat_configure_keyboard(struct sway_seat *seat, + struct sway_seat_device *seat_device) { + if (!seat_device->keyboard) { + sway_keyboard_create(seat, seat_device); + } + sway_keyboard_configure(seat_device->keyboard); } -bool sway_seat_has_device(struct sway_seat *seat, - struct sway_input_device *device) { - return false; +static struct sway_seat_device *sway_seat_get_device(struct sway_seat *seat, + struct sway_input_device *input_device) { + struct sway_seat_device *seat_device = NULL; + wl_list_for_each(seat_device, &seat->devices, link) { + if (seat_device->input_device == input_device) { + return seat_device; + } + } + + return NULL; } -void sway_seat_add_device(struct sway_seat *seat, - struct sway_input_device *device) { - if (sway_seat_has_device(seat, device)) { +void sway_seat_configure_device(struct sway_seat *seat, + struct sway_input_device *input_device) { + struct sway_seat_device *seat_device = + sway_seat_get_device(seat, input_device); + if (!seat_device) { return; } - sway_log(L_DEBUG, "input add: %s", device->identifier); - switch (device->wlr_device->type) { + if (seat->config) { + seat_device->attachment_config = + seat_config_get_attachment(seat->config, input_device->identifier); + } + + switch (input_device->wlr_device->type) { case WLR_INPUT_DEVICE_POINTER: - seat_add_pointer(seat, device); + seat_configure_pointer(seat, seat_device); break; case WLR_INPUT_DEVICE_KEYBOARD: - seat_add_keyboard(seat, device); + seat_configure_keyboard(seat, seat_device); + wlr_seat_set_keyboard(seat->wlr_seat, + seat_device->input_device->wlr_device); break; case WLR_INPUT_DEVICE_TOUCH: case WLR_INPUT_DEVICE_TABLET_PAD: case WLR_INPUT_DEVICE_TABLET_TOOL: - sway_log(L_DEBUG, "TODO: add other devices"); + sway_log(L_DEBUG, "TODO: configure other devices"); break; } - - list_add(seat->devices, device); } -static void seat_remove_keyboard(struct sway_seat *seat, - struct sway_input_device *device) { - if (device && device->keyboard) { - sway_keyboard_destroy(device->keyboard); +void sway_seat_add_device(struct sway_seat *seat, + struct sway_input_device *input_device) { + if (sway_seat_get_device(seat, input_device)) { + return; } -} -static void seat_remove_pointer(struct sway_seat *seat, - struct sway_input_device *device) { - wlr_cursor_detach_input_device(seat->cursor->cursor, device->wlr_device); + struct sway_seat_device *seat_device = + calloc(1, sizeof(struct sway_seat_device)); + if (!seat_device) { + sway_log(L_DEBUG, "could not allocate seat device"); + return; + } + + seat_device->sway_seat = seat; + seat_device->input_device = input_device; + wl_list_insert(&seat->devices, &seat_device->link); + + sway_seat_configure_device(seat, input_device); } void sway_seat_remove_device(struct sway_seat *seat, - struct sway_input_device *device) { - sway_log(L_DEBUG, "input remove: %s", device->identifier); - if (!sway_seat_has_device(seat, device)) { - return; - } + struct sway_input_device *input_device) { + sway_log(L_DEBUG, "input remove: %s", input_device->identifier); + struct sway_seat_device *seat_device = + sway_seat_get_device(seat, input_device); - switch (device->wlr_device->type) { - case WLR_INPUT_DEVICE_POINTER: - seat_remove_pointer(seat, device); - break; - case WLR_INPUT_DEVICE_KEYBOARD: - seat_remove_keyboard(seat, device); - break; - case WLR_INPUT_DEVICE_TOUCH: - case WLR_INPUT_DEVICE_TABLET_PAD: - case WLR_INPUT_DEVICE_TABLET_TOOL: - sway_log(L_DEBUG, "TODO: remove other devices"); - break; + if (!seat_device) { + return; } - for (int i = 0; i < seat->devices->length; ++i) { - if (seat->devices->items[i] == device) { - list_del(seat->devices, i); - break; - } - } + seat_device_destroy(seat_device); } void sway_seat_configure_xcursor(struct sway_seat *seat) { @@ -135,7 +153,8 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) { seat->cursor->xcursor_manager = wlr_xcursor_manager_create("default", 24); if (sway_assert(seat->cursor->xcursor_manager, - "Cannot create XCursor manager for theme %s", cursor_theme)) { + "Cannot create XCursor manager for theme %s", + cursor_theme)) { return; } } @@ -183,7 +202,7 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { view->iface.set_activated(view, true); wl_signal_add(&container->events.destroy, &seat->focus_destroy); seat->focus_destroy.notify = handle_focus_destroy; - wlr_seat_keyboard_notify_enter(seat->seat, view->surface); + wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface); } seat->focus = container; @@ -195,3 +214,29 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { } } + +void sway_seat_set_config(struct sway_seat *seat, + struct seat_config *seat_config) { + // clear configs + seat->config = NULL; + + struct sway_seat_device *seat_device = NULL; + wl_list_for_each(seat_device, &seat->devices, link) { + seat_device->attachment_config = NULL; + } + + if (!seat_config) { + return; + } + + // add configs + seat->config = seat_config; + + wl_list_for_each(seat_device, &seat->devices, link) { + seat_device->attachment_config = + seat_config_get_attachment(seat_config, + seat_device->input_device->identifier); + sway_seat_configure_device(seat, seat_device->input_device); + } + +} |