From 6e7c0b57f6b601a8c6883f71d00719dbd208c79d Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Apr 2018 17:26:33 +0100 Subject: [PATCH] cursor: use NAN for unspecified axes, refactor absolute warping code --- include/wlr/types/wlr_cursor.h | 31 +++++++--- rootston/cursor.c | 15 ++--- types/wlr_cursor.c | 107 +++++++++++++++------------------ 3 files changed, 73 insertions(+), 80 deletions(-) diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index b764e6d2..1a9e0d38 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -69,16 +69,34 @@ void wlr_cursor_destroy(struct wlr_cursor *cur); * `dev` may be passed to respect device mapping constraints. If `dev` is NULL, * device mapping constraints will be ignored. * - * Returns true when the mouse warp was successful. + * Returns true when the cursor warp was successful. */ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, - double x, double y); + double lx, double ly); +/** + * Convert absolute 0..1 coordinates to layout coordinates. + * + * `dev` may be passed to respect device mapping constraints. If `dev` is NULL, + * device mapping constraints will be ignored. + */ +void wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, + struct wlr_input_device *dev, double x, double y, double *lx, double *ly); + +/** + * Warp the cursor to the given x and y in absolute 0..1 coordinates. If the + * given point is out of the layout boundaries or constraints, the closest point + * will be used. If one coordinate is NAN, it will be ignored. + * + * `dev` may be passed to respect device mapping constraints. If `dev` is NULL, + * device mapping constraints will be ignored. + */ void wlr_cursor_warp_absolute(struct wlr_cursor *cur, struct wlr_input_device *dev, double x, double y); /** - * Move the cursor in the direction of the given x and y coordinates. + * Move the cursor in the direction of the given x and y layout coordinates. If + * one coordinate is NAN, it will be ignored. * * `dev` may be passed to respect device mapping constraints. If `dev` is NULL, * device mapping constraints will be ignored. @@ -153,11 +171,4 @@ void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_box *box); void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, struct wlr_input_device *dev, struct wlr_box *box); -/** - * Convert absolute coordinates to layout coordinates for the device. - */ -bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, - struct wlr_input_device *device, double x, double y, - double *lx, double *ly); - #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 21e32a09..61a34db9 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -320,11 +320,9 @@ void roots_cursor_handle_touch_down(struct roots_cursor *cursor, struct wlr_event_touch_down *event) { struct roots_desktop *desktop = cursor->seat->input->server->desktop; double lx, ly; - bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, - event->device, event->x, event->y, &lx, &ly); - if (!result) { - return; - } + wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, + event->x, event->y, &lx, &ly); + double sx, sy; struct wlr_surface *surface = desktop_surface_at( desktop, lx, ly, &sx, &sy, NULL); @@ -371,11 +369,8 @@ void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, } double lx, ly; - bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, - event->device, event->x, event->y, &lx, &ly); - if (!result) { - return; - } + wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, + event->x, event->y, &lx, &ly); double sx, sy; struct wlr_surface *surface = desktop_surface_at( diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 7f0e6c62..aec7b013 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -175,21 +176,20 @@ static struct wlr_cursor_device *get_cursor_device(struct wlr_cursor *cur, } static void cursor_warp_unchecked(struct wlr_cursor *cur, - double x, double y) { + double lx, double ly) { assert(cur->state->layout); struct wlr_cursor_output_cursor *output_cursor; wl_list_for_each(output_cursor, &cur->state->output_cursors, link) { - double output_x = x; - double output_y = y; + double output_x = lx, output_y = ly; wlr_output_layout_output_coords(cur->state->layout, output_cursor->output_cursor->output, &output_x, &output_y); - wlr_output_cursor_move(output_cursor->output_cursor, output_x, - output_y); + wlr_output_cursor_move(output_cursor->output_cursor, + output_x, output_y); } - cur->x = x; - cur->y = y; + cur->x = lx; + cur->y = ly; } /** @@ -233,28 +233,41 @@ static struct wlr_box *get_mapping(struct wlr_cursor *cur, } bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, - double x, double y) { + double lx, double ly) { assert(cur->state->layout); + bool result = false; - struct wlr_box *mapping = get_mapping(cur, dev); - if (mapping) { - if (wlr_box_contains_point(mapping, x, y)) { - cursor_warp_unchecked(cur, x, y); - result = true; - } - } else if (wlr_output_layout_contains_point(cur->state->layout, NULL, - x, y)) { - cursor_warp_unchecked(cur, x, y); - result = true; + result = wlr_box_contains_point(mapping, lx, ly); + } else { + result = wlr_output_layout_contains_point(cur->state->layout, NULL, + lx, ly); + } + + if (result) { + cursor_warp_unchecked(cur, lx, ly); } return result; } -void wlr_cursor_warp_absolute(struct wlr_cursor *cur, - struct wlr_input_device *dev, double x, double y) { +static void cursor_warp_closest(struct wlr_cursor *cur, + struct wlr_input_device *dev, double lx, double ly) { + struct wlr_box *mapping = get_mapping(cur, dev); + if (mapping) { + wlr_box_closest_point(mapping, lx, ly, &lx, &ly); + } else { + wlr_output_layout_closest_point(cur->state->layout, NULL, lx, ly, + &lx, &ly); + } + + cursor_warp_unchecked(cur, lx, ly); +} + +void wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, + struct wlr_input_device *dev, double x, double y, + double *lx, double *ly) { assert(cur->state->layout); struct wlr_box *mapping = get_mapping(cur, dev); @@ -262,40 +275,28 @@ void wlr_cursor_warp_absolute(struct wlr_cursor *cur, mapping = wlr_output_layout_get_box(cur->state->layout, NULL); } - x = x >= 0 ? mapping->width * x + mapping->x : cur->x; - y = y >= 0 ? mapping->height * y + mapping->y : cur->y; + *lx = !isnan(x) ? mapping->width * x + mapping->x : cur->x; + *ly = !isnan(y) ? mapping->height * y + mapping->y : cur->y; +} - cursor_warp_unchecked(cur, x, y); +void wlr_cursor_warp_absolute(struct wlr_cursor *cur, + struct wlr_input_device *dev, double x, double y) { + assert(cur->state->layout); + + double lx, ly; + wlr_cursor_absolute_to_layout_coords(cur, dev, x, y, &lx, &ly); + + cursor_warp_closest(cur, dev, lx, ly); } void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev, double delta_x, double delta_y) { assert(cur->state->layout); - double x = cur->x + delta_x; - double y = cur->y + delta_y; + double lx = !isnan(delta_x) ? cur->x + delta_x : cur->x; + double ly = !isnan(delta_y) ? cur->y + delta_y : cur->y; - struct wlr_box *mapping = get_mapping(cur, dev); - - if (mapping) { - 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)) { - double layout_x, layout_y; - wlr_output_layout_closest_point(cur->state->layout, NULL, x, y, - &layout_x, &layout_y); - x = layout_x; - y = layout_y; - } - } - - cursor_warp_unchecked(cur, x, y); + cursor_warp_closest(cur, dev, lx, ly); } void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels, @@ -638,17 +639,3 @@ void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, c_device->mapped_box = box; } - -bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, - struct wlr_input_device *device, double x, double y, - double *lx, double *ly) { - struct wlr_box *mapping = get_mapping(cur, device); - if (!mapping) { - mapping = wlr_output_layout_get_box(cur->state->layout, NULL); - } - - *lx = x > 0 ? mapping->width * x + mapping->x : cur->x; - *ly = y > 0 ? mapping->height * y + mapping->y : cur->y; - - return true; -}