Browse Source

Added the concept of display natural orientation

Also renamed SDL_GetDisplayOrientation() SDL_GetDisplayCurrentOrientation()

The natural orientation of the primary display is the frame of reference for accelerometer and gyro sensor readings.
Sam Lantinga 1 year ago
parent
commit
e6d1ba2a17

+ 40 - 25
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java

@@ -193,7 +193,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     protected static final int SDL_ORIENTATION_PORTRAIT = 3;
     protected static final int SDL_ORIENTATION_PORTRAIT_FLIPPED = 4;
 
-    protected static int mCurrentOrientation;
+    protected static int mCurrentRotation;
     protected static Locale mCurrentLocale;
 
     // Handle the state of the native layer
@@ -437,9 +437,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
         mLayout.addView(mSurface);
 
         // Get our current screen orientation and pass it down.
-        mCurrentOrientation = SDLActivity.getCurrentOrientation();
-        // Only record current orientation
-        SDLActivity.onNativeOrientationChanged(mCurrentOrientation);
+        SDLActivity.nativeSetNaturalOrientation(SDLActivity.getNaturalOrientation());
+        mCurrentRotation = SDLActivity.getCurrentRotation();
+        SDLActivity.onNativeRotationChanged(mCurrentRotation);
 
         try {
             if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
@@ -543,33 +543,47 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
         }
     }
 
-    public static int getCurrentOrientation() {
+    public static int getNaturalOrientation() {
         int result = SDL_ORIENTATION_UNKNOWN;
 
         Activity activity = (Activity)getContext();
-        if (activity == null) {
-            return result;
-        }
-        Display display = activity.getWindowManager().getDefaultDisplay();
-
-        switch (display.getRotation()) {
-            case Surface.ROTATION_0:
-                result = SDL_ORIENTATION_PORTRAIT;
-                break;
-
-            case Surface.ROTATION_90:
+        if (activity != null) {
+            Configuration config = activity.getResources().getConfiguration();
+            Display display = activity.getWindowManager().getDefaultDisplay();
+            int rotation = display.getRotation();
+            if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
+                    config.orientation == Configuration.ORIENTATION_LANDSCAPE) ||
+                ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
+                    config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
                 result = SDL_ORIENTATION_LANDSCAPE;
-                break;
+            } else {
+                result = SDL_ORIENTATION_PORTRAIT;
+            }
+        }
+        return result;
+    }
 
-            case Surface.ROTATION_180:
-                result = SDL_ORIENTATION_PORTRAIT_FLIPPED;
-                break;
+    public static int getCurrentRotation() {
+        int result = 0;
 
-            case Surface.ROTATION_270:
-                result = SDL_ORIENTATION_LANDSCAPE_FLIPPED;
-                break;
+        Activity activity = (Activity)getContext();
+        if (activity != null) {
+            Display display = activity.getWindowManager().getDefaultDisplay();
+            switch (display.getRotation()) {
+                case Surface.ROTATION_0:
+                    result = 0;
+                    break;
+                case Surface.ROTATION_90:
+                    result = 90;
+                    break;
+                case Surface.ROTATION_180:
+                    result = 180;
+                    break;
+                case Surface.ROTATION_270:
+                    result = 270;
+                    break;
+            }
         }
-
         return result;
     }
 
@@ -987,7 +1001,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     public static native String nativeGetHint(String name);
     public static native boolean nativeGetHintBoolean(String name, boolean default_value);
     public static native void nativeSetenv(String name, String value);
-    public static native void onNativeOrientationChanged(int orientation);
+    public static native void nativeSetNaturalOrientation(int orientation);
+    public static native void onNativeRotationChanged(int rotation);
     public static native void nativeAddTouch(int touchId, String name);
     public static native void nativePermissionResult(int requestCode, boolean result);
     public static native void onNativeLocaleChanged();

+ 16 - 16
android-project/app/src/main/java/org/libsdl/app/SDLSurface.java

@@ -325,36 +325,36 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
 
             // Since we may have an orientation set, we won't receive onConfigurationChanged events.
             // We thus should check here.
