From e6d1ba2a17a7e157d5aa36957f16842ac17cba89 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 17 Jun 2023 00:52:40 -0700 Subject: [PATCH] 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. --- .../main/java/org/libsdl/app/SDLActivity.java | 67 ++++++++++++------- .../main/java/org/libsdl/app/SDLSurface.java | 40 +++++------ build-scripts/SDL_migration.cocci | 5 ++ docs/README-migration.md | 1 + include/SDL3/SDL_oldnames.h | 2 + include/SDL3/SDL_sensor.h | 4 +- include/SDL3/SDL_video.h | 15 ++++- src/core/android/SDL_android.c | 54 ++++++++++++--- src/core/android/SDL_android.h | 3 +- src/dynapi/SDL_dynapi.sym | 3 +- src/dynapi/SDL_dynapi_overrides.h | 3 +- src/dynapi/SDL_dynapi_procs.h | 3 +- src/events/SDL_displayevents.c | 4 +- src/test/SDL_test_common.c | 9 ++- src/video/SDL_sysvideo.h | 3 +- src/video/SDL_video.c | 23 ++++++- src/video/android/SDL_androidvideo.c | 3 +- src/video/uikit/SDL_uikitmodes.m | 11 +++ src/video/wayland/SDL_waylandvideo.c | 7 +- src/video/windows/SDL_windowsmodes.c | 32 ++++++--- 20 files changed, 213 insertions(+), 79 deletions(-) diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index 629dabb16..30a3fe1a8 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/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; - - case Surface.ROTATION_180: - result = SDL_ORIENTATION_PORTRAIT_FLIPPED; - break; - - case Surface.ROTATION_270: - result = SDL_ORIENTATION_LANDSCAPE_FLIPPED; - break; + } else { + result = SDL_ORIENTATION_PORTRAIT; + } } + return result; + } + public static int getCurrentRotation() { + int result = 0; + + 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(); diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java index a14234309..c4c144914 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java +++ b/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_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; - break; - case Surface.ROTATION_180: - x = -event.values[0]; - y = -event.values[1]; - newOrientation = SDLActivity.SDL_ORIENTATION_PORTRAIT_FLIPPED; - break; case Surface.ROTATION_0: default: x = event.values[0]; y = event.values[1]; - newOrientation = SDLActivity.SDL_ORIENTATION_PORTRAIT; + newRotation = 0; + break; + case Surface.ROTATION_90: + x = -event.values[1]; + y = event.values[0]; + newRotation = 90; + break; + case Surface.ROTATION_180: + x = -event.values[0]; + y = -event.values[1]; + newRotation = 180; + break; + 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, diff --git a/build-scripts/SDL_migration.cocci b/build-scripts/SDL_migration.cocci index 99d9c0487..a9afa8082 100644 --- a/build-scripts/SDL_migration.cocci +++ b/build-scripts/SDL_migration.cocci @@ -2668,3 +2668,8 @@ typedef SDL_cond, SDL_Condition; - SDL_TLSCleanup + SDL_CleanupTLS (...) +@@ +@@ +- SDL_GetDisplayOrientation ++ SDL_GetDisplayCurrentOrientation + (...) diff --git a/docs/README-migration.md b/docs/README-migration.md index 6d649e52a..6199d7a93 100644 --- a/docs/README-migration.md +++ b/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() diff --git a/include/SDL3/SDL_oldnames.h b/include/SDL3/SDL_oldnames.h index 9378a9c90..a79f0cec8 100644 --- a/include/SDL3/SDL_oldnames.h +++ b/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 diff --git a/include/SDL3/SDL_sensor.h b/include/SDL3/SDL_sensor.h index dda75f036..1b8069533 100644 --- a/include/SDL3/SDL_sensor.h +++ b/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 */ diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index c6f6fa150..664777e8c 100644 --- a/include/SDL3/SDL_video.h +++ b/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. diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 8238979c3..1d3909b69 100644 --- a/src/core/android/SDL_android.c +++ b/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 displayOrientation; + return displayNaturalOrientation; +} + +SDL_DisplayOrientation Android_JNI_GetDisplayCurrentOrientation(void) +{ + return displayCurrentOrientation; } void *Android_JNI_GetAudioBuffer(void) diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index 3e318ac9e..a245af980 100644 --- a/src/core/android/SDL_android.h +++ b/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); diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index d10df5474..b06d9f1af 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/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: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index c3635845f..6a5ad66de 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/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 diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 5bbe6227b..7557f35ce 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/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) diff --git a/src/events/SDL_displayevents.c b/src/events/SDL_displayevents.c index 803d24d43..edccb033f 100644 --- a/src/events/SDL_displayevents.c +++ b/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; diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index d77b65212..3e5e370f7 100644 --- a/src/test/SDL_test_common.c +++ b/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; diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 9da28a1c3..db67e46af 100644 --- a/src/video/SDL_sysvideo.h +++ b/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; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 925b411e0..e211f5ad4 100644 --- a/src/video/SDL_video.c +++ b/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) diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c index 7804fe9de..021607ce5 100644 --- a/src/video/android/SDL_androidvideo.c +++ b/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(); diff --git a/src/video/uikit/SDL_uikitmodes.m b/src/video/uikit/SDL_uikitmodes.m index 220589d10..3ce798102 100644 --- a/src/video/uikit/SDL_uikitmodes.m +++ b/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 */ diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index ba6aecf31..79358c23b 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/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); diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c index 05f3e1d64..018f0e13c 100644 --- a/src/video/windows/SDL_windowsmodes.c +++ b/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, ¤t_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)) {