我想了解从键盘的hid用法id到gdk keyval包含布局转换的整个系统。或者更具体地说:我有一个utf-8字符串,wan不需要创建一个hid密钥列表,外部设备必须播放才能得到相同的结果。
我到目前为止所做的:
(无shift/alt处理的精简版本)
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
static GdkKeymapKey *get_key_with_group_0(GdkKeymapKey *keys, gint n_keys) {
gint i;
for (i = 0; i < n_keys; ++i)
if (keys[i].group == 0)
return &keys[i];
/* fallback: return first element */
g_warning("can't find keycode for group 0");
return keys;
}
static guint keycode_to_keyval(guint keycode) {
GdkKeymap *keymap;
GdkKeymapKey key = {keycode, 0, 0};
guint keyval;
keymap = gdk_keymap_get_default();
keyval = gdk_keymap_lookup_key(keymap, &key);
if (keyval == 0)
g_warning("keycode %i has no keyval!\n", keycode);
return keyval;
}
/* Hid usage tables v1.12 chapter 10 and /usr/include/gtk-2.0/gdk/gdkkeysyms.h */
/* stores keyvals without modifiers */
static guint const table_hid_usage_id_to_keyval[232] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0x0000, 0x0000, 0x0000, 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, /* 0 */
0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x0031, 0x0032, /* 1 */
0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x0030, 0xff0d, 0xff1b, 0xff08, 0xff09, 0x0020, 0x00df, 0x00b4, 0x00fc, /* 2 */
0x002b, 0x005c, 0x0023, 0x00f6, 0x00e4, 0x005e, 0x002c, 0x002e, 0x002d, 0xffe5, 0xffbe, 0xffbf, 0xffc0, 0xffc1, 0xffc2, 0xffc3, /* 3 */
0xffc4, 0xffc5, 0xffc6, 0xffc7, 0xffc8, 0xffc9, 0x0000, 0xff14, 0xff13, 0xff63, 0xff50, 0xff55, 0xffff, 0xff57, 0xff56, 0xff53, /* 4 */
0xff51, 0xff54, 0xff52, 0xff7f, 0xffaf, 0xffaa, 0xffad, 0xffab, 0xff8d, 0xff9c, 0xff99, 0xff9b, 0xff96, 0xff9d, 0xff98, 0xff95, /* 5 */
0xff97, 0xff9a, 0xff9e, 0xff9f, 0x003c, 0xff67, 0x0000, 0x0000, 0xffca, 0xffcb, 0xffcc, 0xffcd, 0xffce, 0xffcf, 0xffd0, 0xffd1, /* 6 */
0xffd2, 0xffd3, 0xffd4, 0xffd5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 7 */
0x0000, 0x0000, 0xffe5, 0x0000, 0xff14, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 8 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 9 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* A */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff89, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* B */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff80, 0x0000, 0x0000, /* C */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffae, 0x0000, 0x0000, 0x0000, /* D */
0xffe3, 0xffe1, 0xffe9, 0xffeb, 0xffe4, 0xffe2, 0xffea, 0xff67 /* E */
};
// Needs keyval without modifications
static guint8 keyval_to_hid(guint keyval) {
guint i;
for (i = 0; i < 232; ++i) {
if (table_hid_usage_id_to_keyval[i] == keyval)
return i;
}
return 0;
}
static void do_it(gchar const *text) {
gchar const *iter;
guint keyval;
gunichar character;
GdkKeymapKey *keys;
GdkKeymapKey *key;
gint n_keys;
GdkKeymap *keymap;
iter = text;
keymap = gdk_keymap_get_default();
while(TRUE) {
character = g_utf8_get_char_validated(iter, -1);
if (character == 0)
break;
keyval = gdk_unicode_to_keyval(character);
/* get keyval without modifications */
if (!gdk_keymap_get_entries_for_keyval(keymap, keyval, &keys, &n_keys)) {
g_warning("keyval 0x%04x has no keycode!", keyval);
iter = g_utf8_find_next_char(iter, NULL);
break;
}
key = get_key_with_group_0(keys, n_keys);
keyval = keycode_to_keyval(key->keycode);
g_print("0x%04x\n", keyval_to_hid(keyval));
g_free(keys);
iter = g_utf8_find_next_char(iter, NULL);
}
}
int main(int argc, char **argv) {
g_type_init();
gtk_init(&argc, &argv);
do_it("Testing z");
return 0;
}
我的问题:
键盘布局翻译在哪里以及如何完成?
在我的德语键盘上我得到了这个:
按“Z”键
设备发送HID使用ID 0x1C(Y和Y)
xev说keycode 29;keysym 0x7a;“z”
这个翻译在哪里完成,我怎么能这样回去呢?
最佳答案
回答我自己的问题:
gtk返回的keycode是keycode x使用的,它独立于keymap。
通过静态查找将xkeycode转换为keyval并返回hid usage id是错误的,因为keyval依赖于keymap。
可以使用静态表[1]将xkeycode传输回内核keycode。内核keycode到hid用法id的进一步转换也通过静态表[2]完成。
[1]http://lists.x.org/archives/xorg/2006-June/015633.html
[2]https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-input.c?id=refs/tags/v3.9
关于linux - 了解Linux上从隐藏使用ID到gdk keyval的方式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14527037/