-            int newOrientation;
+            int newRotation;
 
             float x, y;
             switch (mDisplay.getRotation()) {
+                case Surface.ROTATION_0:
+                default:
+                    x = event.values[0];
+                    y = event.values[1];
+                    newRotation = 0;
+                    break;
                 case Surface.ROTATION_90:
                     x = -event.values[1];
                     y = event.values[0];
-                    newOrientation = SDLActivity.SDL_ORIENTATION_LANDSCAPE;
-                    break;
-                case Surface.ROTATION_270:
-                    x = event.values[1];
-                    y = -event.values[0];
-                    newOrientation = SDLActivity.SDL_ORIENTATION_LANDSCAPE_FLIPPED;
+                    newRotation = 90;
                     break;
                 case Surface.ROTATION_180:
                     x = -event.values[0];
                     y = -event.values[1];
-                    newOrientation = SDLActivity.SDL_ORIENTATION_PORTRAIT_FLIPPED;
+                    newRotation = 180;
                     break;
-                case Surface.ROTATION_0:
-                default:
-                    x = event.values[0];
-                    y = event.values[1];
-                    newOrientation = SDLActivity.SDL_ORIENTATION_PORTRAIT;
+                case Surface.ROTATION_270:
+                    x = event.values[1];
+                    y = -event.values[0];
+                    newRotation = 270;
                     break;
             }
 
