12352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown/*
22352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Copyright (C) 2011 The Android Open Source Project
32352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown *
42352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
52352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * you may not use this file except in compliance with the License.
62352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * You may obtain a copy of the License at
72352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown *
82352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
92352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown *
102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Unless required by applicable law or agreed to in writing, software
112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * See the License for the specific language governing permissions and
142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * limitations under the License.
152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */
162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define LOG_TAG "PointerIcon-JNI"
182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include "JNIHelp.h"
202352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include "android_view_PointerIcon.h"
222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
232352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <android_runtime/AndroidRuntime.h>
2487eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include <android_runtime/Log.h>
252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <utils/Log.h>
262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <android/graphics/GraphicsJNI.h>
272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownnamespace android {
292352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatic struct {
312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jclass clazz;
322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jfieldID mStyle;
332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jfieldID mBitmap;
342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jfieldID mHotSpotX;
352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jfieldID mHotSpotY;
362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jmethodID getSystemIcon;
372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jmethodID load;
382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} gPointerIconClassInfo;
392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// --- Global Functions ---
422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownjobject android_view_PointerIcon_getSystemIcon(JNIEnv* env, jobject contextObj, int32_t style) {
442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jobject pointerIconObj = env->CallStaticObjectMethod(gPointerIconClassInfo.clazz,
452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            gPointerIconClassInfo.getSystemIcon, contextObj, style);
462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (env->ExceptionCheck()) {
478564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("An exception occurred while getting a pointer icon with style %d.", style);
482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        LOGW_EX(env);
492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        env->ExceptionClear();
502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        return NULL;
512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    }
522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    return pointerIconObj;
532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown}
542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatus_t android_view_PointerIcon_load(JNIEnv* env, jobject pointerIconObj, jobject contextObj,
562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        PointerIcon* outPointerIcon) {
572352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    outPointerIcon->reset();
582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (!pointerIconObj) {
602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        return OK;
612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    }
622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jobject loadedPointerIconObj = env->CallObjectMethod(pointerIconObj,
642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            gPointerIconClassInfo.load, contextObj);
652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (env->ExceptionCheck() || !loadedPointerIconObj) {
668564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("An exception occurred while loading a pointer icon.");
672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        LOGW_EX(env);
682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        env->ExceptionClear();
692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        return UNKNOWN_ERROR;
702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    }
712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    outPointerIcon->style = env->GetIntField(loadedPointerIconObj,
732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            gPointerIconClassInfo.mStyle);
742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    outPointerIcon->hotSpotX = env->GetFloatField(loadedPointerIconObj,
752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            gPointerIconClassInfo.mHotSpotX);
762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    outPointerIcon->hotSpotY = env->GetFloatField(loadedPointerIconObj,
772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            gPointerIconClassInfo.mHotSpotY);
782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jobject bitmapObj = env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmap);
802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (bitmapObj) {
812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        SkBitmap* bitmap = GraphicsJNI::getNativeBitmap(env, bitmapObj);
822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        if (bitmap) {
832352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            outPointerIcon->bitmap = *bitmap; // use a shared pixel ref
842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        }
852352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        env->DeleteLocalRef(bitmapObj);
862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    }
872352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
882352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    env->DeleteLocalRef(loadedPointerIconObj);
892352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    return OK;
902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown}
912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatus_t android_view_PointerIcon_loadSystemIcon(JNIEnv* env, jobject contextObj,
932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        int32_t style, PointerIcon* outPointerIcon) {
942352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    jobject pointerIconObj = android_view_PointerIcon_getSystemIcon(env, contextObj, style);
952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (!pointerIconObj) {
962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        outPointerIcon->reset();
972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        return UNKNOWN_ERROR;
982352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    }
992352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1002352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    status_t status = android_view_PointerIcon_load(env, pointerIconObj,
1012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            contextObj, outPointerIcon);
1022352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    env->DeleteLocalRef(pointerIconObj);
1032352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    return status;
1042352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown}
1052352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1062352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1072352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// --- JNI Registration ---
1082352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1092352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define FIND_CLASS(var, className) \
1102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        var = env->FindClass(className); \
1112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        LOG_FATAL_IF(! var, "Unable to find class " className); \
1122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        var = jclass(env->NewGlobalRef(var));
1132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
1162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        LOG_FATAL_IF(! var, "Unable to find method " methodName);
1172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1202352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        LOG_FATAL_IF(! var, "Unable to find method " methodName);
1212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1232352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1242352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownint register_android_view_PointerIcon(JNIEnv* env) {
1272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    FIND_CLASS(gPointerIconClassInfo.clazz, "android/view/PointerIcon");
1282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1292352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    GET_FIELD_ID(gPointerIconClassInfo.mBitmap, gPointerIconClassInfo.clazz,
1302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "mBitmap", "Landroid/graphics/Bitmap;");
1312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    GET_FIELD_ID(gPointerIconClassInfo.mStyle, gPointerIconClassInfo.clazz,
1332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "mStyle", "I");
1342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    GET_FIELD_ID(gPointerIconClassInfo.mHotSpotX, gPointerIconClassInfo.clazz,
1362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "mHotSpotX", "F");
1372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    GET_FIELD_ID(gPointerIconClassInfo.mHotSpotY, gPointerIconClassInfo.clazz,
1392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "mHotSpotY", "F");
1402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    GET_STATIC_METHOD_ID(gPointerIconClassInfo.getSystemIcon, gPointerIconClassInfo.clazz,
1422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "getSystemIcon", "(Landroid/content/Context;I)Landroid/view/PointerIcon;");
1432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    GET_METHOD_ID(gPointerIconClassInfo.load, gPointerIconClassInfo.clazz,
1452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "load", "(Landroid/content/Context;)Landroid/view/PointerIcon;");
1462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    return 0;
1482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown}
1492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
1502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} // namespace android
151