Просмотр исходного кода

Drop apps that went back to OFW (#60)

あく 2 лет назад
Родитель
Сommit
6b57580880
76 измененных файлов с 0 добавлено и 2990 удалено
  1. 0 49
      hid_app/.catalog/README_BLE.md
  2. 0 45
      hid_app/.catalog/README_USB.md
  3. BIN
      hid_app/.catalog/screenshots/1.png
  4. BIN
      hid_app/.catalog/screenshots/2.png
  5. BIN
      hid_app/.catalog/screenshots/3.png
  6. BIN
      hid_app/.catalog/screenshots/4.png
  7. 0 28
      hid_app/application.fam
  8. BIN
      hid_app/assets/Alt_11x7.png
  9. BIN
      hid_app/assets/Arr_dwn_7x9.png
  10. BIN
      hid_app/assets/Arr_up_7x9.png
  11. BIN
      hid_app/assets/Ble_connected_15x15.png
  12. BIN
      hid_app/assets/Ble_disconnected_15x15.png
  13. BIN
      hid_app/assets/ButtonDown_7x4.png
  14. BIN
      hid_app/assets/ButtonF10_5x8.png
  15. BIN
      hid_app/assets/ButtonF11_5x8.png
  16. BIN
      hid_app/assets/ButtonF12_5x8.png
  17. BIN
      hid_app/assets/ButtonF1_5x8.png
  18. BIN
      hid_app/assets/ButtonF2_5x8.png
  19. BIN
      hid_app/assets/ButtonF3_5x8.png
  20. BIN
      hid_app/assets/ButtonF4_5x8.png
  21. BIN
      hid_app/assets/ButtonF5_5x8.png
  22. BIN
      hid_app/assets/ButtonF6_5x8.png
  23. BIN
      hid_app/assets/ButtonF7_5x8.png
  24. BIN
      hid_app/assets/ButtonF8_5x8.png
  25. BIN
      hid_app/assets/ButtonF9_5x8.png
  26. BIN
      hid_app/assets/ButtonLeft_4x7.png
  27. BIN
      hid_app/assets/ButtonRight_4x7.png
  28. BIN
      hid_app/assets/ButtonUp_7x4.png
  29. BIN
      hid_app/assets/Button_18x18.png
  30. BIN
      hid_app/assets/Circles_47x47.png
  31. BIN
      hid_app/assets/Cmd_15x7.png
  32. BIN
      hid_app/assets/Ctrl_15x7.png
  33. BIN
      hid_app/assets/Del_12x7.png
  34. BIN
      hid_app/assets/Esc_14x7.png
  35. BIN
      hid_app/assets/Left_mouse_icon_9x9.png
  36. BIN
      hid_app/assets/Like_def_11x9.png
  37. BIN
      hid_app/assets/Like_pressed_17x17.png
  38. BIN
      hid_app/assets/Ok_btn_9x9.png
  39. BIN
      hid_app/assets/Ok_btn_pressed_13x13.png
  40. BIN
      hid_app/assets/Pin_arrow_down_7x9.png
  41. BIN
      hid_app/assets/Pin_arrow_left_9x7.png
  42. BIN
      hid_app/assets/Pin_arrow_right_9x7.png
  43. BIN
      hid_app/assets/Pin_arrow_up_7x9.png
  44. BIN
      hid_app/assets/Pin_back_arrow_10x8.png
  45. BIN
      hid_app/assets/Pressed_Button_13x13.png
  46. BIN
      hid_app/assets/Right_mouse_icon_9x9.png
  47. BIN
      hid_app/assets/Space_60x18.png
  48. BIN
      hid_app/assets/Space_65x18.png
  49. BIN
      hid_app/assets/Tab_15x7.png
  50. BIN
      hid_app/assets/Voldwn_6x6.png
  51. BIN
      hid_app/assets/Volup_8x6.png
  52. 0 452
      hid_app/hid.c
  53. 0 67
      hid_app/hid.h
  54. BIN
      hid_app/hid_ble_10px.png
  55. BIN
      hid_app/hid_usb_10px.png
  56. 0 11
      hid_app/views.h
  57. 0 411
      hid_app/views/hid_keyboard.c
  58. 0 14
      hid_app/views/hid_keyboard.h
  59. 0 312
      hid_app/views/hid_keynote.c
  60. 0 16
      hid_app/views/hid_keynote.h
  61. 0 218
      hid_app/views/hid_media.c
  62. 0 13
      hid_app/views/hid_media.h
  63. 0 226
      hid_app/views/hid_mouse.c
  64. 0 17
      hid_app/views/hid_mouse.h
  65. 0 214
      hid_app/views/hid_mouse_clicker.c
  66. 0 14
      hid_app/views/hid_mouse_clicker.h
  67. 0 159
      hid_app/views/hid_mouse_jiggler.c
  68. 0 17
      hid_app/views/hid_mouse_jiggler.h
  69. 0 241
      hid_app/views/hid_tiktok.c
  70. 0 14
      hid_app/views/hid_tiktok.h
  71. 0 5
      snake_game/.catalog/README.md
  72. BIN
      snake_game/.catalog/screenshots/1.png
  73. BIN
      snake_game/.catalog/screenshots/2.png
  74. 0 13
      snake_game/application.fam
  75. BIN
      snake_game/snake_10px.png
  76. 0 434
      snake_game/snake_game.c

+ 0 - 49
hid_app/.catalog/README_BLE.md

@@ -1,49 +0,0 @@
-# BLE Remote
-
-This application allows you to use your Flipper Zero as a HID (Human Interface Device) keyboard or mouse over Bluetooth Low Energy. It can be used to control a computer or a smartphone.
-
-# Pairing
-
-After selecting a mode, open the Bluetooth settings on your computer or smartphone and search for new devices. The Flipper Zero will appear as "Control NAME", where "NAME" is the name of your Flipper Zero. Pair with the device and it will be ready to use.
-
-# Modes
-
-## Keynote
-
-Use your Flipper Zero as a wireless presenter for any presentation software that supports keyboard navigation. There is also a vertical version that has the interface and controls rotated 90 degrees for easier use.
-
-## Keyboard
-
-Use your Flipper Zero as a wireless keyboard. Please note that key combinations are not supported.
-
-## Media
-
-Media controller mode allows you to control media playback on your computer or smartphone. It supports the following commands:
-
-* Play/Pause
-* Next Track
-* Previous Track
-* Volume Up
-* Volume Down
-
-## Mouse
-
-Use your Flipper Zero as a wireless mouse. Use the D-pad to move the cursor, and click with the OK and BACK buttons.
-
-## TikTok Controller
-
-Use your Flipper Zero as a wireless TikTok controller. It supports the following commands:
-
-* Like
-* Next Video
-* Previous Video
-* Volume Up
-* Volume Down
-
-## Mouse Clicker
-
-Repeatedly clicks the mouse button. The click interval can be adjusted with the UP and DOWN buttons.
-
-## Mouse Jiggler
-
-Moves your cursor slightly a few times per second. This can be used to prevent your computer from going to sleep.

+ 0 - 45
hid_app/.catalog/README_USB.md

@@ -1,45 +0,0 @@
-# BLE Remote
-
-This application allows you to use your Flipper Zero as a HID (Human Interface Device) keyboard or mouse over USB. It can be used to control a computer or a smartphone.
-
-# Modes
-
-## Keynote
-
-Use your Flipper Zero as a presenter for any presentation software that supports keyboard navigation. There is also a vertical version that has the interface and controls rotated 90 degrees for easier use.
-
-## Keyboard
-
-Use your Flipper Zero as a keyboard. Please note that key combinations are not supported.
-
-## Media
-
-Media controller mode allows you to control media playback on your computer or smartphone. It supports the following commands:
-
-* Play/Pause
-* Next Track
-* Previous Track
-* Volume Up
-* Volume Down
-
-## Mouse
-
-Use your Flipper Zero as a mouse. Use the D-pad to move the cursor, and click with the OK and BACK buttons.
-
-## TikTok Controller
-
-Use your Flipper Zero as a TikTok controller. It supports the following commands:
-
-* Like
-* Next Video
-* Previous Video
-* Volume Up
-* Volume Down
-
-## Mouse Clicker
-
-Repeatedly clicks the mouse button. The click interval can be adjusted with the UP and DOWN buttons.
-
-## Mouse Jiggler
-
-Moves your cursor slightly a few times per second. This can be used to prevent your computer from going to sleep.

BIN
hid_app/.catalog/screenshots/1.png


BIN
hid_app/.catalog/screenshots/2.png


BIN
hid_app/.catalog/screenshots/3.png


BIN
hid_app/.catalog/screenshots/4.png


+ 0 - 28
hid_app/application.fam

@@ -1,28 +0,0 @@
-App(
-    appid="hid_usb",
-    name="Remote",
-    apptype=FlipperAppType.EXTERNAL,
-    entry_point="hid_usb_app",
-    stack_size=1 * 1024,
-    fap_description="Use Flipper as a HID remote control over USB",
-    fap_version="1.0",
-    fap_category="USB",
-    fap_icon="hid_usb_10px.png",
-    fap_icon_assets="assets",
-    fap_icon_assets_symbol="hid",
-)
-
-
-App(
-    appid="hid_ble",
-    name="Remote",
-    apptype=FlipperAppType.EXTERNAL,
-    entry_point="hid_ble_app",
-    stack_size=1 * 1024,
-    fap_description="Use Flipper as a HID remote control over Bluetooth",
-    fap_version="1.0",
-    fap_category="Bluetooth",
-    fap_icon="hid_ble_10px.png",
-    fap_icon_assets="assets",
-    fap_icon_assets_symbol="hid",
-)

BIN
hid_app/assets/Alt_11x7.png


BIN
hid_app/assets/Arr_dwn_7x9.png


BIN
hid_app/assets/Arr_up_7x9.png


BIN
hid_app/assets/Ble_connected_15x15.png


BIN
hid_app/assets/Ble_disconnected_15x15.png


BIN
hid_app/assets/ButtonDown_7x4.png


BIN
hid_app/assets/ButtonF10_5x8.png


BIN
hid_app/assets/ButtonF11_5x8.png


BIN
hid_app/assets/ButtonF12_5x8.png


BIN
hid_app/assets/ButtonF1_5x8.png


BIN
hid_app/assets/ButtonF2_5x8.png


BIN
hid_app/assets/ButtonF3_5x8.png


BIN
hid_app/assets/ButtonF4_5x8.png


BIN
hid_app/assets/ButtonF5_5x8.png


BIN
hid_app/assets/ButtonF6_5x8.png


BIN
hid_app/assets/ButtonF7_5x8.png


BIN
hid_app/assets/ButtonF8_5x8.png


BIN
hid_app/assets/ButtonF9_5x8.png


BIN
hid_app/assets/ButtonLeft_4x7.png


BIN
hid_app/assets/ButtonRight_4x7.png


BIN
hid_app/assets/ButtonUp_7x4.png


BIN
hid_app/assets/Button_18x18.png


BIN
hid_app/assets/Circles_47x47.png


BIN
hid_app/assets/Cmd_15x7.png


BIN
hid_app/assets/Ctrl_15x7.png


BIN
hid_app/assets/Del_12x7.png


BIN
hid_app/assets/Esc_14x7.png


BIN
hid_app/assets/Left_mouse_icon_9x9.png


BIN
hid_app/assets/Like_def_11x9.png


BIN
hid_app/assets/Like_pressed_17x17.png


BIN
hid_app/assets/Ok_btn_9x9.png


BIN
hid_app/assets/Ok_btn_pressed_13x13.png


BIN
hid_app/assets/Pin_arrow_down_7x9.png


BIN
hid_app/assets/Pin_arrow_left_9x7.png


BIN
hid_app/assets/Pin_arrow_right_9x7.png


BIN
hid_app/assets/Pin_arrow_up_7x9.png


BIN
hid_app/assets/Pin_back_arrow_10x8.png


BIN
hid_app/assets/Pressed_Button_13x13.png


BIN
hid_app/assets/Right_mouse_icon_9x9.png


BIN
hid_app/assets/Space_60x18.png


BIN
hid_app/assets/Space_65x18.png


BIN
hid_app/assets/Tab_15x7.png


BIN
hid_app/assets/Voldwn_6x6.png


BIN
hid_app/assets/Volup_8x6.png


+ 0 - 452
hid_app/hid.c

@@ -1,452 +0,0 @@
-#include "hid.h"
-#include "views.h"
-#include <notification/notification_messages.h>
-#include <dolphin/dolphin.h>
-
-#define TAG "HidApp"
-
-enum HidDebugSubmenuIndex {
-    HidSubmenuIndexKeynote,
-    HidSubmenuIndexKeynoteVertical,
-    HidSubmenuIndexKeyboard,
-    HidSubmenuIndexMedia,
-    HidSubmenuIndexTikTok,
-    HidSubmenuIndexMouse,
-    HidSubmenuIndexMouseClicker,
-    HidSubmenuIndexMouseJiggler,
-};
-
-static void hid_submenu_callback(void* context, uint32_t index) {
-    furi_assert(context);
-    Hid* app = context;
-    if(index == HidSubmenuIndexKeynote) {
-        app->view_id = HidViewKeynote;
-        hid_keynote_set_orientation(app->hid_keynote, false);
-        view_dispatcher_switch_to_view(app->view_dispatcher, HidViewKeynote);
-    } else if(index == HidSubmenuIndexKeynoteVertical) {
-        app->view_id = HidViewKeynote;
-        hid_keynote_set_orientation(app->hid_keynote, true);
-        view_dispatcher_switch_to_view(app->view_dispatcher, HidViewKeynote);
-    } else if(index == HidSubmenuIndexKeyboard) {
-        app->view_id = HidViewKeyboard;
-        view_dispatcher_switch_to_view(app->view_dispatcher, HidViewKeyboard);
-    } else if(index == HidSubmenuIndexMedia) {
-        app->view_id = HidViewMedia;
-        view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMedia);
-    } else if(index == HidSubmenuIndexMouse) {
-        app->view_id = HidViewMouse;
-        view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouse);
-    } else if(index == HidSubmenuIndexTikTok) {
-        app->view_id = BtHidViewTikTok;
-        view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewTikTok);
-    } else if(index == HidSubmenuIndexMouseClicker) {
-        app->view_id = HidViewMouseClicker;
-        view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouseClicker);
-    } else if(index == HidSubmenuIndexMouseJiggler) {
-        app->view_id = HidViewMouseJiggler;
-        view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouseJiggler);
-    }
-}
-
-static void bt_hid_connection_status_changed_callback(BtStatus status, void* context) {
-    furi_assert(context);
-    Hid* hid = context;
-    bool connected = (status == BtStatusConnected);
-    if(hid->transport == HidTransportBle) {
-        if(connected) {
-            notification_internal_message(hid->notifications, &sequence_set_blue_255);
-        } else {
-            notification_internal_message(hid->notifications, &sequence_reset_blue);
-        }
-    }
-    hid_keynote_set_connected_status(hid->hid_keynote, connected);
-    hid_keyboard_set_connected_status(hid->hid_keyboard, connected);
-    hid_media_set_connected_status(hid->hid_media, connected);
-    hid_mouse_set_connected_status(hid->hid_mouse, connected);
-    hid_mouse_clicker_set_connected_status(hid->hid_mouse_clicker, connected);
-    hid_mouse_jiggler_set_connected_status(hid->hid_mouse_jiggler, connected);
-    hid_tiktok_set_connected_status(hid->hid_tiktok, connected);
-}
-
-static void hid_dialog_callback(DialogExResult result, void* context) {
-    furi_assert(context);
-    Hid* app = context;
-    if(result == DialogExResultLeft) {
-        view_dispatcher_stop(app->view_dispatcher);
-    } else if(result == DialogExResultRight) {
-        view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id); // Show last view
-    } else if(result == DialogExResultCenter) {
-        view_dispatcher_switch_to_view(app->view_dispatcher, HidViewSubmenu);
-    }
-}
-
-static uint32_t hid_exit_confirm_view(void* context) {
-    UNUSED(context);
-    return HidViewExitConfirm;
-}
-
-static uint32_t hid_exit(void* context) {
-    UNUSED(context);
-    return VIEW_NONE;
-}
-
-Hid* hid_alloc(HidTransport transport) {
-    Hid* app = malloc(sizeof(Hid));
-    app->transport = transport;
-
-    // Gui
-    app->gui = furi_record_open(RECORD_GUI);
-
-    // Bt
-    app->bt = furi_record_open(RECORD_BT);
-
-    // Notifications
-    app->notifications = furi_record_open(RECORD_NOTIFICATION);
-
-    // View dispatcher
-    app->view_dispatcher = view_dispatcher_alloc();
-    view_dispatcher_enable_queue(app->view_dispatcher);
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-    // Device Type Submenu view
-    app->device_type_submenu = submenu_alloc();
-    submenu_add_item(
-        app->device_type_submenu, "Keynote", HidSubmenuIndexKeynote, hid_submenu_callback, app);
-    submenu_add_item(
-        app->device_type_submenu,
-        "Keynote Vertical",
-        HidSubmenuIndexKeynoteVertical,
-        hid_submenu_callback,
-        app);
-    submenu_add_item(
-        app->device_type_submenu, "Keyboard", HidSubmenuIndexKeyboard, hid_submenu_callback, app);
-    submenu_add_item(
-        app->device_type_submenu, "Media", HidSubmenuIndexMedia, hid_submenu_callback, app);
-    submenu_add_item(
-        app->device_type_submenu, "Mouse", HidSubmenuIndexMouse, hid_submenu_callback, app);
-    if(app->transport == HidTransportBle) {
-        submenu_add_item(
-            app->device_type_submenu,
-            "TikTok Controller",
-            HidSubmenuIndexTikTok,
-            hid_submenu_callback,
-            app);
-    }
-    submenu_add_item(
-        app->device_type_submenu,
-        "Mouse Clicker",
-        HidSubmenuIndexMouseClicker,
-        hid_submenu_callback,
-        app);
-    submenu_add_item(
-        app->device_type_submenu,
-        "Mouse Jiggler",
-        HidSubmenuIndexMouseJiggler,
-        hid_submenu_callback,
-        app);
-    view_set_previous_callback(submenu_get_view(app->device_type_submenu), hid_exit);
-    view_dispatcher_add_view(
-        app->view_dispatcher, HidViewSubmenu, submenu_get_view(app->device_type_submenu));
-    app->view_id = HidViewSubmenu;
-    view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id);
-    return app;
-}
-
-Hid* hid_app_alloc_view(void* context) {
-    furi_assert(context);
-    Hid* app = context;
-    // Dialog view
-    app->dialog = dialog_ex_alloc();
-    dialog_ex_set_result_callback(app->dialog, hid_dialog_callback);
-    dialog_ex_set_context(app->dialog, app);
-    dialog_ex_set_left_button_text(app->dialog, "Exit");
-    dialog_ex_set_right_button_text(app->dialog, "Stay");
-    dialog_ex_set_center_button_text(app->dialog, "Menu");
-    dialog_ex_set_header(app->dialog, "Close Current App?", 16, 12, AlignLeft, AlignTop);
-    view_dispatcher_add_view(
-        app->view_dispatcher, HidViewExitConfirm, dialog_ex_get_view(app->dialog));
-
-    // Keynote view
-    app->hid_keynote = hid_keynote_alloc(app);
-    view_set_previous_callback(hid_keynote_get_view(app->hid_keynote), hid_exit_confirm_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher, HidViewKeynote, hid_keynote_get_view(app->hid_keynote));
-
-    // Keyboard view
-    app->hid_keyboard = hid_keyboard_alloc(app);
-    view_set_previous_callback(hid_keyboard_get_view(app->hid_keyboard), hid_exit_confirm_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher, HidViewKeyboard, hid_keyboard_get_view(app->hid_keyboard));
-
-    // Media view
-    app->hid_media = hid_media_alloc(app);
-    view_set_previous_callback(hid_media_get_view(app->hid_media), hid_exit_confirm_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher, HidViewMedia, hid_media_get_view(app->hid_media));
-
-    // TikTok view
-    app->hid_tiktok = hid_tiktok_alloc(app);
-    view_set_previous_callback(hid_tiktok_get_view(app->hid_tiktok), hid_exit_confirm_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher, BtHidViewTikTok, hid_tiktok_get_view(app->hid_tiktok));
-
-    // Mouse view
-    app->hid_mouse = hid_mouse_alloc(app);
-    view_set_previous_callback(hid_mouse_get_view(app->hid_mouse), hid_exit_confirm_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher, HidViewMouse, hid_mouse_get_view(app->hid_mouse));
-
-    // Mouse clicker view
-    app->hid_mouse_clicker = hid_mouse_clicker_alloc(app);
-    view_set_previous_callback(
-        hid_mouse_clicker_get_view(app->hid_mouse_clicker), hid_exit_confirm_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher,
-        HidViewMouseClicker,
-        hid_mouse_clicker_get_view(app->hid_mouse_clicker));
-
-    // Mouse jiggler view
-    app->hid_mouse_jiggler = hid_mouse_jiggler_alloc(app);
-    view_set_previous_callback(
-        hid_mouse_jiggler_get_view(app->hid_mouse_jiggler), hid_exit_confirm_view);
-    view_dispatcher_add_view(
-        app->view_dispatcher,
-        HidViewMouseJiggler,
-        hid_mouse_jiggler_get_view(app->hid_mouse_jiggler));
-
-    return app;
-}
-
-void hid_free(Hid* app) {
-    furi_assert(app);
-
-    // Reset notification
-    if(app->transport == HidTransportBle) {
-        notification_internal_message(app->notifications, &sequence_reset_blue);
-    }
-
-    // Free views
-    view_dispatcher_remove_view(app->view_dispatcher, HidViewSubmenu);
-    submenu_free(app->device_type_submenu);
-    view_dispatcher_remove_view(app->view_dispatcher, HidViewExitConfirm);
-    dialog_ex_free(app->dialog);
-    view_dispatcher_remove_view(app->view_dispatcher, HidViewKeynote);
-    hid_keynote_free(app->hid_keynote);
-    view_dispatcher_remove_view(app->view_dispatcher, HidViewKeyboard);
-    hid_keyboard_free(app->hid_keyboard);
-    view_dispatcher_remove_view(app->view_dispatcher, HidViewMedia);
-    hid_media_free(app->hid_media);
-    view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse);
-    hid_mouse_free(app->hid_mouse);
-    view_dispatcher_remove_view(app->view_dispatcher, HidViewMouseClicker);
-    hid_mouse_clicker_free(app->hid_mouse_clicker);
-    view_dispatcher_remove_view(app->view_dispatcher, HidViewMouseJiggler);
-    hid_mouse_jiggler_free(app->hid_mouse_jiggler);
-    view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok);
-    hid_tiktok_free(app->hid_tiktok);
-    view_dispatcher_free(app->view_dispatcher);
-
-    // Close records
-    furi_record_close(RECORD_GUI);
-    app->gui = NULL;
-    furi_record_close(RECORD_NOTIFICATION);
-    app->notifications = NULL;
-    furi_record_close(RECORD_BT);
-    app->bt = NULL;
-
-    // Free rest
-    free(app);
-}
-
-void hid_hal_keyboard_press(Hid* instance, uint16_t event) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_kb_press(event);
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_kb_press(event);
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_keyboard_release(Hid* instance, uint16_t event) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_kb_release(event);
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_kb_release(event);
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_keyboard_release_all(Hid* instance) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_kb_release_all();
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_kb_release_all();
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_consumer_key_press(Hid* instance, uint16_t event) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_consumer_key_press(event);
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_consumer_key_press(event);
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_consumer_key_release(Hid* instance, uint16_t event) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_consumer_key_release(event);
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_consumer_key_release(event);
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_consumer_key_release_all(Hid* instance) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_consumer_key_release_all();
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_kb_release_all();
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_mouse_move(Hid* instance, int8_t dx, int8_t dy) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_mouse_move(dx, dy);
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_mouse_move(dx, dy);
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_mouse_scroll(Hid* instance, int8_t delta) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_mouse_scroll(delta);
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_mouse_scroll(delta);
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_mouse_press(Hid* instance, uint16_t event) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_mouse_press(event);
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_mouse_press(event);
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_mouse_release(Hid* instance, uint16_t event) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_mouse_release(event);
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_mouse_release(event);
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-void hid_hal_mouse_release_all(Hid* instance) {
-    furi_assert(instance);
-    if(instance->transport == HidTransportBle) {
-        furi_hal_bt_hid_mouse_release_all();
-    } else if(instance->transport == HidTransportUsb) {
-        furi_hal_hid_mouse_release(HID_MOUSE_BTN_LEFT);
-        furi_hal_hid_mouse_release(HID_MOUSE_BTN_RIGHT);
-    } else {
-        furi_crash(NULL);
-    }
-}
-
-int32_t hid_usb_app(void* p) {
-    UNUSED(p);
-    Hid* app = hid_alloc(HidTransportUsb);
-    app = hid_app_alloc_view(app);
-    FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
-    furi_hal_usb_unlock();
-    furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
-
-    bt_hid_connection_status_changed_callback(BtStatusConnected, app);
-
-    dolphin_deed(DolphinDeedPluginStart);
-
-    view_dispatcher_run(app->view_dispatcher);
-
-    furi_hal_usb_set_config(usb_mode_prev, NULL);
-
-    hid_free(app);
-
-    return 0;
-}
-
-int32_t hid_ble_app(void* p) {
-    UNUSED(p);
-    Hid* app = hid_alloc(HidTransportBle);
-    app = hid_app_alloc_view(app);
-
-    bt_disconnect(app->bt);
-
-    // Wait 2nd core to update nvm storage
-    furi_delay_ms(200);
-
-    // Migrate data from old sd-card folder
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-
-    storage_common_migrate(
-        storage,
-        EXT_PATH("apps/Tools/" HID_BT_KEYS_STORAGE_NAME),
-        APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME));
-
-    bt_keys_storage_set_storage_path(app->bt, APP_DATA_PATH(HID_BT_KEYS_STORAGE_NAME));
-
-    furi_record_close(RECORD_STORAGE);
-
-    if(!bt_set_profile(app->bt, BtProfileHidKeyboard)) {
-        FURI_LOG_E(TAG, "Failed to switch to HID profile");
-    }
-
-    furi_hal_bt_start_advertising();
-    bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app);
-
-    dolphin_deed(DolphinDeedPluginStart);
-
-    view_dispatcher_run(app->view_dispatcher);
-
-    bt_set_status_changed_callback(app->bt, NULL, NULL);
-
-    bt_disconnect(app->bt);
-
-    // Wait 2nd core to update nvm storage
-    furi_delay_ms(200);
-
-    bt_keys_storage_set_default_path(app->bt);
-
-    if(!bt_set_profile(app->bt, BtProfileSerial)) {
-        FURI_LOG_E(TAG, "Failed to switch to Serial profile");
-    }
-
-    hid_free(app);
-
-    return 0;
-}

