Skip to content

Commit 6957b60

Browse files
Jeff BrownAndroid (Google) Code Review
authored andcommitted
Merge "Add Dvorak keyboard layout."
2 parents 62d52f9 + 4a3862f commit 6957b60

File tree

6 files changed

+186
-26
lines changed

6 files changed

+186
-26
lines changed

include/androidfw/KeyCharacterMap.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ class KeyCharacterMap : public RefBase {
120120
bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
121121
Vector<KeyEvent>& outEvents) const;
122122

123+
/* Maps a scan code and usage code to a key code, in case this key map overrides
124+
* the mapping in some way. */
125+
status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const;
126+
123127
#if HAVE_ANDROID_OS
124128
/* Reads a key map from a parcel. */
125129
static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);
@@ -198,6 +202,8 @@ class KeyCharacterMap : public RefBase {
198202

199203
private:
200204
status_t parseType();
205+
status_t parseMap();
206+
status_t parseMapKey();
201207
status_t parseKey();
202208
status_t parseKeyProperty();
203209
status_t parseModifier(const String8& token, int32_t* outMetaState);
@@ -209,6 +215,9 @@ class KeyCharacterMap : public RefBase {
209215
KeyedVector<int32_t, Key*> mKeys;
210216
int mType;
211217

218+
KeyedVector<int32_t, int32_t> mKeysByScanCode;
219+
KeyedVector<int32_t, int32_t> mKeysByUsageCode;
220+
212221
KeyCharacterMap();
213222
KeyCharacterMap(const KeyCharacterMap& other);
214223

libs/androidfw/KeyCharacterMap.cpp

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ KeyCharacterMap::KeyCharacterMap() :
9090
}
9191

9292
KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) :
93-
RefBase(), mType(other.mType) {
93+
RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode),
94+
mKeysByUsageCode(other.mKeysByUsageCode) {
9495
for (size_t i = 0; i < other.mKeys.size(); i++) {
9596
mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i)));
9697
}
@@ -180,6 +181,16 @@ sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base,
180181
map->mKeys.add(keyCode, new Key(*key));
181182
}
182183
}
184+
185+
for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) {
186+
map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i),
187+
overlay->mKeysByScanCode.valueAt(i));
188+
}
189+
190+
for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) {
191+
map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i),
192+
overlay->mKeysByUsageCode.valueAt(i));
193+
}
183194
return map;
184195
}
185196

@@ -315,6 +326,37 @@ bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t
315326
return true;
316327
}
317328

329+
status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const {
330+
if (usageCode) {
331+
ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
332+
if (index >= 0) {
333+
#if DEBUG_MAPPING
334+
ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
335+
scanCode, usageCode, *outKeyCode);
336+
#endif
337+
*outKeyCode = mKeysByUsageCode.valueAt(index);
338+
return OK;
339+
}
340+
}
341+
if (scanCode) {
342+
ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
343+
if (index >= 0) {
344+
#if DEBUG_MAPPING
345+
ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
346+
scanCode, usageCode, *outKeyCode);
347+
#endif
348+
*outKeyCode = mKeysByScanCode.valueAt(index);
349+
return OK;
350+
}
351+
}
352+
353+
#if DEBUG_MAPPING
354+
ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
355+
#endif
356+
*outKeyCode = AKEYCODE_UNKNOWN;
357+
return NAME_NOT_FOUND;
358+
}
359+
318360
bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
319361
ssize_t index = mKeys.indexOfKey(keyCode);
320362
if (index >= 0) {
@@ -616,6 +658,10 @@ status_t KeyCharacterMap::Parser::parse() {
616658
mTokenizer->skipDelimiters(WHITESPACE);
617659
status_t status = parseType();
618660
if (status) return status;
661+
} else if (keywordToken == "map") {
662+
mTokenizer->skipDelimiters(WHITESPACE);
663+
status_t status = parseMap();
664+
if (status) return status;
619665
} else if (keywordToken == "key") {
620666
mTokenizer->skipDelimiters(WHITESPACE);
621667
status_t status = parseKey();
@@ -710,6 +756,58 @@ status_t KeyCharacterMap::Parser::parseType() {
710756
return NO_ERROR;
711757
}
712758

759+
status_t KeyCharacterMap::Parser::parseMap() {
760+
String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
761+
if (keywordToken == "key") {
762+
mTokenizer->skipDelimiters(WHITESPACE);
763+
return parseMapKey();
764+
}
765+
ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(),
766+
keywordToken.string());
767+
return BAD_VALUE;
768+
}
769+
770+
status_t KeyCharacterMap::Parser::parseMapKey() {
771+
String8 codeToken = mTokenizer->nextToken(WHITESPACE);
772+
bool mapUsage = false;
773+
if (codeToken == "usage") {
774+
mapUsage = true;
775+
mTokenizer->skipDelimiters(WHITESPACE);
776+
codeToken = mTokenizer->nextToken(WHITESPACE);
777+
}
778+
779+
char* end;
780+
int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
781+
if (*end) {
782+
ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
783+
mapUsage ? "usage" : "scan code", codeToken.string());
784+
return BAD_VALUE;
785+
}
786+
KeyedVector<int32_t, int32_t>& map =
787+
mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
788+
if (map.indexOfKey(code) >= 0) {
789+
ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
790+
mapUsage ? "usage" : "scan code", codeToken.string());
791+
return BAD_VALUE;
792+
}
793+
794+
mTokenizer->skipDelimiters(WHITESPACE);
795+
String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
796+
int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
797+
if (!keyCode) {
798+
ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
799+
keyCodeToken.string());
800+
return BAD_VALUE;
801+
}
802+
803+
#if DEBUG_PARSER
804+
ALOGD("Parsed map key %s: code=%d, keyCode=%d.",
805+
mapUsage ? "usage" : "scan code", code, keyCode);
806+
#endif
807+
map.add(code, keyCode);
808+
return NO_ERROR;
809+
}
810+
713811
status_t KeyCharacterMap::Parser::parseKey() {
714812
String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
715813
int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());

