Move android_main and CloseWindow() out of rcore

This commit is contained in:
michaelfiber 2023-09-14 13:14:54 -04:00
parent a0afba2de0
commit cc5249b82c
5 changed files with 271 additions and 184 deletions

View File

@ -418,190 +418,6 @@ const char *TextFormat(const char *text, ...); // Formatting of text with
//----------------------------------------------------------------------------------
// Module Functions Definition - Window and OpenGL Context Functions
//----------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID)
// To allow easier porting to android, we allow the user to define a
// main function which we call from android_main, defined by ourselves
extern int main(int argc, char *argv[]);
void android_main(struct android_app *app)
{
char arg0[] = "raylib"; // NOTE: argv[] are mutable
CORE.Android.app = app;
// NOTE: Return from main is ignored
(void)main(1, (char *[]) { arg0, NULL });
// Request to end the native activity
ANativeActivity_finish(app->activity);
// Android ALooper_pollAll() variables
int pollResult = 0;
int pollEvents = 0;
// Waiting for application events before complete finishing
while (!app->destroyRequested)
{
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void **)&CORE.Android.source)) >= 0)
{
if (CORE.Android.source != NULL) CORE.Android.source->process(app, CORE.Android.source);
}
}
}
// NOTE: Add this to header (if apps really need it)
struct android_app *GetAndroidApp(void)
{
return CORE.Android.app;
}
#endif
// Close window and unload OpenGL context
void CloseWindow(void)
{
#if defined(SUPPORT_GIF_RECORDING)
if (gifRecording)
{
MsfGifResult result = msf_gif_end(&gifState);
msf_gif_free(result);
gifRecording = false;
}
#endif
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
UnloadFontDefault(); // WARNING: Module required: rtext
#endif
rlglClose(); // De-init rlgl
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
glfwDestroyWindow(CORE.Window.handle);
glfwTerminate();
#endif
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
timeEndPeriod(1); // Restore time period
#endif
#if defined(PLATFORM_ANDROID)
// Close surface, context and display
if (CORE.Window.device != EGL_NO_DISPLAY)
{
eglMakeCurrent(CORE.Window.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (CORE.Window.surface != EGL_NO_SURFACE)
{
eglDestroySurface(CORE.Window.device, CORE.Window.surface);
CORE.Window.surface = EGL_NO_SURFACE;
}
if (CORE.Window.context != EGL_NO_CONTEXT)
{
eglDestroyContext(CORE.Window.device, CORE.Window.context);
CORE.Window.context = EGL_NO_CONTEXT;
}
eglTerminate(CORE.Window.device);
CORE.Window.device = EGL_NO_DISPLAY;
}
#endif
#if defined(PLATFORM_DRM)
if (CORE.Window.prevFB)
{
drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
CORE.Window.prevFB = 0;
}
if (CORE.Window.prevBO)
{
gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
CORE.Window.prevBO = NULL;
}
if (CORE.Window.gbmSurface)
{
gbm_surface_destroy(CORE.Window.gbmSurface);
CORE.Window.gbmSurface = NULL;
}
if (CORE.Window.gbmDevice)
{
gbm_device_destroy(CORE.Window.gbmDevice);
CORE.Window.gbmDevice = NULL;
}
if (CORE.Window.crtc)
{
if (CORE.Window.connector)
{
drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, CORE.Window.crtc->buffer_id,
CORE.Window.crtc->x, CORE.Window.crtc->y, &CORE.Window.connector->connector_id, 1, &CORE.Window.crtc->mode);
drmModeFreeConnector(CORE.Window.connector);
CORE.Window.connector = NULL;
}
drmModeFreeCrtc(CORE.Window.crtc);
CORE.Window.crtc = NULL;
}
if (CORE.Window.fd != -1)
{
close(CORE.Window.fd);
CORE.Window.fd = -1;
}
// Close surface, context and display
if (CORE.Window.device != EGL_NO_DISPLAY)
{
if (CORE.Window.surface != EGL_NO_SURFACE)
{
eglDestroySurface(CORE.Window.device, CORE.Window.surface);
CORE.Window.surface = EGL_NO_SURFACE;
}
if (CORE.Window.context != EGL_NO_CONTEXT)
{
eglDestroyContext(CORE.Window.device, CORE.Window.context);
CORE.Window.context = EGL_NO_CONTEXT;
}
eglTerminate(CORE.Window.device);
CORE.Window.device = EGL_NO_DISPLAY;
}
#endif
#if defined(PLATFORM_DRM)
// Wait for mouse and gamepad threads to finish before closing
// NOTE: Those threads should already have finished at this point
// because they are controlled by CORE.Window.shouldClose variable
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
// Close the evdev keyboard
if (CORE.Input.Keyboard.fd != -1)
{
close(CORE.Input.Keyboard.fd);
CORE.Input.Keyboard.fd = -1;
}
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{
if (CORE.Input.eventWorker[i].threadId)
{
pthread_join(CORE.Input.eventWorker[i].threadId, NULL);
}
}
if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
#endif
#if defined(SUPPORT_EVENTS_AUTOMATION)
RL_FREE(events);
#endif
CORE.Window.ready = false;
TRACELOG(LOG_INFO, "Window closed successfully");
}
// Check if KEY_ESCAPE pressed or Close icon pressed
bool WindowShouldClose(void)

