C语言 从操作系统应用程序获取输入,即使应用程序不活动(Ubuntu)

xpcnnkqh  于 2023-08-03  发布在  其他
关注(0)|答案(2)|浏览(109)

有一些应用程序,用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)中的任何应用程序获取密钥我应该如何修改代码?

vmjh9lq9

vmjh9lq91#

我需要为Ubuntu制作QuickTextPaste的模拟您可以进行设置:如果按下控制+ T你得到弹出菜单,每个项目符号发送所需命令的粘贴,你可以使用它https://www.softwareok.com/?seite=Microsoft/QuickTextPaste/Screenshot-2

yi0zb3m4

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驱动程序中不进行控制字符处理,因此,字符将被传递到进程,而不处理/生成SIGINTSIGHUPSIGQUIT(最后一个,通常由Ctrl-]生成,如果启用,则生成进程的核心转储)(挂起)是由Ctrl-D而不是Ctrl-C生成的(它通常生成SIGINT)但就像我说的,如果你移动到原始模式,在tty驱动程序中没有进行字符处理,您得到的是字符 raw

  • Ctrl-C生成ASCII ETX(文本结束)字符,而不使用SIGINT中断程序。
  • Ctrl-D产生ASCII EOT(传输结束)字符,而不向tty驱动程序发送更多数据。至此,将不会向进程组交付SIGHUP
  • Ctrl-]生成ASCII GS(组分隔符)字符,但不向进程发送SIGQUIT信号(并且没有核心转储)

相关问题