hid_mouse_jiggler.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "hid_mouse_jiggler.h"
  2. #include <gui/elements.h>
  3. #include "../hid.h"
  4. #include "hid_icons.h"
  5. #include <assets_icons.h>
  6. #define TAG "HidMouseJiggler"
  7. struct HidMouseJiggler {
  8. View* view;
  9. Hid* hid;
  10. FuriTimer* timer;
  11. };
  12. typedef struct {
  13. bool connected;
  14. bool running;
  15. int interval_idx;
  16. uint8_t counter;
  17. HidTransport transport;
  18. } HidMouseJigglerModel;
  19. const int intervals[6] = {500, 2000, 5000, 10000, 30000, 60000};
  20. static void hid_mouse_jiggler_draw_callback(Canvas* canvas, void* context) {
  21. furi_assert(context);
  22. HidMouseJigglerModel* model = context;
  23. // Header
  24. if(model->transport == HidTransportBle) {
  25. if(model->connected) {
  26. canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15);
  27. } else {
  28. canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
  29. }
  30. }
  31. canvas_set_font(canvas, FontPrimary);
  32. elements_multiline_text_aligned(canvas, 17, 2, AlignLeft, AlignTop, "Mouse Jiggler");
  33. // Timeout
  34. elements_multiline_text(canvas, AlignLeft, 26, "Interval (ms):");
  35. canvas_set_font(canvas, FontSecondary);
  36. if(model->interval_idx != 0) canvas_draw_icon(canvas, 74, 19, &I_ButtonLeft_4x7);
  37. if(model->interval_idx != (int)COUNT_OF(intervals) - 1)
  38. canvas_draw_icon(canvas, 80, 19, &I_ButtonRight_4x7);
  39. FuriString* interval_str = furi_string_alloc_printf("%d", intervals[model->interval_idx]);
  40. elements_multiline_text(canvas, 91, 26, furi_string_get_cstr(interval_str));
  41. furi_string_free(interval_str);
  42. canvas_set_font(canvas, FontPrimary);
  43. elements_multiline_text(canvas, AlignLeft, 40, "Press Start\nto jiggle");
  44. canvas_set_font(canvas, FontSecondary);
  45. // Ok
  46. canvas_draw_icon(canvas, 63, 30, &I_Space_65x18);
  47. if(model->running) {
  48. elements_slightly_rounded_box(canvas, 66, 32, 60, 13);
  49. canvas_set_color(canvas, ColorWhite);
  50. }
  51. canvas_draw_icon(canvas, 74, 34, &I_Ok_btn_9x9);
  52. if(model->running) {
  53. elements_multiline_text_aligned(canvas, 91, 41, AlignLeft, AlignBottom, "Stop");
  54. } else {
  55. elements_multiline_text_aligned(canvas, 91, 41, AlignLeft, AlignBottom, "Start");
  56. }
  57. canvas_set_color(canvas, ColorBlack);
  58. // Back
  59. canvas_draw_icon(canvas, 74, 54, &I_Pin_back_arrow_10x8);
  60. elements_multiline_text_aligned(canvas, 91, 62, AlignLeft, AlignBottom, "Quit");
  61. }
  62. static void hid_mouse_jiggler_timer_callback(void* context) {
  63. furi_assert(context);
  64. HidMouseJiggler* hid_mouse_jiggler = context;
  65. with_view_model(
  66. hid_mouse_jiggler->view,
  67. HidMouseJigglerModel * model,
  68. {
  69. if(model->running) {
  70. model->counter++;
  71. hid_hal_mouse_move(
  72. hid_mouse_jiggler->hid,
  73. (model->counter % 2 == 0) ? MOUSE_MOVE_SHORT : -MOUSE_MOVE_SHORT,
  74. 0);
  75. }
  76. },
  77. false);
  78. }
  79. static void hid_mouse_jiggler_exit_callback(void* context) {
  80. furi_assert(context);
  81. HidMouseJiggler* hid_mouse_jiggler = context;
  82. furi_timer_stop(hid_mouse_jiggler->timer);
  83. }
  84. static bool hid_mouse_jiggler_input_callback(InputEvent* event, void* context) {
  85. furi_assert(context);
  86. HidMouseJiggler* hid_mouse_jiggler = context;
  87. bool consumed = false;
  88. with_view_model(
  89. hid_mouse_jiggler->view,
  90. HidMouseJigglerModel * model,
  91. {
  92. if(event->type == InputTypePress && event->key == InputKeyOk) {
  93. model->running = !model->running;
  94. if(model->running) {
  95. furi_timer_stop(hid_mouse_jiggler->timer);
  96. furi_timer_start(hid_mouse_jiggler->timer, intervals[model->interval_idx]);
  97. };
  98. consumed = true;
  99. }
  100. if(event->type == InputTypePress && event->key == InputKeyRight && !model->running &&
  101. model->interval_idx < (int)COUNT_OF(intervals) - 1) {
  102. model->interval_idx++;
  103. consumed = true;
  104. }
  105. if(event->type == InputTypePress && event->key == InputKeyLeft && !model->running &&
  106. model->interval_idx > 0) {
  107. model->interval_idx--;
  108. consumed = true;
  109. }
  110. },
  111. true);
  112. return consumed;
  113. }
  114. HidMouseJiggler* hid_mouse_jiggler_alloc(Hid* hid) {
  115. HidMouseJiggler* hid_mouse_jiggler = malloc(sizeof(HidMouseJiggler));
  116. hid_mouse_jiggler->view = view_alloc();
  117. view_set_context(hid_mouse_jiggler->view, hid_mouse_jiggler);
  118. view_allocate_model(
  119. hid_mouse_jiggler->view, ViewModelTypeLocking, sizeof(HidMouseJigglerModel));
  120. view_set_draw_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_draw_callback);
  121. view_set_input_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_input_callback);
  122. view_set_exit_callback(hid_mouse_jiggler->view, hid_mouse_jiggler_exit_callback);
  123. hid_mouse_jiggler->hid = hid;
  124. hid_mouse_jiggler->timer = furi_timer_alloc(
  125. hid_mouse_jiggler_timer_callback, FuriTimerTypePeriodic, hid_mouse_jiggler);
  126. with_view_model(
  127. hid_mouse_jiggler->view,
  128. HidMouseJigglerModel * model,
  129. {
  130. model->transport = hid->transport;
  131. model->interval_idx = 2;
  132. },
  133. true);
  134. return hid_mouse_jiggler;
  135. }
  136. void hid_mouse_jiggler_free(HidMouseJiggler* hid_mouse_jiggler) {
  137. furi_assert(hid_mouse_jiggler);
  138. furi_timer_stop(hid_mouse_jiggler->timer);
  139. furi_timer_free(hid_mouse_jiggler->timer);
  140. view_free(hid_mouse_jiggler->view);
  141. free(hid_mouse_jiggler);
  142. }
  143. View* hid_mouse_jiggler_get_view(HidMouseJiggler* hid_mouse_jiggler) {
  144. furi_assert(hid_mouse_jiggler);
  145. return hid_mouse_jiggler->view;
  146. }
  147. void hid_mouse_jiggler_set_connected_status(HidMouseJiggler* hid_mouse_jiggler, bool connected) {
  148. furi_assert(hid_mouse_jiggler);
  149. with_view_model(
  150. hid_mouse_jiggler->view,
  151. HidMouseJigglerModel * model,
  152. { model->connected = connected; },
  153. true);
  154. }