Rev 2479 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2479 | Rev 3343 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright (c) 2007 Michal Kebrt |
2 | * Copyright (c) 2007 Michal Kebrt |
3 | * All rights reserved. |
3 | * All rights reserved. |
4 | * |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
7 | * are met: |
8 | * |
8 | * |
9 | * - Redistributions of source code must retain the above copyright |
9 | * - Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * - Redistributions in binary form must reproduce the above copyright |
11 | * - Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
13 | * documentation and/or other materials provided with the distribution. |
14 | * - The name of the author may not be used to endorse or promote products |
14 | * - The name of the author may not be used to endorse or promote products |
15 | * derived from this software without specific prior written permission. |
15 | * derived from this software without specific prior written permission. |
16 | * |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
27 | */ |
28 | 28 | ||
29 | /** @addtogroup kbdarm32gxemul GXemul |
29 | /** @addtogroup kbdarm32gxemul GXemul |
30 | * @brief HelenOS arm32 GXEmul uspace keyboard handler. |
30 | * @brief HelenOS arm32 GXEmul uspace keyboard handler. |
31 | * @ingroup kbdarm32 |
31 | * @ingroup kbdarm32 |
32 | * @{ |
32 | * @{ |
33 | */ |
33 | */ |
34 | /** @file |
34 | /** @file |
35 | * @brief GXemul uspace keyboard handler. |
35 | * @brief GXemul uspace keyboard handler. |
36 | */ |
36 | */ |
37 | 37 | ||
38 | #include <ipc/ipc.h> |
38 | #include <ipc/ipc.h> |
39 | #include <sysinfo.h> |
39 | #include <sysinfo.h> |
40 | #include <kbd.h> |
40 | #include <kbd.h> |
41 | #include <keys.h> |
41 | #include <keys.h> |
42 | #include <bool.h> |
42 | #include <bool.h> |
43 | 43 | ||
44 | 44 | ||
45 | /* GXemul key codes in no-framebuffer mode. */ |
45 | /* GXemul key codes in no-framebuffer mode. */ |
46 | #define GXEMUL_KEY_F1 0x504f1bL |
46 | #define GXEMUL_KEY_F1 0x504f1bL |
47 | #define GXEMUL_KEY_F2 0x514f1bL |
47 | #define GXEMUL_KEY_F2 0x514f1bL |
48 | #define GXEMUL_KEY_F3 0x524f1bL |
48 | #define GXEMUL_KEY_F3 0x524f1bL |
49 | #define GXEMUL_KEY_F4 0x534f1bL |
49 | #define GXEMUL_KEY_F4 0x534f1bL |
50 | #define GXEMUL_KEY_F5 0x35315b1bL |
50 | #define GXEMUL_KEY_F5 0x35315b1bL |
51 | #define GXEMUL_KEY_F6 0x37315b1bL |
51 | #define GXEMUL_KEY_F6 0x37315b1bL |
52 | #define GXEMUL_KEY_F7 0x38315b1bL |
52 | #define GXEMUL_KEY_F7 0x38315b1bL |
53 | #define GXEMUL_KEY_F8 0x39315b1bL |
53 | #define GXEMUL_KEY_F8 0x39315b1bL |
54 | #define GXEMUL_KEY_F9 0x30325b1bL |
54 | #define GXEMUL_KEY_F9 0x30325b1bL |
55 | #define GXEMUL_KEY_F10 0x31325b1bL |
55 | #define GXEMUL_KEY_F10 0x31325b1bL |
56 | #define GXEMUL_KEY_F11 0x33325d1bL |
56 | #define GXEMUL_KEY_F11 0x33325d1bL |
57 | #define GXEMUL_KEY_F12 0x34325b1bL |
57 | #define GXEMUL_KEY_F12 0x34325b1bL |
58 | 58 | ||
59 | /** Start code of F5-F12 keys. */ |
59 | /** Start code of F5-F12 keys. */ |
60 | #define GXEMUL_KEY_F5_F12_START_CODE 0x7e |
60 | #define GXEMUL_KEY_F5_F12_START_CODE 0x7e |
61 | 61 | ||
62 | /* GXemul key codes in framebuffer mode. */ |
62 | /* GXemul key codes in framebuffer mode. */ |
63 | #define GXEMUL_FB_KEY_F1 0x504f5b1bL |
63 | #define GXEMUL_FB_KEY_F1 0x504f5b1bL |
64 | #define GXEMUL_FB_KEY_F2 0x514f5b1bL |
64 | #define GXEMUL_FB_KEY_F2 0x514f5b1bL |
65 | #define GXEMUL_FB_KEY_F3 0x524f5b1bL |
65 | #define GXEMUL_FB_KEY_F3 0x524f5b1bL |
66 | #define GXEMUL_FB_KEY_F4 0x534f5b1bL |
66 | #define GXEMUL_FB_KEY_F4 0x534f5b1bL |
67 | #define GXEMUL_FB_KEY_F5 0x35315b1bL |
67 | #define GXEMUL_FB_KEY_F5 0x35315b1bL |
68 | #define GXEMUL_FB_KEY_F6 0x37315b1bL |
68 | #define GXEMUL_FB_KEY_F6 0x37315b1bL |
69 | #define GXEMUL_FB_KEY_F7 0x38315b1bL |
69 | #define GXEMUL_FB_KEY_F7 0x38315b1bL |
70 | #define GXEMUL_FB_KEY_F8 0x39315b1bL |
70 | #define GXEMUL_FB_KEY_F8 0x39315b1bL |
71 | #define GXEMUL_FB_KEY_F9 0x38325b1bL |
71 | #define GXEMUL_FB_KEY_F9 0x38325b1bL |
72 | #define GXEMUL_FB_KEY_F10 0x39325b1bL |
72 | #define GXEMUL_FB_KEY_F10 0x39325b1bL |
73 | #define GXEMUL_FB_KEY_F11 0x33325b1bL |
73 | #define GXEMUL_FB_KEY_F11 0x33325b1bL |
74 | #define GXEMUL_FB_KEY_F12 0x34325b1bL |
74 | #define GXEMUL_FB_KEY_F12 0x34325b1bL |
75 | 75 | ||
76 | 76 | ||
77 | /** Function keys start code (F1=0x101) */ |
77 | /** Function keys start code (F1=0x101) */ |
78 | #define FUNCTION_KEYS 0x100 |
78 | #define FUNCTION_KEYS 0x100 |
79 | 79 | ||
80 | static irq_cmd_t gxemul_cmds[] = { |
80 | static irq_cmd_t gxemul_cmds[] = { |
81 | { |
81 | { |
82 | CMD_MEM_READ_1, |
82 | CMD_MEM_READ_1, |
83 | (void *) 0, |
83 | (void *) 0, |
84 | 0, |
84 | 0, |
85 | 2 |
85 | 2 |
86 | } |
86 | } |
87 | }; |
87 | }; |
88 | 88 | ||
89 | static irq_code_t gxemul_kbd = { |
89 | static irq_code_t gxemul_kbd = { |
90 | 1, |
90 | 1, |
91 | gxemul_cmds |
91 | gxemul_cmds |
92 | }; |
92 | }; |
93 | 93 | ||
94 | 94 | ||
95 | /** Framebuffer switched on. */ |
95 | /** Framebuffer switched on. */ |
96 | static bool fb; |
96 | static bool fb; |
97 | 97 | ||
98 | 98 | ||
99 | /* |
99 | /* |
100 | // Please preserve this code (it can be used to determine scancodes) |
100 | // Please preserve this code (it can be used to determine scancodes) |
101 | int to_hex(int v) |
101 | int to_hex(int v) |
102 | { |
102 | { |
103 | return "0123456789ABCDEF"[v]; |
103 | return "0123456789ABCDEF"[v]; |
104 | } |
104 | } |
105 | */ |
105 | */ |
106 | 106 | ||
107 | 107 | ||
108 | /** Process data sent when a key is pressed (in no-framebuffer mode). |
108 | /** Process data sent when a key is pressed (in no-framebuffer mode). |
109 | * |
109 | * |
110 | * @param keybuffer Buffer of pressed key. |
110 | * @param keybuffer Buffer of pressed key. |
111 | * @param scan_code Scan code. |
111 | * @param scan_code Scan code. |
112 | * |
112 | * |
113 | * @return Always 1. |
113 | * @return Always 1. |
114 | */ |
114 | */ |
115 | static int gxemul_kbd_process_no_fb(keybuffer_t *keybuffer, int scan_code) |
115 | static int gxemul_kbd_process_no_fb(keybuffer_t *keybuffer, int scan_code) |
116 | { |
116 | { |
117 | // holds at most 4 latest scan codes |
117 | // holds at most 4 latest scan codes |
118 | static unsigned long buf = 0; |
118 | static unsigned long buf = 0; |
119 | 119 | ||
120 | // number of scan codes in #buf |
120 | // number of scan codes in #buf |
121 | static int count = 0; |
121 | static int count = 0; |
122 | 122 | ||
123 | /* |
123 | /* |
124 | // Preserve for detecting scan codes. |
124 | // Preserve for detecting scan codes. |
125 | keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf)); |
125 | keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf)); |
126 | keybuffer_push(keybuffer, to_hex(scan_code&0xf)); |
126 | keybuffer_push(keybuffer, to_hex(scan_code&0xf)); |
127 | keybuffer_push(keybuffer, 'X'); |
127 | keybuffer_push(keybuffer, 'X'); |
128 | keybuffer_push(keybuffer, 'Y'); |
128 | keybuffer_push(keybuffer, 'Y'); |
129 | return 1; |
129 | return 1; |
130 | */ |
130 | */ |
131 | 131 | ||
132 | if (scan_code == '\r') { |
132 | if (scan_code == '\r') { |
133 | scan_code = '\n'; |
133 | scan_code = '\n'; |
134 | } |
134 | } |
135 | 135 | ||
136 | if (scan_code == GXEMUL_KEY_F5_F12_START_CODE) { |
136 | if (scan_code == GXEMUL_KEY_F5_F12_START_CODE) { |
137 | switch (buf) { |
137 | switch (buf) { |
138 | case GXEMUL_KEY_F5: |
138 | case GXEMUL_KEY_F5: |
139 | keybuffer_push(keybuffer,FUNCTION_KEYS | 5); |
139 | keybuffer_push(keybuffer,FUNCTION_KEYS | 5); |
140 | buf = count = 0; |
140 | buf = count = 0; |
141 | return 1; |
141 | return 1; |
142 | case GXEMUL_KEY_F6: |
142 | case GXEMUL_KEY_F6: |
143 | keybuffer_push(keybuffer,FUNCTION_KEYS | 6); |
143 | keybuffer_push(keybuffer,FUNCTION_KEYS | 6); |
144 | buf = count = 0; |
144 | buf = count = 0; |
145 | return 1; |
145 | return 1; |
146 | case GXEMUL_KEY_F7: |
146 | case GXEMUL_KEY_F7: |
147 | keybuffer_push(keybuffer,FUNCTION_KEYS | 7); |
147 | keybuffer_push(keybuffer,FUNCTION_KEYS | 7); |
148 | buf = count = 0; |
148 | buf = count = 0; |
149 | return 1; |
149 | return 1; |
150 | case GXEMUL_KEY_F8: |
150 | case GXEMUL_KEY_F8: |
151 | keybuffer_push(keybuffer,FUNCTION_KEYS | 8); |
151 | keybuffer_push(keybuffer,FUNCTION_KEYS | 8); |
152 | buf = count = 0; |
152 | buf = count = 0; |
153 | return 1; |
153 | return 1; |
154 | case GXEMUL_KEY_F9: |
154 | case GXEMUL_KEY_F9: |
155 | keybuffer_push(keybuffer,FUNCTION_KEYS | 9); |
155 | keybuffer_push(keybuffer,FUNCTION_KEYS | 9); |
156 | buf = count = 0; |
156 | buf = count = 0; |
157 | return 1; |
157 | return 1; |
158 | case GXEMUL_KEY_F10: |
158 | case GXEMUL_KEY_F10: |
159 | keybuffer_push(keybuffer,FUNCTION_KEYS | 10); |
159 | keybuffer_push(keybuffer,FUNCTION_KEYS | 10); |
160 | buf = count = 0; |
160 | buf = count = 0; |
161 | return 1; |
161 | return 1; |
162 | case GXEMUL_KEY_F11: |
162 | case GXEMUL_KEY_F11: |
163 | keybuffer_push(keybuffer,FUNCTION_KEYS | 11); |
163 | keybuffer_push(keybuffer,FUNCTION_KEYS | 11); |
164 | buf = count = 0; |
164 | buf = count = 0; |
165 | return 1; |
165 | return 1; |
166 | case GXEMUL_KEY_F12: |
166 | case GXEMUL_KEY_F12: |
167 | keybuffer_push(keybuffer,FUNCTION_KEYS | 12); |
167 | keybuffer_push(keybuffer,FUNCTION_KEYS | 12); |
168 | buf = count = 0; |
168 | buf = count = 0; |
169 | return 1; |
169 | return 1; |
170 | default: |
170 | default: |
171 | keybuffer_push(keybuffer, buf & 0xff); |
171 | keybuffer_push(keybuffer, buf & 0xff); |
172 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
172 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
173 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
173 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
174 | keybuffer_push(keybuffer, (buf >> 24) & 0xff); |
174 | keybuffer_push(keybuffer, (buf >> 24) & 0xff); |
175 | keybuffer_push(keybuffer, scan_code); |
175 | keybuffer_push(keybuffer, scan_code); |
176 | buf = count = 0; |
176 | buf = count = 0; |
177 | return 1; |
177 | return 1; |
178 | } |
178 | } |
179 | } |
179 | } |
180 | 180 | ||
181 | // add to buffer |
181 | // add to buffer |
182 | buf |= ((unsigned long) scan_code) << (8 * (count++)); |
182 | buf |= ((unsigned long) scan_code) << (8 * (count++)); |
183 | 183 | ||
184 | if ((buf & 0xff) != (GXEMUL_KEY_F1 & 0xff)) { |
184 | if ((buf & 0xff) != (GXEMUL_KEY_F1 & 0xff)) { |
185 | keybuffer_push(keybuffer, buf); |
185 | keybuffer_push(keybuffer, buf); |
186 | buf = count = 0; |
186 | buf = count = 0; |
187 | return 1; |
187 | return 1; |
188 | } |
188 | } |
189 | 189 | ||
190 | if (count <= 1) { |
190 | if (count <= 1) { |
191 | return 1; |
191 | return 1; |
192 | } |
192 | } |
193 | 193 | ||
194 | if ((buf & 0xffff) != (GXEMUL_KEY_F1 & 0xffff) |
194 | if ((buf & 0xffff) != (GXEMUL_KEY_F1 & 0xffff) |
195 | && (buf & 0xffff) != (GXEMUL_KEY_F5 & 0xffff) ) { |
195 | && (buf & 0xffff) != (GXEMUL_KEY_F5 & 0xffff) ) { |
196 | 196 | ||
197 | keybuffer_push(keybuffer, buf & 0xff); |
197 | keybuffer_push(keybuffer, buf & 0xff); |
198 | keybuffer_push(keybuffer, (buf >> 8) &0xff); |
198 | keybuffer_push(keybuffer, (buf >> 8) &0xff); |
199 | buf = count = 0; |
199 | buf = count = 0; |
200 | return 1; |
200 | return 1; |
201 | } |
201 | } |
202 | 202 | ||
203 | if (count <= 2) { |
203 | if (count <= 2) { |
204 | return 1; |
204 | return 1; |
205 | } |
205 | } |
206 | 206 | ||
207 | switch (buf) { |
207 | switch (buf) { |
208 | case GXEMUL_KEY_F1: |
208 | case GXEMUL_KEY_F1: |
209 | keybuffer_push(keybuffer,FUNCTION_KEYS | 1); |
209 | keybuffer_push(keybuffer,FUNCTION_KEYS | 1); |
210 | buf = count = 0; |
210 | buf = count = 0; |
211 | return 1; |
211 | return 1; |
212 | case GXEMUL_KEY_F2: |
212 | case GXEMUL_KEY_F2: |
213 | keybuffer_push(keybuffer,FUNCTION_KEYS | 2); |
213 | keybuffer_push(keybuffer,FUNCTION_KEYS | 2); |
214 | buf = count = 0; |
214 | buf = count = 0; |
215 | return 1; |
215 | return 1; |
216 | case GXEMUL_KEY_F3: |
216 | case GXEMUL_KEY_F3: |
217 | keybuffer_push(keybuffer,FUNCTION_KEYS | 3); |
217 | keybuffer_push(keybuffer,FUNCTION_KEYS | 3); |
218 | buf = count = 0; |
218 | buf = count = 0; |
219 | return 1; |
219 | return 1; |
220 | case GXEMUL_KEY_F4: |
220 | case GXEMUL_KEY_F4: |
221 | keybuffer_push(keybuffer,FUNCTION_KEYS | 4); |
221 | keybuffer_push(keybuffer,FUNCTION_KEYS | 4); |
222 | buf = count = 0; |
222 | buf = count = 0; |
223 | return 1; |
223 | return 1; |
224 | } |
224 | } |
225 | 225 | ||
226 | 226 | ||
227 | if ((buf & 0xffffff) != (GXEMUL_KEY_F5 & 0xffffff) |
227 | if ((buf & 0xffffff) != (GXEMUL_KEY_F5 & 0xffffff) |
228 | && (buf & 0xffffff) != (GXEMUL_KEY_F9 & 0xffffff)) { |
228 | && (buf & 0xffffff) != (GXEMUL_KEY_F9 & 0xffffff)) { |
229 | 229 | ||
230 | keybuffer_push(keybuffer, buf & 0xff); |
230 | keybuffer_push(keybuffer, buf & 0xff); |
231 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
231 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
232 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
232 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
233 | buf = count = 0; |
233 | buf = count = 0; |
234 | return 1; |
234 | return 1; |
235 | } |
235 | } |
236 | 236 | ||
237 | if (count <= 3) { |
237 | if (count <= 3) { |
238 | return 1; |
238 | return 1; |
239 | } |
239 | } |
240 | 240 | ||
241 | switch (buf) { |
241 | switch (buf) { |
242 | case GXEMUL_KEY_F5: |
242 | case GXEMUL_KEY_F5: |
243 | case GXEMUL_KEY_F6: |
243 | case GXEMUL_KEY_F6: |
244 | case GXEMUL_KEY_F7: |
244 | case GXEMUL_KEY_F7: |
245 | case GXEMUL_KEY_F8: |
245 | case GXEMUL_KEY_F8: |
246 | case GXEMUL_KEY_F9: |
246 | case GXEMUL_KEY_F9: |
247 | case GXEMUL_KEY_F10: |
247 | case GXEMUL_KEY_F10: |
248 | case GXEMUL_KEY_F11: |
248 | case GXEMUL_KEY_F11: |
249 | case GXEMUL_KEY_F12: |
249 | case GXEMUL_KEY_F12: |
250 | return 1; |
250 | return 1; |
251 | default: |
251 | default: |
252 | keybuffer_push(keybuffer, buf & 0xff); |
252 | keybuffer_push(keybuffer, buf & 0xff); |
253 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
253 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
254 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
254 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
255 | keybuffer_push(keybuffer, (buf >> 24) & 0xff); |
255 | keybuffer_push(keybuffer, (buf >> 24) & 0xff); |
256 | buf = count = 0; |
256 | buf = count = 0; |
257 | return 1; |
257 | return 1; |
258 | } |
258 | } |
259 | 259 | ||
260 | return 1; |
260 | return 1; |
261 | } |
261 | } |
262 | 262 | ||
263 | 263 | ||
264 | /** Process data sent when a key is pressed (in framebuffer mode). |
264 | /** Process data sent when a key is pressed (in framebuffer mode). |
265 | * |
265 | * |
266 | * @param keybuffer Buffer of pressed keys. |
266 | * @param keybuffer Buffer of pressed keys. |
267 | * @param scan_code Scan code. |
267 | * @param scan_code Scan code. |
268 | * |
268 | * |
269 | * @return Always 1. |
269 | * @return Always 1. |
270 | */ |
270 | */ |
271 | static int gxemul_kbd_process_fb(keybuffer_t *keybuffer, int scan_code) |
271 | static int gxemul_kbd_process_fb(keybuffer_t *keybuffer, int scan_code) |
272 | { |
272 | { |
273 | // holds at most 4 latest scan codes |
273 | // holds at most 4 latest scan codes |
274 | static unsigned long buf = 0; |
274 | static unsigned long buf = 0; |
275 | 275 | ||
276 | // number of scan codes in #buf |
276 | // number of scan codes in #buf |
277 | static int count = 0; |
277 | static int count = 0; |
278 | 278 | ||
279 | /* |
279 | /* |
280 | // Please preserve this code (it can be used to determine scancodes) |
280 | // Please preserve this code (it can be used to determine scancodes) |
281 | keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf)); |
281 | keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf)); |
282 | keybuffer_push(keybuffer, to_hex(scan_code&0xf)); |
282 | keybuffer_push(keybuffer, to_hex(scan_code&0xf)); |
283 | keybuffer_push(keybuffer, ' '); |
283 | keybuffer_push(keybuffer, ' '); |
284 | keybuffer_push(keybuffer, ' '); |
284 | keybuffer_push(keybuffer, ' '); |
285 | return 1; |
285 | return 1; |
286 | */ |
286 | */ |
287 | 287 | ||
288 | if (scan_code == '\r') { |
288 | if (scan_code == '\r') { |
289 | scan_code = '\n'; |
289 | scan_code = '\n'; |
290 | } |
290 | } |
291 | 291 | ||
292 | // add to buffer |
292 | // add to buffer |
293 | buf |= ((unsigned long) scan_code) << (8*(count++)); |
293 | buf |= ((unsigned long) scan_code) << (8*(count++)); |
294 | 294 | ||
295 | 295 | ||
296 | if ((buf & 0xff) != (GXEMUL_FB_KEY_F1 & 0xff)) { |
296 | if ((buf & 0xff) != (GXEMUL_FB_KEY_F1 & 0xff)) { |
297 | keybuffer_push(keybuffer, buf); |
297 | keybuffer_push(keybuffer, buf); |
298 | buf = count = 0; |
298 | buf = count = 0; |
299 | return 1; |
299 | return 1; |
300 | } |
300 | } |
301 | 301 | ||
302 | if (count <= 1) { |
302 | if (count <= 1) { |
303 | return 1; |
303 | return 1; |
304 | } |
304 | } |
305 | 305 | ||
306 | if ((buf & 0xffff) != (GXEMUL_FB_KEY_F1 & 0xffff)) { |
306 | if ((buf & 0xffff) != (GXEMUL_FB_KEY_F1 & 0xffff)) { |
307 | keybuffer_push(keybuffer, buf & 0xff); |
307 | keybuffer_push(keybuffer, buf & 0xff); |
308 | keybuffer_push(keybuffer, (buf >> 8) &0xff); |
308 | keybuffer_push(keybuffer, (buf >> 8) &0xff); |
309 | buf = count = 0; |
309 | buf = count = 0; |
310 | return 1; |
310 | return 1; |
311 | } |
311 | } |
312 | 312 | ||
313 | if (count <= 2) { |
313 | if (count <= 2) { |
314 | return 1; |
314 | return 1; |
315 | } |
315 | } |
316 | 316 | ||
317 | if ((buf & 0xffffff) != (GXEMUL_FB_KEY_F1 & 0xffffff) |
317 | if ((buf & 0xffffff) != (GXEMUL_FB_KEY_F1 & 0xffffff) |
318 | && (buf & 0xffffff) != (GXEMUL_FB_KEY_F5 & 0xffffff) |
318 | && (buf & 0xffffff) != (GXEMUL_FB_KEY_F5 & 0xffffff) |
319 | && (buf & 0xffffff) != (GXEMUL_FB_KEY_F9 & 0xffffff)) { |
319 | && (buf & 0xffffff) != (GXEMUL_FB_KEY_F9 & 0xffffff)) { |
320 | 320 | ||
321 | keybuffer_push(keybuffer, buf & 0xff); |
321 | keybuffer_push(keybuffer, buf & 0xff); |
322 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
322 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
323 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
323 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
324 | buf = count = 0; |
324 | buf = count = 0; |
325 | return 1; |
325 | return 1; |
326 | } |
326 | } |
327 | 327 | ||
328 | if (count <= 3) { |
328 | if (count <= 3) { |
329 | return 1; |
329 | return 1; |
330 | } |
330 | } |
331 | 331 | ||
332 | switch (buf) { |
332 | switch (buf) { |
333 | case GXEMUL_FB_KEY_F1: |
333 | case GXEMUL_FB_KEY_F1: |
334 | keybuffer_push(keybuffer,FUNCTION_KEYS | 1 ); |
334 | keybuffer_push(keybuffer,FUNCTION_KEYS | 1 ); |
335 | buf = count = 0; |
335 | buf = count = 0; |
336 | return 1; |
336 | return 1; |
337 | case GXEMUL_FB_KEY_F2: |
337 | case GXEMUL_FB_KEY_F2: |
338 | keybuffer_push(keybuffer,FUNCTION_KEYS | 2 ); |
338 | keybuffer_push(keybuffer,FUNCTION_KEYS | 2 ); |
339 | buf = count = 0; |
339 | buf = count = 0; |
340 | return 1; |
340 | return 1; |
341 | case GXEMUL_FB_KEY_F3: |
341 | case GXEMUL_FB_KEY_F3: |
342 | keybuffer_push(keybuffer,FUNCTION_KEYS | 3 ); |
342 | keybuffer_push(keybuffer,FUNCTION_KEYS | 3 ); |
343 | buf = count = 0; |
343 | buf = count = 0; |
344 | return 1; |
344 | return 1; |
345 | case GXEMUL_FB_KEY_F4: |
345 | case GXEMUL_FB_KEY_F4: |
346 | keybuffer_push(keybuffer,FUNCTION_KEYS | 4 ); |
346 | keybuffer_push(keybuffer,FUNCTION_KEYS | 4 ); |
347 | buf = count = 0; |
347 | buf = count = 0; |
348 | return 1; |
348 | return 1; |
349 | case GXEMUL_FB_KEY_F5: |
349 | case GXEMUL_FB_KEY_F5: |
350 | keybuffer_push(keybuffer,FUNCTION_KEYS | 5 ); |
350 | keybuffer_push(keybuffer,FUNCTION_KEYS | 5 ); |
351 | buf = count = 0; |
351 | buf = count = 0; |
352 | return 1; |
352 | return 1; |
353 | case GXEMUL_FB_KEY_F6: |
353 | case GXEMUL_FB_KEY_F6: |
354 | keybuffer_push(keybuffer,FUNCTION_KEYS | 6 ); |
354 | keybuffer_push(keybuffer,FUNCTION_KEYS | 6 ); |
355 | buf = count = 0; |
355 | buf = count = 0; |
356 | return 1; |
356 | return 1; |
357 | case GXEMUL_FB_KEY_F7: |
357 | case GXEMUL_FB_KEY_F7: |
358 | keybuffer_push(keybuffer,FUNCTION_KEYS | 7 ); |
358 | keybuffer_push(keybuffer,FUNCTION_KEYS | 7 ); |
359 | buf = count = 0; |
359 | buf = count = 0; |
360 | return 1; |
360 | return 1; |
361 | case GXEMUL_FB_KEY_F8: |
361 | case GXEMUL_FB_KEY_F8: |
362 | keybuffer_push(keybuffer,FUNCTION_KEYS | 8 ); |
362 | keybuffer_push(keybuffer,FUNCTION_KEYS | 8 ); |
363 | buf = count = 0; |
363 | buf = count = 0; |
364 | return 1; |
364 | return 1; |
365 | case GXEMUL_FB_KEY_F9: |
365 | case GXEMUL_FB_KEY_F9: |
366 | keybuffer_push(keybuffer,FUNCTION_KEYS | 9 ); |
366 | keybuffer_push(keybuffer,FUNCTION_KEYS | 9 ); |
367 | buf = count = 0; |
367 | buf = count = 0; |
368 | return 1; |
368 | return 1; |
369 | case GXEMUL_FB_KEY_F10: |
369 | case GXEMUL_FB_KEY_F10: |
370 | keybuffer_push(keybuffer,FUNCTION_KEYS | 10 ); |
370 | keybuffer_push(keybuffer,FUNCTION_KEYS | 10 ); |
371 | buf = count = 0; |
371 | buf = count = 0; |
372 | return 1; |
372 | return 1; |
373 | case GXEMUL_FB_KEY_F11: |
373 | case GXEMUL_FB_KEY_F11: |
374 | keybuffer_push(keybuffer,FUNCTION_KEYS | 11 ); |
374 | keybuffer_push(keybuffer,FUNCTION_KEYS | 11 ); |
375 | buf = count = 0; |
375 | buf = count = 0; |
376 | return 1; |
376 | return 1; |
377 | case GXEMUL_FB_KEY_F12: |
377 | case GXEMUL_FB_KEY_F12: |
378 | keybuffer_push(keybuffer,FUNCTION_KEYS | 12 ); |
378 | keybuffer_push(keybuffer,FUNCTION_KEYS | 12 ); |
379 | buf = count = 0; |
379 | buf = count = 0; |
380 | return 1; |
380 | return 1; |
381 | default: |
381 | default: |
382 | keybuffer_push(keybuffer, buf & 0xff ); |
382 | keybuffer_push(keybuffer, buf & 0xff ); |
383 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
383 | keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
384 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
384 | keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
385 | keybuffer_push(keybuffer, (buf >> 24) & 0xff); |
385 | keybuffer_push(keybuffer, (buf >> 24) & 0xff); |
386 | buf = count = 0; |
386 | buf = count = 0; |
387 | return 1; |
387 | return 1; |
388 | } |
388 | } |
389 | 389 | ||
390 | return 1; |
390 | return 1; |
391 | } |
391 | } |
392 | 392 | ||
393 | 393 | ||
394 | /** Initializes keyboard handler. */ |
394 | /** Initializes keyboard handler. */ |
395 | int kbd_arch_init(void) |
395 | int kbd_arch_init(void) |
396 | { |
396 | { |
397 | fb = (sysinfo_value("fb.kind") == 1); |
397 | fb = (sysinfo_value("fb.kind") == 1); |
398 | gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual"); |
398 | gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual"); |
399 | ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &gxemul_kbd); |
399 | ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &gxemul_kbd); |
400 | return 0; |
400 | return 0; |
401 | } |
401 | } |
402 | 402 | ||
403 | 403 | ||
404 | /** Process data sent when a key is pressed. |
404 | /** Process data sent when a key is pressed. |
405 | * |
405 | * |
406 | * @param keybuffer Buffer of pressed keys. |
406 | * @param keybuffer Buffer of pressed keys. |
407 | * @param call IPC call. |
407 | * @param call IPC call. |
408 | * |
408 | * |
409 | * @return Always 1. |
409 | * @return Always 1. |
410 | */ |
410 | */ |
411 | int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
411 | int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
412 | { |
412 | { |
413 | int scan_code = IPC_GET_ARG2(*call); |
413 | int scan_code = IPC_GET_ARG2(*call); |
414 | 414 | ||
415 | if (fb) { |
415 | if (fb) { |
416 | return gxemul_kbd_process_fb(keybuffer, scan_code); |
416 | return gxemul_kbd_process_fb(keybuffer, scan_code); |
417 | } else { |
417 | } else { |
418 | return gxemul_kbd_process_no_fb(keybuffer, scan_code); |
418 | return gxemul_kbd_process_no_fb(keybuffer, scan_code); |
419 | } |
419 | } |
420 | 420 | ||
421 | } |
421 | } |
422 | 422 | ||
423 | /** @} |
423 | /** @} |
424 | */ |
424 | */ |
425 | 425 |