URI:
       refactor(style): apply openbsd style(9) - timed-remote - Flipper Zero app for sending delayed IR commands
  HTML git clone git://src.adamsgaard.dk/timed-remote
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 45ffc081a50c3e5508c8bae60c0de9987c47a621
   DIR parent e6560e7f271134addcbadcf3c326feec4b76b0d8
  HTML Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Tue, 17 Feb 2026 21:30:35 +0100
       
       refactor(style): apply openbsd style(9)
       
       Diffstat:
         M helpers/ir_helper.c                 |     265 ++++++++++++++++---------------
         M helpers/ir_helper.h                 |      10 +++++-----
         M helpers/time_helper.c               |      47 ++++++++++++++++---------------
         M helpers/time_helper.h               |       8 ++++----
         M scenes/scene_confirm.c              |      45 +++++++++++++++++++------------
         M scenes/scene_ir_browse.c            |      83 ++++++++++++++++++++-----------
         M scenes/scene_ir_select.c            |     102 ++++++++++++++++++-------------
         M scenes/scene_timer_config.c         |     261 ++++++++++++++++++-------------
         M scenes/scene_timer_running.c        |     192 +++++++++++++++++++------------
         M scenes/timed_remote_scene.c         |      44 ++++++++++++++++----------------
         M scenes/timed_remote_scene.h         |      56 ++++++++++++++++----------------
         M timed_remote.c                      |      69 +++++++++++++++++--------------
         M timed_remote.h                      |      14 +++++++-------
       
       13 files changed, 686 insertions(+), 510 deletions(-)
       ---
   DIR diff --git a/helpers/ir_helper.c b/helpers/ir_helper.c
       @@ -1,123 +1,111 @@
       -#include "ir_helper.h"
       -
        #include <flipper_format/flipper_format.h>
        #include <furi.h>
        #include <infrared/worker/infrared_worker.h>
        #include <lib/infrared/signal/infrared_error_code.h>
       +#include <stdlib.h>
        #include <storage/storage.h>
       +#include <string.h>
       +
       +#include "ir_helper.h"
       +
       +static bool        ir_add_signal(IrSignalList *, InfraredSignal *, const char *);
       +static bool        ir_is_file(const FileInfo *, const char *);
        
        IrSignalList *
        ir_list_alloc(void)
        {
       -        IrSignalList *list = malloc(sizeof(IrSignalList));
       -        if (!list)
       +        IrSignalList *list;
       +
       +        list = malloc(sizeof(IrSignalList));
       +        if (list == NULL)
                        return NULL;
       +
                list->items = NULL;
                list->count = 0;
                list->capacity = 0;
       +
                return list;
        }
        
        void
        ir_list_free(IrSignalList *list)
        {
       -        if (!list)
       +        size_t i;
       +
       +        if (list == NULL)
                        return;
        
       -        for (size_t i = 0; i < list->count; i++)
       -        {
       -                if (list->items[i].signal)
       -                {
       +        for (i = 0; i < list->count; i++) {
       +                if (list->items[i].signal != NULL)
                                infrared_signal_free(list->items[i].signal);
       -                }
       -                if (list->items[i].name)
       -                {
       +                if (list->items[i].name != NULL)
                                furi_string_free(list->items[i].name);
       -                }
       -        }
       -        if (list->items)
       -        {
       -                free(list->items);
                }
       +        free(list->items);
                free(list);
        }
        
       -static bool
       -add_sig(IrSignalList *list, InfraredSignal *signal, const char *name)
       -{
       -        if (list->count >= list->capacity)
       -        {
       -                size_t new_capacity = list->capacity == 0 ? 8 : list->capacity * 2;
       -                IrSignalItem *items = realloc(list->items, new_capacity * sizeof(IrSignalItem));
       -                if (!items)
       -                        return false;
       -                list->items = items;
       -                list->capacity = new_capacity;
       -        }
       -
       -        list->items[list->count].signal = signal;
       -        list->items[list->count].name = furi_string_alloc_set(name);
       -        if (!list->items[list->count].name)
       -                return false;
       -        list->count++;
       -        return true;
       -}
       -
        bool
        ir_load(const char *path, IrSignalList *list)
        {
       -        if (!path || !list)
       +        InfraredErrorCode err;
       +        InfraredSignal *signal;
       +        FlipperFormat *ff;
       +        FuriString *filetype;
       +        FuriString *sig;
       +        Storage *storage;
       +        uint32_t version;
       +        bool header_ok;
       +        bool success;
       +
       +        if (path == NULL || list == NULL)
                        return false;
        
       -        Storage *storage = furi_record_open(RECORD_STORAGE);
       -        if (!storage)
       +        storage = furi_record_open(RECORD_STORAGE);
       +        if (storage == NULL)
                        return false;
        
       -        FlipperFormat *ff = flipper_format_file_alloc(storage);
       -        if (!ff)
       -        {
       +        ff = flipper_format_file_alloc(storage);
       +        if (ff == NULL) {
                        furi_record_close(RECORD_STORAGE);
                        return false;
                }
        
       -        bool success = false;
       -        FuriString *filetype = NULL;
       -        FuriString *sig = NULL;
       +        success = false;
       +        filetype = NULL;
       +        sig = NULL;
        
       -        do
       -        {
       +        do {
                        if (!flipper_format_file_open_existing(ff, path))
                                break;
        
                        filetype = furi_string_alloc();
       -                if (!filetype)
       +                if (filetype == NULL)
                                break;
        
       -                uint32_t version;
       -                bool header_ok = flipper_format_read_header(ff, filetype, &version);
       +                header_ok = flipper_format_read_header(ff, filetype, &version);
                        if (!header_ok)
                                break;
        
                        sig = furi_string_alloc();
       -                if (!sig)
       +                if (sig == NULL)
                                break;
        
       -                while (true)
       -                {
       -                        InfraredSignal *signal = infrared_signal_alloc();
       -                        if (!signal)
       +                for (;;) {
       +                        signal = infrared_signal_alloc();
       +                        if (signal == NULL)
                                        break;
        
       -                        InfraredErrorCode err = infrared_signal_read(signal, ff, sig);
       -                        if (err == InfraredErrorCodeNone)
       -                        {
       -                                if (!add_sig(list, signal, furi_string_get_cstr(sig)))
       -                                {
       +                        err = infrared_signal_read(signal, ff, sig);
       +                        if (err == InfraredErrorCodeNone) {
       +                                if (!ir_add_signal(
       +                                        list,
       +                                        signal,
       +                                        furi_string_get_cstr(sig))) {
                                                infrared_signal_free(signal);
                                                break;
                                        }
       -                        } else
       -                        {
       +                        } else {
                                        infrared_signal_free(signal);
                                        break;
                                }
       @@ -125,12 +113,14 @@ ir_load(const char *path, IrSignalList *list)
                        success = true;
                } while (false);
        
       -        if (filetype)
       +        if (filetype != NULL)
                        furi_string_free(filetype);
       -        if (sig)
       +        if (sig != NULL)
                        furi_string_free(sig);
       +
                flipper_format_free(ff);
                furi_record_close(RECORD_STORAGE);
       +
                return success;
        }
        
       @@ -140,103 +130,130 @@ ir_tx(InfraredSignal *signal)
                infrared_signal_transmit(signal);
        }
        
       -static bool
       -is_ir(const FileInfo *file_info, const char *name)
       -{
       -        if ((file_info->flags & FSF_DIRECTORY) || !name)
       -                return false;
       -
       -        size_t len = strlen(name);
       -        return len > 3 && strcmp(name + len - 3, ".ir") == 0;
       -}
       -
        bool
       -ir_files(const char *dir_path, FuriString ***files,
       -                     size_t *count)
       +ir_files(const char *dir_path, FuriString ***files, size_t *count)
        {
       -        if (!dir_path || !files || !count)
       +        FuriString **next_files;
       +        Storage *storage;
       +        FileInfo file_info;
       +        size_t capacity;
       +        char name_buf[256];
       +        File *dir;
       +        bool dir_open;
       +        bool ok;
       +
       +        if (dir_path == NULL || files == NULL || count == NULL)
                        return false;
        
                *files = NULL;
                *count = 0;
       +        capacity = 0;
       +        dir_open = false;
       +        ok = false;
        
       -        Storage *storage = furi_record_open(RECORD_STORAGE);
       -        if (!storage)
       +        storage = furi_record_open(RECORD_STORAGE);
       +        if (storage == NULL)
                        return false;
        
       -        File *dir = storage_file_alloc(storage);
       -        if (!dir)
       -        {
       -                furi_record_close(RECORD_STORAGE);
       -                return false;
       -        }
       +        dir = storage_file_alloc(storage);
       +        if (dir == NULL)
       +                goto done;
        
                if (!storage_dir_open(dir, dir_path))
       -        {
       -                storage_file_free(dir);
       -                furi_record_close(RECORD_STORAGE);
       -                return false;
       -        }
       -
       -        FileInfo file_info;
       -        char name_buf[256];
       -        size_t capacity = 0;
       +                goto done;
       +        dir_open = true;
        
       -        while (storage_dir_read(dir, &file_info, name_buf, sizeof(name_buf)))
       -        {
       -                if (!is_ir(&file_info, name_buf))
       +        while (storage_dir_read(dir, &file_info, name_buf, sizeof(name_buf))) {
       +                if (!ir_is_file(&file_info, name_buf))
                                continue;
        
       -                if (*count >= capacity)
       -                {
       -                        size_t new_capacity = capacity == 0 ? 8 : capacity * 2;
       -                        FuriString **next_files = realloc(*files, new_capacity * sizeof(FuriString *));
       -                        if (!next_files)
       -                        {
       +                if (*count >= capacity) {
       +                        size_t new_capacity;
       +
       +                        new_capacity = capacity == 0 ? 8 : capacity * 2;
       +                        next_files = realloc(*files, new_capacity * sizeof(FuriString *));
       +                        if (next_files == NULL) {
                                        ir_files_free(*files, *count);
                                        *files = NULL;
                                        *count = 0;
       -                                storage_dir_close(dir);
       -                                storage_file_free(dir);
       -                                furi_record_close(RECORD_STORAGE);
       -                                return false;
       +                                goto done;
                                }
                                *files = next_files;
                                capacity = new_capacity;
                        }
        
                        (*files)[*count] = furi_string_alloc_set(name_buf);
       -                if (!(*files)[*count])
       -                {
       +                if ((*files)[*count] == NULL) {
                                ir_files_free(*files, *count);
                                *files = NULL;
                                *count = 0;
       -                        storage_dir_close(dir);
       -                        storage_file_free(dir);
       -                        furi_record_close(RECORD_STORAGE);
       -                        return false;
       +                        goto done;
                        }
                        (*count)++;
                }
        
       -        storage_dir_close(dir);
       -        storage_file_free(dir);
       +        ok = true;
       +
       +done:
       +        if (dir != NULL) {
       +                if (dir_open)
       +                        storage_dir_close(dir);
       +                storage_file_free(dir);
       +        }
                furi_record_close(RECORD_STORAGE);
       -        return true;
       +        return ok;
        }
        
        void
        ir_files_free(FuriString **files, size_t count)
        {
       -        if (!files)
       +        size_t i;
       +
       +        if (files == NULL)
                        return;
        
       -        for (size_t i = 0; i < count; i++)
       -        {
       -                if (files[i])
       -                {
       +        for (i = 0; i < count; i++) {
       +                if (files[i] != NULL)
                                furi_string_free(files[i]);
       -                }
                }
                free(files);
        }
       +
       +static bool
       +ir_add_signal(IrSignalList *list, InfraredSignal *signal, const char *name)
       +{
       +        IrSignalItem *items;
       +        size_t new_capacity;
       +
       +        if (list->count >= list->capacity) {
       +                new_capacity = list->capacity == 0 ? 8 : list->capacity * 2;
       +                items = realloc(list->items, new_capacity * sizeof(IrSignalItem));
       +                if (items == NULL)
       +                        return false;
       +                list->items = items;
       +                list->capacity = new_capacity;
       +        }
       +
       +        list->items[list->count].signal = signal;
       +        list->items[list->count].name = furi_string_alloc_set(name);
       +        if (list->items[list->count].name == NULL)
       +                return false;
       +
       +        list->count++;
       +        return true;
       +}
       +
       +static bool
       +ir_is_file(const FileInfo *file_info, const char *name)
       +{
       +        size_t len;
       +
       +        if ((file_info->flags & FSF_DIRECTORY) || name == NULL)
       +                return false;
       +
       +        len = strlen(name);
       +        if (len <= 3)
       +                return false;
       +
       +        return strcmp(name + len - 3, ".ir") == 0;
       +}
   DIR diff --git a/helpers/ir_helper.h b/helpers/ir_helper.h
       @@ -21,8 +21,8 @@ typedef struct
        } IrSignalList;
        
        IrSignalList *ir_list_alloc(void);
       -void ir_list_free(IrSignalList *list);
       -bool ir_load(const char *path, IrSignalList *list);
       -void ir_tx(InfraredSignal *signal);
       -bool ir_files(const char *dir_path, FuriString ***files, size_t *count);
       -void ir_files_free(FuriString **files, size_t count);
       +void ir_list_free(IrSignalList *);
       +bool ir_load(const char *, IrSignalList *);
       +void ir_tx(InfraredSignal *);
       +bool ir_files(const char *, FuriString ***, size_t *);
       +void ir_files_free(FuriString **, size_t);
   DIR diff --git a/helpers/time_helper.c b/helpers/time_helper.c
       @@ -1,49 +1,44 @@
       -#include "time_helper.h"
       -
        #ifndef TIMED_REMOTE_TEST_BUILD
        #include <furi_hal.h>
        #include <stdio.h>
        #endif
        
       +#include "time_helper.h"
       +
        uint32_t
        time_hms_sec(uint8_t h, uint8_t m, uint8_t s)
        {
       -        return (uint32_t) h * 3600 + (uint32_t) m * 60 + (uint32_t) s;
       +        return (uint32_t)h * 3600 + (uint32_t)m * 60 + (uint32_t)s;
        }
        
        void
       -time_sec_hms(uint32_t total_seconds, uint8_t *h, uint8_t *m,
       -                           uint8_t *s)
       +time_sec_hms(uint32_t total_seconds, uint8_t *h, uint8_t *m, uint8_t *s)
        {
       -        /* Handle times >= 24 hours by wrapping */
       -        total_seconds = total_seconds % (24 * 3600);
       +        /* Wrap values >= 24 hours into a single day. */
       +        total_seconds %= 24 * 3600;
        
       -        *h = (uint8_t) (total_seconds / 3600);
       +        *h = (uint8_t)(total_seconds / 3600);
                total_seconds %= 3600;
       -        *m = (uint8_t) (total_seconds / 60);
       -        *s = (uint8_t) (total_seconds % 60);
       +        *m = (uint8_t)(total_seconds / 60);
       +        *s = (uint8_t)(total_seconds % 60);
        }
        
        #ifndef TIMED_REMOTE_TEST_BUILD
        uint32_t
       -time_until(uint8_t target_h, uint8_t target_m,
       -                          uint8_t target_s)
       +time_until(uint8_t target_h, uint8_t target_m, uint8_t target_s)
        {
                DateTime now;
       +        uint32_t now_seconds;
       +        uint32_t target_seconds;
       +
                furi_hal_rtc_get_datetime(&now);
        
       -        uint32_t now_seconds =
       -        time_hms_sec(now.hour, now.minute, now.second);
       -        uint32_t target_seconds =
       -        time_hms_sec(target_h, target_m, target_s);
       +        now_seconds = time_hms_sec(now.hour, now.minute, now.second);
       +        target_seconds = time_hms_sec(target_h, target_m, target_s);
        
                if (target_seconds < now_seconds)
       -        {
       -                /* Roll to next day */
                        return (24 * 3600 - now_seconds) + target_seconds;
       -        }
        
       -        /* Target time is now or later today */
                return target_seconds - now_seconds;
        }
        
       @@ -51,9 +46,17 @@ void
        time_name(char *buffer, size_t buffer_size)
        {
                DateTime now;
       +
                furi_hal_rtc_get_datetime(&now);
        
       -        snprintf(buffer, buffer_size, "IR_%04d%02d%02d_%02d%02d%02d", now.year,
       -                 now.month, now.day, now.hour, now.minute, now.second);
       +        snprintf(buffer,
       +            buffer_size,
       +            "IR_%04d%02d%02d_%02d%02d%02d",
       +            now.year,
       +            now.month,
       +            now.day,
       +            now.hour,
       +            now.minute,
       +            now.second);
        }
        #endif
   DIR diff --git a/helpers/time_helper.h b/helpers/time_helper.h
       @@ -3,10 +3,10 @@
        #include <stddef.h>
        #include <stdint.h>
        
       -uint32_t time_hms_sec(uint8_t h, uint8_t m, uint8_t s);
       -void time_sec_hms(uint32_t total_seconds, uint8_t *h, uint8_t *m, uint8_t *s);
       +uint32_t time_hms_sec(uint8_t, uint8_t, uint8_t);
       +void time_sec_hms(uint32_t, uint8_t *, uint8_t *, uint8_t *);
        
        #ifndef TIMED_REMOTE_TEST_BUILD
       -uint32_t time_until(uint8_t target_h, uint8_t target_m, uint8_t target_s);
       -void time_name(char *buffer, size_t buffer_size);
       +uint32_t time_until(uint8_t, uint8_t, uint8_t);
       +void time_name(char *, size_t);
        #endif
   DIR diff --git a/scenes/scene_confirm.c b/scenes/scene_confirm.c
       @@ -2,39 +2,50 @@
        #include "timed_remote_scene.h"
        
        static void
       -done_cb(void *context)
       +on_popup_done(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        view_dispatcher_send_custom_event(a->vd, EvDone);
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        view_dispatcher_send_custom_event(app->vd, EVENT_DONE);
        }
        
        void
        scene_done_enter(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        popup_reset(a->popup);
       -        popup_set_header(a->popup, "Signal Sent!", 64, 20, AlignCenter, AlignCenter);
       -        popup_set_text(a->popup, a->sig, 64, 35, AlignCenter, AlignCenter);
       -        popup_set_timeout(a->popup, 2000);
       -        popup_set_context(a->popup, a);
       -        popup_set_callback(a->popup, done_cb);
       -        popup_enable_timeout(a->popup);
       -        view_dispatcher_switch_to_view(a->vd, ViewPop);
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        popup_reset(app->popup);
       +        popup_set_header(app->popup, "Signal Sent!", 64, 20, AlignCenter, AlignCenter);
       +        popup_set_text(app->popup, app->sig, 64, 35, AlignCenter, AlignCenter);
       +        popup_set_timeout(app->popup, 2000);
       +        popup_set_context(app->popup, app);
       +        popup_set_callback(app->popup, on_popup_done);
       +        popup_enable_timeout(app->popup);
       +        view_dispatcher_switch_to_view(app->vd, VIEW_POP);
        }
        
        bool
        scene_done_event(void *context, SceneManagerEvent event)
        {
       -        TimedRemoteApp *a = context;
       -        if (event.type != SceneManagerEventTypeCustom || event.event != EvDone)
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        if (event.type != SceneManagerEventTypeCustom)
                        return false;
       -        scene_manager_search_and_switch_to_previous_scene(a->sm, ScBrowse);
       +        if (event.event != EVENT_DONE)
       +                return false;
       +
       +        scene_manager_search_and_switch_to_previous_scene(app->sm, SCENE_BROWSE);
                return true;
        }
        
        void
        scene_done_exit(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        popup_reset(a->popup);
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        popup_reset(app->popup);
        }
   DIR diff --git a/scenes/scene_ir_browse.c b/scenes/scene_ir_browse.c
       @@ -1,64 +1,89 @@
       +#include <stdio.h>
       +
        #include "../helpers/ir_helper.h"
        #include "../timed_remote.h"
        #include "timed_remote_scene.h"
        
       -#define IR_DIR "/ext/infrared"
       +#define IR_DIRECTORY "/ext/infrared"
        
        static FuriString **files;
        static size_t nfiles;
        
        static void
       -pick_file(void *context, uint32_t i)
       +pick_file(void *context, uint32_t index)
        {
       -        TimedRemoteApp *a = context;
       -        if (i >= nfiles)
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        if (index >= nfiles)
                        return;
       -        snprintf(a->file, sizeof(a->file), "%s/%s", IR_DIR, furi_string_get_cstr(files[i]));
       -        view_dispatcher_send_custom_event(a->vd, EvFile);
       +
       +        snprintf(
       +            app->file,
       +            sizeof(app->file),
       +            "%s/%s",
       +            IR_DIRECTORY,
       +            furi_string_get_cstr(files[index]));
       +        view_dispatcher_send_custom_event(app->vd, EVENT_FILE_SELECTED);
        }
        
        void
        scene_browse_enter(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        submenu_reset(a->submenu);
       -        submenu_set_header(a->submenu, "Select IR File");
       -
       -        if (ir_files(IR_DIR, &files, &nfiles))
       -        {
       -                if (nfiles == 0)
       -                {
       -                        submenu_add_item(a->submenu, "(No IR files found)", 0, NULL, NULL);
       -                } else
       -                {
       -                        for (size_t i = 0; i < nfiles; i++)
       -                                submenu_add_item(a->submenu, furi_string_get_cstr(files[i]), i, pick_file, a);
       +        TimedRemoteApp *app;
       +        size_t i;
       +
       +        app = context;
       +        submenu_reset(app->submenu);
       +        submenu_set_header(app->submenu, "Select IR File");
       +
       +        if (ir_files(IR_DIRECTORY, &files, &nfiles)) {
       +                if (nfiles == 0) {
       +                        submenu_add_item(
       +                            app->submenu, "(No IR files found)", 0, NULL, NULL);
       +                } else {
       +                        for (i = 0; i < nfiles; i++) {
       +                                submenu_add_item(
       +                                    app->submenu,
       +                                    furi_string_get_cstr(files[i]),
       +                                    i,
       +                                    pick_file,
       +                                    app);
       +                        }
                        }
       -        } else
       -        {
       -                submenu_add_item(a->submenu, "(Error reading directory)", 0, NULL, NULL);
       +        } else {
       +                submenu_add_item(
       +                    app->submenu, "(Error reading directory)", 0, NULL, NULL);
                }
        
       -        view_dispatcher_switch_to_view(a->vd, ViewMenu);
       +        view_dispatcher_switch_to_view(app->vd, VIEW_MENU);
        }
        
        bool
        scene_browse_event(void *context, SceneManagerEvent event)
        {
       -        TimedRemoteApp *a = context;
       -        if (event.type != SceneManagerEventTypeCustom || event.event != EvFile)
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        if (event.type != SceneManagerEventTypeCustom)
       +                return false;
       +        if (event.event != EVENT_FILE_SELECTED)
                        return false;
       -        scene_manager_next_scene(a->sm, ScSelect);
       +
       +        scene_manager_next_scene(app->sm, SCENE_SELECT);
                return true;
        }
        
        void
        scene_browse_exit(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        submenu_reset(a->submenu);
       -        if (!files)
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        submenu_reset(app->submenu);
       +        if (files == NULL)
                        return;
       +
                ir_files_free(files, nfiles);
                files = NULL;
                nfiles = 0;
   DIR diff --git a/scenes/scene_ir_select.c b/scenes/scene_ir_select.c
       @@ -1,75 +1,95 @@
       +#include <string.h>
       +
        #include "../helpers/ir_helper.h"
        #include "../timed_remote.h"
        #include "timed_remote_scene.h"
        
       -static IrSignalList *sigs;
       +static IrSignalList *signals;
        
        static void
       -pick_sig(void *context, uint32_t i)
       +pick_signal(void *context, uint32_t index)
        {
       -        TimedRemoteApp *a = context;
       -        if (!sigs || i >= sigs->count)
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        if (signals == NULL || index >= signals->count)
                        return;
        
       -        if (a->ir)
       -                infrared_signal_free(a->ir);
       -        a->ir = infrared_signal_alloc();
       -        if (!a->ir)
       +        if (app->ir != NULL)
       +                infrared_signal_free(app->ir);
       +
       +        app->ir = infrared_signal_alloc();
       +        if (app->ir == NULL)
                        return;
        
       -        infrared_signal_set_signal(a->ir, sigs->items[i].signal);
       -        strncpy(a->sig, furi_string_get_cstr(sigs->items[i].name), sizeof(a->sig) - 1);
       -        a->sig[sizeof(a->sig) - 1] = '\0';
       -        view_dispatcher_send_custom_event(a->vd, EvSig);
       +        infrared_signal_set_signal(app->ir, signals->items[index].signal);
       +        strncpy(
       +            app->sig,
       +            furi_string_get_cstr(signals->items[index].name),
       +            sizeof(app->sig) - 1);
       +        app->sig[sizeof(app->sig) - 1] = '\0';
       +        view_dispatcher_send_custom_event(app->vd, EVENT_SIGNAL_SELECTED);
        }
        
        void
        scene_select_enter(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        submenu_reset(a->submenu);
       -        submenu_set_header(a->submenu, "Select Signal");
       -
       -        sigs = ir_list_alloc();
       -        if (!sigs)
       -        {
       -                submenu_add_item(a->submenu, "(Out of memory)", 0, NULL, NULL);
       -        } else if (ir_load(a->file, sigs))
       -        {
       -                if (sigs->count == 0)
       -                {
       -                        submenu_add_item(a->submenu, "(No signals in file)", 0, NULL, NULL);
       -                } else
       -                {
       -                        for (size_t i = 0; i < sigs->count; i++)
       +        TimedRemoteApp *app;
       +        size_t i;
       +
       +        app = context;
       +        submenu_reset(app->submenu);
       +        submenu_set_header(app->submenu, "Select Signal");
       +
       +        signals = ir_list_alloc();
       +        if (signals == NULL) {
       +                submenu_add_item(app->submenu, "(Out of memory)", 0, NULL, NULL);
       +        } else if (ir_load(app->file, signals)) {
       +                if (signals->count == 0) {
       +                        submenu_add_item(
       +                            app->submenu, "(No signals in file)", 0, NULL, NULL);
       +                } else {
       +                        for (i = 0; i < signals->count; i++) {
                                        submenu_add_item(
       -                                        a->submenu, furi_string_get_cstr(sigs->items[i].name), i, pick_sig, a);
       +                                    app->submenu,
       +                                    furi_string_get_cstr(signals->items[i].name),
       +                                    i,
       +                                    pick_signal,
       +                                    app);
       +                        }
                        }
       -        } else
       -        {
       -                submenu_add_item(a->submenu, "(Error reading file)", 0, NULL, NULL);
       +        } else {
       +                submenu_add_item(app->submenu, "(Error reading file)", 0, NULL, NULL);
                }
        
       -        view_dispatcher_switch_to_view(a->vd, ViewMenu);
       +        view_dispatcher_switch_to_view(app->vd, VIEW_MENU);
        }
        
        bool
        scene_select_event(void *context, SceneManagerEvent event)
        {
       -        TimedRemoteApp *a = context;
       -        if (event.type != SceneManagerEventTypeCustom || event.event != EvSig)
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        if (event.type != SceneManagerEventTypeCustom)
       +                return false;
       +        if (event.event != EVENT_SIGNAL_SELECTED)
                        return false;
       -        scene_manager_next_scene(a->sm, ScCfg);
       +
       +        scene_manager_next_scene(app->sm, SCENE_CONFIG);
                return true;
        }
        
        void
        scene_select_exit(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        submenu_reset(a->submenu);
       -        if (!sigs)
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        submenu_reset(app->submenu);
       +        if (signals == NULL)
                        return;
       -        ir_list_free(sigs);
       -        sigs = NULL;
       +
       +        ir_list_free(signals);
       +        signals = NULL;
        }
   DIR diff --git a/scenes/scene_timer_config.c b/scenes/scene_timer_config.c
       @@ -1,199 +1,246 @@
       +#include <stdio.h>
       +
        #include "../timed_remote.h"
        #include "timed_remote_scene.h"
        
        enum
        {
       -        IdxMode,
       -        IdxH,
       -        IdxM,
       -        IdxS,
       -        IdxRepeat,
       -        IdxStart,
       +        ITEM_MODE,
       +        ITEM_HOURS,
       +        ITEM_MINUTES,
       +        ITEM_SECONDS,
       +        ITEM_REPEAT,
       +        ITEM_START,
        };
        
       -#define REP_OFF 0U
       -#define REP_INF 255U
       +#define REPEAT_OFF 0U
       +#define REPEAT_UNLIMITED 255U
       +
       +static void        add_time_item(VariableItemList *, const char *, uint8_t, uint8_t,
       +            VariableItemChangeCallback, TimedRemoteApp *);
       +static void        build_items(TimedRemoteApp *);
       +static uint8_t        index_from_repeat(uint8_t);
       +static void        set_repeat_text(VariableItem *, uint8_t);
       +static uint8_t        repeat_from_index(uint8_t);
       +static void        set_two_digits(VariableItem *, uint8_t);
       +static uint32_t        start_item_index(const TimedRemoteApp *);
        
        static void
       -set2(VariableItem *it, uint8_t v)
       +set_two_digits(VariableItem *item, uint8_t value)
        {
       -        char s[4];
       -        snprintf(s, sizeof(s), "%02d", v);
       -        variable_item_set_current_value_text(it, s);
       +        char text[4];
       +
       +        snprintf(text, sizeof(text), "%02d", value);
       +        variable_item_set_current_value_text(item, text);
        }
        
        static uint8_t
       -rep_from_idx(uint8_t i)
       +repeat_from_index(uint8_t index)
        {
       -        if (i == 0)
       -                return REP_OFF;
       -        if (i == 1)
       -                return REP_INF;
       -        return i - 1;
       +        if (index == 0)
       +                return REPEAT_OFF;
       +        if (index == 1)
       +                return REPEAT_UNLIMITED;
       +        return index - 1;
        }
        
        static uint8_t
       -idx_from_rep(uint8_t r)
       +index_from_repeat(uint8_t repeat)
        {
       -        if (r == REP_OFF)
       +        if (repeat == REPEAT_OFF)
                        return 0;
       -        if (r == REP_INF)
       +        if (repeat == REPEAT_UNLIMITED)
                        return 1;
       -        return r + 1;
       +        return repeat + 1;
        }
        
        static void
       -set_rep(VariableItem *it, uint8_t r)
       +set_repeat_text(VariableItem *item, uint8_t repeat)
        {
       -        if (r == REP_OFF)
       -        {
       -                variable_item_set_current_value_text(it, "Off");
       +        char text[16];
       +
       +        if (repeat == REPEAT_OFF) {
       +                variable_item_set_current_value_text(item, "Off");
                        return;
                }
       -        if (r == REP_INF)
       -        {
       -                variable_item_set_current_value_text(it, "Unlimited");
       +        if (repeat == REPEAT_UNLIMITED) {
       +                variable_item_set_current_value_text(item, "Unlimited");
                        return;
                }
       -        char s[16];
       -        snprintf(s, sizeof(s), "%u", r);
       -        variable_item_set_current_value_text(it, s);
       +
       +        snprintf(text, sizeof(text), "%u", repeat);
       +        variable_item_set_current_value_text(item, text);
        }
        
        static uint32_t
       -start_idx(const TimedRemoteApp *a)
       +start_item_index(const TimedRemoteApp *app)
        {
       -        if (a->mode == ModeDown)
       -                return IdxStart;
       -        return IdxRepeat;
       +        if (app->mode == MODE_COUNTDOWN)
       +                return ITEM_START;
       +        return ITEM_REPEAT;
        }
        
        static void
       -mode_chg(VariableItem *it)
       +on_mode_change(VariableItem *item)
        {
       -        TimedRemoteApp *a = variable_item_get_context(it);
       -        a->mode = variable_item_get_current_value_index(it) == 0
       -                ? ModeDown
       -                : ModeSched;
       +        TimedRemoteApp *app;
       +        uint8_t mode_index;
       +
       +        app = variable_item_get_context(item);
       +        mode_index = variable_item_get_current_value_index(item);
       +        app->mode = mode_index == 0 ? MODE_COUNTDOWN : MODE_SCHEDULED;
                variable_item_set_current_value_text(
       -                                             it, a->mode == ModeDown ? "Countdown" : "Scheduled");
       -        if (a->mode == ModeSched)
       -                a->repeat = REP_OFF;
       -        view_dispatcher_send_custom_event(a->vd, EvMode);
       +            item,
       +            app->mode == MODE_COUNTDOWN ? "Countdown" : "Scheduled");
       +        if (app->mode == MODE_SCHEDULED)
       +                app->repeat = REPEAT_OFF;
       +
       +        view_dispatcher_send_custom_event(app->vd, EVENT_MODE_CHANGED);
        }
        
        static void
       -h_chg(VariableItem *it)
       +on_hours_change(VariableItem *item)
        {
       -        TimedRemoteApp *a = variable_item_get_context(it);
       -        a->h = variable_item_get_current_value_index(it);
       -        set2(it, a->h);
       +        TimedRemoteApp *app;
       +
       +        app = variable_item_get_context(item);
       +        app->h = variable_item_get_current_value_index(item);
       +        set_two_digits(item, app->h);
        }
        
        static void
       -m_chg(VariableItem *it)
       +on_minutes_change(VariableItem *item)
        {
       -        TimedRemoteApp *a = variable_item_get_context(it);
       -        a->m = variable_item_get_current_value_index(it);
       -        set2(it, a->m);
       +        TimedRemoteApp *app;
       +
       +        app = variable_item_get_context(item);
       +        app->m = variable_item_get_current_value_index(item);
       +        set_two_digits(item, app->m);
        }
        
        static void
       -s_chg(VariableItem *it)
       +on_seconds_change(VariableItem *item)
        {
       -        TimedRemoteApp *a = variable_item_get_context(it);
       -        a->s = variable_item_get_current_value_index(it);
       -        set2(it, a->s);
       +        TimedRemoteApp *app;
       +
       +        app = variable_item_get_context(item);
       +        app->s = variable_item_get_current_value_index(item);
       +        set_two_digits(item, app->s);
        }
        
        static void
       -rep_chg(VariableItem *it)
       +on_repeat_change(VariableItem *item)
        {
       -        TimedRemoteApp *a = variable_item_get_context(it);
       -        a->repeat = rep_from_idx(variable_item_get_current_value_index(it));
       -        set_rep(it, a->repeat);
       +        TimedRemoteApp *app;
       +
       +        app = variable_item_get_context(item);
       +        app->repeat = repeat_from_index(variable_item_get_current_value_index(item));
       +        set_repeat_text(item, app->repeat);
        }
        
        static void
       -enter_cb(void *ctx, uint32_t i)
       +on_enter(void *context, uint32_t index)
        {
       -        TimedRemoteApp *a = ctx;
       -        if (i != start_idx(a))
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        if (index != start_item_index(app))
                        return;
       -        view_dispatcher_send_custom_event(a->vd, EvCfg);
       +
       +        view_dispatcher_send_custom_event(app->vd, EVENT_TIMER_CONFIGURED);
        }
        
        static void
       -add_tm(VariableItemList *l, const char *n, uint8_t nvals, uint8_t v, VariableItemChangeCallback cb, TimedRemoteApp *a)
       +add_time_item(VariableItemList *list,
       +    const char *name,
       +    uint8_t value_count,
       +    uint8_t value,
       +    VariableItemChangeCallback callback,
       +    TimedRemoteApp *app)
        {
       -        VariableItem *it = variable_item_list_add(l, n, nvals, cb, a);
       -        variable_item_set_current_value_index(it, v);
       -        set2(it, v);
       +        VariableItem *item;
       +
       +        item = variable_item_list_add(list, name, value_count, callback, app);
       +        variable_item_set_current_value_index(item, value);
       +        set_two_digits(item, value);
        }
        
        static void
       -build(TimedRemoteApp *a)
       +build_items(TimedRemoteApp *app)
        {
       -        variable_item_list_reset(a->vlist);
       -
       -        VariableItem *it = variable_item_list_add(a->vlist, "Mode", 2, mode_chg, a);
       -        variable_item_set_current_value_index(it, a->mode == ModeDown ? 0 : 1);
       -        variable_item_set_current_value_text(
       -                                             it, a->mode == ModeDown ? "Countdown" : "Scheduled");
       +        VariableItem *item;
        
       -        add_tm(a->vlist, "Hours", 24, a->h, h_chg, a);
       -        add_tm(a->vlist, "Minutes", 60, a->m, m_chg, a);
       -        add_tm(a->vlist, "Seconds", 60, a->s, s_chg, a);
       +        variable_item_list_reset(app->vlist);
        
       -        if (a->mode == ModeDown)
       -        {
       -                it = variable_item_list_add(a->vlist, "Repeat", 101, rep_chg, a);
       -                variable_item_set_current_value_index(it, idx_from_rep(a->repeat));
       -                set_rep(it, a->repeat);
       +        item = variable_item_list_add(app->vlist, "Mode", 2, on_mode_change, app);
       +        variable_item_set_current_value_index(
       +            item,
       +            app->mode == MODE_COUNTDOWN ? 0 : 1);
       +        variable_item_set_current_value_text(
       +            item,
       +            app->mode == MODE_COUNTDOWN ? "Countdown" : "Scheduled");
       +
       +        add_time_item(app->vlist, "Hours", 24, app->h, on_hours_change, app);
       +        add_time_item(app->vlist, "Minutes", 60, app->m, on_minutes_change, app);
       +        add_time_item(app->vlist, "Seconds", 60, app->s, on_seconds_change, app);
       +
       +        if (app->mode == MODE_COUNTDOWN) {
       +                item = variable_item_list_add(
       +                    app->vlist,
       +                    "Repeat",
       +                    101,
       +                    on_repeat_change,
       +                    app);
       +                variable_item_set_current_value_index(item, index_from_repeat(app->repeat));
       +                set_repeat_text(item, app->repeat);
                }
        
       -        variable_item_list_add(a->vlist, ">> Start Timer <<", 0, NULL, NULL);
       -        variable_item_list_set_enter_callback(a->vlist, enter_cb, a);
       +        variable_item_list_add(app->vlist, ">> Start Timer <<", 0, NULL, NULL);
       +        variable_item_list_set_enter_callback(app->vlist, on_enter, app);
        }
        
        void
        scene_cfg_enter(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        build(a);
       -        view_dispatcher_switch_to_view(a->vd, ViewList);
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        build_items(app);
       +        view_dispatcher_switch_to_view(app->vd, VIEW_LIST);
        }
        
        bool
        scene_cfg_event(void *context, SceneManagerEvent event)
        {
       -        TimedRemoteApp *a = context;
       +        TimedRemoteApp *app;
       +
       +        app = context;
                if (event.type != SceneManagerEventTypeCustom)
                        return false;
       -        if (event.event == EvMode)
       -        {
       -                build(a);
       +
       +        if (event.event == EVENT_MODE_CHANGED) {
       +                build_items(app);
                        return true;
                }
       -        if (event.event != EvCfg)
       +        if (event.event != EVENT_TIMER_CONFIGURED)
                        return false;
       -        if (a->repeat == REP_OFF)
       -        {
       -                a->repeat_left = 1;
       -        } else if (a->repeat == REP_INF)
       -        {
       -                a->repeat_left = REP_INF;
       -        } else
       -        {
       -                a->repeat_left = a->repeat + 1;
       -        }
       -        scene_manager_next_scene(a->sm, ScRun);
       +
       +        if (app->repeat == REPEAT_OFF)
       +                app->repeat_left = 1;
       +        else if (app->repeat == REPEAT_UNLIMITED)
       +                app->repeat_left = REPEAT_UNLIMITED;
       +        else
       +                app->repeat_left = app->repeat + 1;
       +
       +        scene_manager_next_scene(app->sm, SCENE_RUN);
                return true;
        }
        
        void
        scene_cfg_exit(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        variable_item_list_reset(a->vlist);
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        variable_item_list_reset(app->vlist);
        }
   DIR diff --git a/scenes/scene_timer_running.c b/scenes/scene_timer_running.c
       @@ -1,132 +1,176 @@
       +#include <stdio.h>
       +
        #include "../helpers/ir_helper.h"
        #include "../helpers/time_helper.h"
        #include "../timed_remote.h"
        #include "timed_remote_scene.h"
        
       +static uint32_t        countdown_seconds(const TimedRemoteApp *);
       +static void        render_timer(TimedRemoteApp *);
       +
       +#define REPEAT_UNLIMITED 255U
       +
        static void
       -tick_cb(void *context)
       +on_timer_tick(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        view_dispatcher_send_custom_event(a->vd, EvTick);
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        view_dispatcher_send_custom_event(app->vd, EVENT_TIMER_TICK);
        }
        
        static uint32_t
       -countdown(const TimedRemoteApp *a)
       +countdown_seconds(const TimedRemoteApp *app)
        {
       -        return time_hms_sec(a->h, a->m, a->s);
       +        return time_hms_sec(app->h, app->m, app->s);
        }
        
        static void
       -redraw(TimedRemoteApp *a)
       +render_timer(TimedRemoteApp *app)
        {
       -        uint8_t h, m, s;
       -        time_sec_hms(a->left, &h, &m, &s);
       -
       -        char t[16];
       -        snprintf(t, sizeof(t), "%02d:%02d:%02d", h, m, s);
       -
       -        widget_reset(a->widget);
       -        widget_add_string_element(a->widget, 64, 5, AlignCenter, AlignTop, FontSecondary, a->sig);
       -        widget_add_string_element(a->widget, 64, 25, AlignCenter, AlignTop, FontBigNumbers, t);
       -        if (a->repeat > 0 && a->repeat < 255)
       -        {
       -                char r[24];
       -                snprintf(r, sizeof(r), "Repeat: %d/%d", a->repeat - a->repeat_left + 1, a->repeat);
       -                widget_add_string_element(a->widget, 64, 52, AlignCenter, AlignTop, FontSecondary, r);
       -        } else if (a->repeat == 255)
       -        {
       +        char timer[16];
       +        uint8_t h;
       +        uint8_t m;
       +        uint8_t s;
       +
       +        time_sec_hms(app->left, &h, &m, &s);
       +        snprintf(timer, sizeof(timer), "%02d:%02d:%02d", h, m, s);
       +
       +        widget_reset(app->widget);
       +        widget_add_string_element(
       +            app->widget,
       +            64,
       +            5,
       +            AlignCenter,
       +            AlignTop,
       +            FontSecondary,
       +            app->sig);
       +        widget_add_string_element(
       +            app->widget,
       +            64,
       +            25,
       +            AlignCenter,
       +            AlignTop,
       +            FontBigNumbers,
       +            timer);
       +
       +        if (app->repeat > 0 && app->repeat < REPEAT_UNLIMITED) {
       +                char repeat[24];
       +
       +                snprintf(
       +                    repeat,
       +                    sizeof(repeat),
       +                    "Repeat: %d/%d",
       +                    app->repeat - app->repeat_left + 1,
       +                    app->repeat);
       +                widget_add_string_element(
       +                    app->widget,
       +                    64,
       +                    52,
       +                    AlignCenter,
       +                    AlignTop,
       +                    FontSecondary,
       +                    repeat);
       +        } else if (app->repeat == REPEAT_UNLIMITED) {
                        widget_add_string_element(
       -                                        a->widget, 64, 52, AlignCenter, AlignTop, FontSecondary, "Repeat: Unlimited");
       +                    app->widget,
       +                    64,
       +                    52,
       +                    AlignCenter,
       +                    AlignTop,
       +                    FontSecondary,
       +                    "Repeat: Unlimited");
                }
        }
        
        void
        scene_run_enter(void *context)
        {
       -        TimedRemoteApp *a = context;
       -
       -        if (a->mode == ModeDown)
       -        {
       -                a->left = countdown(a);
       -        } else
       -        {
       -                a->left = time_until(a->h, a->m, a->s);
       -                if (a->left == 0)
       -                {
       -                        view_dispatcher_send_custom_event(a->vd, EvFire);
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        if (app->mode == MODE_COUNTDOWN) {
       +                app->left = countdown_seconds(app);
       +        } else {
       +                app->left = time_until(app->h, app->m, app->s);
       +                if (app->left == 0) {
       +                        view_dispatcher_send_custom_event(app->vd, EVENT_FIRE_SIGNAL);
                                return;
                        }
                }
        
       -        if (a->repeat == 0)
       -                a->repeat_left = 1;
       +        if (app->repeat == 0)
       +                app->repeat_left = 1;
        
       -        redraw(a);
       -        view_dispatcher_switch_to_view(a->vd, ViewRun);
       +        render_timer(app);
       +        view_dispatcher_switch_to_view(app->vd, VIEW_RUN);
        
       -        a->timer = furi_timer_alloc(tick_cb, FuriTimerTypePeriodic, a);
       -        if (!a->timer)
       +        app->timer = furi_timer_alloc(on_timer_tick, FuriTimerTypePeriodic, app);
       +        if (app->timer == NULL)
                        return;
       -        furi_timer_start(a->timer, furi_kernel_get_tick_frequency());
       +
       +        furi_timer_start(app->timer, furi_kernel_get_tick_frequency());
        }
        
        bool
        scene_run_event(void *context, SceneManagerEvent event)
        {
       -        TimedRemoteApp *a = context;
       -        if (event.type == SceneManagerEventTypeBack)
       -        {
       -                scene_manager_search_and_switch_to_previous_scene(a->sm, ScBrowse);
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        if (event.type == SceneManagerEventTypeBack) {
       +                scene_manager_search_and_switch_to_previous_scene(
       +                    app->sm,
       +                    SCENE_BROWSE);
                        return true;
                }
                if (event.type != SceneManagerEventTypeCustom)
                        return false;
       -        if (event.event == EvTick)
       -        {
       -                if (a->left > 0)
       -                {
       -                        a->left--;
       -                        redraw(a);
       +
       +        if (event.event == EVENT_TIMER_TICK) {
       +                if (app->left > 0) {
       +                        app->left--;
       +                        render_timer(app);
                        }
       -                if (a->left == 0)
       -                        view_dispatcher_send_custom_event(a->vd, EvFire);
       +                if (app->left == 0)
       +                        view_dispatcher_send_custom_event(app->vd, EVENT_FIRE_SIGNAL);
                        return true;
                }
       -        if (event.event != EvFire)
       +        if (event.event != EVENT_FIRE_SIGNAL)
                        return false;
        
       -        if (a->ir)
       -                ir_tx(a->ir);
       +        if (app->ir != NULL)
       +                ir_tx(app->ir);
        
       -        if (a->repeat == 255)
       -        {
       -                a->left = countdown(a);
       -                redraw(a);
       +        if (app->repeat == REPEAT_UNLIMITED) {
       +                app->left = countdown_seconds(app);
       +                render_timer(app);
                        return true;
                }
        
       -        if (a->repeat_left > 0)
       -                a->repeat_left--;
       -        if (a->repeat != 0 && a->repeat_left > 0)
       -        {
       -                a->left = countdown(a);
       -                redraw(a);
       +        if (app->repeat_left > 0)
       +                app->repeat_left--;
       +
       +        if (app->repeat != 0 && app->repeat_left > 0) {
       +                app->left = countdown_seconds(app);
       +                render_timer(app);
                        return true;
                }
        
       -        scene_manager_next_scene(a->sm, ScDone);
       +        scene_manager_next_scene(app->sm, SCENE_DONE);
                return true;
        }
        
        void
        scene_run_exit(void *context)
        {
       -        TimedRemoteApp *a = context;
       -        if (a->timer)
       -        {
       -                furi_timer_stop(a->timer);
       -                furi_timer_free(a->timer);
       -                a->timer = NULL;
       +        TimedRemoteApp *app;
       +
       +        app = context;
       +        if (app->timer != NULL) {
       +                furi_timer_stop(app->timer);
       +                furi_timer_free(app->timer);
       +                app->timer = NULL;
                }
       -        widget_reset(a->widget);
       +        widget_reset(app->widget);
        }
   DIR diff --git a/scenes/timed_remote_scene.c b/scenes/timed_remote_scene.c
       @@ -1,32 +1,32 @@
        #include "timed_remote_scene.h"
        
       -static void (*const enter[])(void *) = {
       -        [ScBrowse] = scene_browse_enter,
       -        [ScSelect] = scene_select_enter,
       -        [ScCfg] = scene_cfg_enter,
       -        [ScRun] = scene_run_enter,
       -        [ScDone] = scene_done_enter,
       +static void (*const scene_on_enter[])(void *) = {
       +        [SCENE_BROWSE] = scene_browse_enter,
       +        [SCENE_SELECT] = scene_select_enter,
       +        [SCENE_CONFIG] = scene_cfg_enter,
       +        [SCENE_RUN] = scene_run_enter,
       +        [SCENE_DONE] = scene_done_enter,
        };
        
       -static bool (*const event[])(void *, SceneManagerEvent) = {
       -        [ScBrowse] = scene_browse_event,
       -        [ScSelect] = scene_select_event,
       -        [ScCfg] = scene_cfg_event,
       -        [ScRun] = scene_run_event,
       -        [ScDone] = scene_done_event,
       +static bool (*const scene_on_event[])(void *, SceneManagerEvent) = {
       +        [SCENE_BROWSE] = scene_browse_event,
       +        [SCENE_SELECT] = scene_select_event,
       +        [SCENE_CONFIG] = scene_cfg_event,
       +        [SCENE_RUN] = scene_run_event,
       +        [SCENE_DONE] = scene_done_event,
        };
        
       -static void (*const on_exit[])(void *) = {
       -        [ScBrowse] = scene_browse_exit,
       -        [ScSelect] = scene_select_exit,
       -        [ScCfg] = scene_cfg_exit,
       -        [ScRun] = scene_run_exit,
       -        [ScDone] = scene_done_exit,
       +static void (*const scene_on_exit[])(void *) = {
       +        [SCENE_BROWSE] = scene_browse_exit,
       +        [SCENE_SELECT] = scene_select_exit,
       +        [SCENE_CONFIG] = scene_cfg_exit,
       +        [SCENE_RUN] = scene_run_exit,
       +        [SCENE_DONE] = scene_done_exit,
        };
        
        const SceneManagerHandlers scene_handlers = {
       -        .on_enter_handlers = enter,
       -        .on_event_handlers = event,
       -        .on_exit_handlers = on_exit,
       -        .scene_num = ScN,
       +        .on_enter_handlers = scene_on_enter,
       +        .on_event_handlers = scene_on_event,
       +        .on_exit_handlers = scene_on_exit,
       +        .scene_num = SCENE_COUNT,
        };
   DIR diff --git a/scenes/timed_remote_scene.h b/scenes/timed_remote_scene.h
       @@ -4,37 +4,37 @@
        
        typedef enum
        {
       -        ScBrowse,
       -        ScSelect,
       -        ScCfg,
       -        ScRun,
       -        ScDone,
       -        ScN,
       +        SCENE_BROWSE,
       +        SCENE_SELECT,
       +        SCENE_CONFIG,
       +        SCENE_RUN,
       +        SCENE_DONE,
       +        SCENE_COUNT,
        } SceneId;
        
        typedef enum
        {
       -        EvFile,
       -        EvSig,
       -        EvMode,
       -        EvCfg,
       -        EvTick,
       -        EvFire,
       -        EvDone,
       +        EVENT_FILE_SELECTED,
       +        EVENT_SIGNAL_SELECTED,
       +        EVENT_MODE_CHANGED,
       +        EVENT_TIMER_CONFIGURED,
       +        EVENT_TIMER_TICK,
       +        EVENT_FIRE_SIGNAL,
       +        EVENT_DONE,
        } EvId;
        
       -void scene_browse_enter(void *context);
       -bool scene_browse_event(void *context, SceneManagerEvent event);
       -void scene_browse_exit(void *context);
       -void scene_select_enter(void *context);
       -bool scene_select_event(void *context, SceneManagerEvent event);
       -void scene_select_exit(void *context);
       -void scene_cfg_enter(void *context);
       -bool scene_cfg_event(void *context, SceneManagerEvent event);
       -void scene_cfg_exit(void *context);
       -void scene_run_enter(void *context);
       -bool scene_run_event(void *context, SceneManagerEvent event);
       -void scene_run_exit(void *context);
       -void scene_done_enter(void *context);
       -bool scene_done_event(void *context, SceneManagerEvent event);
       -void scene_done_exit(void *context);
       +void scene_browse_enter(void *);
       +bool scene_browse_event(void *, SceneManagerEvent);
       +void scene_browse_exit(void *);
       +void scene_select_enter(void *);
       +bool scene_select_event(void *, SceneManagerEvent);
       +void scene_select_exit(void *);
       +void scene_cfg_enter(void *);
       +bool scene_cfg_event(void *, SceneManagerEvent);
       +void scene_cfg_exit(void *);
       +void scene_run_enter(void *);
       +bool scene_run_event(void *, SceneManagerEvent);
       +void scene_run_exit(void *);
       +void scene_done_enter(void *);
       +bool scene_done_event(void *, SceneManagerEvent);
       +void scene_done_exit(void *);
   DIR diff --git a/timed_remote.c b/timed_remote.c
       @@ -1,26 +1,37 @@
       -#include "timed_remote.h"
       +#include <stdlib.h>
       +#include <string.h>
       +
        #include "scenes/timed_remote_scene.h"
       +#include "timed_remote.h"
        
        extern const SceneManagerHandlers scene_handlers;
        
        static bool
        nav_cb(void *context)
        {
       -        TimedRemoteApp *app = context;
       +        TimedRemoteApp *app;
       +
       +        app = context;
                return scene_manager_handle_back_event(app->sm);
        }
        
        static bool
        evt_cb(void *context, uint32_t evt)
        {
       -        TimedRemoteApp *app = context;
       +        TimedRemoteApp *app;
       +
       +        app = context;
                return scene_manager_handle_custom_event(app->sm, evt);
        }
        
        TimedRemoteApp *
        timed_remote_app_alloc(void)
        {
       -        TimedRemoteApp *app = malloc(sizeof(TimedRemoteApp));
       +        TimedRemoteApp *app;
       +
       +        app = malloc(sizeof(TimedRemoteApp));
       +        if (app == NULL)
       +                return NULL;
                memset(app, 0, sizeof(TimedRemoteApp));
        
                app->gui = furi_record_open(RECORD_GUI);
       @@ -29,27 +40,26 @@ timed_remote_app_alloc(void)
                view_dispatcher_set_event_callback_context(app->vd, app);
                view_dispatcher_set_navigation_event_callback(app->vd, nav_cb);
                view_dispatcher_set_custom_event_callback(app->vd, evt_cb);
       -        view_dispatcher_attach_to_gui(app->vd, app->gui,
       -                                      ViewDispatcherTypeFullscreen);
       +        view_dispatcher_attach_to_gui(
       +            app->vd, app->gui, ViewDispatcherTypeFullscreen);
        
                app->sm = scene_manager_alloc(&scene_handlers, app);
        
                app->submenu = submenu_alloc();
       -        view_dispatcher_add_view(app->vd, ViewMenu,
       -                                 submenu_get_view(app->submenu));
       +        view_dispatcher_add_view(
       +            app->vd, VIEW_MENU, submenu_get_view(app->submenu));
        
                app->vlist = variable_item_list_alloc();
                view_dispatcher_add_view(
       -                      app->vd, ViewList,
       -                      variable_item_list_get_view(app->vlist));
       +            app->vd, VIEW_LIST, variable_item_list_get_view(app->vlist));
        
                app->widget = widget_alloc();
       -        view_dispatcher_add_view(app->vd, ViewRun,
       -                                 widget_get_view(app->widget));
       +        view_dispatcher_add_view(
       +            app->vd, VIEW_RUN, widget_get_view(app->widget));
        
                app->popup = popup_alloc();
       -        view_dispatcher_add_view(app->vd, ViewPop,
       -                                 popup_get_view(app->popup));
       +        view_dispatcher_add_view(
       +            app->vd, VIEW_POP, popup_get_view(app->popup));
        
                return app;
        }
       @@ -57,34 +67,31 @@ timed_remote_app_alloc(void)
        void
        timed_remote_app_free(TimedRemoteApp *app)
        {
       -        if (app->timer)
       -        {
       +        if (app == NULL)
       +                return;
       +
       +        if (app->timer != NULL) {
                        furi_timer_stop(app->timer);
                        furi_timer_free(app->timer);
                }
        
       -        if (app->ir)
       -        {
       +        if (app->ir != NULL)
                        infrared_signal_free(app->ir);
       -        }
        
       -        view_dispatcher_remove_view(app->vd, ViewMenu);
       +        view_dispatcher_remove_view(app->vd, VIEW_MENU);
                submenu_free(app->submenu);
        
       -        view_dispatcher_remove_view(app->vd,
       -                                    ViewList);
       +        view_dispatcher_remove_view(app->vd, VIEW_LIST);
                variable_item_list_free(app->vlist);
        
       -        view_dispatcher_remove_view(app->vd, ViewRun);
       +        view_dispatcher_remove_view(app->vd, VIEW_RUN);
                widget_free(app->widget);
        
       -        view_dispatcher_remove_view(app->vd, ViewPop);
       +        view_dispatcher_remove_view(app->vd, VIEW_POP);
                popup_free(app->popup);
        
                scene_manager_free(app->sm);
       -
                view_dispatcher_free(app->vd);
       -
                furi_record_close(RECORD_GUI);
        
                free(app);
       @@ -93,14 +100,16 @@ timed_remote_app_free(TimedRemoteApp *app)
        int32_t
        timed_remote_app(void *p)
        {
       -        UNUSED(p);
       +        TimedRemoteApp *app;
        
       -        TimedRemoteApp *app = timed_remote_app_alloc();
       +        UNUSED(p);
        
       -        scene_manager_next_scene(app->sm, ScBrowse);
       +        app = timed_remote_app_alloc();
       +        if (app == NULL)
       +                return -1;
        
       +        scene_manager_next_scene(app->sm, SCENE_BROWSE);
                view_dispatcher_run(app->vd);
       -
                timed_remote_app_free(app);
        
                return 0;
   DIR diff --git a/timed_remote.h b/timed_remote.h
       @@ -12,16 +12,16 @@
        
        typedef enum
        {
       -        ModeDown,
       -        ModeSched,
       +        MODE_COUNTDOWN,
       +        MODE_SCHEDULED,
        } ModeId;
        
        typedef enum
        {
       -        ViewMenu,
       -        ViewList,
       -        ViewRun,
       -        ViewPop,
       +        VIEW_MENU,
       +        VIEW_LIST,
       +        VIEW_RUN,
       +        VIEW_POP,
        } ViewId;
        
        #define SIGNAL_NAME_MAX_LEN 32
       @@ -55,4 +55,4 @@ typedef struct
        } TimedRemoteApp;
        
        TimedRemoteApp *timed_remote_app_alloc(void);
       -void timed_remote_app_free(TimedRemoteApp *app);
       +void timed_remote_app_free(TimedRemoteApp *);