These were moved to their own repos, and are now included in keyboardio-libraries, which in turn is included in Arduino-Boards. As such, remove the libraries from the core firmware. Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>pull/85/head
parent
743c6e45d3
commit
f721cac732
@ -1,10 +0,0 @@
|
|||||||
name=Keyboardio-Macros
|
|
||||||
version=0.0.1
|
|
||||||
author=Jesse Vincent
|
|
||||||
maintainer=Jesse Vincent <jesse@keyboard.io>
|
|
||||||
sentence=Macro keys for Keyboardio boards.
|
|
||||||
paragraph=...
|
|
||||||
category=Communication
|
|
||||||
url=https://github.com/keyboardio/KeyboardioFirmware
|
|
||||||
architectures=avr
|
|
||||||
dot_a_linkage=true
|
|
@ -1,68 +0,0 @@
|
|||||||
#include "Keyboardio-Macros.h"
|
|
||||||
|
|
||||||
__attribute__((weak))
|
|
||||||
const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
|
|
||||||
return MACRO_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Macros_::play(const macro_t *macro_p) {
|
|
||||||
macro_t macro = END;
|
|
||||||
uint8_t interval = 0;
|
|
||||||
Key key;
|
|
||||||
|
|
||||||
if (!macro_p)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
switch (macro = pgm_read_byte(macro_p++)) {
|
|
||||||
case MACRO_ACTION_STEP_INTERVAL:
|
|
||||||
interval = pgm_read_byte(macro_p++);
|
|
||||||
break;
|
|
||||||
case MACRO_ACTION_STEP_WAIT: {
|
|
||||||
uint8_t wait = pgm_read_byte(macro_p++);
|
|
||||||
delay(wait);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MACRO_ACTION_STEP_KEYDOWN:
|
|
||||||
key.flags = pgm_read_byte(macro_p++);
|
|
||||||
key.keyCode = pgm_read_byte(macro_p++);
|
|
||||||
handle_key_event(key, 255, 255, IS_PRESSED | INJECTED);
|
|
||||||
Keyboard.sendReport();
|
|
||||||
break;
|
|
||||||
case MACRO_ACTION_STEP_KEYUP:
|
|
||||||
key.flags = pgm_read_byte(macro_p++);
|
|
||||||
key.keyCode = pgm_read_byte(macro_p++);
|
|
||||||
handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED);
|
|
||||||
Keyboard.sendReport();
|
|
||||||
break;
|
|
||||||
case END:
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(interval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) {
|
|
||||||
if (mappedKey.flags != (SYNTHETIC | IS_MACRO))
|
|
||||||
return mappedKey;
|
|
||||||
|
|
||||||
if (!key_toggled_on(keyState))
|
|
||||||
return Key_NoKey;
|
|
||||||
|
|
||||||
const macro_t *m = macroAction(mappedKey.keyCode, keyState);
|
|
||||||
|
|
||||||
Macros.play(m);
|
|
||||||
return Key_NoKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
Macros_::Macros_ (void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Macros_::begin (void) {
|
|
||||||
event_handler_hook_add (handleMacroEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Macros_ Macros;
|
|
@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <KeyboardioFirmware.h>
|
|
||||||
|
|
||||||
#include "MacroKeyDefs.h"
|
|
||||||
#include "MacroSteps.h"
|
|
||||||
|
|
||||||
const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState);
|
|
||||||
|
|
||||||
class Macros_ : public KeyboardioPlugin {
|
|
||||||
public:
|
|
||||||
Macros_(void);
|
|
||||||
|
|
||||||
virtual void begin(void) final;
|
|
||||||
|
|
||||||
void play(const macro_t *macro_p);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Macros_ Macros;
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define IS_MACRO B00100000
|
|
||||||
|
|
||||||
#define M(n) (Key){ KEY_FLAGS|SYNTHETIC|IS_MACRO, n}
|
|
||||||
#define Key_macroKey1 M(1)
|
|
||||||
#define Key_macroKey2 M(2)
|
|
||||||
#define Key_macroKey3 M(3)
|
|
||||||
#define Key_macroKey4 M(4)
|
|
||||||
#define Key_macroKey5 M(5)
|
|
||||||
#define Key_macroKey6 M(6)
|
|
||||||
#define Key_macroKey7 M(7)
|
|
||||||
#define Key_macroKey8 M(8)
|
|
||||||
#define Key_macroKey9 M(9)
|
|
||||||
#define Key_macroKey10 M(10)
|
|
@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
MACRO_ACTION_END,
|
|
||||||
|
|
||||||
MACRO_ACTION_STEP_INTERVAL,
|
|
||||||
MACRO_ACTION_STEP_WAIT,
|
|
||||||
MACRO_ACTION_STEP_KEYDOWN,
|
|
||||||
MACRO_ACTION_STEP_KEYUP,
|
|
||||||
} MacroActionStepType;
|
|
||||||
|
|
||||||
typedef uint8_t macro_t;
|
|
||||||
|
|
||||||
#define MACRO_NONE 0
|
|
||||||
#define MACRO(...) ({static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
|
|
||||||
#define MACRODOWN(...) (key_toggled_on(keyState) ? MACRO(__VA_ARGS__) : MACRO_NONE)
|
|
||||||
|
|
||||||
#define I(n) MACRO_ACTION_STEP_INTERVAL, n
|
|
||||||
#define W(n) MACRO_ACTION_STEP_WAIT, n
|
|
||||||
#define Dr(k) MACRO_ACTION_STEP_KEYDOWN, (k).flags, (k).keyCode
|
|
||||||
#define D(k) Dr(Key_ ## k)
|
|
||||||
#define Ur(k) MACRO_ACTION_STEP_KEYUP, (k).flags, (k).keyCode
|
|
||||||
#define U(k) Ur(Key_ ## k)
|
|
||||||
#define Tr(k) Dr(k), Ur(k)
|
|
||||||
#define T(k) D(k), U(k)
|
|
||||||
#define END MACRO_ACTION_END
|
|
@ -1,10 +0,0 @@
|
|||||||
name=Keyboardio-MouseKeys
|
|
||||||
version=0.0.1
|
|
||||||
author=Jesse Vincent
|
|
||||||
maintainer=Jesse Vincent <jesse@keyboard.io>
|
|
||||||
sentence=Mouse keys for Keyboardio boards.
|
|
||||||
paragraph=...
|
|
||||||
category=Communication
|
|
||||||
url=https://github.com/keyboardio/KeyboardioFirmware
|
|
||||||
architectures=avr
|
|
||||||
dot_a_linkage=true
|
|
@ -1,68 +0,0 @@
|
|||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
#include "Keyboardio-MouseKeys.h"
|
|
||||||
#include "MouseWrapper.h"
|
|
||||||
#include "KeyboardioFirmware.h"
|
|
||||||
|
|
||||||
static void handle_mouse_key_event(Key mappedKey, uint8_t keyState) {
|
|
||||||
if (key_toggled_off(keyState)) {
|
|
||||||
if (mappedKey.keyCode & KEY_MOUSE_UP || mappedKey.keyCode & KEY_MOUSE_DOWN) {
|
|
||||||
MouseWrapper.mouseActiveForCyclesY=0;
|
|
||||||
}
|
|
||||||
if (mappedKey.keyCode & KEY_MOUSE_LEFT || mappedKey.keyCode & KEY_MOUSE_RIGHT) {
|
|
||||||
MouseWrapper.mouseActiveForCyclesX=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key_is_pressed(keyState))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mappedKey.keyCode & KEY_MOUSE_UP) {
|
|
||||||
MouseWrapper.move(0,-1);
|
|
||||||
} else if (mappedKey.keyCode & KEY_MOUSE_DOWN) {
|
|
||||||
MouseWrapper.move(0,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mappedKey.keyCode & KEY_MOUSE_LEFT) {
|
|
||||||
MouseWrapper.move(-1,0);
|
|
||||||
} else if (mappedKey.keyCode & KEY_MOUSE_RIGHT) {
|
|
||||||
MouseWrapper.move(1,0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Key handleMouseKeys(Key mappedKey, byte row, byte col, uint8_t keyState) {
|
|
||||||
if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY))
|
|
||||||
return mappedKey;
|
|
||||||
|
|
||||||
if (mappedKey.keyCode & KEY_MOUSE_BUTTON) {
|
|
||||||
uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON;
|
|
||||||
|
|
||||||
if (key_toggled_on(keyState)) {
|
|
||||||
MouseWrapper.press_button(button);
|
|
||||||
} else if (key_toggled_off(keyState)) {
|
|
||||||
MouseWrapper.release_button(button);
|
|
||||||
}
|
|
||||||
} else if (!(mappedKey.keyCode & KEY_MOUSE_WARP)) {
|
|
||||||
handle_mouse_key_event(mappedKey, keyState);
|
|
||||||
} else if (key_toggled_on(keyState)) {
|
|
||||||
if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) {
|
|
||||||
// we don't pass in the left and up values because those are the
|
|
||||||
// default, "no-op" conditionals
|
|
||||||
MouseWrapper.warp( ((mappedKey.keyCode & KEY_MOUSE_WARP_END) ? WARP_END : 0x00) |
|
|
||||||
((mappedKey.keyCode & KEY_MOUSE_DOWN) ? WARP_DOWN : 0x00) |
|
|
||||||
((mappedKey.keyCode & KEY_MOUSE_RIGHT) ? WARP_RIGHT : 0x00) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Key_NoKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseKeys_::MouseKeys_(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MouseKeys_::begin (void) {
|
|
||||||
event_handler_hook_add (handleMouseKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseKeys_ MouseKeys;
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "KeyboardioFirmware.h"
|
|
||||||
#include "MouseKeyDefs.h"
|
|
||||||
|
|
||||||
class MouseKeys_ : public KeyboardioPlugin {
|
|
||||||
public:
|
|
||||||
MouseKeys_ (void);
|
|
||||||
|
|
||||||
virtual void begin(void) final;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern MouseKeys_ MouseKeys;
|
|
@ -1,41 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define IS_MOUSE_KEY B00010000
|
|
||||||
|
|
||||||
// Synthetic, not internal
|
|
||||||
#define KEY_MOUSE_BTN_L 0x01 // Synthetic key
|
|
||||||
#define KEY_MOUSE_BTN_M 0x02 // Synthetic key
|
|
||||||
#define KEY_MOUSE_BTN_R 0x03 // Synthetic key
|
|
||||||
|
|
||||||
|
|
||||||
#define KEY_MOUSE_UP B0000001
|
|
||||||
#define KEY_MOUSE_DOWN B0000010
|
|
||||||
#define KEY_MOUSE_LEFT B0000100
|
|
||||||
#define KEY_MOUSE_RIGHT B0001000
|
|
||||||
#define KEY_MOUSE_BUTTON B0010000
|
|
||||||
#define KEY_MOUSE_WARP B0100000
|
|
||||||
#define KEY_MOUSE_WARP_END B1000000
|
|
||||||
|
|
||||||
|
|
||||||
#define Key_mouseWarpNW (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT }
|
|
||||||
#define Key_mouseWarpNE (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_RIGHT }
|
|
||||||
#define Key_mouseWarpSW (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_LEFT }
|
|
||||||
#define Key_mouseWarpSE (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT }
|
|
||||||
#define Key_mouseWarpEnd (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_WARP_END}
|
|
||||||
|
|
||||||
|
|
||||||
#define Key_mouseUpL (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_UP | KEY_MOUSE_LEFT }
|
|
||||||
#define Key_mouseUp (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_UP }
|
|
||||||
#define Key_mouseUpR (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_UP | KEY_MOUSE_RIGHT }
|
|
||||||
#define Key_mouseL (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_LEFT }
|
|
||||||
#define Key_mouseR (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_RIGHT }
|
|
||||||
#define Key_mouseDnL (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_DOWN | KEY_MOUSE_LEFT }
|
|
||||||
#define Key_mouseDn (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_DOWN }
|
|
||||||
#define Key_mouseDnR (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT }
|
|
||||||
#define Key_mouseScrollUp
|
|
||||||
#define Key_mouseScrollDn
|
|
||||||
#define Key_mouseScrollL
|
|
||||||
#define Key_mouseScrollR
|
|
||||||
#define Key_mouseBtnL (Key){ KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY, KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_L }
|
|
||||||
#define Key_mouseBtnM (Key){ KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY, KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_M }
|
|
||||||
#define Key_mouseBtnR (Key){ KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY, KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_R }
|
|
@ -1,120 +0,0 @@
|
|||||||
|
|
||||||
// Mouse-related methods
|
|
||||||
//
|
|
||||||
//
|
|
||||||
#include "MouseWrapper.h"
|
|
||||||
|
|
||||||
|
|
||||||
MouseWrapper_::MouseWrapper_(void) {
|
|
||||||
Mouse.begin();
|
|
||||||
AbsoluteMouse.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseWrapper_::press_button(uint8_t button) {
|
|
||||||
Mouse.press(button);
|
|
||||||
end_warping();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseWrapper_::release_button(uint8_t button) {
|
|
||||||
Mouse.release(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MouseWrapper_::warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width) {
|
|
||||||
uint16_t x_center = left + width/2;
|
|
||||||
uint16_t y_center = top + height/2;
|
|
||||||
AbsoluteMouse.moveTo(x_center,y_center);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MouseWrapper_::begin_warping() {
|
|
||||||
section_left = WARP_ABS_LEFT;
|
|
||||||
section_top = WARP_ABS_TOP;
|
|
||||||
next_width = MAX_WARP_WIDTH;
|
|
||||||
next_height = MAX_WARP_HEIGHT;
|
|
||||||
is_warping = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseWrapper_::end_warping() {
|
|
||||||
is_warping= false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseWrapper_::warp(uint8_t warp_cmd) {
|
|
||||||
if (is_warping == false) {
|
|
||||||
begin_warping();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( warp_cmd & WARP_END) {
|
|
||||||
end_warping();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
next_width = next_width / 2;
|
|
||||||
next_height = next_height/2;
|
|
||||||
|
|
||||||
if (warp_cmd & WARP_UP) {
|
|
||||||
// Serial.print(" - up ");
|
|
||||||
} else if (warp_cmd & WARP_DOWN) {
|
|
||||||
// Serial.print(" - down ");
|
|
||||||
section_top = section_top + next_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (warp_cmd & WARP_LEFT) {
|
|
||||||
// Serial.print(" - left ");
|
|
||||||
} else if (warp_cmd & WARP_RIGHT) {
|
|
||||||
// Serial.print(" - right ");
|
|
||||||
section_left = section_left + next_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
warp_jump(section_left, section_top, next_height,next_width);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// cubic wave function based on code from FastLED
|
|
||||||
uint8_t MouseWrapper_::acceleration(uint8_t cycles) {
|
|
||||||
uint8_t i = cycles;
|
|
||||||
|
|
||||||
if( i & 0x80) {
|
|
||||||
i = 255 - i;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = i << 1;
|
|
||||||
|
|
||||||
uint8_t ii = (i*i) >> 8;
|
|
||||||
uint8_t iii = (ii*i) >> 8;
|
|
||||||
|
|
||||||
i = (( (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii))) / 2) + ACCELERATION_FLOOR;
|
|
||||||
|
|
||||||
if ( i > ACCELERATION_CEIL) {
|
|
||||||
i = ACCELERATION_CEIL;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MouseWrapper_::move( int8_t x, int8_t y) {
|
|
||||||
int16_t moveX =0;
|
|
||||||
int16_t moveY = 0;
|
|
||||||
if (x != 0 ) {
|
|
||||||
if (mouseActiveForCyclesX < 255) { mouseActiveForCyclesX++;}
|
|
||||||
moveX = (x * acceleration(mouseActiveForCyclesX));
|
|
||||||
}
|
|
||||||
if (y != 0) {
|
|
||||||
if (mouseActiveForCyclesY < 255) { mouseActiveForCyclesY++;}
|
|
||||||
moveY = (y * acceleration(mouseActiveForCyclesY));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
end_warping();
|
|
||||||
Mouse.move(moveX, moveY, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseWrapper_ MouseWrapper;
|
|
@ -1,56 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "KeyboardioHID.h"
|
|
||||||
|
|
||||||
// Warping commands
|
|
||||||
|
|
||||||
#define WARP_END 1
|
|
||||||
#define WARP_UP 2
|
|
||||||
#define WARP_DOWN 4
|
|
||||||
#define WARP_LEFT 8
|
|
||||||
#define WARP_RIGHT 16
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// apparently, the mac discards 15% of the value space for mouse movement.
|
|
||||||
// need to test this on other platforms
|
|
||||||
|
|
||||||
#define MAX_WARP_WIDTH 32767
|
|
||||||
#define MAX_WARP_HEIGHT 32767
|
|
||||||
|
|
||||||
#define WARP_ABS_TOP 0
|
|
||||||
#define WARP_ABS_LEFT 0
|
|
||||||
|
|
||||||
// Mouse acceleration
|
|
||||||
|
|
||||||
// we want the whole s curve, not just the bit
|
|
||||||
// that's usually above the x and y axes;
|
|
||||||
#define ACCELERATION_FLOOR 2
|
|
||||||
#define ACCELERATION_CEIL 50
|
|
||||||
|
|
||||||
|
|
||||||
class MouseWrapper_ {
|
|
||||||
public:
|
|
||||||
MouseWrapper_(void);
|
|
||||||
void move( int8_t x, int8_t y);
|
|
||||||
void warp(uint8_t warp_cmd);
|
|
||||||
void press_button(uint8_t button);
|
|
||||||
void release_button(uint8_t button);
|
|
||||||
uint8_t mouseActiveForCyclesX = 0;
|
|
||||||
uint8_t mouseActiveForCyclesY = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint16_t next_width = 0;
|
|
||||||
uint16_t next_height = 0;
|
|
||||||
uint16_t section_top = 0;
|
|
||||||
uint16_t section_left = 0;
|
|
||||||
boolean is_warping = false;
|
|
||||||
|
|
||||||
uint8_t acceleration (uint8_t cycles);
|
|
||||||
void begin_warping();
|
|
||||||
void end_warping();
|
|
||||||
void warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width);
|
|
||||||
|
|
||||||
};
|
|
||||||
extern MouseWrapper_ MouseWrapper;
|
|
Loading…
Reference in new issue