6adbb9e438
Issue #1082
169 lines
6.7 KiB
C++
169 lines
6.7 KiB
C++
/*
|
|
* \brief Keyboard manager
|
|
* \author Markus Partheymueller
|
|
* \date 2012-07-31
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2012 Intel Corporation
|
|
* Copyright (C) 2013 Genode Labs GmbH
|
|
*
|
|
* This file is distributed under the terms of the GNU General Public License
|
|
* version 2.
|
|
*
|
|
* The code is partially based on the Vancouver VMM, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*
|
|
* Modifications by Intel Corporation are contributed under the terms and
|
|
* conditions of the GNU General Public License version 2.
|
|
*/
|
|
|
|
/* local includes */
|
|
#include "keyboard.h"
|
|
|
|
/* vancouver generic keyboard helper */
|
|
#include <host/keyboard.h>
|
|
#include <nul/vcpu.h>
|
|
|
|
|
|
Vancouver_keyboard::Vancouver_keyboard(Synced_motherboard &mb)
|
|
: _motherboard(mb), _flags(0) { }
|
|
|
|
|
|
void Vancouver_keyboard::handle_keycode_press(unsigned keycode)
|
|
{
|
|
unsigned orig_keycode = keycode;
|
|
|
|
switch (keycode) {
|
|
|
|
/* modifiers */
|
|
case Input::KEY_LEFTSHIFT: _flags |= KBFLAG_LSHIFT; keycode = 0x12; break;
|
|
case Input::KEY_RIGHTSHIFT: _flags |= KBFLAG_RSHIFT; keycode = 0x59; break;
|
|
case Input::KEY_LEFTALT: _flags |= KBFLAG_LALT; keycode = 0x11; break;
|
|
case Input::KEY_RIGHTALT: _flags |= KBFLAG_RALT; keycode = 0x11; break;
|
|
case Input::KEY_LEFTCTRL: _flags |= KBFLAG_LCTRL; keycode = 0x14; break;
|
|
case Input::KEY_RIGHTCTRL: _flags |= KBFLAG_RCTRL; keycode = 0x14; break;
|
|
case Input::KEY_LEFTMETA: _flags |= KBFLAG_LWIN; keycode = 0x1f; return;
|
|
case Input::KEY_RIGHTMETA: _flags |= KBFLAG_RWIN; keycode = 0x27; return;
|
|
|
|
case Input::KEY_KPSLASH: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x35); break;
|
|
case Input::KEY_KPENTER: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x1c); break;
|
|
case Input::KEY_F11: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x57); break;
|
|
case Input::KEY_F12: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x58); break;
|
|
case Input::KEY_INSERT: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x52); break;
|
|
case Input::KEY_DELETE: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x53); break;
|
|
case Input::KEY_HOME: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x47); break;
|
|
case Input::KEY_END: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4f); break;
|
|
case Input::KEY_PAGEUP: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x49); break;
|
|
case Input::KEY_PAGEDOWN: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x51); break;
|
|
case Input::KEY_LEFT: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4b); break;
|
|
case Input::KEY_RIGHT: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4d); break;
|
|
case Input::KEY_UP: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x48); break;
|
|
case Input::KEY_DOWN: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x50); break;
|
|
|
|
/* up to 0x53, the Genode key codes correspond to scan code set 1 */
|
|
default:
|
|
if (keycode <= 0x53) {
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(keycode);
|
|
break;
|
|
} else return;
|
|
}
|
|
|
|
MessageInput msg(0x10000, _flags | keycode);
|
|
|
|
/* debug */
|
|
if ((_flags & KBFLAG_LWIN) && orig_keycode == Input::KEY_INSERT) {
|
|
Logging::printf("DEBUG key\n");
|
|
|
|
/* we send an empty event */
|
|
CpuEvent msg(VCpu::EVENT_DEBUG);
|
|
for (VCpu *vcpu = _motherboard()->last_vcpu; vcpu; vcpu=vcpu->get_last())
|
|
vcpu->bus_event.send(msg);
|
|
}
|
|
|
|
/* reset */
|
|
else if ((_flags & KBFLAG_LWIN) && orig_keycode == Input::KEY_END) {
|
|
Logging::printf("Reset VM\n");
|
|
MessageLegacy msg2(MessageLegacy::RESET, 0);
|
|
_motherboard()->bus_legacy.send_fifo(msg2);
|
|
}
|
|
|
|
else _motherboard()->bus_input.send(msg);
|
|
|
|
_flags &= ~(KBFLAG_EXTEND0 | KBFLAG_RELEASE | KBFLAG_EXTEND1);
|
|
}
|
|
|
|
|
|
void Vancouver_keyboard::handle_keycode_release(unsigned keycode)
|
|
{
|
|
_flags |= KBFLAG_RELEASE;
|
|
|
|
switch (keycode) {
|
|
|
|
/* modifiers */
|
|
case Input::KEY_LEFTSHIFT: _flags |= KBFLAG_LSHIFT; keycode = 0x12; break;
|
|
case Input::KEY_RIGHTSHIFT: _flags |= KBFLAG_RSHIFT; keycode = 0x59; break;
|
|
case Input::KEY_LEFTALT: _flags |= KBFLAG_LALT; keycode = 0x11; break;
|
|
case Input::KEY_RIGHTALT: _flags |= KBFLAG_RALT; keycode = 0x11; break;
|
|
case Input::KEY_LEFTCTRL: _flags |= KBFLAG_LCTRL; keycode = 0x14; break;
|
|
case Input::KEY_RIGHTCTRL: _flags |= KBFLAG_RCTRL; keycode = 0x14; break;
|
|
case Input::KEY_LEFTMETA: _flags |= KBFLAG_LWIN; keycode = 0x1f; break;
|
|
case Input::KEY_RIGHTMETA: _flags |= KBFLAG_RWIN; keycode = 0x27; break;
|
|
|
|
case Input::KEY_KPSLASH: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x35); break;
|
|
case Input::KEY_KPENTER: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x1c); break;
|
|
case Input::KEY_F11: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x57); break;
|
|
case Input::KEY_F12: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x58); break;
|
|
case Input::KEY_INSERT: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x52); break;
|
|
case Input::KEY_DELETE: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x53); break;
|
|
case Input::KEY_HOME: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x47); break;
|
|
case Input::KEY_END: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4f); break;
|
|
case Input::KEY_PAGEUP: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x49); break;
|
|
case Input::KEY_PAGEDOWN: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x51); break;
|
|
case Input::KEY_LEFT: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4b); break;
|
|
case Input::KEY_RIGHT: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4d); break;
|
|
case Input::KEY_UP: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x48); break;
|
|
case Input::KEY_DOWN: _flags |= KBFLAG_EXTEND0;
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(0x50); break;
|
|
|
|
/* up to 0x53, the Genode key codes correspond to scan code set 1 */
|
|
default:
|
|
if (keycode <= 0x53) {
|
|
keycode = GenericKeyboard::translate_sc1_to_sc2(keycode);
|
|
break;
|
|
} else return;
|
|
}
|
|
|
|
MessageInput msg(0x10000, _flags | keycode);
|
|
_motherboard()->bus_input.send(msg);
|
|
|
|
_flags &= ~(KBFLAG_EXTEND0 | KBFLAG_RELEASE | KBFLAG_EXTEND1);
|
|
}
|