【问题标题】:Convert ASCII character to x11 keycode将 ASCII 字符转换为 x11 键码
【发布时间】:2020-05-13 08:53:12
【问题描述】:

我有一个以 ascii 字符形式输入的小程序。我需要能够将这些转换为用于 x11 功能的键码。是否有执行此操作的 xlib 函数或其他库?还是大型开关盒效果最好?

【问题讨论】:

  • 虽然这个问题很老了,但考虑接受@BobDoolittle 的回答而不是我的回答
  • 由于这个问题已经过时了,可能值得一提的是,现在大多数输入都不是以 ASCII 格式给出的,将 UTF 转换为键码的解决方案是可能的,尽管更复杂或标准化程度稍低。

标签: c ascii xll


【解决方案1】:

这个问题有一个古老的错误答案(来自@oldrinb),奇怪的是从未受到挑战。如评论中所述,您不能使用 XStringToKeysym 以一般方式将字符映射到 KeySyms。它适用于字母和数字,但仅此而已,因为 KeySym 名称恰好直接映射那些 ASCII 字符。对于其他 ASCII 字符,例如标点符号或空格,它将不起作用。

但你可以做得更好。如果您查看<X11/keysymdef.h>,您会发现对于ASCII 0x20-0xFF,字符直接映射到XKeySyms。所以,我想说直接使用该范围的字符作为KeySyms,并将剩余的32 个字符映射到它们对应的KeyCodes 会更简单。所以我想说代码应该更合适:

Display *display = ...;
if ((int)c >= 0x20) {
    XKeysymToKeycode(display, (KeySym)c);
} else {
    ... // Exercise left to the reader :-)
}

“else”子句将需要多个 KeyCodes,因为例如 ASCII 1(Control-A)是带有 XK_CONTROL_R(或 XK_CONTROL_L)修饰符的 XK_A。所以你必须发出例如:XK_CONTROL_L DOWN、XK_A DOWN、XK_A UP、XK_CONTROL_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);
}

您需要将其链接到:-lX11 -lxcb -lxcb-xtest -lX11-xcb

免责声明:在编写此代码时没有损害 KeySyms。

【讨论】:

  • 答案取决于您的业务逻辑。在这种情况下没有 ASCII 映射。当没有映射时,您希望您的应用程序做什么?您可以忽略它、产生错误、敲响警钟或停止并着火。任何对您的应用有意义的东西。
【解决方案2】:

您可以使用XStringToKeysym 将至少字母数字字符转换为KeySyms,然后使用XKeysymToKeycode 转换为KeyCodes:

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

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

【讨论】:

  • 这在一般情况下不起作用。 XStringToKeysym 映射 KeySym 名称,而不是 ASCII 字符。您通常会没事,因为对于常见的打印字符,KeySym 名称与该字符匹配,但它不适用于例如空格字符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-10
相关资源
最近更新 更多