1 /* 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> 18 19 #include <nativehelper/jni.h> 20 #include <android_runtime/AndroidRuntime.h> 21 #include <nativehelper/JNIHelp.h> 22 23 namespace android { 24 25 static jint 26 ctor(JNIEnv *env, jobject clazz, jint id) 27 { 28 return reinterpret_cast<int>(KeyCharacterMap::load(id)); 29 } 30 31 static void 32 dtor(JNIEnv *env, jobject clazz, jint ptr) 33 { 34 delete reinterpret_cast<KeyCharacterMap*>(ptr); 35 } 36 37 static jchar 38 get(JNIEnv *env, jobject clazz, jint ptr, jint keycode, jint meta) 39 { 40 return reinterpret_cast<KeyCharacterMap*>(ptr)->get(keycode, meta); 41 } 42 43 static jchar 44 getNumber(JNIEnv *env, jobject clazz, jint ptr, jint keycode) 45 { 46 return reinterpret_cast<KeyCharacterMap*>(ptr)->getNumber(keycode); 47 } 48 49 static jchar 50 getMatch(JNIEnv *env, jobject clazz, jint ptr, jint keycode, jcharArray chars, jint modifiers) 51 { 52 jchar rv; 53 jchar* ch = env->GetCharArrayElements(chars, NULL); 54 jsize chsize = env->GetArrayLength(chars); 55 56 rv = reinterpret_cast<KeyCharacterMap*>(ptr)->getMatch(keycode, ch, chsize, modifiers); 57 58 env->ReleaseCharArrayElements(chars, ch, JNI_ABORT); 59 return rv; 60 } 61 62 static jchar 63 getDisplayLabel(JNIEnv *env, jobject clazz, jint ptr, jint keycode) 64 { 65 return reinterpret_cast<KeyCharacterMap*>(ptr)->getDisplayLabel(keycode); 66 } 67 68 static jfieldID gKeyDataMetaField; 69 static jfieldID gKeyDataNumberField; 70 static jfieldID gKeyDataDisplayLabelField; 71 72 static jboolean 73 getKeyData(JNIEnv *env, jobject clazz, jint ptr, jint keycode, jobject keydata) 74 { 75 jboolean rv; 76 77 unsigned short displayLabel = env->GetCharField(keydata, gKeyDataDisplayLabelField); 78 unsigned short number = env->GetCharField(keydata, gKeyDataNumberField); 79 80 jcharArray chars = (jcharArray) env->GetObjectField(keydata, gKeyDataMetaField); 81 jchar* ch = env->GetCharArrayElements(chars, NULL); 82 83 KeyCharacterMap* kmap = reinterpret_cast<KeyCharacterMap*>(ptr); 84 rv = kmap->getKeyData(keycode, &displayLabel, &number, ch); 85 86 env->SetCharField(keydata, gKeyDataDisplayLabelField, displayLabel); 87 env->SetCharField(keydata, gKeyDataNumberField, number); 88 89 env->ReleaseCharArrayElements(chars, ch, 0); 90 return rv; 91 } 92 93 static jint 94 getKeyboardType(JNIEnv *env, jobject clazz, jint ptr) 95 { 96 return reinterpret_cast<KeyCharacterMap*>(ptr)->getKeyboardType(); 97 } 98 99 static jlongArray 100 getEvents(JNIEnv *env, jobject clazz, jint ptr, jcharArray jchars) 101 { 102 KeyCharacterMap* kmap = reinterpret_cast<KeyCharacterMap*>(ptr); 103 104 uint16_t* chars = env->GetCharArrayElements(jchars, NULL); 105 size_t len = env->GetArrayLength(jchars); 106 107 Vector<int32_t> keys; 108 Vector<uint32_t> modifiers; 109 bool success = kmap->getEvents(chars, len, &keys, &modifiers); 110 111 env->ReleaseCharArrayElements(jchars, chars, JNI_ABORT); 112 113 if (success) { 114 size_t N = keys.size(); 115 116 jlongArray rv = env->NewLongArray(N); 117 uint64_t* results = (uint64_t*)env->GetLongArrayElements(rv, NULL); 118 119 for (size_t i=0; i<N; i++) { 120 uint64_t v = modifiers[i]; 121 v <<= 32; 122 v |= keys[i]; 123 results[i] = v; 124 } 125 126 env->ReleaseLongArrayElements(rv, (jlong*)results, 0); 127 return rv; 128 } else { 129 return NULL; 130 } 131 } 132 133 // ============================================================================ 134 /* 135 * JNI registration. 136 */ 137 138 static JNINativeMethod g_methods[] = { 139 /* name, signature, funcPtr */ 140 { "ctor_native", "(I)I", (void*)ctor }, 141 { "dtor_native", "(I)V", (void*)dtor }, 142 { "get_native", "(III)C", (void*)get }, 143 { "getNumber_native", "(II)C", (void*)getNumber }, 144 { "getMatch_native", "(II[CI)C", (void*)getMatch }, 145 { "getDisplayLabel_native", "(II)C", (void*)getDisplayLabel }, 146 { "getKeyData_native", "(IILandroid/view/KeyCharacterMap$KeyData;)Z", 147 (void*)getKeyData }, 148 { "getKeyboardType_native", "(I)I", (void*)getKeyboardType }, 149 { "getEvents_native", "(I[C)[J", (void*)getEvents } 150 }; 151 152 int register_android_text_KeyCharacterMap(JNIEnv* env) 153 { 154 jclass clazz; 155 156 clazz = env->FindClass("android/view/KeyCharacterMap$KeyData"); 157 if (clazz == NULL) { 158 LOGE("Can't find android/view/KeyCharacterMap$KeyData"); 159 return -1; 160 } 161 162 gKeyDataMetaField = env->GetFieldID(clazz, "meta", "[C"); 163 gKeyDataNumberField = env->GetFieldID(clazz, "number", "C"); 164 gKeyDataDisplayLabelField = env->GetFieldID(clazz, "displayLabel", "C"); 165 166 return AndroidRuntime::registerNativeMethods(env, 167 "android/view/KeyCharacterMap", g_methods, NELEM(g_methods)); 168 } 169 170 }; // namespace android 171 172 173 174