+ 0 - 67
hid_app/hid.h

@@ -1,67 +0,0 @@
-#pragma once
-
-#include <furi.h>
-#include <furi_hal_bt.h>
-#include <furi_hal_bt_hid.h>
-#include <furi_hal_usb.h>
-#include <furi_hal_usb_hid.h>
-
-#include <bt/bt_service/bt.h>
-#include <gui/gui.h>
-#include <gui/view.h>
-#include <gui/view_dispatcher.h>
-#include <notification/notification.h>
-#include <storage/storage.h>
-
-#include <gui/modules/submenu.h>
-#include <gui/modules/dialog_ex.h>
-#include <gui/modules/popup.h>
-#include "views/hid_keynote.h"
-#include "views/hid_keyboard.h"
-#include "views/hid_media.h"
-#include "views/hid_mouse.h"
-#include "views/hid_mouse_clicker.h"
-#include "views/hid_mouse_jiggler.h"
-#include "views/hid_tiktok.h"
-
-#define HID_BT_KEYS_STORAGE_NAME ".bt_hid.keys"
-
-typedef enum {
-    HidTransportUsb,
-    HidTransportBle,
-} HidTransport;
-
-typedef struct Hid Hid;
-
-struct Hid {
-    Bt* bt;
-    Gui* gui;
-    NotificationApp* notifications;
-    ViewDispatcher* view_dispatcher;
-    Submenu* device_type_submenu;
-    DialogEx* dialog;
-    HidKeynote* hid_keynote;
-    HidKeyboard* hid_keyboard;
-    HidMedia* hid_media;
-    HidMouse* hid_mouse;
-    HidMouseClicker* hid_mouse_clicker;
-    HidMouseJiggler* hid_mouse_jiggler;
-    HidTikTok* hid_tiktok;
-
-    HidTransport transport;
-    uint32_t view_id;
-};
-
-void hid_hal_keyboard_press(Hid* instance, uint16_t event);
-void hid_hal_keyboard_release(Hid* instance, uint16_t event);
-void hid_hal_keyboard_release_all(Hid* instance);
-
-void hid_hal_consumer_key_press(Hid* instance, uint16_t event);
-void hid_hal_consumer_key_release(Hid* instance, uint16_t event);
-void hid_hal_consumer_key_release_all(Hid* instance);
-
-void hid_hal_mouse_move(Hid* instance, int8_t dx, int8_t dy);
-void hid_hal_mouse_scroll(Hid* instance, int8_t delta);
-void hid_hal_mouse_press(Hid* instance, uint16_t event);
-void hid_hal_mouse_release(Hid* instance, uint16_t event);
-void hid_hal_mouse_release_all(Hid* instance);

