1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2011 Intel Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 /*
20 * This file is derived from the "native-activity" sample of the android NDK
21 * r5b. The coding style has been adapted to the code style most commonly found
22 * in glib/gobject based projects.
23 */
24
25 #include <android_native_app_glue.h>
26
27 #include <glib.h>
28 #include <glib-android/glib-android.h>
29 #include <cogl/cogl.h>
30
31 typedef struct
32 {
33 struct android_app* app;
34
35 CoglContext *context;
36 CoglPrimitive *triangle;
37 CoglFramebuffer *fb;
38 } TestData;
39
test_init(TestData * data)40 static int test_init (TestData* data)
41 {
42 CoglOnscreen *onscreen;
43 CoglError *error = NULL;
44 CoglVertexP2C4 triangle_vertices[] = {
45 {0, 0.7, 0xff, 0x00, 0x00, 0xff},
46 {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
47 {0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
48 };
49
50 cogl_android_set_native_window (data->app->window);
51
52 data->context = cogl_context_new (NULL, &error);
53 if (!data->context)
54 {
55 g_critical ("Failed to create context: %s\n", error->message);
56 return 1;
57 }
58
59 onscreen = cogl_onscreen_new (data->context, 320, 420);
60
61 /* Eventually there will be an implicit allocate on first use so this
62 * will become optional... */
63 data->fb = COGL_FRAMEBUFFER (onscreen);
64 if (!cogl_framebuffer_allocate (data->fb, &error))
65 {
66 if (error)
67 g_critical ("Failed to allocate framebuffer: %s\n", error->message);
68 else
69 g_critical ("Failed to allocate framebuffer");
70 return 1;
71 }
72
73 cogl_onscreen_show (onscreen);
74
75 cogl_push_framebuffer (data->fb);
76
77 data->triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
78 3, triangle_vertices);
79
80 return 0;
81 }
82
test_draw_frame_and_swap(TestData * data)83 static test_draw_frame_and_swap (TestData *data)
84 {
85 if (data->context)
86 {
87 cogl_primitive_draw (data->triangle);
88 cogl_framebuffer_swap_buffers (data->fb);
89 }
90 }
91
92 static void
test_fini(TestData * data)93 test_fini (TestData *data)
94 {
95 if (data->fb)
96 {
97 cogl_object_unref (data->triangle);
98 cogl_object_unref (data->fb);
99 cogl_object_unref (data->context);
100 data->triangle = NULL;
101 data->fb = NULL;
102 data->context = NULL;
103 }
104 }
105
106 /**
107 * Process the next main command.
108 */
109 static void
test_handle_cmd(struct android_app * app,int32_t cmd)110 test_handle_cmd (struct android_app* app,
111 int32_t cmd)
112 {
113 TestData *data = (TestData *) app->userData;
114
115 switch (cmd)
116 {
117 case APP_CMD_INIT_WINDOW:
118 /* The window is being shown, get it ready */
119 g_message ("command: INIT_WINDOW");
120 if (data->app->window != NULL)
121 {
122 test_init (data);
123 test_draw_frame_and_swap (data);
124 }
125 break;
126
127 case APP_CMD_TERM_WINDOW:
128 /* The window is being hidden or closed, clean it up */
129 g_message ("command: TERM_WINDOW");
130 test_fini (data);
131 break;
132
133 case APP_CMD_GAINED_FOCUS:
134 g_message ("command: GAINED_FOCUS");
135 break;
136
137 case APP_CMD_LOST_FOCUS:
138 /* When our app loses focus, we stop monitoring the accelerometer.
139 * This is to avoid consuming battery while not being used. */
140 g_message ("command: LOST_FOCUS");
141 test_draw_frame_and_swap (data);
142 break;
143 }
144 }
145
146 /**
147 * This is the main entry point of a native application that is using
148 * android_native_app_glue. It runs in its own thread, with its own
149 * event loop for receiving input events and doing other things.
150 */
151 void
android_main(struct android_app * application)152 android_main (struct android_app* application)
153 {
154 TestData data;
155
156 /* Make sure glue isn't stripped */
157 app_dummy ();
158
159 g_android_init ();
160
161 memset (&data, 0, sizeof (TestData));
162 application->userData = &data;
163 application->onAppCmd = test_handle_cmd;
164 data.app = application;
165
166 while (1)
167 {
168 int events;
169 struct android_poll_source* source;
170
171 while ((ALooper_pollAll (0, NULL, &events, (void**)&source)) >= 0)
172 {
173
174 /* Process this event */
175 if (source != NULL)
176 source->process (application, source);
177
178 /* Check if we are exiting */
179 if (application->destroyRequested != 0)
180 {
181 test_fini (&data);
182 return;
183 }
184 }
185
186 test_draw_frame_and_swap (&data);
187 }
188 }
189