Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将ASCII字符转换为x11密钥码_C_Ascii_Xll - Fatal编程技术网

将ASCII字符转换为x11密钥码

将ASCII字符转换为x11密钥码,c,ascii,xll,C,Ascii,Xll,我有一个以ascii字符形式输入的小程序。我需要能够将这些转换为键码,以便与x11函数一起使用。是否有xlib函数来执行此操作或其他库?或者一个大的开关盒工作得最好吗?您可以使用至少将字母数字字符转换为KeySyms,然后再转换为KeyCodes: Display *display = ...; KeySym sym_a = XStringToKeysym("A"); KeyCode code_a = XKeysymToKeycode(display, sym_a); 正如@BobDooli

我有一个以ascii字符形式输入的小程序。我需要能够将这些转换为键码,以便与x11函数一起使用。是否有xlib函数来执行此操作或其他库?或者一个大的开关盒工作得最好吗?

您可以使用至少将字母数字字符转换为
KeySym
s,然后再转换为
KeyCode
s:

Display *display = ...;
KeySym sym_a = XStringToKeysym("A");
KeyCode code_a = XKeysymToKeycode(display, sym_a);


正如@BobDoolitle在他的文章中指出的那样,虽然
XStringToKeysym
适用于字母数字单字符字符串,但它在ASCII一般情况下失败。他提供了一种简单地处理大多数ASCII字符(
0x20
0x7F
)的方法,尽管超出该范围的字符需要更仔细的处理。

这个问题有一个古老的错误答案(来自@oldrinb),奇怪的是从未被质疑过。如注释中所述,不能使用XStringToKeysym以常规方式将字符映射到键值。它适用于字母和数字,但仅此而已,因为KeySym名称恰好直接映射到这些ASCII字符。对于其他ASCII字符,如标点符号或空格,它将不起作用

但你可以做得更好。如果查看
,您会发现对于
ASCII
0x20-0xFF,字符直接映射到
XKeySyms
。因此,我想说,直接将该范围的字符用作
键符号
,并将其余32个字符映射到相应的
键码
,更简单。因此,我认为代码应该更恰当:

Display *display = ...;
if ((int)c >= 0x20) {
    XKeysymToKeycode(display, (KeySym)c);
} else {
    ... // Exercise left to the reader :-)
}
“else”子句将需要多个
KeyCodes
,因为例如
ASCII
1(Control-A)是带有
XK\u Control\R
(或
XK\u Control\L
)修饰符的
XK\u A
。因此,您必须发出例如:
XK\u CONTROL\u L
DOWN、
XK\u A
DOWN、
XK\u A
UP、
XK\u CONTROL\u L
UP

下面是一个玩具程序,通过模拟键盘事件回显第一个参数来演示这一点:

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
#include <xcb/xcb.h>
#include <xcb/xcb_event.h>
#include <xcb/xtest.h>

main(int argc, char **argv)
{
    char *pc;
    xcb_connection_t *xconn;
    KeyCode code_a;
    Display *dpy = XOpenDisplay(NULL);

    xconn = XGetXCBConnection(dpy);

    for (pc = argv[1]; *pc != '\0'; ++pc) {
        if (*pc >= (char)0x20) {
            code_a = XKeysymToKeycode(dpy, (KeySym)*pc);
            xcb_test_fake_input(xconn, XCB_KEY_PRESS, code_a, XCB_CURRENT_TIME, XCB_NONE, 0, 0, 0);
            xcb_test_fake_input(xconn, XCB_KEY_RELEASE, code_a, XCB_CURRENT_TIME, XCB_NONE, 0, 0, 0);
            xcb_flush(xconn);
        } else {
            fprintf(stderr, "Eeek - out-of-range character 0x%x\n", (unsigned int)*pc);
        }
    }
    XCloseDisplay(dpy);
}
#包括
#包括
#包括
#包括
#包括
#包括
主(内部argc,字符**argv)
{
char*pc;
xcb_连接xconn;
密钥码a;
Display*dpy=XOpenDisplay(空);
xconn=XGetXCBConnection(dpy);
用于(pc=argv[1];*pc!='\0';++pc){
如果(*pc>=(字符)0x20){
代码a=XKeysymToKeycode(dpy,(KeySym)*pc);
xcb_测试_伪_输入(xconn,xcb_按键,代码a,xcb_当前时间,xcb_无,0,0);
xcb_测试_伪_输入(xconn、xcb_密钥释放、代码a、xcb_当前时间、xcb_无、0、0);
xcb_冲洗(xconn);
}否则{
fprintf(stderr,“Eeek-超出范围字符0x%x\n”,(无符号整数)*pc);
}
}
XCloseDisplay(dpy);
}
您需要将其链接到:
-lX11-lxcb-lxcb xtest-lX11 xcb


免责声明:在编写此代码的过程中,没有任何键符号受到损害。

这在一般情况下不起作用。XStringToKeysym映射键符号名称,而不是ASCII字符。您通常可以,因为对于常见的打印字符,KeySym名称与字符匹配,但对于空格字符,它不起作用。答案取决于您的业务逻辑。在这种情况下,没有ASCII映射。当没有映射时,您希望应用程序执行什么操作?你可以忽略它,产生一个错误,按铃,或者停下来着火。不管你的应用程序有什么意义。尽管这个问题很古老,但请接受“BododoLITTLE”的回答,而不是MIT,因为这个问题已经过时了,很可能提一下,目前ASCII中没有给出大多数输入,并且将UTF转换成关键代码的解决方案是可能的,虽然比较复杂或标准化程度稍低。