Bug 912858 part.5 Implement KeyboardEvent.key for printable keys on Android r=jchen+smaug

This commit is contained in:
Masayuki Nakano 2013-12-11 01:14:54 +09:00
parent 427ae50181
commit 7b5fa95cec
4 changed files with 54 additions and 14 deletions

View File

@ -166,6 +166,7 @@ public class GeckoEvent {
private int mKeyCode;
private int mUnicodeChar;
private int mBaseUnicodeChar; // mUnicodeChar without meta states applied
private int mDOMPrintableKeyValue;
private int mRepeatCount;
private int mCount;
private int mStart;
@ -253,6 +254,17 @@ public class GeckoEvent {
mBaseUnicodeChar = k.getUnicodeChar(0);
mRepeatCount = k.getRepeatCount();
mCharacters = k.getCharacters();
if (mUnicodeChar >= ' ') {
mDOMPrintableKeyValue = mUnicodeChar;
} else {
int unmodifiedMetaState =
mMetaState & ~(KeyEvent.META_ALT_MASK |
KeyEvent.META_CTRL_MASK |
KeyEvent.META_META_MASK);
if (unmodifiedMetaState != mMetaState) {
mDOMPrintableKeyValue = k.getUnicodeChar(unmodifiedMetaState);
}
}
mDomKeyLocation = isJoystickButton(mKeyCode) ? DomKeyLocation.DOM_KEY_LOCATION_JOYSTICK
: DomKeyLocation.DOM_KEY_LOCATION_MOBILE;
}

View File

@ -35,6 +35,7 @@ jfieldID AndroidGeckoEvent::jNativeWindowField = 0;
jfieldID AndroidGeckoEvent::jCharactersField = 0;
jfieldID AndroidGeckoEvent::jCharactersExtraField = 0;
jfieldID AndroidGeckoEvent::jDataField = 0;
jfieldID AndroidGeckoEvent::jDOMPrintableKeyValueField = 0;
jfieldID AndroidGeckoEvent::jKeyCodeField = 0;
jfieldID AndroidGeckoEvent::jMetaStateField = 0;
jfieldID AndroidGeckoEvent::jDomKeyLocationField = 0;
@ -146,6 +147,7 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
jFlagsField = getField("mFlags", "I");
jUnicodeCharField = getField("mUnicodeChar", "I");
jBaseUnicodeCharField = getField("mBaseUnicodeChar", "I");
jDOMPrintableKeyValueField = getField("mDOMPrintableKeyValue", "I");
jRepeatCountField = getField("mRepeatCount", "I");
jCountField = getField("mCount", "I");
jStartField = getField("mStart", "I");
@ -424,6 +426,8 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
mKeyCode = jenv->GetIntField(jobj, jKeyCodeField);
mUnicodeChar = jenv->GetIntField(jobj, jUnicodeCharField);
mBaseUnicodeChar = jenv->GetIntField(jobj, jBaseUnicodeCharField);
mDOMPrintableKeyValue =
jenv->GetIntField(jobj, jDOMPrintableKeyValueField);
mRepeatCount = jenv->GetIntField(jobj, jRepeatCountField);
ReadCharactersField(jenv);
break;

View File

@ -511,6 +511,7 @@ public:
int Flags() { return mFlags; }
int UnicodeChar() { return mUnicodeChar; }
int BaseUnicodeChar() { return mBaseUnicodeChar; }
int DOMPrintableKeyValue() { return mDOMPrintableKeyValue; }
int RepeatCount() const { return mRepeatCount; }
int Count() { return mCount; }
int Start() { return mStart; }
@ -552,7 +553,7 @@ protected:
nsIntRect mRect;
int mFlags, mMetaState;
uint32_t mDomKeyLocation;
int mKeyCode, mUnicodeChar, mBaseUnicodeChar;
int mKeyCode, mUnicodeChar, mBaseUnicodeChar, mDOMPrintableKeyValue;
int mRepeatCount;
int mCount;
int mStart, mEnd;
@ -616,6 +617,7 @@ protected:
static jfieldID jCharactersField;
static jfieldID jCharactersExtraField;
static jfieldID jDataField;
static jfieldID jDOMPrintableKeyValueField;
static jfieldID jKeyCodeField;
static jfieldID jMetaStateField;
static jfieldID jDomKeyLocationField;

View File

@ -1393,18 +1393,20 @@ static unsigned int ConvertAndroidKeyCodeToDOMKeyCode(int androidKeyCode)
}
}
static KeyNameIndex ConvertAndroidKeyCodeToKeyNameIndex(int aAndroidKeyCode)
static KeyNameIndex
ConvertAndroidKeyCodeToKeyNameIndex(AndroidGeckoEvent& aAndroidGeckoEvent)
{
int keyCode = aAndroidGeckoEvent.KeyCode();
// Special-case alphanumeric keycodes because they are most common.
if (aAndroidKeyCode >= AKEYCODE_A && aAndroidKeyCode <= AKEYCODE_Z) {
return KEY_NAME_INDEX_PrintableKey;
if (keyCode >= AKEYCODE_A && keyCode <= AKEYCODE_Z) {
return KEY_NAME_INDEX_USE_STRING;
}
if (aAndroidKeyCode >= AKEYCODE_0 && aAndroidKeyCode <= AKEYCODE_9) {
return KEY_NAME_INDEX_PrintableKey;
if (keyCode >= AKEYCODE_0 && keyCode <= AKEYCODE_9) {
return KEY_NAME_INDEX_USE_STRING;
}
switch (aAndroidKeyCode) {
switch (keyCode) {
#define NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex) \
case aNativeKey: return aKeyNameIndex;
@ -1421,6 +1423,7 @@ static KeyNameIndex ConvertAndroidKeyCodeToKeyNameIndex(int aAndroidKeyCode)
case AKEYCODE_COMMA: // ',' key
case AKEYCODE_PERIOD: // '.' key
case AKEYCODE_SPACE:
case AKEYCODE_GRAVE: // '`' key
case AKEYCODE_MINUS: // '-' key
case AKEYCODE_EQUALS: // '=' key
@ -1433,7 +1436,6 @@ static KeyNameIndex ConvertAndroidKeyCodeToKeyNameIndex(int aAndroidKeyCode)
case AKEYCODE_AT: // '@' key
case AKEYCODE_PLUS: // '+' key
case AKEYCODE_UNKNOWN:
case AKEYCODE_NUMPAD_0:
case AKEYCODE_NUMPAD_1:
case AKEYCODE_NUMPAD_2:
@ -1444,13 +1446,19 @@ static KeyNameIndex ConvertAndroidKeyCodeToKeyNameIndex(int aAndroidKeyCode)
case AKEYCODE_NUMPAD_7:
case AKEYCODE_NUMPAD_8:
case AKEYCODE_NUMPAD_9:
case AKEYCODE_NUMPAD_DIVIDE:
case AKEYCODE_NUMPAD_MULTIPLY:
case AKEYCODE_NUMPAD_SUBTRACT:
case AKEYCODE_NUMPAD_ADD:
case AKEYCODE_NUMPAD_DOT:
case AKEYCODE_NUMPAD_COMMA:
case AKEYCODE_NUMPAD_EQUALS:
case AKEYCODE_NUMPAD_LEFT_PAREN:
case AKEYCODE_NUMPAD_RIGHT_PAREN:
case AKEYCODE_YEN: // yen sign key
case AKEYCODE_RO: // Japanese Ro key
return KEY_NAME_INDEX_PrintableKey;
return KEY_NAME_INDEX_USE_STRING;
case AKEYCODE_SOFT_LEFT:
case AKEYCODE_SOFT_RIGHT:
@ -1521,9 +1529,18 @@ static KeyNameIndex ConvertAndroidKeyCodeToKeyNameIndex(int aAndroidKeyCode)
case AKEYCODE_KATAKANA_HIRAGANA:
return KEY_NAME_INDEX_Unidentified;
case AKEYCODE_UNKNOWN:
MOZ_ASSERT(
aAndroidGeckoEvent.Action() != AKEY_EVENT_ACTION_MULTIPLE,
"Don't call this when action is AKEY_EVENT_ACTION_MULTIPLE!");
// It's actually an unknown key if the action isn't ACTION_MULTIPLE.
// However, it might cause text input. So, let's check the value.
return aAndroidGeckoEvent.DOMPrintableKeyValue() ?
KEY_NAME_INDEX_USE_STRING : KEY_NAME_INDEX_Unidentified;
default:
ALOG("ConvertAndroidKeyCodeToKeyNameIndex: "
"No DOM key name index for Android keycode %d", aAndroidKeyCode);
"No DOM key name index for Android keycode %d", keyCode);
return KEY_NAME_INDEX_Unidentified;
}
}
@ -1554,9 +1571,14 @@ void
nsWindow::InitKeyEvent(WidgetKeyboardEvent& event, AndroidGeckoEvent& key,
ANPEvent* pluginEvent)
{
int androidKeyCode = key.KeyCode();
event.mKeyNameIndex = ConvertAndroidKeyCodeToKeyNameIndex(androidKeyCode);
uint32_t domKeyCode = ConvertAndroidKeyCodeToDOMKeyCode(androidKeyCode);
event.mKeyNameIndex = ConvertAndroidKeyCodeToKeyNameIndex(key);
if (event.mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
int keyValue = key.DOMPrintableKeyValue();
if (keyValue) {
event.mKeyValue = static_cast<PRUnichar>(keyValue);
}
}
uint32_t domKeyCode = ConvertAndroidKeyCodeToDOMKeyCode(key.KeyCode());
if (event.message == NS_KEY_PRESS) {
// Android gives us \n, so filter out some control characters.