am 2f3c3eb4
: Merge "Allow defining replacement key events in keymap" into mnc-dr-dev
* commit '2f3c3eb4e47d7cb6ef67e0fd2063e4b93e38e9ec': Allow defining replacement key events in keymap
This commit is contained in:
commit
ec1323dbd4
@ -124,6 +124,11 @@ public:
|
|||||||
* the mapping in some way. */
|
* the mapping in some way. */
|
||||||
status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const;
|
status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const;
|
||||||
|
|
||||||
|
/* Tries to find a replacement key code for a given key code and meta state
|
||||||
|
* in character map. */
|
||||||
|
void tryRemapKey(int32_t scanCode, int32_t metaState,
|
||||||
|
int32_t* outKeyCode, int32_t* outMetaState) const;
|
||||||
|
|
||||||
#if HAVE_ANDROID_OS
|
#if HAVE_ANDROID_OS
|
||||||
/* Reads a key map from a parcel. */
|
/* Reads a key map from a parcel. */
|
||||||
static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);
|
static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);
|
||||||
@ -151,6 +156,9 @@ private:
|
|||||||
|
|
||||||
/* The fallback keycode if the key is not handled. */
|
/* The fallback keycode if the key is not handled. */
|
||||||
int32_t fallbackKeyCode;
|
int32_t fallbackKeyCode;
|
||||||
|
|
||||||
|
/* The replacement keycode if the key has to be replaced outright. */
|
||||||
|
int32_t replacementKeyCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Key {
|
struct Key {
|
||||||
|
@ -87,6 +87,13 @@ extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentif
|
|||||||
*/
|
*/
|
||||||
extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
|
extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the meta state such that if either the left or right modifier
|
||||||
|
* meta state bits are set then the result will also include the universal
|
||||||
|
* bit for that modifier.
|
||||||
|
*/
|
||||||
|
extern int32_t normalizeMetaState(int32_t oldMetaState);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a key is a meta key like ALT or CAPS_LOCK.
|
* Returns true if a key is a meta key like ALT or CAPS_LOCK.
|
||||||
*/
|
*/
|
||||||
|
@ -332,33 +332,75 @@ status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* o
|
|||||||
if (usageCode) {
|
if (usageCode) {
|
||||||
ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
|
ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
#if DEBUG_MAPPING
|
|
||||||
ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
|
|
||||||
scanCode, usageCode, *outKeyCode);
|
|
||||||
#endif
|
|
||||||
*outKeyCode = mKeysByUsageCode.valueAt(index);
|
*outKeyCode = mKeysByUsageCode.valueAt(index);
|
||||||
|
#if DEBUG_MAPPING
|
||||||
|
ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
|
||||||
|
scanCode, usageCode, *outKeyCode);
|
||||||
|
#endif
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (scanCode) {
|
if (scanCode) {
|
||||||
ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
|
ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
#if DEBUG_MAPPING
|
|
||||||
ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
|
|
||||||
scanCode, usageCode, *outKeyCode);
|
|
||||||
#endif
|
|
||||||
*outKeyCode = mKeysByScanCode.valueAt(index);
|
*outKeyCode = mKeysByScanCode.valueAt(index);
|
||||||
|
#if DEBUG_MAPPING
|
||||||
|
ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
|
||||||
|
scanCode, usageCode, *outKeyCode);
|
||||||
|
#endif
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG_MAPPING
|
#if DEBUG_MAPPING
|
||||||
ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
|
ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
|
||||||
#endif
|
#endif
|
||||||
*outKeyCode = AKEYCODE_UNKNOWN;
|
*outKeyCode = AKEYCODE_UNKNOWN;
|
||||||
return NAME_NOT_FOUND;
|
return NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KeyCharacterMap::tryRemapKey(int32_t keyCode, int32_t metaState,
|
||||||
|
int32_t *outKeyCode, int32_t *outMetaState) const {
|
||||||
|
*outKeyCode = keyCode;
|
||||||
|
*outMetaState = metaState;
|
||||||
|
|
||||||
|
const Key* key;
|
||||||
|
const Behavior* behavior;
|
||||||
|
if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
|
||||||
|
if (behavior->replacementKeyCode) {
|
||||||
|
*outKeyCode = behavior->replacementKeyCode;
|
||||||
|
int32_t newMetaState = metaState & ~behavior->metaState;
|
||||||
|
// Reset dependent meta states.
|
||||||
|
if (behavior->metaState & AMETA_ALT_ON) {
|
||||||
|
newMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON);
|
||||||
|
}
|
||||||
|
if (behavior->metaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
|
||||||
|
newMetaState &= ~AMETA_ALT_ON;
|
||||||
|
}
|
||||||
|
if (behavior->metaState & AMETA_CTRL_ON) {
|
||||||
|
newMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON);
|
||||||
|
}
|
||||||
|
if (behavior->metaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
|
||||||
|
newMetaState &= ~AMETA_CTRL_ON;
|
||||||
|
}
|
||||||
|
if (behavior->metaState & AMETA_SHIFT_ON) {
|
||||||
|
newMetaState &= ~(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON);
|
||||||
|
}
|
||||||
|
if (behavior->metaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
|
||||||
|
newMetaState &= ~AMETA_SHIFT_ON;
|
||||||
|
}
|
||||||
|
// ... and put universal bits back if needed
|
||||||
|
*outMetaState = normalizeMetaState(newMetaState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG_MAPPING
|
||||||
|
ALOGD("tryRemapKey: keyCode=%d, metaState=0x%08x ~ "
|
||||||
|
"replacement keyCode=%d, replacement metaState=0x%08x.",
|
||||||
|
keyCode, metaState, *outKeyCode, *outMetaState);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
|
bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
|
||||||
ssize_t index = mKeys.indexOfKey(keyCode);
|
ssize_t index = mKeys.indexOfKey(keyCode);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
@ -584,6 +626,7 @@ sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) {
|
|||||||
int32_t metaState = parcel->readInt32();
|
int32_t metaState = parcel->readInt32();
|
||||||
char16_t character = parcel->readInt32();
|
char16_t character = parcel->readInt32();
|
||||||
int32_t fallbackKeyCode = parcel->readInt32();
|
int32_t fallbackKeyCode = parcel->readInt32();
|
||||||
|
int32_t replacementKeyCode = parcel->readInt32();
|
||||||
if (parcel->errorCheck()) {
|
if (parcel->errorCheck()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -592,6 +635,7 @@ sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) {
|
|||||||
behavior->metaState = metaState;
|
behavior->metaState = metaState;
|
||||||
behavior->character = character;
|
behavior->character = character;
|
||||||
behavior->fallbackKeyCode = fallbackKeyCode;
|
behavior->fallbackKeyCode = fallbackKeyCode;
|
||||||
|
behavior->replacementKeyCode = replacementKeyCode;
|
||||||
if (lastBehavior) {
|
if (lastBehavior) {
|
||||||
lastBehavior->next = behavior;
|
lastBehavior->next = behavior;
|
||||||
} else {
|
} else {
|
||||||
@ -624,6 +668,7 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const {
|
|||||||
parcel->writeInt32(behavior->metaState);
|
parcel->writeInt32(behavior->metaState);
|
||||||
parcel->writeInt32(behavior->character);
|
parcel->writeInt32(behavior->character);
|
||||||
parcel->writeInt32(behavior->fallbackKeyCode);
|
parcel->writeInt32(behavior->fallbackKeyCode);
|
||||||
|
parcel->writeInt32(behavior->replacementKeyCode);
|
||||||
}
|
}
|
||||||
parcel->writeInt32(0);
|
parcel->writeInt32(0);
|
||||||
}
|
}
|
||||||
@ -655,13 +700,14 @@ KeyCharacterMap::Key::~Key() {
|
|||||||
// --- KeyCharacterMap::Behavior ---
|
// --- KeyCharacterMap::Behavior ---
|
||||||
|
|
||||||
KeyCharacterMap::Behavior::Behavior() :
|
KeyCharacterMap::Behavior::Behavior() :
|
||||||
next(NULL), metaState(0), character(0), fallbackKeyCode(0) {
|
next(NULL), metaState(0), character(0), fallbackKeyCode(0), replacementKeyCode(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
|
KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
|
||||||
next(other.next ? new Behavior(*other.next) : NULL),
|
next(other.next ? new Behavior(*other.next) : NULL),
|
||||||
metaState(other.metaState), character(other.character),
|
metaState(other.metaState), character(other.character),
|
||||||
fallbackKeyCode(other.fallbackKeyCode) {
|
fallbackKeyCode(other.fallbackKeyCode),
|
||||||
|
replacementKeyCode(other.replacementKeyCode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -923,6 +969,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() {
|
|||||||
Behavior behavior;
|
Behavior behavior;
|
||||||
bool haveCharacter = false;
|
bool haveCharacter = false;
|
||||||
bool haveFallback = false;
|
bool haveFallback = false;
|
||||||
|
bool haveReplacement = false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char ch = mTokenizer->peekChar();
|
char ch = mTokenizer->peekChar();
|
||||||
@ -939,6 +986,11 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() {
|
|||||||
mTokenizer->getLocation().string());
|
mTokenizer->getLocation().string());
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
if (haveReplacement) {
|
||||||
|
ALOGE("%s: Cannot combine character literal with replace action.",
|
||||||
|
mTokenizer->getLocation().string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
behavior.character = character;
|
behavior.character = character;
|
||||||
haveCharacter = true;
|
haveCharacter = true;
|
||||||
} else {
|
} else {
|
||||||
@ -949,6 +1001,11 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() {
|
|||||||
mTokenizer->getLocation().string());
|
mTokenizer->getLocation().string());
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
if (haveReplacement) {
|
||||||
|
ALOGE("%s: Cannot combine 'none' with replace action.",
|
||||||
|
mTokenizer->getLocation().string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
haveCharacter = true;
|
haveCharacter = true;
|
||||||
} else if (token == "fallback") {
|
} else if (token == "fallback") {
|
||||||
mTokenizer->skipDelimiters(WHITESPACE);
|
mTokenizer->skipDelimiters(WHITESPACE);
|
||||||
@ -960,13 +1017,36 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() {
|
|||||||
token.string());
|
token.string());
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
if (haveFallback) {
|
if (haveFallback || haveReplacement) {
|
||||||
ALOGE("%s: Cannot combine multiple fallback key codes.",
|
ALOGE("%s: Cannot combine multiple fallback/replacement key codes.",
|
||||||
mTokenizer->getLocation().string());
|
mTokenizer->getLocation().string());
|
||||||
return BAD_VALUE;
|
return BAD_VALUE;
|
||||||
}
|
}
|
||||||
behavior.fallbackKeyCode = keyCode;
|
behavior.fallbackKeyCode = keyCode;
|
||||||
haveFallback = true;
|
haveFallback = true;
|
||||||
|
} else if (token == "replace") {
|
||||||
|
mTokenizer->skipDelimiters(WHITESPACE);
|
||||||
|
token = mTokenizer->nextToken(WHITESPACE);
|
||||||
|
int32_t keyCode = getKeyCodeByLabel(token.string());
|
||||||
|
if (!keyCode) {
|
||||||
|
ALOGE("%s: Invalid key code label for replace, got '%s'.",
|
||||||
|
mTokenizer->getLocation().string(),
|
||||||
|
token.string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
if (haveCharacter) {
|
||||||
|
ALOGE("%s: Cannot combine character literal with replace action.",
|
||||||
|
mTokenizer->getLocation().string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
if (haveFallback || haveReplacement) {
|
||||||
|
ALOGE("%s: Cannot combine multiple fallback/replacement key codes.",
|
||||||
|
mTokenizer->getLocation().string());
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
behavior.replacementKeyCode = keyCode;
|
||||||
|
haveReplacement = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ALOGE("%s: Expected a key behavior after ':'.",
|
ALOGE("%s: Expected a key behavior after ':'.",
|
||||||
mTokenizer->getLocation().string());
|
mTokenizer->getLocation().string());
|
||||||
@ -1016,8 +1096,10 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() {
|
|||||||
newBehavior->next = key->firstBehavior;
|
newBehavior->next = key->firstBehavior;
|
||||||
key->firstBehavior = newBehavior;
|
key->firstBehavior = newBehavior;
|
||||||
#if DEBUG_PARSER
|
#if DEBUG_PARSER
|
||||||
ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d.", mKeyCode,
|
ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.",
|
||||||
newBehavior->metaState, newBehavior->character, newBehavior->fallbackKeyCode);
|
mKeyCode,
|
||||||
|
newBehavior->metaState, newBehavior->character,
|
||||||
|
newBehavior->fallbackKeyCode, newBehavior->replacementKeyCode);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,11 @@ static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaSta
|
|||||||
~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON);
|
~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return normalizeMetaState(newMetaState);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t normalizeMetaState(int32_t oldMetaState) {
|
||||||
|
int32_t newMetaState = oldMetaState;
|
||||||
if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
|
if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
|
||||||
newMetaState |= AMETA_ALT_ON;
|
newMetaState |= AMETA_ALT_ON;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user