usb_mouse.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. #define MOUSE_SCROLL 2
  21. static void usb_mouse_process(UsbMouse* usb_mouse, InputEvent* event) {
  22. with_view_model(
  23. usb_mouse->view,
  24. void* model,
  25. {
  26. UNUSED(model);
  27. if(event->key == InputKeyUp) {
  28. if(event->type == InputTypePress) {
  29. furi_hal_hid_mouse_press(HID_MOUSE_BTN_LEFT);
  30. } else if(event->type == InputTypeRelease) {
  31. furi_hal_hid_mouse_release(HID_MOUSE_BTN_LEFT);
  32. }
  33. } else if(event->key == InputKeyDown) {
  34. if(event->type == InputTypePress) {
  35. furi_hal_hid_mouse_press(HID_MOUSE_BTN_RIGHT);
  36. } else if(event->type == InputTypeRelease) {
  37. furi_hal_hid_mouse_release(HID_MOUSE_BTN_RIGHT);
  38. }
  39. } else if(event->key == InputKeyOk) {
  40. if(event->type == InputTypePress) {
  41. furi_hal_hid_mouse_press(HID_MOUSE_BTN_WHEEL);
  42. } else if(event->type == InputTypeRelease) {
  43. furi_hal_hid_mouse_release(HID_MOUSE_BTN_WHEEL);
  44. }
  45. } else if(event->key == InputKeyRight) {
  46. if(event->type == InputTypePress || event->type == InputTypeRepeat) {
  47. furi_hal_hid_mouse_scroll(MOUSE_SCROLL);
  48. }
  49. } else if(event->key == InputKeyLeft) {
  50. if(event->type == InputTypePress || event->type == InputTypeRepeat) {
  51. furi_hal_hid_mouse_scroll(-MOUSE_SCROLL);
  52. }
  53. }
  54. },
  55. true);
  56. }
  57. static bool usb_mouse_input_callback(InputEvent* event, void* context) {
  58. furi_assert(context);
  59. UsbMouse* usb_mouse = context;
  60. bool consumed = false;
  61. if(event->type == InputTypeLong && event->key == InputKeyBack) {
  62. // furi_hal_hid_mouse_release_all();
  63. } else {
  64. usb_mouse_process(usb_mouse, event);
  65. consumed = true;
  66. }
  67. return consumed;
  68. }
  69. void usb_mouse_enter_callback(void* context) {
  70. furi_assert(context);
  71. UsbMouse* usb_mouse = context;
  72. usb_mouse->usb_mode_prev = furi_hal_usb_get_config();
  73. furi_hal_usb_unlock();
  74. furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
  75. tracking_begin();
  76. view_dispatcher_send_custom_event(usb_mouse->view_dispatcher, 0);
  77. }
  78. bool usb_mouse_move(int8_t dx, int8_t dy, void* context) {
  79. UNUSED(context);
  80. return furi_hal_hid_mouse_move(dx, dy);
  81. }
  82. bool usb_mouse_custom_callback(uint32_t event, void* context) {
  83. UNUSED(event);
  84. furi_assert(context);
  85. UsbMouse* usb_mouse = context;
  86. tracking_step(usb_mouse_move, context);
  87. furi_delay_ms(3); // Magic! Removing this will break the buttons
  88. view_dispatcher_send_custom_event(usb_mouse->view_dispatcher, 0);
  89. return true;
  90. }
  91. void usb_mouse_exit_callback(void* context) {
  92. furi_assert(context);
  93. UsbMouse* usb_mouse = context;
  94. tracking_end();
  95. furi_hal_usb_set_config(usb_mouse->usb_mode_prev, NULL);
  96. }
  97. UsbMouse* usb_mouse_alloc(ViewDispatcher* view_dispatcher) {
  98. UsbMouse* usb_mouse = malloc(sizeof(UsbMouse));
  99. usb_mouse->view = view_alloc();
  100. usb_mouse->view_dispatcher = view_dispatcher;
  101. view_set_context(usb_mouse->view, usb_mouse);
  102. view_set_draw_callback(usb_mouse->view, usb_mouse_draw_callback);
  103. view_set_input_callback(usb_mouse->view, usb_mouse_input_callback);
  104. view_set_enter_callback(usb_mouse->view, usb_mouse_enter_callback);
  105. view_set_custom_callback(usb_mouse->view, usb_mouse_custom_callback);
  106. view_set_exit_callback(usb_mouse->view, usb_mouse_exit_callback);
  107. return usb_mouse;
  108. }
  109. void usb_mouse_free(UsbMouse* usb_mouse) {
  110. furi_assert(usb_mouse);
  111. view_free(usb_mouse->view);
  112. free(usb_mouse);
  113. }
  114. View* usb_mouse_get_view(UsbMouse* usb_mouse) {
  115. furi_assert(usb_mouse);
  116. return usb_mouse->view;
  117. }