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