Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2011 Skia
      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 
     18 #include <jni.h>
     19 
     20 #include "SkCanvas.h"
     21 #include "GraphicsJNI.h"
     22 #include "SkEvent.h"
     23 #include "SkWindow.h"
     24 #include "SkApplication.h"
     25 #include "utils/android/AndroidKeyToSkKey.h"
     26 
     27 ///////////////////////////////////////////
     28 ///////////////// Globals /////////////////
     29 ///////////////////////////////////////////
     30 
     31 struct ActivityGlue {
     32     JNIEnv* m_env;
     33     jweak m_obj;
     34     jmethodID m_setTitle;
     35     ActivityGlue() {
     36         m_env = NULL;
     37         m_obj = NULL;
     38         m_setTitle = NULL;
     39     }
     40 } gActivityGlue;
     41 
     42 struct WindowGlue {
     43     jweak m_obj;
     44     jmethodID m_inval;
     45     WindowGlue() {
     46         m_obj = NULL;
     47         m_inval = NULL;
     48     }
     49 } gWindowGlue;
     50 
     51 SkOSWindow* gWindow;
     52 
     53 ///////////////////////////////////////////
     54 ///////////// SkOSWindow impl /////////////
     55 ///////////////////////////////////////////
     56 
     57 void SkOSWindow::onSetTitle(const char title[])
     58 {
     59     if (gActivityGlue.m_env) {
     60         JNIEnv* env = gActivityGlue.m_env;
     61         jstring string = env->NewStringUTF(title);
     62         env->CallVoidMethod(gActivityGlue.m_obj, gActivityGlue.m_setTitle,
     63                 string);
     64         env->DeleteLocalRef(string);
     65     }
     66 }
     67 
     68 void SkOSWindow::onHandleInval(const SkIRect& rect)
     69 {
     70     if (!gActivityGlue.m_env || !gWindowGlue.m_inval || !gWindowGlue.m_obj) {
     71         return;
     72     }
     73     gActivityGlue.m_env->CallVoidMethod(gWindowGlue.m_obj, gWindowGlue.m_inval,
     74             rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
     75 }
     76 
     77 ///////////////////////////////////////////
     78 /////////////// SkEvent impl //////////////
     79 ///////////////////////////////////////////
     80 
     81 void SkEvent::SignalQueueTimer(SkMSec) {}
     82 
     83 void SkEvent::SignalNonEmptyQueue() {}
     84 
     85 ///////////////////////////////////////////
     86 ////////////////// JNI ////////////////////
     87 ///////////////////////////////////////////
     88 
     89 static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[],
     90         const char signature[])
     91 {
     92     jmethodID m = env->GetMethodID(clazz, name, signature);
     93     if (!m) SkDebugf("Could not find Java method %s\n", name);
     94     return m;
     95 }
     96 
     97 extern "C" {
     98 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_drawToCanvas(
     99         JNIEnv* env, jobject thiz, jobject jcanvas);
    100 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_init(
    101         JNIEnv* env, jobject thiz);
    102 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_term(
    103         JNIEnv* env, jobject thiz);
    104 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_updateSize(
    105         JNIEnv* env, jobject thiz, jint w, jint h);
    106 JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyDown(
    107         JNIEnv* env, jobject thiz, jint keyCode, jint uni);
    108 JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyUp(
    109         JNIEnv* env, jobject thiz, jint keyCode);
    110 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_handleClick(
    111         JNIEnv* env, jobject thiz, jint x, jint y, jint state);
    112 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_createOSWindow(
    113         JNIEnv* env, jobject thiz, jobject jsampleView);
    114 };
    115 
    116 JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyDown(
    117         JNIEnv* env, jobject thiz, jint keyCode, jint uni)
    118 {
    119     bool handled = gWindow->handleKey(AndroidKeycodeToSkKey(keyCode));
    120     handled |= gWindow->handleChar((SkUnichar) uni);
    121     return handled;
    122 }
    123 
    124 JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyUp(JNIEnv* env,
    125         jobject thiz, jint keyCode)
    126 {
    127     return gWindow->handleKeyUp(AndroidKeycodeToSkKey(keyCode));
    128 }
    129 
    130 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_handleClick(JNIEnv* env,
    131         jobject thiz, jint x, jint y, jint jstate)
    132 {
    133     SkView::Click::State state;
    134     switch(jstate) {
    135         case 0:     // MotionEvent.ACTION_DOWN
    136             state = SkView::Click::kDown_State;
    137             break;
    138         case 1:     // MotionEvent.ACTION_UP
    139         case 3:     // MotionEvent.ACTION_CANCEL
    140             state = SkView::Click::kUp_State;
    141             break;
    142         case 2:     // MotionEvent.ACTION_MOVE
    143             state = SkView::Click::kMoved_State;
    144             break;
    145         default:
    146             SkDebugf("motion event ignored\n");
    147             return;
    148     }
    149     gWindow->handleClick(x, y, state);
    150 }
    151 
    152 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_updateSize(JNIEnv* env,
    153         jobject thiz, jint w, jint h)
    154 {
    155     gWindow->resize(w, h);
    156 }
    157 
    158 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_createOSWindow(
    159         JNIEnv* env, jobject thiz, jobject jsampleView)
    160 {
    161     gWindow = create_sk_window(NULL);
    162     // Only using a method on View.
    163     jclass clazz = gActivityGlue.m_env->FindClass("android/view/View");
    164     gWindowGlue.m_obj = gActivityGlue.m_env->NewWeakGlobalRef(jsampleView);
    165     gWindowGlue.m_inval = GetJMethod(gActivityGlue.m_env, clazz, "invalidate",
    166             "(IIII)V");
    167     gActivityGlue.m_env->DeleteLocalRef(clazz);
    168 }
    169 
    170 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_init(JNIEnv* env,
    171         jobject thiz)
    172 {
    173     gActivityGlue.m_env = env;
    174     // Only using a method on Activity.
    175     jclass clazz = env->FindClass("android/app/Activity");
    176     gActivityGlue.m_obj = env->NewWeakGlobalRef(thiz);
    177     gActivityGlue.m_setTitle = GetJMethod(env, clazz, "setTitle",
    178             "(Ljava/lang/CharSequence;)V");
    179     env->DeleteLocalRef(clazz);
    180 
    181     application_init();
    182 }
    183 
    184 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_term(JNIEnv* env,
    185         jobject thiz)
    186 {
    187     application_term();
    188     if (gWindowGlue.m_obj) {
    189         env->DeleteWeakGlobalRef(gWindowGlue.m_obj);
    190         gWindowGlue.m_obj = NULL;
    191     }
    192     if (gActivityGlue.m_obj) {
    193         env->DeleteWeakGlobalRef(gActivityGlue.m_obj);
    194         gActivityGlue.m_obj = NULL;
    195     }
    196     delete gWindow;
    197     gWindow = NULL;
    198 }
    199 
    200 
    201 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_drawToCanvas(
    202         JNIEnv* env, jobject thiz, jobject jcanvas)
    203 {
    204     if (!gWindow) return;
    205     gWindow->update(NULL);
    206     SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
    207     canvas->drawBitmap(gWindow->getBitmap(), 0, 0);
    208 }
    209