From e5ca416e2f2f17d6a4213094b547ccb6d44d4e56 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Date: Mon, 23 Nov 2015 11:39:20 +0100
Subject: [PATCH] Windows QPA: Add API for setting the application orientation
 preference.

Dynamically load the Win32 API functions for setting the rotation
preference and map this to static functions taking a
Qt::ScreenOrientation in QWindowsScreen.

Task-number: QTBUG-49541
Change-Id: I1c81cf6274d79a023a2ee755dd7c085ffd7cc015
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
---
 .../platforms/windows/qwindowscontext.cpp     |  5 +-
 .../platforms/windows/qwindowscontext.h       |  6 ++
 .../platforms/windows/qwindowsscreen.cpp      | 68 +++++++++++++++++++
 .../platforms/windows/qwindowsscreen.h        |  3 +
 4 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 5cda6379de4..f2f6402889f 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -177,7 +177,8 @@ QWindowsUser32DLL::QWindowsUser32DLL() :
     isHungAppWindow(0), isTouchWindow(0),
     registerTouchWindow(0), unregisterTouchWindow(0),
     getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0),
-    addClipboardFormatListener(0), removeClipboardFormatListener(0)
+    addClipboardFormatListener(0), removeClipboardFormatListener(0),
+    getDisplayAutoRotationPreferences(0), setDisplayAutoRotationPreferences(0)
 {
 }
 
@@ -198,6 +199,8 @@ void QWindowsUser32DLL::init()
         addClipboardFormatListener = (AddClipboardFormatListener)library.resolve("AddClipboardFormatListener");
         removeClipboardFormatListener = (RemoveClipboardFormatListener)library.resolve("RemoveClipboardFormatListener");
     }
+    getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences");
+    setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences");
 }
 
 bool QWindowsUser32DLL::initTouch()
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 641e3ed41fe..d08fc8f726a 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -94,6 +94,8 @@ struct QWindowsUser32DLL
     typedef BOOL (WINAPI *SetProcessDPIAware)();
     typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND);
     typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND);
+    typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *);
+    typedef BOOL (WINAPI *SetDisplayAutoRotationPreferences)(DWORD);
 
     // Functions missing in Q_CC_GNU stub libraries.
     SetLayeredWindowAttributes setLayeredWindowAttributes;
@@ -116,6 +118,10 @@ struct QWindowsUser32DLL
     // Clipboard listeners, Windows Vista onwards
     AddClipboardFormatListener addClipboardFormatListener;
     RemoveClipboardFormatListener removeClipboardFormatListener;
+
+    // Rotation API
+    GetDisplayAutoRotationPreferences getDisplayAutoRotationPreferences;
+    SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences;
 };
 
 struct QWindowsShell32DLL
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index e69665e4a9b..02696c87cde 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -325,6 +325,74 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData)
     }
 }
 
+enum OrientationPreference // matching Win32 API ORIENTATION_PREFERENCE
+#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC)
+    : DWORD
+#endif
+{
+    orientationPreferenceNone = 0,
+    orientationPreferenceLandscape = 0x1,
+    orientationPreferencePortrait = 0x2,
+    orientationPreferenceLandscapeFlipped = 0x4,
+    orientationPreferencePortraitFlipped = 0x8
+};
+
+bool QWindowsScreen::setOrientationPreference(Qt::ScreenOrientation o)
+{
+    bool result = false;
+#ifndef Q_OS_WINCE
+    if (QWindowsContext::user32dll.setDisplayAutoRotationPreferences) {
+        DWORD orientationPreference = 0;
+        switch (o) {
+        case Qt::PrimaryOrientation:
+            orientationPreference = orientationPreferenceNone;
+            break;
+        case Qt::PortraitOrientation:
+            orientationPreference = orientationPreferencePortrait;
+            break;
+        case Qt::LandscapeOrientation:
+            orientationPreference = orientationPreferenceLandscape;
+            break;
+        case Qt::InvertedPortraitOrientation:
+            orientationPreference = orientationPreferencePortraitFlipped;
+            break;
+        case Qt::InvertedLandscapeOrientation:
+            orientationPreference = orientationPreferenceLandscapeFlipped;
+            break;
+        }
+        result = QWindowsContext::user32dll.setDisplayAutoRotationPreferences(orientationPreference);
+    }
+#endif // !Q_OS_WINCE
+    return result;
+}
+
+Qt::ScreenOrientation QWindowsScreen::orientationPreference()
+{
+    Qt::ScreenOrientation result = Qt::PrimaryOrientation;
+#ifndef Q_OS_WINCE
+    if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences) {
+        DWORD orientationPreference = 0;
+        if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences(&orientationPreference)) {
+            switch (orientationPreference) {
+            case orientationPreferenceLandscape:
+                result = Qt::LandscapeOrientation;
+                break;
+            case orientationPreferencePortrait:
+                result = Qt::PortraitOrientation;
+                break;
+            case orientationPreferenceLandscapeFlipped:
+                result = Qt::InvertedLandscapeOrientation;
+                break;
+            case orientationPreferencePortraitFlipped:
+                result = Qt::InvertedPortraitOrientation;
+                break;
+            }
+        }
+    }
+#endif // !Q_OS_WINCE
+    return result;
+}
+
 /*!
     \brief Queries ClearType settings to check the pixel layout
 */
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 879cda047e5..b46bd88ec63 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -97,6 +97,9 @@ public:
     QPixmap grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const Q_DECL_OVERRIDE;
     QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE;
 
+    static Qt::ScreenOrientation orientationPreference();
+    static bool setOrientationPreference(Qt::ScreenOrientation o);
+
     inline void handleChanges(const QWindowsScreenData &newData);
 
 #ifndef QT_NO_CURSOR
-- 
GitLab