Skip to content

Commit

Permalink
Added the concept of display natural orientation
Browse files Browse the repository at this point in the history
Also renamed SDL_GetDisplayOrientation() SDL_GetDisplayCurrentOrientation()

The natural orientation of the primary display is the frame of reference for accelerometer and gyro sensor readings.
  • Loading branch information
slouken committed Jun 17, 2023
1 parent 8de6ce7 commit e6d1ba2
Show file tree
Hide file tree
Showing 20 changed files with 208 additions and 74 deletions.
65 changes: 40 additions & 25 deletions android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public static void debugSource(int sources, String prefix) {
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
Expand Down Expand Up @@ -437,9 +437,9 @@ public void onClick(DialogInterface dialog,int id) {
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) */) {
Expand Down Expand Up @@ -543,33 +543,47 @@ protected void onStart() {
}
}

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;
}

Expand Down Expand Up @@ -987,7 +1001,8 @@ public static native void onNativeTouch(int touchDevId, int pointerFingerId,
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();
Expand Down
32 changes: 16 additions & 16 deletions android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
Original file line number Diff line number Diff line change
Expand Up @@ -325,36 +325,36 @@ public void onSensorChanged(SensorEvent event) {

// 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,
Expand Down
5 changes: 5 additions & 0 deletions build-scripts/SDL_migration.cocci
Original file line number Diff line number Diff line change
Expand Up @@ -2668,3 +2668,8 @@ typedef SDL_cond, SDL_Condition;
- SDL_TLSCleanup
+ SDL_CleanupTLS
(...)
@@
@@
- SDL_GetDisplayOrientation
+ SDL_GetDisplayCurrentOrientation
(...)
1 change: 1 addition & 0 deletions docs/README-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 2 additions & 0 deletions include/SDL3/SDL_oldnames.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions include/SDL3/SDL_sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 */
Expand Down
15 changes: 14 additions & 1 deletion include/SDL3/SDL_video.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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.
Expand Down
54 changes: 46 additions & 8 deletions src/core/android/SDL_android.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) },
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion src/core/android/SDL_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ SDL3_0.0.0 {
SDL_GetDisplayForPoint;
SDL_GetDisplayForRect;
SDL_GetDisplayName;
SDL_GetDisplayOrientation;
SDL_GetDisplayCurrentOrientation;
SDL_GetDisplayUsableBounds;
SDL_GetError;
SDL_GetErrorMsg;
Expand Down Expand Up @@ -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: *;
};
3 changes: 2 additions & 1 deletion src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
3 changes: 2 additions & 1 deletion src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Loading

0 comments on commit e6d1ba2

Please sign in to comment.