Loading include/androidfw/KeyCharacterMap.h +9 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,10 @@ public: bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars, Vector<KeyEvent>& outEvents) const; /* Maps a scan code and usage code to a key code, in case this key map overrides * the mapping in some way. */ status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const; #if HAVE_ANDROID_OS /* Reads a key map from a parcel. */ static sp<KeyCharacterMap> readFromParcel(Parcel* parcel); Loading Loading @@ -198,6 +202,8 @@ private: private: status_t parseType(); status_t parseMap(); status_t parseMapKey(); status_t parseKey(); status_t parseKeyProperty(); status_t parseModifier(const String8& token, int32_t* outMetaState); Loading @@ -209,6 +215,9 @@ private: KeyedVector<int32_t, Key*> mKeys; int mType; KeyedVector<int32_t, int32_t> mKeysByScanCode; KeyedVector<int32_t, int32_t> mKeysByUsageCode; KeyCharacterMap(); KeyCharacterMap(const KeyCharacterMap& other); Loading libs/androidfw/KeyCharacterMap.cpp +99 −1 Original line number Diff line number Diff line Loading @@ -90,7 +90,8 @@ KeyCharacterMap::KeyCharacterMap() : } KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) : RefBase(), mType(other.mType) { RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode), mKeysByUsageCode(other.mKeysByUsageCode) { for (size_t i = 0; i < other.mKeys.size(); i++) { mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i))); } Loading Loading @@ -180,6 +181,16 @@ sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base, map->mKeys.add(keyCode, new Key(*key)); } } for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) { map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i), overlay->mKeysByScanCode.valueAt(i)); } for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) { map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i), overlay->mKeysByUsageCode.valueAt(i)); } return map; } Loading Loading @@ -315,6 +326,37 @@ bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t return true; } status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const { if (usageCode) { ssize_t index = mKeysByUsageCode.indexOfKey(usageCode); if (index >= 0) { #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", scanCode, usageCode, *outKeyCode); #endif *outKeyCode = mKeysByUsageCode.valueAt(index); return OK; } } if (scanCode) { ssize_t index = mKeysByScanCode.indexOfKey(scanCode); if (index >= 0) { #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", scanCode, usageCode, *outKeyCode); #endif *outKeyCode = mKeysByScanCode.valueAt(index); return OK; } } #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode); #endif *outKeyCode = AKEYCODE_UNKNOWN; return NAME_NOT_FOUND; } bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { ssize_t index = mKeys.indexOfKey(keyCode); if (index >= 0) { Loading Loading @@ -616,6 +658,10 @@ status_t KeyCharacterMap::Parser::parse() { mTokenizer->skipDelimiters(WHITESPACE); status_t status = parseType(); if (status) return status; } else if (keywordToken == "map") { mTokenizer->skipDelimiters(WHITESPACE); status_t status = parseMap(); if (status) return status; } else if (keywordToken == "key") { mTokenizer->skipDelimiters(WHITESPACE); status_t status = parseKey(); Loading Loading @@ -710,6 +756,58 @@ status_t KeyCharacterMap::Parser::parseType() { return NO_ERROR; } status_t KeyCharacterMap::Parser::parseMap() { String8 keywordToken = mTokenizer->nextToken(WHITESPACE); if (keywordToken == "key") { mTokenizer->skipDelimiters(WHITESPACE); return parseMapKey(); } ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(), keywordToken.string()); return BAD_VALUE; } status_t KeyCharacterMap::Parser::parseMapKey() { String8 codeToken = mTokenizer->nextToken(WHITESPACE); bool mapUsage = false; if (codeToken == "usage") { mapUsage = true; mTokenizer->skipDelimiters(WHITESPACE); codeToken = mTokenizer->nextToken(WHITESPACE); } char* end; int32_t code = int32_t(strtol(codeToken.string(), &end, 0)); if (*end) { ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } KeyedVector<int32_t, int32_t>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; if (map.indexOfKey(code) >= 0) { ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } mTokenizer->skipDelimiters(WHITESPACE); String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string()); if (!keyCode) { ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(), keyCodeToken.string()); return BAD_VALUE; } #if DEBUG_PARSER ALOGD("Parsed map key %s: code=%d, keyCode=%d.", mapUsage ? "usage" : "scan code", code, keyCode); #endif map.add(code, keyCode); return NO_ERROR; } status_t KeyCharacterMap::Parser::parseKey() { String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string()); Loading libs/androidfw/KeyLayoutMap.cpp +19 −9 Original line number Diff line number Diff line Loading @@ -199,17 +199,26 @@ status_t KeyLayoutMap::Parser::parse() { } status_t KeyLayoutMap::Parser::parseKey() { String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE); String8 codeToken = mTokenizer->nextToken(WHITESPACE); bool mapUsage = false; if (codeToken == "usage") { mapUsage = true; mTokenizer->skipDelimiters(WHITESPACE); codeToken = mTokenizer->nextToken(WHITESPACE); } char* end; int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0)); int32_t code = int32_t(strtol(codeToken.string(), &end, 0)); if (*end) { ALOGE("%s: Expected key scan code number, got '%s'.", mTokenizer->getLocation().string(), scanCodeToken.string()); ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } if (mMap->mKeysByScanCode.indexOfKey(scanCode) >= 0) { ALOGE("%s: Duplicate entry for key scan code '%s'.", mTokenizer->getLocation().string(), scanCodeToken.string()); KeyedVector<int32_t, Key>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; if (map.indexOfKey(code) >= 0) { ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } Loading Loading @@ -243,12 +252,13 @@ status_t KeyLayoutMap::Parser::parseKey() { } #if DEBUG_PARSER ALOGD("Parsed key: scanCode=%d, keyCode=%d, flags=0x%08x.", scanCode, keyCode, flags); ALOGD("Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.", mapUsage ? "usage" : "scan code", code, keyCode, flags); #endif Key key; key.keyCode = keyCode; key.flags = flags; mMap->mKeysByScanCode.add(scanCode, key); map.add(code, key); return NO_ERROR; } Loading packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm +35 −7 Original line number Diff line number Diff line Loading @@ -19,10 +19,38 @@ type OVERLAY # Test key A { label: 'X' base: 'x' shift, capslock: 'X' ctrl, alt, meta: none } map key 12 LEFT_BRACKET map key 13 RIGHT_BRACKET map key 16 APOSTROPHE map key 17 COMMA map key 18 PERIOD map key 19 P map key 20 Y map key 21 F map key 22 G map key 23 C map key 24 R map key 25 L map key 26 SLASH map key 27 EQUALS map key 30 A map key 31 O map key 32 E map key 33 U map key 34 I map key 35 D map key 36 H map key 37 T map key 38 N map key 39 S map key 40 MINUS map key 44 SEMICOLON map key 45 Q map key 46 J map key 47 K map key 48 X map key 49 B map key 50 M map key 51 W map key 52 V map key 53 Z services/input/EventHub.cpp +17 −9 Original line number Diff line number Diff line Loading @@ -443,13 +443,24 @@ status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); if (device && device->keyMap.haveKeyLayout()) { status_t err = device->keyMap.keyLayoutMap->mapKey( scanCode, usageCode, outKeycode, outFlags); if (err == NO_ERROR) { if (device) { // Check the key character map first. sp<KeyCharacterMap> kcm = device->getKeyCharacterMap(); if (kcm != NULL) { if (!kcm->mapKey(scanCode, usageCode, outKeycode)) { *outFlags = 0; return NO_ERROR; } } // Check the key layout next. if (device->keyMap.haveKeyLayout()) { if (!device->keyMap.keyLayoutMap->mapKey( scanCode, usageCode, outKeycode, outFlags)) { return NO_ERROR; } } } *outKeycode = 0; *outFlags = 0; Loading Loading @@ -531,10 +542,7 @@ sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); if (device) { if (device->combinedKeyMap != NULL) { return device->combinedKeyMap; } return device->keyMap.keyCharacterMap; return device->getKeyCharacterMap(); } return NULL; } Loading Loading
include/androidfw/KeyCharacterMap.h +9 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,10 @@ public: bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars, Vector<KeyEvent>& outEvents) const; /* Maps a scan code and usage code to a key code, in case this key map overrides * the mapping in some way. */ status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const; #if HAVE_ANDROID_OS /* Reads a key map from a parcel. */ static sp<KeyCharacterMap> readFromParcel(Parcel* parcel); Loading Loading @@ -198,6 +202,8 @@ private: private: status_t parseType(); status_t parseMap(); status_t parseMapKey(); status_t parseKey(); status_t parseKeyProperty(); status_t parseModifier(const String8& token, int32_t* outMetaState); Loading @@ -209,6 +215,9 @@ private: KeyedVector<int32_t, Key*> mKeys; int mType; KeyedVector<int32_t, int32_t> mKeysByScanCode; KeyedVector<int32_t, int32_t> mKeysByUsageCode; KeyCharacterMap(); KeyCharacterMap(const KeyCharacterMap& other); Loading
libs/androidfw/KeyCharacterMap.cpp +99 −1 Original line number Diff line number Diff line Loading @@ -90,7 +90,8 @@ KeyCharacterMap::KeyCharacterMap() : } KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) : RefBase(), mType(other.mType) { RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode), mKeysByUsageCode(other.mKeysByUsageCode) { for (size_t i = 0; i < other.mKeys.size(); i++) { mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i))); } Loading Loading @@ -180,6 +181,16 @@ sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base, map->mKeys.add(keyCode, new Key(*key)); } } for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) { map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i), overlay->mKeysByScanCode.valueAt(i)); } for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) { map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i), overlay->mKeysByUsageCode.valueAt(i)); } return map; } Loading Loading @@ -315,6 +326,37 @@ bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t return true; } status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const { if (usageCode) { ssize_t index = mKeysByUsageCode.indexOfKey(usageCode); if (index >= 0) { #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", scanCode, usageCode, *outKeyCode); #endif *outKeyCode = mKeysByUsageCode.valueAt(index); return OK; } } if (scanCode) { ssize_t index = mKeysByScanCode.indexOfKey(scanCode); if (index >= 0) { #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", scanCode, usageCode, *outKeyCode); #endif *outKeyCode = mKeysByScanCode.valueAt(index); return OK; } } #if DEBUG_MAPPING ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode); #endif *outKeyCode = AKEYCODE_UNKNOWN; return NAME_NOT_FOUND; } bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { ssize_t index = mKeys.indexOfKey(keyCode); if (index >= 0) { Loading Loading @@ -616,6 +658,10 @@ status_t KeyCharacterMap::Parser::parse() { mTokenizer->skipDelimiters(WHITESPACE); status_t status = parseType(); if (status) return status; } else if (keywordToken == "map") { mTokenizer->skipDelimiters(WHITESPACE); status_t status = parseMap(); if (status) return status; } else if (keywordToken == "key") { mTokenizer->skipDelimiters(WHITESPACE); status_t status = parseKey(); Loading Loading @@ -710,6 +756,58 @@ status_t KeyCharacterMap::Parser::parseType() { return NO_ERROR; } status_t KeyCharacterMap::Parser::parseMap() { String8 keywordToken = mTokenizer->nextToken(WHITESPACE); if (keywordToken == "key") { mTokenizer->skipDelimiters(WHITESPACE); return parseMapKey(); } ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(), keywordToken.string()); return BAD_VALUE; } status_t KeyCharacterMap::Parser::parseMapKey() { String8 codeToken = mTokenizer->nextToken(WHITESPACE); bool mapUsage = false; if (codeToken == "usage") { mapUsage = true; mTokenizer->skipDelimiters(WHITESPACE); codeToken = mTokenizer->nextToken(WHITESPACE); } char* end; int32_t code = int32_t(strtol(codeToken.string(), &end, 0)); if (*end) { ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } KeyedVector<int32_t, int32_t>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; if (map.indexOfKey(code) >= 0) { ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } mTokenizer->skipDelimiters(WHITESPACE); String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string()); if (!keyCode) { ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(), keyCodeToken.string()); return BAD_VALUE; } #if DEBUG_PARSER ALOGD("Parsed map key %s: code=%d, keyCode=%d.", mapUsage ? "usage" : "scan code", code, keyCode); #endif map.add(code, keyCode); return NO_ERROR; } status_t KeyCharacterMap::Parser::parseKey() { String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string()); Loading
libs/androidfw/KeyLayoutMap.cpp +19 −9 Original line number Diff line number Diff line Loading @@ -199,17 +199,26 @@ status_t KeyLayoutMap::Parser::parse() { } status_t KeyLayoutMap::Parser::parseKey() { String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE); String8 codeToken = mTokenizer->nextToken(WHITESPACE); bool mapUsage = false; if (codeToken == "usage") { mapUsage = true; mTokenizer->skipDelimiters(WHITESPACE); codeToken = mTokenizer->nextToken(WHITESPACE); } char* end; int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0)); int32_t code = int32_t(strtol(codeToken.string(), &end, 0)); if (*end) { ALOGE("%s: Expected key scan code number, got '%s'.", mTokenizer->getLocation().string(), scanCodeToken.string()); ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } if (mMap->mKeysByScanCode.indexOfKey(scanCode) >= 0) { ALOGE("%s: Duplicate entry for key scan code '%s'.", mTokenizer->getLocation().string(), scanCodeToken.string()); KeyedVector<int32_t, Key>& map = mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; if (map.indexOfKey(code) >= 0) { ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(), mapUsage ? "usage" : "scan code", codeToken.string()); return BAD_VALUE; } Loading Loading @@ -243,12 +252,13 @@ status_t KeyLayoutMap::Parser::parseKey() { } #if DEBUG_PARSER ALOGD("Parsed key: scanCode=%d, keyCode=%d, flags=0x%08x.", scanCode, keyCode, flags); ALOGD("Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.", mapUsage ? "usage" : "scan code", code, keyCode, flags); #endif Key key; key.keyCode = keyCode; key.flags = flags; mMap->mKeysByScanCode.add(scanCode, key); map.add(code, key); return NO_ERROR; } Loading
packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm +35 −7 Original line number Diff line number Diff line Loading @@ -19,10 +19,38 @@ type OVERLAY # Test key A { label: 'X' base: 'x' shift, capslock: 'X' ctrl, alt, meta: none } map key 12 LEFT_BRACKET map key 13 RIGHT_BRACKET map key 16 APOSTROPHE map key 17 COMMA map key 18 PERIOD map key 19 P map key 20 Y map key 21 F map key 22 G map key 23 C map key 24 R map key 25 L map key 26 SLASH map key 27 EQUALS map key 30 A map key 31 O map key 32 E map key 33 U map key 34 I map key 35 D map key 36 H map key 37 T map key 38 N map key 39 S map key 40 MINUS map key 44 SEMICOLON map key 45 Q map key 46 J map key 47 K map key 48 X map key 49 B map key 50 M map key 51 W map key 52 V map key 53 Z
services/input/EventHub.cpp +17 −9 Original line number Diff line number Diff line Loading @@ -443,13 +443,24 @@ status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); if (device && device->keyMap.haveKeyLayout()) { status_t err = device->keyMap.keyLayoutMap->mapKey( scanCode, usageCode, outKeycode, outFlags); if (err == NO_ERROR) { if (device) { // Check the key character map first. sp<KeyCharacterMap> kcm = device->getKeyCharacterMap(); if (kcm != NULL) { if (!kcm->mapKey(scanCode, usageCode, outKeycode)) { *outFlags = 0; return NO_ERROR; } } // Check the key layout next. if (device->keyMap.haveKeyLayout()) { if (!device->keyMap.keyLayoutMap->mapKey( scanCode, usageCode, outKeycode, outFlags)) { return NO_ERROR; } } } *outKeycode = 0; *outFlags = 0; Loading Loading @@ -531,10 +542,7 @@ sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); if (device) { if (device->combinedKeyMap != NULL) { return device->combinedKeyMap; } return device->keyMap.keyCharacterMap; return device->getKeyCharacterMap(); } return NULL; } Loading