diff --git a/command.h b/command.h index 154b35b083..ceae119934 100644 --- a/command.h +++ b/command.h @@ -43,6 +43,8 @@ enum event_command { CMD_SPECIAL = -1, CMD_EVENT_NONE = 0, + /* Toggle Kiosk Mode*/ + CMD_EVENT_KIOSK, /* Resets RetroArch. */ CMD_EVENT_RESET, CMD_EVENT_SET_PER_GAME_RESOLUTION, @@ -456,6 +458,7 @@ static const struct cmd_map map[] = { { "MENU_TOGGLE", RARCH_MENU_TOGGLE }, { "QUIT", RARCH_QUIT_KEY }, { "CLOSE_CONTENT", RARCH_CLOSE_CONTENT_KEY }, + { "KIOSK_MODE", RARCH_KIOSK_MODE }, { "RESET", RARCH_RESET }, { "FAST_FORWARD", RARCH_FAST_FORWARD_KEY }, diff --git a/config.def.keybinds.h b/config.def.keybinds.h index e6190e0db8..8230e72f26 100644 --- a/config.def.keybinds.h +++ b/config.def.keybinds.h @@ -570,6 +570,13 @@ static const struct retro_keybind retro_keybinds_1[] = { RARCH_UI_COMPANION_TOGGLE, NO_BTN, NO_BTN, 0, true }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_KIOSK, RETROK_UNKNOWN, + RARCH_KIOSK_MODE, NO_BTN, NO_BTN, 0, + true + }, { NULL, NULL, AXIS_NONE, AXIS_NONE, @@ -1209,6 +1216,13 @@ static const struct retro_keybind retro_keybinds_1[] = { RARCH_UI_COMPANION_TOGGLE, NO_BTN, NO_BTN, 0, true }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_KIOSK, RETROK_UNKNOWN, + RARCH_KIOSK_MODE, NO_BTN, NO_BTN, 0, + true + }, { NULL, NULL, AXIS_NONE, AXIS_NONE, @@ -1858,6 +1872,13 @@ static const struct retro_keybind retro_keybinds_1[] = { RARCH_UI_COMPANION_TOGGLE, NO_BTN, NO_BTN, 0, true }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_KIOSK, RETROK_F5, + RARCH_KIOSK_MODE, NO_BTN, NO_BTN, 0, + true + }, { NULL, NULL, AXIS_NONE, AXIS_NONE, diff --git a/configuration.c b/configuration.c index 8b96508b90..c02d065364 100644 --- a/configuration.c +++ b/configuration.c @@ -345,6 +345,7 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = { DECLARE_META_BIND(2, exit_emulator, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY), #endif DECLARE_META_BIND(2, close_content, RARCH_CLOSE_CONTENT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_CLOSE_CONTENT_KEY), + DECLARE_META_BIND(2, kiosk_toggle, RARCH_KIOSK_MODE, MENU_ENUM_LABEL_VALUE_INPUT_META_KIOSK), DECLARE_META_BIND(2, reset, RARCH_RESET, MENU_ENUM_LABEL_VALUE_INPUT_META_RESET), DECLARE_META_BIND(1, toggle_fast_forward, RARCH_FAST_FORWARD_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY), DECLARE_META_BIND(2, hold_fast_forward, RARCH_FAST_FORWARD_HOLD_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY), diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c index 0d44ba14a5..097cd625f5 100644 --- a/gfx/common/win32_common.c +++ b/gfx/common/win32_common.c @@ -802,6 +802,8 @@ static LRESULT win32_menu_loop(HWND owner, WPARAM wparam) win32_load_content_from_gui(win32_file); } break; + case ID_M_KIOSK: + command_event(CMD_EVENT_KIOSK, NULL); case ID_M_RESET: command_event(CMD_EVENT_RESET, NULL); break; @@ -2028,6 +2030,8 @@ static enum msg_hash_enums menu_id_to_label_enum(unsigned int menuId) { case ID_M_LOAD_CONTENT: return MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST; + case ID_M_KIOSK: + return MENU_ENUM_LABEL_VALUE_INPUT_META_KIOSK; case ID_M_RESET: return MENU_ENUM_LABEL_VALUE_RESTART_CONTENT; case ID_M_QUIT: @@ -2068,6 +2072,8 @@ static unsigned int menu_id_to_meta_key(unsigned int menu_id) { switch (menu_id) { + case ID_M_KIOSK: + return RARCH_KIOSK_MODE; case ID_M_RESET: return RARCH_RESET; case ID_M_QUIT: diff --git a/input/input_defines.h b/input/input_defines.h index ea18b5e11a..95ddfbce70 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -126,6 +126,7 @@ enum RARCH_MENU_TOGGLE, RARCH_QUIT_KEY, RARCH_CLOSE_CONTENT_KEY, + RARCH_KIOSK_MODE, RARCH_RESET, RARCH_FAST_FORWARD_KEY, RARCH_FAST_FORWARD_HOLD_KEY, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 49449d9f65..9068ebe0a5 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -16111,6 +16111,14 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, "Use PAL60 Mode" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_KIOSK, + "Kiosk Mode (Toggle)" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_META_KIOSK, + "Toggles Kiosk Mode." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_RESTART_KEY, "Restart RetroArch" diff --git a/media/rarch.rc b/media/rarch.rc index 02867a4382..0583243ee5 100644 --- a/media/rarch.rc +++ b/media/rarch.rc @@ -47,6 +47,7 @@ IDR_MENU MENU MENUITEM "Load State", ID_M_LOAD_STATE MENUITEM "Save State", ID_M_SAVE_STATE } + MENUITEM "Kiosk", ID_M_KIOSK MENUITEM "Reset", ID_M_RESET MENUITEM "Pause Toggle", ID_M_PAUSE_TOGGLE MENUITEM "Menu Toggle", ID_M_MENU_TOGGLE diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 6376e05af2..790442336a 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -473,6 +473,10 @@ typedef struct xmb_handle /* Whether to show entry index for current list */ bool entry_idx_enabled; + + /* Kiosk Mode Fix - Makes sure we only call our function once after menu is ready */ + bool is_kiosk_init; + } xmb_handle_t; static float xmb_scale_mod[8] = { @@ -5856,10 +5860,17 @@ static enum menu_action xmb_parse_menu_entry_action( else { /* Jump to Main Menu */ + settings_t *settings = config_get_ptr(); size_t i = 0; size_t current_tab = xmb->categories_selection_ptr; - menu_entry_t entry; + + /* Kiosk Mode Fix - Only jump to Main Menu if not in Kiosk Mode!*/ + if(settings->bools.kiosk_mode_enable) + { + return MENU_ACTION_NOOP; + } + MENU_ENTRY_INITIALIZE(entry); menu_entry_get(&entry, 0, menu_st->selection_ptr, NULL, true); @@ -6437,6 +6448,7 @@ static bool xmb_context_reset_textures( const char *iconpath, unsigned menu_xmb_theme) { + settings_t *settings = config_get_ptr(); unsigned i; for (i = 0; i < XMB_TEXTURE_LAST; i++) @@ -6507,11 +6519,13 @@ static bool xmb_context_reset_textures( } } } - - xmb->main_menu_node.icon = xmb->textures.list[XMB_TEXTURE_MAIN_MENU]; - xmb->main_menu_node.alpha = xmb->categories_active_alpha; - xmb->main_menu_node.zoom = xmb->categories_active_zoom; - + /* Kiosk Mode Fix - Hide Main Menu Icon if kiosk mode is enabled */ + if (!settings->bools.kiosk_mode_enable) + { + xmb->main_menu_node.icon = xmb->textures.list[XMB_TEXTURE_MAIN_MENU]; + xmb->main_menu_node.alpha = xmb->categories_active_alpha; + xmb->main_menu_node.zoom = xmb->categories_active_zoom; + } xmb->settings_tab_node.icon = xmb->textures.list[XMB_TEXTURE_SETTINGS]; xmb->settings_tab_node.alpha = xmb->categories_active_alpha; xmb->settings_tab_node.zoom = xmb->categories_active_zoom; @@ -8718,7 +8732,10 @@ static void *xmb_init(void **userdata, bool video_is_threaded) xmb->depth = 1; xmb->old_depth = 1; xmb->alpha = 1.0f; - + + /* Kiosk Mode Fix */ + xmb->is_kiosk_init = false; + xmb_refresh_system_tabs_list(xmb); for (i = 0; i < XMB_TAB_MAX_LENGTH; i++) @@ -8787,6 +8804,45 @@ error: return NULL; } +/* Kiosk Mode Fix */ +static void xmb_kiosk_mode_fix(xmb_handle_t *xmb) +{ + settings_t *settings = config_get_ptr(); + if (settings->bools.kiosk_mode_enable) + { + /* Only jump if we have a Horizontal Menu ( if Play lists Tab is not empty ! ) */ + /* If we have no playlists on the playlists tab, disable Kiosk mode and reset !*/ + if((unsigned)xmb_list_get_size(xmb, MENU_LIST_HORIZONTAL) <= 0) + { + /* Disable Kiosk Mode ( Prevents Crash when kiosk mode enabled with no playlists ) */ + settings->bools.kiosk_mode_enable = false; + /* Re-Enable Main Menu Icon! */ + xmb->main_menu_node.icon = xmb->textures.list[XMB_TEXTURE_MAIN_MENU]; + xmb->main_menu_node.alpha = xmb->categories_active_alpha; + xmb->main_menu_node.zoom = xmb->categories_active_zoom; + /* Refresh list */ + xmb_refresh_system_tabs_list(xmb); + } + else + { + /* Jump one Categorie Right after init ( "hides" main menu ) */ + /* Only happens once on init */ + if (!xmb->is_kiosk_init) + { + struct menu_state *menu_st = menu_state_get_ptr(); + menu_list_t *menu_list = menu_st->entries.list; + + menu_entry_t entry; + MENU_ENTRY_INITIALIZE(entry); + menu_entry_get(&entry, 0, menu_st->selection_ptr, NULL, true); + + xmb_menu_entry_action(xmb, &entry, menu_st->selection_ptr, MENU_ACTION_RIGHT); + xmb->is_kiosk_init = true; + } + } + } +} + static void xmb_free(void *data) { xmb_handle_t *xmb = (xmb_handle_t*)data; @@ -9004,6 +9060,7 @@ static void xmb_list_cache(void *data, enum menu_list_type type, file_list_t *menu_stack = MENU_LIST_GET(menu_list, 0); file_list_t *selection_buf = MENU_LIST_GET_SELECTION(menu_list, 0); size_t selection = menu_st->selection_ptr; + settings_t *settings = config_get_ptr(); unsigned horizontal_list_size = (xmb->show_playlist_tabs) ? (unsigned)xmb_list_get_size(xmb, MENU_LIST_HORIZONTAL) : 0; @@ -9053,23 +9110,54 @@ static void xmb_list_cache(void *data, enum menu_list_type type, switch (action) { case MENU_ACTION_LEFT: - if (xmb->categories_selection_ptr == 0) + /* Kiosk Mode Fix - Only allow categorie movement between idx 1 and last instead of 0 ( skips main menu ) */ + if (settings->bools.kiosk_mode_enable) { - xmb->categories_selection_ptr = list_size; - xmb->categories_active_idx = (unsigned)(list_size - 1); + if (xmb->categories_selection_ptr == 1) + { + xmb->categories_selection_ptr = list_size; + xmb->categories_active_idx = (unsigned)(list_size - 1); + } + else + xmb->categories_selection_ptr--; + break; } else - xmb->categories_selection_ptr--; - break; + { + if (xmb->categories_selection_ptr == 0) + { + xmb->categories_selection_ptr = list_size; + xmb->categories_active_idx = (unsigned)(list_size - 1); + } + else + xmb->categories_selection_ptr--; + break; + } default: - if (xmb->categories_selection_ptr == list_size) + /* Kiosk Mode Fix - Only allow categorie movement between idx 1 and last instead of 0 ( skips main menu ) */ + if (settings->bools.kiosk_mode_enable) { - xmb->categories_selection_ptr = 0; - xmb->categories_active_idx = 1; + if (xmb->categories_selection_ptr == list_size) + { + xmb->categories_selection_ptr = 1; + xmb->categories_active_idx = 2; + } + else + xmb->categories_selection_ptr++; + break; } else - xmb->categories_selection_ptr++; - break; + { + if (xmb->categories_selection_ptr == list_size) + { + xmb->categories_selection_ptr = 0; + xmb->categories_active_idx = 1; + } + else + xmb->categories_selection_ptr++; + break; + } + } stack_size = menu_stack->size; @@ -9207,7 +9295,10 @@ static void xmb_toggle(void *userdata, bool menu_on) xmb_fade_out(xmb); return; } - + + /* Kiosk Mode Fix */ + xmb_kiosk_mode_fix(xmb); + /* Have to reset this, otherwise savestate * thumbnail won't update after selecting * 'save state' option */ diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index c89b86cc9c..0691596240 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -9578,8 +9578,8 @@ unsigned menu_displaylist_build_list( build_list[i].checked = settings->bools.settings_show_file_browser; break; case MENU_ENUM_LABEL_MENU_KIOSK_MODE_PASSWORD: - if (kiosk_mode_enable) - build_list[i].checked = true; + /* Kiosk Mode Fix - Always show Kiosk Password Settings Option */ + build_list[i].checked = true; break; case MENU_ENUM_LABEL_MENU_SCREENSAVER_TIMEOUT: if (menu_screensaver_supported) @@ -15407,6 +15407,20 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, #endif info->flags |= MD_FLAG_NEED_PUSH; + /* Kiosk Mode Fix - Add empty entry if list is empty */ + if(info->list->size <= 0 || settings->bools.kiosk_mode_enable) + { + menu_entries_clear(info->list); + menu_entries_append(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ITEMS), + msg_hash_to_str(MENU_ENUM_LABEL_NO_ITEMS), + MENU_ENUM_LABEL_NO_ITEMS, + MENU_SETTING_NO_ITEM, 0, 0, NULL); + + info->flags |= MD_FLAG_NEED_REFRESH + | MD_FLAG_NEED_PUSH; + break; + } } break; case DISPLAYLIST_HELP: diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 8758048ed1..666c2029d9 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -18591,7 +18591,8 @@ static bool setting_append_list( (*list)[list_info->index - 1].action_ok = setting_bool_action_left_with_refresh; (*list)[list_info->index - 1].action_left = setting_bool_action_left_with_refresh; (*list)[list_info->index - 1].action_right = setting_bool_action_right_with_refresh; - + MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_RESTART_RETROARCH);/* Kiosk Mode Fix - RESTART RETROARCH UPON SETTING KIOSK MODE!*/ + CONFIG_STRING( list, list_info, settings->paths.kiosk_mode_password, diff --git a/msg_hash.h b/msg_hash.h index 95b4b85a7a..8025fe4cd5 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1102,6 +1102,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, + MENU_ENUM_LABEL_VALUE_INPUT_META_KIOSK, MENU_ENUM_LABEL_VALUE_INPUT_META_RESTART_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_CLOSE_CONTENT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, @@ -1201,6 +1202,7 @@ enum msg_hash_enums MENU_ENUM_SUBLABEL_INPUT_META_ENABLE_HOTKEY, MENU_ENUM_SUBLABEL_INPUT_META_MENU_TOGGLE, MENU_ENUM_SUBLABEL_INPUT_META_QUIT_KEY, + MENU_ENUM_SUBLABEL_INPUT_META_KIOSK, MENU_ENUM_SUBLABEL_INPUT_META_RESTART_KEY, MENU_ENUM_SUBLABEL_INPUT_META_CLOSE_CONTENT_KEY, MENU_ENUM_SUBLABEL_INPUT_META_RESET, diff --git a/retroarch.c b/retroarch.c index 6af2e0fd13..be3b2a9e83 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2989,6 +2989,38 @@ bool is_accessibility_enabled(bool accessibility_enable, bool accessibility_enab } #endif + +/* Kiosk Mode Fix - Confirm User Input - slighlty modified menu_input_st_string_cb_disable_kiosk_mode function from menu_cbs_ok.c */ +static void kiosk_password_input_complete(void *userdata, const char *line) +{ + if (line && *line) + { + const char *label = menu_input_dialog_get_buffer(); + settings_t *settings = config_get_ptr(); + const char *path_kiosk_mode_password = + settings->paths.kiosk_mode_password; + + if (string_is_equal(label, path_kiosk_mode_password)) + { + const char *_msg = msg_hash_to_str(MSG_INPUT_KIOSK_MODE_PASSWORD_OK); + runloop_msg_queue_push(_msg, strlen(_msg), 1, 100, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + /* Disable Kiosk Mode and Restart RetroArch! */ + settings->bools.kiosk_mode_enable = false; + command_event(CMD_EVENT_RESTART_RETROARCH, NULL); + } + else + { + const char *_msg = msg_hash_to_str(MSG_INPUT_KIOSK_MODE_PASSWORD_NOK); + runloop_msg_queue_push(_msg, strlen(_msg), 1, 100, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + } + } + + menu_input_dialog_end(); +} + + /** * command_event: * @cmd : Event command index. @@ -3434,6 +3466,24 @@ bool command_event(enum event_command cmd, void *data) retroarch_menu_running(); #endif break; + /* Kiosk Mode Fix */ + case CMD_EVENT_KIOSK: + /* If were already in Kiosk Mode, ask for the Password! */ + if (settings->bools.kiosk_mode_enable && !string_is_empty(settings->paths.kiosk_mode_password)) + { + menu_input_ctx_line_t line; + line.label = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_MENU_KIOSK_MODE_PASSWORD); + line.label_setting = NULL; + line.type = 0; + line.idx = 0; + line.cb = kiosk_password_input_complete; + menu_input_dialog_start(&line); + break; + } + /* Toggle Kiosk mode then Restart Retroarch */ + settings->bools.kiosk_mode_enable = !(settings->bools.kiosk_mode_enable); + command_event(CMD_EVENT_RESTART_RETROARCH, NULL); + break; case CMD_EVENT_RESET: { const char *_msg = msg_hash_to_str(MSG_RESET); diff --git a/runloop.c b/runloop.c index 19bb1b73f7..eb7fe13d46 100644 --- a/runloop.c +++ b/runloop.c @@ -6118,6 +6118,9 @@ static enum runloop_state_enum runloop_check_state( /* Check close content hotkey */ HOTKEY_CHECK(RARCH_CLOSE_CONTENT_KEY, CMD_EVENT_CLOSE_CONTENT, true, NULL); + /* Check Kiosk hotkey */ + HOTKEY_CHECK(RARCH_KIOSK_MODE, CMD_EVENT_KIOSK, true, NULL); + /* Check FPS hotkey */ HOTKEY_CHECK(RARCH_FPS_TOGGLE, CMD_EVENT_FPS_TOGGLE, true, NULL); diff --git a/tests-other/all_binds_empty.cfg b/tests-other/all_binds_empty.cfg index 51fe9f76d1..ef5a090872 100644 --- a/tests-other/all_binds_empty.cfg +++ b/tests-other/all_binds_empty.cfg @@ -6,6 +6,7 @@ input_exit_emulator = "escape" input_max_users = "10" input_fps_toggle = "f3" +input_kiosk_toggle = "f5" input_ai_service = "nul" input_ai_service_axis = "nul" diff --git a/ui/drivers/ui_win32_resource.h b/ui/drivers/ui_win32_resource.h index 1baed7a134..5aa2f21c86 100644 --- a/ui/drivers/ui_win32_resource.h +++ b/ui/drivers/ui_win32_resource.h @@ -40,3 +40,4 @@ #define ID_M_TAKE_SCREENSHOT 40035 #define ID_M_MUTE_TOGGLE 40036 #define ID_M_TOGGLE_DESKTOP 40037 +#define ID_M_KIOSK 40038