diff --git a/3rdparty/android/android_native_app_glue.d b/3rdparty/android/android_native_app_glue.d new file mode 100644 index 00000000..08879438 --- /dev/null +++ b/3rdparty/android/android_native_app_glue.d @@ -0,0 +1,84 @@ +/* dstep -I/path/to/ndk-r9d/platforms/android-9/arch-x86/usr/include -I/path/to/ndk-r9d/toolchains/llvm-3.4/prebuilt/linux-x86/lib/clang/3.4/include /path/to/ndk-r9d/sources/android/native_app_glue/android_native_app_glue.h -o android_native_app_glue.d */ + +module android.android_native_app_glue; + +import core.sys.posix.pthread; +import android.input, android.native_window, android.rect; +import android.configuration, android.looper, android.native_activity; + +version (Android): +extern (C): +@system: +nothrow: +@nogc: + +enum +{ + LOOPER_ID_MAIN = 1, + LOOPER_ID_INPUT = 2, + LOOPER_ID_USER = 3 +} + +enum +{ + APP_CMD_INPUT_CHANGED, + APP_CMD_INIT_WINDOW, + APP_CMD_TERM_WINDOW, + APP_CMD_WINDOW_RESIZED, + APP_CMD_WINDOW_REDRAW_NEEDED, + APP_CMD_CONTENT_RECT_CHANGED, + APP_CMD_GAINED_FOCUS, + APP_CMD_LOST_FOCUS, + APP_CMD_CONFIG_CHANGED, + APP_CMD_LOW_MEMORY, + APP_CMD_START, + APP_CMD_RESUME, + APP_CMD_SAVE_STATE, + APP_CMD_PAUSE, + APP_CMD_STOP, + APP_CMD_DESTROY +} + +struct android_poll_source +{ + int id; + android_app* app; + void function(android_app*, android_poll_source*) process; +} + +struct android_app +{ + void* userData; + void function(android_app*, int) onAppCmd; + int function(android_app*, AInputEvent*) onInputEvent; + ANativeActivity* activity; + AConfiguration* config; + void* savedState; + size_t savedStateSize; + ALooper* looper; + AInputQueue* inputQueue; + ANativeWindow* window; + ARect contentRect; + int activityState; + int destroyRequested; + pthread_mutex_t mutex; + pthread_cond_t cond; + int msgread; + int msgwrite; + pthread_t thread; + android_poll_source cmdPollSource; + android_poll_source inputPollSource; + int running; + int stateSaved; + int destroyed; + int redrawNeeded; + AInputQueue* pendingInputQueue; + ANativeWindow* pendingWindow; + ARect pendingContentRect; +} + +byte android_app_read_cmd(android_app* android_app); +void android_app_pre_exec_cmd(android_app* android_app, byte cmd); +void android_app_post_exec_cmd(android_app* android_app, byte cmd); +void app_dummy(); +void android_main(android_app* app); diff --git a/3rdparty/android/android_native_app_glue_impl.d b/3rdparty/android/android_native_app_glue_impl.d new file mode 100644 index 00000000..358730ce --- /dev/null +++ b/3rdparty/android/android_native_app_glue_impl.d @@ -0,0 +1,458 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * 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 is translation of android_native_app_glue.c +module android.android_native_app_glue_impl; + +version(Android): +extern(C): +@system: + +import core.sys.posix.pthread; +import android.input, android.native_window, android.rect, android.log; +import android.configuration, android.looper, android.native_activity; +import core.stdc.stdlib; +import core.stdc.string; +import core.stdc.stdio; +import core.stdc.errno; +import core.sys.posix.sys.resource; +import core.sys.posix.unistd; + +import android_native_app_glue; +import android.log; + +void LOGI(S...)(string fmt, S args) { + __android_log_print(android_LogPriority.ANDROID_LOG_INFO, "threaded_app", fmt.ptr, args); +} +void LOGE(S...)(string fmt, S args) { + __android_log_print(android_LogPriority.ANDROID_LOG_ERROR, "threaded_app", fmt.ptr, args); +} +void LOGV(S...)(string fmt, S args) { + debug __android_log_print(android_LogPriority.ANDROID_LOG_VERBOSE, "threaded_app", fmt.ptr, args); +} + +static void free_saved_state(android_app* android_app) { + pthread_mutex_lock(&android_app.mutex); + if (android_app.savedState != null) { + free(android_app.savedState); + android_app.savedState = null; + android_app.savedStateSize = 0; + } + pthread_mutex_unlock(&android_app.mutex); +} + +byte android_app_read_cmd(android_app* android_app) { + byte cmd; + if (read(android_app.msgread, &cmd, cmd.sizeof) == cmd.sizeof) { + switch (cmd) { + case APP_CMD_SAVE_STATE: + free_saved_state(android_app); + break; + default: + break; + } + return cmd; + } else { + LOGE("No data on command pipe!"); + } + return -1; +} + +static void print_cur_config(android_app* android_app) { + + char[2] lang; + char[2] country; + AConfiguration_getLanguage(android_app.config, lang.ptr); + AConfiguration_getCountry(android_app.config, country.ptr); + + LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d " + "keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d " + "modetype=%d modenight=%d", + AConfiguration_getMcc(android_app.config), + AConfiguration_getMnc(android_app.config), + lang[0], lang[1], country[0], country[1], + AConfiguration_getOrientation(android_app.config), + AConfiguration_getTouchscreen(android_app.config), + AConfiguration_getDensity(android_app.config), + AConfiguration_getKeyboard(android_app.config), + AConfiguration_getNavigation(android_app.config), + AConfiguration_getKeysHidden(android_app.config), + AConfiguration_getNavHidden(android_app.config), + AConfiguration_getSdkVersion(android_app.config), + AConfiguration_getScreenSize(android_app.config), + AConfiguration_getScreenLong(android_app.config), + AConfiguration_getUiModeType(android_app.config), + AConfiguration_getUiModeNight(android_app.config)); +} + +void android_app_pre_exec_cmd(android_app* android_app, byte cmd) { + switch (cmd) { + case APP_CMD_INPUT_CHANGED: + LOGV("APP_CMD_INPUT_CHANGED\n"); + pthread_mutex_lock(&android_app.mutex); + if (android_app.inputQueue != null) { + AInputQueue_detachLooper(android_app.inputQueue); + } + android_app.inputQueue = android_app.pendingInputQueue; + if (android_app.inputQueue != null) { + LOGV("Attaching input queue to looper"); + AInputQueue_attachLooper(android_app.inputQueue, + android_app.looper, LOOPER_ID_INPUT, null, + &android_app.inputPollSource); + } + pthread_cond_broadcast(&android_app.cond); + pthread_mutex_unlock(&android_app.mutex); + break; + + case APP_CMD_INIT_WINDOW: + LOGV("APP_CMD_INIT_WINDOW\n"); + pthread_mutex_lock(&android_app.mutex); + android_app.window = android_app.pendingWindow; + pthread_cond_broadcast(&android_app.cond); + pthread_mutex_unlock(&android_app.mutex); + break; + + case APP_CMD_TERM_WINDOW: + LOGV("APP_CMD_TERM_WINDOW\n"); + pthread_cond_broadcast(&android_app.cond); + break; + + case APP_CMD_RESUME: + case APP_CMD_START: + case APP_CMD_PAUSE: + case APP_CMD_STOP: + LOGV("activityState=%d\n", cmd); + pthread_mutex_lock(&android_app.mutex); + android_app.activityState = cmd; + pthread_cond_broadcast(&android_app.cond); + pthread_mutex_unlock(&android_app.mutex); + break; + + case APP_CMD_CONFIG_CHANGED: + LOGV("APP_CMD_CONFIG_CHANGED\n"); + AConfiguration_fromAssetManager(android_app.config, + android_app.activity.assetManager); + print_cur_config(android_app); + break; + + case APP_CMD_DESTROY: + LOGV("APP_CMD_DESTROY\n"); + android_app.destroyRequested = 1; + break; + default: + break; + } +} + +void android_app_post_exec_cmd(android_app* android_app, byte cmd) { + switch (cmd) { + case APP_CMD_TERM_WINDOW: + LOGV("APP_CMD_TERM_WINDOW\n"); + pthread_mutex_lock(&android_app.mutex); + android_app.window = null; + pthread_cond_broadcast(&android_app.cond); + pthread_mutex_unlock(&android_app.mutex); + break; + + case APP_CMD_SAVE_STATE: + LOGV("APP_CMD_SAVE_STATE\n"); + pthread_mutex_lock(&android_app.mutex); + android_app.stateSaved = 1; + pthread_cond_broadcast(&android_app.cond); + pthread_mutex_unlock(&android_app.mutex); + break; + + case APP_CMD_RESUME: + free_saved_state(android_app); + break; + default: + break; + } +} + +void app_dummy() { + +} + +extern(C) static void android_app_destroy(android_app* android_app) { + LOGV("android_app_destroy!"); + free_saved_state(android_app); + pthread_mutex_lock(&android_app.mutex); + if (android_app.inputQueue != null) { + AInputQueue_detachLooper(android_app.inputQueue); + } + AConfiguration_delete(android_app.config); + android_app.destroyed = 1; + pthread_cond_broadcast(&android_app.cond); + pthread_mutex_unlock(&android_app.mutex); + // Can't touch android_app object after this. +} + +extern(C) static void process_input(android_app* app, android_poll_source* source) { + AInputEvent* event = null; + while (AInputQueue_getEvent(app.inputQueue, &event) >= 0) { + LOGV("New input event: type=%d\n", AInputEvent_getType(event)); + if (AInputQueue_preDispatchEvent(app.inputQueue, event)) { + continue; + } + int handled = 0; + if (app.onInputEvent != null) handled = app.onInputEvent(app, event); + AInputQueue_finishEvent(app.inputQueue, event, handled); + } +} + +extern(C) static void process_cmd(android_app* app, android_poll_source* source) { + byte cmd = android_app_read_cmd(app); + android_app_pre_exec_cmd(app, cmd); + if (app.onAppCmd != null) app.onAppCmd(app, cmd); + android_app_post_exec_cmd(app, cmd); +} + +extern(C) static void* android_app_entry(void* param) { + android_app* android_app = cast(android_app*)param; + + android_app.config = AConfiguration_new(); + AConfiguration_fromAssetManager(android_app.config, android_app.activity.assetManager); + + print_cur_config(android_app); + + android_app.cmdPollSource.id = LOOPER_ID_MAIN; + android_app.cmdPollSource.app = android_app; + android_app.cmdPollSource.process = &process_cmd; + android_app.inputPollSource.id = LOOPER_ID_INPUT; + android_app.inputPollSource.app = android_app; + android_app.inputPollSource.process = &process_input; + + ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); + ALooper_addFd(looper, android_app.msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, null, + &android_app.cmdPollSource); + android_app.looper = looper; + + pthread_mutex_lock(&android_app.mutex); + android_app.running = 1; + pthread_cond_broadcast(&android_app.cond); + pthread_mutex_unlock(&android_app.mutex); + + android_main(android_app); + + android_app_destroy(android_app); + return null; +} + +// -------------------------------------------------------------------- +// Native activity interaction (called from main thread) +// -------------------------------------------------------------------- + +static android_app* android_app_create(ANativeActivity* activity, + void* savedState, size_t savedStateSize) { + android_app* android_app = cast(android_app*)malloc(android_app.sizeof); + memset(android_app, 0, android_app.sizeof); + android_app.activity = activity; + + pthread_mutex_init(&android_app.mutex, null); + pthread_cond_init(&android_app.cond, null); + + if (savedState != null) { + android_app.savedState = malloc(savedStateSize); + android_app.savedStateSize = savedStateSize; + memcpy(android_app.savedState, savedState, savedStateSize); + } + + int msgpipe[2]; + if (pipe(msgpipe)) { + LOGE("could not create pipe: %s", strerror(errno)); + return null; + } + android_app.msgread = msgpipe[0]; + android_app.msgwrite = msgpipe[1]; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&android_app.thread, &attr, &android_app_entry, android_app); + + // Wait for thread to start. + pthread_mutex_lock(&android_app.mutex); + while (!android_app.running) { + pthread_cond_wait(&android_app.cond, &android_app.mutex); + } + pthread_mutex_unlock(&android_app.mutex); + + return android_app; +} + +static void android_app_write_cmd(android_app* android_app, byte cmd) { + if (write(android_app.msgwrite, &cmd, cmd.sizeof) != cmd.sizeof) { + LOGE("Failure writing android_app cmd: %s\n", strerror(errno)); + } +} + +static void android_app_set_input(android_app* android_app, AInputQueue* inputQueue) { + pthread_mutex_lock(&android_app.mutex); + android_app.pendingInputQueue = inputQueue; + android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); + while (android_app.inputQueue != android_app.pendingInputQueue) { + pthread_cond_wait(&android_app.cond, &android_app.mutex); + } + pthread_mutex_unlock(&android_app.mutex); +} + +static void android_app_set_window(android_app* android_app, ANativeWindow* window) { + pthread_mutex_lock(&android_app.mutex); + if (android_app.pendingWindow != null) { + android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW); + } + android_app.pendingWindow = window; + if (window != null) { + android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW); + } + while (android_app.window != android_app.pendingWindow) { + pthread_cond_wait(&android_app.cond, &android_app.mutex); + } + pthread_mutex_unlock(&android_app.mutex); +} + +static void android_app_set_activity_state(android_app* android_app, byte cmd) { + pthread_mutex_lock(&android_app.mutex); + android_app_write_cmd(android_app, cmd); + while (android_app.activityState != cmd) { + pthread_cond_wait(&android_app.cond, &android_app.mutex); + } + pthread_mutex_unlock(&android_app.mutex); +} + +static void android_app_free(android_app* android_app) { + pthread_mutex_lock(&android_app.mutex); + android_app_write_cmd(android_app, APP_CMD_DESTROY); + while (!android_app.destroyed) { + pthread_cond_wait(&android_app.cond, &android_app.mutex); + } + pthread_mutex_unlock(&android_app.mutex); + + close(android_app.msgread); + close(android_app.msgwrite); + pthread_cond_destroy(&android_app.cond); + pthread_mutex_destroy(&android_app.mutex); + free(android_app); +} + +static void onDestroy(ANativeActivity* activity) { + LOGV("Destroy: %p\n", activity); + android_app_free(cast(android_app*)activity.instance); +} + +static void onStart(ANativeActivity* activity) { + LOGV("Start: %p\n", activity); + android_app_set_activity_state(cast(android_app*)activity.instance, APP_CMD_START); +} + +static void onResume(ANativeActivity* activity) { + LOGV("Resume: %p\n", activity); + android_app_set_activity_state(cast(android_app*)activity.instance, APP_CMD_RESUME); +} + +static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { + android_app* android_app = cast(android_app*)activity.instance; + void* savedState = null; + + LOGV("SaveInstanceState: %p\n", activity); + pthread_mutex_lock(&android_app.mutex); + android_app.stateSaved = 0; + android_app_write_cmd(android_app, APP_CMD_SAVE_STATE); + while (!android_app.stateSaved) { + pthread_cond_wait(&android_app.cond, &android_app.mutex); + } + + if (android_app.savedState != null) { + savedState = android_app.savedState; + *outLen = android_app.savedStateSize; + android_app.savedState = null; + android_app.savedStateSize = 0; + } + + pthread_mutex_unlock(&android_app.mutex); + + return savedState; +} + +static void onPause(ANativeActivity* activity) { + LOGV("Pause: %p\n", activity); + android_app_set_activity_state(cast(android_app*)activity.instance, APP_CMD_PAUSE); +} + +static void onStop(ANativeActivity* activity) { + LOGV("Stop: %p\n", activity); + android_app_set_activity_state(cast(android_app*)activity.instance, APP_CMD_STOP); +} + +static void onConfigurationChanged(ANativeActivity* activity) { + android_app* android_app = cast(android_app*)activity.instance; + LOGV("ConfigurationChanged: %p\n", activity); + android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED); +} + +static void onLowMemory(ANativeActivity* activity) { + android_app* android_app = cast(android_app*)activity.instance; + LOGV("LowMemory: %p\n", activity); + android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY); +} + +static void onWindowFocusChanged(ANativeActivity* activity, int focused) { + LOGV("WindowFocusChanged: %p -- %d\n", activity, focused); + android_app_write_cmd(cast(android_app*)activity.instance, + focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS); +} + +static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { + LOGV("NativeWindowCreated: %p -- %p\n", activity, window); + android_app_set_window(cast(android_app*)activity.instance, window); +} + +static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { + LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window); + android_app_set_window(cast(android_app*)activity.instance, null); +} + +static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { + LOGV("InputQueueCreated: %p -- %p\n", activity, queue); + android_app_set_input(cast(android_app*)activity.instance, queue); +} + +static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { + LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue); + android_app_set_input(cast(android_app*)activity.instance, null); +} + +void ANativeActivity_onCreate(ANativeActivity* activity, + void* savedState, size_t savedStateSize) { + LOGV("Creating: %p\n", activity); + activity.callbacks.onDestroy = &onDestroy; + activity.callbacks.onStart = &onStart; + activity.callbacks.onResume = &onResume; + activity.callbacks.onSaveInstanceState = &onSaveInstanceState; + activity.callbacks.onPause = &onPause; + activity.callbacks.onStop = &onStop; + activity.callbacks.onConfigurationChanged = &onConfigurationChanged; + activity.callbacks.onLowMemory = &onLowMemory; + activity.callbacks.onWindowFocusChanged = &onWindowFocusChanged; + activity.callbacks.onNativeWindowCreated = &onNativeWindowCreated; + activity.callbacks.onNativeWindowDestroyed = &onNativeWindowDestroyed; + activity.callbacks.onInputQueueCreated = &onInputQueueCreated; + activity.callbacks.onInputQueueDestroyed = &onInputQueueDestroyed; + + activity.instance = android_app_create(activity, savedState, savedStateSize); +} diff --git a/3rdparty/android/jni.d b/3rdparty/android/jni.d new file mode 100644 index 00000000..18859b56 --- /dev/null +++ b/3rdparty/android/jni.d @@ -0,0 +1,368 @@ +/* dstep -I/path/to/ndk-r9d/platforms/android-9/arch-x86/usr/include -I/path/to/ndk-r9d/toolchains/llvm-3.4/prebuilt/linux-x86/lib/clang/3.4/include /path/to/ndk-r9d/platforms/android-9/arch-x86/usr/include/jni.h -o jni.d*/ + +module android.jni; + +import core.stdc.stdarg; + +version (Android): +extern (C): +@system: +nothrow: +@nogc: + +alias ubyte jboolean; +alias byte jbyte; +alias ushort jchar; +alias short jshort; +alias int jint; +alias long jlong; +alias float jfloat; +alias double jdouble; +alias jint jsize; +alias void* jobject; +alias jobject jclass; +alias jobject jstring; +alias jobject jarray; +alias jarray jobjectArray; +alias jarray jbooleanArray; +alias jarray jbyteArray; +alias jarray jcharArray; +alias jarray jshortArray; +alias jarray jintArray; +alias jarray jlongArray; +alias jarray jfloatArray; +alias jarray jdoubleArray; +alias jobject jthrowable; +alias jobject jweak; +alias _jfieldID* jfieldID; +alias _jmethodID* jmethodID; +alias const(JNINativeInterface)* C_JNIEnv; +alias const(JNINativeInterface)* JNIEnv; +alias const(JNIInvokeInterface)* JavaVM; + +enum jobjectRefType +{ + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} + +enum JNI_FALSE = 0; +enum JNI_TRUE = 1; +enum JNI_VERSION_1_1 = 0x00010001; +enum JNI_VERSION_1_2 = 0x00010002; +enum JNI_VERSION_1_4 = 0x00010004; +enum JNI_VERSION_1_6 = 0x00010006; +enum JNI_OK = 0; +enum JNI_ERR = -1; +enum JNI_EDETACHED = -2; +enum JNI_EVERSION = -3; +enum JNI_COMMIT = 1; +enum JNI_ABORT = 2; + +struct JNINativeMethod +{ + const(char)* name; + const(char)* signature; + void* fnPtr; +} + +struct JNINativeInterface +{ + void* reserved0; + void* reserved1; + void* reserved2; + void* reserved3; + jint function(JNIEnv*) GetVersion; + jclass function(JNIEnv*, const(char)*, jobject, const(jbyte)*, jsize) DefineClass; + jclass function(JNIEnv*, const(char)*) FindClass; + jmethodID function(JNIEnv*, jobject) FromReflectedMethod; + jfieldID function(JNIEnv*, jobject) FromReflectedField; + jobject function(JNIEnv*, jclass, jmethodID, jboolean) ToReflectedMethod; + jclass function(JNIEnv*, jclass) GetSuperclass; + jboolean function(JNIEnv*, jclass, jclass) IsAssignableFrom; + jobject function(JNIEnv*, jclass, jfieldID, jboolean) ToReflectedField; + jint function(JNIEnv*, jthrowable) Throw; + jint function(JNIEnv*, jclass, const(char)*) ThrowNew; + jthrowable function(JNIEnv*) ExceptionOccurred; + void function(JNIEnv*) ExceptionDescribe; + void function(JNIEnv*) ExceptionClear; + void function(JNIEnv*, const(char)*) FatalError; + jint function(JNIEnv*, jint) PushLocalFrame; + jobject function(JNIEnv*, jobject) PopLocalFrame; + jobject function(JNIEnv*, jobject) NewGlobalRef; + void function(JNIEnv*, jobject) DeleteGlobalRef; + void function(JNIEnv*, jobject) DeleteLocalRef; + jboolean function(JNIEnv*, jobject, jobject) IsSameObject; + jobject function(JNIEnv*, jobject) NewLocalRef; + jint function(JNIEnv*, jint) EnsureLocalCapacity; + jobject function(JNIEnv*, jclass) AllocObject; + jobject function(JNIEnv*, jclass, jmethodID, ...) NewObject; + jobject function(JNIEnv*, jclass, jmethodID, va_list) NewObjectV; + jobject function(JNIEnv*, jclass, jmethodID, jvalue*) NewObjectA; + jclass function(JNIEnv*, jobject) GetObjectClass; + jboolean function(JNIEnv*, jobject, jclass) IsInstanceOf; + jmethodID function(JNIEnv*, jclass, const(char)*, const(char)*) GetMethodID; + jobject function(JNIEnv*, jobject, jmethodID, ...) CallObjectMethod; + jobject function(JNIEnv*, jobject, jmethodID, va_list) CallObjectMethodV; + jobject function(JNIEnv*, jobject, jmethodID, jvalue*) CallObjectMethodA; + jboolean function(JNIEnv*, jobject, jmethodID, ...) CallBooleanMethod; + jboolean function(JNIEnv*, jobject, jmethodID, va_list) CallBooleanMethodV; + jboolean function(JNIEnv*, jobject, jmethodID, jvalue*) CallBooleanMethodA; + jbyte function(JNIEnv*, jobject, jmethodID, ...) CallByteMethod; + jbyte function(JNIEnv*, jobject, jmethodID, va_list) CallByteMethodV; + jbyte function(JNIEnv*, jobject, jmethodID, jvalue*) CallByteMethodA; + jchar function(JNIEnv*, jobject, jmethodID, ...) CallCharMethod; + jchar function(JNIEnv*, jobject, jmethodID, va_list) CallCharMethodV; + jchar function(JNIEnv*, jobject, jmethodID, jvalue*) CallCharMethodA; + jshort function(JNIEnv*, jobject, jmethodID, ...) CallShortMethod; + jshort function(JNIEnv*, jobject, jmethodID, va_list) CallShortMethodV; + jshort function(JNIEnv*, jobject, jmethodID, jvalue*) CallShortMethodA; + jint function(JNIEnv*, jobject, jmethodID, ...) CallIntMethod; + jint function(JNIEnv*, jobject, jmethodID, va_list) CallIntMethodV; + jint function(JNIEnv*, jobject, jmethodID, jvalue*) CallIntMethodA; + jlong function(JNIEnv*, jobject, jmethodID, ...) CallLongMethod; + jlong function(JNIEnv*, jobject, jmethodID, va_list) CallLongMethodV; + jlong function(JNIEnv*, jobject, jmethodID, jvalue*) CallLongMethodA; + jfloat function(JNIEnv*, jobject, jmethodID, ...) CallFloatMethod; + jfloat function(JNIEnv*, jobject, jmethodID, va_list) CallFloatMethodV; + jfloat function(JNIEnv*, jobject, jmethodID, jvalue*) CallFloatMethodA; + jdouble function(JNIEnv*, jobject, jmethodID, ...) CallDoubleMethod; + jdouble function(JNIEnv*, jobject, jmethodID, va_list) CallDoubleMethodV; + jdouble function(JNIEnv*, jobject, jmethodID, jvalue*) CallDoubleMethodA; + void function(JNIEnv*, jobject, jmethodID, ...) CallVoidMethod; + void function(JNIEnv*, jobject, jmethodID, va_list) CallVoidMethodV; + void function(JNIEnv*, jobject, jmethodID, jvalue*) CallVoidMethodA; + jobject function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualObjectMethod; + jobject function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualObjectMethodV; + jobject function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualObjectMethodA; + jboolean function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualBooleanMethod; + jboolean function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualBooleanMethodV; + jboolean function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualBooleanMethodA; + jbyte function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualByteMethod; + jbyte function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualByteMethodV; + jbyte function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualByteMethodA; + jchar function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualCharMethod; + jchar function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualCharMethodV; + jchar function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualCharMethodA; + jshort function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualShortMethod; + jshort function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualShortMethodV; + jshort function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualShortMethodA; + jint function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualIntMethod; + jint function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualIntMethodV; + jint function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualIntMethodA; + jlong function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualLongMethod; + jlong function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualLongMethodV; + jlong function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualLongMethodA; + jfloat function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualFloatMethod; + jfloat function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualFloatMethodV; + jfloat function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualFloatMethodA; + jdouble function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualDoubleMethod; + jdouble function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualDoubleMethodV; + jdouble function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualDoubleMethodA; + void function(JNIEnv*, jobject, jclass, jmethodID, ...) CallNonvirtualVoidMethod; + void function(JNIEnv*, jobject, jclass, jmethodID, va_list) CallNonvirtualVoidMethodV; + void function(JNIEnv*, jobject, jclass, jmethodID, jvalue*) CallNonvirtualVoidMethodA; + jfieldID function(JNIEnv*, jclass, const(char)*, const(char)*) GetFieldID; + jobject function(JNIEnv*, jobject, jfieldID) GetObjectField; + jboolean function(JNIEnv*, jobject, jfieldID) GetBooleanField; + jbyte function(JNIEnv*, jobject, jfieldID) GetByteField; + jchar function(JNIEnv*, jobject, jfieldID) GetCharField; + jshort function(JNIEnv*, jobject, jfieldID) GetShortField; + jint function(JNIEnv*, jobject, jfieldID) GetIntField; + jlong function(JNIEnv*, jobject, jfieldID) GetLongField; + jfloat function(JNIEnv*, jobject, jfieldID) GetFloatField; + jdouble function(JNIEnv*, jobject, jfieldID) GetDoubleField; + void function(JNIEnv*, jobject, jfieldID, jobject) SetObjectField; + void function(JNIEnv*, jobject, jfieldID, jboolean) SetBooleanField; + void function(JNIEnv*, jobject, jfieldID, jbyte) SetByteField; + void function(JNIEnv*, jobject, jfieldID, jchar) SetCharField; + void function(JNIEnv*, jobject, jfieldID, jshort) SetShortField; + void function(JNIEnv*, jobject, jfieldID, jint) SetIntField; + void function(JNIEnv*, jobject, jfieldID, jlong) SetLongField; + void function(JNIEnv*, jobject, jfieldID, jfloat) SetFloatField; + void function(JNIEnv*, jobject, jfieldID, jdouble) SetDoubleField; + jmethodID function(JNIEnv*, jclass, const(char)*, const(char)*) GetStaticMethodID; + jobject function(JNIEnv*, jclass, jmethodID, ...) CallStaticObjectMethod; + jobject function(JNIEnv*, jclass, jmethodID, va_list) CallStaticObjectMethodV; + jobject function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticObjectMethodA; + jboolean function(JNIEnv*, jclass, jmethodID, ...) CallStaticBooleanMethod; + jboolean function(JNIEnv*, jclass, jmethodID, va_list) CallStaticBooleanMethodV; + jboolean function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticBooleanMethodA; + jbyte function(JNIEnv*, jclass, jmethodID, ...) CallStaticByteMethod; + jbyte function(JNIEnv*, jclass, jmethodID, va_list) CallStaticByteMethodV; + jbyte function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticByteMethodA; + jchar function(JNIEnv*, jclass, jmethodID, ...) CallStaticCharMethod; + jchar function(JNIEnv*, jclass, jmethodID, va_list) CallStaticCharMethodV; + jchar function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticCharMethodA; + jshort function(JNIEnv*, jclass, jmethodID, ...) CallStaticShortMethod; + jshort function(JNIEnv*, jclass, jmethodID, va_list) CallStaticShortMethodV; + jshort function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticShortMethodA; + jint function(JNIEnv*, jclass, jmethodID, ...) CallStaticIntMethod; + jint function(JNIEnv*, jclass, jmethodID, va_list) CallStaticIntMethodV; + jint function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticIntMethodA; + jlong function(JNIEnv*, jclass, jmethodID, ...) CallStaticLongMethod; + jlong function(JNIEnv*, jclass, jmethodID, va_list) CallStaticLongMethodV; + jlong function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticLongMethodA; + jfloat function(JNIEnv*, jclass, jmethodID, ...) CallStaticFloatMethod; + jfloat function(JNIEnv*, jclass, jmethodID, va_list) CallStaticFloatMethodV; + jfloat function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticFloatMethodA; + jdouble function(JNIEnv*, jclass, jmethodID, ...) CallStaticDoubleMethod; + jdouble function(JNIEnv*, jclass, jmethodID, va_list) CallStaticDoubleMethodV; + jdouble function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticDoubleMethodA; + void function(JNIEnv*, jclass, jmethodID, ...) CallStaticVoidMethod; + void function(JNIEnv*, jclass, jmethodID, va_list) CallStaticVoidMethodV; + void function(JNIEnv*, jclass, jmethodID, jvalue*) CallStaticVoidMethodA; + jfieldID function(JNIEnv*, jclass, const(char)*, const(char)*) GetStaticFieldID; + jobject function(JNIEnv*, jclass, jfieldID) GetStaticObjectField; + jboolean function(JNIEnv*, jclass, jfieldID) GetStaticBooleanField; + jbyte function(JNIEnv*, jclass, jfieldID) GetStaticByteField; + jchar function(JNIEnv*, jclass, jfieldID) GetStaticCharField; + jshort function(JNIEnv*, jclass, jfieldID) GetStaticShortField; + jint function(JNIEnv*, jclass, jfieldID) GetStaticIntField; + jlong function(JNIEnv*, jclass, jfieldID) GetStaticLongField; + jfloat function(JNIEnv*, jclass, jfieldID) GetStaticFloatField; + jdouble function(JNIEnv*, jclass, jfieldID) GetStaticDoubleField; + void function(JNIEnv*, jclass, jfieldID, jobject) SetStaticObjectField; + void function(JNIEnv*, jclass, jfieldID, jboolean) SetStaticBooleanField; + void function(JNIEnv*, jclass, jfieldID, jbyte) SetStaticByteField; + void function(JNIEnv*, jclass, jfieldID, jchar) SetStaticCharField; + void function(JNIEnv*, jclass, jfieldID, jshort) SetStaticShortField; + void function(JNIEnv*, jclass, jfieldID, jint) SetStaticIntField; + void function(JNIEnv*, jclass, jfieldID, jlong) SetStaticLongField; + void function(JNIEnv*, jclass, jfieldID, jfloat) SetStaticFloatField; + void function(JNIEnv*, jclass, jfieldID, jdouble) SetStaticDoubleField; + jstring function(JNIEnv*, const(jchar)*, jsize) NewString; + jsize function(JNIEnv*, jstring) GetStringLength; + const(jchar)* function(JNIEnv*, jstring, jboolean*) GetStringChars; + void function(JNIEnv*, jstring, const(jchar)*) ReleaseStringChars; + jstring function(JNIEnv*, const(char)*) NewStringUTF; + jsize function(JNIEnv*, jstring) GetStringUTFLength; + const(char)* function(JNIEnv*, jstring, jboolean*) GetStringUTFChars; + void function(JNIEnv*, jstring, const(char)*) ReleaseStringUTFChars; + jsize function(JNIEnv*, jarray) GetArrayLength; + jobjectArray function(JNIEnv*, jsize, jclass, jobject) NewObjectArray; + jobject function(JNIEnv*, jobjectArray, jsize) GetObjectArrayElement; + void function(JNIEnv*, jobjectArray, jsize, jobject) SetObjectArrayElement; + jbooleanArray function(JNIEnv*, jsize) NewBooleanArray; + jbyteArray function(JNIEnv*, jsize) NewByteArray; + jcharArray function(JNIEnv*, jsize) NewCharArray; + jshortArray function(JNIEnv*, jsize) NewShortArray; + jintArray function(JNIEnv*, jsize) NewIntArray; + jlongArray function(JNIEnv*, jsize) NewLongArray; + jfloatArray function(JNIEnv*, jsize) NewFloatArray; + jdoubleArray function(JNIEnv*, jsize) NewDoubleArray; + jboolean* function(JNIEnv*, jbooleanArray, jboolean*) GetBooleanArrayElements; + jbyte* function(JNIEnv*, jbyteArray, jboolean*) GetByteArrayElements; + jchar* function(JNIEnv*, jcharArray, jboolean*) GetCharArrayElements; + jshort* function(JNIEnv*, jshortArray, jboolean*) GetShortArrayElements; + jint* function(JNIEnv*, jintArray, jboolean*) GetIntArrayElements; + jlong* function(JNIEnv*, jlongArray, jboolean*) GetLongArrayElements; + jfloat* function(JNIEnv*, jfloatArray, jboolean*) GetFloatArrayElements; + jdouble* function(JNIEnv*, jdoubleArray, jboolean*) GetDoubleArrayElements; + void function(JNIEnv*, jbooleanArray, jboolean*, jint) ReleaseBooleanArrayElements; + void function(JNIEnv*, jbyteArray, jbyte*, jint) ReleaseByteArrayElements; + void function(JNIEnv*, jcharArray, jchar*, jint) ReleaseCharArrayElements; + void function(JNIEnv*, jshortArray, jshort*, jint) ReleaseShortArrayElements; + void function(JNIEnv*, jintArray, jint*, jint) ReleaseIntArrayElements; + void function(JNIEnv*, jlongArray, jlong*, jint) ReleaseLongArrayElements; + void function(JNIEnv*, jfloatArray, jfloat*, jint) ReleaseFloatArrayElements; + void function(JNIEnv*, jdoubleArray, jdouble*, jint) ReleaseDoubleArrayElements; + void function(JNIEnv*, jbooleanArray, jsize, jsize, jboolean*) GetBooleanArrayRegion; + void function(JNIEnv*, jbyteArray, jsize, jsize, jbyte*) GetByteArrayRegion; + void function(JNIEnv*, jcharArray, jsize, jsize, jchar*) GetCharArrayRegion; + void function(JNIEnv*, jshortArray, jsize, jsize, jshort*) GetShortArrayRegion; + void function(JNIEnv*, jintArray, jsize, jsize, jint*) GetIntArrayRegion; + void function(JNIEnv*, jlongArray, jsize, jsize, jlong*) GetLongArrayRegion; + void function(JNIEnv*, jfloatArray, jsize, jsize, jfloat*) GetFloatArrayRegion; + void function(JNIEnv*, jdoubleArray, jsize, jsize, jdouble*) GetDoubleArrayRegion; + void function(JNIEnv*, jbooleanArray, jsize, jsize, const(jboolean)*) SetBooleanArrayRegion; + void function(JNIEnv*, jbyteArray, jsize, jsize, const(jbyte)*) SetByteArrayRegion; + void function(JNIEnv*, jcharArray, jsize, jsize, const(jchar)*) SetCharArrayRegion; + void function(JNIEnv*, jshortArray, jsize, jsize, const(jshort)*) SetShortArrayRegion; + void function(JNIEnv*, jintArray, jsize, jsize, const(jint)*) SetIntArrayRegion; + void function(JNIEnv*, jlongArray, jsize, jsize, const(jlong)*) SetLongArrayRegion; + void function(JNIEnv*, jfloatArray, jsize, jsize, const(jfloat)*) SetFloatArrayRegion; + void function(JNIEnv*, jdoubleArray, jsize, jsize, const(jdouble)*) SetDoubleArrayRegion; + jint function(JNIEnv*, jclass, const(JNINativeMethod)*, jint) RegisterNatives; + jint function(JNIEnv*, jclass) UnregisterNatives; + jint function(JNIEnv*, jobject) MonitorEnter; + jint function(JNIEnv*, jobject) MonitorExit; + jint function(JNIEnv*, JavaVM**) GetJavaVM; + void function(JNIEnv*, jstring, jsize, jsize, jchar*) GetStringRegion; + void function(JNIEnv*, jstring, jsize, jsize, char*) GetStringUTFRegion; + void* function(JNIEnv*, jarray, jboolean*) GetPrimitiveArrayCritical; + void function(JNIEnv*, jarray, void*, jint) ReleasePrimitiveArrayCritical; + const(jchar)* function(JNIEnv*, jstring, jboolean*) GetStringCritical; + void function(JNIEnv*, jstring, const(jchar)*) ReleaseStringCritical; + jweak function(JNIEnv*, jobject) NewWeakGlobalRef; + void function(JNIEnv*, jweak) DeleteWeakGlobalRef; + jboolean function(JNIEnv*) ExceptionCheck; + jobject function(JNIEnv*, void*, jlong) NewDirectByteBuffer; + void* function(JNIEnv*, jobject) GetDirectBufferAddress; + jlong function(JNIEnv*, jobject) GetDirectBufferCapacity; + jobjectRefType function(JNIEnv*, jobject) GetObjectRefType; +} + +struct _JNIEnv +{ + const(JNINativeInterface)* functions; +} + +struct JNIInvokeInterface +{ + void* reserved0; + void* reserved1; + void* reserved2; + jint function(JavaVM*) DestroyJavaVM; + jint function(JavaVM*, JNIEnv**, void*) AttachCurrentThread; + jint function(JavaVM*) DetachCurrentThread; + jint function(JavaVM*, void**, jint) GetEnv; + jint function(JavaVM*, JNIEnv**, void*) AttachCurrentThreadAsDaemon; +} + +struct _JavaVM +{ + const(JNIInvokeInterface)* functions; +} + +struct JavaVMAttachArgs +{ + jint version_; + const(char)* name; + jobject group; +} + +struct JavaVMOption +{ + const(char)* optionString; + void* extraInfo; +} + +struct JavaVMInitArgs +{ + jint version_; + jint nOptions; + JavaVMOption* options; + jboolean ignoreUnrecognized; +} + +struct _jfieldID; +struct _jmethodID; + +union jvalue +{ + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} + +jint JNI_OnLoad(JavaVM* vm, void* reserved); +void JNI_OnUnload(JavaVM* vm, void* reserved); diff --git a/src/dlangui/core/config.d b/src/dlangui/core/config.d index 24b0008f..53f5afd2 100644 --- a/src/dlangui/core/config.d +++ b/src/dlangui/core/config.d @@ -22,6 +22,19 @@ version (USE_SDL) { enum BACKEND_X11 = false; enum BACKEND_DSFML = false; enum BACKEND_WIN32 = false; + enum BACKEND_ANDROID = false; +} else version (USE_ANDROID) { + // Android backend already selected using version identifier + version (USE_OPENGL) { + enum ENABLE_OPENGL = true; + } else { + enum ENABLE_OPENGL = false; + } + enum BACKEND_SDL = false; + enum BACKEND_X11 = false; + enum BACKEND_DSFML = false; + enum BACKEND_WIN32 = false; + enum BACKEND_ANDROID = true; } else version (USE_X11) { // X11 backend already selected using version identifier version (USE_OPENGL) { @@ -44,6 +57,7 @@ version (USE_SDL) { enum BACKEND_X11 = false; enum BACKEND_DSFML = false; enum BACKEND_WIN32 = true; + enum BACKEND_ANDROID = false; } else version (USE_DSFML) { // DSFML backend already selected using version identifier version (USE_OPENGL) { @@ -55,6 +69,7 @@ version (USE_SDL) { enum BACKEND_X11 = false; enum BACKEND_DSFML = true; enum BACKEND_WIN32 = false; + enum BACKEND_ANDROID = false; } else { // no backend selected: set default based on platform version (Windows) { @@ -68,6 +83,15 @@ version (USE_SDL) { enum BACKEND_X11 = false; enum BACKEND_DSFML = false; enum BACKEND_WIN32 = true; + enum BACKEND_ANDROID = false; + } else version(Android) { + // Default for Linux: use SDL and OpenGL + enum ENABLE_OPENGL = true; + enum BACKEND_SDL = true; + enum BACKEND_X11 = false; + enum BACKEND_DSFML = false; + enum BACKEND_WIN32 = false; + enum BACKEND_ANDROID = true; } else version(linux) { // Default for Linux: use SDL and OpenGL version (NO_OPENGL) { @@ -79,6 +103,7 @@ version (USE_SDL) { enum BACKEND_X11 = false; enum BACKEND_DSFML = false; enum BACKEND_WIN32 = false; + enum BACKEND_ANDROID = false; } else version(OSX) { // Default: use SDL and OpenGL version (NO_OPENGL) { @@ -90,6 +115,7 @@ version (USE_SDL) { enum BACKEND_X11 = false; enum BACKEND_DSFML = false; enum BACKEND_WIN32 = false; + enum BACKEND_ANDROID = false; } else { // Unknown platform: use SDL and OpenGL version (NO_OPENGL) { @@ -101,5 +127,6 @@ version (USE_SDL) { enum BACKEND_X11 = false; enum BACKEND_DSFML = false; enum BACKEND_WIN32 = false; + enum BACKEND_ANDROID = false; } }