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 --- examples/wlr-example.ini.example | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 examples/wlr-example.ini.example (limited to 'examples/wlr-example.ini.example') 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/wlr-example.ini.example') 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/wlr-example.ini.example') 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/wlr-example.ini.example') 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