|
-
May 13th, 2012, 11:57 AM
#1
Detect arrow key press in c++ for linux only, 80% of the job is done.
Hello all - here is my first post,
I've googled this one to death.
I'm trying to implement this on ubuntu, to compile and run only under ubuntu.
I found 100s of other attempts at answering the general question of arrow key press in c++. Nothing solid.
Some recommend using the Readline for the functionality I am trying to implement, but I need to stay clear of GNU licences if I
can for this project. And some tips only work on projects for windows machines... for example the conio library.
For linux there may be the option of using the ncurses library which I will take a look at, but I am stubborn and want to implement this myself. It should be an easy straight forward thing to do, which is why I am a bit frustrated at the moment.
Here is my test code so far.
My dirty code...
Code:
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
using namespace std;
int main(void)
{
char a;
stringstream ss;
string s;
string s2;
int i;
const char * cs;
// Here I attempt to set stdin to unbuffered, read directly from the keyboard.
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
// I wait and get each key press here, initialise to first keystroke.
a=getchar();
// While enter is not pressed, build a complete string.
while(a != '\n')
{s=s+a;
a=getchar();
ss << a;
ss >> s2;
cs = s2.c_str();
//Here I output the ascii code number each time a key is pressed.
i=cs[0];
cout<< i;
ss.clear();
};
//Restore buffer mode
tcgetattr(STDIN_FILENO, &term);
term.c_lflag |= ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
return 0;
}
So! This works... 80% of the problem is solved.
If you compile this, g++ under linux, ubuntu in my case, and run.
Each keystroke reveals the correct key numbers.
q=113
w=119
when I click on the up key I get,
up = 279165
GREAT! I thought, I can use this number is a if(int == '279165') to detect the up key.
I was not so lucky... this int is not behaving like an int!
So I modified the code to see it I could carry out an int operation on this number.
I added a 100000 to int i.
cout<< i + 100000;
Code:
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
using namespace std;
int main(void)
{
char a;
stringstream ss;
string s;
string s2;
int i;
const char * cs;
// Here I attempt to set stdin to unbuffered, read directly from the keyboard.
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
// I wait and get each key press here, initialise to first keystroke.
a=getchar();
// While enter is not pressed, build a complete string.
while(a != '\n')
{s=s+a;
a=getchar();
ss << a;
ss >> s2;
cs = s2.c_str();
//Here I output the ascii code number each time a key is pressed.
i=cs[0];
cout<< i + 100000;
ss.clear();
};
//Restore buffer mode
tcgetattr(STDIN_FILENO, &term);
term.c_lflag |= ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
return 0;
}
Compiling and running this, and pressing the UP key gives the following number.
100027100091100065
!Ha! Some some sort of array, something like, [27][91][65].
I tried all ways to access these individual numbers, actually the third one for comparison purposes,
but no luck.
For completeness sake I list the other arrows.
UP = [27][91][65]
DOWN = [27][91][66]
LEFT = [27][91][68]
RIGHT = [27][91][67]
A little further digging shows that these numbers are derived from the representation of a "multi-char" constant, the data type
given when pressing special characters...
Now here is the main problem I have, I can find ANY decent documentation on how to handle and
play with "multi-char"
If I had that, I would feel happy.
Any ideas anyone?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|