summaryrefslogtreecommitdiffstats
path: root/core/jni/android_view_KeyCharacterMap.cpp
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-12-06 17:13:33 -0800
committerJeff Brown <jeffbrown@google.com>2010-12-07 17:35:26 -0800
commit49ed71db425c5054e3ad9526496a7e116c89556b (patch)
tree3d3b28bdaf76d5cc531fd3b52fcbb0efb32a05ba /core/jni/android_view_KeyCharacterMap.cpp
parentf30c8287525ac049d4d7589a330be5713256046b (diff)
downloadframeworks_base-49ed71db425c5054e3ad9526496a7e116c89556b.zip
frameworks_base-49ed71db425c5054e3ad9526496a7e116c89556b.tar.gz
frameworks_base-49ed71db425c5054e3ad9526496a7e116c89556b.tar.bz2
Add support for fallback keycodes.
This change enables the framework to synthesize key events to implement default behavior when an application does not handle a key. For example, this change enables numeric keypad keys to perform their associated special function when numlock is off. The application is informed that it is processing a fallback keypress so it can choose to ignore it. Added a new keycode for switching applications. Added ALT key deadkeys. New default key mappings: - ESC -> BACK - Meta+ESC -> HOME - Alt+ESC -> MENU - Meta+Space -> SEARCH - Meta+Tab -> APP_SWITCH Fixed some comments. Fixed some tests. Change-Id: Id7f3b6645f3a350275e624547822f72652f3defe
Diffstat (limited to 'core/jni/android_view_KeyCharacterMap.cpp')
-rw-r--r--core/jni/android_view_KeyCharacterMap.cpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
new file mode 100644
index 0000000..bfeec4f
--- /dev/null
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2006, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+#include <ui/KeyCharacterMap.h>
+#include <ui/Input.h>
+
+#include <android_runtime/AndroidRuntime.h>
+#include <nativehelper/jni.h>
+#include <nativehelper/JNIHelp.h>
+
+#include "android_view_KeyEvent.h"
+
+namespace android {
+
+static struct {
+ jclass clazz;
+} gKeyEventClassInfo;
+
+static struct {
+ jclass clazz;
+
+ jfieldID keyCode;
+ jfieldID metaState;
+} gFallbackActionClassInfo;
+
+
+static jint nativeLoad(JNIEnv *env, jobject clazz, jint deviceId) {
+ KeyCharacterMap* map;
+ status_t status = KeyCharacterMap::loadByDeviceId(deviceId, &map);
+ if (status) {
+ String8 msg;
+ msg.appendFormat("Could not load key character map for device %d due to error %d. "
+ "Refer to the log for details.", deviceId, status);
+ jniThrowException(env, "android/view/KeyCharacterMap$KeyCharacterMapUnavailableException",
+ msg.string());
+ return 0;
+ }
+ return reinterpret_cast<jint>(map);
+}
+
+static void nativeDispose(JNIEnv *env, jobject clazz, jint ptr) {
+ KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
+ delete map;
+}
+
+static jchar nativeGetCharacter(JNIEnv *env, jobject clazz, jint ptr,
+ jint keyCode, jint metaState) {
+ KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
+ return map->getCharacter(keyCode, metaState);
+}
+
+static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
+ jint metaState, jobject fallbackActionObj) {
+ KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
+ KeyCharacterMap::FallbackAction fallbackAction;
+
+ bool result = map->getFallbackAction(keyCode, metaState, &fallbackAction);
+ if (result) {
+ env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.keyCode,
+ fallbackAction.keyCode);
+ env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.metaState,
+ fallbackAction.metaState);
+ }
+ return result;
+}
+
+static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
+ KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
+ return map->getNumber(keyCode);
+}
+
+static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
+ jcharArray charsArray, jint metaState) {
+ KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
+
+ jsize numChars = env->GetArrayLength(charsArray);
+ jchar* chars = static_cast<jchar*>(env->GetPrimitiveArrayCritical(charsArray, NULL));
+ if (!chars) {
+ return 0;
+ }
+
+ char16_t result = map->getMatch(keyCode, chars, size_t(numChars), metaState);
+
+ env->ReleasePrimitiveArrayCritical(charsArray, chars, JNI_ABORT);
+ return result;
+}
+
+static jchar nativeGetDisplayLabel(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
+ KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
+ return map->getDisplayLabel(keyCode);
+}
+
+static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jint ptr) {
+ KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
+ return map->getKeyboardType();
+}
+
+static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, jint deviceId,
+ jcharArray charsArray) {
+ KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
+
+ jchar* chars = env->GetCharArrayElements(charsArray, NULL);
+ if (!chars) {
+ return NULL;
+ }
+ jsize numChars = env->GetArrayLength(charsArray);
+
+ Vector<KeyEvent> events;
+ jobjectArray result = NULL;
+ if (map->getEvents(deviceId, chars, size_t(numChars), events)) {
+ result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL);
+ if (result) {
+ for (size_t i = 0; i < events.size(); i++) {
+ jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i));
+ if (!keyEventObj) break; // threw OOM exception
+ env->SetObjectArrayElement(result, jsize(i), keyEventObj);
+ env->DeleteLocalRef(keyEventObj);
+ }
+ }
+ }
+
+ env->ReleaseCharArrayElements(charsArray, chars, JNI_ABORT);
+ return result;
+}
+
+
+/*
+ * JNI registration.
+ */
+
+static JNINativeMethod g_methods[] = {
+ /* name, signature, funcPtr */
+ { "nativeLoad", "(I)I",
+ (void*)nativeLoad },
+ { "nativeDispose", "(I)V",
+ (void*)nativeDispose },
+ { "nativeGetCharacter", "(III)C",
+ (void*)nativeGetCharacter },
+ { "nativeGetFallbackAction", "(IIILandroid/view/KeyCharacterMap$FallbackAction;)Z",
+ (void*)nativeGetFallbackAction },
+ { "nativeGetNumber", "(II)C",
+ (void*)nativeGetNumber },
+ { "nativeGetMatch", "(II[CI)C",
+ (void*)nativeGetMatch },
+ { "nativeGetDisplayLabel", "(II)C",
+ (void*)nativeGetDisplayLabel },
+ { "nativeGetKeyboardType", "(I)I",
+ (void*)nativeGetKeyboardType },
+ { "nativeGetEvents", "(II[C)[Landroid/view/KeyEvent;",
+ (void*)nativeGetEvents },
+};
+
+#define FIND_CLASS(var, className) \
+ var = env->FindClass(className); \
+ LOG_FATAL_IF(! var, "Unable to find class " className); \
+ var = jclass(env->NewGlobalRef(var));
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+ var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+ LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+int register_android_text_KeyCharacterMap(JNIEnv* env)
+{
+ FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
+
+ FIND_CLASS(gFallbackActionClassInfo.clazz, "android/view/KeyCharacterMap$FallbackAction");
+
+ GET_FIELD_ID(gFallbackActionClassInfo.keyCode, gFallbackActionClassInfo.clazz,
+ "keyCode", "I");
+
+ GET_FIELD_ID(gFallbackActionClassInfo.metaState, gFallbackActionClassInfo.clazz,
+ "metaState", "I");
+
+ return AndroidRuntime::registerNativeMethods(env,
+ "android/view/KeyCharacterMap", g_methods, NELEM(g_methods));
+}
+
+}; // namespace android