hid_mouse_jiggler.c 5.9 KB

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