Implement input map_to_region command

This commit is contained in:
Tadeo Kondrak 2019-10-28 18:26:00 -06:00 committed by Simon Ser
parent df1a046875
commit 4829f1c26a
8 changed files with 97 additions and 2 deletions

View file

@ -246,6 +246,7 @@ sway_cmd input_cmd_events;
sway_cmd input_cmd_left_handed; sway_cmd input_cmd_left_handed;
sway_cmd input_cmd_map_from_region; sway_cmd input_cmd_map_from_region;
sway_cmd input_cmd_map_to_output; sway_cmd input_cmd_map_to_output;
sway_cmd input_cmd_map_to_region;
sway_cmd input_cmd_middle_emulation; sway_cmd input_cmd_middle_emulation;
sway_cmd input_cmd_natural_scroll; sway_cmd input_cmd_natural_scroll;
sway_cmd input_cmd_pointer_accel; sway_cmd input_cmd_pointer_accel;

View file

@ -148,6 +148,7 @@ struct input_config {
struct input_config_mapped_from_region *mapped_from_region; struct input_config_mapped_from_region *mapped_from_region;
char *mapped_to_output; char *mapped_to_output;
struct wlr_box *mapped_to_region;
bool capturable; bool capturable;
struct wlr_box region; struct wlr_box region;

View file

@ -18,6 +18,7 @@ static struct cmd_handler input_handlers[] = {
{ "left_handed", input_cmd_left_handed }, { "left_handed", input_cmd_left_handed },
{ "map_from_region", input_cmd_map_from_region }, { "map_from_region", input_cmd_map_from_region },
{ "map_to_output", input_cmd_map_to_output }, { "map_to_output", input_cmd_map_to_output },
{ "map_to_region", input_cmd_map_to_region },
{ "middle_emulation", input_cmd_middle_emulation }, { "middle_emulation", input_cmd_middle_emulation },
{ "natural_scroll", input_cmd_natural_scroll }, { "natural_scroll", input_cmd_natural_scroll },
{ "pointer_accel", input_cmd_pointer_accel }, { "pointer_accel", input_cmd_pointer_accel },

View file

@ -0,0 +1,56 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <string.h>
#include <wlr/types/wlr_box.h>
#include "sway/commands.h"
#include "sway/config.h"
struct cmd_results *input_cmd_map_to_region(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "map_to_region", EXPECTED_EQUAL_TO, 4))) {
return error;
}
struct input_config *ic = config->handler_context.input_config;
if (!ic) {
return cmd_results_new(CMD_FAILURE, "No input device defined");
}
// This is used to clear the current output mapping.
ic->mapped_to_output = strdup("");
ic->mapped_to_region = calloc(1, sizeof(struct wlr_box));
const char *errstr;
char *end;
ic->mapped_to_region->x = strtol(argv[0], &end, 10);
if (end[0] != '\0') {
errstr = "Invalid X coordinate";
goto error;
}
ic->mapped_to_region->y = strtol(argv[1], &end, 10);
if (end[0] != '\0') {
errstr = "Invalid Y coordinate";
goto error;
}
ic->mapped_to_region->width = strtol(argv[2], &end, 10);
if (end[0] != '\0' || ic->mapped_to_region->width < 1) {
errstr = "Invalid width";
goto error;
}
ic->mapped_to_region->height = strtol(argv[3], &end, 10);
if (end[0] != '\0' || ic->mapped_to_region->height < 1) {
errstr = "Invalid height";
goto error;
}
return cmd_results_new(CMD_SUCCESS, NULL);
error:
free(ic->mapped_to_region);
ic->mapped_to_region = NULL;
return cmd_results_new(CMD_FAILURE, errstr);
}

View file

@ -138,6 +138,13 @@ void merge_input_config(struct input_config *dst, struct input_config *src) {
free(dst->mapped_to_output); free(dst->mapped_to_output);
dst->mapped_to_output = strdup(src->mapped_to_output); dst->mapped_to_output = strdup(src->mapped_to_output);
} }
if (src->mapped_to_region) {
free(dst->mapped_to_region);
dst->mapped_to_region =
malloc(sizeof(struct wlr_box));
memcpy(dst->mapped_to_region, src->mapped_to_region,
sizeof(struct wlr_box));
}
if (src->calibration_matrix.configured) { if (src->calibration_matrix.configured) {
dst->calibration_matrix.configured = src->calibration_matrix.configured; dst->calibration_matrix.configured = src->calibration_matrix.configured;
memcpy(dst->calibration_matrix.matrix, src->calibration_matrix.matrix, memcpy(dst->calibration_matrix.matrix, src->calibration_matrix.matrix,
@ -323,6 +330,7 @@ void free_input_config(struct input_config *ic) {
free(ic->xkb_variant); free(ic->xkb_variant);
free(ic->mapped_from_region); free(ic->mapped_from_region);
free(ic->mapped_to_output); free(ic->mapped_to_output);
free(ic->mapped_to_region);
free(ic); free(ic);
} }

View file

@ -576,6 +576,7 @@ static void seat_reset_input_config(struct sway_seat *seat,
static void seat_apply_input_config(struct sway_seat *seat, static void seat_apply_input_config(struct sway_seat *seat,
struct sway_seat_device *sway_device) { struct sway_seat_device *sway_device) {
const char *mapped_to_output = NULL; const char *mapped_to_output = NULL;
struct wlr_box *mapped_to_region = NULL;
struct input_config *ic = input_device_get_config( struct input_config *ic = input_device_get_config(
sway_device->input_device); sway_device->input_device);
@ -583,12 +584,31 @@ static void seat_apply_input_config(struct sway_seat *seat,
sway_log(SWAY_DEBUG, "Applying input config to %s", sway_log(SWAY_DEBUG, "Applying input config to %s",
sway_device->input_device->identifier); sway_device->input_device->identifier);
mapped_to_output = ic->mapped_to_output; // We use an empty string as a marker to clear the mapped_to_output
// property, because a NULL set in a handler_context isn't preserved.
if (ic->mapped_to_output != NULL && ic->mapped_to_output[0] == '\0') {
free(ic->mapped_to_output);
ic->mapped_to_output = NULL;
wlr_cursor_map_input_to_output(seat->cursor->cursor,
sway_device->input_device->wlr_device, NULL);
} }
if (mapped_to_output == NULL) { mapped_to_output = ic->mapped_to_output;
if (mapped_to_output != NULL) {
// Output has just been set, clear region setting.
free(ic->mapped_to_region);
ic->mapped_to_region = NULL;
wlr_cursor_map_input_to_region(seat->cursor->cursor,
sway_device->input_device->wlr_device, NULL);
}
mapped_to_region = ic->mapped_to_region;
}
if (mapped_to_output == NULL && mapped_to_region == NULL) {
mapped_to_output = sway_device->input_device->wlr_device->output_name; mapped_to_output = sway_device->input_device->wlr_device->output_name;
} }
if (mapped_to_output != NULL) { if (mapped_to_output != NULL) {
sway_log(SWAY_DEBUG, "Mapping input device %s to output %s", sway_log(SWAY_DEBUG, "Mapping input device %s to output %s",
sway_device->input_device->identifier, mapped_to_output); sway_device->input_device->identifier, mapped_to_output);
@ -604,6 +624,13 @@ static void seat_apply_input_config(struct sway_seat *seat,
sway_device->input_device->wlr_device, output->wlr_output); sway_device->input_device->wlr_device, output->wlr_output);
sway_log(SWAY_DEBUG, "Mapped to output %s", output->wlr_output->name); sway_log(SWAY_DEBUG, "Mapped to output %s", output->wlr_output->name);
} }
} else if (mapped_to_region != NULL) {
sway_log(SWAY_DEBUG, "Mapping input device %s to %d,%d %dx%d",
sway_device->input_device->identifier,
mapped_to_region->x, mapped_to_region->y,
mapped_to_region->width, mapped_to_region->height);
wlr_cursor_map_input_to_region(seat->cursor->cursor,
sway_device->input_device->wlr_device, mapped_to_region);
} }
} }

View file

@ -150,6 +150,7 @@ sway_sources = files(
'commands/input/left_handed.c', 'commands/input/left_handed.c',
'commands/input/map_from_region.c', 'commands/input/map_from_region.c',
'commands/input/map_to_output.c', 'commands/input/map_to_output.c',
'commands/input/map_to_region.c',
'commands/input/middle_emulation.c', 'commands/input/middle_emulation.c',
'commands/input/natural_scroll.c', 'commands/input/natural_scroll.c',
'commands/input/pointer_accel.c', 'commands/input/pointer_accel.c',

View file

@ -88,7 +88,7 @@ The following commands may only be used in the configuration file.
Maps inputs from this device to the specified output. Only meaningful if the Maps inputs from this device to the specified output. Only meaningful if the
device is a pointer, touch, or drawing tablet device. device is a pointer, touch, or drawing tablet device.
*input* <identifier> map_to_region <WxH@X,Y> *input* <identifier> map_to_region <X> <Y> <width> <height>
Maps inputs from this device to the specified region of the global output Maps inputs from this device to the specified region of the global output
layout. Only meaningful if the device is a pointer, touch, or drawing tablet layout. Only meaningful if the device is a pointer, touch, or drawing tablet
device. device.