-            if (newOrientation != SDLActivity.mCurrentOrientation) {
-                SDLActivity.mCurrentOrientation = newOrientation;
-                SDLActivity.onNativeOrientationChanged(newOrientation);
+            if (newRotation != SDLActivity.mCurrentRotation) {
+                SDLActivity.mCurrentRotation = newRotation;
+                SDLActivity.onNativeRotationChanged(newRotation);
             }
 
             SDLActivity.onNativeAccel(-x / SensorManager.GRAVITY_EARTH,

+ 5 - 0
build-scripts/SDL_migration.cocci

@@ -2668,3 +2668,8 @@ typedef SDL_cond, SDL_Condition;
 - SDL_TLSCleanup
 + SDL_CleanupTLS
   (...)
+@@
+@@
+- SDL_GetDisplayOrientation
++ SDL_GetDisplayCurrentOrientation
+  (...)

+ 1 - 0
docs/README-migration.md

@@ -1139,6 +1139,7 @@ The SDL_WINDOW_TOOLTIP and SDL_WINDOW_POPUP_MENU window flags are now supported
 
 The following functions have been renamed:
 * SDL_GetClosestDisplayMode() => SDL_GetClosestFullscreenDisplayMode()
+* SDL_GetDisplayOrientation() => SDL_GetDisplayCurrentOrientation()
 * SDL_GetPointDisplayIndex() => SDL_GetDisplayForPoint()
 * SDL_GetRectDisplayIndex() => SDL_GetDisplayForRect()
 * SDL_GetWindowDisplayIndex() => SDL_GetDisplayForWindow()

+ 2 - 0
include/SDL3/SDL_oldnames.h

@@ -466,6 +466,7 @@
 
 /* ##SDL_video.h */
 #define SDL_GetClosestDisplayMode SDL_GetClosestFullscreenDisplayMode
+#define SDL_GetDisplayOrientation SDL_GetDisplayCurrentOrientation
 #define SDL_GetPointDisplayIndex SDL_GetDisplayForPoint
 #define SDL_GetRectDisplayIndex SDL_GetDisplayForRect
 #define SDL_GetWindowDisplayIndex SDL_GetDisplayForWindow
@@ -902,6 +903,7 @@
 
 /* ##SDL_video.h */
 #define SDL_GetClosestDisplayMode SDL_GetClosestDisplayMode_renamed_SDL_GetClosestFullscreenDisplayMode
+#define SDL_GetDisplayOrientation SDL_GetDisplayOrientation_renamed_SDL_GetDisplayCurrentOrientation
 #define SDL_GetPointDisplayIndex SDL_GetPointDisplayIndex_renamed_SDL_GetDisplayForPoint
 #define SDL_GetRectDisplayIndex SDL_GetRectDisplayIndex_renamed_SDL_GetDisplayForRect
 #define SDL_GetWindowDisplayIndex SDL_GetWindowDisplayIndex_renamed_SDL_GetDisplayForWindow

+ 2 - 2
include/SDL3/SDL_sensor.h

@@ -96,7 +96,7 @@ typedef enum
  *
  * The axis data is not changed when the device is rotated.
  *
- * \sa SDL_GetDisplayOrientation()
+ * \sa SDL_GetDisplayCurrentOrientation()
  */
 #define SDL_STANDARD_GRAVITY    9.80665f
 
@@ -120,7 +120,7 @@ typedef enum
  *
  * The axis data is not changed when the device is rotated.
  *
- * \sa SDL_GetDisplayOrientation()
+ * \sa SDL_GetDisplayCurrentOrientation()
  */
 
 /* Function prototypes */

+ 14 - 1
include/SDL3/SDL_video.h

@@ -394,6 +394,19 @@ extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(SDL_DisplayID displayID, SDL_Re
  */
 extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(SDL_DisplayID displayID, SDL_Rect *rect);
 
+/**
+ * Get the orientation of a display when it is unrotated.
+ *
+ * \param displayID the instance ID of the display to query
+ * \returns The SDL_DisplayOrientation enum value of the display, or
+ *          `SDL_ORIENTATION_UNKNOWN` if it isn't available.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_GetDisplays
+ */
+extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayNaturalOrientation(SDL_DisplayID displayID);
+
 /**
  * Get the orientation of a display.
  *
@@ -405,7 +418,7 @@ extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(SDL_DisplayID displayID,
  *
  * \sa SDL_GetDisplays
  */
-extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(SDL_DisplayID displayID);
+extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayCurrentOrientation(SDL_DisplayID displayID);
 
 /**
  * Get the content scale of a display.

+ 46 - 8
src/core/android/SDL_android.c

@@ -155,10 +155,14 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
     JNIEnv *env, jclass cls,
     jstring name, jstring value);
 
-JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetNaturalOrientation)(
     JNIEnv *env, jclass cls,
     jint orientation);
 
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeRotationChanged)(
+    JNIEnv *env, jclass cls,
+    jint rotation);
+
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
     JNIEnv *env, jclass cls,
     jint touchId, jstring name);
@@ -202,7 +206,8 @@ static JNINativeMethod SDLActivity_tab[] = {
     { "nativeGetHint", "(Ljava/lang/String;)Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetHint) },
     { "nativeGetHintBoolean", "(Ljava/lang/String;Z)Z", SDL_JAVA_INTERFACE(nativeGetHintBoolean) },
     { "nativeSetenv", "(Ljava/lang/String;Ljava/lang/String;)V", SDL_JAVA_INTERFACE(nativeSetenv) },
-    { "onNativeOrientationChanged", "(I)V", SDL_JAVA_INTERFACE(onNativeOrientationChanged) },
+    { "nativeSetNaturalOrientation", "(I)V", SDL_JAVA_INTERFACE(nativeSetNaturalOrientation) },
+    { "onNativeRotationChanged", "(I)V", SDL_JAVA_INTERFACE(onNativeRotationChanged) },
     { "nativeAddTouch", "(ILjava/lang/String;)V", SDL_JAVA_INTERFACE(nativeAddTouch) },
     { "nativePermissionResult", "(IZ)V", SDL_JAVA_INTERFACE(nativePermissionResult) },
     { "nativeAllowRecreateActivity", "()Z", SDL_JAVA_INTERFACE(nativeAllowRecreateActivity) },
@@ -369,7 +374,8 @@ static jmethodID midHapticRun;
 static jmethodID midHapticStop;
 
 /* Accelerometer data storage */
-static SDL_DisplayOrientation displayOrientation;
+static SDL_DisplayOrientation displayNaturalOrientation;
+static SDL_DisplayOrientation displayCurrentOrientation;
 static float fLastAccelerometer[3];
 static SDL_bool bHasNewData;
 
@@ -934,17 +940,44 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
     SDL_UnlockMutex(Android_ActivityMutex);
 }
 
-JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetNaturalOrientation)(
     JNIEnv *env, jclass jcls,
     jint orientation)
+{
+    displayNaturalOrientation = (SDL_DisplayOrientation)orientation;
+}
+
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeRotationChanged)(
+    JNIEnv *env, jclass jcls,
+    jint rotation)
 {
     SDL_LockMutex(Android_ActivityMutex);
 
-    displayOrientation = (SDL_DisplayOrientation)orientation;
+    if (displayNaturalOrientation == SDL_ORIENTATION_LANDSCAPE) {
+        rotation += 90;
+    }
+
+    switch (rotation % 360) {
+    case 0:
+        displayCurrentOrientation = SDL_ORIENTATION_PORTRAIT;
+        break;
+    case 90:
+        displayCurrentOrientation = SDL_ORIENTATION_LANDSCAPE;
+        break;
+    case 180:
+        displayCurrentOrientation = SDL_ORIENTATION_PORTRAIT_FLIPPED;
+        break;
+    case 270:
+        displayCurrentOrientation = SDL_ORIENTATION_LANDSCAPE_FLIPPED;
+        break;
+    default:
+        displayCurrentOrientation = SDL_ORIENTATION_UNKNOWN;
+        break;
+    }
 
     if (Android_Window) {
         SDL_VideoDisplay *display = SDL_GetVideoDisplay(SDL_GetPrimaryDisplay());
-        SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_ORIENTATION, orientation);
+        SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_ORIENTATION, displayCurrentOrientation);
     }
 
     SDL_UnlockMutex(Android_ActivityMutex);
