是否有一种简单的方法来检查按键是否被按下,以便我可以在线程中循环执行?最好不要使用库,当然也不能使用ncurses。我在网上找不到任何有效的解决方案。
#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;
}
从这里来:
#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);
};
!!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)))
?好吧,这是一些位操作,但这些神奇的数字从哪里来的? - gavrilikhin.dkeys_return
是一个由 32*8
位组成的数组,其中编号为 kc2
的每一位都代表着对应按键的状态。我们的目标是将 kc2
转换为 "二维数组" keys_return
中的坐标。为了实现这个目标,我们首先需要通过除以 8
来获取正确的行数(请记住,每一行有 8
位)。kc2 >> 3
和 kc2 / 8
的结果相同。然后我们获取 "列",即 kc2 % 8
,它与 kc2 & 7
相同。但是,由于它是一个位,我们需要将 1
进行移位操作来获取它。 - gavrilikhin.dkeys_return[kc2 / 8] & (1 << (kc2 % 8)
。几乎就像是 arr[n/8][n%8]
。 - gavrilikhin.d