usb_hid_autofire.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <string.h>
  2. #include <furi.h>
  3. #include <furi_hal.h>
  4. #include <gui/gui.h>
  5. #include <input/input.h>
  6. #include "version.h"
  7. #include "tools.h"
  8. // Uncomment to be able to make a screenshot
  9. //#define USB_HID_AUTOFIRE_SCREENSHOT
  10. typedef enum {
  11. EventTypeInput,
  12. } EventType;
  13. typedef struct {
  14. union {
  15. InputEvent input;
  16. };
  17. EventType type;
  18. } UsbMouseEvent;
  19. bool btn_left_autofire = false;
  20. uint32_t autofire_delay = 10;
  21. static void usb_hid_autofire_render_callback(Canvas* canvas, void* ctx) {
  22. UNUSED(ctx);
  23. char autofire_delay_str[12];
  24. //std::string pi = "pi is " + std::to_string(3.1415926);
  25. itoa(autofire_delay, autofire_delay_str, 10);
  26. //sprintf(autofire_delay_str, "%lu", autofire_delay);
  27. canvas_clear(canvas);
  28. canvas_set_font(canvas, FontPrimary);
  29. canvas_draw_str(canvas, 0, 10, "USB HID Autofire");
  30. canvas_draw_str(canvas, 0, 34, btn_left_autofire ? "<active>" : "<inactive>");
  31. canvas_set_font(canvas, FontSecondary);
  32. canvas_draw_str(canvas, 90, 10, "v");
  33. canvas_draw_str(canvas, 96, 10, VERSION);
  34. canvas_draw_str(canvas, 0, 22, "Press [ok] for auto left clicking");
  35. canvas_draw_str(canvas, 0, 46, "delay [ms]:");
  36. canvas_draw_str(canvas, 50, 46, autofire_delay_str);
  37. canvas_draw_str(canvas, 0, 63, "Press [back] to exit");
  38. }
  39. static void usb_hid_autofire_input_callback(InputEvent* input_event, void* ctx) {
  40. FuriMessageQueue* event_queue = ctx;
  41. UsbMouseEvent event;
  42. event.type = EventTypeInput;
  43. event.input = *input_event;
  44. furi_message_queue_put(event_queue, &event, FuriWaitForever);
  45. }
  46. int32_t usb_hid_autofire_app(void* p) {
  47. UNUSED(p);
  48. FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(UsbMouseEvent));
  49. furi_check(event_queue);
  50. ViewPort* view_port = view_port_alloc();
  51. FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
  52. #ifndef USB_HID_AUTOFIRE_SCREENSHOT
  53. furi_hal_usb_unlock();
  54. furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
  55. #endif
  56. view_port_draw_callback_set(view_port, usb_hid_autofire_render_callback, NULL);
  57. view_port_input_callback_set(view_port, usb_hid_autofire_input_callback, event_queue);
  58. // Open GUI and register view_port
  59. Gui* gui = furi_record_open(RECORD_GUI);
  60. gui_add_view_port(gui, view_port, GuiLayerFullscreen);
  61. UsbMouseEvent event;
  62. while(1) {
  63. FuriStatus event_status = furi_message_queue_get(event_queue, &event, 50);
  64. if(event_status == FuriStatusOk) {
  65. if(event.type == EventTypeInput) {
  66. if(event.input.key == InputKeyBack) {
  67. break;
  68. }
  69. if(event.input.type != InputTypeRelease) {
  70. continue;
  71. }
  72. switch(event.input.key) {
  73. case InputKeyOk:
  74. btn_left_autofire = !btn_left_autofire;
  75. break;
  76. case InputKeyLeft:
  77. if(autofire_delay > 0) {
  78. autofire_delay -= 10;
  79. }
  80. break;
  81. case InputKeyRight:
  82. autofire_delay += 10;
  83. break;
  84. default:
  85. break;
  86. }
  87. }
  88. }
  89. if(btn_left_autofire) {
  90. furi_hal_hid_mouse_press(HID_MOUSE_BTN_LEFT);
  91. // TODO: Don't wait, but use the timer directly to just don't send the release event (see furi_hal_cortex_delay_us)
  92. furi_delay_us(autofire_delay * 500);
  93. furi_hal_hid_mouse_release(HID_MOUSE_BTN_LEFT);
  94. furi_delay_us(autofire_delay * 500);
  95. }
  96. view_port_update(view_port);
  97. }
  98. furi_hal_usb_set_config(usb_mode_prev, NULL);
  99. // remove & free all stuff created by app
  100. gui_remove_view_port(gui, view_port);
  101. view_port_free(view_port);
  102. furi_message_queue_free(event_queue);
  103. return 0;
  104. }