BIN
hid_app/hid_ble_10px.png


BIN
hid_app/hid_usb_10px.png


+ 0 - 11
hid_app/views.h

@@ -1,11 +0,0 @@
-typedef enum {
-    HidViewSubmenu,
-    HidViewKeynote,
-    HidViewKeyboard,
-    HidViewMedia,
-    HidViewMouse,
-    HidViewMouseClicker,
-    HidViewMouseJiggler,
-    BtHidViewTikTok,
-    HidViewExitConfirm,
-} HidView;

+ 0 - 411
hid_app/views/hid_keyboard.c

@@ -1,411 +0,0 @@
-#include "hid_keyboard.h"
-#include <furi.h>
-#include <gui/elements.h>
-#include <gui/icon_i.h>
-#include "../hid.h"
-#include "hid_icons.h"
-
-#define TAG "HidKeyboard"
-
-struct HidKeyboard {
-    View* view;
-    Hid* hid;
-};
-
-typedef struct {
-    bool shift;
-    bool alt;
-    bool ctrl;
-    bool gui;
-    uint8_t x;
-    uint8_t y;
-    uint8_t last_key_code;
-    uint16_t modifier_code;
-    bool ok_pressed;
-    bool back_pressed;
-    bool connected;
-    char key_string[5];
-    HidTransport transport;
-} HidKeyboardModel;
-
-typedef struct {
-    uint8_t width;
-    char* key;
-    const Icon* icon;
-    char* shift_key;
-    uint8_t value;
-} HidKeyboardKey;
-
-typedef struct {
-    int8_t x;
-    int8_t y;
-} HidKeyboardPoint;
-// 4 BY 12
-#define MARGIN_TOP 0
-#define MARGIN_LEFT 4
-#define KEY_WIDTH 9
-#define KEY_HEIGHT 12
-#define KEY_PADDING 1
-#define ROW_COUNT 7
-#define COLUMN_COUNT 12
-
-// 0 width items are not drawn, but there value is used
-const HidKeyboardKey hid_keyboard_keyset[ROW_COUNT][COLUMN_COUNT] = {
-    {
-        {.width = 1, .icon = &I_ButtonF1_5x8, .value = HID_KEYBOARD_F1},
-        {.width = 1, .icon = &I_ButtonF2_5x8, .value = HID_KEYBOARD_F2},
-        {.width = 1, .icon = &I_ButtonF3_5x8, .value = HID_KEYBOARD_F3},
-        {.width = 1, .icon = &I_ButtonF4_5x8, .value = HID_KEYBOARD_F4},
-        {.width = 1, .icon = &I_ButtonF5_5x8, .value = HID_KEYBOARD_F5},
-        {.width = 1, .icon = &I_ButtonF6_5x8, .value = HID_KEYBOARD_F6},
-        {.width = 1, .icon = &I_ButtonF7_5x8, .value = HID_KEYBOARD_F7},
-        {.width = 1, .icon = &I_ButtonF8_5x8, .value = HID_KEYBOARD_F8},
-        {.width = 1, .icon = &I_ButtonF9_5x8, .value = HID_KEYBOARD_F9},
-        {.width = 1, .icon = &I_ButtonF10_5x8, .value = HID_KEYBOARD_F10},
-        {.width = 1, .icon = &I_ButtonF11_5x8, .value = HID_KEYBOARD_F11},
-        {.width = 1, .icon = &I_ButtonF12_5x8, .value = HID_KEYBOARD_F12},
-    },
-    {
-        {.width = 1, .icon = NULL, .key = "1", .shift_key = "!", .value = HID_KEYBOARD_1},
-        {.width = 1, .icon = NULL, .key = "2", .shift_key = "@", .value = HID_KEYBOARD_2},
-        {.width = 1, .icon = NULL, .key = "3", .shift_key = "#", .value = HID_KEYBOARD_3},
-        {.width = 1, .icon = NULL, .key = "4", .shift_key = "$", .value = HID_KEYBOARD_4},
-        {.width = 1, .icon = NULL, .key = "5", .shift_key = "%", .value = HID_KEYBOARD_5},
-        {.width = 1, .icon = NULL, .key = "6", .shift_key = "^", .value = HID_KEYBOARD_6},
-        {.width = 1, .icon = NULL, .key = "7", .shift_key = "&", .value = HID_KEYBOARD_7},
-        {.width = 1, .icon = NULL, .key = "8", .shift_key = "*", .value = HID_KEYBOARD_8},
-        {.width = 1, .icon = NULL, .key = "9", .shift_key = "(", .value = HID_KEYBOARD_9},
-        {.width = 1, .icon = NULL, .key = "0", .shift_key = ")", .value = HID_KEYBOARD_0},
-        {.width = 2, .icon = &I_Pin_arrow_left_9x7, .value = HID_KEYBOARD_DELETE},
-        {.width = 0, .value = HID_KEYBOARD_DELETE},
-    },
-    {
-        {.width = 1, .icon = NULL, .key = "q", .shift_key = "Q", .value = HID_KEYBOARD_Q},
-        {.width = 1, .icon = NULL, .key = "w", .shift_key = "W", .value = HID_KEYBOARD_W},
-        {.width = 1, .icon = NULL, .key = "e", .shift_key = "E", .value = HID_KEYBOARD_E},
-        {.width = 1, .icon = NULL, .key = "r", .shift_key = "R", .value = HID_KEYBOARD_R},
-        {.width = 1, .icon = NULL, .key = "t", .shift_key = "T", .value = HID_KEYBOARD_T},
-        {.width = 1, .icon = NULL, .key = "y", .shift_key = "Y", .value = HID_KEYBOARD_Y},
-        {.width = 1, .icon = NULL, .key = "u", .shift_key = "U", .value = HID_KEYBOARD_U},
-        {.width = 1, .icon = NULL, .key = "i", .shift_key = "I", .value = HID_KEYBOARD_I},
-        {.width = 1, .icon = NULL, .key = "o", .shift_key = "O", .value = HID_KEYBOARD_O},
-        {.width = 1, .icon = NULL, .key = "p", .shift_key = "P", .value = HID_KEYBOARD_P},
-        {.width = 1, .icon = NULL, .key = "[", .shift_key = "{", .value = HID_KEYBOARD_OPEN_BRACKET},
-        {.width = 1,
-         .icon = NULL,
-         .key = "]",
-         .shift_key = "}",
-         .value = HID_KEYBOARD_CLOSE_BRACKET},
-    },
-    {
-        {.width = 1, .icon = NULL, .key = "a", .shift_key = "A", .value = HID_KEYBOARD_A},
-        {.width = 1, .icon = NULL, .key = "s", .shift_key = "S", .value = HID_KEYBOARD_S},
-        {.width = 1, .icon = NULL, .key = "d", .shift_key = "D", .value = HID_KEYBOARD_D},
-        {.width = 1, .icon = NULL, .key = "f", .shift_key = "F", .value = HID_KEYBOARD_F},
-        {.width = 1, .icon = NULL, .key = "g", .shift_key = "G", .value = HID_KEYBOARD_G},
-        {.width = 1, .icon = NULL, .key = "h", .shift_key = "H", .value = HID_KEYBOARD_H},
-        {.width = 1, .icon = NULL, .key = "j", .shift_key = "J", .value = HID_KEYBOARD_J},
-        {.width = 1, .icon = NULL, .key = "k", .shift_key = "K", .value = HID_KEYBOARD_K},
-        {.width = 1, .icon = NULL, .key = "l", .shift_key = "L", .value = HID_KEYBOARD_L},
-        {.width = 1, .icon = NULL, .key = ";", .shift_key = ":", .value = HID_KEYBOARD_SEMICOLON},
-        {.width = 2, .icon = &I_Pin_arrow_right_9x7, .value = HID_KEYBOARD_RETURN},
-        {.width = 0, .value = HID_KEYBOARD_RETURN},
-    },
-    {
-        {.width = 1, .icon = NULL, .key = "z", .shift_key = "Z", .value = HID_KEYBOARD_Z},
-        {.width = 1, .icon = NULL, .key = "x", .shift_key = "X", .value = HID_KEYBOARD_X},
-        {.width = 1, .icon = NULL, .key = "c", .shift_key = "C", .value = HID_KEYBOARD_C},
-        {.width = 1, .icon = NULL, .key = "v", .shift_key = "V", .value = HID_KEYBOARD_V},
-        {.width = 1, .icon = NULL, .key = "b", .shift_key = "B", .value = HID_KEYBOARD_B},
-        {.width = 1, .icon = NULL, .key = "n", .shift_key = "N", .value = HID_KEYBOARD_N},
-        {.width = 1, .icon = NULL, .key = "m", .shift_key = "M", .value = HID_KEYBOARD_M},
-        {.width = 1, .icon = NULL, .key = "/", .shift_key = "?", .value = HID_KEYBOARD_SLASH},
-        {.width = 1, .icon = NULL, .key = "\\", .shift_key = "|", .value = HID_KEYBOARD_BACKSLASH},
-        {.width = 1, .icon = NULL, .key = "`", .shift_key = "~", .value = HID_KEYBOARD_GRAVE_ACCENT},
-        {.width = 1, .icon = &I_ButtonUp_7x4, .value = HID_KEYBOARD_UP_ARROW},
-        {.width = 1, .icon = NULL, .key = "-", .shift_key = "_", .value = HID_KEYBOARD_MINUS},
-    },
-    {
-        {.width = 1, .icon = &I_Pin_arrow_up_7x9, .value = HID_KEYBOARD_L_SHIFT},
-        {.width = 1, .icon = NULL, .key = ",", .shift_key = "<", .value = HID_KEYBOARD_COMMA},
-        {.width = 1, .icon = NULL, .key = ".", .shift_key = ">", .value = HID_KEYBOARD_DOT},
-        {.width = 4, .icon = NULL, .key = " ", .value = HID_KEYBOARD_SPACEBAR},
-        {.width = 0, .value = HID_KEYBOARD_SPACEBAR},
-        {.width = 0, .value = HID_KEYBOARD_SPACEBAR},
-        {.width = 0, .value = HID_KEYBOARD_SPACEBAR},
-        {.width = 1, .icon = NULL, .key = "'", .shift_key = "\"", .value = HID_KEYBOARD_APOSTROPHE},
-        {.width = 1, .icon = NULL, .key = "=", .shift_key = "+", .value = HID_KEYBOARD_EQUAL_SIGN},
-        {.width = 1, .icon = &I_ButtonLeft_4x7, .value = HID_KEYBOARD_LEFT_ARROW},
-        {.width = 1, .icon = &I_ButtonDown_7x4, .value = HID_KEYBOARD_DOWN_ARROW},
-        {.width = 1, .icon = &I_ButtonRight_4x7, .value = HID_KEYBOARD_RIGHT_ARROW},
-    },
-    {
-        {.width = 2, .icon = &I_Ctrl_15x7, .value = HID_KEYBOARD_L_CTRL},
-        {.width = 0, .value = HID_KEYBOARD_L_CTRL},
-        {.width = 2, .icon = &I_Alt_11x7, .value = HID_KEYBOARD_L_ALT},
-        {.width = 0, .value = HID_KEYBOARD_L_ALT},
-        {.width = 2, .icon = &I_Cmd_15x7, .value = HID_KEYBOARD_L_GUI},
-        {.width = 0, .value = HID_KEYBOARD_L_GUI},
-        {.width = 2, .icon = &I_Tab_15x7, .value = HID_KEYBOARD_TAB},
-        {.width = 0, .value = HID_KEYBOARD_TAB},
-        {.width = 2, .icon = &I_Esc_14x7, .value = HID_KEYBOARD_ESCAPE},
-        {.width = 0, .value = HID_KEYBOARD_ESCAPE},
-        {.width = 2, .icon = &I_Del_12x7, .value = HID_KEYBOARD_DELETE_FORWARD},
-        {.width = 0, .value = HID_KEYBOARD_DELETE_FORWARD},
-    },
-};
-
-static void hid_keyboard_to_upper(char* str) {
-    while(*str) {
-        *str = toupper((unsigned char)*str);
-        str++;
-    }
-}
-
-static void hid_keyboard_draw_key(
-    Canvas* canvas,
-    HidKeyboardModel* model,
-    uint8_t x,
-    uint8_t y,
-    HidKeyboardKey key,
-    bool selected) {
-    if(!key.width) return;
-
-    canvas_set_color(canvas, ColorBlack);
-    uint8_t keyWidth = KEY_WIDTH * key.width + KEY_PADDING * (key.width - 1);
-    if(selected) {
-        // Draw a filled box
-        elements_slightly_rounded_box(
-            canvas,
-            MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING),
-            MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING),
-            keyWidth,
-            KEY_HEIGHT);
-        canvas_set_color(canvas, ColorWhite);
-    } else {
-        // Draw a framed box
-        elements_slightly_rounded_frame(
-            canvas,
-            MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING),
-            MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING),
-            keyWidth,
-            KEY_HEIGHT);
-    }
-    if(key.icon != NULL) {
-        // Draw the icon centered on the button
-        canvas_draw_icon(
-            canvas,
-            MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 - key.icon->width / 2,
-            MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2 - key.icon->height / 2,
-            key.icon);
-    } else {
-        // If shift is toggled use the shift key when available
-        strcpy(model->key_string, (model->shift && key.shift_key != 0) ? key.shift_key : key.key);
-        // Upper case if ctrl or alt was toggled true
-        if((model->ctrl && key.value == HID_KEYBOARD_L_CTRL) ||
-           (model->alt && key.value == HID_KEYBOARD_L_ALT) ||
-           (model->gui && key.value == HID_KEYBOARD_L_GUI)) {
-            hid_keyboard_to_upper(model->key_string);
-        }
-        canvas_draw_str_aligned(
-            canvas,
-            MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 + 1,
-            MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + KEY_HEIGHT / 2,
-            AlignCenter,
-            AlignCenter,
-            model->key_string);
-    }
-}
-
-static void hid_keyboard_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    HidKeyboardModel* model = context;
-
-    // Header
-    if((!model->connected) && (model->transport == HidTransportBle)) {
-        canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
-        canvas_set_font(canvas, FontPrimary);
-        elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Keyboard");
-
-        canvas_draw_icon(canvas, 68, 3, &I_Pin_back_arrow_10x8);
-        canvas_set_font(canvas, FontSecondary);
-        elements_multiline_text_aligned(canvas, 127, 4, AlignRight, AlignTop, "Hold to exit");
-
-        elements_multiline_text_aligned(
-            canvas, 4, 60, AlignLeft, AlignBottom, "Waiting for Connection...");
-        return; // Dont render the keyboard if we are not yet connected
-    }
-
-    canvas_set_font(canvas, FontKeyboard);
-    // Start shifting the all keys up if on the next row (Scrolling)
-    uint8_t initY = model->y == 0 ? 0 : 1;
-
-    if(model->y > 5) {
-        initY = model->y - 4;
-    }
-
-    for(uint8_t y = initY; y < ROW_COUNT; y++) {
-        const HidKeyboardKey* keyboardKeyRow = hid_keyboard_keyset[y];
-        uint8_t x = 0;
-        for(uint8_t i = 0; i < COLUMN_COUNT; i++) {
-            HidKeyboardKey key = keyboardKeyRow[i];
-            // Select when the button is hovered
-            // Select if the button is hovered within its width
-            // Select if back is clicked and its the backspace key
-            // Deselect when the button clicked or not hovered
-            bool keySelected = (x <= model->x && model->x < (x + key.width)) && y == model->y;
-            bool backSelected = model->back_pressed && key.value == HID_KEYBOARD_DELETE;
-            hid_keyboard_draw_key(
-                canvas,
-                model,
-                x,
-                y - initY,
-                key,
-                (!model->ok_pressed && keySelected) || backSelected);
-            x += key.width;
-        }
-    }
-}
-
-static uint8_t hid_keyboard_get_selected_key(HidKeyboardModel* model) {
-    HidKeyboardKey key = hid_keyboard_keyset[model->y][model->x];
-    return key.value;
-}
-
-static void hid_keyboard_get_select_key(HidKeyboardModel* model, HidKeyboardPoint delta) {
-    // Keep going until a valid spot is found, this allows for nulls and zero width keys in the map
-    do {
-        const int delta_sum = model->y + delta.y;
-        model->y = delta_sum < 0 ? ROW_COUNT - 1 : delta_sum % ROW_COUNT;
-    } while(delta.y != 0 && hid_keyboard_keyset[model->y][model->x].value == 0);
-
-    do {
-        const int delta_sum = model->x + delta.x;
-        model->x = delta_sum < 0 ? COLUMN_COUNT - 1 : delta_sum % COLUMN_COUNT;
-    } while(delta.x != 0 && hid_keyboard_keyset[model->y][model->x].width ==
-                                0); // Skip zero width keys, pretend they are one key
-}
-
-static void hid_keyboard_process(HidKeyboard* hid_keyboard, InputEvent* event) {
-    with_view_model(
-        hid_keyboard->view,
-        HidKeyboardModel * model,
-        {
-            if(event->key == InputKeyOk) {
-                if(event->type == InputTypePress) {
-                    model->ok_pressed = true;
-                } else if(event->type == InputTypeLong || event->type == InputTypeShort) {
-                    model->last_key_code = hid_keyboard_get_selected_key(model);
-
-                    // Toggle the modifier key when clicked, and click the key
-                    if(model->last_key_code == HID_KEYBOARD_L_SHIFT) {
-                        model->shift = !model->shift;
-                        if(model->shift)
-                            model->modifier_code |= KEY_MOD_LEFT_SHIFT;
-                        else
-                            model->modifier_code &= ~KEY_MOD_LEFT_SHIFT;
-                    } else if(model->last_key_code == HID_KEYBOARD_L_ALT) {
-                        model->alt = !model->alt;
-                        if(model->alt)
-                            model->modifier_code |= KEY_MOD_LEFT_ALT;
-                        else
-                            model->modifier_code &= ~KEY_MOD_LEFT_ALT;
-                    } else if(model->last_key_code == HID_KEYBOARD_L_CTRL) {
-                        model->ctrl = !model->ctrl;
-                        if(model->ctrl)
-                            model->modifier_code |= KEY_MOD_LEFT_CTRL;
-                        else
-                            model->modifier_code &= ~KEY_MOD_LEFT_CTRL;
-                    } else if(model->last_key_code == HID_KEYBOARD_L_GUI) {
-                        model->gui = !model->gui;
-                        if(model->gui)
-                            model->modifier_code |= KEY_MOD_LEFT_GUI;
-                        else
-                            model->modifier_code &= ~KEY_MOD_LEFT_GUI;
-                    }
-                    hid_hal_keyboard_press(
-                        hid_keyboard->hid, model->modifier_code | model->last_key_code);
-                } else if(event->type == InputTypeRelease) {
-                    // Release happens after short and long presses
-                    hid_hal_keyboard_release(
-                        hid_keyboard->hid, model->modifier_code | model->last_key_code);
-                    model->ok_pressed = false;
-                }
-            } else if(event->key == InputKeyBack) {
-                // If back is pressed for a short time, backspace
-                if(event->type == InputTypePress) {
-                    model->back_pressed = true;
-                } else if(event->type == InputTypeShort) {
-                    hid_hal_keyboard_press(hid_keyboard->hid, HID_KEYBOARD_DELETE);
-                    hid_hal_keyboard_release(hid_keyboard->hid, HID_KEYBOARD_DELETE);
-                } else if(event->type == InputTypeRelease) {
-                    model->back_pressed = false;
-                }
-            } else if(event->type == InputTypePress || event->type == InputTypeRepeat) {
-                // Cycle the selected keys
-                if(event->key == InputKeyUp) {
-                    hid_keyboard_get_select_key(model, (HidKeyboardPoint){.x = 0, .y = -1});
-                } else if(event->key == InputKeyDown) {
-                    hid_keyboard_get_select_key(model, (HidKeyboardPoint){.x = 0, .y = 1});
-                } else if(event->key == InputKeyLeft) {
-                    hid_keyboard_get_select_key(model, (HidKeyboardPoint){.x = -1, .y = 0});
-                } else if(event->key == InputKeyRight) {
-                    hid_keyboard_get_select_key(model, (HidKeyboardPoint){.x = 1, .y = 0});
-                }
-            }
-        },
-        true);
-}
-
-static bool hid_keyboard_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    HidKeyboard* hid_keyboard = context;
-    bool consumed = false;
-
-    if(event->type == InputTypeLong && event->key == InputKeyBack) {
-        hid_hal_keyboard_release_all(hid_keyboard->hid);
-    } else {
-        hid_keyboard_process(hid_keyboard, event);
-        consumed = true;
-    }
-
-    return consumed;
-}
-
-HidKeyboard* hid_keyboard_alloc(Hid* bt_hid) {
-    HidKeyboard* hid_keyboard = malloc(sizeof(HidKeyboard));
-    hid_keyboard->view = view_alloc();
-    hid_keyboard->hid = bt_hid;
-    view_set_context(hid_keyboard->view, hid_keyboard);
-    view_allocate_model(hid_keyboard->view, ViewModelTypeLocking, sizeof(HidKeyboardModel));
-    view_set_draw_callback(hid_keyboard->view, hid_keyboard_draw_callback);
-    view_set_input_callback(hid_keyboard->view, hid_keyboard_input_callback);
-
-    with_view_model(
-        hid_keyboard->view,
-        HidKeyboardModel * model,
-        {
-            model->transport = bt_hid->transport;
-            model->y = 1;
-        },
-        true);
-
-    return hid_keyboard;
-}
-
-void hid_keyboard_free(HidKeyboard* hid_keyboard) {
-    furi_assert(hid_keyboard);
-    view_free(hid_keyboard->view);
-    free(hid_keyboard);
-}
-
-View* hid_keyboard_get_view(HidKeyboard* hid_keyboard) {
-    furi_assert(hid_keyboard);
-    return hid_keyboard->view;
-}
-
-void hid_keyboard_set_connected_status(HidKeyboard* hid_keyboard, bool connected) {
-    furi_assert(hid_keyboard);
-    with_view_model(
-        hid_keyboard->view, HidKeyboardModel * model, { model->connected = connected; }, true);
-}

