[Concept,07/14] expo: Store mouse pointer and size in expo

Message ID 20251006165452.1675349-8-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>

Store the mouse pointer image and its dimensions in the expo structure
when mouse support is enabled. This avoids repeatedly looking up the
image and calculating its size.

Use struct vid_size to store the mouse pointer dimensions.

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

 boot/cedit.c   | 12 +++++++++---
 boot/expo.c    | 23 ++++++++++++++++++++++-
 cmd/bootflow.c | 12 ++++++++++--
 include/expo.h | 25 +++++++++++++++++++++++++
 4 files changed, 66 insertions(+), 6 deletions(-)
  

Patch

diff --git a/boot/cedit.c b/boot/cedit.c
index ad2c98aa7a5..691780512ca 100644
--- a/boot/cedit.c
+++ b/boot/cedit.c
@@ -245,20 +245,26 @@  int cedit_run(struct expo *exp)
 
 	expo_set_mouse_enable(exp, true);
 
+	expo_enter_mode(exp);
+
 	exp->done = false;
 	exp->save = false;
 	do {
 		struct expo_action act;
 
 		ret = expo_render(exp);
-		if (ret)
+		if (ret) {
+			expo_exit_mode(exp);
 			return log_msg_ret("cer", ret);
+		}
 
 		ret = expo_poll(exp, &act);
-		if (!ret)
+		if (!ret) {
 			cedit_do_action(exp, scn, vid_priv, &act);
-		else if (ret != -EAGAIN)
+		} else if (ret != -EAGAIN) {
+			expo_exit_mode(exp);
 			return log_msg_ret("cep", ret);
+		}
 	} while (!exp->done);
 
 	if (ret)
diff --git a/boot/expo.c b/boot/expo.c
index b5c54291220..42109b88e72 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -168,7 +168,7 @@  int expo_set_mouse_enable(struct expo *exp, bool enable)
 {
 	int ret;
 
-	if (!enable) {
+	if (!IS_ENABLED(CONFIG_MOUSE) || !enable) {
 		exp->mouse_enabled = false;
 		return 0;
 	}
@@ -177,6 +177,17 @@  int expo_set_mouse_enable(struct expo *exp, bool enable)
 	if (ret)
 		return log_msg_ret("sme", ret);
 
+	/* Get mouse pointer image and dimensions */
+	exp->mouse_ptr = video_image_getptr(riscos_arrow);
+	if (exp->mouse_ptr) {
+		ulong width, height;
+		uint bpix;
+
+		video_bmp_get_info(exp->mouse_ptr, &width, &height, &bpix);
+		exp->mouse_size.w = width;
+		exp->mouse_size.h = height;
+	}
+
 	exp->mouse_enabled = true;
 
 	return 0;
@@ -456,3 +467,13 @@  void expo_req_size(struct expo *exp, int width, int height)
 	exp->req_width = width;
 	exp->req_height = height;
 }
+
+void expo_enter_mode(struct expo *exp)
+{
+	video_manual_sync(exp->display, true);
+}
+
+void expo_exit_mode(struct expo *exp)
+{
+	video_manual_sync(exp->display, false);
+}
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index c9f36a364dd..caff52fcc7c 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -55,19 +55,27 @@  __maybe_unused static int bootflow_handle_menu(struct bootstd_priv *std,
 	if (ret)
 		return log_msg_ret("bhs", ret);
 
+	expo_enter_mode(exp);
+
 	ret = -ERESTART;
 	do {
 		if (ret == -ERESTART) {
 			ret = expo_arrange(exp);
-			if (ret)
+			if (ret) {
+				expo_exit_mode(exp);
 				return log_msg_ret("bha", ret);
+			}
 			ret = expo_render(exp);
-			if (ret)
+			if (ret) {
+				expo_exit_mode(exp);
 				return log_msg_ret("bhr", ret);
+			}
 		}
 		ret = bootflow_menu_poll(exp, &seq);
 	} while (ret == -EAGAIN || ret == -ERESTART || ret == -EREMCHG);
 
+	expo_exit_mode(exp);
+
 	if (ret == -EPIPE) {
 		printf("Nothing chosen\n");
 		std->cur_bootflow = NULL;
diff --git a/include/expo.h b/include/expo.h
index e359da1343b..3250ecee40e 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -9,6 +9,7 @@ 
 
 #include <abuf.h>
 #include <alist.h>
+#include <video_defs.h>
 #include <dm/ofnode_decl.h>
 #include <linux/bitops.h>
 #include <linux/list.h>
@@ -131,6 +132,8 @@  struct expo_theme {
  * @popup: true to use popup menus, instead of showing all items
  * @show_highlight: show a highlight bar on the selected menu item
  * @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)
  * @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
@@ -153,6 +156,8 @@  struct expo {
 	bool popup;
 	bool show_highlight;
 	bool mouse_enabled;
+	const void *mouse_ptr;
+	struct vid_size mouse_size;
 	void *priv;
 	bool done;
 	bool save;
@@ -1185,4 +1190,24 @@  int expo_poll(struct expo *exp, struct expo_action *act);
  */
 void expo_req_size(struct expo *exp, int width, int height);
 
+/**
+ * expo_enter_mode() - Enter expo mode for the video subsystem
+ *
+ * @exp: Expo to update
+ *
+ * This suppresses automatic video sync operations to allow expo to control
+ * rendering timing. Should be called before starting the expo loop.
+ */
+void expo_enter_mode(struct expo *exp);
+
+/**
+ * expo_exit_mode() - Exit expo mode for the video subsystem
+ *
+ * @exp: Expo to update
+ *
+ * This restores normal video sync operations. Should be called after
+ * finishing the expo loop.
+ */
+void expo_exit_mode(struct expo *exp);
+
 #endif /*__EXPO_H */