259 lines
5.7 KiB
C++
259 lines
5.7 KiB
C++
#include <Keyboard.h>
|
|
#include <Mouse.h>
|
|
#include <SoftwareSerial.h>
|
|
|
|
// Setup ---------------------------------------------
|
|
|
|
int SoftSerialRX = 8;
|
|
int SoftSerialTX = 9;
|
|
|
|
// Types ---------------------------------------------
|
|
|
|
#define KEY_F13 0xF0 // 0x68 + 0x88
|
|
#define KEY_F14 0xF1 // 0x69 + 0x88
|
|
#define KEY_F15 0xF2 // 0x6A + 0x88
|
|
#define KEY_F16 0xF3 // 0x6B + 0x88
|
|
#define KEY_F17 0xF4 // 0x6C + 0x88
|
|
#define KEY_F18 0xF5 // 0x6D + 0x88
|
|
|
|
#define key_timeout 100
|
|
|
|
enum parse_mode{
|
|
none,
|
|
regular_key,
|
|
special_key,
|
|
trackball_x,
|
|
trackball_y,
|
|
trackball_key
|
|
};
|
|
|
|
// Globals -------------------------------------------
|
|
|
|
parse_mode ParseMode;
|
|
SoftwareSerial KeyboardSerial(SoftSerialRX, SoftSerialTX);
|
|
unsigned long TrackballY;
|
|
unsigned long TrackballX;
|
|
bool shift;
|
|
bool mouse_left;
|
|
bool mouse_middle;
|
|
bool mouse_right;
|
|
unsigned long time_since_last_key;
|
|
|
|
// Functions -----------------------------------------
|
|
|
|
void setup() {
|
|
digitalWrite(SoftSerialTX, HIGH);
|
|
pinMode(SoftSerialRX, INPUT);
|
|
pinMode(SoftSerialTX, OUTPUT);
|
|
Serial.begin(2400);
|
|
Keyboard.begin();
|
|
Mouse.begin();
|
|
ParseMode = parse_mode::none;
|
|
KeyboardSerial.begin(2400);
|
|
while (!Serial) {
|
|
;
|
|
}
|
|
TrackballX = 0;
|
|
TrackballY = 0;
|
|
shift = false;
|
|
mouse_left = false;
|
|
mouse_right = false;
|
|
mouse_middle = false;
|
|
time_since_last_key = millis();
|
|
}
|
|
|
|
void parseRegularKey(unsigned long v)
|
|
{
|
|
char result;
|
|
bool parsed = false;
|
|
if ((v & 32) == 32)
|
|
{
|
|
shift = true;
|
|
}
|
|
else
|
|
{
|
|
shift = false;
|
|
}
|
|
if (v <= 126)
|
|
{ // main keyboard
|
|
result = v;
|
|
parsed = true;
|
|
}
|
|
// A few keys that need some adjustments to match their label.
|
|
if (v == 13) result = '\n';
|
|
if (v == 94) result = '^';
|
|
if (v == 126) result = '~';
|
|
// tab
|
|
if (v == 129){ result = 9; shift = false; parsed = true; }
|
|
// shift+tab
|
|
if (v == 130)
|
|
{
|
|
Keyboard.press(KEY_LEFT_SHIFT);
|
|
Keyboard.press(KEY_TAB);
|
|
parsed = false;
|
|
}
|
|
if (parsed == true)
|
|
{
|
|
Keyboard.print(result);
|
|
}
|
|
}
|
|
|
|
void parseSpecialKey(unsigned long v)
|
|
{
|
|
switch(v)
|
|
{
|
|
case 49:
|
|
Keyboard.press(KEY_HOME);
|
|
break;
|
|
case 50: // insert line
|
|
Keyboard.write(KEY_HOME);
|
|
Keyboard.write(KEY_RETURN);
|
|
Keyboard.write(KEY_UP_ARROW);
|
|
break;
|
|
case 51: // delete line (using the vim way for this)
|
|
// non-vim people might want to do:
|
|
// END-SHIFT-HOME-BS or something...
|
|
Keyboard.write(KEY_ESC);
|
|
Keyboard.write('d');
|
|
Keyboard.write('d');
|
|
Keyboard.write('i');
|
|
break;
|
|
case 53: // insert char - using this as regular insert.
|
|
Keyboard.write(KEY_INSERT);
|
|
break;
|
|
case 54: // delete char - using this as regular delete.
|
|
Keyboard.write(KEY_DELETE);
|
|
break;
|
|
case 48: // up / down arrow (they send the same keycode?!)
|
|
Keyboard.write(KEY_UP_ARROW);
|
|
break;
|
|
case 120:
|
|
Keyboard.write(KEY_RIGHT_ARROW);
|
|
break;
|
|
case 126:
|
|
Keyboard.write(KEY_LEFT_ARROW);
|
|
break;
|
|
}
|
|
// F1..F12
|
|
if ((v >= 86) && (v <= 97))
|
|
{
|
|
Keyboard.write(v + 108);
|
|
}
|
|
if (v == 98) Keyboard.write(KEY_F13);
|
|
if (v == 99) Keyboard.write(KEY_F14);
|
|
if (v == 100) Keyboard.write(KEY_F14);
|
|
// the 'cancel' key we'll use as ESC key, since there
|
|
// is no actual key labeled escape.
|
|
if (v == 101) Keyboard.write(KEY_ESC);
|
|
}
|
|
|
|
void parse_trackball(unsigned long x, unsigned long y)
|
|
{
|
|
Mouse.move(x, -y);
|
|
}
|
|
|
|
void parse_trackball_key(unsigned long v)
|
|
{
|
|
switch(v)
|
|
{
|
|
case 0x40: // T1 key
|
|
Mouse.press(MOUSE_LEFT);
|
|
mouse_left = true;
|
|
//Serial.println("Pressed left mouse");
|
|
break;
|
|
case 0x41: // T2 key
|
|
Mouse.press(MOUSE_MIDDLE);
|
|
//Serial.println("Pressed middle mouse");
|
|
mouse_middle = true;
|
|
break;
|
|
case 0x42: // T3 key
|
|
Mouse.press(MOUSE_RIGHT);
|
|
//Serial.println("Pressed right mouse");
|
|
mouse_right = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void detect_key_release()
|
|
{
|
|
if ((millis() - time_since_last_key) > key_timeout)
|
|
{
|
|
Keyboard.releaseAll();
|
|
if (mouse_right == true)
|
|
{
|
|
Mouse.release(MOUSE_RIGHT);
|
|
mouse_right = false;
|
|
//Serial.println("Released right mouse");
|
|
}
|
|
if (mouse_left == true)
|
|
{
|
|
Mouse.release(MOUSE_LEFT);
|
|
mouse_left = false;
|
|
//Serial.println("Released left mouse");
|
|
}
|
|
if (mouse_middle == true)
|
|
{
|
|
Mouse.release(MOUSE_MIDDLE);
|
|
mouse_middle = false;
|
|
//Serial.println("Released middle mouse");
|
|
}
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
KeyboardSerial.listen();
|
|
if (KeyboardSerial.available())
|
|
{
|
|
unsigned long v = KeyboardSerial.read();
|
|
switch (v)
|
|
{
|
|
case 0xA8:
|
|
ParseMode = parse_mode::regular_key;
|
|
Serial.println("Regular key");
|
|
break;
|
|
case 0xA1:
|
|
ParseMode = parse_mode::special_key;
|
|
Serial.println("Special key");
|
|
break;
|
|
case 0xA2:
|
|
ParseMode = parse_mode::trackball_x;
|
|
break;
|
|
case 0xA4:
|
|
ParseMode = parse_mode::trackball_key;
|
|
break;
|
|
default:
|
|
if (ParseMode == parse_mode::regular_key)
|
|
{
|
|
parseRegularKey(v);
|
|
}
|
|
else if (ParseMode == parse_mode::special_key)
|
|
{
|
|
parseSpecialKey(v);
|
|
}
|
|
else if (ParseMode == parse_mode::trackball_x)
|
|
{
|
|
TrackballX = v;
|
|
ParseMode = parse_mode::trackball_y;
|
|
}
|
|
else if (ParseMode == parse_mode::trackball_y)
|
|
{
|
|
TrackballY = v;
|
|
ParseMode = parse_mode::none;
|
|
parse_trackball(TrackballX, TrackballY);
|
|
}
|
|
else if (ParseMode == parse_mode::trackball_key)
|
|
{
|
|
parse_trackball_key(v);
|
|
}
|
|
break;
|
|
}
|
|
//Serial.println(v, BIN);
|
|
//Serial.println(v, HEX);
|
|
time_since_last_key = millis();
|
|
}
|
|
else
|
|
{
|
|
detect_key_release();
|
|
}
|
|
}
|