aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-07-18 01:06:25 -0400
committerLibravatar Simon Ser <contact@emersion.fr>2019-07-23 20:45:46 +0300
commit1a16262903dce09a60f94698afa96c1b2c91c264 (patch)
tree5232ce26dccf8008bcc2cb0cda95dcde382e1c39 /sway/input
parentipc: add an input event (diff)
downloadsway-1a16262903dce09a60f94698afa96c1b2c91c264.tar.gz
sway-1a16262903dce09a60f94698afa96c1b2c91c264.tar.zst
sway-1a16262903dce09a60f94698afa96c1b2c91c264.zip
ipc: add input::libinput_config event
This adds a libinput_config change type to the input event for when the libinput config for a device changes In order for this to be possible to track, the libinput config code had to be refactored. It is now extracted into a separate file to isolate it from the rest of the input management code.
Diffstat (limited to 'sway/input')
-rw-r--r--sway/input/input-manager.c434
-rw-r--r--sway/input/libinput.c382
2 files changed, 386 insertions, 430 deletions
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index dd84a0b3..4f9ed891 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -1,16 +1,14 @@
1#define _POSIX_C_SOURCE 200809L 1#define _POSIX_C_SOURCE 200809L
2#include <ctype.h> 2#include <ctype.h>
3#include <float.h>
4#include <limits.h>
5#include <stdio.h> 3#include <stdio.h>
6#include <string.h> 4#include <string.h>
7#include <libinput.h>
8#include <math.h> 5#include <math.h>
9#include <wlr/backend/libinput.h> 6#include <wlr/backend/libinput.h>
10#include <wlr/types/wlr_input_inhibitor.h> 7#include <wlr/types/wlr_input_inhibitor.h>
11#include <wlr/types/wlr_virtual_keyboard_v1.h> 8#include <wlr/types/wlr_virtual_keyboard_v1.h>
12#include "sway/config.h" 9#include "sway/config.h"
13#include "sway/input/input-manager.h" 10#include "sway/input/input-manager.h"
11#include "sway/input/libinput.h"
14#include "sway/input/seat.h" 12#include "sway/input/seat.h"
15#include "sway/ipc-server.h" 13#include "sway/ipc-server.h"
16#include "sway/server.h" 14#include "sway/server.h"
@@ -173,401 +171,6 @@ void input_manager_verify_fallback_seat(void) {
173 } 171 }
174} 172}
175 173
176static void log_libinput_config_status(enum libinput_config_status status) {
177 if (status != LIBINPUT_CONFIG_STATUS_SUCCESS) {
178 sway_log(SWAY_ERROR, "Failed to apply libinput config: %s",
179 libinput_config_status_to_str(status));
180 }
181}
182
183static void input_manager_libinput_config_keyboard(
184 struct sway_input_device *input_device) {
185 struct wlr_input_device *wlr_device = input_device->wlr_device;
186 struct input_config *ic = input_device_get_config(input_device);
187 struct libinput_device *libinput_device;
188
189 if (!ic || !wlr_input_device_is_libinput(wlr_device)) {
190 return;
191 }
192
193 libinput_device = wlr_libinput_get_device_handle(wlr_device);
194 sway_log(SWAY_DEBUG, "input_manager_libinput_config_keyboard(%s)",
195 ic->identifier);
196
197 if (ic->send_events != INT_MIN) {
198 sway_log(SWAY_DEBUG, "libinput_config_keyboard(%s) send_events_set_mode(%d)",
199 ic->identifier, ic->send_events);
200 log_libinput_config_status(libinput_device_config_send_events_set_mode(
201 libinput_device, ic->send_events));
202 }
203}
204
205static void input_manager_libinput_reset_keyboard(
206 struct sway_input_device *input_device) {
207 struct wlr_input_device *wlr_device = input_device->wlr_device;
208 struct libinput_device *libinput_device;
209
210 if (!wlr_input_device_is_libinput(wlr_device)) {
211 return;
212 }
213
214 libinput_device = wlr_libinput_get_device_handle(wlr_device);
215
216 uint32_t send_events =
217 libinput_device_config_send_events_get_default_mode(libinput_device);
218 sway_log(SWAY_DEBUG, "libinput_reset_keyboard(%s) send_events_set_mode(%d)",
219 input_device->identifier, send_events);
220 log_libinput_config_status(libinput_device_config_send_events_set_mode(
221 libinput_device, send_events));
222}
223
224static void input_manager_libinput_config_switch(
225 struct sway_input_device *input_device) {
226 struct wlr_input_device *wlr_device = input_device->wlr_device;
227 struct input_config *ic = input_device_get_config(input_device);
228 struct libinput_device *libinput_device;
229
230 if (!ic || !wlr_input_device_is_libinput(wlr_device)) {
231 return;
232 }
233
234 libinput_device = wlr_libinput_get_device_handle(wlr_device);
235 sway_log(SWAY_DEBUG, "input_manager_libinput_config_switch(%s)",
236 ic->identifier);
237
238 if (ic->send_events != INT_MIN) {
239 sway_log(SWAY_DEBUG, "libinput_config_switch(%s) send_events_set_mode(%d)",
240 ic->identifier, ic->send_events);
241 log_libinput_config_status(libinput_device_config_send_events_set_mode(
242 libinput_device, ic->send_events));
243 }
244}
245
246static void input_manager_libinput_reset_switch(
247 struct sway_input_device *input_device) {
248 struct wlr_input_device *wlr_device = input_device->wlr_device;
249 struct libinput_device *libinput_device;
250
251 if (!wlr_input_device_is_libinput(wlr_device)) {
252 return;
253 }
254
255 libinput_device = wlr_libinput_get_device_handle(wlr_device);
256
257 uint32_t send_events =
258 libinput_device_config_send_events_get_default_mode(libinput_device);
259 sway_log(SWAY_DEBUG, "libinput_reset_switch(%s) send_events_set_mode(%d)",
260 input_device->identifier, send_events);
261 log_libinput_config_status(libinput_device_config_send_events_set_mode(
262 libinput_device, send_events));
263}
264
265static void input_manager_libinput_config_touch(
266 struct sway_input_device *input_device) {
267 struct wlr_input_device *wlr_device = input_device->wlr_device;
268 struct input_config *ic = input_device_get_config(input_device);
269 struct libinput_device *libinput_device;
270
271 if (!ic || !wlr_input_device_is_libinput(wlr_device)) {
272 return;
273 }
274
275 libinput_device = wlr_libinput_get_device_handle(wlr_device);
276 sway_log(SWAY_DEBUG, "input_manager_libinput_config_touch(%s)",
277 ic->identifier);
278
279 if (ic->send_events != INT_MIN) {
280 sway_log(SWAY_DEBUG, "libinput_config_touch(%s) send_events_set_mode(%d)",
281 ic->identifier, ic->send_events);
282 log_libinput_config_status(libinput_device_config_send_events_set_mode(
283 libinput_device, ic->send_events));
284 }
285 float *m = ic->calibration_matrix.matrix;
286 if (ic->calibration_matrix.configured) {
287 sway_log(SWAY_DEBUG, "libinput_config_touch(%s) calibration_set_matrix(%f %f %f %f %f %f)",
288 ic->identifier, m[0], m[1], m[2], m[3], m[4], m[5]);
289 log_libinput_config_status(libinput_device_config_calibration_set_matrix(
290 libinput_device, ic->calibration_matrix.matrix));
291 }
292}
293
294static void input_manager_libinput_reset_touch(
295 struct sway_input_device *input_device) {
296 struct wlr_input_device *wlr_device = input_device->wlr_device;
297 struct libinput_device *libinput_device;
298
299 if (!wlr_input_device_is_libinput(wlr_device)) {
300 return;
301 }
302
303 libinput_device = wlr_libinput_get_device_handle(wlr_device);
304
305 uint32_t send_events =
306 libinput_device_config_send_events_get_default_mode(libinput_device);
307 sway_log(SWAY_DEBUG, "libinput_reset_touch(%s) send_events_set_mode(%d)",
308 input_device->identifier, send_events);
309 log_libinput_config_status(libinput_device_config_send_events_set_mode(
310 libinput_device, send_events));
311
312 if (libinput_device_config_calibration_has_matrix(libinput_device)) {
313 float m[6];
314 libinput_device_config_calibration_get_default_matrix(libinput_device, m);
315 sway_log(SWAY_DEBUG, "libinput_reset_touch(%s) calibration_set_matrix("
316 "%f %f %f %f %f %f)", input_device->identifier, m[0], m[1],
317 m[2], m[3], m[4], m[5]);
318 log_libinput_config_status(libinput_device_config_calibration_set_matrix(
319 libinput_device, m));
320 }
321}
322
323static void input_manager_libinput_config_pointer(
324 struct sway_input_device *input_device) {
325 struct wlr_input_device *wlr_device = input_device->wlr_device;
326 struct input_config *ic = input_device_get_config(input_device);
327 struct libinput_device *libinput_device;
328
329 if (!ic || !wlr_input_device_is_libinput(wlr_device)) {
330 return;
331 }
332
333 libinput_device = wlr_libinput_get_device_handle(wlr_device);
334 sway_log(SWAY_DEBUG, "input_manager_libinput_config_pointer(%s)",
335 ic->identifier);
336
337 if (ic->accel_profile != INT_MIN) {
338 sway_log(SWAY_DEBUG, "libinput_config_pointer(%s) accel_set_profile(%d)",
339 ic->identifier, ic->accel_profile);
340 log_libinput_config_status(libinput_device_config_accel_set_profile(
341 libinput_device, ic->accel_profile));
342 }
343 if (ic->click_method != INT_MIN) {
344 sway_log(SWAY_DEBUG, "libinput_config_pointer(%s) click_set_method(%d)",
345 ic->identifier, ic->click_method);
346 log_libinput_config_status(libinput_device_config_click_set_method(
347 libinput_device, ic->click_method));
348 }
349 if (ic->drag != INT_MIN) {
350 sway_log(SWAY_DEBUG,
351 "libinput_config_pointer(%s) tap_set_drag_enabled(%d)",
352 ic->identifier, ic->drag);
353 log_libinput_config_status(libinput_device_config_tap_set_drag_enabled(
354 libinput_device, ic->drag));
355 }
356 if (ic->drag_lock != INT_MIN) {
357 sway_log(SWAY_DEBUG,
358 "libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)",
359 ic->identifier, ic->drag_lock);
360 log_libinput_config_status(
361 libinput_device_config_tap_set_drag_lock_enabled(
362 libinput_device, ic->drag_lock));
363 }
364 if (ic->dwt != INT_MIN) {
365 sway_log(SWAY_DEBUG, "libinput_config_pointer(%s) dwt_set_enabled(%d)",
366 ic->identifier, ic->dwt);
367 log_libinput_config_status(libinput_device_config_dwt_set_enabled(
368 libinput_device, ic->dwt));
369 }
370 if (ic->left_handed != INT_MIN) {
371 sway_log(SWAY_DEBUG,
372 "libinput_config_pointer(%s) left_handed_set_enabled(%d)",
373 ic->identifier, ic->left_handed);
374 log_libinput_config_status(libinput_device_config_left_handed_set(
375 libinput_device, ic->left_handed));
376 }
377 if (ic->middle_emulation != INT_MIN) {
378 sway_log(SWAY_DEBUG,
379 "libinput_config_pointer(%s) middle_emulation_set_enabled(%d)",
380 ic->identifier, ic->middle_emulation);
381 log_libinput_config_status(
382 libinput_device_config_middle_emulation_set_enabled(
383 libinput_device, ic->middle_emulation));
384 }
385 if (ic->natural_scroll != INT_MIN) {
386 sway_log(SWAY_DEBUG,
387 "libinput_config_pointer(%s) natural_scroll_set_enabled(%d)",
388 ic->identifier, ic->natural_scroll);
389 log_libinput_config_status(
390 libinput_device_config_scroll_set_natural_scroll_enabled(
391 libinput_device, ic->natural_scroll));
392 }
393 if (ic->pointer_accel != FLT_MIN) {
394 sway_log(SWAY_DEBUG, "libinput_config_pointer(%s) accel_set_speed(%f)",
395 ic->identifier, ic->pointer_accel);
396 log_libinput_config_status(libinput_device_config_accel_set_speed(
397 libinput_device, ic->pointer_accel));
398 }
399 if (ic->scroll_button != INT_MIN) {
400 sway_log(SWAY_DEBUG, "libinput_config_pointer(%s) scroll_set_button(%d)",
401 ic->identifier, ic->scroll_button);
402 log_libinput_config_status(libinput_device_config_scroll_set_button(
403 libinput_device, ic->scroll_button));
404 }
405 if (ic->scroll_method != INT_MIN) {
406 sway_log(SWAY_DEBUG, "libinput_config_pointer(%s) scroll_set_method(%d)",
407 ic->identifier, ic->scroll_method);
408 log_libinput_config_status(libinput_device_config_scroll_set_method(
409 libinput_device, ic->scroll_method));
410 }
411 if (ic->send_events != INT_MIN) {
412 sway_log(SWAY_DEBUG, "libinput_config_pointer(%s) send_events_set_mode(%d)",
413 ic->identifier, ic->send_events);
414 log_libinput_config_status(libinput_device_config_send_events_set_mode(
415 libinput_device, ic->send_events));
416 }
417 if (ic->tap != INT_MIN) {
418 sway_log(SWAY_DEBUG, "libinput_config_pointer(%s) tap_set_enabled(%d)",
419 ic->identifier, ic->tap);
420 log_libinput_config_status(libinput_device_config_tap_set_enabled(
421 libinput_device, ic->tap));
422 }
423 if (ic->tap_button_map != INT_MIN) {
424 sway_log(SWAY_DEBUG, "libinput_config_pointer(%s) tap_set_button_map(%d)",
425 ic->identifier, ic->tap_button_map);
426 log_libinput_config_status(libinput_device_config_tap_set_button_map(
427 libinput_device, ic->tap_button_map));
428 }
429}
430
431static void input_manager_libinput_reset_pointer(
432 struct sway_input_device *input_device) {
433 struct wlr_input_device *wlr_device = input_device->wlr_device;
434
435 if (!wlr_input_device_is_libinput(wlr_device)) {
436 return;
437 }
438
439 struct libinput_device *libinput_device =
440 wlr_libinput_get_device_handle(wlr_device);
441
442 uint32_t send_events =
443 libinput_device_config_send_events_get_default_mode(libinput_device);
444 sway_log(SWAY_DEBUG, "libinput_reset_pointer(%s) send_events_set_mode(%d)",
445 input_device->identifier, send_events);
446 log_libinput_config_status(libinput_device_config_send_events_set_mode(
447 libinput_device, send_events));
448
449 if (libinput_device_config_tap_get_finger_count(libinput_device) > 0) {
450 enum libinput_config_tap_state tap =
451 libinput_device_config_tap_get_default_enabled(libinput_device);
452 sway_log(SWAY_DEBUG, "libinput_reset_pointer(%s) tap_set_enabled(%d)",
453 input_device->identifier, tap);
454 log_libinput_config_status(libinput_device_config_tap_set_enabled(
455 libinput_device, tap));
456
457 enum libinput_config_tap_button_map tap_button_map =
458 libinput_device_config_tap_get_button_map(libinput_device);
459 sway_log(SWAY_DEBUG,
460 "libinput_reset_pointer(%s) tap_set_button_map(%d)",
461 input_device->identifier, tap_button_map);
462 log_libinput_config_status(libinput_device_config_tap_set_button_map(
463 libinput_device, tap_button_map));
464
465 enum libinput_config_drag_state drag =
466 libinput_device_config_tap_get_default_drag_enabled(libinput_device);
467 sway_log(SWAY_DEBUG,
468 "libinput_reset_pointer(%s) tap_set_drag_enabled(%d)",
469 input_device->identifier, drag);
470 log_libinput_config_status(libinput_device_config_tap_set_drag_enabled(
471 libinput_device, drag));
472
473 enum libinput_config_drag_lock_state drag_lock =
474 libinput_device_config_tap_get_default_drag_lock_enabled(
475 libinput_device);
476 sway_log(SWAY_DEBUG,
477 "libinput_reset_pointer(%s) tap_set_drag_lock_enabled(%d)",
478 input_device->identifier, drag_lock);
479 log_libinput_config_status(
480 libinput_device_config_tap_set_drag_lock_enabled(
481 libinput_device, drag_lock));
482 }
483
484 if (libinput_device_config_accel_is_available(libinput_device)) {
485 double pointer_accel =
486 libinput_device_config_accel_get_default_speed(libinput_device);
487 sway_log(SWAY_DEBUG, "libinput_reset_pointer(%s) accel_set_speed(%f)",
488 input_device->identifier, pointer_accel);
489 log_libinput_config_status(libinput_device_config_accel_set_speed(
490 libinput_device, pointer_accel));
491
492 enum libinput_config_accel_profile accel_profile =
493 libinput_device_config_accel_get_default_profile(libinput_device);
494 sway_log(SWAY_DEBUG, "libinput_reset_pointer(%s) accel_set_profile(%d)",
495 input_device->identifier, accel_profile);
496 log_libinput_config_status(libinput_device_config_accel_set_profile(
497 libinput_device, accel_profile));
498 }
499
500 if (libinput_device_config_scroll_has_natural_scroll(libinput_device)) {
501 int natural_scroll =
502 libinput_device_config_scroll_get_default_natural_scroll_enabled(
503 libinput_device);
504 sway_log(SWAY_DEBUG,
505 "libinput_reset_pointer(%s) natural_scroll_set_enabled(%d)",
506 input_device->identifier, natural_scroll);
507 log_libinput_config_status(
508 libinput_device_config_scroll_set_natural_scroll_enabled(
509 libinput_device, natural_scroll));
510 }
511
512 if (libinput_device_config_left_handed_is_available(libinput_device)) {
513 int left_handed =
514 libinput_device_config_left_handed_get_default(libinput_device);
515 sway_log(SWAY_DEBUG,
516 "libinput_reset_pointer(%s) left_handed_set_enabled(%d)",
517 input_device->identifier, left_handed);
518 log_libinput_config_status(libinput_device_config_left_handed_set(
519 libinput_device, left_handed));
520 }
521
522 uint32_t click = libinput_device_config_click_get_methods(libinput_device);
523 if ((click & ~LIBINPUT_CONFIG_CLICK_METHOD_NONE) != 0) {
524 enum libinput_config_click_method click_method =
525 libinput_device_config_click_get_default_method(libinput_device);
526 sway_log(SWAY_DEBUG, "libinput_reset_pointer(%s) click_set_method(%d)",
527 input_device->identifier, click_method);
528 log_libinput_config_status(libinput_device_config_click_set_method(
529 libinput_device, click_method));
530 }
531
532 if (libinput_device_config_middle_emulation_is_available(libinput_device)) {
533 enum libinput_config_middle_emulation_state middle_emulation =
534 libinput_device_config_middle_emulation_get_default_enabled(
535 libinput_device);
536 sway_log(SWAY_DEBUG,
537 "libinput_reset_pointer(%s) middle_emulation_set_enabled(%d)",
538 input_device->identifier, middle_emulation);
539 log_libinput_config_status(
540 libinput_device_config_middle_emulation_set_enabled(
541 libinput_device, middle_emulation));
542 }
543
544 uint32_t scroll = libinput_device_config_scroll_get_methods(libinput_device);
545 if ((scroll & ~LIBINPUT_CONFIG_SCROLL_NO_SCROLL) != 0) {
546 enum libinput_config_scroll_method scroll_method =
547 libinput_device_config_scroll_get_default_method(libinput_device);
548 sway_log(SWAY_DEBUG, "libinput_reset_pointer(%s) scroll_set_method(%d)",
549 input_device->identifier, scroll_method);
550 log_libinput_config_status(libinput_device_config_scroll_set_method(
551 libinput_device, scroll_method));
552
553 uint32_t scroll_button =
554 libinput_device_config_scroll_get_default_button(libinput_device);
555 sway_log(SWAY_DEBUG, "libinput_reset_pointer(%s) scroll_set_button(%d)",
556 input_device->identifier, scroll_button);
557 log_libinput_config_status(libinput_device_config_scroll_set_button(
558 libinput_device, scroll_button));
559 }
560
561 if (libinput_device_config_dwt_is_available(libinput_device)) {
562 enum libinput_config_dwt_state dwt =
563 libinput_device_config_dwt_get_default_enabled(libinput_device);
564 sway_log(SWAY_DEBUG, "libinput_reset_pointer(%s) dwt_set_enabled(%d)",
565 input_device->identifier, dwt);
566 log_libinput_config_status(libinput_device_config_dwt_set_enabled(
567 libinput_device, dwt));
568 }
569}
570
571static void handle_device_destroy(struct wl_listener *listener, void *data) { 174static void handle_device_destroy(struct wl_listener *listener, void *data) {
572 struct wlr_input_device *device = data; 175 struct wlr_input_device *device = data;
573 176
@@ -614,16 +217,7 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
614 217
615 apply_input_type_config(input_device); 218 apply_input_type_config(input_device);
616 219
617 if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER || 220 sway_input_configure_libinput_device(input_device);
618 input_device->wlr_device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
619 input_manager_libinput_config_pointer(input_device);
620 } else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) {
621 input_manager_libinput_config_keyboard(input_device);
622 } else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_SWITCH) {
623 input_manager_libinput_config_switch(input_device);
624 } else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_TOUCH) {
625 input_manager_libinput_config_touch(input_device);
626 }
627 221
628 wl_signal_add(&device->events.destroy, &input_device->device_destroy); 222 wl_signal_add(&device->events.destroy, &input_device->device_destroy);
629 input_device->device_destroy.notify = handle_device_destroy; 223 input_device->device_destroy.notify = handle_device_destroy;
@@ -775,17 +369,7 @@ void input_manager_apply_input_config(struct input_config *input_config) {
775 if (strcmp(input_device->identifier, input_config->identifier) == 0 369 if (strcmp(input_device->identifier, input_config->identifier) == 0
776 || wildcard 370 || wildcard
777 || type_matches) { 371 || type_matches) {
778 if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER || 372 sway_input_configure_libinput_device(input_device);
779 input_device->wlr_device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
780 input_manager_libinput_config_pointer(input_device);
781 } else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) {
782 input_manager_libinput_config_keyboard(input_device);
783 } else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_SWITCH) {
784 input_manager_libinput_config_switch(input_device);
785 } else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_TOUCH) {
786 input_manager_libinput_config_touch(input_device);
787 }
788
789 struct sway_seat *seat = NULL; 373 struct sway_seat *seat = NULL;
790 wl_list_for_each(seat, &server.input->seats, link) { 374 wl_list_for_each(seat, &server.input->seats, link) {
791 seat_configure_device(seat, input_device); 375 seat_configure_device(seat, input_device);
@@ -795,17 +379,7 @@ void input_manager_apply_input_config(struct input_config *input_config) {
795} 379}
796 380
797void input_manager_reset_input(struct sway_input_device *input_device) { 381void input_manager_reset_input(struct sway_input_device *input_device) {
798 if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER || 382 sway_input_reset_libinput_device(input_device);
799 input_device->wlr_device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
800 input_manager_libinput_reset_pointer(input_device);
801 } else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) {
802 input_manager_libinput_reset_keyboard(input_device);
803 } else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_SWITCH) {
804 input_manager_libinput_reset_switch(input_device);
805 } else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_TOUCH) {
806 input_manager_libinput_reset_touch(input_device);
807 }
808
809 struct sway_seat *seat = NULL; 383 struct sway_seat *seat = NULL;
810 wl_list_for_each(seat, &server.input->seats, link) { 384 wl_list_for_each(seat, &server.input->seats, link) {
811 seat_reset_device(seat, input_device); 385 seat_reset_device(seat, input_device);
diff --git a/sway/input/libinput.c b/sway/input/libinput.c
new file mode 100644
index 00000000..60d7da46
--- /dev/null
+++ b/sway/input/libinput.c
@@ -0,0 +1,382 @@
1#include <float.h>
2#include <libinput.h>
3#include <limits.h>
4#include <wlr/backend/libinput.h>
5#include "log.h"
6#include "sway/config.h"
7#include "sway/input/input-manager.h"
8#include "sway/ipc-server.h"
9
10static void log_status(enum libinput_config_status status) {
11 if (status != LIBINPUT_CONFIG_STATUS_SUCCESS) {
12 sway_log(SWAY_ERROR, "Failed to apply libinput config: %s",
13 libinput_config_status_to_str(status));
14 }
15}
16
17static bool set_send_events(struct libinput_device *device, uint32_t mode) {
18 if ((libinput_device_config_send_events_get_mode(device) & mode) == 0) {
19 return false;
20 }
21 sway_log(SWAY_DEBUG, "send_events_set_mode(%d)", mode);
22 log_status(libinput_device_config_send_events_set_mode(device, mode));
23 return true;
24}
25
26static bool set_tap(struct libinput_device *device,
27 enum libinput_config_tap_state tap) {
28 if (libinput_device_config_tap_get_finger_count(device) <= 0 ||
29 libinput_device_config_tap_get_enabled(device) == tap) {
30 return false;
31 }
32 sway_log(SWAY_DEBUG, "tap_set_enabled(%d)", tap);
33 log_status(libinput_device_config_tap_set_enabled(device, tap));
34 return true;
35}
36
37static bool set_tap_button_map(struct libinput_device *device,
38 enum libinput_config_tap_button_map map) {
39 if (libinput_device_config_tap_get_finger_count(device) <= 0 ||
40 libinput_device_config_tap_get_button_map(device) == map) {
41 return false;
42 }
43 sway_log(SWAY_DEBUG, "tap_set_button_map(%d)", map);
44 log_status(libinput_device_config_tap_set_button_map(device, map));
45 return true;
46}
47
48static bool set_tap_drag(struct libinput_device *device,
49 enum libinput_config_drag_state drag) {
50 if (libinput_device_config_tap_get_finger_count(device) <= 0 ||
51 libinput_device_config_tap_get_drag_enabled(device) == drag) {
52 return false;
53 }
54 sway_log(SWAY_DEBUG, "tap_set_drag_enabled(%d)", drag);
55 log_status(libinput_device_config_tap_set_drag_enabled(device, drag));
56 return true;
57}
58
59static bool set_tap_drag_lock(struct libinput_device *device,
60 enum libinput_config_drag_lock_state lock) {
61 if (libinput_device_config_tap_get_finger_count(device) <= 0 ||
62 libinput_device_config_tap_get_drag_lock_enabled(device) == lock) {
63 return false;
64 }
65 sway_log(SWAY_DEBUG, "tap_set_drag_lock_enabled(%d)", lock);
66 log_status(libinput_device_config_tap_set_drag_lock_enabled(device, lock));
67 return true;
68}
69
70static bool set_accel_speed(struct libinput_device *device, double speed) {
71 if (!libinput_device_config_accel_is_available(device) ||
72 libinput_device_config_accel_get_speed(device) == speed) {
73 return false;
74 }
75 sway_log(SWAY_DEBUG, "accel_set_speed(%f)", speed);
76 log_status(libinput_device_config_accel_set_speed(device, speed));
77 return true;
78}
79
80static bool set_accel_profile(struct libinput_device *device,
81 enum libinput_config_accel_profile profile) {
82 if (!libinput_device_config_accel_is_available(device) ||
83 libinput_device_config_accel_get_profile(device) == profile) {
84 return false;
85 }
86 sway_log(SWAY_DEBUG, "accel_set_profile(%d)", profile);
87 log_status(libinput_device_config_accel_set_profile(device, profile));
88 return true;
89}
90
91static bool set_natural_scroll(struct libinput_device *d, bool n) {
92 if (!libinput_device_config_scroll_has_natural_scroll(d) ||
93 libinput_device_config_scroll_get_natural_scroll_enabled(d) == n) {
94 return false;
95 }
96 sway_log(SWAY_DEBUG, "scroll_set_natural_scroll(%d)", n);
97 log_status(libinput_device_config_scroll_set_natural_scroll_enabled(d, n));
98 return true;
99}
100
101static bool set_left_handed(struct libinput_device *device, bool left) {
102 if (!libinput_device_config_left_handed_is_available(device) ||
103 libinput_device_config_left_handed_get(device) == left) {
104 return false;
105 }
106 sway_log(SWAY_DEBUG, "left_handed_set(%d)", left);
107 log_status(libinput_device_config_left_handed_set(device, left));
108 return true;
109}
110
111static bool set_click_method(struct libinput_device *device,
112 enum libinput_config_click_method method) {
113 uint32_t click = libinput_device_config_click_get_methods(device);
114 if ((click & ~LIBINPUT_CONFIG_CLICK_METHOD_NONE) == 0 ||
115 libinput_device_config_click_get_method(device) == method) {
116 return false;
117 }
118 sway_log(SWAY_DEBUG, "click_set_method(%d)", method);
119 log_status(libinput_device_config_click_set_method(device, method));
120 return true;
121}
122
123static bool set_middle_emulation(struct libinput_device *dev,
124 enum libinput_config_middle_emulation_state mid) {
125 if (!libinput_device_config_middle_emulation_is_available(dev) ||
126 libinput_device_config_middle_emulation_get_enabled(dev) == mid) {
127 return false;
128 }
129 sway_log(SWAY_DEBUG, "middle_emulation_set_enabled(%d)", mid);
130 log_status(libinput_device_config_left_handed_set(dev, mid));
131 return true;
132}
133
134static bool set_scroll_method(struct libinput_device *device,
135 enum libinput_config_scroll_method method) {
136 uint32_t scroll = libinput_device_config_scroll_get_methods(device);
137 if ((scroll & ~LIBINPUT_CONFIG_SCROLL_NO_SCROLL) == 0 ||
138 libinput_device_config_scroll_get_method(device) == method) {
139 return false;
140 }
141 sway_log(SWAY_DEBUG, "scroll_set_method(%d)", method);
142 log_status(libinput_device_config_scroll_set_method(device, method));
143 return true;
144}
145
146static bool set_scroll_button(struct libinput_device *dev, uint32_t button) {
147 uint32_t scroll = libinput_device_config_scroll_get_methods(dev);
148 if ((scroll & ~LIBINPUT_CONFIG_SCROLL_NO_SCROLL) == 0 ||
149 libinput_device_config_scroll_get_button(dev) == button) {
150 return false;
151 }
152 sway_log(SWAY_DEBUG, "scroll_set_button(%d)", button);
153 log_status(libinput_device_config_scroll_set_button(dev, button));
154 return true;
155}
156
157static bool set_dwt(struct libinput_device *device, bool dwt) {
158 if (!libinput_device_config_dwt_is_available(device) ||
159 libinput_device_config_dwt_get_enabled(device) == dwt) {
160 return false;
161 }
162 sway_log(SWAY_DEBUG, "dwt_set_enabled(%d)", dwt);
163 log_status(libinput_device_config_dwt_set_enabled(device, dwt));
164 return true;
165}
166
167static bool set_calibration_matrix(struct libinput_device *dev, float mat[6]) {
168 if (!libinput_device_config_calibration_has_matrix(dev)) {
169 return false;
170 }
171 bool changed = false;
172 float current[6];
173 libinput_device_config_calibration_get_matrix(dev, current);
174 for (int i = 0; i < 6; i++) {
175 if (current[i] != mat[i]) {
176 changed = true;
177 break;
178 }
179 }
180 if (changed) {
181 sway_log(SWAY_DEBUG, "calibration_set_matrix(%f, %f, %f, %f, %f, %f)",
182 mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
183 log_status(libinput_device_config_calibration_set_matrix(dev, mat));
184 }
185 return changed;
186}
187
188static bool config_libinput_pointer(struct libinput_device *device,
189 struct input_config *ic, const char *device_id) {
190 sway_log(SWAY_DEBUG, "config_libinput_pointer('%s' on '%s')",
191 ic->identifier, device_id);
192 bool changed = false;
193 if (ic->send_events != INT_MIN) {
194 changed |= set_send_events(device, ic->send_events);
195 }
196 if (ic->tap != INT_MIN) {
197 changed |= set_tap(device, ic->tap);
198 }
199 if (ic->tap_button_map != INT_MIN) {
200 changed |= set_tap_button_map(device, ic->tap_button_map);
201 }
202 if (ic->drag != INT_MIN) {
203 changed |= set_tap_drag(device, ic->drag);
204 }
205 if (ic->drag_lock != INT_MIN) {
206 changed |= set_tap_drag_lock(device, ic->drag_lock);
207 }
208
209 if (ic->pointer_accel != FLT_MIN) {
210 changed |= set_accel_speed(device, ic->pointer_accel);
211 }
212 if (ic->accel_profile != INT_MIN) {
213 changed |= set_accel_profile(device, ic->accel_profile);
214 }
215 if (ic->natural_scroll != INT_MIN) {
216 changed |= set_natural_scroll(device, ic->natural_scroll);
217 }
218 if (ic->left_handed != INT_MIN) {
219 changed |= set_left_handed(device, ic->left_handed);
220 }
221 if (ic->click_method != INT_MIN) {
222 changed |= set_click_method(device, ic->click_method);
223 }
224 if (ic->middle_emulation != INT_MIN) {
225 changed |= set_middle_emulation(device, ic->middle_emulation);
226 }
227 if (ic->scroll_method != INT_MIN) {
228 changed |= set_scroll_method(device, ic->scroll_method);
229 }
230 if (ic->scroll_button != INT_MIN) {
231 changed |= set_scroll_button(device, ic->scroll_button);
232 }
233 if (ic->dwt != INT_MIN) {
234 changed |= set_dwt(device, ic->dwt);
235 }
236 return changed;
237}
238
239static bool config_libinput_keyboard(struct libinput_device *device,
240 struct input_config *ic, const char *device_id) {
241 sway_log(SWAY_DEBUG, "config_libinput_keyboard('%s' on '%s')",
242 ic->identifier, device_id);
243 if (ic->send_events != INT_MIN) {
244 return set_send_events(device, ic->send_events);
245 }
246 return false;
247}
248
249static bool config_libinput_switch(struct libinput_device *device,
250 struct input_config *ic, const char *device_id) {
251 sway_log(SWAY_DEBUG, "config_libinput_switch('%s' on '%s')",
252 ic->identifier, device_id);
253 if (ic->send_events != INT_MIN) {
254 return set_send_events(device, ic->send_events);
255 }
256 return false;
257}
258
259static bool config_libinput_touch(struct libinput_device *device,
260 struct input_config *ic, const char *device_id) {
261 sway_log(SWAY_DEBUG, "config_libinput_touch('%s' on '%s')",
262 ic->identifier, device_id);
263 bool changed = false;
264 if (ic->send_events != INT_MIN) {
265 changed |= set_send_events(device, ic->send_events);
266 }
267 if (ic->calibration_matrix.configured) {
268 changed |= set_calibration_matrix(device, ic->calibration_matrix.matrix);
269 }
270 return changed;
271}
272
273void sway_input_configure_libinput_device(struct sway_input_device *device) {
274 struct input_config *ic = input_device_get_config(device);
275 if (!ic || !wlr_input_device_is_libinput(device->wlr_device)) {
276 return;
277 }
278 bool changed = false;
279 const char *device_id = device->identifier;
280 struct libinput_device *libinput_device =
281 wlr_libinput_get_device_handle(device->wlr_device);
282 if (device->wlr_device->type == WLR_INPUT_DEVICE_POINTER ||
283 device->wlr_device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
284 changed = config_libinput_pointer(libinput_device, ic, device_id);
285 } else if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) {
286 changed = config_libinput_keyboard(libinput_device, ic, device_id);
287 } else if (device->wlr_device->type == WLR_INPUT_DEVICE_SWITCH) {
288 changed = config_libinput_switch(libinput_device, ic, device_id);
289 } else if (device->wlr_device->type == WLR_INPUT_DEVICE_TOUCH) {
290 changed = config_libinput_touch(libinput_device, ic, device_id);
291 }
292 if (changed) {
293 ipc_event_input("libinput_config", device);
294 }
295}
296
297static bool reset_libinput_pointer(struct libinput_device *device,
298 const char *device_id) {
299 sway_log(SWAY_DEBUG, "reset_libinput_pointer(%s)", device_id);
300 bool changed = false;
301 changed |= set_send_events(device,
302 libinput_device_config_send_events_get_default_mode(device));
303 changed |= set_tap(device,
304 libinput_device_config_tap_get_default_enabled(device));
305 changed |= set_tap_button_map(device,
306 libinput_device_config_tap_get_button_map(device));
307 changed |= set_tap_drag(device,
308 libinput_device_config_tap_get_default_drag_enabled(device));
309 changed |= set_tap_drag_lock(device,
310 libinput_device_config_tap_get_default_drag_lock_enabled(device));
311 changed |= set_accel_speed(device,
312 libinput_device_config_accel_get_default_speed(device));
313 changed |= set_accel_profile(device,
314 libinput_device_config_accel_get_default_profile(device));
315 changed |= set_natural_scroll(device,
316 libinput_device_config_scroll_get_default_natural_scroll_enabled(
317 device));
318 changed |= set_left_handed(device,
319 libinput_device_config_left_handed_get_default(device));
320 changed |= set_click_method(device,
321 libinput_device_config_click_get_default_method(device));
322 changed |= set_middle_emulation(device,
323 libinput_device_config_middle_emulation_get_default_enabled(device));
324 changed |= set_scroll_method(device,
325 libinput_device_config_scroll_get_default_method(device));
326 changed |= set_scroll_button(device,
327 libinput_device_config_scroll_get_default_button(device));
328 changed |= set_dwt(device,
329 libinput_device_config_dwt_get_default_enabled(device));
330 return changed;
331}
332
333static bool reset_libinput_keyboard(struct libinput_device *device,
334 const char *device_id) {
335 sway_log(SWAY_DEBUG, "reset_libinput_keyboard(%s)", device_id);
336 return set_send_events(device,
337 libinput_device_config_send_events_get_default_mode(device));
338}
339
340static bool reset_libinput_switch(struct libinput_device *device,
341 const char *device_id) {
342 sway_log(SWAY_DEBUG, "reset_libinput_switch(%s)", device_id);
343 return set_send_events(device,
344 libinput_device_config_send_events_get_default_mode(device));
345}
346
347static bool reset_libinput_touch(struct libinput_device *device,
348 const char *device_id) {
349 sway_log(SWAY_DEBUG, "reset_libinput_touch(%s)", device_id);
350 bool changed = false;
351
352 changed |= set_send_events(device,
353 libinput_device_config_send_events_get_default_mode(device));
354
355 float matrix[6];
356 libinput_device_config_calibration_get_matrix(device, matrix);
357 changed |= set_calibration_matrix(device, matrix);
358
359 return changed;
360}
361
362void sway_input_reset_libinput_device(struct sway_input_device *device) {
363 if (!wlr_input_device_is_libinput(device->wlr_device)) {
364 return;
365 }
366 bool changed = false;
367 struct libinput_device *libinput_device =
368 wlr_libinput_get_device_handle(device->wlr_device);
369 if (device->wlr_device->type == WLR_INPUT_DEVICE_POINTER ||
370 device->wlr_device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
371 changed = reset_libinput_pointer(libinput_device, device->identifier);
372 } else if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) {
373 changed = reset_libinput_keyboard(libinput_device, device->identifier);
374 } else if (device->wlr_device->type == WLR_INPUT_DEVICE_SWITCH) {
375 changed = reset_libinput_switch(libinput_device, device->identifier);
376 } else if (device->wlr_device->type == WLR_INPUT_DEVICE_TOUCH) {
377 changed = reset_libinput_touch(libinput_device, device->identifier);
378 }
379 if (changed) {
380 ipc_event_input("libinput_config", device);
381 }
382}