Merge remote-tracking branch 'OFW/dev' into dev

This commit is contained in:
MX 2024-09-07 22:31:11 +03:00
commit 6911ba12ad
No known key found for this signature in database
GPG key ID: 7CCC66B7DBDD1C83
44 changed files with 452 additions and 137 deletions

View file

@ -24,7 +24,7 @@ static void rpc_debug_app_tick_event_callback(void* context) {
static void static void
rpc_debug_app_format_hex(const uint8_t* data, size_t data_size, char* buf, size_t buf_size) { rpc_debug_app_format_hex(const uint8_t* data, size_t data_size, char* buf, size_t buf_size) {
if(data == NULL || data_size == 0) { if(data == NULL || data_size == 0) {
strncpy(buf, "<Data empty>", buf_size); strlcpy(buf, "<Data empty>", buf_size);
return; return;
} }

View file

@ -26,7 +26,7 @@ static void rpc_debug_app_scene_input_error_code_result_callback(void* context)
void rpc_debug_app_scene_input_error_code_on_enter(void* context) { void rpc_debug_app_scene_input_error_code_on_enter(void* context) {
RpcDebugApp* app = context; RpcDebugApp* app = context;
strncpy(app->text_store, "666", TEXT_STORE_SIZE); strlcpy(app->text_store, "666", TEXT_STORE_SIZE);
text_input_set_header_text(app->text_input, "Enter error code"); text_input_set_header_text(app->text_input, "Enter error code");
text_input_set_validator( text_input_set_validator(
app->text_input, rpc_debug_app_scene_input_error_code_validator_callback, NULL); app->text_input, rpc_debug_app_scene_input_error_code_validator_callback, NULL);

View file

@ -7,7 +7,7 @@ static void rpc_debug_app_scene_input_error_text_result_callback(void* context)
void rpc_debug_app_scene_input_error_text_on_enter(void* context) { void rpc_debug_app_scene_input_error_text_on_enter(void* context) {
RpcDebugApp* app = context; RpcDebugApp* app = context;
strncpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE); strlcpy(app->text_store, "I'm a scary error message!", TEXT_STORE_SIZE);
text_input_set_header_text(app->text_input, "Enter error text"); text_input_set_header_text(app->text_input, "Enter error text");
text_input_set_result_callback( text_input_set_result_callback(
app->text_input, app->text_input,

View file

@ -2,7 +2,7 @@
void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) { void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) {
RpcDebugApp* app = context; RpcDebugApp* app = context;
strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE); strlcpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);
text_box_set_text(app->text_box, app->text_store); text_box_set_text(app->text_box, app->text_store);
text_box_set_font(app->text_box, TextBoxFontHex); text_box_set_font(app->text_box, TextBoxFontHex);

View file

@ -257,7 +257,7 @@ static void example_thermo_draw_callback(Canvas* canvas, void* ctx) {
snprintf(text_store, TEXT_STORE_SIZE, "Temperature: %+.1f%c", (double)temp, temp_units); snprintf(text_store, TEXT_STORE_SIZE, "Temperature: %+.1f%c", (double)temp, temp_units);
} else { } else {
/* Or show a message that no data is available */ /* Or show a message that no data is available */
strncpy(text_store, "-- No data --", TEXT_STORE_SIZE); strlcpy(text_store, "-- No data --", TEXT_STORE_SIZE);
} }
canvas_draw_str_aligned(canvas, middle_x, 58, AlignCenter, AlignBottom, text_store); canvas_draw_str_aligned(canvas, middle_x, 58, AlignCenter, AlignBottom, text_store);

View file

@ -0,0 +1,51 @@
ID 1234:abcd Generic:USB Keyboard
REM Declare ourselves as a generic usb keyboard
REM This will install qFlipper on Linux/Gnome, using the latest AppImage package
REM Open a terminal
ALT F2
DELAY 1000
STRINGLN gnome-terminal --maximize
DELAY 1000
REM Ensure we have a folder to run executables from
STRINGLN mkdir -p $HOME/.local/bin
REM Download the latest AppImage
STRINGLN curl -fsSL "https://update.flipperzero.one/qFlipper/release/linux-amd64/AppImage" -o "$HOME/.local/bin/qFlipper"
DELAY 1000
REM Make it executable
STRINGLN chmod +x $HOME/.local/bin/qFlipper
REM Extract the appimage in /tmp to install icon and .desktop file
STRINGLN cd /tmp
STRINGLN $HOME/.local/bin/qFlipper --appimage-extract > /dev/null
STRINGLN sed "s@Exec=qFlipper@Exec=$HOME/.local/bin/qFlipper@" squashfs-root/usr/share/applications/qFlipper.desktop > $HOME/.local/share/applications/qFlipper.desktop
STRINGLN mkdir -p $HOME/.local/share/icons/hicolor/512x512/apps
STRINGLN cp squashfs-root/usr/share/icons/hicolor/512x512/apps/qFlipper.png $HOME/.local/share/icons/hicolor/512x512/apps/qFlipper.png
STRINGLN rm -rf squashfs-root
STRINGLN cd
REM Depending on the Linux distribution and display manager
REM there might be several ways to update desktop entries
REM try all
STRINGLN xdg-desktop-menu forceupdate || true
STRINGLN update-desktop-database ~/.local/share/applications || true
STRINGLN echo "
ENTER
REPEAT 60
STRINGLN ==========================================================================================
STRINGLN qFlipper has been installed to $HOME/.local/bin/
STRINGLN It should appear in your Applications menu.
STRINGLN If it does not, you might want to log out and log in again.
ENTER
STRINGLN If you prefer to run qFlipper from your terminal, either use the absolute path
STRINGLN or make sure $HOME/.local/bin/ is included in your PATH environment variable.
ENTER
STRINGLN Additional configurations might be required by your Linux distribution such as
STRINGLN group membership, udev rules or else.
STRINGLN ==========================================================================================
STRINGLN "

View file

@ -0,0 +1,87 @@
ID 1234:abcd Generic:USB Keyboard
REM Declare ourselves as a generic usb keyboard
REM You can override this to use something else
REM Check the `lsusb` command to know your own devices IDs
REM This is BadUSB demo script for Linux/Gnome
REM Open terminal window
DELAY 1000
ALT F2
DELAY 500
STRING gnome-terminal --maximize
DELAY 500
ENTER
DELAY 750
REM Clear the screen in case some banner was displayed
STRING clear
ENTER
REM Bigger shell script example
STRING cat > /dev/null << EOF
ENTER
STRING Hello World!
ENTER
DEFAULT_DELAY 50
STRING =
REPEAT 59
ENTER
ENTER
STRING _.-------.._ -,
ENTER
HOME
STRING .-"'''"--..,,_/ /'-, -, \
ENTER
HOME
STRING .:" /:/ /'\ \ ,_..., '. | |
ENTER
HOME
STRING / ,----/:/ /'\ _\~'_-"' _;
ENTER
HOME
STRING ' / /'"""'\ \ \.~'_-' ,-"'/
ENTER
HOME
STRING | | | 0 | | .-' ,/' /
ENTER
HOME
STRING | ,..\ \ ,.-"' ,/' /
ENTER
HOME
STRING ; : '/'""\' ,/--==,/-----,
ENTER
HOME
STRING | '-...| -.___-Z:_______J...---;
ENTER
HOME
STRING : ' _-'
ENTER
HOME
STRING _L_ _ ___ ___ ___ ___ ____--"'
ENTER
HOME
STRING | __|| | |_ _|| _ \| _ \| __|| _ \
ENTER
HOME
STRING | _| | |__ | | | _/| _/| _| | /
ENTER
HOME
STRING |_| |____||___||_| |_| |___||_|_\
ENTER
HOME
ENTER
STRING Flipper Zero BadUSB feature is compatible with USB Rubber Ducky script format
ENTER
STRING More information about script syntax can be found here:
ENTER
STRING https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/file_formats/BadUsbScriptFormat.md
ENTER
STRING EOF
ENTER

View file

@ -183,7 +183,7 @@ bool ibutton_load_key(iButton* ibutton, bool show_error) {
FuriString* tmp = furi_string_alloc(); FuriString* tmp = furi_string_alloc();
path_extract_filename(ibutton->file_path, tmp, true); path_extract_filename(ibutton->file_path, tmp, true);
strncpy(ibutton->key_name, furi_string_get_cstr(tmp), IBUTTON_KEY_NAME_SIZE); strlcpy(ibutton->key_name, furi_string_get_cstr(tmp), IBUTTON_KEY_NAME_SIZE);
furi_string_free(tmp); furi_string_free(tmp);
} else if(show_error) { } else if(show_error) {
@ -243,7 +243,7 @@ bool ibutton_delete_key(iButton* ibutton) {
} }
void ibutton_reset_key(iButton* ibutton) { void ibutton_reset_key(iButton* ibutton) {
memset(ibutton->key_name, 0, IBUTTON_KEY_NAME_SIZE + 1); ibutton->key_name[0] = '\0';
furi_string_reset(ibutton->file_path); furi_string_reset(ibutton->file_path);
ibutton_key_reset(ibutton->key); ibutton_key_reset(ibutton->key);
} }

View file

@ -32,7 +32,7 @@
#define IBUTTON_APP_FILENAME_PREFIX "iBtn" #define IBUTTON_APP_FILENAME_PREFIX "iBtn"
#define IBUTTON_APP_FILENAME_EXTENSION ".ibtn" #define IBUTTON_APP_FILENAME_EXTENSION ".ibtn"
#define IBUTTON_KEY_NAME_SIZE 22 #define IBUTTON_KEY_NAME_SIZE 23
typedef enum { typedef enum {
iButtonWriteModeInvalid, iButtonWriteModeInvalid,
@ -56,7 +56,7 @@ struct iButton {
iButtonWriteMode write_mode; iButtonWriteMode write_mode;
FuriString* file_path; FuriString* file_path;
char key_name[IBUTTON_KEY_NAME_SIZE + 1]; char key_name[IBUTTON_KEY_NAME_SIZE];
Submenu* submenu; Submenu* submenu;
ByteInput* byte_input; ByteInput* byte_input;

View file

@ -43,8 +43,8 @@
#define INFRARED_TEXT_STORE_NUM 2 #define INFRARED_TEXT_STORE_NUM 2
#define INFRARED_TEXT_STORE_SIZE 128 #define INFRARED_TEXT_STORE_SIZE 128
#define INFRARED_MAX_BUTTON_NAME_LENGTH 22 #define INFRARED_MAX_BUTTON_NAME_LENGTH 23
#define INFRARED_MAX_REMOTE_NAME_LENGTH 22 #define INFRARED_MAX_REMOTE_NAME_LENGTH 23
#define INFRARED_APP_FOLDER EXT_PATH("infrared") #define INFRARED_APP_FOLDER EXT_PATH("infrared")
#define INFRARED_APP_EXTENSION ".ir" #define INFRARED_APP_EXTENSION ".ir"

View file

@ -39,7 +39,7 @@ void infrared_scene_edit_rename_on_enter(void* context) {
furi_check(current_button_index != InfraredButtonIndexNone); furi_check(current_button_index != InfraredButtonIndexNone);
enter_name_length = INFRARED_MAX_BUTTON_NAME_LENGTH; enter_name_length = INFRARED_MAX_BUTTON_NAME_LENGTH;
strncpy( strlcpy(
infrared->text_store[0], infrared->text_store[0],
infrared_remote_get_signal_name(remote, current_button_index), infrared_remote_get_signal_name(remote, current_button_index),
enter_name_length); enter_name_length);
@ -47,7 +47,7 @@ void infrared_scene_edit_rename_on_enter(void* context) {
} else if(edit_target == InfraredEditTargetRemote) { } else if(edit_target == InfraredEditTargetRemote) {
text_input_set_header_text(text_input, "Name the remote"); text_input_set_header_text(text_input, "Name the remote");
enter_name_length = INFRARED_MAX_REMOTE_NAME_LENGTH; enter_name_length = INFRARED_MAX_REMOTE_NAME_LENGTH;
strncpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length); strlcpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length);
FuriString* folder_path; FuriString* folder_path;
folder_path = furi_string_alloc(); folder_path = furi_string_alloc();

View file

@ -51,8 +51,7 @@ static bool animation_storage_load_single_manifest_info(
if(furi_string_cmp_str(read_string, name)) break; if(furi_string_cmp_str(read_string, name)) break;
flipper_format_set_strict_mode(file, true); flipper_format_set_strict_mode(file, true);
manifest_info->name = malloc(furi_string_size(read_string) + 1); manifest_info->name = strdup(furi_string_get_cstr(read_string));
strcpy((char*)manifest_info->name, furi_string_get_cstr(read_string));
if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break; if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break;
manifest_info->min_butthurt = u32value; manifest_info->min_butthurt = u32value;
@ -104,9 +103,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis
storage_animation->manifest_info.name = NULL; storage_animation->manifest_info.name = NULL;
if(!flipper_format_read_string(file, "Name", read_string)) break; if(!flipper_format_read_string(file, "Name", read_string)) break;
storage_animation->manifest_info.name = malloc(furi_string_size(read_string) + 1); storage_animation->manifest_info.name = strdup(furi_string_get_cstr(read_string));
strcpy(
(char*)storage_animation->manifest_info.name, furi_string_get_cstr(read_string));
if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break; if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break;
storage_animation->manifest_info.min_butthurt = u32value; storage_animation->manifest_info.min_butthurt = u32value;
@ -400,8 +397,7 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo
furi_string_replace_all(str, "\\n", "\n"); furi_string_replace_all(str, "\\n", "\n");
FURI_CONST_ASSIGN_PTR(bubble->bubble.text, malloc(furi_string_size(str) + 1)); FURI_CONST_ASSIGN_PTR(bubble->bubble.text, strdup(furi_string_get_cstr(str)));
strcpy((char*)bubble->bubble.text, furi_string_get_cstr(str));
if(!flipper_format_read_string(ff, "AlignH", str)) break; if(!flipper_format_read_string(ff, "AlignH", str)) break;
if(!animation_storage_cast_align(str, (Align*)&bubble->bubble.align_h)) break; if(!animation_storage_cast_align(str, (Align*)&bubble->bubble.align_h)) break;

View file

@ -47,6 +47,26 @@ void dolphin_deed(DolphinDeed deed) {
furi_record_close(RECORD_DOLPHIN); furi_record_close(RECORD_DOLPHIN);
} }
void dolphin_get_settings(Dolphin* dolphin, DolphinSettings* settings) {
furi_check(dolphin);
furi_check(settings);
DolphinEvent event;
event.type = DolphinEventTypeSettingsGet;
event.settings = settings;
dolphin_event_send_wait(dolphin, &event);
}
void dolphin_set_settings(Dolphin* dolphin, DolphinSettings* settings) {
furi_check(dolphin);
furi_check(settings);
DolphinEvent event;
event.type = DolphinEventTypeSettingsSet;
event.settings = settings;
dolphin_event_send_wait(dolphin, &event);
}
DolphinStats dolphin_stats(Dolphin* dolphin) { DolphinStats dolphin_stats(Dolphin* dolphin) {
furi_check(dolphin); furi_check(dolphin);
@ -211,7 +231,9 @@ static bool dolphin_process_event(FuriEventLoopObject* object, void* context) {
} else if(event.type == DolphinEventTypeStats) { } else if(event.type == DolphinEventTypeStats) {
event.stats->icounter = dolphin->state->data.icounter; event.stats->icounter = dolphin->state->data.icounter;
event.stats->butthurt = dolphin->state->data.butthurt; event.stats->butthurt = (dolphin->state->data.flags & DolphinFlagHappyMode) ?
0 :
dolphin->state->data.butthurt;
event.stats->timestamp = dolphin->state->data.timestamp; event.stats->timestamp = dolphin->state->data.timestamp;
event.stats->level = dolphin_get_level(dolphin->state->data.icounter); event.stats->level = dolphin_get_level(dolphin->state->data.icounter);
event.stats->level_up_is_pending = event.stats->level_up_is_pending =
@ -228,6 +250,15 @@ static bool dolphin_process_event(FuriEventLoopObject* object, void* context) {
dolphin_state_load(dolphin->state); dolphin_state_load(dolphin->state);
furi_event_loop_timer_start(dolphin->butthurt_timer, BUTTHURT_INCREASE_PERIOD_TICKS); furi_event_loop_timer_start(dolphin->butthurt_timer, BUTTHURT_INCREASE_PERIOD_TICKS);
} else if(event.type == DolphinEventTypeSettingsGet) {
event.settings->happy_mode = dolphin->state->data.flags & DolphinFlagHappyMode;
} else if(event.type == DolphinEventTypeSettingsSet) {
dolphin->state->data.flags &= ~DolphinFlagHappyMode;
if(event.settings->happy_mode) dolphin->state->data.flags |= DolphinFlagHappyMode;
dolphin->state->dirty = true;
dolphin_state_save(dolphin->state);
} else { } else {
furi_crash(); furi_crash();
} }

View file

@ -21,6 +21,10 @@ typedef struct {
bool level_up_is_pending; bool level_up_is_pending;
} DolphinStats; } DolphinStats;
typedef struct {
bool happy_mode;
} DolphinSettings;
typedef enum { typedef enum {
DolphinPubsubEventUpdate, DolphinPubsubEventUpdate,
} DolphinPubsubEvent; } DolphinPubsubEvent;
@ -31,6 +35,10 @@ typedef enum {
*/ */
void dolphin_deed(DolphinDeed deed); void dolphin_deed(DolphinDeed deed);
void dolphin_get_settings(Dolphin* dolphin, DolphinSettings* settings);
void dolphin_set_settings(Dolphin* dolphin, DolphinSettings* settings);
/** Retrieve dolphin stats /** Retrieve dolphin stats
* Thread safe, blocking * Thread safe, blocking
*/ */

View file

@ -13,6 +13,8 @@ typedef enum {
DolphinEventTypeFlush, DolphinEventTypeFlush,
DolphinEventTypeLevel, DolphinEventTypeLevel,
DolphinEventTypeReloadState, DolphinEventTypeReloadState,
DolphinEventTypeSettingsGet,
DolphinEventTypeSettingsSet,
} DolphinEventType; } DolphinEventType;
typedef struct { typedef struct {
@ -21,6 +23,7 @@ typedef struct {
union { union {
DolphinDeed deed; DolphinDeed deed;
DolphinStats* stats; DolphinStats* stats;
DolphinSettings* settings;
}; };
} DolphinEvent; } DolphinEvent;

View file

@ -5,6 +5,10 @@
#include "dolphin_deed.h" #include "dolphin_deed.h"
typedef enum {
DolphinFlagHappyMode = 1,
} DolphinFlags;
typedef struct DolphinState DolphinState; typedef struct DolphinState DolphinState;
typedef struct { typedef struct {
uint8_t icounter_daily_limit[DolphinAppMAX]; uint8_t icounter_daily_limit[DolphinAppMAX];

View file

@ -767,7 +767,7 @@ static bool loader_do_signal(Loader* loader, uint32_t signal, void* arg) {
static bool loader_do_get_application_name(Loader* loader, FuriString* name) { static bool loader_do_get_application_name(Loader* loader, FuriString* name) {
if(loader_is_application_running(loader)) { if(loader_is_application_running(loader)) {
furi_string_set(name, furi_thread_get_name(loader->app.thread)); furi_string_set(name, furi_thread_get_name(furi_thread_get_id(loader->app.thread)));
return true; return true;
} }

View file

@ -226,9 +226,7 @@ static void rpc_system_storage_list_root(const PB_Main* request, void* context)
response.content.storage_list_response.file[i].data = NULL; response.content.storage_list_response.file[i].data = NULL;
response.content.storage_list_response.file[i].size = 0; response.content.storage_list_response.file[i].size = 0;
response.content.storage_list_response.file[i].type = PB_Storage_File_FileType_DIR; response.content.storage_list_response.file[i].type = PB_Storage_File_FileType_DIR;
char* str = malloc(strlen(hard_coded_dirs[i]) + 1); response.content.storage_list_response.file[i].name = strdup(hard_coded_dirs[i]);
strcpy(str, hard_coded_dirs[i]);
response.content.storage_list_response.file[i].name = str;
} }
rpc_send_and_release(session, &response); rpc_send_and_release(session, &response);

View file

@ -1,5 +1,6 @@
#include <furi.h> #include <furi.h>
#include <gui/modules/popup.h> #include <gui/modules/popup.h>
#include <gui/modules/dialog_ex.h>
#include <gui/scene_manager.h> #include <gui/scene_manager.h>
#include <namechanger/namechanger.h> #include <namechanger/namechanger.h>
#include <flipper_format/flipper_format.h> #include <flipper_format/flipper_format.h>
@ -48,6 +49,7 @@ DesktopSettingsApp* desktop_settings_app_alloc(void) {
app->pin_input_view = desktop_view_pin_input_alloc(); app->pin_input_view = desktop_view_pin_input_alloc();
app->pin_setup_howto_view = desktop_settings_view_pin_setup_howto_alloc(); app->pin_setup_howto_view = desktop_settings_view_pin_setup_howto_alloc();
app->pin_setup_howto2_view = desktop_settings_view_pin_setup_howto2_alloc(); app->pin_setup_howto2_view = desktop_settings_view_pin_setup_howto2_alloc();
app->dialog_ex = dialog_ex_alloc();
view_dispatcher_add_view( view_dispatcher_add_view(
app->view_dispatcher, DesktopSettingsAppViewMenu, submenu_get_view(app->submenu)); app->view_dispatcher, DesktopSettingsAppViewMenu, submenu_get_view(app->submenu));
@ -69,6 +71,8 @@ DesktopSettingsApp* desktop_settings_app_alloc(void) {
app->view_dispatcher, app->view_dispatcher,
DesktopSettingsAppViewIdPinSetupHowto2, DesktopSettingsAppViewIdPinSetupHowto2,
desktop_settings_view_pin_setup_howto2_get_view(app->pin_setup_howto2_view)); desktop_settings_view_pin_setup_howto2_get_view(app->pin_setup_howto2_view));
view_dispatcher_add_view(
app->view_dispatcher, DesktopSettingsAppViewDialogEx, dialog_ex_get_view(app->dialog_ex));
// Text Input // Text Input
app->text_input = text_input_alloc(); app->text_input = text_input_alloc();
@ -111,6 +115,7 @@ void desktop_settings_app_free(DesktopSettingsApp* app) {
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2);
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewDialogEx);
// TextInput // TextInput
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewTextInput); view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewTextInput);
text_input_free(app->text_input); text_input_free(app->text_input);
@ -121,6 +126,7 @@ void desktop_settings_app_free(DesktopSettingsApp* app) {
desktop_view_pin_input_free(app->pin_input_view); desktop_view_pin_input_free(app->pin_input_view);
desktop_settings_view_pin_setup_howto_free(app->pin_setup_howto_view); desktop_settings_view_pin_setup_howto_free(app->pin_setup_howto_view);
desktop_settings_view_pin_setup_howto2_free(app->pin_setup_howto2_view); desktop_settings_view_pin_setup_howto2_free(app->pin_setup_howto2_view);
dialog_ex_free(app->dialog_ex);
// View dispatcher // View dispatcher
view_dispatcher_free(app->view_dispatcher); view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager); scene_manager_free(app->scene_manager);

View file

@ -7,6 +7,7 @@
#include <gui/modules/submenu.h> #include <gui/modules/submenu.h>
#include <gui/modules/variable_item_list.h> #include <gui/modules/variable_item_list.h>
#include <gui/modules/text_input.h> #include <gui/modules/text_input.h>
#include <gui/modules/dialog_ex.h>
#include <dialogs/dialogs.h> #include <dialogs/dialogs.h>
#include <assets_icons.h> #include <assets_icons.h>
@ -25,6 +26,7 @@ typedef enum {
DesktopSettingsAppViewIdPinSetupHowto, DesktopSettingsAppViewIdPinSetupHowto,
DesktopSettingsAppViewIdPinSetupHowto2, DesktopSettingsAppViewIdPinSetupHowto2,
DesktopSettingsAppViewTextInput, DesktopSettingsAppViewTextInput,
DesktopSettingsAppViewDialogEx,
} DesktopSettingsAppView; } DesktopSettingsAppView;
typedef struct { typedef struct {
@ -41,6 +43,7 @@ typedef struct {
DesktopViewPinInput* pin_input_view; DesktopViewPinInput* pin_input_view;
DesktopSettingsViewPinSetupHowto* pin_setup_howto_view; DesktopSettingsViewPinSetupHowto* pin_setup_howto_view;
DesktopSettingsViewPinSetupHowto2* pin_setup_howto2_view; DesktopSettingsViewPinSetupHowto2* pin_setup_howto2_view;
DialogEx* dialog_ex;
DesktopPinCode pincode_buffer; DesktopPinCode pincode_buffer;
bool pincode_buffer_filled; bool pincode_buffer_filled;

View file

@ -0,0 +1,26 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
// reserve 100 for button presses, submenu selections, etc.
DesktopSettingsCustomEventExit = 100,
DesktopSettingsCustomEventDone,
DesktopSettingsCustomEvent1stPinEntered,
DesktopSettingsCustomEventPinsEqual,
DesktopSettingsCustomEventPinsDifferent,
DesktopSettingsCustomEventSetPin,
DesktopSettingsCustomEventChangePin,
DesktopSettingsCustomEventDisablePin,
DesktopSettingsCustomEventSetDefault,
DesktopSettingsCustomEventSetDummy,
} DesktopSettingsCustomEvent;
#ifdef __cplusplus
}
#endif

View file

@ -12,3 +12,5 @@ ADD_SCENE(desktop_settings, pin_setup_done, PinSetupDone)
ADD_SCENE(desktop_settings, change_name, ChangeName) ADD_SCENE(desktop_settings, change_name, ChangeName)
ADD_SCENE(desktop_settings, name_popup, NamePopup) ADD_SCENE(desktop_settings, name_popup, NamePopup)
ADD_SCENE(desktop_settings, happy_mode, HappyMode)

View file

@ -191,7 +191,7 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e
if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) { if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) {
submenu_reset(app->submenu); // Prevent menu from being shown when we exiting scene submenu_reset(app->submenu); // Prevent menu from being shown when we exiting scene
strncpy( strlcpy(
curr_favorite_app->name_or_path, curr_favorite_app->name_or_path,
furi_string_get_cstr(temp_path), furi_string_get_cstr(temp_path),
sizeof(curr_favorite_app->name_or_path)); sizeof(curr_favorite_app->name_or_path));
@ -201,7 +201,7 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e
size_t app_index = event.event - MAIN_LIST_APPLICATION_OFFSET; size_t app_index = event.event - MAIN_LIST_APPLICATION_OFFSET;
const char* name = favorite_fap_get_app_name(app_index); const char* name = favorite_fap_get_app_name(app_index);
if(name) if(name)
strncpy( strlcpy(
curr_favorite_app->name_or_path, curr_favorite_app->name_or_path,
name, name,
sizeof(curr_favorite_app->name_or_path)); sizeof(curr_favorite_app->name_or_path));

View file

@ -0,0 +1,64 @@
#include <furi.h>
#include <gui/scene_manager.h>
#include <gui/view_dispatcher.h>
#include <gui/modules/dialog_ex.h>
#include <dolphin/dolphin.h>
#include "desktop_settings_scene.h"
#include "../desktop_settings_app.h"
#include "../desktop_settings_custom_event.h"
static void desktop_settings_scene_happy_mode_done_callback(DialogExResult result, void* context) {
DesktopSettingsApp* app = context;
DolphinSettings settings;
Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN);
dolphin_get_settings(dolphin, &settings);
settings.happy_mode = (result == DialogExResultRight);
dolphin_set_settings(dolphin, &settings);
furi_record_close(RECORD_DOLPHIN);
view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
}
void desktop_settings_scene_happy_mode_on_enter(void* context) {
DesktopSettingsApp* app = context;
Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN);
DolphinSettings settings;
dolphin_get_settings(dolphin, &settings);
furi_record_close(RECORD_DOLPHIN);
dialog_ex_set_header(app->dialog_ex, "Happy Mode", 64, 0, AlignCenter, AlignTop);
dialog_ex_set_text(
app->dialog_ex,
"I will never get angry at you\nfor not spending time with me\nas long as this mode is enabled",
64,
30,
AlignCenter,
AlignCenter);
dialog_ex_set_left_button_text(app->dialog_ex, settings.happy_mode ? "Disable" : "Go back");
dialog_ex_set_right_button_text(
app->dialog_ex, settings.happy_mode ? "Keep enabled" : "Enable");
dialog_ex_set_result_callback(app->dialog_ex, desktop_settings_scene_happy_mode_done_callback);
dialog_ex_set_context(app->dialog_ex, app);
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewDialogEx);
}
bool desktop_settings_scene_happy_mode_on_event(void* context, SceneManagerEvent event) {
DesktopSettingsApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) {
case DesktopSettingsCustomEventExit:
scene_manager_previous_scene(app->scene_manager);
consumed = true;
break;
default:
furi_crash();
}
}
return consumed;
}
void desktop_settings_scene_happy_mode_on_exit(void* context) {
UNUSED(context);
}

View file

@ -3,15 +3,12 @@
#include <gui/scene_manager.h> #include <gui/scene_manager.h>
#include <desktop/helpers/pin_code.h> #include <desktop/helpers/pin_code.h>
#include "../desktop_settings_app.h" #include "../desktop_settings_app.h"
#include "../desktop_settings_custom_event.h"
#include <desktop/desktop_settings.h> #include <desktop/desktop_settings.h>
#include <desktop/views/desktop_view_pin_input.h> #include <desktop/views/desktop_view_pin_input.h>
#include "desktop_settings_scene.h" #include "desktop_settings_scene.h"
#include "desktop_settings_scene_i.h" #include "desktop_settings_scene_i.h"
#define SCENE_EVENT_EXIT (0U)
#define SCENE_EVENT_PINS_EQUAL (1U)
#define SCENE_EVENT_PINS_DIFFERENT (2U)
static void pin_auth_done_callback(const DesktopPinCode* pin_code, void* context) { static void pin_auth_done_callback(const DesktopPinCode* pin_code, void* context) {
furi_assert(pin_code); furi_assert(pin_code);
furi_assert(context); furi_assert(context);
@ -20,15 +17,17 @@ static void pin_auth_done_callback(const DesktopPinCode* pin_code, void* context
app->pincode_buffer = *pin_code; app->pincode_buffer = *pin_code;
if(desktop_pin_code_check(pin_code)) { if(desktop_pin_code_check(pin_code)) {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_EQUAL); view_dispatcher_send_custom_event(
app->view_dispatcher, DesktopSettingsCustomEventPinsEqual);
} else { } else {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_DIFFERENT); view_dispatcher_send_custom_event(
app->view_dispatcher, DesktopSettingsCustomEventPinsDifferent);
} }
} }
static void pin_auth_back_callback(void* context) { static void pin_auth_back_callback(void* context) {
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
} }
void desktop_settings_scene_pin_auth_on_enter(void* context) { void desktop_settings_scene_pin_auth_on_enter(void* context) {
@ -54,13 +53,13 @@ bool desktop_settings_scene_pin_auth_on_event(void* context, SceneManagerEvent e
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) { switch(event.event) {
case SCENE_EVENT_PINS_DIFFERENT: case DesktopSettingsCustomEventPinsDifferent:
scene_manager_set_scene_state( scene_manager_set_scene_state(
app->scene_manager, DesktopSettingsAppScenePinError, SCENE_STATE_PIN_ERROR_WRONG); app->scene_manager, DesktopSettingsAppScenePinError, SCENE_STATE_PIN_ERROR_WRONG);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinError); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinError);
consumed = true; consumed = true;
break; break;
case SCENE_EVENT_PINS_EQUAL: { case DesktopSettingsCustomEventPinsEqual: {
uint32_t state = uint32_t state =
scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppScenePinAuth); scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppScenePinAuth);
if(state == SCENE_STATE_PIN_AUTH_CHANGE_PIN) { if(state == SCENE_STATE_PIN_AUTH_CHANGE_PIN) {
@ -73,7 +72,7 @@ bool desktop_settings_scene_pin_auth_on_event(void* context, SceneManagerEvent e
consumed = true; consumed = true;
break; break;
} }
case SCENE_EVENT_EXIT: case DesktopSettingsCustomEventExit:
scene_manager_search_and_switch_to_previous_scene( scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu); app->scene_manager, DesktopSettingsAppScenePinMenu);
consumed = true; consumed = true;

View file

@ -3,15 +3,14 @@
#include <gui/modules/popup.h> #include <gui/modules/popup.h>
#include "../desktop_settings_app.h" #include "../desktop_settings_app.h"
#include "../desktop_settings_custom_event.h"
#include <desktop/desktop_settings.h> #include <desktop/desktop_settings.h>
#include "desktop_settings_scene.h" #include "desktop_settings_scene.h"
#define SCENE_EVENT_EXIT (0U)
static void pin_disable_back_callback(void* context) { static void pin_disable_back_callback(void* context) {
furi_assert(context); furi_assert(context);
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
} }
void desktop_settings_scene_pin_disable_on_enter(void* context) { void desktop_settings_scene_pin_disable_on_enter(void* context) {
@ -35,7 +34,7 @@ bool desktop_settings_scene_pin_disable_on_event(void* context, SceneManagerEven
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) { switch(event.event) {
case SCENE_EVENT_EXIT: case DesktopSettingsCustomEventExit:
scene_manager_search_and_switch_to_previous_scene( scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu); app->scene_manager, DesktopSettingsAppScenePinMenu);
consumed = true; consumed = true;

View file

@ -8,20 +8,19 @@
#include "desktop_settings_scene_i.h" #include "desktop_settings_scene_i.h"
#include <desktop/helpers/pin_code.h> #include <desktop/helpers/pin_code.h>
#include "../desktop_settings_app.h" #include "../desktop_settings_app.h"
#include "../desktop_settings_custom_event.h"
#define SCENE_EVENT_EXIT (0U)
static void pin_error_back_callback(void* context) { static void pin_error_back_callback(void* context) {
furi_assert(context); furi_assert(context);
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
} }
static void pin_error_done_callback(const DesktopPinCode* pin_code, void* context) { static void pin_error_done_callback(const DesktopPinCode* pin_code, void* context) {
UNUSED(pin_code); UNUSED(pin_code);
furi_assert(context); furi_assert(context);
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
} }
void desktop_settings_scene_pin_error_on_enter(void* context) { void desktop_settings_scene_pin_error_on_enter(void* context) {
@ -55,7 +54,7 @@ bool desktop_settings_scene_pin_error_on_event(void* context, SceneManagerEvent
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) { switch(event.event) {
case SCENE_EVENT_EXIT: case DesktopSettingsCustomEventExit:
scene_manager_previous_scene(app->scene_manager); scene_manager_previous_scene(app->scene_manager);
consumed = true; consumed = true;
break; break;

View file

@ -4,10 +4,7 @@
#include "../desktop_settings_app.h" #include "../desktop_settings_app.h"
#include "desktop_settings_scene.h" #include "desktop_settings_scene.h"
#include "desktop_settings_scene_i.h" #include "desktop_settings_scene_i.h"
#include "../desktop_settings_custom_event.h"
#define SCENE_EVENT_SET_PIN 0
#define SCENE_EVENT_CHANGE_PIN 1
#define SCENE_EVENT_DISABLE_PIN 2
static void desktop_settings_scene_pin_menu_submenu_callback(void* context, uint32_t index) { static void desktop_settings_scene_pin_menu_submenu_callback(void* context, uint32_t index) {
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
@ -23,7 +20,7 @@ void desktop_settings_scene_pin_menu_on_enter(void* context) {
submenu_add_item( submenu_add_item(
submenu, submenu,
"Set PIN", "Set PIN",
SCENE_EVENT_SET_PIN, DesktopSettingsCustomEventSetPin,
desktop_settings_scene_pin_menu_submenu_callback, desktop_settings_scene_pin_menu_submenu_callback,
app); app);
@ -31,14 +28,14 @@ void desktop_settings_scene_pin_menu_on_enter(void* context) {
submenu_add_item( submenu_add_item(
submenu, submenu,
"Change PIN", "Change PIN",
SCENE_EVENT_CHANGE_PIN, DesktopSettingsCustomEventChangePin,
desktop_settings_scene_pin_menu_submenu_callback, desktop_settings_scene_pin_menu_submenu_callback,
app); app);
submenu_add_item( submenu_add_item(
submenu, submenu,
"Remove PIN", "Remove PIN",
SCENE_EVENT_DISABLE_PIN, DesktopSettingsCustomEventDisablePin,
desktop_settings_scene_pin_menu_submenu_callback, desktop_settings_scene_pin_menu_submenu_callback,
app); app);
} }
@ -54,11 +51,11 @@ bool desktop_settings_scene_pin_menu_on_event(void* context, SceneManagerEvent e
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) { switch(event.event) {
case SCENE_EVENT_SET_PIN: case DesktopSettingsCustomEventSetPin:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto);
consumed = true; consumed = true;
break; break;
case SCENE_EVENT_CHANGE_PIN: case DesktopSettingsCustomEventChangePin:
scene_manager_set_scene_state( scene_manager_set_scene_state(
app->scene_manager, app->scene_manager,
DesktopSettingsAppScenePinAuth, DesktopSettingsAppScenePinAuth,
@ -66,7 +63,7 @@ bool desktop_settings_scene_pin_menu_on_event(void* context, SceneManagerEvent e
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinAuth); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinAuth);
consumed = true; consumed = true;
break; break;
case SCENE_EVENT_DISABLE_PIN: case DesktopSettingsCustomEventDisablePin:
scene_manager_set_scene_state( scene_manager_set_scene_state(
app->scene_manager, DesktopSettingsAppScenePinAuth, SCENE_STATE_PIN_AUTH_DISABLE); app->scene_manager, DesktopSettingsAppScenePinAuth, SCENE_STATE_PIN_AUTH_DISABLE);
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinAuth); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinAuth);

View file

@ -8,11 +8,7 @@
#include "desktop_settings_scene.h" #include "desktop_settings_scene.h"
#include "desktop_settings_scene_i.h" #include "desktop_settings_scene_i.h"
#include <desktop/helpers/pin_code.h> #include <desktop/helpers/pin_code.h>
#include "../desktop_settings_custom_event.h"
#define SCENE_EVENT_EXIT (0U)
#define SCENE_EVENT_1ST_PIN_ENTERED (1U)
#define SCENE_EVENT_PINS_EQUAL (2U)
#define SCENE_EVENT_PINS_DIFFERENT (3U)
static void pin_setup_done_callback(const DesktopPinCode* pin_code, void* context) { static void pin_setup_done_callback(const DesktopPinCode* pin_code, void* context) {
furi_assert(pin_code); furi_assert(pin_code);
@ -22,20 +18,23 @@ static void pin_setup_done_callback(const DesktopPinCode* pin_code, void* contex
if(!app->pincode_buffer_filled) { if(!app->pincode_buffer_filled) {
app->pincode_buffer = *pin_code; app->pincode_buffer = *pin_code;
app->pincode_buffer_filled = true; app->pincode_buffer_filled = true;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_1ST_PIN_ENTERED); view_dispatcher_send_custom_event(
app->view_dispatcher, DesktopSettingsCustomEvent1stPinEntered);
} else { } else {
app->pincode_buffer_filled = false; app->pincode_buffer_filled = false;
if(desktop_pin_code_is_equal(&app->pincode_buffer, pin_code)) { if(desktop_pin_code_is_equal(&app->pincode_buffer, pin_code)) {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_EQUAL); view_dispatcher_send_custom_event(
app->view_dispatcher, DesktopSettingsCustomEventPinsEqual);
} else { } else {
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_PINS_DIFFERENT); view_dispatcher_send_custom_event(
app->view_dispatcher, DesktopSettingsCustomEventPinsDifferent);
} }
} }
} }
static void pin_setup_back_callback(void* context) { static void pin_setup_back_callback(void* context) {
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT); view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
} }
void desktop_settings_scene_pin_setup_on_enter(void* context) { void desktop_settings_scene_pin_setup_on_enter(void* context) {
@ -60,7 +59,7 @@ bool desktop_settings_scene_pin_setup_on_event(void* context, SceneManagerEvent
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) { switch(event.event) {
case SCENE_EVENT_1ST_PIN_ENTERED: case DesktopSettingsCustomEvent1stPinEntered:
desktop_view_pin_input_set_label_button(app->pin_input_view, "OK"); desktop_view_pin_input_set_label_button(app->pin_input_view, "OK");
desktop_view_pin_input_set_label_primary(app->pin_input_view, 0, 0, NULL); desktop_view_pin_input_set_label_primary(app->pin_input_view, 0, 0, NULL);
desktop_view_pin_input_set_label_secondary( desktop_view_pin_input_set_label_secondary(
@ -69,7 +68,7 @@ bool desktop_settings_scene_pin_setup_on_event(void* context, SceneManagerEvent
desktop_view_pin_input_unlock_input(app->pin_input_view); desktop_view_pin_input_unlock_input(app->pin_input_view);
consumed = true; consumed = true;
break; break;
case SCENE_EVENT_PINS_DIFFERENT: case DesktopSettingsCustomEventPinsDifferent:
scene_manager_set_scene_state( scene_manager_set_scene_state(
app->scene_manager, app->scene_manager,
DesktopSettingsAppScenePinError, DesktopSettingsAppScenePinError,
@ -77,11 +76,11 @@ bool desktop_settings_scene_pin_setup_on_event(void* context, SceneManagerEvent
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinError); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinError);
consumed = true; consumed = true;
break; break;
case SCENE_EVENT_PINS_EQUAL: case DesktopSettingsCustomEventPinsEqual:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto2); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupHowto2);
consumed = true; consumed = true;
break; break;
case SCENE_EVENT_EXIT: { case DesktopSettingsCustomEventExit: {
uint32_t scene_found; uint32_t scene_found;
scene_found = scene_manager_search_and_switch_to_previous_scene( scene_found = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu); app->scene_manager, DesktopSettingsAppScenePinMenu);

View file

@ -5,18 +5,17 @@
#include <gui/view_dispatcher.h> #include <gui/view_dispatcher.h>
#include "../desktop_settings_app.h" #include "../desktop_settings_app.h"
#include "../desktop_settings_custom_event.h"
#include <desktop/desktop_settings.h> #include <desktop/desktop_settings.h>
#include <desktop/views/desktop_view_pin_input.h> #include <desktop/views/desktop_view_pin_input.h>
#include "desktop_settings_scene.h" #include "desktop_settings_scene.h"
#define SCENE_EVENT_DONE (0U)
static void pin_setup_done_callback(const DesktopPinCode* pin_code, void* context) { static void pin_setup_done_callback(const DesktopPinCode* pin_code, void* context) {
furi_assert(pin_code); furi_assert(pin_code);
furi_assert(context); furi_assert(context);
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_DONE); view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventDone);
} }
void desktop_settings_scene_pin_setup_done_on_enter(void* context) { void desktop_settings_scene_pin_setup_done_on_enter(void* context) {
@ -48,7 +47,7 @@ bool desktop_settings_scene_pin_setup_done_on_event(void* context, SceneManagerE
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) { switch(event.event) {
case SCENE_EVENT_DONE: { case DesktopSettingsCustomEventDone: {
bool scene_found = false; bool scene_found = false;
scene_found = scene_manager_search_and_switch_to_previous_scene( scene_found = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu); app->scene_manager, DesktopSettingsAppScenePinMenu);

View file

@ -5,12 +5,11 @@
#include "desktop_settings_scene.h" #include "desktop_settings_scene.h"
#include "../desktop_settings_app.h" #include "../desktop_settings_app.h"
#include "../views/desktop_settings_view_pin_setup_howto.h" #include "../views/desktop_settings_view_pin_setup_howto.h"
#include "../desktop_settings_custom_event.h"
#define SCENE_EXIT_EVENT (0U)
static void desktop_settings_scene_pin_lock_done_callback(void* context) { static void desktop_settings_scene_pin_lock_done_callback(void* context) {
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EXIT_EVENT); view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
} }
void desktop_settings_scene_pin_setup_howto_on_enter(void* context) { void desktop_settings_scene_pin_setup_howto_on_enter(void* context) {
@ -27,7 +26,7 @@ bool desktop_settings_scene_pin_setup_howto_on_event(void* context, SceneManager
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) { switch(event.event) {
case SCENE_EXIT_EVENT: case DesktopSettingsCustomEventExit:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetup); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetup);
consumed = true; consumed = true;
break; break;

View file

@ -4,18 +4,16 @@
#include "desktop_settings_scene.h" #include "desktop_settings_scene.h"
#include "../desktop_settings_app.h" #include "../desktop_settings_app.h"
#include "../views/desktop_settings_view_pin_setup_howto2.h" #include "../views/desktop_settings_view_pin_setup_howto2.h"
#include "../desktop_settings_custom_event.h"
#define SCENE_EXIT_EVENT (0U)
#define SCENE_DONE_EVENT (1U)
static void desktop_settings_scene_pin_setup_howto2_done_callback(void* context) { static void desktop_settings_scene_pin_setup_howto2_done_callback(void* context) {
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_DONE_EVENT); view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventDone);
} }
static void desktop_settings_scene_pin_setup_howto2_exit_callback(void* context) { static void desktop_settings_scene_pin_setup_howto2_exit_callback(void* context) {
DesktopSettingsApp* app = context; DesktopSettingsApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EXIT_EVENT); view_dispatcher_send_custom_event(app->view_dispatcher, DesktopSettingsCustomEventExit);
} }
void desktop_settings_scene_pin_setup_howto2_on_enter(void* context) { void desktop_settings_scene_pin_setup_howto2_on_enter(void* context) {
@ -35,12 +33,12 @@ bool desktop_settings_scene_pin_setup_howto2_on_event(void* context, SceneManage
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
switch(event.event) { switch(event.event) {
case SCENE_DONE_EVENT: { case DesktopSettingsCustomEventDone: {
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupDone); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppScenePinSetupDone);
consumed = true; consumed = true;
break; break;
} }
case SCENE_EXIT_EVENT: { case DesktopSettingsCustomEventExit: {
bool scene_found = false; bool scene_found = false;
scene_found = scene_manager_search_and_switch_to_previous_scene( scene_found = scene_manager_search_and_switch_to_previous_scene(
app->scene_manager, DesktopSettingsAppScenePinMenu); app->scene_manager, DesktopSettingsAppScenePinMenu);

View file

@ -11,6 +11,7 @@ typedef enum {
DesktopSettingsAutoLockDelay, DesktopSettingsAutoLockDelay,
DesktopSettingsBatteryDisplay, DesktopSettingsBatteryDisplay,
DesktopSettingsClockDisplay, DesktopSettingsClockDisplay,
DesktopSettingsHappyMode,
DesktopSettingsChangeName, DesktopSettingsChangeName,
DesktopSettingsFavoriteLeftShort, DesktopSettingsFavoriteLeftShort,
DesktopSettingsFavoriteLeftLong, DesktopSettingsFavoriteLeftLong,
@ -132,7 +133,7 @@ void desktop_settings_scene_start_on_enter(void* context) {
variable_item_list, variable_item_list,
"Show Clock", "Show Clock",
CLOCK_ENABLE_COUNT, CLOCK_ENABLE_COUNT,
desktop_settings_scene_start_clock_enable_changed, // desktop_settings_scene_start_clock_enable_changed,
app); app);
value_index = value_index =
@ -142,6 +143,8 @@ void desktop_settings_scene_start_on_enter(void* context) {
variable_item_list_add(variable_item_list, "Change Flipper Name", 0, NULL, app); variable_item_list_add(variable_item_list, "Change Flipper Name", 0, NULL, app);
variable_item_list_add(variable_item_list, "Happy Mode", 1, NULL, NULL);
variable_item_list_add(variable_item_list, "Favorite App - Left Short", 1, NULL, NULL); variable_item_list_add(variable_item_list, "Favorite App - Left Short", 1, NULL, NULL);
variable_item_list_add(variable_item_list, "Favorite App - Left Long", 1, NULL, NULL); variable_item_list_add(variable_item_list, "Favorite App - Left Long", 1, NULL, NULL);
variable_item_list_add(variable_item_list, "Favorite App - Right Short", 1, NULL, NULL); variable_item_list_add(variable_item_list, "Favorite App - Right Short", 1, NULL, NULL);
@ -275,6 +278,10 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite);
break; break;
case DesktopSettingsHappyMode:
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneHappyMode);
break;
default: default:
break; break;
} }

View file

@ -1,4 +1,5 @@
#include "../power_settings_app.h" #include "../power_settings_app.h"
#include <dolphin/dolphin.h>
void power_settings_scene_power_off_dialog_callback(DialogExResult result, void* context) { void power_settings_scene_power_off_dialog_callback(DialogExResult result, void* context) {
furi_assert(context); furi_assert(context);
@ -9,11 +10,23 @@ void power_settings_scene_power_off_dialog_callback(DialogExResult result, void*
void power_settings_scene_power_off_on_enter(void* context) { void power_settings_scene_power_off_on_enter(void* context) {
PowerSettingsApp* app = context; PowerSettingsApp* app = context;
DialogEx* dialog = app->dialog; DialogEx* dialog = app->dialog;
Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN);
DolphinSettings settings;
dolphin_get_settings(dolphin, &settings);
furi_record_close(RECORD_DOLPHIN);
dialog_ex_set_header(dialog, "Turn Off Device?", 64, 0, AlignCenter, AlignTop); dialog_ex_set_header(
dialog,
"Turn Off Device?",
64,
settings.happy_mode ? 32 : 0,
AlignCenter,
settings.happy_mode ? AlignCenter : AlignTop);
if(!settings.happy_mode) {
dialog_ex_set_text( dialog_ex_set_text(
dialog, " I will be\nwaiting for\n you here...", 78, 14, AlignLeft, AlignTop); dialog, " I will be\nwaiting for\n you here...", 78, 14, AlignLeft, AlignTop);
dialog_ex_set_icon(dialog, 14, 10, &I_dolph_cry_49x54); dialog_ex_set_icon(dialog, 14, 10, &I_dolph_cry_49x54);
}
dialog_ex_set_left_button_text(dialog, "Cancel"); dialog_ex_set_left_button_text(dialog, "Cancel");
dialog_ex_set_right_button_text(dialog, "Power Off"); dialog_ex_set_right_button_text(dialog, "Power Off");
dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback); dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback);

View file

@ -71,9 +71,9 @@ FuriEventLoop* furi_event_loop_alloc(void) {
PendingQueue_init(instance->pending_queue); PendingQueue_init(instance->pending_queue);
// Clear notification state and value // Clear notification state and value
xTaskNotifyStateClearIndexed(instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX); TaskHandle_t task = (TaskHandle_t)instance->thread_id;
ulTaskNotifyValueClearIndexed( xTaskNotifyStateClearIndexed(task, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX);
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, 0xFFFFFFFF); ulTaskNotifyValueClearIndexed(task, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, 0xFFFFFFFF);
return instance; return instance;
} }
@ -178,7 +178,7 @@ static void furi_event_loop_process_waiting_list(FuriEventLoop* instance) {
static void furi_event_loop_restore_flags(FuriEventLoop* instance, uint32_t flags) { static void furi_event_loop_restore_flags(FuriEventLoop* instance, uint32_t flags) {
if(flags) { if(flags) {
xTaskNotifyIndexed( xTaskNotifyIndexed(
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, flags, eSetBits); (TaskHandle_t)instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, flags, eSetBits);
} }
} }
@ -186,10 +186,11 @@ void furi_event_loop_run(FuriEventLoop* instance) {
furi_check(instance); furi_check(instance);
furi_check(instance->thread_id == furi_thread_get_current_id()); furi_check(instance->thread_id == furi_thread_get_current_id());
FuriThread* thread = furi_thread_get_current();
// Set the default signal callback if none was previously set // Set the default signal callback if none was previously set
if(furi_thread_get_signal_callback(instance->thread_id) == NULL) { if(furi_thread_get_signal_callback(thread) == NULL) {
furi_thread_set_signal_callback( furi_thread_set_signal_callback(thread, furi_event_loop_signal_callback, instance);
instance->thread_id, furi_event_loop_signal_callback, instance);
} }
furi_event_loop_init_tick(instance); furi_event_loop_init_tick(instance);
@ -233,8 +234,8 @@ void furi_event_loop_run(FuriEventLoop* instance) {
} }
// Disable the default signal callback // Disable the default signal callback
if(furi_thread_get_signal_callback(instance->thread_id) == furi_event_loop_signal_callback) { if(furi_thread_get_signal_callback(thread) == furi_event_loop_signal_callback) {
furi_thread_set_signal_callback(instance->thread_id, NULL, NULL); furi_thread_set_signal_callback(thread, NULL, NULL);
} }
} }
@ -242,7 +243,10 @@ void furi_event_loop_stop(FuriEventLoop* instance) {
furi_check(instance); furi_check(instance);
xTaskNotifyIndexed( xTaskNotifyIndexed(
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagStop, eSetBits); (TaskHandle_t)instance->thread_id,
FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX,
FuriEventLoopFlagStop,
eSetBits);
} }
/* /*
@ -265,7 +269,10 @@ void furi_event_loop_pend_callback(
PendingQueue_push_front(instance->pending_queue, item); PendingQueue_push_front(instance->pending_queue, item);
xTaskNotifyIndexed( xTaskNotifyIndexed(
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagPending, eSetBits); (TaskHandle_t)instance->thread_id,
FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX,
FuriEventLoopFlagPending,
eSetBits);
} }
/* /*
@ -473,7 +480,10 @@ static void furi_event_loop_item_notify(FuriEventLoopItem* instance) {
FURI_CRITICAL_EXIT(); FURI_CRITICAL_EXIT();
xTaskNotifyIndexed( xTaskNotifyIndexed(
owner->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagEvent, eSetBits); (TaskHandle_t)owner->thread_id,
FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX,
FuriEventLoopFlagEvent,
eSetBits);
} }
static bool furi_event_loop_item_is_waiting(FuriEventLoopItem* instance) { static bool furi_event_loop_item_is_waiting(FuriEventLoopItem* instance) {

View file

@ -65,7 +65,10 @@ static void furi_event_loop_timer_enqueue_request(
TimerQueue_push_back(instance->timer_queue, timer); TimerQueue_push_back(instance->timer_queue, timer);
xTaskNotifyIndexed( xTaskNotifyIndexed(
instance->thread_id, FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX, FuriEventLoopFlagTimer, eSetBits); (TaskHandle_t)instance->thread_id,
FURI_EVENT_LOOP_FLAG_NOTIFY_INDEX,
FuriEventLoopFlagTimer,
eSetBits);
} }
/* /*

View file

@ -97,7 +97,7 @@ static void furi_thread_body(void* context) {
furi_thread_set_state(thread, FuriThreadStateRunning); furi_thread_set_state(thread, FuriThreadStateRunning);
if(thread->heap_trace_enabled == true) { if(thread->heap_trace_enabled == true) {
memmgr_heap_enable_thread_trace(thread); memmgr_heap_enable_thread_trace((FuriThreadId)thread);
} }
thread->ret = thread->callback(thread->context); thread->ret = thread->callback(thread->context);
@ -106,14 +106,14 @@ static void furi_thread_body(void* context) {
if(thread->heap_trace_enabled == true) { if(thread->heap_trace_enabled == true) {
furi_delay_ms(33); furi_delay_ms(33);
thread->heap_size = memmgr_heap_get_thread_memory(thread); thread->heap_size = memmgr_heap_get_thread_memory((FuriThreadId)thread);
furi_log_print_format( furi_log_print_format(
thread->heap_size ? FuriLogLevelError : FuriLogLevelInfo, thread->heap_size ? FuriLogLevelError : FuriLogLevelInfo,
TAG, TAG,
"%s allocation balance: %zu", "%s allocation balance: %zu",
thread->name ? thread->name : "Thread", thread->name ? thread->name : "Thread",
thread->heap_size); thread->heap_size);
memmgr_heap_disable_thread_trace(thread); memmgr_heap_disable_thread_trace((FuriThreadId)thread);
} }
furi_check(thread->state == FuriThreadStateRunning); furi_check(thread->state == FuriThreadStateRunning);
@ -275,7 +275,7 @@ void furi_thread_set_priority(FuriThread* thread, FuriThreadPriority priority) {
FuriThreadPriority furi_thread_get_priority(FuriThread* thread) { FuriThreadPriority furi_thread_get_priority(FuriThread* thread) {
furi_check(thread); furi_check(thread);
TaskHandle_t hTask = furi_thread_get_id(thread); TaskHandle_t hTask = (TaskHandle_t)thread;
return (FuriThreadPriority)uxTaskPriorityGet(hTask); return (FuriThreadPriority)uxTaskPriorityGet(hTask);
} }
@ -390,7 +390,7 @@ bool furi_thread_join(FuriThread* thread) {
FuriThreadId furi_thread_get_id(FuriThread* thread) { FuriThreadId furi_thread_get_id(FuriThread* thread) {
furi_check(thread); furi_check(thread);
return thread; return (FuriThreadId)thread;
} }
void furi_thread_enable_heap_trace(FuriThread* thread) { void furi_thread_enable_heap_trace(FuriThread* thread) {
@ -418,7 +418,7 @@ int32_t furi_thread_get_return_code(FuriThread* thread) {
} }
FuriThreadId furi_thread_get_current_id(void) { FuriThreadId furi_thread_get_current_id(void) {
return xTaskGetCurrentTaskHandle(); return (FuriThreadId)xTaskGetCurrentTaskHandle();
} }
FuriThread* furi_thread_get_current(void) { FuriThread* furi_thread_get_current(void) {
@ -624,15 +624,16 @@ bool furi_thread_enumerate(FuriThreadList* thread_list) {
FuriThreadListItem* item = FuriThreadListItem* item =
furi_thread_list_get_or_insert(thread_list, (FuriThread*)task[i].xHandle); furi_thread_list_get_or_insert(thread_list, (FuriThread*)task[i].xHandle);
item->thread = (FuriThreadId)task[i].xHandle; FuriThreadId thread_id = (FuriThreadId)task[i].xHandle;
item->app_id = furi_thread_get_appid(item->thread); item->thread = (FuriThread*)thread_id;
item->app_id = furi_thread_get_appid(thread_id);
item->name = task[i].pcTaskName; item->name = task[i].pcTaskName;
item->priority = task[i].uxCurrentPriority; item->priority = task[i].uxCurrentPriority;
item->stack_address = (uint32_t)tcb->pxStack; item->stack_address = (uint32_t)tcb->pxStack;
size_t thread_heap = memmgr_heap_get_thread_memory(item->thread); size_t thread_heap = memmgr_heap_get_thread_memory(thread_id);
item->heap = thread_heap == MEMMGR_HEAP_UNKNOWN ? 0u : thread_heap; item->heap = thread_heap == MEMMGR_HEAP_UNKNOWN ? 0u : thread_heap;
item->stack_size = (tcb->pxEndOfStack - tcb->pxStack + 1) * sizeof(StackType_t); item->stack_size = (tcb->pxEndOfStack - tcb->pxStack + 1) * sizeof(StackType_t);
item->stack_min_free = furi_thread_get_stack_space(item->thread); item->stack_min_free = furi_thread_get_stack_space(thread_id);
item->state = furi_thread_state_name(task[i].eCurrentState); item->state = furi_thread_state_name(task[i].eCurrentState);
item->counter_previous = item->counter_current; item->counter_previous = item->counter_current;
item->counter_current = task[i].ulRunTimeCounter; item->counter_current = task[i].ulRunTimeCounter;

View file

@ -9,7 +9,6 @@ struct FuriTimer {
StaticTimer_t container; StaticTimer_t container;
FuriTimerCallback cb_func; FuriTimerCallback cb_func;
void* cb_context; void* cb_context;
volatile bool can_be_removed;
}; };
// IMPORTANT: container MUST be the FIRST struct member // IMPORTANT: container MUST be the FIRST struct member
@ -42,9 +41,8 @@ static void furi_timer_epilogue(void* context, uint32_t arg) {
furi_assert(context); furi_assert(context);
UNUSED(arg); UNUSED(arg);
FuriTimer* instance = context; volatile bool* can_be_removed = context;
*can_be_removed = true;
instance->can_be_removed = true;
} }
void furi_timer_free(FuriTimer* instance) { void furi_timer_free(FuriTimer* instance) {
@ -53,9 +51,13 @@ void furi_timer_free(FuriTimer* instance) {
TimerHandle_t hTimer = (TimerHandle_t)instance; TimerHandle_t hTimer = (TimerHandle_t)instance;
furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS); furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS);
furi_check(xTimerPendFunctionCall(furi_timer_epilogue, instance, 0, portMAX_DELAY) == pdPASS);
while(!instance->can_be_removed) { volatile bool can_be_removed = false;
furi_check(
xTimerPendFunctionCall(furi_timer_epilogue, (void*)&can_be_removed, 0, portMAX_DELAY) ==
pdPASS);
while(!can_be_removed) {
furi_delay_tick(2); furi_delay_tick(2);
} }

View file

@ -150,7 +150,8 @@ static int json_isspace(int ch) {
} }
static void json_skip_whitespaces(struct frozen* f) { static void json_skip_whitespaces(struct frozen* f) {
while(f->cur < f->end && json_isspace(*f->cur)) f->cur++; while(f->cur < f->end && json_isspace(*f->cur))
f->cur++;
} }
static int json_cur(struct frozen* f) { static int json_cur(struct frozen* f) {
@ -263,15 +264,18 @@ static int json_parse_number(struct frozen* f) {
f->cur += 2; f->cur += 2;
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
EXPECT(json_isxdigit(f->cur[0]), JSON_STRING_INVALID); EXPECT(json_isxdigit(f->cur[0]), JSON_STRING_INVALID);
while(f->cur < f->end && json_isxdigit(f->cur[0])) f->cur++; while(f->cur < f->end && json_isxdigit(f->cur[0]))
f->cur++;
} else { } else {
EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID);
while(f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; while(f->cur < f->end && json_isdigit(f->cur[0]))
f->cur++;
if(f->cur < f->end && f->cur[0] == '.') { if(f->cur < f->end && f->cur[0] == '.') {
f->cur++; f->cur++;
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID);
while(f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; while(f->cur < f->end && json_isdigit(f->cur[0]))
f->cur++;
} }
if(f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) { if(f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) {
f->cur++; f->cur++;
@ -279,7 +283,8 @@ static int json_parse_number(struct frozen* f) {
if((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++; if((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++;
EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE);
EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID); EXPECT(json_isdigit(f->cur[0]), JSON_STRING_INVALID);
while(f->cur < f->end && json_isdigit(f->cur[0])) f->cur++; while(f->cur < f->end && json_isdigit(f->cur[0]))
f->cur++;
} }
} }
json_truncate_path(f, fstate.path_len); json_truncate_path(f, fstate.path_len);
@ -639,8 +644,7 @@ int json_vprintf(struct json_out* out, const char* fmt, va_list xap) {
int need_len, size = sizeof(buf); int need_len, size = sizeof(buf);
char fmt2[20]; char fmt2[20];
va_list ap_copy; va_list ap_copy;
strncpy(fmt2, fmt, n + 1 > (int)sizeof(fmt2) ? sizeof(fmt2) : (size_t)n + 1); strlcpy(fmt2, fmt, sizeof(fmt2));
fmt2[n + 1] = '\0';
va_copy(ap_copy, ap); va_copy(ap_copy, ap);
need_len = vsnprintf(pbuf, size, fmt2, ap_copy); need_len = vsnprintf(pbuf, size, fmt2, ap_copy);
@ -1047,7 +1051,7 @@ int json_vscanf(const char* s, int len, const char* fmt, va_list ap) {
while(fmt[i] != '\0') { while(fmt[i] != '\0') {
if(fmt[i] == '{') { if(fmt[i] == '{') {
strcat(path, "."); strlcat(path, ".", sizeof(path));
i++; i++;
} else if(fmt[i] == '}') { } else if(fmt[i] == '}') {
if((p = strrchr(path, '.')) != NULL) *p = '\0'; if((p = strrchr(path, '.')) != NULL) *p = '\0';
@ -1160,7 +1164,8 @@ struct json_setf_data {
static int get_matched_prefix_len(const char* s1, const char* s2) { static int get_matched_prefix_len(const char* s1, const char* s2) {
int i = 0; int i = 0;
while(s1[i] && s2[i] && s1[i] == s2[i]) i++; while(s1[i] && s2[i] && s1[i] == s2[i])
i++;
return i; return i;
} }
@ -1235,7 +1240,8 @@ int json_vsetf(
/* Trim comma after the value that begins at object/array start */ /* Trim comma after the value that begins at object/array start */
if(s[data.prev - 1] == '{' || s[data.prev - 1] == '[') { if(s[data.prev - 1] == '{' || s[data.prev - 1] == '[') {
int i = data.end; int i = data.end;
while(i < len && json_isspace(s[i])) i++; while(i < len && json_isspace(s[i]))
i++;
if(s[i] == ',') data.end = i + 1; /* Point after comma */ if(s[i] == ',') data.end = i + 1; /* Point after comma */
} }
json_printf(out, "%.*s", len - data.end, s + data.end); json_printf(out, "%.*s", len - data.end, s + data.end);
@ -1305,7 +1311,8 @@ struct prettify_data {
}; };
static void indent(struct json_out* out, int level) { static void indent(struct json_out* out, int level) {
while(level-- > 0) out->printer(out, " ", 2); while(level-- > 0)
out->printer(out, " ", 2);
} }
static void print_key(struct prettify_data* pd, const char* path, const char* name, int name_len) { static void print_key(struct prettify_data* pd, const char* path, const char* name, int name_len) {

View file

@ -138,8 +138,7 @@ MJS_PRIVATE mjs_err_t to_json_or_debug(
vp < mjs->json_visited_stack.buf + mjs->json_visited_stack.len; vp < mjs->json_visited_stack.buf + mjs->json_visited_stack.len;
vp += sizeof(mjs_val_t)) { vp += sizeof(mjs_val_t)) {
if(*(mjs_val_t*)vp == v) { if(*(mjs_val_t*)vp == v) {
strncpy(buf, "[Circular]", size); len = strlcpy(buf, "[Circular]", size);
len = 10;
goto clean; goto clean;
} }
} }

View file

@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,72.3,, Version,+,72.5,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli.h,,
@ -869,6 +869,8 @@ Function,+,dolphin_deed_get_app_limit,uint8_t,DolphinApp
Function,+,dolphin_deed_get_weight,uint8_t,DolphinDeed Function,+,dolphin_deed_get_weight,uint8_t,DolphinDeed
Function,+,dolphin_flush,void,Dolphin* Function,+,dolphin_flush,void,Dolphin*
Function,+,dolphin_get_pubsub,FuriPubSub*,Dolphin* Function,+,dolphin_get_pubsub,FuriPubSub*,Dolphin*
Function,+,dolphin_get_settings,void,"Dolphin*, DolphinSettings*"
Function,+,dolphin_set_settings,void,"Dolphin*, DolphinSettings*"
Function,+,dolphin_stats,DolphinStats,Dolphin* Function,+,dolphin_stats,DolphinStats,Dolphin*
Function,+,dolphin_upgrade_level,void,Dolphin* Function,+,dolphin_upgrade_level,void,Dolphin*
Function,-,dprintf,int,"int, const char*, ..." Function,-,dprintf,int,"int, const char*, ..."
@ -2596,7 +2598,7 @@ Function,+,strint_to_int64,StrintParseError,"const char*, char**, int64_t*, uint
Function,+,strint_to_uint16,StrintParseError,"const char*, char**, uint16_t*, uint8_t" Function,+,strint_to_uint16,StrintParseError,"const char*, char**, uint16_t*, uint8_t"
Function,+,strint_to_uint32,StrintParseError,"const char*, char**, uint32_t*, uint8_t" Function,+,strint_to_uint32,StrintParseError,"const char*, char**, uint32_t*, uint8_t"
Function,+,strint_to_uint64,StrintParseError,"const char*, char**, uint64_t*, uint8_t" Function,+,strint_to_uint64,StrintParseError,"const char*, char**, uint64_t*, uint8_t"
Function,-,strlcat,size_t,"char*, const char*, size_t" Function,+,strlcat,size_t,"char*, const char*, size_t"
Function,+,strlcpy,size_t,"char*, const char*, size_t" Function,+,strlcpy,size_t,"char*, const char*, size_t"
Function,+,strlen,size_t,const char* Function,+,strlen,size_t,const char*
Function,-,strlwr,char*,char* Function,-,strlwr,char*,char*

1 entry status name type params
2 Version + 72.3 72.5
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/bt/bt_service/bt_keys_storage.h
5 Header + applications/services/cli/cli.h
869 Function + dolphin_deed_get_weight uint8_t DolphinDeed
870 Function + dolphin_flush void Dolphin*
871 Function + dolphin_get_pubsub FuriPubSub* Dolphin*
872 Function + dolphin_get_settings void Dolphin*, DolphinSettings*
873 Function + dolphin_set_settings void Dolphin*, DolphinSettings*
874 Function + dolphin_stats DolphinStats Dolphin*
875 Function + dolphin_upgrade_level void Dolphin*
876 Function - dprintf int int, const char*, ...
2598 Function + strint_to_uint16 StrintParseError const char*, char**, uint16_t*, uint8_t
2599 Function + strint_to_uint32 StrintParseError const char*, char**, uint32_t*, uint8_t
2600 Function + strint_to_uint64 StrintParseError const char*, char**, uint64_t*, uint8_t
2601 Function - + strlcat size_t char*, const char*, size_t
2602 Function + strlcpy size_t char*, const char*, size_t
2603 Function + strlen size_t const char*
2604 Function - strlwr char* char*

View file

@ -40,6 +40,7 @@ void furi_hal_init(void) {
furi_hal_interrupt_init(); furi_hal_interrupt_init();
furi_hal_flash_init(); furi_hal_flash_init();
furi_hal_resources_init(); furi_hal_resources_init();
furi_hal_region_init();
furi_hal_spi_config_init(); furi_hal_spi_config_init();
furi_hal_spi_dma_init(); furi_hal_spi_dma_init();
furi_hal_speaker_init(); furi_hal_speaker_init();

View file

@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,72.3,, Version,+,72.5,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
@ -965,6 +965,8 @@ Function,+,dolphin_deed_get_app_limit,uint8_t,DolphinApp
Function,+,dolphin_deed_get_weight,uint8_t,DolphinDeed Function,+,dolphin_deed_get_weight,uint8_t,DolphinDeed
Function,+,dolphin_flush,void,Dolphin* Function,+,dolphin_flush,void,Dolphin*
Function,+,dolphin_get_pubsub,FuriPubSub*,Dolphin* Function,+,dolphin_get_pubsub,FuriPubSub*,Dolphin*
Function,+,dolphin_get_settings,void,"Dolphin*, DolphinSettings*"
Function,+,dolphin_set_settings,void,"Dolphin*, DolphinSettings*"
Function,+,dolphin_stats,DolphinStats,Dolphin* Function,+,dolphin_stats,DolphinStats,Dolphin*
Function,+,dolphin_upgrade_level,void,Dolphin* Function,+,dolphin_upgrade_level,void,Dolphin*
Function,-,dprintf,int,"int, const char*, ..." Function,-,dprintf,int,"int, const char*, ..."
@ -3320,7 +3322,7 @@ Function,+,strint_to_int64,StrintParseError,"const char*, char**, int64_t*, uint
Function,+,strint_to_uint16,StrintParseError,"const char*, char**, uint16_t*, uint8_t" Function,+,strint_to_uint16,StrintParseError,"const char*, char**, uint16_t*, uint8_t"
Function,+,strint_to_uint32,StrintParseError,"const char*, char**, uint32_t*, uint8_t" Function,+,strint_to_uint32,StrintParseError,"const char*, char**, uint32_t*, uint8_t"
Function,+,strint_to_uint64,StrintParseError,"const char*, char**, uint64_t*, uint8_t" Function,+,strint_to_uint64,StrintParseError,"const char*, char**, uint64_t*, uint8_t"
Function,-,strlcat,size_t,"char*, const char*, size_t" Function,+,strlcat,size_t,"char*, const char*, size_t"
Function,+,strlcpy,size_t,"char*, const char*, size_t" Function,+,strlcpy,size_t,"char*, const char*, size_t"
Function,+,strlen,size_t,const char* Function,+,strlen,size_t,const char*
Function,-,strlwr,char*,char* Function,-,strlwr,char*,char*

1 entry status name type params
2 Version + 72.3 72.5
3 Header + applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/bt/bt_service/bt_keys_storage.h
965 Function + dolphin_deed_get_weight uint8_t DolphinDeed
966 Function + dolphin_flush void Dolphin*
967 Function + dolphin_get_pubsub FuriPubSub* Dolphin*
968 Function + dolphin_get_settings void Dolphin*, DolphinSettings*
969 Function + dolphin_set_settings void Dolphin*, DolphinSettings*
970 Function + dolphin_stats DolphinStats Dolphin*
971 Function + dolphin_upgrade_level void Dolphin*
972 Function - dprintf int int, const char*, ...
3322 Function + strint_to_uint16 StrintParseError const char*, char**, uint16_t*, uint8_t
3323 Function + strint_to_uint32 StrintParseError const char*, char**, uint32_t*, uint8_t
3324 Function + strint_to_uint64 StrintParseError const char*, char**, uint64_t*, uint8_t
3325 Function - + strlcat size_t char*, const char*, size_t
3326 Function + strlcpy size_t char*, const char*, size_t
3327 Function + strlen size_t const char*
3328 Function - strlwr char* char*

View file

@ -100,7 +100,7 @@ void furi_hal_version_set_name(const char* name) {
"xFlipper %s", "xFlipper %s",
furi_hal_version.name); furi_hal_version.name);
} else { } else {
snprintf(furi_hal_version.device_name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH, "xFlipper"); strlcpy(furi_hal_version.device_name, "xFlipper", FURI_HAL_VERSION_DEVICE_NAME_LENGTH);
} }
furi_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; furi_hal_version.device_name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;