Check keypress in C++ on Linux
11,367
Solution 1
I find a simpler way:
#include <X11/Xlib.h>
#include <iostream>
#include "X11/keysym.h"
/**
*
* @param ks like XK_Shift_L, see /usr/include/X11/keysymdef.h
* @return
*/
bool key_is_pressed(KeySym ks) {
Display *dpy = XOpenDisplay(":0");
char keys_return[32];
XQueryKeymap(dpy, keys_return);
KeyCode kc2 = XKeysymToKeycode(dpy, ks);
bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)));
XCloseDisplay(dpy);
return isPressed;
}
bool ctrl_is_pressed() {
return key_is_pressed(XK_Control_L) || key_is_pressed(XK_Control_R);
}
int main(int argc, char **argv) {
std::cout << ctrl_is_pressed() << std::endl;
return (0);
};
Solution 2
Try this:-
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
int main()
{
struct termios oldSettings, newSettings;
tcgetattr( fileno( stdin ), &oldSettings );
newSettings = oldSettings;
newSettings.c_lflag &= (~ICANON & ~ECHO);
tcsetattr( fileno( stdin ), TCSANOW, &newSettings );
while ( 1 )
{
fd_set set;
struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;
FD_ZERO( &set );
FD_SET( fileno( stdin ), &set );
int res = select( fileno( stdin )+1, &set, NULL, NULL, &tv );
if( res > 0 )
{
char c;
printf( "Input available\n" );
read( fileno( stdin ), &c, 1 );
}
else if( res < 0 )
{
perror( "select error" );
break;
}
else
{
printf( "Select timeout\n" );
}
}
tcsetattr( fileno( stdin ), TCSANOW, &oldSettings );
return 0;
}
From here
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Author by
Admin
Updated on July 24, 2022Comments
-
Admin almost 2 years
Is there an easy way to check if a key is being pressed so I can loop through that in a thread? Preferred not to use a library and definitely not ncurses. There isn't a single thing working that I have found over the internet.
-
JimR almost 11 yearscommonly known as kbhit in windows!os/2!dos land. Keep in mind you have to get the key or this will continue to report there's a keypress available. Call getch() when this indicates a key is ready.
-
domsson over 3 yearsNice, but I assume this will only work if you're in an X environment (in other words, won't work on a pure tty or under Wayland, for example)?
-
gavrilikhin.d almost 3 yearsWhat's the hell is this:
!!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)))
? Ok, it's some bits manipulating, but where do these magic numbers come from? -
gavrilikhin.d almost 3 yearsOh, I got it. There's a quick explanation:
-
gavrilikhin.d almost 3 years
keys_return
is an array of32*8
bits, where every bit with the numberkc2
is a status of the corresponding key with keycodekc2
. Our goal is to convertkc2
to somewhat of coordinates in "two-dimensional array"keys_return
. To achieve that, we first need to get correct row by dividingkc2 / 8
(remember each "row" is8
bits.kc2 >> 3
does the same askc2 / 8
. Then we get "column"kc2 % 8
, which is the same askc2 & 7
. Hovewer, since it's a bit, we need to shift1
to get it. -
gavrilikhin.d almost 3 yearsSo, equivalent is
keys_return[kc2 / 8] & (1 << (kc2 % 8)
. Almost likearr[n/8][n%8]
.