我想了解从键盘的hid使用id到系统到GDK keyval包含布局转换的方式。或者更具体一点:我有一个UTF-8字符串,并且不想创建一个外部设备必须播放以获得相同结果的隐藏密钥列表。
到目前为止我尝试了什么:
(没有移位/替代处理的剥离版本)
#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;
}
我的问题:
键盘布局转换的位置和方式如何? 在我的德语键盘上,我得到了这个:
这个翻译在哪里,我怎么能这样回去?
答案 0 :(得分:1)
回答我自己的问题:
GTK返回的键码是X使用的键码,它与键映射无关。 通过静态查找将xkeycode转换为keyval并返回到hid使用id是错误的,因为keyval是依赖于键映射的。
可以使用静态表[1]将xkeycode传回内核密钥代码。使用静态表[2]进一步将内核密钥转换为隐藏使用id。