@@ -1706,9 +1739,14 @@ int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spe
     return 0;
 }
 
-SDL_DisplayOrientation Android_JNI_GetDisplayOrientation(void)
+SDL_DisplayOrientation Android_JNI_GetDisplayNaturalOrientation(void)
+{
+    return displayNaturalOrientation;
+}
+
+SDL_DisplayOrientation Android_JNI_GetDisplayCurrentOrientation(void)
 {
-    return displayOrientation;
+    return displayCurrentOrientation;
 }
 
 void *Android_JNI_GetAudioBuffer(void)

+ 2 - 1
src/core/android/SDL_android.h

@@ -43,7 +43,8 @@ extern void Android_JNI_HideTextInput(void);
 extern SDL_bool Android_JNI_IsScreenKeyboardShown(void);
 extern ANativeWindow *Android_JNI_GetNativeWindow(void);
 
-extern SDL_DisplayOrientation Android_JNI_GetDisplayOrientation(void);
+extern SDL_DisplayOrientation Android_JNI_GetDisplayNaturalOrientation(void);
+extern SDL_DisplayOrientation Android_JNI_GetDisplayCurrentOrientation(void);
 
 /* Audio support */
 extern void Android_DetectDevices(void);

+ 2 - 1
src/dynapi/SDL_dynapi.sym

@@ -166,7 +166,7 @@ SDL3_0.0.0 {
     SDL_GetDisplayForPoint;
     SDL_GetDisplayForRect;
     SDL_GetDisplayName;
-    SDL_GetDisplayOrientation;
+    SDL_GetDisplayCurrentOrientation;
     SDL_GetDisplayUsableBounds;
     SDL_GetError;
     SDL_GetErrorMsg;
@@ -866,6 +866,7 @@ SDL3_0.0.0 {
     SDL_hid_get_report_descriptor;
     SDL_HasWindowSurface;
     SDL_DestroyWindowSurface;
+    SDL_GetDisplayNaturalOrientation;
     # extra symbols go here (don't modify this line)
   local: *;
 };

+ 2 - 1
src/dynapi/SDL_dynapi_overrides.h

@@ -190,7 +190,7 @@
 #define SDL_GetDisplayForPoint SDL_GetDisplayForPoint_REAL
 #define SDL_GetDisplayForRect SDL_GetDisplayForRect_REAL
 #define SDL_GetDisplayName SDL_GetDisplayName_REAL
-#define SDL_GetDisplayOrientation SDL_GetDisplayOrientation_REAL
+#define SDL_GetDisplayCurrentOrientation SDL_GetDisplayCurrentOrientation_REAL
 #define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL
 #define SDL_GetError SDL_GetError_REAL
 #define SDL_GetErrorMsg SDL_GetErrorMsg_REAL
@@ -892,3 +892,4 @@
 #define SDL_hid_get_report_descriptor SDL_hid_get_report_descriptor_REAL
 #define SDL_HasWindowSurface SDL_HasWindowSurface_REAL
 #define SDL_DestroyWindowSurface SDL_DestroyWindowSurface_REAL
+#define SDL_GetDisplayNaturalOrientation SDL_GetDisplayNaturalOrientation_REAL

+ 2 - 1
src/dynapi/SDL_dynapi_procs.h

@@ -265,7 +265,7 @@ SDL_DYNAPI_PROC(int,SDL_GetDisplayBounds,(SDL_DisplayID a, SDL_Rect *b),(a,b),re
 SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetDisplayForPoint,(const SDL_Point *a),(a),return)
 SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetDisplayForRect,(const SDL_Rect *a),(a),return)
 SDL_DYNAPI_PROC(const char*,SDL_GetDisplayName,(SDL_DisplayID a),(a),return)
-SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetDisplayOrientation,(SDL_DisplayID a),(a),return)
+SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetDisplayCurrentOrientation,(SDL_DisplayID a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_GetDisplayUsableBounds,(SDL_DisplayID a, SDL_Rect *b),(a,b),return)
 SDL_DYNAPI_PROC(const char*,SDL_GetError,(void),(),return)
 SDL_DYNAPI_PROC(char*,SDL_GetErrorMsg,(char *a, int b),(a,b),return)
@@ -937,3 +937,4 @@ SDL_DYNAPI_PROC(SDL_hid_device_info*,SDL_hid_get_device_info,(SDL_hid_device *a)
 SDL_DYNAPI_PROC(int,SDL_hid_get_report_descriptor,(SDL_hid_device *a, unsigned char *b, size_t c),(a,b,c),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_HasWindowSurface,(SDL_Window *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_DestroyWindowSurface,(SDL_Window *a),(a),return)
+SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetDisplayNaturalOrientation,(SDL_DisplayID a),(a),return)

+ 2 - 2
src/events/SDL_displayevents.c

@@ -33,10 +33,10 @@ int SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent,
     }
     switch (displayevent) {
     case SDL_EVENT_DISPLAY_ORIENTATION:
-        if (data1 == SDL_ORIENTATION_UNKNOWN || data1 == display->orientation) {
+        if (data1 == SDL_ORIENTATION_UNKNOWN || data1 == display->current_orientation) {
             return 0;
         }
-        display->orientation = (SDL_DisplayOrientation)data1;
+        display->current_orientation = (SDL_DisplayOrientation)data1;
         break;
     default:
         break;

+ 7 - 2
src/test/SDL_test_common.c

@@ -2464,8 +2464,13 @@ void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, fl
         textY += lineHeight;
     }
 
-    (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayOrientation: ");
-    SDLTest_PrintDisplayOrientation(text, sizeof(text), SDL_GetDisplayOrientation(windowDisplayID));
+    (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayNaturalOrientation: ");
+    SDLTest_PrintDisplayOrientation(text, sizeof(text), SDL_GetDisplayNaturalOrientation(windowDisplayID));
+    SDLTest_DrawString(renderer, 0.0f, textY, text);
+    textY += lineHeight;
+
+    (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayCurrentOrientation: ");
+    SDLTest_PrintDisplayOrientation(text, sizeof(text), SDL_GetDisplayCurrentOrientation(windowDisplayID));
     SDLTest_DrawString(renderer, 0.0f, textY, text);
     textY += lineHeight;
 

+ 2 - 1
src/video/SDL_sysvideo.h

@@ -145,7 +145,8 @@ struct SDL_VideoDisplay
     SDL_DisplayMode *fullscreen_modes;
     SDL_DisplayMode desktop_mode;
     const SDL_DisplayMode *current_mode;
-    SDL_DisplayOrientation orientation;
+    SDL_DisplayOrientation natural_orientation;
+    SDL_DisplayOrientation current_orientation;
     float content_scale;
 
     SDL_Window *fullscreen_window;

+ 21 - 2
src/video/SDL_video.c

@@ -889,13 +889,32 @@ int SDL_GetDisplayUsableBounds(SDL_DisplayID displayID, SDL_Rect *rect)
     return SDL_GetDisplayBounds(displayID, rect);
 }
 
-SDL_DisplayOrientation SDL_GetDisplayOrientation(SDL_DisplayID displayID)
+SDL_DisplayOrientation SDL_GetDisplayNaturalOrientation(SDL_DisplayID displayID)
 {
     SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID);
 
     CHECK_DISPLAY_MAGIC(display, SDL_ORIENTATION_UNKNOWN);
 
-    return display->orientation;
+    if (display->natural_orientation != SDL_ORIENTATION_UNKNOWN) {
+        return display->natural_orientation;
+    } else {
+        /* Default to landscape if the driver hasn't set it */
+        return SDL_ORIENTATION_LANDSCAPE;
+    }
+}
+
+SDL_DisplayOrientation SDL_GetDisplayCurrentOrientation(SDL_DisplayID displayID)
+{
+    SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID);
+
+    CHECK_DISPLAY_MAGIC(display, SDL_ORIENTATION_UNKNOWN);
+
+    if (display->current_orientation != SDL_ORIENTATION_UNKNOWN) {
+        return display->current_orientation;
+    } else {
+        /* Default to landscape if the driver hasn't set it */
+        return SDL_ORIENTATION_LANDSCAPE;
+    }
 }
 
 void SDL_SetDisplayContentScale(SDL_VideoDisplay *display, float scale)

+ 2 - 1
src/video/android/SDL_androidvideo.c

@@ -189,7 +189,8 @@ int Android_VideoInit(SDL_VideoDevice *_this)
         return -1;
     }
     display = SDL_GetVideoDisplay(displayID);
