]> Joshua Wise's Git repositories - netwatch.git/blob - netwatch/keyboard.c
64be4452182ff5f7cef723771501dfb0740d1470
[netwatch.git] / netwatch / keyboard.c
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
16 static unsigned char kbd_inj_buffer[128];
17 static int kbd_inj_start = 0;
18 static int kbd_inj_end = 0;
19 int kbd_mode = 1;
20
21 static 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
120 static 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
143 const 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
162 unsigned 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
181 void 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
189 void 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
218 unsigned 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
235 int 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.028112 seconds and 2 git commands to generate.