6 #include "android_native_app_glue.h"
9 static void handle_command(struct android_app *app, int32_t cmd);
10 static int handle_input(struct android_app *app, AInputEvent *ev);
11 static int handle_touch_input(struct android_app *app, AInputEvent *ev);
12 static int init_gl(void);
13 static void destroy_gl(void);
15 struct android_app *app;
17 static EGLDisplay dpy;
18 static EGLSurface surf;
19 static EGLContext ctx;
20 static int init_done, paused;
22 static int width, height;
25 void android_main(struct android_app *app_ptr)
29 app->onAppCmd = handle_command;
30 app->onInputEvent = handle_input;
36 struct android_poll_source *pollsrc;
38 while(ALooper_pollAll(0, 0, &num_events, (void**)&pollsrc) >= 0) {
40 pollsrc->process(app, pollsrc);
44 if(app->destroyRequested) {
47 if(init_done && !paused) {
49 eglSwapBuffers(dpy, surf);
54 static void handle_command(struct android_app *app, int32_t cmd)
60 paused = 1; /* TODO: handle timers */
66 case APP_CMD_INIT_WINDOW:
70 if(demo_init() == -1) {
73 demo_reshape(width, height);
77 case APP_CMD_TERM_WINDOW:
83 case APP_CMD_WINDOW_RESIZED:
84 case APP_CMD_CONFIG_CHANGED:
85 xsz = ANativeWindow_getWidth(app->window);
86 ysz = ANativeWindow_getHeight(app->window);
87 if(xsz != width || ysz != height) {
88 printf("reshape(%d, %d)\n", xsz, ysz);
89 demo_reshape(xsz, ysz);
96 case APP_CMD_SAVE_STATE:
97 case APP_CMD_GAINED_FOCUS:
98 case APP_CMD_LOST_FOCUS:
105 static int handle_input(struct android_app *app, AInputEvent *ev)
107 int evtype = AInputEvent_getType(ev);
110 case AINPUT_EVENT_TYPE_MOTION:
111 return handle_touch_input(app, ev);
119 static int handle_touch_input(struct android_app *app, AInputEvent *ev)
121 int i, pcount, x, y, idx;
123 static int prev_pos[2];
125 action = AMotionEvent_getAction(ev);
127 idx = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
128 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
130 x = AMotionEvent_getX(ev, idx);
131 y = AMotionEvent_getY(ev, idx);
133 switch(action & AMOTION_EVENT_ACTION_MASK) {
134 case AMOTION_EVENT_ACTION_DOWN:
135 case AMOTION_EVENT_ACTION_POINTER_DOWN:
136 demo_mouse(0, 1, x, y);
142 case AMOTION_EVENT_ACTION_UP:
143 case AMOTION_EVENT_ACTION_POINTER_UP:
144 demo_mouse(0, 0, x, y);
150 case AMOTION_EVENT_ACTION_MOVE:
151 pcount = AMotionEvent_getPointerCount(ev);
152 for(i=0; i<pcount; i++) {
153 int id = AMotionEvent_getPointerId(ev, i);
170 static int init_gl(void)
172 static const int eglattr[] = {
173 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
174 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
181 static const int ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
186 dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
187 if(!dpy || !eglInitialize(dpy, 0, 0)) {
188 fprintf(stderr, "failed to initialize EGL\n");
193 if(!eglChooseConfig(dpy, eglattr, &eglcfg, 1, &count)) {
194 fprintf(stderr, "no matching EGL config found\n");
199 /* configure the native window visual according to the chosen EGL config */
200 eglGetConfigAttrib(dpy, &eglcfg, EGL_NATIVE_VISUAL_ID, &vis);
201 ANativeWindow_setBuffersGeometry(app->window, 0, 0, vis);
203 if(!(surf = eglCreateWindowSurface(dpy, eglcfg, app->window, 0))) {
204 fprintf(stderr, "failed to create window\n");
209 if(!(ctx = eglCreateContext(dpy, eglcfg, EGL_NO_CONTEXT, ctxattr))) {
210 fprintf(stderr, "failed to create OpenGL ES context\n");
214 eglMakeCurrent(dpy, surf, surf, ctx);
216 eglQuerySurface(dpy, surf, EGL_WIDTH, &width);
217 eglQuerySurface(dpy, surf, EGL_HEIGHT, &height);
221 static void destroy_gl(void)
225 eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
228 eglDestroyContext(dpy, ctx);
232 eglDestroySurface(dpy, surf);