1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
#include "cInput.h"
cInput::cInput()
{
// Save original serial communication configuration for stdin
tcgetattr( STDIN_FILENO, &original);
// Put stdin in raw mode so keys get through directly without
// requiring pressing enter.
cfmakeraw (&raw);
tcsetattr (STDIN_FILENO, TCSANOW, &raw);
// Enable mouse tracking
write (STDOUT_FILENO, "\e[?1000h", 8);
}
cInput::~cInput()
{
//revert changes to console
write (STDOUT_FILENO, "\e[?1000l", 8);
tcsetattr (STDIN_FILENO, TCSANOW, &original);
}
sInputEvent cInput::poll()
{
const unsigned int buff_len = 5;
sInputEvent ret;
unsigned char buff [buff_len];
//TODO maybe poll()?
//setup for select
fd_set rfds;
struct timeval tv;
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
ret.type = _EVENT_NULL;
//Check for Input. return of none
if(!select(1, &rfds, NULL, NULL, &tv))
return ret;
read (STDIN_FILENO, &buff, 1);
if (buff[0] && buff[0] <= 26) {
//Ctrl keys are 1-26. check with CTRL_KEY( ) Macro
ret.type = _EVENT_CTRL;
ret.c = buff[0];
//To not break compatability
if (buff[0] == CTRL_KEY('c'))
ret.type = _EVENT_TERM;
}
else if (buff[0] == '\x1B') //Escape sequence
{
read (STDIN_FILENO, &buff, buff_len);
if(buff[0] == '[')
{
if(buff[1] == 'M') //Mouse Event
{
ret.b = buff[2] - 32;
ret.x = buff[3] - 32 - 1; //Console sees origin at 1,1
ret.y = buff[4] - 32 - 1; //Program at 0,0
ret.type = _EVENT_MOUSE;
}
else //e.g. Arrow Keys
{
ret.c = buff[1];
ret.type = _EVENT_KEY;
}
}
else if(buff[0] == 'O')
{
ret.c = buff[1];
ret.type = _EVENT_FUNCTION1;
}
}
else
{
ret.type = _EVENT_CHAR;
ret.c = buff[0];
}
return ret;
}
|