summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/include/EGL/eglplatform.h10
-rw-r--r--src/3rdparty/angle/src/compiler/osinclude.h35
-rw-r--r--src/3rdparty/angle/src/compiler/ossource_posix.cpp8
-rw-r--r--src/3rdparty/angle/src/compiler/ossource_win.cpp8
-rw-r--r--src/3rdparty/angle/src/compiler/ossource_winrt.cpp75
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.cpp8
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.h4
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.cpp35
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.h7
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL.cpp4
-rw-r--r--src/3rdparty/angle/src/libEGL/main.cpp40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.cpp39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/precompiled.h15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp23
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h27
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp29
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/utilities.cpp53
-rw-r--r--src/3rdparty/libpng/pngpriv.h2
-rw-r--r--src/angle/patches/0012-ANGLE-Support-WinRT.patch1131
-rw-r--r--src/angle/src/common/common.pri2
-rw-r--r--src/angle/src/compiler/translator_common.pro7
-rw-r--r--src/angle/src/config.pri5
-rw-r--r--src/corelib/global/qglobal.cpp15
-rw-r--r--src/corelib/global/qglobal.h7
-rw-r--r--src/corelib/global/qnumeric.cpp136
-rw-r--r--src/corelib/global/qnumeric.h3
-rw-r--r--src/corelib/io/io.pri6
-rw-r--r--src/corelib/io/qdatastream.cpp3
-rw-r--r--src/corelib/io/qdatastream.h5
-rw-r--r--src/corelib/io/qsettings.cpp67
-rw-r--r--src/corelib/io/qstandardpaths_winrt.cpp74
-rw-r--r--src/corelib/kernel/kernel.pri18
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp6
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp394
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt_p.h168
-rw-r--r--src/corelib/kernel/qfunctions_p.h2
-rw-r--r--src/corelib/kernel/qfunctions_winrt.cpp105
-rw-r--r--src/corelib/kernel/qfunctions_winrt.h122
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp4
-rw-r--r--src/corelib/thread/qmutex_win.cpp9
-rw-r--r--src/corelib/thread/qthread.cpp2
-rw-r--r--src/corelib/thread/qthread_p.h9
-rw-r--r--src/corelib/thread/qthread_win.cpp154
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp11
-rw-r--r--src/corelib/tools/qtimezone.cpp6
-rw-r--r--src/corelib/tools/tools.pri6
-rw-r--r--src/gui/painting/qbrush.cpp81
-rw-r--r--src/gui/painting/qpen.cpp4
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp1
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.cpp17
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.cpp8
-rw-r--r--src/plugins/platforms/platforms.pro3
-rw-r--r--src/plugins/platforms/winrt/blit.hlsl14
-rw-r--r--src/plugins/platforms/winrt/main.cpp74
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.cpp393
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.h77
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.cpp153
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.h77
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp63
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.h63
-rw-r--r--src/plugins/platforms/winrt/qwinrteventdispatcher.cpp79
-rw-r--r--src/plugins/platforms/winrt/qwinrteventdispatcher.h80
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.cpp64
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.h57
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.cpp300
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.h121
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp192
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.h86
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp1012
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h163
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.cpp138
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.h80
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp119
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h72
-rw-r--r--src/plugins/platforms/winrt/winrt.json3
-rw-r--r--src/plugins/platforms/winrt/winrt.pro55
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp1
-rw-r--r--src/src.pro8
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp2
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp2
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp4
-rw-r--r--src/widgets/itemviews/qfileiconprovider.cpp8
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp4
-rw-r--r--src/widgets/kernel/qwidget.cpp2
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp6
-rw-r--r--src/widgets/kernel/win.pri2
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp20
-rw-r--r--src/widgets/util/util.pri2
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp4
93 files changed, 6473 insertions, 158 deletions
diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h
index 34283f2e90..eb15ae569d 100644
--- a/src/3rdparty/angle/include/EGL/eglplatform.h
+++ b/src/3rdparty/angle/include/EGL/eglplatform.h
@@ -67,7 +67,15 @@
* implementations.
*/
-#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
+
+struct IUnknown;
+
+typedef int EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef IUnknown *EGLNativeWindowType;
+
+#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
diff --git a/src/3rdparty/angle/src/compiler/osinclude.h b/src/3rdparty/angle/src/compiler/osinclude.h
index d8bb1a797c..60177d5fe5 100644
--- a/src/3rdparty/angle/src/compiler/osinclude.h
+++ b/src/3rdparty/angle/src/compiler/osinclude.h
@@ -13,27 +13,26 @@
//
#if defined(_WIN32) || defined(_WIN64)
+#define STRICT
+#define VC_EXTRALEAN 1
+#include <windows.h>
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+#define ANGLE_OS_WINRT
+#else
#define ANGLE_OS_WIN
+#endif
#elif defined(__APPLE__) || defined(__linux__) || \
defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__sun) || defined(ANDROID) || \
defined(__GLIBC__) || defined(__GNU__) || \
defined(__QNX__)
#define ANGLE_OS_POSIX
-#else
-#error Unsupported platform.
-#endif
-
-#if defined(ANGLE_OS_WIN)
-#define STRICT
-#define VC_EXTRALEAN 1
-#include <windows.h>
-#elif defined(ANGLE_OS_POSIX)
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
-#endif // ANGLE_OS_WIN
-
+#else
+#error Unsupported platform.
+#endif
#include "compiler/debug.h"
@@ -43,23 +42,17 @@
#if defined(ANGLE_OS_WIN)
typedef DWORD OS_TLSIndex;
#define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
+#elif defined(ANGLE_OS_WINRT)
+typedef size_t OS_TLSIndex;
+#define OS_INVALID_TLS_INDEX ((DWORD)0xFFFFFF)
#elif defined(ANGLE_OS_POSIX)
typedef pthread_key_t OS_TLSIndex;
#define OS_INVALID_TLS_INDEX (static_cast<OS_TLSIndex>(-1))
#endif // ANGLE_OS_WIN
OS_TLSIndex OS_AllocTLSIndex();
+void *OS_GetTLSValue(OS_TLSIndex nIndex);
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
-inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
-{
- ASSERT(nIndex != OS_INVALID_TLS_INDEX);
-#if defined(ANGLE_OS_WIN)
- return TlsGetValue(nIndex);
-#elif defined(ANGLE_OS_POSIX)
- return pthread_getspecific(nIndex);
-#endif // ANGLE_OS_WIN
-}
-
#endif // __OSINCLUDE_H
diff --git a/src/3rdparty/angle/src/compiler/ossource_posix.cpp b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
index 1e1e699aeb..35510c1af5 100644
--- a/src/3rdparty/angle/src/compiler/ossource_posix.cpp
+++ b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
@@ -33,6 +33,14 @@ OS_TLSIndex OS_AllocTLSIndex()
}
+void *OS_GetTLSValue(OS_TLSIndex nIndex)
+{
+ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+
+ return pthread_getspecific(nIndex);
+}
+
+
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
{
if (nIndex == OS_INVALID_TLS_INDEX) {
diff --git a/src/3rdparty/angle/src/compiler/ossource_win.cpp b/src/3rdparty/angle/src/compiler/ossource_win.cpp
index 89922fef3f..708a1ad311 100644
--- a/src/3rdparty/angle/src/compiler/ossource_win.cpp
+++ b/src/3rdparty/angle/src/compiler/ossource_win.cpp
@@ -29,6 +29,14 @@ OS_TLSIndex OS_AllocTLSIndex()
}
+void *OS_GetTLSValue(OS_TLSIndex nIndex)
+{
+ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+
+ return TlsGetValue(nIndex);
+}
+
+
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
{
if (nIndex == OS_INVALID_TLS_INDEX) {
diff --git a/src/3rdparty/angle/src/compiler/ossource_winrt.cpp b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
new file mode 100644
index 0000000000..84443abc02
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/osinclude.h"
+//
+// This file contains contains Windows Runtime specific functions
+//
+
+#if !defined(ANGLE_OS_WINRT)
+#error Trying to build a WinRT specific file in a non-WinRT build.
+#endif
+
+#include <vector>
+
+
+//
+// Thread Local Storage Operations
+//
+__declspec(thread) std::vector<void *> *tls = nullptr;
+__declspec(thread) std::vector<OS_TLSIndex> *freeIndices = nullptr;
+
+OS_TLSIndex OS_AllocTLSIndex()
+{
+ if (!tls)
+ tls = new std::vector<void*>;
+
+ if (freeIndices && !freeIndices->empty()) {
+ OS_TLSIndex index = freeIndices->back();
+ freeIndices->pop_back();
+ return index;
+ } else {
+ tls->push_back(nullptr);
+ return tls->size() - 1;
+ }
+}
+
+
+void *OS_GetTLSValue(OS_TLSIndex nIndex)
+{
+ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+ ASSERT(tls);
+
+ return tls->at(nIndex);
+}
+
+
+bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+{
+ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
+ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
+ return false;
+ }
+
+ tls->at(nIndex) = lpvValue;
+ return true;
+}
+
+
+bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
+{
+ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
+ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
+ return false;
+ }
+
+ if (!freeIndices)
+ freeIndices = new std::vector<OS_TLSIndex>;
+
+ freeIndices->push_back(nIndex);
+
+ return true;
+}
diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
index a382c3b1eb..14973aff30 100644
--- a/src/3rdparty/angle/src/libEGL/Display.cpp
+++ b/src/3rdparty/angle/src/libEGL/Display.cpp
@@ -186,7 +186,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
-EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
+EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
{
const Config *configuration = mConfigSet.get(config);
EGLint postSubBufferSupported = EGL_FALSE;
@@ -456,7 +456,7 @@ bool Display::isValidSurface(egl::Surface *surface)
return mSurfaceSet.find(surface) != mSurfaceSet.end();
}
-bool Display::hasExistingWindowSurface(HWND window)
+bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
{
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
@@ -471,7 +471,6 @@ bool Display::hasExistingWindowSurface(HWND window)
void Display::initExtensionString()
{
- HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
bool shareHandleSupported = mRenderer->getShareHandleSupport();
mExtensionString = "";
@@ -487,10 +486,13 @@ void Display::initExtensionString()
mExtensionString += "EGL_ANGLE_query_surface_pointer ";
+#if !defined(ANGLE_OS_WINRT)
+ HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
if (swiftShader)
{
mExtensionString += "EGL_ANGLE_software_display ";
}
+#endif
if (shareHandleSupported)
{
diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
index 58c3940331..5d55410440 100644
--- a/src/3rdparty/angle/src/libEGL/Display.h
+++ b/src/3rdparty/angle/src/libEGL/Display.h
@@ -40,7 +40,7 @@ class Display
bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
- EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
+ EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
@@ -51,7 +51,7 @@ class Display
bool isValidConfig(EGLConfig config);
bool isValidContext(gl::Context *context);
bool isValidSurface(egl::Surface *surface);
- bool hasExistingWindowSurface(HWND window);
+ bool hasExistingWindowSurface(EGLNativeWindowType window);
rx::Renderer *getRenderer() { return mRenderer; };
diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
index b47a7bcc20..abc6d7d3b9 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
@@ -20,10 +20,15 @@
#include "libEGL/main.h"
#include "libEGL/Display.h"
+#if defined(ANGLE_OS_WINRT)
+#include <windows.foundation.h>
+#include <windows.ui.core.h>
+#endif
+
namespace egl
{
-Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
+Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported)
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{
mRenderer = mDisplay->getRenderer();
@@ -96,6 +101,7 @@ bool Surface::resetSwapChain()
if (mWindow)
{
+#if !defined(ANGLE_OS_WINRT)
RECT windowRect;
if (!GetClientRect(getWindowHandle(), &windowRect))
{
@@ -107,6 +113,14 @@ bool Surface::resetSwapChain()
width = windowRect.right - windowRect.left;
height = windowRect.bottom - windowRect.top;
+#else
+ ABI::Windows::Foundation::Rect windowRect;
+ ABI::Windows::UI::Core::ICoreWindow *window;
+ ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
+ window->get_Bounds(&windowRect);
+ width = windowRect.Width;
+ height = windowRect.Height;
+#endif
}
else
{
@@ -226,7 +240,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
return true;
}
-HWND Surface::getWindowHandle()
+EGLNativeWindowType Surface::getWindowHandle()
{
return mWindow;
}
@@ -235,6 +249,7 @@ HWND Surface::getWindowHandle()
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
+#if !defined(ANGLE_OS_WINRT)
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (message == WM_SIZE)
@@ -248,9 +263,13 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
}
+#endif
void Surface::subclassWindow()
{
+#if defined(ANGLE_OS_WINRT)
+ mWindowSubclassed = false;
+#else
if (!mWindow)
{
return;
@@ -274,10 +293,12 @@ void Surface::subclassWindow()
SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
mWindowSubclassed = true;
+#endif
}
void Surface::unsubclassWindow()
{
+#if !defined(ANGLE_OS_WINRT)
if(!mWindowSubclassed)
{
return;
@@ -300,10 +321,12 @@ void Surface::unsubclassWindow()
RemoveProp(mWindow, kSurfaceProperty);
RemoveProp(mWindow, kParentWndProc);
mWindowSubclassed = false;
+#endif
}
bool Surface::checkForOutOfDateSwapChain()
{
+#if !defined(ANGLE_OS_WINRT)
RECT client;
if (!GetClientRect(getWindowHandle(), &client))
{
@@ -314,6 +337,14 @@ bool Surface::checkForOutOfDateSwapChain()
// Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
int clientWidth = client.right - client.left;
int clientHeight = client.bottom - client.top;
+#else
+ ABI::Windows::Foundation::Rect windowRect;
+ ABI::Windows::UI::Core::ICoreWindow *window;
+ ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
+ window->get_Bounds(&windowRect);
+ int clientWidth = windowRect.Width;
+ int clientHeight = windowRect.Height;
+#endif
bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
if (mSwapIntervalDirty)
diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h
index 938b800cdd..ae9a380858 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.h
+++ b/src/3rdparty/angle/src/libEGL/Surface.h
@@ -15,6 +15,7 @@
#include <EGL/egl.h>
#include "common/angleutils.h"
+#include "windows.h"
namespace gl
{
@@ -34,7 +35,7 @@ class Config;
class Surface
{
public:
- Surface(Display *display, const egl::Config *config, HWND window, EGLint postSubBufferSupported);
+ Surface(Display *display, const egl::Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported);
Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
~Surface();
@@ -43,7 +44,7 @@ class Surface
void release();
bool resetSwapChain();
- HWND getWindowHandle();
+ EGLNativeWindowType getWindowHandle();
bool swap();
bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
@@ -79,7 +80,7 @@ private:
bool resetSwapChain(int backbufferWidth, int backbufferHeight);
bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
- const HWND mWindow; // Window that the surface is created for.
+ const EGLNativeWindowType mWindow; // Window that the surface is created for.
bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
const egl::Config *mConfig; // EGL config surface was created with
EGLint mHeight; // Height of surface
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
index 6e10c3926d..5bcb5d5959 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
@@ -308,14 +308,16 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
return EGL_NO_SURFACE;
}
+#if !defined(ANGLE_OS_WINRT)
HWND window = (HWND)win;
if (!IsWindow(window))
{
return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
}
+#endif
- return display->createWindowSurface(window, config, attrib_list);
+ return display->createWindowSurface(win, config, attrib_list);
}
catch(std::bad_alloc&)
{
diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
index 7dea5fc74b..964b4b21fd 100644
--- a/src/3rdparty/angle/src/libEGL/main.cpp
+++ b/src/3rdparty/angle/src/libEGL/main.cpp
@@ -1,3 +1,4 @@
+#include "../libGLESv2/precompiled.h"
//
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -12,7 +13,13 @@
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+#if !defined(ANGLE_OS_WINRT)
static DWORD currentTLS = TLS_OUT_OF_INDEXES;
+#else
+static __declspec(thread) void *currentTLS = 0;
+#endif
+
+namespace egl { Current *getCurrent(); }
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
@@ -35,22 +42,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
}
#endif
+#if !defined(ANGLE_OS_WINRT)
currentTLS = TlsAlloc();
if (currentTLS == TLS_OUT_OF_INDEXES)
{
return FALSE;
}
+#endif
}
// Fall throught to initialize index
case DLL_THREAD_ATTACH:
{
- egl::Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
+ egl::Current *current = egl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
TlsSetValue(currentTLS, current);
-
+#endif
current->error = EGL_SUCCESS;
current->API = EGL_OPENGL_ES_API;
current->display = EGL_NO_DISPLAY;
@@ -61,24 +71,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
break;
case DLL_THREAD_DETACH:
{
- void *current = TlsGetValue(currentTLS);
+ egl::Current *current = egl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
LocalFree((HLOCAL)current);
+#else
+ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
+ currentTLS = 0;
+#endif
}
}
break;
case DLL_PROCESS_DETACH:
{
- void *current = TlsGetValue(currentTLS);
+ egl::Current *current = egl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
LocalFree((HLOCAL)current);
}
TlsFree(currentTLS);
+#else
+ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
+ currentTLS = 0;
+ }
+#endif
}
break;
default:
@@ -95,7 +116,16 @@ namespace egl
Current *getCurrent()
{
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
- return (Current*)TlsGetValue(currentTLS);
+#if !defined(ANGLE_OS_WINRT)
+ Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
+ return current;
+#else
+ if (!currentTLS)
+ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
+ return (Current*)currentTLS;
+#endif
#else
// No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
static Current curr = { EGL_SUCCESS, EGL_OPENGL_ES_API, EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE };
diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
index 730a6ac022..defdf35f77 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
@@ -13,7 +13,13 @@
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+#if !defined(ANGLE_OS_WINRT)
static DWORD currentTLS = TLS_OUT_OF_INDEXES;
+#else
+static __declspec(thread) void *currentTLS = 0;
+#endif
+
+namespace gl { Current *getCurrent(); }
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
@@ -21,22 +27,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
{
case DLL_PROCESS_ATTACH:
{
+#if !defined(ANGLE_OS_WINRT)
currentTLS = TlsAlloc();
if (currentTLS == TLS_OUT_OF_INDEXES)
{
return FALSE;
}
+#endif
}
// Fall throught to initialize index
case DLL_THREAD_ATTACH:
{
- gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current));
+ gl::Current *current = gl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
TlsSetValue(currentTLS, current);
-
+#endif
current->context = NULL;
current->display = NULL;
}
@@ -44,24 +53,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
break;
case DLL_THREAD_DETACH:
{
- void *current = TlsGetValue(currentTLS);
+ gl::Current *current = gl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
LocalFree((HLOCAL)current);
+#else
+ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
+ currentTLS = 0;
+#endif
}
}
break;
case DLL_PROCESS_DETACH:
{
- void *current = TlsGetValue(currentTLS);
+ gl::Current *current = gl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
LocalFree((HLOCAL)current);
}
TlsFree(currentTLS);
+#else
+ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
+ currentTLS = 0;
+ }
+#endif
}
break;
default:
@@ -78,7 +98,16 @@ namespace gl
Current *getCurrent()
{
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
- return (Current*)TlsGetValue(currentTLS);
+#if !defined(ANGLE_OS_WINRT)
+ Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
+ return current;
+#else
+ if (!currentTLS)
+ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
+ return (Current*)currentTLS;
+#endif
#else
// No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
static gl::Current curr = { 0, 0 };
diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h
index 50dec6b084..823d27bb60 100644
--- a/src/3rdparty/angle/src/libGLESv2/precompiled.h
+++ b/src/3rdparty/angle/src/libGLESv2/precompiled.h
@@ -32,13 +32,28 @@
#include <unordered_map>
#include <vector>
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+#define ANGLE_OS_WINRT
+#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
+#define ANGLE_OS_WINPHONE
+#endif
+#endif
+
#ifndef ANGLE_ENABLE_D3D11
#include <d3d9.h>
#else
+#if !defined(ANGLE_OS_WINRT)
#include <D3D11.h>
+#else
+#include <d3d11_1.h>
+#define Sleep(x) WaitForSingleObjectEx(GetCurrentThread(), x, FALSE)
+#define GetVersion() WINVER
+#endif
#include <dxgi.h>
#endif
+#ifndef ANGLE_OS_WINPHONE
#include <D3Dcompiler.h>
+#endif
#ifdef _MSC_VER
#include <hash_map>
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
index 21ad223467..7ba183d250 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
@@ -28,13 +28,18 @@
#define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT(1, 0x876, 380)
#endif
-#ifdef __MINGW32__
-
#ifndef D3DCOMPILER_DLL
+#ifndef ANGLE_OS_WINPHONE
+#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" // Lowest common denominator
+#else
+#define D3DCOMPILER_DLL L"qtd3dcompiler.dll" // Placeholder DLL for phone
+#endif // ANGLE_OS_WINPHONE
+#endif // D3DCOMPILER_DLL
-//Add define + typedefs for older MinGW-w64 headers (pre 5783)
+#if defined(__MINGW32__) || defined(ANGLE_OS_WINPHONE)
-#define D3DCOMPILER_DLL L"d3dcompiler_43.dll"
+//Add define + typedefs for older MinGW-w64 headers (pre 5783)
+//Also define these on Windows Phone, which doesn't have a shader compiler
HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
@@ -43,9 +48,7 @@ typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const
const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
-#endif // D3DCOMPILER_DLL
-
-#endif // __MINGW32__
+#endif // __MINGW32__ || ANGLE_OS_WINPHONE
namespace rx
{
@@ -81,7 +84,11 @@ bool Renderer::initializeCompiler()
}
#else
// Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
+#if !defined(ANGLE_OS_WINRT)
mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
+#else
+ mD3dCompilerModule = LoadPackagedLibrary(D3DCOMPILER_DLL, NULL);
+#endif
#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
if (!mD3dCompilerModule)
@@ -225,4 +232,4 @@ void glDestroyRenderer(rx::Renderer *renderer)
delete renderer;
}
-} \ No newline at end of file
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
index 04e877ba9e..ac67c27e71 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
@@ -1,3 +1,4 @@
+#include "../precompiled.h"
//
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -13,6 +14,30 @@
#include "libGLESv2/Uniform.h"
#include "libGLESv2/angletypes.h"
+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL0
+#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14)
+#endif
+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL1
+#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0
+#endif
+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL2
+#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15))
+#endif
+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3
+#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15)
+#endif
+#ifndef D3DCOMPILE_DEBUG
+#define D3DCOMPILE_DEBUG (1 << 0)
+#endif
+#ifndef D3DCOMPILE_SKIP_OPTIMIZATION
+#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2)
+#endif
+#ifndef D3DCOMPILE_AVOID_FLOW_CONTROL
+#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9)
+#endif
+#ifndef D3DCOMPILE_PREFER_FLOW_CONTROL
+#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10)
+#endif
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
@@ -107,7 +132,7 @@ class Renderer
virtual void sync(bool block) = 0;
- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
+ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0;
virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
index a43101807a..d04467b2a0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
@@ -137,6 +137,7 @@ EGLint Renderer11::initialize()
return EGL_NOT_INITIALIZED;
}
+#if !defined(ANGLE_OS_WINRT)
mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
@@ -155,6 +156,7 @@ EGLint Renderer11::initialize()
ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
return EGL_NOT_INITIALIZED;
}
+#endif
D3D_FEATURE_LEVEL featureLevels[] =
{
@@ -203,8 +205,12 @@ EGLint Renderer11::initialize()
}
}
+#if !defined(ANGLE_OS_WINRT)
IDXGIDevice *dxgiDevice = NULL;
- result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
+#else
+ IDXGIDevice1 *dxgiDevice = NULL;
+#endif
+ result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice));
if (FAILED(result))
{
@@ -524,7 +530,7 @@ void Renderer11::sync(bool block)
}
}
-SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
{
return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
index f024855f97..a7f5a397e5 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
@@ -52,7 +52,7 @@ class Renderer11 : public Renderer
virtual void sync(bool block);
- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
index 14c0515fc8..a6870ebedc 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
@@ -18,7 +18,7 @@ namespace rx
class SwapChain
{
public:
- SwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+ SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
: mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat)
{
}
@@ -33,7 +33,7 @@ class SwapChain
virtual HANDLE getShareHandle() {return mShareHandle;};
protected:
- const HWND mWindow; // Window that the surface is created for.
+ const EGLNativeWindowType mWindow; // Window that the surface is created for.
const GLenum mBackBufferFormat;
const GLenum mDepthBufferFormat;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
index 0da58cbe2e..0797fd7d82 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
@@ -17,7 +17,7 @@
namespace rx
{
-SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
+SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat)
: mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
{
@@ -468,6 +468,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
if (mWindow)
{
+#if !defined(ANGLE_OS_WINRT)
// We cannot create a swap chain for an HWND that is owned by a different process
DWORD currentProcessId = GetCurrentProcessId();
DWORD wndProcessId;
@@ -491,14 +492,34 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
+ swapChainDesc.Windowed = TRUE;
+ swapChainDesc.OutputWindow = mWindow;
+#else
+ IDXGIFactory2 *factory;
+ HRESULT result = mRenderer->getDxgiFactory()->QueryInterface(IID_PPV_ARGS(&factory));
+ ASSERT(SUCCEEDED(result));
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+ swapChainDesc.Width = backbufferWidth;
+ swapChainDesc.Height = backbufferHeight;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+#endif
+
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.Flags = 0;
- swapChainDesc.OutputWindow = mWindow;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.Windowed = TRUE;
- HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
+#if !defined(ANGLE_OS_WINRT)
+ result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
+#else
+ IDXGISwapChain1 *swapChain;
+ result = factory->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
+ mSwapChain = swapChain;
+#endif
if (FAILED(result))
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
index 800104602e..2a030c839d 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
@@ -19,7 +19,7 @@ class Renderer11;
class SwapChain11 : public SwapChain
{
public:
- SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
+ SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain11();
diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.cpp b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
index 32df49e672..8fd193b164 100644
--- a/src/3rdparty/angle/src/libGLESv2/utilities.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
@@ -10,6 +10,14 @@
#include "libGLESv2/utilities.h"
#include "libGLESv2/mathutil.h"
+#if defined(ANGLE_OS_WINRT)
+#include <locale>
+#include <codecvt>
+#include <wrl.h>
+#include <windows.storage.h>
+using namespace ABI::Windows::Storage;
+#endif
+
namespace gl
{
@@ -737,7 +745,50 @@ bool IsTriangleMode(GLenum drawMode)
std::string getTempPath()
{
+#if defined(ANGLE_OS_WINRT)
+
+ static std::string path;
+
+ while (path.empty()) {
+ IApplicationDataStatics *applicationDataFactory;
+ HRESULT result = RoGetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Storage_ApplicationData).Get(),
+ IID_PPV_ARGS(&applicationDataFactory));
+ if (FAILED(result))
+ break;
+
+ IApplicationData *applicationData;
+ result = applicationDataFactory->get_Current(&applicationData);
+ if (FAILED(result))
+ break;
+
+ IStorageFolder *storageFolder;
+ result = applicationData->get_LocalFolder(&storageFolder);
+ if (FAILED(result))
+ break;
+
+ IStorageItem *localFolder;
+ result = storageFolder->QueryInterface(IID_PPV_ARGS(&localFolder));
+ if (FAILED(result))
+ break;
+
+ HSTRING localFolderPath;
+ result = localFolder->get_Path(&localFolderPath);
+ if (FAILED(result))
+ break;
+
+ std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
+ path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
+ if (path.empty())
+ {
+ UNREACHABLE();
+ break;
+ }
+ }
+
+#else
+
char path[MAX_PATH];
+
DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
if (pathLen == 0)
{
@@ -751,6 +802,8 @@ std::string getTempPath()
UNREACHABLE();
return std::string();
}
+
+#endif
return path;
}
diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h
index 592d4ee0cb..f01e56f612 100644
--- a/src/3rdparty/libpng/pngpriv.h
+++ b/src/3rdparty/libpng/pngpriv.h
@@ -362,7 +362,7 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
defined(_WIN32) || defined(__WIN32__)
# include <windows.h> /* defines _WINDOWS_ macro */
-# if defined(WINAPI_FAMILY) && ((WINAPI_FAMILY & WINAPI_FAMILY_DESKTOP_APP) == WINAPI_PARTITION_APP)
+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
# define _WINRT_ /* Define a macro for Windows Runtime builds */
# endif
#endif
diff --git a/src/angle/patches/0012-ANGLE-Support-WinRT.patch b/src/angle/patches/0012-ANGLE-Support-WinRT.patch
new file mode 100644
index 0000000000..8a5b96c7c0
--- /dev/null
+++ b/src/angle/patches/0012-ANGLE-Support-WinRT.patch
@@ -0,0 +1,1131 @@
+From 67c318c7b9c6d95d3170d11956dbec56494511ca Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Tue, 1 Oct 2013 09:43:29 +0300
+Subject: [PATCH] ANGLE: Support WinRT
+
+This enables EGL for WinRT's native types, and adjusts some codepaths
+to accommodate differences in between desktop Windows and WinRT.
+
+- WinRT native handles added to eglplatform.h
+- References to native handles in libEGL/libGLESv2 follow eglplatform.h
+- D3D 11.1 structures and methods used when necessary
+- TLS replaced with thread attribute
+- LocalAlloc/Free replaced with Heap API
+
+Change-Id: Ia90377e700d335a1c569c2145008dd4b0dfd84d3
+Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
+---
+ src/3rdparty/angle/include/EGL/eglplatform.h | 10 ++-
+ src/3rdparty/angle/src/compiler/osinclude.h | 35 ++++------
+ src/3rdparty/angle/src/compiler/ossource_posix.cpp | 8 +++
+ src/3rdparty/angle/src/compiler/ossource_win.cpp | 8 +++
+ src/3rdparty/angle/src/compiler/ossource_winrt.cpp | 75 ++++++++++++++++++++++
+ src/3rdparty/angle/src/libEGL/Display.cpp | 8 ++-
+ src/3rdparty/angle/src/libEGL/Display.h | 4 +-
+ src/3rdparty/angle/src/libEGL/Surface.cpp | 35 +++++++++-
+ src/3rdparty/angle/src/libEGL/Surface.h | 7 +-
+ src/3rdparty/angle/src/libEGL/libEGL.cpp | 4 +-
+ src/3rdparty/angle/src/libEGL/main.cpp | 40 ++++++++++--
+ src/3rdparty/angle/src/libGLESv2/main.cpp | 39 +++++++++--
+ src/3rdparty/angle/src/libGLESv2/precompiled.h | 15 +++++
+ .../angle/src/libGLESv2/renderer/Renderer.cpp | 23 ++++---
+ .../angle/src/libGLESv2/renderer/Renderer.h | 27 +++++++-
+ .../angle/src/libGLESv2/renderer/Renderer11.cpp | 10 ++-
+ .../angle/src/libGLESv2/renderer/Renderer11.h | 2 +-
+ .../angle/src/libGLESv2/renderer/SwapChain.h | 4 +-
+ .../angle/src/libGLESv2/renderer/SwapChain11.cpp | 29 +++++++--
+ .../angle/src/libGLESv2/renderer/SwapChain11.h | 2 +-
+ src/3rdparty/angle/src/libGLESv2/utilities.cpp | 53 +++++++++++++++
+ src/angle/src/common/common.pri | 2 +-
+ src/angle/src/compiler/translator_common.pro | 7 +-
+ src/angle/src/config.pri | 5 +-
+ 24 files changed, 386 insertions(+), 66 deletions(-)
+ create mode 100644 src/3rdparty/angle/src/compiler/ossource_winrt.cpp
+
+diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h
+index 34283f2..eb15ae5 100644
+--- a/src/3rdparty/angle/include/EGL/eglplatform.h
++++ b/src/3rdparty/angle/include/EGL/eglplatform.h
+@@ -67,7 +67,15 @@
+ * implementations.
+ */
+
+-#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
++
++struct IUnknown;
++
++typedef int EGLNativeDisplayType;
++typedef void *EGLNativePixmapType;
++typedef IUnknown *EGLNativeWindowType;
++
++#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+ #ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN 1
+ #endif
+diff --git a/src/3rdparty/angle/src/compiler/osinclude.h b/src/3rdparty/angle/src/compiler/osinclude.h
+index d8bb1a7..60177d5 100644
+--- a/src/3rdparty/angle/src/compiler/osinclude.h
++++ b/src/3rdparty/angle/src/compiler/osinclude.h
+@@ -13,27 +13,26 @@
+ //
+
+ #if defined(_WIN32) || defined(_WIN64)
++#define STRICT
++#define VC_EXTRALEAN 1
++#include <windows.h>
++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
++#define ANGLE_OS_WINRT
++#else
+ #define ANGLE_OS_WIN
++#endif
+ #elif defined(__APPLE__) || defined(__linux__) || \
+ defined(__FreeBSD__) || defined(__OpenBSD__) || \
+ defined(__sun) || defined(ANDROID) || \
+ defined(__GLIBC__) || defined(__GNU__) || \
+ defined(__QNX__)
+ #define ANGLE_OS_POSIX
+-#else
+-#error Unsupported platform.
+-#endif
+-
+-#if defined(ANGLE_OS_WIN)
+-#define STRICT
+-#define VC_EXTRALEAN 1
+-#include <windows.h>
+-#elif defined(ANGLE_OS_POSIX)
+ #include <pthread.h>
+ #include <semaphore.h>
+ #include <errno.h>
+-#endif // ANGLE_OS_WIN
+-
++#else
++#error Unsupported platform.
++#endif
+
+ #include "compiler/debug.h"
+
+@@ -43,23 +42,17 @@
+ #if defined(ANGLE_OS_WIN)
+ typedef DWORD OS_TLSIndex;
+ #define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
++#elif defined(ANGLE_OS_WINRT)
++typedef size_t OS_TLSIndex;
++#define OS_INVALID_TLS_INDEX ((DWORD)0xFFFFFF)
+ #elif defined(ANGLE_OS_POSIX)
+ typedef pthread_key_t OS_TLSIndex;
+ #define OS_INVALID_TLS_INDEX (static_cast<OS_TLSIndex>(-1))
+ #endif // ANGLE_OS_WIN
+
+ OS_TLSIndex OS_AllocTLSIndex();
++void *OS_GetTLSValue(OS_TLSIndex nIndex);
+ bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
+ bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
+
+-inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
+-{
+- ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+-#if defined(ANGLE_OS_WIN)
+- return TlsGetValue(nIndex);
+-#elif defined(ANGLE_OS_POSIX)
+- return pthread_getspecific(nIndex);
+-#endif // ANGLE_OS_WIN
+-}
+-
+ #endif // __OSINCLUDE_H
+diff --git a/src/3rdparty/angle/src/compiler/ossource_posix.cpp b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
+index 1e1e699..35510c1 100644
+--- a/src/3rdparty/angle/src/compiler/ossource_posix.cpp
++++ b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
+@@ -33,6 +33,14 @@ OS_TLSIndex OS_AllocTLSIndex()
+ }
+
+
++void *OS_GetTLSValue(OS_TLSIndex nIndex)
++{
++ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
++
++ return pthread_getspecific(nIndex);
++}
++
++
+ bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+ {
+ if (nIndex == OS_INVALID_TLS_INDEX) {
+diff --git a/src/3rdparty/angle/src/compiler/ossource_win.cpp b/src/3rdparty/angle/src/compiler/ossource_win.cpp
+index 89922fe..708a1ad 100644
+--- a/src/3rdparty/angle/src/compiler/ossource_win.cpp
++++ b/src/3rdparty/angle/src/compiler/ossource_win.cpp
+@@ -29,6 +29,14 @@ OS_TLSIndex OS_AllocTLSIndex()
+ }
+
+
++void *OS_GetTLSValue(OS_TLSIndex nIndex)
++{
++ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
++
++ return TlsGetValue(nIndex);
++}
++
++
+ bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+ {
+ if (nIndex == OS_INVALID_TLS_INDEX) {
+diff --git a/src/3rdparty/angle/src/compiler/ossource_winrt.cpp b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
+new file mode 100644
+index 0000000..84443ab
+--- /dev/null
++++ b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
+@@ -0,0 +1,75 @@
++//
++// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++//
++
++#include "compiler/osinclude.h"
++//
++// This file contains contains Windows Runtime specific functions
++//
++
++#if !defined(ANGLE_OS_WINRT)
++#error Trying to build a WinRT specific file in a non-WinRT build.
++#endif
++
++#include <vector>
++
++
++//
++// Thread Local Storage Operations
++//
++__declspec(thread) std::vector<void *> *tls = nullptr;
++__declspec(thread) std::vector<OS_TLSIndex> *freeIndices = nullptr;
++
++OS_TLSIndex OS_AllocTLSIndex()
++{
++ if (!tls)
++ tls = new std::vector<void*>;
++
++ if (freeIndices && !freeIndices->empty()) {
++ OS_TLSIndex index = freeIndices->back();
++ freeIndices->pop_back();
++ return index;
++ } else {
++ tls->push_back(nullptr);
++ return tls->size() - 1;
++ }
++}
++
++
++void *OS_GetTLSValue(OS_TLSIndex nIndex)
++{
++ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
++ ASSERT(tls);
++
++ return tls->at(nIndex);
++}
++
++
++bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
++{
++ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
++ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
++ return false;
++ }
++
++ tls->at(nIndex) = lpvValue;
++ return true;
++}
++
++
++bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
++{
++ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
++ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
++ return false;
++ }
++
++ if (!freeIndices)
++ freeIndices = new std::vector<OS_TLSIndex>;
++
++ freeIndices->push_back(nIndex);
++
++ return true;
++}
+diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
+index a382c3b..14973af 100644
+--- a/src/3rdparty/angle/src/libEGL/Display.cpp
++++ b/src/3rdparty/angle/src/libEGL/Display.cpp
+@@ -186,7 +186,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
+
+
+
+-EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
++EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
+ {
+ const Config *configuration = mConfigSet.get(config);
+ EGLint postSubBufferSupported = EGL_FALSE;
+@@ -456,7 +456,7 @@ bool Display::isValidSurface(egl::Surface *surface)
+ return mSurfaceSet.find(surface) != mSurfaceSet.end();
+ }
+
+-bool Display::hasExistingWindowSurface(HWND window)
++bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
+ {
+ for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+ {
+@@ -471,7 +471,6 @@ bool Display::hasExistingWindowSurface(HWND window)
+
+ void Display::initExtensionString()
+ {
+- HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+ bool shareHandleSupported = mRenderer->getShareHandleSupport();
+
+ mExtensionString = "";
+@@ -487,10 +486,13 @@ void Display::initExtensionString()
+
+ mExtensionString += "EGL_ANGLE_query_surface_pointer ";
+
++#if !defined(ANGLE_OS_WINRT)
++ HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+ if (swiftShader)
+ {
+ mExtensionString += "EGL_ANGLE_software_display ";
+ }
++#endif
+
+ if (shareHandleSupported)
+ {
+diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
+index 58c3940..5d55410 100644
+--- a/src/3rdparty/angle/src/libEGL/Display.h
++++ b/src/3rdparty/angle/src/libEGL/Display.h
+@@ -40,7 +40,7 @@ class Display
+ bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
+ bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
+
+- EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
++ EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
+ EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
+ EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
+
+@@ -51,7 +51,7 @@ class Display
+ bool isValidConfig(EGLConfig config);
+ bool isValidContext(gl::Context *context);
+ bool isValidSurface(egl::Surface *surface);
+- bool hasExistingWindowSurface(HWND window);
++ bool hasExistingWindowSurface(EGLNativeWindowType window);
+
+ rx::Renderer *getRenderer() { return mRenderer; };
+
+diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
+index b47a7bc..abc6d7d 100644
+--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
++++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
+@@ -20,10 +20,15 @@
+ #include "libEGL/main.h"
+ #include "libEGL/Display.h"
+
++#if defined(ANGLE_OS_WINRT)
++#include <windows.foundation.h>
++#include <windows.ui.core.h>
++#endif
++
+ namespace egl
+ {
+
+-Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
++Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported)
+ : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
+ {
+ mRenderer = mDisplay->getRenderer();
+@@ -96,6 +101,7 @@ bool Surface::resetSwapChain()
+
+ if (mWindow)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ RECT windowRect;
+ if (!GetClientRect(getWindowHandle(), &windowRect))
+ {
+@@ -107,6 +113,14 @@ bool Surface::resetSwapChain()
+
+ width = windowRect.right - windowRect.left;
+ height = windowRect.bottom - windowRect.top;
++#else
++ ABI::Windows::Foundation::Rect windowRect;
++ ABI::Windows::UI::Core::ICoreWindow *window;
++ ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ window->get_Bounds(&windowRect);
++ width = windowRect.Width;
++ height = windowRect.Height;
++#endif
+ }
+ else
+ {
+@@ -226,7 +240,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ return true;
+ }
+
+-HWND Surface::getWindowHandle()
++EGLNativeWindowType Surface::getWindowHandle()
+ {
+ return mWindow;
+ }
+@@ -235,6 +249,7 @@ HWND Surface::getWindowHandle()
+ #define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
+ #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
+
++#if !defined(ANGLE_OS_WINRT)
+ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
+ {
+ if (message == WM_SIZE)
+@@ -248,9 +263,13 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
+ WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
+ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
+ }
++#endif
+
+ void Surface::subclassWindow()
+ {
++#if defined(ANGLE_OS_WINRT)
++ mWindowSubclassed = false;
++#else
+ if (!mWindow)
+ {
+ return;
+@@ -274,10 +293,12 @@ void Surface::subclassWindow()
+ SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
+ SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+ mWindowSubclassed = true;
++#endif
+ }
+
+ void Surface::unsubclassWindow()
+ {
++#if !defined(ANGLE_OS_WINRT)
+ if(!mWindowSubclassed)
+ {
+ return;
+@@ -300,10 +321,12 @@ void Surface::unsubclassWindow()
+ RemoveProp(mWindow, kSurfaceProperty);
+ RemoveProp(mWindow, kParentWndProc);
+ mWindowSubclassed = false;
++#endif
+ }
+
+ bool Surface::checkForOutOfDateSwapChain()
+ {
++#if !defined(ANGLE_OS_WINRT)
+ RECT client;
+ if (!GetClientRect(getWindowHandle(), &client))
+ {
+@@ -314,6 +337,14 @@ bool Surface::checkForOutOfDateSwapChain()
+ // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
+ int clientWidth = client.right - client.left;
+ int clientHeight = client.bottom - client.top;
++#else
++ ABI::Windows::Foundation::Rect windowRect;
++ ABI::Windows::UI::Core::ICoreWindow *window;
++ ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ window->get_Bounds(&windowRect);
++ int clientWidth = windowRect.Width;
++ int clientHeight = windowRect.Height;
++#endif
+ bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
+
+ if (mSwapIntervalDirty)
+diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h
+index 938b800..ae9a380 100644
+--- a/src/3rdparty/angle/src/libEGL/Surface.h
++++ b/src/3rdparty/angle/src/libEGL/Surface.h
+@@ -15,6 +15,7 @@
+ #include <EGL/egl.h>
+
+ #include "common/angleutils.h"
++#include "windows.h"
+
+ namespace gl
+ {
+@@ -34,7 +35,7 @@ class Config;
+ class Surface
+ {
+ public:
+- Surface(Display *display, const egl::Config *config, HWND window, EGLint postSubBufferSupported);
++ Surface(Display *display, const egl::Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported);
+ Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
+
+ ~Surface();
+@@ -43,7 +44,7 @@ class Surface
+ void release();
+ bool resetSwapChain();
+
+- HWND getWindowHandle();
++ EGLNativeWindowType getWindowHandle();
+ bool swap();
+ bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
+
+@@ -79,7 +80,7 @@ private:
+ bool resetSwapChain(int backbufferWidth, int backbufferHeight);
+ bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
+
+- const HWND mWindow; // Window that the surface is created for.
++ const EGLNativeWindowType mWindow; // Window that the surface is created for.
+ bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
+ const egl::Config *mConfig; // EGL config surface was created with
+ EGLint mHeight; // Height of surface
+diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
+index 6e10c39..5bcb5d5 100644
+--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
++++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
+@@ -308,14 +308,16 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
+ return EGL_NO_SURFACE;
+ }
+
++#if !defined(ANGLE_OS_WINRT)
+ HWND window = (HWND)win;
+
+ if (!IsWindow(window))
+ {
+ return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
++#endif
+
+- return display->createWindowSurface(window, config, attrib_list);
++ return display->createWindowSurface(win, config, attrib_list);
+ }
+ catch(std::bad_alloc&)
+ {
+diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
+index 7dea5fc..964b4b2 100644
+--- a/src/3rdparty/angle/src/libEGL/main.cpp
++++ b/src/3rdparty/angle/src/libEGL/main.cpp
+@@ -1,3 +1,4 @@
++#include "../libGLESv2/precompiled.h"
+ //
+ // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+@@ -12,7 +13,13 @@
+
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
++#if !defined(ANGLE_OS_WINRT)
+ static DWORD currentTLS = TLS_OUT_OF_INDEXES;
++#else
++static __declspec(thread) void *currentTLS = 0;
++#endif
++
++namespace egl { Current *getCurrent(); }
+
+ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+ {
+@@ -35,22 +42,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ }
+ #endif
+
++#if !defined(ANGLE_OS_WINRT)
+ currentTLS = TlsAlloc();
+
+ if (currentTLS == TLS_OUT_OF_INDEXES)
+ {
+ return FALSE;
+ }
++#endif
+ }
+ // Fall throught to initialize index
+ case DLL_THREAD_ATTACH:
+ {
+- egl::Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
++ egl::Current *current = egl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ TlsSetValue(currentTLS, current);
+-
++#endif
+ current->error = EGL_SUCCESS;
+ current->API = EGL_OPENGL_ES_API;
+ current->display = EGL_NO_DISPLAY;
+@@ -61,24 +71,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ break;
+ case DLL_THREAD_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ egl::Current *current = egl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++#endif
+ }
+ }
+ break;
+ case DLL_PROCESS_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ egl::Current *current = egl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
+ }
+
+ TlsFree(currentTLS);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++ }
++#endif
+ }
+ break;
+ default:
+@@ -95,7 +116,16 @@ namespace egl
+ Current *getCurrent()
+ {
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+- return (Current*)TlsGetValue(currentTLS);
++#if !defined(ANGLE_OS_WINRT)
++ Current *current = (Current*)TlsGetValue(currentTLS);
++ if (!current)
++ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
++ return current;
++#else
++ if (!currentTLS)
++ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
++ return (Current*)currentTLS;
++#endif
+ #else
+ // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
+ static Current curr = { EGL_SUCCESS, EGL_OPENGL_ES_API, EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE };
+diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
+index 730a6ac..defdf35 100644
+--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
+@@ -13,7 +13,13 @@
+
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
++#if !defined(ANGLE_OS_WINRT)
+ static DWORD currentTLS = TLS_OUT_OF_INDEXES;
++#else
++static __declspec(thread) void *currentTLS = 0;
++#endif
++
++namespace gl { Current *getCurrent(); }
+
+ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+ {
+@@ -21,22 +27,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ {
+ case DLL_PROCESS_ATTACH:
+ {
++#if !defined(ANGLE_OS_WINRT)
+ currentTLS = TlsAlloc();
+
+ if (currentTLS == TLS_OUT_OF_INDEXES)
+ {
+ return FALSE;
+ }
++#endif
+ }
+ // Fall throught to initialize index
+ case DLL_THREAD_ATTACH:
+ {
+- gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current));
++ gl::Current *current = gl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ TlsSetValue(currentTLS, current);
+-
++#endif
+ current->context = NULL;
+ current->display = NULL;
+ }
+@@ -44,24 +53,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ break;
+ case DLL_THREAD_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ gl::Current *current = gl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++#endif
+ }
+ }
+ break;
+ case DLL_PROCESS_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ gl::Current *current = gl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
+ }
+
+ TlsFree(currentTLS);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++ }
++#endif
+ }
+ break;
+ default:
+@@ -78,7 +98,16 @@ namespace gl
+ Current *getCurrent()
+ {
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+- return (Current*)TlsGetValue(currentTLS);
++#if !defined(ANGLE_OS_WINRT)
++ Current *current = (Current*)TlsGetValue(currentTLS);
++ if (!current)
++ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
++ return current;
++#else
++ if (!currentTLS)
++ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
++ return (Current*)currentTLS;
++#endif
+ #else
+ // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
+ static gl::Current curr = { 0, 0 };
+diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h
+index 50dec6b..823d27b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/precompiled.h
++++ b/src/3rdparty/angle/src/libGLESv2/precompiled.h
+@@ -32,13 +32,28 @@
+ #include <unordered_map>
+ #include <vector>
+
++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
++#define ANGLE_OS_WINRT
++#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
++#define ANGLE_OS_WINPHONE
++#endif
++#endif
++
+ #ifndef ANGLE_ENABLE_D3D11
+ #include <d3d9.h>
+ #else
++#if !defined(ANGLE_OS_WINRT)
+ #include <D3D11.h>
++#else
++#include <d3d11_1.h>
++#define Sleep(x) WaitForSingleObjectEx(GetCurrentThread(), x, FALSE)
++#define GetVersion() WINVER
++#endif
+ #include <dxgi.h>
+ #endif
++#ifndef ANGLE_OS_WINPHONE
+ #include <D3Dcompiler.h>
++#endif
+
+ #ifdef _MSC_VER
+ #include <hash_map>
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+index 21ad223..7ba183d 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+@@ -28,13 +28,18 @@
+ #define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT(1, 0x876, 380)
+ #endif
+
+-#ifdef __MINGW32__
+-
+ #ifndef D3DCOMPILER_DLL
++#ifndef ANGLE_OS_WINPHONE
++#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" // Lowest common denominator
++#else
++#define D3DCOMPILER_DLL L"qtd3dcompiler.dll" // Placeholder DLL for phone
++#endif // ANGLE_OS_WINPHONE
++#endif // D3DCOMPILER_DLL
+
+-//Add define + typedefs for older MinGW-w64 headers (pre 5783)
++#if defined(__MINGW32__) || defined(ANGLE_OS_WINPHONE)
+
+-#define D3DCOMPILER_DLL L"d3dcompiler_43.dll"
++//Add define + typedefs for older MinGW-w64 headers (pre 5783)
++//Also define these on Windows Phone, which doesn't have a shader compiler
+
+ HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
+@@ -43,9 +48,7 @@ typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
+
+-#endif // D3DCOMPILER_DLL
+-
+-#endif // __MINGW32__
++#endif // __MINGW32__ || ANGLE_OS_WINPHONE
+
+ namespace rx
+ {
+@@ -81,7 +84,11 @@ bool Renderer::initializeCompiler()
+ }
+ #else
+ // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
++#if !defined(ANGLE_OS_WINRT)
+ mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
++#else
++ mD3dCompilerModule = LoadPackagedLibrary(D3DCOMPILER_DLL, NULL);
++#endif
+ #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
+
+ if (!mD3dCompilerModule)
+@@ -225,4 +232,4 @@ void glDestroyRenderer(rx::Renderer *renderer)
+ delete renderer;
+ }
+
+-}
+\ No newline at end of file
++}
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+index 04e877b..ac67c27 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+@@ -1,3 +1,4 @@
++#include "../precompiled.h"
+ //
+ // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+@@ -13,6 +14,30 @@
+ #include "libGLESv2/Uniform.h"
+ #include "libGLESv2/angletypes.h"
+
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL0
++#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14)
++#endif
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL1
++#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0
++#endif
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL2
++#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15))
++#endif
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3
++#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15)
++#endif
++#ifndef D3DCOMPILE_DEBUG
++#define D3DCOMPILE_DEBUG (1 << 0)
++#endif
++#ifndef D3DCOMPILE_SKIP_OPTIMIZATION
++#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2)
++#endif
++#ifndef D3DCOMPILE_AVOID_FLOW_CONTROL
++#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9)
++#endif
++#ifndef D3DCOMPILE_PREFER_FLOW_CONTROL
++#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10)
++#endif
+ #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+ #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
+ #endif
+@@ -107,7 +132,7 @@ class Renderer
+
+ virtual void sync(bool block) = 0;
+
+- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
++ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
+
+ virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0;
+ virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+index a431018..d04467b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+@@ -137,6 +137,7 @@ EGLint Renderer11::initialize()
+ return EGL_NOT_INITIALIZED;
+ }
+
++#if !defined(ANGLE_OS_WINRT)
+ mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
+ mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+
+@@ -155,6 +156,7 @@ EGLint Renderer11::initialize()
+ ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
++#endif
+
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
+@@ -203,8 +205,12 @@ EGLint Renderer11::initialize()
+ }
+ }
+
++#if !defined(ANGLE_OS_WINRT)
+ IDXGIDevice *dxgiDevice = NULL;
+- result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
++#else
++ IDXGIDevice1 *dxgiDevice = NULL;
++#endif
++ result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice));
+
+ if (FAILED(result))
+ {
+@@ -524,7 +530,7 @@ void Renderer11::sync(bool block)
+ }
+ }
+
+-SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
++SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+ {
+ return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+ }
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+index f024855..a7f5a39 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+@@ -52,7 +52,7 @@ class Renderer11 : public Renderer
+
+ virtual void sync(bool block);
+
+- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
++ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+
+ virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
+ virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+index 14c0515..a6870eb 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+@@ -18,7 +18,7 @@ namespace rx
+ class SwapChain
+ {
+ public:
+- SwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
++ SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+ : mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat)
+ {
+ }
+@@ -33,7 +33,7 @@ class SwapChain
+ virtual HANDLE getShareHandle() {return mShareHandle;};
+
+ protected:
+- const HWND mWindow; // Window that the surface is created for.
++ const EGLNativeWindowType mWindow; // Window that the surface is created for.
+ const GLenum mBackBufferFormat;
+ const GLenum mDepthBufferFormat;
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+index 0da58cb..0797fd7 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+@@ -17,7 +17,7 @@
+ namespace rx
+ {
+
+-SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
++SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
+ GLenum backBufferFormat, GLenum depthBufferFormat)
+ : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+ {
+@@ -468,6 +468,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+
+ if (mWindow)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ // We cannot create a swap chain for an HWND that is owned by a different process
+ DWORD currentProcessId = GetCurrentProcessId();
+ DWORD wndProcessId;
+@@ -491,14 +492,34 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+ swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+ swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
++ swapChainDesc.Windowed = TRUE;
++ swapChainDesc.OutputWindow = mWindow;
++#else
++ IDXGIFactory2 *factory;
++ HRESULT result = mRenderer->getDxgiFactory()->QueryInterface(IID_PPV_ARGS(&factory));
++ ASSERT(SUCCEEDED(result));
++
++ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
++ swapChainDesc.BufferCount = 2;
++ swapChainDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
++ swapChainDesc.Width = backbufferWidth;
++ swapChainDesc.Height = backbufferHeight;
++ swapChainDesc.Stereo = FALSE;
++ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
++#endif
++
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.Flags = 0;
+- swapChainDesc.OutputWindow = mWindow;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+- swapChainDesc.Windowed = TRUE;
+
+- HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
++#if !defined(ANGLE_OS_WINRT)
++ result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
++#else
++ IDXGISwapChain1 *swapChain;
++ result = factory->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
++ mSwapChain = swapChain;
++#endif
+
+ if (FAILED(result))
+ {
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
+index 8001046..2a030c8 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
+@@ -19,7 +19,7 @@ class Renderer11;
+ class SwapChain11 : public SwapChain
+ {
+ public:
+- SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
++ SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
+ GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual ~SwapChain11();
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.cpp b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
+index 32df49e..8fd193b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/utilities.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
+@@ -10,6 +10,14 @@
+ #include "libGLESv2/utilities.h"
+ #include "libGLESv2/mathutil.h"
+
++#if defined(ANGLE_OS_WINRT)
++#include <locale>
++#include <codecvt>
++#include <wrl.h>
++#include <windows.storage.h>
++using namespace ABI::Windows::Storage;
++#endif
++
+ namespace gl
+ {
+
+@@ -737,7 +745,50 @@ bool IsTriangleMode(GLenum drawMode)
+
+ std::string getTempPath()
+ {
++#if defined(ANGLE_OS_WINRT)
++
++ static std::string path;
++
++ while (path.empty()) {
++ IApplicationDataStatics *applicationDataFactory;
++ HRESULT result = RoGetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Storage_ApplicationData).Get(),
++ IID_PPV_ARGS(&applicationDataFactory));
++ if (FAILED(result))
++ break;
++
++ IApplicationData *applicationData;
++ result = applicationDataFactory->get_Current(&applicationData);
++ if (FAILED(result))
++ break;
++
++ IStorageFolder *storageFolder;
++ result = applicationData->get_LocalFolder(&storageFolder);
++ if (FAILED(result))
++ break;
++
++ IStorageItem *localFolder;
++ result = storageFolder->QueryInterface(IID_PPV_ARGS(&localFolder));
++ if (FAILED(result))
++ break;
++
++ HSTRING localFolderPath;
++ result = localFolder->get_Path(&localFolderPath);
++ if (FAILED(result))
++ break;
++
++ std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
++ path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
++ if (path.empty())
++ {
++ UNREACHABLE();
++ break;
++ }
++ }
++
++#else
++
+ char path[MAX_PATH];
++
+ DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
+ if (pathLen == 0)
+ {
+@@ -751,6 +802,8 @@ std::string getTempPath()
+ UNREACHABLE();
+ return std::string();
+ }
++
++#endif
+
+ return path;
+ }
+diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri
+index a94b9a6..12e26a9 100644
+--- a/src/angle/src/common/common.pri
++++ b/src/angle/src/common/common.pri
+@@ -7,7 +7,7 @@ INCLUDEPATH += \
+ LIBS = $$QMAKE_LIBS_CORE $$QMAKE_LIBS_GUI
+
+ # DirectX is included in the Windows 8 Kit, but everything else requires the DX SDK.
+-win32-msvc2012 {
++win32-msvc2012|winrt {
+ FXC = fxc.exe
+ } else {
+ DX_DIR = $$(DXSDK_DIR)
+diff --git a/src/angle/src/compiler/translator_common.pro b/src/angle/src/compiler/translator_common.pro
+index b281215..5581c9d 100644
+--- a/src/angle/src/compiler/translator_common.pro
++++ b/src/angle/src/compiler/translator_common.pro
+@@ -78,7 +78,6 @@ SOURCES += \
+ $$ANGLE_DIR/src/compiler/intermOut.cpp \
+ $$ANGLE_DIR/src/compiler/IntermTraverse.cpp \
+ $$ANGLE_DIR/src/compiler/MapLongVariableNames.cpp \
+- $$ANGLE_DIR/src/compiler/ossource_win.cpp \
+ $$ANGLE_DIR/src/compiler/parseConst.cpp \
+ $$ANGLE_DIR/src/compiler/ParseHelper.cpp \
+ $$ANGLE_DIR/src/compiler/PoolAlloc.cpp \
+@@ -98,6 +97,12 @@ SOURCES += \
+ $$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.cpp \
+ $$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.cpp
+
++winrt {
++ SOURCES += $$ANGLE_DIR/src/compiler/ossource_winrt.cpp
++} else {
++ SOURCES += $$ANGLE_DIR/src/compiler/ossource_win.cpp
++}
++
+ # NOTE: 'win_flex' and 'bison' can be found in qt5/gnuwin32/bin
+ flex.commands = $$addGnuPath(win_flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}_lex.cpp ${QMAKE_FILE_NAME}
+ flex.output = ${QMAKE_FILE_BASE}_lex.cpp
+diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri
+index 1c6d8b0..ed25581 100644
+--- a/src/angle/src/config.pri
++++ b/src/angle/src/config.pri
+@@ -37,8 +37,9 @@ DEFINES += _WINDOWS \
+ NOMINMAX \
+ WIN32_LEAN_AND_MEAN=1
+
+-# Defines specifying the API version (0x0600 = Vista)
+-DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
++# Defines specifying the API version (0x0600 = Vista, 0x0602 = Win8))
++winrt: DEFINES += _WIN32_WINNT=0x0602 WINVER=0x0602
++else: DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
+
+ # ANGLE specific defines
+ DEFINES += ANGLE_DISABLE_TRACE \
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri
index a94b9a6fc3..12e26a9a68 100644
--- a/src/angle/src/common/common.pri
+++ b/src/angle/src/common/common.pri
@@ -7,7 +7,7 @@ INCLUDEPATH += \
LIBS = $$QMAKE_LIBS_CORE $$QMAKE_LIBS_GUI
# DirectX is included in the Windows 8 Kit, but everything else requires the DX SDK.
-win32-msvc2012 {
+win32-msvc2012|winrt {
FXC = fxc.exe
} else {
DX_DIR = $$(DXSDK_DIR)
diff --git a/src/angle/src/compiler/translator_common.pro b/src/angle/src/compiler/translator_common.pro
index b2812158e1..5581c9dc58 100644
--- a/src/angle/src/compiler/translator_common.pro
+++ b/src/angle/src/compiler/translator_common.pro
@@ -78,7 +78,6 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/intermOut.cpp \
$$ANGLE_DIR/src/compiler/IntermTraverse.cpp \
$$ANGLE_DIR/src/compiler/MapLongVariableNames.cpp \
- $$ANGLE_DIR/src/compiler/ossource_win.cpp \
$$ANGLE_DIR/src/compiler/parseConst.cpp \
$$ANGLE_DIR/src/compiler/ParseHelper.cpp \
$$ANGLE_DIR/src/compiler/PoolAlloc.cpp \
@@ -98,6 +97,12 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.cpp \
$$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.cpp
+winrt {
+ SOURCES += $$ANGLE_DIR/src/compiler/ossource_winrt.cpp
+} else {
+ SOURCES += $$ANGLE_DIR/src/compiler/ossource_win.cpp
+}
+
# NOTE: 'win_flex' and 'bison' can be found in qt5/gnuwin32/bin
flex.commands = $$addGnuPath(win_flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}_lex.cpp ${QMAKE_FILE_NAME}
flex.output = ${QMAKE_FILE_BASE}_lex.cpp
diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri
index 1c6d8b0167..ed2558117e 100644
--- a/src/angle/src/config.pri
+++ b/src/angle/src/config.pri
@@ -37,8 +37,9 @@ DEFINES += _WINDOWS \
NOMINMAX \
WIN32_LEAN_AND_MEAN=1
-# Defines specifying the API version (0x0600 = Vista)
-DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
+# Defines specifying the API version (0x0600 = Vista, 0x0602 = Win8))
+winrt: DEFINES += _WIN32_WINNT=0x0602 WINVER=0x0602
+else: DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
# ANGLE specific defines
DEFINES += ANGLE_DISABLE_TRACE \
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index e2b1502a8e..41a9c0d950 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -2136,7 +2136,9 @@ QString qt_error_string(int errorCode)
s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device");
break;
default: {
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN)
+ // Retrieve the system error message for the last-error code.
+# ifndef Q_OS_WINRT
wchar_t *string = 0;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
@@ -2147,6 +2149,17 @@ QString qt_error_string(int errorCode)
NULL);
ret = QString::fromWCharArray(string);
LocalFree((HLOCAL)string);
+# else // !Q_OS_WINRT
+ __declspec(thread) static wchar_t errorString[4096];
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ errorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ errorString,
+ ARRAYSIZE(errorString),
+ NULL);
+ ret = QString::fromWCharArray(errorString);
+# endif // Q_OS_WINRT
if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND)
ret = QString::fromLatin1("The specified module could not be found.");
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index b1a22ddf03..fd5ab865f3 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -45,11 +45,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "5.2.0"
+#define QT_VERSION_STR "5.3.0"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x050200
+#define QT_VERSION 0x050300
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -192,7 +192,7 @@ typedef qint64 qlonglong;
typedef quint64 qulonglong;
#ifndef QT_POINTER_SIZE
-# if defined(Q_OS_WIN64)
+# if defined(Q_OS_WIN64) || (defined(Q_OS_WINRT) && defined(_M_X64))
# define QT_POINTER_SIZE 8
# elif defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
# define QT_POINTER_SIZE 4
@@ -542,6 +542,7 @@ class QDataStream;
#if defined(Q_OS_WINRT)
# define QT_NO_PROCESS
+# define QT_NO_FILESYSTEMWATCHER
#endif
inline void qt_noop(void) {}
diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp
index 5e71753c8a..83ccb7075d 100644
--- a/src/corelib/global/qnumeric.cpp
+++ b/src/corelib/global/qnumeric.cpp
@@ -41,6 +41,7 @@
#include "qnumeric.h"
#include "qnumeric_p.h"
+#include <string.h>
QT_BEGIN_NAMESPACE
@@ -99,4 +100,139 @@ Q_CORE_EXPORT double qQNaN() { return qt_qnan(); }
Q_CORE_EXPORT double qInf() { return qt_inf(); }
+
+/*!
+ \internal
+ */
+static inline quint32 f2i(float f)
+{
+ quint32 i;
+ memcpy(&i, &f, sizeof(f));
+ return i;
+}
+
+/*!
+ Returns the number of representable floating-point numbers between \a a and \a b.
+
+ This function provides an alternative way of doing approximated comparisons of floating-point
+ numbers similar to qFuzzyCompare(). However, it returns the distance between two numbers, which
+ gives the caller a possibility to choose the accepted error. Errors are relative, so for
+ instance the distance between 1.0E-5 and 1.00001E-5 will give 110, while the distance between
+ 1.0E36 and 1.00001E36 will give 127.
+
+ This function is useful if a floating point comparison requires a certain precision.
+ Therefore, if \a a and \a b are equal it will return 0. The maximum value it will return for 32-bit
+ floating point numbers is 4,278,190,078. This is the distance between \c{-FLT_MAX} and
+ \c{+FLT_MAX}.
+
+ The function does not give meaningful results if any of the arguments are \c Infinite or \c NaN.
+ You can check for this by calling qIsFinite().
+
+ The return value can be considered as the "error", so if you for instance want to compare
+ two 32-bit floating point numbers and all you need is an approximated 24-bit precision, you can
+ use this function like this:
+
+ \code
+ if (qFloatDistance(a, b) < (1 << 7)) { // The last 7 bits are not
+ // significant
+ // precise enough
+ }
+ \endcode
+
+ \sa qFuzzyCompare()
+ \relates <QtGlobal>
+*/
+Q_CORE_EXPORT quint32 qFloatDistance(float a, float b)
+{
+ static const quint32 smallestPositiveFloatAsBits = 0x00000001; // denormalized, (SMALLEST), (1.4E-45)
+ /* Assumes:
+ * IEE754 format.
+ * Integers and floats have the same endian
+ */
+ Q_STATIC_ASSERT(sizeof(quint32) == sizeof(float));
+ Q_ASSERT(qIsFinite(a) && qIsFinite(b));
+ if (a == b)
+ return 0;
+ if ((a < 0) != (b < 0)) {
+ // if they have different signs
+ if (a < 0)
+ a = -a;
+ else /*if (b < 0)*/
+ b = -b;
+ return qFloatDistance(0.0F, a) + qFloatDistance(0.0F, b);
+ }
+ if (a < 0) {
+ a = -a;
+ b = -b;
+ }
+ // at this point a and b should not be negative
+
+ // 0 is special
+ if (!a)
+ return f2i(b) - smallestPositiveFloatAsBits + 1;
+ if (!b)
+ return f2i(a) - smallestPositiveFloatAsBits + 1;
+
+ // finally do the common integer subtraction
+ return a > b ? f2i(a) - f2i(b) : f2i(b) - f2i(a);
+}
+
+
+/*!
+ \internal
+ */
+static inline quint64 d2i(double d)
+{
+ quint64 i;
+ memcpy(&i, &d, sizeof(d));
+ return i;
+}
+
+/*!
+ Returns the number of representable floating-point numbers between \a a and \a b.
+
+ This function serves the same purpose as \c{qFloatDistance(float, float)}, but
+ returns the distance between two \c double numbers. Since the range is larger
+ than for two \c float numbers (\c{[-DBL_MAX,DBL_MAX]}), the return type is quint64.
+
+
+ \sa qFuzzyCompare()
+ \relates <QtGlobal>
+*/
+Q_CORE_EXPORT quint64 qFloatDistance(double a, double b)
+{
+ static const quint64 smallestPositiveFloatAsBits = 0x1; // denormalized, (SMALLEST)
+ /* Assumes:
+ * IEE754 format double precision
+ * Integers and floats have the same endian
+ */
+ Q_STATIC_ASSERT(sizeof(quint64) == sizeof(double));
+ Q_ASSERT(qIsFinite(a) && qIsFinite(b));
+ if (a == b)
+ return 0;
+ if ((a < 0) != (b < 0)) {
+ // if they have different signs
+ if (a < 0)
+ a = -a;
+ else /*if (b < 0)*/
+ b = -b;
+ return qFloatDistance(0.0, a) + qFloatDistance(0.0, b);
+ }
+ if (a < 0) {
+ a = -a;
+ b = -b;
+ }
+ // at this point a and b should not be negative
+
+ // 0 is special
+ if (!a)
+ return d2i(b) - smallestPositiveFloatAsBits + 1;
+ if (!b)
+ return d2i(a) - smallestPositiveFloatAsBits + 1;
+
+ // finally do the common integer subtraction
+ return a > b ? d2i(a) - d2i(b) : d2i(b) - d2i(a);
+}
+
+
QT_END_NAMESPACE
diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h
index 25db5443eb..633486dff1 100644
--- a/src/corelib/global/qnumeric.h
+++ b/src/corelib/global/qnumeric.h
@@ -57,6 +57,9 @@ Q_CORE_EXPORT double qSNaN();
Q_CORE_EXPORT double qQNaN();
Q_CORE_EXPORT double qInf();
+Q_CORE_EXPORT quint32 qFloatDistance(float a, float b);
+Q_CORE_EXPORT quint64 qFloatDistance(double a, double b);
+
#define Q_INFINITY (QT_PREPEND_NAMESPACE(qInf)())
#define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)())
#define Q_QNAN (QT_PREPEND_NAMESPACE(qQNaN)())
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index eab3981f7a..701f79d21e 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -94,7 +94,6 @@ SOURCES += \
io/qloggingregistry.cpp
win32 {
- SOURCES += io/qsettings_win.cpp
SOURCES += io/qfsfileengine_win.cpp
SOURCES += io/qlockfile_win.cpp
@@ -102,11 +101,12 @@ win32 {
HEADERS += io/qfilesystemwatcher_win_p.h
SOURCES += io/qfilesystemengine_win.cpp
SOURCES += io/qfilesystemiterator_win.cpp
- SOURCES += io/qstandardpaths_win.cpp
!winrt {
+ SOURCES += io/qsettings_win.cpp
HEADERS += io/qwindowspipewriter_p.h
SOURCES += io/qwindowspipewriter.cpp
+ SOURCES += io/qstandardpaths_win.cpp
wince* {
SOURCES += io/qprocess_wince.cpp
@@ -119,6 +119,8 @@ win32 {
io/qwinoverlappedionotifier.cpp \
io/qwindowspipereader.cpp
}
+ } else {
+ SOURCES += io/qstandardpaths_winrt.cpp
}
} else:unix|integrity {
SOURCES += \
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index 008460df5d..614ac97f2f 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -251,7 +251,7 @@ QT_BEGIN_NAMESPACE
return retVal;
enum {
- DefaultStreamVersion = QDataStream::Qt_5_2
+ DefaultStreamVersion = QDataStream::Qt_5_3
};
/*!
@@ -541,6 +541,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_0 Version 13 (Qt 5.0)
\value Qt_5_1 Version 14 (Qt 5.1)
\value Qt_5_2 Version 15 (Qt 5.2)
+ \value Qt_5_3 Same as Qt_5_2
\sa setVersion(), version()
*/
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index f107e801b6..28f1d51a12 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -87,8 +87,9 @@ public:
Qt_4_9 = Qt_4_8,
Qt_5_0 = 13,
Qt_5_1 = 14,
- Qt_5_2 = 15
-#if QT_VERSION >= 0x050300
+ Qt_5_2 = 15,
+ Qt_5_3 = Qt_5_2
+#if QT_VERSION >= 0x050400
#error Add the datastream version for this Qt version
#endif
};
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index ebcaf062e3..e3adcad4bd 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -80,6 +80,16 @@
# include <qt_windows.h>
#endif
+#ifdef Q_OS_WINRT
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+#endif
+
#ifndef CSIDL_COMMON_APPDATA
#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
#endif
@@ -365,7 +375,7 @@ after_loop:
// see also qsettings_win.cpp and qsettings_mac.cpp
-#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
+#if defined(Q_OS_WINRT) || (!defined(Q_OS_WIN) && !defined(Q_OS_MAC))
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,
const QString &organization, const QString &application)
{
@@ -373,7 +383,7 @@ QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::
}
#endif
-#if !defined(Q_OS_WIN)
+#if defined(Q_OS_WINRT) || !defined(Q_OS_WIN)
QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::Format format)
{
return new QConfFileSettingsPrivate(fileName, format);
@@ -1019,7 +1029,7 @@ void QConfFileSettingsPrivate::initAccess()
sync(); // loads the files the first time
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static QString windowsConfigPath(int type)
{
QString result;
@@ -1061,7 +1071,40 @@ static QString windowsConfigPath(int type)
return result;
}
-#endif // Q_OS_WIN
+#elif defined(Q_OS_WINRT) // Q_OS_WIN && !Q_OS_WINRT
+static QString windowsConfigPath(int type)
+{
+ static QString result;
+ while (result.isEmpty()) {
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ return result;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ return result;
+ ComPtr<IStorageFolder> localFolder;
+ if (FAILED(applicationData->get_LocalFolder(&localFolder)))
+ return result;
+ ComPtr<IStorageItem> localFolderItem;
+ if (FAILED(localFolder.As(&localFolderItem)))
+ return result;
+ HSTRING path;
+ if (FAILED(localFolderItem->get_Path(&path)))
+ return result;
+ result = QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr));
+ }
+
+ switch (type) {
+ case CSIDL_COMMON_APPDATA:
+ return result + QLatin1String("\\qt-common");
+ case CSIDL_APPDATA:
+ return result + QLatin1String("\\qt-user");
+ default:
+ break;
+ }
+ return result;
+}
+#endif // Q_OS_WINRT
static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope)
{
@@ -1447,10 +1490,18 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QString writeSemName = QLatin1String("QSettingsWriteSem ");
writeSemName.append(file.fileName());
+#ifndef Q_OS_WINRT
writeSemaphore = CreateSemaphore(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()));
+#else
+ writeSemaphore = CreateSemaphoreEx(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
+#endif
if (writeSemaphore) {
+#ifndef Q_OS_WINRT
WaitForSingleObject(writeSemaphore, INFINITE);
+#else
+ WaitForSingleObjectEx(writeSemaphore, INFINITE, FALSE);
+#endif
} else {
setStatus(QSettings::AccessError);
return;
@@ -1463,11 +1514,19 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QString readSemName(QLatin1String("QSettingsReadSem "));
readSemName.append(file.fileName());
+#ifndef Q_OS_WINRT
readSemaphore = CreateSemaphore(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()));
+#else
+ readSemaphore = CreateSemaphoreEx(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
+#endif
if (readSemaphore) {
for (int i = 0; i < numReadLocks; ++i)
+#ifndef Q_OS_WINRT
WaitForSingleObject(readSemaphore, INFINITE);
+#else
+ WaitForSingleObjectEx(readSemaphore, INFINITE, FALSE);
+#endif
} else {
setStatus(QSettings::AccessError);
if (writeSemaphore != 0) {
diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp
new file mode 100644
index 0000000000..55a801332e
--- /dev/null
+++ b/src/corelib/io/qstandardpaths_winrt.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstandardpaths.h"
+
+#include <qdir.h>
+#include <private/qsystemlibrary_p.h>
+#include <qcoreapplication.h>
+#include <qstringlist.h>
+
+#include <qt_windows.h>
+
+#ifndef QT_NO_STANDARDPATHS
+
+QT_BEGIN_NAMESPACE
+
+static QString convertCharArray(const wchar_t *path)
+{
+ return QDir::fromNativeSeparators(QString::fromWCharArray(path));
+}
+
+QString QStandardPaths::writableLocation(StandardLocation type)
+{
+ Q_UNUSED(type)
+ Q_UNIMPLEMENTED();
+ return QString();
+}
+
+QStringList QStandardPaths::standardLocations(StandardLocation type)
+{
+ return QStringList(writableLocation(type));
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 26ad9f488c..998bf56874 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -68,16 +68,21 @@ SOURCES += \
win32 {
SOURCES += \
- kernel/qeventdispatcher_win.cpp \
kernel/qcoreapplication_win.cpp \
kernel/qwineventnotifier.cpp \
kernel/qsharedmemory_win.cpp \
kernel/qsystemsemaphore_win.cpp
HEADERS += \
- kernel/qeventdispatcher_win_p.h \
kernel/qwineventnotifier.h
-}
+ winrt {
+ SOURCES += kernel/qeventdispatcher_winrt.cpp
+ HEADERS += kernel/qeventdispatcher_winrt_p.h
+ } else {
+ SOURCES += kernel/qeventdispatcher_win.cpp
+ HEADERS += kernel/qeventdispatcher_win_p.h
+ }
+}
wince*: {
SOURCES += \
@@ -86,6 +91,13 @@ wince*: {
kernel/qfunctions_wince.h
}
+winrt {
+ SOURCES += \
+ kernel/qfunctions_winrt.cpp
+ HEADERS += \
+ kernel/qfunctions_winrt.h
+}
+
mac {
SOURCES += \
kernel/qcoreapplication_mac.cpp
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 71ff47eab8..8ae3057f3e 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -85,7 +85,11 @@
# endif
#endif
#ifdef Q_OS_WIN
+# ifdef Q_OS_WINRT
+# include "qeventdispatcher_winrt_p.h"
+# else
# include "qeventdispatcher_win_p.h"
+# endif
#endif
#endif // QT_NO_QOBJECT
@@ -472,6 +476,8 @@ void QCoreApplicationPrivate::createEventDispatcher()
# endif
eventDispatcher = new QEventDispatcherUNIX(q);
# endif
+#elif defined(Q_OS_WINRT)
+ eventDispatcher = new QEventDispatcherWinRT(q);
#elif defined(Q_OS_WIN)
eventDispatcher = new QEventDispatcherWin32(q);
#else
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
new file mode 100644
index 0000000000..c94c69b90f
--- /dev/null
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -0,0 +1,394 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeventdispatcher_winrt_p.h"
+
+#include "qelapsedtimer.h"
+#include "qcoreapplication.h"
+#include "qthread.h"
+
+#include <private/qcoreapplication_p.h>
+#include <private/qthread_p.h>
+
+#include <windows.foundation.h>
+#include <windows.system.threading.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::System::Threading;
+using namespace ABI::Windows::Foundation;
+
+QT_BEGIN_NAMESPACE
+
+QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
+ : QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
+{
+}
+
+QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent)
+ : QAbstractEventDispatcher(dd, parent)
+{ }
+
+QEventDispatcherWinRT::~QEventDispatcherWinRT()
+{
+}
+
+bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ Q_UNUSED(flags);
+
+ // we are awake, broadcast it
+ emit awake();
+ QCoreApplicationPrivate::sendPostedEvents(0, 0, QThreadData::current());
+
+ return false;
+}
+
+bool QEventDispatcherWinRT::hasPendingEvents()
+{
+ return qGlobalPostedEventsCount();
+}
+
+void QEventDispatcherWinRT::registerSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+}
+void QEventDispatcherWinRT::unregisterSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+}
+
+void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
+{
+ Q_UNUSED(timerType);
+
+ if (timerId < 1 || interval < 0 || !object) {
+ qWarning("QEventDispatcherWinRT::registerTimer: invalid arguments");
+ return;
+ } else if (object->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QObject::startTimer: timers cannot be started from another thread");
+ return;
+ }
+
+ Q_D(QEventDispatcherWinRT);
+
+ WinRTTimerInfo *t = new WinRTTimerInfo();
+ t->dispatcher = this;
+ t->timerId = timerId;
+ t->interval = interval;
+ t->timeout = interval;
+ t->timerType = timerType;
+ t->obj = object;
+ t->inTimerEvent = false;
+
+ d->registerTimer(t);
+ d->timerVec.append(t); // store in timer vector
+ d->timerDict.insert(t->timerId, t); // store timers in dict
+}
+
+bool QEventDispatcherWinRT::unregisterTimer(int timerId)
+{
+ if (timerId < 1) {
+ qWarning("QEventDispatcherWinRT::unregisterTimer: invalid argument");
+ return false;
+ }
+ if (thread() != QThread::currentThread()) {
+ qWarning("QObject::killTimer: timers cannot be stopped from another thread");
+ return false;
+ }
+
+ Q_D(QEventDispatcherWinRT);
+ if (d->timerVec.isEmpty() || timerId <= 0)
+ return false;
+
+ WinRTTimerInfo *t = d->timerDict.value(timerId);
+ if (!t)
+ return false;
+
+ if (t->timer)
+ d->threadPoolTimerDict.remove(t->timer);
+ d->timerDict.remove(t->timerId);
+ d->timerVec.removeAll(t);
+ d->unregisterTimer(t);
+ return true;
+}
+
+bool QEventDispatcherWinRT::unregisterTimers(QObject *object)
+{
+ if (!object) {
+ qWarning("QEventDispatcherWinRT::unregisterTimers: invalid argument");
+ return false;
+ }
+ QThread *currentThread = QThread::currentThread();
+ if (object->thread() != thread() || thread() != currentThread) {
+ qWarning("QObject::killTimers: timers cannot be stopped from another thread");
+ return false;
+ }
+
+ Q_D(QEventDispatcherWinRT);
+ if (d->timerVec.isEmpty())
+ return false;
+ register WinRTTimerInfo *t;
+ for (int i = 0; i < d->timerVec.size(); i++) {
+ t = d->timerVec.at(i);
+ if (t && t->obj == object) { // object found
+ if (t->timer)
+ d->threadPoolTimerDict.remove(t->timer);
+ d->timerDict.remove(t->timerId);
+ d->timerVec.removeAt(i);
+ d->unregisterTimer(t);
+ --i;
+ }
+ }
+ return true;
+}
+
+QList<QAbstractEventDispatcher::TimerInfo> QEventDispatcherWinRT::registeredTimers(QObject *object) const
+{
+ if (!object) {
+ qWarning("QEventDispatcherWinRT:registeredTimers: invalid argument");
+ return QList<TimerInfo>();
+ }
+
+ Q_D(const QEventDispatcherWinRT);
+ QList<TimerInfo> list;
+ for (int i = 0; i < d->timerVec.size(); ++i) {
+ const WinRTTimerInfo *t = d->timerVec.at(i);
+ if (t && t->obj == object)
+ list << TimerInfo(t->timerId, t->interval, t->timerType);
+ }
+ return list;
+}
+
+bool QEventDispatcherWinRT::registerEventNotifier(QWinEventNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+ return false;
+}
+
+void QEventDispatcherWinRT::unregisterEventNotifier(QWinEventNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+}
+
+int QEventDispatcherWinRT::remainingTime(int timerId)
+{
+#ifndef QT_NO_DEBUG
+ if (timerId < 1) {
+ qWarning("QEventDispatcherWinRT::remainingTime: invalid argument");
+ return -1;
+ }
+#endif
+
+ Q_D(QEventDispatcherWinRT);
+
+ if (d->timerVec.isEmpty())
+ return -1;
+
+ quint64 currentTime = qt_msectime();
+
+ register WinRTTimerInfo *t;
+ for (int i = 0; i < d->timerVec.size(); i++) {
+ t = d->timerVec.at(i);
+ if (t && t->timerId == timerId) { // timer found
+ if (currentTime < t->timeout) {
+ // time to wait
+ return t->timeout - currentTime;
+ } else {
+ return 0;
+ }
+ }
+ }
+
+#ifndef QT_NO_DEBUG
+ qWarning("QEventDispatcherWinRT::remainingTime: timer id %d not found", timerId);
+#endif
+
+ return -1;
+}
+
+void QEventDispatcherWinRT::wakeUp()
+{
+ Q_D(QEventDispatcherWinRT);
+ if (d->wakeUps.testAndSetAcquire(0, 1)) {
+ // ###TODO: is there any thing to wake up?
+ }
+}
+
+void QEventDispatcherWinRT::interrupt()
+{
+ Q_D(QEventDispatcherWinRT);
+ d->interrupt = true;
+ wakeUp();
+}
+
+void QEventDispatcherWinRT::flush()
+{
+}
+
+void QEventDispatcherWinRT::startingUp()
+{
+}
+
+void QEventDispatcherWinRT::closingDown()
+{
+ Q_D(QEventDispatcherWinRT);
+
+ // clean up any timers
+ for (int i = 0; i < d->timerVec.count(); ++i)
+ d->unregisterTimer(d->timerVec.at(i));
+ d->timerVec.clear();
+ d->timerDict.clear();
+ d->threadPoolTimerDict.clear();
+}
+
+bool QEventDispatcherWinRT::event(QEvent *e)
+{
+ Q_D(QEventDispatcherWinRT);
+ if (e->type() == QEvent::ZeroTimerEvent) {
+ QZeroTimerEvent *zte = static_cast<QZeroTimerEvent*>(e);
+ WinRTTimerInfo *t = d->timerDict.value(zte->timerId());
+ if (t) {
+ t->inTimerEvent = true;
+
+ QTimerEvent te(zte->timerId());
+ QCoreApplication::sendEvent(t->obj, &te);
+
+ t = d->timerDict.value(zte->timerId());
+ if (t) {
+ if (t->interval == 0 && t->inTimerEvent) {
+ // post the next zero timer event as long as the timer was not restarted
+ QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId()));
+ }
+
+ t->inTimerEvent = false;
+ }
+ }
+ return true;
+ } else if (e->type() == QEvent::Timer) {
+ QTimerEvent *te = static_cast<QTimerEvent*>(e);
+ d->sendTimerEvent(te->timerId());
+ }
+ return QAbstractEventDispatcher::event(e);
+}
+
+QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate()
+ : interrupt(false)
+ , timerFactory(0)
+{
+ CoInitializeEx(NULL, COINIT_MULTITHREADED);
+ HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory);
+ if (FAILED(hr))
+ qWarning("QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate: Could not obtain timer factory: %lx", hr);
+}
+
+QEventDispatcherWinRTPrivate::~QEventDispatcherWinRTPrivate()
+{
+ if (timerFactory)
+ timerFactory->Release();
+ CoUninitialize();
+}
+
+void QEventDispatcherWinRTPrivate::registerTimer(WinRTTimerInfo *t)
+{
+ Q_Q(QEventDispatcherWinRT);
+
+ int ok = 0;
+ uint interval = t->interval;
+ if (interval == 0u) {
+ // optimization for single-shot-zero-timer
+ QCoreApplication::postEvent(q, new QZeroTimerEvent(t->timerId));
+ ok = 1;
+ } else {
+ TimeSpan period;
+ period.Duration = interval * 10000; // TimeSpan is based on 100-nanosecond units
+ ok = SUCCEEDED(timerFactory->CreatePeriodicTimer(
+ Callback<ITimerElapsedHandler>(this, &QEventDispatcherWinRTPrivate::timerExpiredCallback).Get(), period, &t->timer));
+ if (ok)
+ threadPoolTimerDict.insert(t->timer, t);
+ }
+ t->timeout = qt_msectime() + interval;
+ if (ok == 0)
+ qErrnoWarning("QEventDispatcherWinRT::registerTimer: Failed to create a timer");
+}
+
+void QEventDispatcherWinRTPrivate::unregisterTimer(WinRTTimerInfo *t)
+{
+ if (t->timer) {
+ t->timer->Cancel();
+ t->timer->Release();
+ }
+ delete t;
+ t = 0;
+}
+
+void QEventDispatcherWinRTPrivate::sendTimerEvent(int timerId)
+{
+ WinRTTimerInfo *t = timerDict.value(timerId);
+ if (t && !t->inTimerEvent) {
+ // send event, but don't allow it to recurse
+ t->inTimerEvent = true;
+
+ QTimerEvent e(t->timerId);
+ QCoreApplication::sendEvent(t->obj, &e);
+
+ // timer could have been removed
+ t = timerDict.value(timerId);
+ if (t) {
+ t->inTimerEvent = false;
+ }
+ }
+}
+
+HRESULT QEventDispatcherWinRTPrivate::timerExpiredCallback(IThreadPoolTimer *source)
+{
+ register WinRTTimerInfo *t = threadPoolTimerDict.value(source);
+ if (t)
+ QCoreApplication::postEvent(t->dispatcher, new QTimerEvent(t->timerId));
+ else
+ qWarning("QEventDispatcherWinRT::timerExpiredCallback: Could not find timer %d in timer list", source);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h
new file mode 100644
index 0000000000..35b3faa771
--- /dev/null
+++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QEVENTDISPATCHER_WINRT_P_H
+#define QEVENTDISPATCHER_WINRT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qabstracteventdispatcher.h"
+#include "private/qabstracteventdispatcher_p.h"
+
+#include <qt_windows.h>
+#include <wrl.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace System {
+ namespace Threading {
+ struct IThreadPoolTimer;
+ struct IThreadPoolTimerStatics;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+int qt_msectime();
+
+class QEventDispatcherWinRTPrivate;
+
+class Q_CORE_EXPORT QEventDispatcherWinRT : public QAbstractEventDispatcher
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QEventDispatcherWinRT)
+
+public:
+ explicit QEventDispatcherWinRT(QObject *parent = 0);
+ ~QEventDispatcherWinRT();
+
+ bool processEvents(QEventLoop::ProcessEventsFlags flags);
+ bool hasPendingEvents();
+
+ void registerSocketNotifier(QSocketNotifier *notifier);
+ void unregisterSocketNotifier(QSocketNotifier *notifier);
+
+ void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
+ bool unregisterTimer(int timerId);
+ bool unregisterTimers(QObject *object);
+ QList<TimerInfo> registeredTimers(QObject *object) const;
+
+ int remainingTime(int timerId);
+
+ bool registerEventNotifier(QWinEventNotifier *notifier);
+ void unregisterEventNotifier(QWinEventNotifier *notifier);
+
+ void wakeUp();
+ void interrupt();
+ void flush();
+
+ void startingUp();
+ void closingDown();
+
+protected:
+ QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent = 0);
+
+
+ bool event(QEvent *);
+ int activateTimers();
+ int activateSocketNotifiers();
+};
+
+struct WinRTTimerInfo // internal timer info
+{
+ WinRTTimerInfo() : timer(0) {}
+
+ QObject *dispatcher;
+ int timerId;
+ int interval;
+ Qt::TimerType timerType;
+ quint64 timeout; // - when to actually fire
+ QObject *obj; // - object to receive events
+ bool inTimerEvent;
+ ABI::Windows::System::Threading::IThreadPoolTimer *timer;
+};
+
+class QZeroTimerEvent : public QTimerEvent
+{
+public:
+ explicit inline QZeroTimerEvent(int timerId)
+ : QTimerEvent(timerId)
+ { t = QEvent::ZeroTimerEvent; }
+};
+
+class Q_CORE_EXPORT QEventDispatcherWinRTPrivate : public QAbstractEventDispatcherPrivate
+{
+ Q_DECLARE_PUBLIC(QEventDispatcherWinRT)
+
+public:
+ QEventDispatcherWinRTPrivate();
+ ~QEventDispatcherWinRTPrivate();
+
+ QList<WinRTTimerInfo*> timerVec;
+ QHash<int, WinRTTimerInfo*> timerDict;
+ QHash<ABI::Windows::System::Threading::IThreadPoolTimer*, WinRTTimerInfo*> threadPoolTimerDict;
+
+ void registerTimer(WinRTTimerInfo *t);
+ void unregisterTimer(WinRTTimerInfo *t);
+ void sendTimerEvent(int timerId);
+ HRESULT timerExpiredCallback(ABI::Windows::System::Threading::IThreadPoolTimer *source);
+
+ QAtomicInt wakeUps;
+ bool interrupt;
+
+ ABI::Windows::System::Threading::IThreadPoolTimerStatics *timerFactory;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEVENTDISPATCHER_WINRT_P_H
diff --git a/src/corelib/kernel/qfunctions_p.h b/src/corelib/kernel/qfunctions_p.h
index 6e094f1ed3..e3014a0dcf 100644
--- a/src/corelib/kernel/qfunctions_p.h
+++ b/src/corelib/kernel/qfunctions_p.h
@@ -61,6 +61,8 @@
# include "QtCore/qfunctions_vxworks.h"
#elif defined(Q_OS_NACL)
# include "QtCore/qfunctions_nacl.h"
+#elif defined(Q_OS_WINRT)
+# include "QtCore/qfunctions_winrt.h"
#endif
#ifdef Q_CC_RVCT
diff --git a/src/corelib/kernel/qfunctions_winrt.cpp b/src/corelib/kernel/qfunctions_winrt.cpp
new file mode 100644
index 0000000000..f4a278dc43
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_winrt.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifdef Q_OS_WINRT
+
+#include "qfunctions_winrt.h"
+#include "qstring.h"
+#include "qbytearray.h"
+#include "qhash.h"
+
+QT_USE_NAMESPACE
+
+// Environment ------------------------------------------------------
+inline QHash<QByteArray, QByteArray> &qt_app_environment()
+{
+ static QHash<QByteArray, QByteArray> internalEnvironment;
+ return internalEnvironment;
+}
+
+errno_t qt_winrt_getenv_s(size_t* sizeNeeded, char* buffer, size_t bufferSize, const char* varName)
+{
+ if (!sizeNeeded)
+ return EINVAL;
+
+ if (!qt_app_environment().contains(varName)) {
+ if (buffer)
+ buffer[0] = '\0';
+ return ENOENT;
+ }
+
+ QByteArray value = qt_app_environment().value(varName);
+ if (!value.endsWith('\0')) // win32 guarantees terminated string
+ value.append('\0');
+
+ if (bufferSize < (size_t)value.size()) {
+ *sizeNeeded = value.size();
+ return 0;
+ }
+
+ strcpy(buffer, value.constData());
+ return 0;
+}
+
+errno_t qt_winrt__putenv_s(const char* varName, const char* value)
+{
+ QByteArray input = value;
+ if (input.isEmpty()) {
+ if (qt_app_environment().contains(varName))
+ qt_app_environment().remove(varName);
+ } else {
+ // win32 on winrt guarantees terminated string
+ if (!input.endsWith('\0'))
+ input.append('\0');
+ qt_app_environment()[varName] = input;
+ }
+
+ return 0;
+}
+
+void qt_winrt_tzset()
+{
+}
+
+void qt_winrt__tzset()
+{
+}
+
+#endif // Q_OS_WINRT
diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h
new file mode 100644
index 0000000000..fa2b2e12ff
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_winrt.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFUNCTIONS_WINRT_H
+#define QFUNCTIONS_WINRT_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WINRT
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BUILD_CORE_LIB
+#endif
+
+QT_END_NAMESPACE
+
+// Environment ------------------------------------------------------
+errno_t qt_winrt_getenv_s(size_t*, char*, size_t, const char*);
+errno_t qt_winrt__putenv_s(const char*, const char*);
+void qt_winrt_tzset();
+void qt_winrt__tzset();
+
+// As Windows Runtime lacks some standard functions used in Qt, these got
+// reimplemented. Other projects do this as well. Inline functions are used
+// that there is a central place to disable functions for newer versions if
+// they get available. There are no defines used anymore, because this
+// will break member functions of classes which are called like these
+// functions.
+// The other declarations available in this file are being used per
+// define inside qplatformdefs.h of the corresponding WinRT mkspec.
+
+#define generate_inline_return_func0(funcname, returntype) \
+ inline returntype funcname() \
+ { \
+ return qt_winrt_##funcname(); \
+ }
+#define generate_inline_return_func1(funcname, returntype, param1) \
+ inline returntype funcname(param1 p1) \
+ { \
+ return qt_winrt_##funcname(p1); \
+ }
+#define generate_inline_return_func2(funcname, returntype, param1, param2) \
+ inline returntype funcname(param1 p1, param2 p2) \
+ { \
+ return qt_winrt_##funcname(p1, p2); \
+ }
+#define generate_inline_return_func3(funcname, returntype, param1, param2, param3) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3); \
+ }
+#define generate_inline_return_func4(funcname, returntype, param1, param2, param3, param4) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4); \
+ }
+#define generate_inline_return_func5(funcname, returntype, param1, param2, param3, param4, param5) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4, p5); \
+ }
+#define generate_inline_return_func6(funcname, returntype, param1, param2, param3, param4, param5, param6) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6); \
+ }
+#define generate_inline_return_func7(funcname, returntype, param1, param2, param3, param4, param5, param6, param7) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6, p7); \
+ }
+
+typedef unsigned (__stdcall *StartAdressExFunc)(void *);
+typedef void(*StartAdressFunc)(void *);
+typedef int ( __cdecl *CompareFunc ) (const void *, const void *) ;
+
+generate_inline_return_func4(getenv_s, errno_t, size_t *, char *, size_t, const char *)
+generate_inline_return_func2(_putenv_s, errno_t, const char *, const char *)
+generate_inline_return_func0(tzset, void)
+generate_inline_return_func0(_tzset, void)
+
+#endif // Q_OS_WINRT
+#endif // QFUNCTIONS_WINRT_H
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index 242702b304..5eb34e635e 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -41,7 +41,11 @@
#include "qwineventnotifier.h"
+#ifdef Q_OS_WINRT
+#include "qeventdispatcher_winrt_p.h"
+#else
#include "qeventdispatcher_win_p.h"
+#endif
#include "qcoreapplication.h"
#include <private/qthread_p.h>
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
index 14b7f34008..a8cdf85fb6 100644
--- a/src/corelib/thread/qmutex_win.cpp
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -48,7 +48,12 @@ QT_BEGIN_NAMESPACE
QMutexPrivate::QMutexPrivate()
{
+#ifndef Q_OS_WINRT
event = CreateEvent(0, FALSE, FALSE, 0);
+#else
+ event = CreateEventEx(0, NULL, 0, EVENT_ALL_ACCESS);
+#endif
+
if (!event)
qWarning("QMutexData::QMutexData: Cannot create event");
}
@@ -58,7 +63,11 @@ QMutexPrivate::~QMutexPrivate()
bool QMutexPrivate::wait(int timeout)
{
+#ifndef Q_OS_WINRT
return (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0);
+#else
+ return (WaitForSingleObjectEx(event, timeout < 0 ? INFINITE : timeout, FALSE) == WAIT_OBJECT_0);
+#endif
}
void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 35d57b3d83..77a5584f43 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -154,7 +154,9 @@ QThreadPrivate::QThreadPrivate(QThreadData *d)
thread_id = 0;
#elif defined (Q_OS_WIN)
handle = 0;
+# ifndef Q_OS_WINRT
id = 0;
+# endif
waiters = 0;
#endif
#if defined (Q_OS_WIN)
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 5e4eedaac7..8c75690404 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -66,6 +66,10 @@
#include <algorithm>
+#ifdef Q_OS_WINRT
+#include <thread>
+#endif
+
QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
@@ -173,8 +177,13 @@ public:
static unsigned int __stdcall start(void *);
static void finish(void *, bool lockAnyway=true);
+# ifndef Q_OS_WINRT
Qt::HANDLE handle;
unsigned int id;
+# else
+ std::thread *handle;
+ std::thread::id id;
+# endif
int waiters;
bool terminationEnabled, terminatePending;
# endif
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index d49a6a9a8e..3de1e991c1 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
//#define WINVER 0x0500
-#if _WIN32_WINNT < 0x0400
+#if (_WIN32_WINNT < 0x0400) && !defined(Q_OS_WINRT)
#define _WIN32_WINNT 0x0400
#endif
@@ -54,10 +54,17 @@
#include <qpointer.h>
#include <private/qcoreapplication_p.h>
+#ifdef Q_OS_WINRT
+#include "private/qeventdispatcher_winrt_p.h"
+#else
#include <private/qeventdispatcher_win_p.h>
+#endif
#include <qt_windows.h>
+#ifdef Q_OS_WINRT
+#include <thread>
+#endif
#ifndef Q_OS_WINCE
#ifndef _MT
@@ -71,6 +78,7 @@
#ifndef QT_NO_THREAD
QT_BEGIN_NAMESPACE
+#ifndef Q_OS_WINRT
void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread);
DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID);
@@ -92,6 +100,38 @@ static void qt_free_tls()
}
}
Q_DESTRUCTOR_FUNCTION(qt_free_tls)
+#else // !Q_OS_WINRT
+
+__declspec(thread) static QThreadData* qt_current_thread_data_tls_index = 0;
+void qt_create_tls()
+{
+}
+
+static void qt_free_tls()
+{
+ if (qt_current_thread_data_tls_index) {
+ qt_current_thread_data_tls_index->deref();
+ qt_current_thread_data_tls_index = 0;
+ }
+}
+
+QThreadData* TlsGetValue(QThreadData*& tls)
+{
+ Q_ASSERT(tls == qt_current_thread_data_tls_index);
+ return tls;
+}
+
+void TlsSetValue(QThreadData*& tls, QThreadData* data)
+{
+ Q_ASSERT(tls == qt_current_thread_data_tls_index);
+ if (tls)
+ tls->deref();
+ tls = data;
+ if (tls)
+ tls->ref();
+}
+Q_DESTRUCTOR_FUNCTION(qt_free_tls)
+#endif // Q_OS_WINRT
/*
QThreadData
@@ -124,6 +164,9 @@ QThreadData *QThreadData::current()
if (!QCoreApplicationPrivate::theMainThread) {
QCoreApplicationPrivate::theMainThread = threadData->thread;
+#ifndef Q_OS_WINRT
+ // TODO: is there a way to reflect the branch's behavior using
+ // WinRT API?
} else {
HANDLE realHandle = INVALID_HANDLE_VALUE;
#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
@@ -138,6 +181,7 @@ QThreadData *QThreadData::current()
realHandle = reinterpret_cast<HANDLE>(GetCurrentThreadId());
#endif
qt_watch_adopted_thread(realHandle, threadData->thread);
+#endif // !Q_OS_WINRT
}
}
return threadData;
@@ -145,10 +189,16 @@ QThreadData *QThreadData::current()
void QAdoptedThread::init()
{
+#ifndef Q_OS_WINRT
d_func()->handle = GetCurrentThread();
d_func()->id = GetCurrentThreadId();
+#else
+ d_func()->handle = nullptr;
+ d_func()->id = std::this_thread::get_id();
+#endif
}
+#ifndef Q_OS_WINRT
static QVector<HANDLE> qt_adopted_thread_handles;
static QVector<QThread *> qt_adopted_qthreads;
static QMutex qt_adopted_thread_watcher_mutex;
@@ -297,6 +347,7 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
}
}
#endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINCE
+#endif // !Q_OS_WINRT
/**************************************************************************
** QThreadPrivate
@@ -306,7 +357,11 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
void QThreadPrivate::createEventDispatcher(QThreadData *data)
{
+#ifdef Q_OS_WINRT
+ QEventDispatcherWinRT *theEventDispatcher = new QEventDispatcherWinRT;
+#else
QEventDispatcherWin32 *theEventDispatcher = new QEventDispatcherWin32;
+#endif
data->eventDispatcher.storeRelease(theEventDispatcher);
theEventDispatcher->startingUp();
}
@@ -334,7 +389,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
else
createEventDispatcher(data);
-#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE)
+#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
// sets the name of the current thread.
QByteArray objectName = thr->objectName().toLocal8Bit();
qt_set_thread_name((HANDLE)-1,
@@ -380,11 +435,20 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway)
d->interruptionRequested = false;
if (!d->waiters) {
+#ifndef Q_OS_WINRT
CloseHandle(d->handle);
+#else
+ CloseHandle(d->handle->native_handle());
+ delete d->handle;
+#endif
d->handle = 0;
}
+#ifndef Q_OS_WINRT
d->id = 0;
+#else
+ d->id = std::thread::id();
+#endif
}
@@ -400,10 +464,15 @@ Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
int QThread::idealThreadCount() Q_DECL_NOTHROW
{
SYSTEM_INFO sysinfo;
+#ifndef Q_OS_WINRT
GetSystemInfo(&sysinfo);
+#else
+ GetNativeSystemInfo(&sysinfo);
+#endif
return sysinfo.dwNumberOfProcessors;
}
+#ifndef Q_OS_WINRT
void QThread::yieldCurrentThread()
{
#ifndef Q_OS_WINCE
@@ -427,7 +496,28 @@ void QThread::usleep(unsigned long usecs)
{
::Sleep((usecs / 1000) + 1);
}
+#else // !Q_OS_WINRT
+
+void QThread::yieldCurrentThread()
+{
+ std::this_thread::yield();
+}
+void QThread::sleep(unsigned long secs)
+{
+ std::this_thread::sleep_for(std::chrono::seconds(secs));
+}
+
+void QThread::msleep(unsigned long msecs)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(msecs));
+}
+
+void QThread::usleep(unsigned long usecs)
+{
+ std::this_thread::sleep_for(std::chrono::microseconds(usecs));
+}
+#endif // Q_OS_WINRT
void QThread::start(Priority priority)
{
@@ -449,6 +539,7 @@ void QThread::start(Priority priority)
d->returnCode = 0;
d->interruptionRequested = false;
+#ifndef Q_OS_WINRT
/*
NOTE: we create the thread in the suspended state, set the
priority and then resume the thread.
@@ -513,6 +604,23 @@ void QThread::start(Priority priority)
if (ResumeThread(d->handle) == (DWORD) -1) {
qErrnoWarning("QThread::start: Failed to resume new thread");
}
+#else // !Q_OS_WINRT
+ d->handle = new std::thread(QThreadPrivate::start, this);
+
+ if (!d->handle) {
+ qErrnoWarning(errno, "QThread::start: Failed to create thread");
+ d->running = false;
+ d->finished = true;
+ return;
+ }
+
+ d->id = d->handle->get_id();
+
+ if (priority != NormalPriority || priority != InheritPriority) {
+ qWarning("QThread::start: Failed to set thread priority (not implemented)");
+ d->priority = NormalPriority;
+ }
+#endif // Q_OS_WINRT
}
void QThread::terminate()
@@ -525,7 +633,14 @@ void QThread::terminate()
d->terminatePending = true;
return;
}
+
+#ifndef Q_OS_WINRT
TerminateThread(d->handle, 0);
+#else // !Q_OS_WINRT
+ qWarning("QThread::terminate: Terminate is not supported on WinRT");
+ CloseHandle(d->handle->native_handle());
+ d->handle = 0;
+#endif // Q_OS_WINRT
QThreadPrivate::finish(this, false);
}
@@ -534,7 +649,11 @@ bool QThread::wait(unsigned long time)
Q_D(QThread);
QMutexLocker locker(&d->mutex);
+#ifndef Q_OS_WINRT
if (d->id == GetCurrentThreadId()) {
+#else
+ if (d->id == std::this_thread::get_id()) {
+#endif
qWarning("QThread::wait: Thread tried to wait on itself");
return false;
}
@@ -545,6 +664,7 @@ bool QThread::wait(unsigned long time)
locker.mutex()->unlock();
bool ret = false;
+#ifndef Q_OS_WINRT
switch (WaitForSingleObject(d->handle, time)) {
case WAIT_OBJECT_0:
ret = true;
@@ -557,6 +677,23 @@ bool QThread::wait(unsigned long time)
default:
break;
}
+#else // !Q_OS_WINRT
+ if (d->handle->joinable()) {
+ switch (WaitForSingleObjectEx(d->handle->native_handle(), time, FALSE)) {
+ case WAIT_OBJECT_0:
+ ret = true;
+ d->handle->join();
+ break;
+ case WAIT_FAILED:
+ qErrnoWarning("QThread::wait: WaitForSingleObjectEx() failed");
+ break;
+ case WAIT_ABANDONED:
+ case WAIT_TIMEOUT:
+ default:
+ break;
+ }
+ }
+#endif // Q_OS_WINRT
locker.mutex()->lock();
--d->waiters;
@@ -568,7 +705,11 @@ bool QThread::wait(unsigned long time)
}
if (d->finished && !d->waiters) {
+#ifndef Q_OS_WINRT
CloseHandle(d->handle);
+#else
+ delete d->handle;
+#endif
d->handle = 0;
}
@@ -586,13 +727,16 @@ void QThread::setTerminationEnabled(bool enabled)
if (enabled && d->terminatePending) {
QThreadPrivate::finish(thr, false);
locker.unlock(); // don't leave the mutex locked!
+#ifndef Q_OS_WINRT
_endthreadex(0);
+#endif
}
}
// Caller must hold the mutex
void QThreadPrivate::setPriority(QThread::Priority threadPriority)
{
+#ifndef Q_OS_WINRT
// copied from start() with a few modifications:
int prio;
@@ -635,6 +779,12 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
if (!SetThreadPriority(handle, prio)) {
qErrnoWarning("QThread::setPriority: Failed to set thread priority");
}
+#else // !Q_OS_WINRT
+ if (priority != threadPriority) {
+ qWarning("QThread::setPriority: Failed to set thread priority (not implemented)");
+ return;
+ }
+#endif // Q_OS_WINRT
}
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index 1cb1f82b03..f09667a364 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -64,7 +64,11 @@ class QWaitConditionEvent
public:
inline QWaitConditionEvent() : priority(0), wokenUp(false)
{
+#ifndef Q_OS_WINRT
event = CreateEvent(NULL, TRUE, FALSE, NULL);
+#else
+ event = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
+#endif
}
inline ~QWaitConditionEvent() { CloseHandle(event); }
int priority;
@@ -91,7 +95,9 @@ QWaitConditionEvent *QWaitConditionPrivate::pre()
mtx.lock();
QWaitConditionEvent *wce =
freeQueue.isEmpty() ? new QWaitConditionEvent : freeQueue.takeFirst();
+#ifndef Q_OS_WINRT
wce->priority = GetThreadPriority(GetCurrentThread());
+#endif
wce->wokenUp = false;
// insert 'wce' into the queue (sorted by priority)
@@ -111,7 +117,12 @@ bool QWaitConditionPrivate::wait(QWaitConditionEvent *wce, unsigned long time)
{
// wait for the event
bool ret = false;
+#ifndef Q_OS_WINRT
switch (WaitForSingleObject(wce->event, time)) {
+#else
+ switch (WaitForSingleObjectEx(wce->event, time, FALSE)) {
+#endif
+
default: break;
case WAIT_OBJECT_0:
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index 762ad6fd09..860ad180f1 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -65,7 +65,8 @@ static QTimeZonePrivate *newBackendTimeZone()
return new QMacTimeZonePrivate();
#elif defined Q_OS_UNIX
return new QTzTimeZonePrivate();
-#elif defined Q_OS_WIN
+ // Registry based timezone backend not available on WinRT
+#elif defined Q_OS_WIN && !defined Q_OS_WINRT
return new QWinTimeZonePrivate();
#elif defined QT_USE_ICU
return new QIcuTimeZonePrivate();
@@ -89,7 +90,8 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &olsenId)
return new QMacTimeZonePrivate(olsenId);
#elif defined Q_OS_UNIX
return new QTzTimeZonePrivate(olsenId);
-#elif defined Q_OS_WIN
+ // Registry based timezone backend not available on WinRT
+#elif defined Q_OS_WIN && !defined Q_OS_WINRT
return new QWinTimeZonePrivate(olsenId);
#elif defined QT_USE_ICU
return new QIcuTimeZonePrivate(olsenId);
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index e043a4cd15..a645961236 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -124,8 +124,10 @@ else:blackberry {
HEADERS += tools/qlocale_blackberry.h
}
else:unix:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_tz.cpp
-else:win32:SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp tools/qtimezoneprivate_win.cpp
-else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
+else:win32 {
+ SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp
+ !winrt: SOURCES += tools/qtimezoneprivate_win.cpp
+} else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
else:SOURCES += tools/qelapsedtimer_generic.cpp
contains(QT_CONFIG, zlib) {
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index 4ec47fa4a9..252e6ff9b5 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -56,44 +56,49 @@ QT_BEGIN_NAMESPACE
const uchar *qt_patternForBrush(int brushStyle, bool invert)
{
Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
- if(invert) {
- static const uchar dense1_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
- static const uchar dense2_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
- static const uchar dense3_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
- static const uchar dense4_pat[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
- static const uchar dense5_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
- static const uchar dense6_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
- static const uchar dense7_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
- static const uchar hor_pat[] = { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 };
- static const uchar ver_pat[] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 };
- static const uchar cross_pat[] = { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 };
- static const uchar bdiag_pat[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
- static const uchar fdiag_pat[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
- static const uchar dcross_pat[] = { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 };
- static const uchar *const pat_tbl[] = {
- dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
- dense6_pat, dense7_pat,
- hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
- return pat_tbl[brushStyle - Qt::Dense1Pattern];
- }
- static const uchar dense1_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
- static const uchar dense2_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
- static const uchar dense3_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
- static const uchar dense4_pat[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };
- static const uchar dense5_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
- static const uchar dense6_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
- static const uchar dense7_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
- static const uchar hor_pat[] = { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff };
- static const uchar ver_pat[] = { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef };
- static const uchar cross_pat[] = { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef };
- static const uchar bdiag_pat[] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
- static const uchar fdiag_pat[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
- static const uchar dcross_pat[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e };
- static const uchar *const pat_tbl[] = {
- dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
- dense6_pat, dense7_pat,
- hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
- return pat_tbl[brushStyle - Qt::Dense1Pattern];
+ static const uchar pat_tbl[][2][8] = {
+ {
+ /* dense1 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
+ /*~dense1 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
+ }, {
+ /* dense2 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
+ /*~dense2 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
+ }, {
+ /* dense3 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
+ /*~dense3 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
+ }, {
+ /* dense4 */ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
+ /*~dense4 */ { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 },
+ }, {
+ /* dense5 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
+ /*~dense5 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
+ }, {
+ /* dense6 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
+ /*~dense6 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
+ }, {
+ /* dense7 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
+ /*~dense7 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
+ }, {
+ /* hor */ { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff },
+ /*~hor */ { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 },
+ }, {
+ /* ver */ { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef },
+ /*~ver */ { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
+ }, {
+ /* cross */ { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef },
+ /*~cross */ { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 },
+ }, {
+ /* bdiag */ { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe },
+ /*~bdiag */ { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 },
+ }, {
+ /* fdiag */ { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f },
+ /*~fdiag */ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
+ }, {
+ /* dcross */ { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e },
+ /*~dcross */ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 },
+ },
+ };
+ return pat_tbl[brushStyle - Qt::Dense1Pattern][invert];
}
QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index a7c4a0eae1..d8db244d66 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -455,15 +455,19 @@ QVector<qreal> QPen::dashPattern() const
switch (d->style) {
case Qt::DashLine:
+ dd->dashPattern.reserve(2);
dd->dashPattern << dash << space;
break;
case Qt::DotLine:
+ dd->dashPattern.reserve(2);
dd->dashPattern << dot << space;
break;
case Qt::DashDotLine:
+ dd->dashPattern.reserve(4);
dd->dashPattern << dash << space << dot << space;
break;
case Qt::DashDotDotLine:
+ dd->dashPattern.reserve(6);
dd->dashPattern << dash << space << dot << space << dot << space;
break;
default:
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index c222b62a36..4cfc2a6cc4 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -57,6 +57,7 @@
#include <string.h> // strchr, strncmp, etc.
#include <strings.h> // strncasecmp
+#include <clocale> // LC_CTYPE
TableGenerator::TableGenerator() : m_state(NoErrors),
m_systemComposeDir(QString())
diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp
index a08cede76a..bb2c5f53c3 100644
--- a/src/plugins/platforms/minimal/qminimalintegration.cpp
+++ b/src/plugins/platforms/minimal/qminimalintegration.cpp
@@ -41,16 +41,19 @@
#include "qminimalintegration.h"
#include "qminimalbackingstore.h"
-#ifndef Q_OS_WIN
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#else
-#include <QtCore/private/qeventdispatcher_win_p.h>
-#endif
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformwindow.h>
+#if !defined(Q_OS_WIN)
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#elif defined(Q_OS_WINRT)
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#else
+#include <QtCore/private/qeventdispatcher_win_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
QMinimalIntegration::QMinimalIntegration()
@@ -89,7 +92,11 @@ QPlatformBackingStore *QMinimalIntegration::createPlatformBackingStore(QWindow *
QAbstractEventDispatcher *QMinimalIntegration::createEventDispatcher() const
{
#ifdef Q_OS_WIN
+#ifndef Q_OS_WINRT
return new QEventDispatcherWin32;
+#else // !Q_OS_WINRT
+ return new QEventDispatcherWinRT;
+#endif // Q_OS_WINRT
#else
return createUnixEventDispatcher();
#endif
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
index a1da8e3a16..76881db6fc 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
@@ -52,7 +52,11 @@
#endif
#elif defined(Q_OS_WIN)
#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
+#ifndef Q_OS_WINRT
#include <QtCore/private/qeventdispatcher_win_p.h>
+#else
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#endif
#endif
#include <QtGui/private/qpixmap_raster_p.h>
@@ -143,7 +147,11 @@ QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const
#if defined(Q_OS_UNIX)
return createUnixEventDispatcher();
#elif defined(Q_OS_WIN)
+#ifndef Q_OS_WINRT
return new QOffscreenEventDispatcher<QEventDispatcherWin32>();
+#else // !Q_OS_WINRT
+ return new QOffscreenEventDispatcher<QEventDispatcherWinRT>();
+#endif // Q_OS_WINRT
#else
return 0;
#endif
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 377ca32e64..4a7c3b279f 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -15,7 +15,8 @@ mac {
else: SUBDIRS += cocoa
}
-win32: SUBDIRS += windows
+win32:!winrt: SUBDIRS += windows
+winrt: SUBDIRS += winrt
qnx {
SUBDIRS += qnx
diff --git a/src/plugins/platforms/winrt/blit.hlsl b/src/plugins/platforms/winrt/blit.hlsl
new file mode 100644
index 0000000000..170e7f40ca
--- /dev/null
+++ b/src/plugins/platforms/winrt/blit.hlsl
@@ -0,0 +1,14 @@
+uniform SamplerState Sampler : register(s0);
+uniform Texture2D Texture : register(t0);
+
+void blitvs(in float4 pos0 : TEXCOORD0, in float2 tex0 : TEXCOORD1,
+ out float4 gl_Position : SV_POSITION, out float2 coord : TEXCOORD0)
+{
+ coord = tex0;
+ gl_Position = pos0 * float4(1.0, -1.0, 1.0, 1.0);
+}
+
+float4 blitps(in float4 gl_Position : SV_POSITION, in float2 coord : TEXCOORD0) : SV_TARGET0
+{
+ return Texture.Sample(Sampler, coord);
+}
diff --git a/src/plugins/platforms/winrt/main.cpp b/src/plugins/platforms/winrt/main.cpp
new file mode 100644
index 0000000000..89d560dbe3
--- /dev/null
+++ b/src/plugins/platforms/winrt/main.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtintegration.h"
+
+#include <qpa/qplatformintegrationplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "winrt.json")
+
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QWinRTIntegrationPlugin::keys() const
+{
+ return QStringList(QStringLiteral("WinRT"));
+}
+
+QPlatformIntegration *QWinRTIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (!system.compare(QLatin1String("winrt"), Qt::CaseInsensitive))
+ return QWinRTIntegration::create();
+
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
new file mode 100644
index 0000000000..b219548788
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtbackingstore.h"
+
+#include "qwinrtscreen.h"
+#include "qwinrtwindow.h"
+#include "qwinrteglcontext.h"
+#include <QtGui/QOpenGLContext>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <dxgi.h>
+
+// Generated shader headers
+#include "blitps.h"
+#include "blitvs.h"
+
+namespace { // Utility namespace for writing out an ANGLE-compatible binary blob
+
+// Must match packaged ANGLE
+enum : quint32 {
+ AngleMajorVersion = 1,
+ AngleMinorVersion = 2,
+ AngleBuildRevision = 2446,
+ AngleVersion = ((AngleMajorVersion << 24) | (AngleMinorVersion << 16) | AngleBuildRevision),
+ AngleOptimizationLevel = (1 << 14)
+};
+
+struct ShaderString
+{
+ ShaderString(const char *data = 0) : data(data) { }
+ const char *data;
+};
+
+// ANGLE stream compatibility - when size_t is 32-bit, QDataStream::writeBytes() also works
+QDataStream &operator<<(QDataStream &stream, const ShaderString &shaderString)
+{
+ if (!shaderString.data)
+ return stream << size_t(0);
+
+ size_t len = strlen(shaderString.data);
+ stream << len;
+ stream.writeRawData(shaderString.data, int(len));
+ return stream;
+}
+
+struct Attribute
+{
+ Attribute(GLenum type = 0, const char *name = 0, quint32 index = 0)
+ : type(type), name(name), index(index) { }
+ GLenum type;
+ ShaderString name;
+ quint32 index;
+};
+
+struct Sampler
+{
+ enum TextureType { Texture2D, TextureCube };
+ Sampler(bool active = false, GLint unit = 0, TextureType type = Texture2D)
+ : active(active), unit(unit), type(type) { }
+ bool active;
+ GLint unit;
+ TextureType type;
+};
+
+struct Uniform
+{
+ Uniform() { }
+ Uniform(GLenum type, quint32 precision, const char *name, quint32 arraySize,
+ quint32 psRegisterIndex, quint32 vsRegisterIndex, quint32 registerCount)
+ : type(type), precision(precision), name(name), arraySize(arraySize)
+ , psRegisterIndex(psRegisterIndex), vsRegisterIndex(vsRegisterIndex), registerCount(registerCount) { }
+ GLenum type;
+ quint32 precision;
+ ShaderString name;
+ quint32 arraySize;
+ quint32 psRegisterIndex;
+ quint32 vsRegisterIndex;
+ quint32 registerCount;
+};
+
+struct UniformIndex
+{
+ UniformIndex(const char *name = 0, quint32 element = 0, quint32 index = 0)
+ : name(name), element(element), index(index) { }
+ ShaderString name;
+ quint32 element;
+ quint32 index;
+};
+
+static const QByteArray createAngleBinary(
+ const QVector<Attribute> &attributes,
+ const QVector<Sampler> &textureSamplers,
+ const QVector<Sampler> &vertexSamplers,
+ const QVector<Uniform> &uniforms,
+ const QVector<UniformIndex> &uniformIndex,
+ const QByteArray &pixelShader,
+ const QByteArray &vertexShader,
+ const QByteArray &geometryShader = QByteArray(),
+ bool usesPointSize = false)
+{
+ QByteArray binary;
+
+ QDataStream stream(&binary, QIODevice::WriteOnly);
+ stream.setByteOrder(QDataStream::LittleEndian);
+
+ stream << quint32(GL_PROGRAM_BINARY_ANGLE)
+ << quint32(AngleVersion)
+ << quint32(AngleOptimizationLevel);
+
+ // Vertex attributes
+ for (int i = 0; i < 16; ++i) {
+ if (i < attributes.size())
+ stream << quint32(attributes[i].type) << attributes[i].name << attributes[i].index;
+ else
+ stream << quint32(GL_NONE) << ShaderString() << qint32(-1);
+ }
+
+ // Texture units
+ for (int i = 0; i < 16; ++i) {
+ if (i < textureSamplers.size())
+ stream << textureSamplers[i].active << textureSamplers[i].unit << qint32(textureSamplers[i].type);
+ else
+ stream << false << qint32(0) << qint32(Sampler::Texture2D);
+ }
+
+ // Vertex texture units
+ for (int i = 0; i < 16; ++i) {
+ if (i < vertexSamplers.size())
+ stream << vertexSamplers[i].active << vertexSamplers[i].unit << qint32(vertexSamplers[i].type);
+ else
+ stream << false << qint32(0) << qint32(Sampler::Texture2D);
+ }
+
+ stream << vertexSamplers.size()
+ << textureSamplers.size()
+ << usesPointSize;
+
+ stream << size_t(uniforms.size());
+ foreach (const Uniform &uniform, uniforms) {
+ stream << uniform.type << uniform.precision << uniform.name << uniform.arraySize
+ << uniform.psRegisterIndex << uniform.vsRegisterIndex << uniform.registerCount;
+ }
+
+ stream << size_t(uniformIndex.size());
+ foreach (const UniformIndex &index, uniformIndex)
+ stream << index.name << index.element << index.index;
+
+ stream << quint32(pixelShader.size())
+ << quint32(vertexShader.size())
+ << quint32(geometryShader.size());
+
+ // ANGLE requires that we query the adapter for its LUID. Later on, it may be useful
+ // for checking feature level support, picking the best adapter on the system, etc.
+ IDXGIFactory1 *dxgiFactory;
+ if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)))) {
+ qCritical("QWinRTBackingStore: failed to create DXGI factory.");
+ return QByteArray();
+ }
+ IDXGIAdapter *dxgiAdapter;
+ if (FAILED(dxgiFactory->EnumAdapters(0, &dxgiAdapter))) {
+ qCritical("QWinRTBackingStore:: failed to enumerate adapter.");
+ dxgiFactory->Release();
+ return QByteArray();
+ }
+ DXGI_ADAPTER_DESC desc;
+ dxgiAdapter->GetDesc(&desc);
+ dxgiAdapter->Release();
+ QByteArray guid(sizeof(GUID), '\0');
+ memcpy(guid.data(), &desc.AdapterLuid, sizeof(LUID));
+ stream.writeRawData(guid.constData(), guid.size());
+ stream.writeRawData(pixelShader.constData(), pixelShader.size());
+ stream.writeRawData(vertexShader.constData(), vertexShader.size());
+ if (!geometryShader.isEmpty())
+ stream.writeRawData(geometryShader.constData(), geometryShader.size());
+
+ return binary;
+}
+
+} // namespace
+
+QT_BEGIN_NAMESPACE
+
+static const GLfloat normCoords[] = { -1, 1, 1, 1, 1, -1, -1, -1 };
+static const GLfloat quadCoords[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
+
+QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+ , m_context(new QOpenGLContext)
+ , m_shaderProgram(0)
+ , m_fbo(0)
+ , m_texture(0)
+ , m_screen(static_cast<QWinRTScreen*>(window->screen()->handle()))
+{
+ window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap
+
+ m_context->setFormat(window->requestedFormat());
+ m_context->setScreen(window->screen());
+ m_context->create();
+
+ m_context->makeCurrent(window);
+ glGenFramebuffers(1, &m_fbo);
+ glGenRenderbuffers(1, &m_rbo);
+ glGenTextures(1, &m_texture);
+ m_shaderProgram = glCreateProgram();
+
+#if 0 // Standard GLES passthrough shader program
+ static const char *vertexShaderSource =
+ "attribute vec4 pos0;\n"
+ "attribute vec2 tex0;\n"
+ "varying vec2 coord;\n"
+ "void main() {\n"
+ " coord = tex0;\n"
+ " gl_Position = pos0;\n"
+ "}\n";
+ static const char *fragmentShaderSource =
+ "uniform sampler2D texture;\n"
+ "varying highp vec2 coord;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(texture, coord);\n"
+ "}\n";
+ GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
+ glCompileShader(vertexShader);
+ GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
+ glCompileShader(fragmentShader);
+ glAttachShader(m_shaderProgram, vertexShader);
+ glAttachShader(m_shaderProgram, fragmentShader);
+ glLinkProgram(m_shaderProgram);
+#else // Precompiled passthrough shader
+ QVector<Attribute> attributes = QVector<Attribute>() << Attribute(GL_FLOAT_VEC4, "pos0", 0)
+ << Attribute(GL_FLOAT_VEC2, "tex0", 1);
+ QVector<Sampler> textureSamplers = QVector<Sampler>() << Sampler(true, 0, Sampler::Texture2D);
+ QVector<Sampler> vertexSamplers;
+ QVector<Uniform> uniforms = QVector<Uniform>() << Uniform(GL_SAMPLER_2D, 0, "texture", 0, 0, -1, 1);
+ QVector<UniformIndex> uniformsIndex = QVector<UniformIndex>() << UniformIndex("texture", 0, 0);
+ QByteArray pixelShader(reinterpret_cast<const char *>(q_blitps), sizeof(q_blitps));
+ QByteArray vertexShader(reinterpret_cast<const char *>(q_blitvs), sizeof(q_blitvs));
+ QByteArray binary = createAngleBinary(attributes, textureSamplers, vertexSamplers,
+ uniforms, uniformsIndex, pixelShader, vertexShader);
+ glProgramBinaryOES(m_shaderProgram, GL_PROGRAM_BINARY_ANGLE, binary.constData(), binary.size());
+#endif
+ m_context->doneCurrent();
+ resize(window->size(), QRegion());
+}
+
+QWinRTBackingStore::~QWinRTBackingStore()
+{
+ glDeleteBuffers(1, &m_fbo);
+ glDeleteRenderbuffers(1, &m_rbo);
+ glDeleteTextures(1, &m_texture);
+ glDeleteProgram(m_shaderProgram);
+}
+
+QPaintDevice *QWinRTBackingStore::paintDevice()
+{
+ return m_paintDevice.data();
+}
+
+void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(offset)
+
+ const QImage *image = static_cast<QImage *>(m_paintDevice.data());
+
+ m_context->makeCurrent(window);
+
+ // Blitting the entire image width trades zero image copy/relayout for a larger texture upload.
+ // Since we're blitting the whole width anyway, the boundingRect() is used in the assumption that
+ // we don't repeat upload. This is of course dependent on the distance between update regions.
+ // Ideally, we would use the GL_EXT_unpack_subimage extension, which should be possible to implement
+ // since D3D11_MAPPED_SUBRESOURCE supports RowPitch (see below).
+ // Note that single-line blits in a loop are *very* slow, so reducing calls to glTexSubImage2D
+ // is probably a good idea anyway.
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ QRect bounds = region.boundingRect();
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), m_size.width(), bounds.height(),
+ GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y()));
+ // TODO: Implement GL_EXT_unpack_subimage in ANGLE for more minimal uploads
+ //glPixelStorei(GL_UNPACK_ROW_LENGTH, image->bytesPerLine());
+ //glTexSubImage2D(GL_TEXTURE_2D, 0, bounds.x(), bounds.y(), bounds.width(), bounds.height(),
+ // GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y()) + bounds.x() * 4);
+
+ // Bind render buffer
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
+
+ // Bind position
+ glUseProgram(m_shaderProgram);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, normCoords);
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, quadCoords);
+
+ // Render
+ glViewport(0, 0, m_size.width(), m_size.height());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // Unbind
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+ glUseProgram(0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ // fast blit - TODO: perform the blit inside swap buffers instead
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_fbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0);
+ glBlitFramebufferANGLE(0, 0, m_size.width(), m_size.height(), // TODO: blit only the changed rectangle
+ 0, 0, m_size.width(), m_size.height(),
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ m_context->swapBuffers(window);
+ m_context->doneCurrent();
+}
+
+void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents)
+ if (m_size == size)
+ return;
+
+ m_size = size;
+ m_paintDevice.reset(new QImage(m_size, QImage::Format_ARGB32_Premultiplied));
+
+ m_context->makeCurrent(window());
+ // Input texture
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, m_size.width(), m_size.height(),
+ 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ // Render buffer
+ glBindRenderbuffer(GL_RENDERBUFFER, m_rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_BGRA8_EXT, m_size.width(), m_size.height());
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ m_context->doneCurrent();
+}
+
+void QWinRTBackingStore::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region)
+}
+
+void QWinRTBackingStore::endPaint()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h
new file mode 100644
index 0000000000..8be549b441
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTBACKINGSTORE_H
+#define QWINRTBACKINGSTORE_H
+
+#include <qpa/qplatformbackingstore.h>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTScreen;
+class QOpenGLContext;
+
+class QWinRTBackingStore : public QPlatformBackingStore
+{
+public:
+ explicit QWinRTBackingStore(QWindow *window);
+ ~QWinRTBackingStore();
+ QPaintDevice *paintDevice();
+ void beginPaint(const QRegion &);
+ void endPaint();
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+
+private:
+ QSize m_size;
+ QScopedPointer<QPaintDevice> m_paintDevice;
+ QScopedPointer<QOpenGLContext> m_context;
+ quint32 m_shaderProgram;
+ quint32 m_fbo;
+ quint32 m_rbo;
+ quint32 m_texture;
+ QWinRTScreen *m_screen;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTBACKINGSTORE_H
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp
new file mode 100644
index 0000000000..8241560cef
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtcursor.h"
+
+#include <wrl.h>
+#include <windows.ui.core.h>
+#include <windows.foundation.h>
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::Foundation;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTCursor::QWinRTCursor(ICoreWindow *window) : m_window(window), m_cursorFactory(nullptr)
+{
+#ifndef Q_OS_WINPHONE
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Core_CoreCursor).Get(), &m_cursorFactory);
+#endif
+}
+
+QWinRTCursor::~QWinRTCursor()
+{
+ if (m_cursorFactory)
+ m_cursorFactory->Release();
+}
+
+#ifndef QT_NO_CURSOR
+void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *)
+{
+#ifndef Q_OS_WINPHONE
+ if (!m_cursorFactory)
+ return;
+
+ CoreCursorType type;
+ switch (windowCursor ? windowCursor->shape() : Qt::ArrowCursor) {
+ case Qt::BlankCursor:
+ m_window->put_PointerCursor(nullptr);
+ return;
+ default:
+ case Qt::OpenHandCursor:
+ case Qt::ClosedHandCursor:
+ case Qt::DragCopyCursor:
+ case Qt::DragMoveCursor:
+ case Qt::DragLinkCursor:
+ // (unavailable)
+ case Qt::ArrowCursor:
+ type = CoreCursorType_Arrow;
+ break;
+ case Qt::UpArrowCursor:
+ type = CoreCursorType_UpArrow;
+ break;
+ case Qt::CrossCursor:
+ type = CoreCursorType_Cross;
+ break;
+ case Qt::WaitCursor:
+ case Qt::BusyCursor:
+ type = CoreCursorType_Wait;
+ break;
+ case Qt::IBeamCursor:
+ type = CoreCursorType_IBeam;
+ break;
+ case Qt::SizeVerCursor:
+ case Qt::SplitVCursor:
+ type = CoreCursorType_SizeNorthSouth;
+ break;
+ case Qt::SizeHorCursor:
+ case Qt::SplitHCursor:
+ type = CoreCursorType_SizeWestEast;
+ break;
+ case Qt::SizeBDiagCursor:
+ type = CoreCursorType_SizeNortheastSouthwest;
+ break;
+ case Qt::SizeFDiagCursor:
+ type = CoreCursorType_SizeNorthwestSoutheast;
+ break;
+ case Qt::SizeAllCursor:
+ type = CoreCursorType_SizeAll;
+ break;
+ case Qt::PointingHandCursor:
+ type = CoreCursorType_Hand;
+ break;
+ case Qt::ForbiddenCursor:
+ type = CoreCursorType_UniversalNo;
+ break;
+ case Qt::WhatsThisCursor:
+ type = CoreCursorType_Help;
+ break;
+ case Qt::BitmapCursor:
+ case Qt::CustomCursor:
+ // TODO: figure out if arbitrary bitmaps can be made into resource IDs
+ // For now, we don't get enough info from QCursor to set a custom cursor
+ type = CoreCursorType_Custom;
+ break;
+ }
+
+ ICoreCursor *cursor;
+ if (SUCCEEDED(m_cursorFactory->CreateCursor(type, 0, &cursor)))
+ m_window->put_PointerCursor(cursor);
+#endif // Q_OS_WINPHONE
+}
+#endif // QT_NO_CURSOR
+
+QPoint QWinRTCursor::pos() const
+{
+#ifdef Q_OS_WINPHONE
+ return QPlatformCursor::pos();
+#else
+ Point point;
+ m_window->get_PointerPosition(&point);
+ return QPoint(point.X, point.Y);
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.h b/src/plugins/platforms/winrt/qwinrtcursor.h
new file mode 100644
index 0000000000..f7b301a98b
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcursor.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTCURSOR_H
+#define QWINRTCURSOR_H
+
+#include <qpa/qplatformcursor.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Core {
+ struct ICoreWindow;
+ struct ICoreCursorFactory;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTCursor : public QPlatformCursor
+{
+public:
+ explicit QWinRTCursor(ABI::Windows::UI::Core::ICoreWindow *window);
+ ~QWinRTCursor();
+#ifndef QT_NO_CURSOR
+ void changeCursor(QCursor * windowCursor, QWindow *);
+#endif
+ QPoint pos() const;
+
+private:
+ ABI::Windows::UI::Core::ICoreWindow *m_window;
+ ABI::Windows::UI::Core::ICoreCursorFactory *m_cursorFactory;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCURSOR_H
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
new file mode 100644
index 0000000000..014378f896
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrteglcontext.h"
+
+QT_BEGIN_NAMESPACE
+
+QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface)
+ : QEGLPlatformContext(format, share, display, EGL_OPENGL_ES_API), m_eglSurface(surface)
+{
+}
+
+EGLSurface QWinRTEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+{
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
+ // All windows use the same surface
+ return m_eglSurface;
+ } else {
+ // TODO: return EGL surfaces for offscreen surfaces
+ qWarning("This plugin does not support offscreen surfaces.");
+ return EGL_NO_SURFACE;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h
new file mode 100644
index 0000000000..c065847374
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSEGLCONTEXT_H
+#define QWINDOWSEGLCONTEXT_H
+
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTEGLContext : public QEGLPlatformContext
+{
+public:
+ explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface);
+
+protected:
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
+
+private:
+ EGLSurface m_eglSurface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSEGLCONTEXT_H
diff --git a/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp
new file mode 100644
index 0000000000..3fada75b25
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrteventdispatcher.h"
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformscreen.h>
+#include <qpa/qplatformscreenpageflipper.h>
+#include <QtCore/QThread>
+#include <QtGui/QGuiApplication>
+
+#include <Windows.ui.core.h>
+#include <Windows.ApplicationModel.core.h>
+
+using namespace ABI::Windows::ApplicationModel::Core;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::Foundation;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTEventDispatcher::QWinRTEventDispatcher(ICoreDispatcher *dispatcher, QObject *parent)
+ : QEventDispatcherWinRT(parent)
+ , m_dispatcher(dispatcher)
+{
+}
+
+bool QWinRTEventDispatcher::hasPendingEvents()
+{
+ return QEventDispatcherWinRT::hasPendingEvents() || QWindowSystemInterface::windowSystemEventsQueued();
+}
+
+bool QWinRTEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ if (m_dispatcher)
+ m_dispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
+
+ const bool didProcess = QWindowSystemInterface::sendWindowSystemEvents(flags);
+
+ return QEventDispatcherWinRT::processEvents(flags & ~QEventLoop::WaitForMoreEvents) || didProcess;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrteventdispatcher.h b/src/plugins/platforms/winrt/qwinrteventdispatcher.h
new file mode 100644
index 0000000000..275a508b3c
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTEVENTDISPATCHER_H
+#define QWINRTEVENTDISPATCHER_H
+
+#include <QtCore/QAbstractEventDispatcher>
+#include <QtCore/QEvent>
+
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Core {
+ struct ICoreDispatcher;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTEventDispatcher : public QEventDispatcherWinRT
+{
+ Q_OBJECT
+public:
+ explicit QWinRTEventDispatcher(ABI::Windows::UI::Core::ICoreDispatcher *dispatcher, QObject *parent = 0);
+
+protected:
+ bool hasPendingEvents();
+ bool processEvents(QEventLoop::ProcessEventsFlags flags);
+
+private:
+ ABI::Windows::UI::Core::ICoreDispatcher *m_dispatcher;
+
+ friend class QWinRTIntegration;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTEVENTDISPATCHER_H
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
new file mode 100644
index 0000000000..c7fa339fad
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtfontdatabase.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFile>
+
+QT_BEGIN_NAMESPACE
+
+QString QWinRTFontDatabase::fontDir() const
+{
+ QString fontDirectory = QBasicFontDatabase::fontDir();
+ if (!QFile::exists(fontDirectory)) {
+ // Fall back to app directory + fonts, and just app directory after that
+ const QString applicationDirPath = QCoreApplication::applicationDirPath();
+ fontDirectory = applicationDirPath + QLatin1String("/fonts");
+ if (!QFile::exists(fontDirectory)) {
+ qWarning("No fonts directory found in application package.");
+ fontDirectory = applicationDirPath;
+ }
+ }
+ return fontDirectory;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
new file mode 100644
index 0000000000..49e32470c2
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTFONTDATABASE_H
+#define QWINRTFONTDATABASE_H
+
+#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTFontDatabase : public QBasicFontDatabase
+{
+public:
+ QString fontDir() const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTFONTDATABASE_H
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
new file mode 100644
index 0000000000..bc15f1e448
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtinputcontext.h"
+#include <QtGui/QWindow>
+
+#include <wrl.h>
+#include <roapi.h>
+#include <windows.ui.viewmanagement.h>
+#include <windows.ui.core.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::UI::Core;
+
+#ifdef Q_OS_WINPHONE
+#include <windows.phone.ui.core.h>
+using namespace ABI::Windows::Phone::UI::Core;
+#endif
+
+typedef ITypedEventHandler<InputPane*, InputPaneVisibilityEventArgs*> InputPaneVisibilityHandler;
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWinRTInputContext
+ \brief Manages Input Method visibility
+ \internal
+ \ingroup qt-qpa-winrt
+
+ Listens to the native virtual keyboard for hide/show events and provides
+ hints to the OS for showing/hiding. On WinRT, showInputPanel()/hideInputPanel()
+ have no effect because WinRT dictates that keyboard presence is user-driven:
+ (http://msdn.microsoft.com/en-us/library/windows/apps/hh465404.aspx)
+ Windows Phone, however, supports direct hiding/showing of the keyboard.
+*/
+
+QWinRTInputContext::QWinRTInputContext(ICoreWindow *window)
+ : m_window(window)
+{
+ IInputPaneStatics *statics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(),
+ &statics))) {
+ qWarning(Q_FUNC_INFO ": failed to retrieve input pane statics.");
+ return;
+ }
+
+ IInputPane *inputPane;
+ statics->GetForCurrentView(&inputPane);
+ statics->Release();
+ if (inputPane) {
+ EventRegistrationToken showToken, hideToken;
+ inputPane->add_Showing(Callback<InputPaneVisibilityHandler>(
+ this, &QWinRTInputContext::onShowing).Get(), &showToken);
+ inputPane->add_Hiding(Callback<InputPaneVisibilityHandler>(
+ this, &QWinRTInputContext::onHiding).Get(), &hideToken);
+
+ Rect rect;
+ inputPane->get_OccludedRect(&rect);
+ m_keyboardRect = QRectF(rect.X, rect.Y, rect.Width, rect.Height);
+ m_isInputPanelVisible = !m_keyboardRect.isEmpty();
+ } else {
+ qWarning(Q_FUNC_INFO ": failed to retrieve InputPane.");
+ }
+}
+
+QRectF QWinRTInputContext::keyboardRect() const
+{
+ return m_keyboardRect;
+}
+
+bool QWinRTInputContext::isInputPanelVisible() const
+{
+ return m_isInputPanelVisible;
+}
+
+HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEventArgs *)
+{
+ m_isInputPanelVisible = true;
+ emitInputPanelVisibleChanged();
+
+ Rect rect;
+ pane->get_OccludedRect(&rect);
+ setKeyboardRect(QRectF(rect.X, rect.Y, rect.Width, rect.Height));
+
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEventArgs *)
+{
+ m_isInputPanelVisible = false;
+ emitInputPanelVisibleChanged();
+
+ Rect rect;
+ pane->get_OccludedRect(&rect);
+ setKeyboardRect(QRectF(rect.X, rect.Y, rect.Width, rect.Height));
+
+ return S_OK;
+}
+
+void QWinRTInputContext::setKeyboardRect(const QRectF rect)
+{
+ if (m_keyboardRect == rect)
+ return;
+
+ m_keyboardRect = rect;
+ emitKeyboardRectChanged();
+}
+
+#ifdef Q_OS_WINPHONE
+
+void QWinRTInputContext::showInputPanel()
+{
+ ICoreWindowKeyboardInput *input;
+ if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) {
+ input->put_IsKeyboardInputEnabled(true);
+ input->Release();
+ }
+}
+
+void QWinRTInputContext::hideInputPanel()
+{
+ ICoreWindowKeyboardInput *input;
+ if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) {
+ input->put_IsKeyboardInputEnabled(false);
+ input->Release();
+ }
+}
+
+#else // Q_OS_WINPHONE
+
+// IRawElementProviderSimple
+HRESULT QWinRTInputContext::get_ProviderOptions(ProviderOptions *retVal)
+{
+ *retVal = ProviderOptions_ServerSideProvider|ProviderOptions_UseComThreading;
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::GetPatternProvider(PATTERNID id, IUnknown **retVal)
+{
+ switch (id) {
+ case 10002: //UIA_ValuePatternId
+ return QueryInterface(__uuidof(IValueProvider), (void**)retVal);
+ break;
+ case 10014: //UIA_TextPatternId:
+ return QueryInterface(__uuidof(ITextProvider), (void**)retVal);
+ case 10029: //UIA_TextChildPatternId:
+ *retVal = nullptr;
+ break;
+ default:
+ qWarning("Unhandled pattern ID: %d", id);
+ break;
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::GetPropertyValue(PROPERTYID idProp, VARIANT *retVal)
+{
+ switch (idProp) {
+ case 30003: //UIA_ControlTypePropertyId
+ retVal->vt = VT_I4;
+ retVal->lVal = 50025; //UIA_CustomControlTypeId
+ break;
+ case 30008: //UIA_IsKeyboardFocusablePropertyId
+ case 30009: //UIA_HasKeyboardFocusPropertyId
+ // These are probably never actually called
+ case 30016: //UIA_IsControlElementPropertyId
+ case 30017: //UIA_IsContentElementPropertyId
+ retVal->vt = VT_BOOL;
+ retVal->boolVal = VARIANT_TRUE;
+ break;
+ case 30019: //UIA_IsPasswordPropertyId
+ retVal->vt = VT_BOOL;
+ retVal->boolVal = VARIANT_FALSE;
+ break;
+ case 30020: //UIA_NativeWindowHandlePropertyId
+ retVal->vt = VT_PTR;
+ retVal->punkVal = m_window;
+ break;
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_HostRawElementProvider(IRawElementProviderSimple **retVal)
+{
+ // Return the window's element provider
+ IInspectable *hostProvider;
+ HRESULT hr = m_window->get_AutomationHostProvider(&hostProvider);
+ if (SUCCEEDED(hr)) {
+ hr = hostProvider->QueryInterface(IID_PPV_ARGS(retVal));
+ hostProvider->Release();
+ }
+ return hr;
+}
+
+// ITextProvider
+HRESULT QWinRTInputContext::GetSelection(SAFEARRAY **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::GetVisibleRanges(SAFEARRAY **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::RangeFromChild(IRawElementProviderSimple *,ITextRangeProvider **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::RangeFromPoint(UiaPoint, ITextRangeProvider **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_DocumentRange(ITextRangeProvider **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_SupportedTextSelection(SupportedTextSelection *)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+// IValueProvider
+HRESULT QWinRTInputContext::SetValue(LPCWSTR)
+{
+ // To be useful, requires listening to the focus object for a value change and raising an event
+ // May be useful for inputPanel autocomplete, etc.
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_Value(BSTR *)
+{
+ // To be useful, requires listening to the focus object for a value change and raising an event
+ // May be useful for inputPanel autocomplete, etc.
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_IsReadOnly(BOOL *isReadOnly)
+{
+ // isReadOnly dictates keyboard opening behavior when view is tapped.
+ // We need to decide if the user tapped within a control which is about to receive focus...
+ // Since this isn't possible (this function gets called before we receive the touch event),
+ // the most platform-aligned option is to show the keyboard if an editable item has focus,
+ // and close the keyboard if it is already open.
+ *isReadOnly = m_isInputPanelVisible || !inputMethodAccepted();
+ return S_OK;
+}
+
+#endif // !Q_OS_WINPHONE
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h
new file mode 100644
index 0000000000..0a35f9b6e1
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTINPUTCONTEXT_H
+#define QWINRTINPUTCONTEXT_H
+
+#include <qpa/qplatforminputcontext.h>
+#include <QtCore/QRectF>
+
+#include <wrl.h>
+#ifndef Q_OS_WINPHONE
+# include <UIAutomationCore.h>
+#endif
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Core {
+ struct ICoreWindow;
+ }
+ namespace ViewManagement {
+ struct IInputPane;
+ struct IInputPaneVisibilityEventArgs;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTInputContext : public QPlatformInputContext
+#ifndef Q_OS_WINPHONE
+ , public Microsoft::WRL::RuntimeClass<
+ Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
+ IRawElementProviderSimple, ITextProvider, IValueProvider>
+#endif // !Q_OS_WINPHONE
+{
+public:
+ explicit QWinRTInputContext(ABI::Windows::UI::Core::ICoreWindow *window);
+
+ QRectF keyboardRect() const;
+
+ bool isInputPanelVisible() const;
+
+#ifdef Q_OS_WINPHONE
+ void showInputPanel();
+ void hideInputPanel();
+#else // Q_OS_WINPHONE
+ // IRawElementProviderSimple
+ HRESULT __stdcall get_ProviderOptions(ProviderOptions *retVal);
+ HRESULT __stdcall GetPatternProvider(PATTERNID, IUnknown **);
+ HRESULT __stdcall GetPropertyValue(PROPERTYID idProp, VARIANT *retVal);
+ HRESULT __stdcall get_HostRawElementProvider(IRawElementProviderSimple **retVal);
+
+ // ITextProvider
+ HRESULT __stdcall GetSelection(SAFEARRAY **);
+ HRESULT __stdcall GetVisibleRanges(SAFEARRAY **);
+ HRESULT __stdcall RangeFromChild(IRawElementProviderSimple *,ITextRangeProvider **);
+ HRESULT __stdcall RangeFromPoint(UiaPoint, ITextRangeProvider **);
+ HRESULT __stdcall get_DocumentRange(ITextRangeProvider **);
+ HRESULT __stdcall get_SupportedTextSelection(SupportedTextSelection *);
+
+ // IValueProvider
+ HRESULT __stdcall SetValue(LPCWSTR);
+ HRESULT __stdcall get_Value(BSTR *);
+ HRESULT __stdcall get_IsReadOnly(BOOL *);
+#endif // !Q_OS_WINPHONE
+
+private:
+ HRESULT onShowing(ABI::Windows::UI::ViewManagement::IInputPane *,
+ ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs *);
+ HRESULT onHiding(ABI::Windows::UI::ViewManagement::IInputPane *,
+ ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs *);
+ void setKeyboardRect(const QRectF rect);
+
+ ABI::Windows::UI::Core::ICoreWindow *m_window;
+ QRectF m_keyboardRect;
+ bool m_isInputPanelVisible;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTINPUTCONTEXT_H
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
new file mode 100644
index 0000000000..9113ffeb19
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtintegration.h"
+#include "qwinrtwindow.h"
+#include "qwinrteventdispatcher.h"
+#include "qwinrtbackingstore.h"
+#include "qwinrtscreen.h"
+#include "qwinrtinputcontext.h"
+#include "qwinrtservices.h"
+#include "qwinrteglcontext.h"
+#include "qwinrtfontdatabase.h"
+
+#include <QtGui/QOpenGLContext>
+
+#include <wrl.h>
+#include <windows.ui.core.h>
+#include <windows.ui.viewmanagement.h>
+#include <Windows.ApplicationModel.core.h>
+
+using namespace Microsoft::WRL;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::ApplicationModel::Core;
+
+static IUISettings *getSettings()
+{
+ static IUISettings *settings = 0;
+ if (!settings) {
+ if (FAILED(RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_UISettings).Get(),
+ reinterpret_cast<IInspectable **>(&settings)))) {
+ qWarning("Could not activate UISettings.");
+ }
+ }
+ return settings;
+}
+
+QT_BEGIN_NAMESPACE
+
+QWinRTIntegration::QWinRTIntegration()
+ : m_success(false)
+ , m_fontDatabase(new QWinRTFontDatabase)
+ , m_services(new QWinRTServices)
+{
+ // Obtain the WinRT Application, view, and window
+ ICoreApplication *application;
+ if (FAILED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&application))))
+ qCritical("Could not attach to the application factory.");
+
+ ICoreApplicationView *view;
+ if (FAILED(application->GetCurrentView(&view))) {
+ qCritical("Could not obtain the application view - have you started outside of WinRT?");
+ return;
+ }
+
+ // Get core window (will act as our screen)
+ ICoreWindow *window;
+ if (FAILED(view->get_CoreWindow(&window))) {
+ qCritical("Could not obtain the application window - have you started outside of WinRT?");
+ return;
+ }
+ window->Activate();
+ m_screen = new QWinRTScreen(window);
+ screenAdded(m_screen);
+
+ // Get event dispatcher
+ ICoreDispatcher *dispatcher;
+ if (FAILED(window->get_Dispatcher(&dispatcher)))
+ qCritical("Could not capture UI Dispatcher");
+ m_eventDispatcher = new QWinRTEventDispatcher(dispatcher);
+
+ m_success = true;
+}
+
+QWinRTIntegration::~QWinRTIntegration()
+{
+ Windows::Foundation::Uninitialize();
+}
+
+QAbstractEventDispatcher *QWinRTIntegration::guiThreadEventDispatcher() const
+{
+ return m_eventDispatcher;
+}
+
+bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps:
+ case OpenGL:
+ case ApplicationState:
+ return true;
+ default:
+ return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QVariant QWinRTIntegration::styleHint(StyleHint hint) const
+{
+ switch (hint) {
+ case CursorFlashTime:
+ if (IUISettings *settings = getSettings()) {
+ quint32 blinkRate;
+ settings->get_CaretBlinkRate(&blinkRate);
+ return blinkRate;
+ }
+ break;
+ case MouseDoubleClickInterval:
+ if (IUISettings *settings = getSettings()) {
+ quint32 doubleClickTime;
+ settings->get_DoubleClickTime(&doubleClickTime);
+ return doubleClickTime;
+ }
+ case ShowIsFullScreen:
+ return true;
+ default:
+ break;
+ }
+ return QPlatformIntegration::styleHint(hint);
+}
+
+QPlatformWindow *QWinRTIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QWinRTWindow(window);
+}
+
+QPlatformBackingStore *QWinRTIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QWinRTBackingStore(window);
+}
+
+QPlatformOpenGLContext *QWinRTIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ QWinRTScreen *screen = static_cast<QWinRTScreen *>(context->screen()->handle());
+ return new QWinRTEGLContext(context->format(), context->handle(), screen->eglDisplay(), screen->eglSurface());
+}
+
+QPlatformFontDatabase *QWinRTIntegration::fontDatabase() const
+{
+ return m_fontDatabase;
+}
+
+QPlatformInputContext *QWinRTIntegration::inputContext() const
+{
+ return m_screen->inputContext();
+}
+
+QPlatformServices *QWinRTIntegration::services() const
+{
+ return m_services;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h
new file mode 100644
index 0000000000..b53c1cf7d2
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtintegration.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTINTEGRATION_H
+#define QWINRTINTEGRATION_H
+
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractEventDispatcher;
+class QWinRTScreen;
+
+class QWinRTIntegration : public QPlatformIntegration
+{
+private:
+ explicit QWinRTIntegration();
+public:
+ ~QWinRTIntegration();
+
+ static QWinRTIntegration *create()
+ {
+ QWinRTIntegration *integration = new QWinRTIntegration;
+ return integration->m_success ? integration : 0;
+ }
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+ QVariant styleHint(StyleHint hint) const;
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+ QPlatformFontDatabase *fontDatabase() const;
+ QPlatformInputContext *inputContext() const;
+ QPlatformServices *services() const;
+
+private:
+ bool m_success;
+ QWinRTScreen *m_screen;
+ QAbstractEventDispatcher *m_eventDispatcher;
+ QPlatformFontDatabase *m_fontDatabase;
+ QPlatformServices *m_services;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTINTEGRATION_H
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
new file mode 100644
index 0000000000..93c2736238
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -0,0 +1,1012 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtscreen.h"
+
+#include "qwinrtbackingstore.h"
+#include "qwinrtinputcontext.h"
+#include "qwinrtcursor.h"
+#include "qwinrteglcontext.h"
+
+#include <QtGui/QSurfaceFormat>
+#include <QtGui/QGuiApplication>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <qpa/qwindowsysteminterface.h>
+#include <QtCore/qt_windows.h>
+
+#include <wrl.h>
+#include <windows.system.h>
+#include <windows.devices.input.h>
+#include <windows.ui.h>
+#include <windows.ui.core.h>
+#include <windows.ui.input.h>
+#include <windows.ui.viewmanagement.h>
+#include <windows.graphics.display.h>
+#include <windows.foundation.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::System;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::Input;
+using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::Devices::Input;
+using namespace ABI::Windows::Graphics::Display;
+
+typedef ITypedEventHandler<CoreWindow*, WindowActivatedEventArgs*> ActivatedHandler;
+typedef ITypedEventHandler<CoreWindow*, CoreWindowEventArgs*> ClosedHandler;
+typedef ITypedEventHandler<CoreWindow*, CharacterReceivedEventArgs*> CharacterReceivedHandler;
+typedef ITypedEventHandler<CoreWindow*, InputEnabledEventArgs*> InputEnabledHandler;
+typedef ITypedEventHandler<CoreWindow*, KeyEventArgs*> KeyHandler;
+typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
+typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler;
+typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
+typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler;
+
+QT_BEGIN_NAMESPACE
+
+static inline Qt::ScreenOrientation qOrientationFromNative(DisplayOrientations orientation)
+{
+ switch (orientation) {
+ default:
+ case DisplayOrientations_None:
+ return Qt::PrimaryOrientation;
+ case DisplayOrientations_Landscape:
+ return Qt::LandscapeOrientation;
+ case DisplayOrientations_LandscapeFlipped:
+ return Qt::InvertedLandscapeOrientation;
+ case DisplayOrientations_Portrait:
+ return Qt::PortraitOrientation;
+ case DisplayOrientations_PortraitFlipped:
+ return Qt::InvertedPortraitOrientation;
+ }
+}
+
+static inline Qt::KeyboardModifiers qKeyModifiers(ICoreWindow *window)
+{
+ Qt::KeyboardModifiers mods;
+ CoreVirtualKeyStates mod;
+ window->GetAsyncKeyState(VirtualKey_Shift, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::ShiftModifier;
+ window->GetAsyncKeyState(VirtualKey_Menu, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::AltModifier;
+ window->GetAsyncKeyState(VirtualKey_Control, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::ControlModifier;
+ window->GetAsyncKeyState(VirtualKey_LeftWindows, &mod);
+ if (mod == CoreVirtualKeyStates_Down) {
+ mods |= Qt::MetaModifier;
+ } else {
+ window->GetAsyncKeyState(VirtualKey_RightWindows, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::MetaModifier;
+ }
+ return mods;
+}
+
+// Return Qt meta key from VirtualKey (discard character keys)
+static inline Qt::Key qMetaKeyFromVirtual(VirtualKey key)
+{
+ switch (key) {
+
+ default:
+ return Qt::Key_unknown;
+
+ // Modifiers
+ case VirtualKey_Shift:
+ case VirtualKey_LeftShift:
+ case VirtualKey_RightShift:
+ return Qt::Key_Shift;
+ case VirtualKey_Control:
+ case VirtualKey_LeftControl:
+ case VirtualKey_RightControl:
+ return Qt::Key_Control;
+ case VirtualKey_Menu:
+ case VirtualKey_LeftMenu:
+ case VirtualKey_RightMenu:
+ return Qt::Key_Alt;
+ case VirtualKey_LeftWindows:
+ case VirtualKey_RightWindows:
+ return Qt::Key_Meta;
+
+ // Toggle keys
+ case VirtualKey_CapitalLock:
+ return Qt::Key_CapsLock;
+ case VirtualKey_NumberKeyLock:
+ return Qt::Key_NumLock;
+ case VirtualKey_Scroll:
+ return Qt::Key_ScrollLock;
+
+ // East-Asian language keys
+ case VirtualKey_Kana:
+ //case VirtualKey_Hangul: // Same enum as Kana
+ return Qt::Key_Kana_Shift;
+ case VirtualKey_Junja:
+ return Qt::Key_Hangul_Jeonja;
+ case VirtualKey_Kanji:
+ //case VirtualKey_Hanja: // Same enum as Kanji
+ return Qt::Key_Kanji;
+ case VirtualKey_ModeChange:
+ return Qt::Key_Mode_switch;
+ case VirtualKey_Convert:
+ return Qt::Key_Henkan;
+ case VirtualKey_NonConvert:
+ return Qt::Key_Muhenkan;
+
+ // Misc. keys
+ case VirtualKey_Cancel:
+ return Qt::Key_Cancel;
+ case VirtualKey_Back:
+ return Qt::Key_Back;
+ case VirtualKey_Clear:
+ return Qt::Key_Clear;
+ case VirtualKey_Application:
+ return Qt::Key_ApplicationLeft;
+ case VirtualKey_Sleep:
+ return Qt::Key_Sleep;
+ case VirtualKey_Pause:
+ return Qt::Key_Pause;
+ case VirtualKey_Space:
+ return Qt::Key_Space;
+ case VirtualKey_PageUp:
+ return Qt::Key_PageUp;
+ case VirtualKey_PageDown:
+ return Qt::Key_PageDown;
+ case VirtualKey_End:
+ return Qt::Key_End;
+ case VirtualKey_Home:
+ return Qt::Key_Home;
+ case VirtualKey_Left:
+ return Qt::Key_Left;
+ case VirtualKey_Up:
+ return Qt::Key_Up;
+ case VirtualKey_Right:
+ return Qt::Key_Right;
+ case VirtualKey_Down:
+ return Qt::Key_Down;
+ case VirtualKey_Select:
+ return Qt::Key_Select;
+ case VirtualKey_Print:
+ return Qt::Key_Print;
+ case VirtualKey_Execute:
+ return Qt::Key_Execute;
+ case VirtualKey_Insert:
+ return Qt::Key_Insert;
+ case VirtualKey_Delete:
+ return Qt::Key_Delete;
+ case VirtualKey_Help:
+ return Qt::Key_Help;
+ case VirtualKey_Snapshot:
+ return Qt::Key_Camera;
+ case VirtualKey_Escape:
+ return Qt::Key_Escape;
+
+ // Function Keys
+ case VirtualKey_F1:
+ return Qt::Key_F1;
+ case VirtualKey_F2:
+ return Qt::Key_F2;
+ case VirtualKey_F3:
+ return Qt::Key_F3;
+ case VirtualKey_F4:
+ return Qt::Key_F4;
+ case VirtualKey_F5:
+ return Qt::Key_F5;
+ case VirtualKey_F6:
+ return Qt::Key_F6;
+ case VirtualKey_F7:
+ return Qt::Key_F7;
+ case VirtualKey_F8:
+ return Qt::Key_F8;
+ case VirtualKey_F9:
+ return Qt::Key_F9;
+ case VirtualKey_F10:
+ return Qt::Key_F10;
+ case VirtualKey_F11:
+ return Qt::Key_F11;
+ case VirtualKey_F12:
+ return Qt::Key_F12;
+ case VirtualKey_F13:
+ return Qt::Key_F13;
+ case VirtualKey_F14:
+ return Qt::Key_F14;
+ case VirtualKey_F15:
+ return Qt::Key_F15;
+ case VirtualKey_F16:
+ return Qt::Key_F16;
+ case VirtualKey_F17:
+ return Qt::Key_F17;
+ case VirtualKey_F18:
+ return Qt::Key_F18;
+ case VirtualKey_F19:
+ return Qt::Key_F19;
+ case VirtualKey_F20:
+ return Qt::Key_F20;
+ case VirtualKey_F21:
+ return Qt::Key_F21;
+ case VirtualKey_F22:
+ return Qt::Key_F22;
+ case VirtualKey_F23:
+ return Qt::Key_F23;
+ case VirtualKey_F24:
+ return Qt::Key_F24;
+
+ /* Character keys - pass through.
+ case VirtualKey_Enter:
+ case VirtualKey_Tab:
+ case VirtualKey_Number0:
+ case VirtualKey_Number1:
+ case VirtualKey_Number2:
+ case VirtualKey_Number3:
+ case VirtualKey_Number4:
+ case VirtualKey_Number5:
+ case VirtualKey_Number6:
+ case VirtualKey_Number7:
+ case VirtualKey_Number8:
+ case VirtualKey_Number9:
+ case VirtualKey_A:
+ case VirtualKey_B:
+ case VirtualKey_C:
+ case VirtualKey_D:
+ case VirtualKey_E:
+ case VirtualKey_F:
+ case VirtualKey_G:
+ case VirtualKey_H:
+ case VirtualKey_I:
+ case VirtualKey_J:
+ case VirtualKey_K:
+ case VirtualKey_L:
+ case VirtualKey_M:
+ case VirtualKey_N:
+ case VirtualKey_O:
+ case VirtualKey_P:
+ case VirtualKey_Q:
+ case VirtualKey_R:
+ case VirtualKey_S:
+ case VirtualKey_T:
+ case VirtualKey_U:
+ case VirtualKey_V:
+ case VirtualKey_W:
+ case VirtualKey_X:
+ case VirtualKey_Y:
+ case VirtualKey_Z:
+ case VirtualKey_Multiply:
+ case VirtualKey_Add:
+ case VirtualKey_Separator:
+ case VirtualKey_Subtract:
+ case VirtualKey_Decimal:
+ case VirtualKey_Divide:*/
+
+ /* NumberPad keys. No special Alt handling is needed, as WinRT doesn't send events if Alt is pressed.
+ case VirtualKey_NumberPad0:
+ case VirtualKey_NumberPad1:
+ case VirtualKey_NumberPad2:
+ case VirtualKey_NumberPad3:
+ case VirtualKey_NumberPad4:
+ case VirtualKey_NumberPad5:
+ case VirtualKey_NumberPad6:
+ case VirtualKey_NumberPad7:
+ case VirtualKey_NumberPad8:
+ case VirtualKey_NumberPad9:*/
+
+ /* Keys with no matching Qt enum (?)
+ case VirtualKey_None:
+ case VirtualKey_LeftButton:
+ case VirtualKey_RightButton:
+ case VirtualKey_MiddleButton:
+ case VirtualKey_XButton1:
+ case VirtualKey_XButton2:
+ case VirtualKey_Final:
+ case VirtualKey_Accept:*/
+ }
+}
+
+// Map Qt keys from char
+static inline Qt::Key qKeyFromChar(quint32 code, Qt::KeyboardModifiers mods = Qt::NoModifier)
+{
+ switch (code) {
+ case 0x1:
+ case 'a':
+ case 'A':
+ return Qt::Key_A;
+ case 0x2:
+ case 'b':
+ case 'B':
+ return Qt::Key_B;
+ case 0x3:
+ case 'c':
+ case 'C':
+ return Qt::Key_C;
+ case 0x4:
+ case 'd':
+ case 'D':
+ return Qt::Key_D;
+ case 0x5:
+ case 'e':
+ case 'E':
+ return Qt::Key_E;
+ case 0x6:
+ case 'f':
+ case 'F':
+ return Qt::Key_F;
+ case 0x7:
+ case 'g':
+ case 'G':
+ return Qt::Key_G;
+ case 0x8:
+ //case '\b':
+ return mods & Qt::ControlModifier ? Qt::Key_H : Qt::Key_Backspace;
+ case 'h':
+ case 'H':
+ return Qt::Key_H;
+ case 0x9:
+ //case '\t':
+ return mods & Qt::ControlModifier ? Qt::Key_I : Qt::Key_Tab;
+ case 'i':
+ case 'I':
+ return Qt::Key_I;
+ case 0xa:
+ //case '\n':
+ return mods & Qt::ControlModifier ? Qt::Key_J : Qt::Key_Enter;
+ case 'j':
+ case 'J':
+ return Qt::Key_J;
+ case 0xb:
+ case 'k':
+ case 'K':
+ return Qt::Key_K;
+ case 0xc:
+ case 'l':
+ case 'L':
+ return Qt::Key_L;
+ case 0xd:
+ case 'm':
+ case 'M':
+ return Qt::Key_M;
+ case 0xe:
+ case 'n':
+ case 'N':
+ return Qt::Key_N;
+ case 0xf:
+ case 'o':
+ case 'O':
+ return Qt::Key_O;
+ case 0x10:
+ case 'p':
+ case 'P':
+ return Qt::Key_P;
+ case 0x11:
+ case 'q':
+ case 'Q':
+ return Qt::Key_Q;
+ case 0x12:
+ case 'r':
+ case 'R':
+ return Qt::Key_R;
+ case 0x13:
+ case 's':
+ case 'S':
+ return Qt::Key_S;
+ case 0x14:
+ case 't':
+ case 'T':
+ return Qt::Key_T;
+ case 0x15:
+ case 'u':
+ case 'U':
+ return Qt::Key_U;
+ case 0x16:
+ case 'v':
+ case 'V':
+ return Qt::Key_V;
+ case 0x17:
+ case 'w':
+ case 'W':
+ return Qt::Key_W;
+ case 0x18:
+ case 'x':
+ case 'X':
+ return Qt::Key_X;
+ case 0x19:
+ case 'y':
+ case 'Y':
+ return Qt::Key_Y;
+ case 0x1A:
+ case 'z':
+ case 'Z':
+ return Qt::Key_Z;
+ }
+ return Qt::Key_unknown;
+}
+
+QWinRTScreen::QWinRTScreen(ICoreWindow *window)
+ : m_coreWindow(window)
+ , m_depth(32)
+ , m_format(QImage::Format_ARGB32_Premultiplied)
+#ifdef Q_OS_WINPHONE
+ , m_inputContext(new QWinRTInputContext(m_coreWindow))
+#else
+ , m_inputContext(Make<QWinRTInputContext>(m_coreWindow).Detach())
+#endif
+ , m_cursor(new QWinRTCursor(window))
+ , m_orientation(Qt::PrimaryOrientation)
+{
+#ifdef Q_OS_WINPHONE // On phone, there can be only one touch device
+ QTouchDevice *touchDevice = new QTouchDevice;
+ touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure);
+ touchDevice->setType(QTouchDevice::TouchScreen);
+ touchDevice->setName(QStringLiteral("WinPhoneTouchScreen"));
+ Pointer pointer = { Pointer::TouchScreen, touchDevice };
+ m_pointers.insert(0, pointer);
+ QWindowSystemInterface::registerTouchDevice(touchDevice);
+#endif
+
+ Rect rect;
+ window->get_Bounds(&rect);
+ m_geometry = QRect(0, 0, rect.Width, rect.Height);
+
+ m_surfaceFormat.setAlphaBufferSize(0);
+ m_surfaceFormat.setRedBufferSize(8);
+ m_surfaceFormat.setGreenBufferSize(8);
+ m_surfaceFormat.setBlueBufferSize(8);
+
+ m_surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
+ m_surfaceFormat.setSamples(1);
+ m_surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ m_surfaceFormat.setDepthBufferSize(24);
+ m_surfaceFormat.setStencilBufferSize(8);
+
+ m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (m_eglDisplay == EGL_NO_DISPLAY)
+ qFatal("Qt WinRT platform plugin: failed to initialize EGL display.");
+
+ if (!eglInitialize(m_eglDisplay, NULL, NULL))
+ qFatal("Qt WinRT platform plugin: failed to initialize EGL. This can happen if you haven't included the D3D compiler DLL in your application package.");
+
+ // TODO: move this to Window
+ m_eglSurface = eglCreateWindowSurface(m_eglDisplay, q_configFromGLFormat(m_eglDisplay, m_surfaceFormat), window, NULL);
+ if (m_eglSurface == EGL_NO_SURFACE)
+ qFatal("Could not create EGL surface, error 0x%X", eglGetError());
+
+ // Event handlers mapped to QEvents
+ m_coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKey).Get(), &m_tokens[QEvent::KeyPress]);
+ m_coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKey).Get(), &m_tokens[QEvent::KeyRelease]);
+ m_coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &m_tokens[QEvent::User]);
+ m_coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &m_tokens[QEvent::Enter]);
+ m_coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &m_tokens[QEvent::Leave]);
+ m_coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseMove]);
+ m_coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonPress]);
+ m_coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonRelease]);
+ m_coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::Wheel]);
+ m_coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &m_tokens[QEvent::Resize]);
+
+ // Window event handlers
+ m_coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &m_tokens[QEvent::WindowActivate]);
+ m_coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &m_tokens[QEvent::WindowDeactivate]);
+ m_coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &m_tokens[QEvent::Show]);
+ m_coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &m_tokens[QEvent::InputMethodQuery]);
+
+ // Orientation handling
+ if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(),
+ &m_displayProperties))) {
+ // Set native orientation
+ DisplayOrientations displayOrientation;
+ m_displayProperties->get_NativeOrientation(&displayOrientation);
+ m_nativeOrientation = qOrientationFromNative(displayOrientation);
+
+ // Set initial orientation
+ onOrientationChanged(0);
+
+ m_displayProperties->add_OrientationChanged(Callback<IDisplayPropertiesEventHandler>(this, &QWinRTScreen::onOrientationChanged).Get(),
+ &m_tokens[QEvent::OrientationChange]);
+ }
+
+#ifndef Q_OS_WINPHONE
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
+ &m_applicationView);
+#endif
+}
+
+QRect QWinRTScreen::geometry() const
+{
+ return m_geometry;
+}
+
+int QWinRTScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QWinRTScreen::format() const
+{
+ return m_format;
+}
+
+QSurfaceFormat QWinRTScreen::surfaceFormat() const
+{
+ return m_surfaceFormat;
+}
+
+QWinRTInputContext *QWinRTScreen::inputContext() const
+{
+ return m_inputContext;
+}
+
+QPlatformCursor *QWinRTScreen::cursor() const
+{
+ return m_cursor;
+}
+
+Qt::ScreenOrientation QWinRTScreen::nativeOrientation() const
+{
+ return m_nativeOrientation;
+}
+
+Qt::ScreenOrientation QWinRTScreen::orientation() const
+{
+ return m_orientation;
+}
+
+ICoreWindow *QWinRTScreen::coreWindow() const
+{
+ return m_coreWindow;
+}
+
+EGLDisplay QWinRTScreen::eglDisplay() const
+{
+ return m_eglDisplay;
+}
+
+EGLSurface QWinRTScreen::eglSurface() const
+{
+ return m_eglSurface;
+}
+
+QWindow *QWinRTScreen::topWindow() const
+{
+ return m_visibleWindows.isEmpty() ? 0 : m_visibleWindows.first();
+}
+
+void QWinRTScreen::addWindow(QWindow *window)
+{
+ if (window == topWindow())
+ return;
+ m_visibleWindows.prepend(window);
+ QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
+ handleExpose();
+}
+
+void QWinRTScreen::removeWindow(QWindow *window)
+{
+ const bool wasTopWindow = window == topWindow();
+ if (!m_visibleWindows.removeAll(window))
+ return;
+ if (wasTopWindow)
+ QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
+ handleExpose();
+}
+
+void QWinRTScreen::raise(QWindow *window)
+{
+ m_visibleWindows.removeAll(window);
+ addWindow(window);
+}
+
+void QWinRTScreen::lower(QWindow *window)
+{
+ const bool wasTopWindow = window == topWindow();
+ if (wasTopWindow && m_visibleWindows.size() == 1)
+ return;
+ m_visibleWindows.removeAll(window);
+ m_visibleWindows.append(window);
+ if (wasTopWindow)
+ QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
+ handleExpose();
+}
+
+void QWinRTScreen::handleExpose()
+{
+ if (m_visibleWindows.isEmpty())
+ return;
+ QList<QWindow *>::const_iterator it = m_visibleWindows.constBegin();
+ QWindowSystemInterface::handleExposeEvent(*it, m_geometry);
+ while (++it != m_visibleWindows.constEnd())
+ QWindowSystemInterface::handleExposeEvent(*it, QRegion());
+ QWindowSystemInterface::flushWindowSystemEvents();
+}
+
+HRESULT QWinRTScreen::onKey(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ // Windows Phone documentation claims this will throw, but doesn't seem to
+ CorePhysicalKeyStatus keyStatus;
+ args->get_KeyStatus(&keyStatus);
+
+ VirtualKey virtualKey;
+ args->get_VirtualKey(&virtualKey);
+
+ // Filter meta keys
+ Qt::Key key = qMetaKeyFromVirtual(virtualKey);
+
+ // Get keyboard modifiers. This could alternatively be tracked by key presses, but
+ // WinRT doesn't send key events for Alt unless Ctrl is also pressed.
+ // If the key that caused this event is a modifier, it is not returned in the flags.
+ Qt::KeyboardModifiers mods = qKeyModifiers(m_coreWindow);
+
+ if (m_activeKeys.contains(keyStatus.ScanCode)) { // Handle tracked keys (release/repeat)
+ QString text = keyStatus.IsKeyReleased ? m_activeKeys.take(keyStatus.ScanCode) : m_activeKeys.value(keyStatus.ScanCode);
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, key, mods, text);
+
+ if (!keyStatus.IsKeyReleased) // Repeating key
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text);
+
+ } else if (keyStatus.IsKeyReleased) { // Unlikely, but possible if key is held before application is focused
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, key, mods);
+
+ } else { // Handle key presses
+ if (key != Qt::Key_unknown) // Handle non-character key presses here, others in onCharacterReceived
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods);
+
+ m_activeKeys.insert(keyStatus.ScanCode, QString());
+ }
+
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceivedEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ quint32 keyCode;
+ args->get_KeyCode(&keyCode);
+
+ // Windows Phone documentation claims this will throw, but doesn't seem to
+ CorePhysicalKeyStatus keyStatus;
+ args->get_KeyStatus(&keyStatus);
+
+ QString text = QChar(keyCode);
+
+ Qt::KeyboardModifiers mods = qKeyModifiers(m_coreWindow);
+ Qt::Key key = qKeyFromChar(keyCode, mods);
+
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text);
+
+ // Note that we can receive a character without corresponding press/release events, such as
+ // the case of an Alt-combo. In this case, we should send the release immediately.
+ if (m_activeKeys.contains(keyStatus.ScanCode))
+ m_activeKeys.insert(keyStatus.ScanCode, text);
+ else
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, key, mods, text);
+
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *window, IPointerEventArgs *args)
+{
+ Q_UNUSED(window);
+ IPointerPoint *pointerPoint;
+ if (SUCCEEDED(args->get_CurrentPoint(&pointerPoint))) {
+ // Assumes full-screen window
+ Point point;
+ pointerPoint->get_Position(&point);
+ QPoint pos(point.X, point.Y);
+
+ QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos);
+ pointerPoint->Release();
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onPointerExited(ICoreWindow *window, IPointerEventArgs *args)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(args);
+ QWindowSystemInterface::handleLeaveEvent(0);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ IPointerPoint *pointerPoint;
+ if (FAILED(args->get_CurrentPoint(&pointerPoint)))
+ return E_INVALIDARG;
+
+ // Common traits - point, modifiers, properties
+ Point point;
+ pointerPoint->get_Position(&point);
+ QPointF pos(point.X, point.Y);
+
+ VirtualKeyModifiers modifiers;
+ args->get_KeyModifiers(&modifiers);
+ Qt::KeyboardModifiers mods;
+ if (modifiers & VirtualKeyModifiers_Control)
+ mods |= Qt::ControlModifier;
+ if (modifiers & VirtualKeyModifiers_Menu)
+ mods |= Qt::AltModifier;
+ if (modifiers & VirtualKeyModifiers_Shift)
+ mods |= Qt::ShiftModifier;
+ if (modifiers & VirtualKeyModifiers_Windows)
+ mods |= Qt::MetaModifier;
+
+ IPointerPointProperties *properties;
+ if (FAILED(pointerPoint->get_Properties(&properties)))
+ return E_INVALIDARG;
+
+#ifdef Q_OS_WINPHONE
+ quint32 pointerId = 0;
+ Pointer pointer = m_pointers.value(pointerId);
+#else
+ Pointer pointer = { Pointer::Unknown, 0 };
+ quint32 pointerId;
+ pointerPoint->get_PointerId(&pointerId);
+ if (m_pointers.contains(pointerId)) {
+ pointer = m_pointers.value(pointerId);
+ } else { // We have not yet enumerated this device. Do so now...
+ IPointerDevice *device;
+ if (SUCCEEDED(pointerPoint->get_PointerDevice(&device))) {
+ PointerDeviceType type;
+ device->get_PointerDeviceType(&type);
+ switch (type) {
+ case PointerDeviceType_Touch:
+ pointer.type = Pointer::TouchScreen;
+ pointer.device = new QTouchDevice;
+ pointer.device->setName(QStringLiteral("WinRT TouchScreen ") + QString::number(pointerId));
+ // TODO: We may want to probe the device usage flags for more accurate values for these next two
+ pointer.device->setType(QTouchDevice::TouchScreen);
+ pointer.device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure);
+ QWindowSystemInterface::registerTouchDevice(pointer.device);
+ break;
+
+ case PointerDeviceType_Pen:
+ pointer.type = Pointer::Tablet;
+ break;
+
+ case PointerDeviceType_Mouse:
+ pointer.type = Pointer::Mouse;
+ break;
+ }
+
+ m_pointers.insert(pointerId, pointer);
+ device->Release();
+ }
+ }
+#endif
+ switch (pointer.type) {
+ case Pointer::Mouse: {
+ qint32 delta;
+ properties->get_MouseWheelDelta(&delta);
+ if (delta) {
+ boolean isHorizontal;
+ properties->get_IsHorizontalMouseWheel(&isHorizontal);
+ QPoint angleDelta(isHorizontal ? delta : 0, isHorizontal ? 0 : delta);
+ QWindowSystemInterface::handleWheelEvent(topWindow(), pos, pos, QPoint(), angleDelta, mods);
+ break;
+ }
+
+ boolean isPressed;
+ Qt::MouseButtons buttons = Qt::NoButton;
+ properties->get_IsLeftButtonPressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::LeftButton;
+
+ properties->get_IsMiddleButtonPressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::MiddleButton;
+
+ properties->get_IsRightButtonPressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::RightButton;
+
+ properties->get_IsXButton1Pressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::XButton1;
+
+ properties->get_IsXButton2Pressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::XButton2;
+
+ QWindowSystemInterface::handleMouseEvent(topWindow(), pos, pos, buttons, mods);
+
+ break;
+ }
+ case Pointer::TouchScreen: {
+ quint32 id;
+ pointerPoint->get_PointerId(&id);
+
+ Rect area;
+ properties->get_ContactRect(&area);
+
+ float pressure;
+ properties->get_Pressure(&pressure);
+
+ QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = m_touchPoints.find(id);
+ if (it != m_touchPoints.end()) {
+ boolean isPressed;
+ pointerPoint->get_IsInContact(&isPressed);
+ it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased;
+ } else {
+ it = m_touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
+ it.value().state = Qt::TouchPointPressed;
+ it.value().id = id;
+ }
+ it.value().area = QRectF(area.X, area.Y, area.Width, area.Height);
+ it.value().normalPosition = QPointF(pos.x()/m_geometry.width(), pos.y()/m_geometry.height());
+ it.value().pressure = pressure;
+
+ QWindowSystemInterface::handleTouchEvent(topWindow(), pointer.device, m_touchPoints.values(), mods);
+
+ // Remove released points, station others
+ for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = m_touchPoints.begin(); i != m_touchPoints.end();) {
+ if (i.value().state == Qt::TouchPointReleased)
+ i = m_touchPoints.erase(i);
+ else
+ (i++).value().state = Qt::TouchPointStationary;
+ }
+
+ break;
+ }
+ case Pointer::Tablet: {
+ quint32 id;
+ pointerPoint->get_PointerId(&id);
+
+ boolean isPressed;
+ pointerPoint->get_IsInContact(&isPressed);
+
+ boolean isEraser;
+ properties->get_IsEraser(&isEraser);
+ int pointerType = isEraser ? 3 : 1;
+
+ float pressure;
+ properties->get_Pressure(&pressure);
+
+ float xTilt;
+ properties->get_XTilt(&xTilt);
+
+ float yTilt;
+ properties->get_YTilt(&yTilt);
+
+ float rotation;
+ properties->get_Twist(&rotation);
+
+ QWindowSystemInterface::handleTabletEvent(topWindow(), isPressed, pos, pos, pointerId,
+ pointerType, pressure, xTilt, yTilt,
+ 0, rotation, 0, id, mods);
+
+ break;
+ }
+ }
+
+ properties->Release();
+ pointerPoint->Release();
+
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args)
+{
+#ifndef Q_OS_WINPHONE
+ args->put_AutomationProvider(m_inputContext);
+#endif
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *window, IWindowSizeChangedEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ Size size;
+ if (FAILED(args->get_Size(&size))) {
+ qWarning(Q_FUNC_INFO ": failed to get size");
+ return S_OK;
+ }
+
+ // Regardless of state, all top-level windows are viewport-sized - this might change if
+ // a more advanced compositor is written.
+ m_geometry.setSize(QSize(size.Width, size.Height));
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry);
+ QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry);
+ QPlatformScreen::resizeMaximizedWindows();
+ handleExpose();
+
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onActivated(ICoreWindow *window, IWindowActivatedEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ CoreWindowActivationState activationState;
+ args->get_WindowActivationState(&activationState);
+ if (activationState == CoreWindowActivationState_Deactivated) {
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
+ return S_OK;
+ }
+
+ // Activate topWindow
+ if (!m_visibleWindows.isEmpty()) {
+ Qt::FocusReason focusReason = activationState == CoreWindowActivationState_PointerActivated
+ ? Qt::MouseFocusReason : Qt::ActiveWindowFocusReason;
+ QWindowSystemInterface::handleWindowActivated(topWindow(), focusReason);
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onClosed(ICoreWindow *window, ICoreWindowEventArgs *args)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(args);
+
+ foreach (QWindow *w, QGuiApplication::topLevelWindows())
+ QWindowSystemInterface::handleCloseEvent(w);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChangedEventArgs *args)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(args);
+
+ boolean visible;
+ args->get_Visible(&visible);
+ QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onOrientationChanged(IInspectable *)
+{
+ DisplayOrientations displayOrientation;
+ m_displayProperties->get_CurrentOrientation(&displayOrientation);
+ Qt::ScreenOrientation newOrientation = qOrientationFromNative(displayOrientation);
+ if (m_orientation != newOrientation) {
+ m_orientation = newOrientation;
+ QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
+ }
+
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
new file mode 100644
index 0000000000..d0ac53d56d
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTSCREEN_H
+#define QWINRTSCREEN_H
+
+#include <qpa/qplatformscreen.h>
+#include <qpa/qwindowsysteminterface.h>
+
+#include <QtCore/QHash>
+#include <QtGui/QSurfaceFormat>
+#include <EGL/egl.h>
+
+#include <EventToken.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Core {
+ struct IAutomationProviderRequestedEventArgs;
+ struct ICharacterReceivedEventArgs;
+ struct ICoreWindow;
+ struct ICoreWindowEventArgs;
+ struct IKeyEventArgs;
+ struct IPointerEventArgs;
+ struct IVisibilityChangedEventArgs;
+ struct IWindowActivatedEventArgs;
+ struct IWindowSizeChangedEventArgs;
+ }
+ namespace ViewManagement {
+ struct IApplicationViewStatics;
+ }
+ }
+ namespace Graphics {
+ namespace Display {
+ struct IDisplayPropertiesStatics;
+ }
+ }
+ }
+}
+struct IInspectable;
+
+QT_BEGIN_NAMESPACE
+
+class QTouchDevice;
+class QWinRTEGLContext;
+class QWinRTPageFlipper;
+class QWinRTCursor;
+class QWinRTInputContext;
+
+struct Pointer {
+ enum Type { Unknown, Mouse, TouchScreen, Tablet };
+ Type type;
+ QTouchDevice *device;
+};
+
+class QWinRTScreen : public QPlatformScreen
+{
+public:
+ explicit QWinRTScreen(ABI::Windows::UI::Core::ICoreWindow *window);
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSurfaceFormat surfaceFormat() const;
+ QWinRTInputContext *inputContext() const;
+ QPlatformCursor *cursor() const;
+
+ Qt::ScreenOrientation nativeOrientation() const;
+ Qt::ScreenOrientation orientation() const;
+
+ QWindow *topWindow() const;
+ void addWindow(QWindow *window);
+ void removeWindow(QWindow *window);
+ void raise(QWindow *window);
+ void lower(QWindow *window);
+
+ ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
+ EGLDisplay eglDisplay() const; // To opengl context
+ EGLSurface eglSurface() const; // To window
+
+private:
+ void handleExpose();
+
+ // Event handlers
+ QHash<QEvent::Type, EventRegistrationToken> m_tokens;
+
+ HRESULT onKey(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args);
+ HRESULT onCharacterReceived(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::ICharacterReceivedEventArgs *args);
+ HRESULT onPointerEntered(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
+ HRESULT onPointerExited(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
+ HRESULT onPointerUpdated(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
+ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *args);
+
+ HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *args);
+ HRESULT onClosed(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICoreWindowEventArgs *args);
+ HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *args);
+ HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *args);
+
+ HRESULT onOrientationChanged(IInspectable *);
+
+ ABI::Windows::UI::Core::ICoreWindow *m_coreWindow;
+ ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView;
+ QRect m_geometry;
+ QImage::Format m_format;
+ QSurfaceFormat m_surfaceFormat;
+ int m_depth;
+ QWinRTInputContext *m_inputContext;
+ QWinRTCursor *m_cursor;
+ QList<QWindow *> m_visibleWindows;
+
+ EGLDisplay m_eglDisplay;
+ EGLSurface m_eglSurface;
+
+ ABI::Windows::Graphics::Display::IDisplayPropertiesStatics *m_displayProperties;
+ Qt::ScreenOrientation m_nativeOrientation;
+ Qt::ScreenOrientation m_orientation;
+
+ QHash<quint32, QString> m_activeKeys;
+ QHash<quint32, Pointer> m_pointers;
+ QHash<quint32, QWindowSystemInterface::TouchPoint> m_touchPoints;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTSCREEN_H
diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp
new file mode 100644
index 0000000000..8f0a1d55bb
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtservices.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtservices.h"
+#include <QtCore/QUrl>
+#include <QtCore/QDir>
+#include <QtCore/QCoreApplication>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+#include <windows.system.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::System;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTServices::QWinRTServices()
+{
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Uri).Get(), &m_uriFactory);
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFile).Get(), &m_fileFactory);
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Launcher).Get(), &m_launcher);
+}
+
+QWinRTServices::~QWinRTServices()
+{
+ if (m_uriFactory)
+ m_uriFactory->Release();
+
+ if (m_fileFactory)
+ m_fileFactory->Release();
+
+ if (m_launcher)
+ m_launcher->Release();
+}
+
+bool QWinRTServices::openUrl(const QUrl &url)
+{
+ if (!(m_uriFactory && m_launcher))
+ return QPlatformServices::openUrl(url);
+
+ IUriRuntimeClass *uri;
+ QString urlString = url.toString(); HSTRING uriString; HSTRING_HEADER header;
+ WindowsCreateStringReference((const wchar_t*)urlString.utf16(), urlString.length(), &header, &uriString);
+ m_uriFactory->CreateUri(uriString, &uri);
+ if (!uri)
+ return false;
+
+ IAsyncOperation<bool> *launchOp;
+ m_launcher->LaunchUriAsync(uri, &launchOp);
+ uri->Release();
+ if (!launchOp)
+ return false;
+
+ boolean result = false;
+ while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+ launchOp->Release();
+
+ return result;
+}
+
+bool QWinRTServices::openDocument(const QUrl &url)
+{
+ if (!(m_fileFactory && m_launcher))
+ return QPlatformServices::openDocument(url);
+
+ QString pathString = QDir::toNativeSeparators(
+ QDir::cleanPath(qApp->applicationDirPath().append(url.toString(QUrl::RemoveScheme))));
+ HSTRING_HEADER header; HSTRING path;
+ WindowsCreateStringReference((const wchar_t*)pathString.utf16(), pathString.length(), &header, &path);
+ IAsyncOperation<StorageFile*> *fileOp;
+ m_fileFactory->GetFileFromPathAsync(path, &fileOp);
+ if (!fileOp)
+ return false;
+
+ IStorageFile *file = nullptr;
+ while (fileOp->GetResults(&file) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+ fileOp->Release();
+ if (!file)
+ return false;
+
+ IAsyncOperation<bool> *launchOp;
+ m_launcher->LaunchFileAsync(file, &launchOp);
+ if (!launchOp)
+ return false;
+
+ boolean result = false;
+ while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+ launchOp->Release();
+
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtservices.h b/src/plugins/platforms/winrt/qwinrtservices.h
new file mode 100644
index 0000000000..9cc917030a
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtservices.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTSERVICES_H
+#define QWINRTSERVICES_H
+
+#include <qpa/qplatformservices.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace Foundation {
+ struct IUriRuntimeClassFactory;
+ }
+ namespace Storage {
+ struct IStorageFileStatics;
+ }
+ namespace System {
+ struct ILauncherStatics;
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTServices : public QPlatformServices
+{
+public:
+ explicit QWinRTServices();
+ ~QWinRTServices();
+
+ bool openUrl(const QUrl &url);
+ bool openDocument(const QUrl &url);
+
+private:
+ ABI::Windows::Foundation::IUriRuntimeClassFactory *m_uriFactory;
+ ABI::Windows::Storage::IStorageFileStatics *m_fileFactory;
+ ABI::Windows::System::ILauncherStatics *m_launcher;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTSERVICES_H
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
new file mode 100644
index 0000000000..88b753b463
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtwindow.h"
+#include "qwinrtscreen.h"
+
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformscreen.h>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLContext>
+
+QT_BEGIN_NAMESPACE
+
+QWinRTWindow::QWinRTWindow(QWindow *window)
+ : QPlatformWindow(window)
+ , m_screen(static_cast<QWinRTScreen*>(screen()))
+{
+ setWindowFlags(window->flags());
+ setWindowState(window->windowState());
+ handleContentOrientationChange(window->contentOrientation());
+ setGeometry(window->geometry());
+}
+
+QWinRTWindow::~QWinRTWindow()
+{
+ m_screen->removeWindow(window());
+}
+
+QSurfaceFormat QWinRTWindow::format() const
+{
+ return m_screen->surfaceFormat();
+}
+
+bool QWinRTWindow::isActive() const
+{
+ return m_screen->topWindow() == window();
+}
+
+bool QWinRTWindow::isExposed() const
+{
+ const bool exposed = isActive();
+ return exposed;
+}
+
+void QWinRTWindow::setGeometry(const QRect &rect)
+{
+ if (window()->isTopLevel()) {
+ QPlatformWindow::setGeometry(m_screen->geometry());
+ QWindowSystemInterface::handleGeometryChange(window(), geometry());
+ } else {
+ QPlatformWindow::setGeometry(rect);
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
+ }
+}
+
+void QWinRTWindow::setVisible(bool visible)
+{
+ if (!window()->isTopLevel())
+ return;
+ if (visible)
+ m_screen->addWindow(window());
+ else
+ m_screen->removeWindow(window());
+}
+
+void QWinRTWindow::raise()
+{
+ if (!window()->isTopLevel())
+ return;
+ m_screen->raise(window());
+}
+
+void QWinRTWindow::lower()
+{
+ if (!window()->isTopLevel())
+ return;
+ m_screen->lower(window());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
new file mode 100644
index 0000000000..1f19b4f2d5
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTWINDOW_H
+#define QWINRTWINDOW_H
+
+#include <qpa/qplatformwindow.h>
+#include <qpa/qwindowsysteminterface.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTScreen;
+
+class QWinRTWindow : public QPlatformWindow
+{
+public:
+ QWinRTWindow(QWindow *window);
+ ~QWinRTWindow();
+
+ QSurfaceFormat format() const;
+ bool isActive() const;
+ bool isExposed() const;
+ void setGeometry(const QRect &rect);
+ void setVisible(bool visible);
+ void raise();
+ void lower();
+
+private:
+ QWinRTScreen *m_screen;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTWINDOW_H
diff --git a/src/plugins/platforms/winrt/winrt.json b/src/plugins/platforms/winrt/winrt.json
new file mode 100644
index 0000000000..962747b697
--- /dev/null
+++ b/src/plugins/platforms/winrt/winrt.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "winrt" ]
+}
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
new file mode 100644
index 0000000000..ea5ff93d00
--- /dev/null
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -0,0 +1,55 @@
+TARGET = qwinrt
+CONFIG -= precompile_header
+
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin
+load(qt_plugin)
+
+QT += core-private gui-private platformsupport-private
+
+DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES
+
+LIBS += $$QMAKE_LIBS_CORE -ldxgi
+
+SOURCES = \
+ main.cpp \
+ qwinrtbackingstore.cpp \
+ qwinrtcursor.cpp \
+ qwinrteglcontext.cpp \
+ qwinrteventdispatcher.cpp \
+ qwinrtfontdatabase.cpp \
+ qwinrtinputcontext.cpp \
+ qwinrtintegration.cpp \
+ qwinrtscreen.cpp \
+ qwinrtservices.cpp \
+ qwinrtwindow.cpp
+
+HEADERS = \
+ qwinrtbackingstore.h \
+ qwinrtcursor.h \
+ qwinrteglcontext.h \
+ qwinrteventdispatcher.h \
+ qwinrtfontdatabase.h \
+ qwinrtinputcontext.h \
+ qwinrtintegration.h \
+ qwinrtscreen.h \
+ qwinrtservices.h \
+ qwinrtwindow.h
+
+BLIT_INPUT = $$PWD/blit.hlsl
+fxc_blitps.commands = fxc.exe /nologo /T ps_4_0_level_9_1 /E blitps /Vn q_blitps /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+fxc_blitps.output = $$OUT_PWD/blitps.h
+fxc_blitps.input = BLIT_INPUT
+fxc_blitps.dependency_type = TYPE_C
+fxc_blitps.variable_out = HEADERS
+fxc_blitps.CONFIG += target_predeps
+fxc_blitvs.commands = fxc.exe /nologo /T vs_4_0_level_9_1 /E blitvs /Vn q_blitvs /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+fxc_blitvs.output = $$OUT_PWD/blitvs.h
+fxc_blitvs.input = BLIT_INPUT
+fxc_blitvs.dependency_type = TYPE_C
+fxc_blitvs.variable_out = HEADERS
+fxc_blitvs.CONFIG += target_predeps
+QMAKE_EXTRA_COMPILERS += fxc_blitps fxc_blitvs
+
+OTHER_FILES += winrt.json \
+ blit.hlsl
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index 6abe24b7ab..a3d6a65695 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -49,6 +49,7 @@
#include <qsocketnotifier.h>
#include <X11/SM/SMlib.h>
+#include <cerrno> // ERANGE
class QSmSocketReceiver : public QObject
{
diff --git a/src/src.pro b/src/src.pro
index 377e8cb650..641a8a98a6 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -141,6 +141,12 @@ SUBDIRS += src_plugins src_tools_qdoc
nacl: SUBDIRS -= src_network src_testlib
+winrt {
+ src_platformsupport.depends -= src_network
+ src_plugins.depends -= src_network
+ SUBDIRS -= src_network
+}
+
android:!android-no-sdk: SUBDIRS += src_android
TR_EXCLUDE = \
@@ -148,4 +154,4 @@ TR_EXCLUDE = \
src_tools_bootstrap_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
sub-tools.depends = $$TOOLS
-QMAKE_EXTRA_TARGETS = sub-tools \ No newline at end of file
+QMAKE_EXTRA_TARGETS = sub-tools
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 62cec34b2b..c9394dd9f8 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -1644,7 +1644,7 @@ int QFileDialogPrivate::maxNameLength(const QString &path)
{
#if defined(Q_OS_UNIX)
return ::pathconf(QFile::encodeName(path).data(), _PC_NAME_MAX);
-#elif defined(Q_OS_WINCE)
+#elif defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
Q_UNUSED(path);
return MAX_PATH;
#elif defined(Q_OS_WIN)
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index c86c7ff931..72dc8a5d05 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -1713,7 +1713,7 @@ QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFile
#ifndef QT_NO_FILESYSTEMWATCHER
node->populate(info);
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
//The parentNode is "" so we are listing the drives
if (parentNode->fileName.isEmpty()) {
wchar_t name[MAX_PATH + 1];
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index 9101c568e0..13aaca2f48 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -73,7 +73,7 @@
QT_BEGIN_NAMESPACE
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
HMENU qt_getWindowsSystemMenu(const QWidget *w)
{
if (QWindow *window = QApplicationPrivate::windowForWidget(w))
@@ -1608,7 +1608,7 @@ void QMessageBox::showEvent(QShowEvent *e)
QAccessibleEvent event(this, QAccessible::Alert);
QAccessible::updateAccessibility(&event);
#endif
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
if (const HMENU systemMenu = qt_getWindowsSystemMenu(this)) {
EnableMenuItem(systemMenu, SC_CLOSE, d->detectedEscapeButton ?
MF_BYCOMMAND|MF_ENABLED : MF_BYCOMMAND|MF_GRAYED);
diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp
index 71697ddc40..b12ab736f4 100644
--- a/src/widgets/itemviews/qfileiconprovider.cpp
+++ b/src/widgets/itemviews/qfileiconprovider.cpp
@@ -53,8 +53,10 @@
#if defined(Q_OS_WIN)
# include <qt_windows.h>
-# include <commctrl.h>
-# include <objbase.h>
+# ifndef Q_OS_WINRT
+# include <commctrl.h>
+# include <objbase.h>
+# endif
#endif
#if defined(Q_OS_UNIX) && !defined(QT_NO_STYLE_GTK)
@@ -313,7 +315,7 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const
return retIcon;
if (info.isRoot())
-#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
{
UINT type = GetDriveType((wchar_t *)info.absoluteFilePath().utf16());
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index 1f8e950d00..7977ae3528 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -451,7 +451,7 @@ void qt_init(QApplicationPrivate *priv, int type)
QApplicationPrivate::initializeWidgetFontHash();
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
// #fixme: Remove.
static HDC displayDC = 0; // display device context
@@ -470,7 +470,7 @@ void qt_cleanup()
QColormap::cleanup();
QApplicationPrivate::active_window = 0; //### this should not be necessary
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
if (displayDC) {
ReleaseDC(0, displayDC);
displayDC = 0;
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 02d95d2fa5..6db52e1cbc 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -4174,7 +4174,7 @@ const QPalette &QWidget::palette() const
if (!isEnabled()) {
data->pal.setCurrentColorGroup(QPalette::Disabled);
} else if ((!isVisible() || isActiveWindow())
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
&& !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this))
#endif
) {
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 02fa80bef6..9fcd14e813 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -120,7 +120,7 @@ static inline void qt_flush(QWidget *widget, const QRegion &region, QBackingStor
}
#ifndef QT_NO_PAINT_DEBUG
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static void showYellowThing_win(QWidget *widget, const QRegion &region, int msec)
{
@@ -160,7 +160,7 @@ static void showYellowThing_win(QWidget *widget, const QRegion &region, int msec
QGuiApplication::platformNativeInterface()->nativeResourceForWindow(QByteArrayLiteral("releaseDC"), nativeWindow);
::Sleep(msec);
}
-#endif // Q_OS_WIN
+#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePainted, int msec, bool unclipped)
{
@@ -175,7 +175,7 @@ void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePa
widget = nativeParent;
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
Q_UNUSED(unclipped);
showYellowThing_win(widget, paintRegion, msec);
#else
diff --git a/src/widgets/kernel/win.pri b/src/widgets/kernel/win.pri
index dd47664c28..18bd692476 100644
--- a/src/widgets/kernel/win.pri
+++ b/src/widgets/kernel/win.pri
@@ -2,6 +2,6 @@
# --------------------------------------------------------------------
INCLUDEPATH += ../3rdparty/wintab
-!wince* {
+!wince*:!winrt {
LIBS *= -lshell32
}
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index b153d05885..85f0461f48 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -252,7 +252,7 @@ void QWindowsStyle::polish(QApplication *app)
d->inactiveGradientCaptionColor = app->palette().dark().color();
d->inactiveCaptionText = app->palette().background().color();
-#if defined(Q_OS_WIN) //fetch native title bar colors
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) //fetch native title bar colors
if(app->desktopSettingsAware()){
DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION);
DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
@@ -413,6 +413,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
#if defined(Q_OS_WIN)
+#ifndef Q_OS_WINRT // There is no title bar in Windows Runtime applications
case PM_TitleBarHeight:
if (widget && (widget->windowType() == Qt::Tool)) {
// MS always use one less than they say
@@ -426,16 +427,17 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
}
break;
+#endif // !Q_OS_WINRT
case PM_ScrollBarExtent:
{
-#ifndef Q_OS_WINCE
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
NONCLIENTMETRICS ncm;
ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
ret = qMax(ncm.iScrollHeight, ncm.iScrollWidth);
else
-#endif
+#endif // !Q_OS_WINCE && !Q_OS_WINRT
ret = QCommonStyle::pixelMetric(pm, opt, widget);
}
break;
@@ -446,6 +448,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
break;
#if defined(Q_OS_WIN)
+#ifndef Q_OS_WINRT // Mdi concept not available for WinRT applications
case PM_MdiSubWindowFrameWidth:
#if defined(Q_OS_WINCE)
ret = GetSystemMetrics(SM_CYDLGFRAME);
@@ -453,7 +456,8 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
ret = GetSystemMetrics(SM_CYFRAME);
#endif
break;
-#endif
+#endif // !Q_OS_WINRT
+#endif // Q_OS_WIN
case PM_ToolBarItemMargin:
ret = 1;
break;
@@ -477,7 +481,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
const QWidget *widget) const
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QPixmap desktopIcon;
switch(standardPixmap) {
case SP_DriveCDIcon:
@@ -516,7 +520,7 @@ QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyl
if (!desktopIcon.isNull()) {
return desktopIcon;
}
-#endif
+#endif // Q_OS_WIN && !Q_OS_WINCE && !Q_OS_WINRT
return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
}
@@ -554,7 +558,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid
ret = 0;
break;
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // Option not used on WinRT -> common style
case SH_UnderlineShortcut:
{
ret = 1;
@@ -590,7 +594,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid
#endif // QT_NO_ACCESSIBILITY
break;
}
-#endif
+#endif // Q_OS_WIN && !Q_OS_WINRT
#ifndef QT_NO_RUBBERBAND
case SH_RubberBand_Mask:
if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri
index 072c736f71..b4bbc5fc30 100644
--- a/src/widgets/util/util.pri
+++ b/src/widgets/util/util.pri
@@ -27,7 +27,7 @@ SOURCES += \
util/qundostack.cpp \
util/qundoview.cpp
-win32:!wince* {
+win32:!wince*:!winrt {
SOURCES += util/qsystemtrayicon_win.cpp
} else:contains(QT_CONFIG, xcb) {
SOURCES += util/qsystemtrayicon_x11.cpp
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index b2a0d3f8b8..db9db68039 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -251,7 +251,9 @@ inline static bool waitForWindowExposed(QWindow *window, int timeout = 1000)
break;
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WINRT)
+ WaitForSingleObjectEx(GetCurrentThread(), TimeOutMs, false);
+#elif defined(Q_OS_WIN)
Sleep(uint(TimeOutMs));
#else
struct timespec ts = { TimeOutMs / 1000, (TimeOutMs % 1000) * 1000 * 1000 };