From ca8f680000de97dd03e4e37119f9c9e8ed6f3de6 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sun, 25 Mar 2018 22:27:21 +0000 Subject: Android: Added keycodes to make arrow keys, delete, return, and other non text-keys work. ALso added a Java helper class to make Java call easier. We may need more Java/JNI in the future. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12801 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/drivers/Android/Fl_Android_Application.H | 23 ++ src/drivers/Android/Fl_Android_Application.cxx | 37 ++ src/drivers/Android/Fl_Android_Screen_Keyboard.cxx | 377 +++++++++++++++------ src/drivers/Android/Fl_Android_Window_Driver.H | 2 +- 4 files changed, 326 insertions(+), 113 deletions(-) (limited to 'src') diff --git a/src/drivers/Android/Fl_Android_Application.H b/src/drivers/Android/Fl_Android_Application.H index ad9fffe77..103c43dda 100644 --- a/src/drivers/Android/Fl_Android_Application.H +++ b/src/drivers/Android/Fl_Android_Application.H @@ -39,6 +39,29 @@ extern void (*fl_lock_function)(); #include #include + +/** + * A class to make Java calls from C++ easier. + */ +class Fl_Android_Java +{ + JavaVM *pJavaVM = nullptr; + JNIEnv *pJNIEnv = nullptr; + jobject pNativeActivity; + jclass pNativeActivityClass; + bool pAttached = false; + +public: + Fl_Android_Java(); + ~Fl_Android_Java(); + bool is_attached() { return pAttached; } + JavaVM *VM() { return pJavaVM; } + JNIEnv *env() { return pJNIEnv; } + jobject native_ativity() { return pNativeActivity; } + jclass native_activity_class() { return pNativeActivityClass; } +}; + + /** * Static class that manages all interaction between the Android Native Activity * and the FLTK library. It also keeps often used data for global access. diff --git a/src/drivers/Android/Fl_Android_Application.cxx b/src/drivers/Android/Fl_Android_Application.cxx index 97b692199..fca8d9a46 100644 --- a/src/drivers/Android/Fl_Android_Application.cxx +++ b/src/drivers/Android/Fl_Android_Application.cxx @@ -804,6 +804,43 @@ JNIEXPORT void ANativeActivity_onCreate(ANativeActivity* activity, void* savedSt Fl_Android_Activity::create(activity, savedState, savedStateSize); } + +// ---- Java Stuff ------------------------------------------------------------- + + +Fl_Android_Java::Fl_Android_Java() +{ + jint lResult; + jint lFlags = 0; + + pJavaVM = Fl_Android_Application::get_activity()->vm; + pJNIEnv = Fl_Android_Application::get_activity()->env; + + JavaVMAttachArgs lJavaVMAttachArgs = { + .version = JNI_VERSION_1_6, + .name = "NativeThread", + .group = nullptr + }; + + lResult = pJavaVM->AttachCurrentThread(&pJNIEnv, &lJavaVMAttachArgs); + if (lResult == JNI_ERR) return; + + pNativeActivity = Fl_Android_Application::get_activity()->clazz; + + pNativeActivityClass = env()->GetObjectClass(pNativeActivity); + + pAttached = true; +} + + +Fl_Android_Java::~Fl_Android_Java() +{ + if (is_attached()) { + pJavaVM->DetachCurrentThread(); + } +} + + // // End of "$Id$". // diff --git a/src/drivers/Android/Fl_Android_Screen_Keyboard.cxx b/src/drivers/Android/Fl_Android_Screen_Keyboard.cxx index 341f48238..57de673cf 100644 --- a/src/drivers/Android/Fl_Android_Screen_Keyboard.cxx +++ b/src/drivers/Android/Fl_Android_Screen_Keyboard.cxx @@ -31,15 +31,162 @@ #include +// convert an FLTK (X) keysym to a MacOS symbol: +// This table is in numeric order by FLTK symbol order for binary search. +static const struct {unsigned short vk, fltk;} vktab[] = { + { AKEYCODE_SPACE, ' ' }, { AKEYCODE_APOSTROPHE, '\'' }, { AKEYCODE_COMMA, ',' }, { AKEYCODE_MINUS, '-' }, { AKEYCODE_PERIOD, '.' }, { AKEYCODE_SLASH, '/' }, + { AKEYCODE_0, '0' }, { AKEYCODE_1, '1' }, { AKEYCODE_2, '2' }, { AKEYCODE_3, '3' }, + { AKEYCODE_4, '4' }, { AKEYCODE_5, '5' }, { AKEYCODE_6, '6' }, { AKEYCODE_7, '7' }, + { AKEYCODE_8, '8' }, { AKEYCODE_9, '9' }, { AKEYCODE_SEMICOLON, ';' }, { AKEYCODE_EQUALS, '=' }, + { AKEYCODE_A, 'A' }, { AKEYCODE_B, 'B' }, { AKEYCODE_C, 'C' }, { AKEYCODE_D, 'D' }, + { AKEYCODE_E, 'E' }, { AKEYCODE_F, 'F' }, { AKEYCODE_G, 'G' }, { AKEYCODE_H, 'H' }, + { AKEYCODE_I, 'I' }, { AKEYCODE_J, 'J' }, { AKEYCODE_K, 'K' }, { AKEYCODE_L, 'L' }, + { AKEYCODE_M, 'M' }, { AKEYCODE_N, 'N' }, { AKEYCODE_O, 'O' }, { AKEYCODE_P, 'P' }, + { AKEYCODE_Q, 'Q' }, { AKEYCODE_R, 'R' }, { AKEYCODE_S, 'S' }, { AKEYCODE_T, 'T' }, + { AKEYCODE_U, 'U' }, { AKEYCODE_V, 'V' }, { AKEYCODE_W, 'W' }, { AKEYCODE_X, 'X' }, + { AKEYCODE_Y, 'Y' }, { AKEYCODE_Z, 'Z' }, + { AKEYCODE_LEFT_BRACKET, '[' }, { AKEYCODE_BACKSLASH, '\\' }, { AKEYCODE_RIGHT_BRACKET, ']' }, { AKEYCODE_GRAVE, '`' }, + { AKEYCODE_VOLUME_DOWN, FL_Volume_Down}, { AKEYCODE_MUTE, FL_Volume_Mute}, { AKEYCODE_VOLUME_UP, FL_Volume_Up}, +#if 0 + #define FL_Volume_Down 0xEF11 /* Volume control down */ + 513 #define FL_Volume_Mute 0xEF12 /* Mute sound from the system */ + 514 #define FL_Volume_Up 0xEF13 /* Volume control up */ + 515 #define FL_Media_Play 0xEF14 /* Start playing of audio */ + 516 #define FL_Media_Stop 0xEF15 /* Stop playing audio */ + 517 #define FL_Media_Prev 0xEF16 /* Previous track */ + 518 #define FL_Media_Next 0xEF17 /* Next track */ + 519 #define FL_Home_Page 0xEF18 /* Display user's home page */ + 520 #define FL_Mail 0xEF19 /* Invoke user's mail program */ + 521 #define FL_Search 0xEF1B /* Search */ + 522 #define FL_Back 0xEF26 /* Like back on a browser */ + 523 #define FL_Forward 0xEF27 /* Like forward on a browser */ + 524 #define FL_Stop 0xEF28 /* Stop current operation */ + 525 #define FL_Refresh 0xEF29 /* Refresh the page */ + 526 #define FL_Sleep 0xEF2F /* Put system to sleep */ + 527 #define FL_Favorites 0xEF30 /* Show favorite locations */ + 528 +#endif + { AKEYCODE_DEL, FL_BackSpace }, { AKEYCODE_TAB, FL_Tab }, { AKEYCODE_POUND, FL_Iso_Key }, { AKEYCODE_ENTER, FL_Enter }, /*{ 0x7F, FL_Pause }, + { 0x7F, FL_Scroll_Lock },*/ { AKEYCODE_ESCAPE, FL_Escape }, + { AKEYCODE_KANA, FL_Kana}, { AKEYCODE_EISU, FL_Eisu}, { AKEYCODE_YEN, FL_Yen}, /*{ AKEYCODE_UND, FL_JIS_Underscore},*/ + { AKEYCODE_MOVE_HOME, FL_Home }, { AKEYCODE_DPAD_LEFT, FL_Left }, + { AKEYCODE_DPAD_UP, FL_Up }, { AKEYCODE_DPAD_RIGHT, FL_Right }, { AKEYCODE_DPAD_DOWN, FL_Down }, { AKEYCODE_PAGE_UP, FL_Page_Up }, + { AKEYCODE_PAGE_DOWN, FL_Page_Down }, { AKEYCODE_MOVE_END, FL_End }, { AKEYCODE_SYSRQ, FL_Print }, { AKEYCODE_INSERT, FL_Insert }, + { AKEYCODE_MENU, FL_Menu }, { AKEYCODE_HELP, FL_Help }, { AKEYCODE_NUM_LOCK, FL_Num_Lock }, + { AKEYCODE_NUMPAD_ENTER, FL_KP_Enter }, { AKEYCODE_NUMPAD_MULTIPLY, FL_KP+'*' }, { AKEYCODE_NUMPAD_ADD, FL_KP+'+'}, + { AKEYCODE_NUMPAD_COMMA, FL_KP+',' }, + { AKEYCODE_NUMPAD_SUBTRACT, FL_KP+'-' }, { AKEYCODE_NUMPAD_DOT, FL_KP+'.' }, { AKEYCODE_NUMPAD_DIVIDE, FL_KP+'/' }, + { AKEYCODE_NUMPAD_0, FL_KP+'0' }, { AKEYCODE_NUMPAD_1, FL_KP+'1' }, { AKEYCODE_NUMPAD_2, FL_KP+'2' }, { AKEYCODE_NUMPAD_3, FL_KP+'3' }, + { AKEYCODE_NUMPAD_4, FL_KP+'4' }, { AKEYCODE_NUMPAD_5, FL_KP+'5' }, { AKEYCODE_NUMPAD_6, FL_KP+'6' }, { AKEYCODE_NUMPAD_7, FL_KP+'7' }, + { AKEYCODE_NUMPAD_8, FL_KP+'8' }, { AKEYCODE_NUMPAD_9, FL_KP+'9' }, { AKEYCODE_NUMPAD_EQUALS, FL_KP+'=' }, + { AKEYCODE_F1, FL_F+1 }, { AKEYCODE_F2, FL_F+2 }, { AKEYCODE_F3, FL_F+3 }, { AKEYCODE_F4, FL_F+4 }, + { AKEYCODE_F5, FL_F+5 }, { AKEYCODE_F6, FL_F+6 }, { AKEYCODE_F7, FL_F+7 }, { AKEYCODE_F8, FL_F+8 }, + { AKEYCODE_F9, FL_F+9 }, { AKEYCODE_F10, FL_F+10 }, { AKEYCODE_F11, FL_F+11 }, { AKEYCODE_F12, FL_F+12 }, + //{ AKEYCODE_F13, FL_F+13 }, { AKEYCODE_F14, FL_F+14 }, { AKEYCODE_F15, FL_F+15 }, { AKEYCODE_F16, FL_F+16 }, + //{ AKEYCODE_F17, FL_F+17 }, { AKEYCODE_F18, FL_F+18 }, { AKEYCODE_F19, FL_F+19 }, { AKEYCODE_F20, FL_F+20 }, + { AKEYCODE_SHIFT_LEFT, FL_Shift_L }, { AKEYCODE_SHIFT_RIGHT, FL_Shift_R }, { AKEYCODE_CTRL_LEFT, FL_Control_L }, { AKEYCODE_CTRL_RIGHT, FL_Control_R }, + { AKEYCODE_CAPS_LOCK, FL_Caps_Lock }, { AKEYCODE_META_LEFT, FL_Meta_L }, { AKEYCODE_META_RIGHT, FL_Meta_R }, + { AKEYCODE_ALT_LEFT, FL_Alt_L }, { AKEYCODE_ALT_RIGHT, FL_Alt_R }, { AKEYCODE_FORWARD_DEL, FL_Delete } +}; + +#if 0 + + +// public static final int KEYCODE_ALL_APPS = 284; +// private static final int LAST_KEYCODE = KEYCODE_ALL_APPS; + +// Computes the macKeyLookUp table that transforms a Mac OS virtual keycode into an FLTK keysym +unsigned short *fl_compute_macKeyLookUp() +{ + static unsigned short macKeyLookUp[128]; + memset(macKeyLookUp, 0, sizeof(macKeyLookUp)); + for (unsigned i = 0; i < sizeof(vktab)/sizeof(*vktab); i++) { + macKeyLookUp[vktab[i].vk] = vktab[i].fltk; + } + return macKeyLookUp; +} + +static int fltk2mac(int fltk) { + int a = 0; + int b = sizeof(vktab)/sizeof(*vktab); + while (a < b) { + int c = (a+b)/2; + if (vktab[c].fltk == fltk) return vktab[c].vk; + if (vktab[c].fltk < fltk) a = c+1; else b = c; + } + return vktab[a].vk; +} + +//: returns true, if that key was pressed during the last event +int Fl_Darwin_System_Driver::event_key(int k) { + return get_key(k); +} + +//: returns true, if that key is pressed right now +int Fl_Darwin_System_Driver::get_key(int k) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if (&CGEventSourceKeyState != NULL) { + return (int)CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, fltk2mac(k) ); + } + else +#endif + { + typedef UInt32 fl_KeyMap[4]; + fl_KeyMap foo; + // use the GetKeys Carbon function + typedef void (*keymap_f)(fl_KeyMap); + static keymap_f f = NULL; + if (!f) f = ( keymap_f )Fl_Darwin_System_Driver::get_carbon_function("GetKeys"); + (*f)(foo); +#ifdef MAC_TEST_FOR_KEYCODES + static int cnt = 0; + if (cnt++>1024) { + cnt = 0; + printf("%08x %08x %08x %08x\n", (ulong*)(foo)[3], (ulong*)(foo)[2], (ulong*)(foo)[1], (ulong*)(foo)[0]); + } +#endif + unsigned char *b = (unsigned char*)foo; + // KP_Enter can be at different locations for Powerbooks vs. desktop Macs + if (k==FL_KP_Enter) { + return (((b[0x34>>3]>>(0x34&7))&1)||((b[0x4c>>3]>>(0x4c&7))&1)); + } + int i = fltk2mac(k); + return (b[i>>3]>>(i&7))&1; + } +} + +#endif + int Fl_Android_Screen_Driver::compose(int &del) { - del = 0; + int condition; + unsigned char ascii = (unsigned char)Fl::e_text[0]; + condition = (Fl::e_state & (FL_ALT | FL_META | FL_CTRL)) && !(ascii & 128) ; + if (condition) { del = 0; return 0;} // this stuff is to be treated as a function key + del = Fl::compose_state; + Fl::compose_state = 0; + // Only insert non-control characters: + if ( (!Fl::compose_state) && ! (ascii & ~31 && ascii!=127)) { return 0; } return 1; } +static unsigned short *key_lookup = nullptr; + +// Computes the macKeyLookUp table that transforms a Mac OS virtual keycode into an FLTK keysym +static unsigned short *compute_key_lookup() +{ + static unsigned short AndroidKeyLookUp[AKEYCODE_ALL_APPS+1]; + memset(AndroidKeyLookUp, 0, sizeof(AndroidKeyLookUp)); + for (unsigned i = 0; i < sizeof(vktab)/sizeof(*vktab); i++) { + AndroidKeyLookUp[vktab[i].vk] = vktab[i].fltk; + } + return AndroidKeyLookUp; +} + + int Fl_Android_Screen_Driver::handle_keyboard_event(AInputQueue *queue, AInputEvent *event) { /* @@ -100,43 +247,65 @@ int64_t AKeyEvent_getEventTime (const AInputEvent *key_event) // String class KeyEvent::getCharacters() [Java] // is there a way to get the true Java event somehow? // override dispatchKeyEvent(android.view.KeyEvent event) + // getDeadChar() + // + // This seems to work for hardware keys only: +// public static interface View.OnKeyListener +// boolean onKey (View v, +// int keyCode, +// KeyEvent event) + // public static interface KeyEvent.Callback + // onKeyDown(int keyCode, KeyEvent event) + // public static interface Window.Callback + // abstract boolean dispatchKeyEvent(KeyEvent event) + // view.setOnKeyListener(new OnKeyListener() + // + // NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN,checkKeypress); + // public function CheckKeypress(event:KeyboardEvent):void + // + // https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/KeyEvent.java } else { // send keycode as many times as getRepeatCount() / AKeyEvent_getRepeatCount(event) } } - JavaVM *javaVM = Fl_Android_Application::get_activity()->vm; - JNIEnv *jniEnv = Fl_Android_Application::get_activity()->env; - - JavaVMAttachArgs Args = { JNI_VERSION_1_6, "NativeThread", NULL }; - jint result = javaVM->AttachCurrentThread(&jniEnv, &Args); - if (result == JNI_ERR) return 0; - - jclass class_key_event = jniEnv->FindClass("android/view/KeyEvent"); - jmethodID eventConstructor = jniEnv->GetMethodID(class_key_event, "", - "(JJIIIIIIII)V"); - jobject eventObj = jniEnv->NewObject(class_key_event, eventConstructor, - AKeyEvent_getDownTime(event), - AKeyEvent_getEventTime(event), - AKeyEvent_getAction(event), - AKeyEvent_getKeyCode(event), - AKeyEvent_getRepeatCount(event), - AKeyEvent_getMetaState(event), - AInputEvent_getDeviceId(event), - AKeyEvent_getScanCode(event), - AKeyEvent_getFlags(event), - AInputEvent_getSource(event)); - - jmethodID method_get_unicode_char = jniEnv->GetMethodID(class_key_event, - "getUnicodeChar", - "(I)I"); - int unicodeKey = jniEnv->CallIntMethod(eventObj, method_get_unicode_char, - AKeyEvent_getMetaState(event)); - - jniEnv->DeleteLocalRef(class_key_event); - jniEnv->DeleteLocalRef(eventObj); - - javaVM->DetachCurrentThread(); + int unicodeKey = 0; + auto aKeyCode = AKeyEvent_getKeyCode(event); + + Fl_Android_Java java; + if (java.is_attached()) { + + jclass class_key_event = java.env()->FindClass("android/view/KeyEvent"); + + jmethodID eventConstructor = java.env()->GetMethodID( + class_key_event, "", + "(JJIIIIIIII)V"); + + jobject eventObj = java.env()->NewObject( + class_key_event, eventConstructor, + AKeyEvent_getDownTime(event), + AKeyEvent_getEventTime(event), + AKeyEvent_getAction(event), + aKeyCode, + AKeyEvent_getRepeatCount(event), + AKeyEvent_getMetaState(event), + AInputEvent_getDeviceId(event), + AKeyEvent_getScanCode(event), + AKeyEvent_getFlags(event), + AInputEvent_getSource(event)); + + jmethodID method_get_unicode_char = java.env()->GetMethodID( + class_key_event, + "getUnicodeChar", + "(I)I"); + + unicodeKey = java.env()->CallIntMethod( + eventObj, method_get_unicode_char, + AKeyEvent_getMetaState(event)); + + java.env()->DeleteLocalRef(class_key_event); + java.env()->DeleteLocalRef(eventObj); + } static char buf[8]; int len = fl_utf8encode(unicodeKey, buf); @@ -146,14 +315,22 @@ int64_t AKeyEvent_getEventTime (const AInputEvent *key_event) buf[0] = 0; Fl_Android_Application::log_i("Unicode: %d Text: %s", unicodeKey, buf); + if (!key_lookup) key_lookup = compute_key_lookup(); + Fl::e_keysym = (aKeyCode>AKEYCODE_ALL_APPS) ? 0 : key_lookup[aKeyCode]; + AInputQueue_finishEvent(queue, event, 0); Fl_Widget *w = Fl::focus(); if (w) { Fl_Window *win = w->window(); - if (keyAction==AKEY_EVENT_ACTION_DOWN && unicodeKey>0) { - Fl::e_text = buf; - Fl::e_length = len; + if (keyAction==AKEY_EVENT_ACTION_DOWN) { + if (unicodeKey>0) { + Fl::e_text = buf; + Fl::e_length = len; + } else { + Fl::e_text = (char*)""; + Fl::e_length = 0; + } Fl::handle(FL_KEYBOARD, win); } } @@ -166,99 +343,75 @@ void Fl_Android_Screen_Driver::request_keyboard() { if (pKeyboardCount==0) { /* + * The following line does not work as of March 2018. The pseudo-Java + * code that follows is needed to make the virtaul keyboard show. + * ANativeActivity_showSoftInput(Fl_Android_Application::get_activity(), ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT); - */ -// void displayKeyboard(bool pShow) -// InputMethodManager imm = ( InputMethodManager )getSystemService( Context.INPUT_METHOD_SERVICE ); -// imm.showSoftInput( this.getWindow().getDecorView(), InputMethodManager.SHOW_FORCED ); - - bool pShow = true; - { - // Attaches the current thread to the JVM. - jint lResult; - jint lFlags = 0; + * + * This is the actual Java code that we recreate in C++ + * + InputMethodManager imm = ( InputMethodManager )getSystemService( Context.INPUT_METHOD_SERVICE ); + imm.showSoftInput( this.getWindow().getDecorView(), InputMethodManager.SHOW_FORCED ); + */ - JavaVM* lJavaVM = Fl_Android_Application::get_activity()->vm; - JNIEnv* lJNIEnv = Fl_Android_Application::get_activity()->env; + Fl_Android_Java java; + if (java.is_attached()) { - JavaVMAttachArgs lJavaVMAttachArgs; - lJavaVMAttachArgs.version = JNI_VERSION_1_6; - lJavaVMAttachArgs.name = "NativeThread"; - lJavaVMAttachArgs.group = NULL; - - lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs); - if (lResult == JNI_ERR) { - return; - } - - // Retrieves NativeActivity. - jobject lNativeActivity = Fl_Android_Application::get_activity()->clazz; - jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity); + jint lFlags = 0; // Retrieves Context.INPUT_METHOD_SERVICE. - jclass ClassContext = lJNIEnv->FindClass("android/content/Context"); - jfieldID FieldINPUT_METHOD_SERVICE = - lJNIEnv->GetStaticFieldID(ClassContext, - "INPUT_METHOD_SERVICE", "Ljava/lang/String;"); - jobject INPUT_METHOD_SERVICE = - lJNIEnv->GetStaticObjectField(ClassContext, - FieldINPUT_METHOD_SERVICE); -// jniCheck(INPUT_METHOD_SERVICE); + jclass ClassContext = java.env()->FindClass("android/content/Context"); + jfieldID FieldINPUT_METHOD_SERVICE = java.env()->GetStaticFieldID( + ClassContext, + "INPUT_METHOD_SERVICE", + "Ljava/lang/String;"); + jobject INPUT_METHOD_SERVICE = java.env()->GetStaticObjectField( + ClassContext, + FieldINPUT_METHOD_SERVICE); // Runs getSystemService(Context.INPUT_METHOD_SERVICE). - jclass ClassInputMethodManager = lJNIEnv->FindClass( + jclass ClassInputMethodManager = java.env()->FindClass( "android/view/inputmethod/InputMethodManager"); - jmethodID MethodGetSystemService = lJNIEnv->GetMethodID( - ClassNativeActivity, "getSystemService", + jmethodID MethodGetSystemService = java.env()->GetMethodID( + java.native_activity_class(), "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); - jobject lInputMethodManager = lJNIEnv->CallObjectMethod( - lNativeActivity, MethodGetSystemService, + jobject lInputMethodManager = java.env()->CallObjectMethod( + java.native_ativity(), MethodGetSystemService, INPUT_METHOD_SERVICE); // Runs getWindow().getDecorView(). - jmethodID MethodGetWindow = lJNIEnv->GetMethodID( - ClassNativeActivity, "getWindow", + jmethodID MethodGetWindow = java.env()->GetMethodID( + java.native_activity_class(), "getWindow", "()Landroid/view/Window;"); - jobject lWindow = lJNIEnv->CallObjectMethod(lNativeActivity, - MethodGetWindow); - jclass ClassWindow = lJNIEnv->FindClass( + jobject lWindow = java.env()->CallObjectMethod( + java.native_ativity(), + MethodGetWindow); + jclass ClassWindow = java.env()->FindClass( "android/view/Window"); - jmethodID MethodGetDecorView = lJNIEnv->GetMethodID( + jmethodID MethodGetDecorView = java.env()->GetMethodID( ClassWindow, "getDecorView", "()Landroid/view/View;"); - jobject lDecorView = lJNIEnv->CallObjectMethod(lWindow, - MethodGetDecorView); - - if (pShow) { - // Runs lInputMethodManager.showSoftInput(...). - jmethodID MethodShowSoftInput = lJNIEnv->GetMethodID( - ClassInputMethodManager, "showSoftInput", - "(Landroid/view/View;I)Z"); - jboolean lResult = lJNIEnv->CallBooleanMethod( - lInputMethodManager, MethodShowSoftInput, - lDecorView, lFlags); - } else { - // Runs lWindow.getViewToken() - jclass ClassView = lJNIEnv->FindClass( - "android/view/View"); - jmethodID MethodGetWindowToken = lJNIEnv->GetMethodID( - ClassView, "getWindowToken", "()Landroid/os/IBinder;"); - jobject lBinder = lJNIEnv->CallObjectMethod(lDecorView, - MethodGetWindowToken); - - // lInputMethodManager.hideSoftInput(...). - jmethodID MethodHideSoftInput = lJNIEnv->GetMethodID( - ClassInputMethodManager, "hideSoftInputFromWindow", - "(Landroid/os/IBinder;I)Z"); - jboolean lRes = lJNIEnv->CallBooleanMethod( - lInputMethodManager, MethodHideSoftInput, - lBinder, lFlags); - } - - // Finished with the JVM. - lJavaVM->DetachCurrentThread(); + jobject lDecorView = java.env()->CallObjectMethod( + lWindow, + MethodGetDecorView); + + // Runs lInputMethodManager.showSoftInput(...). + jmethodID MethodShowSoftInput = java.env()->GetMethodID( + ClassInputMethodManager, "showSoftInput", + "(Landroid/view/View;I)Z"); + jboolean lResult = java.env()->CallBooleanMethod( + lInputMethodManager, MethodShowSoftInput, + lDecorView, lFlags); + + java.env()->DeleteLocalRef(ClassContext); + java.env()->DeleteLocalRef(ClassInputMethodManager); + java.env()->DeleteLocalRef(ClassWindow); + + java.env()->DeleteLocalRef(INPUT_METHOD_SERVICE); + java.env()->DeleteLocalRef(lInputMethodManager); + java.env()->DeleteLocalRef(lWindow); + java.env()->DeleteLocalRef(lDecorView); } - } pKeyboardCount++; } diff --git a/src/drivers/Android/Fl_Android_Window_Driver.H b/src/drivers/Android/Fl_Android_Window_Driver.H index 95c31b247..1df475a3d 100644 --- a/src/drivers/Android/Fl_Android_Window_Driver.H +++ b/src/drivers/Android/Fl_Android_Window_Driver.H @@ -134,7 +134,7 @@ public: #endif - void wait_for_expose() { wait_for_expose_value = 1; } + virtual void wait_for_expose() override { wait_for_expose_value = 1; } static void expose_all(); }; -- cgit v1.2.3