istereo2
view src/android/amain.c @ 29:c6c45fa9658d
fixed jni calls for ads
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 08 Oct 2015 04:55:45 +0300 |
parents | f0da8b2b61ec |
children | 900651a2f401 |
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <EGL/egl.h>
5 #include <jni.h>
6 #include "android_native_app_glue.h"
7 #include <android/window.h>
8 #include <android/sensor.h>
9 #include "logger.h"
10 #include "istereo.h"
12 struct android_app *app;
14 static void handle_command(struct android_app *app, int32_t cmd);
15 static int handle_input(struct android_app *app, AInputEvent *ev);
16 static int handle_touch_input(struct android_app *app, AInputEvent *ev);
17 static int init_gl(void);
18 static void destroy_gl(void);
20 static EGLDisplay dpy;
21 static EGLSurface surf;
22 static EGLContext ctx;
24 static int redisp_pending = 1; /* TODO stop busy-looping */
26 static int width, height;
27 static int init_done;
29 static JavaVM *jvm;
30 static JNIEnv *jni;
31 static jclass activity_class;
32 static jobject activity;
34 void android_main(struct android_app *app_ptr)
35 {
36 app_dummy();
37 app = app_ptr;
39 app->onAppCmd = handle_command;
40 app->onInputEvent = handle_input;
42 //ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FULLSCREEN, 0);
44 start_logger();
46 jvm = app->activity->vm;
47 if((*jvm)->AttachCurrentThread(jvm, &jni, 0) != 0) {
48 fprintf(stderr, "failed to attach native thread to Java VM\n");
49 exit(1);
50 }
51 activity = app->activity->clazz;
52 activity_class = (*jni)->GetObjectClass(jni, app->activity->clazz);
54 for(;;) {
55 int num_events;
56 struct android_poll_source *pollsrc;
58 while(ALooper_pollAll(0, 0, &num_events, (void**)&pollsrc) >= 0) {
59 if(pollsrc) {
60 pollsrc->process(app, pollsrc);
61 }
62 }
64 if(app->destroyRequested) {
65 return;
66 }
68 if(init_done && redisp_pending) {
69 redraw();
70 eglSwapBuffers(dpy, surf);
71 }
72 }
73 }
75 void set_mouse_pos(int x, int y)
76 {
77 }
79 void set_mouse_cursor(int enable)
80 {
81 }
83 /* TODO */
84 void ad_banner_show(void)
85 {
86 jmethodID method;
87 if(!jvm) return;
89 if(!(method = (*jni)->GetMethodID(jni, activity_class, "show_ad", "()V"))) {
90 fprintf(stderr, "failed to retrieve MainActivity.show_ad method\n");
91 return;
92 }
93 (*jni)->CallVoidMethod(jni, activity, method);
94 }
96 void ad_banner_hide(void)
97 {
98 jmethodID method;
99 if(!jvm) return;
101 if(!(method = (*jni)->GetMethodID(jni, activity_class, "hide_ad", "()V"))) {
102 fprintf(stderr, "failed to retrieve MainActivity.hide_ad method\n");
103 return;
104 }
105 (*jni)->CallVoidMethod(jni, activity, method);
106 }
108 static void handle_command(struct android_app *app, int32_t cmd)
109 {
110 switch(cmd) {
111 case APP_CMD_SAVE_STATE:
112 /* save the application state to be reloaded on restart if needed */
113 break;
115 case APP_CMD_INIT_WINDOW:
116 printf("APP_CMD_INIT_WINDOW\n");
117 if(init_gl() == -1) {
118 exit(1);
119 }
120 /* initialize the application */
121 if(init() == -1) {
122 exit(1); /* initialization failed, quit */
123 }
124 reshape(width, height);
125 init_done = 1;
126 break;
128 case APP_CMD_TERM_WINDOW:
129 /* cleanup */
130 printf("APP_CMD_TERM_WINDOW\n");
131 init_done = 0;
132 cleanup();
133 destroy_gl();
134 break;
136 case APP_CMD_GAINED_FOCUS:
137 printf("APP_CMD_GAINED_FOCUS\n");
138 /* app focused */
139 break;
141 case APP_CMD_LOST_FOCUS:
142 printf("APP_CMD_LOST_FOCUS\n");
143 /* app lost focus */
144 break;
146 case APP_CMD_WINDOW_RESIZED:
147 case APP_CMD_CONFIG_CHANGED:
148 {
149 int nx = ANativeWindow_getWidth(app->window);
150 int ny = ANativeWindow_getHeight(app->window);
151 if(nx != width || ny != height) {
152 printf("reshape(%d, %d)\n", nx, ny);
153 reshape(nx, ny);
154 width = nx;
155 height = ny;
156 }
157 }
158 break;
160 default:
161 break;
162 }
163 }
165 static int handle_input(struct android_app *app, AInputEvent *ev)
166 {
167 int evtype = AInputEvent_getType(ev);
169 switch(evtype) {
170 case AINPUT_EVENT_TYPE_MOTION:
171 return handle_touch_input(app, ev);
173 default:
174 break;
175 }
176 return 0;
177 }
179 #define MAX_TOUCH_IDS 32
181 static int handle_touch_input(struct android_app *app, AInputEvent *ev)
182 {
183 int x, y, idx, touch_id;
184 unsigned int action;
185 static int prev_pos[MAX_TOUCH_IDS][2];
187 action = AMotionEvent_getAction(ev);
189 idx = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
190 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
191 touch_id = AMotionEvent_getPointerId(ev, idx);
193 x = AMotionEvent_getX(ev, idx);
194 y = AMotionEvent_getY(ev, idx);
196 switch(action & AMOTION_EVENT_ACTION_MASK) {
197 case AMOTION_EVENT_ACTION_DOWN:
198 case AMOTION_EVENT_ACTION_POINTER_DOWN:
199 if(touch_id == 0) {
200 mouse_button(0, 1, x, y);
201 }
202 if(touch_id < MAX_TOUCH_IDS) {
203 prev_pos[touch_id][0] = x;
204 prev_pos[touch_id][1] = y;
205 }
206 break;
208 case AMOTION_EVENT_ACTION_UP:
209 case AMOTION_EVENT_ACTION_POINTER_UP:
210 if(touch_id == 0) {
211 mouse_button(0, 0, x, y);
212 }
213 if(touch_id < MAX_TOUCH_IDS) {
214 prev_pos[touch_id][0] = x;
215 prev_pos[touch_id][1] = y;
216 }
217 break;
219 case AMOTION_EVENT_ACTION_MOVE:
220 {
221 int i, pcount = AMotionEvent_getPointerCount(ev);
222 for(i=0; i<pcount; i++) {
223 int id = AMotionEvent_getPointerId(ev, i);
224 if(id < MAX_TOUCH_IDS && x != prev_pos[id][0] && y != prev_pos[id][1]) {
225 if(id == 0) {
226 mouse_motion(x, y);
227 }
228 prev_pos[id][0] = x;
229 prev_pos[id][1] = y;
230 }
231 }
232 }
233 break;
235 default:
236 break;
237 }
239 return 1;
240 }
243 static int init_gl(void)
244 {
245 static const int eglattr[] = {
246 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
247 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
248 EGL_RED_SIZE, 5,
249 EGL_GREEN_SIZE, 5,
250 EGL_BLUE_SIZE, 5,
251 EGL_DEPTH_SIZE, 16,
252 EGL_NONE
253 };
254 static const int ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
256 EGLConfig eglcfg;
257 int count, vis;
259 dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
260 if(!dpy || !eglInitialize(dpy, 0, 0)) {
261 fprintf(stderr, "failed to initialize EGL\n");
262 destroy_gl();
263 return -1;
264 }
266 if(!eglChooseConfig(dpy, eglattr, &eglcfg, 1, &count)) {
267 fprintf(stderr, "no matching EGL config found\n");
268 destroy_gl();
269 return -1;
270 }
272 /* configure the native window visual according to the chosen EGL config */
273 eglGetConfigAttrib(dpy, &eglcfg, EGL_NATIVE_VISUAL_ID, &vis);
274 ANativeWindow_setBuffersGeometry(app->window, 0, 0, vis);
276 if(!(surf = eglCreateWindowSurface(dpy, eglcfg, app->window, 0))) {
277 fprintf(stderr, "failed to create window\n");
278 destroy_gl();
279 return -1;
280 }
282 if(!(ctx = eglCreateContext(dpy, eglcfg, EGL_NO_CONTEXT, ctxattr))) {
283 fprintf(stderr, "failed to create OpenGL ES context\n");
284 destroy_gl();
285 return -1;
286 }
287 eglMakeCurrent(dpy, surf, surf, ctx);
289 eglQuerySurface(dpy, surf, EGL_WIDTH, &width);
290 eglQuerySurface(dpy, surf, EGL_HEIGHT, &height);
291 printf("initial reshape call: %dx%d\n", width, height);
292 reshape(width, height);
294 return 0;
295 }
297 static void destroy_gl(void)
298 {
299 if(!dpy) return;
301 eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
303 if(ctx) {
304 eglDestroyContext(dpy, ctx);
305 ctx = 0;
306 }
307 if(surf) {
308 eglDestroySurface(dpy, surf);
309 surf = 0;
310 }
312 eglTerminate(dpy);
313 dpy = 0;
314 }