diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/config.c | 75 | ||||
-rw-r--r-- | examples/config.h | 2 | ||||
-rw-r--r-- | examples/pointer.c | 15 | ||||
-rw-r--r-- | examples/wlr-example.ini.example | 8 |
4 files changed, 97 insertions, 3 deletions
diff --git a/examples/config.c b/examples/config.c index 31aaa6d7..829350c1 100644 --- a/examples/config.c +++ b/examples/config.c @@ -7,6 +7,7 @@ #include <string.h> #include <unistd.h> #include <wlr/util/log.h> +#include <wlr/types/wlr_geometry.h> #include "shared.h" #include "config.h" #include "ini.h" @@ -21,6 +22,64 @@ static void usage(const char *name, int ret) { exit(ret); } +static struct wlr_geometry *parse_geometry(const char *str) { + // format: {width}x{height}+{x}+{y} + if (strlen(str) > 255l) { + wlr_log(L_ERROR, "cannot parse geometry string, too long"); + return NULL; + } + + char *buf = strdup(str); + struct wlr_geometry *geo = calloc(1, sizeof(struct wlr_geometry)); + + bool has_width, has_height, has_x, has_y; + char *pch = strtok(buf, "x+"); + while (pch != NULL) { + errno = 0; + char *endptr; + long val = strtol(pch, &endptr, 0); + + if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) + || (errno != 0 && val == 0)) { + goto invalid_input; + } + + if (endptr == pch) { + goto invalid_input; + } + + if (!has_width) { + geo->width = val; + has_width = true; + } else if (!has_height) { + geo->height = val; + has_height = true; + } else if (!has_x) { + geo->x = val; + has_x = true; + } else if (!has_y) { + geo->y = val; + has_y = true; + } else { + goto invalid_input; + } + pch = strtok(NULL, "x+"); + } + + if (!has_width || !has_height || !has_x || !has_y) { + goto invalid_input; + } + + free(buf); + return geo; + +invalid_input: + wlr_log(L_ERROR, "could not parse geometry string: %s", str); + free(buf); + free(geo); + return NULL; +} + static const char *output_prefix = "output:"; static const char *device_prefix = "device:"; @@ -71,6 +130,11 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else if (strcmp(section, "cursor") == 0) { if (strcmp(name, "map-to-output") == 0) { config->cursor.mapped_output = strdup(value); + } else if (strcmp(name, "geometry") == 0) { + if (config->cursor.mapped_geo) { + free(config->cursor.mapped_geo); + } + config->cursor.mapped_geo = parse_geometry(value); } else { wlr_log(L_ERROR, "got unknown cursor config: %s", name); } @@ -97,6 +161,11 @@ static int config_ini_handler(void *user, const char *section, const char *name, free(dc->mapped_output); } dc->mapped_output = strdup(value); + } else if (strcmp(name, "geometry") == 0) { + if (dc->mapped_geo) { + free(dc->mapped_geo); + } + dc->mapped_geo = parse_geometry(value); } else { wlr_log(L_ERROR, "got unknown device config: %s", name); } @@ -166,6 +235,9 @@ void example_config_destroy(struct example_config *config) { if (dc->mapped_output) { free(dc->mapped_output); } + if (dc->mapped_geo) { + free(dc->mapped_geo); + } free(dc); } @@ -175,6 +247,9 @@ void example_config_destroy(struct example_config *config) { if (config->cursor.mapped_output) { free(config->cursor.mapped_output); } + if (config->cursor.mapped_geo) { + free(config->cursor.mapped_geo); + } free(config); } diff --git a/examples/config.h b/examples/config.h index e1765c57..cd19dc5e 100644 --- a/examples/config.h +++ b/examples/config.h @@ -15,12 +15,14 @@ struct output_config { struct device_config { char *name; char *mapped_output; + struct wlr_geometry *mapped_geo; struct wl_list link; }; struct example_config { struct { char *mapped_output; + struct wlr_geometry *mapped_geo; } cursor; struct wl_list outputs; diff --git a/examples/pointer.c b/examples/pointer.c index bec71dff..9492adab 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -63,14 +63,21 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts static void configure_devices(struct sample_state *sample) { struct sample_input_device *dev; - // reset device to output mappings + struct device_config *dc; + + // reset device mappings wl_list_for_each(dev, &sample->devices, link) { wlr_cursor_map_input_to_output(sample->cursor, dev->device, NULL); + wl_list_for_each(dc, &sample->config->devices, link) { + if (strcmp(dev->device->name, dc->name) == 0) { + wlr_cursor_map_input_to_region(sample->cursor, dev->device, + dc->mapped_geo); + } + } } struct output_state *ostate; wl_list_for_each(ostate, &sample->compositor->outputs, link) { - struct device_config *dc; wl_list_for_each(dc, &sample->config->devices, link) { // configure device to output mappings if (dc->mapped_output && @@ -123,7 +130,8 @@ static void handle_output_remove(struct output_state *ostate) { configure_devices(sample); - if (strcmp(sample->config->cursor.mapped_output, ostate->output->name) == 0) { + char *mapped_output = sample->config->cursor.mapped_output; + if (mapped_output && strcmp(mapped_output, ostate->output->name) == 0) { wlr_cursor_map_to_output(sample->cursor, NULL); } } @@ -216,6 +224,7 @@ int main(int argc, char *argv[]) { state.config = parse_args(argc, argv); state.cursor = wlr_cursor_init(); + wlr_cursor_map_to_region(state.cursor, state.config->cursor.mapped_geo); wl_list_init(&state.devices); wl_signal_add(&state.cursor->events.motion, &state.cursor_motion); diff --git a/examples/wlr-example.ini.example b/examples/wlr-example.ini.example index ffb6229e..1698e0c6 100644 --- a/examples/wlr-example.ini.example +++ b/examples/wlr-example.ini.example @@ -34,8 +34,12 @@ y=232 # ~~~~~~~~~~~~~~~~~~~~ # Value "map-to-output" specifies the output to which the cursor is # constrained. +# +# Value "geometry" specifies the geometry (widthxheight+x+y) to which the cursor +# is constrained. [cursor] map-to-output=HDMI-A-1 +geometry=500x700+50+50 # Device Configuration # ~~~~~~~~~~~~~~~~~~~~ @@ -43,7 +47,11 @@ map-to-output=HDMI-A-1 # name given to this device. See a log file for device names. # # Value "map-to-output" specifies the output to which the device is constrained. +# +# Value "geometry" specifies the geometry (widthxheight+x+y) to which the device +# is constrained. [device:Razer Razer DeathAdder 2013] map-to-output=DP-1 +geometry=500x700+50+50 # vim:filetype=dosini |