112660Sandreas.sandberg@arm.com/* 212660Sandreas.sandberg@arm.com * Copyright (c) 2011, 2018 ARM Limited 312660Sandreas.sandberg@arm.com * All rights reserved 412660Sandreas.sandberg@arm.com * 512660Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 612660Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 712660Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 812660Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 912660Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1012660Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1112660Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1212660Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1312660Sandreas.sandberg@arm.com * 1412660Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 1512660Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 1612660Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 1712660Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 1812660Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1912660Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2012660Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2112660Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2212660Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2312660Sandreas.sandberg@arm.com * this software without specific prior written permission. 2412660Sandreas.sandberg@arm.com * 2512660Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2612660Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2712660Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2812660Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2912660Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3012660Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3112660Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3212660Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3312660Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3412660Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3512660Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3612660Sandreas.sandberg@arm.com * 3712660Sandreas.sandberg@arm.com * Authors: Ali Saidi 3812660Sandreas.sandberg@arm.com */ 3912660Sandreas.sandberg@arm.com 4012660Sandreas.sandberg@arm.com#include "dev/ps2/types.hh" 4112660Sandreas.sandberg@arm.com 4212660Sandreas.sandberg@arm.com#include <list> 4312660Sandreas.sandberg@arm.com 4412660Sandreas.sandberg@arm.com#include "base/logging.hh" 4512660Sandreas.sandberg@arm.com#include "x11keysym/keysym.h" 4612660Sandreas.sandberg@arm.com 4712660Sandreas.sandberg@arm.comconst std::vector<uint8_t> Ps2::Keyboard::ID{0xAB, 0x83}; 4812660Sandreas.sandberg@arm.comconst std::vector<uint8_t> Ps2::Mouse::ID{0x00}; 4912660Sandreas.sandberg@arm.com 5012660Sandreas.sandberg@arm.comnamespace Ps2 { 5112660Sandreas.sandberg@arm.com 5212660Sandreas.sandberg@arm.com/** Table to convert simple key symbols (0x00XX) into ps2 bytes. Lower byte 5312660Sandreas.sandberg@arm.com * is the scan code to send and upper byte is if a modifier is required to 5412660Sandreas.sandberg@arm.com * generate it. The table generates us keyboard codes, (e.g. the guest is 5512660Sandreas.sandberg@arm.com * supposed to recognize the keyboard as en_US). A new table would be required 5612660Sandreas.sandberg@arm.com * for another locale. 5712660Sandreas.sandberg@arm.com */ 5812660Sandreas.sandberg@arm.com 5912660Sandreas.sandberg@arm.comstatic const uint16_t keySymToPs2Byte[128] = { 6012660Sandreas.sandberg@arm.com// 0 / 8 1 / 9 2 / A 3 / B 4 / C 5 / D 6 / E 7 / F 6112660Sandreas.sandberg@arm.com 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00-0x07 6212660Sandreas.sandberg@arm.com 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x08-0x0f 6312660Sandreas.sandberg@arm.com 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x10-0x17 6412660Sandreas.sandberg@arm.com 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x18-0x1f 6512660Sandreas.sandberg@arm.com 0x0029, 0x0116, 0x0152, 0x0126, 0x0125, 0x012e, 0x013d, 0x0052, // 0x20-0x27 6612660Sandreas.sandberg@arm.com 0x0146, 0x0145, 0x013e, 0x0155, 0x0041, 0x004e, 0x0049, 0x004a, // 0x28-0x2f 6712660Sandreas.sandberg@arm.com 0x0045, 0x0016, 0x001e, 0x0026, 0x0025, 0x002e, 0x0036, 0x003d, // 0x30-0x37 6812660Sandreas.sandberg@arm.com 0x003e, 0x0046, 0x014c, 0x004c, 0x0141, 0x0055, 0x0149, 0x014a, // 0x38-0x3f 6912660Sandreas.sandberg@arm.com 0x011e, 0x011c, 0x0132, 0x0121, 0x0123, 0x0124, 0x012b, 0x0134, // 0x40-0x47 7012660Sandreas.sandberg@arm.com 0x0133, 0x0143, 0x013b, 0x0142, 0x014b, 0x013a, 0x0131, 0x0144, // 0x48-0x4f 7112660Sandreas.sandberg@arm.com 0x014d, 0x0115, 0x012d, 0x011b, 0x012c, 0x013c, 0x012a, 0x011d, // 0x50-0x57 7212660Sandreas.sandberg@arm.com 0x0122, 0x0135, 0x011a, 0x0054, 0x005d, 0x005b, 0x0136, 0x014e, // 0x58-0x5f 7312660Sandreas.sandberg@arm.com 0x000e, 0x001c, 0x0032, 0x0021, 0x0023, 0x0024, 0x002b, 0x0034, // 0x60-0x67 7412660Sandreas.sandberg@arm.com 0x0033, 0x0043, 0x003b, 0x0042, 0x004b, 0x003a, 0x0031, 0x0044, // 0x68-0x6f 7512660Sandreas.sandberg@arm.com 0x004d, 0x0015, 0x002d, 0x001b, 0x002c, 0x003c, 0x002a, 0x001d, // 0x70-0x77 7612660Sandreas.sandberg@arm.com 0x0022, 0x0035, 0x001a, 0x0154, 0x015d, 0x015b, 0x010e, 0x0000 // 0x78-0x7f 7712660Sandreas.sandberg@arm.com}; 7812660Sandreas.sandberg@arm.com 7912660Sandreas.sandberg@arm.comconst uint8_t ShiftKey = 0x12; 8012660Sandreas.sandberg@arm.comconst uint8_t BreakKey = 0xf0; 8112660Sandreas.sandberg@arm.comconst uint8_t ExtendedKey = 0xe0; 8212660Sandreas.sandberg@arm.comconst uint32_t UpperKeys = 0xff00; 8312660Sandreas.sandberg@arm.com 8412660Sandreas.sandberg@arm.comvoid 8512660Sandreas.sandberg@arm.comkeySymToPs2(uint32_t key, bool down, bool &cur_shift, 8612660Sandreas.sandberg@arm.com std::list<uint8_t> &keys) 8712660Sandreas.sandberg@arm.com{ 8812660Sandreas.sandberg@arm.com if (key <= XK_asciitilde) { 8912660Sandreas.sandberg@arm.com uint16_t tmp = keySymToPs2Byte[key]; 9012660Sandreas.sandberg@arm.com uint8_t code = tmp & 0xff; 9112660Sandreas.sandberg@arm.com bool shift = tmp >> 8; 9212660Sandreas.sandberg@arm.com 9312660Sandreas.sandberg@arm.com if (down) { 9412660Sandreas.sandberg@arm.com if (!cur_shift && shift) { 9512660Sandreas.sandberg@arm.com keys.push_back(ShiftKey); 9612660Sandreas.sandberg@arm.com cur_shift = true; 9712660Sandreas.sandberg@arm.com } 9812660Sandreas.sandberg@arm.com keys.push_back(code); 9912660Sandreas.sandberg@arm.com } else { 10012660Sandreas.sandberg@arm.com if (cur_shift && !shift) { 10112660Sandreas.sandberg@arm.com keys.push_back(BreakKey); 10212660Sandreas.sandberg@arm.com keys.push_back(ShiftKey); 10312660Sandreas.sandberg@arm.com cur_shift = false; 10412660Sandreas.sandberg@arm.com } 10512660Sandreas.sandberg@arm.com keys.push_back(BreakKey); 10612660Sandreas.sandberg@arm.com keys.push_back(code); 10712660Sandreas.sandberg@arm.com } 10812660Sandreas.sandberg@arm.com } else { 10912660Sandreas.sandberg@arm.com if ((key & UpperKeys) == UpperKeys) { 11012660Sandreas.sandberg@arm.com bool extended = false; 11112660Sandreas.sandberg@arm.com switch (key) { 11212660Sandreas.sandberg@arm.com case XK_BackSpace: 11312660Sandreas.sandberg@arm.com keys.push_back(0x66); 11412660Sandreas.sandberg@arm.com break; 11512660Sandreas.sandberg@arm.com case XK_Tab: 11612660Sandreas.sandberg@arm.com keys.push_back(0x0d); 11712660Sandreas.sandberg@arm.com break; 11812660Sandreas.sandberg@arm.com case XK_Return: 11912660Sandreas.sandberg@arm.com keys.push_back(0x5a); 12012660Sandreas.sandberg@arm.com break; 12112660Sandreas.sandberg@arm.com case XK_Escape: 12212660Sandreas.sandberg@arm.com keys.push_back(0x76); 12312660Sandreas.sandberg@arm.com break; 12412660Sandreas.sandberg@arm.com case XK_Delete: 12512660Sandreas.sandberg@arm.com extended = true; 12612660Sandreas.sandberg@arm.com keys.push_back(0x71); 12712660Sandreas.sandberg@arm.com break; 12812660Sandreas.sandberg@arm.com case XK_Home: 12912660Sandreas.sandberg@arm.com extended = true; 13012660Sandreas.sandberg@arm.com keys.push_back(0x6c); 13112660Sandreas.sandberg@arm.com break; 13212660Sandreas.sandberg@arm.com case XK_Left: 13312660Sandreas.sandberg@arm.com extended = true; 13412660Sandreas.sandberg@arm.com keys.push_back(0x6b); 13512660Sandreas.sandberg@arm.com break; 13612660Sandreas.sandberg@arm.com case XK_Right: 13712660Sandreas.sandberg@arm.com extended = true; 13812660Sandreas.sandberg@arm.com keys.push_back(0x74); 13912660Sandreas.sandberg@arm.com break; 14012660Sandreas.sandberg@arm.com case XK_Down: 14112660Sandreas.sandberg@arm.com extended = true; 14212660Sandreas.sandberg@arm.com keys.push_back(0x72); 14312660Sandreas.sandberg@arm.com break; 14412660Sandreas.sandberg@arm.com case XK_Up: 14512660Sandreas.sandberg@arm.com extended = true; 14612660Sandreas.sandberg@arm.com keys.push_back(0x75); 14712660Sandreas.sandberg@arm.com break; 14812660Sandreas.sandberg@arm.com case XK_Page_Up: 14912660Sandreas.sandberg@arm.com extended = true; 15012660Sandreas.sandberg@arm.com keys.push_back(0x7d); 15112660Sandreas.sandberg@arm.com break; 15212660Sandreas.sandberg@arm.com case XK_Page_Down: 15312660Sandreas.sandberg@arm.com extended = true; 15412660Sandreas.sandberg@arm.com keys.push_back(0x7a); 15512660Sandreas.sandberg@arm.com break; 15612660Sandreas.sandberg@arm.com case XK_End: 15712660Sandreas.sandberg@arm.com extended = true; 15812660Sandreas.sandberg@arm.com keys.push_back(0x69); 15912660Sandreas.sandberg@arm.com break; 16012660Sandreas.sandberg@arm.com case XK_Shift_L: 16112660Sandreas.sandberg@arm.com keys.push_back(0x12); 16212660Sandreas.sandberg@arm.com if (down) 16312660Sandreas.sandberg@arm.com cur_shift = true; 16412660Sandreas.sandberg@arm.com else 16512660Sandreas.sandberg@arm.com cur_shift = false; 16612660Sandreas.sandberg@arm.com break; 16712660Sandreas.sandberg@arm.com case XK_Shift_R: 16812660Sandreas.sandberg@arm.com keys.push_back(0x59); 16912660Sandreas.sandberg@arm.com if (down) 17012660Sandreas.sandberg@arm.com cur_shift = true; 17112660Sandreas.sandberg@arm.com else 17212660Sandreas.sandberg@arm.com cur_shift = false; 17312660Sandreas.sandberg@arm.com break; 17412660Sandreas.sandberg@arm.com case XK_Control_L: 17512660Sandreas.sandberg@arm.com keys.push_back(0x14); 17612660Sandreas.sandberg@arm.com break; 17712660Sandreas.sandberg@arm.com case XK_Control_R: 17812660Sandreas.sandberg@arm.com extended = true; 17912660Sandreas.sandberg@arm.com keys.push_back(0x14); 18012660Sandreas.sandberg@arm.com break; 18112660Sandreas.sandberg@arm.com case XK_Alt_L: 18212660Sandreas.sandberg@arm.com keys.push_back(0x11); 18312660Sandreas.sandberg@arm.com break; 18412660Sandreas.sandberg@arm.com case XK_Alt_R: 18512660Sandreas.sandberg@arm.com extended = true; 18612660Sandreas.sandberg@arm.com keys.push_back(0x11); 18712660Sandreas.sandberg@arm.com break; 18812660Sandreas.sandberg@arm.com default: 18912660Sandreas.sandberg@arm.com warn("Unknown extended key %#x\n", key); 19012660Sandreas.sandberg@arm.com return; 19112660Sandreas.sandberg@arm.com } 19212660Sandreas.sandberg@arm.com 19312660Sandreas.sandberg@arm.com if (extended) { 19412660Sandreas.sandberg@arm.com if (down) { 19512660Sandreas.sandberg@arm.com keys.push_front(ExtendedKey); 19612660Sandreas.sandberg@arm.com } else { 19712660Sandreas.sandberg@arm.com keys.push_front(BreakKey); 19812660Sandreas.sandberg@arm.com keys.push_front(ExtendedKey); 19912660Sandreas.sandberg@arm.com } 20012660Sandreas.sandberg@arm.com } else { 20112660Sandreas.sandberg@arm.com if (!down) 20212660Sandreas.sandberg@arm.com keys.push_front(BreakKey); 20312660Sandreas.sandberg@arm.com } 20412660Sandreas.sandberg@arm.com } // upper keys 20512660Sandreas.sandberg@arm.com } // extended keys 20612660Sandreas.sandberg@arm.com return; 20712660Sandreas.sandberg@arm.com} 20812660Sandreas.sandberg@arm.com 20912660Sandreas.sandberg@arm.com} /* namespace Ps2 */ 21012660Sandreas.sandberg@arm.com 211