mirror of
https://github.com/fltk/fltk.git
synced 2026-05-22 23:37:02 +08:00
Android version compiles, links, launches, and receives commands.
Still need to implement window creation and drawing. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11349 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
@@ -1,2 +1,4 @@
|
||||
APP_ABI := all
|
||||
#APP_ABI := armeabi armeabi-v7a mips x64
|
||||
#APP_ABI := all
|
||||
APP_ABI := armeabi-v7a
|
||||
APP_PLATFORM := android-10
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -20,11 +20,198 @@
|
||||
#include "../../config_lib.h"
|
||||
#include "Fl_PicoAndroid_Screen_Driver.H"
|
||||
|
||||
#include <FL/Fl_Window_Driver.H>
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES/gl.h>
|
||||
|
||||
//#define __APPLE__
|
||||
//#include <SDL2/SDL.h>
|
||||
//#undef __APPLE__
|
||||
#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__))
|
||||
|
||||
|
||||
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()
|
||||
@@ -71,17 +258,60 @@ double Fl_PicoAndroid_Screen_Driver::wait(double time_to_wait)
|
||||
// break;
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// 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!
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user