diff --git a/src/duckparser/duckparser.cpp b/src/duckparser/duckparser.cpp index 6eec287..92506da 100644 --- a/src/duckparser/duckparser.cpp +++ b/src/duckparser/duckparser.cpp @@ -5,12 +5,15 @@ #include "../../config.h" #include "../../debug.h" #include "../hid/keyboard.h" +#include "../hid/mouse.h" #include "../led/led.h" #include "../tasks/tasks.h" #include // millis(), delay() -#include "parser.h" // parse_lines +#include "parser.h" // parse_lines + +#define TU_BIT(n) (1U << (n)) namespace duckparser { // ====== PRIVATE ===== // @@ -32,9 +35,9 @@ namespace duckparser { unsigned long sleep_time = 0; void type(const char* str, size_t len) { - for (size_t i=0; istr, cmd->len, "default_delay", CASE_SENSETIVE) || compare(cmd->str, cmd->len, "DEFAULT_DELAY", CASE_SENSETIVE)) { - default_delay = toInt(line_str, line_str_len); + default_delay = to_uint(line_str, line_str_len); ignore_delay = true; } // DELAY (-> sleep for x ms) else if (compare(cmd->str, cmd->len, "DELAY", CASE_SENSETIVE)) { - sleep(toInt(line_str, line_str_len)); + sleep(to_uint(line_str, line_str_len)); ignore_delay = true; } // STRING (-> type each character) @@ -256,12 +268,12 @@ namespace duckparser { } // REPEAT (-> repeat last command n times) else if (compare(cmd->str, cmd->len, "REPEAT", CASE_SENSETIVE) || compare(cmd->str, cmd->len, "REPLAY", CASE_SENSETIVE)) { - repeat_num = toInt(line_str, line_str_len) + 1; + repeat_num = to_uint(line_str, line_str_len) + 1; ignore_delay = true; } // LOOP_BEGIN else if (compare(cmd->str, cmd->len, "LOOP_BEGIN", CASE_SENSETIVE)) { - loop_num = toInt(line_str, line_str_len); + loop_num = to_uint(line_str, line_str_len); loop_begin = true; ignore_delay = true; } @@ -316,7 +328,7 @@ namespace duckparser { for (uint8_t i = 0; i<4; ++i) { if (w) { - c[i] = toInt(w->str, w->len); + c[i] = to_uint(w->str, w->len); w = w->next; } else { c[i] = 0; @@ -334,12 +346,12 @@ namespace duckparser { if (w) { keyboard::report_t k; - k.modifiers = (uint8_t)toInt(w->str, w->len); + k.modifiers = (uint8_t)to_uint(w->str, w->len); w = w->next; for (uint8_t i = 0; i<6; ++i) { if (w) { - k.keys[i] = (uint8_t)toInt(w->str, w->len); + k.keys[i] = (uint8_t)to_uint(w->str, w->len); w = w->next; } else { k.keys[i] = 0; @@ -350,6 +362,42 @@ namespace duckparser { keyboard::release(); } } + // MOUSE x y, MOVE x y + else if (compare(cmd->str, cmd->len, "MOUSE", CASE_SENSETIVE) || compare(cmd->str, cmd->len, "MOVE", CASE_SENSETIVE)) { + word_node* w = cmd->next; + int x = w ? to_int(w->str, w->len) : 0; + w = w->next; + int y = w ? to_int(w->str, w->len) : 0; + + mouse::move(x, y); + } + // MOUSE_CLICK button, CLICK button + else if (compare(cmd->str, cmd->len, "MOUSE_CLICK", CASE_SENSETIVE) || compare(cmd->str, cmd->len, "CLICK", CASE_SENSETIVE)) { + word_node* w = cmd->next; + int button = TU_BIT(w ? to_uint(w->str, w->len) : 0); + mouse::click(button); + } + // MOUSE_PRESS button, PRESS button + else if (compare(cmd->str, cmd->len, "MOUSE_PRESS", CASE_SENSETIVE) || compare(cmd->str, cmd->len, "PRESS", CASE_SENSETIVE)) { + word_node* w = cmd->next; + int button = TU_BIT(w ? to_uint(w->str, w->len) : 0); + mouse::press(button); + } + // MOUSE_RELEASE button, RELEASE button + else if (compare(cmd->str, cmd->len, "MOUSE_RELEASE", CASE_SENSETIVE) || compare(cmd->str, cmd->len, "RELEASE", CASE_SENSETIVE)) { + word_node* w = cmd->next; + int button = TU_BIT(w ? to_uint(w->str, w->len) : 0); + mouse::release(button); + } + // MOUSE_SCROLL v h, SCROLL v h + else if (compare(cmd->str, cmd->len, "MOUSE_SCROLL", CASE_SENSETIVE) || compare(cmd->str, cmd->len, "SCROLL", CASE_SENSETIVE)) { + word_node* w = cmd->next; + int vertical = w ? to_int(w->str, w->len) : 0; + w = w->next; + int horizontal = w ? to_int(w->str, w->len) : 0; + + mouse::scroll(vertical, horizontal); + } // IMPORT (-> open another script) else if (compare(cmd->str, cmd->len, "IMPORT", CASE_SENSETIVE)) { import_path = std::string(line_str, line_str_len); diff --git a/src/hid/hid.cpp b/src/hid/hid.cpp index 2d7f984..3537415 100644 --- a/src/hid/hid.cpp +++ b/src/hid/hid.cpp @@ -90,6 +90,21 @@ namespace hid { usb_hid.keyboardReport(RID::KEYBOARD, modifier, keys); } + + void sendMouseReport(uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { + if (TinyUSBDevice.suspended()) { + // Wake up host if we are in suspend mode + // and REMOTE_WAKEUP feature is enabled by host + TinyUSBDevice.remoteWakeup(); + } + + // Wait until ready to send next report + while (!usb_hid.ready()){ + delay(1); + } + + usb_hid.mouseReport(RID::MOUSE, buttons, x, y, vertical, horizontal); + } uint8_t getIndicator() { return indicator; diff --git a/src/hid/hid.h b/src/hid/hid.h index eb39ed9..f192891 100644 --- a/src/hid/hid.h +++ b/src/hid/hid.h @@ -17,6 +17,7 @@ namespace hid { bool mounted(); void sendKeyboardReport(uint8_t modifier, uint8_t* keys); + void sendMouseReport(uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); uint8_t getIndicator(); bool indicatorChanged(); diff --git a/src/hid/keyboard.cpp b/src/hid/keyboard.cpp index b2e0a09..9241923 100644 --- a/src/hid/keyboard.cpp +++ b/src/hid/keyboard.cpp @@ -11,9 +11,9 @@ namespace keyboard { report_t prev_report = report_t{ KEY_NONE, { KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE } }; - report_t makeReport(uint8_t modifiers = 0, uint8_t key1 = 0, uint8_t key2 = 0, uint8_t key3 = 0, uint8_t key4 = 0, uint8_t key5 = 0, uint8_t key6 = 0); + report_t make_report(uint8_t modifiers = 0, uint8_t key1 = 0, uint8_t key2 = 0, uint8_t key3 = 0, uint8_t key4 = 0, uint8_t key5 = 0, uint8_t key6 = 0); - report_t makeReport(uint8_t modifiers, uint8_t key1, uint8_t key2, uint8_t key3, uint8_t key4, uint8_t key5, uint8_t key6) { + report_t make_report(uint8_t modifiers, uint8_t key1, uint8_t key2, uint8_t key3, uint8_t key4, uint8_t key5, uint8_t key6) { report_t k; k.modifiers = modifiers; @@ -39,7 +39,7 @@ namespace keyboard { } void release() { - prev_report = makeReport(); + prev_report = make_report(); send(&prev_report); } diff --git a/src/hid/mouse.cpp b/src/hid/mouse.cpp index df18474..9607883 100644 --- a/src/hid/mouse.cpp +++ b/src/hid/mouse.cpp @@ -2,10 +2,67 @@ #include "mouse.h" +#include "hid.h" + namespace mouse { // ====== PRIVATE ====== // - + report_t prev_report = report_t{ 0, 0, 0, 0, 0 }; + + report_t make_report(uint8_t buttons = 0, int8_t x = 0, int8_t y = 0, int8_t vertical = 0, int8_t horizontal = 0); + + report_t make_report(uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { + report_t m; + + m.buttons = buttons; + m.x = x; + m.y = y; + m.vertical = vertical; + m.horizontal = horizontal; + + return m; + } // ====== PUBLIC ====== // - + void send(report_t* m) { + hid::sendMouseReport(m->buttons, m->x, m->y, m->vertical, m->horizontal); + } + + void release() { + prev_report = make_report(); + send(&prev_report); + } + + void move(int8_t x, int8_t y) { + prev_report.x += x; + prev_report.y += y; + + send(&prev_report); + release(); + } + + void click(uint8_t button) { + // Mouse buttons: https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h#L306 + press(button); + release(button); + } + + void press(uint8_t button) { + prev_report.buttons |= button; + + send(&prev_report); + } + + void release(uint8_t button) { + prev_report.buttons &= ~button; + + send(&prev_report); + } + + void scroll(int8_t vertical, int8_t horizontal) { + prev_report.vertical += vertical; + prev_report.horizontal += horizontal; + + send(&prev_report); + release(); + } } \ No newline at end of file diff --git a/src/hid/mouse.h b/src/hid/mouse.h index 81dcc5b..ee713f6 100644 --- a/src/hid/mouse.h +++ b/src/hid/mouse.h @@ -2,6 +2,25 @@ #pragma once +#include // uint8_t + namespace mouse { - + typedef struct report_t { + uint8_t buttons; + int8_t x; + int8_t y; + int8_t vertical; + int8_t horizontal; + } report_t; + + void send(report_t* m); + void release(); + + void move(int8_t x, int8_t y); + + void click(uint8_t button); + void press(uint8_t button); + void release(uint8_t button); + + void scroll(int8_t vertical, int8_t horizontal); } \ No newline at end of file