View File

@ -1198,4 +1198,90 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
else CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0;
return 0;
}
// To allow easier porting to android, we allow the user to define a
// main function which we call from android_main, defined by ourselves
extern int main(int argc, char *argv[]);
void android_main(struct android_app *app)
{
char arg0[] = "raylib"; // NOTE: argv[] are mutable
CORE.Android.app = app;
// NOTE: Return from main is ignored
(void)main(1, (char *[]) { arg0, NULL });
// Request to end the native activity
ANativeActivity_finish(app->activity);
// Android ALooper_pollAll() variables
int pollResult = 0;
int pollEvents = 0;
// Waiting for application events before complete finishing
while (!app->destroyRequested)
{
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void **)&CORE.Android.source)) >= 0)
{
if (CORE.Android.source != NULL) CORE.Android.source->process(app, CORE.Android.source);
}
}
}
// NOTE: Add this to header (if apps really need it)
struct android_app *GetAndroidApp(void)
{
return CORE.Android.app;
}
// Close window and unload OpenGL context
void CloseWindow(void)
{
#if defined(SUPPORT_GIF_RECORDING)
if (gifRecording)
{
MsfGifResult result = msf_gif_end(&gifState);
msf_gif_free(result);
gifRecording = false;
}
#endif
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
UnloadFontDefault(); // WARNING: Module required: rtext
#endif
rlglClose(); // De-init rlgl
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
timeEndPeriod(1); // Restore time period
#endif
// Close surface, context and display
if (CORE.Window.device != EGL_NO_DISPLAY)
{
eglMakeCurrent(CORE.Window.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (CORE.Window.surface != EGL_NO_SURFACE)
{
eglDestroySurface(CORE.Window.device, CORE.Window.surface);
CORE.Window.surface = EGL_NO_SURFACE;
}
if (CORE.Window.context != EGL_NO_CONTEXT)
{
eglDestroyContext(CORE.Window.device, CORE.Window.context);
CORE.Window.context = EGL_NO_CONTEXT;
}
eglTerminate(CORE.Window.device);
CORE.Window.device = EGL_NO_DISPLAY;
}
#if defined(SUPPORT_EVENTS_AUTOMATION)
RL_FREE(events);
#endif
CORE.Window.ready = false;
TRACELOG(LOG_INFO, "Window closed successfully");
}

View File

@ -467,3 +467,37 @@ static bool InitGraphicsDevice(int width, int height)
return true;
}
// Close window and unload OpenGL context
void CloseWindow(void)
{
#if defined(SUPPORT_GIF_RECORDING)
if (gifRecording)
{
MsfGifResult result = msf_gif_end(&gifState);
msf_gif_free(result);
gifRecording = false;
}
#endif
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
UnloadFontDefault(); // WARNING: Module required: rtext
#endif
rlglClose(); // De-init rlgl
glfwDestroyWindow(CORE.Window.handle);
glfwTerminate();
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
timeEndPeriod(1); // Restore time period
#endif
#if defined(SUPPORT_EVENTS_AUTOMATION)
RL_FREE(events);
#endif
CORE.Window.ready = false;
TRACELOG(LOG_INFO, "Window closed successfully");
}

