summaryrefslogtreecommitdiff
path: root/src/drivers/Android
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2018-03-25 16:48:44 +0000
committerMatthias Melcher <fltk@matthiasm.com>2018-03-25 16:48:44 +0000
commiteb09ab161aa7d44164d959a3fb3abd49816229ef (patch)
tree8fe45d3f47a208f2d2175a372ba28e65eefcdf7b /src/drivers/Android
parent832377fc21fb5b44f419c17322ca95abdbf8db4a (diff)
Android: Separating keyboard stuff into a new file
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12800 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers/Android')
-rw-r--r--src/drivers/Android/Fl_Android_Screen_Driver.H12
-rw-r--r--src/drivers/Android/Fl_Android_Screen_Driver.cxx266
-rw-r--r--src/drivers/Android/Fl_Android_Screen_Keyboard.cxx280
3 files changed, 289 insertions, 269 deletions
diff --git a/src/drivers/Android/Fl_Android_Screen_Driver.H b/src/drivers/Android/Fl_Android_Screen_Driver.H
index 59cec5462..4154bf64d 100644
--- a/src/drivers/Android/Fl_Android_Screen_Driver.H
+++ b/src/drivers/Android/Fl_Android_Screen_Driver.H
@@ -48,10 +48,10 @@ private:
public:
Fl_Android_Screen_Driver() : Fl_Screen_Driver(), pScreenContentChanged(false) { }
- void add_timeout(double time, Fl_Timeout_Handler cb, void *argp);
- void repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp);
- int has_timeout(Fl_Timeout_Handler cb, void *argp);
- void remove_timeout(Fl_Timeout_Handler cb, void *argp);
+ virtual void add_timeout(double time, Fl_Timeout_Handler cb, void *argp) override;
+ virtual void repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) override;
+ virtual int has_timeout(Fl_Timeout_Handler cb, void *argp) override;
+ virtual void remove_timeout(Fl_Timeout_Handler cb, void *argp) override;
virtual int compose(int &del) override;
@@ -79,8 +79,8 @@ public:
virtual void beep(int type);
// --- global events
#endif
- virtual void flush();
- virtual double wait(double time_to_wait);
+ virtual void flush() override;
+ virtual double wait(double time_to_wait) override;
#if 0
virtual int ready();
virtual void grab(Fl_Window* win);
diff --git a/src/drivers/Android/Fl_Android_Screen_Driver.cxx b/src/drivers/Android/Fl_Android_Screen_Driver.cxx
index 4a3f8484d..43ad41148 100644
--- a/src/drivers/Android/Fl_Android_Screen_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_Screen_Driver.cxx
@@ -38,22 +38,6 @@ void (*fl_lock_function)() = nothing;
static void timer_do_callback(int timerIndex);
-#if 0
-
-// these are set by Fl::args() and override any system colors: from Fl_get_system_colors.cxx
-extern const char *fl_fg;
-extern const char *fl_bg;
-extern const char *fl_bg2;
-// end of extern additions workaround
-
-
-#if !defined(HMONITOR_DECLARED) && (_WIN32_WINNT < 0x0500)
-# define COMPILE_MULTIMON_STUBS
-# include <multimon.h>
-#endif // !HMONITOR_DECLARED && _WIN32_WINNT < 0x0500
-
-#endif
-
/*
Creates a driver that manages all screen and display related calls.
@@ -67,6 +51,7 @@ Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver()
extern int fl_send_system_handlers(void *e);
+
int Fl_Android_Screen_Driver::handle_app_command()
{
// get the command
@@ -84,6 +69,7 @@ int Fl_Android_Screen_Driver::handle_app_command()
return 1;
}
+
int Fl_Android_Screen_Driver::handle_input_event()
{
AInputQueue *queue = Fl_Android_Application::input_event_queue();
@@ -112,135 +98,6 @@ int Fl_Android_Screen_Driver::handle_input_event()
}
-int Fl_Android_Screen_Driver::compose(int &del)
-{
- del = 0;
- return 1;
-}
-
-
-int Fl_Android_Screen_Driver::handle_keyboard_event(AInputQueue *queue, AInputEvent *event)
-{
-/*
-int32_t AKeyEvent_getAction (const AInputEvent *key_event)
- { AKEY_EVENT_ACTION_DOWN = 0, AKEY_EVENT_ACTION_UP = 1, AKEY_EVENT_ACTION_MULTIPLE = 2 }
-> Reading up on ACTION_MULTIPLE also explains how to deal with
-> special or sequences of characters:
-> "If the key code is not KEYCODE_UNKNOWN then the getRepeatCount()
-> method returns the number of times the given key code should be
-> executed. Otherwise, if the key code is KEYCODE_UNKNOWN, then this
-> is a sequence of characters as returned by getCharacters()."
-
-int32_t AKeyEvent_getFlags (const AInputEvent *key_event)
- {
- AKEY_EVENT_FLAG_WOKE_HERE = 0x1, AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2, AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4, AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8,
- AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10, AKEY_EVENT_FLAG_CANCELED = 0x20, AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40, AKEY_EVENT_FLAG_LONG_PRESS = 0x80,
- AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100, AKEY_EVENT_FLAG_TRACKING = 0x200, AKEY_EVENT_FLAG_FALLBACK = 0x400
-}
-
-int32_t AKeyEvent_getKeyCode (const AInputEvent *key_event)
- {
- AKEYCODE_UNKNOWN = 0, AKEYCODE_SOFT_LEFT = 1, AKEYCODE_SOFT_RIGHT = 2, AKEYCODE_HOME = 3,
- AKEYCODE_BACK = 4, AKEYCODE_CALL = 5, AKEYCODE_ENDCALL = 6, AKEYCODE_0 = 7,
- AKEYCODE_1 = 8, AKEYCODE_2 = 9, AKEYCODE_3 = 10, AKEYCODE_4 = 11,
- AKEYCODE_5 = 12, AKEYCODE_6 = 13, AKEYCODE_7 = 14, AKEYCODE_8 = 15,
- AKEYCODE_9 = 16, AKEYCODE_STAR = 17, AKEYCODE_POUND = 18, AKEYCODE_DPAD_UP = 19,
- AKEYCODE_DPAD_DOWN = 20, AKEYCODE_DPAD_LEFT = 21, AKEYCODE_DPAD_RIGHT = 22, AKEYCODE_DPAD_CENTER = 23,
- AKEYCODE_VOLUME_UP = 24, AKEYCODE_VOLUME_DOWN = 25, AKEYCODE_POWER = 26, AKEYCODE_CAMERA = 27,
- AKEYCODE_CLEAR = 28, AKEYCODE_A = 29, AKEYCODE_B = 30, AKEYCODE_C = 31,
- AKEYCODE_D = 32, AKEYCODE_E = 33, AKEYCODE_F = 34, AKEYCODE_G = 35, ...
-
-int32_t AKeyEvent_getScanCode (const AInputEvent *key_event)
- { AKEY_STATE_UNKNOWN = -1, AKEY_STATE_UP = 0, AKEY_STATE_DOWN = 1, AKEY_STATE_VIRTUAL = 2 }
-
-int32_t AKeyEvent_getMetaState (const AInputEvent *key_event)
- {
- AMETA_NONE = 0, AMETA_ALT_ON = 0x02, AMETA_ALT_LEFT_ON = 0x10, AMETA_ALT_RIGHT_ON = 0x20,
- AMETA_SHIFT_ON = 0x01, AMETA_SHIFT_LEFT_ON = 0x40, AMETA_SHIFT_RIGHT_ON = 0x80, AMETA_SYM_ON = 0x04,
- AMETA_FUNCTION_ON = 0x08, AMETA_CTRL_ON = 0x1000, AMETA_CTRL_LEFT_ON = 0x2000, AMETA_CTRL_RIGHT_ON = 0x4000,
- AMETA_META_ON = 0x10000, AMETA_META_LEFT_ON = 0x20000, AMETA_META_RIGHT_ON = 0x40000, AMETA_CAPS_LOCK_ON = 0x100000,
- AMETA_NUM_LOCK_ON = 0x200000, AMETA_SCROLL_LOCK_ON = 0x400000
-}
-
-int32_t AKeyEvent_getRepeatCount (const AInputEvent *key_event)
-int64_t AKeyEvent_getDownTime (const AInputEvent *key_event)
-int64_t AKeyEvent_getEventTime (const AInputEvent *key_event)
-*/
- Fl_Android_Application::log_i("Key event: action=%d keyCode=%d metaState=0x%x scanCode=%d",
- AKeyEvent_getAction(event),
- AKeyEvent_getKeyCode(event),
- AKeyEvent_getMetaState(event),
- AKeyEvent_getScanCode(event));
-
- auto keyAction = AKeyEvent_getAction(event);
- if (keyAction==AKEY_EVENT_ACTION_MULTIPLE) {
- if (AKeyEvent_getKeyCode(event)==AKEYCODE_UNKNOWN) {
- // characters are in getCharacters()
- // String class KeyEvent::getCharacters() [Java]
- // is there a way to get the true Java event somehow?
- // override dispatchKeyEvent(android.view.KeyEvent event)
- } 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, "<init>",
- "(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();
-
- static char buf[8];
- int len = fl_utf8encode(unicodeKey, buf);
- if (len >= 0 && len < 8)
- buf[len] = 0;
- else
- buf[0] = 0;
- Fl_Android_Application::log_i("Unicode: %d Text: %s", unicodeKey, buf);
-
- 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;
- Fl::handle(FL_KEYBOARD, win);
- }
- }
-
- return 0;
-}
-
-
int Fl_Android_Screen_Driver::handle_mouse_event(AInputQueue *queue, AInputEvent *event)
{
int ex = Fl::e_x_root = (int)(AMotionEvent_getX(event, 0) * 600 /
@@ -304,7 +161,6 @@ int Fl_Android_Screen_Driver::handle_mouse_event(AInputQueue *queue, AInputEvent
*/
int Fl_Android_Screen_Driver::handle_queued_events(double time_to_wait)
{
- AInputQueue *queue = Fl_Android_Application::input_event_queue();
int ret = 0;
// Read all pending events.
int ident;
@@ -414,9 +270,9 @@ void Fl_Android_Screen_Driver::flush()
}
}
-
// ---- timers -----------------------------------------------------------------
+
struct TimerData
{
timer_t handle;
@@ -561,122 +417,6 @@ void Fl_Android_Screen_Driver::remove_timeout(Fl_Timeout_Handler cb, void *data)
}
-// ---- keyboard ---------------------------------------------------------------
-
-
-void Fl_Android_Screen_Driver::request_keyboard()
-{
- if (pKeyboardCount==0) {
- /*
- 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;
-
- JavaVM* lJavaVM = Fl_Android_Application::get_activity()->vm;
- JNIEnv* lJNIEnv = Fl_Android_Application::get_activity()->env;
-
- 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);
-
- // 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);
-
- // Runs getSystemService(Context.INPUT_METHOD_SERVICE).
- jclass ClassInputMethodManager = lJNIEnv->FindClass(
- "android/view/inputmethod/InputMethodManager");
- jmethodID MethodGetSystemService = lJNIEnv->GetMethodID(
- ClassNativeActivity, "getSystemService",
- "(Ljava/lang/String;)Ljava/lang/Object;");
- jobject lInputMethodManager = lJNIEnv->CallObjectMethod(
- lNativeActivity, MethodGetSystemService,
- INPUT_METHOD_SERVICE);
-
- // Runs getWindow().getDecorView().
- jmethodID MethodGetWindow = lJNIEnv->GetMethodID(
- ClassNativeActivity, "getWindow",
- "()Landroid/view/Window;");
- jobject lWindow = lJNIEnv->CallObjectMethod(lNativeActivity,
- MethodGetWindow);
- jclass ClassWindow = lJNIEnv->FindClass(
- "android/view/Window");
- jmethodID MethodGetDecorView = lJNIEnv->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();
- }
-
- }
- pKeyboardCount++;
-}
-
-
-void Fl_Android_Screen_Driver::release_keyboard()
-{
- pKeyboardCount--;
- if (pKeyboardCount==0) {
- ANativeActivity_hideSoftInput(Fl_Android_Application::get_activity(),
- ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS);
- }
-}
-
-
-
//
// End of "$Id$".
//
diff --git a/src/drivers/Android/Fl_Android_Screen_Keyboard.cxx b/src/drivers/Android/Fl_Android_Screen_Keyboard.cxx
new file mode 100644
index 000000000..341f48238
--- /dev/null
+++ b/src/drivers/Android/Fl_Android_Screen_Keyboard.cxx
@@ -0,0 +1,280 @@
+//
+// "$Id$"
+//
+// Android screen interface for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2018 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+
+#include "../../config_lib.h"
+#include "Fl_Android_Screen_Driver.H"
+#include "Fl_Android_Application.H"
+#include "Fl_Android_Graphics_Font.H"
+#include <FL/Fl.H>
+#include <FL/platform.H>
+#include <FL/Fl_Graphics_Driver.H>
+#include <FL/Fl_RGB_Image.H>
+#include <FL/fl_ask.H>
+#include <stdio.h>
+#include <errno.h>
+#include <math.h>
+
+
+
+
+int Fl_Android_Screen_Driver::compose(int &del)
+{
+ del = 0;
+ return 1;
+}
+
+
+int Fl_Android_Screen_Driver::handle_keyboard_event(AInputQueue *queue, AInputEvent *event)
+{
+/*
+int32_t AKeyEvent_getAction (const AInputEvent *key_event)
+ { AKEY_EVENT_ACTION_DOWN = 0, AKEY_EVENT_ACTION_UP = 1, AKEY_EVENT_ACTION_MULTIPLE = 2 }
+> Reading up on ACTION_MULTIPLE also explains how to deal with
+> special or sequences of characters:
+> "If the key code is not KEYCODE_UNKNOWN then the getRepeatCount()
+> method returns the number of times the given key code should be
+> executed. Otherwise, if the key code is KEYCODE_UNKNOWN, then this
+> is a sequence of characters as returned by getCharacters()."
+
+int32_t AKeyEvent_getFlags (const AInputEvent *key_event)
+ {
+ AKEY_EVENT_FLAG_WOKE_HERE = 0x1, AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2, AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4, AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8,
+ AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10, AKEY_EVENT_FLAG_CANCELED = 0x20, AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40, AKEY_EVENT_FLAG_LONG_PRESS = 0x80,
+ AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100, AKEY_EVENT_FLAG_TRACKING = 0x200, AKEY_EVENT_FLAG_FALLBACK = 0x400
+}
+
+int32_t AKeyEvent_getKeyCode (const AInputEvent *key_event)
+ {
+ AKEYCODE_UNKNOWN = 0, AKEYCODE_SOFT_LEFT = 1, AKEYCODE_SOFT_RIGHT = 2, AKEYCODE_HOME = 3,
+ AKEYCODE_BACK = 4, AKEYCODE_CALL = 5, AKEYCODE_ENDCALL = 6, AKEYCODE_0 = 7,
+ AKEYCODE_1 = 8, AKEYCODE_2 = 9, AKEYCODE_3 = 10, AKEYCODE_4 = 11,
+ AKEYCODE_5 = 12, AKEYCODE_6 = 13, AKEYCODE_7 = 14, AKEYCODE_8 = 15,
+ AKEYCODE_9 = 16, AKEYCODE_STAR = 17, AKEYCODE_POUND = 18, AKEYCODE_DPAD_UP = 19,
+ AKEYCODE_DPAD_DOWN = 20, AKEYCODE_DPAD_LEFT = 21, AKEYCODE_DPAD_RIGHT = 22, AKEYCODE_DPAD_CENTER = 23,
+ AKEYCODE_VOLUME_UP = 24, AKEYCODE_VOLUME_DOWN = 25, AKEYCODE_POWER = 26, AKEYCODE_CAMERA = 27,
+ AKEYCODE_CLEAR = 28, AKEYCODE_A = 29, AKEYCODE_B = 30, AKEYCODE_C = 31,
+ AKEYCODE_D = 32, AKEYCODE_E = 33, AKEYCODE_F = 34, AKEYCODE_G = 35, ...
+
+int32_t AKeyEvent_getScanCode (const AInputEvent *key_event)
+ { AKEY_STATE_UNKNOWN = -1, AKEY_STATE_UP = 0, AKEY_STATE_DOWN = 1, AKEY_STATE_VIRTUAL = 2 }
+
+int32_t AKeyEvent_getMetaState (const AInputEvent *key_event)
+ {
+ AMETA_NONE = 0, AMETA_ALT_ON = 0x02, AMETA_ALT_LEFT_ON = 0x10, AMETA_ALT_RIGHT_ON = 0x20,
+ AMETA_SHIFT_ON = 0x01, AMETA_SHIFT_LEFT_ON = 0x40, AMETA_SHIFT_RIGHT_ON = 0x80, AMETA_SYM_ON = 0x04,
+ AMETA_FUNCTION_ON = 0x08, AMETA_CTRL_ON = 0x1000, AMETA_CTRL_LEFT_ON = 0x2000, AMETA_CTRL_RIGHT_ON = 0x4000,
+ AMETA_META_ON = 0x10000, AMETA_META_LEFT_ON = 0x20000, AMETA_META_RIGHT_ON = 0x40000, AMETA_CAPS_LOCK_ON = 0x100000,
+ AMETA_NUM_LOCK_ON = 0x200000, AMETA_SCROLL_LOCK_ON = 0x400000
+}
+
+int32_t AKeyEvent_getRepeatCount (const AInputEvent *key_event)
+int64_t AKeyEvent_getDownTime (const AInputEvent *key_event)
+int64_t AKeyEvent_getEventTime (const AInputEvent *key_event)
+*/
+ Fl_Android_Application::log_i("Key event: action=%d keyCode=%d metaState=0x%x scanCode=%d",
+ AKeyEvent_getAction(event),
+ AKeyEvent_getKeyCode(event),
+ AKeyEvent_getMetaState(event),
+ AKeyEvent_getScanCode(event));
+
+ auto keyAction = AKeyEvent_getAction(event);
+ if (keyAction==AKEY_EVENT_ACTION_MULTIPLE) {
+ if (AKeyEvent_getKeyCode(event)==AKEYCODE_UNKNOWN) {
+ // characters are in getCharacters()
+ // String class KeyEvent::getCharacters() [Java]
+ // is there a way to get the true Java event somehow?
+ // override dispatchKeyEvent(android.view.KeyEvent event)
+ } 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, "<init>",
+ "(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();
+
+ static char buf[8];
+ int len = fl_utf8encode(unicodeKey, buf);
+ if (len >= 0 && len < 8)
+ buf[len] = 0;
+ else
+ buf[0] = 0;
+ Fl_Android_Application::log_i("Unicode: %d Text: %s", unicodeKey, buf);
+
+ 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;
+ Fl::handle(FL_KEYBOARD, win);
+ }
+ }
+
+ return 0;
+}
+
+
+void Fl_Android_Screen_Driver::request_keyboard()
+{
+ if (pKeyboardCount==0) {
+ /*
+ 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;
+
+ JavaVM* lJavaVM = Fl_Android_Application::get_activity()->vm;
+ JNIEnv* lJNIEnv = Fl_Android_Application::get_activity()->env;
+
+ 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);
+
+ // 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);
+
+ // Runs getSystemService(Context.INPUT_METHOD_SERVICE).
+ jclass ClassInputMethodManager = lJNIEnv->FindClass(
+ "android/view/inputmethod/InputMethodManager");
+ jmethodID MethodGetSystemService = lJNIEnv->GetMethodID(
+ ClassNativeActivity, "getSystemService",
+ "(Ljava/lang/String;)Ljava/lang/Object;");
+ jobject lInputMethodManager = lJNIEnv->CallObjectMethod(
+ lNativeActivity, MethodGetSystemService,
+ INPUT_METHOD_SERVICE);
+
+ // Runs getWindow().getDecorView().
+ jmethodID MethodGetWindow = lJNIEnv->GetMethodID(
+ ClassNativeActivity, "getWindow",
+ "()Landroid/view/Window;");
+ jobject lWindow = lJNIEnv->CallObjectMethod(lNativeActivity,
+ MethodGetWindow);
+ jclass ClassWindow = lJNIEnv->FindClass(
+ "android/view/Window");
+ jmethodID MethodGetDecorView = lJNIEnv->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();
+ }
+
+ }
+ pKeyboardCount++;
+}
+
+
+void Fl_Android_Screen_Driver::release_keyboard()
+{
+ pKeyboardCount--;
+ if (pKeyboardCount==0) {
+ ANativeActivity_hideSoftInput(Fl_Android_Application::get_activity(),
+ ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS);
+ }
+}
+
+
+
+//
+// End of "$Id$".
+//