aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2017-12-14 11:11:56 -0500
committerLibravatar Tony Crisci <tony@dubstepdish.com>2017-12-14 11:11:56 -0500
commit92fef27eaa0b52c9d37bdabff14ae21cd6660f46 (patch)
tree7a923bbbc233079006597d82721117bae88b6ac6 /sway/input
parentseat configuration (diff)
downloadsway-92fef27eaa0b52c9d37bdabff14ae21cd6660f46.tar.gz
sway-92fef27eaa0b52c9d37bdabff14ae21cd6660f46.tar.zst
sway-92fef27eaa0b52c9d37bdabff14ae21cd6660f46.zip
basic configuration
Diffstat (limited to 'sway/input')
-rw-r--r--sway/input/cursor.c8
-rw-r--r--sway/input/input-manager.c139
-rw-r--r--sway/input/keyboard.c51
-rw-r--r--sway/input/seat.c163
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) {
24 24
25static void cursor_send_pointer_motion(struct sway_cursor *cursor, 25static void cursor_send_pointer_motion(struct sway_cursor *cursor,
26 uint32_t time) { 26 uint32_t time) {
27 struct wlr_seat *seat = cursor->seat->seat; 27 struct wlr_seat *seat = cursor->seat->wlr_seat;
28 struct wlr_surface *surface = NULL; 28 struct wlr_surface *surface = NULL;
29 double sx, sy; 29 double sx, sy;
30 swayc_t *swayc = 30 swayc_t *swayc =
@@ -72,7 +72,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
72 sway_seat_set_focus(cursor->seat, swayc); 72 sway_seat_set_focus(cursor->seat, swayc);
73 } 73 }
74 74
75 wlr_seat_pointer_notify_button(cursor->seat->seat, event->time_msec, 75 wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, event->time_msec,
76 event->button, event->state); 76 event->button, event->state);
77} 77}
78 78
@@ -80,7 +80,7 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) {
80 struct sway_cursor *cursor = 80 struct sway_cursor *cursor =
81 wl_container_of(listener, cursor, axis); 81 wl_container_of(listener, cursor, axis);
82 struct wlr_event_pointer_axis *event = data; 82 struct wlr_event_pointer_axis *event = data;
83 wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, 83 wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec,
84 event->orientation, event->delta); 84 event->orientation, event->delta);
85} 85}
86 86
@@ -173,7 +173,7 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
173 wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &cursor->tool_tip); 173 wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &cursor->tool_tip);
174 cursor->tool_tip.notify = handle_tool_tip; 174 cursor->tool_tip.notify = handle_tool_tip;
175 175
176 wl_signal_add(&seat->seat->events.request_set_cursor, 176 wl_signal_add(&seat->wlr_seat->events.request_set_cursor,
177 &cursor->request_set_cursor); 177 &cursor->request_set_cursor);
178 cursor->request_set_cursor.notify = handle_request_set_cursor; 178 cursor->request_set_cursor.notify = handle_request_set_cursor;
179 179
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";
18struct sway_input_manager *input_manager; 18struct sway_input_manager *input_manager;
19 19
20struct input_config *current_input_config = NULL; 20struct input_config *current_input_config = NULL;
21struct seat_config *current_seat_config = NULL;
21 22
22static struct sway_seat *input_manager_get_seat( 23static struct sway_seat *input_manager_get_seat(
23 struct sway_input_manager *input, const char *seat_name) { 24 struct sway_input_manager *input, const char *seat_name) {
24 struct sway_seat *seat = NULL; 25 struct sway_seat *seat = NULL;
25 wl_list_for_each(seat, &input->seats, link) { 26 wl_list_for_each(seat, &input->seats, link) {
26 if (strcmp(seat->seat->name, seat_name) == 0) { 27 if (strcmp(seat->wlr_seat->name, seat_name) == 0) {
27 return seat; 28 return seat;
28 } 29 }
29 } 30 }
@@ -58,56 +59,88 @@ static char *get_device_identifier(struct wlr_input_device *device) {
58 return identifier; 59 return identifier;
59} 60}
60 61
61static struct sway_input_device *input_sway_device_from_wlr(struct sway_input_manager *input, 62static struct sway_input_device *input_sway_device_from_wlr(
62 struct wlr_input_device *device) { 63 struct sway_input_manager *input, struct wlr_input_device *device) {
63 struct sway_input_device *sway_device = NULL; 64 struct sway_input_device *input_device = NULL;
64 wl_list_for_each(sway_device, &input->devices, link) { 65 wl_list_for_each(input_device, &input->devices, link) {
65 if (sway_device->wlr_device == device) { 66 if (input_device->wlr_device == device) {
66 return sway_device; 67 return input_device;
67 } 68 }
68 } 69 }
69 return NULL; 70 return NULL;
70} 71}
71 72
72static struct sway_input_device *input_sway_device_from_config(struct sway_input_manager *input, 73static struct sway_input_device *input_sway_device_from_config(
73 struct input_config *config) { 74 struct sway_input_manager *input, struct input_config *config) {
74 struct sway_input_device *sway_device = NULL; 75 struct sway_input_device *input_device = NULL;
75 wl_list_for_each(sway_device, &input->devices, link) { 76 wl_list_for_each(input_device, &input->devices, link) {
76 if (strcmp(sway_device->identifier, config->identifier) == 0) { 77 if (strcmp(input_device->identifier, config->identifier) == 0) {
77 return sway_device; 78 return input_device;
78 } 79 }
79 } 80 }
80 return NULL; 81 return NULL;
81} 82}
82 83
84static struct sway_input_device *input_sway_device_from_identifier(
85 struct sway_input_manager *input, char *identifier) {
86 struct sway_input_device *input_device = NULL;
87 wl_list_for_each(input_device, &input->devices, link) {
88 if (strcmp(input_device->identifier, identifier) == 0) {
89 return input_device;
90 }
91 }
92 return NULL;
93}
94
95static bool input_has_seat_configuration(struct sway_input_manager *input) {
96 struct sway_seat *seat = NULL;
97 wl_list_for_each(seat, &input->seats, link) {
98 if (seat->config) {
99 return true;
100 }
101 }
102
103 return false;
104}
105
83static void input_add_notify(struct wl_listener *listener, void *data) { 106static void input_add_notify(struct wl_listener *listener, void *data) {
84 struct sway_input_manager *input = 107 struct sway_input_manager *input =
85 wl_container_of(listener, input, input_add); 108 wl_container_of(listener, input, input_add);
86 struct wlr_input_device *device = data; 109 struct wlr_input_device *device = data;
87 110
88 struct sway_input_device *sway_device = 111 struct sway_input_device *input_device =
89 calloc(1, sizeof(struct sway_input_device)); 112 calloc(1, sizeof(struct sway_input_device));
90 if (!sway_assert(sway_device, "could not allocate input device")) { 113 if (!sway_assert(input_device, "could not allocate input device")) {
91 return; 114 return;
92 } 115 }
93 116
94 sway_device->wlr_device = device; 117 input_device->wlr_device = device;
95 sway_device->identifier = get_device_identifier(device); 118 input_device->identifier = get_device_identifier(device);
96 wl_list_insert(&input->devices, &sway_device->link); 119 wl_list_insert(&input->devices, &input_device->link);
97 120
98 // find config 121 // find config
99 for (int i = 0; i < config->input_configs->length; ++i) { 122 for (int i = 0; i < config->input_configs->length; ++i) {
100 struct input_config *input_config = config->input_configs->items[i]; 123 struct input_config *input_config = config->input_configs->items[i];
101 if (strcmp(input_config->identifier, sway_device->identifier) == 0) { 124 if (strcmp(input_config->identifier, input_device->identifier) == 0) {
102 sway_device->config = input_config; 125 input_device->config = input_config;
103 break; 126 break;
104 } 127 }
105 } 128 }
106 129
107 const char *seat_name = 130 struct sway_seat *seat = NULL;
108 (sway_device->config ? sway_device->config->seat : default_seat); 131 if (!input_has_seat_configuration(input)) {
109 struct sway_seat *seat = input_manager_get_seat(input, seat_name); 132 seat = input_manager_get_seat(input, default_seat);
110 sway_seat_add_device(seat, sway_device); 133 sway_seat_add_device(seat, input_device);
134 return;
135 }
136
137 wl_list_for_each(seat, &input->seats, link) {
138 if (seat->config &&
139 (seat_config_get_attachment(seat->config, input_device->identifier) ||
140 seat_config_get_attachment(seat->config, "*"))) {
141 sway_seat_add_device(seat, input_device);
142 }
143 }
111} 144}
112 145
113static void input_remove_notify(struct wl_listener *listener, void *data) { 146static 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) {
115 wl_container_of(listener, input, input_remove); 148 wl_container_of(listener, input, input_remove);
116 struct wlr_input_device *device = data; 149 struct wlr_input_device *device = data;
117 150
118 struct sway_input_device *sway_device = 151 struct sway_input_device *input_device =
119 input_sway_device_from_wlr(input, device); 152 input_sway_device_from_wlr(input, device);
120 153
121 if (!sway_assert(sway_device, "could not find sway device")) { 154 if (!sway_assert(input_device, "could not find sway device")) {
122 return; 155 return;
123 } 156 }
124 157
125 struct sway_seat *seat = NULL; 158 struct sway_seat *seat = NULL;
126 wl_list_for_each(seat, &input->seats, link) { 159 wl_list_for_each(seat, &input->seats, link) {
127 sway_seat_remove_device(seat, sway_device); 160 sway_seat_remove_device(seat, input_device);
128 } 161 }
129 162
130 wl_list_remove(&sway_device->link); 163 wl_list_remove(&input_device->link);
131 free(sway_device->identifier); 164 free(input_device->identifier);
132 free(sway_device); 165 free(input_device);
133} 166}
134 167
135struct sway_input_manager *sway_input_manager_create( 168struct sway_input_manager *sway_input_manager_create(
@@ -139,7 +172,6 @@ struct sway_input_manager *sway_input_manager_create(
139 if (!input) { 172 if (!input) {
140 return NULL; 173 return NULL;
141 } 174 }
142 // XXX probably don't need the full server
143 input->server = server; 175 input->server = server;
144 176
145 wl_list_init(&input->devices); 177 wl_list_init(&input->devices);
@@ -177,22 +209,53 @@ void sway_input_manager_set_focus(struct sway_input_manager *input,
177 } 209 }
178} 210}
179 211
180void sway_input_manager_apply_config(struct sway_input_manager *input, 212void sway_input_manager_apply_input_config(struct sway_input_manager *input,
181 struct input_config *input_config) { 213 struct input_config *input_config) {
182 struct sway_input_device *sway_device = 214 struct sway_input_device *input_device =
183 input_sway_device_from_config(input, input_config); 215 input_sway_device_from_config(input, input_config);
184 if (!sway_device) { 216 if (!input_device) {
185 return; 217 return;
186 } 218 }
219 input_device->config = input_config;
187 220
188 struct sway_seat *seat = NULL; 221 struct sway_seat *seat = NULL;
189 wl_list_for_each(seat, &input->seats, link) { 222 wl_list_for_each(seat, &input->seats, link) {
190 sway_seat_remove_device(seat, sway_device); 223 sway_seat_configure_device(seat, input_device);
224 }
225}
226
227void sway_input_manager_apply_seat_config(struct sway_input_manager *input,
228 struct seat_config *seat_config) {
229 struct sway_seat *seat = input_manager_get_seat(input, seat_config->name);
230 // the old config is invalid so clear it
231 sway_seat_set_config(seat, NULL);
232
233 // clear devices
234 struct sway_input_device *input_device = NULL;
235 wl_list_for_each(input_device, &input->devices, link) {
236 sway_seat_remove_device(seat, input_device);
237 }
238
239 if (seat_config_get_attachment(seat_config, "*")) {
240 wl_list_for_each(input_device, &input->devices, link) {
241 sway_seat_add_device(seat, input_device);
242 }
243 } else {
244 for (int i = 0; i < seat_config->attachments->length; ++i) {
245 struct seat_attachment_config *attachment =
246 seat_config->attachments->items[i];
247
248 struct sway_input_device *device =
249 input_sway_device_from_identifier(input,
250 attachment->identifier);
251
252 if (device) {
253 sway_seat_add_device(seat, device);
254 }
255 }
191 } 256 }
192 257
193 const char *seat_name = (input_config->seat ? input_config->seat : default_seat); 258 sway_seat_set_config(seat, seat_config);
194 seat = input_manager_get_seat(input, seat_name);
195 sway_seat_add_device(seat, sway_device);
196} 259}
197 260
198void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { 261void 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 @@
5static void handle_keyboard_key(struct wl_listener *listener, void *data) { 5static void handle_keyboard_key(struct wl_listener *listener, void *data) {
6 struct sway_keyboard *keyboard = 6 struct sway_keyboard *keyboard =
7 wl_container_of(listener, keyboard, keyboard_key); 7 wl_container_of(listener, keyboard, keyboard_key);
8 struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
9 struct wlr_input_device *wlr_device =
10 keyboard->seat_device->input_device->wlr_device;
8 struct wlr_event_keyboard_key *event = data; 11 struct wlr_event_keyboard_key *event = data;
9 wlr_seat_set_keyboard(keyboard->seat->seat, keyboard->device->wlr_device); 12 wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap);
10 wlr_seat_keyboard_notify_key(keyboard->seat->seat, event->time_msec, 13 wlr_seat_set_keyboard(wlr_seat, wlr_device);
11 event->keycode, event->state); 14 wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,event->keycode,
15 event->state);
12} 16}
13 17
14static void handle_keyboard_modifiers(struct wl_listener *listener, 18static void handle_keyboard_modifiers(struct wl_listener *listener,
15 void *data) { 19 void *data) {
16 struct sway_keyboard *keyboard = 20 struct sway_keyboard *keyboard =
17 wl_container_of(listener, keyboard, keyboard_modifiers); 21 wl_container_of(listener, keyboard, keyboard_modifiers);
18 wlr_seat_set_keyboard(keyboard->seat->seat, keyboard->device->wlr_device); 22 struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat;
19 wlr_seat_keyboard_notify_modifiers(keyboard->seat->seat); 23 struct wlr_input_device *wlr_device =
24 keyboard->seat_device->input_device->wlr_device;
25 wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap);
26 wlr_seat_set_keyboard(wlr_seat, wlr_device);
27 wlr_seat_keyboard_notify_modifiers(wlr_seat);
20} 28}
21 29
22struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, 30struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
23 struct sway_input_device *device) { 31 struct sway_seat_device *device) {
24 struct sway_keyboard *keyboard = 32 struct sway_keyboard *keyboard =
25 calloc(1, sizeof(struct sway_keyboard)); 33 calloc(1, sizeof(struct sway_keyboard));
26 if (!sway_assert(keyboard, "could not allocate sway keyboard")) { 34 if (!sway_assert(keyboard, "could not allocate sway keyboard")) {
27 return NULL; 35 return NULL;
28 } 36 }
29 37
30 keyboard->device = device; 38 keyboard->seat_device = device;
31 keyboard->seat = seat; 39 device->keyboard = keyboard;
32 40
33 // TODO keyboard config 41 wl_list_init(&keyboard->keyboard_key.link);
42 wl_list_init(&keyboard->keyboard_modifiers.link);
43
44 return keyboard;
45}
46
47void sway_keyboard_configure(struct sway_keyboard *keyboard) {
34 struct xkb_rule_names rules; 48 struct xkb_rule_names rules;
35 memset(&rules, 0, sizeof(rules)); 49 memset(&rules, 0, sizeof(rules));
36 rules.rules = getenv("XKB_DEFAULT_RULES"); 50 rules.rules = getenv("XKB_DEFAULT_RULES");
@@ -38,27 +52,32 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
38 rules.layout = getenv("XKB_DEFAULT_LAYOUT"); 52 rules.layout = getenv("XKB_DEFAULT_LAYOUT");
39 rules.variant = getenv("XKB_DEFAULT_VARIANT"); 53 rules.variant = getenv("XKB_DEFAULT_VARIANT");
40 rules.options = getenv("XKB_DEFAULT_OPTIONS"); 54 rules.options = getenv("XKB_DEFAULT_OPTIONS");
55
41 struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); 56 struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
42 if (!sway_assert(context, "cannot create XKB context")) { 57 if (!sway_assert(context, "cannot create XKB context")) {
43 return NULL; 58 return;
44 } 59 }
45 60
46 wlr_keyboard_set_keymap(device->wlr_device->keyboard, 61 keyboard->keymap =
47 xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); 62 xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
63 wlr_keyboard_set_keymap(keyboard->seat_device->input_device->wlr_device->keyboard, keyboard->keymap);
48 xkb_context_unref(context); 64 xkb_context_unref(context);
49 65
50 wl_signal_add(&device->wlr_device->keyboard->events.key, 66 wl_list_remove(&keyboard->keyboard_key.link);
67 wl_signal_add(
68 &keyboard->seat_device->input_device->wlr_device->keyboard->events.key,
51 &keyboard->keyboard_key); 69 &keyboard->keyboard_key);
52 keyboard->keyboard_key.notify = handle_keyboard_key; 70 keyboard->keyboard_key.notify = handle_keyboard_key;
53 71
54 wl_signal_add(&device->wlr_device->keyboard->events.modifiers, 72 wl_list_remove(&keyboard->keyboard_modifiers.link);
73 wl_signal_add(
74 &keyboard->seat_device->input_device->wlr_device->keyboard->events.modifiers,
55 &keyboard->keyboard_modifiers); 75 &keyboard->keyboard_modifiers);
56 keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; 76 keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers;
57
58 return keyboard;
59} 77}
60 78
61void sway_keyboard_destroy(struct sway_keyboard *keyboard) { 79void sway_keyboard_destroy(struct sway_keyboard *keyboard) {
80 xkb_keymap_unref(keyboard->keymap);
62 wl_list_remove(&keyboard->keyboard_key.link); 81 wl_list_remove(&keyboard->keyboard_key.link);
63 wl_list_remove(&keyboard->keyboard_modifiers.link); 82 wl_list_remove(&keyboard->keyboard_modifiers.link);
64 wl_list_remove(&keyboard->link); 83 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 @@
9#include "sway/view.h" 9#include "sway/view.h"
10#include "log.h" 10#include "log.h"
11 11
12static void seat_device_destroy(struct sway_seat_device *seat_device) {
13 if (!seat_device) {
14 return;
15 }
16
17 sway_keyboard_destroy(seat_device->keyboard);
18 wlr_cursor_detach_input_device(seat_device->sway_seat->cursor->cursor,
19 seat_device->input_device->wlr_device);
20 wl_list_remove(&seat_device->link);
21 free(seat_device);
22}
23
12struct sway_seat *sway_seat_create(struct sway_input_manager *input, 24struct sway_seat *sway_seat_create(struct sway_input_manager *input,
13 const char *seat_name) { 25 const char *seat_name) {
14 struct sway_seat *seat = calloc(1, sizeof(struct sway_seat)); 26 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,
16 return NULL; 28 return NULL;
17 } 29 }
18 30
19 seat->seat = wlr_seat_create(input->server->wl_display, seat_name); 31 seat->wlr_seat = wlr_seat_create(input->server->wl_display, seat_name);
20 if (!sway_assert(seat->seat, "could not allocate seat")) { 32 if (!sway_assert(seat->wlr_seat, "could not allocate seat")) {
21 return NULL; 33 return NULL;
22 } 34 }
23 35
24 seat->cursor = sway_cursor_create(seat); 36 seat->cursor = sway_cursor_create(seat);
25 if (!seat->cursor) { 37 if (!seat->cursor) {
26 wlr_seat_destroy(seat->seat); 38 wlr_seat_destroy(seat->wlr_seat);
27 free(seat); 39 free(seat);
28 return NULL; 40 return NULL;
29 } 41 }
30 42
31 seat->input = input; 43 seat->input = input;
32 seat->devices = create_list(); 44 wl_list_init(&seat->devices);
33 45
34 wlr_seat_set_capabilities(seat->seat, 46 wlr_seat_set_capabilities(seat->wlr_seat,
35 WL_SEAT_CAPABILITY_KEYBOARD | 47 WL_SEAT_CAPABILITY_KEYBOARD |
36 WL_SEAT_CAPABILITY_POINTER | 48 WL_SEAT_CAPABILITY_POINTER |
37 WL_SEAT_CAPABILITY_TOUCH); 49 WL_SEAT_CAPABILITY_TOUCH);
@@ -43,88 +55,94 @@ struct sway_seat *sway_seat_create(struct sway_input_manager *input,
43 return seat; 55 return seat;
44} 56}
45 57
46static void seat_add_pointer(struct sway_seat *seat, 58static void seat_configure_pointer(struct sway_seat *seat,
47 struct sway_input_device *sway_device) { 59 struct sway_seat_device *sway_device) {
48 // TODO pointer configuration 60 // TODO pointer configuration
49 wlr_cursor_attach_input_device(seat->cursor->cursor, 61 wlr_cursor_attach_input_device(seat->cursor->cursor,
50 sway_device->wlr_device); 62 sway_device->input_device->wlr_device);
51} 63}
52 64
53static void seat_add_keyboard(struct sway_seat *seat, 65static void seat_configure_keyboard(struct sway_seat *seat,
54 struct sway_input_device *device) { 66 struct sway_seat_device *seat_device) {
55 // TODO keyboard configuration 67 if (!seat_device->keyboard) {
56 sway_keyboard_create(seat, device); 68 sway_keyboard_create(seat, seat_device);
57 wlr_seat_set_keyboard(seat->seat, device->wlr_device); 69 }
70 sway_keyboard_configure(seat_device->keyboard);
58} 71}
59 72
60bool sway_seat_has_device(struct sway_seat *seat, 73static struct sway_seat_device *sway_seat_get_device(struct sway_seat *seat,
61 struct sway_input_device *device) { 74 struct sway_input_device *input_device) {
62 return false; 75 struct sway_seat_device *seat_device = NULL;
76 wl_list_for_each(seat_device, &seat->devices, link) {
77 if (seat_device->input_device == input_device) {
78 return seat_device;
79 }
80 }
81
82 return NULL;
63} 83}
64 84
65void sway_seat_add_device(struct sway_seat *seat, 85void sway_seat_configure_device(struct sway_seat *seat,
66 struct sway_input_device *device) { 86 struct sway_input_device *input_device) {
67 if (sway_seat_has_device(seat, device)) { 87 struct sway_seat_device *seat_device =
88 sway_seat_get_device(seat, input_device);
89 if (!seat_device) {
68 return; 90 return;
69 } 91 }
70 92
71 sway_log(L_DEBUG, "input add: %s", device->identifier); 93 if (seat->config) {
72 switch (device->wlr_device->type) { 94 seat_device->attachment_config =
95 seat_config_get_attachment(seat->config, input_device->identifier);
96 }
97
98 switch (input_device->wlr_device->type) {
73 case WLR_INPUT_DEVICE_POINTER: 99 case WLR_INPUT_DEVICE_POINTER:
74 seat_add_pointer(seat, device); 100 seat_configure_pointer(seat, seat_device);
75 break; 101 break;
76 case WLR_INPUT_DEVICE_KEYBOARD: 102 case WLR_INPUT_DEVICE_KEYBOARD:
77 seat_add_keyboard(seat, device); 103 seat_configure_keyboard(seat, seat_device);
104 wlr_seat_set_keyboard(seat->wlr_seat,
105 seat_device->input_device->wlr_device);
78 break; 106 break;
79 case WLR_INPUT_DEVICE_TOUCH: 107 case WLR_INPUT_DEVICE_TOUCH:
80 case WLR_INPUT_DEVICE_TABLET_PAD: 108 case WLR_INPUT_DEVICE_TABLET_PAD:
81 case WLR_INPUT_DEVICE_TABLET_TOOL: 109 case WLR_INPUT_DEVICE_TABLET_TOOL:
82 sway_log(L_DEBUG, "TODO: add other devices"); 110 sway_log(L_DEBUG, "TODO: configure other devices");
83 break; 111 break;
84 } 112 }
85
86 list_add(seat->devices, device);
87} 113}
88 114
89static void seat_remove_keyboard(struct sway_seat *seat, 115void sway_seat_add_device(struct sway_seat *seat,
90 struct sway_input_device *device) { 116 struct sway_input_device *input_device) {
91 if (device && device->keyboard) { 117 if (sway_seat_get_device(seat, input_device)) {
92 sway_keyboard_destroy(device->keyboard); 118 return;
93 } 119 }
94}
95 120
96static void seat_remove_pointer(struct sway_seat *seat, 121 struct sway_seat_device *seat_device =
97 struct sway_input_device *device) { 122 calloc(1, sizeof(struct sway_seat_device));
98 wlr_cursor_detach_input_device(seat->cursor->cursor, device->wlr_device); 123 if (!seat_device) {
124 sway_log(L_DEBUG, "could not allocate seat device");
125 return;
126 }
127
128 seat_device->sway_seat = seat;
129 seat_device->input_device = input_device;
130 wl_list_insert(&seat->devices, &seat_device->link);
131
132 sway_seat_configure_device(seat, input_device);
99} 133}
100 134
101void sway_seat_remove_device(struct sway_seat *seat, 135void sway_seat_remove_device(struct sway_seat *seat,
102 struct sway_input_device *device) { 136 struct sway_input_device *input_device) {
103 sway_log(L_DEBUG, "input remove: %s", device->identifier); 137 sway_log(L_DEBUG, "input remove: %s", input_device->identifier);
104 if (!sway_seat_has_device(seat, device)) { 138 struct sway_seat_device *seat_device =
105 return; 139 sway_seat_get_device(seat, input_device);
106 }
107 140
108 switch (device->wlr_device->type) { 141 if (!seat_device) {
109 case WLR_INPUT_DEVICE_POINTER: 142 return;
110 seat_remove_pointer(seat, device);
111 break;
112 case WLR_INPUT_DEVICE_KEYBOARD:
113 seat_remove_keyboard(seat, device);
114 break;
115 case WLR_INPUT_DEVICE_TOUCH:
116 case WLR_INPUT_DEVICE_TABLET_PAD:
117 case WLR_INPUT_DEVICE_TABLET_TOOL:
118 sway_log(L_DEBUG, "TODO: remove other devices");
119 break;
120 } 143 }
121 144
122 for (int i = 0; i < seat->devices->length; ++i) { 145 seat_device_destroy(seat_device);
123 if (seat->devices->items[i] == device) {
124 list_del(seat->devices, i);
125 break;
126 }
127 }
128} 146}
129 147
130void sway_seat_configure_xcursor(struct sway_seat *seat) { 148void sway_seat_configure_xcursor(struct sway_seat *seat) {
@@ -135,7 +153,8 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) {
135 seat->cursor->xcursor_manager = 153 seat->cursor->xcursor_manager =
136 wlr_xcursor_manager_create("default", 24); 154 wlr_xcursor_manager_create("default", 24);
137 if (sway_assert(seat->cursor->xcursor_manager, 155 if (sway_assert(seat->cursor->xcursor_manager,
138 "Cannot create XCursor manager for theme %s", cursor_theme)) { 156 "Cannot create XCursor manager for theme %s",
157 cursor_theme)) {
139 return; 158 return;
140 } 159 }
141 } 160 }
@@ -183,7 +202,7 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) {
183 view->iface.set_activated(view, true); 202 view->iface.set_activated(view, true);
184 wl_signal_add(&container->events.destroy, &seat->focus_destroy); 203 wl_signal_add(&container->events.destroy, &seat->focus_destroy);
185 seat->focus_destroy.notify = handle_focus_destroy; 204 seat->focus_destroy.notify = handle_focus_destroy;
186 wlr_seat_keyboard_notify_enter(seat->seat, view->surface); 205 wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface);
187 } 206 }
188 207
189 seat->focus = container; 208 seat->focus = container;
@@ -195,3 +214,29 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) {
195 214
196 } 215 }
197} 216}
217
218void sway_seat_set_config(struct sway_seat *seat,
219 struct seat_config *seat_config) {
220 // clear configs
221 seat->config = NULL;
222
223 struct sway_seat_device *seat_device = NULL;
224 wl_list_for_each(seat_device, &seat->devices, link) {
225 seat_device->attachment_config = NULL;
226 }
227
228 if (!seat_config) {
229 return;
230 }
231
232 // add configs
233 seat->config = seat_config;
234
235 wl_list_for_each(seat_device, &seat->devices, link) {
236 seat_device->attachment_config =
237 seat_config_get_attachment(seat_config,
238 seat_device->input_device->identifier);
239 sway_seat_configure_device(seat, seat_device->input_device);
240 }
241
242}