View File

@ -884,3 +884,121 @@ static bool InitGraphicsDevice(int width, int height)
return true;
}
// Close window and unload OpenGL context
void CloseWindow(void)
{
#if defined(SUPPORT_GIF_RECORDING)
if (gifRecording)
{
MsfGifResult result = msf_gif_end(&gifState);
msf_gif_free(result);
gifRecording = false;
}
#endif
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
UnloadFontDefault(); // WARNING: Module required: rtext
#endif
rlglClose(); // De-init rlgl
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
timeEndPeriod(1); // Restore time period
#endif
if (CORE.Window.prevFB)
{
drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
CORE.Window.prevFB = 0;
}
if (CORE.Window.prevBO)
{
gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
CORE.Window.prevBO = NULL;
}
if (CORE.Window.gbmSurface)
{
gbm_surface_destroy(CORE.Window.gbmSurface);
CORE.Window.gbmSurface = NULL;
}
if (CORE.Window.gbmDevice)
{
gbm_device_destroy(CORE.Window.gbmDevice);
CORE.Window.gbmDevice = NULL;
}
if (CORE.Window.crtc)
{
if (CORE.Window.connector)
{
drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, CORE.Window.crtc->buffer_id,
CORE.Window.crtc->x, CORE.Window.crtc->y, &CORE.Window.connector->connector_id, 1, &CORE.Window.crtc->mode);
drmModeFreeConnector(CORE.Window.connector);
CORE.Window.connector = NULL;
}
drmModeFreeCrtc(CORE.Window.crtc);
CORE.Window.crtc = NULL;
}
if (CORE.Window.fd != -1)
{
close(CORE.Window.fd);
CORE.Window.fd = -1;
}
// Close surface, context and display
if (CORE.Window.device != EGL_NO_DISPLAY)
{
if (CORE.Window.surface != EGL_NO_SURFACE)
{
eglDestroySurface(CORE.Window.device, CORE.Window.surface);
CORE.Window.surface = EGL_NO_SURFACE;
}
if (CORE.Window.context != EGL_NO_CONTEXT)
{
eglDestroyContext(CORE.Window.device, CORE.Window.context);
CORE.Window.context = EGL_NO_CONTEXT;
}
eglTerminate(CORE.Window.device);
CORE.Window.device = EGL_NO_DISPLAY;
}
// Wait for mouse and gamepad threads to finish before closing
// NOTE: Those threads should already have finished at this point
// because they are controlled by CORE.Window.shouldClose variable
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
// Close the evdev keyboard
if (CORE.Input.Keyboard.fd != -1)
{
close(CORE.Input.Keyboard.fd);
CORE.Input.Keyboard.fd = -1;
}
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{
if (CORE.Input.eventWorker[i].threadId)
{
pthread_join(CORE.Input.eventWorker[i].threadId, NULL);
}
}
if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
#if defined(SUPPORT_EVENTS_AUTOMATION)
RL_FREE(events);
#endif
CORE.Window.ready = false;
TRACELOG(LOG_INFO, "Window closed successfully");
}

View File

@ -1041,3 +1041,36 @@ static bool InitGraphicsDevice(int width, int height)
return true;
}
// Close window and unload OpenGL context
void CloseWindow(void)
{
#if defined(SUPPORT_GIF_RECORDING)
if (gifRecording)
{
MsfGifResult result = msf_gif_end(&gifState);
msf_gif_free(result);
gifRecording = false;
}
#endif
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
UnloadFontDefault(); // WARNING: Module required: rtext
#endif
rlglClose(); // De-init rlgl
glfwDestroyWindow(CORE.Window.handle);
glfwTerminate();
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
timeEndPeriod(1); // Restore time period
#endif
#if defined(SUPPORT_EVENTS_AUTOMATION)
RL_FREE(events);
#endif
CORE.Window.ready = false;
TRACELOG(LOG_INFO, "Window closed successfully");
}