Added mouse support \o/

This commit is contained in:
Spacehuhn 2022-07-20 23:32:13 +02:00
parent 2a9740d627
commit e2fe5400f5
6 changed files with 157 additions and 17 deletions

View File

@ -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 <Arduino.h> // 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; i<len; ++i) {
for (size_t i = 0; i<len; ++i) {
i += keyboard::write(&str[i]);
if(i%10==0) tasks::update();
if (i%10==0) tasks::update();
}
}
@ -113,7 +116,16 @@ namespace duckparser {
keyboard::release();
}
unsigned int toInt(const char* str, size_t len) {
int to_int(const char* str, size_t len) {
char newstr[len+1];
memcpy(newstr, (void*)str, len);
newstr[len+1] = '\0';
return atoi(newstr);
}
unsigned int to_uint(const char* str, size_t len) {
if (!str || (len == 0)) return 0;
unsigned int val = 0;
@ -233,12 +245,12 @@ namespace duckparser {
}
// default_delay/DEFAULT_DELAY (set default delay per command)
else if (compare(cmd->str, 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);

View File

@ -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;

View File

@ -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();

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -2,6 +2,25 @@
#pragma once
#include <cstdint> // 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);
}