Home | History | Annotate | Download | only in jni
      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