diff options
Diffstat (limited to 'src/drivers/PicoAndroid')
3 files changed, 260 insertions, 8 deletions
diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.H b/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.H index f0e0efdd0..e9b10fb5a 100644 --- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.H +++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.H @@ -27,13 +27,31 @@ #include "../Pico/Fl_Pico_Screen_Driver.H" +#include <jni.h> +#include <errno.h> + +#include <android/sensor.h> +#include <android/log.h> +#include <android_native_app_glue.h> + + class FL_EXPORT Fl_PicoAndroid_Screen_Driver : public Fl_Pico_Screen_Driver { + struct android_app* pApp; + + static void handleAppCmdCB(struct android_app* app, int32_t cmd); + void handleAppCmd(struct android_app* app, int32_t cmd); + static int32_t handleInputEventCB(struct android_app* app, AInputEvent* event); + int32_t handleInputEvent(struct android_app* app, AInputEvent* event); + public: Fl_PicoAndroid_Screen_Driver(); virtual ~Fl_PicoAndroid_Screen_Driver(); virtual double wait(double time_to_wait); + +public: + void android_main(struct android_app* state); }; diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.cxx b/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.cxx index ec134f5cb..670c998f9 100644 --- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.cxx +++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Screen_Driver.cxx @@ -20,11 +20,198 @@ #include "../../config_lib.h" #include "Fl_PicoAndroid_Screen_Driver.H" +#include <EGL/egl.h> +#include <GLES/gl.h> + +#include <FL/x.H> +#include <FL/Fl.H> +#include <FL/Fl_Window.H> +#include <FL/Fl_Double_Window.H> #include <FL/Fl_Window_Driver.H> +#include <FL/Fl_Image_Surface.H> +#include <FL/Fl_Graphics_Driver.H> + + +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__)) +#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__)) -//#define __APPLE__ -//#include <SDL2/SDL.h> -//#undef __APPLE__ + +void Fl_PicoAndroid_Screen_Driver::handleAppCmdCB(struct android_app* app, int32_t cmd) +{ + Fl_PicoAndroid_Screen_Driver *This = (Fl_PicoAndroid_Screen_Driver*)(app->userData); + This->handleAppCmd(app, cmd); +} + + +void Fl_PicoAndroid_Screen_Driver::handleAppCmd(struct android_app* app, int32_t cmd) +{ + LOGI("CMD %d", cmd); +// struct engine* engine = (struct engine*)app->userData; + switch (cmd) { + case APP_CMD_SAVE_STATE: + // The system has asked us to save our current state. Do so. +// engine->app->savedState = malloc(sizeof(struct saved_state)); +// *((struct saved_state*)engine->app->savedState) = engine->state; +// engine->app->savedStateSize = sizeof(struct saved_state); + break; + case APP_CMD_INIT_WINDOW: + // The window is being shown, get it ready. +// if (engine->app->window != NULL) { +// engine_init_display(engine); +// engine_draw_frame(engine); +// } + break; + case APP_CMD_TERM_WINDOW: + // The window is being hidden or closed, clean it up. +// engine_term_display(engine); + break; + case APP_CMD_GAINED_FOCUS: + // When our app gains focus, we start monitoring the accelerometer. +// if (engine->accelerometerSensor != NULL) { +// ASensorEventQueue_enableSensor(engine->sensorEventQueue, +// engine->accelerometerSensor); +// // We'd like to get 60 events per second (in us). +// ASensorEventQueue_setEventRate(engine->sensorEventQueue, +// engine->accelerometerSensor, (1000L/60)*1000); +// } + break; + case APP_CMD_LOST_FOCUS: + // When our app loses focus, we stop monitoring the accelerometer. + // This is to avoid consuming battery while not being used. +// if (engine->accelerometerSensor != NULL) { +// ASensorEventQueue_disableSensor(engine->sensorEventQueue, +// engine->accelerometerSensor); +// } +// // Also stop animating. +// engine->animating = 0; +// engine_draw_frame(engine); + break; + } +} + + +int32_t Fl_PicoAndroid_Screen_Driver::handleInputEventCB(struct android_app* app, AInputEvent* event) +{ + Fl_PicoAndroid_Screen_Driver *This = (Fl_PicoAndroid_Screen_Driver*)(app->userData); + This->handleInputEvent(app, event); +} + + +int32_t Fl_PicoAndroid_Screen_Driver::handleInputEvent(struct android_app* app, AInputEvent* event) +{ + if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { + int x = AMotionEvent_getX(event, 0); + int y = AMotionEvent_getY(event, 0); + LOGI("Motion at %d, %d", x, y); + return 1; + } + return 0; +} + + +extern int main(int argc, const char **argv); + +void android_main(struct android_app* state) +{ + LOGI("Android Main call"); + Fl_PicoAndroid_Screen_Driver *This = (Fl_PicoAndroid_Screen_Driver*)Fl::screen_driver(); + This->android_main(state); + static const char *argv[1] = { "native-activity" }; + main(1, argv); +} + +/** + * This is the main entry point of a native application that is using + * android_native_app_glue. It runs in its own thread, with its own + * event loop for receiving input events and doing other things. + */ +void Fl_PicoAndroid_Screen_Driver::android_main(struct android_app* state) +{ + app_dummy(); + + pApp = state; + pApp->userData = this; + pApp->onAppCmd = handleAppCmdCB; + pApp->onInputEvent = handleInputEventCB; + + +#if 0 + struct engine engine; + + // Make sure glue isn't stripped. + app_dummy(); + + memset(&engine, 0, sizeof(engine)); + state->userData = &engine; + state->onAppCmd = engine_handle_cmd; + state->onInputEvent = engine_handle_input; + engine.app = state; + + // Prepare to monitor accelerometer + engine.sensorManager = ASensorManager_getInstance(); + engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, + ASENSOR_TYPE_ACCELEROMETER); + engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, + state->looper, LOOPER_ID_USER, NULL, NULL); + + if (state->savedState != NULL) { + // We are starting with a previous saved state; restore from it. + engine.state = *(struct saved_state*)state->savedState; + } + + // 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); + } + + // If a sensor has data, process it now. + if (ident == LOOPER_ID_USER) { + if (engine.accelerometerSensor != NULL) { + ASensorEvent event; + while (ASensorEventQueue_getEvents(engine.sensorEventQueue, + &event, 1) > 0) { + LOGI("accelerometer: x=%f y=%f z=%f", + event.acceleration.x, event.acceleration.y, + event.acceleration.z); + } + } + } + + // Check if we are exiting. + if (state->destroyRequested != 0) { + engine_term_display(&engine); + return; + } + } + + if (engine.animating) { + // Done with events; draw next animation frame. + engine.state.angle += .01f; + if (engine.state.angle > 1) { + engine.state.angle = 0; + } + + // Drawing is throttled to the screen update rate, so there + // is no need to do timing here. + engine_draw_frame(&engine); + } + } +#endif +} Fl_Screen_Driver* Fl_Screen_Driver::newScreenDriver() @@ -72,16 +259,59 @@ double Fl_PicoAndroid_Screen_Driver::wait(double time_to_wait) // // } // } + // 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. + // int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) + if ((ident=ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0) { + + // Process this event. + if (source != NULL) { + source->process(pApp, source); + } + + // If a sensor has data, process it now. +// if (ident == LOOPER_ID_USER) { +// if (engine.accelerometerSensor != NULL) { +// ASensorEvent event; +// while (ASensorEventQueue_getEvents(engine.sensorEventQueue, +// &event, 1) > 0) { +// LOGI("accelerometer: x=%f y=%f z=%f", +// event.acceleration.x, event.acceleration.y, +// event.acceleration.z); +// } +// } +// } + + // Check if we are exiting. +// if (state->destroyRequested != 0) { +// engine_term_display(&engine); +// return; +// } + } + +// if (engine.animating) { +// // Done with events; draw next animation frame. +// engine.state.angle += .01f; +// if (engine.state.angle > 1) { +// engine.state.angle = 0; +// } +// +// // Drawing is throttled to the screen update rate, so there +// // is no need to do timing here. +// engine_draw_frame(&engine); +// } +// } return 0.0; } -#include <FL/x.H> -#include <FL/Fl.H> -#include <FL/Fl_Image_Surface.H> -#include <FL/Fl_Double_Window.H> -#include <FL/Fl_Graphics_Driver.H> /* * The following code should not be here! diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx b/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx index fc0afc339..34001a695 100644 --- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx +++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Window_Driver.cxx @@ -19,7 +19,11 @@ #include "../../config_lib.h" #include "Fl_PicoAndroid_Window_Driver.H" + +#include <FL/x.H> #include <FL/Fl.H> +#include <FL/Fl_Window.H> +#include <FL/Fl_Window_Driver.H> Fl_Window_Driver *Fl_Window_Driver::newWindowDriver(Fl_Window *win) |
