diff options
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 1 | ||||
-rw-r--r-- | sway/commands/input.c | 1 | ||||
-rw-r--r-- | sway/commands/input/map_to_region.c | 56 | ||||
-rw-r--r-- | sway/config/input.c | 8 | ||||
-rw-r--r-- | sway/input/seat.c | 29 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway-input.5.scd | 2 |
8 files changed, 97 insertions, 2 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h index 7ff3b651..d994ae9b 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -246,6 +246,7 @@ sway_cmd input_cmd_events; | |||
246 | sway_cmd input_cmd_left_handed; | 246 | sway_cmd input_cmd_left_handed; |
247 | sway_cmd input_cmd_map_from_region; | 247 | sway_cmd input_cmd_map_from_region; |
248 | sway_cmd input_cmd_map_to_output; | 248 | sway_cmd input_cmd_map_to_output; |
249 | sway_cmd input_cmd_map_to_region; | ||
249 | sway_cmd input_cmd_middle_emulation; | 250 | sway_cmd input_cmd_middle_emulation; |
250 | sway_cmd input_cmd_natural_scroll; | 251 | sway_cmd input_cmd_natural_scroll; |
251 | sway_cmd input_cmd_pointer_accel; | 252 | sway_cmd input_cmd_pointer_accel; |
diff --git a/include/sway/config.h b/include/sway/config.h index 8c93c20d..0a010c6d 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -148,6 +148,7 @@ struct input_config { | |||
148 | 148 | ||
149 | struct input_config_mapped_from_region *mapped_from_region; | 149 | struct input_config_mapped_from_region *mapped_from_region; |
150 | char *mapped_to_output; | 150 | char *mapped_to_output; |
151 | struct wlr_box *mapped_to_region; | ||
151 | 152 | ||
152 | bool capturable; | 153 | bool capturable; |
153 | struct wlr_box region; | 154 | struct wlr_box region; |
diff --git a/sway/commands/input.c b/sway/commands/input.c index 2289ede5..a11ad79a 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c | |||
@@ -18,6 +18,7 @@ static struct cmd_handler input_handlers[] = { | |||
18 | { "left_handed", input_cmd_left_handed }, | 18 | { "left_handed", input_cmd_left_handed }, |
19 | { "map_from_region", input_cmd_map_from_region }, | 19 | { "map_from_region", input_cmd_map_from_region }, |
20 | { "map_to_output", input_cmd_map_to_output }, | 20 | { "map_to_output", input_cmd_map_to_output }, |
21 | { "map_to_region", input_cmd_map_to_region }, | ||
21 | { "middle_emulation", input_cmd_middle_emulation }, | 22 | { "middle_emulation", input_cmd_middle_emulation }, |
22 | { "natural_scroll", input_cmd_natural_scroll }, | 23 | { "natural_scroll", input_cmd_natural_scroll }, |
23 | { "pointer_accel", input_cmd_pointer_accel }, | 24 | { "pointer_accel", input_cmd_pointer_accel }, |
diff --git a/sway/commands/input/map_to_region.c b/sway/commands/input/map_to_region.c new file mode 100644 index 00000000..e0b69ed5 --- /dev/null +++ b/sway/commands/input/map_to_region.c | |||
@@ -0,0 +1,56 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include <wlr/types/wlr_box.h> | ||
5 | #include "sway/commands.h" | ||
6 | #include "sway/config.h" | ||
7 | |||
8 | struct cmd_results *input_cmd_map_to_region(int argc, char **argv) { | ||
9 | struct cmd_results *error = NULL; | ||
10 | if ((error = checkarg(argc, "map_to_region", EXPECTED_EQUAL_TO, 4))) { | ||
11 | return error; | ||
12 | } | ||
13 | struct input_config *ic = config->handler_context.input_config; | ||
14 | if (!ic) { | ||
15 | return cmd_results_new(CMD_FAILURE, "No input device defined"); | ||
16 | } | ||
17 | |||
18 | // This is used to clear the current output mapping. | ||
19 | ic->mapped_to_output = strdup(""); | ||
20 | |||
21 | ic->mapped_to_region = calloc(1, sizeof(struct wlr_box)); | ||
22 | |||
23 | const char *errstr; | ||
24 | char *end; | ||
25 | |||
26 | ic->mapped_to_region->x = strtol(argv[0], &end, 10); | ||
27 | if (end[0] != '\0') { | ||
28 | errstr = "Invalid X coordinate"; | ||
29 | goto error; | ||
30 | } | ||
31 | |||
32 | ic->mapped_to_region->y = strtol(argv[1], &end, 10); | ||
33 | if (end[0] != '\0') { | ||
34 | errstr = "Invalid Y coordinate"; | ||
35 | goto error; | ||
36 | } | ||
37 | |||
38 | ic->mapped_to_region->width = strtol(argv[2], &end, 10); | ||
39 | if (end[0] != '\0' || ic->mapped_to_region->width < 1) { | ||
40 | errstr = "Invalid width"; | ||
41 | goto error; | ||
42 | } | ||
43 | |||
44 | ic->mapped_to_region->height = strtol(argv[3], &end, 10); | ||
45 | if (end[0] != '\0' || ic->mapped_to_region->height < 1) { | ||
46 | errstr = "Invalid height"; | ||
47 | goto error; | ||
48 | } | ||
49 | |||
50 | return cmd_results_new(CMD_SUCCESS, NULL); | ||
51 | |||
52 | error: | ||
53 | free(ic->mapped_to_region); | ||
54 | ic->mapped_to_region = NULL; | ||
55 | return cmd_results_new(CMD_FAILURE, errstr); | ||
56 | } | ||
diff --git a/sway/config/input.c b/sway/config/input.c index ad4a64ee..294ed08f 100644 --- a/sway/config/input.c +++ b/sway/config/input.c | |||
@@ -138,6 +138,13 @@ void merge_input_config(struct input_config *dst, struct input_config *src) { | |||
138 | free(dst->mapped_to_output); | 138 | free(dst->mapped_to_output); |
139 | dst->mapped_to_output = strdup(src->mapped_to_output); | 139 | dst->mapped_to_output = strdup(src->mapped_to_output); |
140 | } | 140 | } |
141 | if (src->mapped_to_region) { | ||
142 | free(dst->mapped_to_region); | ||
143 | dst->mapped_to_region = | ||
144 | malloc(sizeof(struct wlr_box)); | ||
145 | memcpy(dst->mapped_to_region, src->mapped_to_region, | ||
146 | sizeof(struct wlr_box)); | ||
147 | } | ||
141 | if (src->calibration_matrix.configured) { | 148 | if (src->calibration_matrix.configured) { |
142 | dst->calibration_matrix.configured = src->calibration_matrix.configured; | 149 | dst->calibration_matrix.configured = src->calibration_matrix.configured; |
143 | memcpy(dst->calibration_matrix.matrix, src->calibration_matrix.matrix, | 150 | memcpy(dst->calibration_matrix.matrix, src->calibration_matrix.matrix, |
@@ -323,6 +330,7 @@ void free_input_config(struct input_config *ic) { | |||
323 | free(ic->xkb_variant); | 330 | free(ic->xkb_variant); |
324 | free(ic->mapped_from_region); | 331 | free(ic->mapped_from_region); |
325 | free(ic->mapped_to_output); | 332 | free(ic->mapped_to_output); |
333 | free(ic->mapped_to_region); | ||
326 | free(ic); | 334 | free(ic); |
327 | } | 335 | } |
328 | 336 | ||
diff --git a/sway/input/seat.c b/sway/input/seat.c index dc21ce61..5fc23a19 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -576,6 +576,7 @@ static void seat_reset_input_config(struct sway_seat *seat, | |||
576 | static void seat_apply_input_config(struct sway_seat *seat, | 576 | static void seat_apply_input_config(struct sway_seat *seat, |
577 | struct sway_seat_device *sway_device) { | 577 | struct sway_seat_device *sway_device) { |
578 | const char *mapped_to_output = NULL; | 578 | const char *mapped_to_output = NULL; |
579 | struct wlr_box *mapped_to_region = NULL; | ||
579 | 580 | ||
580 | struct input_config *ic = input_device_get_config( | 581 | struct input_config *ic = input_device_get_config( |
581 | sway_device->input_device); | 582 | sway_device->input_device); |
@@ -583,12 +584,31 @@ static void seat_apply_input_config(struct sway_seat *seat, | |||
583 | sway_log(SWAY_DEBUG, "Applying input config to %s", | 584 | sway_log(SWAY_DEBUG, "Applying input config to %s", |
584 | sway_device->input_device->identifier); | 585 | sway_device->input_device->identifier); |
585 | 586 | ||
587 | // We use an empty string as a marker to clear the mapped_to_output | ||
588 | // property, because a NULL set in a handler_context isn't preserved. | ||
589 | if (ic->mapped_to_output != NULL && ic->mapped_to_output[0] == '\0') { | ||
590 | free(ic->mapped_to_output); | ||
591 | ic->mapped_to_output = NULL; | ||
592 | wlr_cursor_map_input_to_output(seat->cursor->cursor, | ||
593 | sway_device->input_device->wlr_device, NULL); | ||
594 | } | ||
595 | |||
586 | mapped_to_output = ic->mapped_to_output; | 596 | mapped_to_output = ic->mapped_to_output; |
597 | if (mapped_to_output != NULL) { | ||
598 | // Output has just been set, clear region setting. | ||
599 | free(ic->mapped_to_region); | ||
600 | ic->mapped_to_region = NULL; | ||
601 | wlr_cursor_map_input_to_region(seat->cursor->cursor, | ||
602 | sway_device->input_device->wlr_device, NULL); | ||
603 | } | ||
604 | |||
605 | mapped_to_region = ic->mapped_to_region; | ||
587 | } | 606 | } |
588 | 607 | ||
589 | if (mapped_to_output == NULL) { | 608 | if (mapped_to_output == NULL && mapped_to_region == NULL) { |
590 | mapped_to_output = sway_device->input_device->wlr_device->output_name; | 609 | mapped_to_output = sway_device->input_device->wlr_device->output_name; |
591 | } | 610 | } |
611 | |||
592 | if (mapped_to_output != NULL) { | 612 | if (mapped_to_output != NULL) { |
593 | sway_log(SWAY_DEBUG, "Mapping input device %s to output %s", | 613 | sway_log(SWAY_DEBUG, "Mapping input device %s to output %s", |
594 | sway_device->input_device->identifier, mapped_to_output); | 614 | sway_device->input_device->identifier, mapped_to_output); |
@@ -604,6 +624,13 @@ static void seat_apply_input_config(struct sway_seat *seat, | |||
604 | sway_device->input_device->wlr_device, output->wlr_output); | 624 | sway_device->input_device->wlr_device, output->wlr_output); |
605 | sway_log(SWAY_DEBUG, "Mapped to output %s", output->wlr_output->name); | 625 | sway_log(SWAY_DEBUG, "Mapped to output %s", output->wlr_output->name); |
606 | } | 626 | } |
627 | } else if (mapped_to_region != NULL) { | ||
628 | sway_log(SWAY_DEBUG, "Mapping input device %s to %d,%d %dx%d", | ||
629 | sway_device->input_device->identifier, | ||
630 | mapped_to_region->x, mapped_to_region->y, | ||
631 | mapped_to_region->width, mapped_to_region->height); | ||
632 | wlr_cursor_map_input_to_region(seat->cursor->cursor, | ||
633 | sway_device->input_device->wlr_device, mapped_to_region); | ||
607 | } | 634 | } |
608 | } | 635 | } |
609 | 636 | ||
diff --git a/sway/meson.build b/sway/meson.build index 24628100..8fcf841c 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -150,6 +150,7 @@ sway_sources = files( | |||
150 | 'commands/input/left_handed.c', | 150 | 'commands/input/left_handed.c', |
151 | 'commands/input/map_from_region.c', | 151 | 'commands/input/map_from_region.c', |
152 | 'commands/input/map_to_output.c', | 152 | 'commands/input/map_to_output.c', |
153 | 'commands/input/map_to_region.c', | ||
153 | 'commands/input/middle_emulation.c', | 154 | 'commands/input/middle_emulation.c', |
154 | 'commands/input/natural_scroll.c', | 155 | 'commands/input/natural_scroll.c', |
155 | 'commands/input/pointer_accel.c', | 156 | 'commands/input/pointer_accel.c', |
diff --git a/sway/sway-input.5.scd b/sway/sway-input.5.scd index 2ee95c0b..d0bf648b 100644 --- a/sway/sway-input.5.scd +++ b/sway/sway-input.5.scd | |||
@@ -88,7 +88,7 @@ The following commands may only be used in the configuration file. | |||
88 | Maps inputs from this device to the specified output. Only meaningful if the | 88 | Maps inputs from this device to the specified output. Only meaningful if the |
89 | device is a pointer, touch, or drawing tablet device. | 89 | device is a pointer, touch, or drawing tablet device. |
90 | 90 | ||
91 | *input* <identifier> map_to_region <WxH@X,Y> | 91 | *input* <identifier> map_to_region <X> <Y> <width> <height> |
92 | Maps inputs from this device to the specified region of the global output | 92 | Maps inputs from this device to the specified region of the global output |
93 | layout. Only meaningful if the device is a pointer, touch, or drawing tablet | 93 | layout. Only meaningful if the device is a pointer, touch, or drawing tablet |
94 | device. | 94 | device. |