2 * Copyright 2009-2011, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Michael Lotz <mmlr@mlotz.ch>
10 #include <debugger_keymaps.h>
12 static bool sUseUSBKeyboard
= false;
13 static uint8 sUSBTransferData
[64];
14 static uint8 sLastTransferData
[64];
15 static size_t sUSBTransferLength
= 0;
16 static void *sUSBPipe
= NULL
;
19 static int sBufferedChars
[32];
20 static uint8 sBufferSize
= sizeof(sBufferedChars
) / sizeof(sBufferedChars
[0]);
21 static uint8 sBufferedCharCount
= 0;
22 static uint8 sBufferWriteIndex
= 0;
23 static uint8 sBufferReadIndex
= 0;
25 #define MODIFIER_CONTROL 0x01
26 #define MODIFIER_SHIFT 0x02
27 #define MODIFIER_ALT 0x04
29 static uint32 sModifierTable
[] = {
40 static uint8 sKeyTable
[] = {
113 0, // Pause (0x7f with Ctrl)
116 0x80 | '5', // Page up
117 0x80 | '3', // Delete
119 0x80 | '6', // Page down
120 0x80 | 'C', // Right arrow
121 0x80 | 'D', // Left arrow
122 0x80 | 'B', // Down arrow
123 0x80 | 'A', // Up arrow
147 static size_t sKeyTableSize
= sizeof(sKeyTable
) / sizeof(sKeyTable
[0]);
153 if (!has_debugger_command("get_usb_keyboard_config")
154 || !has_debugger_command("get_usb_pipe_for_id")
155 || !has_debugger_command("usb_process_transfer")) {
159 unset_debug_variable("_usbPipe");
160 unset_debug_variable("_usbReportSize");
162 evaluate_debug_command("get_usb_keyboard_config");
163 sUSBTransferLength
= get_debug_variable("_usbReportSize", 0);
164 if (sUSBTransferLength
== 0 || sUSBTransferLength
> sizeof(sUSBTransferData
))
167 evaluate_debug_command("get_usb_pipe_for_id");
168 sUSBPipe
= (void *)get_debug_variable("_usbPipe", 0);
169 if (sUSBPipe
== NULL
)
172 sUseUSBKeyboard
= true;
179 if (sUseUSBKeyboard
) {
180 // make sure a possibly pending transfer is canceled
181 set_debug_variable("_usbPipe", (uint64
)sUSBPipe
);
182 evaluate_debug_command("usb_process_transfer cancel");
183 sUseUSBKeyboard
= false;
191 sBufferedChars
[sBufferWriteIndex
++] = key
;
192 sBufferWriteIndex
%= sBufferSize
;
193 sBufferedCharCount
++;
198 debugger_getchar(void)
200 if (!sUseUSBKeyboard
)
203 if (sBufferedCharCount
== 0) {
204 set_debug_variable("_usbPipe", (uint64
)sUSBPipe
);
205 set_debug_variable("_usbTransferData", (uint64
)sUSBTransferData
);
206 set_debug_variable("_usbTransferLength", (uint64
)sUSBTransferLength
);
208 status_t status
= evaluate_debug_command("usb_process_transfer");
209 if (status
== B_DEV_PENDING
)
212 if (status
!= B_OK
) {
213 // try clearing a possibly set halt due to toggle mismatches
214 evaluate_debug_command("usb_clear_stall");
218 bool phantomState
= true;
219 for (size_t i
= 2; i
< sUSBTransferLength
; i
++) {
220 if (sUSBTransferData
[i
] != 0x01) {
221 phantomState
= false;
230 for (uint32 i
= 0; i
< 8; i
++) {
231 if (sUSBTransferData
[0] & (1 << i
))
232 modifiers
|= sModifierTable
[i
];
235 uint8
*current
= sUSBTransferData
;
236 uint8
*compare
= sLastTransferData
;
237 for (uint32 i
= 2; i
< sUSBTransferLength
; i
++) {
238 if (current
[i
] == 0x00 || current
[i
] == 0x01)
242 for (uint32 j
= 2; j
< sUSBTransferLength
; j
++) {
243 if (compare
[j
] == current
[i
]) {
252 if (current
[i
] >= sKeyTableSize
)
256 uint8 key
= sKeyTable
[current
[i
]];
264 if (key
== '5' || key
== '6' || key
== '3')
268 } else if (modifiers
& MODIFIER_CONTROL
) {
269 char c
= kShiftedKeymap
[key
];
270 if (c
>= 'A' && c
<= 'Z')
272 } else if (modifiers
& MODIFIER_ALT
)
273 result
= kAltedKeymap
[key
];
274 else if (modifiers
& MODIFIER_SHIFT
)
275 result
= kShiftedKeymap
[key
];
277 result
= kUnshiftedKeymap
[key
];
285 for (uint32 i
= 0; i
< sUSBTransferLength
; i
++)
286 sLastTransferData
[i
] = sUSBTransferData
[i
];
289 if (sBufferedCharCount
== 0)
292 int result
= sBufferedChars
[sBufferReadIndex
++];
293 sBufferReadIndex
%= sBufferSize
;
294 sBufferedCharCount
--;
300 std_ops(int32 op
, ...)
302 if (op
== B_MODULE_INIT
|| op
== B_MODULE_UNINIT
)
309 static struct debugger_module_info sModuleInfo
= {
311 "debugger/usb_keyboard/v1",
322 module_info
*modules
[] = {
323 (module_info
*)&sModuleInfo
,