comparison mupdf-source/thirdparty/freeglut/src/android/fg_runtime_android.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /*
2 * fg_runtime_android.c
3 *
4 * Android runtime
5 *
6 * Copyright (C) 2012 Sylvain Beucler
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /* Parts taken from Android NDK's 'native-activity' sample: */
27 /*
28 * Copyright (C) 2010 The Android Open Source Project
29 *
30 * Licensed under the Apache License, Version 2.0 (the "License");
31 * you may not use this file except in compliance with the License.
32 * You may obtain a copy of the License at
33 *
34 * http://www.apache.org/licenses/LICENSE-2.0
35 *
36 * Unless required by applicable law or agreed to in writing, software
37 * distributed under the License is distributed on an "AS IS" BASIS,
38 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39 * See the License for the specific language governing permissions and
40 * limitations under the License.
41 *
42 */
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <jni.h>
48 #include <android/log.h>
49 #include <android/asset_manager.h>
50 #include <android/native_window.h>
51 #include "android/native_app_glue/android_native_app_glue.h"
52 #include "android/fg_main_android.h"
53
54 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "FreeGLUT-jnicb", __VA_ARGS__))
55 #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "FreeGLUT-jnicb", __VA_ARGS__))
56
57 /* Cf. fg_main_android.c */
58 extern int32_t handle_input(struct android_app* app, AInputEvent* event);
59 extern void handle_cmd(struct android_app* app, int32_t cmd);
60
61 extern int main(int argc, char* argv[]);
62
63 /** NativeActivity Callbacks **/
64 /* Caution: they are called in the native_activity thread, not the
65 FreeGLUT thread. Use android_app_write_cmd. */
66
67 /* Could be used instead of onNativeWindowRedrawNeeded */
68 /* Deals with status bar presence */
69 static void onContentRectChanged(ANativeActivity* activity, const ARect* rect) {
70 LOGI("onContentRectChanged: l=%d,t=%d,r=%d,b=%d", rect->left, rect->top, rect->right, rect->bottom);
71 }
72
73 /* Bug: not called during a resize in android-9, only once on startup :/ */
74 static void onNativeWindowResized(ANativeActivity* activity, ANativeWindow* window) {
75 LOGI("onNativeWindowResized: %p\n", (void*)activity);
76 }
77
78 /* Called after a resize, compensate broken onNativeWindowResized */
79 static void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window) {
80 LOGI("onNativeWindowRedrawNeeded: %p\n", (void*)activity);
81 struct android_app* app = (struct android_app*)activity->instance;
82 android_app_write_cmd(app, APP_CMD_WINDOW_RESIZED);
83 }
84
85 /**
86 * Extract all .apk assets to the application directory so they can be
87 * accessed using accessed.
88 * TODO: parse directories recursively
89 */
90 static void extract_assets(struct android_app* app) {
91 /* Get usable JNI context */
92 JNIEnv* env = app->activity->env;
93 JavaVM* vm = app->activity->vm;
94 (*vm)->AttachCurrentThread(vm, &env, NULL);
95
96 {
97 /* Get a handle on our calling NativeActivity class */
98 jclass activityClass = (*env)->GetObjectClass(env, app->activity->clazz);
99
100 /* Get path to cache dir (/data/data/org.myapp/cache) */
101 jmethodID getCacheDir = (*env)->GetMethodID(env, activityClass, "getCacheDir", "()Ljava/io/File;");
102 jobject file = (*env)->CallObjectMethod(env, app->activity->clazz, getCacheDir);
103 jclass fileClass = (*env)->FindClass(env, "java/io/File");
104 jmethodID getAbsolutePath = (*env)->GetMethodID(env, fileClass, "getAbsolutePath", "()Ljava/lang/String;");
105 jstring jpath = (jstring)(*env)->CallObjectMethod(env, file, getAbsolutePath);
106 const char* app_dir = (*env)->GetStringUTFChars(env, jpath, NULL);
107
108 /* chdir in the application cache directory */
109 LOGI("app_dir: %s", app_dir);
110 chdir(app_dir);
111 (*env)->ReleaseStringUTFChars(env, jpath, app_dir);
112
113 /* Pre-extract assets, to avoid Android-specific file opening */
114 {
115 AAssetManager* mgr = app->activity->assetManager;
116 AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
117 const char* filename = (const char*)NULL;
118 while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
119 AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
120 char buf[BUFSIZ];
121 int nb_read = 0;
122 FILE* out = fopen(filename, "w");
123 while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
124 fwrite(buf, nb_read, 1, out);
125 fclose(out);
126 AAsset_close(asset);
127 }
128 AAssetDir_close(assetDir);
129 }
130 }
131
132 (*vm)->DetachCurrentThread(vm);
133 }
134
135 /**
136 * This is the main entry point of a native application that is using
137 * android_native_app_glue. It runs in its own thread, with its own
138 * event loop for receiving input events and doing other things.
139 */
140 void android_main(struct android_app* app) {
141 LOGI("android_main savedState=%p", app->savedState);
142
143 /* Register window resize callback */
144 app->activity->callbacks->onNativeWindowResized = onNativeWindowResized;
145 app->activity->callbacks->onContentRectChanged = onContentRectChanged;
146 app->activity->callbacks->onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded;
147
148 app->onAppCmd = handle_cmd;
149 app->onInputEvent = handle_input;
150
151 extract_assets(app);
152
153 /* Call user's main */
154 {
155 char progname[5] = "self";
156 char* argv[] = {progname, NULL};
157 fgDisplay.pDisplay.app = app;
158 main(1, argv);
159 /* FreeGLUT will exit() by itself if
160 GLUT_ACTION_ON_WINDOW_CLOSE == GLUT_ACTION_EXIT */
161 }
162
163 LOGI("android_main: end");
164
165 /* Let NativeActivity restart us */
166 /* Users may want to forcibly exit() in their main() anyway because
167 NativeActivity doesn't dlclose() us, so all statically-assigned
168 variables keep their old values on restart.. */
169 }