[Concept,08/14] expo: Show the mouse when enabled

Message ID 20251006165452.1675349-9-sjg@u-boot.org
State New
Headers
Series expo: Continue development of expo with mouse |

Commit Message

Simon Glass Oct. 6, 2025, 4:54 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

When the mouse is enabled, show it at its new position each time the
expo is rendered.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 boot/expo.c    | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/expo.h |  2 ++
 2 files changed, 61 insertions(+)
  

Patch

diff --git a/boot/expo.c b/boot/expo.c
index 42109b88e72..295b779dce8 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -12,6 +12,7 @@ 
 #include <expo.h>
 #include <log.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <menu.h>
 #include <mouse.h>
 #include <video.h>
@@ -249,6 +250,56 @@  int expo_arrange(struct expo *exp)
 	return 0;
 }
 
+static int update_mouse_position(struct expo *exp)
+{
+	struct mouse_event event;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_MOUSE) || !exp->mouse_enabled)
+		return 0;
+
+	/* Process all available mouse events to get latest position */
+	while (1) {
+		ret = mouse_get_event(exp->mouse, &event);
+		if (ret)
+			break; /* No more events available */
+
+		if (event.type == MOUSE_EV_MOTION) {
+			exp->mouse_pos.x = event.motion.x;
+			exp->mouse_pos.y = event.motion.y;
+		} else if (event.type == MOUSE_EV_BUTTON) {
+			exp->mouse_pos.x = event.button.x;
+			exp->mouse_pos.y = event.button.y;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * render_mouse_pointer() - Render the mouse pointer if enabled and visible
+ *
+ * @exp: Expo containing mouse state
+ * Return: 0 if OK, -ve on error
+ */
+static int render_mouse_pointer(struct expo *exp)
+{
+	struct udevice *dev = exp->display;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_MOUSE) || !exp->mouse_enabled || !exp->mouse_ptr)
+		return 0;
+
+	/* Use white (0xffffff) as transparent color */
+	ret = video_bmp_displaya(dev, map_to_sysmem(exp->mouse_ptr),
+				 exp->mouse_pos.x, exp->mouse_pos.y, false, true,
+				 0xffffff);
+	if (ret)
+		log_debug("Failed to display mouse pointer: %d\n", ret);
+
+	return 0;
+}
+
 int expo_render(struct expo *exp)
 {
 	struct udevice *dev = exp->display;
@@ -274,6 +325,11 @@  int expo_render(struct expo *exp)
 			return log_msg_ret("ren", ret);
 	}
 
+	/* Render mouse pointer if mouse is enabled */
+	ret = render_mouse_pointer(exp);
+	if (ret)
+		return log_msg_ret("mou", ret);
+
 	video_sync(dev, true);
 
 	return scn ? 0 : -ECHILD;
@@ -441,6 +497,9 @@  int expo_poll(struct expo *exp, struct expo_action *act)
 {
 	int key, ret = -EAGAIN;
 
+	/* update mouse position if mouse is enabled */
+	update_mouse_position(exp);
+
 	key = poll_keys(exp);
 	if (key != -EAGAIN) {
 		ret = expo_send_key(exp, key);
diff --git a/include/expo.h b/include/expo.h
index 3250ecee40e..622088f395b 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -134,6 +134,7 @@  struct expo_theme {
  * @mouse_enabled: true if the mouse is enabled
  * @mouse_ptr: Pointer to mouse pointer image data (BMP format)
  * @mouse_size: Size of mouse pointer (width and height in pixels)
+ * @mouse_pos: Current mouse position
  * @priv: Private data for the controller
  * @done: Indicates that a cedit session is complete and the user has quit
  * @save: Indicates that cedit data should be saved, rather than discarded
@@ -158,6 +159,7 @@  struct expo {
 	bool mouse_enabled;
 	const void *mouse_ptr;
 	struct vid_size mouse_size;
+	struct vid_pos mouse_pos;
 	void *priv;
 	bool done;
 	bool save;