src/video/android/SDL_androidwindow.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 28 Sep 2018 20:39:57 -0700
changeset 12255 d2e5d4520677
parent 12017 d8a165136edf
child 12305 85c6aa0836d8
permissions -rw-r--r--
Ensure we wait on the surface resize before returning from setting fullscreen mode.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../../SDL_internal.h"
    22 
    23 #if SDL_VIDEO_DRIVER_ANDROID
    24 
    25 #include "SDL_syswm.h"
    26 #include "../SDL_sysvideo.h"
    27 #include "../../events/SDL_keyboard_c.h"
    28 #include "../../events/SDL_mouse_c.h"
    29 #include "../../events/SDL_windowevents_c.h"
    30 #include "../../core/android/SDL_android.h"
    31 
    32 #include "SDL_androidvideo.h"
    33 #include "SDL_androidwindow.h"
    34 #include "SDL_hints.h"
    35 
    36 int
    37 Android_CreateWindow(_THIS, SDL_Window * window)
    38 {
    39     SDL_WindowData *data;
    40     
    41     if (Android_Window) {
    42         return SDL_SetError("Android only supports one window");
    43     }
    44     
    45     Android_PauseSem = SDL_CreateSemaphore(0);
    46     Android_ResumeSem = SDL_CreateSemaphore(0);
    47 
    48     /* Set orientation */
    49     Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
    50 
    51     /* Adjust the window data to match the screen */
    52     window->x = 0;
    53     window->y = 0;
    54     window->w = Android_SurfaceWidth;
    55     window->h = Android_SurfaceHeight;
    56 
    57     window->flags &= ~SDL_WINDOW_RESIZABLE;     /* window is NEVER resizeable */
    58     window->flags &= ~SDL_WINDOW_HIDDEN;
    59     window->flags |= SDL_WINDOW_SHOWN;          /* only one window on Android */
    60     window->flags |= SDL_WINDOW_INPUT_FOCUS;    /* always has input focus */
    61 
    62     /* One window, it always has focus */
    63     SDL_SetMouseFocus(window);
    64     SDL_SetKeyboardFocus(window);
    65     
    66     data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
    67     if (!data) {
    68         return SDL_OutOfMemory();
    69     }
    70     
    71     data->native_window = Android_JNI_GetNativeWindow();
    72     
    73     if (!data->native_window) {
    74         SDL_free(data);
    75         return SDL_SetError("Could not fetch native window");
    76     }
    77 
    78     /* Do not create EGLSurface for Vulkan window since it will then make the window
    79        incompatible with vkCreateAndroidSurfaceKHR */
    80     if ((window->flags & SDL_WINDOW_VULKAN) == 0) {
    81         data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window);
    82 
    83         if (data->egl_surface == EGL_NO_SURFACE) {
    84             ANativeWindow_release(data->native_window);
    85             SDL_free(data);
    86             return SDL_SetError("Could not create GLES window surface");
    87         }
    88     }
    89 
    90     window->driverdata = data;
    91     Android_Window = window;
    92     
    93     return 0;
    94 }
    95 
    96 void
    97 Android_SetWindowTitle(_THIS, SDL_Window * window)
    98 {
    99     Android_JNI_SetActivityTitle(window->title);
   100 }
   101 
   102 void
   103 Android_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
   104 {
   105     Android_JNI_SetWindowStyle(fullscreen);
   106 
   107     // Ensure our size matches reality after we've executed the window style change.
   108     //
   109     // It is possible that we've set width and height to the full-size display, but on
   110     // Samsung DeX or Chromebooks or other windowed Android environemtns, our window may 
   111     // still not be the full display size.
   112     //
   113     if (!SDL_IsDeXMode() && !SDL_IsChromebook()) {
   114         return;
   115     }
   116 
   117     SDL_WindowData * data = (SDL_WindowData *)window->driverdata;
   118 
   119     if (!data || !data->native_window) {
   120         return;
   121     }
   122 
   123     int old_w = window->w;
   124     int old_h = window->h;
   125 
   126     int new_w = ANativeWindow_getWidth(data->native_window);
   127     int new_h = ANativeWindow_getHeight(data->native_window);
   128 
   129     if (old_w != new_w || old_h != new_h) {
   130         SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
   131     }
   132 }
   133 
   134 void
   135 Android_DestroyWindow(_THIS, SDL_Window * window)
   136 {
   137     SDL_WindowData *data;
   138     
   139     if (window == Android_Window) {
   140         Android_Window = NULL;
   141         if (Android_PauseSem) SDL_DestroySemaphore(Android_PauseSem);
   142         if (Android_ResumeSem) SDL_DestroySemaphore(Android_ResumeSem);
   143         Android_PauseSem = NULL;
   144         Android_ResumeSem = NULL;
   145         
   146         if(window->driverdata) {
   147             data = (SDL_WindowData *) window->driverdata;
   148             if (data->egl_surface != EGL_NO_SURFACE) {
   149                 SDL_EGL_DestroySurface(_this, data->egl_surface);
   150             }
   151             if (data->native_window) {
   152                 ANativeWindow_release(data->native_window);
   153             }
   154             SDL_free(window->driverdata);
   155             window->driverdata = NULL;
   156         }
   157     }
   158 }
   159 
   160 SDL_bool
   161 Android_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
   162 {
   163     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   164 
   165     if (info->version.major == SDL_MAJOR_VERSION &&
   166         info->version.minor == SDL_MINOR_VERSION) {
   167         info->subsystem = SDL_SYSWM_ANDROID;
   168         info->info.android.window = data->native_window;
   169         info->info.android.surface = data->egl_surface;
   170         return SDL_TRUE;
   171     } else {
   172         SDL_SetError("Application not compiled with SDL %d.%d",
   173                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   174         return SDL_FALSE;
   175     }
   176 }
   177 
   178 #endif /* SDL_VIDEO_DRIVER_ANDROID */
   179 
   180 /* vi: set ts=4 sw=4 expandtab: */