remove the syscalls.h #include from these files that aren't making direct syscalls...
[newos.git] / apps / consoled / keyboard_us.c
blobc67c5b38df53a29a3496fc478ccae9fd08aed41f
1 /*
2 ** Copyright 2002, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 #include <unistd.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <ctype.h>
10 #include <newos/tty_priv.h>
11 #include <newos/key_event.h>
13 #include "consoled.h"
15 const char unshifted_keymap[] = {
16 0, 0, 0, 0, 0, 0, 0, 0,
17 0, 0, 0, 0, 0, 0, 0, 0,
18 0, 0, 0, 0, 0, 0, 0, 0,
19 0, 0, 0, 0, 0, 0, 0, 0,
20 ' ', '!', '"', '#', '$', '%', '&', '\'',
21 '(', ')', '*', '+', ',', '-', '.', '/',
22 '0', '1', '2', '3', '4', '5', '6', '7',
23 '8', '9', ':', ';', '<', '=', '>', '?',
24 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
25 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
26 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
27 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
28 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
29 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
30 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
31 'x', 'y', 'z', '{', '|', '}', '~', 0
34 const char caps_keymap[] = {
35 0, 0, 0, 0, 0, 0, 0, 0,
36 0, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0,
39 ' ', '!', '"', '#', '$', '%', '&', '\'',
40 '(', ')', '*', '+', ',', '-', '.', '/',
41 '0', '1', '2', '3', '4', '5', '6', '7',
42 '8', '9', ':', ';', '<', '=', '>', '?',
43 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
44 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
45 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
46 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
47 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
48 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
49 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
50 'X', 'Y', 'Z', '{', '|', '}', '~', 0
53 const char shifted_keymap[] = {
54 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0,
56 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0,
58 ' ', '!', '"', '#', '$', '%', '&', '"',
59 '(', ')', '*', '+', '<', '_', '>', '?',
60 ')', '!', '@', '#', '$', '%', '^', '&',
61 '*', '(', ':', ':', '<', '+', '>', '?',
62 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
63 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
64 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
65 'X', 'Y', 'Z', '{', '|', '}', '^', '_',
66 '~', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
67 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
68 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
69 'X', 'Y', 'Z', '{', '|', '}', '~', 0
72 const char shifted_caps_keymap[] = {
73 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0,
77 ' ', '!', '"', '#', '$', '%', '&', '"',
78 '(', ')', '*', '+', '<', '_', '>', '?',
79 ')', '!', '@', '#', '$', '%', '^', '&',
80 '*', '(', ':', ':', '<', '+', '>', '?',
81 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
82 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
83 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
84 'X', 'Y', 'Z', '{', '|', '}', '^', '_',
85 '~', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
86 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
87 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
88 'x', 'y', 'z', '{', '|', '}', '~', 0
91 int process_key_events(_key_event *kevents, int num_events, char *out_buf, int buf_len, int keyboard_fd)
93 int i;
94 static bool numlock = false;
95 static bool shift = false;
96 static bool caps = false;
97 static bool ctrl = false;
98 // dont really need to track these
99 static bool alt = false;
100 static bool win = false;
101 static bool menu = false;
102 static const char *keymap = unshifted_keymap; // track the status of shift + caps
103 static int leds = 0;
104 int buf_pos = 0;
105 char c;
107 for(i=0; i<num_events; i++) {
108 bool reset_keymap = false;
109 // printf("process_key_events: event %d: keycode 0x%x modifiers 0x%x\n", i, kevents[i].keycode, kevents[i].modifiers);
111 if(kevents[i].modifiers & KEY_MODIFIER_DOWN) {
112 // deal with the common case first
113 if(kevents[i].keycode < KEY_NONE) {
114 c = keymap[kevents[i].keycode];
115 if(c == 0)
116 continue;
118 if(ctrl) {
119 if(c == ' ') {
120 c = 0;
121 } else {
122 char temp = toupper(c);
123 if(temp >= 'A' && temp <= ']')
124 c = temp - 'A' + 1;
128 out_buf[buf_pos++] = c;
129 } else {
130 /* extended keys */
131 char buf[16];
132 int count = 0;
133 int j;
135 switch(kevents[i].keycode) {
136 case KEY_LSHIFT:
137 case KEY_RSHIFT:
138 shift = true;
139 reset_keymap = true;
140 break;
141 case KEY_LCTRL:
142 case KEY_RCTRL:
143 ctrl = true;
144 break;
145 case KEY_LALT:
146 case KEY_RALT:
147 alt = true;
148 break;
149 case KEY_LWIN:
150 case KEY_RWIN:
151 win = true;
152 break;
153 case KEY_MENU:
154 menu = true;
155 break;
156 case KEY_CAPSLOCK:
157 caps = !caps;
158 reset_keymap = true;
159 leds = caps ? (leds | KEY_LED_CAPS) : (leds & ~KEY_LED_CAPS);
160 _kern_ioctl(keyboard_fd, _KEYBOARD_IOCTL_SET_LEDS, &leds, sizeof(leds));
161 break;
162 case KEY_PAD_NUMLOCK:
163 numlock = !numlock;
164 leds = numlock ? (leds | KEY_LED_NUM) : (leds & ~KEY_LED_NUM);
165 _kern_ioctl(keyboard_fd, _KEYBOARD_IOCTL_SET_LEDS, &leds, sizeof(leds));
166 break;
167 case KEY_RETURN:
168 case KEY_PAD_ENTER:
169 buf[count++] = '\n';
170 break;
171 case KEY_BACKSPACE:
172 buf[count++] = 0x8;
173 break;
174 case KEY_TAB:
175 buf[count++] = '\t';
176 break;
177 case KEY_PAD_DIVIDE:
178 buf[count++] = '/';
179 break;
180 case KEY_PAD_MULTIPLY:
181 buf[count++] = '*';
182 break;
183 case KEY_PAD_MINUS:
184 buf[count++] = '-';
185 break;
186 case KEY_PAD_PLUS:
187 buf[count++] = '+';
188 break;
189 case KEY_PAD_PERIOD:
190 buf[count++] = '.';
191 break;
192 case KEY_PAD_0:
193 if(numlock) buf[count++] = '0';
194 break;
195 case KEY_PAD_1:
196 if(numlock) buf[count++] = '1';
197 break;
198 case KEY_PAD_2:
199 if(numlock) buf[count++] = '2';
200 break;
201 case KEY_PAD_3:
202 if(numlock) buf[count++] = '3';
203 break;
204 case KEY_PAD_4:
205 if(numlock) buf[count++] = '4';
206 break;
207 case KEY_PAD_5:
208 if(numlock) buf[count++] = '5';
209 break;
210 case KEY_PAD_6:
211 if(numlock) buf[count++] = '6';
212 break;
213 case KEY_PAD_7:
214 if(numlock) buf[count++] = '7';
215 break;
216 case KEY_PAD_8:
217 if(numlock) buf[count++] = '8';
218 break;
219 case KEY_PAD_9:
220 if(numlock) buf[count++] = '9';
221 break;
223 for(j = 0; j < count; j++) {
224 out_buf[buf_pos++] = buf[j];
227 } else if(kevents[i].modifiers & KEY_MODIFIER_UP) {
228 switch(kevents[i].keycode) {
229 case KEY_LSHIFT:
230 case KEY_RSHIFT:
231 shift = false;
232 reset_keymap = true;
233 break;
234 case KEY_LCTRL:
235 case KEY_RCTRL:
236 ctrl = false;
237 break;
238 case KEY_LALT:
239 case KEY_RALT:
240 alt = false;
241 break;
242 case KEY_LWIN:
243 case KEY_RWIN:
244 win = false;
245 break;
246 case KEY_MENU:
247 menu = false;
248 break;
252 // the shift or caps state changed, reset the keymap
253 if(reset_keymap) {
254 if(shift) {
255 if(caps) keymap = shifted_caps_keymap;
256 else keymap = shifted_keymap;
257 } else {
258 if(caps) keymap = caps_keymap;
259 else keymap = unshifted_keymap;
263 return buf_pos;