From 44181b57aceb2a49846d15e9cea11a704cba9786 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 16 Aug 2017 11:51:22 -0400 Subject: Add wlr_output_layout implementation An output layout consists of a mapping of outputs to their position in a global coordinate system that usually cooresponds to the output position in physical space in front of the user. Add an example that allows configuration of an output layout and demonstrates its boundaries with a bouncing image. --- include/wlr/types/wlr_output_layout.h | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 include/wlr/types/wlr_output_layout.h (limited to 'include/wlr') diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h new file mode 100644 index 00000000..cd36482a --- /dev/null +++ b/include/wlr/types/wlr_output_layout.h @@ -0,0 +1,40 @@ +#ifndef _WLR_TYPES_OUTPUT_LAYOUT_H +#define _WLR_TYPES_OUTPUT_LAYOUT_H +#include +#include +#include + +struct wlr_output_layout { + struct wl_list outputs; +}; + +struct wlr_output_layout_output { + struct wlr_output *output; + int x, y; + struct wl_list link; +}; + +struct wlr_output_layout *wlr_output_layout_init(); + +void wlr_output_layout_destroy(struct wlr_output_layout *layout); + +struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, + double x, double y); + +void wlr_output_layout_add(struct wlr_output_layout *layout, + struct wlr_output *output, int x, int y); + +void wlr_output_layout_move(struct wlr_output_layout *layout, + struct wlr_output *output, int x, int y); + +void wlr_output_layout_remove(struct wlr_output_layout *layout, + struct wlr_output *output); + +/** + * Given x and y as pointers to global coordinates, adjusts them to local output + * coordinates relative to the given reference output. + */ +void wlr_output_layout_output_coords(struct wlr_output_layout *layout, + struct wlr_output *reference, int *x, int *y); + +#endif -- cgit v1.2.3 From 2e9e237f9d5485f65afbf3d8b49c740ed0653e5b Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 16 Aug 2017 15:00:15 -0400 Subject: layout-output example: handle empty config --- examples/output-layout.c | 31 +++++++++++++++++++++++++++++-- include/wlr/types/wlr_output_layout.h | 3 +++ types/wlr_output_layout.c | 2 +- 3 files changed, 33 insertions(+), 3 deletions(-) (limited to 'include/wlr') diff --git a/examples/output-layout.c b/examples/output-layout.c index f0e2d2d4..81a7251b 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -31,6 +31,7 @@ struct sample_state { float x_offs, y_offs; float x_vel, y_vel; struct wlr_output *main_output; + struct wl_list outputs; }; struct output_config { @@ -109,6 +110,7 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts static void handle_output_add(struct output_state *output) { struct sample_state *sample = output->compositor->data; + bool found = false; struct output_config *conf; wl_list_for_each(conf, &sample->config, link) { if (strcmp(conf->name, output->output->name) == 0) { @@ -120,13 +122,35 @@ static void handle_output_add(struct output_state *output) { sample->main_output = output->output; sample->x_offs = conf->x + 20; sample->y_offs = conf->y + 20; - sample->x_vel = 500; - sample->y_vel = 500; } wlr_log(L_DEBUG, "Adding output to layout: %s", output->output->name); + found = true; + break; + } + } + + // if it's not in the config, just place it next to the rightmost output + if (!found) { + int x = 0; + struct output_state *_output; + wl_list_for_each(_output, &sample->outputs, link) { + struct wlr_output_layout_output *layout_output = + wlr_output_layout_get(sample->layout, _output->output); + if (layout_output && layout_output->output) { + x += layout_output->x + _output->output->width; + } } + wlr_output_layout_add(sample->layout, output->output, x, 0); + + if (wl_list_empty(&sample->config) && !sample->main_output) { + sample->main_output = output->output; + sample->x_offs = x + 20; + sample->y_offs = 20; + } } + + wl_list_insert(&sample->outputs, &output->link); } static void update_velocities(struct compositor_state *state, @@ -245,9 +269,12 @@ static void parse_args(int argc, char *argv[], struct wl_list *config) { int main(int argc, char *argv[]) { struct sample_state state = {0}; + state.x_vel = 500; + state.y_vel = 500; state.layout = wlr_output_layout_init(); wl_list_init(&state.config); + wl_list_init(&state.outputs); parse_args(argc, argv, &state.config); struct compositor_state compositor = { 0 }; diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h index cd36482a..7c904838 100644 --- a/include/wlr/types/wlr_output_layout.h +++ b/include/wlr/types/wlr_output_layout.h @@ -18,6 +18,9 @@ struct wlr_output_layout *wlr_output_layout_init(); void wlr_output_layout_destroy(struct wlr_output_layout *layout); +struct wlr_output_layout_output *wlr_output_layout_get( + struct wlr_output_layout *layout, struct wlr_output *reference); + struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, double x, double y); diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index 8b4256f9..dd31aef8 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -33,7 +33,7 @@ void wlr_output_layout_add(struct wlr_output_layout *layout, wl_list_insert(&layout->outputs, &layout_output->link); } -static struct wlr_output_layout_output *wlr_output_layout_get( +struct wlr_output_layout_output *wlr_output_layout_get( struct wlr_output_layout *layout, struct wlr_output *reference) { struct wlr_output_layout_output *ret = NULL; struct wlr_output_layout_output *_output; -- cgit v1.2.3 From 5a9baf487e0161cfbf9481c31eb6f72be0ec2fbe Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 17 Aug 2017 10:12:36 -0400 Subject: add helper methods for intersection --- examples/output-layout.c | 22 +++++++++------------- include/wlr/types/wlr_output_layout.h | 6 ++++++ types/wlr_output_layout.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) (limited to 'include/wlr') diff --git a/examples/output-layout.c b/examples/output-layout.c index cc363504..13abb6a1 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -46,24 +46,20 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts struct sample_state *sample = state->data; struct wlr_output *wlr_output = output->output; - int32_t width, height; - wlr_output_effective_resolution(wlr_output, &width, &height); - wlr_output_make_current(wlr_output); wlr_renderer_begin(sample->renderer, wlr_output); - float matrix[16]; - - // transform global coordinates to local coordinates - int local_x = sample->x_offs; - int local_y = sample->y_offs; + if (wlr_output_layout_intersects(sample->layout, output->output, + sample->x_offs, sample->y_offs, + sample->x_offs + 128, sample->y_offs + 128)) { + float matrix[16]; - wlr_output_layout_output_coords(sample->layout, output->output, &local_x, - &local_y); + // transform global coordinates to local coordinates + int local_x = sample->x_offs; + int local_y = sample->y_offs; + wlr_output_layout_output_coords(sample->layout, output->output, &local_x, + &local_y); - if (local_x < width && local_x + 128 > 0 && local_y < height && - local_y + 128 > 0) { - // render the image if it intersects with the output wlr_texture_get_matrix(sample->cat_texture, &matrix, &wlr_output->transform_matrix, local_x, local_y); wlr_render_with_matrix(sample->renderer, diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h index 7c904838..1b83bfaf 100644 --- a/include/wlr/types/wlr_output_layout.h +++ b/include/wlr/types/wlr_output_layout.h @@ -40,4 +40,10 @@ void wlr_output_layout_remove(struct wlr_output_layout *layout, void wlr_output_layout_output_coords(struct wlr_output_layout *layout, struct wlr_output *reference, int *x, int *y); +bool wlr_output_layout_contains_point(struct wlr_output_layout *layout, + struct wlr_output *reference, int x, int y); + +bool wlr_output_layout_intersects(struct wlr_output_layout *layout, + struct wlr_output *reference, int x1, int y1, int x2, int y2); + #endif diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index b4a3565e..ea93610d 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -47,6 +47,36 @@ struct wlr_output_layout_output *wlr_output_layout_get( } +static bool output_contains_point( struct wlr_output_layout_output *l_output, + int x, int y, int width, int height) { + return x >= l_output->x && x <= l_output->x + width && + y >= l_output->y && y <= l_output->y + height; +} + +bool wlr_output_layout_contains_point(struct wlr_output_layout *layout, + struct wlr_output *reference, int x, int y) { + struct wlr_output_layout_output *layout_output = wlr_output_layout_get(layout, reference); + int width, height; + wlr_output_effective_resolution(layout_output->output, &width, &height); + return output_contains_point(layout_output, x, y, width, height); +} + +bool wlr_output_layout_intersects(struct wlr_output_layout *layout, + struct wlr_output *reference, int x1, int y1, int x2, int y2) { + struct wlr_output_layout_output *l_output = wlr_output_layout_get(layout, reference); + if (!l_output) { + return false; + } + int width, height; + wlr_output_effective_resolution(l_output->output, &width, &height); + + // the output must contain one of the points + return output_contains_point(l_output, x1, y1, width, height) || + output_contains_point(l_output, x2, y2, width, height) || + output_contains_point(l_output, x2, y1, width, height) || + output_contains_point(l_output, y2, x1, width, height); +} + struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, double x, double y) { struct wlr_output *ret = NULL; -- cgit v1.2.3 From 3138c5ddf04441fb7572db8c1a80b3789c4cc563 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 17 Aug 2017 21:04:05 -0400 Subject: Clean up wlr_output_layout --- examples/output-layout.c | 8 +++----- include/wlr/types/wlr_output_layout.h | 14 +++++++------- types/wlr_output_layout.c | 14 ++++---------- 3 files changed, 14 insertions(+), 22 deletions(-) (limited to 'include/wlr') diff --git a/examples/output-layout.c b/examples/output-layout.c index 320d11f8..c16af634 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -127,9 +127,7 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts } static inline int max(int a, int b) { - if (a < b) - return b; - return a; + return a < b ? b : a; } static void configure_layout(struct sample_state *sample) { @@ -202,8 +200,8 @@ static void update_velocities(struct compositor_state *state, sample->y_vel += y_diff; } -static void handle_keyboard_key(struct keyboard_state *kbstate, - xkb_keysym_t sym, enum wlr_key_state key_state) { +static void handle_keyboard_key(struct keyboard_state *kbstate, uint32_t keycode, + xkb_keysym_t sym, enum wlr_key_state key_state) { // NOTE: It may be better to simply refer to our key state during each frame // and make this change in pixels/sec^2 // Also, key repeat diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h index 1b83bfaf..f6a1efdd 100644 --- a/include/wlr/types/wlr_output_layout.h +++ b/include/wlr/types/wlr_output_layout.h @@ -22,28 +22,28 @@ struct wlr_output_layout_output *wlr_output_layout_get( struct wlr_output_layout *layout, struct wlr_output *reference); struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, - double x, double y); + double x, double y); void wlr_output_layout_add(struct wlr_output_layout *layout, - struct wlr_output *output, int x, int y); + struct wlr_output *output, int x, int y); void wlr_output_layout_move(struct wlr_output_layout *layout, - struct wlr_output *output, int x, int y); + struct wlr_output *output, int x, int y); void wlr_output_layout_remove(struct wlr_output_layout *layout, - struct wlr_output *output); + struct wlr_output *output); /** * Given x and y as pointers to global coordinates, adjusts them to local output * coordinates relative to the given reference output. */ void wlr_output_layout_output_coords(struct wlr_output_layout *layout, - struct wlr_output *reference, int *x, int *y); + struct wlr_output *reference, int *x, int *y); bool wlr_output_layout_contains_point(struct wlr_output_layout *layout, - struct wlr_output *reference, int x, int y); + struct wlr_output *reference, int x, int y); bool wlr_output_layout_intersects(struct wlr_output_layout *layout, - struct wlr_output *reference, int x1, int y1, int x2, int y2); + struct wlr_output *reference, int x1, int y1, int x2, int y2); #endif diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index ea93610d..2e2032b3 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -35,16 +35,13 @@ void wlr_output_layout_add(struct wlr_output_layout *layout, struct wlr_output_layout_output *wlr_output_layout_get( struct wlr_output_layout *layout, struct wlr_output *reference) { - struct wlr_output_layout_output *ret = NULL; struct wlr_output_layout_output *_output; wl_list_for_each(_output, &layout->outputs, link) { if (_output->output == reference) { - ret = _output; + return _output; } } - - return ret; - + return NULL; } static bool output_contains_point( struct wlr_output_layout_output *l_output, @@ -79,7 +76,6 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout, struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, double x, double y) { - struct wlr_output *ret = NULL; struct wlr_output_layout_output *_output; wl_list_for_each(_output, &layout->outputs, link) { if (_output->output) { @@ -88,13 +84,11 @@ struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, bool has_x = x >= _output->x && x <= _output->x + width; bool has_y = y >= _output->y && y <= _output->y + height; if (has_x && has_y) { - ret = _output->output; - break; + return _output->output; } } } - - return ret; + return NULL; } void wlr_output_layout_move(struct wlr_output_layout *layout, -- cgit v1.2.3