usb_mouse.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "usb_mouse.h"
  2. #include "../tracking/main_loop.h"
  3. #include <furi.h>
  4. #include <furi_hal_usb.h>
  5. #include <furi_hal_usb_hid.h>
  6. #include <gui/elements.h>
  7. struct UsbMouse {
  8. View* view;
  9. ViewDispatcher* view_dispatcher;
  10. FuriHalUsbInterface* usb_mode_prev;
  11. };
  12. static void usb_mouse_draw_callback(Canvas* canvas, void* context) {
  13. UNUSED(context);
  14. canvas_clear(canvas);
  15. canvas_set_font(canvas, FontPrimary);
  16. canvas_draw_str(canvas, 0, 10, "USB Mouse mode");
  17. canvas_set_font(canvas, FontSecondary);
  18. canvas_draw_str(canvas, 0, 63, "Hold [back] to exit");
  19. }
  20. static void usb_mouse_process(UsbMouse* usb_mouse, InputEvent* event) {
  21. with_view_model(
  22. usb_mouse->view,
  23. void* model,
  24. {
  25. UNUSED(model);
  26. if(event->key == InputKeyUp) {
  27. if(event->type == InputTypePress) {
  28. furi_hal_hid_mouse_press(HID_MOUSE_BTN_LEFT);
  29. } else if(event->type == InputTypeRelease) {
  30. furi_hal_hid_mouse_release(HID_MOUSE_BTN_LEFT);
  31. }
  32. } else if(event->key == InputKeyDown) {
  33. if(event->type == InputTypePress) {
  34. furi_hal_hid_mouse_press(HID_MOUSE_BTN_RIGHT);
  35. } else if(event->type == InputTypeRelease) {
  36. furi_hal_hid_mouse_release(HID_MOUSE_BTN_RIGHT);
  37. }
  38. } else if(event->key == InputKeyOk) {
  39. if(event->type == InputTypePress) {
  40. furi_hal_hid_mouse_press(HID_MOUSE_BTN_WHEEL);
  41. } else if(event->type == InputTypeRelease) {
  42. furi_hal_hid_mouse_release(HID_MOUSE_BTN_WHEEL);
  43. }
  44. }
  45. },
  46. true);
  47. }
  48. static bool usb_mouse_input_callback(InputEvent* event, void* context) {
  49. furi_assert(context);
  50. UsbMouse* usb_mouse = context;
  51. bool consumed = false;
  52. if(event->type == InputTypeLong && event->key == InputKeyBack) {
  53. // furi_hal_hid_mouse_release_all();
  54. } else {
  55. usb_mouse_process(usb_mouse, event);
  56. consumed = true;
  57. }
  58. return consumed;
  59. }
  60. void usb_mouse_enter_callback(void* context) {
  61. furi_assert(context);
  62. UsbMouse* usb_mouse = context;
  63. usb_mouse->usb_mode_prev = furi_hal_usb_get_config();
  64. furi_hal_usb_unlock();
  65. furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
  66. tracking_begin();
  67. view_dispatcher_send_custom_event(usb_mouse->view_dispatcher, 0);
  68. }
  69. bool usb_mouse_custom_callback(uint32_t event, void* context) {
  70. UNUSED(event);
  71. furi_assert(context);
  72. UsbMouse* usb_mouse = context;
  73. tracking_step(furi_hal_hid_mouse_move);
  74. furi_delay_ms(1); // Magic! Removing this will break the buttons
  75. view_dispatcher_send_custom_event(usb_mouse->view_dispatcher, 0);
  76. return true;
  77. }
  78. void usb_mouse_exit_callback(void* context) {
  79. furi_assert(context);
  80. UsbMouse* usb_mouse = context;
  81. tracking_end();
  82. furi_hal_usb_set_config(usb_mouse->usb_mode_prev, NULL);
  83. }
  84. UsbMouse* usb_mouse_alloc(ViewDispatcher* view_dispatcher) {
  85. UsbMouse* usb_mouse = malloc(sizeof(UsbMouse));
  86. usb_mouse->view = view_alloc();
  87. usb_mouse->view_dispatcher = view_dispatcher;
  88. view_set_context(usb_mouse->view, usb_mouse);
  89. view_set_draw_callback(usb_mouse->view, usb_mouse_draw_callback);
  90. view_set_input_callback(usb_mouse->view, usb_mouse_input_callback);
  91. view_set_enter_callback(usb_mouse->view, usb_mouse_enter_callback);
  92. view_set_custom_callback(usb_mouse->view, usb_mouse_custom_callback);
  93. view_set_exit_callback(usb_mouse->view, usb_mouse_exit_callback);
  94. return usb_mouse;
  95. }
  96. void usb_mouse_free(UsbMouse* usb_mouse) {
  97. furi_assert(usb_mouse);
  98. view_free(usb_mouse->view);
  99. free(usb_mouse);
  100. }
  101. View* usb_mouse_get_view(UsbMouse* usb_mouse) {
  102. furi_assert(usb_mouse);
  103. return usb_mouse->view;
  104. }