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 static struct android_app *app;
16 static EGLDisplay dpy;
17 static EGLSurface surf;
18 static EGLContext ctx;
21 static int width, height;
24 void android_main(struct android_app *app_ptr)
28 app->onAppCmd = handle_command;
29 app->onInputEvent = handle_input;
35 struct android_poll_source *pollsrc;
37 while(ALooper_pollAll(0, 0, &num_events, (void**)&pollsrc) >= 0) {
39 pollsrc->process(app, pollsrc);
43 if(app->destroyRequested) {
48 eglSwapBuffers(dpy, surf);
53 static void handle_command(struct android_app *app, int32_t cmd)
59 running = 0; /* TODO: handle timers */
65 case APP_CMD_INIT_WINDOW:
69 if(demo_init() == -1) {
72 demo_reshape(width, height);
76 case APP_CMD_TERM_WINDOW:
82 case APP_CMD_WINDOW_RESIZED:
83 case APP_CMD_CONFIG_CHANGED:
84 xsz = ANativeWindow_getWidth(app->window);
85 ysz = ANativeWindow_getHeight(app->window);
86 if(xsz != width || ysz != height) {
87 printf("reshape(%d, %d)\n", xsz, ysz);
88 demo_reshape(xsz, ysz);
95 case APP_CMD_SAVE_STATE:
96 case APP_CMD_GAINED_FOCUS:
97 case APP_CMD_LOST_FOCUS:
104 static int handle_input(struct android_app *app, AInputEvent *ev)
106 int evtype = AInputEvent_getType(ev);
109 case AINPUT_EVENT_TYPE_MOTION:
110 return handle_touch_input(app, ev);
118 static int handle_touch_input(struct android_app *app, AInputEvent *ev)
120 int i, pcount, x, y, idx;
122 static int prev_pos[2];
124 action = AMotionEvent_getAction(ev);
126 idx = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
127 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
129 x = AMotionEvent_getX(ev, idx);
130 y = AMotionEvent_getY(ev, idx);
132 switch(action & AMOTION_EVENT_ACTION_MASK) {
133 case AMOTION_EVENT_ACTION_DOWN:
134 case AMOTION_EVENT_ACTION_POINTER_DOWN:
135 demo_mouse(0, 1, x, y);
141 case AMOTION_EVENT_ACTION_UP:
142 case AMOTION_EVENT_ACTION_POINTER_UP:
143 demo_mouse(0, 0, x, y);
149 case AMOTION_EVENT_ACTION_MOVE:
150 pcount = AMotionEvent_getPointerCount(ev);
151 for(i=0; i<pcount; i++) {
152 int id = AMotionEvent_getPointerId(ev, i);
169 static int init_gl(void)
171 static const int eglattr[] = {
172 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
173 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
180 static const int ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
185 dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
186 if(!dpy || !eglInitialize(dpy, 0, 0)) {
187 fprintf(stderr, "failed to initialize EGL\n");
192 if(!eglChooseConfig(dpy, eglattr, &eglcfg, 1, &count)) {
193 fprintf(stderr, "no matching EGL config found\n");
198 /* configure the native window visual according to the chosen EGL config */
199 eglGetConfigAttrib(dpy, &eglcfg, EGL_NATIVE_VISUAL_ID, &vis);
200 ANativeWindow_setBuffersGeometry(app->window, 0, 0, vis);
202 if(!(surf = eglCreateWindowSurface(dpy, eglcfg, app->window, 0))) {
203 fprintf(stderr, "failed to create window\n");
208 if(!(ctx = eglCreateContext(dpy, eglcfg, EGL_NO_CONTEXT, ctxattr))) {
209 fprintf(stderr, "failed to create OpenGL ES context\n");
213 eglMakeCurrent(dpy, surf, surf, ctx);
215 eglQuerySurface(dpy, surf, EGL_WIDTH, &width);
216 eglQuerySurface(dpy, surf, EGL_HEIGHT, &height);
220 static void destroy_gl(void)
224 eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
227 eglDestroyContext(dpy, ctx);
231 eglDestroySurface(dpy, surf);