+ 0 - 14
hid_app/views/hid_keyboard.h

@@ -1,14 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-typedef struct Hid Hid;
-typedef struct HidKeyboard HidKeyboard;
-
-HidKeyboard* hid_keyboard_alloc(Hid* bt_hid);
-
-void hid_keyboard_free(HidKeyboard* hid_keyboard);
-
-View* hid_keyboard_get_view(HidKeyboard* hid_keyboard);
-
-void hid_keyboard_set_connected_status(HidKeyboard* hid_keyboard, bool connected);

+ 0 - 312
hid_app/views/hid_keynote.c

@@ -1,312 +0,0 @@
-#include "hid_keynote.h"
-#include <gui/elements.h>
-#include "../hid.h"
-
-#include "hid_icons.h"
-
-#define TAG "HidKeynote"
-
-struct HidKeynote {
-    View* view;
-    Hid* hid;
-};
-
-typedef struct {
-    bool left_pressed;
-    bool up_pressed;
-    bool right_pressed;
-    bool down_pressed;
-    bool ok_pressed;
-    bool back_pressed;
-    bool connected;
-    HidTransport transport;
-} HidKeynoteModel;
-
-static void hid_keynote_draw_arrow(Canvas* canvas, uint8_t x, uint8_t y, CanvasDirection dir) {
-    canvas_draw_triangle(canvas, x, y, 5, 3, dir);
-    if(dir == CanvasDirectionBottomToTop) {
-        canvas_draw_line(canvas, x, y + 6, x, y - 1);
-    } else if(dir == CanvasDirectionTopToBottom) {
-        canvas_draw_line(canvas, x, y - 6, x, y + 1);
-    } else if(dir == CanvasDirectionRightToLeft) {
-        canvas_draw_line(canvas, x + 6, y, x - 1, y);
-    } else if(dir == CanvasDirectionLeftToRight) {
-        canvas_draw_line(canvas, x - 6, y, x + 1, y);
-    }
-}
-
-static void hid_keynote_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    HidKeynoteModel* model = context;
-
-    // Header
-    if(model->transport == HidTransportBle) {
-        if(model->connected) {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15);
-        } else {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
-        }
-    }
-
-    canvas_set_font(canvas, FontPrimary);
-    elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Keynote");
-
-    canvas_draw_icon(canvas, 68, 2, &I_Pin_back_arrow_10x8);
-    canvas_set_font(canvas, FontSecondary);
-    elements_multiline_text_aligned(canvas, 127, 3, AlignRight, AlignTop, "Hold to exit");
-
-    // Up
-    canvas_draw_icon(canvas, 21, 24, &I_Button_18x18);
-    if(model->up_pressed) {
-        elements_slightly_rounded_box(canvas, 24, 26, 13, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_keynote_draw_arrow(canvas, 30, 30, CanvasDirectionBottomToTop);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Down
-    canvas_draw_icon(canvas, 21, 45, &I_Button_18x18);
-    if(model->down_pressed) {
-        elements_slightly_rounded_box(canvas, 24, 47, 13, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_keynote_draw_arrow(canvas, 30, 55, CanvasDirectionTopToBottom);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Left
-    canvas_draw_icon(canvas, 0, 45, &I_Button_18x18);
-    if(model->left_pressed) {
-        elements_slightly_rounded_box(canvas, 3, 47, 13, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_keynote_draw_arrow(canvas, 7, 53, CanvasDirectionRightToLeft);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Right
-    canvas_draw_icon(canvas, 42, 45, &I_Button_18x18);
-    if(model->right_pressed) {
-        elements_slightly_rounded_box(canvas, 45, 47, 13, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_keynote_draw_arrow(canvas, 53, 53, CanvasDirectionLeftToRight);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Ok
-    canvas_draw_icon(canvas, 63, 25, &I_Space_65x18);
-    if(model->ok_pressed) {
-        elements_slightly_rounded_box(canvas, 66, 27, 60, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 74, 29, &I_Ok_btn_9x9);
-    elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Space");
-    canvas_set_color(canvas, ColorBlack);
-
-    // Back
-    canvas_draw_icon(canvas, 63, 45, &I_Space_65x18);
-    if(model->back_pressed) {
-        elements_slightly_rounded_box(canvas, 66, 47, 60, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 74, 49, &I_Pin_back_arrow_10x8);
-    elements_multiline_text_aligned(canvas, 91, 57, AlignLeft, AlignBottom, "Back");
-}
-
-static void hid_keynote_draw_vertical_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    HidKeynoteModel* model = context;
-
-    // Header
-    if(model->transport == HidTransportBle) {
-        if(model->connected) {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15);
-        } else {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
-        }
-        canvas_set_font(canvas, FontPrimary);
-        elements_multiline_text_aligned(canvas, 20, 3, AlignLeft, AlignTop, "Keynote");
-    } else {
-        canvas_set_font(canvas, FontPrimary);
-        elements_multiline_text_aligned(canvas, 12, 3, AlignLeft, AlignTop, "Keynote");
-    }
-
-    canvas_draw_icon(canvas, 2, 18, &I_Pin_back_arrow_10x8);
-    canvas_set_font(canvas, FontSecondary);
-    elements_multiline_text_aligned(canvas, 15, 19, AlignLeft, AlignTop, "Hold to exit");
-
-    const uint8_t x_2 = 23;
-    const uint8_t x_1 = 2;
-    const uint8_t x_3 = 44;
-
-    const uint8_t y_1 = 44;
-    const uint8_t y_2 = 65;
-
-    // Up
-    canvas_draw_icon(canvas, x_2, y_1, &I_Button_18x18);
-    if(model->up_pressed) {
-        elements_slightly_rounded_box(canvas, x_2 + 3, y_1 + 2, 13, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_keynote_draw_arrow(canvas, x_2 + 9, y_1 + 6, CanvasDirectionBottomToTop);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Down
-    canvas_draw_icon(canvas, x_2, y_2, &I_Button_18x18);
-    if(model->down_pressed) {
-        elements_slightly_rounded_box(canvas, x_2 + 3, y_2 + 2, 13, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_keynote_draw_arrow(canvas, x_2 + 9, y_2 + 10, CanvasDirectionTopToBottom);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Left
-    canvas_draw_icon(canvas, x_1, y_2, &I_Button_18x18);
-    if(model->left_pressed) {
-        elements_slightly_rounded_box(canvas, x_1 + 3, y_2 + 2, 13, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_keynote_draw_arrow(canvas, x_1 + 7, y_2 + 8, CanvasDirectionRightToLeft);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Right
-    canvas_draw_icon(canvas, x_3, y_2, &I_Button_18x18);
-    if(model->right_pressed) {
-        elements_slightly_rounded_box(canvas, x_3 + 3, y_2 + 2, 13, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_keynote_draw_arrow(canvas, x_3 + 11, y_2 + 8, CanvasDirectionLeftToRight);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Ok
-    canvas_draw_icon(canvas, 2, 86, &I_Space_60x18);
-    if(model->ok_pressed) {
-        elements_slightly_rounded_box(canvas, 5, 88, 55, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 11, 90, &I_Ok_btn_9x9);
-    elements_multiline_text_aligned(canvas, 26, 98, AlignLeft, AlignBottom, "Space");
-    canvas_set_color(canvas, ColorBlack);
-
-    // Back
-    canvas_draw_icon(canvas, 2, 107, &I_Space_60x18);
-    if(model->back_pressed) {
-        elements_slightly_rounded_box(canvas, 5, 109, 55, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 11, 111, &I_Pin_back_arrow_10x8);
-    elements_multiline_text_aligned(canvas, 26, 119, AlignLeft, AlignBottom, "Back");
-}
-
-static void hid_keynote_process(HidKeynote* hid_keynote, InputEvent* event) {
-    with_view_model(
-        hid_keynote->view,
-        HidKeynoteModel * model,
-        {
-            if(event->type == InputTypePress) {
-                if(event->key == InputKeyUp) {
-                    model->up_pressed = true;
-                    hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_UP_ARROW);
-                } else if(event->key == InputKeyDown) {
-                    model->down_pressed = true;
-                    hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_DOWN_ARROW);
-                } else if(event->key == InputKeyLeft) {
-                    model->left_pressed = true;
-                    hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_LEFT_ARROW);
-                } else if(event->key == InputKeyRight) {
-                    model->right_pressed = true;
-                    hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_RIGHT_ARROW);
-                } else if(event->key == InputKeyOk) {
-                    model->ok_pressed = true;
-                    hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_SPACEBAR);
-                } else if(event->key == InputKeyBack) {
-                    model->back_pressed = true;
-                }
-            } else if(event->type == InputTypeRelease) {
-                if(event->key == InputKeyUp) {
-                    model->up_pressed = false;
-                    hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_UP_ARROW);
-                } else if(event->key == InputKeyDown) {
-                    model->down_pressed = false;
-                    hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_DOWN_ARROW);
-                } else if(event->key == InputKeyLeft) {
-                    model->left_pressed = false;
-                    hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_LEFT_ARROW);
-                } else if(event->key == InputKeyRight) {
-                    model->right_pressed = false;
-                    hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_RIGHT_ARROW);
-                } else if(event->key == InputKeyOk) {
-                    model->ok_pressed = false;
-                    hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_SPACEBAR);
-                } else if(event->key == InputKeyBack) {
-                    model->back_pressed = false;
-                }
-            } else if(event->type == InputTypeShort) {
-                if(event->key == InputKeyBack) {
-                    hid_hal_keyboard_press(hid_keynote->hid, HID_KEYBOARD_DELETE);
-                    hid_hal_keyboard_release(hid_keynote->hid, HID_KEYBOARD_DELETE);
-                    hid_hal_consumer_key_press(hid_keynote->hid, HID_CONSUMER_AC_BACK);
-                    hid_hal_consumer_key_release(hid_keynote->hid, HID_CONSUMER_AC_BACK);
-                }
-            }
-        },
-        true);
-}
-
-static bool hid_keynote_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    HidKeynote* hid_keynote = context;
-    bool consumed = false;
-
-    if(event->type == InputTypeLong && event->key == InputKeyBack) {
-        hid_hal_keyboard_release_all(hid_keynote->hid);
-    } else {
-        hid_keynote_process(hid_keynote, event);
-        consumed = true;
-    }
-
-    return consumed;
-}
-
-HidKeynote* hid_keynote_alloc(Hid* hid) {
-    HidKeynote* hid_keynote = malloc(sizeof(HidKeynote));
-    hid_keynote->view = view_alloc();
-    hid_keynote->hid = hid;
-    view_set_context(hid_keynote->view, hid_keynote);
-    view_allocate_model(hid_keynote->view, ViewModelTypeLocking, sizeof(HidKeynoteModel));
-    view_set_draw_callback(hid_keynote->view, hid_keynote_draw_callback);
-    view_set_input_callback(hid_keynote->view, hid_keynote_input_callback);
-
-    with_view_model(
-        hid_keynote->view, HidKeynoteModel * model, { model->transport = hid->transport; }, true);
-
-    return hid_keynote;
-}
-
-void hid_keynote_free(HidKeynote* hid_keynote) {
-    furi_assert(hid_keynote);
-    view_free(hid_keynote->view);
-    free(hid_keynote);
-}
-
-View* hid_keynote_get_view(HidKeynote* hid_keynote) {
-    furi_assert(hid_keynote);
-    return hid_keynote->view;
-}
-
-void hid_keynote_set_connected_status(HidKeynote* hid_keynote, bool connected) {
-    furi_assert(hid_keynote);
-    with_view_model(
-        hid_keynote->view, HidKeynoteModel * model, { model->connected = connected; }, true);
-}
-
-void hid_keynote_set_orientation(HidKeynote* hid_keynote, bool vertical) {
-    furi_assert(hid_keynote);
-
-    if(vertical) {
-        view_set_draw_callback(hid_keynote->view, hid_keynote_draw_vertical_callback);
-        view_set_orientation(hid_keynote->view, ViewOrientationVerticalFlip);
-
-    } else {
-        view_set_draw_callback(hid_keynote->view, hid_keynote_draw_callback);
-        view_set_orientation(hid_keynote->view, ViewOrientationHorizontal);
-    }
-}

+ 0 - 16
hid_app/views/hid_keynote.h

@@ -1,16 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-typedef struct Hid Hid;
-typedef struct HidKeynote HidKeynote;
-
-HidKeynote* hid_keynote_alloc(Hid* bt_hid);
-
-void hid_keynote_free(HidKeynote* hid_keynote);
-
-View* hid_keynote_get_view(HidKeynote* hid_keynote);
-
-void hid_keynote_set_connected_status(HidKeynote* hid_keynote, bool connected);
-
-void hid_keynote_set_orientation(HidKeynote* hid_keynote, bool vertical);

+ 0 - 218
hid_app/views/hid_media.c

@@ -1,218 +0,0 @@
-#include "hid_media.h"
-#include <furi.h>
-#include <furi_hal_bt_hid.h>
-#include <furi_hal_usb_hid.h>
-#include <gui/elements.h>
-#include "../hid.h"
-
-#include "hid_icons.h"
-
-#define TAG "HidMedia"
-
-struct HidMedia {
-    View* view;
-    Hid* hid;
-};
-
-typedef struct {
-    bool left_pressed;
-    bool up_pressed;
-    bool right_pressed;
-    bool down_pressed;
-    bool ok_pressed;
-    bool connected;
-    HidTransport transport;
-} HidMediaModel;
-
-static void hid_media_draw_arrow(Canvas* canvas, uint8_t x, uint8_t y, CanvasDirection dir) {
-    canvas_draw_triangle(canvas, x, y, 5, 3, dir);
-    if(dir == CanvasDirectionBottomToTop) {
-        canvas_draw_dot(canvas, x, y - 1);
-    } else if(dir == CanvasDirectionTopToBottom) {
-        canvas_draw_dot(canvas, x, y + 1);
-    } else if(dir == CanvasDirectionRightToLeft) {
-        canvas_draw_dot(canvas, x - 1, y);
-    } else if(dir == CanvasDirectionLeftToRight) {
-        canvas_draw_dot(canvas, x + 1, y);
-    }
-}
-
-static void hid_media_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    HidMediaModel* model = context;
-
-    // Header
-    if(model->transport == HidTransportBle) {
-        if(model->connected) {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15);
-        } else {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
-        }
-    }
-
-    canvas_set_font(canvas, FontPrimary);
-    elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Media");
-    canvas_set_font(canvas, FontSecondary);
-
-    // Keypad circles
-    canvas_draw_icon(canvas, 76, 8, &I_Circles_47x47);
-
-    // Up
-    if(model->up_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 93, 9, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 96, 12, &I_Volup_8x6);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Down
-    if(model->down_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 93, 41, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 96, 45, &I_Voldwn_6x6);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Left
-    if(model->left_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 77, 25, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_media_draw_arrow(canvas, 82, 31, CanvasDirectionRightToLeft);
-    hid_media_draw_arrow(canvas, 86, 31, CanvasDirectionRightToLeft);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Right
-    if(model->right_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 109, 25, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_media_draw_arrow(canvas, 112, 31, CanvasDirectionLeftToRight);
-    hid_media_draw_arrow(canvas, 116, 31, CanvasDirectionLeftToRight);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Ok
-    if(model->ok_pressed) {
-        canvas_draw_icon(canvas, 93, 25, &I_Pressed_Button_13x13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    hid_media_draw_arrow(canvas, 96, 31, CanvasDirectionLeftToRight);
-    canvas_draw_line(canvas, 100, 29, 100, 33);
-    canvas_draw_line(canvas, 102, 29, 102, 33);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Exit
-    canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8);
-    canvas_set_font(canvas, FontSecondary);
-    elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit");
-}
-
-static void hid_media_process_press(HidMedia* hid_media, InputEvent* event) {
-    with_view_model(
-        hid_media->view,
-        HidMediaModel * model,
-        {
-            if(event->key == InputKeyUp) {
-                model->up_pressed = true;
-                hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_VOLUME_INCREMENT);
-            } else if(event->key == InputKeyDown) {
-                model->down_pressed = true;
-                hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_VOLUME_DECREMENT);
-            } else if(event->key == InputKeyLeft) {
-                model->left_pressed = true;
-                hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_SCAN_PREVIOUS_TRACK);
-            } else if(event->key == InputKeyRight) {
-                model->right_pressed = true;
-                hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_SCAN_NEXT_TRACK);
-            } else if(event->key == InputKeyOk) {
-                model->ok_pressed = true;
-                hid_hal_consumer_key_press(hid_media->hid, HID_CONSUMER_PLAY_PAUSE);
-            }
-        },
-        true);
-}
-
-static void hid_media_process_release(HidMedia* hid_media, InputEvent* event) {
-    with_view_model(
-        hid_media->view,
-        HidMediaModel * model,
-        {
-            if(event->key == InputKeyUp) {
-                model->up_pressed = false;
-                hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_VOLUME_INCREMENT);
-            } else if(event->key == InputKeyDown) {
-                model->down_pressed = false;
-                hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_VOLUME_DECREMENT);
-            } else if(event->key == InputKeyLeft) {
-                model->left_pressed = false;
-                hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_SCAN_PREVIOUS_TRACK);
-            } else if(event->key == InputKeyRight) {
-                model->right_pressed = false;
-                hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_SCAN_NEXT_TRACK);
-            } else if(event->key == InputKeyOk) {
-                model->ok_pressed = false;
-                hid_hal_consumer_key_release(hid_media->hid, HID_CONSUMER_PLAY_PAUSE);
-            }
-        },
-        true);
-}
-
-static bool hid_media_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    HidMedia* hid_media = context;
-    bool consumed = false;
-
-    if(event->type == InputTypePress) {
-        hid_media_process_press(hid_media, event);
-        consumed = true;
-    } else if(event->type == InputTypeRelease) {
-        hid_media_process_release(hid_media, event);
-        consumed = true;
-    } else if(event->type == InputTypeShort) {
-        if(event->key == InputKeyBack) {
-            hid_hal_consumer_key_release_all(hid_media->hid);
-        }
-    }
-
-    return consumed;
-}
-
-HidMedia* hid_media_alloc(Hid* hid) {
-    HidMedia* hid_media = malloc(sizeof(HidMedia));
-    hid_media->view = view_alloc();
-    hid_media->hid = hid;
-    view_set_context(hid_media->view, hid_media);
-    view_allocate_model(hid_media->view, ViewModelTypeLocking, sizeof(HidMediaModel));
-    view_set_draw_callback(hid_media->view, hid_media_draw_callback);
-    view_set_input_callback(hid_media->view, hid_media_input_callback);
-
-    with_view_model(
-        hid_media->view, HidMediaModel * model, { model->transport = hid->transport; }, true);
-
-    return hid_media;
-}
-
-void hid_media_free(HidMedia* hid_media) {
-    furi_assert(hid_media);
-    view_free(hid_media->view);
-    free(hid_media);
-}
-
-View* hid_media_get_view(HidMedia* hid_media) {
-    furi_assert(hid_media);
-    return hid_media->view;
-}
-
-void hid_media_set_connected_status(HidMedia* hid_media, bool connected) {
-    furi_assert(hid_media);
-    with_view_model(
-        hid_media->view, HidMediaModel * model, { model->connected = connected; }, true);
-}

