From 54f87146c3755653bbbe076c86b4b85c23a0989d Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 24 Aug 2017 15:26:51 -0400 Subject: refactor example config and add ini.c --- examples/config.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 examples/config.c (limited to 'examples/config.c') diff --git a/examples/config.c b/examples/config.c new file mode 100644 index 00000000..4f70faf0 --- /dev/null +++ b/examples/config.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include "shared.h" +#include "config.h" + +static void usage(const char *name, int ret) { + fprintf(stderr, + "usage: %s [-d [-r | -f]]*\n" + "\n" + " -o The name of the DRM display. e.g. DVI-I-1.\n" + " -r The rotation counter clockwise. Valid values are 90, 180, 270.\n" + " -x The X-axis coordinate position of this output in the layout.\n" + " -y The Y-axis coordinate position of this output in the layout.\n" + " -f Flip the output along the vertical axis.\n", name); + + exit(ret); +} + +struct example_config *parse_args(int argc, char *argv[]) { + struct example_config *config = calloc(1, sizeof(struct example_config)); + wl_list_init(&config->outputs); + struct output_config *oc = NULL; + + int c; + while ((c = getopt(argc, argv, "o:r:x:y:fh")) != -1) { + switch (c) { + case 'o': + oc = calloc(1, sizeof(*oc)); + oc->name = optarg; + oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; + wl_list_insert(&config->outputs, &oc->link); + break; + case 'r': + if (!oc) { + fprintf(stderr, "You must specify an output first\n"); + usage(argv[0], 1); + } + + if (oc->transform != WL_OUTPUT_TRANSFORM_NORMAL + && oc->transform != WL_OUTPUT_TRANSFORM_FLIPPED) { + fprintf(stderr, "Rotation for %s already specified\n", oc->name); + usage(argv[0], 1); + } + + if (strcmp(optarg, "90") == 0) { + oc->transform += WL_OUTPUT_TRANSFORM_90; + } else if (strcmp(optarg, "180") == 0) { + oc->transform += WL_OUTPUT_TRANSFORM_180; + } else if (strcmp(optarg, "270") == 0) { + oc->transform += WL_OUTPUT_TRANSFORM_270; + } else { + fprintf(stderr, "Invalid rotation '%s'\n", optarg); + usage(argv[0], 1); + } + break; + case 'x': + if (!oc) { + fprintf(stderr, "You must specify an output first\n"); + usage(argv[0], 1); + } + oc->x = strtol(optarg, NULL, 0); + break; + case 'y': + if (!oc) { + fprintf(stderr, "You must specify an output first\n"); + usage(argv[0], 1); + } + oc->y = strtol(optarg, NULL, 0); + break; + case 'f': + if (!oc) { + fprintf(stderr, "You must specify an output first\n"); + usage(argv[0], 1); + } + + if (oc->transform >= WL_OUTPUT_TRANSFORM_FLIPPED) { + fprintf(stderr, "Flip for %s already specified\n", oc->name); + usage(argv[0], 1); + } + + oc->transform += WL_OUTPUT_TRANSFORM_FLIPPED; + break; + case 'h': + case '?': + usage(argv[0], c != 'h'); + } + } + + return config; +} + +void example_config_destroy(struct example_config *config) { + struct output_config *oc, *tmp = NULL; + wl_list_for_each_safe(oc, tmp, &config->outputs, link) { + free(oc); + } + free(config); +} + +struct wlr_output_layout *configure_layout(struct example_config *config, struct wl_list *outputs) { + struct wlr_output_layout *layout = wlr_output_layout_init(); + int max_x = INT_MIN; + int max_x_y = INT_MIN; // y value for the max_x output + + // first add all the configured outputs + struct output_state *output; + wl_list_for_each(output, outputs, link) { + struct output_config *conf; + wl_list_for_each(conf, &config->outputs, link) { + if (strcmp(conf->name, output->output->name) == 0) { + wlr_output_layout_add(layout, output->output, + conf->x, conf->y); + wlr_output_transform(output->output, conf->transform); + int width, height; + wlr_output_effective_resolution(output->output, &width, &height); + if (conf->x + width > max_x) { + max_x = conf->x + width; + max_x_y = conf->y; + } + break; + } + } + } + + if (max_x == INT_MIN) { + // couldn't find a configured output + max_x = 0; + max_x_y = 0; + } + + // now add all the other configured outputs in a sensible position + wl_list_for_each(output, outputs, link) { + if (wlr_output_layout_get(layout, output->output)) { + continue; + } + wlr_output_layout_add(layout, output->output, max_x, max_x_y); + int width, height; + wlr_output_effective_resolution(output->output, &width, &height); + max_x += width; + } + + return layout; +} + -- cgit v1.2.3 From b3a43e226140d9b5d49c4ed24798e3f3006dcae5 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 25 Aug 2017 08:06:38 -0400 Subject: add configuration file --- .gitignore | 1 + examples/config.c | 154 +++++++++++++++++++++++---------------- examples/config.h | 1 + examples/wlr-example.ini.example | 33 +++++++++ 4 files changed, 128 insertions(+), 61 deletions(-) create mode 100644 examples/wlr-example.ini.example (limited to 'examples/config.c') diff --git a/.gitignore b/.gitignore index ce85118c..d4edde88 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ test/ build/ .lvimrc wayland-*-protocol.* +wlr-example.ini diff --git a/examples/config.c b/examples/config.c index 4f70faf0..bca2b44b 100644 --- a/examples/config.c +++ b/examples/config.c @@ -1,86 +1,88 @@ +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif #include #include #include #include +#include +#include #include "shared.h" #include "config.h" +#include "ini.h" static void usage(const char *name, int ret) { fprintf(stderr, - "usage: %s [-d [-r | -f]]*\n" + "usage: %s [-C ]\n" "\n" - " -o The name of the DRM display. e.g. DVI-I-1.\n" - " -r The rotation counter clockwise. Valid values are 90, 180, 270.\n" - " -x The X-axis coordinate position of this output in the layout.\n" - " -y The Y-axis coordinate position of this output in the layout.\n" - " -f Flip the output along the vertical axis.\n", name); + " -C Path to the configuration file (default: wlr-example.ini).\n" + " See `examples/wlr-example.ini.example` for config file documentation.\n", name); exit(ret); } -struct example_config *parse_args(int argc, char *argv[]) { - struct example_config *config = calloc(1, sizeof(struct example_config)); - wl_list_init(&config->outputs); - struct output_config *oc = NULL; +static const char *output_prefix = "output:"; - int c; - while ((c = getopt(argc, argv, "o:r:x:y:fh")) != -1) { - switch (c) { - case 'o': - oc = calloc(1, sizeof(*oc)); - oc->name = optarg; - oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; - wl_list_insert(&config->outputs, &oc->link); - break; - case 'r': - if (!oc) { - fprintf(stderr, "You must specify an output first\n"); - usage(argv[0], 1); - } +static int config_ini_handler(void *user, const char *section, const char *name, const char *value) { + struct example_config *config = user; + if (strncmp(output_prefix, section, strlen(output_prefix)) == 0) { + const char *output_name = section + strlen(output_prefix); + struct output_config *oc; + bool found = false; - if (oc->transform != WL_OUTPUT_TRANSFORM_NORMAL - && oc->transform != WL_OUTPUT_TRANSFORM_FLIPPED) { - fprintf(stderr, "Rotation for %s already specified\n", oc->name); - usage(argv[0], 1); + wl_list_for_each(oc, &config->outputs, link) { + if (strcmp(oc->name, output_name) == 0) { + found = true; + break; } + } + + if (!found) { + oc = calloc(1, sizeof(struct output_config)); + oc->name = strdup(output_name); + oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; + wl_list_insert(&config->outputs, &oc->link); + } - if (strcmp(optarg, "90") == 0) { - oc->transform += WL_OUTPUT_TRANSFORM_90; - } else if (strcmp(optarg, "180") == 0) { - oc->transform += WL_OUTPUT_TRANSFORM_180; - } else if (strcmp(optarg, "270") == 0) { - oc->transform += WL_OUTPUT_TRANSFORM_270; + if (strcmp(name, "x") == 0) { + oc->x = strtol(value, NULL, 10); + } else if (strcmp(name, "y") == 0) { + oc->y = strtol(value, NULL, 10); + } else if (strcmp(name, "rotate") == 0) { + if (strcmp(value, "90") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_90; + } else if (strcmp(value, "180") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_180; + } else if (strcmp(value, "270") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_270; + } else if (strcmp(value, "flipped") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_FLIPPED; + } else if (strcmp(value, "flipped-90") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; + } else if (strcmp(value, "flipped-180") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180; + } else if (strcmp(value, "flipped-270") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; } else { - fprintf(stderr, "Invalid rotation '%s'\n", optarg); - usage(argv[0], 1); - } - break; - case 'x': - if (!oc) { - fprintf(stderr, "You must specify an output first\n"); - usage(argv[0], 1); - } - oc->x = strtol(optarg, NULL, 0); - break; - case 'y': - if (!oc) { - fprintf(stderr, "You must specify an output first\n"); - usage(argv[0], 1); - } - oc->y = strtol(optarg, NULL, 0); - break; - case 'f': - if (!oc) { - fprintf(stderr, "You must specify an output first\n"); - usage(argv[0], 1); + wlr_log(L_ERROR, "got unknown transform value: %s", value); } + } + } else { + wlr_log(L_ERROR, "got unknown config section: %s", section); + } - if (oc->transform >= WL_OUTPUT_TRANSFORM_FLIPPED) { - fprintf(stderr, "Flip for %s already specified\n", oc->name); - usage(argv[0], 1); - } + return 1; +} + +struct example_config *parse_args(int argc, char *argv[]) { + struct example_config *config = calloc(1, sizeof(struct example_config)); + wl_list_init(&config->outputs); - oc->transform += WL_OUTPUT_TRANSFORM_FLIPPED; + int c; + while ((c = getopt(argc, argv, "C:h")) != -1) { + switch (c) { + case 'C': + config->config_path = strdup(optarg); break; case 'h': case '?': @@ -88,14 +90,44 @@ struct example_config *parse_args(int argc, char *argv[]) { } } + if (!config->config_path) { + // get the config path from the current directory + char cwd[1024]; + if (getcwd(cwd, sizeof(cwd)) != NULL) { + char buf[1024]; + sprintf(buf, "%s/%s", cwd, "wlr-example.ini"); + config->config_path = strdup(buf); + } else { + wlr_log(L_ERROR, "could not get cwd"); + exit(1); + } + } + + int result = ini_parse(config->config_path, config_ini_handler, config); + + if (result == -1) { + wlr_log(L_ERROR, "Could not find config file at %s", config->config_path); + exit(1); + } else if (result == -2) { + wlr_log(L_ERROR, "Could not allocate memory to parse config file"); + exit(1); + } else if (result != 0) { + wlr_log(L_ERROR, "Could not parse config file"); + exit(1); + } + return config; } void example_config_destroy(struct example_config *config) { struct output_config *oc, *tmp = NULL; wl_list_for_each_safe(oc, tmp, &config->outputs, link) { + free(oc->name); free(oc); } + if (config->config_path) { + free(config->config_path); + } free(config); } diff --git a/examples/config.h b/examples/config.h index 1ecadd81..d02d1a2c 100644 --- a/examples/config.h +++ b/examples/config.h @@ -14,6 +14,7 @@ struct output_config { struct example_config { struct wl_list outputs; + char *config_path; }; struct example_config *parse_args(int argc, char *argv[]); diff --git a/examples/wlr-example.ini.example b/examples/wlr-example.ini.example new file mode 100644 index 00000000..283439f0 --- /dev/null +++ b/examples/wlr-example.ini.example @@ -0,0 +1,33 @@ +# Configuration +# ------------- +# Some examples will read a configuration file. Not all examples will use all of +# the configuration options. The configuration file will be loaded from +# `wlr-example.ini` from the current directory or the path can be specified by the +# `-C` option given on the command line. +# +# Output configuration +# ~~~~~~~~~~~~~~~~~~~~ +# Each output is specified in a section named [output:{NAME}] where NAME is the +# drm name for this output. +# +# Value "x" specifies the x-coordinate in the output layout. +# +# Value "y" specifies the y-coordinate in the output layout. +# +# Value "rotate" specifies output rotation and can be 90, 180, 270, flipped, +# flipped-90, flipped-180, or flipped-270 +[output:HDMI-A-1] +x=3000 +y=0 +rotate=90 + +[output:DP-1] +x=0 +y=0 +rotate=270 + +[output:DVI-D-1] +x=1080 +y=232 + +# vim:filetype=dosini -- cgit v1.2.3 From 699d489f936826a808f955c47442342e850bfc1b Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 25 Aug 2017 08:58:02 -0400 Subject: add cursor configuration --- examples/config.c | 9 +++++++++ examples/config.h | 4 ++++ examples/pointer.c | 9 +++++++++ examples/wlr-example.ini.example | 7 +++++++ 4 files changed, 29 insertions(+) (limited to 'examples/config.c') diff --git a/examples/config.c b/examples/config.c index bca2b44b..909a2463 100644 --- a/examples/config.c +++ b/examples/config.c @@ -67,6 +67,12 @@ static int config_ini_handler(void *user, const char *section, const char *name, wlr_log(L_ERROR, "got unknown transform value: %s", value); } } + } else if (strcmp(section, "cursor") == 0) { + if (strcmp(name, "map-to-output") == 0) { + config->cursor.mapped_output = strdup(value); + } else { + wlr_log(L_ERROR, "got unknown cursor config: %s", name); + } } else { wlr_log(L_ERROR, "got unknown config section: %s", section); } @@ -128,6 +134,9 @@ void example_config_destroy(struct example_config *config) { if (config->config_path) { free(config->config_path); } + if (config->cursor.mapped_output) { + free(config->cursor.mapped_output); + } free(config); } diff --git a/examples/config.h b/examples/config.h index d02d1a2c..c5f0c8dd 100644 --- a/examples/config.h +++ b/examples/config.h @@ -13,6 +13,10 @@ struct output_config { }; struct example_config { + struct { + char *mapped_output; + } cursor; + struct wl_list outputs; char *config_path; }; diff --git a/examples/pointer.c b/examples/pointer.c index fcf9805f..88fdaef7 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -70,6 +70,11 @@ static void handle_output_add(struct output_state *ostate) { sample->layout = configure_layout(sample->config, &ostate->compositor->outputs); wlr_cursor_attach_output_layout(sample->cursor, sample->layout); + char *mapped_output = sample->config->cursor.mapped_output; + if (mapped_output && strcmp(mapped_output, wlr_output->name) == 0) { + wlr_cursor_map_to_output(sample->cursor, wlr_output); + } + /* // TODO configuration if (strcmp("DP-1", ostate->output->name) == 0) { @@ -95,6 +100,10 @@ static void handle_output_remove(struct output_state *ostate) { wlr_output_layout_destroy(sample->layout); sample->layout = configure_layout(sample->config, &ostate->compositor->outputs); wlr_cursor_attach_output_layout(sample->cursor, sample->layout); + + if (strcmp(sample->config->cursor.mapped_output, ostate->output->name) == 0) { + wlr_cursor_map_to_output(sample->cursor, NULL); + } } static void handle_output_resolution(struct compositor_state *state, diff --git a/examples/wlr-example.ini.example b/examples/wlr-example.ini.example index 283439f0..a9dff591 100644 --- a/examples/wlr-example.ini.example +++ b/examples/wlr-example.ini.example @@ -30,4 +30,11 @@ rotate=270 x=1080 y=232 +# Cursor Configuration +# ~~~~~~~~~~~~~~~~~~~~ +# Value "map-to-output" specifies the output to which the cursor is +# constrained. +[cursor] +map-to-output=HDMI-A-1 + # vim:filetype=dosini -- cgit v1.2.3 From d0cf8d0d01b12d359be5c4216ef5f0bdbdfee622 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 25 Aug 2017 09:40:01 -0400 Subject: add device configuration --- examples/config.c | 42 ++++++++++++++++++++++++++++-- examples/config.h | 7 +++++ examples/pointer.c | 55 +++++++++++++++++++++++++--------------- examples/wlr-example.ini.example | 9 +++++++ 4 files changed, 91 insertions(+), 22 deletions(-) (limited to 'examples/config.c') diff --git a/examples/config.c b/examples/config.c index 909a2463..31aaa6d7 100644 --- a/examples/config.c +++ b/examples/config.c @@ -22,6 +22,7 @@ static void usage(const char *name, int ret) { } static const char *output_prefix = "output:"; +static const char *device_prefix = "device:"; static int config_ini_handler(void *user, const char *section, const char *name, const char *value) { struct example_config *config = user; @@ -73,6 +74,32 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else { wlr_log(L_ERROR, "got unknown cursor config: %s", name); } + } else if (strncmp(device_prefix, section, strlen(device_prefix)) == 0) { + const char *device_name = section + strlen(device_prefix); + struct device_config *dc; + bool found = false; + + wl_list_for_each(dc, &config->devices, link) { + if (strcmp(dc->name, device_name) == 0) { + found = true; + break; + } + } + + if (!found) { + dc = calloc(1, sizeof(struct device_config)); + dc->name = strdup(device_name); + wl_list_insert(&config->devices, &dc->link); + } + + if (strcmp(name, "map-to-output") == 0) { + if (dc->mapped_output) { + free(dc->mapped_output); + } + dc->mapped_output = strdup(value); + } else { + wlr_log(L_ERROR, "got unknown device config: %s", name); + } } else { wlr_log(L_ERROR, "got unknown config section: %s", section); } @@ -83,6 +110,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, struct example_config *parse_args(int argc, char *argv[]) { struct example_config *config = calloc(1, sizeof(struct example_config)); wl_list_init(&config->outputs); + wl_list_init(&config->devices); int c; while ((c = getopt(argc, argv, "C:h")) != -1) { @@ -126,11 +154,21 @@ struct example_config *parse_args(int argc, char *argv[]) { } void example_config_destroy(struct example_config *config) { - struct output_config *oc, *tmp = NULL; - wl_list_for_each_safe(oc, tmp, &config->outputs, link) { + struct output_config *oc, *otmp = NULL; + wl_list_for_each_safe(oc, otmp, &config->outputs, link) { free(oc->name); free(oc); } + + struct device_config *dc, *dtmp = NULL; + wl_list_for_each_safe(dc, dtmp, &config->devices, link) { + free(dc->name); + if (dc->mapped_output) { + free(dc->mapped_output); + } + free(dc); + } + if (config->config_path) { free(config->config_path); } diff --git a/examples/config.h b/examples/config.h index c5f0c8dd..e1765c57 100644 --- a/examples/config.h +++ b/examples/config.h @@ -12,12 +12,19 @@ struct output_config { struct wl_list link; }; +struct device_config { + char *name; + char *mapped_output; + struct wl_list link; +}; + struct example_config { struct { char *mapped_output; } cursor; struct wl_list outputs; + struct wl_list devices; char *config_path; }; diff --git a/examples/pointer.c b/examples/pointer.c index 88fdaef7..bec71dff 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -61,30 +61,50 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts wlr_output_swap_buffers(wlr_output); } +static void configure_devices(struct sample_state *sample) { + struct sample_input_device *dev; + // reset device to output mappings + wl_list_for_each(dev, &sample->devices, link) { + wlr_cursor_map_input_to_output(sample->cursor, dev->device, NULL); + } + + 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 && + strcmp(dc->mapped_output, ostate->output->name) == 0) { + wl_list_for_each(dev, &sample->devices, link) { + if (strcmp(dev->device->name, dc->name) == 0) { + wlr_cursor_map_input_to_output(sample->cursor, + dev->device, ostate->output); + } + } + } + } + } +} + static void handle_output_add(struct output_state *ostate) { struct sample_state *sample = ostate->compositor->data; struct wlr_output *wlr_output = ostate->output; struct wlr_xcursor_image *image = sample->xcursor->images[0]; + // reset layout wlr_output_layout_destroy(sample->layout); sample->layout = configure_layout(sample->config, &ostate->compositor->outputs); wlr_cursor_attach_output_layout(sample->cursor, sample->layout); + // cursor configuration char *mapped_output = sample->config->cursor.mapped_output; if (mapped_output && strcmp(mapped_output, wlr_output->name) == 0) { wlr_cursor_map_to_output(sample->cursor, wlr_output); } - /* - // TODO configuration - if (strcmp("DP-1", ostate->output->name) == 0) { - struct sample_input_device *dev; - wl_list_for_each(dev, &sample->devices, link) { - wlr_cursor_map_input_to_output(sample->cursor, dev->device, ostate->output); - } - } - */ + configure_devices(sample); + // TODO move to wlr_cursor if (!wlr_output_set_cursor(wlr_output, image->buffer, image->width, image->width, image->height)) { wlr_log(L_DEBUG, "Failed to set hardware cursor"); @@ -101,6 +121,8 @@ static void handle_output_remove(struct output_state *ostate) { sample->layout = configure_layout(sample->config, &ostate->compositor->outputs); wlr_cursor_attach_output_layout(sample->cursor, sample->layout); + configure_devices(sample); + if (strcmp(sample->config->cursor.mapped_output, ostate->output->name) == 0) { wlr_cursor_map_to_output(sample->cursor, NULL); } @@ -122,19 +144,10 @@ static void handle_input_add(struct compositor_state *state, struct if (device->type == WLR_INPUT_DEVICE_POINTER) { struct sample_input_device *s_device = calloc(1, sizeof(struct sample_input_device)); s_device->device = device; - wl_list_insert(&sample->devices, &s_device->link); - - /* - // TODO configuration - struct output_state *ostate; - wl_list_for_each(ostate, &sample->compositor->outputs, link) { - if (strcmp(ostate->output->name, "DP-1") == 0) { - wlr_cursor_map_input_to_output(sample->cursor, device, ostate->output); - } - } - */ + wl_list_insert(&sample->devices, &s_device->link); wlr_cursor_attach_input_device(sample->cursor, device); + configure_devices(sample); } } @@ -224,6 +237,8 @@ int main(int argc, char *argv[]) { compositor.output_resolution_cb = handle_output_resolution; compositor.output_frame_cb = handle_output_frame; compositor.input_add_cb = handle_input_add; + // TODO input_remove_cb + //compositor.input_remove_cb = handle_input_add; state.compositor = &compositor; diff --git a/examples/wlr-example.ini.example b/examples/wlr-example.ini.example index a9dff591..ffb6229e 100644 --- a/examples/wlr-example.ini.example +++ b/examples/wlr-example.ini.example @@ -37,4 +37,13 @@ y=232 [cursor] map-to-output=HDMI-A-1 +# Device Configuration +# ~~~~~~~~~~~~~~~~~~~~ +# Each device is specified in a section named [device:{NAME}] where NAME is the +# 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. +[device:Razer Razer DeathAdder 2013] +map-to-output=DP-1 + # vim:filetype=dosini -- cgit v1.2.3 From 0a97b68278a621882c712b55ffe851101e5902d0 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 25 Aug 2017 13:26:13 -0400 Subject: implement cursor and device geometry mapping --- examples/config.c | 75 ++++++++++++++++++++++++++++++++++++++++ examples/config.h | 2 ++ examples/pointer.c | 15 ++++++-- examples/wlr-example.ini.example | 8 +++++ include/wlr/types/wlr_cursor.h | 6 ++-- include/wlr/types/wlr_geometry.h | 12 +++++++ types/meson.build | 1 + types/wlr_cursor.c | 35 +++++++++++++++++++ types/wlr_geometry.c | 36 +++++++++++++++++++ types/wlr_output_layout.c | 1 + 10 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 include/wlr/types/wlr_geometry.h create mode 100644 types/wlr_geometry.c (limited to 'examples/config.c') 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 #include #include +#include #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 diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index 64a75e4f..30495d44 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -4,6 +4,7 @@ #include #include #include +#include #include struct wlr_cursor_state; @@ -87,12 +88,13 @@ void wlr_cursor_map_input_to_output(struct wlr_cursor *cur, /** * Maps this cursor to an arbitrary region on the associated wlr_output_layout. */ -//void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_geometry *geo); +void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_geometry *geo); /** * Maps inputs from this input device to an arbitrary region on the associated * wlr_output_layout. */ -//void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, struct wlr_input_device *dev, struct wlr_geometry *geo); +void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, + struct wlr_input_device *dev, struct wlr_geometry *geo); #endif diff --git a/include/wlr/types/wlr_geometry.h b/include/wlr/types/wlr_geometry.h new file mode 100644 index 00000000..3e218bed --- /dev/null +++ b/include/wlr/types/wlr_geometry.h @@ -0,0 +1,12 @@ +#ifndef _WLR_TYPES_GEOMETRY_H +#define _WLR_TYPES_GEOMETRY_H + +struct wlr_geometry { + int x, y; + int width, height; +}; + +void wlr_geometry_closest_boundary(struct wlr_geometry *geo, double x, double y, + int *dest_x, int *dest_y, double *distance); + +#endif diff --git a/types/meson.build b/types/meson.build index 3992c6e9..d0ed85fe 100644 --- a/types/meson.build +++ b/types/meson.build @@ -16,6 +16,7 @@ lib_wlr_types = static_library('wlr_types', files( 'wlr_xdg_shell_v6.c', 'wlr_wl_shell.c', 'wlr_compositor.c', + 'wlr_geometry.c', ), include_directories: wlr_inc, dependencies: [wayland_server, pixman, wlr_protos]) diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 6917526e..c0b2b6ae 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -12,6 +12,7 @@ struct wlr_cursor_device { struct wlr_input_device *device; struct wl_list link; struct wlr_output *mapped_output; + struct wlr_geometry *mapped_geometry; struct wl_listener motion; struct wl_listener motion_absolute; @@ -24,6 +25,7 @@ struct wlr_cursor_state { struct wlr_output_layout *layout; struct wlr_xcursor *xcursor; struct wlr_output *mapped_output; + struct wlr_geometry *mapped_geometry; }; struct wlr_cursor *wlr_cursor_init() { @@ -145,6 +147,25 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev, double x = cur->x + delta_x; double y = cur->y + delta_y; + // cursor geometry constraints + if (cur->state->mapped_geometry) { + int closest_x, closest_y; + wlr_geometry_closest_boundary(cur->state->mapped_geometry, x, y, + &closest_x, &closest_y, NULL); + x = closest_x; + y = closest_y; + } + + // device constraints + if (c_device->mapped_geometry) { + int closest_x, closest_y; + wlr_geometry_closest_boundary(c_device->mapped_geometry, x, y, + &closest_x, &closest_y, NULL); + x = closest_x; + y = closest_y; + } + + // layout constraints struct wlr_output *output; output = wlr_output_layout_output_at(cur->state->layout, x, y); @@ -271,3 +292,17 @@ void wlr_cursor_map_input_to_output(struct wlr_cursor *cur, c_device->mapped_output = output; } + +void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_geometry *geo) { + cur->state->mapped_geometry = geo; +} + +void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, + struct wlr_input_device *dev, struct wlr_geometry *geo) { + struct wlr_cursor_device *c_device = get_cursor_device(cur, dev); + if (!c_device) { + wlr_log(L_ERROR, "Cannot map device \"%s\" to geometry (not found in this cursor)", dev->name); + return; + } + c_device->mapped_geometry = geo; +} diff --git a/types/wlr_geometry.c b/types/wlr_geometry.c new file mode 100644 index 00000000..8358d887 --- /dev/null +++ b/types/wlr_geometry.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +static double get_distance(double x1, double y1, double x2, double y2) { + double distance; + distance = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); + return distance; +} + +void wlr_geometry_closest_boundary(struct wlr_geometry *geo, double x, double y, + int *dest_x, int *dest_y, double *distance) { + // find the closest x point + if (x < geo->x) { + *dest_x = geo->x; + } else if (x > geo->x + geo->width) { + *dest_x = geo->x + geo->width; + } else { + *dest_x = x; + } + + // find closest y point + if (y < geo->y) { + *dest_y = geo->y; + } else if (y > geo->y + geo->height) { + *dest_y = geo->y + geo->height; + } else { + *dest_y = y; + } + + // calculate distance + if (distance) { + *distance = get_distance(*dest_x, *dest_y, x, y); + } +} diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index 5e2067da..7dcb4651 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -149,6 +149,7 @@ void wlr_output_layout_closest_boundary(struct wlr_output_layout *layout, wlr_output_effective_resolution(l_output->output, &width, &height); // find the closest x point + // TODO use wlr_geometry_closest_boundary if (x < l_output->x) { output_x = l_output->x; } else if (x > l_output->x + width) { -- cgit v1.2.3 From dc7e32552dd47f400aa2d7c1f8355b89376ae60e Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 26 Aug 2017 11:53:16 -0400 Subject: config: fix uninitialized variables and accept trailing for geom --- examples/config.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'examples/config.c') diff --git a/examples/config.c b/examples/config.c index 829350c1..1bd4672e 100644 --- a/examples/config.c +++ b/examples/config.c @@ -32,7 +32,11 @@ static struct wlr_geometry *parse_geometry(const char *str) { char *buf = strdup(str); struct wlr_geometry *geo = calloc(1, sizeof(struct wlr_geometry)); - bool has_width, has_height, has_x, has_y; + bool has_width = false; + bool has_height = false; + bool has_x = false; + bool has_y = false; + char *pch = strtok(buf, "x+"); while (pch != NULL) { errno = 0; @@ -61,7 +65,7 @@ static struct wlr_geometry *parse_geometry(const char *str) { geo->y = val; has_y = true; } else { - goto invalid_input; + break; } pch = strtok(NULL, "x+"); } -- cgit v1.2.3 From 1193dd564bddfe75e972ae0d17715bee8645d273 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 29 Aug 2017 08:32:02 -0400 Subject: config fixes --- examples/config.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'examples/config.c') diff --git a/examples/config.c b/examples/config.c index 1bd4672e..b99f130d 100644 --- a/examples/config.c +++ b/examples/config.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include "shared.h" @@ -16,15 +17,17 @@ static void usage(const char *name, int ret) { fprintf(stderr, "usage: %s [-C ]\n" "\n" - " -C Path to the configuration file (default: wlr-example.ini).\n" - " See `examples/wlr-example.ini.example` for config file documentation.\n", name); + " -C Path to the configuration file\n" + " (default: wlr-example.ini).\n" + " See `examples/wlr-example.ini.example` for config\n" + " file documentation.\n", name); exit(ret); } static struct wlr_geometry *parse_geometry(const char *str) { // format: {width}x{height}+{x}+{y} - if (strlen(str) > 255l) { + if (strlen(str) > 255) { wlr_log(L_ERROR, "cannot parse geometry string, too long"); return NULL; } @@ -43,8 +46,8 @@ static struct wlr_geometry *parse_geometry(const char *str) { char *endptr; long val = strtol(pch, &endptr, 0); - if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) - || (errno != 0 && val == 0)) { + if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || + (errno != 0 && val == 0)) { goto invalid_input; } @@ -70,7 +73,7 @@ static struct wlr_geometry *parse_geometry(const char *str) { pch = strtok(NULL, "x+"); } - if (!has_width || !has_height || !has_x || !has_y) { + if (!has_width || !has_height) { goto invalid_input; } @@ -87,7 +90,8 @@ invalid_input: static const char *output_prefix = "output:"; static const char *device_prefix = "device:"; -static int config_ini_handler(void *user, const char *section, const char *name, const char *value) { +static int config_ini_handler(void *user, const char *section, const char *name, + const char *value) { struct example_config *config = user; if (strncmp(output_prefix, section, strlen(output_prefix)) == 0) { const char *output_name = section + strlen(output_prefix); @@ -133,11 +137,10 @@ 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) { + free(config->cursor.mapped_output); config->cursor.mapped_output = strdup(value); } else if (strcmp(name, "geometry") == 0) { - if (config->cursor.mapped_geo) { - free(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); @@ -161,14 +164,10 @@ static int config_ini_handler(void *user, const char *section, const char *name, } if (strcmp(name, "map-to-output") == 0) { - if (dc->mapped_output) { - free(dc->mapped_output); - } + free(dc->mapped_output); dc->mapped_output = strdup(value); } else if (strcmp(name, "geometry") == 0) { - if (dc->mapped_geo) { - free(dc->mapped_geo); - } + free(dc->mapped_geo); dc->mapped_geo = parse_geometry(value); } else { wlr_log(L_ERROR, "got unknown device config: %s", name); @@ -199,10 +198,10 @@ struct example_config *parse_args(int argc, char *argv[]) { if (!config->config_path) { // get the config path from the current directory - char cwd[1024]; + char cwd[MAXPATHLEN]; if (getcwd(cwd, sizeof(cwd)) != NULL) { - char buf[1024]; - sprintf(buf, "%s/%s", cwd, "wlr-example.ini"); + char buf[MAXPATHLEN]; + snprintf(buf, MAXPATHLEN, "%s/%s", cwd, "wlr-example.ini"); config->config_path = strdup(buf); } else { wlr_log(L_ERROR, "could not get cwd"); @@ -213,7 +212,8 @@ struct example_config *parse_args(int argc, char *argv[]) { int result = ini_parse(config->config_path, config_ini_handler, config); if (result == -1) { - wlr_log(L_ERROR, "Could not find config file at %s", config->config_path); + wlr_log(L_ERROR, "Could not find config file at %s", + config->config_path); exit(1); } else if (result == -2) { wlr_log(L_ERROR, "Could not allocate memory to parse config file"); @@ -257,7 +257,8 @@ void example_config_destroy(struct example_config *config) { free(config); } -struct wlr_output_layout *configure_layout(struct example_config *config, struct wl_list *outputs) { +struct wlr_output_layout *configure_layout(struct example_config *config, + struct wl_list *outputs) { struct wlr_output_layout *layout = wlr_output_layout_init(); int max_x = INT_MIN; int max_x_y = INT_MIN; // y value for the max_x output @@ -272,7 +273,8 @@ struct wlr_output_layout *configure_layout(struct example_config *config, struct conf->x, conf->y); wlr_output_transform(output->output, conf->transform); int width, height; - wlr_output_effective_resolution(output->output, &width, &height); + wlr_output_effective_resolution(output->output, &width, + &height); if (conf->x + width > max_x) { max_x = conf->x + width; max_x_y = conf->y; @@ -301,4 +303,3 @@ struct wlr_output_layout *configure_layout(struct example_config *config, struct return layout; } - -- cgit v1.2.3 From 9b65d0b3f0030bf2103cd7d65448f727c62de468 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 29 Aug 2017 12:08:49 -0400 Subject: refactor and rename wlr_geometry to wlr_box --- examples/config.c | 34 +++++++------- examples/config.h | 4 +- examples/pointer.c | 4 +- include/wlr/types/wlr_box.h | 20 ++++++++ include/wlr/types/wlr_cursor.h | 6 +-- include/wlr/types/wlr_geometry.h | 20 -------- include/wlr/types/wlr_output_layout.h | 6 +-- types/meson.build | 2 +- types/wlr_box.c | 67 +++++++++++++++++++++++++++ types/wlr_cursor.c | 52 ++++++++++----------- types/wlr_geometry.c | 86 ----------------------------------- types/wlr_output_layout.c | 36 +++++++-------- 12 files changed, 159 insertions(+), 178 deletions(-) create mode 100644 include/wlr/types/wlr_box.h delete mode 100644 include/wlr/types/wlr_geometry.h create mode 100644 types/wlr_box.c delete mode 100644 types/wlr_geometry.c (limited to 'examples/config.c') diff --git a/examples/config.c b/examples/config.c index b99f130d..a1ed5d5a 100644 --- a/examples/config.c +++ b/examples/config.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include "shared.h" #include "config.h" #include "ini.h" @@ -25,7 +25,7 @@ static void usage(const char *name, int ret) { exit(ret); } -static struct wlr_geometry *parse_geometry(const char *str) { +static struct wlr_box *parse_geometry(const char *str) { // format: {width}x{height}+{x}+{y} if (strlen(str) > 255) { wlr_log(L_ERROR, "cannot parse geometry string, too long"); @@ -33,7 +33,7 @@ static struct wlr_geometry *parse_geometry(const char *str) { } char *buf = strdup(str); - struct wlr_geometry *geo = calloc(1, sizeof(struct wlr_geometry)); + struct wlr_box *box = calloc(1, sizeof(struct wlr_box)); bool has_width = false; bool has_height = false; @@ -56,16 +56,16 @@ static struct wlr_geometry *parse_geometry(const char *str) { } if (!has_width) { - geo->width = val; + box->width = val; has_width = true; } else if (!has_height) { - geo->height = val; + box->height = val; has_height = true; } else if (!has_x) { - geo->x = val; + box->x = val; has_x = true; } else if (!has_y) { - geo->y = val; + box->y = val; has_y = true; } else { break; @@ -78,12 +78,12 @@ static struct wlr_geometry *parse_geometry(const char *str) { } free(buf); - return geo; + return box; invalid_input: wlr_log(L_ERROR, "could not parse geometry string: %s", str); free(buf); - free(geo); + free(box); return NULL; } @@ -140,8 +140,8 @@ static int config_ini_handler(void *user, const char *section, const char *name, free(config->cursor.mapped_output); config->cursor.mapped_output = strdup(value); } else if (strcmp(name, "geometry") == 0) { - free(config->cursor.mapped_geo); - config->cursor.mapped_geo = parse_geometry(value); + free(config->cursor.mapped_box); + config->cursor.mapped_box = parse_geometry(value); } else { wlr_log(L_ERROR, "got unknown cursor config: %s", name); } @@ -167,8 +167,8 @@ 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) { - free(dc->mapped_geo); - dc->mapped_geo = parse_geometry(value); + free(dc->mapped_box); + dc->mapped_box = parse_geometry(value); } else { wlr_log(L_ERROR, "got unknown device config: %s", name); } @@ -239,8 +239,8 @@ void example_config_destroy(struct example_config *config) { if (dc->mapped_output) { free(dc->mapped_output); } - if (dc->mapped_geo) { - free(dc->mapped_geo); + if (dc->mapped_box) { + free(dc->mapped_box); } free(dc); } @@ -251,8 +251,8 @@ 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); + if (config->cursor.mapped_box) { + free(config->cursor.mapped_box); } free(config); } diff --git a/examples/config.h b/examples/config.h index cd19dc5e..2a69c4f4 100644 --- a/examples/config.h +++ b/examples/config.h @@ -15,14 +15,14 @@ struct output_config { struct device_config { char *name; char *mapped_output; - struct wlr_geometry *mapped_geo; + struct wlr_box *mapped_box; struct wl_list link; }; struct example_config { struct { char *mapped_output; - struct wlr_geometry *mapped_geo; + struct wlr_box *mapped_box; } cursor; struct wl_list outputs; diff --git a/examples/pointer.c b/examples/pointer.c index 5341c72c..d9a06339 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -105,7 +105,7 @@ static void configure_devices(struct sample_state *sample) { 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); + dc->mapped_box); } } } @@ -341,7 +341,7 @@ int main(int argc, char *argv[]) { state.config = parse_args(argc, argv); state.cursor = wlr_cursor_create(); - wlr_cursor_map_to_region(state.cursor, state.config->cursor.mapped_geo); + wlr_cursor_map_to_region(state.cursor, state.config->cursor.mapped_box); wl_list_init(&state.devices); // pointer events diff --git a/include/wlr/types/wlr_box.h b/include/wlr/types/wlr_box.h new file mode 100644 index 00000000..e2b1ab4e --- /dev/null +++ b/include/wlr/types/wlr_box.h @@ -0,0 +1,20 @@ +#ifndef _WLR_TYPES_GEOMETRY_H +#define _WLR_TYPES_GEOMETRY_H +#include + +struct wlr_box { + int x, y; + int width, height; +}; + +void wlr_box_closest_point(struct wlr_box *box, double x, double y, + double *dest_x, double *dest_y); + +bool wlr_box_intersection(struct wlr_box *box_a, + struct wlr_box *box_b, struct wlr_box **dest); + +bool wlr_box_contains_point(struct wlr_box *box, double x, double y); + +bool wlr_box_empty(struct wlr_box *box); + +#endif diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index ef3b8dbb..5fc0ec76 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include struct wlr_cursor_state; @@ -100,13 +100,13 @@ void wlr_cursor_map_input_to_output(struct wlr_cursor *cur, /** * Maps this cursor to an arbitrary region on the associated wlr_output_layout. */ -void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_geometry *geo); +void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_box *box); /** * Maps inputs from this input device to an arbitrary region on the associated * wlr_output_layout. */ void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, - struct wlr_input_device *dev, struct wlr_geometry *geo); + struct wlr_input_device *dev, struct wlr_box *box); #endif diff --git a/include/wlr/types/wlr_geometry.h b/include/wlr/types/wlr_geometry.h deleted file mode 100644 index cac75431..00000000 --- a/include/wlr/types/wlr_geometry.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _WLR_TYPES_GEOMETRY_H -#define _WLR_TYPES_GEOMETRY_H -#include - -struct wlr_geometry { - int x, y; - int width, height; -}; - -void wlr_geometry_closest_boundary(struct wlr_geometry *geo, double x, double y, - int *dest_x, int *dest_y, double *distance); - -bool wlr_geometry_intersection(struct wlr_geometry *geo_a, - struct wlr_geometry *geo_b, struct wlr_geometry **dest); - -bool wlr_geometry_contains_point(struct wlr_geometry *geo, int x, int y); - -bool wlr_geometry_empty(struct wlr_geometry *geo); - -#endif diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h index dfb5234d..794fc491 100644 --- a/include/wlr/types/wlr_output_layout.h +++ b/include/wlr/types/wlr_output_layout.h @@ -62,10 +62,10 @@ void wlr_output_layout_closest_boundary(struct wlr_output_layout *layout, double *dest_y); /** - * Get the geometry of the layout for the given reference output. If `reference` - * is NULL, the geometry will be for the extents of the entire layout. + * Get the box of the layout for the given reference output. If `reference` + * is NULL, the box will be for the extents of the entire layout. */ -struct wlr_geometry *wlr_output_layout_get_geometry( +struct wlr_box *wlr_output_layout_get_box( struct wlr_output_layout *layout, struct wlr_output *reference); #endif diff --git a/types/meson.build b/types/meson.build index 8b8b215b..56390475 100644 --- a/types/meson.build +++ b/types/meson.build @@ -16,7 +16,7 @@ lib_wlr_types = static_library('wlr_types', files( 'wlr_xdg_shell_v6.c', 'wlr_wl_shell.c', 'wlr_compositor.c', - 'wlr_geometry.c', + 'wlr_box.c', ), include_directories: wlr_inc, dependencies: [wayland_server, pixman, wlr_protos]) diff --git a/types/wlr_box.c b/types/wlr_box.c new file mode 100644 index 00000000..7e981833 --- /dev/null +++ b/types/wlr_box.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include + +void wlr_box_closest_point(struct wlr_box *box, double x, double y, + double *dest_x, double *dest_y) { + // find the closest x point + if (x < box->x) { + *dest_x = box->x; + } else if (x > box->x + box->width) { + *dest_x = box->x + box->width; + } else { + *dest_x = x; + } + + // find closest y point + if (y < box->y) { + *dest_y = box->y; + } else if (y > box->y + box->height) { + *dest_y = box->y + box->height; + } else { + *dest_y = y; + } +} + +bool wlr_box_empty(struct wlr_box *box) { + return box == NULL || box->width <= 0 || box->height <= 0; +} + +bool wlr_box_intersection(struct wlr_box *box_a, + struct wlr_box *box_b, struct wlr_box **box_dest) { + struct wlr_box *dest = *box_dest; + bool a_empty = wlr_box_empty(box_a); + bool b_empty = wlr_box_empty(box_b); + + if (a_empty || b_empty) { + dest->x = 0; + dest->y = 0; + dest->width = -100; + dest->height = -100; + return false; + } + + int x1 = fmax(box_a->x, box_b->x); + int y1 = fmax(box_a->y, box_b->y); + int x2 = fmin(box_a->x + box_a->width, box_b->x + box_b->width); + int y2 = fmin(box_a->y + box_a->height, box_b->y + box_b->height); + + dest->x = x1; + dest->y = y1; + dest->width = x2 - x1; + dest->height = y2 - y1; + + return !wlr_box_empty(dest); +} + +bool wlr_box_contains_point(struct wlr_box *box, double x, double y) { + if (wlr_box_empty(box)) { + return false; + } else { + return x >= box->x && x <= box->x + box->width && + y >= box->y && y <= box->y + box->height; + } +} diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 4bbf897b..bc546b15 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -13,7 +13,7 @@ struct wlr_cursor_device { struct wlr_input_device *device; struct wl_list link; struct wlr_output *mapped_output; - struct wlr_geometry *mapped_geometry; + struct wlr_box *mapped_box; struct wl_listener motion; struct wl_listener motion_absolute; @@ -38,7 +38,7 @@ struct wlr_cursor_state { struct wlr_output_layout *layout; struct wlr_xcursor *xcursor; struct wlr_output *mapped_output; - struct wlr_geometry *mapped_geometry; + struct wlr_box *mapped_box; }; struct wlr_cursor *wlr_cursor_create() { @@ -149,26 +149,26 @@ static void wlr_cursor_warp_unchecked(struct wlr_cursor *cur, * If none of these are set, returns NULL and absolute movement should be * relative to the extents of the layout. */ -static struct wlr_geometry *get_mapping(struct wlr_cursor *cur, +static struct wlr_box *get_mapping(struct wlr_cursor *cur, struct wlr_input_device *dev) { assert(cur->state->layout); struct wlr_cursor_device *c_device = get_cursor_device(cur, dev); if (c_device) { - if (c_device->mapped_geometry) { - return c_device->mapped_geometry; + if (c_device->mapped_box) { + return c_device->mapped_box; } if (c_device->mapped_output) { - return wlr_output_layout_get_geometry(cur->state->layout, + return wlr_output_layout_get_box(cur->state->layout, c_device->mapped_output); } } - if (cur->state->mapped_geometry) { - return cur->state->mapped_geometry; + if (cur->state->mapped_box) { + return cur->state->mapped_box; } if (cur->state->mapped_output) { - return wlr_output_layout_get_geometry(cur->state->layout, + return wlr_output_layout_get_box(cur->state->layout, cur->state->mapped_output); } @@ -180,10 +180,10 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, assert(cur->state->layout); bool result = false; - struct wlr_geometry *mapping = get_mapping(cur, dev); + struct wlr_box *mapping = get_mapping(cur, dev); if (mapping) { - if (wlr_geometry_contains_point(mapping, x, y)) { + if (wlr_box_contains_point(mapping, x, y)) { wlr_cursor_warp_unchecked(cur, x, y); result = true; } @@ -200,9 +200,9 @@ void wlr_cursor_warp_absolute(struct wlr_cursor *cur, struct wlr_input_device *dev, double x_mm, double y_mm) { assert(cur->state->layout); - struct wlr_geometry *mapping = get_mapping(cur, dev); + struct wlr_box *mapping = get_mapping(cur, dev); if (!mapping) { - mapping = wlr_output_layout_get_geometry(cur->state->layout, NULL); + mapping = wlr_output_layout_get_box(cur->state->layout, NULL); } double x = mapping->width * x_mm + mapping->x; @@ -218,15 +218,15 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev, double x = cur->x + delta_x; double y = cur->y + delta_y; - struct wlr_geometry *mapping = get_mapping(cur, dev); + struct wlr_box *mapping = get_mapping(cur, dev); if (mapping) { - int boundary_x, boundary_y; - if (!wlr_geometry_contains_point(mapping, x, y)) { - wlr_geometry_closest_boundary(mapping, x, y, &boundary_x, - &boundary_y, NULL); - x = boundary_x; - y = boundary_y; + double closest_x, closest_y; + if (!wlr_box_contains_point(mapping, x, y)) { + wlr_box_closest_point(mapping, x, y, &closest_x, + &closest_y); + x = closest_x; + y = closest_y; } } else { if (!wlr_output_layout_contains_point(cur->state->layout, NULL, x, y)) { @@ -452,18 +452,18 @@ void wlr_cursor_map_input_to_output(struct wlr_cursor *cur, } void wlr_cursor_map_to_region(struct wlr_cursor *cur, - struct wlr_geometry *geo) { - if (geo && wlr_geometry_empty(geo)) { + struct wlr_box *box) { + if (box && wlr_box_empty(box)) { wlr_log(L_ERROR, "cannot map cursor to an empty region"); return; } - cur->state->mapped_geometry = geo; + cur->state->mapped_box = box; } void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, - struct wlr_input_device *dev, struct wlr_geometry *geo) { - if (geo && wlr_geometry_empty(geo)) { + struct wlr_input_device *dev, struct wlr_box *box) { + if (box && wlr_box_empty(box)) { wlr_log(L_ERROR, "cannot map device \"%s\" input to an empty region", dev->name); return; @@ -476,5 +476,5 @@ void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, return; } - c_device->mapped_geometry = geo; + c_device->mapped_box = box; } diff --git a/types/wlr_geometry.c b/types/wlr_geometry.c deleted file mode 100644 index 4f532d6f..00000000 --- a/types/wlr_geometry.c +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include -#include -#include -#include - -static double get_distance(double x1, double y1, double x2, double y2) { - double distance; - distance = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); - return distance; -} - -void wlr_geometry_closest_boundary(struct wlr_geometry *geo, double x, double y, - int *dest_x, int *dest_y, double *distance) { - // find the closest x point - if (x < geo->x) { - *dest_x = geo->x; - } else if (x > geo->x + geo->width) { - *dest_x = geo->x + geo->width; - } else { - *dest_x = x; - } - - // find closest y point - if (y < geo->y) { - *dest_y = geo->y; - } else if (y > geo->y + geo->height) { - *dest_y = geo->y + geo->height; - } else { - *dest_y = y; - } - - // calculate distance - if (distance) { - *distance = get_distance(*dest_x, *dest_y, x, y); - } -} - -#ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) -#endif - -#ifndef min -#define min(a,b) ((a) < (b) ? (a) : (b)) -#endif - -bool wlr_geometry_empty(struct wlr_geometry *geo) { - return geo == NULL || geo->width <= 0 || geo->height <= 0; -} - -bool wlr_geometry_intersection(struct wlr_geometry *geo_a, - struct wlr_geometry *geo_b, struct wlr_geometry **geo_dest) { - struct wlr_geometry *dest = *geo_dest; - bool a_empty = wlr_geometry_empty(geo_a); - bool b_empty = wlr_geometry_empty(geo_b); - - if (a_empty || b_empty) { - dest->x = 0; - dest->y = 0; - dest->width = -100; - dest->height = -100; - return false; - } - - int x1 = max(geo_a->x, geo_b->x); - int y1 = max(geo_a->y, geo_b->y); - int x2 = min(geo_a->x + geo_a->width, geo_b->x + geo_b->width); - int y2 = min(geo_a->y + geo_a->height, geo_b->y + geo_b->height); - - dest->x = x1; - dest->y = y1; - dest->width = x2 - x1; - dest->height = y2 - y1; - - return !wlr_geometry_empty(dest); -} - -bool wlr_geometry_contains_point(struct wlr_geometry *geo, int x, int y) { - if (wlr_geometry_empty(geo)) { - return false; - } else { - return x >= geo->x && x <= geo->x + geo->width && - y >= geo->y && y <= geo->y + geo->height; - } -} diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index b097b1b8..ba2c158a 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -1,24 +1,24 @@ #include #include #include -#include +#include #include #include #include struct wlr_output_layout_state { - struct wlr_geometry *_geo; + struct wlr_box *_box; }; struct wlr_output_layout_output_state { - struct wlr_geometry *_geo; + struct wlr_box *_box; }; struct wlr_output_layout *wlr_output_layout_init() { struct wlr_output_layout *layout = calloc(1, sizeof(struct wlr_output_layout)); layout->state = calloc(1, sizeof(struct wlr_output_layout_state)); - layout->state->_geo = calloc(1, sizeof(struct wlr_geometry)); + layout->state->_box = calloc(1, sizeof(struct wlr_box)); wl_list_init(&layout->outputs); return layout; } @@ -26,7 +26,7 @@ struct wlr_output_layout *wlr_output_layout_init() { static void wlr_output_layout_output_destroy( struct wlr_output_layout_output *l_output) { wl_list_remove(&l_output->link); - free(l_output->state->_geo); + free(l_output->state->_box); free(l_output->state); free(l_output); } @@ -41,7 +41,7 @@ void wlr_output_layout_destroy(struct wlr_output_layout *layout) { wlr_output_layout_output_destroy(_output); } - free(layout->state->_geo); + free(layout->state->_box); free(layout->state); free(layout); } @@ -51,7 +51,7 @@ void wlr_output_layout_add(struct wlr_output_layout *layout, struct wlr_output_layout_output *l_output; l_output= calloc(1, sizeof(struct wlr_output_layout_output)); l_output->state = calloc(1, sizeof(struct wlr_output_layout_output_state)); - l_output->state->_geo = calloc(1, sizeof(struct wlr_geometry)); + l_output->state->_box = calloc(1, sizeof(struct wlr_box)); l_output->output = output; l_output->x = x; l_output->y = y; @@ -178,7 +178,7 @@ void wlr_output_layout_closest_boundary(struct wlr_output_layout *layout, wlr_output_effective_resolution(l_output->output, &width, &height); // find the closest x point - // TODO use wlr_geometry_closest_boundary + // TODO use wlr_box_closest_boundary if (x < l_output->x) { output_x = l_output->x; } else if (x > l_output->x + width) { @@ -209,17 +209,17 @@ void wlr_output_layout_closest_boundary(struct wlr_output_layout *layout, *dest_y = min_y; } -struct wlr_geometry *wlr_output_layout_get_geometry( +struct wlr_box *wlr_output_layout_get_box( struct wlr_output_layout *layout, struct wlr_output *reference) { struct wlr_output_layout_output *l_output; if (reference) { // output extents l_output= wlr_output_layout_get(layout, reference); - l_output->state->_geo->x = l_output->x; - l_output->state->_geo->y = l_output->y; + l_output->state->_box->x = l_output->x; + l_output->state->_box->y = l_output->y; wlr_output_effective_resolution(reference, - &l_output->state->_geo->width, &l_output->state->_geo->height); - return l_output->state->_geo; + &l_output->state->_box->width, &l_output->state->_box->height); + return l_output->state->_box; } else { // layout extents int min_x = INT_MAX, min_y = INT_MAX; @@ -241,12 +241,12 @@ struct wlr_geometry *wlr_output_layout_get_geometry( } } - layout->state->_geo->x = min_x; - layout->state->_geo->y = min_y; - layout->state->_geo->width = max_x - min_x; - layout->state->_geo->height = max_y - min_y; + layout->state->_box->x = min_x; + layout->state->_box->y = min_y; + layout->state->_box->width = max_x - min_x; + layout->state->_box->height = max_y - min_y; - return layout->state->_geo; + return layout->state->_box; } // not reached -- cgit v1.2.3 From 6699024b445a152e78670549efabe024cd670e99 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 29 Aug 2017 12:43:33 -0400 Subject: handle empty config file --- examples/config.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'examples/config.c') diff --git a/examples/config.c b/examples/config.c index a1ed5d5a..954edb06 100644 --- a/examples/config.c +++ b/examples/config.c @@ -212,9 +212,7 @@ struct example_config *parse_args(int argc, char *argv[]) { int result = ini_parse(config->config_path, config_ini_handler, config); if (result == -1) { - wlr_log(L_ERROR, "Could not find config file at %s", - config->config_path); - exit(1); + wlr_log(L_DEBUG, "No config file found. Using empty config."); } else if (result == -2) { wlr_log(L_ERROR, "Could not allocate memory to parse config file"); exit(1); -- cgit v1.2.3