为什么 XKeysymToKeycode() 将我的所有键都设为小写?
Why is XKeysymToKeycode() making all of my keys lowercase?
我目前在使用 Xlib 时遇到问题,每当我调用 XKeysymToKeycode()
并传入大写字母 KeySym
时,它 returns 就会传递一个小写字母 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()
之后仍然是大写。 (注意,这不是我的实际程序,而是在这里发布的简化版本。在实际程序中,我发送按键事件和结果键码,发送的按键仍然存在此处显示的问题(它们都变成小写))
KeySyms
和KeyCodes
在语义上是不同的,它们之间不是一对一的关系。
一个KeyCode
是一个任意的小整数,代表键盘上的一个键。 (不是一个字符。一个键。)Xlib 要求键码在 [8, 255]
范围内,但幸运的是大多数键盘只有 100 多个键。
A KeySym
是与键关联的一些实际字符的表示。几乎总会有几个:在大多数终端布局中,小写和大写字母对应于相同的键。
所以不存在 "upper-case" 或 "lower-case" KeyCode
这样的东西。当你得到一个Keysym对应的KeyCode
时,你实际上是在丢失信息。
在 Xlib 中,给定的键至少有四个对应的 KeySyms
(小写、大写、备用小写、备用大写),尽管有些可能未分配。当你要求 KeySym
对应一个 KeyCode
时,你需要提供一个索引;索引 0(在您的代码中)将获得未移位的未修改字符。
对于给定的按键,转换为 KeySym 将考虑修改键的状态。其中有八个,包括 Shift
和 Lock
修饰符。忽略使情况复杂化的 Lock
,shift 修饰键通常会将小写字母转换为对应的大写字母(对于字母键)。
键盘处理比那个简短的总结要复杂得多,但这只是一个开始。
对于您的任务,您可能应该看看 XkbKeysymToModifiers
。
我目前在使用 Xlib 时遇到问题,每当我调用 XKeysymToKeycode()
并传入大写字母 KeySym
时,它 returns 就会传递一个小写字母 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()
之后仍然是大写。 (注意,这不是我的实际程序,而是在这里发布的简化版本。在实际程序中,我发送按键事件和结果键码,发送的按键仍然存在此处显示的问题(它们都变成小写))
KeySyms
和KeyCodes
在语义上是不同的,它们之间不是一对一的关系。
一个
KeyCode
是一个任意的小整数,代表键盘上的一个键。 (不是一个字符。一个键。)Xlib 要求键码在[8, 255]
范围内,但幸运的是大多数键盘只有 100 多个键。A
KeySym
是与键关联的一些实际字符的表示。几乎总会有几个:在大多数终端布局中,小写和大写字母对应于相同的键。
所以不存在 "upper-case" 或 "lower-case" KeyCode
这样的东西。当你得到一个Keysym对应的KeyCode
时,你实际上是在丢失信息。
在 Xlib 中,给定的键至少有四个对应的 KeySyms
(小写、大写、备用小写、备用大写),尽管有些可能未分配。当你要求 KeySym
对应一个 KeyCode
时,你需要提供一个索引;索引 0(在您的代码中)将获得未移位的未修改字符。
对于给定的按键,转换为 KeySym 将考虑修改键的状态。其中有八个,包括 Shift
和 Lock
修饰符。忽略使情况复杂化的 Lock
,shift 修饰键通常会将小写字母转换为对应的大写字母(对于字母键)。
键盘处理比那个简短的总结要复杂得多,但这只是一个开始。
对于您的任务,您可能应该看看 XkbKeysymToModifiers
。