blob: b9f373882440dd59a51c25ce6ea1bff43b078c7e [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright 2006, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15*/
16
17#include <ui/KeyCharacterMap.h>
Jeff Brown6b53e8d2010-11-10 16:03:06 -080018#include <ui/Input.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020#include <android_runtime/AndroidRuntime.h>
Jeff Brown6b53e8d2010-11-10 16:03:06 -080021#include <nativehelper/jni.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022#include <nativehelper/JNIHelp.h>
23
Jeff Brown6b53e8d2010-11-10 16:03:06 -080024#include "android_view_KeyEvent.h"
25
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026namespace android {
27
Jeff Brown6b53e8d2010-11-10 16:03:06 -080028static struct {
29 jclass clazz;
30} gKeyEventClassInfo;
31
Jeff Brown49ed71d2010-12-06 17:13:33 -080032static struct {
Jeff Brown49ed71d2010-12-06 17:13:33 -080033 jfieldID keyCode;
34 jfieldID metaState;
35} gFallbackActionClassInfo;
36
37
Jeff Brown1e08fe92011-11-15 17:48:10 -080038static jint nativeLoad(JNIEnv *env, jobject clazz, jstring fileStr) {
39 const char* file = env->GetStringUTFChars(fileStr, NULL);
40
Jeff Brown6b53e8d2010-11-10 16:03:06 -080041 KeyCharacterMap* map;
Jeff Brown1e08fe92011-11-15 17:48:10 -080042 status_t status = KeyCharacterMap::load(String8(file), &map);
43 jint result;
Jeff Brown6b53e8d2010-11-10 16:03:06 -080044 if (status) {
45 String8 msg;
Jeff Brown1e08fe92011-11-15 17:48:10 -080046 msg.appendFormat("Could not load key character map '%s' due to error %d. "
47 "Refer to the log for details.", file, status);
Jeff Brown6b53e8d2010-11-10 16:03:06 -080048 jniThrowException(env, "android/view/KeyCharacterMap$KeyCharacterMapUnavailableException",
49 msg.string());
Jeff Brown1e08fe92011-11-15 17:48:10 -080050 result = 0;
51 } else {
52 result = reinterpret_cast<jint>(map);
Jeff Brown6b53e8d2010-11-10 16:03:06 -080053 }
Jeff Brown1e08fe92011-11-15 17:48:10 -080054
55 env->ReleaseStringUTFChars(fileStr, file);
56 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057}
58
Jeff Brown6b53e8d2010-11-10 16:03:06 -080059static void nativeDispose(JNIEnv *env, jobject clazz, jint ptr) {
60 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
61 delete map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062}
63
Jeff Brown6b53e8d2010-11-10 16:03:06 -080064static jchar nativeGetCharacter(JNIEnv *env, jobject clazz, jint ptr,
65 jint keyCode, jint metaState) {
66 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
67 return map->getCharacter(keyCode, metaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068}
69
Jeff Brown49ed71d2010-12-06 17:13:33 -080070static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
71 jint metaState, jobject fallbackActionObj) {
72 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
73 KeyCharacterMap::FallbackAction fallbackAction;
74
75 bool result = map->getFallbackAction(keyCode, metaState, &fallbackAction);
76 if (result) {
77 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.keyCode,
78 fallbackAction.keyCode);
79 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.metaState,
80 fallbackAction.metaState);
81 }
82 return result;
83}
84
Jeff Brown6b53e8d2010-11-10 16:03:06 -080085static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
86 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
87 return map->getNumber(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088}
89
Jeff Brown6b53e8d2010-11-10 16:03:06 -080090static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
91 jcharArray charsArray, jint metaState) {
92 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093
Jeff Brown6b53e8d2010-11-10 16:03:06 -080094 jsize numChars = env->GetArrayLength(charsArray);
95 jchar* chars = static_cast<jchar*>(env->GetPrimitiveArrayCritical(charsArray, NULL));
96 if (!chars) {
97 return 0;
98 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800100 char16_t result = map->getMatch(keyCode, chars, size_t(numChars), metaState);
101
102 env->ReleasePrimitiveArrayCritical(charsArray, chars, JNI_ABORT);
103 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104}
105
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800106static jchar nativeGetDisplayLabel(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
107 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
108 return map->getDisplayLabel(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109}
110
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800111static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jint ptr) {
112 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
113 return map->getKeyboardType();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114}
115
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800116static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, jint deviceId,
117 jcharArray charsArray) {
118 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800120 jchar* chars = env->GetCharArrayElements(charsArray, NULL);
121 if (!chars) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 return NULL;
123 }
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800124 jsize numChars = env->GetArrayLength(charsArray);
125
126 Vector<KeyEvent> events;
127 jobjectArray result = NULL;
128 if (map->getEvents(deviceId, chars, size_t(numChars), events)) {
129 result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL);
130 if (result) {
131 for (size_t i = 0; i < events.size(); i++) {
132 jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i));
133 if (!keyEventObj) break; // threw OOM exception
134 env->SetObjectArrayElement(result, jsize(i), keyEventObj);
135 env->DeleteLocalRef(keyEventObj);
136 }
137 }
138 }
139
140 env->ReleaseCharArrayElements(charsArray, chars, JNI_ABORT);
141 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142}
143
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145/*
146 * JNI registration.
147 */
148
149static JNINativeMethod g_methods[] = {
150 /* name, signature, funcPtr */
Jeff Brown1e08fe92011-11-15 17:48:10 -0800151 { "nativeLoad", "(Ljava/lang/String;)I",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800152 (void*)nativeLoad },
153 { "nativeDispose", "(I)V",
154 (void*)nativeDispose },
155 { "nativeGetCharacter", "(III)C",
156 (void*)nativeGetCharacter },
Jeff Brown49ed71d2010-12-06 17:13:33 -0800157 { "nativeGetFallbackAction", "(IIILandroid/view/KeyCharacterMap$FallbackAction;)Z",
158 (void*)nativeGetFallbackAction },
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800159 { "nativeGetNumber", "(II)C",
160 (void*)nativeGetNumber },
161 { "nativeGetMatch", "(II[CI)C",
162 (void*)nativeGetMatch },
163 { "nativeGetDisplayLabel", "(II)C",
164 (void*)nativeGetDisplayLabel },
165 { "nativeGetKeyboardType", "(I)I",
166 (void*)nativeGetKeyboardType },
167 { "nativeGetEvents", "(II[C)[Landroid/view/KeyEvent;",
168 (void*)nativeGetEvents },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169};
170
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800171#define FIND_CLASS(var, className) \
172 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800173 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800174
Jeff Brown49ed71d2010-12-06 17:13:33 -0800175#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
176 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
177 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179int register_android_text_KeyCharacterMap(JNIEnv* env)
180{
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800181 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800182 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800184 jclass clazz;
185 FIND_CLASS(clazz, "android/view/KeyCharacterMap$FallbackAction");
Jeff Brown49ed71d2010-12-06 17:13:33 -0800186
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800187 GET_FIELD_ID(gFallbackActionClassInfo.keyCode, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800188 "keyCode", "I");
189
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800190 GET_FIELD_ID(gFallbackActionClassInfo.metaState, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800191 "metaState", "I");
192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 return AndroidRuntime::registerNativeMethods(env,
194 "android/view/KeyCharacterMap", g_methods, NELEM(g_methods));
195}
196
197}; // namespace android