我目前在使用Xlib时遇到了一个问题,每当我调用XKeysymToKeycode()并传入一个大写的KeySym,它就会返回一个小写的KeyCode。对于这个问题,Google似乎没有一个真正的答案,也没有太多关于我正在使用的函数的文档。
下面是我使用的代码:

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>

int main(void) {
    Display *display;
    char *ptr;
    char c[2] = {0, 0};
    KeySym ksym;
    KeyCode kcode;

    display = XOpenDisplay(0);
    ptr = "Test";

    while (*ptr) {
        c[0] = *ptr;
        ksym = XStringToKeysym(c);
        printf("Before XKeysymToKeycode(): %s\n", XKeysymToString(ksym));
        kcode = XKeysymToKeycode(display, ksym);
        printf("Key code after XKeysymToKeycode(): %s\n", XKeysymToString(XKeycodeToKeysym(display, kcode, 0)));
        ptr++;
    }

    XCloseDisplay(display);

    return 0;
}

它可以用gcc -o sendkeys sendkeys_min.c -lX11 -lXtst -g -Wall -Wextra -pedantic -ansi编译(假设它已保存为sendkeys_min.c
电流输出如下:
Before XKeysymToKeycode(): T
Key code after XKeysymToKeycode(): t
Before XKeysymToKeycode(): e
Key code after XKeysymToKeycode(): e
Before XKeysymToKeycode(): s
Key code after XKeysymToKeycode(): s
Before XKeysymToKeycode(): t
Key code after XKeysymToKeycode(): t

当然,预期的输出是,“Test”中的第一个T在运行完XKeysymToKeycode()之后仍然是大写的。(请注意,这不是我的实际程序,而是一个用于在此处发布的简化版本。在实际的程序中,我用生成的键代码发送键事件,并且发送的键仍然有这里显示的问题(它们都变为小写)

最佳答案

KeySymsKeyCodes在语义上是不同的,它们之间没有1-1的关系。
KeyCode是表示键盘上键的任意小整数。(不是一个角色。Xlib要求密钥代码在[8, 255]范围内,但幸运的是,大多数键盘只有略多于100个密钥。
AKeySym是与键相关联的某些实际字符的表示。几乎总是有几个这样的:小写和大写字母对应于大多数终端布局上的同一个键。
所以没有“大写”或“小写”KeyCode。当您得到对应于Keysym的KeyCode时,实际上是在丢失信息。
在Xlib中,一个给定的密钥至少有四个对应的KeySyms(小写、大写、替换小写、替换大写),尽管有些可能是未分配的。当您要求与KeySym对应的KeyCode时,您需要提供一个索引;索引0(如您的代码中所示)将得到未移位的未修改字符。
对于给定的按键,对KeySym的转换将考虑修改键的状态。其中有8个,包括ShiftLock修饰符。忽略会使情况复杂化的Lock,shift修饰符键通常会将小写字母转换为大写字母(对于字母键)。
键盘操作要比那个简短的总结复杂得多,但这只是一个开始。
对于您的任务,您可能应该查看XkbKeysymToModifiers

10-04 21:54
查看更多