• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
ActivityGlueActivityGlue35     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;
WindowGlueWindowGlue45     WindowGlue() {
46         m_obj = NULL;
47         m_inval = NULL;
48     }
49 } gWindowGlue;
50 
51 SkOSWindow* gWindow;
52 
53 ///////////////////////////////////////////
54 ///////////// SkOSWindow impl /////////////
55 ///////////////////////////////////////////
56 
onSetTitle(const char title[])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 
onHandleInval(const SkIRect & rect)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 
SignalQueueTimer(SkMSec)81 void SkEvent::SignalQueueTimer(SkMSec) {}
82 
SignalNonEmptyQueue()83 void SkEvent::SignalNonEmptyQueue() {}
84 
85 ///////////////////////////////////////////
86 ////////////////// JNI ////////////////////
87 ///////////////////////////////////////////
88 
GetJMethod(JNIEnv * env,jclass clazz,const char name[],const char signature[])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 
Java_com_skia_sampleapp_SampleApp_handleKeyDown(JNIEnv * env,jobject thiz,jint keyCode,jint uni)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 
Java_com_skia_sampleapp_SampleApp_handleKeyUp(JNIEnv * env,jobject thiz,jint keyCode)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 
Java_com_skia_sampleapp_SampleApp_handleClick(JNIEnv * env,jobject thiz,jint x,jint y,jint jstate)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 
Java_com_skia_sampleapp_SampleApp_updateSize(JNIEnv * env,jobject thiz,jint w,jint h)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 
Java_com_skia_sampleapp_SampleApp_createOSWindow(JNIEnv * env,jobject thiz,jobject jsampleView)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 
Java_com_skia_sampleapp_SampleApp_init(JNIEnv * env,jobject thiz)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 
Java_com_skia_sampleapp_SampleApp_term(JNIEnv * env,jobject thiz)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 
Java_com_skia_sampleapp_SampleApp_drawToCanvas(JNIEnv * env,jobject thiz,jobject jcanvas)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