15912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown/* 25912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Copyright (C) 2010 The Android Open Source Project 35912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * 45912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 55912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * you may not use this file except in compliance with the License. 65912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * You may obtain a copy of the License at 75912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * 85912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 95912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * 105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Unless required by applicable law or agreed to in writing, software 115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * See the License for the specific language governing permissions and 145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * limitations under the License. 155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */ 165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#define LOG_TAG "Keyboard" 185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <stdlib.h> 205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <unistd.h> 215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <limits.h> 225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <input/Keyboard.h> 24872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright#include <input/InputEventLabels.h> 255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <input/KeyLayoutMap.h> 265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <input/KeyCharacterMap.h> 275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <input/InputDevice.h> 285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <utils/Errors.h> 295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <utils/Log.h> 305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownnamespace android { 325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- KeyMap --- 345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownKeyMap::KeyMap() { 365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownKeyMap::~KeyMap() { 395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier, 425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const PropertyMap* deviceConfiguration) { 435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Use the configured key layout if available. 445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (deviceConfiguration) { 455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown String8 keyLayoutName; 465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"), 475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown keyLayoutName)) { 485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown status_t status = loadKeyLayout(deviceIdenfifier, keyLayoutName); 495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (status == NAME_NOT_FOUND) { 505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but " 515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown "it was not found.", 525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown deviceIdenfifier.name.string(), keyLayoutName.string()); 535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown String8 keyCharacterMapName; 575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"), 585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown keyCharacterMapName)) { 595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown status_t status = loadKeyCharacterMap(deviceIdenfifier, keyCharacterMapName); 605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (status == NAME_NOT_FOUND) { 615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ALOGE("Configuration for keyboard device '%s' requested keyboard character " 625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown "map '%s' but it was not found.", 635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown deviceIdenfifier.name.string(), keyLayoutName.string()); 645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (isComplete()) { 685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return OK; 695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Try searching by device identifier. 735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (probeKeyMap(deviceIdenfifier, String8::empty())) { 745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return OK; 755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Fall back on the Generic key map. 785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // TODO Apply some additional heuristics here to figure out what kind of 795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // generic key map to use (US English, etc.) for typical external keyboards. 805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (probeKeyMap(deviceIdenfifier, String8("Generic"))) { 815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return OK; 825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Try the Virtual key map as a last resort. 855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (probeKeyMap(deviceIdenfifier, String8("Virtual"))) { 865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return OK; 875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Give up! 905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ALOGE("Could not determine key map for device '%s' and no default key maps were found!", 915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown deviceIdenfifier.name.string()); 925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return NAME_NOT_FOUND; 935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, 965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const String8& keyMapName) { 975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (!haveKeyLayout()) { 985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown loadKeyLayout(deviceIdentifier, keyMapName); 995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (!haveKeyCharacterMap()) { 1015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown loadKeyCharacterMap(deviceIdentifier, keyMapName); 1025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return isComplete(); 1045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 1055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, 1075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const String8& name) { 1085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown String8 path(getPath(deviceIdentifier, name, 1095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT)); 1105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (path.isEmpty()) { 1115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return NAME_NOT_FOUND; 1125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown status_t status = KeyLayoutMap::load(path, &keyLayoutMap); 1155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (status) { 1165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return status; 1175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown keyLayoutFile.setTo(path); 1205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return OK; 1215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 1225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier, 1245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const String8& name) { 1255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown String8 path(getPath(deviceIdentifier, name, 1265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP)); 1275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (path.isEmpty()) { 1285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return NAME_NOT_FOUND; 1295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown status_t status = KeyCharacterMap::load(path, 1325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown KeyCharacterMap::FORMAT_BASE, &keyCharacterMap); 1335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (status) { 1345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return status; 1355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown keyCharacterMapFile.setTo(path); 1385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return OK; 1395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 1405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownString8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier, 1425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const String8& name, InputDeviceConfigurationFileType type) { 1435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return name.isEmpty() 1445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type) 1455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown : getInputDeviceConfigurationFilePathByName(name, type); 1465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 1475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- Global functions --- 1505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier, 1525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const PropertyMap* deviceConfiguration, const KeyMap* keyMap) { 1535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (!keyMap->haveKeyCharacterMap() 1545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown || keyMap->keyCharacterMap->getKeyboardType() 1555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown == KeyCharacterMap::KEYBOARD_TYPE_SPECIAL_FUNCTION) { 1565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return false; 1575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (deviceConfiguration) { 1605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool builtIn = false; 1615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (deviceConfiguration->tryGetProperty(String8("keyboard.builtIn"), builtIn) 1625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown && builtIn) { 1635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return true; 1645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return strstr(deviceIdentifier.name.string(), "-keypad"); 1685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 1695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatic int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) { 1715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown int32_t newMetaState; 1725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (down) { 1735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown newMetaState = oldMetaState | mask; 1745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } else { 1755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown newMetaState = oldMetaState & 1765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON); 1775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 179115f93eeebf7f33b56ed090de70d6e8c733e5d88Dmitry Torokhov return normalizeMetaState(newMetaState); 180115f93eeebf7f33b56ed090de70d6e8c733e5d88Dmitry Torokhov} 181115f93eeebf7f33b56ed090de70d6e8c733e5d88Dmitry Torokhov 182115f93eeebf7f33b56ed090de70d6e8c733e5d88Dmitry Torokhovint32_t normalizeMetaState(int32_t oldMetaState) { 183115f93eeebf7f33b56ed090de70d6e8c733e5d88Dmitry Torokhov int32_t newMetaState = oldMetaState; 1845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { 1855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown newMetaState |= AMETA_ALT_ON; 1865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) { 1895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown newMetaState |= AMETA_SHIFT_ON; 1905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (newMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) { 1935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown newMetaState |= AMETA_CTRL_ON; 1945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (newMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) { 1975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown newMetaState |= AMETA_META_ON; 1985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return newMetaState; 2005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 2015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatic int32_t toggleLockedMetaState(int32_t mask, bool down, int32_t oldMetaState) { 2035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown if (down) { 2045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return oldMetaState; 2055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } else { 2065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return oldMetaState ^ mask; 2075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 2085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 2095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownint32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) { 2115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown int32_t mask; 2125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown switch (keyCode) { 2135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_ALT_LEFT: 2145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_ALT_LEFT_ON, down, oldMetaState); 2155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_ALT_RIGHT: 2165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_ALT_RIGHT_ON, down, oldMetaState); 2175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_SHIFT_LEFT: 2185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_SHIFT_LEFT_ON, down, oldMetaState); 2195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_SHIFT_RIGHT: 2205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_SHIFT_RIGHT_ON, down, oldMetaState); 2215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_SYM: 2225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_SYM_ON, down, oldMetaState); 2235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_FUNCTION: 2245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_FUNCTION_ON, down, oldMetaState); 2255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_CTRL_LEFT: 2265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_CTRL_LEFT_ON, down, oldMetaState); 2275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_CTRL_RIGHT: 2285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_CTRL_RIGHT_ON, down, oldMetaState); 2295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_META_LEFT: 2305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_META_LEFT_ON, down, oldMetaState); 2315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_META_RIGHT: 2325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return setEphemeralMetaState(AMETA_META_RIGHT_ON, down, oldMetaState); 2335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_CAPS_LOCK: 2345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return toggleLockedMetaState(AMETA_CAPS_LOCK_ON, down, oldMetaState); 2355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_NUM_LOCK: 2365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return toggleLockedMetaState(AMETA_NUM_LOCK_ON, down, oldMetaState); 2375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_SCROLL_LOCK: 2385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return toggleLockedMetaState(AMETA_SCROLL_LOCK_ON, down, oldMetaState); 2395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown default: 2405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return oldMetaState; 2415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 2425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 2435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool isMetaKey(int32_t keyCode) { 2455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown switch (keyCode) { 2465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_ALT_LEFT: 2475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_ALT_RIGHT: 2485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_SHIFT_LEFT: 2495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_SHIFT_RIGHT: 2505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_SYM: 2515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_FUNCTION: 2525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_CTRL_LEFT: 2535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_CTRL_RIGHT: 2545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_META_LEFT: 2555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_META_RIGHT: 2565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_CAPS_LOCK: 2575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_NUM_LOCK: 2585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown case AKEYCODE_SCROLL_LOCK: 2595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return true; 2605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown default: 2615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return false; 2625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 2635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} 2645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} // namespace android 267