6 static unsigned char kbd_inj_buffer[128];
7 static int kbd_inj_start = 0;
8 static int kbd_inj_end = 0;
11 static const char scancodes2[][2][8] = {
12 ['a'] = { "\x1c", "\xf0\x1c" },
13 ['b'] = { "\x32", "\xf0\x32" },
14 ['c'] = { "\x21", "\xf0\x21" },
15 ['d'] = { "\x23", "\xf0\x23" },
16 ['e'] = { "\x24", "\xf0\x24" },
17 ['f'] = { "\x2b", "\xf0\x2b" },
18 ['g'] = { "\x34", "\xf0\x34" },
19 ['h'] = { "\x33", "\xf0\x33" },
20 ['i'] = { "\x43", "\xf0\x43" },
21 ['j'] = { "\x3b", "\xf0\x3b" },
22 ['k'] = { "\x42", "\xf0\x42" },
23 ['l'] = { "\x4b", "\xf0\x4b" },
24 ['m'] = { "\x3a", "\xf0\x3a" },
25 ['n'] = { "\x31", "\xf0\x31" },
26 ['o'] = { "\x44", "\xf0\x44" },
27 ['p'] = { "\x4d", "\xf0\x4d" },
28 ['q'] = { "\x15", "\xf0\x15" },
29 ['r'] = { "\x2d", "\xf0\x2d" },
30 ['s'] = { "\x1b", "\xf0\x1b" },
31 ['t'] = { "\x2c", "\xf0\x2c" },
32 ['u'] = { "\x3c", "\xf0\x3c" },
33 ['v'] = { "\x2a", "\xf0\x2a" },
34 ['w'] = { "\x1d", "\xf0\x1d" },
35 ['x'] = { "\x22", "\xf0\x22" },
36 ['y'] = { "\x35", "\xf0\x35" },
37 ['z'] = { "\x1a", "\xf0\x1a" },
38 ['A'] = { "\x12\x1c", "\xf0\x1c\xf0\x12" },
39 ['B'] = { "\x12\x32", "\xf0\x32\xf0\x12" },
40 ['C'] = { "\x12\x21", "\xf0\x21\xf0\x12" },
41 ['D'] = { "\x12\x23", "\xf0\x23\xf0\x12" },
42 ['E'] = { "\x12\x24", "\xf0\x24\xf0\x12" },
43 ['F'] = { "\x12\x2b", "\xf0\x2b\xf0\x12" },
44 ['G'] = { "\x12\x34", "\xf0\x34\xf0\x12" },
45 ['H'] = { "\x12\x33", "\xf0\x33\xf0\x12" },
46 ['I'] = { "\x12\x43", "\xf0\x43\xf0\x12" },
47 ['J'] = { "\x12\x3b", "\xf0\x3b\xf0\x12" },
48 ['K'] = { "\x12\x42", "\xf0\x42\xf0\x12" },
49 ['L'] = { "\x12\x4b", "\xf0\x4b\xf0\x12" },
50 ['M'] = { "\x12\x3a", "\xf0\x3a\xf0\x12" },
51 ['N'] = { "\x12\x31", "\xf0\x31\xf0\x12" },
52 ['O'] = { "\x12\x44", "\xf0\x44\xf0\x12" },
53 ['P'] = { "\x12\x4d", "\xf0\x4d\xf0\x12" },
54 ['Q'] = { "\x12\x15", "\xf0\x15\xf0\x12" },
55 ['R'] = { "\x12\x2d", "\xf0\x2d\xf0\x12" },
56 ['S'] = { "\x12\x1b", "\xf0\x1b\xf0\x12" },
57 ['T'] = { "\x12\x2c", "\xf0\x2c\xf0\x12" },
58 ['U'] = { "\x12\x3c", "\xf0\x3c\xf0\x12" },
59 ['V'] = { "\x12\x2a", "\xf0\x2a\xf0\x12" },
60 ['W'] = { "\x12\x1d", "\xf0\x1d\xf0\x12" },
61 ['X'] = { "\x12\x22", "\xf0\x22\xf0\x12" },
62 ['Y'] = { "\x12\x35", "\xf0\x35\xf0\x12" },
63 ['Z'] = { "\x12\x1a", "\xf0\x1a\xf0\x12" },
64 ['`'] = { "\x0e", "\xf0\x0e" },
65 ['~'] = { "\x12\x0e", "\xf0\x0e\xf0\x12" },
66 ['1'] = { "\x16", "\xf0\x16" },
67 ['!'] = { "\x12\x16", "\xf0\x16\xf0\x12" },
68 ['2'] = { "\x1e", "\xf0\x1e" },
69 ['@'] = { "\x12\x1e", "\xf0\x1e\xf0\x12" },
70 ['3'] = { "\x26", "\xf0\x26" },
71 ['#'] = { "\x12\x26", "\xf0\x26\xf0\x12" },
72 ['4'] = { "\x25", "\xf0\x25" },
73 ['$'] = { "\x12\x25", "\xf0\x25\xf0\x12" },
74 ['5'] = { "\x2e", "\xf0\x2e" },
75 ['%'] = { "\x12\x2e", "\xf0\x2e\xf0\x12" },
76 ['6'] = { "\x36", "\xf0\x36" },
77 ['^'] = { "\x12\x36", "\xf0\x36\xf0\x12" },
78 ['7'] = { "\x3d", "\xf0\x3d" },
79 ['&'] = { "\x12\x3d", "\xf0\x3d\xf0\x12" },
80 ['8'] = { "\x3e", "\xf0\x3e" },
81 ['*'] = { "\x12\x3e", "\xf0\x3e\xf0\x12" },
82 ['9'] = { "\x46", "\xf0\x46" },
83 ['('] = { "\x12\x46", "\xf0\x46\xf0\x12" },
84 ['0'] = { "\x45", "\xf0\x45" },
85 [')'] = { "\x12\x45", "\xf0\x45\xf0\x12" },
86 ['-'] = { "\x4e", "\xf0\x4e" },
87 ['_'] = { "\x12\x4e", "\xf0\x4e\xf0\x12" },
88 ['='] = { "\x55", "\xf0\x55" },
89 ['+'] = { "\x12\x55", "\xf0\x55\xf0\x12" },
90 ['['] = { "\x54", "\xf0\x54" },
91 ['{'] = { "\x12\x54", "\xf0\x54\xf0\x12" },
92 [']'] = { "\x5b", "\xf0\x5b" },
93 ['}'] = { "\x12\x5b", "\xf0\x5b\xf0\x12" },
94 ['\\'] = { "\x5d", "\xf0\x5d" },
95 ['|'] = { "\x12\x5d", "\xf0\x5d\xf0\x12" },
96 [';'] = { "\x4c", "\xf0\x4c" },
97 [':'] = { "\x12\x4c", "\xf0\x4c\xf0\x12" },
98 ['\''] = { "\x52", "\xf0\x52" },
99 ['"'] = { "\x12\x52", "\xf0\x52\xf0\x12" },
100 [','] = { "\x41", "\xf0\x41" },
101 ['<'] = { "\x12\x41", "\xf0\x41\xf0\x12" },
102 ['.'] = { "\x49", "\xf0\x49" },
103 ['>'] = { "\x12\x49", "\xf0\x49\xf0\x12" },
104 ['/'] = { "\x4a", "\xf0\x4a" },
105 [' '] = { "\x29", "\xf0\x29" },
106 ['?'] = { "\x12\x4a", "\xf0\x4a\xf0\x12" }
110 static const char scancodes2high[][2][8] = {
111 [0x08] = { "\x66", "\xf0\x66" },
112 [0x09] = { "\x0d", "\xf0\x0d" },
113 [0x0d] = { "\x5a", "\xf0\x5a" },
114 [0x1b] = { "\x76", "\xf0\x76" },
115 [0x63] = { "\xE0\x70", "\xE0\xF0\x70" },
116 [0xff] = { "\xE0\x71", "\xE0\xF0\x71" },
117 [0x50] = { "\xE0\x6C", "\xE0\xF0\x6C" },
118 [0x57] = { "\xE0\x69", "\xE0\xF0\x69" },
119 [0x55] = { "\xE0\x75", "\xE0\xF0\x75" },
120 [0x56] = { "\xE0\x7A", "\xE0\xF0\x7A" },
121 [0x51] = { "\xE0\x74", "\xE0\xF0\x74" },
122 [0x52] = { "\xE0\x75", "\xE0\xF0\x75" },
123 [0x53] = { "\xE0\x6B", "\xE0\xF0\x6B" },
124 [0x54] = { "\xE0\x72", "\xE0\xF0\x72" },
125 [0xe1] = { "\x12", "\xf0\x12" },
126 [0xe2] = { "\x59", "\xf0\x59" },
127 [0xe3] = { "\x14", "\xf0\x14" },
128 [0xe4] = { "\xE0\x14", "\xE0\xF0\x14" },
129 [0xe9] = { "\x11", "\xf0\x11" },
130 [0xea] = { "\xE0\x11", "\xE0\xF0\x11" }
133 const unsigned char convert_table[] = {
134 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
135 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a, 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
136 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c, 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
137 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e, 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
138 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60, 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
139 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e, 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
140 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b, 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
141 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
142 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
143 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
144 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
145 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
146 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
147 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
148 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
149 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
152 unsigned char sc_convert_1(unsigned char in)
154 static int shifted = 0;
159 return convert_table[in] | 0x80;
167 return convert_table[in];
171 void kbd_inject_scancode (unsigned char sc)
173 outputf("Buffering %02x", sc);
174 kbd_inj_buffer[kbd_inj_end] = sc;
176 kbd_inj_end %= sizeof(kbd_inj_buffer);
179 void kbd_inject_keysym(uint32_t k, int downflag)
183 if ((k & 0xFFFFFF00) == 0)
185 c = scancodes2[k & 0xFF][downflag ? 0 : 1];
186 } else if ((k & 0xFFFFFF00) == 0xFF00) {
187 c = scancodes2high[k & 0xFF][downflag ? 0 : 1];
196 char cconv = sc_convert_1(*c);
197 if (cconv) kbd_inject_scancode(cconv);
202 kbd_inject_scancode(*c);
208 unsigned char kbd_get_injected_scancode()
212 if (kbd_inj_end != kbd_inj_start)
214 b = kbd_inj_buffer[kbd_inj_start];
216 kbd_inj_start %= sizeof(kbd_inj_buffer);
217 outputf("Injecting %02x", b);
220 outputf("Not injecting");
225 int kbd_has_injected_scancode()
227 if (kbd_inj_end != kbd_inj_start)