mirror of
https://github.com/UberGuidoZ/Flipper.git
synced 2025-01-05 13:20:22 +00:00
140 lines
4.4 KiB
C
140 lines
4.4 KiB
C
#include "usb_mouse.h"
|
|
#include "../tracking/main_loop.h"
|
|
|
|
#include <furi.h>
|
|
#include <furi_hal_usb.h>
|
|
#include <furi_hal_usb_hid.h>
|
|
#include <gui/elements.h>
|
|
|
|
struct UsbMouse {
|
|
View* view;
|
|
ViewDispatcher* view_dispatcher;
|
|
FuriHalUsbInterface* usb_mode_prev;
|
|
};
|
|
|
|
static void usb_mouse_draw_callback(Canvas* canvas, void* context) {
|
|
UNUSED(context);
|
|
canvas_clear(canvas);
|
|
canvas_set_font(canvas, FontPrimary);
|
|
canvas_draw_str(canvas, 0, 10, "USB Mouse mode");
|
|
canvas_set_font(canvas, FontSecondary);
|
|
canvas_draw_str(canvas, 0, 63, "Hold [back] to exit");
|
|
}
|
|
|
|
#define MOUSE_SCROLL 2
|
|
|
|
static void usb_mouse_process(UsbMouse* usb_mouse, InputEvent* event) {
|
|
with_view_model(
|
|
usb_mouse->view,
|
|
void* model,
|
|
{
|
|
UNUSED(model);
|
|
if(event->key == InputKeyUp) {
|
|
if(event->type == InputTypePress) {
|
|
furi_hal_hid_mouse_press(HID_MOUSE_BTN_LEFT);
|
|
} else if(event->type == InputTypeRelease) {
|
|
furi_hal_hid_mouse_release(HID_MOUSE_BTN_LEFT);
|
|
}
|
|
} else if(event->key == InputKeyDown) {
|
|
if(event->type == InputTypePress) {
|
|
furi_hal_hid_mouse_press(HID_MOUSE_BTN_RIGHT);
|
|
} else if(event->type == InputTypeRelease) {
|
|
furi_hal_hid_mouse_release(HID_MOUSE_BTN_RIGHT);
|
|
}
|
|
} else if(event->key == InputKeyOk) {
|
|
if(event->type == InputTypePress) {
|
|
furi_hal_hid_mouse_press(HID_MOUSE_BTN_WHEEL);
|
|
} else if(event->type == InputTypeRelease) {
|
|
furi_hal_hid_mouse_release(HID_MOUSE_BTN_WHEEL);
|
|
}
|
|
} else if(event->key == InputKeyRight) {
|
|
if(event->type == InputTypePress || event->type == InputTypeRepeat) {
|
|
furi_hal_hid_mouse_scroll(MOUSE_SCROLL);
|
|
}
|
|
} else if(event->key == InputKeyLeft) {
|
|
if(event->type == InputTypePress || event->type == InputTypeRepeat) {
|
|
furi_hal_hid_mouse_scroll(-MOUSE_SCROLL);
|
|
}
|
|
}
|
|
},
|
|
true);
|
|
}
|
|
|
|
static bool usb_mouse_input_callback(InputEvent* event, void* context) {
|
|
furi_assert(context);
|
|
UsbMouse* usb_mouse = context;
|
|
bool consumed = false;
|
|
|
|
if(event->type == InputTypeLong && event->key == InputKeyBack) {
|
|
// furi_hal_hid_mouse_release_all();
|
|
} else {
|
|
usb_mouse_process(usb_mouse, event);
|
|
consumed = true;
|
|
}
|
|
|
|
return consumed;
|
|
}
|
|
|
|
void usb_mouse_enter_callback(void* context) {
|
|
furi_assert(context);
|
|
UsbMouse* usb_mouse = context;
|
|
|
|
usb_mouse->usb_mode_prev = furi_hal_usb_get_config();
|
|
furi_hal_usb_unlock();
|
|
furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
|
|
|
|
tracking_begin();
|
|
|
|
view_dispatcher_send_custom_event(usb_mouse->view_dispatcher, 0);
|
|
}
|
|
|
|
bool usb_mouse_move(int8_t dx, int8_t dy, void* context) {
|
|
UNUSED(context);
|
|
return furi_hal_hid_mouse_move(dx, dy);
|
|
}
|
|
|
|
bool usb_mouse_custom_callback(uint32_t event, void* context) {
|
|
UNUSED(event);
|
|
furi_assert(context);
|
|
UsbMouse* usb_mouse = context;
|
|
|
|
tracking_step(usb_mouse_move, context);
|
|
furi_delay_ms(3); // Magic! Removing this will break the buttons
|
|
|
|
view_dispatcher_send_custom_event(usb_mouse->view_dispatcher, 0);
|
|
return true;
|
|
}
|
|
|
|
void usb_mouse_exit_callback(void* context) {
|
|
furi_assert(context);
|
|
UsbMouse* usb_mouse = context;
|
|
|
|
tracking_end();
|
|
|
|
furi_hal_usb_set_config(usb_mouse->usb_mode_prev, NULL);
|
|
}
|
|
|
|
UsbMouse* usb_mouse_alloc(ViewDispatcher* view_dispatcher) {
|
|
UsbMouse* usb_mouse = malloc(sizeof(UsbMouse));
|
|
usb_mouse->view = view_alloc();
|
|
usb_mouse->view_dispatcher = view_dispatcher;
|
|
view_set_context(usb_mouse->view, usb_mouse);
|
|
view_set_draw_callback(usb_mouse->view, usb_mouse_draw_callback);
|
|
view_set_input_callback(usb_mouse->view, usb_mouse_input_callback);
|
|
view_set_enter_callback(usb_mouse->view, usb_mouse_enter_callback);
|
|
view_set_custom_callback(usb_mouse->view, usb_mouse_custom_callback);
|
|
view_set_exit_callback(usb_mouse->view, usb_mouse_exit_callback);
|
|
return usb_mouse;
|
|
}
|
|
|
|
void usb_mouse_free(UsbMouse* usb_mouse) {
|
|
furi_assert(usb_mouse);
|
|
view_free(usb_mouse->view);
|
|
free(usb_mouse);
|
|
}
|
|
|
|
View* usb_mouse_get_view(UsbMouse* usb_mouse) {
|
|
furi_assert(usb_mouse);
|
|
return usb_mouse->view;
|
|
}
|