diff options
Diffstat (limited to 'sway/input/input-manager.c')
-rw-r--r-- | sway/input/input-manager.c | 139 |
1 files changed, 101 insertions, 38 deletions
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"; | |||
18 | struct sway_input_manager *input_manager; | 18 | struct sway_input_manager *input_manager; |
19 | 19 | ||
20 | struct input_config *current_input_config = NULL; | 20 | struct input_config *current_input_config = NULL; |
21 | struct seat_config *current_seat_config = NULL; | ||
21 | 22 | ||
22 | static struct sway_seat *input_manager_get_seat( | 23 | static 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 | ||
61 | static struct sway_input_device *input_sway_device_from_wlr(struct sway_input_manager *input, | 62 | static 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 | ||
72 | static struct sway_input_device *input_sway_device_from_config(struct sway_input_manager *input, | 73 | static 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 | ||
84 | static 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 | |||
95 | static 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 | |||
83 | static void input_add_notify(struct wl_listener *listener, void *data) { | 106 | static 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 | ||
113 | static void input_remove_notify(struct wl_listener *listener, void *data) { | 146 | 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) { | |||
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 | ||
135 | struct sway_input_manager *sway_input_manager_create( | 168 | struct 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 | ||
180 | void sway_input_manager_apply_config(struct sway_input_manager *input, | 212 | void 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 | |||
227 | void 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 | ||
198 | void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { | 261 | void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { |