blob: aba3a72d8b6f56e3d2cf219dfe8af0bd8b25e23b [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 Brown6b53e8d2010-11-10 16:03:06 -080038static jint nativeLoad(JNIEnv *env, jobject clazz, jint deviceId) {
39 KeyCharacterMap* map;
40 status_t status = KeyCharacterMap::loadByDeviceId(deviceId, &map);
41 if (status) {
42 String8 msg;
43 msg.appendFormat("Could not load key character map for device %d due to error %d. "
44 "Refer to the log for details.", deviceId, status);
45 jniThrowException(env, "android/view/KeyCharacterMap$KeyCharacterMapUnavailableException",
46 msg.string());
47 return 0;
48 }
49 return reinterpret_cast<jint>(map);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050}
51
Jeff Brown6b53e8d2010-11-10 16:03:06 -080052static void nativeDispose(JNIEnv *env, jobject clazz, jint ptr) {
53 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
54 delete map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055}
56
Jeff Brown6b53e8d2010-11-10 16:03:06 -080057static jchar nativeGetCharacter(JNIEnv *env, jobject clazz, jint ptr,
58 jint keyCode, jint metaState) {
59 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
60 return map->getCharacter(keyCode, metaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061}
62
Jeff Brown49ed71d2010-12-06 17:13:33 -080063static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
64 jint metaState, jobject fallbackActionObj) {
65 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
66 KeyCharacterMap::FallbackAction fallbackAction;
67
68 bool result = map->getFallbackAction(keyCode, metaState, &fallbackAction);
69 if (result) {
70 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.keyCode,
71 fallbackAction.keyCode);
72 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.metaState,
73 fallbackAction.metaState);
74 }
75 return result;
76}
77
Jeff Brown6b53e8d2010-11-10 16:03:06 -080078static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
79 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
80 return map->getNumber(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081}
82
Jeff Brown6b53e8d2010-11-10 16:03:06 -080083static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
84 jcharArray charsArray, jint metaState) {
85 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086
Jeff Brown6b53e8d2010-11-10 16:03:06 -080087 jsize numChars = env->GetArrayLength(charsArray);
88 jchar* chars = static_cast<jchar*>(env->GetPrimitiveArrayCritical(charsArray, NULL));
89 if (!chars) {
90 return 0;
91 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092
Jeff Brown6b53e8d2010-11-10 16:03:06 -080093 char16_t result = map->getMatch(keyCode, chars, size_t(numChars), metaState);
94
95 env->ReleasePrimitiveArrayCritical(charsArray, chars, JNI_ABORT);
96 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097}
98
Jeff Brown6b53e8d2010-11-10 16:03:06 -080099static jchar nativeGetDisplayLabel(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
100 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
101 return map->getDisplayLabel(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102}
103
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800104static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jint ptr) {
105 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
106 return map->getKeyboardType();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107}
108
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800109static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, jint deviceId,
110 jcharArray charsArray) {
111 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800113 jchar* chars = env->GetCharArrayElements(charsArray, NULL);
114 if (!chars) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115 return NULL;
116 }
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800117 jsize numChars = env->GetArrayLength(charsArray);
118
119 Vector<KeyEvent> events;
120 jobjectArray result = NULL;
121 if (map->getEvents(deviceId, chars, size_t(numChars), events)) {
122 result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL);
123 if (result) {
124 for (size_t i = 0; i < events.size(); i++) {
125 jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i));
126 if (!keyEventObj) break; // threw OOM exception
127 env->SetObjectArrayElement(result, jsize(i), keyEventObj);
128 env->DeleteLocalRef(keyEventObj);
129 }
130 }
131 }
132
133 env->ReleaseCharArrayElements(charsArray, chars, JNI_ABORT);
134 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135}
136
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138/*
139 * JNI registration.
140 */
141
142static JNINativeMethod g_methods[] = {
143 /* name, signature, funcPtr */
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800144 { "nativeLoad", "(I)I",
145 (void*)nativeLoad },
146 { "nativeDispose", "(I)V",
147 (void*)nativeDispose },
148 { "nativeGetCharacter", "(III)C",
149 (void*)nativeGetCharacter },
Jeff Brown49ed71d2010-12-06 17:13:33 -0800150 { "nativeGetFallbackAction", "(IIILandroid/view/KeyCharacterMap$FallbackAction;)Z",
151 (void*)nativeGetFallbackAction },
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800152 { "nativeGetNumber", "(II)C",
153 (void*)nativeGetNumber },
154 { "nativeGetMatch", "(II[CI)C",
155 (void*)nativeGetMatch },
156 { "nativeGetDisplayLabel", "(II)C",
157 (void*)nativeGetDisplayLabel },
158 { "nativeGetKeyboardType", "(I)I",
159 (void*)nativeGetKeyboardType },
160 { "nativeGetEvents", "(II[C)[Landroid/view/KeyEvent;",
161 (void*)nativeGetEvents },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162};
163
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800164#define FIND_CLASS(var, className) \
165 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800166 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800167
Jeff Brown49ed71d2010-12-06 17:13:33 -0800168#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
169 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
170 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172int register_android_text_KeyCharacterMap(JNIEnv* env)
173{
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800174 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800175 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800177 jclass clazz;
178 FIND_CLASS(clazz, "android/view/KeyCharacterMap$FallbackAction");
Jeff Brown49ed71d2010-12-06 17:13:33 -0800179
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800180 GET_FIELD_ID(gFallbackActionClassInfo.keyCode, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800181 "keyCode", "I");
182
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800183 GET_FIELD_ID(gFallbackActionClassInfo.metaState, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800184 "metaState", "I");
185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 return AndroidRuntime::registerNativeMethods(env,
187 "android/view/KeyCharacterMap", g_methods, NELEM(g_methods));
188}
189
190}; // namespace android