From ecf91524a956f773881d564c4ada833f844264ca Mon Sep 17 00:00:00 2001 From: RogueMaster Date: Sat, 13 May 2023 19:55:41 -0400 Subject: [PATCH] Initial CFW Settings Frontend By Willy-JL --- ReadMe.md | 1 + applications/main/cfw_app/application.fam | 16 + applications/main/cfw_app/cfw_app.c | 316 ++++++++++++++++++ applications/main/cfw_app/cfw_app.h | 75 +++++ applications/main/cfw_app/cfw_app_10px.png | Bin 0 -> 525 bytes .../main/cfw_app/scenes/cfw_app_scene.c | 30 ++ .../main/cfw_app/scenes/cfw_app_scene.h | 29 ++ .../cfw_app/scenes/cfw_app_scene_config.h | 15 + .../cfw_app/scenes/cfw_app_scene_interface.c | 69 ++++ .../scenes/cfw_app_scene_interface_common.c | 121 +++++++ .../scenes/cfw_app_scene_interface_graphics.c | 171 ++++++++++ .../cfw_app_scene_interface_lockscreen.c | 152 +++++++++ .../scenes/cfw_app_scene_interface_mainmenu.c | 106 ++++++ .../cfw_app_scene_interface_mainmenu_add.c | 67 ++++ .../cfw_app_scene_interface_statusbar.c | 121 +++++++ .../main/cfw_app/scenes/cfw_app_scene_misc.c | 150 +++++++++ .../scenes/cfw_app_scene_misc_rename.c | 72 ++++ .../cfw_app/scenes/cfw_app_scene_protocols.c | 92 +++++ .../cfw_app_scene_protocols_frequencies.c | 76 +++++ .../cfw_app_scene_protocols_frequencies_add.c | 83 +++++ ...w_app_scene_protocols_frequencies_hopper.c | 104 ++++++ ...w_app_scene_protocols_frequencies_static.c | 104 ++++++ .../main/cfw_app/scenes/cfw_app_scene_start.c | 71 ++++ applications/main/lfrfid/application.fam | 2 +- firmware/targets/f7/api_symbols.csv | 5 + firmware/targets/f7/furi_hal/furi_hal_light.c | 1 + .../targets/f7/furi_hal/furi_hal_subghz.c | 35 +- .../targets/f7/furi_hal/furi_hal_subghz.h | 12 + furi/flipper.c | 5 + lib/SConscript | 1 + lib/cfw/assets.c | 166 +++++++++ lib/cfw/cfw.h | 78 +++++ lib/cfw/namespoof.c | 27 ++ lib/cfw/namespoof.h | 5 + lib/cfw/private.h | 5 + lib/cfw/settings.c | 130 +++++++ lib/misc.scons | 2 + 37 files changed, 2512 insertions(+), 3 deletions(-) create mode 100644 applications/main/cfw_app/application.fam create mode 100644 applications/main/cfw_app/cfw_app.c create mode 100644 applications/main/cfw_app/cfw_app.h create mode 100644 applications/main/cfw_app/cfw_app_10px.png create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene.h create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_config.h create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_interface.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_interface_common.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_interface_graphics.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_interface_lockscreen.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_interface_mainmenu.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_interface_mainmenu_add.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_interface_statusbar.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_misc.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_misc_rename.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_protocols.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_add.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_hopper.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_static.c create mode 100644 applications/main/cfw_app/scenes/cfw_app_scene_start.c create mode 100644 lib/cfw/assets.c create mode 100644 lib/cfw/cfw.h create mode 100644 lib/cfw/namespoof.c create mode 100644 lib/cfw/namespoof.h create mode 100644 lib/cfw/private.h create mode 100644 lib/cfw/settings.c diff --git a/ReadMe.md b/ReadMe.md index 918504c86b6..469ac77b2da 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -45,6 +45,7 @@ This software is for experimental purposes only and is not meant for any illegal - [NFCV + SLIX Protocol Updates (By g3gg0)](https://github.com/flipperdevices/flipperzero-firmware/pull/2316) - UL PR: [SubGhz some improvements #465 (By gid9798)](https://github.com/DarkFlippers/unleashed-firmware/pull/465) - UL PR: [SubGHz: Notifications refines #464 (By wosk)](https://github.com/DarkFlippers/unleashed-firmware/pull/464) +- Added: [CFW Settings - Imported/Modified By RogueMaster (By Willy-JL)] WIP diff --git a/applications/main/cfw_app/application.fam b/applications/main/cfw_app/application.fam new file mode 100644 index 00000000000..b3cb45b31f6 --- /dev/null +++ b/applications/main/cfw_app/application.fam @@ -0,0 +1,16 @@ +App( + appid="CFW", + name="CFW Settings", + apptype=FlipperAppType.EXTERNAL, + entry_point="cfw_app", + requires=[ + "gui", + "dolphin", + ], + stack_size=2 * 1024, + # icon="A_CFW_14", + order=90, + fap_libs=["assets"], + fap_category="Settings", + fap_icon="cfw_app_10px.png", +) diff --git a/applications/main/cfw_app/cfw_app.c b/applications/main/cfw_app/cfw_app.c new file mode 100644 index 00000000000..ff9a535edf9 --- /dev/null +++ b/applications/main/cfw_app/cfw_app.c @@ -0,0 +1,316 @@ +#include "cfw_app.h" + +static bool cfw_app_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + CfwApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +void callback_reboot(void* context) { + UNUSED(context); + power_reboot(PowerBootModeNormal); +} + +bool cfw_app_apply(CfwApp* app) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + if(app->save_mainmenu_apps) { + Stream* stream = file_stream_alloc(storage); + if(file_stream_open(stream, CFW_APPS_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)) { + CharList_it_t it; + CharList_it(it, app->mainmenu_app_paths); + for(uint i = 0; i < CharList_size(app->mainmenu_app_paths); i++) { + stream_write_format(stream, "%s\n", *CharList_get(app->mainmenu_app_paths, i)); + } + } + file_stream_close(stream); + stream_free(stream); + } + + if(app->save_subghz_frequencies) { + FlipperFormat* file = flipper_format_file_alloc(storage); + do { + FrequencyList_it_t it; + if(!flipper_format_file_open_always(file, EXT_PATH("subghz/assets/setting_user.txt"))) + break; + + if(!flipper_format_write_header_cstr( + file, SUBGHZ_SETTING_FILE_TYPE, SUBGHZ_SETTING_FILE_VERSION)) + break; + + while(flipper_format_delete_key(file, "Add_standard_frequencies")) + ; + flipper_format_write_bool( + file, "Add_standard_frequencies", &app->subghz_use_defaults, 1); + + if(!flipper_format_rewind(file)) break; + while(flipper_format_delete_key(file, "Frequency")) + ; + FrequencyList_it(it, app->subghz_static_freqs); + for(uint i = 0; i < FrequencyList_size(app->subghz_static_freqs); i++) { + flipper_format_write_uint32( + file, "Frequency", FrequencyList_get(app->subghz_static_freqs, i), 1); + } + + if(!flipper_format_rewind(file)) break; + while(flipper_format_delete_key(file, "Hopper_frequency")) + ; + for(uint i = 0; i < FrequencyList_size(app->subghz_hopper_freqs); i++) { + flipper_format_write_uint32( + file, "Hopper_frequency", FrequencyList_get(app->subghz_hopper_freqs, i), 1); + } + } while(false); + flipper_format_free(file); + } + + if(app->save_subghz) { + furi_hal_subghz_set_is_extended(app->subghz_extend); + } + + if(app->save_name) { + if(strcmp(app->device_name, "") == 0) { + storage_simply_remove(storage, NAMESPOOF_PATH); + } else { + FlipperFormat* file = flipper_format_file_alloc(storage); + + do { + if(!flipper_format_file_open_always(file, NAMESPOOF_PATH)) break; + if(!flipper_format_write_header_cstr(file, NAMESPOOF_HEADER, NAMESPOOF_VERSION)) + break; + if(!flipper_format_write_string_cstr(file, "Name", app->device_name)) break; + } while(0); + + flipper_format_free(file); + } + } + + // if(app->save_level) { + // Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); + // int32_t xp = app->xp_level > 1 ? dolphin_get_levels()[app->xp_level - 2] : 0; + // dolphin->state->data.icounter = xp + 1; + // dolphin->state->dirty = true; + // dolphin_state_save(dolphin->state); + // furi_record_close(RECORD_DOLPHIN); + // } + + if(app->save_backlight) { + rgb_backlight_save_settings(); + } + + if(app->save_settings) { + CFW_SETTINGS_SAVE(); + } + + // if(app->show_slideshow) { + // callback_reboot(NULL); + // } + + if(app->require_reboot) { + popup_set_header(app->popup, "Rebooting...", 64, 26, AlignCenter, AlignCenter); + popup_set_text(app->popup, "Applying changes...", 64, 40, AlignCenter, AlignCenter); + popup_set_callback(app->popup, callback_reboot); + popup_set_context(app->popup, app); + popup_set_timeout(app->popup, 1000); + popup_enable_timeout(app->popup); + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewPopup); + return true; + } + + furi_record_close(RECORD_STORAGE); + return false; +} + +static bool cfw_app_back_event_callback(void* context) { + furi_assert(context); + CfwApp* app = context; + + if(!scene_manager_has_previous_scene(app->scene_manager, CfwAppSceneStart)) { + if(cfw_app_apply(app)) { + return true; + } + } + + return scene_manager_handle_back_event(app->scene_manager); +} + +CfwApp* cfw_app_alloc() { + CfwApp* app = malloc(sizeof(CfwApp)); + app->gui = furi_record_open(RECORD_GUI); + app->dialogs = furi_record_open(RECORD_DIALOGS); + app->notification = furi_record_open(RECORD_NOTIFICATION); + + // View Dispatcher and Scene Manager + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&cfw_app_scene_handlers, app); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + + view_dispatcher_set_custom_event_callback( + app->view_dispatcher, cfw_app_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, cfw_app_back_event_callback); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + // Gui Modules + app->var_item_list = variable_item_list_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + CfwAppViewVarItemList, + variable_item_list_get_view(app->var_item_list)); + + app->text_input = text_input_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, CfwAppViewTextInput, text_input_get_view(app->text_input)); + + app->popup = popup_alloc(); + view_dispatcher_add_view(app->view_dispatcher, CfwAppViewPopup, popup_get_view(app->popup)); + + // Settings init + + CfwSettings* cfw_settings = CFW_SETTINGS(); + + // app->asset_pack_index = 0; + // CharList_init(app->asset_pack_names); + Storage* storage = furi_record_open(RECORD_STORAGE); + // File* folder = storage_file_alloc(storage); + // FileInfo info; + // char* name = malloc(CFW_ASSETS_PACK_NAME_LEN); + // if(storage_dir_open(folder, CFW_ASSETS_PATH)) { + // while(storage_dir_read(folder, &info, name, CFW_ASSETS_PACK_NAME_LEN)) { + // if(info.flags & FSF_DIRECTORY) { + // char* copy = malloc(CFW_ASSETS_PACK_NAME_LEN); + // strlcpy(copy, name, CFW_ASSETS_PACK_NAME_LEN); + // uint idx = 0; + // if(strcmp(copy, "NSFW") != 0) { + // for(; idx < CharList_size(app->asset_pack_names); idx++) { + // char* comp = *CharList_get(app->asset_pack_names, idx); + // if(strcasecmp(copy, comp) < 0 && strcmp(comp, "NSFW") != 0) { + // break; + // } + // } + // } + // CharList_push_at(app->asset_pack_names, idx, copy); + // if(app->asset_pack_index != 0) { + // if(idx < app->asset_pack_index) app->asset_pack_index++; + // } else { + // if(strcmp(copy, CFW_settings->asset_pack) == 0) + // app->asset_pack_index = idx + 1; + // } + // } + // } + // } + // free(name); + // storage_file_free(folder); + + CharList_init(app->mainmenu_app_names); + CharList_init(app->mainmenu_app_paths); + Stream* stream = file_stream_alloc(storage); + FuriString* line = furi_string_alloc(); + if(file_stream_open(stream, CFW_APPS_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { + while(stream_read_line(stream, line)) { + furi_string_replace_all(line, "\r", ""); + furi_string_replace_all(line, "\n", ""); + CharList_push_back(app->mainmenu_app_paths, strdup(furi_string_get_cstr(line))); + fap_loader_load_name_and_icon(line, storage, NULL, line); + CharList_push_back(app->mainmenu_app_names, strdup(furi_string_get_cstr(line))); + } + } + furi_string_free(line); + file_stream_close(stream); + stream_free(stream); + + FlipperFormat* file = flipper_format_file_alloc(storage); + FrequencyList_init(app->subghz_static_freqs); + FrequencyList_init(app->subghz_hopper_freqs); + app->subghz_use_defaults = true; + do { + uint32_t temp; + if(!flipper_format_file_open_existing(file, EXT_PATH("subghz/assets/setting_user.txt"))) break; + + flipper_format_read_bool(file, "Add_standard_frequencies", &app->subghz_use_defaults, 1); + + if(!flipper_format_rewind(file)) break; + while(flipper_format_read_uint32(file, "Frequency", &temp, 1)) { + if(furi_hal_subghz_is_frequency_valid(temp)) { + FrequencyList_push_back(app->subghz_static_freqs, temp); + } + } + + if(!flipper_format_rewind(file)) break; + while(flipper_format_read_uint32(file, "Hopper_frequency", &temp, 1)) { + if(furi_hal_subghz_is_frequency_valid(temp)) { + FrequencyList_push_back(app->subghz_hopper_freqs, temp); + } + } + } while(false); + flipper_format_free(file); + furi_record_close(RECORD_STORAGE); + + app->subghz_extend = furi_hal_subghz_get_is_extended(); + + strlcpy(app->device_name, furi_hal_version_get_name_ptr(), FURI_HAL_VERSION_ARRAY_NAME_LENGTH); + + // Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); + // DolphinStats stats = dolphin_stats(dolphin); + // app->xp_level = stats.level; + // furi_record_close(RECORD_DOLPHIN); + + app->version_tag = + furi_string_alloc_printf("%s %s", version_get_version(NULL), version_get_builddate(NULL)); + + return app; +} + +void cfw_app_free(CfwApp* app) { + furi_assert(app); + + // Gui modules + view_dispatcher_remove_view(app->view_dispatcher, CfwAppViewVarItemList); + variable_item_list_free(app->var_item_list); + view_dispatcher_remove_view(app->view_dispatcher, CfwAppViewTextInput); + text_input_free(app->text_input); + view_dispatcher_remove_view(app->view_dispatcher, CfwAppViewPopup); + popup_free(app->popup); + + // View Dispatcher and Scene Manager + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + + // Settings deinit + + CharList_it_t it; + // for(CharList_it(it, app->asset_pack_names); !CharList_end_p(it); CharList_next(it)) { + // free(*CharList_cref(it)); + // } + // CharList_clear(app->asset_pack_names); + + for(CharList_it(it, app->mainmenu_app_names); !CharList_end_p(it); CharList_next(it)) { + free(*CharList_cref(it)); + } + CharList_clear(app->mainmenu_app_names); + for(CharList_it(it, app->mainmenu_app_paths); !CharList_end_p(it); CharList_next(it)) { + free(*CharList_cref(it)); + } + CharList_clear(app->mainmenu_app_paths); + + FrequencyList_clear(app->subghz_static_freqs); + FrequencyList_clear(app->subghz_hopper_freqs); + + furi_string_free(app->version_tag); + + // Records + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_DIALOGS); + furi_record_close(RECORD_GUI); + free(app); +} + +extern int32_t cfw_app(void* p) { + UNUSED(p); + CfwApp* app = cfw_app_alloc(); + scene_manager_next_scene(app->scene_manager, CfwAppSceneStart); + view_dispatcher_run(app->view_dispatcher); + cfw_app_free(app); + return 0; +} diff --git a/applications/main/cfw_app/cfw_app.h b/applications/main/cfw_app/cfw_app.h new file mode 100644 index 00000000000..eb9b0da26e8 --- /dev/null +++ b/applications/main/cfw_app/cfw_app.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scenes/cfw_app_scene.h" +#include "dolphin/helpers/dolphin_state.h" +#include "dolphin/dolphin.h" +#include "dolphin/dolphin_i.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#define CFW_SUBGHZ_FREQ_BUFFER_SIZE 6 + +ARRAY_DEF(CharList, char*) + +typedef struct { + Gui* gui; + DialogsApp* dialogs; + NotificationApp* notification; + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + VariableItemList* var_item_list; + TextInput* text_input; + Popup* popup; + + // CharList_t asset_pack_names; + // uint8_t asset_pack_index; + CharList_t mainmenu_app_names; + CharList_t mainmenu_app_paths; + uint8_t mainmenu_app_index; + bool subghz_use_defaults; + FrequencyList_t subghz_static_freqs; + uint8_t subghz_static_index; + FrequencyList_t subghz_hopper_freqs; + uint8_t subghz_hopper_index; + char subghz_freq_buffer[CFW_SUBGHZ_FREQ_BUFFER_SIZE]; + bool subghz_extend; + char device_name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH]; + // int32_t xp_level; + FuriString* version_tag; + + bool save_mainmenu_apps; + bool save_subghz_frequencies; + bool save_subghz; + bool save_name; + // bool save_level; + bool save_backlight; + bool save_settings; + // bool show_slideshow; + bool require_reboot; +} CfwApp; + +typedef enum { + CfwAppViewVarItemList, + CfwAppViewTextInput, + CfwAppViewPopup, +} CfwAppView; + +bool cfw_app_apply(CfwApp* app); diff --git a/applications/main/cfw_app/cfw_app_10px.png b/applications/main/cfw_app/cfw_app_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..77c1ceb841d8925d4e7c93de540ae0ed0c9dec43 GIT binary patch literal 525 zcmV+o0`mQdP)4Tx04UFukxeK>Q5?m8Geab@Fhy9rgcTbkONNr7ra{eM;k`FzOwD_y_eM6B z%2rwU*!Wu5ShKaTRZ96N+1gkU8%@vuzELx&QEuJtuXFD?-Fq$s53{D_Rtu$go6!i&O#Yx$hw zUE#2~tS5!fgnJyhpzwpzjUvA)PWv2GnPF!pHYywz*3xBcl(D(&Si%Fsok`1<{9wGu zNyY1mt?a7#b5Hfc`XzgITIn*|8E1kiqG%Ybk|9f8`pRI7;u4enNCkhZ?~jVh5LX6M z9Am6tq5FQ+AN=mtP4)K`ljs+YaDG+Nj2*bxgqFvg?&!W0k{L{;;O$htDFID4P&Z%f?Ps5pdzg`~Ca+;{AG*_$ zy-?xZwdKA2dB*RL$T#H(a@4*7rqTca00vM@R7L;){{R30Rl?JL00009a7bBm000XU z000XU0RWnu7ytkOA4x<(R2b7^U=$P(6oioi41x?uq#zOr7YC{YlY$HYI=TVfXN=Oo P00000NkvXXu0mjfzCP>6 literal 0 HcmV?d00001 diff --git a/applications/main/cfw_app/scenes/cfw_app_scene.c b/applications/main/cfw_app/scenes/cfw_app_scene.c new file mode 100644 index 00000000000..acf552fad26 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene.c @@ -0,0 +1,30 @@ +#include "cfw_app_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const cfw_app_on_enter_handlers[])(void*) = { +#include "cfw_app_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const cfw_app_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "cfw_app_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const cfw_app_on_exit_handlers[])(void* context) = { +#include "cfw_app_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers cfw_app_scene_handlers = { + .on_enter_handlers = cfw_app_on_enter_handlers, + .on_event_handlers = cfw_app_on_event_handlers, + .on_exit_handlers = cfw_app_on_exit_handlers, + .scene_num = CfwAppSceneNum, +}; diff --git a/applications/main/cfw_app/scenes/cfw_app_scene.h b/applications/main/cfw_app/scenes/cfw_app_scene.h new file mode 100644 index 00000000000..f25a549f6c1 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) CfwAppScene##id, +typedef enum { +#include "cfw_app_scene_config.h" + CfwAppSceneNum, +} CfwAppScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers cfw_app_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "cfw_app_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "cfw_app_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "cfw_app_scene_config.h" +#undef ADD_SCENE diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_config.h b/applications/main/cfw_app/scenes/cfw_app_scene_config.h new file mode 100644 index 00000000000..db84cfa3021 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_config.h @@ -0,0 +1,15 @@ +ADD_SCENE(cfw_app, start, Start) +ADD_SCENE(cfw_app, interface, Interface) +// ADD_SCENE(cfw_app, interface_graphics, InterfaceGraphics) +ADD_SCENE(cfw_app, interface_mainmenu, InterfaceMainmenu) +ADD_SCENE(cfw_app, interface_mainmenu_add, InterfaceMainmenuAdd) +// ADD_SCENE(cfw_app, interface_lockscreen, InterfaceLockscreen) +// ADD_SCENE(cfw_app, interface_statusbar, InterfaceStatusbar) +ADD_SCENE(cfw_app, interface_common, InterfaceCommon) +ADD_SCENE(cfw_app, protocols, Protocols) +ADD_SCENE(cfw_app, protocols_frequencies, ProtocolsFrequencies) +ADD_SCENE(cfw_app, protocols_frequencies_static, ProtocolsFrequenciesStatic) +ADD_SCENE(cfw_app, protocols_frequencies_hopper, ProtocolsFrequenciesHopper) +ADD_SCENE(cfw_app, protocols_frequencies_add, ProtocolsFrequenciesAdd) +ADD_SCENE(cfw_app, misc, Misc) +ADD_SCENE(cfw_app, misc_rename, MiscRename) diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_interface.c b/applications/main/cfw_app/scenes/cfw_app_scene_interface.c new file mode 100644 index 00000000000..f8735a05238 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_interface.c @@ -0,0 +1,69 @@ +#include "../cfw_app.h" + +enum VarItemListIndex { + // VarItemListIndexGraphics, + VarItemListIndexMainmenu, + // VarItemListIndexLockscreen, + // VarItemListIndexStatusbar, + VarItemListIndexCommon, +}; + +void cfw_app_scene_interface_var_item_list_callback(void* context, uint32_t index) { + CfwApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void cfw_app_scene_interface_on_enter(void* context) { + CfwApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + + // variable_item_list_add(var_item_list, "Graphics", 0, NULL, app); + variable_item_list_add(var_item_list, "Mainmenu", 0, NULL, app); + // variable_item_list_add(var_item_list, "Lockscreen", 0, NULL, app); + // variable_item_list_add(var_item_list, "Statusbar", 0, NULL, app); + variable_item_list_add(var_item_list, "Common", 0, NULL, app); + + variable_item_list_set_enter_callback( + var_item_list, cfw_app_scene_interface_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, scene_manager_get_scene_state(app->scene_manager, CfwAppSceneInterface)); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +} + +bool cfw_app_scene_interface_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(app->scene_manager, CfwAppSceneInterface, event.event); + consumed = true; + switch(event.event) { + // case VarItemListIndexGraphics: + // scene_manager_next_scene(app->scene_manager, CfwAppSceneInterfaceGraphics); + // break; + case VarItemListIndexMainmenu: + scene_manager_next_scene(app->scene_manager, CfwAppSceneInterfaceMainmenu); + break; + // case VarItemListIndexLockscreen: + // scene_manager_next_scene(app->scene_manager, CfwAppSceneInterfaceLockscreen); + // break; + // case VarItemListIndexStatusbar: + // scene_manager_next_scene(app->scene_manager, CfwAppSceneInterfaceStatusbar); + // break; + case VarItemListIndexCommon: + scene_manager_next_scene(app->scene_manager, CfwAppSceneInterfaceCommon); + break; + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_interface_on_exit(void* context) { + CfwApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_interface_common.c b/applications/main/cfw_app/scenes/cfw_app_scene_interface_common.c new file mode 100644 index 00000000000..4d86efd6e86 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_interface_common.c @@ -0,0 +1,121 @@ +#include "../cfw_app.h" + +enum VarItemListIndex { + // VarItemListIndexSortDirsFirst, + VarItemListIndexDarkMode, + VarItemListIndexLeftHanded, +}; + +void cfw_app_scene_interface_common_var_item_list_callback(void* context, uint32_t index) { + CfwApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +// static void cfw_app_scene_interface_common_sort_dirs_first_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->sort_dirs_first = value; + // app->save_settings = true; +// } + +static void cfw_app_scene_interface_common_dark_mode_changed(VariableItem* item) { + CfwApp* app = variable_item_get_context(item); + bool value = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + CFW_SETTINGS()->dark_mode = value; + app->save_settings = true; +} + +static void cfw_app_scene_interface_common_left_handed_changed(VariableItem* item) { + bool value = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + if(value) { + furi_hal_rtc_set_flag(FuriHalRtcFlagHandOrient); + } else { + furi_hal_rtc_reset_flag(FuriHalRtcFlagHandOrient); + } +} + +// static void cfw_app_scene_interface_common_favorite_timeout_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // uint32_t value = variable_item_get_current_value_index(item); + // char text[6]; + // snprintf(text, sizeof(text), "%lu S", value); + // variable_item_set_current_value_text(item, value ? text : "OFF"); + // CFW_SETTINGS()->favorite_timeout = value; + // app->save_settings = true; +// } + +void cfw_app_scene_interface_common_on_enter(void* context) { + CfwApp* app = context; + CfwSettings* cfw_settings = CFW_SETTINGS(); + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + + // item = variable_item_list_add( + // var_item_list, + // "Sort Dirs First", + // 2, + // cfw_app_scene_interface_common_sort_dirs_first_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->sort_dirs_first); + // variable_item_set_current_value_text(item, cfw_settings->sort_dirs_first ? "ON" : "OFF"); + + item = variable_item_list_add( + var_item_list, "Dark Mode", 2, cfw_app_scene_interface_common_dark_mode_changed, app); + variable_item_set_current_value_index(item, cfw_settings->dark_mode); + variable_item_set_current_value_text(item, cfw_settings->dark_mode ? "ON" : "OFF"); + + item = variable_item_list_add( + var_item_list, + "Left Handed", + 2, + cfw_app_scene_interface_common_left_handed_changed, + app); + bool value = furi_hal_rtc_is_flag_set(FuriHalRtcFlagHandOrient); + variable_item_set_current_value_index(item, value); + variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + + // item = variable_item_list_add( + // var_item_list, + // "Favorite Timeout", + // 61, + // cfw_app_scene_interface_common_favorite_timeout_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->favorite_timeout); + // char text[4]; + // snprintf(text, sizeof(text), "%lu S", cfw_settings->favorite_timeout); + // variable_item_set_current_value_text(item, cfw_settings->favorite_timeout ? text : "OFF"); + + variable_item_list_set_enter_callback( + var_item_list, cfw_app_scene_interface_common_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, + scene_manager_get_scene_state(app->scene_manager, CfwAppSceneInterfaceCommon)); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +} + +bool cfw_app_scene_interface_common_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state( + app->scene_manager, CfwAppSceneInterfaceCommon, event.event); + consumed = true; + switch(event.event) { + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_interface_common_on_exit(void* context) { + CfwApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_interface_graphics.c b/applications/main/cfw_app/scenes/cfw_app_scene_interface_graphics.c new file mode 100644 index 00000000000..e55abbc6de9 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_interface_graphics.c @@ -0,0 +1,171 @@ +// #include "../cfw_app.h" + +// enum VarItemListIndex { + // VarItemListIndexAssetPack, + // VarItemListIndexAnimSpeed, + // VarItemListIndexCycleAnims, + // VarItemListIndexUnlockAnims, +// }; + +// void cfw_app_scene_interface_graphics_var_item_list_callback(void* context, uint32_t index) { + // CfwApp* app = context; + // view_dispatcher_send_custom_event(app->view_dispatcher, index); +// } + +// static void cfw_app_scene_interface_graphics_asset_pack_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // uint8_t index = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text( + // item, index == 0 ? "SFW" : *CharList_get(app->asset_pack_names, index - 1)); + // strlcpy( + // CFW_SETTINGS()->asset_pack, + // index == 0 ? "" : *CharList_get(app->asset_pack_names, index - 1), + // CFW_ASSETS_PACK_NAME_LEN); + // app->asset_pack_index = index; + // app->save_settings = true; + // app->require_reboot = true; +// } + +// const char* const anim_speed_names[] = + // {"25%", "50%", "75%", "100%", "125%", "150%", "175%", "200%", "225%", "250%", "275%", "300%"}; +// const int32_t anim_speed_values[COUNT_OF(anim_speed_names)] = + // {25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300}; +// static void cfw_app_scene_interface_graphics_anim_speed_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // uint8_t index = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, anim_speed_names[index]); + // CFW_SETTINGS()->anim_speed = anim_speed_values[index]; + // app->save_settings = true; +// } + +// const char* const cycle_anims_names[] = { + // "OFF", + // "Meta.txt", + // "30 S", + // "1 M", + // "5 M", + // "10 M", + // "15 M", + // "30 M", + // "1 H", + // "2 H", + // "6 H", + // "12 H", + // "24 H"}; +// const int32_t cycle_anims_values[COUNT_OF(cycle_anims_names)] = + // {-1, 0, 30, 60, 300, 600, 900, 1800, 3600, 7200, 21600, 43200, 86400}; +// static void cfw_app_scene_interface_graphics_cycle_anims_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // uint8_t index = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, cycle_anims_names[index]); + // CFW_SETTINGS()->cycle_anims = cycle_anims_values[index]; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_graphics_unlock_anims_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->unlock_anims = value; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_graphics_fallback_anim_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->fallback_anim = value; + // app->save_settings = true; +// } + +// void cfw_app_scene_interface_graphics_on_enter(void* context) { + // CfwApp* app = context; + // CfwSettings* cfw_settings = CFW_SETTINGS(); + // VariableItemList* var_item_list = app->var_item_list; + // VariableItem* item; + // uint8_t value_index; + + // item = variable_item_list_add( + // var_item_list, + // "Asset Pack", + // CharList_size(app->asset_pack_names) + 1, + // cfw_app_scene_interface_graphics_asset_pack_changed, + // app); + // variable_item_set_current_value_index(item, app->asset_pack_index); + // variable_item_set_current_value_text( + // item, + // app->asset_pack_index == 0 ? + // "SFW" : + // *CharList_get(app->asset_pack_names, app->asset_pack_index - 1)); + + // item = variable_item_list_add( + // var_item_list, + // "Anim Speed", + // COUNT_OF(anim_speed_names), + // cfw_app_scene_interface_graphics_anim_speed_changed, + // app); + // value_index = value_index_int32( + // cfw_settings->anim_speed, anim_speed_values, COUNT_OF(anim_speed_names)); + // variable_item_set_current_value_index(item, value_index); + // variable_item_set_current_value_text(item, anim_speed_names[value_index]); + + // item = variable_item_list_add( + // var_item_list, + // "Cycle Anims", + // COUNT_OF(cycle_anims_names), + // cfw_app_scene_interface_graphics_cycle_anims_changed, + // app); + // value_index = value_index_int32( + // cfw_settings->cycle_anims, cycle_anims_values, COUNT_OF(cycle_anims_names)); + // variable_item_set_current_value_index(item, value_index); + // variable_item_set_current_value_text(item, cycle_anims_names[value_index]); + + // item = variable_item_list_add( + // var_item_list, + // "Unlock Anims", + // 2, + // cfw_app_scene_interface_graphics_unlock_anims_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->unlock_anims); + // variable_item_set_current_value_text(item, cfw_settings->unlock_anims ? "ON" : "OFF"); + + // item = variable_item_list_add( + // var_item_list, + // "Fallback Anim", + // 2, + // cfw_app_scene_interface_graphics_fallback_anim_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->fallback_anim); + // variable_item_set_current_value_text(item, cfw_settings->fallback_anim ? "ON" : "OFF"); + + // variable_item_list_set_enter_callback( + // var_item_list, cfw_app_scene_interface_graphics_var_item_list_callback, app); + + // variable_item_list_set_selected_item( + // var_item_list, + // scene_manager_get_scene_state(app->scene_manager, CfwAppSceneInterfaceGraphics)); + + // view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +// } + +// bool cfw_app_scene_interface_graphics_on_event(void* context, SceneManagerEvent event) { + // CfwApp* app = context; + // bool consumed = false; + + // if(event.type == SceneManagerEventTypeCustom) { + // scene_manager_set_scene_state( + // app->scene_manager, CfwAppSceneInterfaceGraphics, event.event); + // consumed = true; + // switch(event.event) { + // default: + // break; + // } + // } + + // return consumed; +// } + +// void cfw_app_scene_interface_graphics_on_exit(void* context) { + // CfwApp* app = context; + // variable_item_list_reset(app->var_item_list); +// } diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_interface_lockscreen.c b/applications/main/cfw_app/scenes/cfw_app_scene_interface_lockscreen.c new file mode 100644 index 00000000000..afd09f311cb --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_interface_lockscreen.c @@ -0,0 +1,152 @@ +// #include "../cfw_app.h" + +// enum VarItemListIndex { + // VarItemListIndexShowClock, + // VarItemListIndexShowDate, +// }; + +// void cfw_app_scene_interface_lockscreen_var_item_list_callback(void* context, uint32_t index) { + // CfwApp* app = context; + // view_dispatcher_send_custom_event(app->view_dispatcher, index); +// } + +// static void cfw_app_scene_interface_lockscreen_bad_pins_format_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->bad_pins_format = value; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_lockscreen_show_time_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->lockscreen_time = value; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_lockscreen_show_seconds_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->lockscreen_seconds = value; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_lockscreen_show_date_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->lockscreen_date = value; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_lockscreen_show_statusbar_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->lockscreen_statusbar = value; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_lockscreen_unlock_prompt_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->lockscreen_prompt = value; + // app->save_settings = true; +// } + +// void cfw_app_scene_interface_lockscreen_on_enter(void* context) { + // CfwApp* app = context; + // CfwSettings* cfw_settings = CFW_SETTINGS(); + // VariableItemList* var_item_list = app->var_item_list; + // VariableItem* item; + + // item = variable_item_list_add( + // var_item_list, + // "Format on 10 bad PINs", + // 2, + // cfw_app_scene_interface_lockscreen_bad_pins_format_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->bad_pins_format); + // variable_item_set_current_value_text(item, cfw_settings->bad_pins_format ? "ON" : "OFF"); + + // item = variable_item_list_add( + // var_item_list, + // "Show Time", + // 2, + // cfw_app_scene_interface_lockscreen_show_time_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->lockscreen_time); + // variable_item_set_current_value_text(item, cfw_settings->lockscreen_time ? "ON" : "OFF"); + + // item = variable_item_list_add( + // var_item_list, + // "Show Seconds", + // 2, + // cfw_app_scene_interface_lockscreen_show_seconds_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->lockscreen_seconds); + // variable_item_set_current_value_text(item, cfw_settings->lockscreen_seconds ? "ON" : "OFF"); + + // item = variable_item_list_add( + // var_item_list, + // "Show Date", + // 2, + // cfw_app_scene_interface_lockscreen_show_date_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->lockscreen_date); + // variable_item_set_current_value_text(item, cfw_settings->lockscreen_date ? "ON" : "OFF"); + + // item = variable_item_list_add( + // var_item_list, + // "Show Statusbar", + // 2, + // cfw_app_scene_interface_lockscreen_show_statusbar_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->lockscreen_statusbar); + // variable_item_set_current_value_text( + // item, cfw_settings->lockscreen_statusbar ? "ON" : "OFF"); + + // item = variable_item_list_add( + // var_item_list, + // "Unlock Prompt", + // 2, + // cfw_app_scene_interface_lockscreen_unlock_prompt_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->lockscreen_prompt); + // variable_item_set_current_value_text(item, cfw_settings->lockscreen_prompt ? "ON" : "OFF"); + + // variable_item_list_set_enter_callback( + // var_item_list, cfw_app_scene_interface_lockscreen_var_item_list_callback, app); + + // variable_item_list_set_selected_item( + // var_item_list, + // scene_manager_get_scene_state(app->scene_manager, CfwAppSceneInterfaceLockscreen)); + + // view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +// } + +// bool cfw_app_scene_interface_lockscreen_on_event(void* context, SceneManagerEvent event) { + // CfwApp* app = context; + // bool consumed = false; + + // if(event.type == SceneManagerEventTypeCustom) { + // scene_manager_set_scene_state( + // app->scene_manager, CfwAppSceneInterfaceLockscreen, event.event); + // consumed = true; + // switch(event.event) { + // default: + // break; + // } + // } + + // return consumed; +// } + +// void cfw_app_scene_interface_lockscreen_on_exit(void* context) { + // CfwApp* app = context; + // variable_item_list_reset(app->var_item_list); +// } diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_interface_mainmenu.c b/applications/main/cfw_app/scenes/cfw_app_scene_interface_mainmenu.c new file mode 100644 index 00000000000..bb2eb555eed --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_interface_mainmenu.c @@ -0,0 +1,106 @@ +#include "../cfw_app.h" + +enum VarItemListIndex { + VarItemListIndexWiiMenu, + VarItemListIndexApp, + VarItemListIndexRemoveApp, + VarItemListIndexAddApp, +}; + +void cfw_app_scene_interface_mainmenu_var_item_list_callback(void* context, uint32_t index) { + CfwApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +static void cfw_app_scene_interface_mainmenu_wii_menu_changed(VariableItem* item) { + CfwApp* app = variable_item_get_context(item); + bool value = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, value ? "Wii Grid" : "App List"); + CFW_SETTINGS()->wii_menu = value; + app->save_settings = true; +} + +static void cfw_app_scene_interface_mainmenu_app_changed(VariableItem* item) { + CfwApp* app = variable_item_get_context(item); + app->mainmenu_app_index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text( + item, *CharList_get(app->mainmenu_app_names, app->mainmenu_app_index)); +} + +void cfw_app_scene_interface_mainmenu_on_enter(void* context) { + CfwApp* app = context; + CfwSettings* cfw_settings = CFW_SETTINGS(); + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + + item = variable_item_list_add( + var_item_list, "Menu Style", 2, cfw_app_scene_interface_mainmenu_wii_menu_changed, app); + variable_item_set_current_value_index(item, cfw_settings->wii_menu); + variable_item_set_current_value_text( + item, cfw_settings->wii_menu ? "Wii Grid" : "App List"); + + item = variable_item_list_add( + var_item_list, + "App", + CharList_size(app->mainmenu_app_names), + cfw_app_scene_interface_mainmenu_app_changed, + app); + app->mainmenu_app_index = 0; + variable_item_set_current_value_index(item, app->mainmenu_app_index); + if(CharList_size(app->mainmenu_app_names)) { + variable_item_set_current_value_text( + item, *CharList_get(app->mainmenu_app_names, app->mainmenu_app_index)); + } else { + variable_item_set_current_value_text(item, "None"); + } + + variable_item_list_add(var_item_list, "Remove App", 0, NULL, app); + + variable_item_list_add(var_item_list, "Add App", 0, NULL, app); + + variable_item_list_set_enter_callback( + var_item_list, cfw_app_scene_interface_mainmenu_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, + scene_manager_get_scene_state(app->scene_manager, CfwAppSceneInterfaceMainmenu)); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +} + +bool cfw_app_scene_interface_mainmenu_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state( + app->scene_manager, CfwAppSceneInterfaceMainmenu, event.event); + consumed = true; + switch(event.event) { + case VarItemListIndexRemoveApp: + if(!CharList_size(app->mainmenu_app_names)) break; + if(!CharList_size(app->mainmenu_app_paths)) break; + CharList_remove_v( + app->mainmenu_app_names, app->mainmenu_app_index, app->mainmenu_app_index + 1); + CharList_remove_v( + app->mainmenu_app_paths, app->mainmenu_app_index, app->mainmenu_app_index + 1); + app->save_mainmenu_apps = true; + app->require_reboot = true; + scene_manager_previous_scene(app->scene_manager); + scene_manager_next_scene(app->scene_manager, CfwAppSceneInterfaceMainmenu); + break; + case VarItemListIndexAddApp: + scene_manager_next_scene(app->scene_manager, CfwAppSceneInterfaceMainmenuAdd); + break; + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_interface_mainmenu_on_exit(void* context) { + CfwApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_interface_mainmenu_add.c b/applications/main/cfw_app/scenes/cfw_app_scene_interface_mainmenu_add.c new file mode 100644 index 00000000000..f13fe4d43eb --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_interface_mainmenu_add.c @@ -0,0 +1,67 @@ +#include "../cfw_app.h" + +enum FileBrowserResult { + FileBrowserResultOk, +}; + +static bool cfw_app_scene_interface_mainmenu_add_file_browser_callback( + FuriString* file_path, + void* context, + uint8_t** icon_ptr, + FuriString* item_name) { + UNUSED(context); + Storage* storage = furi_record_open(RECORD_STORAGE); + bool success = fap_loader_load_name_and_icon(file_path, storage, icon_ptr, item_name); + furi_record_close(RECORD_STORAGE); + return success; +} + +void cfw_app_scene_interface_mainmenu_add_on_enter(void* context) { + CfwApp* app = context; + FuriString* string = furi_string_alloc_set_str(EXT_PATH("apps")); + + const DialogsFileBrowserOptions browser_options = { + .extension = ".fap", + .skip_assets = true, + .hide_ext = true, + .item_loader_callback = cfw_app_scene_interface_mainmenu_add_file_browser_callback, + .item_loader_context = app, + .base_path = EXT_PATH("apps"), + }; + + if(dialog_file_browser_show(app->dialogs, string, string, &browser_options)) { + CharList_push_back(app->mainmenu_app_paths, strdup(furi_string_get_cstr(string))); + Storage* storage = furi_record_open(RECORD_STORAGE); + fap_loader_load_name_and_icon(string, storage, NULL, string); + furi_record_close(RECORD_STORAGE); + CharList_push_back(app->mainmenu_app_names, strdup(furi_string_get_cstr(string))); + app->save_mainmenu_apps = true; + app->require_reboot = true; + } + + furi_string_free(string); + + view_dispatcher_send_custom_event(app->view_dispatcher, FileBrowserResultOk); +} + +bool cfw_app_scene_interface_mainmenu_add_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + switch(event.event) { + case FileBrowserResultOk: + scene_manager_previous_scene(app->scene_manager); + break; + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_interface_mainmenu_add_on_exit(void* context) { + UNUSED(context); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_interface_statusbar.c b/applications/main/cfw_app/scenes/cfw_app_scene_interface_statusbar.c new file mode 100644 index 00000000000..6a32d0147c9 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_interface_statusbar.c @@ -0,0 +1,121 @@ +// #include "../cfw_app.h" + +// enum VarItemListIndex { + // VarItemListIndexBatteryIcon, + // VarItemListIndexStatusIcons, + // VarItemListIndexBarBorders, + // VarItemListIndexBarBackground, +// }; + +// void cfw_app_scene_interface_statusbar_var_item_list_callback(void* context, uint32_t index) { + // CfwApp* app = context; + // view_dispatcher_send_custom_event(app->view_dispatcher, index); +// } + +// const char* const battery_icon_names[] = + // {"OFF", "Bar", "%", "Inv. %", "Retro 3", "Retro 5", "Bar %"}; +// static void cfw_app_scene_interface_statusbar_battery_icon_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // uint8_t index = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, battery_icon_names[index]); + // CFW_SETTINGS()->battery_icon = index; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_statusbar_status_icons_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->status_icons = value; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_statusbar_bar_borders_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->bar_borders = value; + // app->save_settings = true; +// } + +// static void cfw_app_scene_interface_statusbar_bar_background_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->bar_background = value; + // app->save_settings = true; +// } + +// void cfw_app_scene_interface_statusbar_on_enter(void* context) { + // CfwApp* app = context; + // CfwSettings* cfw_settings = CFW_SETTINGS(); + // VariableItemList* var_item_list = app->var_item_list; + // VariableItem* item; + + // item = variable_item_list_add( + // var_item_list, + // "Battery Icon", + // BatteryIconCount, + // cfw_app_scene_interface_statusbar_battery_icon_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->battery_icon); + // variable_item_set_current_value_text(item, battery_icon_names[cfw_settings->battery_icon]); + + // item = variable_item_list_add( + // var_item_list, + // "Status Icons", + // 2, + // cfw_app_scene_interface_statusbar_status_icons_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->status_icons); + // variable_item_set_current_value_text(item, cfw_settings->status_icons ? "ON" : "OFF"); + + // item = variable_item_list_add( + // var_item_list, + // "Bar Borders", + // 2, + // cfw_app_scene_interface_statusbar_bar_borders_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->bar_borders); + // variable_item_set_current_value_text(item, cfw_settings->bar_borders ? "ON" : "OFF"); + + // item = variable_item_list_add( + // var_item_list, + // "Bar Background", + // 2, + // cfw_app_scene_interface_statusbar_bar_background_changed, + // app); + // variable_item_set_current_value_index(item, cfw_settings->bar_background); + // variable_item_set_current_value_text(item, cfw_settings->bar_background ? "ON" : "OFF"); + + // variable_item_list_set_enter_callback( + // var_item_list, cfw_app_scene_interface_statusbar_var_item_list_callback, app); + + // variable_item_list_set_selected_item( + // var_item_list, + // scene_manager_get_scene_state(app->scene_manager, CfwAppSceneInterfaceStatusbar)); + + // view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +// } + +// bool cfw_app_scene_interface_statusbar_on_event(void* context, SceneManagerEvent event) { + // CfwApp* app = context; + // bool consumed = false; + + // if(event.type == SceneManagerEventTypeCustom) { + // scene_manager_set_scene_state( + // app->scene_manager, CfwAppSceneInterfaceStatusbar, event.event); + // consumed = true; + // switch(event.event) { + // default: + // break; + // } + // } + + // return consumed; +// } + +// void cfw_app_scene_interface_statusbar_on_exit(void* context) { + // CfwApp* app = context; + // variable_item_list_reset(app->var_item_list); +// } diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_misc.c b/applications/main/cfw_app/scenes/cfw_app_scene_misc.c new file mode 100644 index 00000000000..b62b12885b5 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_misc.c @@ -0,0 +1,150 @@ +#include "../cfw_app.h" + +enum VarItemListIndex { + VarItemListIndexChangeDeviceName, + VarItemListIndexXpLevel, + VarItemListIndexButthurtTimer, + VarItemListIndexRgbBacklight, + VarItemListIndexLcdColor, +}; + +void cfw_app_scene_misc_var_item_list_callback(void* context, uint32_t index) { + CfwApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +// static void cfw_app_scene_misc_xp_level_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // app->xp_level = variable_item_get_current_value_index(item) + 1; + // char level_str[4]; + // snprintf(level_str, 4, "%li", app->xp_level); + // variable_item_set_current_value_text(item, level_str); + // app->save_level = true; +// } + +// const char* const butthurt_timer_names[] = + // {"OFF", "30 M", "1 H", "2 H", "4 H", "6 H", "8 H", "12 H", "24 H", "48 H"}; +// const int32_t butthurt_timer_values[COUNT_OF(butthurt_timer_names)] = + // {-1, 1800, 3600, 7200, 14400, 21600, 28800, 43200, 86400, 172800}; +// static void cfw_app_scene_misc_butthurt_timer_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // uint8_t index = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, butthurt_timer_names[index]); + // CFW_SETTINGS()->butthurt_timer = butthurt_timer_values[index]; + // app->save_settings = true; + // app->require_reboot = true; +// } + +static void cfw_app_scene_misc_lcd_color_changed(VariableItem* item) { + CfwApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, rgb_backlight_get_color_text(index)); + rgb_backlight_set_color(index); + app->save_backlight = true; + notification_message(app->notification, &sequence_display_backlight_on); +} + +void cfw_app_scene_misc_on_enter(void* context) { + CfwApp* app = context; + CfwSettings* cfw_settings = CFW_SETTINGS(); + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + uint8_t value_index; + + variable_item_list_add(var_item_list, "Change Device Name", 0, NULL, app); + + // char level_str[4]; + // snprintf(level_str, 4, "%li", app->xp_level); + // item = variable_item_list_add( + // var_item_list, + // "XP Level", + // DOLPHIN_LEVEL_COUNT + 1, + // cfw_app_scene_misc_xp_level_changed, + // app); + // variable_item_set_current_value_index(item, app->xp_level - 1); + // variable_item_set_current_value_text(item, level_str); + + // item = variable_item_list_add( + // var_item_list, + // "Butthurt Timer", + // COUNT_OF(butthurt_timer_names), + // cfw_app_scene_misc_butthurt_timer_changed, + // app); + // value_index = value_index_int32( + // cfw_settings->butthurt_timer, butthurt_timer_values, COUNT_OF(butthurt_timer_names)); + // variable_item_set_current_value_index(item, value_index); + // variable_item_set_current_value_text(item, butthurt_timer_names[value_index]); + + item = variable_item_list_add(var_item_list, "RGB Backlight", 1, NULL, app); + variable_item_set_current_value_text(item, cfw_settings->rgb_backlight ? "ON" : "OFF"); + + item = variable_item_list_add( + var_item_list, + "LCD Color", + rgb_backlight_get_color_count(), + cfw_app_scene_misc_lcd_color_changed, + app); + value_index = rgb_backlight_get_settings()->display_color_index; + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, rgb_backlight_get_color_text(value_index)); + variable_item_set_locked(item, !cfw_settings->rgb_backlight, "Needs RGB\nBacklight!"); + + variable_item_list_set_enter_callback( + var_item_list, cfw_app_scene_misc_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, scene_manager_get_scene_state(app->scene_manager, CfwAppSceneMisc)); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +} + +bool cfw_app_scene_misc_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(app->scene_manager, CfwAppSceneMisc, event.event); + consumed = true; + switch(event.event) { + case VarItemListIndexChangeDeviceName: + scene_manager_next_scene(app->scene_manager, CfwAppSceneMiscRename); + break; + case VarItemListIndexRgbBacklight: { + bool change = CFW_SETTINGS()->rgb_backlight; + if(!change) { + DialogMessage* msg = dialog_message_alloc(); + dialog_message_set_header(msg, "RGB Backlight", 64, 0, AlignCenter, AlignTop); + dialog_message_set_buttons(msg, "No", NULL, "Yes"); + dialog_message_set_text( + msg, + "This option requires installing\na hardware modification!\nIs it installed?", + 64, + 32, + AlignCenter, + AlignCenter); + if(dialog_message_show(app->dialogs, msg) == DialogMessageButtonRight) { + change = true; + } + dialog_message_free(msg); + } + if(change) { + CFW_SETTINGS()->rgb_backlight = !CFW_SETTINGS()->rgb_backlight; + app->save_settings = true; + notification_message(app->notification, &sequence_display_backlight_on); + scene_manager_previous_scene(app->scene_manager); + scene_manager_next_scene(app->scene_manager, CfwAppSceneMisc); + } + break; + } + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_misc_on_exit(void* context) { + CfwApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_misc_rename.c b/applications/main/cfw_app/scenes/cfw_app_scene_misc_rename.c new file mode 100644 index 00000000000..bbbf13abeaf --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_misc_rename.c @@ -0,0 +1,72 @@ +#include "../cfw_app.h" + +enum TextInputIndex { + TextInputResultOk, +}; + +static void cfw_app_scene_misc_rename_text_input_callback(void* context) { + CfwApp* app = context; + + app->save_name = true; + app->require_reboot = true; + view_dispatcher_send_custom_event(app->view_dispatcher, TextInputResultOk); +} + +static bool + cfw_app_scene_misc_rename_validator(const char* text, FuriString* error, void* context) { + UNUSED(context); + + for(; *text; ++text) { + const char c = *text; + if((c < '0' || c > '9') && (c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) { + furi_string_printf(error, "Please only\nenter letters\nand numbers!"); + return false; + } + } + + return true; +} + +void cfw_app_scene_misc_rename_on_enter(void* context) { + CfwApp* app = context; + TextInput* text_input = app->text_input; + + text_input_set_header_text(text_input, "Leave empty for default"); + + text_input_set_validator(text_input, cfw_app_scene_misc_rename_validator, NULL); + + text_input_set_minimum_length(text_input, 0); + + text_input_set_result_callback( + text_input, + cfw_app_scene_misc_rename_text_input_callback, + app, + app->device_name, + FURI_HAL_VERSION_ARRAY_NAME_LENGTH, + true); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewTextInput); +} + +bool cfw_app_scene_misc_rename_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + switch(event.event) { + case TextInputResultOk: + scene_manager_previous_scene(app->scene_manager); + break; + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_misc_rename_on_exit(void* context) { + CfwApp* app = context; + text_input_reset(app->text_input); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_protocols.c b/applications/main/cfw_app/scenes/cfw_app_scene_protocols.c new file mode 100644 index 00000000000..4db00cf2f56 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_protocols.c @@ -0,0 +1,92 @@ +#include "../cfw_app.h" + +enum VarItemListIndex { + // VarItemListIndexBadkbMode, + // VarItemListIndexBadbtRemember, + VarItemListIndexSubghzFrequencies, + VarItemListIndexSubghzExtend, +}; + +void cfw_app_scene_protocols_var_item_list_callback(void* context, uint32_t index) { + CfwApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +// static void cfw_app_scene_protocols_badkb_mode_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "BT" : "USB"); + // CFW_SETTINGS()->bad_bt = value; + // app->save_settings = true; +// } + +// static void cfw_app_scene_protocols_badbt_remember_changed(VariableItem* item) { + // CfwApp* app = variable_item_get_context(item); + // bool value = variable_item_get_current_value_index(item); + // variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + // CFW_SETTINGS()->bad_bt_remember = value; + // app->save_settings = true; +// } + +static void cfw_app_scene_protocols_subghz_extend_changed(VariableItem* item) { + CfwApp* app = variable_item_get_context(item); + app->subghz_extend = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, app->subghz_extend ? "ON" : "OFF"); + app->save_subghz = true; +} + +void cfw_app_scene_protocols_on_enter(void* context) { + CfwApp* app = context; + CfwSettings* cfw_settings = CFW_SETTINGS(); + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + + // item = variable_item_list_add( + // var_item_list, "BadKB Mode", 2, cfw_app_scene_protocols_badkb_mode_changed, app); + // variable_item_set_current_value_index(item, cfw_settings->bad_bt); + // variable_item_set_current_value_text(item, cfw_settings->bad_bt ? "BT" : "USB"); + + // item = variable_item_list_add( + // var_item_list, "BadBT Remember", 2, cfw_app_scene_protocols_badbt_remember_changed, app); + // variable_item_set_current_value_index(item, cfw_settings->bad_bt_remember); + // variable_item_set_current_value_text(item, cfw_settings->bad_bt_remember ? "ON" : "OFF"); + + variable_item_list_add(var_item_list, "SubGHz Frequencies", 0, NULL, app); + + item = variable_item_list_add( + var_item_list, "SubGHz Extend", 2, cfw_app_scene_protocols_subghz_extend_changed, app); + variable_item_set_current_value_index(item, app->subghz_extend); + variable_item_set_current_value_text(item, app->subghz_extend ? "ON" : "OFF"); + + variable_item_list_set_enter_callback( + var_item_list, cfw_app_scene_protocols_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, scene_manager_get_scene_state(app->scene_manager, CfwAppSceneProtocols)); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +} + +bool cfw_app_scene_protocols_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(app->scene_manager, CfwAppSceneProtocols, event.event); + consumed = true; + switch(event.event) { + case VarItemListIndexSubghzFrequencies: + scene_manager_next_scene(app->scene_manager, CfwAppSceneProtocolsFrequencies); + break; + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_protocols_on_exit(void* context) { + CfwApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies.c b/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies.c new file mode 100644 index 00000000000..7516bda6017 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies.c @@ -0,0 +1,76 @@ +#include "../cfw_app.h" + +enum VarItemListIndex { + VarItemListIndexUseDefaults, + VarItemListIndexStaticFrequencies, + VarItemListIndexHopperFrequencies, +}; + +void cfw_app_scene_protocols_frequencies_var_item_list_callback(void* context, uint32_t index) { + CfwApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +static void cfw_app_scene_protocols_frequencies_use_defaults_changed(VariableItem* item) { + CfwApp* app = variable_item_get_context(item); + bool value = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + app->subghz_use_defaults = value; + app->save_subghz_frequencies = true; +} + +void cfw_app_scene_protocols_frequencies_on_enter(void* context) { + CfwApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + + item = variable_item_list_add( + var_item_list, + "Use Defaults", + 2, + cfw_app_scene_protocols_frequencies_use_defaults_changed, + app); + variable_item_set_current_value_index(item, app->subghz_use_defaults); + variable_item_set_current_value_text(item, app->subghz_use_defaults ? "ON" : "OFF"); + + variable_item_list_add(var_item_list, "Static Frequencies", 0, NULL, app); + + variable_item_list_add(var_item_list, "Hopper Frequencies", 0, NULL, app); + + variable_item_list_set_enter_callback( + var_item_list, cfw_app_scene_protocols_frequencies_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, + scene_manager_get_scene_state(app->scene_manager, CfwAppSceneProtocolsFrequencies)); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +} + +bool cfw_app_scene_protocols_frequencies_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state( + app->scene_manager, CfwAppSceneProtocolsFrequencies, event.event); + consumed = true; + switch(event.event) { + case VarItemListIndexStaticFrequencies: + scene_manager_next_scene(app->scene_manager, CfwAppSceneProtocolsFrequenciesStatic); + break; + case VarItemListIndexHopperFrequencies: + scene_manager_next_scene(app->scene_manager, CfwAppSceneProtocolsFrequenciesHopper); + break; + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_protocols_frequencies_on_exit(void* context) { + CfwApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_add.c b/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_add.c new file mode 100644 index 00000000000..09bd23641a9 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_add.c @@ -0,0 +1,83 @@ +#include "../cfw_app.h" + +enum TextInputResult { + TextInputResultOk, + TextInputResultError, +}; + +static void cfw_app_scene_protocols_frequencies_add_text_input_callback(void* context) { + CfwApp* app = context; + + char* end; + uint32_t value = strtol(app->subghz_freq_buffer, &end, 0) * 10000; + if(*end || !furi_hal_subghz_is_frequency_valid(value)) { + view_dispatcher_send_custom_event(app->view_dispatcher, TextInputResultError); + return; + } + bool is_hopper = + scene_manager_get_scene_state(app->scene_manager, CfwAppSceneProtocolsFrequenciesAdd); + if(is_hopper) { + FrequencyList_push_back(app->subghz_hopper_freqs, value); + } else { + FrequencyList_push_back(app->subghz_static_freqs, value); + } + app->save_subghz_frequencies = true; + view_dispatcher_send_custom_event(app->view_dispatcher, TextInputResultOk); +} + +void cfw_app_scene_protocols_frequencies_add_on_enter(void* context) { + CfwApp* app = context; + TextInput* text_input = app->text_input; + + text_input_set_header_text(text_input, "Format: 12356"); + + strlcpy(app->subghz_freq_buffer, "", CFW_SUBGHZ_FREQ_BUFFER_SIZE); + + text_input_set_result_callback( + text_input, + cfw_app_scene_protocols_frequencies_add_text_input_callback, + app, + app->subghz_freq_buffer, + CFW_SUBGHZ_FREQ_BUFFER_SIZE, + true); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewTextInput); +} + +void callback_return(void* context) { + CfwApp* app = context; + scene_manager_previous_scene(app->scene_manager); +} + +bool cfw_app_scene_protocols_frequencies_add_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + switch(event.event) { + case TextInputResultOk: + scene_manager_previous_scene(app->scene_manager); + break; + case TextInputResultError: + popup_set_header(app->popup, "Invalid value!", 64, 26, AlignCenter, AlignCenter); + popup_set_text( + app->popup, "Frequency was not added...", 64, 40, AlignCenter, AlignCenter); + popup_set_callback(app->popup, callback_return); + popup_set_context(app->popup, app); + popup_set_timeout(app->popup, 1000); + popup_enable_timeout(app->popup); + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewPopup); + break; + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_protocols_frequencies_add_on_exit(void* context) { + CfwApp* app = context; + text_input_reset(app->text_input); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_hopper.c b/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_hopper.c new file mode 100644 index 00000000000..0194785399f --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_hopper.c @@ -0,0 +1,104 @@ +#include "../cfw_app.h" + +enum VarItemListIndex { + VarItemListIndexHopperFrequency, + VarItemListIndexRemoveHopperFreq, + VarItemListIndexAddHopperFreq, +}; + +void cfw_app_scene_protocols_frequencies_hopper_var_item_list_callback( + void* context, + uint32_t index) { + CfwApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +static void cfw_app_scene_protocols_frequencies_hopper_frequency_changed(VariableItem* item) { + CfwApp* app = variable_item_get_context(item); + app->subghz_hopper_index = variable_item_get_current_value_index(item); + uint32_t value = *FrequencyList_get(app->subghz_hopper_freqs, app->subghz_hopper_index); + char text[10] = {0}; + snprintf(text, sizeof(text), "%lu.%02lu", value / 1000000, (value % 1000000) / 10000); + variable_item_set_current_value_text(item, text); +} + +void cfw_app_scene_protocols_frequencies_hopper_on_enter(void* context) { + CfwApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + + item = variable_item_list_add( + var_item_list, + "Hopper Freq", + FrequencyList_size(app->subghz_hopper_freqs), + cfw_app_scene_protocols_frequencies_hopper_frequency_changed, + app); + app->subghz_hopper_index = 0; + variable_item_set_current_value_index(item, app->subghz_hopper_index); + if(FrequencyList_size(app->subghz_hopper_freqs)) { + uint32_t value = *FrequencyList_get(app->subghz_hopper_freqs, app->subghz_hopper_index); + char text[10] = {0}; + snprintf(text, sizeof(text), "%lu.%02lu", value / 1000000, (value % 1000000) / 10000); + variable_item_set_current_value_text(item, text); + } else { + variable_item_set_current_value_text(item, "None"); + } + + variable_item_list_add(var_item_list, "Remove Hopper Freq", 0, NULL, app); + + variable_item_list_add(var_item_list, "Add Hopper Freq", 0, NULL, app); + + variable_item_list_set_enter_callback( + var_item_list, cfw_app_scene_protocols_frequencies_hopper_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, + scene_manager_get_scene_state( + app->scene_manager, CfwAppSceneProtocolsFrequenciesHopper)); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +} + +bool cfw_app_scene_protocols_frequencies_hopper_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state( + app->scene_manager, CfwAppSceneProtocolsFrequenciesHopper, event.event); + consumed = true; + switch(event.event) { + case VarItemListIndexRemoveHopperFreq: + if(!FrequencyList_size(app->subghz_hopper_freqs)) break; + uint32_t value = + *FrequencyList_get(app->subghz_hopper_freqs, app->subghz_hopper_index); + FrequencyList_it_t it; + FrequencyList_it(it, app->subghz_hopper_freqs); + while(!FrequencyList_end_p(it)) { + if(*FrequencyList_ref(it) == value) { + FrequencyList_remove(app->subghz_hopper_freqs, it); + } else { + FrequencyList_next(it); + } + } + app->save_subghz_frequencies = true; + scene_manager_previous_scene(app->scene_manager); + scene_manager_next_scene(app->scene_manager, CfwAppSceneProtocolsFrequenciesHopper); + break; + case VarItemListIndexAddHopperFreq: + scene_manager_set_scene_state( + app->scene_manager, CfwAppSceneProtocolsFrequenciesAdd, true); + scene_manager_next_scene(app->scene_manager, CfwAppSceneProtocolsFrequenciesAdd); + break; + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_protocols_frequencies_hopper_on_exit(void* context) { + CfwApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_static.c b/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_static.c new file mode 100644 index 00000000000..88fccd7b624 --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_protocols_frequencies_static.c @@ -0,0 +1,104 @@ +#include "../cfw_app.h" + +enum VarItemListIndex { + VarItemListIndexStaticFrequency, + VarItemListIndexRemoveStaticFreq, + VarItemListIndexAddStaticFreq, +}; + +void cfw_app_scene_protocols_frequencies_static_var_item_list_callback( + void* context, + uint32_t index) { + CfwApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +static void cfw_app_scene_protocols_frequencies_static_frequency_changed(VariableItem* item) { + CfwApp* app = variable_item_get_context(item); + app->subghz_static_index = variable_item_get_current_value_index(item); + uint32_t value = *FrequencyList_get(app->subghz_static_freqs, app->subghz_static_index); + char text[10] = {0}; + snprintf(text, sizeof(text), "%lu.%02lu", value / 1000000, (value % 1000000) / 10000); + variable_item_set_current_value_text(item, text); +} + +void cfw_app_scene_protocols_frequencies_static_on_enter(void* context) { + CfwApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + + item = variable_item_list_add( + var_item_list, + "Static Freq", + FrequencyList_size(app->subghz_static_freqs), + cfw_app_scene_protocols_frequencies_static_frequency_changed, + app); + app->subghz_static_index = 0; + variable_item_set_current_value_index(item, app->subghz_static_index); + if(FrequencyList_size(app->subghz_static_freqs)) { + uint32_t value = *FrequencyList_get(app->subghz_static_freqs, app->subghz_static_index); + char text[10] = {0}; + snprintf(text, sizeof(text), "%lu.%02lu", value / 1000000, (value % 1000000) / 10000); + variable_item_set_current_value_text(item, text); + } else { + variable_item_set_current_value_text(item, "None"); + } + + variable_item_list_add(var_item_list, "Remove Static Freq", 0, NULL, app); + + variable_item_list_add(var_item_list, "Add Static Freq", 0, NULL, app); + + variable_item_list_set_enter_callback( + var_item_list, cfw_app_scene_protocols_frequencies_static_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, + scene_manager_get_scene_state( + app->scene_manager, CfwAppSceneProtocolsFrequenciesStatic)); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +} + +bool cfw_app_scene_protocols_frequencies_static_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state( + app->scene_manager, CfwAppSceneProtocolsFrequenciesStatic, event.event); + consumed = true; + switch(event.event) { + case VarItemListIndexRemoveStaticFreq: + if(!FrequencyList_size(app->subghz_static_freqs)) break; + uint32_t value = + *FrequencyList_get(app->subghz_static_freqs, app->subghz_static_index); + FrequencyList_it_t it; + FrequencyList_it(it, app->subghz_static_freqs); + while(!FrequencyList_end_p(it)) { + if(*FrequencyList_ref(it) == value) { + FrequencyList_remove(app->subghz_static_freqs, it); + } else { + FrequencyList_next(it); + } + } + app->save_subghz_frequencies = true; + scene_manager_previous_scene(app->scene_manager); + scene_manager_next_scene(app->scene_manager, CfwAppSceneProtocolsFrequenciesStatic); + break; + case VarItemListIndexAddStaticFreq: + scene_manager_set_scene_state( + app->scene_manager, CfwAppSceneProtocolsFrequenciesAdd, false); + scene_manager_next_scene(app->scene_manager, CfwAppSceneProtocolsFrequenciesAdd); + break; + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_protocols_frequencies_static_on_exit(void* context) { + CfwApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/cfw_app/scenes/cfw_app_scene_start.c b/applications/main/cfw_app/scenes/cfw_app_scene_start.c new file mode 100644 index 00000000000..197f032a43f --- /dev/null +++ b/applications/main/cfw_app/scenes/cfw_app_scene_start.c @@ -0,0 +1,71 @@ +#include "../cfw_app.h" + +enum VarItemListIndex { + VarItemListIndexInterface, + VarItemListIndexProtocols, + VarItemListIndexMisc, + // VarItemListIndexVersion, +}; + +void cfw_app_scene_start_var_item_list_callback(void* context, uint32_t index) { + CfwApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void cfw_app_scene_start_on_enter(void* context) { + CfwApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + + variable_item_list_add(var_item_list, "Interface", 0, NULL, app); + variable_item_list_add(var_item_list, "Protocols", 0, NULL, app); + variable_item_list_add(var_item_list, "Misc", 0, NULL, app); + variable_item_list_add(var_item_list, furi_string_get_cstr(app->version_tag), 0, NULL, app); + + variable_item_list_set_enter_callback( + var_item_list, cfw_app_scene_start_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, scene_manager_get_scene_state(app->scene_manager, CfwAppSceneStart)); + + view_dispatcher_switch_to_view(app->view_dispatcher, CfwAppViewVarItemList); +} + +bool cfw_app_scene_start_on_event(void* context, SceneManagerEvent event) { + CfwApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(app->scene_manager, CfwAppSceneStart, event.event); + consumed = true; + switch(event.event) { + case VarItemListIndexInterface: + scene_manager_next_scene(app->scene_manager, CfwAppSceneInterface); + break; + case VarItemListIndexProtocols: + scene_manager_next_scene(app->scene_manager, CfwAppSceneProtocols); + break; + case VarItemListIndexMisc: + scene_manager_next_scene(app->scene_manager, CfwAppSceneMisc); + break; + // case VarItemListIndexVersion: { + // if(storage_common_copy( + // furi_record_open(RECORD_STORAGE), + // EXT_PATH("dolphin/cfwfirstboot.bin"), + // EXT_PATH(".slideshow"))) { + // app->show_slideshow = true; + // cfw_app_apply(app); + // } + // break; + // } + default: + break; + } + } + + return consumed; +} + +void cfw_app_scene_start_on_exit(void* context) { + CfwApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/lfrfid/application.fam b/applications/main/lfrfid/application.fam index d143447b062..f79e1afa4de 100644 --- a/applications/main/lfrfid/application.fam +++ b/applications/main/lfrfid/application.fam @@ -1,6 +1,6 @@ App( appid="lfrfid", - name="125 kHz RFID", + name="RFID", apptype=FlipperAppType.APP, targets=["f7"], entry_point="lfrfid_app", diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 583b04b5ed7..4eb46ce0df3 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -87,6 +87,7 @@ Header,+,firmware/targets/furi_hal_include/furi_hal_usb_hid.h,, Header,+,firmware/targets/furi_hal_include/furi_hal_usb_hid_u2f.h,, Header,+,firmware/targets/furi_hal_include/furi_hal_version.h,, Header,+,firmware/targets/furi_hal_include/furi_hal_vibro.h,, +Header,+,lib/cfw/cfw.h,, Header,+,lib/drivers/rgb_backlight.h,, Header,+,lib/flipper_application/api_hashtable/api_hashtable.h,, Header,+,lib/flipper_application/api_hashtable/compilesort.hpp,, @@ -216,6 +217,8 @@ Header,+,lib/toolbox/tar/tar_archive.h,, Header,+,lib/toolbox/value_index.h,, Header,+,lib/toolbox/version.h,, Header,+,lib/u8g2/u8g2.h,, +Function,+,CFW_SETTINGS,CfwSettings*, +Function,+,CFW_SETTINGS_SAVE,void, Function,-,LL_ADC_CommonDeInit,ErrorStatus,ADC_Common_TypeDef* Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, const LL_ADC_CommonInitTypeDef*" Function,-,LL_ADC_CommonStructInit,void,LL_ADC_CommonInitTypeDef* @@ -1452,6 +1455,7 @@ Function,+,furi_hal_subghz_enable_ext_power,_Bool, Function,+,furi_hal_subghz_flush_rx,void, Function,+,furi_hal_subghz_flush_tx,void, Function,+,furi_hal_subghz_get_external_power_disable,_Bool, +Function,+,furi_hal_subghz_get_is_extended,_Bool, Function,+,furi_hal_subghz_get_lqi,uint8_t, Function,+,furi_hal_subghz_get_radio_type,SubGhzRadioType, Function,+,furi_hal_subghz_get_rolling_counter_mult,uint8_t, @@ -1478,6 +1482,7 @@ Function,+,furi_hal_subghz_set_async_mirror_pin,void,const GpioPin* Function,+,furi_hal_subghz_set_external_power_disable,void,_Bool Function,+,furi_hal_subghz_set_frequency,uint32_t,uint32_t Function,+,furi_hal_subghz_set_frequency_and_path,uint32_t,uint32_t +Function,+,furi_hal_subghz_set_is_extended,void,_Bool Function,+,furi_hal_subghz_set_path,void,FuriHalSubGhzPath Function,+,furi_hal_subghz_set_rolling_counter_mult,void,uint8_t Function,+,furi_hal_subghz_set_timestamp_file_names,void,_Bool diff --git a/firmware/targets/f7/furi_hal/furi_hal_light.c b/firmware/targets/f7/furi_hal/furi_hal_light.c index 73c720bc1de..20c3da0e8a4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_light.c +++ b/firmware/targets/f7/furi_hal/furi_hal_light.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #define LED_CURRENT_RED 50 diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 4553604299c..e682b441841 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -9,10 +9,10 @@ #include #include -#include - #include +#include + #include #include #include @@ -448,6 +448,37 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { return value; } +bool furi_hal_subghz_get_is_extended() { + bool is_extended = false; + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + + if(flipper_format_file_open_existing(file, "/ext/subghz/assets/extend_range.txt")) { + flipper_format_read_bool(file, "use_ext_range_at_own_risk", &is_extended, 1); + } + + flipper_format_free(file); + furi_record_close(RECORD_STORAGE); + return is_extended; +} + +void furi_hal_subghz_set_is_extended(bool is_extended) { + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + + do { + if(!flipper_format_file_open_always(file, "/ext/subghz/assets/extend_range.txt")) break; + if(!flipper_format_write_header_cstr(file, "Flipper SubGhz Setting File", 1)) break; + if(!flipper_format_write_comment_cstr( + file, "Whether to allow extended ranges that can break your flipper")) + break; + if(!flipper_format_write_bool(file, "use_ext_range_at_own_risk", &is_extended, 1)) break; + } while(0); + + flipper_format_free(file); + furi_record_close(RECORD_STORAGE); +} + bool furi_hal_subghz_is_tx_allowed(uint32_t value) { //checking regional settings bool is_extended = false; diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.h b/firmware/targets/f7/furi_hal/furi_hal_subghz.h index 35eab4faf83..8383c27f2de 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.h +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.h @@ -225,6 +225,18 @@ bool furi_hal_subghz_is_frequency_valid(uint32_t value); */ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value); +/** Read extend and bypass settings values into out params + * + * @return is_extended bool + */ +bool furi_hal_subghz_get_is_extended(); + +/** Set extend and bypass settings values to file + * + * @param is_extended bool for extend + */ +void furi_hal_subghz_set_is_extended(bool is_extended); + /** Сheck if transmission is allowed on this frequency with your current config * * @param value frequency in Hz diff --git a/furi/flipper.c b/furi/flipper.c index bc668dcf19f..e54a5320f66 100644 --- a/furi/flipper.c +++ b/furi/flipper.c @@ -4,6 +4,7 @@ #include #include #include +#include #define TAG "Flipper" @@ -45,6 +46,10 @@ void flipper_init() { flipper_start_service(&FLIPPER_SERVICES[0]); + // NAMESPOOF_INIT(); + // CFW_SETTINGS_LOAD(); + // CFW_ASSETS_LOAD(); + for(size_t i = 1; i < FLIPPER_SERVICES_COUNT; i++) { flipper_start_service(&FLIPPER_SERVICES[i]); } diff --git a/lib/SConscript b/lib/SConscript index 879fa2b7bbe..4cf62abf170 100644 --- a/lib/SConscript +++ b/lib/SConscript @@ -52,6 +52,7 @@ env.Append( ) ), File("u8g2/u8g2.h"), + File("cfw/cfw.h"), ], CPPDEFINES=[ '"M_MEMORY_FULL(x)=abort()"', diff --git a/lib/cfw/assets.c b/lib/cfw/assets.c new file mode 100644 index 00000000000..563f0deb658 --- /dev/null +++ b/lib/cfw/assets.c @@ -0,0 +1,166 @@ +#include "cfw.h" +#include "private.h" +#include +#include +#include + +#define TAG "CfwAssets" + +#define ICONS_FMT CFW_ASSETS_PATH "/%s/Icons/%s" + +// CfwAssets cfw_assets = { + // .A_Levelup_128x64 = &A_Levelup_128x64, + // .I_BLE_Pairing_128x64 = &I_BLE_Pairing_128x64, + // .I_DolphinCommon_56x48 = &I_DolphinCommon_56x48, + // .I_DolphinMafia_115x62 = &I_DolphinMafia_115x62, + // .I_DolphinNice_96x59 = &I_DolphinNice_96x59, + // .I_DolphinWait_61x59 = &I_DolphinWait_61x59, + // .I_iButtonDolphinVerySuccess_108x52 = &I_iButtonDolphinVerySuccess_108x52, + // .I_DolphinReadingSuccess_59x63 = &I_DolphinReadingSuccess_59x63, + // .I_Lockscreen = &I_Lockscreen, + // .I_WarningDolphin_45x42 = &I_WarningDolphin_45x42, + // .I_NFC_dolphin_emulation_47x61 = &I_NFC_dolphin_emulation_47x61, + // .I_passport_bad_46x49 = &I_passport_bad_46x49, + // .I_passport_DB = &I_passport_DB, + // .I_passport_happy_46x49 = &I_passport_happy_46x49, + // .I_passport_okay_46x49 = &I_passport_okay_46x49, + // .I_RFIDDolphinReceive_97x61 = &I_RFIDDolphinReceive_97x61, + // .I_RFIDDolphinSend_97x61 = &I_RFIDDolphinSend_97x61, + // .I_RFIDDolphinSuccess_108x57 = &I_RFIDDolphinSuccess_108x57, + // .I_Cry_dolph_55x52 = &I_Cry_dolph_55x52, + // .I_Background_128x11 = &I_Background_128x11, + // .I_Fishing_123x52 = &I_Fishing_123x52, + // .I_Scanning_123x52 = &I_Scanning_123x52, + // .I_Auth_62x31 = &I_Auth_62x31, + // .I_Connect_me_62x31 = &I_Connect_me_62x31, + // .I_Connected_62x31 = &I_Connected_62x31, + // .I_Error_62x31 = &I_Error_62x31, +// }; + +// void anim(const Icon** replace, const char* name, FuriString* path, File* file) { + // do { + // furi_string_printf(path, ICONS_FMT "/meta", CFW_SETTINGS()->asset_pack, name); + // if(!storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) + // break; + // int32_t width, height, frame_rate, frame_count; + // storage_file_read(file, &width, 4); + // storage_file_read(file, &height, 4); + // storage_file_read(file, &frame_rate, 4); + // storage_file_read(file, &frame_count, 4); + // storage_file_close(file); + + // Icon* icon = malloc(sizeof(Icon)); + // FURI_CONST_ASSIGN(icon->width, width); + // FURI_CONST_ASSIGN(icon->height, height); + // FURI_CONST_ASSIGN(icon->frame_rate, frame_rate); + // FURI_CONST_ASSIGN(icon->frame_count, frame_count); + // icon->frames = malloc(sizeof(const uint8_t*) * icon->frame_count); + // const char* pack = CFW_SETTINGS()->asset_pack; + + // bool ok = true; + // for(int i = 0; i < icon->frame_count; ++i) { + // FURI_CONST_ASSIGN_PTR(icon->frames[i], 0); + // if(ok) { + // ok = false; + // furi_string_printf(path, ICONS_FMT "/frame_%02d.bm", pack, name, i); + // do { + // if(!storage_file_open( + // file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) + // break; + + // uint64_t size = storage_file_size(file); + // FURI_CONST_ASSIGN_PTR(icon->frames[i], malloc(size)); + // if(storage_file_read(file, (void*)icon->frames[i], size) == size) ok = true; + // storage_file_close(file); + // } while(0); + // } + // } + // if(!ok) { + // for(int i = 0; i < icon->frame_count; ++i) { + // if(icon->frames[i]) { + // free((void*)icon->frames[i]); + // } + // } + // free((void*)icon->frames); + // free(icon); + + // break; + // } + + // *replace = icon; + // } while(false); +// } + +// void icon(const Icon** replace, const char* name, FuriString* path, File* file) { + // furi_string_printf(path, ICONS_FMT ".bmx", CFW_SETTINGS()->asset_pack, name); + // if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + // uint64_t size = storage_file_size(file) - 8; + // int32_t width, height; + // storage_file_read(file, &width, 4); + // storage_file_read(file, &height, 4); + + // Icon* icon = malloc(sizeof(Icon)); + // FURI_CONST_ASSIGN(icon->frame_count, 1); + // FURI_CONST_ASSIGN(icon->frame_rate, 0); + // FURI_CONST_ASSIGN(icon->width, width); + // FURI_CONST_ASSIGN(icon->height, height); + // icon->frames = malloc(sizeof(const uint8_t*)); + // FURI_CONST_ASSIGN_PTR(icon->frames[0], malloc(size)); + // storage_file_read(file, (void*)icon->frames[0], size); + // *replace = icon; + + // storage_file_close(file); + // } +// } + +// void swap(CfwAssets* x, FuriString* p, File* f) { + // anim(&x->A_Levelup_128x64, "Animations/Levelup_128x64", p, f); + // icon(&x->I_BLE_Pairing_128x64, "BLE/BLE_Pairing_128x64", p, f); + // icon(&x->I_DolphinCommon_56x48, "Dolphin/DolphinCommon_56x48", p, f); + // icon(&x->I_DolphinMafia_115x62, "iButton/DolphinMafia_115x62", p, f); + // icon(&x->I_DolphinNice_96x59, "iButton/DolphinNice_96x59", p, f); + // icon(&x->I_DolphinWait_61x59, "iButton/DolphinWait_61x59", p, f); + // icon(&x->I_iButtonDolphinVerySuccess_108x52, "iButton/iButtonDolphinVerySuccess_108x52", p, f); + // icon(&x->I_DolphinReadingSuccess_59x63, "Infrared/DolphinReadingSuccess_59x63", p, f); + // icon(&x->I_Lockscreen, "Interface/Lockscreen", p, f); + // icon(&x->I_WarningDolphin_45x42, "Interface/WarningDolphin_45x42", p, f); + // icon(&x->I_NFC_dolphin_emulation_47x61, "NFC/NFC_dolphin_emulation_47x61", p, f); + // icon(&x->I_passport_bad_46x49, "Passport/passport_bad_46x49", p, f); + // icon(&x->I_passport_DB, "Passport/passport_DB", p, f); + // icon(&x->I_passport_happy_46x49, "Passport/passport_happy_46x49", p, f); + // icon(&x->I_passport_okay_46x49, "Passport/passport_okay_46x49", p, f); + // icon(&x->I_RFIDDolphinReceive_97x61, "RFID/RFIDDolphinReceive_97x61", p, f); + // icon(&x->I_RFIDDolphinSend_97x61, "RFID/RFIDDolphinSend_97x61", p, f); + // icon(&x->I_RFIDDolphinSuccess_108x57, "RFID/RFIDDolphinSuccess_108x57", p, f); + // icon(&x->I_Cry_dolph_55x52, "Settings/Cry_dolph_55x52", p, f); + // icon(&x->I_Background_128x11, "StatusBar/Background_128x11", p, f); + // icon(&x->I_Fishing_123x52, "SubGhz/Fishing_123x52", p, f); + // icon(&x->I_Scanning_123x52, "SubGhz/Scanning_123x52", p, f); + // icon(&x->I_Auth_62x31, "U2F/Auth_62x31", p, f); + // icon(&x->I_Connect_me_62x31, "U2F/Connect_me_62x31", p, f); + // icon(&x->I_Connected_62x31, "U2F/Connected_62x31", p, f); + // icon(&x->I_Error_62x31, "U2F/Error_62x31", p, f); +// } + +void CFW_ASSETS_LOAD() { + CfwSettings* cfw_settings = CFW_SETTINGS(); + // if(cfw_settings->asset_pack[0] == '\0') return; + // cfw_assets.is_nsfw = strncmp(xtreme_settings->asset_pack, "NSFW", strlen("NSFW")) == 0; + + // Storage* storage = furi_record_open(RECORD_STORAGE); + // FileInfo info; + // FuriString* path = furi_string_alloc(); + // furi_string_printf(path, CFW_ASSETS_PATH "/%s", cfw_settings->asset_pack); + // if(storage_common_stat(storage, furi_string_get_cstr(path), &info) == FSE_OK && + // info.flags & FSF_DIRECTORY) { + // File* file = storage_file_alloc(storage); + // swap(&cfw_assets, path, file); + // storage_file_free(file); + // } + // furi_string_free(path); + // furi_record_close(RECORD_STORAGE); +} + +// CfwAssets* CFW_ASSETS() { + // return &cfw_assets; +// } diff --git a/lib/cfw/cfw.h b/lib/cfw/cfw.h new file mode 100644 index 00000000000..e69e0c364f7 --- /dev/null +++ b/lib/cfw/cfw.h @@ -0,0 +1,78 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CFW_SETTINGS_PATH CFG_PATH("cfw_settings.txt") +// #define CFW_ASSETS_PATH EXT_PATH("dolphin_custom") +#define CFW_APPS_PATH CFG_PATH("cfw_apps.txt") +#define CFW_ASSETS_PACK_NAME_LEN 32 + +typedef struct { + // char asset_pack[CFW_ASSETS_PACK_NAME_LEN]; + // uint32_t anim_speed; + // int32_t cycle_anims; + // bool unlock_anims; + // bool fallback_anim; + bool wii_menu; + bool bad_pins_format; + // bool lockscreen_time; + // bool lockscreen_seconds; + // bool lockscreen_date; + // bool lockscreen_statusbar; + // bool lockscreen_prompt; + // BatteryIcon battery_icon; + // bool status_icons; + // bool bar_borders; + // bool bar_background; + // bool sort_dirs_first; + bool dark_mode; + // uint32_t favorite_timeout; + // bool bad_bt; + // bool bad_bt_remember; + // int32_t butthurt_timer; + bool rgb_backlight; +} CfwSettings; + +void CFW_SETTINGS_SAVE(); +CfwSettings* CFW_SETTINGS(); + +// typedef struct { + // bool is_nsfw; + // const Icon* A_Levelup_128x64; + // const Icon* I_BLE_Pairing_128x64; + // const Icon* I_DolphinCommon_56x48; + // const Icon* I_DolphinMafia_115x62; + // const Icon* I_DolphinNice_96x59; + // const Icon* I_DolphinWait_61x59; + // const Icon* I_iButtonDolphinVerySuccess_108x52; + // const Icon* I_DolphinReadingSuccess_59x63; + // const Icon* I_Lockscreen; + // const Icon* I_WarningDolphin_45x42; + // const Icon* I_NFC_dolphin_emulation_47x61; + // const Icon* I_passport_bad_46x49; + // const Icon* I_passport_DB; + // const Icon* I_passport_happy_46x49; + // const Icon* I_passport_okay_46x49; + // const Icon* I_RFIDDolphinReceive_97x61; + // const Icon* I_RFIDDolphinSend_97x61; + // const Icon* I_RFIDDolphinSuccess_108x57; + // const Icon* I_Cry_dolph_55x52; + // const Icon* I_Background_128x11; + // const Icon* I_Fishing_123x52; + // const Icon* I_Scanning_123x52; + // const Icon* I_Auth_62x31; + // const Icon* I_Connect_me_62x31; + // const Icon* I_Connected_62x31; + // const Icon* I_Error_62x31; +// } CfwAssets; + +// CfwAssets* CFW_ASSETS(); + +#ifdef __cplusplus +} +#endif diff --git a/lib/cfw/namespoof.c b/lib/cfw/namespoof.c new file mode 100644 index 00000000000..3a5918a381f --- /dev/null +++ b/lib/cfw/namespoof.c @@ -0,0 +1,27 @@ +#include "namespoof.h" +#include +#include + +#define TAG "NameSpoof" + +void NAMESPOOF_INIT() { + FuriString* str = furi_string_alloc(); + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + + do { + uint32_t version; + if(!flipper_format_file_open_existing(file, NAMESPOOF_PATH)) break; + if(!flipper_format_read_header(file, str, &version)) break; + if(furi_string_cmp_str(str, NAMESPOOF_HEADER)) break; + if(version != NAMESPOOF_VERSION) break; + + if(!flipper_format_read_string(file, "Name", str)) break; + version_set_custom_name(NULL, strdup(furi_string_get_cstr(str))); + furi_hal_version_set_name(version_get_custom_name(NULL)); + } while(false); + + flipper_format_free(file); + furi_record_close(RECORD_STORAGE); + furi_string_free(str); +} diff --git a/lib/cfw/namespoof.h b/lib/cfw/namespoof.h new file mode 100644 index 00000000000..5d7e91a1fd4 --- /dev/null +++ b/lib/cfw/namespoof.h @@ -0,0 +1,5 @@ +#pragma once + +#define NAMESPOOF_HEADER "Flipper Name File" +#define NAMESPOOF_VERSION 1 +#define NAMESPOOF_PATH EXT_PATH("dolphin/name.txt") diff --git a/lib/cfw/private.h b/lib/cfw/private.h new file mode 100644 index 00000000000..fc37f7eed91 --- /dev/null +++ b/lib/cfw/private.h @@ -0,0 +1,5 @@ +#pragma once + +void NAMESPOOF_INIT(); +void CFW_SETTINGS_LOAD(); +void CFW_ASSETS_LOAD(); diff --git a/lib/cfw/settings.c b/lib/cfw/settings.c new file mode 100644 index 00000000000..1e672e77c95 --- /dev/null +++ b/lib/cfw/settings.c @@ -0,0 +1,130 @@ +#include "cfw.h" +#include "private.h" +#include +#include + +#define TAG "CfwSettings" + +CfwSettings cfw_settings = { + // .asset_pack = "", + // .anim_speed = 100, // 100% + // .cycle_anims = 0, // Meta.txt + // .unlock_anims = false, // OFF + // .fallback_anim = true, // ON + .wii_menu = true, // ON + .bad_pins_format = false, // OFF + // .lockscreen_time = true, // ON + // .lockscreen_seconds = false, // OFF + // .lockscreen_date = true, // ON + // .lockscreen_statusbar = true, // ON + // .lockscreen_prompt = true, // ON + // .battery_icon = BatteryIconBarPercent, // Bar % + // .status_icons = true, // ON + // .bar_borders = true, // ON + // .bar_background = false, // OFF + // .sort_dirs_first = true, // ON + .dark_mode = false, // OFF + // .favorite_timeout = 0, // OFF + // .bad_bt = false, // USB + // .bad_bt_remember = false, // OFF + // .butthurt_timer = 21600, // 6 H + .rgb_backlight = false, // OFF +}; + +void CFW_SETTINGS_LOAD() { + CfwSettings* x = &cfw_settings; + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + if(flipper_format_file_open_existing(file, CFW_SETTINGS_PATH)) { + FuriString* string = furi_string_alloc(); + // if(flipper_format_read_string(file, "asset_pack", string)) { + // strlcpy(x->asset_pack, furi_string_get_cstr(string), CFW_ASSETS_PACK_NAME_LEN); + // } + furi_string_free(string); + // flipper_format_rewind(file); + // flipper_format_read_uint32(file, "anim_speed", &x->anim_speed, 1); + // flipper_format_rewind(file); + // flipper_format_read_int32(file, "cycle_anims", &x->cycle_anims, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "unlock_anims", &x->unlock_anims, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "fallback_anim", &x->fallback_anim, 1); + flipper_format_rewind(file); + flipper_format_read_bool(file, "wii_menu", &x->wii_menu, 1); + flipper_format_rewind(file); + flipper_format_read_bool(file, "bad_pins_format", &x->bad_pins_format, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "lockscreen_time", &x->lockscreen_time, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "lockscreen_seconds", &x->lockscreen_seconds, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "lockscreen_date", &x->lockscreen_date, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "lockscreen_statusbar", &x->lockscreen_statusbar, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "lockscreen_prompt", &x->lockscreen_prompt, 1); + // flipper_format_rewind(file); + // flipper_format_read_uint32(file, "battery_icon", (uint32_t*)&x->battery_icon, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "status_icons", &x->status_icons, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "bar_borders", &x->bar_borders, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "bar_background", &x->bar_background, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "sort_dirs_first", &x->sort_dirs_first, 1); + flipper_format_rewind(file); + flipper_format_read_bool(file, "dark_mode", &x->dark_mode, 1); + // flipper_format_rewind(file); + // flipper_format_read_uint32(file, "favorite_timeout", &x->favorite_timeout, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "bad_bt", &x->bad_bt, 1); + // flipper_format_rewind(file); + // flipper_format_read_bool(file, "bad_bt_remember", &x->bad_bt_remember, 1); + // flipper_format_rewind(file); + // flipper_format_read_int32(file, "butthurt_timer", &x->butthurt_timer, 1); + flipper_format_rewind(file); + flipper_format_read_bool(file, "rgb_backlight", &x->rgb_backlight, 1); + } + flipper_format_free(file); + furi_record_close(RECORD_STORAGE); +} + +void CFW_SETTINGS_SAVE() { + if(!furi_hal_is_normal_boot()) return; + + CfwSettings* x = &cfw_settings; + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* file = flipper_format_file_alloc(storage); + if(flipper_format_file_open_always(file, CFW_SETTINGS_PATH)) { + // flipper_format_write_string_cstr(file, "asset_pack", x->asset_pack); + // flipper_format_write_uint32(file, "anim_speed", &x->anim_speed, 1); + // flipper_format_write_int32(file, "cycle_anims", &x->cycle_anims, 1); + // flipper_format_write_bool(file, "unlock_anims", &x->unlock_anims, 1); + // flipper_format_write_bool(file, "fallback_anim", &x->fallback_anim, 1); + flipper_format_write_bool(file, "wii_menu", &x->wii_menu, 1); + flipper_format_write_bool(file, "bad_pins_format", &x->bad_pins_format, 1); + // flipper_format_write_bool(file, "lockscreen_time", &x->lockscreen_time, 1); + // flipper_format_write_bool(file, "lockscreen_seconds", &x->lockscreen_seconds, 1); + // flipper_format_write_bool(file, "lockscreen_date", &x->lockscreen_date, 1); + // flipper_format_write_bool(file, "lockscreen_statusbar", &x->lockscreen_statusbar, 1); + // flipper_format_write_bool(file, "lockscreen_prompt", &x->lockscreen_prompt, 1); + // flipper_format_write_uint32(file, "battery_icon", (uint32_t*)&x->battery_icon, 1); + // flipper_format_write_bool(file, "status_icons", &x->status_icons, 1); + // flipper_format_write_bool(file, "bar_borders", &x->bar_borders, 1); + // flipper_format_write_bool(file, "bar_background", &x->bar_background, 1); + // flipper_format_write_bool(file, "sort_dirs_first", &x->sort_dirs_first, 1); + flipper_format_write_bool(file, "dark_mode", &x->dark_mode, 1); + // flipper_format_write_uint32(file, "favorite_timeout", &x->favorite_timeout, 1); + // flipper_format_write_bool(file, "bad_bt", &x->bad_bt, 1); + // flipper_format_write_bool(file, "bad_bt_remember", &x->bad_bt_remember, 1); + // flipper_format_write_int32(file, "butthurt_timer", &x->butthurt_timer, 1); + flipper_format_write_bool(file, "rgb_backlight", &x->rgb_backlight, 1); + } + flipper_format_free(file); + furi_record_close(RECORD_STORAGE); +} + +CfwSettings* CFW_SETTINGS() { + return &cfw_settings; +} diff --git a/lib/misc.scons b/lib/misc.scons index 3782c924b65..edf835563db 100644 --- a/lib/misc.scons +++ b/lib/misc.scons @@ -11,6 +11,7 @@ env.Append( "#/lib/micro-ecc", "#/lib/nanopb", "#/lib/u8g2", + "#/lib/cfw", ], CPPDEFINES=[ "PB_ENABLE_MALLOC", @@ -32,6 +33,7 @@ libs_recurse = [ "micro-ecc", "u8g2", "update_util", + "cfw", ] for lib in libs_recurse: