sway/sway/commands/input/map_to_region.c
Manuel Stoeckl 221a8b40de Have commands return cmd_results on the stack
sway commands are implemented using functions that return an error
code and (if the function was not successful) an error string. The
two are bundled together by the type `struct cmd_results`. This
patch alters the command handler prototype so that the cmd_results
objects are returned by value (on the stack), instead of by a pointer
to a heap allocated instance of a cmd_results.

The latter method had the flaw that, if the heap allocation of the
cmd_results object failed, the exact return code would be lost.
Furthermore, for some command handlers (such as those in
sway/commands/output), returning NULL signified success, so an
allocation failure could lead to an ignored error. This change
prevents both classes of errors.
2019-12-22 10:13:41 -05:00

54 lines
1.3 KiB
C

#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;
if (checkarg(&error, 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");
}
ic->mapped_to = MAPPED_TO_REGION;
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);
}