+ 0 - 13
hid_app/views/hid_media.h

@@ -1,13 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-typedef struct HidMedia HidMedia;
-
-HidMedia* hid_media_alloc();
-
-void hid_media_free(HidMedia* hid_media);
-
-View* hid_media_get_view(HidMedia* hid_media);
-
-void hid_media_set_connected_status(HidMedia* hid_media, bool connected);

+ 0 - 226
hid_app/views/hid_mouse.c

@@ -1,226 +0,0 @@
-#include "hid_mouse.h"
-#include <gui/elements.h>
-#include "../hid.h"
-
-#include "hid_icons.h"
-
-#define TAG "HidMouse"
-
-struct HidMouse {
-    View* view;
-    Hid* hid;
-};
-
-typedef struct {
-    bool left_pressed;
-    bool up_pressed;
-    bool right_pressed;
-    bool down_pressed;
-    bool left_mouse_pressed;
-    bool left_mouse_held;
-    bool right_mouse_pressed;
-    bool connected;
-    HidTransport transport;
-} HidMouseModel;
-
-static void hid_mouse_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    HidMouseModel* model = context;
-
-    // Header
-    if(model->transport == HidTransportBle) {
-        if(model->connected) {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15);
-        } else {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
-        }
-    }
-
-    canvas_set_font(canvas, FontPrimary);
-    elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Mouse");
-    canvas_set_font(canvas, FontSecondary);
-
-    if(model->left_mouse_held == true) {
-        elements_multiline_text_aligned(canvas, 0, 62, AlignLeft, AlignBottom, "Selecting...");
-    } else {
-        canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8);
-        canvas_set_font(canvas, FontSecondary);
-        elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit");
-    }
-
-    // Keypad circles
-    canvas_draw_icon(canvas, 64, 8, &I_Circles_47x47);
-
-    // Up
-    if(model->up_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 81, 9, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 84, 10, &I_Pin_arrow_up_7x9);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Down
-    if(model->down_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 81, 41, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 84, 43, &I_Pin_arrow_down_7x9);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Left
-    if(model->left_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 65, 25, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 67, 28, &I_Pin_arrow_left_9x7);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Right
-    if(model->right_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 97, 25, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 99, 28, &I_Pin_arrow_right_9x7);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Ok
-    if(model->left_mouse_pressed) {
-        canvas_draw_icon(canvas, 81, 25, &I_Ok_btn_pressed_13x13);
-    } else {
-        canvas_draw_icon(canvas, 83, 27, &I_Left_mouse_icon_9x9);
-    }
-
-    // Back
-    if(model->right_mouse_pressed) {
-        canvas_draw_icon(canvas, 108, 48, &I_Ok_btn_pressed_13x13);
-    } else {
-        canvas_draw_icon(canvas, 110, 50, &I_Right_mouse_icon_9x9);
-    }
-}
-
-static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) {
-    with_view_model(
-        hid_mouse->view,
-        HidMouseModel * model,
-        {
-            if(event->key == InputKeyBack) {
-                if(event->type == InputTypeShort) {
-                    hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_RIGHT);
-                    hid_hal_mouse_release(hid_mouse->hid, HID_MOUSE_BTN_RIGHT);
-                } else if(event->type == InputTypePress) {
-                    model->right_mouse_pressed = true;
-                } else if(event->type == InputTypeRelease) {
-                    model->right_mouse_pressed = false;
-                }
-            } else if(event->key == InputKeyOk) {
-                if(event->type == InputTypeShort) {
-                    // Just release if it was being held before
-                    if(!model->left_mouse_held)
-                        hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_LEFT);
-                    hid_hal_mouse_release(hid_mouse->hid, HID_MOUSE_BTN_LEFT);
-                    model->left_mouse_held = false;
-                } else if(event->type == InputTypeLong) {
-                    hid_hal_mouse_press(hid_mouse->hid, HID_MOUSE_BTN_LEFT);
-                    model->left_mouse_held = true;
-                    model->left_mouse_pressed = true;
-                } else if(event->type == InputTypePress) {
-                    model->left_mouse_pressed = true;
-                } else if(event->type == InputTypeRelease) {
-                    // Only release if it wasn't a long press
-                    if(!model->left_mouse_held) model->left_mouse_pressed = false;
-                }
-            } else if(event->key == InputKeyRight) {
-                if(event->type == InputTypePress) {
-                    model->right_pressed = true;
-                    hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_SHORT, 0);
-                } else if(event->type == InputTypeRepeat) {
-                    hid_hal_mouse_move(hid_mouse->hid, MOUSE_MOVE_LONG, 0);
-                } else if(event->type == InputTypeRelease) {
-                    model->right_pressed = false;
-                }
-            } else if(event->key == InputKeyLeft) {
-                if(event->type == InputTypePress) {
-                    model->left_pressed = true;
-                    hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_SHORT, 0);
-                } else if(event->type == InputTypeRepeat) {
-                    hid_hal_mouse_move(hid_mouse->hid, -MOUSE_MOVE_LONG, 0);
-                } else if(event->type == InputTypeRelease) {
-                    model->left_pressed = false;
-                }
-            } else if(event->key == InputKeyDown) {
-                if(event->type == InputTypePress) {
-                    model->down_pressed = true;
-                    hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_SHORT);
-                } else if(event->type == InputTypeRepeat) {
-                    hid_hal_mouse_move(hid_mouse->hid, 0, MOUSE_MOVE_LONG);
-                } else if(event->type == InputTypeRelease) {
-                    model->down_pressed = false;
-                }
-            } else if(event->key == InputKeyUp) {
-                if(event->type == InputTypePress) {
-                    model->up_pressed = true;
-                    hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_SHORT);
-                } else if(event->type == InputTypeRepeat) {
-                    hid_hal_mouse_move(hid_mouse->hid, 0, -MOUSE_MOVE_LONG);
-                } else if(event->type == InputTypeRelease) {
-                    model->up_pressed = false;
-                }
-            }
-        },
-        true);
-}
-
-static bool hid_mouse_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    HidMouse* hid_mouse = context;
-    bool consumed = false;
-
-    if(event->type == InputTypeLong && event->key == InputKeyBack) {
-        hid_hal_mouse_release_all(hid_mouse->hid);
-    } else {
-        hid_mouse_process(hid_mouse, event);
-        consumed = true;
-    }
-
-    return consumed;
-}
-
-HidMouse* hid_mouse_alloc(Hid* hid) {
-    HidMouse* hid_mouse = malloc(sizeof(HidMouse));
-    hid_mouse->view = view_alloc();
-    hid_mouse->hid = hid;
-    view_set_context(hid_mouse->view, hid_mouse);
-    view_allocate_model(hid_mouse->view, ViewModelTypeLocking, sizeof(HidMouseModel));
-    view_set_draw_callback(hid_mouse->view, hid_mouse_draw_callback);
-    view_set_input_callback(hid_mouse->view, hid_mouse_input_callback);
-
-    with_view_model(
-        hid_mouse->view, HidMouseModel * model, { model->transport = hid->transport; }, true);
-
-    return hid_mouse;
-}
-
-void hid_mouse_free(HidMouse* hid_mouse) {
-    furi_assert(hid_mouse);
-    view_free(hid_mouse->view);
-    free(hid_mouse);
-}
-
-View* hid_mouse_get_view(HidMouse* hid_mouse) {
-    furi_assert(hid_mouse);
-    return hid_mouse->view;
-}
-
-void hid_mouse_set_connected_status(HidMouse* hid_mouse, bool connected) {
-    furi_assert(hid_mouse);
-    with_view_model(
-        hid_mouse->view, HidMouseModel * model, { model->connected = connected; }, true);
-}

