blob: bfeec4fcc088e6de64dc3d41e768cf308429abf5 [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 {
33 jclass clazz;
34
35 jfieldID keyCode;
36 jfieldID metaState;
37} gFallbackActionClassInfo;
38
39
Jeff Brown6b53e8d2010-11-10 16:03:06 -080040static jint nativeLoad(JNIEnv *env, jobject clazz, jint deviceId) {
41 KeyCharacterMap* map;
42 status_t status = KeyCharacterMap::loadByDeviceId(deviceId, &map);
43 if (status) {
44 String8 msg;
45 msg.appendFormat("Could not load key character map for device %d due to error %d. "
46 "Refer to the log for details.", deviceId, status);
47 jniThrowException(env, "android/view/KeyCharacterMap$KeyCharacterMapUnavailableException",
48 msg.string());
49 return 0;
50 }
51 return reinterpret_cast<jint>(map);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052}
53
Jeff Brown6b53e8d2010-11-10 16:03:06 -080054static void nativeDispose(JNIEnv *env, jobject clazz, jint ptr) {
55 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
56 delete map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057}
58
Jeff Brown6b53e8d2010-11-10 16:03:06 -080059static jchar nativeGetCharacter(JNIEnv *env, jobject clazz, jint ptr,
60 jint keyCode, jint metaState) {
61 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
62 return map->getCharacter(keyCode, metaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063}
64
Jeff Brown49ed71d2010-12-06 17:13:33 -080065static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
66 jint metaState, jobject fallbackActionObj) {
67 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
68 KeyCharacterMap::FallbackAction fallbackAction;
69
70 bool result = map->getFallbackAction(keyCode, metaState, &fallbackAction);
71 if (result) {
72 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.keyCode,
73 fallbackAction.keyCode);
74 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.metaState,
75 fallbackAction.metaState);
76 }
77 return result;
78}
79
Jeff Brown6b53e8d2010-11-10 16:03:06 -080080static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
81 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
82 return map->getNumber(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083}
84
Jeff Brown6b53e8d2010-11-10 16:03:06 -080085static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
86 jcharArray charsArray, jint metaState) {
87 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
Jeff Brown6b53e8d2010-11-10 16:03:06 -080089 jsize numChars = env->GetArrayLength(charsArray);
90 jchar* chars = static_cast<jchar*>(env->GetPrimitiveArrayCritical(charsArray, NULL));
91 if (!chars) {
92 return 0;
93 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094
Jeff Brown6b53e8d2010-11-10 16:03:06 -080095 char16_t result = map->getMatch(keyCode, chars, size_t(numChars), metaState);
96
97 env->ReleasePrimitiveArrayCritical(charsArray, chars, JNI_ABORT);
98 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099}
100
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800101static jchar nativeGetDisplayLabel(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
102 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
103 return map->getDisplayLabel(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104}
105
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800106static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jint ptr) {
107 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
108 return map->getKeyboardType();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109}
110
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800111static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, jint deviceId,
112 jcharArray charsArray) {
113 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800115 jchar* chars = env->GetCharArrayElements(charsArray, NULL);
116 if (!chars) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 return NULL;
118 }
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800119 jsize numChars = env->GetArrayLength(charsArray);
120
121 Vector<KeyEvent> events;
122 jobjectArray result = NULL;
123 if (map->getEvents(deviceId, chars, size_t(numChars), events)) {
124 result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL);
125 if (result) {
126 for (size_t i = 0; i < events.size(); i++) {
127 jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i));
128 if (!keyEventObj) break; // threw OOM exception
129 env->SetObjectArrayElement(result, jsize(i), keyEventObj);
130 env->DeleteLocalRef(keyEventObj);
131 }
132 }
133 }
134
135 env->ReleaseCharArrayElements(charsArray, chars, JNI_ABORT);
136 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137}
138
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140/*
141 * JNI registration.
142 */
143
144static JNINativeMethod g_methods[] = {
145 /* name, signature, funcPtr */
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800146 { "nativeLoad", "(I)I",
147 (void*)nativeLoad },
148 { "nativeDispose", "(I)V",
149 (void*)nativeDispose },
150 { "nativeGetCharacter", "(III)C",
151 (void*)nativeGetCharacter },
Jeff Brown49ed71d2010-12-06 17:13:33 -0800152 { "nativeGetFallbackAction", "(IIILandroid/view/KeyCharacterMap$FallbackAction;)Z",
153 (void*)nativeGetFallbackAction },
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800154 { "nativeGetNumber", "(II)C",
155 (void*)nativeGetNumber },
156 { "nativeGetMatch", "(II[CI)C",
157 (void*)nativeGetMatch },
158 { "nativeGetDisplayLabel", "(II)C",
159 (void*)nativeGetDisplayLabel },
160 { "nativeGetKeyboardType", "(I)I",
161 (void*)nativeGetKeyboardType },
162 { "nativeGetEvents", "(II[C)[Landroid/view/KeyEvent;",
163 (void*)nativeGetEvents },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164};
165
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800166#define FIND_CLASS(var, className) \
167 var = env->FindClass(className); \
168 LOG_FATAL_IF(! var, "Unable to find class " className); \
169 var = jclass(env->NewGlobalRef(var));
170
Jeff Brown49ed71d2010-12-06 17:13:33 -0800171#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
172 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
173 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175int register_android_text_KeyCharacterMap(JNIEnv* env)
176{
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800177 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178
Jeff Brown49ed71d2010-12-06 17:13:33 -0800179 FIND_CLASS(gFallbackActionClassInfo.clazz, "android/view/KeyCharacterMap$FallbackAction");
180
181 GET_FIELD_ID(gFallbackActionClassInfo.keyCode, gFallbackActionClassInfo.clazz,
182 "keyCode", "I");
183
184 GET_FIELD_ID(gFallbackActionClassInfo.metaState, gFallbackActionClassInfo.clazz,
185 "metaState", "I");
186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 return AndroidRuntime::registerNativeMethods(env,
188 "android/view/KeyCharacterMap", g_methods, NELEM(g_methods));
189}
190
191}; // namespace android