/* * Copyright (C) 2010 The Android Open Source Project * Copyright (C) 2011 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * This file is derived from the "native-activity" sample of the android NDK * r5b. The coding style has been adapted to the code style most commonly found * in glib/gobject based projects. */ #include #include #include #include typedef struct { struct android_app* app; CoglContext *context; CoglPrimitive *triangle; CoglFramebuffer *fb; } TestData; static int test_init (TestData* data) { CoglOnscreen *onscreen; GError *error = NULL; CoglVertexP2C4 triangle_vertices[] = { {0, 0.7, 0xff, 0x00, 0x00, 0x80}, {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} }; cogl_android_set_native_window (data->app->window); data->context = cogl_context_new (NULL, &error); if (!data->context) { g_critical ("Failed to create context: %s\n", error->message); return 1; } onscreen = cogl_onscreen_new (data->context, 320, 420); /* Eventually there will be an implicit allocate on first use so this * will become optional... */ data->fb = COGL_FRAMEBUFFER (onscreen); if (!cogl_framebuffer_allocate (data->fb, &error)) { if (error) g_critical ("Failed to allocate framebuffer: %s\n", error->message); else g_critical ("Failed to allocate framebuffer"); return 1; } cogl_onscreen_show (onscreen); cogl_push_framebuffer (data->fb); data->triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); return 0; } static test_draw_frame_and_swap (TestData *data) { if (data->context) { cogl_primitive_draw (data->triangle); cogl_framebuffer_swap_buffers (data->fb); } } static void test_fini (TestData *data) { if (data->fb) { cogl_object_unref (data->triangle); cogl_object_unref (data->fb); cogl_object_unref (data->context); data->triangle = NULL; data->fb = NULL; data->context = NULL; } } /** * Process the next main command. */ static void test_handle_cmd (struct android_app* app, int32_t cmd) { TestData *data = (TestData *) app->userData; switch (cmd) { case APP_CMD_INIT_WINDOW: /* The window is being shown, get it ready */ g_message ("command: INIT_WINDOW"); if (data->app->window != NULL) { test_init (data); test_draw_frame_and_swap (data); } break; case APP_CMD_TERM_WINDOW: /* The window is being hidden or closed, clean it up */ g_message ("command: TERM_WINDOW"); test_fini (data); break; case APP_CMD_GAINED_FOCUS: g_message ("command: GAINED_FOCUS"); break; case APP_CMD_LOST_FOCUS: /* When our app loses focus, we stop monitoring the accelerometer. * This is to avoid consuming battery while not being used. */ g_message ("command: LOST_FOCUS"); test_draw_frame_and_swap (data); break; } } /** * This is the main entry point of a native application that is using * android_native_app_glue. It runs in its own thread, with its own * event loop for receiving input events and doing other things. */ void android_main (struct android_app* application) { TestData data; /* Make sure glue isn't stripped */ app_dummy (); g_android_init (NULL, NULL, G_ANDROID_INIT_FLAG_LOG_HANDLER); memset (&data, 0, sizeof (TestData)); application->userData = &data; application->onAppCmd = test_handle_cmd; data.app = application; while (1) { int events; struct android_poll_source* source; while ((ALooper_pollAll (0, NULL, &events, (void**)&source)) >= 0) { /* Process this event */ if (source != NULL) source->process (application, source); /* Check if we are exiting */ if (application->destroyRequested != 0) { test_fini (&data); return; } } test_draw_frame_and_swap (&data); } }