有一些应用程序,用x11库制作,测试了ubuntu。它采用简单的键盘输入并输出相应的值。如果应用程序窗口(Ubuntu终端)当前处于打开状态,则可以正常工作
linux-kbhit.h
#define ESC "\033"
#define UP "\033[A"
#define DOWN "\033[B"
#define LEFT "\033[D"
#define RIGHT "\033[C"
#define A "a"
void term_setup(void (*sighandler)(int));
void term_restore();
bool kbhit();
bool keydown(const char* key);
字符串
linux-kbhit.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
static struct termios oldtio;
static struct termios curtio;
void term_setup(void (*sighandler)(int)){
struct sigaction sa;
/* Save stdin terminal attributes */
tcgetattr(0, &oldtio);
if(sighandler){
/* Make sure we exit cleanly */
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = sighandler;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
}
/* This is needed to be able to tcsetattr() after a hangup (Ctrl-C)
* see tcsetattr() on POSIX
*/
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = SIG_IGN;
sigaction(SIGTTOU, &sa, NULL);
/* Set non-canonical no-echo for stdin */
tcgetattr(0, &curtio);
curtio.c_lflag &= ~(ICANON | ECHO);
tcsetattr(0, TCSANOW, &curtio);
}
void term_restore(){
/* restore terminal attributes */
tcsetattr(0, TCSANOW, &oldtio);
}
static char get[4]= {0};
bool kbhit(){
struct pollfd pfds[1];
int ret;
memset(get, 0, sizeof(char) * 4);
/* See if there is data available */
pfds[0].fd = 0;
pfds[0].events = POLLIN;
ret = poll(pfds, 1, 0);
/* Consume data */
if (ret > 0) {
read(0, get, 3);
return strlen(get) > 0;
}
return false;
}
bool keydown(const char* key){
return !strcmp(get, key);
}
型
它完美地适用于活动应用程序的键盘输入,但应用程序的目的是获取所有OS键输入并解释它以供进一步使用
main.c
#include "linux-kbhit.h"
#include "stdio.h"
#include <signal.h>
static sig_atomic_t end = 0;
static void sighandler(int signo)
{
end = 1;
printf("good beye!\n");
}
int main()
{
term_setup(sighandler);
while (!end) {
if (kbhit()) {
if (keydown(ESC))
printf("This is \"ESC\" button!\n");
if (keydown(UP))
printf("This is \"UP\" button!\n");
if (keydown(DOWN))
printf("This is \"DOWN\" button!\n");
if (keydown(LEFT))
printf("This is \"LEFT\" button!\n");
if (keydown(RIGHT))
printf("This is \"RIGHT\" button!\n");
if (keydown(A))
printf("This is \"A\" button!\n");
}
}
term_restore();
return 0;
}
型
我需要从操作系统(Ubuntu)中的任何应用程序获取密钥我应该如何修改代码?
2条答案
按热度按时间vmjh9lq91#
我需要为Ubuntu制作QuickTextPaste的模拟您可以进行设置:如果按下控制+ T你得到弹出菜单,每个项目符号发送所需命令的粘贴,你可以使用它https://www.softwareok.com/?seite=Microsoft/QuickTextPaste/Screenshot-2
yi0zb3m42#
如果你的应用程序是用XWindow库构建的,当你启动XWindow连接到服务器时,你将无法控制所有的输入,因为XWindow键盘事件不会通过普通的tty输入进入应用程序。如果应用程序具有键盘焦点,则按下哪个键(ctrl-d、ctrl-c或ctrl-])生成EOF、SIGINT或SIGQUIT都无关紧要。因为这些键是通过键盘事件管理器(通过服务器tcp/unix套接字)编码的,而从不通过标准输入文件描述符。
顺便说一句,你在处理tty
termios
驱动程序时有一些误解。你说这是在挂断后能够tcsetattr()所必需的(Ctrl-C)
挂断是指调制解调器取消DSR调制解调器线路的Assert并产生
SIGHUP
信号时发生的情况(当用户发信号通知文件的终端结束时,它由tty驱动程序生成,并被发送到控制终端的进程组中的所有进程),但是您已经将终端设置设置为raw模式,然后,在tty驱动程序中不进行控制字符处理,因此,字符将被传递到进程,而不处理/生成SIGINT
、SIGHUP
或SIGQUIT
(最后一个,通常由Ctrl-]生成,如果启用,则生成进程的核心转储)(挂起)是由Ctrl-D而不是Ctrl-C生成的(它通常生成SIGINT
)但就像我说的,如果你移动到原始模式,在tty驱动程序中没有进行字符处理,您得到的是字符 raw。ASCII ETX
(文本结束)字符,而不使用SIGINT
中断程序。ASCII EOT
(传输结束)字符,而不向tty驱动程序发送更多数据。至此,将不会向进程组交付SIGHUP
。ASCII GS
(组分隔符)字符,但不向进程发送SIGQUIT
信号(并且没有核心转储)