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 #include +#include #include #include #include @@ -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 */