+ 0 - 17
hid_app/views/hid_mouse.h

@@ -1,17 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-#define MOUSE_MOVE_SHORT 5
-#define MOUSE_MOVE_LONG 20
-
-typedef struct Hid Hid;
-typedef struct HidMouse HidMouse;
-
-HidMouse* hid_mouse_alloc(Hid* bt_hid);
-
-void hid_mouse_free(HidMouse* hid_mouse);
-
-View* hid_mouse_get_view(HidMouse* hid_mouse);
-
-void hid_mouse_set_connected_status(HidMouse* hid_mouse, bool connected);

+ 0 - 214
hid_app/views/hid_mouse_clicker.c

@@ -1,214 +0,0 @@
-#include "hid_mouse_clicker.h"
-#include <gui/elements.h>
-#include "../hid.h"
-
-#include "hid_icons.h"
-
-#define TAG "HidMouseClicker"
-#define DEFAULT_CLICK_RATE 1
-#define MAXIMUM_CLICK_RATE 60
-
-struct HidMouseClicker {
-    View* view;
-    Hid* hid;
-    FuriTimer* timer;
-};
-
-typedef struct {
-    bool connected;
-    bool running;
-    int rate;
-    HidTransport transport;
-} HidMouseClickerModel;
-
-static void hid_mouse_clicker_start_or_restart_timer(void* context) {
-    furi_assert(context);
-    HidMouseClicker* hid_mouse_clicker = context;
-
-    if(furi_timer_is_running(hid_mouse_clicker->timer)) {
-        furi_timer_stop(hid_mouse_clicker->timer);
-    }
-
-    with_view_model(
-        hid_mouse_clicker->view,
-        HidMouseClickerModel * model,
-        {
-            furi_timer_start(
-                hid_mouse_clicker->timer, furi_kernel_get_tick_frequency() / model->rate);
-        },
-        true);
-}
-
-static void hid_mouse_clicker_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    HidMouseClickerModel* model = context;
-
-    // Header
-    if(model->transport == HidTransportBle) {
-        if(model->connected) {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15);
-        } else {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
-        }
-    }
-
-    canvas_set_font(canvas, FontPrimary);
-    elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Mouse Clicker");
-
-    // Ok
-    canvas_draw_icon(canvas, 63, 25, &I_Space_65x18);
-    if(model->running) {
-        canvas_set_font(canvas, FontPrimary);
-
-        FuriString* rate_label = furi_string_alloc();
-        furi_string_printf(rate_label, "%d clicks/s\n\nUp / Down", model->rate);
-        elements_multiline_text(canvas, AlignLeft, 35, furi_string_get_cstr(rate_label));
-        canvas_set_font(canvas, FontSecondary);
-        furi_string_free(rate_label);
-
-        elements_slightly_rounded_box(canvas, 66, 27, 60, 13);
-        canvas_set_color(canvas, ColorWhite);
-    } else {
-        canvas_set_font(canvas, FontPrimary);
-        elements_multiline_text(canvas, AlignLeft, 35, "Press Start\nto start\nclicking");
-        canvas_set_font(canvas, FontSecondary);
-    }
-    canvas_draw_icon(canvas, 74, 29, &I_Ok_btn_9x9);
-    if(model->running) {
-        elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Stop");
-    } else {
-        elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Start");
-    }
-    canvas_set_color(canvas, ColorBlack);
-
-    // Back
-    canvas_draw_icon(canvas, 74, 49, &I_Pin_back_arrow_10x8);
-    elements_multiline_text_aligned(canvas, 91, 57, AlignLeft, AlignBottom, "Quit");
-}
-
-static void hid_mouse_clicker_timer_callback(void* context) {
-    furi_assert(context);
-    HidMouseClicker* hid_mouse_clicker = context;
-    with_view_model(
-        hid_mouse_clicker->view,
-        HidMouseClickerModel * model,
-        {
-            if(model->running) {
-                hid_hal_mouse_press(hid_mouse_clicker->hid, HID_MOUSE_BTN_LEFT);
-                hid_hal_mouse_release(hid_mouse_clicker->hid, HID_MOUSE_BTN_LEFT);
-            }
-        },
-        false);
-}
-
-static void hid_mouse_clicker_enter_callback(void* context) {
-    hid_mouse_clicker_start_or_restart_timer(context);
-}
-
-static void hid_mouse_clicker_exit_callback(void* context) {
-    furi_assert(context);
-    HidMouseClicker* hid_mouse_clicker = context;
-    furi_timer_stop(hid_mouse_clicker->timer);
-}
-
-static bool hid_mouse_clicker_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    HidMouseClicker* hid_mouse_clicker = context;
-
-    bool consumed = false;
-    bool rate_changed = false;
-
-    if(event->type != InputTypeShort && event->type != InputTypeRepeat) {
-        return false;
-    }
-
-    with_view_model(
-        hid_mouse_clicker->view,
-        HidMouseClickerModel * model,
-        {
-            switch(event->key) {
-            case InputKeyOk:
-                model->running = !model->running;
-                consumed = true;
-                break;
-            case InputKeyUp:
-                if(model->rate < MAXIMUM_CLICK_RATE) {
-                    model->rate++;
-                }
-                rate_changed = true;
-                consumed = true;
-                break;
-            case InputKeyDown:
-                if(model->rate > 1) {
-                    model->rate--;
-                }
-                rate_changed = true;
-                consumed = true;
-                break;
-            default:
-                consumed = true;
-                break;
-            }
-        },
-        true);
-
-    if(rate_changed) {
-        hid_mouse_clicker_start_or_restart_timer(context);
-    }
-
-    return consumed;
-}
-
-HidMouseClicker* hid_mouse_clicker_alloc(Hid* hid) {
-    HidMouseClicker* hid_mouse_clicker = malloc(sizeof(HidMouseClicker));
-
-    hid_mouse_clicker->view = view_alloc();
-    view_set_context(hid_mouse_clicker->view, hid_mouse_clicker);
-    view_allocate_model(
-        hid_mouse_clicker->view, ViewModelTypeLocking, sizeof(HidMouseClickerModel));
-    view_set_draw_callback(hid_mouse_clicker->view, hid_mouse_clicker_draw_callback);
-    view_set_input_callback(hid_mouse_clicker->view, hid_mouse_clicker_input_callback);
-    view_set_enter_callback(hid_mouse_clicker->view, hid_mouse_clicker_enter_callback);
-    view_set_exit_callback(hid_mouse_clicker->view, hid_mouse_clicker_exit_callback);
-
-    hid_mouse_clicker->hid = hid;
-
-    hid_mouse_clicker->timer = furi_timer_alloc(
-        hid_mouse_clicker_timer_callback, FuriTimerTypePeriodic, hid_mouse_clicker);
-
-    with_view_model(
-        hid_mouse_clicker->view,
-        HidMouseClickerModel * model,
-        {
-            model->transport = hid->transport;
-            model->rate = DEFAULT_CLICK_RATE;
-        },
-        true);
-
-    return hid_mouse_clicker;
-}
-
-void hid_mouse_clicker_free(HidMouseClicker* hid_mouse_clicker) {
-    furi_assert(hid_mouse_clicker);
-
-    furi_timer_stop(hid_mouse_clicker->timer);
-    furi_timer_free(hid_mouse_clicker->timer);
-
-    view_free(hid_mouse_clicker->view);
-
-    free(hid_mouse_clicker);
-}
-
-View* hid_mouse_clicker_get_view(HidMouseClicker* hid_mouse_clicker) {
-    furi_assert(hid_mouse_clicker);
-    return hid_mouse_clicker->view;
-}
-
-void hid_mouse_clicker_set_connected_status(HidMouseClicker* hid_mouse_clicker, bool connected) {
-    furi_assert(hid_mouse_clicker);
-    with_view_model(
-        hid_mouse_clicker->view,
-        HidMouseClickerModel * model,
-        { model->connected = connected; },
-        true);
-}

+ 0 - 14
hid_app/views/hid_mouse_clicker.h

@@ -1,14 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-typedef struct Hid Hid;
-typedef struct HidMouseClicker HidMouseClicker;
-
-HidMouseClicker* hid_mouse_clicker_alloc(Hid* bt_hid);
-
-void hid_mouse_clicker_free(HidMouseClicker* hid_mouse_clicker);
-
-View* hid_mouse_clicker_get_view(HidMouseClicker* hid_mouse_clicker);
-
-void hid_mouse_clicker_set_connected_status(HidMouseClicker* hid_mouse_clicker, bool connected);

+ 0 - 159
hid_app/views/hid_mouse_jiggler.c

