From 74d2249e37ba8cdefba8d90345a620dc6adfa411 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 13 Sep 2013 13:11:45 +0200 Subject: Android: handle inverted orientations Add logic to detect InvertedPortrait and InvertedLandscape orientations and implement QPlatformScreen::nativeOrientation() for Android. Task-number: QTBUG-32144 Change-Id: I294506714ea0faa9eacd7a15e1cfc45342659964 Reviewed-by: BogDan Vatra --- .../qtproject/qt5/android/QtActivityDelegate.java | 25 +++++++++---- .../src/org/qtproject/qt5/android/QtNative.java | 2 +- .../platforms/android/src/androidjnimain.cpp | 42 ++++++++++++++++------ .../android/src/opengl/qeglfshooks_android.cpp | 11 ++++++ .../android/src/qandroidplatformintegration.cpp | 10 ++++++ .../android/src/qandroidplatformintegration.h | 5 +++ .../android/src/raster/qandroidplatformscreen.cpp | 10 ++++++ .../android/src/raster/qandroidplatformscreen.h | 2 ++ src/plugins/platforms/eglfs/qeglfshooks.h | 2 ++ src/plugins/platforms/eglfs/qeglfshooks_stub.cpp | 10 ++++++ src/plugins/platforms/eglfs/qeglfsscreen.cpp | 9 +++++ src/plugins/platforms/eglfs/qeglfsscreen.h | 2 ++ 12 files changed, 111 insertions(+), 19 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 8dc804cce4..dff437c3d8 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -70,6 +70,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; +import android.view.Surface; public class QtActivityDelegate { @@ -93,7 +94,8 @@ public class QtActivityDelegate private static String m_environmentVariables = null; private static String m_applicationParameters = null; - private int m_currentOrientation = Configuration.ORIENTATION_UNDEFINED; + private int m_currentRotation = -1; // undefined + private int m_nativeOrientation = Configuration.ORIENTATION_UNDEFINED; private String m_mainLib; private long m_metaState; @@ -587,7 +589,17 @@ public class QtActivityDelegate m_layout.bringChildToFront(m_surface); m_activity.registerForContextMenu(m_layout); - m_currentOrientation = m_activity.getResources().getConfiguration().orientation; + int orientation = m_activity.getResources().getConfiguration().orientation; + int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation(); + boolean rot90 = (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270); + boolean currentlyLandscape = (orientation == Configuration.ORIENTATION_LANDSCAPE); + if ((currentlyLandscape && !rot90) || (!currentlyLandscape && rot90)) + m_nativeOrientation = Configuration.ORIENTATION_LANDSCAPE; + else + m_nativeOrientation = Configuration.ORIENTATION_PORTRAIT; + + QtNative.handleOrientationChanged(rotation, m_nativeOrientation); + m_currentRotation = rotation; } public void onConfigurationChanged(Configuration configuration) @@ -597,13 +609,12 @@ public class QtActivityDelegate } catch (Exception e) { e.printStackTrace(); } - - if (configuration.orientation != m_currentOrientation - && m_currentOrientation != Configuration.ORIENTATION_UNDEFINED) { - QtNative.handleOrientationChanged(configuration.orientation); + int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation(); + if (rotation != m_currentRotation) { + QtNative.handleOrientationChanged(rotation, m_nativeOrientation); } - m_currentOrientation = configuration.orientation; + m_currentRotation = rotation; } public void onDestroy() diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 51f00a73c6..244654786d 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -553,7 +553,7 @@ public class QtNative double XDpi, double YDpi, double scaledDensity); - public static native void handleOrientationChanged(int newOrientation); + public static native void handleOrientationChanged(int newRotation, int nativeOrientation); // screen methods // pointer methods diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index b426839f3d..5941737fde 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -675,17 +675,37 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state)); } -static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newOrientation) +static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newRotation, jint nativeOrientation) { - if (m_androidPlatformIntegration == 0) - return; - - Qt::ScreenOrientation screenOrientation = newOrientation == 1 - ? Qt::PortraitOrientation - : Qt::LandscapeOrientation; - QPlatformScreen *screen = m_androidPlatformIntegration->screen(); - QWindowSystemInterface::handleScreenOrientationChange(screen->screen(), - screenOrientation); + // Array of orientations rotated in 90 degree increments, counterclockwise + // (same direction as Android measures angles) + static const Qt::ScreenOrientation orientations[] = { + Qt::PortraitOrientation, + Qt::LandscapeOrientation, + Qt::InvertedPortraitOrientation, + Qt::InvertedLandscapeOrientation + }; + + // The Android API defines the following constants: + // ROTATION_0 : 0 + // ROTATION_90 : 1 + // ROTATION_180 : 2 + // ROTATION_270 : 3 + // ORIENTATION_PORTRAIT : 1 + // ORIENTATION_LANDSCAPE : 2 + + // and newRotation is how much the current orientation is rotated relative to nativeOrientation + + // which means that we can be really clever here :) + Qt::ScreenOrientation screenOrientation = orientations[(nativeOrientation - 1 + newRotation) % 4]; + Qt::ScreenOrientation native = orientations[nativeOrientation - 1]; + + QAndroidPlatformIntegration::setScreenOrientation(screenOrientation, native); + if (m_androidPlatformIntegration) { + QPlatformScreen *screen = m_androidPlatformIntegration->screen(); + QWindowSystemInterface::handleScreenOrientationChange(screen->screen(), + screenOrientation); + } } static JNINativeMethod methods[] = { @@ -702,7 +722,7 @@ static JNINativeMethod methods[] = { {"unlockSurface", "()V", (void *)unlockSurface}, {"updateWindow", "()V", (void *)updateWindow}, {"updateApplicationState", "(I)V", (void *)updateApplicationState}, - {"handleOrientationChanged", "(I)V", (void *)handleOrientationChanged} + {"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged} }; #define FIND_AND_CHECK_CLASS(CLASS_NAME) \ diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp index 0c26aadc53..917942128f 100644 --- a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp +++ b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp @@ -57,6 +57,8 @@ public: QSize screenSize() const; QSizeF physicalScreenSize() const; QDpi logicalDpi() const; + Qt::ScreenOrientation orientation() const; + Qt::ScreenOrientation nativeOrientation() const; int screenDepth() const; QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; EGLNativeWindowType createNativeWindow(const QSize &size, const QSurfaceFormat &format); @@ -94,6 +96,15 @@ QDpi QEglFSAndroidHooks::logicalDpi() const return QDpi(lDpi, lDpi); } +Qt::ScreenOrientation QEglFSAndroidHooks::orientation() const +{ + return QAndroidPlatformIntegration::m_orientation; +} + +Qt::ScreenOrientation QEglFSAndroidHooks::nativeOrientation() const +{ + return QAndroidPlatformIntegration::m_nativeOrientation; +} EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(const QSize &size, const QSurfaceFormat &format) { diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index d7ed3499af..358c3caf89 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -76,6 +76,9 @@ int QAndroidPlatformIntegration::m_defaultGeometryHeight = 455; int QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth = 50; int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71; +Qt::ScreenOrientation QAndroidPlatformIntegration::m_orientation = Qt::PrimaryOrientation; +Qt::ScreenOrientation QAndroidPlatformIntegration::m_nativeOrientation = Qt::PrimaryOrientation; + void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource) { if (resource=="JavaVM") @@ -268,6 +271,13 @@ void QAndroidPlatformIntegration::setDefaultDesktopSize(int gw, int gh) m_defaultGeometryHeight = gh; } +void QAndroidPlatformIntegration::setScreenOrientation(Qt::ScreenOrientation currentOrientation, + Qt::ScreenOrientation nativeOrientation) +{ + m_orientation = currentOrientation; + m_nativeOrientation = nativeOrientation; +} + #ifndef QT_NO_ACCESSIBILITY QPlatformAccessibility *QAndroidPlatformIntegration::accessibility() const { diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h index 20aa52cf22..e7bb55b3d5 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h @@ -129,6 +129,8 @@ public: void resumeApp(); static void setDefaultDisplayMetrics(int gw, int gh, int sw, int sh); static void setDefaultDesktopSize(int gw, int gh); + static void setScreenOrientation(Qt::ScreenOrientation currentOrientation, + Qt::ScreenOrientation nativeOrientation); static QSize defaultDesktopSize() { @@ -156,6 +158,9 @@ private: static int m_defaultPhysicalSizeWidth; static int m_defaultPhysicalSizeHeight; + static Qt::ScreenOrientation m_orientation; + static Qt::ScreenOrientation m_nativeOrientation; + QPlatformFontDatabase *m_androidFDB; QImage *m_FbScreenImage; QPainter *m_compositePainter; diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp index cf24d68ab5..0250a6122c 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp @@ -75,3 +75,13 @@ QDpi QAndroidPlatformScreen::logicalDpi() const qreal lDpi = QtAndroid::scaledDensity() * 72; return QDpi(lDpi, lDpi); } + +Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const +{ + return QAndroidPlatformIntegration::m_orientation; +} + +Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const +{ + return QAndroidPlatformIntegration::m_nativeOrientation; +} diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h index cfd503d611..9f8807b995 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h @@ -51,6 +51,8 @@ public: QAndroidPlatformScreen(); void topWindowChanged(QWindow *w); QDpi logicalDpi() const; + Qt::ScreenOrientation orientation() const; + Qt::ScreenOrientation nativeOrientation() const; public slots: QRegion doRedraw(); diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h index 461ffa0f25..1cd1380994 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks.h +++ b/src/plugins/platforms/eglfs/qeglfshooks.h @@ -63,6 +63,8 @@ public: virtual QSizeF physicalScreenSize() const; virtual QSize screenSize() const; virtual QDpi logicalDpi() const; + virtual Qt::ScreenOrientation nativeOrientation() const; + virtual Qt::ScreenOrientation orientation() const; virtual int screenDepth() const; virtual QImage::Format screenFormat() const; virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index d04803d8e3..4dc0783d43 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -192,6 +192,16 @@ QDpi QEglFSHooks::logicalDpi() const 25.4 * s.height() / ps.height()); } +Qt::ScreenOrientation QEglFSHooks::nativeOrientation() const +{ + return Qt::PrimaryOrientation; +} + +Qt::ScreenOrientation QEglFSHooks::orientation() const +{ + return Qt::PrimaryOrientation; +} + int QEglFSHooks::screenDepth() const { static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt(); diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 1fe8bcc11b..a726215e67 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -90,6 +90,15 @@ QDpi QEglFSScreen::logicalDpi() const return QEglFSHooks::hooks()->logicalDpi(); } +Qt::ScreenOrientation QEglFSScreen::nativeOrientation() const +{ + return QEglFSHooks::hooks()->nativeOrientation(); +} + +Qt::ScreenOrientation QEglFSScreen::orientation() const +{ + return QEglFSHooks::hooks()->orientation(); +} QPlatformCursor *QEglFSScreen::cursor() const { diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index b04c85797f..06cafa20c8 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -65,6 +65,8 @@ public: QSizeF physicalSize() const; QDpi logicalDpi() const; + Qt::ScreenOrientation nativeOrientation() const; + Qt::ScreenOrientation orientation() const; QPlatformCursor *cursor() const; -- cgit v1.2.3