From 6ee661398d94db9f6eac38b31269a3665432125a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 13 Aug 2017 20:55:59 -0700 Subject: [PATCH] Fixed bug 3235 - Make the Android window creation similar to iOS' window creation Sylvain Here's a patch. It tries to get the hint first. Resizable will allow any orientation. Otherwise it uses width/height window. setOrientation method is splitted in static and non-static, so that it can be overloaded in a user subclass. Some artefact observed : surfaceChanged() can be called twice at the beginning. When the phone starts in portrait and run a landscape application. --- .../src/org/libsdl/app/SDLActivity.java | 55 +++++++++++++++++++ src/core/android/SDL_android.c | 12 ++++ src/core/android/SDL_android.h | 1 + src/video/android/SDL_androidwindow.c | 4 ++ 4 files changed, 72 insertions(+) diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java index 10c34543ec131..1d8eb2cbfecc9 100644 --- a/android-project/src/org/libsdl/app/SDLActivity.java +++ b/android-project/src/org/libsdl/app/SDLActivity.java @@ -513,6 +513,61 @@ public static boolean setActivityTitle(String title) { return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); } + /** + * This method is called by SDL using JNI. + * This is a static method for JNI convenience, it calls a non-static method + * so that is can be overridden + */ + public static void setOrientation(int w, int h, boolean resizable, String hint) + { + mSingleton.setOrientationBis(w, h, resizable, hint); + return; + } + + /** + * This can be overridden + */ + public void setOrientationBis(int w, int h, boolean resizable, String hint) + { + int orientation = -1; + + if (hint != "") { + if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + } else if (hint.contains("LandscapeRight")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + } else if (hint.contains("LandscapeLeft")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; + } else if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; + } else if (hint.contains("Portrait")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + } else if (hint.contains("PortraitUpsideDown")) { + orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + } + } + + /* no valid hint */ + if (orientation == -1) { + if (resizable) { + /* no fixed orientation */ + } else { + if (w > h) { + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; + } else { + orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; + } + } + } + + Log.v("SDL", "setOrientation() orientation=" + orientation + " width=" + w +" height="+ h +" resizable=" + resizable + " hint=" + hint); + if (orientation != -1) { + mSingleton.setRequestedOrientation(orientation); + } + + return; + } + /** * This method is called by SDL using JNI. */ diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 902925408e1b9..1d7d15923d4d6 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -636,6 +636,18 @@ void Android_JNI_SetActivityTitle(const char *title) } } +void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint) +{ + jmethodID mid; + JNIEnv *mEnv = Android_JNI_GetEnv(); + mid = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,"setOrientation","(IIZLjava/lang/String;)V"); + if (mid) { + jstring jhint = (jstring)((*mEnv)->NewStringUTF(mEnv, (hint ? hint : ""))); + (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, mid, w, h, (resizable? 1 : 0), jhint); + (*mEnv)->DeleteLocalRef(mEnv, jhint); + } +} + SDL_bool Android_JNI_GetAccelerometerValues(float values[3]) { int i; diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index 8fe18d610c475..7d4ded8215284 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -34,6 +34,7 @@ extern "C" { /* Interface from the SDL library into the Android Java activity */ extern void Android_JNI_SetActivityTitle(const char *title); +extern void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint); extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]); extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect); extern void Android_JNI_HideTextInput(void); diff --git a/src/video/android/SDL_androidwindow.c b/src/video/android/SDL_androidwindow.c index 68bc7a77fcebe..4b8ac7fbc421f 100644 --- a/src/video/android/SDL_androidwindow.c +++ b/src/video/android/SDL_androidwindow.c @@ -29,6 +29,7 @@ #include "SDL_androidvideo.h" #include "SDL_androidwindow.h" +#include "SDL_hints.h" int Android_CreateWindow(_THIS, SDL_Window * window) @@ -42,6 +43,9 @@ Android_CreateWindow(_THIS, SDL_Window * window) Android_PauseSem = SDL_CreateSemaphore(0); Android_ResumeSem = SDL_CreateSemaphore(0); + /* Set orientation */ + Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS)); + /* Adjust the window data to match the screen */ window->x = 0; window->y = 0;