cursor: use NAN for unspecified axes, refactor absolute warping code

This commit is contained in:
emersion 2018-04-27 17:26:33 +01:00
parent 4d7877420d
commit 6e7c0b57f6
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
3 changed files with 73 additions and 80 deletions

View file

@ -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, * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
* device mapping constraints will be ignored. * 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, 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, void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
struct wlr_input_device *dev, double x, double y); 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, * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
* device mapping constraints will be ignored. * 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, void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
struct wlr_input_device *dev, struct wlr_box *box); 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 #endif

View file

@ -320,11 +320,9 @@ void roots_cursor_handle_touch_down(struct roots_cursor *cursor,
struct wlr_event_touch_down *event) { struct wlr_event_touch_down *event) {
struct roots_desktop *desktop = cursor->seat->input->server->desktop; struct roots_desktop *desktop = cursor->seat->input->server->desktop;
double lx, ly; double lx, ly;
bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device,
event->device, event->x, event->y, &lx, &ly); event->x, event->y, &lx, &ly);
if (!result) {
return;
}
double sx, sy; double sx, sy;
struct wlr_surface *surface = desktop_surface_at( struct wlr_surface *surface = desktop_surface_at(
desktop, lx, ly, &sx, &sy, NULL); desktop, lx, ly, &sx, &sy, NULL);
@ -371,11 +369,8 @@ void roots_cursor_handle_touch_motion(struct roots_cursor *cursor,
} }
double lx, ly; double lx, ly;
bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device,
event->device, event->x, event->y, &lx, &ly); event->x, event->y, &lx, &ly);
if (!result) {
return;
}
double sx, sy; double sx, sy;
struct wlr_surface *surface = desktop_surface_at( struct wlr_surface *surface = desktop_surface_at(

View file

@ -1,5 +1,6 @@
#include <assert.h> #include <assert.h>
#include <limits.h> #include <limits.h>
#include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <wayland-server.h> #include <wayland-server.h>
#include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_cursor.h>
@ -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, static void cursor_warp_unchecked(struct wlr_cursor *cur,
double x, double y) { double lx, double ly) {
assert(cur->state->layout); assert(cur->state->layout);
struct wlr_cursor_output_cursor *output_cursor; struct wlr_cursor_output_cursor *output_cursor;
wl_list_for_each(output_cursor, &cur->state->output_cursors, link) { wl_list_for_each(output_cursor, &cur->state->output_cursors, link) {
double output_x = x; double output_x = lx, output_y = ly;
double output_y = y;
wlr_output_layout_output_coords(cur->state->layout, wlr_output_layout_output_coords(cur->state->layout,
output_cursor->output_cursor->output, &output_x, &output_y); output_cursor->output_cursor->output, &output_x, &output_y);
wlr_output_cursor_move(output_cursor->output_cursor, output_x, wlr_output_cursor_move(output_cursor->output_cursor,
output_y); output_x, output_y);
} }
cur->x = x; cur->x = lx;
cur->y = y; 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, 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); assert(cur->state->layout);
bool result = false; bool result = false;
struct wlr_box *mapping = get_mapping(cur, dev); struct wlr_box *mapping = get_mapping(cur, dev);
if (mapping) { if (mapping) {
if (wlr_box_contains_point(mapping, x, y)) { result = wlr_box_contains_point(mapping, lx, ly);
cursor_warp_unchecked(cur, x, y); } else {
result = true; result = wlr_output_layout_contains_point(cur->state->layout, NULL,
lx, ly);
} }
} else if (wlr_output_layout_contains_point(cur->state->layout, NULL,
x, y)) { if (result) {
cursor_warp_unchecked(cur, x, y); cursor_warp_unchecked(cur, lx, ly);
result = true;
} }
return result; return result;
} }
void wlr_cursor_warp_absolute(struct wlr_cursor *cur, static void cursor_warp_closest(struct wlr_cursor *cur,
struct wlr_input_device *dev, double x, double y) { 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); assert(cur->state->layout);
struct wlr_box *mapping = get_mapping(cur, dev); 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); mapping = wlr_output_layout_get_box(cur->state->layout, NULL);
} }
x = x >= 0 ? mapping->width * x + mapping->x : cur->x; *lx = !isnan(x) ? mapping->width * x + mapping->x : cur->x;
y = y >= 0 ? mapping->height * y + mapping->y : cur->y; *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, void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
double delta_x, double delta_y) { double delta_x, double delta_y) {
assert(cur->state->layout); assert(cur->state->layout);
double x = cur->x + delta_x; double lx = !isnan(delta_x) ? cur->x + delta_x : cur->x;
double y = cur->y + delta_y; double ly = !isnan(delta_y) ? cur->y + delta_y : cur->y;
struct wlr_box *mapping = get_mapping(cur, dev); cursor_warp_closest(cur, dev, lx, ly);
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);
} }
void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels, 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; 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;
}