From 6e7c0b57f6b601a8c6883f71d00719dbd208c79d Mon Sep 17 00:00:00 2001
From: emersion <contact@emersion.fr>
Date: Fri, 27 Apr 2018 17:26:33 +0100
Subject: 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 <assert.h>
 #include <limits.h>
+#include <math.h>
 #include <stdlib.h>
 #include <wayland-server.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,
-		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;
 
+	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;
-
-	struct wlr_box *mapping = get_mapping(cur, dev);
+	double lx = !isnan(delta_x) ? cur->x + delta_x : cur->x;
+	double ly = !isnan(delta_y) ? cur->y + delta_y : cur->y;
 
-	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;
-}
-- 
cgit v1.2.3