@@ -1,159 +0,0 @@
-#include "hid_mouse_jiggler.h"
-#include <gui/elements.h>
-#include "../hid.h"
-
-#include "hid_icons.h"
-
-#define TAG "HidMouseJiggler"
-
-struct HidMouseJiggler {
-    View* view;
-    Hid* hid;
-    FuriTimer* timer;
-};
-
-typedef struct {
-    bool connected;
-    bool running;
-    uint8_t counter;
-    HidTransport transport;
-} HidMouseJigglerModel;
-
-static void hid_mouse_jiggler_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    HidMouseJigglerModel* model = context;
-
-    // Header
-    if(model->transport == HidTransportBle) {
-        if(model->connected) {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15);
-        } else {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
-        }
-    }
-
-    canvas_set_font(canvas, FontPrimary);
-    elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Mouse Jiggler");
-
-    canvas_set_font(canvas, FontPrimary);
-    elements_multiline_text(canvas, AlignLeft, 35, "Press Start\nto jiggle");
-    canvas_set_font(canvas, FontSecondary);
-
-    // Ok
-    canvas_draw_icon(canvas, 63, 25, &I_Space_65x18);
-    if(model->running) {
-        elements_slightly_rounded_box(canvas, 66, 27, 60, 13);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 74, 29, &I_Ok_btn_9x9);
-    if(model->running) {
-        elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Stop");
-    } else {
-        elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Start");
-    }
-    canvas_set_color(canvas, ColorBlack);
-
-    // Back
-    canvas_draw_icon(canvas, 74, 49, &I_Pin_back_arrow_10x8);
-    elements_multiline_text_aligned(canvas, 91, 57, AlignLeft, AlignBottom, "Quit");
-}
-
-static void hid_mouse_jiggler_timer_callback(void* context) {
-    furi_assert(context);
-    HidMouseJiggler* hid_mouse_jiggler = context;
-    with_view_model(
-        hid_mouse_jiggler->view,
-        HidMouseJigglerModel * model,
-        {
-            if(model->running) {
-                model->counter++;
-                hid_hal_mouse_move(
-                    hid_mouse_jiggler->hid,
-                    (model->counter % 2 == 0) ? MOUSE_MOVE_SHORT : -MOUSE_MOVE_SHORT,
-                    0);
-            }
-        },
-        false);
-}
-
-static void hid_mouse_jiggler_enter_callback(void* context) {
-    furi_assert(context);
-    HidMouseJiggler* hid_mouse_jiggler = context;
-
-    furi_timer_start(hid_mouse_jiggler->timer, 500);
-}
-
-static void hid_mouse_jiggler_exit_callback(void* context) {
-    furi_assert(context);
-    HidMouseJiggler* hid_mouse_jiggler = context;
-    furi_timer_stop(hid_mouse_jiggler->timer);
-}
-
-static bool hid_mouse_jiggler_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    HidMouseJiggler* hid_mouse_jiggler = context;
-
-    bool consumed = false;
-
-    if(event->type == InputTypeShort && event->key == InputKeyOk) {
-        with_view_model(
-            hid_mouse_jiggler->view,
-            HidMouseJigglerModel * model,
-            { model->running = !model->running; },
-            true);
-        consumed = true;
-    }
-
-    return consumed;
-}
-
-HidMouseJiggler* hid_mouse_jiggler_alloc(Hid* hid) {
-    HidMouseJiggler* hid_mouse_jiggler = malloc(sizeof(HidMouseJiggler));
-
-    hid_mouse_jiggler->view = view_alloc();
-    view_set_context(hid_mouse_jiggler->view, hid_mouse_jiggler);
-    view_allocate_model(
-        hid_mouse_jiggler->view, ViewModelTypeLocking, sizeof(HidMouseJigglerModel));
-    view_set_draw_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_draw_callback);
-    view_set_input_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_input_callback);
-    view_set_enter_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_enter_callback);
-    view_set_exit_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_exit_callback);
-
-    hid_mouse_jiggler->hid = hid;
-
-    hid_mouse_jiggler->timer = furi_timer_alloc(
-        hid_mouse_jiggler_timer_callback, FuriTimerTypePeriodic, hid_mouse_jiggler);
-
-    with_view_model(
-        hid_mouse_jiggler->view,
-        HidMouseJigglerModel * model,
-        { model->transport = hid->transport; },
-        true);
-
-    return hid_mouse_jiggler;
-}
-
-void hid_mouse_jiggler_free(HidMouseJiggler* hid_mouse_jiggler) {
-    furi_assert(hid_mouse_jiggler);
-
-    furi_timer_stop(hid_mouse_jiggler->timer);
-    furi_timer_free(hid_mouse_jiggler->timer);
-
-    view_free(hid_mouse_jiggler->view);
-
-    free(hid_mouse_jiggler);
-}
-
-View* hid_mouse_jiggler_get_view(HidMouseJiggler* hid_mouse_jiggler) {
-    furi_assert(hid_mouse_jiggler);
-    return hid_mouse_jiggler->view;
-}
-
-void hid_mouse_jiggler_set_connected_status(HidMouseJiggler* hid_mouse_jiggler, bool connected) {
-    furi_assert(hid_mouse_jiggler);
-    with_view_model(
-        hid_mouse_jiggler->view,
-        HidMouseJigglerModel * model,
-        { model->connected = connected; },
-        true);
-}

+ 0 - 17
hid_app/views/hid_mouse_jiggler.h

@@ -1,17 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-#define MOUSE_MOVE_SHORT 5
-#define MOUSE_MOVE_LONG 20
-
-typedef struct Hid Hid;
-typedef struct HidMouseJiggler HidMouseJiggler;
-
-HidMouseJiggler* hid_mouse_jiggler_alloc(Hid* bt_hid);
-
-void hid_mouse_jiggler_free(HidMouseJiggler* hid_mouse_jiggler);
-
-View* hid_mouse_jiggler_get_view(HidMouseJiggler* hid_mouse_jiggler);
-
-void hid_mouse_jiggler_set_connected_status(HidMouseJiggler* hid_mouse_jiggler, bool connected);

+ 0 - 241
hid_app/views/hid_tiktok.c

@@ -1,241 +0,0 @@
-#include "hid_tiktok.h"
-#include "../hid.h"
-#include <gui/elements.h>
-
-#include "hid_icons.h"
-
-#define TAG "HidTikTok"
-
-struct HidTikTok {
-    View* view;
-    Hid* hid;
-};
-
-typedef struct {
-    bool left_pressed;
-    bool up_pressed;
-    bool right_pressed;
-    bool down_pressed;
-    bool ok_pressed;
-    bool connected;
-    bool is_cursor_set;
-    HidTransport transport;
-} HidTikTokModel;
-
-static void hid_tiktok_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    HidTikTokModel* model = context;
-
-    // Header
-    if(model->transport == HidTransportBle) {
-        if(model->connected) {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15);
-        } else {
-            canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
-        }
-    }
-
-    canvas_set_font(canvas, FontPrimary);
-    elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "TikTok");
-    canvas_set_font(canvas, FontSecondary);
-
-    // Keypad circles
-    canvas_draw_icon(canvas, 76, 8, &I_Circles_47x47);
-
-    // Up
-    if(model->up_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 93, 9, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 96, 11, &I_Arr_up_7x9);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Down
-    if(model->down_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 93, 41, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 96, 44, &I_Arr_dwn_7x9);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Left
-    if(model->left_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 77, 25, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 81, 29, &I_Voldwn_6x6);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Right
-    if(model->right_pressed) {
-        canvas_set_bitmap_mode(canvas, 1);
-        canvas_draw_icon(canvas, 109, 25, &I_Pressed_Button_13x13);
-        canvas_set_bitmap_mode(canvas, 0);
-        canvas_set_color(canvas, ColorWhite);
-    }
-    canvas_draw_icon(canvas, 111, 29, &I_Volup_8x6);
-    canvas_set_color(canvas, ColorBlack);
-
-    // Ok
-    if(model->ok_pressed) {
-        canvas_draw_icon(canvas, 91, 23, &I_Like_pressed_17x17);
-    } else {
-        canvas_draw_icon(canvas, 94, 27, &I_Like_def_11x9);
-    }
-    // Exit
-    canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8);
-    canvas_set_font(canvas, FontSecondary);
-    elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit");
-}
-
-static void hid_tiktok_reset_cursor(HidTikTok* hid_tiktok) {
-    // Set cursor to the phone's left up corner
-    // Delays to guarantee one packet per connection interval
-    for(size_t i = 0; i < 8; i++) {
-        hid_hal_mouse_move(hid_tiktok->hid, -127, -127);
-        furi_delay_ms(50);
-    }
-    // Move cursor from the corner
-    hid_hal_mouse_move(hid_tiktok->hid, 20, 120);
-    furi_delay_ms(50);
-}
-
-static void
-    hid_tiktok_process_press(HidTikTok* hid_tiktok, HidTikTokModel* model, InputEvent* event) {
-    if(event->key == InputKeyUp) {
-        model->up_pressed = true;
-    } else if(event->key == InputKeyDown) {
-        model->down_pressed = true;
-    } else if(event->key == InputKeyLeft) {
-        model->left_pressed = true;
-        hid_hal_consumer_key_press(hid_tiktok->hid, HID_CONSUMER_VOLUME_DECREMENT);
-    } else if(event->key == InputKeyRight) {
-        model->right_pressed = true;
-        hid_hal_consumer_key_press(hid_tiktok->hid, HID_CONSUMER_VOLUME_INCREMENT);
-    } else if(event->key == InputKeyOk) {
-        model->ok_pressed = true;
-    }
-}
-
-static void
-    hid_tiktok_process_release(HidTikTok* hid_tiktok, HidTikTokModel* model, InputEvent* event) {
-    if(event->key == InputKeyUp) {
-        model->up_pressed = false;
-    } else if(event->key == InputKeyDown) {
-        model->down_pressed = false;
-    } else if(event->key == InputKeyLeft) {
-        model->left_pressed = false;
-        hid_hal_consumer_key_release(hid_tiktok->hid, HID_CONSUMER_VOLUME_DECREMENT);
-    } else if(event->key == InputKeyRight) {
-        model->right_pressed = false;
-        hid_hal_consumer_key_release(hid_tiktok->hid, HID_CONSUMER_VOLUME_INCREMENT);
-    } else if(event->key == InputKeyOk) {
-        model->ok_pressed = false;
-    }
-}
-
-static bool hid_tiktok_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    HidTikTok* hid_tiktok = context;
-    bool consumed = false;
-
-    with_view_model(
-        hid_tiktok->view,
-        HidTikTokModel * model,
-        {
-            if(event->type == InputTypePress) {
-                hid_tiktok_process_press(hid_tiktok, model, event);
-                if(model->connected && !model->is_cursor_set) {
-                    hid_tiktok_reset_cursor(hid_tiktok);
-                    model->is_cursor_set = true;
-                }
-                consumed = true;
-            } else if(event->type == InputTypeRelease) {
-                hid_tiktok_process_release(hid_tiktok, model, event);
-                consumed = true;
-            } else if(event->type == InputTypeShort) {
-                if(event->key == InputKeyOk) {
-                    hid_hal_mouse_press(hid_tiktok->hid, HID_MOUSE_BTN_LEFT);
-                    furi_delay_ms(50);
-                    hid_hal_mouse_release(hid_tiktok->hid, HID_MOUSE_BTN_LEFT);
-                    furi_delay_ms(50);
-                    hid_hal_mouse_press(hid_tiktok->hid, HID_MOUSE_BTN_LEFT);
-                    furi_delay_ms(50);
-                    hid_hal_mouse_release(hid_tiktok->hid, HID_MOUSE_BTN_LEFT);
-                    consumed = true;
-                } else if(event->key == InputKeyUp) {
-                    // Emulate up swipe
-                    hid_hal_mouse_scroll(hid_tiktok->hid, -6);
-                    hid_hal_mouse_scroll(hid_tiktok->hid, -12);
-                    hid_hal_mouse_scroll(hid_tiktok->hid, -19);
-                    hid_hal_mouse_scroll(hid_tiktok->hid, -12);
-                    hid_hal_mouse_scroll(hid_tiktok->hid, -6);
-                    consumed = true;
-                } else if(event->key == InputKeyDown) {
-                    // Emulate down swipe
-                    hid_hal_mouse_scroll(hid_tiktok->hid, 6);
-                    hid_hal_mouse_scroll(hid_tiktok->hid, 12);
-                    hid_hal_mouse_scroll(hid_tiktok->hid, 19);
-                    hid_hal_mouse_scroll(hid_tiktok->hid, 12);
-                    hid_hal_mouse_scroll(hid_tiktok->hid, 6);
-                    consumed = true;
-                } else if(event->key == InputKeyBack) {
-                    hid_hal_consumer_key_release_all(hid_tiktok->hid);
-                    consumed = true;
-                }
-            } else if(event->type == InputTypeLong) {
-                if(event->key == InputKeyBack) {
-                    hid_hal_consumer_key_release_all(hid_tiktok->hid);
-                    model->is_cursor_set = false;
-                    consumed = false;
-                }
-            }
-        },
-        true);
-
-    return consumed;
-}
-
-HidTikTok* hid_tiktok_alloc(Hid* bt_hid) {
-    HidTikTok* hid_tiktok = malloc(sizeof(HidTikTok));
-    hid_tiktok->hid = bt_hid;
-    hid_tiktok->view = view_alloc();
-    view_set_context(hid_tiktok->view, hid_tiktok);
-    view_allocate_model(hid_tiktok->view, ViewModelTypeLocking, sizeof(HidTikTokModel));
-    view_set_draw_callback(hid_tiktok->view, hid_tiktok_draw_callback);
-    view_set_input_callback(hid_tiktok->view, hid_tiktok_input_callback);
-
-    with_view_model(
-        hid_tiktok->view, HidTikTokModel * model, { model->transport = bt_hid->transport; }, true);
-
-    return hid_tiktok;
-}
-
-void hid_tiktok_free(HidTikTok* hid_tiktok) {
-    furi_assert(hid_tiktok);
-    view_free(hid_tiktok->view);
-    free(hid_tiktok);
-}
-
-View* hid_tiktok_get_view(HidTikTok* hid_tiktok) {
-    furi_assert(hid_tiktok);
-    return hid_tiktok->view;
-}
-
-void hid_tiktok_set_connected_status(HidTikTok* hid_tiktok, bool connected) {
-    furi_assert(hid_tiktok);
-    with_view_model(
-        hid_tiktok->view,
-        HidTikTokModel * model,
-        {
-            model->connected = connected;
-            model->is_cursor_set = false;
-        },
-        true);
-}

+ 0 - 14
hid_app/views/hid_tiktok.h

@@ -1,14 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-typedef struct Hid Hid;
-typedef struct HidTikTok HidTikTok;
-
-HidTikTok* hid_tiktok_alloc(Hid* bt_hid);
-
-void hid_tiktok_free(HidTikTok* hid_tiktok);
-
-View* hid_tiktok_get_view(HidTikTok* hid_tiktok);
-
-void hid_tiktok_set_connected_status(HidTikTok* hid_tiktok, bool connected);

+ 0 - 5
snake_game/.catalog/README.md

