blob: a7e62c1be72d5a4602a21204973a6b297ca8d2ec [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
32static jint nativeLoad(JNIEnv *env, jobject clazz, jint deviceId) {
33 KeyCharacterMap* map;
34 status_t status = KeyCharacterMap::loadByDeviceId(deviceId, &map);
35 if (status) {
36 String8 msg;
37 msg.appendFormat("Could not load key character map for device %d due to error %d. "
38 "Refer to the log for details.", deviceId, status);
39 jniThrowException(env, "android/view/KeyCharacterMap$KeyCharacterMapUnavailableException",
40 msg.string());
41 return 0;
42 }
43 return reinterpret_cast<jint>(map);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044}
45
Jeff Brown6b53e8d2010-11-10 16:03:06 -080046static void nativeDispose(JNIEnv *env, jobject clazz, jint ptr) {
47 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
48 delete map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049}
50
Jeff Brown6b53e8d2010-11-10 16:03:06 -080051static jchar nativeGetCharacter(JNIEnv *env, jobject clazz, jint ptr,
52 jint keyCode, jint metaState) {
53 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
54 return map->getCharacter(keyCode, metaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055}
56
Jeff Brown6b53e8d2010-11-10 16:03:06 -080057static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
58 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
59 return map->getNumber(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060}
61
Jeff Brown6b53e8d2010-11-10 16:03:06 -080062static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jint ptr, jint keyCode,
63 jcharArray charsArray, jint metaState) {
64 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065
Jeff Brown6b53e8d2010-11-10 16:03:06 -080066 jsize numChars = env->GetArrayLength(charsArray);
67 jchar* chars = static_cast<jchar*>(env->GetPrimitiveArrayCritical(charsArray, NULL));
68 if (!chars) {
69 return 0;
70 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071
Jeff Brown6b53e8d2010-11-10 16:03:06 -080072 char16_t result = map->getMatch(keyCode, chars, size_t(numChars), metaState);
73
74 env->ReleasePrimitiveArrayCritical(charsArray, chars, JNI_ABORT);
75 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076}
77
Jeff Brown6b53e8d2010-11-10 16:03:06 -080078static jchar nativeGetDisplayLabel(JNIEnv *env, jobject clazz, jint ptr, jint keyCode) {
79 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
80 return map->getDisplayLabel(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081}
82
Jeff Brown6b53e8d2010-11-10 16:03:06 -080083static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jint ptr) {
84 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
85 return map->getKeyboardType();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086}
87
Jeff Brown6b53e8d2010-11-10 16:03:06 -080088static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jint ptr, jint deviceId,
89 jcharArray charsArray) {
90 KeyCharacterMap* map = reinterpret_cast<KeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091
Jeff Brown6b53e8d2010-11-10 16:03:06 -080092 jchar* chars = env->GetCharArrayElements(charsArray, NULL);
93 if (!chars) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 return NULL;
95 }
Jeff Brown6b53e8d2010-11-10 16:03:06 -080096 jsize numChars = env->GetArrayLength(charsArray);
97
98 Vector<KeyEvent> events;
99 jobjectArray result = NULL;
100 if (map->getEvents(deviceId, chars, size_t(numChars), events)) {
101 result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL);
102 if (result) {
103 for (size_t i = 0; i < events.size(); i++) {
104 jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i));
105 if (!keyEventObj) break; // threw OOM exception
106 env->SetObjectArrayElement(result, jsize(i), keyEventObj);
107 env->DeleteLocalRef(keyEventObj);
108 }
109 }
110 }
111
112 env->ReleaseCharArrayElements(charsArray, chars, JNI_ABORT);
113 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114}
115
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117/*
118 * JNI registration.
119 */
120
121static JNINativeMethod g_methods[] = {
122 /* name, signature, funcPtr */
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800123 { "nativeLoad", "(I)I",
124 (void*)nativeLoad },
125 { "nativeDispose", "(I)V",
126 (void*)nativeDispose },
127 { "nativeGetCharacter", "(III)C",
128 (void*)nativeGetCharacter },
129 { "nativeGetNumber", "(II)C",
130 (void*)nativeGetNumber },
131 { "nativeGetMatch", "(II[CI)C",
132 (void*)nativeGetMatch },
133 { "nativeGetDisplayLabel", "(II)C",
134 (void*)nativeGetDisplayLabel },
135 { "nativeGetKeyboardType", "(I)I",
136 (void*)nativeGetKeyboardType },
137 { "nativeGetEvents", "(II[C)[Landroid/view/KeyEvent;",
138 (void*)nativeGetEvents },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139};
140
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800141#define FIND_CLASS(var, className) \
142 var = env->FindClass(className); \
143 LOG_FATAL_IF(! var, "Unable to find class " className); \
144 var = jclass(env->NewGlobalRef(var));
145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146int register_android_text_KeyCharacterMap(JNIEnv* env)
147{
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800148 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
150 return AndroidRuntime::registerNativeMethods(env,
151 "android/view/KeyCharacterMap", g_methods, NELEM(g_methods));
152}
153
154}; // namespace android