pip 0.4.0_r5 stable
git-svn-id: svn://db.shs.com.ru/pip@1 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
168
pikbdlistener.cpp
Normal file
168
pikbdlistener.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Keyboard grabber for console
|
||||
Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pikbdlistener.h"
|
||||
|
||||
|
||||
/** \class PIKbdListener
|
||||
* \brief Keyboard console input listener
|
||||
* \details This class provide listening of console keyboard input.
|
||||
* There is two ways to receive pressed key:
|
||||
* * external static functionwith format "void func(char key, void * data_)"
|
||||
* * event \a keyPressed()
|
||||
*
|
||||
* Also there is static variable \a exiting which by default is set to
|
||||
* \b false. If \a enableExitCapture() was called and listener was started
|
||||
* with function \a start(), this variable will be set to \b true if exit
|
||||
* key will be pressed. By default exit key is 'Q' = shift + 'q'.
|
||||
* To wait for this variable changes to \b true there is WAIT_FOR_EXIT macro
|
||||
* \snippet pikbdlistener.cpp main
|
||||
* */
|
||||
|
||||
|
||||
bool PIKbdListener::exiting;
|
||||
|
||||
PIKbdListener::PIKbdListener(KBFunc slot, void * _data): PIThread() {
|
||||
#ifdef WINDOWS
|
||||
hIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
GetConsoleMode(hIn, &smode);
|
||||
#else
|
||||
struct termios term;
|
||||
tcgetattr(0, &term);
|
||||
sterm = term;
|
||||
#endif
|
||||
is_active = true;
|
||||
ret_func = slot;
|
||||
data_ = _data;
|
||||
PIKbdListener::exiting = exit_enabled = false;
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
void PIKbdListener::begin() {
|
||||
//cout << "list begin" << endl;
|
||||
#ifdef WINDOWS
|
||||
GetConsoleMode(hIn, &tmode);
|
||||
SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT);
|
||||
#else
|
||||
struct termios term;
|
||||
tcgetattr(0, &term);
|
||||
term.c_lflag &= ~(ECHO | ICANON) | NOFLSH;
|
||||
tterm = term;
|
||||
tcsetattr(0, TCSAFLUSH, &term);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIKbdListener::run() {
|
||||
rc = 0;
|
||||
char lc = 0;
|
||||
#ifdef WINDOWS
|
||||
INPUT_RECORD ir;
|
||||
ReadConsoleInput(hIn, &ir, 1, &ret);
|
||||
if (ir.EventType == KEY_EVENT) {
|
||||
KEY_EVENT_RECORD ker = ir.Event.KeyEvent;
|
||||
if (ker.bKeyDown) {
|
||||
bool ctrl = ((ker.dwControlKeyState & LEFT_CTRL_PRESSED) || (ker.dwControlKeyState & RIGHT_CTRL_PRESSED));
|
||||
bool shift = (ker.dwControlKeyState & SHIFT_PRESSED);
|
||||
if (ker.dwControlKeyState & CAPSLOCK_ON) shift = !shift;
|
||||
//cout << "key " << int(ker.wVirtualKeyCode) << endl;
|
||||
switch (ker.wVirtualKeyCode) {
|
||||
case 37: ret = 1; lc = (ctrl ? CtrlLeftArrow : LeftArrow); break;
|
||||
case 38: ret = 1; lc = (ctrl ? CtrlUpArrow : UpArrow); break;
|
||||
case 39: ret = 1; lc = (ctrl ? CtrlRightArrow : RightArrow); break;
|
||||
case 40: ret = 1; lc = (ctrl ? CtrlDownArrow : DownArrow); break;
|
||||
default: ret = 1; lc = (shift ? char(toupper(ker.uChar.AsciiChar)) : ker.uChar.AsciiChar); break;
|
||||
}
|
||||
if (lc == 0) {piMSleep(10); return;}
|
||||
} else {piMSleep(10); return;}
|
||||
} else {piMSleep(10); return;}
|
||||
/*if (lc == 0) {
|
||||
ReadConsole(hIn, &rc, 1, &ret, 0);
|
||||
//cout << "read console" << endl;
|
||||
lc = char(rc);
|
||||
}*/
|
||||
/*if (ret < 0 || ret > 3) return;
|
||||
lc = char(((uchar * )&rc)[ret - 1]);
|
||||
for (int i = 0; i < ret; ++i)
|
||||
cout << std::hex << int(((uchar * )&rc)[i]) << ' ';
|
||||
cout << endl << std::hex << rc << endl;*/
|
||||
#else
|
||||
ret = read(0, &rc, 4);
|
||||
if (ret < 0 || ret > 3) {piMSleep(10); return;}
|
||||
lc = char(((uchar * )&rc)[ret - 1]);
|
||||
//for (int i = 0; i < ret; ++i)
|
||||
// cout << std::hex << int(((uchar * )&rc)[i]) << ' ';
|
||||
//cout << endl << std::hex << rc << endl;
|
||||
if (((char * )&rc)[0] == '\e' && ret == 3) {
|
||||
if (((char * )&rc)[1] == '[') {
|
||||
switch (((char * )&rc)[2]) {
|
||||
case 'A': lc = UpArrow; break; // up
|
||||
case 'B': lc = DownArrow; break; // down
|
||||
case 'C': lc = RightArrow; break; // right
|
||||
case 'D': lc = LeftArrow; break; // left
|
||||
}
|
||||
}
|
||||
}
|
||||
if (((char * )&rc)[0] == '5' && ret == 2) {
|
||||
switch (((char * )&rc)[1]) {
|
||||
case 'A': lc = CtrlUpArrow; break; // up
|
||||
case 'B': lc = CtrlDownArrow; break; // down
|
||||
case 'C': lc = CtrlRightArrow; break; // right
|
||||
case 'D': lc = CtrlLeftArrow; break; // left
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (exit_enabled && ret == 1 && lc == exit_key) {
|
||||
PIKbdListener::exiting = true;
|
||||
return;
|
||||
}
|
||||
if (ret > 0) {
|
||||
keyPressed(lc, data_);
|
||||
if (ret_func != 0) ret_func(lc, data_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIKbdListener::end() {
|
||||
//cout << "list end" << endl;
|
||||
#ifdef WINDOWS
|
||||
SetConsoleMode(hIn, smode);
|
||||
#else
|
||||
tcsetattr(0, TCSANOW, &sterm);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIKbdListener::setActive(bool yes) {
|
||||
is_active = yes;
|
||||
if (is_active) {
|
||||
#ifdef WINDOWS
|
||||
SetConsoleMode(hIn, tmode);
|
||||
#else
|
||||
tcsetattr(0, TCSANOW, &tterm);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef WINDOWS
|
||||
SetConsoleMode(hIn, smode);
|
||||
#else
|
||||
tcsetattr(0, TCSANOW, &sterm);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user