@@ -1,5 +0,0 @@
-# Snake
-
-This is a recreation of the classic Snake game. It is a simple game where you control a snake that grows in length as it eats food. The goal is to eat as much food as possible without running into yourself or the walls.
-
-At the end of the game you can see your final score, which is the number of food items you ate.

BIN
snake_game/.catalog/screenshots/1.png


BIN
snake_game/.catalog/screenshots/2.png


+ 0 - 13
snake_game/application.fam

@@ -1,13 +0,0 @@
-App(
-    appid="snake_game",
-    name="Snake Game",
-    apptype=FlipperAppType.EXTERNAL,
-    entry_point="snake_game_app",
-    requires=["gui"],
-    stack_size=1 * 1024,
-    targets=["f7"],
-    fap_version="1.0",
-    fap_description="Classic Snake Game",
-    fap_icon="snake_10px.png",
-    fap_category="Games",
-)

BIN
snake_game/snake_10px.png


+ 0 - 434
snake_game/snake_game.c

@@ -1,434 +0,0 @@
-#include <furi.h>
-#include <gui/gui.h>
-#include <input/input.h>
-#include <stdlib.h>
-#include <dolphin/dolphin.h>
-#include <notification/notification.h>
-#include <notification/notification_messages.h>
-
-typedef struct {
-    //    +-----x
-    //    |
-    //    |
-    //    y
-    uint8_t x;
-    uint8_t y;
-} Point;
-
-typedef enum {
-    GameStateLife,
-
-    // https://melmagazine.com/en-us/story/snake-nokia-6110-oral-history-taneli-armanto
-    // Armanto: While testing the early versions of the game, I noticed it was hard
-    // to control the snake upon getting close to and edge but not crashing — especially
-    // in the highest speed levels. I wanted the highest level to be as fast as I could
-    // possibly make the device "run," but on the other hand, I wanted to be friendly
-    // and help the player manage that level. Otherwise it might not be fun to play. So
-    // I implemented a little delay. A few milliseconds of extra time right before
-    // the player crashes, during which she can still change the directions. And if
-    // she does, the game continues.
-    GameStateLastChance,
-
-    GameStateGameOver,
-} GameState;
-
-// Note: do not change without purpose. Current values are used in smart
-// orthogonality calculation in `snake_game_get_turn_snake`.
-typedef enum {
-    DirectionUp,
-    DirectionRight,
-    DirectionDown,
-    DirectionLeft,
-} Direction;
-
-#define MAX_SNAKE_LEN 253
-
-typedef struct {
-    Point points[MAX_SNAKE_LEN];
-    uint16_t len;
-    Direction currentMovement;
-    Direction nextMovement; // if backward of currentMovement, ignore
-    Point fruit;
-    GameState state;
-    FuriMutex* mutex;
-} SnakeState;
-
-typedef enum {
-    EventTypeTick,
-    EventTypeKey,
-} EventType;
-
-typedef struct {
-    EventType type;
-    InputEvent input;
-} SnakeEvent;
-
-const NotificationSequence sequence_fail = {
-    &message_vibro_on,
-
-    &message_note_ds4,
-    &message_delay_10,
-    &message_sound_off,
-    &message_delay_10,
-
-    &message_note_ds4,
-    &message_delay_10,
-    &message_sound_off,
-    &message_delay_10,
-
-    &message_note_ds4,
-    &message_delay_10,
-    &message_sound_off,
-    &message_delay_10,
-
-    &message_vibro_off,
-    NULL,
-};
-
-const NotificationSequence sequence_eat = {
-    &message_note_c7,
-    &message_delay_50,
-    &message_sound_off,
-    NULL,
-};
-
-static void snake_game_render_callback(Canvas* const canvas, void* ctx) {
-    furi_assert(ctx);
-    const SnakeState* snake_state = ctx;
-
-    furi_mutex_acquire(snake_state->mutex, FuriWaitForever);
-
-    // Frame
-    canvas_draw_frame(canvas, 0, 0, 128, 64);
-
-    // Fruit
-    Point f = snake_state->fruit;
-    f.x = f.x * 4 + 1;
-    f.y = f.y * 4 + 1;
-    canvas_draw_rframe(canvas, f.x, f.y, 6, 6, 2);
-
-    // Snake
-    for(uint16_t i = 0; i < snake_state->len; i++) {
-        Point p = snake_state->points[i];
-        p.x = p.x * 4 + 2;
-        p.y = p.y * 4 + 2;
-        canvas_draw_box(canvas, p.x, p.y, 4, 4);
-    }
-
-    // Game Over banner
-    if(snake_state->state == GameStateGameOver) {
-        // Screen is 128x64 px
-        canvas_set_color(canvas, ColorWhite);
-        canvas_draw_box(canvas, 34, 20, 62, 24);
-
-        canvas_set_color(canvas, ColorBlack);
-        canvas_draw_frame(canvas, 34, 20, 62, 24);
-
-        canvas_set_font(canvas, FontPrimary);
-        canvas_draw_str(canvas, 37, 31, "Game Over");
-
-        canvas_set_font(canvas, FontSecondary);
-        char buffer[12];
-        snprintf(buffer, sizeof(buffer), "Score: %u", snake_state->len - 7U);
-        canvas_draw_str_aligned(canvas, 64, 41, AlignCenter, AlignBottom, buffer);
-    }
-
-    furi_mutex_release(snake_state->mutex);
-}
-
-static void snake_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
-    furi_assert(event_queue);
-
-    SnakeEvent event = {.type = EventTypeKey, .input = *input_event};
-    furi_message_queue_put(event_queue, &event, FuriWaitForever);
-}
-
-static void snake_game_update_timer_callback(FuriMessageQueue* event_queue) {
-    furi_assert(event_queue);
-
-    SnakeEvent event = {.type = EventTypeTick};
-    furi_message_queue_put(event_queue, &event, 0);
-}
-
-static void snake_game_init_game(SnakeState* const snake_state) {
-    Point p[] = {{8, 6}, {7, 6}, {6, 6}, {5, 6}, {4, 6}, {3, 6}, {2, 6}};
-    memcpy(snake_state->points, p, sizeof(p)); //-V1086
-
-    snake_state->len = 7;
-
-    snake_state->currentMovement = DirectionRight;
-
-    snake_state->nextMovement = DirectionRight;
-
-    Point f = {18, 6};
-    snake_state->fruit = f;
-
-    snake_state->state = GameStateLife;
-}
-
-static Point snake_game_get_new_fruit(SnakeState const* const snake_state) {
-    // 1 bit for each point on the playing field where the snake can turn
-    // and where the fruit can appear
-    uint16_t buffer[8];
-    memset(buffer, 0, sizeof(buffer));
-    uint8_t empty = 8 * 16;
-
-    for(uint16_t i = 0; i < snake_state->len; i++) {
-        Point p = snake_state->points[i];
-
-        if(p.x % 2 != 0 || p.y % 2 != 0) {
-            continue;
-        }
-        p.x /= 2;
-        p.y /= 2;
-
-        buffer[p.y] |= 1 << p.x;
-        empty--;
-    }
-    // Bit set if snake use that playing field
-
-    uint16_t newFruit = rand() % empty;
-
-    // Skip random number of _empty_ fields
-    for(uint8_t y = 0; y < 8; y++) {
-        for(uint16_t x = 0, mask = 1; x < 16; x += 1, mask <<= 1) {
-            if((buffer[y] & mask) == 0) {
-                if(newFruit == 0) {
-                    Point p = {
-                        .x = x * 2,
-                        .y = y * 2,
-                    };
-                    return p;
-                }
-                newFruit--;
-            }
-        }
-    }
-    // We will never be here
-    Point p = {0, 0};
-    return p;
-}
-
-static bool snake_game_collision_with_frame(Point const next_step) {
-    // if x == 0 && currentMovement == left then x - 1 == 255 ,
-    // so check only x > right border
-    return next_step.x > 30 || next_step.y > 14;
-}
-
-static bool
-    snake_game_collision_with_tail(SnakeState const* const snake_state, Point const next_step) {
-    for(uint16_t i = 0; i < snake_state->len; i++) {
-        Point p = snake_state->points[i];
-        if(p.x == next_step.x && p.y == next_step.y) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-static Direction snake_game_get_turn_snake(SnakeState const* const snake_state) {
-    // Sum of two `Direction` lies between 0 and 6, odd values indicate orthogonality.
-    bool is_orthogonal = (snake_state->currentMovement + snake_state->nextMovement) % 2 == 1;
-    return is_orthogonal ? snake_state->nextMovement : snake_state->currentMovement;
-}
-
-static Point snake_game_get_next_step(SnakeState const* const snake_state) {
-    Point next_step = snake_state->points[0];
-    switch(snake_state->currentMovement) {
-    // +-----x
-    // |
-    // |
-    // y
-    case DirectionUp:
-        next_step.y--;
-        break;
-    case DirectionRight:
-        next_step.x++;
-        break;
-    case DirectionDown:
-        next_step.y++;
-        break;
-    case DirectionLeft:
-        next_step.x--;
-        break;
-    }
-    return next_step;
-}
-
-static void snake_game_move_snake(SnakeState* const snake_state, Point const next_step) {
-    memmove(snake_state->points + 1, snake_state->points, snake_state->len * sizeof(Point));
-    snake_state->points[0] = next_step;
-}
-
-static void
-    snake_game_process_game_step(SnakeState* const snake_state, NotificationApp* notification) {
-    if(snake_state->state == GameStateGameOver) {
-        return;
-    }
-
-    bool can_turn = (snake_state->points[0].x % 2 == 0) && (snake_state->points[0].y % 2 == 0);
-    if(can_turn) {
-        snake_state->currentMovement = snake_game_get_turn_snake(snake_state);
-    }
-
-    Point next_step = snake_game_get_next_step(snake_state);
-
-    bool crush = snake_game_collision_with_frame(next_step);
-    if(crush) {
-        if(snake_state->state == GameStateLife) {
-            snake_state->state = GameStateLastChance;
-            return;
-        } else if(snake_state->state == GameStateLastChance) {
-            snake_state->state = GameStateGameOver;
-            notification_message_block(notification, &sequence_fail);
-            return;
-        }
-    } else {
-        if(snake_state->state == GameStateLastChance) {
-            snake_state->state = GameStateLife;
-        }
-    }
-
-    crush = snake_game_collision_with_tail(snake_state, next_step);
-    if(crush) {
-        snake_state->state = GameStateGameOver;
-        notification_message_block(notification, &sequence_fail);
-        return;
-    }
-
-    bool eatFruit = (next_step.x == snake_state->fruit.x) && (next_step.y == snake_state->fruit.y);
-    if(eatFruit) {
-        snake_state->len++;
-        if(snake_state->len >= MAX_SNAKE_LEN) {
-            snake_state->state = GameStateGameOver;
-            notification_message_block(notification, &sequence_fail);
-            return;
-        }
-    }
-
-    snake_game_move_snake(snake_state, next_step);
-
-    if(eatFruit) {
-        snake_state->fruit = snake_game_get_new_fruit(snake_state);
-        notification_message(notification, &sequence_eat);
-    }
-}
-
-int32_t snake_game_app(void* p) {
-    UNUSED(p);
-
-    FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(SnakeEvent));
-
-    SnakeState* snake_state = malloc(sizeof(SnakeState));
-    snake_game_init_game(snake_state);
-
-    snake_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
-
-    if(!snake_state->mutex) {
-        FURI_LOG_E("SnakeGame", "cannot create mutex\r\n");
-        free(snake_state);
-        return 255;
-    }
-
-    ViewPort* view_port = view_port_alloc();
-    view_port_draw_callback_set(view_port, snake_game_render_callback, snake_state);
-    view_port_input_callback_set(view_port, snake_game_input_callback, event_queue);
-
-    FuriTimer* timer =
-        furi_timer_alloc(snake_game_update_timer_callback, FuriTimerTypePeriodic, event_queue);
-    furi_timer_start(timer, furi_kernel_get_tick_frequency() / 4);
-
-    // Open GUI and register view_port
-    Gui* gui = furi_record_open(RECORD_GUI);
-    gui_add_view_port(gui, view_port, GuiLayerFullscreen);
-    NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
-
-    notification_message_block(notification, &sequence_display_backlight_enforce_on);
-
-    dolphin_deed(DolphinDeedPluginGameStart);
-
-    SnakeEvent event;
-    for(bool processing = true; processing;) {
-        FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
-
-        furi_mutex_acquire(snake_state->mutex, FuriWaitForever);
-
-        if(event_status == FuriStatusOk) {
-            // press events
-            if(event.type == EventTypeKey) {
-                if(event.input.type == InputTypePress) {
-                    switch(event.input.key) {
-                    case InputKeyUp:
-                        snake_state->nextMovement = DirectionUp;
-                        break;
-                    case InputKeyDown:
-                        snake_state->nextMovement = DirectionDown;
-                        break;
-                    case InputKeyRight:
-                        snake_state->nextMovement = DirectionRight;
-                        break;
-                    case InputKeyLeft:
-                        snake_state->nextMovement = DirectionLeft;
-                        break;
-                    case InputKeyOk:
-                        if(snake_state->state == GameStateGameOver) {
-                            snake_game_init_game(snake_state);
-                        }
-                        break;
-                    case InputKeyBack:
-                        processing = false;
-                        break;
-                    default:
-                        break;
-                    }
-                }
-            } else if(event.type == EventTypeTick) {
-                snake_game_process_game_step(snake_state, notification);
-            }
-        } else {
-            // event timeout
-        }
-
-        view_port_update(view_port);
-        furi_mutex_release(snake_state->mutex);
-    }
-
-    // Return backlight to normal state
-    notification_message(notification, &sequence_display_backlight_enforce_auto);
-
-    furi_timer_free(timer);
-    view_port_enabled_set(view_port, false);
-    gui_remove_view_port(gui, view_port);
-    furi_record_close(RECORD_GUI);
-    furi_record_close(RECORD_NOTIFICATION);
-    view_port_free(view_port);
-    furi_message_queue_free(event_queue);
-    furi_mutex_free(snake_state->mutex);
-    free(snake_state);
-
-    return 0;
-}
-
-// Screen is 128x64 px
-// (4 + 4) * 16 - 4 + 2 + 2border == 128
-// (4 + 4) * 8 - 4 + 2 + 2border == 64
-// Game field from point{x:  0, y: 0} to point{x: 30, y: 14}.
-// The snake turns only in even cells - intersections.
-// ┌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┐
-// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎
-// ╎ ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪ ╎
-// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎
-// ╎ ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪ ╎
-// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎
-// ╎ ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪ ╎
-// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎
-// ╎ ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪ ╎
-// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎
-// ╎ ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪ ╎
-// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎
-// ╎ ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪ ╎
-// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎
-// ╎ ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪   ▪ ╎
-// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎
-// └╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┘