Add Mouse Jiggler to HID Remote (#2113)
* feat: add Mouse Jiggler to HID Remote * move processing to use furi_timer instead of draw loop * HidApp: refine mouse jiggler, move timer work into enter/exit callbacks Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
parent
87fb852bcf
commit
d541f142c8
@ -9,10 +9,10 @@ enum HidDebugSubmenuIndex {
|
|||||||
HidSubmenuIndexKeynote,
|
HidSubmenuIndexKeynote,
|
||||||
HidSubmenuIndexKeyboard,
|
HidSubmenuIndexKeyboard,
|
||||||
HidSubmenuIndexMedia,
|
HidSubmenuIndexMedia,
|
||||||
BtHidSubmenuIndexTikTok,
|
HidSubmenuIndexTikTok,
|
||||||
HidSubmenuIndexMouse,
|
HidSubmenuIndexMouse,
|
||||||
|
HidSubmenuIndexMouseJiggler,
|
||||||
};
|
};
|
||||||
typedef enum { ConnTypeSubmenuIndexBluetooth, ConnTypeSubmenuIndexUsb } ConnTypeDebugSubmenuIndex;
|
|
||||||
|
|
||||||
static void hid_submenu_callback(void* context, uint32_t index) {
|
static void hid_submenu_callback(void* context, uint32_t index) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
@ -29,9 +29,12 @@ static void hid_submenu_callback(void* context, uint32_t index) {
|
|||||||
} else if(index == HidSubmenuIndexMouse) {
|
} else if(index == HidSubmenuIndexMouse) {
|
||||||
app->view_id = HidViewMouse;
|
app->view_id = HidViewMouse;
|
||||||
view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouse);
|
view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouse);
|
||||||
} else if(index == BtHidSubmenuIndexTikTok) {
|
} else if(index == HidSubmenuIndexTikTok) {
|
||||||
app->view_id = BtHidViewTikTok;
|
app->view_id = BtHidViewTikTok;
|
||||||
view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewTikTok);
|
view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewTikTok);
|
||||||
|
} else if(index == HidSubmenuIndexMouseJiggler) {
|
||||||
|
app->view_id = HidViewMouseJiggler;
|
||||||
|
view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouseJiggler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +51,7 @@ static void bt_hid_connection_status_changed_callback(BtStatus status, void* con
|
|||||||
hid_keyboard_set_connected_status(hid->hid_keyboard, connected);
|
hid_keyboard_set_connected_status(hid->hid_keyboard, connected);
|
||||||
hid_media_set_connected_status(hid->hid_media, connected);
|
hid_media_set_connected_status(hid->hid_media, connected);
|
||||||
hid_mouse_set_connected_status(hid->hid_mouse, connected);
|
hid_mouse_set_connected_status(hid->hid_mouse, connected);
|
||||||
|
hid_mouse_jiggler_set_connected_status(hid->hid_mouse_jiggler, connected);
|
||||||
hid_tiktok_set_connected_status(hid->hid_tiktok, connected);
|
hid_tiktok_set_connected_status(hid->hid_tiktok, connected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +108,16 @@ Hid* hid_alloc(HidTransport transport) {
|
|||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
app->device_type_submenu,
|
app->device_type_submenu,
|
||||||
"TikTok Controller",
|
"TikTok Controller",
|
||||||
BtHidSubmenuIndexTikTok,
|
HidSubmenuIndexTikTok,
|
||||||
hid_submenu_callback,
|
hid_submenu_callback,
|
||||||
app);
|
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_set_previous_callback(submenu_get_view(app->device_type_submenu), hid_exit);
|
||||||
view_dispatcher_add_view(
|
view_dispatcher_add_view(
|
||||||
app->view_dispatcher, HidViewSubmenu, submenu_get_view(app->device_type_submenu));
|
app->view_dispatcher, HidViewSubmenu, submenu_get_view(app->device_type_submenu));
|
||||||
@ -160,6 +170,15 @@ Hid* hid_app_alloc_view(void* context) {
|
|||||||
view_dispatcher_add_view(
|
view_dispatcher_add_view(
|
||||||
app->view_dispatcher, HidViewMouse, hid_mouse_get_view(app->hid_mouse));
|
app->view_dispatcher, HidViewMouse, hid_mouse_get_view(app->hid_mouse));
|
||||||
|
|
||||||
|
// 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;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,6 +201,8 @@ void hid_free(Hid* app) {
|
|||||||
hid_media_free(app->hid_media);
|
hid_media_free(app->hid_media);
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse);
|
view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse);
|
||||||
hid_mouse_free(app->hid_mouse);
|
hid_mouse_free(app->hid_mouse);
|
||||||
|
view_dispatcher_remove_view(app->view_dispatcher, HidViewMouseJiggler);
|
||||||
|
hid_mouse_jiggler_free(app->hid_mouse_jiggler);
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok);
|
view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok);
|
||||||
hid_tiktok_free(app->hid_tiktok);
|
hid_tiktok_free(app->hid_tiktok);
|
||||||
view_dispatcher_free(app->view_dispatcher);
|
view_dispatcher_free(app->view_dispatcher);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "views/hid_keyboard.h"
|
#include "views/hid_keyboard.h"
|
||||||
#include "views/hid_media.h"
|
#include "views/hid_media.h"
|
||||||
#include "views/hid_mouse.h"
|
#include "views/hid_mouse.h"
|
||||||
|
#include "views/hid_mouse_jiggler.h"
|
||||||
#include "views/hid_tiktok.h"
|
#include "views/hid_tiktok.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -39,6 +40,7 @@ struct Hid {
|
|||||||
HidKeyboard* hid_keyboard;
|
HidKeyboard* hid_keyboard;
|
||||||
HidMedia* hid_media;
|
HidMedia* hid_media;
|
||||||
HidMouse* hid_mouse;
|
HidMouse* hid_mouse;
|
||||||
|
HidMouseJiggler* hid_mouse_jiggler;
|
||||||
HidTikTok* hid_tiktok;
|
HidTikTok* hid_tiktok;
|
||||||
|
|
||||||
HidTransport transport;
|
HidTransport transport;
|
||||||
|
@ -4,6 +4,7 @@ typedef enum {
|
|||||||
HidViewKeyboard,
|
HidViewKeyboard,
|
||||||
HidViewMedia,
|
HidViewMedia,
|
||||||
HidViewMouse,
|
HidViewMouse,
|
||||||
|
HidViewMouseJiggler,
|
||||||
BtHidViewTikTok,
|
BtHidViewTikTok,
|
||||||
HidViewExitConfirm,
|
HidViewExitConfirm,
|
||||||
} HidView;
|
} HidView;
|
149
applications/plugins/hid_app/views/hid_mouse_jiggler.c
Normal file
149
applications/plugins/hid_app/views/hid_mouse_jiggler.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#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;
|
||||||
|
} HidMouseJigglerModel;
|
||||||
|
|
||||||
|
static void hid_mouse_jiggler_draw_callback(Canvas* canvas, void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
HidMouseJigglerModel* model = context;
|
||||||
|
|
||||||
|
// Header
|
||||||
|
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->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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
17
applications/plugins/hid_app/views/hid_mouse_jiggler.h
Normal file
17
applications/plugins/hid_app/views/hid_mouse_jiggler.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#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);
|
Loading…
x
Reference in New Issue
Block a user