/** * menu_init: * @data : Menu context handle. * * Create and initialize menu handle. * * Returns: menu handle on success, otherwise NULL. **/ void *menu_init(const void *data) { menu_handle_t *menu = NULL; menu_display_t *disp = NULL; menu_ctx_driver_t *menu_ctx = (menu_ctx_driver_t*)data; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu_ctx) return NULL; if (!(menu = (menu_handle_t*)menu_ctx->init())) return NULL; strlcpy(settings->menu.driver, menu_ctx->ident, sizeof(settings->menu.driver)); if (menu_init_entries(&menu->entries) != 0) goto error; global->core_info_current = (core_info_t*)calloc(1, sizeof(core_info_t)); if (!global->core_info_current) goto error; #ifdef HAVE_SHADER_MANAGER menu->shader = (struct video_shader*)calloc(1, sizeof(struct video_shader)); if (!menu->shader) goto error; #endif menu->push_start_screen = settings->menu_show_start_screen; settings->menu_show_start_screen = false; menu_shader_manager_init(menu); if (!menu_display_init(menu)) goto error; disp = &menu->display; rarch_assert(disp->msg_queue = msg_queue_new(8)); menu_display_fb_set_dirty(); menu_driver_set_alive(); return menu; error: if (menu->entries.menu_list) menu_list_free(menu->entries.menu_list); menu->entries.menu_list = NULL; if (global->core_info_current) free(global->core_info_current); global->core_info_current = NULL; if (menu->shader) free(menu->shader); menu->shader = NULL; if (menu) free(menu); return NULL; }
static menu_list_t *menu_list_new(void) { unsigned i; menu_list_t *list = (menu_list_t*)calloc(1, sizeof(*list)); if (!list) return NULL; list->menu_stack = (file_list_t**)calloc(1, sizeof(*list->menu_stack)); if (!list->menu_stack) goto error; list->selection_buf = (file_list_t**)calloc(1, sizeof(*list->selection_buf)); if (!list->selection_buf) goto error; list->menu_stack_size = 1; list->selection_buf_size = 1; for (i = 0; i < list->menu_stack_size; i++) list->menu_stack[i] = (file_list_t*)calloc(1, sizeof(*list->menu_stack[i])); for (i = 0; i < list->selection_buf_size; i++) list->selection_buf[i] = (file_list_t*)calloc(1, sizeof(*list->selection_buf[i])); return list; error: menu_list_free(list); return NULL; }
/** * menu_free_list: * @menu : Menu handle. * * Frees menu lists. **/ static void menu_free_list(menu_entries_t *entries) { if (!entries) return; menu_setting_free(entries->list_settings); entries->list_settings = NULL; menu_list_free(entries->menu_list); entries->menu_list = NULL; }
void menu_entries_free(void) { menu_entries_t *entries = menu_entries_get_ptr(); if (!entries) return; if (entries->list_settings) menu_setting_free(entries->list_settings); entries->list_settings = NULL; menu_list_free(entries->menu_list); entries->menu_list = NULL; }
/** * menu_free: * @menu : Menu handle. * * Frees a menu handle **/ void menu_free(menu_handle_t *menu) { global_t *global = global_get_ptr(); if (!menu) return; menu_free_list(menu); #ifdef HAVE_SHADER_MANAGER if (menu->shader) free(menu->shader); menu->shader = NULL; #endif menu_driver_free(menu); #ifdef HAVE_LIBRETRODB menu_database_free(menu); #endif #ifdef HAVE_DYNAMIC libretro_free_system_info(&global->menu.info); #endif if (menu->msg_queue) msg_queue_free(menu->msg_queue); menu->msg_queue = NULL; menu_display_free(menu); if (menu->frame_buf.data) free(menu->frame_buf.data); menu->frame_buf.data = NULL; menu_list_free(menu->menu_list); menu->menu_list = NULL; event_command(EVENT_CMD_HISTORY_DEINIT); if (global->core_info) core_info_list_free(global->core_info); if (global->core_info_current) free(global->core_info_current); free(menu); }
void menu_entries_free(void) { menu_entries_t *entries = menu_entries_data; if (!entries) return; if (entries->list_settings) menu_setting_free(entries->list_settings); entries->list_settings = NULL; menu_list_free(entries->menu_list); entries->menu_list = NULL; free(menu_entries_data); menu_entries_data = NULL; }
static menu_list_t *menu_list_new(void) { menu_list_t *list = (menu_list_t*)calloc(1, sizeof(*list)); if (!list) return NULL; list->menu_stack = (file_list_t*)calloc(1, sizeof(file_list_t)); list->selection_buf = (file_list_t*)calloc(1, sizeof(file_list_t)); if (!list->menu_stack || !list->selection_buf) goto error; return list; error: menu_list_free(list); return NULL; }
bool menu_entries_ctl(enum menu_entries_ctl_state state, void *data) { /* Flagged when menu entries need to be refreshed */ static bool menu_entries_need_refresh = false; static bool menu_entries_nonblocking_refresh = false; static size_t menu_entries_begin = 0; static rarch_setting_t *menu_entries_list_settings = NULL; static menu_list_t *menu_entries_list = NULL; switch (state) { case MENU_ENTRIES_CTL_DEINIT: menu_entries_ctl(MENU_ENTRIES_CTL_SETTINGS_DEINIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_LIST_DEINIT, NULL); menu_entries_need_refresh = false; menu_entries_nonblocking_refresh = false; menu_entries_begin = 0; break; case MENU_ENTRIES_CTL_NEEDS_REFRESH: if (menu_entries_nonblocking_refresh) return false; if (!menu_entries_need_refresh) return false; break; case MENU_ENTRIES_CTL_LIST_GET: { menu_list_t **list = (menu_list_t**)data; if (!list) return false; *list = menu_entries_list; } return true; case MENU_ENTRIES_CTL_LIST_DEINIT: if (menu_entries_list) menu_list_free(menu_entries_list); menu_entries_list = NULL; break; case MENU_ENTRIES_CTL_LIST_INIT: if (!(menu_entries_list = (menu_list_t*)menu_list_new())) return false; break; case MENU_ENTRIES_CTL_SETTINGS_GET: { rarch_setting_t **settings = (rarch_setting_t**)data; if (!settings) return false; *settings = menu_entries_list_settings; } break; case MENU_ENTRIES_CTL_SETTINGS_DEINIT: if (menu_entries_list_settings) menu_setting_ctl(MENU_SETTING_CTL_FREE, menu_entries_list_settings); menu_entries_list_settings = NULL; break; case MENU_ENTRIES_CTL_SETTINGS_INIT: menu_setting_ctl(MENU_SETTING_CTL_NEW, &menu_entries_list_settings); if (!menu_entries_list_settings) return false; break; case MENU_ENTRIES_CTL_SET_REFRESH: { bool *nonblocking = (bool*)data; if (*nonblocking) menu_entries_nonblocking_refresh = true; else menu_entries_need_refresh = true; } break; case MENU_ENTRIES_CTL_UNSET_REFRESH: { bool *nonblocking = (bool*)data; if (*nonblocking) menu_entries_nonblocking_refresh = false; else menu_entries_need_refresh = false; } break; case MENU_ENTRIES_CTL_SET_START: { size_t *idx = (size_t*)data; if (idx) menu_entries_begin = *idx; } case MENU_ENTRIES_CTL_START_GET: { size_t *idx = (size_t*)data; if (!idx) return 0; *idx = menu_entries_begin; } break; case MENU_ENTRIES_CTL_REFRESH: return menu_entries_refresh(data); case MENU_ENTRIES_CTL_CLEAR: return menu_entries_clear((file_list_t*)data); case MENU_ENTRIES_CTL_INIT: return menu_entries_init(); case MENU_ENTRIES_CTL_SHOW_BACK: /* Returns true if a Back button should be shown * (i.e. we are at least * one level deep in the menu hierarchy). */ return (menu_entries_get_stack_size(0) > 1); case MENU_ENTRIES_CTL_NONE: default: break; } return true; }
bool menu_entries_ctl(enum menu_entries_ctl_state state, void *data) { switch (state) { case MENU_ENTRIES_CTL_DEINIT: menu_entries_ctl(MENU_ENTRIES_CTL_SETTINGS_DEINIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_LIST_DEINIT, NULL); menu_entries_need_refresh = false; menu_entries_nonblocking_refresh = false; menu_entries_begin = 0; break; case MENU_ENTRIES_CTL_NEEDS_REFRESH: if (menu_entries_nonblocking_refresh) return false; if (!menu_entries_need_refresh) return false; break; case MENU_ENTRIES_CTL_LIST_GET: { menu_list_t **list = (menu_list_t**)data; if (!list) return false; *list = menu_entries_list; } return true; case MENU_ENTRIES_CTL_LIST_DEINIT: if (menu_entries_list) menu_list_free(menu_entries_list); menu_entries_list = NULL; break; case MENU_ENTRIES_CTL_LIST_INIT: if (!(menu_entries_list = (menu_list_t*)menu_list_new())) return false; break; case MENU_ENTRIES_CTL_SETTINGS_GET: { rarch_setting_t **settings = (rarch_setting_t**)data; if (!settings) return false; *settings = menu_entries_list_settings; } break; case MENU_ENTRIES_CTL_SETTINGS_DEINIT: menu_setting_free(menu_entries_list_settings); if (menu_entries_list_settings) free(menu_entries_list_settings); menu_entries_list_settings = NULL; break; case MENU_ENTRIES_CTL_SETTINGS_INIT: menu_setting_ctl(MENU_SETTING_CTL_NEW, &menu_entries_list_settings); if (!menu_entries_list_settings) return false; break; case MENU_ENTRIES_CTL_SET_REFRESH: { bool *nonblocking = (bool*)data; if (*nonblocking) menu_entries_nonblocking_refresh = true; else menu_entries_need_refresh = true; } break; case MENU_ENTRIES_CTL_UNSET_REFRESH: { bool *nonblocking = (bool*)data; if (*nonblocking) menu_entries_nonblocking_refresh = false; else menu_entries_need_refresh = false; } break; case MENU_ENTRIES_CTL_SET_START: { size_t *idx = (size_t*)data; if (idx) menu_entries_begin = *idx; } case MENU_ENTRIES_CTL_START_GET: { size_t *idx = (size_t*)data; if (!idx) return 0; *idx = menu_entries_begin; } break; case MENU_ENTRIES_CTL_REFRESH: if (!data) return false; return menu_entries_refresh((file_list_t*)data); case MENU_ENTRIES_CTL_CLEAR: { unsigned i; file_list_t *list = (file_list_t*)data; if (!list) return false; menu_driver_list_clear(list); for (i = 0; i < list->size; i++) file_list_free_actiondata(list, i); file_list_clear(list); } break; case MENU_ENTRIES_CTL_INIT: return menu_entries_init(); case MENU_ENTRIES_CTL_SHOW_BACK: /* Returns true if a Back button should be shown * (i.e. we are at least * one level deep in the menu hierarchy). */ if (!menu_entries_list) return false; return (menu_list_get_stack_size(menu_entries_list, 0) > 1); case MENU_ENTRIES_CTL_NONE: default: break; } return true; }