]> Joshua Wise's Git repositories - netwatch.git/blame_incremental - netwatch/keyboard.c
add a lot of copyright headers
[netwatch.git] / netwatch / keyboard.c
... / ...
CommitLineData
1/* keyboard.c
2 * Keyboard scan code conversion and injection.
3 * NetWatch system management mode administration console
4 *
5 * Copyright (c) 2008 Jacob Potter and Joshua Wise. All rights reserved.
6 * This program is free software; you can redistribute and/or modify it under
7 * the terms found in the file LICENSE in the root of this source tree.
8 *
9 */
10
11#include "keyboard.h"
12#include <stdint.h>
13#include <minilib.h>
14#include <output.h>
15
16static unsigned char kbd_inj_buffer[128];
17static int kbd_inj_start = 0;
18static int kbd_inj_end = 0;
19int kbd_mode = 1;
20
21static const char scancodes2[][2][8] = {
22 ['a'] = { "\x1c", "\xf0\x1c" },
23 ['b'] = { "\x32", "\xf0\x32" },
24 ['c'] = { "\x21", "\xf0\x21" },
25 ['d'] = { "\x23", "\xf0\x23" },
26 ['e'] = { "\x24", "\xf0\x24" },
27 ['f'] = { "\x2b", "\xf0\x2b" },
28 ['g'] = { "\x34", "\xf0\x34" },
29 ['h'] = { "\x33", "\xf0\x33" },
30 ['i'] = { "\x43", "\xf0\x43" },
31 ['j'] = { "\x3b", "\xf0\x3b" },
32 ['k'] = { "\x42", "\xf0\x42" },
33 ['l'] = { "\x4b", "\xf0\x4b" },
34 ['m'] = { "\x3a", "\xf0\x3a" },
35 ['n'] = { "\x31", "\xf0\x31" },
36 ['o'] = { "\x44", "\xf0\x44" },
37 ['p'] = { "\x4d", "\xf0\x4d" },
38 ['q'] = { "\x15", "\xf0\x15" },
39 ['r'] = { "\x2d", "\xf0\x2d" },
40 ['s'] = { "\x1b", "\xf0\x1b" },
41 ['t'] = { "\x2c", "\xf0\x2c" },
42 ['u'] = { "\x3c", "\xf0\x3c" },
43 ['v'] = { "\x2a", "\xf0\x2a" },
44 ['w'] = { "\x1d", "\xf0\x1d" },
45 ['x'] = { "\x22", "\xf0\x22" },
46 ['y'] = { "\x35", "\xf0\x35" },
47 ['z'] = { "\x1a", "\xf0\x1a" },
48 ['A'] = { "\x12\x1c", "\xf0\x1c\xf0\x12" },
49 ['B'] = { "\x12\x32", "\xf0\x32\xf0\x12" },
50 ['C'] = { "\x12\x21", "\xf0\x21\xf0\x12" },
51 ['D'] = { "\x12\x23", "\xf0\x23\xf0\x12" },
52 ['E'] = { "\x12\x24", "\xf0\x24\xf0\x12" },
53 ['F'] = { "\x12\x2b", "\xf0\x2b\xf0\x12" },
54 ['G'] = { "\x12\x34", "\xf0\x34\xf0\x12" },
55 ['H'] = { "\x12\x33", "\xf0\x33\xf0\x12" },
56 ['I'] = { "\x12\x43", "\xf0\x43\xf0\x12" },
57 ['J'] = { "\x12\x3b", "\xf0\x3b\xf0\x12" },
58 ['K'] = { "\x12\x42", "\xf0\x42\xf0\x12" },
59 ['L'] = { "\x12\x4b", "\xf0\x4b\xf0\x12" },
60 ['M'] = { "\x12\x3a", "\xf0\x3a\xf0\x12" },
61 ['N'] = { "\x12\x31", "\xf0\x31\xf0\x12" },
62 ['O'] = { "\x12\x44", "\xf0\x44\xf0\x12" },
63 ['P'] = { "\x12\x4d", "\xf0\x4d\xf0\x12" },
64 ['Q'] = { "\x12\x15", "\xf0\x15\xf0\x12" },
65 ['R'] = { "\x12\x2d", "\xf0\x2d\xf0\x12" },
66 ['S'] = { "\x12\x1b", "\xf0\x1b\xf0\x12" },
67 ['T'] = { "\x12\x2c", "\xf0\x2c\xf0\x12" },
68 ['U'] = { "\x12\x3c", "\xf0\x3c\xf0\x12" },
69 ['V'] = { "\x12\x2a", "\xf0\x2a\xf0\x12" },
70 ['W'] = { "\x12\x1d", "\xf0\x1d\xf0\x12" },
71 ['X'] = { "\x12\x22", "\xf0\x22\xf0\x12" },
72 ['Y'] = { "\x12\x35", "\xf0\x35\xf0\x12" },
73 ['Z'] = { "\x12\x1a", "\xf0\x1a\xf0\x12" },
74 ['`'] = { "\x0e", "\xf0\x0e" },
75 ['~'] = { "\x12\x0e", "\xf0\x0e\xf0\x12" },
76 ['1'] = { "\x16", "\xf0\x16" },
77 ['!'] = { "\x12\x16", "\xf0\x16\xf0\x12" },
78 ['2'] = { "\x1e", "\xf0\x1e" },
79 ['@'] = { "\x12\x1e", "\xf0\x1e\xf0\x12" },
80 ['3'] = { "\x26", "\xf0\x26" },
81 ['#'] = { "\x12\x26", "\xf0\x26\xf0\x12" },
82 ['4'] = { "\x25", "\xf0\x25" },
83 ['$'] = { "\x12\x25", "\xf0\x25\xf0\x12" },
84 ['5'] = { "\x2e", "\xf0\x2e" },
85 ['%'] = { "\x12\x2e", "\xf0\x2e\xf0\x12" },
86 ['6'] = { "\x36", "\xf0\x36" },
87 ['^'] = { "\x12\x36", "\xf0\x36\xf0\x12" },
88 ['7'] = { "\x3d", "\xf0\x3d" },
89 ['&'] = { "\x12\x3d", "\xf0\x3d\xf0\x12" },
90 ['8'] = { "\x3e", "\xf0\x3e" },
91 ['*'] = { "\x12\x3e", "\xf0\x3e\xf0\x12" },
92 ['9'] = { "\x46", "\xf0\x46" },
93 ['('] = { "\x12\x46", "\xf0\x46\xf0\x12" },
94 ['0'] = { "\x45", "\xf0\x45" },
95 [')'] = { "\x12\x45", "\xf0\x45\xf0\x12" },
96 ['-'] = { "\x4e", "\xf0\x4e" },
97 ['_'] = { "\x12\x4e", "\xf0\x4e\xf0\x12" },
98 ['='] = { "\x55", "\xf0\x55" },
99 ['+'] = { "\x12\x55", "\xf0\x55\xf0\x12" },
100 ['['] = { "\x54", "\xf0\x54" },
101 ['{'] = { "\x12\x54", "\xf0\x54\xf0\x12" },
102 [']'] = { "\x5b", "\xf0\x5b" },
103 ['}'] = { "\x12\x5b", "\xf0\x5b\xf0\x12" },
104 ['\\'] = { "\x5d", "\xf0\x5d" },
105 ['|'] = { "\x12\x5d", "\xf0\x5d\xf0\x12" },
106 [';'] = { "\x4c", "\xf0\x4c" },
107 [':'] = { "\x12\x4c", "\xf0\x4c\xf0\x12" },
108 ['\''] = { "\x52", "\xf0\x52" },
109 ['"'] = { "\x12\x52", "\xf0\x52\xf0\x12" },
110 [','] = { "\x41", "\xf0\x41" },
111 ['<'] = { "\x12\x41", "\xf0\x41\xf0\x12" },
112 ['.'] = { "\x49", "\xf0\x49" },
113 ['>'] = { "\x12\x49", "\xf0\x49\xf0\x12" },
114 ['/'] = { "\x4a", "\xf0\x4a" },
115 [' '] = { "\x29", "\xf0\x29" },
116 ['?'] = { "\x12\x4a", "\xf0\x4a\xf0\x12" }
117};
118
119
120static const char scancodes2high[][2][8] = {
121 [0x08] = { "\x66", "\xf0\x66" },
122 [0x09] = { "\x0d", "\xf0\x0d" },
123 [0x0d] = { "\x5a", "\xf0\x5a" },
124 [0x1b] = { "\x76", "\xf0\x76" },
125 [0x63] = { "\xE0\x70", "\xE0\xF0\x70" },
126 [0xff] = { "\xE0\x71", "\xE0\xF0\x71" },
127 [0x50] = { "\xE0\x6C", "\xE0\xF0\x6C" },
128 [0x57] = { "\xE0\x69", "\xE0\xF0\x69" },
129 [0x55] = { "\xE0\x75", "\xE0\xF0\x75" },
130 [0x56] = { "\xE0\x7A", "\xE0\xF0\x7A" },
131 [0x51] = { "\xE0\x74", "\xE0\xF0\x74" },
132 [0x52] = { "\xE0\x75", "\xE0\xF0\x75" },
133 [0x53] = { "\xE0\x6B", "\xE0\xF0\x6B" },
134 [0x54] = { "\xE0\x72", "\xE0\xF0\x72" },
135 [0xe1] = { "\x12", "\xf0\x12" },
136 [0xe2] = { "\x59", "\xf0\x59" },
137 [0xe3] = { "\x14", "\xf0\x14" },
138 [0xe4] = { "\xE0\x14", "\xE0\xF0\x14" },
139 [0xe9] = { "\x11", "\xf0\x11" },
140 [0xea] = { "\xE0\x11", "\xE0\xF0\x11" }
141};
142
143const unsigned char convert_table[] = {
144 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
145 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a, 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
146 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c, 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
147 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e, 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
148 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60, 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
149 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e, 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
150 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b, 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
151 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
152 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
153 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
154 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
155 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
156 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
157 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
158 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
159 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
160};
161
162unsigned char sc_convert_1(unsigned char in)
163{
164 static int shifted = 0;
165
166 if (shifted)
167 {
168 shifted = 0;
169 return convert_table[in] | 0x80;
170 }
171
172 if (in == 0xF0)
173 {
174 shifted = 1;
175 return 0;
176 } else {
177 return convert_table[in];
178 }
179}
180
181void kbd_inject_scancode (unsigned char sc)
182{
183 outputf("Buffering %02x", sc);
184 kbd_inj_buffer[kbd_inj_end] = sc;
185 kbd_inj_end += 1;
186 kbd_inj_end %= sizeof(kbd_inj_buffer);
187}
188
189void kbd_inject_keysym(uint32_t k, int downflag)
190{
191 const char * c;
192
193 if ((k & 0xFFFFFF00) == 0)
194 {
195 c = scancodes2[k & 0xFF][downflag ? 0 : 1];
196 } else if ((k & 0xFFFFFF00) == 0xFF00) {
197 c = scancodes2high[k & 0xFF][downflag ? 0 : 1];
198 } else {
199 return;
200 }
201
202 if (!c) return;
203
204 if (kbd_mode == 1) {
205 while (*c) {
206 char cconv = sc_convert_1(*c);
207 if (cconv) kbd_inject_scancode(cconv);
208 c++;
209 }
210 } else {
211 while (*c) {
212 kbd_inject_scancode(*c);
213 c++;
214 }
215 }
216}
217
218unsigned char kbd_get_injected_scancode()
219{
220 unsigned char b;
221
222 if (kbd_inj_end != kbd_inj_start)
223 {
224 b = kbd_inj_buffer[kbd_inj_start];
225 kbd_inj_start += 1;
226 kbd_inj_start %= sizeof(kbd_inj_buffer);
227 outputf("Injecting %02x", b);
228 return b;
229 } else {
230 outputf("Not injecting");
231 return 0;
232 }
233}
234
235int kbd_has_injected_scancode()
236{
237 if (kbd_inj_end != kbd_inj_start)
238 {
239 return 1;
240 } else {
241 return 0;
242 }
243}
This page took 0.024893 seconds and 4 git commands to generate.