-    display->orientation = Android_JNI_GetDisplayOrientation();
+    display->natural_orientation = Android_JNI_GetDisplayNaturalOrientation();
+    display->current_orientation = Android_JNI_GetDisplayCurrentOrientation();
     display->content_scale = Android_ScreenDensity;
 
     Android_InitTouch();

+ 11 - 0
src/video/uikit/SDL_uikitmodes.m

@@ -220,6 +220,17 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
     }
 
     SDL_zero(display);
+#if !TARGET_OS_TV
+    if (uiscreen == [UIScreen mainScreen]) {
+        /* The natural orientation (used by sensors) is portrait */
+        display.natural_orientation = SDL_ORIENTATION_PORTRAIT;
+    } else
+#endif
+    if (UIKit_IsDisplayLandscape(uiscreen)) {
+        display.natural_orientation = SDL_ORIENTATION_LANDSCAPE;
+    } else {
+        display.natural_orientation = SDL_ORIENTATION_PORTRAIT;
+    }
     display.desktop_mode = mode;
 
     /* Allocate the display data */

+ 6 - 1
src/video/wayland/SDL_waylandvideo.c

@@ -594,7 +594,12 @@ static void display_handle_done(void *data,
     if (driverdata->display == 0) {
         /* First time getting display info, create the VideoDisplay */
         SDL_bool send_event = driverdata->videodata->initializing ? SDL_FALSE : SDL_TRUE;
-        driverdata->placeholder.orientation = driverdata->orientation;
+        if (driverdata->physical_width >= driverdata->physical_height) {
+            driverdata->placeholder.natural_orientation = SDL_ORIENTATION_LANDSCAPE;
+        } else {
+            driverdata->placeholder.natural_orientation = SDL_ORIENTATION_PORTRAIT;
+        }
+        driverdata->placeholder.current_orientation = driverdata->orientation;
         driverdata->placeholder.driverdata = driverdata;
         driverdata->display = SDL_AddVideoDisplay(&driverdata->placeholder, send_event);
         SDL_free(driverdata->placeholder.name);

+ 23 - 9
src/video/windows/SDL_windowsmodes.c

@@ -102,7 +102,7 @@ static void WIN_UpdateDisplayMode(SDL_VideoDevice *_this, LPCWSTR deviceName, DW
     }
 }
 
-static SDL_DisplayOrientation WIN_GetDisplayOrientation(DEVMODE *mode)
+static SDL_DisplayOrientation WIN_GetNaturalOrientation(DEVMODE *mode)
 {
     int width = mode->dmPelsWidth;
     int height = mode->dmPelsHeight;
@@ -115,6 +115,15 @@ static SDL_DisplayOrientation WIN_GetDisplayOrientation(DEVMODE *mode)
     }
 
     if (width >= height) {
+        return SDL_ORIENTATION_LANDSCAPE;
+    } else {
+        return SDL_ORIENTATION_PORTRAIT;
+    }
+}
+
+static SDL_DisplayOrientation WIN_GetDisplayOrientation(DEVMODE *mode)
+{
+    if (WIN_GetNaturalOrientation(mode) == SDL_ORIENTATION_LANDSCAPE) {
         switch (mode->dmDisplayOrientation) {
         case DMDO_DEFAULT:
             return SDL_ORIENTATION_LANDSCAPE;
@@ -182,7 +191,7 @@ static float WIN_GetContentScale(SDL_VideoDevice *_this, HMONITOR hMonitor)
     return dpi / 96.0f;
 }
 
-static SDL_bool WIN_GetDisplayMode(SDL_VideoDevice *_this, HMONITOR hMonitor, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode, SDL_DisplayOrientation *orientation)
+static SDL_bool WIN_GetDisplayMode(SDL_VideoDevice *_this, HMONITOR hMonitor, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode, SDL_DisplayOrientation *natural_orientation, SDL_DisplayOrientation *current_orientation)
 {
     SDL_DisplayModeData *data;
     DEVMODE devmode;
@@ -210,8 +219,11 @@ static SDL_bool WIN_GetDisplayMode(SDL_VideoDevice *_this, HMONITOR hMonitor, LP
     /* Fill in the mode information */
     WIN_UpdateDisplayMode(_this, deviceName, index, mode);
 
-    if (orientation) {
-        *orientation = WIN_GetDisplayOrientation(&devmode);
+    if (natural_orientation) {
+        *natural_orientation = WIN_GetNaturalOrientation(&devmode);
+    }
+    if (current_orientation) {
+        *current_orientation = WIN_GetDisplayOrientation(&devmode);
     }
 
     return SDL_TRUE;
@@ -324,14 +336,15 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI
     SDL_VideoDisplay display;
     SDL_DisplayData *displaydata;
     SDL_DisplayMode mode;
-    SDL_DisplayOrientation orientation;
+    SDL_DisplayOrientation natural_orientation;
+    SDL_DisplayOrientation current_orientation;
     float content_scale = WIN_GetContentScale(_this, hMonitor);
 
 #ifdef DEBUG_MODES
     SDL_Log("Display: %s\n", WIN_StringToUTF8W(info->szDevice));
 #endif
 
-    if (!WIN_GetDisplayMode(_this, hMonitor, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &orientation)) {
+    if (!WIN_GetDisplayMode(_this, hMonitor, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &natural_orientation, &current_orientation)) {
         return;
     }
 
@@ -371,7 +384,7 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI
                 if (moved || changed_bounds) {
                     SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_MOVED, 0);
                 }
-                SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_ORIENTATION, orientation);
+                SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_ORIENTATION, current_orientation);
                 SDL_SetDisplayContentScale(existing_display, content_scale);
             }
             goto done;
@@ -398,7 +411,8 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI
     }
 
     display.desktop_mode = mode;
-    display.orientation = orientation;
+    display.natural_orientation = natural_orientation;
+    display.current_orientation = current_orientation;
     display.content_scale = content_scale;
     display.device = _this;
     display.driverdata = displaydata;
@@ -514,7 +528,7 @@ int WIN_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
     SDL_DisplayMode mode;
 
     for (i = 0;; ++i) {
-        if (!WIN_GetDisplayMode(_this, data->MonitorHandle, data->DeviceName, i, &mode, NULL)) {
+        if (!WIN_GetDisplayMode(_this, data->MonitorHandle, data->DeviceName, i, &mode, NULL, NULL)) {
             break;
         }
         if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {