diff --git a/include/sway/commands.h b/include/sway/commands.h index 3212c2cf4..7c251ef6a 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -251,6 +251,7 @@ sway_cmd input_cmd_calibration_matrix; sway_cmd input_cmd_click_method; sway_cmd input_cmd_drag; sway_cmd input_cmd_drag_lock; +sway_cmd input_cmd_transform; sway_cmd input_cmd_dwt; sway_cmd input_cmd_dwtp; sway_cmd input_cmd_events; diff --git a/include/sway/config.h b/include/sway/config.h index aa58da531..1a2585a53 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -138,6 +138,18 @@ struct input_config_tool { enum sway_tablet_tool_mode mode; }; +enum sway_input_transform { + INPUT_TRANSFORM_DEFAULT, + INPUT_TRANSFORM_NORMAL, + INPUT_TRANSFORM_90, + INPUT_TRANSFORM_180, + INPUT_TRANSFORM_270, + INPUT_TRANSFORM_FLIPPED, + INPUT_TRANSFORM_FLIPPED_90, + INPUT_TRANSFORM_FLIPPED_180, + INPUT_TRANSFORM_FLIPPED_270, +}; + /** * options for input devices */ @@ -184,6 +196,8 @@ struct input_config { char *mapped_to_output; struct wlr_box *mapped_to_region; + enum sway_input_transform transform; + list_t *tools; bool capturable; diff --git a/sway/commands/input.c b/sway/commands/input.c index 3075b5f46..f41d7dfc5 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c @@ -32,6 +32,7 @@ static const struct cmd_handler input_handlers[] = { { "tap", input_cmd_tap }, { "tap_button_map", input_cmd_tap_button_map }, { "tool_mode", input_cmd_tool_mode }, + { "transform", input_cmd_transform }, { "xkb_file", input_cmd_xkb_file }, { "xkb_layout", input_cmd_xkb_layout }, { "xkb_model", input_cmd_xkb_model }, diff --git a/sway/commands/input/transform.c b/sway/commands/input/transform.c new file mode 100644 index 000000000..9cd6f8e2f --- /dev/null +++ b/sway/commands/input/transform.c @@ -0,0 +1,77 @@ +#include "log.h" +#include "sway/config.h" +#include "sway/commands.h" +#include "sway/input/input-manager.h" +#include "util.h" +#include + +static enum sway_input_transform invert_rotation_direction( + enum sway_input_transform t) { + switch (t) { + case INPUT_TRANSFORM_90: + return INPUT_TRANSFORM_270; + case INPUT_TRANSFORM_270: + return INPUT_TRANSFORM_90; + case INPUT_TRANSFORM_FLIPPED_90: + return INPUT_TRANSFORM_FLIPPED_270; + case INPUT_TRANSFORM_FLIPPED_270: + return INPUT_TRANSFORM_FLIPPED_90; + default: + return t; + } +} + +struct cmd_results *input_cmd_transform(int argc, char**argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "transform", EXPECTED_AT_LEAST, 1))) { + return error; + } + + enum sway_input_transform transform; + if (strcmp(*argv, "normal") == 0 || + strcmp(*argv, "0") == 0) { + transform = INPUT_TRANSFORM_NORMAL; + } else if (strcmp(*argv, "90") == 0) { + transform = INPUT_TRANSFORM_90; + } else if (strcmp(*argv, "180") == 0) { + transform = INPUT_TRANSFORM_180; + } else if (strcmp(*argv, "270") == 0) { + transform = INPUT_TRANSFORM_270; + } else if (strcmp(*argv, "flipped") == 0) { + transform = INPUT_TRANSFORM_FLIPPED; + } else if (strcmp(*argv, "flipped-90") == 0) { + transform = INPUT_TRANSFORM_FLIPPED_90; + } else if (strcmp(*argv, "flipped-180") == 0) { + transform = INPUT_TRANSFORM_FLIPPED_180; + } else if (strcmp(*argv, "flipped-270") == 0) { + transform = INPUT_TRANSFORM_FLIPPED_270; + } else { + return cmd_results_new(CMD_INVALID, "Invalid output transform."); + } + + struct input_config *ic = config->handler_context.input_config; + if (!ic) { + return cmd_results_new(CMD_FAILURE, "No input device defined."); + } + + if (argc > 1) { + if (strcmp(argv[1], "clockwise") && strcmp(argv[1], "anticlockwise")) { + return cmd_results_new(CMD_INVALID, "Invalid transform direction"); + } + if (config->reloading) { + return cmd_results_new(CMD_INVALID, + "Relative transforms cannot be used in the configuration file"); + } + if (strcmp(ic->identifier, "*") == 0) { + return cmd_results_new(CMD_INVALID, + "Cannot apply relative transforms to all inputs"); + } + if (strcmp(argv[1], "anticlockwise") == 0) { + transform = invert_rotation_direction(transform); + } + } + + ic->transform = transform; + + return cmd_results_new(CMD_SUCCESS, NULL); +} \ No newline at end of file diff --git a/sway/config/input.c b/sway/config/input.c index 2ee165c9d..f98cef280 100644 --- a/sway/config/input.c +++ b/sway/config/input.c @@ -102,6 +102,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) { if (src->tap != INT_MIN) { dst->tap = src->tap; } + if (src->transform) { + dst->transform = src->transform; + } if (src->tap_button_map != INT_MIN) { dst->tap_button_map = src->tap_button_map; } diff --git a/sway/meson.build b/sway/meson.build index c6a274342..cf8aed0e6 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -157,6 +157,7 @@ sway_sources = files( 'commands/input/click_method.c', 'commands/input/drag.c', 'commands/input/drag_lock.c', + 'commands/input/transform.c', 'commands/input/dwt.c', 'commands/input/dwtp.c', 'commands/input/events.c',