Call Pause/Resume callbacks from Android
[freeglut] / src / android / fg_window_android.c
index 8b1f682..5d1bc19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * freeglut_window_android.c
+ * fg_window_android.c
  *
  * Window management methods for Android
  *
@@ -29,7 +29,8 @@
 #define FREEGLUT_BUILDING_LIB
 #include <GL/freeglut.h>
 #include "fg_internal.h"
-extern EGLSurface fghEGLPlatformOpenWindow( EGLNativeWindowType handle );
+#include "egl/fg_window_egl.h"
+#include <android/native_app_glue/android_native_app_glue.h>
 
 /*
  * Opens a window. Requires a SFG_Window object created and attached
@@ -40,41 +41,57 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
                            GLboolean sizeUse, int w, int h,
                            GLboolean gameMode, GLboolean isSubWindow )
 {
-  printf("fgPlatformOpenWindow %p ID=%d\n", (void*)window, window->ID);
-
   /* TODO: only one full-screen window possible? */
-  static int nb_windows = 0;
-  if (nb_windows == 0) {
-    nb_windows++;
-    fgDisplay.pDisplay.single_window = window;
-    printf("=> %p ID=%d\n", (void*)fgDisplay.pDisplay.single_window, fgDisplay.pDisplay.single_window->ID);
-  } else {
+  if (fgDisplay.pDisplay.single_native_window != NULL) {
+    fgWarning("You can't have more than one window on Android");
     return;
   }
 
-  /* Wait until window is available and OpenGL context is created */
+  /* First, wait until Activity surface is available */
   /* Normally events are processed through glutMainLoop(), but the
      user didn't call it yet, and the Android may not have initialized
      the View yet.  So we need to wait for that to happen. */
   /* We can't return from this function before the OpenGL context is
      properly made current with a valid surface. So we wait for the
      surface. */
-  while (fgDisplay.pDisplay.single_window->Window.Handle == NULL) {
+  while (fgDisplay.pDisplay.single_native_window == NULL) {
     /* APP_CMD_INIT_WINDOW will do the job */
-    fgPlatformProcessSingleEvent();
+    int ident;
+    int events;
+    struct android_poll_source* source;
+    if ((ident=ALooper_pollOnce(0, NULL, &events, (void**)&source)) >= 0)
+      if (source != NULL) source->process(source->app, source);
+    /* fgPlatformProcessSingleEvent(); */
   }
+  window->Window.Handle = fgDisplay.pDisplay.single_native_window;
+
+  /* Create context */
+  fghChooseConfig(&window->Window.pContext.egl.Config);
+  window->Window.Context = fghCreateNewContextEGL(window);
+
+  EGLDisplay display = fgDisplay.pDisplay.egl.Display;
 
-  EGLDisplay display = fgDisplay.pDisplay.eglDisplay;
-  EGLint format = fgDisplay.pDisplay.eglContextFormat;
-  ANativeWindow_setBuffersGeometry(window->Window.Handle, 0, 0, format);
-  window->Window.pContext.eglSurface = fghEGLPlatformOpenWindow(window->Window.Handle);
+  /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
+   * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
+   * As soon as we picked a EGLConfig, we can safely reconfigure the
+   * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
+  EGLint vid;
+  eglGetConfigAttrib(display, window->Window.pContext.egl.Config,
+                    EGL_NATIVE_VISUAL_ID, &vid);
+  ANativeWindow_setBuffersGeometry(window->Window.Handle, 0, 0, vid);
+
+  fghPlatformOpenWindowEGL(window);
 
   window->State.Visible = GL_TRUE;
 }
 
-void fgPlatformSetWindow ( SFG_Window *window )
+/*
+ * Closes a window, destroying the frame and OpenGL context
+ */
+void fgPlatformCloseWindow( SFG_Window* window )
 {
-  /* TODO: only a single window possible? */
+  fghPlatformCloseWindowEGL(window);
+  /* Window pre-created by Android, no way to delete it */
 }
 
 /*