aiie/opencv/opencv-keyboard.cpp

224 lines
5.2 KiB
C++

#include "opencv-keyboard.h"
/*
* OpenCV doesn't support very sophisticated keyboard interaction.
* You can't query modifier keys; you don't get up-and-down
* events. There's just a simple "has any key been pressed" method.
*/
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/features2d/features2d.hpp"
using namespace cv;
using namespace std;
OpenCVKeyboard::OpenCVKeyboard(VMKeyboard *k) : PhysicalKeyboard(k)
{
}
OpenCVKeyboard::~OpenCVKeyboard()
{
}
typedef struct {
int8_t actualKey;
bool shifted;
} keymapChar;
// keymap starts at space (32), ends at delete (127).
// Note that this maps them based on what the Apple //e expects. It's the
// same as a modern US keyboard.
const keymapChar keymap[96] =
{ { ' ', false }, // space
{ '1', true }, // !
{ '\'', true }, // "
{ '3', true }, // #
{ '4', true }, // $
{ '5', true }, // %
{ '7', true }, // &
{ '\'', false}, // '
{ '9', true }, // (
{ '0', true }, // )
{ '8', true }, // *
{ '=', true }, // +
{ ',', false }, // ,
{ '-', false }, // -
{ '.', false }, // .
{ '/', false }, // /
{ '0', false }, // 0
{ '1', false }, // 1
{ '2', false }, // 2
{ '3', false }, // 3
{ '4', false }, // 4
{ '5', false }, // 5
{ '6', false }, // 6
{ '7', false }, // 7
{ '8', false }, // 8
{ '9', false }, // 9
{ ':', true }, // :
{ ';', false }, // ;
{ ',', true }, // <
{ '=', false }, // =
{ '.', true }, // >
{ '/', true }, // ?
{ '2', true }, // @
{ 'A', true }, // A
{ 'B', true }, // B
{ 'C', true }, // C
{ 'D', true }, // D
{ 'E', true }, // E
{ 'F', true }, // F
{ 'G', true }, // G
{ 'H', true }, // H
{ 'I', true }, // I
{ 'J', true }, // J
{ 'K', true }, // K
{ 'L', true }, // L
{ 'M', true }, // M
{ 'N', true }, // N
{ 'O', true }, // O
{ 'P', true }, // P
{ 'Q', true }, // Q
{ 'R', true }, // R
{ 'S', true }, // S
{ 'T', true }, // T
{ 'U', true }, // U
{ 'V', true }, // V
{ 'W', true }, // W
{ 'X', true }, // X
{ 'Y', true }, // Y
{ 'Z', true }, // Z
#ifndef TEENSYDUINO
{ LA, false }, // [
#else
{ '[', false }, // [
#endif
{ '\\', false}, // \ ...
#ifndef TEENSYDUINO
{ RA, false }, // ]
#else
{ ']', false }, // ]
#endif
{ '6', true }, // ^
{ '-', true }, // _
{ '`', false }, // `
{ 'A', false }, // a
{ 'B', false }, // b
{ 'C', false }, // c
{ 'D', false }, // d
{ 'E', false }, // e
{ 'F', false }, // f
{ 'G', false }, // g
{ 'H', false }, // h
{ 'I', false }, // i
{ 'J', false }, // j
{ 'K', false }, // k
{ 'L', false }, // l
{ 'M', false }, // m
{ 'N', false }, // n
{ 'O', false }, // o
{ 'P', false }, // p
{ 'Q', false }, // q
{ 'R', false }, // r
{ 'S', false }, // s
{ 'T', false }, // t
{ 'U', false }, // u
{ 'V', false }, // v
{ 'W', false }, // w
{ 'X', false }, // x
{ 'Y', false }, // y
{ 'Z', false }, // z
{ '[', true }, // {
{ '\\', true }, // |
{ ']', true }, // }
{ '`', true }, // ~
{ DEL, false } // delete
};
void OpenCVKeyboard::maintainKeyboard()
{
static int invalidCount = 0;
int c = cv::waitKey(1);
// OpenCV relies on KeyRepeat to deliver individual presses. We want
// to guess about "it's still down": so, unless we get > 3 invalid
// "-1" values in a row, we're gonna assume it's still pressed.
if (c == -1) {
invalidCount++;
if (invalidCount < 4) {
return;
}
} else {
invalidCount = 0;
}
if (c == -1) {
if (lastKey >= ' ' && lastKey <= 127) {
vmkeyboard->keyReleased(keymap[lastKey-' '].actualKey);
if (keymap[lastKey-' '].shifted) {
vmkeyboard->keyReleased(LSHFT);
}
} else {
vmkeyboard->keyReleased(lastKey);
}
lastKey = -1;
return;
}
if (c == 0xF700) {
c = UARR; // up
} else if (c == 0xF701) {
c = DARR; // down
} else if (c == 0xF702) {
c = LARR; // left
} else if (c == 0xF703) {
c = RARR; // right
}
// If we're already repeating this key, do nothing
if (lastKey != -1 &&
lastKey == c) {
return;
}
// If it's a different key, then do a key up
if (lastKey != -1) {
if (lastKey >= ' ' && lastKey <= 127) {
vmkeyboard->keyReleased(keymap[lastKey-' '].actualKey);
if (keymap[lastKey-' '].shifted) {
vmkeyboard->keyReleased(LSHFT);
}
} else {
vmkeyboard->keyReleased(lastKey);
}
lastKey = -1;
}
// Now it's a new keypress - do a key down
if (c >= ' ' && c <= 127) {
if (keymap[c-' '].shifted) {
vmkeyboard->keyDepressed(LSHFT);
}
vmkeyboard->keyDepressed(keymap[c-' '].actualKey);
lastKey = c;
return;
}
// Any other key that could have been reported:
// ESC RET TAB LA RA LARR RARR DARR UARR
vmkeyboard->keyDepressed(c);
// anything else isn't reported by OpenCV, so we can't report it
// specifically. So these are ignored:
// _CTRL LSHFT RSHFT LOCK LA RA
lastKey = c;
}