diff options
author | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
---|---|---|
committer | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
commit | abef6da56913f1c55528103e60a50451a39628b1 (patch) | |
tree | b3c8092471ecbb73e568cd0d336efa0e7871ee8d /src/Window_Android.c |
initial commit
Diffstat (limited to 'src/Window_Android.c')
-rw-r--r-- | src/Window_Android.c | 561 |
1 files changed, 561 insertions, 0 deletions
diff --git a/src/Window_Android.c b/src/Window_Android.c new file mode 100644 index 0000000..7043d0a --- /dev/null +++ b/src/Window_Android.c @@ -0,0 +1,561 @@ +#include "Core.h" +#if CC_WIN_BACKEND == CC_WIN_BACKEND_ANDROID +#include "_WindowBase.h" +#include "String.h" +#include "Funcs.h" +#include "Bitmap.h" +#include "Errors.h" +#include "Graphics.h" +#include "Gui.h" +#include <android/native_window.h> +#include <android/native_window_jni.h> +#include <android/keycodes.h> + +static ANativeWindow* win_handle; +static cc_bool winCreated; +static jmethodID JAVA_openKeyboard, JAVA_setKeyboardText, JAVA_closeKeyboard; +static jmethodID JAVA_getWindowState, JAVA_enterFullscreen, JAVA_exitFullscreen; +static jmethodID JAVA_showAlert, JAVA_setRequestedOrientation; +static jmethodID JAVA_openFileDialog, JAVA_saveFileDialog; +static jmethodID JAVA_processedSurfaceDestroyed, JAVA_processEvents; +static jmethodID JAVA_getDpiX, JAVA_getDpiY, JAVA_setupForGame; + +static void RefreshWindowBounds(void) { + Window_Main.Width = ANativeWindow_getWidth(win_handle); + Window_Main.Height = ANativeWindow_getHeight(win_handle); + Platform_Log2("SCREEN BOUNDS: %i,%i", &Window_Main.Width, &Window_Main.Height); + Event_RaiseVoid(&WindowEvents.Resized); +} + +// https://developer.android.com/ndk/reference/group/input +static int MapNativeKey(int code) { + if (code >= AKEYCODE_0 && code <= AKEYCODE_9) return (code - AKEYCODE_0) + '0'; + if (code >= AKEYCODE_A && code <= AKEYCODE_Z) return (code - AKEYCODE_A) + 'A'; + if (code >= AKEYCODE_F1 && code <= AKEYCODE_F12) return (code - AKEYCODE_F1) + CCKEY_F1; + if (code >= AKEYCODE_NUMPAD_0 && code <= AKEYCODE_NUMPAD_9) return (code - AKEYCODE_NUMPAD_0) + CCKEY_KP0; + + switch (code) { + /* TODO: AKEYCODE_STAR */ + /* TODO: AKEYCODE_POUND */ + case AKEYCODE_BACK: return CCKEY_ESCAPE; + case AKEYCODE_COMMA: return CCKEY_COMMA; + case AKEYCODE_PERIOD: return CCKEY_PERIOD; + case AKEYCODE_ALT_LEFT: return CCKEY_LALT; + case AKEYCODE_ALT_RIGHT: return CCKEY_RALT; + case AKEYCODE_SHIFT_LEFT: return CCKEY_LSHIFT; + case AKEYCODE_SHIFT_RIGHT: return CCKEY_RSHIFT; + case AKEYCODE_TAB: return CCKEY_TAB; + case AKEYCODE_SPACE: return CCKEY_SPACE; + case AKEYCODE_ENTER: return CCKEY_ENTER; + case AKEYCODE_DEL: return CCKEY_BACKSPACE; + case AKEYCODE_GRAVE: return CCKEY_TILDE; + case AKEYCODE_MINUS: return CCKEY_MINUS; + case AKEYCODE_EQUALS: return CCKEY_EQUALS; + case AKEYCODE_LEFT_BRACKET: return CCKEY_LBRACKET; + case AKEYCODE_RIGHT_BRACKET: return CCKEY_RBRACKET; + case AKEYCODE_BACKSLASH: return CCKEY_BACKSLASH; + case AKEYCODE_SEMICOLON: return CCKEY_SEMICOLON; + case AKEYCODE_APOSTROPHE: return CCKEY_QUOTE; + case AKEYCODE_SLASH: return CCKEY_SLASH; + /* TODO: AKEYCODE_AT */ + /* TODO: AKEYCODE_PLUS */ + /* TODO: AKEYCODE_MENU */ + case AKEYCODE_PAGE_UP: return CCKEY_PAGEUP; + case AKEYCODE_PAGE_DOWN: return CCKEY_PAGEDOWN; + case AKEYCODE_ESCAPE: return CCKEY_ESCAPE; + case AKEYCODE_FORWARD_DEL: return CCKEY_DELETE; + case AKEYCODE_CTRL_LEFT: return CCKEY_LCTRL; + case AKEYCODE_CTRL_RIGHT: return CCKEY_RCTRL; + case AKEYCODE_CAPS_LOCK: return CCKEY_CAPSLOCK; + case AKEYCODE_SCROLL_LOCK: return CCKEY_SCROLLLOCK; + case AKEYCODE_META_LEFT: return CCKEY_LWIN; + case AKEYCODE_META_RIGHT: return CCKEY_RWIN; + case AKEYCODE_SYSRQ: return CCKEY_PRINTSCREEN; + case AKEYCODE_BREAK: return CCKEY_PAUSE; + case AKEYCODE_INSERT: return CCKEY_INSERT; + case AKEYCODE_NUM_LOCK: return CCKEY_NUMLOCK; + case AKEYCODE_NUMPAD_DIVIDE: return CCKEY_KP_DIVIDE; + case AKEYCODE_NUMPAD_MULTIPLY: return CCKEY_KP_MULTIPLY; + case AKEYCODE_NUMPAD_SUBTRACT: return CCKEY_KP_MINUS; + case AKEYCODE_NUMPAD_ADD: return CCKEY_KP_PLUS; + case AKEYCODE_NUMPAD_DOT: return CCKEY_KP_DECIMAL; + case AKEYCODE_NUMPAD_ENTER: return CCKEY_KP_ENTER; + + case AKEYCODE_DPAD_UP: return CCPAD_UP; + case AKEYCODE_DPAD_DOWN: return CCPAD_DOWN; + case AKEYCODE_DPAD_LEFT: return CCPAD_LEFT; + case AKEYCODE_DPAD_RIGHT: return CCPAD_RIGHT; + + case AKEYCODE_BUTTON_A: return CCPAD_A; + case AKEYCODE_BUTTON_B: return CCPAD_B; + case AKEYCODE_BUTTON_X: return CCPAD_X; + case AKEYCODE_BUTTON_Y: return CCPAD_Y; + + case AKEYCODE_BUTTON_L1: return CCPAD_L; + case AKEYCODE_BUTTON_R1: return CCPAD_R; + case AKEYCODE_BUTTON_L2: return CCPAD_ZL; + case AKEYCODE_BUTTON_R2: return CCPAD_ZR; + + case AKEYCODE_BUTTON_START: return CCPAD_START; + case AKEYCODE_BUTTON_SELECT: return CCPAD_SELECT; + case AKEYCODE_BUTTON_THUMBL: return CCPAD_LSTICK; + case AKEYCODE_BUTTON_THUMBR: return CCPAD_RSTICK; + } + return INPUT_NONE; +} + +static void JNICALL java_processKeyDown(JNIEnv* env, jobject o, jint code) { + int key = MapNativeKey(code); + Platform_Log2("KEY - DOWN %i,%i", &code, &key); + if (key) Input_SetPressed(key); + + if (Input_IsPadButton(key)) Input.Sources |= INPUT_SOURCE_GAMEPAD; +} + +static void JNICALL java_processKeyUp(JNIEnv* env, jobject o, jint code) { + int key = MapNativeKey(code); + Platform_Log2("KEY - UP %i,%i", &code, &key); + if (key) Input_SetReleased(key); +} + +static void JNICALL java_processKeyChar(JNIEnv* env, jobject o, jint code) { + int key = MapNativeKey(code); + Platform_Log2("KEY - PRESS %i,%i", &code, &key); + Event_RaiseInt(&InputEvents.Press, code); +} + +static void JNICALL java_processKeyText(JNIEnv* env, jobject o, jstring str) { + char buffer[NATIVE_STR_LEN]; + cc_string text = JavaGetString(env, str, buffer); + Platform_Log1("KEY - TEXT %s", &text); + Event_RaiseString(&InputEvents.TextChanged, &text); +} + +static void JNICALL java_processPointerDown(JNIEnv* env, jobject o, jint id, jint x, jint y, jint isMouse) { + Platform_Log4("POINTER %i (%i) - DOWN %i,%i", &id, &isMouse, &x, &y); + Input_AddTouch(id, x, y); +} + +static void JNICALL java_processPointerUp(JNIEnv* env, jobject o, jint id, jint x, jint y, jint isMouse) { + Platform_Log4("POINTER %i (%i) - UP %i,%i", &id, &isMouse, &x, &y); + Input_RemoveTouch(id, x, y); +} + +static void JNICALL java_processPointerMove(JNIEnv* env, jobject o, jint id, jint x, jint y, jint isMouse) { + Platform_Log4("POINTER %i (%i) - MOVE %i,%i", &id, &isMouse, &x, &y); + Input_UpdateTouch(id, x, y); +} + +static void JNICALL java_processJoystickL(JNIEnv* env, jobject o, jint x, jint y) { + Gamepad_SetAxis(0, PAD_AXIS_LEFT, x / 4096.0f, y / 4096.0f, 1.0f / 60); +} + +static void JNICALL java_processJoystickR(JNIEnv* env, jobject o, jint x, jint y) { + Gamepad_SetAxis(0, PAD_AXIS_RIGHT, x / 4096.0f, y / 4096.0f, 1.0f / 60); +} + +static void JNICALL java_processSurfaceCreated(JNIEnv* env, jobject o, jobject surface) { + Platform_LogConst("WIN - CREATED"); + win_handle = ANativeWindow_fromSurface(env, surface); + winCreated = true; + Window_Main.Handle = win_handle; + RefreshWindowBounds(); + /* TODO: Restore context */ + Event_RaiseVoid(&WindowEvents.Created); +} + +static void JNICALL java_processSurfaceDestroyed(JNIEnv* env, jobject o) { + Platform_LogConst("WIN - DESTROYED"); + if (win_handle) ANativeWindow_release(win_handle); + + win_handle = NULL; + Window_Main.Handle = NULL; + /* eglSwapBuffers might return EGL_BAD_SURFACE, EGL_BAD_ALLOC, or some other error */ + /* Instead the context is lost here in a consistent manner */ + if (Gfx.Created) Gfx_LoseContext("surface lost"); + JavaICall_Void(env, JAVA_processedSurfaceDestroyed, NULL); +} + +static void JNICALL java_processSurfaceResized(JNIEnv* env, jobject o, jobject surface) { + Platform_LogConst("WIN - RESIZED"); + RefreshWindowBounds(); +} + +static void JNICALL java_processSurfaceRedrawNeeded(JNIEnv* env, jobject o) { + Platform_LogConst("WIN - REDRAW"); + Event_RaiseVoid(&WindowEvents.RedrawNeeded); +} + +static void JNICALL java_onStart(JNIEnv* env, jobject o) { + Platform_LogConst("APP - ON START"); +} + +static void JNICALL java_onStop(JNIEnv* env, jobject o) { + Platform_LogConst("APP - ON STOP"); +} + +static void JNICALL java_onResume(JNIEnv* env, jobject o) { + Platform_LogConst("APP - ON RESUME"); + /* TODO: Resume rendering */ +} + +static void JNICALL java_onPause(JNIEnv* env, jobject o) { + Platform_LogConst("APP - ON PAUSE"); + /* TODO: Disable rendering */ +} + +static void JNICALL java_onDestroy(JNIEnv* env, jobject o) { + Platform_LogConst("APP - ON DESTROY"); + + if (Window_Main.Exists) Window_RequestClose(); + /* TODO: signal to java code we're done */ + /* JavaICall_Void(env, JAVA_processedDestroyed", NULL); */ +} + +static void JNICALL java_onGotFocus(JNIEnv* env, jobject o) { + Platform_LogConst("APP - GOT FOCUS"); + Window_Main.Focused = true; + Event_RaiseVoid(&WindowEvents.FocusChanged); +} + +static void JNICALL java_onLostFocus(JNIEnv* env, jobject o) { + Platform_LogConst("APP - LOST FOCUS"); + Window_Main.Focused = false; + Event_RaiseVoid(&WindowEvents.FocusChanged); + /* TODO: Disable rendering? */ +} + +static void JNICALL java_onLowMemory(JNIEnv* env, jobject o) { + Platform_LogConst("APP - LOW MEM"); + /* TODO: Low memory */ +} + +static void JNICALL java_processOFDResult(JNIEnv* env, jobject o, jstring str); + +static const JNINativeMethod methods[] = { + { "processKeyDown", "(I)V", java_processKeyDown }, + { "processKeyUp", "(I)V", java_processKeyUp }, + { "processKeyChar", "(I)V", java_processKeyChar }, + { "processKeyText", "(Ljava/lang/String;)V", java_processKeyText }, + + { "processPointerDown", "(IIII)V", java_processPointerDown }, + { "processPointerUp", "(IIII)V", java_processPointerUp }, + { "processPointerMove", "(IIII)V", java_processPointerMove }, + + { "processJoystickL", "(II)V", java_processJoystickL }, + { "processJoystickR", "(II)V", java_processJoystickR }, + + { "processSurfaceCreated", "(Landroid/view/Surface;)V", java_processSurfaceCreated }, + { "processSurfaceDestroyed", "()V", java_processSurfaceDestroyed }, + { "processSurfaceResized", "(Landroid/view/Surface;)V", java_processSurfaceResized }, + { "processSurfaceRedrawNeeded", "()V", java_processSurfaceRedrawNeeded }, + + { "processOnStart", "()V", java_onStart }, + { "processOnStop", "()V", java_onStop }, + { "processOnResume", "()V", java_onResume }, + { "processOnPause", "()V", java_onPause }, + { "processOnDestroy", "()V", java_onDestroy }, + + { "processOnGotFocus", "()V", java_onGotFocus }, + { "processOnLostFocus", "()V", java_onLostFocus }, + { "processOnLowMemory", "()V", java_onLowMemory }, + + { "processOFDResult", "(Ljava/lang/String;)V", java_processOFDResult }, +}; +static void CacheMethodRefs(JNIEnv* env) { + JAVA_openKeyboard = JavaGetIMethod(env, "openKeyboard", "(Ljava/lang/String;I)V"); + JAVA_setKeyboardText = JavaGetIMethod(env, "setKeyboardText", "(Ljava/lang/String;)V"); + JAVA_closeKeyboard = JavaGetIMethod(env, "closeKeyboard", "()V"); + + JAVA_getWindowState = JavaGetIMethod(env, "getWindowState", "()I"); + JAVA_enterFullscreen = JavaGetIMethod(env, "enterFullscreen", "()V"); + JAVA_exitFullscreen = JavaGetIMethod(env, "exitFullscreen", "()V"); + + JAVA_getDpiX = JavaGetIMethod(env, "getDpiX", "()F"); + JAVA_getDpiY = JavaGetIMethod(env, "getDpiY", "()F"); + JAVA_setupForGame = JavaGetIMethod(env, "setupForGame", "()V"); + + JAVA_processedSurfaceDestroyed = JavaGetIMethod(env, "processedSurfaceDestroyed", "()V"); + JAVA_processEvents = JavaGetIMethod(env, "processEvents", "()V"); + + JAVA_showAlert = JavaGetIMethod(env, "showAlert", "(Ljava/lang/String;Ljava/lang/String;)V"); + JAVA_setRequestedOrientation = JavaGetIMethod(env, "setRequestedOrientation", "(I)V"); + JAVA_openFileDialog = JavaGetIMethod(env, "openFileDialog", "(Ljava/lang/String;)I"); + JAVA_saveFileDialog = JavaGetIMethod(env, "saveFileDialog", "(Ljava/lang/String;Ljava/lang/String;)I"); +} + +void Window_PreInit(void) { } +// TODO move to bottom of file? +void Window_Init(void) { + JNIEnv* env; + /* TODO: ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FULLSCREEN, 0); */ + JavaGetCurrentEnv(env); + JavaRegisterNatives(env, methods); + CacheMethodRefs(env); + + Window_Main.SoftKeyboard = SOFT_KEYBOARD_RESIZE; + Input_SetTouchMode(true); + Gui_SetTouchUI(true); + Input.Sources = INPUT_SOURCE_NORMAL; + + DisplayInfo.Depth = 32; + DisplayInfo.ScaleX = JavaICall_Float(env, JAVA_getDpiX, NULL); + DisplayInfo.ScaleY = JavaICall_Float(env, JAVA_getDpiY, NULL); +} + +void Window_Free(void) { } + +static void RemakeWindowSurface(void) { + JNIEnv* env; + JavaGetCurrentEnv(env); + winCreated = false; + + /* Force window to be destroyed and re-created */ + /* (see comments in setupForGame for why this has to be done) */ + JavaICall_Void(env, JAVA_setupForGame, NULL); + Platform_LogConst("Entering wait for window exist loop.."); + + /* Loop until window gets created by main UI thread */ + /* (i.e. until processSurfaceCreated is received) */ + while (!winCreated) { + Window_ProcessEvents(0.01f); + Thread_Sleep(10); + } + + Platform_LogConst("OK window created.."); +} + +static void DoCreateWindow(void) { + Window_Main.Exists = true; + RemakeWindowSurface(); + /* always start as fullscreen */ + Window_EnterFullscreen(); +} +void Window_Create2D(int width, int height) { DoCreateWindow(); } +void Window_Create3D(int width, int height) { DoCreateWindow(); } + +void Window_SetTitle(const cc_string* title) { + /* TODO: Implement this somehow */ + /* Maybe https://stackoverflow.com/questions/2198410/how-to-change-title-of-activity-in-android */ +} + +void Clipboard_GetText(cc_string* value) { + JavaCall_Void_String("getClipboardText", value); +} +void Clipboard_SetText(const cc_string* value) { + JavaCall_String_Void("setClipboardText", value); +} + +int Window_GetWindowState(void) { + JNIEnv* env; + JavaGetCurrentEnv(env); + return JavaICall_Int(env, JAVA_getWindowState, NULL); +} + +cc_result Window_EnterFullscreen(void) { + JNIEnv* env; + JavaGetCurrentEnv(env); + JavaICall_Void(env, JAVA_enterFullscreen, NULL); + return 0; +} + +cc_result Window_ExitFullscreen(void) { + JNIEnv* env; + JavaGetCurrentEnv(env); + JavaICall_Void(env, JAVA_exitFullscreen, NULL); + return 0; +} + +int Window_IsObscured(void) { return 0; } + +void Window_Show(void) { } /* Window already visible */ +void Window_SetSize(int width, int height) { } + +void Window_RequestClose(void) { + Window_Main.Exists = false; + Event_RaiseVoid(&WindowEvents.Closing); + /* TODO: Do we need to call finish here */ + /* ANativeActivity_finish(app->activity); */ +} + +void Window_ProcessEvents(float delta) { + JNIEnv* env; + JavaGetCurrentEnv(env); + /* TODO: Cache the java env */ + JavaICall_Void(env, JAVA_processEvents, NULL); +} + +void Window_ProcessGamepads(float delta) { } + +/* No actual mouse cursor */ +static void Cursor_GetRawPos(int* x, int* y) { *x = 0; *y = 0; } +void Cursor_SetPosition(int x, int y) { } +static void Cursor_DoSetVisible(cc_bool visible) { } + +static void ShowDialogCore(const char* title, const char* msg) { + JNIEnv* env; + jvalue args[2]; + JavaGetCurrentEnv(env); + + Platform_LogConst(title); + Platform_LogConst(msg); + /* in case surface destroyed message has arrived */ + Window_ProcessEvents(0.0); + + args[0].l = JavaMakeConst(env, title); + args[1].l = JavaMakeConst(env, msg); + JavaICall_Void(env, JAVA_showAlert, args); + (*env)->DeleteLocalRef(env, args[0].l); + (*env)->DeleteLocalRef(env, args[1].l); +} + +static FileDialogCallback ofd_callback; +static int ofd_action; +static void JNICALL java_processOFDResult(JNIEnv* env, jobject o, jstring str) { + const char* raw; + + char buffer[NATIVE_STR_LEN]; + cc_string path = JavaGetString(env, str, buffer); + ofd_callback(&path); + + if (ofd_action == OFD_UPLOAD_DELETE) { + // TODO better way of doing this? msybe move to java side? + raw = (*env)->GetStringUTFChars(env, str, NULL); + unlink(raw); + (*env)->ReleaseStringUTFChars(env, str, raw); + } + ofd_callback = NULL; +} + +cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* open_args) { + JNIEnv* env; + jvalue args[1]; + JavaGetCurrentEnv(env); + + ofd_callback = open_args->Callback; + ofd_action = open_args->uploadAction; + + // TODO use filters + args[0].l = JavaMakeConst(env, open_args->uploadFolder); + int OK = JavaICall_Int(env, JAVA_openFileDialog, args); + (*env)->DeleteLocalRef(env, args[0].l); + // TODO: Better error handling + return OK ? 0 : ERR_INVALID_ARGUMENT; +} + +cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* save_args) { + JNIEnv* env; + jvalue args[2]; + JavaGetCurrentEnv(env); + if (!save_args->defaultName.length) return SFD_ERR_NEED_DEFAULT_NAME; + + // save the item to a temp file, which is then (usually) later deleted by intent callback + cc_string tmpDir = String_FromConst("Exported"); + Directory_Create(&tmpDir); + + cc_string path; char pathBuffer[FILENAME_SIZE]; + String_InitArray(path, pathBuffer); + String_Format3(&path, "%s/%s%c", &tmpDir, &save_args->defaultName, save_args->filters[0]); + save_args->Callback(&path); + // TODO kinda ugly, maybe a better way? + cc_string file = String_UNSAFE_SubstringAt(&path, String_IndexOf(&path, '/') + 1); + + args[0].l = JavaMakeString(env, &path); + args[1].l = JavaMakeString(env, &file); + int OK = JavaICall_Int(env, JAVA_saveFileDialog, args); + (*env)->DeleteLocalRef(env, args[0].l); + (*env)->DeleteLocalRef(env, args[1].l); + // TODO: Better error handling + return OK ? 0 : ERR_INVALID_ARGUMENT; +} + +void Window_AllocFramebuffer(struct Bitmap* bmp, int width, int height) { + bmp->scan0 = (BitmapCol*)Mem_Alloc(width * height, 4, "window pixels"); + bmp->width = width; + bmp->height = height; +} + +void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) { + ANativeWindow_Buffer buffer; + cc_uint32* src; + cc_uint32* dst; + ARect b; + int y, res, size; + + /* window not created yet */ + if (!win_handle) return; + b.left = r.x; b.right = r.x + r.width; + b.top = r.y; b.bottom = r.y + r.height; + + /* Platform_Log4("DIRTY: %i,%i - %i,%i", &b.left, &b.top, &b.right, &b.bottom); */ + res = ANativeWindow_lock(win_handle, &buffer, &b); + if (res) Logger_Abort2(res, "Locking window pixels"); + /* Platform_Log4("ADJUS: %i,%i - %i,%i", &b.left, &b.top, &b.right, &b.bottom); */ + + /* In some rare cases, the returned locked region will be entire area of the surface */ + /* This can cause a crash if the surface has been resized (i.e. device rotated), */ + /* but the framebuffer has not been resized yet. So always constrain bounds. */ + b.left = min(b.left, bmp->width); b.right = min(b.right, bmp->width); + b.top = min(b.top, bmp->height); b.bottom = min(b.bottom, bmp->height); + + src = (cc_uint32*)bmp->scan0 + b.left; + dst = (cc_uint32*)buffer.bits + b.left; + size = (b.right - b.left) * 4; + + for (y = b.top; y < b.bottom; y++) + { + Mem_Copy(dst + y * buffer.stride, src + y * bmp->width, size); + } + res = ANativeWindow_unlockAndPost(win_handle); + if (res) Logger_Abort2(res, "Unlocking window pixels"); +} + +void Window_FreeFramebuffer(struct Bitmap* bmp) { + Mem_Free(bmp->scan0); +} + +void OnscreenKeyboard_Open(struct OpenKeyboardArgs* kArgs) { + JNIEnv* env; + jvalue args[2]; + JavaGetCurrentEnv(env); + + args[0].l = JavaMakeString(env, kArgs->text); + args[1].i = kArgs->type; + JavaICall_Void(env, JAVA_openKeyboard, args); + (*env)->DeleteLocalRef(env, args[0].l); +} + +void OnscreenKeyboard_SetText(const cc_string* text) { + JNIEnv* env; + jvalue args[1]; + JavaGetCurrentEnv(env); + + args[0].l = JavaMakeString(env, text); + JavaICall_Void(env, JAVA_setKeyboardText, args); + (*env)->DeleteLocalRef(env, args[0].l); +} + +void OnscreenKeyboard_Draw2D(Rect2D* r, struct Bitmap* bmp) { } +void OnscreenKeyboard_Draw3D(void) { } + +void OnscreenKeyboard_Close(void) { + JNIEnv* env; + JavaGetCurrentEnv(env); + JavaICall_Void(env, JAVA_closeKeyboard, NULL); +} + +void Window_LockLandscapeOrientation(cc_bool lock) { + JNIEnv* env; + jvalue args[1]; + JavaGetCurrentEnv(env); + + /* SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 0x00000006 */ + /* SCREEN_ORIENTATION_UNSPECIFIED = 0xffffffff */ + args[0].i = lock ? 0x00000006 : 0xffffffff; + JavaICall_Void(env, JAVA_setRequestedOrientation, args); +} + +void Window_EnableRawMouse(void) { DefaultEnableRawMouse(); } +void Window_UpdateRawMouse(void) { } +void Window_DisableRawMouse(void) { DefaultDisableRawMouse(); } +#endif |