libs/androidfw/KeyLayoutMap.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,26 @@ status_t KeyLayoutMap::Parser::parse() {
199199
}
200200

201201
status_t KeyLayoutMap::Parser::parseKey() {
202-
String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
202+
String8 codeToken = mTokenizer->nextToken(WHITESPACE);
203+
bool mapUsage = false;
204+
if (codeToken == "usage") {
205+
mapUsage = true;
206+
mTokenizer->skipDelimiters(WHITESPACE);
207+
codeToken = mTokenizer->nextToken(WHITESPACE);
208+
}
209+
203210
char* end;
204-
int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
211+
int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
205212
if (*end) {
206-
ALOGE("%s: Expected key scan code number, got '%s'.", mTokenizer->getLocation().string(),
207-
scanCodeToken.string());
213+
ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
214+
mapUsage ? "usage" : "scan code", codeToken.string());
208215
return BAD_VALUE;
209216
}
210-
if (mMap->mKeysByScanCode.indexOfKey(scanCode) >= 0) {
211-
ALOGE("%s: Duplicate entry for key scan code '%s'.", mTokenizer->getLocation().string(),
212-
scanCodeToken.string());
217+
KeyedVector<int32_t, Key>& map =
218+
mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
219+
if (map.indexOfKey(code) >= 0) {
220+
ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
221+
mapUsage ? "usage" : "scan code", codeToken.string());
213222
return BAD_VALUE;
214223
}
215224

@@ -243,12 +252,13 @@ status_t KeyLayoutMap::Parser::parseKey() {
243252
}
244253

245254
#if DEBUG_PARSER
246-
ALOGD("Parsed key: scanCode=%d, keyCode=%d, flags=0x%08x.", scanCode, keyCode, flags);
255+
ALOGD("Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.",
256+
mapUsage ? "usage" : "scan code", code, keyCode, flags);
247257
#endif
248258
Key key;
249259
key.keyCode = keyCode;
250260
key.flags = flags;
251-
mMap->mKeysByScanCode.add(scanCode, key);
261+
map.add(code, key);
252262
return NO_ERROR;
253263
}
254264

packages/InputDevices/res/raw/keyboard_layout_english_us_dvorak.kcm

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,38 @@
1919

2020
type OVERLAY
2121

22-
# Test
23-
key A {
24-
label: 'X'
25-
base: 'x'
26-
shift, capslock: 'X'
27-
ctrl, alt, meta: none
28-
}
22+
map key 12 LEFT_BRACKET
23+
map key 13 RIGHT_BRACKET
24+
map key 16 APOSTROPHE
25+
map key 17 COMMA
26+
map key 18 PERIOD
27+
map key 19 P
28+
map key 20 Y
29+
map key 21 F
30+
map key 22 G
31+
map key 23 C
32+
map key 24 R
33+
map key 25 L
34+
map key 26 SLASH
35+
map key 27 EQUALS
36+
map key 30 A
37+
map key 31 O
38+
map key 32 E
39+
map key 33 U
40+
map key 34 I
41+
map key 35 D
42+
map key 36 H
43+
map key 37 T
44+
map key 38 N
45+
map key 39 S
46+
map key 40 MINUS
47+
map key 44 SEMICOLON
48+
map key 45 Q
49+
map key 46 J
50+
map key 47 K
51+
map key 48 X
52+
map key 49 B
53+
map key 50 M
54+
map key 51 W
55+
map key 52 V
56+
map key 53 Z

services/input/EventHub.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -443,11 +443,22 @@ status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
443443
AutoMutex _l(mLock);
444444
Device* device = getDeviceLocked(deviceId);
445445

446-
if (device && device->keyMap.haveKeyLayout()) {
447-
status_t err = device->keyMap.keyLayoutMap->mapKey(
448-
scanCode, usageCode, outKeycode, outFlags);
449-
if (err == NO_ERROR) {
450-
return NO_ERROR;
446+
if (device) {
447+
// Check the key character map first.
448+
sp<KeyCharacterMap> kcm = device->getKeyCharacterMap();
449+
if (kcm != NULL) {
450+
if (!kcm->mapKey(scanCode, usageCode, outKeycode)) {
451+
*outFlags = 0;
452+
return NO_ERROR;
453+
}
454+
}
455+
456+
// Check the key layout next.
457+
if (device->keyMap.haveKeyLayout()) {
458+
if (!device->keyMap.keyLayoutMap->mapKey(
459+
scanCode, usageCode, outKeycode, outFlags)) {
460+
return NO_ERROR;
461+
}
451462
}
452463
}
453464

@@ -531,10 +542,7 @@ sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const {
531542
AutoMutex _l(mLock);
532543
Device* device = getDeviceLocked(deviceId);
533544
if (device) {
534-
if (device->combinedKeyMap != NULL) {
535-
return device->combinedKeyMap;
536-
}
537-
return device->keyMap.keyCharacterMap;
545+
return device->getKeyCharacterMap();
538546
}
539547
return NULL;
540548
}

services/input/EventHub.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,13 @@ class EventHub : public EventHubInterface
335335
void close();
336336

337337
inline bool isVirtual() const { return fd < 0; }
338+
339+
const sp<KeyCharacterMap>& getKeyCharacterMap() const {
340+
if (combinedKeyMap != NULL) {
341+
return combinedKeyMap;
342+
}
343+
return keyMap.keyCharacterMap;
344+
}
338345
};
339346

340347
status_t openDeviceLocked(const char *devicePath);

0 commit comments

Comments
 (0)