diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2018-03-07 22:12:34 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2018-03-07 22:12:34 +0000 |
| commit | 2e5b983f4b3da87bf28319fe7ab99bb6206f0411 (patch) | |
| tree | 34475588f4943d9ed379b711887d873d087c79b0 | |
| parent | f058d3a99c396f21d6e17f201682462da1d305cc (diff) | |
Android: moved all Android code from the main app into the driver system. All non-driver-FLTK code and main app are now Android-free.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12719 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx | 166 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Application.H | 1 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Application.cxx | 12 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Screen_Driver.H | 5 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Screen_Driver.cxx | 142 |
5 files changed, 114 insertions, 212 deletions
diff --git a/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx b/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx index b3204cdfd..3c99fb148 100644 --- a/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx +++ b/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx @@ -15,175 +15,21 @@ * */ -//#include <android_native_app_glue.h> -#include <src/drivers/Android/Fl_Android_Application.H> -#include <src/drivers/Android/Fl_Android_Screen_Driver.H> - #include <FL/Fl_Window.H> #include <FL/Fl_Button.H> #include <FL/Enumerations.H> + Fl_Window *win; Fl_Button *btn; -#include <errno.h> -#include <jni.h> -#include <sys/time.h> -#include <time.h> -#include <android/log.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#define LOG_TAG "HelloFLTK" -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) -#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) - -/* Set to 1 to enable debug log traces. */ -#define DEBUG 0 - -// ---------------------------------------------------------------------- - -struct engine { - int animating; -}; - -struct engine engine = { 0 }; - -#if 0 -static void engine_draw_frame() -{ - //if (Fl_Android_Application::lock_screen()) { - //Fl::damage(FL_DAMAGE_ALL); - //win->redraw(); - Fl::flush(); - // Fl_Android_Application::unlock_and_post_screen(); - //} -} - #endif - -static void engine_term_display() { - engine.animating = 0; -} - -static int32_t engine_handle_input(AInputEvent* event) { - if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { - engine.animating = 1; - Fl::e_x = Fl::e_x_root = AMotionEvent_getX(event, 0) * 600 / ANativeWindow_getWidth(Fl_Android_Application::native_window()); - Fl::e_y = Fl::e_y_root = AMotionEvent_getY(event, 0) * 800 / ANativeWindow_getHeight(Fl_Android_Application::native_window()); - Fl::e_state = FL_BUTTON1; - Fl::e_keysym = FL_Button+1; - if (AMotionEvent_getAction(event)==AMOTION_EVENT_ACTION_DOWN) { - Fl::e_is_click = 1; - Fl::handle(FL_PUSH, Fl::first_window()); - LOGE("Mouse push %d at %d, %d", Fl::event_button(), Fl::event_x(), Fl::event_y()); - } else if (AMotionEvent_getAction(event)==AMOTION_EVENT_ACTION_MOVE) { - Fl::handle(FL_DRAG, Fl::first_window()); - } else if (AMotionEvent_getAction(event)==AMOTION_EVENT_ACTION_UP) { - Fl::e_state = 0; - Fl::handle(FL_RELEASE, Fl::first_window()); - } - return 1; - } else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) { - LOGI("Key event: action=%d keyCode=%d metaState=0x%x", - AKeyEvent_getAction(event), - AKeyEvent_getKeyCode(event), - AKeyEvent_getMetaState(event)); - } - - return 0; -} - -static void engine_handle_cmd(int32_t cmd) { - static int32_t format = WINDOW_FORMAT_RGB_565; - switch (cmd) { - case APP_CMD_INIT_WINDOW: - if (Fl_Android_Application::native_window() != NULL) { - // fill_plasma() assumes 565 format, get it here - format = ANativeWindow_getFormat(Fl_Android_Application::native_window()); - ANativeWindow_setBuffersGeometry(Fl_Android_Application::native_window(), -#if 1 - 600, //ANativeWindow_getWidth(app->window), - 800, //ANativeWindow_getHeight(app->window), -#else - ANativeWindow_getWidth(app->window), - ANativeWindow_getHeight(app->window), -#endif - WINDOW_FORMAT_RGB_565); - Fl::damage(FL_DAMAGE_EXPOSE); - } - break; - case APP_CMD_TERM_WINDOW: - engine_term_display(); - ANativeWindow_setBuffersGeometry(Fl_Android_Application::native_window(), -#if 1 - 600, //ANativeWindow_getWidth(app->window), - 800, //ANativeWindow_getHeight(app->window), -#else - ANativeWindow_getWidth(app->window), - ANativeWindow_getHeight(app->window), -#endif - format); - break; - case APP_CMD_LOST_FOCUS: - engine.animating = 0; - //engine_draw_frame(); - break; - default: break; - } -} - - int main(int argc, char **argv) { - Fl_Android_Application::log_e("App path is %s", argv[0]); - - memset(&engine, 0, sizeof(engine)); - Fl_Android_Application::set_on_app_cmd(engine_handle_cmd); - Fl_Android_Application::set_on_input_event(engine_handle_input); - - win = new Fl_Window(10, 10, 600, 400, "Hallo"); - btn = new Fl_Button(190, 200, 280, 35, "Hello, Android!"); - btn->color(FL_LIGHT2); - win->show(argc, argv); - int x; - if (Fl::damage()) - x = 0; - if (win->damage()) - x = 2; - //Fl::damage(FL_DAMAGE_ALL); - //win->redraw(); - - - // loop waiting for stuff to do. - - while (1) { - // Read all pending events. - int ident; - int events; - struct android_poll_source* source; - - // If not animating, we will block forever waiting for events. - // If animating, we loop until all events are read, then continue - // to draw the next frame of animation. - while ((ident=ALooper_pollAll(Fl::damage() ? 0 : -1, NULL, &events, - (void**)&source)) >= 0) { + win = new Fl_Window(10, 10, 600, 400, "Hallo"); + btn = new Fl_Button(190, 200, 280, 35, "Hello, Android!"); + btn->color(FL_LIGHT2); + win->show(argc, argv); - // Process this event. - if (source != NULL) { - source->process(source); - } + Fl::run(); - // Check if we are exiting. - if (Fl_Android_Application::destroy_requested() != 0) { - LOGI("Engine thread destroy requested!"); - engine_term_display(); - return 0; - } - } - Fl::flush(); - } return 0; } diff --git a/src/drivers/Android/Fl_Android_Application.H b/src/drivers/Android/Fl_Android_Application.H index b141a7e7f..004238371 100644 --- a/src/drivers/Android/Fl_Android_Application.H +++ b/src/drivers/Android/Fl_Android_Application.H @@ -119,6 +119,7 @@ public: static int8_t read_cmd(); static void pre_exec_cmd(int8_t cmd); static void post_exec_cmd(int8_t cmd); + static AInputQueue *input_event_queue() { return pInputQueue; } static inline ANativeWindow *native_window() { return pNativeWindow; } static inline ANativeWindow_Buffer &graphics_buffer() { return pApplicationWindowBuffer; } diff --git a/src/drivers/Android/Fl_Android_Application.cxx b/src/drivers/Android/Fl_Android_Application.cxx index 890d175a4..8794ea2b1 100644 --- a/src/drivers/Android/Fl_Android_Application.cxx +++ b/src/drivers/Android/Fl_Android_Application.cxx @@ -235,10 +235,18 @@ void Fl_Android_Application::pre_exec_cmd(int8_t cmd) case APP_CMD_INIT_WINDOW: LOGV("APP_CMD_INIT_WINDOW\n"); + // tell the main thread that we received the window handle pthread_mutex_lock(&pMutex); pNativeWindow = pPendingWindow; pthread_cond_broadcast(&pCond); pthread_mutex_unlock(&pMutex); + // change the format of the buffers to match our needs + // FIXME: current default screen size and format is 600x800xRGB565 + ANativeWindow_setBuffersGeometry(pNativeWindow, + 600, + 800, + WINDOW_FORMAT_RGB_565); + // tell FLTK that the buffer is available now Fl_Android_Window_Driver::expose_all(); break; @@ -394,13 +402,17 @@ bool Fl_Android_Application::copy_screen() bool ret = false; if (lock_screen()) { +#if 0 + // screen activity viewer static int i = 0; fl_color( (i&1) ? FL_RED : FL_GREEN); fl_rectf(i*10, 600+i*10, 50, 50); i++; if (i>10) i = 0; +#endif // TODO: there are endless possibilities to optimize the following code + // We are wasting time by copying the entire screen contents at every dirty frame // We can identify previously written buffers and copy only those pixels // that actually changed. const uint16_t *src = (uint16_t*)pApplicationWindowBuffer.bits; diff --git a/src/drivers/Android/Fl_Android_Screen_Driver.H b/src/drivers/Android/Fl_Android_Screen_Driver.H index 7948c906f..32ae04899 100644 --- a/src/drivers/Android/Fl_Android_Screen_Driver.H +++ b/src/drivers/Android/Fl_Android_Screen_Driver.H @@ -26,6 +26,7 @@ #define FL_ANDROID_SCREEN_DRIVER_H #include <FL/Fl_Screen_Driver.H> +#include <android/input.h> //#include <windows.h> extern void (*fl_unlock_function)(); @@ -39,6 +40,10 @@ class FL_EXPORT Fl_Android_Screen_Driver : public Fl_Screen_Driver { private: int handle_queued_events(double time_to_wait); + int handle_app_command(); + int handle_input_event(); + int handle_keyboard_event(AInputEvent*); + int handle_mouse_event(AInputEvent*); #if 0 diff --git a/src/drivers/Android/Fl_Android_Screen_Driver.cxx b/src/drivers/Android/Fl_Android_Screen_Driver.cxx index 0a187ca9c..9156d8c83 100644 --- a/src/drivers/Android/Fl_Android_Screen_Driver.cxx +++ b/src/drivers/Android/Fl_Android_Screen_Driver.cxx @@ -59,65 +59,103 @@ Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver() return new Fl_Android_Screen_Driver(); } -int Fl_Android_Screen_Driver::handle_queued_events(double time_to_wait) +int Fl_Android_Screen_Driver::handle_app_command() { -/* - int ALooper_pollAll ( int timeoutMillis, - int * outFd, - int * outEvents, - void ** outData - ) - - struct engine engine; - - memset(&engine, 0, sizeof(engine)); - state->userData = &engine; - state->onAppCmd = engine_handle_cmd; - state->onInputEvent = engine_handle_input; - engine.app = state; - - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - start_ms = (((int64_t)now.tv_sec)*1000000000LL + now.tv_nsec)/1000000; - - win = new Fl_Window(10, 10, 600, 400, "Hallo"); - btn = new Fl_Button(190, 200, 280, 35, "Hello, Android!"); - win->show(); - - - // loop waiting for stuff to do. - - while (1) { - // Read all pending events. - int ident; - int events; - struct android_poll_source* source; - - // If not animating, we will block forever waiting for events. - // If animating, we loop until all events are read, then continue - // to draw the next frame of animation. - while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events, - (void**)&source)) >= 0) { - - // Process this event. - if (source != NULL) { - source->process(state, source); - } + int8_t cmd = Fl_Android_Application::read_cmd(); + Fl_Android_Application::pre_exec_cmd(cmd); + // TODO: call Fl::handle() with event parametrs set + Fl_Android_Application::post_exec_cmd(cmd); + return 1; +} - // Check if we are exiting. - if (state->destroyRequested != 0) { - LOGI("Engine thread destroy requested!"); - engine_term_display(&engine); - return; +int Fl_Android_Screen_Driver::handle_input_event() +{ + AInputQueue *queue = Fl_Android_Application::input_event_queue(); + AInputEvent *event = NULL; + + if (AInputQueue_getEvent(queue, &event) >= 0) { + if (AInputQueue_preDispatchEvent(queue, event)==0) { + int consumed = 0; + switch (AInputEvent_getType(event)) { + case AINPUT_EVENT_TYPE_KEY: + consumed = handle_keyboard_event(event); + break; + case AINPUT_EVENT_TYPE_MOTION: + consumed = handle_mouse_event(event); + break; + default: + // don;t do anything. There may be additional event types in the future + break; } + // TODO: handle all events here + AInputQueue_finishEvent(queue, event, consumed); } + } + return 0; +} - if (engine.animating) { - engine_draw_frame(&engine); +int Fl_Android_Screen_Driver::handle_keyboard_event(AInputEvent *event) +{ + Fl_Android_Application::log_i("Key event: action=%d keyCode=%d metaState=0x%x", + AKeyEvent_getAction(event), + AKeyEvent_getKeyCode(event), + AKeyEvent_getMetaState(event)); + return 0; +} + +int Fl_Android_Screen_Driver::handle_mouse_event(AInputEvent *event) +{ + Fl::e_x = Fl::e_x_root = AMotionEvent_getX(event, 0) * 600 / + ANativeWindow_getWidth(Fl_Android_Application::native_window()); + Fl::e_y = Fl::e_y_root = AMotionEvent_getY(event, 0) * 800 / + ANativeWindow_getHeight(Fl_Android_Application::native_window()); + Fl::e_state = FL_BUTTON1; + Fl::e_keysym = FL_Button + 1; + if (AMotionEvent_getAction(event) == AMOTION_EVENT_ACTION_DOWN) { + Fl::e_is_click = 1; + Fl::handle(FL_PUSH, Fl::first_window()); + Fl_Android_Application::log_i("Mouse push %d at %d, %d", Fl::event_button(), Fl::event_x(), + Fl::event_y()); + } else if (AMotionEvent_getAction(event) == AMOTION_EVENT_ACTION_MOVE) { + Fl::handle(FL_DRAG, Fl::first_window()); + } else if (AMotionEvent_getAction(event) == AMOTION_EVENT_ACTION_UP) { + Fl::e_state = 0; + Fl::handle(FL_RELEASE, Fl::first_window()); + } + return 1; +} + +/** + * Handle all events in the even queue. + * + * FIXME: what should this function return? + * + * @param time_to_wait + * @return we do not know + */ +int Fl_Android_Screen_Driver::handle_queued_events(double time_to_wait) +{ + int ret = 0; + // Read all pending events. + int ident; + int events; + struct android_poll_source *source; + + for (;;) { + ident = ALooper_pollAll(Fl::damage() ? 0 : -1, NULL, &events, (void **) &source); + switch (ident) { + // FIXME: ALOOPER_POLL_WAKE = -1, ALOOPER_POLL_CALLBACK = -2, ALOOPER_POLL_TIMEOUT = -3, ALOOPER_POLL_ERROR = -4 + case LOOPER_ID_MAIN: + ret = handle_app_command(); + break; + case LOOPER_ID_INPUT: + ret = handle_input_event(); + break; + case -3: return ret; + default: return ret; } } - */ - return -1; + return ret; } |
