diff options
197 files changed, 7923 insertions, 439 deletions
diff --git a/examples/network/network.pro b/examples/network/network.pro index be4ccdbddf..8ed72315e2 100644 --- a/examples/network/network.pro +++ b/examples/network/network.pro @@ -23,7 +23,7 @@ qtHaveModule(widgets) { multicastsender # no QProcess - !vxworks:!qnx:SUBDIRS += network-chat + !vxworks:!qnx:!winrt:SUBDIRS += network-chat contains(QT_CONFIG, openssl):SUBDIRS += securesocketclient contains(QT_CONFIG, openssl-linked):SUBDIRS += securesocketclient diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index a1bf19d3aa..67831c435b 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -8,9 +8,9 @@ MAKEFILE_GENERATOR = MSBUILD QMAKE_COMPILER = msvc QMAKE_PLATFORM = winrt win32 CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target no_generated_target_info autogen_wmappmanifest rtti -DEFINES += UNICODE WINRT QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN \ +DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN \ QT_NO_PRINTER QT_NO_PRINTDIALOG # TODO: Remove when printing is re-enabled -QMAKE_COMPILER_DEFINES += _MSC_VER=1700 WINRT +QMAKE_COMPILER_DEFINES += _MSC_VER=1700 DEPLOYMENT_PLUGIN += qwinrt @@ -75,9 +75,12 @@ QMAKE_LFLAGS_DLL = /WINMD /MANIFEST:NO /DLL /WINMDFILE:$(DESTDIR_TARGET). QMAKE_LFLAGS_LTCG = /LTCG QMAKE_EXTENSION_STATICLIB = lib +QMAKE_LIBS += runtimeobject.lib QMAKE_LIBS_CORE = -QMAKE_LIBS_GUI = d3d11.lib +QMAKE_LIBS_GUI = QMAKE_LIBS_NETWORK = +QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib +QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib QMAKE_LIBS_QT_ENTRY = -lqtmain /ENTRY:wmainCRTStartup diff --git a/mkspecs/common/winrt_winphone/qplatformdefs.h b/mkspecs/common/winrt_winphone/qplatformdefs.h new file mode 100644 index 0000000000..96f20569d2 --- /dev/null +++ b/mkspecs/common/winrt_winphone/qplatformdefs.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the qmake spec 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 QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +#ifdef UNICODE +#ifndef _UNICODE +#define _UNICODE +#endif +#endif + +// Get Qt defines/settings + +#include "qglobal.h" +#include "qfunctions_winrt.h" + +#define _POSIX_ +#include <limits.h> +#undef _POSIX_ + +#include <tchar.h> +#include <io.h> +#include <direct.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h> +#include <stdlib.h> + +#ifdef QT_LARGEFILE_SUPPORT +#define QT_STATBUF struct _stati64 // non-ANSI defs +#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs +#define QT_STAT ::_stati64 +#define QT_FSTAT ::_fstati64 +#else +#define QT_STATBUF struct _stat // non-ANSI defs +#define QT_STATBUF4TSTAT struct _stat // non-ANSI defs +#define QT_STAT ::_stat +#define QT_FSTAT ::_fstat +#endif +#define QT_STAT_REG _S_IFREG +#define QT_STAT_DIR _S_IFDIR +#define QT_STAT_MASK _S_IFMT +#if defined(_S_IFLNK) +# define QT_STAT_LNK _S_IFLNK +#endif +#define QT_FILENO _fileno +#define QT_OPEN ::_open +#define QT_CLOSE ::_close +#ifdef QT_LARGEFILE_SUPPORT +#define QT_LSEEK ::_lseeki64 +#define QT_TSTAT ::_tstati64 +#else +#define QT_LSEEK ::_lseek +#define QT_TSTAT ::_tstat +#endif +#define QT_READ ::_read +#define QT_WRITE ::_write +#define QT_ACCESS ::_access +#define QT_GETCWD ::_getcwd +#define QT_CHDIR ::_chdir +#define QT_MKDIR ::_mkdir +#define QT_RMDIR ::_rmdir +#define QT_OPEN_LARGEFILE 0 +#define QT_OPEN_RDONLY _O_RDONLY +#define QT_OPEN_WRONLY _O_WRONLY +#define QT_OPEN_RDWR _O_RDWR +#define QT_OPEN_CREAT _O_CREAT +#define QT_OPEN_TRUNC _O_TRUNC +#define QT_OPEN_APPEND _O_APPEND +#if defined(O_TEXT) +# define QT_OPEN_TEXT _O_TEXT +# define QT_OPEN_BINARY _O_BINARY +#endif + +#include "../common/c89/qplatformdefs.h" + +#ifdef QT_LARGEFILE_SUPPORT +#undef QT_FSEEK +#undef QT_FTELL +#undef QT_OFF_T + +#define QT_FSEEK ::_fseeki64 +#define QT_FTELL ::_ftelli64 +#define QT_OFF_T __int64 +#endif + +#define QT_SIGNAL_ARGS int + +#define QT_VSNPRINTF(buffer, count, format, arg) \ + vsnprintf_s(buffer, count, count-1, format, arg) + +#define QT_SNPRINTF ::_snprintf + +# define F_OK 0 +# define X_OK 1 +# define W_OK 2 +# define R_OK 4 + +typedef int mode_t; + +#endif // QPLATFORMDEFS_H diff --git a/mkspecs/unsupported/linux-libc++-clang/qmake.conf b/mkspecs/unsupported/linux-libc++-clang/qmake.conf new file mode 100644 index 0000000000..bf0abb2a54 --- /dev/null +++ b/mkspecs/unsupported/linux-libc++-clang/qmake.conf @@ -0,0 +1,20 @@ +# +# qmake configuration for linux-clang +# + +MAKEFILE_GENERATOR = UNIX +CONFIG += incremental + +QMAKE_INCREMENTAL_STYLE = sublib + +include(../../common/linux.conf) +include(../../common/gcc-base-unix.conf) +include(../../common/clang.conf) + +QMAKE_CFLAGS_RELEASE = -Os +QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE + +QMAKE_CXXFLAGS_CXX11 += -std=c++11 -stdlib=libc++ +QMAKE_LFLAGS_CXX11 += -stdlib=libc++ -lc++abi + +load(qt_config) diff --git a/mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h b/mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h new file mode 100644 index 0000000000..c1066ee9a2 --- /dev/null +++ b/mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the qmake spec 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 QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +// Get Qt defines/settings + +#include "qglobal.h" + +// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs + +// 1) need to reset default environment if _BSD_SOURCE is defined +// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0 +// 3) it seems older glibc need this to include the X/Open stuff +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <unistd.h> + + +// We are hot - unistd.h should have turned on the specific APIs we requested + +#include <features.h> +#include <pthread.h> +#include <dirent.h> +#include <fcntl.h> +#include <grp.h> +#include <pwd.h> +#include <signal.h> + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/ipc.h> +#include <sys/time.h> +#include <sys/shm.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <netinet/in.h> +#ifndef QT_NO_IPV6IFNAME +#include <net/if.h> +#endif + +#define QT_USE_XOPEN_LFS_EXTENSIONS +#include "../../common/posix/qplatformdefs.h" + +#undef QT_SOCKLEN_T + +#if defined(__GLIBC__) && (__GLIBC__ >= 2) +#define QT_SOCKLEN_T socklen_t +#else +#define QT_SOCKLEN_T int +#endif + +#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500) +#define QT_SNPRINTF ::snprintf +#define QT_VSNPRINTF ::vsnprintf +#endif + +#endif // QPLATFORMDEFS_H diff --git a/mkspecs/winphone-arm-msvc2012/qplatformdefs.h b/mkspecs/winphone-arm-msvc2012/qplatformdefs.h index e03bce8e6c..781107b2dc 100644 --- a/mkspecs/winphone-arm-msvc2012/qplatformdefs.h +++ b/mkspecs/winphone-arm-msvc2012/qplatformdefs.h @@ -39,4 +39,4 @@ ** ****************************************************************************/ -#include "../win32-msvc2005/qplatformdefs.h" +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winphone-x86-msvc2012/qplatformdefs.h b/mkspecs/winphone-x86-msvc2012/qplatformdefs.h index e03bce8e6c..781107b2dc 100644 --- a/mkspecs/winphone-x86-msvc2012/qplatformdefs.h +++ b/mkspecs/winphone-x86-msvc2012/qplatformdefs.h @@ -39,4 +39,4 @@ ** ****************************************************************************/ -#include "../win32-msvc2005/qplatformdefs.h" +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-arm-msvc2012/qplatformdefs.h b/mkspecs/winrt-arm-msvc2012/qplatformdefs.h index e03bce8e6c..781107b2dc 100644 --- a/mkspecs/winrt-arm-msvc2012/qplatformdefs.h +++ b/mkspecs/winrt-arm-msvc2012/qplatformdefs.h @@ -39,4 +39,4 @@ ** ****************************************************************************/ -#include "../win32-msvc2005/qplatformdefs.h" +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x64-msvc2012/qplatformdefs.h b/mkspecs/winrt-x64-msvc2012/qplatformdefs.h index e03bce8e6c..781107b2dc 100644 --- a/mkspecs/winrt-x64-msvc2012/qplatformdefs.h +++ b/mkspecs/winrt-x64-msvc2012/qplatformdefs.h @@ -39,4 +39,4 @@ ** ****************************************************************************/ -#include "../win32-msvc2005/qplatformdefs.h" +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x86-msvc2012/qplatformdefs.h b/mkspecs/winrt-x86-msvc2012/qplatformdefs.h index e03bce8e6c..781107b2dc 100644 --- a/mkspecs/winrt-x86-msvc2012/qplatformdefs.h +++ b/mkspecs/winrt-x86-msvc2012/qplatformdefs.h @@ -39,4 +39,4 @@ ** ****************************************************************************/ -#include "../win32-msvc2005/qplatformdefs.h" +#include "../common/winrt_winphone/qplatformdefs.h" 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/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index d02e4cf199..102a6487ee 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -98,6 +98,7 @@ # define Q_UNREACHABLE_IMPL() __assume(0) # define Q_NORETURN __declspec(noreturn) # define Q_DECL_DEPRECATED __declspec(deprecated) +# define Q_DECL_DEPRECATED_X(text) __declspec(deprecated(text)) # define Q_DECL_EXPORT __declspec(dllexport) # define Q_DECL_IMPORT __declspec(dllimport) /* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */ @@ -152,6 +153,9 @@ # define Q_CC_INTEL # define Q_ASSUME_IMPL(expr) __assume(expr) # define Q_UNREACHABLE_IMPL() __builtin_unreachable() +# if __INTEL_COMPILER >= 1300 +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) +# endif # elif defined(__clang__) /* Clang also masquerades as GCC */ # define Q_CC_CLANG @@ -173,6 +177,7 @@ # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 # define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable() # define Q_UNREACHABLE_IMPL() __builtin_unreachable() +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) # endif # endif @@ -526,6 +531,9 @@ # if !__has_feature(cxx_rtti) # define QT_NO_RTTI # endif +# if __has_feature(attribute_deprecated_with_message) +# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text))) +# endif /* C++11 features, see http://clang.llvm.org/cxx_status.html */ # if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) @@ -842,6 +850,9 @@ #ifndef Q_DECL_VARIABLE_DEPRECATED # define Q_DECL_VARIABLE_DEPRECATED Q_DECL_DEPRECATED #endif +#ifndef Q_DECL_DEPRECATED_X +# define Q_DECL_DEPRECATED_X(text) Q_DECL_DEPRECATED +#endif #ifndef Q_DECL_EXPORT # define Q_DECL_EXPORT #endif diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 1dd77c5859..6f74c7de88 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2140,7 +2140,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, @@ -2151,6 +2153,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 d7253c39c6..b654ba3ac8 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 @@ -223,11 +223,14 @@ typedef double qreal; #if defined(QT_NO_DEPRECATED) # undef QT_DEPRECATED +# undef QT_DEPRECATED_X # undef QT_DEPRECATED_VARIABLE # undef QT_DEPRECATED_CONSTRUCTOR #elif defined(QT_DEPRECATED_WARNINGS) # undef QT_DEPRECATED # define QT_DEPRECATED Q_DECL_DEPRECATED +# undef QT_DEPRECATED_X +# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text) # undef QT_DEPRECATED_VARIABLE # define QT_DEPRECATED_VARIABLE Q_DECL_VARIABLE_DEPRECATED # undef QT_DEPRECATED_CONSTRUCTOR @@ -235,6 +238,8 @@ typedef double qreal; #else # undef QT_DEPRECATED # define QT_DEPRECATED +# undef QT_DEPRECATED_X +# define QT_DEPRECATED_X(text) # undef QT_DEPRECATED_VARIABLE # define QT_DEPRECATED_VARIABLE # undef QT_DEPRECATED_CONSTRUCTOR @@ -542,6 +547,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/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 33d7b71cff..a279498e93 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qdir.h" +#include "qstringlist.h" #include "qfile.h" #include "qsettings.h" #include "qlibraryinfo.h" @@ -113,6 +114,8 @@ public: } }; +static const char platformsSection[] = "Platforms"; + QLibrarySettings::QLibrarySettings() : settings(QLibraryInfoPrivate::findConfiguration()) { @@ -132,7 +135,8 @@ QLibrarySettings::QLibrarySettings() haveEffectivePaths = children.contains(QLatin1String("EffectivePaths")); #endif // Backwards compat: an existing but empty file is claimed to contain the Paths section. - havePaths = !haveEffectivePaths || children.contains(QLatin1String("Paths")); + havePaths = (!haveEffectivePaths && !children.contains(QLatin1String(platformsSection))) + || children.contains(QLatin1String("Paths")); #ifndef QT_BOOTSTRAPPED if (!havePaths) settings.reset(0); @@ -466,6 +470,33 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) } /*! + Returns additional arguments to the platform plugin matching + \a platformName which can be specified as a string list using + the key \c Arguments in a group called \c Platforms of the + \c qt.conf file. + + sa {Using qt.conf} + + \internal + + \since 5.3 +*/ + +QStringList QLibraryInfo::platformPluginArguments(const QString &platformName) +{ +#ifndef QT_BOOTSTRAPPED + if (const QSettings *settings = QLibraryInfoPrivate::findConfiguration()) { + QString key = QLatin1String(platformsSection); + key += QLatin1Char('/'); + key += platformName; + key += QLatin1String("Arguments"); + return settings->value(key).toStringList(); + } +#endif // !QT_BOOTSTRAPPED + return QStringList(); +} + +/*! \enum QLibraryInfo::LibraryLocation \keyword library location diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h index 17864b555b..54ef794d3e 100644 --- a/src/corelib/global/qlibraryinfo.h +++ b/src/corelib/global/qlibraryinfo.h @@ -47,6 +47,8 @@ QT_BEGIN_NAMESPACE +class QStringList; + class Q_CORE_EXPORT QLibraryInfo { public: @@ -96,6 +98,8 @@ public: static QString rawLocation(LibraryLocation, PathGroup); #endif + static QStringList platformPluginArguments(const QString &platformName); + private: QLibraryInfo(); }; diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 8a46f3a6ab..758f13596e 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1596,6 +1596,12 @@ public: ScrollUpdate, ScrollEnd }; + + enum MouseEventSource { + MouseEventNotSynthesized, + MouseEventSynthesizedBySystem, + MouseEventSynthesizedByQt + }; } #ifdef Q_MOC_RUN ; diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 90f38fd51c..e33fd085f2 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2897,3 +2897,25 @@ \value ScrollEnd Scrolling has ended, but the scrolling distance did not change anymore. */ + +/*! + \enum Qt::MouseEventSource + \since 5.3 + + This enum describes the source of a mouse event and can be useful + to determine if the event is an artificial mouse event originating + from another device such as a touchscreen. + + \value MouseEventNotSynthesized The most common value. On + platforms where such information is available this value indicates + that the event was generated in response to a genuine mouse event + in the system. + + \value MouseEventSynthesizedBySystem Indicates that the mouse + event was synthesized from a touch event by the platform. + + \value MouseEventSynthesizedByQt Indicates that the mouse event was + synthesized from an unhandled touch event by Qt. + + \sa Qt::AA_SynthesizeMouseForUnhandledTouchEvents +*/ diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp index d09357c26c..7d8bd8c3c6 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 af5605f8c7..a6fbffee7e 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/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 257f18a6bb..77304b2cb9 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -63,13 +63,26 @@ # include <types.h> #endif #include <objbase.h> -#include <shlobj.h> +#ifndef Q_OS_WINRT +# include <shlobj.h> +# include <accctrl.h> +#endif #include <initguid.h> -#include <accctrl.h> #include <ctype.h> #include <limits.h> -#define SECURITY_WIN32 -#include <security.h> +#ifndef Q_OS_WINRT +# define SECURITY_WIN32 +# include <security.h> +#else // !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 // Q_OS_WINRT #ifndef SPI_GETPLATFORMTYPE #define SPI_GETPLATFORMTYPE 257 @@ -141,7 +154,7 @@ QT_BEGIN_NAMESPACE Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0; -#if defined(Q_OS_WINCE) +#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT) static QString qfsPrivateCurrentDir = QLatin1String(""); // As none of the functions we try to resolve do exist on Windows CE // we use QT_NO_LIBRARY to shorten everything up a little bit. @@ -289,14 +302,14 @@ static bool resolveUNCLibs() } #endif triedResolve = true; -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) HINSTANCE hLib = QSystemLibrary::load(L"Netapi32"); if (hLib) { ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum"); if (ptrNetShareEnum) ptrNetApiBufferFree = (PtrNetApiBufferFree)GetProcAddress(hLib, "NetApiBufferFree"); } -#endif +#endif // !Q_OS_WINCE && !Q_OS_WINRT } return ptrNetShareEnum && ptrNetApiBufferFree; } @@ -304,7 +317,7 @@ static bool resolveUNCLibs() static QString readSymLink(const QFileSystemEntry &link) { QString result; -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) HANDLE handle = CreateFile((wchar_t*)link.nativeFilePath().utf16(), FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, @@ -347,11 +360,11 @@ static QString readSymLink(const QFileSystemEntry &link) result.replace(0,matchVolName.matchedLength(), QString::fromWCharArray(buffer)); } } -#endif +#endif // !Q_OS_WINCE && !Q_OS_WINRT } #else Q_UNUSED(link); -#endif // Q_OS_WINCE +#endif // Q_OS_WINCE || Q_OS_WINRT return result; } @@ -432,7 +445,11 @@ static inline bool getFindData(QString path, WIN32_FIND_DATA &findData) // can't handle drives if (!path.endsWith(QLatin1Char(':'))) { +#ifndef Q_OS_WINRT HANDLE hFind = ::FindFirstFile((wchar_t*)path.utf16(), &findData); +#else + HANDLE hFind = ::FindFirstFileEx((const wchar_t*)path.utf16(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0); +#endif if (hFind != INVALID_HANDLE_VALUE) { ::FindClose(hFind); return true; @@ -506,7 +523,7 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path) { // can be //server or //server/share QString absPath; -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) QVarLengthArray<wchar_t, MAX_PATH> buf(qMax(MAX_PATH, path.size() + 1)); wchar_t *fileName = 0; DWORD retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); @@ -516,12 +533,17 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path) } if (retLen != 0) absPath = QString::fromWCharArray(buf.data(), retLen); -#else +#elif !defined(Q_OS_WINCE) + if (QDir::isRelativePath(path)) + absPath = QDir::toNativeSeparators(QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + path)); + else + absPath = QDir::toNativeSeparators(QDir::cleanPath(path)); +#else // Q_OS_WINRT if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\'))) absPath = QDir::toNativeSeparators(path); else absPath = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path)); -#endif +#endif // Q_OS_WINCE // This is really ugly, but GetFullPathName strips off whitespace at the end. // If you for instance write ". " in the lineedit of QFileDialog, // (which is an invalid filename) this function will strip the space off and viola, @@ -548,9 +570,17 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) ret = entry.filePath(); #endif } else { +#ifndef Q_OS_WINRT ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + entry.filePath()); +#else + // Some WinRT APIs do not support absolute paths (due to sandboxing). + // Thus the port uses the executable's directory as its root directory + // and treats paths relative to that as absolute paths. + ret = QDir::cleanPath(QDir::current().relativeFilePath(entry.filePath())); +#endif } +#ifndef Q_OS_WINRT // The path should be absolute at this point. // From the docs : // Absolute paths begin with the directory separator "/" @@ -563,6 +593,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) // Force uppercase drive letters. ret[0] = ret.at(0).toUpper(); } +#endif // !Q_OS_WINRT return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath()); } @@ -590,18 +621,24 @@ typedef struct _FILE_ID_INFO { static inline QByteArray fileId(HANDLE handle) { QByteArray result; +#ifndef Q_OS_WINRT BY_HANDLE_FILE_INFORMATION info; if (GetFileInformationByHandle(handle, &info)) { result = QByteArray::number(uint(info.nFileIndexLow), 16); result += ':'; result += QByteArray::number(uint(info.nFileIndexHigh), 16); } +#else // !Q_OS_WINRT + Q_UNUSED(handle); + Q_UNIMPLEMENTED(); +#endif // Q_OS_WINRT return result; } // File ID for Windows starting from version 8. QByteArray fileIdWin8(HANDLE handle) { +#ifndef Q_OS_WINRT typedef BOOL (WINAPI* GetFileInformationByHandleExType)(HANDLE, Q_FILE_INFO_BY_HANDLE_CLASS, void *, DWORD); // Dynamically resolve GetFileInformationByHandleEx (Vista onwards). @@ -621,6 +658,16 @@ QByteArray fileIdWin8(HANDLE handle) result += QByteArray((char *)&infoEx.FileId, sizeof(infoEx.FileId)).toHex(); } } +#else // !Q_OS_WINRT + QByteArray result; + FILE_ID_INFO infoEx; + if (GetFileInformationByHandleEx(handle, FileIdInfo, + &infoEx, sizeof(FILE_ID_INFO))) { + result = QByteArray::number(infoEx.VolumeSerialNumber, 16); + result += ':'; + result += QByteArray((char *)infoEx.FileId.Identifier, sizeof(infoEx.FileId.Identifier)).toHex(); + } +#endif // Q_OS_WINRT return result; } #endif // !Q_OS_WINCE @@ -631,8 +678,13 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry) #ifndef Q_OS_WINCE QByteArray result; const HANDLE handle = +#ifndef Q_OS_WINRT CreateFile((wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); +#else // !Q_OS_WINRT + CreateFile2((const wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ, + FILE_SHARE_READ, OPEN_EXISTING, NULL); +#endif // Q_OS_WINRT if (handle) { result = QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS8 ? fileIdWin8(handle) : fileId(handle); @@ -810,7 +862,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa { bool entryExists = false; DWORD fileAttrib = 0; -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) if (fname.isDriveRoot()) { // a valid drive ?? DWORD drivesBitmask = ::GetLogicalDrives(); @@ -851,7 +903,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa fileAttrib = FILE_ATTRIBUTE_DIRECTORY; entryExists = true; } -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) } #endif if (entryExists) @@ -894,12 +946,27 @@ bool QFileSystemEngine::fillMetaData(HANDLE fHandle, QFileSystemMetaData &data, { data.entryFlags &= ~what; clearWinStatData(data); +#ifndef Q_OS_WINRT BY_HANDLE_FILE_INFORMATION fileInfo; UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); if (GetFileInformationByHandle(fHandle , &fileInfo)) { data.fillFromFindInfo(fileInfo); } SetErrorMode(oldmode); +#else // !Q_OS_WINRT + FILE_FULL_DIR_INFO fileInfo; + if (GetFileInformationByHandleEx(fHandle, FileFullDirectoryInfo, &fileInfo, sizeof(fileInfo))) { + data.fillFromFileAttribute(fileInfo.FileAttributes); + data.creationTime_.dwHighDateTime = fileInfo.CreationTime.HighPart; + data.creationTime_.dwLowDateTime = fileInfo.CreationTime.LowPart; + data.lastAccessTime_.dwHighDateTime = fileInfo.LastAccessTime.HighPart; + data.lastAccessTime_.dwLowDateTime = fileInfo.LastAccessTime.LowPart; + data.lastWriteTime_.dwHighDateTime = fileInfo.LastWriteTime.HighPart; + data.lastWriteTime_.dwLowDateTime = fileInfo.LastWriteTime.LowPart; + data.fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY ? data.size_ = 0 : data.size_ = fileInfo.AllocationSize.QuadPart; + data.knownFlagsMask |= data.Times | data.SizeAttribute; + } +#endif // Q_OS_WINRT return data.hasFlags(what); } @@ -931,7 +998,9 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM } if (what & QFileSystemMetaData::WinStatFlags) { +#ifndef Q_OS_WINRT UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); +#endif clearWinStatData(data); WIN32_FIND_DATA findData; // The memory structure for WIN32_FIND_DATA is same as WIN32_FILE_ATTRIBUTE_DATA @@ -943,11 +1012,15 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM } else { if (!tryFindFallback(fname, data)) if (!tryDriveUNCFallback(fname, data)) { +#ifndef Q_OS_WINRT SetErrorMode(oldmode); +#endif return false; } } +#ifndef Q_OS_WINRT SetErrorMode(oldmode); +#endif } if (what & QFileSystemMetaData::Permissions) @@ -1006,7 +1079,14 @@ static bool isDirPath(const QString &dirPath, bool *existed) if (path.length() == 2 && path.at(1) == QLatin1Char(':')) path += QLatin1Char('\\'); +#ifndef Q_OS_WINRT DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); +#else // Q_OS_WINRT + DWORD fileAttrib = INVALID_FILE_ATTRIBUTES; + WIN32_FILE_ATTRIBUTE_DATA data; + if (::GetFileAttributesEx((const wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), GetFileExInfoStandard, &data)) + fileAttrib = data.dwFileAttributes; +#endif // Q_OS_WINRT if (fileAttrib == INVALID_FILE_ATTRIBUTES) { int errorCode = GetLastError(); if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) { @@ -1158,12 +1238,13 @@ QString QFileSystemEngine::homePath() QString QFileSystemEngine::tempPath() { QString ret; +#ifndef Q_OS_WINRT wchar_t tempPath[MAX_PATH]; const DWORD len = GetTempPath(MAX_PATH, tempPath); #ifdef Q_OS_WINCE if (len) ret = QString::fromWCharArray(tempPath, len); -#else +#else // Q_OS_WINCE if (len) { // GetTempPath() can return short names, expand. wchar_t longTempPath[MAX_PATH]; const DWORD longLen = GetLongPathName(tempPath, longTempPath, MAX_PATH); @@ -1171,12 +1252,33 @@ QString QFileSystemEngine::tempPath() QString::fromWCharArray(longTempPath, longLen) : QString::fromWCharArray(tempPath, len); } -#endif +#endif // !Q_OS_WINCE if (!ret.isEmpty()) { while (ret.endsWith(QLatin1Char('\\'))) ret.chop(1); ret = QDir::fromNativeSeparators(ret); } +#else // !Q_OS_WINRT + // According to http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.temporaryfolder.aspx + // the API is not available on winphone which should cause one of the functions + // below to fail + ComPtr<IApplicationDataStatics> applicationDataStatics; + if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics))) + return ret; + ComPtr<IApplicationData> applicationData; + if (FAILED(applicationDataStatics->get_Current(&applicationData))) + return ret; + ComPtr<IStorageFolder> tempFolder; + if (FAILED(applicationData->get_TemporaryFolder(&tempFolder))) + return ret; + ComPtr<IStorageItem> tempFolderItem; + if (FAILED(tempFolder.As(&tempFolderItem))) + return ret; + HSTRING path; + if (FAILED(tempFolderItem->get_Path(&path))) + return ret; + ret = QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr)); +#endif // Q_OS_WINRT if (ret.isEmpty()) { #if !defined(Q_OS_WINCE) ret = QLatin1String("C:/tmp"); @@ -1195,7 +1297,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry) if(!(meta.exists() && meta.isDirectory())) return false; -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) //TODO: this should really be using nativeFilePath(), but that returns a path in long format \\?\c:\foo //which causes many problems later on when it's returned through currentPath() return ::SetCurrentDirectory(reinterpret_cast<const wchar_t*>(QDir::toNativeSeparators(entry.filePath()).utf16())) != 0; @@ -1208,7 +1310,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry) QFileSystemEntry QFileSystemEngine::currentPath() { QString ret; -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) DWORD size = 0; wchar_t currentName[PATH_MAX]; size = ::GetCurrentDirectory(PATH_MAX, currentName); @@ -1224,13 +1326,13 @@ QFileSystemEntry QFileSystemEngine::currentPath() } if (ret.length() >= 2 && ret[1] == QLatin1Char(':')) ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters. -#else +#else // !Q_OS_WINCE && !Q_OS_WINRT //TODO - a race condition exists when using currentPath / setCurrentPath from multiple threads if (qfsPrivateCurrentDir.isEmpty()) qfsPrivateCurrentDir = QCoreApplication::applicationDirPath(); ret = qfsPrivateCurrentDir; -#endif +#endif // Q_OS_WINCE || Q_OS_WINRT return QFileSystemEntry(ret, QFileSystemEntry::FromNativePath()); } @@ -1248,8 +1350,16 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy //static bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { +#ifndef Q_OS_WINRT bool ret = ::CopyFile((wchar_t*)source.nativeFilePath().utf16(), (wchar_t*)target.nativeFilePath().utf16(), true) != 0; +#else // !Q_OS_WINRT + COPYFILE2_EXTENDED_PARAMETERS copyParams = { + sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL + }; + bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(), + (const wchar_t*)target.nativeFilePath().utf16(), ©Params) != 0; +#endif // Q_OS_WINRT if(!ret) error = QSystemError(::GetLastError(), QSystemError::NativeError); return ret; @@ -1258,8 +1368,13 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst //static bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { +#ifndef Q_OS_WINRT bool ret = ::MoveFile((wchar_t*)source.nativeFilePath().utf16(), (wchar_t*)target.nativeFilePath().utf16()) != 0; +#else // !Q_OS_WINRT + bool ret = ::MoveFileEx((const wchar_t*)source.nativeFilePath().utf16(), + (const wchar_t*)target.nativeFilePath().utf16(), 0) != 0; +#endif // Q_OS_WINRT if(!ret) error = QSystemError(::GetLastError(), QSystemError::NativeError); return ret; diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 90232f7cfc..dda96bd45a 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -39,10 +39,12 @@ ** ****************************************************************************/ -#if _WIN32_WINNT < 0x0500 -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 -#endif +#if !defined(WINAPI_FAMILY) +# if _WIN32_WINNT < 0x0500 +# undef _WIN32_WINNT +# define _WIN32_WINNT 0x0500 +# endif // _WIN32_WINNT < 0x500 +#endif // !WINAPI_FAMILY #include "qfilesystemiterator_p.h" #include "qfilesystemengine_p.h" @@ -73,6 +75,10 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi if (!nativePath.endsWith(QLatin1Char('\\'))) nativePath.append(QLatin1Char('\\')); nativePath.append(QLatin1Char('*')); +#ifdef Q_OS_WINRT + if (nativePath.startsWith(QLatin1Char('\\'))) + nativePath.remove(0, 1); +#endif if (!dirPath.endsWith(QLatin1Char('/'))) dirPath.append(QLatin1Char('/')); if ((filters & (QDir::Dirs|QDir::Drives)) && (!(filters & (QDir::Files)))) diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 1abc9b7ec4..de79ec32d3 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -219,7 +219,9 @@ public: #if defined(Q_OS_WIN) inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false); inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false); +# ifndef Q_OS_WINRT inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo); +# endif #endif private: friend class QFileSystemEngine; @@ -340,6 +342,7 @@ inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, boo } } +#ifndef Q_OS_WINRT inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo) { fillFromFileAttribute(fileInfo.dwFileAttributes); @@ -355,7 +358,8 @@ inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fi } knownFlagsMask |= Times | SizeAttribute; } -#endif +#endif // !Q_OS_WINRT +#endif // Q_OS_WIN QT_END_NAMESPACE diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 2b38019674..c974daab06 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -60,14 +60,18 @@ # include <types.h> #endif #include <objbase.h> -#include <shlobj.h> +#ifndef Q_OS_WINRT +# include <shlobj.h> +# include <accctrl.h> +#endif #include <initguid.h> -#include <accctrl.h> #include <ctype.h> #include <limits.h> #include <stdio.h> -#define SECURITY_WIN32 -#include <security.h> +#ifndef Q_OS_WINRT +# define SECURITY_WIN32 +# include <security.h> +#endif #ifndef PATH_MAX #define PATH_MAX FILENAME_MAX @@ -93,7 +97,7 @@ QString QFSFileEnginePrivate::longFileName(const QString &path) return path; QString absPath = QFileSystemEngine::nativeAbsoluteFilePath(path); -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) QString prefix = QLatin1String("\\\\?\\"); if (isUncPath(absPath)) { prefix.append(QLatin1String("UNC\\")); // "\\\\?\\UNC\\" @@ -121,11 +125,12 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) if (openMode & QIODevice::WriteOnly) accessRights |= GENERIC_WRITE; - SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE }; // WriteOnly can create files, ReadOnly cannot. DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING; // Create the file handle. +#ifndef Q_OS_WINRT + SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE }; fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(), accessRights, shareMode, @@ -133,6 +138,13 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) creationDisp, FILE_ATTRIBUTE_NORMAL, NULL); +#else // !Q_OS_WINRT + fileHandle = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(), + accessRights, + shareMode, + creationDisp, + NULL); +#endif // Q_OS_WINRT // Bail out on error. if (fileHandle == INVALID_HANDLE_VALUE) { @@ -473,7 +485,7 @@ int QFSFileEnginePrivate::nativeHandle() const */ bool QFSFileEnginePrivate::nativeIsSequential() const { -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) HANDLE handle = fileHandle; if (fh || fd != -1) handle = (HANDLE)_get_osfhandle(fh ? QT_FILENO(fh) : fd); @@ -577,7 +589,7 @@ bool QFSFileEngine::setCurrentPath(const QString &path) QString QFSFileEngine::currentPath(const QString &fileName) { -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) QString ret; //if filename is a drive: then get the pwd of that drive if (fileName.length() >= 2 && @@ -596,10 +608,10 @@ QString QFSFileEngine::currentPath(const QString &fileName) if (ret.length() >= 2 && ret[1] == QLatin1Char(':')) ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters. return ret; -#else +#else // !Q_OS_WINCE && !Q_OS_WINRT Q_UNUSED(fileName); return QFileSystemEngine::currentPath().filePath(); -#endif +#endif // Q_OS_WINCE || Q_OS_WINRT } QString QFSFileEngine::homePath() @@ -620,7 +632,7 @@ QString QFSFileEngine::tempPath() QFileInfoList QFSFileEngine::drives() { QFileInfoList ret; -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) #if defined(Q_OS_WIN32) quint32 driveBits = (quint32) GetLogicalDrives() & 0x3ffffff; #endif @@ -633,10 +645,10 @@ QFileInfoList QFSFileEngine::drives() driveBits = driveBits >> 1; } return ret; -#else +#else // !Q_OS_WINCE && !Q_OS_WINRT ret.append(QFileInfo(QLatin1String("/"))); return ret; -#endif +#endif // Q_OS_WINCE || Q_OS_WINRT } bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const @@ -661,7 +673,7 @@ bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) cons bool QFSFileEngine::link(const QString &newName) { -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) #if !defined(QT_NO_LIBRARY) bool ret = false; @@ -707,7 +719,7 @@ bool QFSFileEngine::link(const QString &newName) Q_UNUSED(newName); return false; #endif // QT_NO_LIBRARY -#else +#elif defined(Q_OS_WINCE) QString linkName = newName; linkName.replace(QLatin1Char('/'), QLatin1Char('\\')); if (!linkName.endsWith(QLatin1String(".lnk"))) @@ -720,7 +732,11 @@ bool QFSFileEngine::link(const QString &newName) if (!ret) setError(QFile::RenameError, qt_error_string()); return ret; -#endif // Q_OS_WINCE +#else // Q_OS_WINCE + Q_UNUSED(newName); + Q_UNIMPLEMENTED(); + return false; +#endif // Q_OS_WINRT } /*! @@ -937,6 +953,7 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) { +#ifndef Q_OS_WINPHONE Q_Q(QFSFileEngine); Q_UNUSED(flags); if (openMode == QFile::NotOpen) { @@ -980,7 +997,11 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, // first create the file mapping handle DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY; +#ifndef Q_OS_WINRT mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0); +#else + mapHandle = ::CreateFileMappingFromApp(handle, 0, protection, 0, 0); +#endif if (mapHandle == NULL) { q->setError(QFile::PermissionsError, qt_error_string()); #ifdef Q_USE_DEPRECATED_MAP_API @@ -998,15 +1019,23 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, DWORD offsetHi = offset >> 32; DWORD offsetLo = offset & Q_UINT64_C(0xffffffff); SYSTEM_INFO sysinfo; +#ifndef Q_OS_WINRT ::GetSystemInfo(&sysinfo); +#else + ::GetNativeSystemInfo(&sysinfo); +#endif DWORD mask = sysinfo.dwAllocationGranularity - 1; DWORD extra = offset & mask; if (extra) offsetLo &= ~mask; // attempt to create the map +#ifndef Q_OS_WINRT LPVOID mapAddress = ::MapViewOfFile(mapHandle, access, offsetHi, offsetLo, size + extra); +#else + LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access, offset, size); +#endif if (mapAddress) { uchar *address = extra + static_cast<uchar*>(mapAddress); maps[address] = extra; @@ -1025,11 +1054,18 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, ::CloseHandle(mapHandle); mapHandle = NULL; +#else // !Q_OS_WINPHONE + Q_UNUSED(offset); + Q_UNUSED(size); + Q_UNUSED(flags); + Q_UNIMPLEMENTED(); +#endif // Q_OS_WINPHONE return 0; } bool QFSFileEnginePrivate::unmap(uchar *ptr) { +#ifndef Q_OS_WINPHONE Q_Q(QFSFileEngine); if (!maps.contains(ptr)) { q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED)); @@ -1048,6 +1084,11 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) } return true; +#else // !Q_OS_WINPHONE + Q_UNUSED(ptr); + Q_UNIMPLEMENTED(); + return false; +#endif // Q_OS_WINPHONE } QT_END_NAMESPACE diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index b5f6d9f3da..28f6b02a64 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE QLockFile::LockError QLockFilePrivate::tryLock_sys() { - SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE }; const QFileSystemEntry fileEntry(fileName); // When writing, allow others to read. // When reading, QFile will allow others to read and write, all good. @@ -60,6 +59,8 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys() // but Windows doesn't allow recreating it while this handle is open anyway, // so this would only create confusion (can't lock, but no lock file to read from). const DWORD dwShareMode = FILE_SHARE_READ; +#ifndef Q_OS_WINRT + SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE }; HANDLE fh = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(), GENERIC_WRITE, dwShareMode, @@ -67,6 +68,13 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys() CREATE_NEW, // error if already exists FILE_ATTRIBUTE_NORMAL, NULL); +#else // !Q_OS_WINRT + HANDLE fh = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(), + GENERIC_WRITE, + dwShareMode, + CREATE_NEW, // error if already exists + NULL); +#endif // Q_OS_WINRT if (fh == INVALID_HANDLE_VALUE) { const DWORD lastError = GetLastError(); switch (lastError) { @@ -112,6 +120,9 @@ bool QLockFilePrivate::isApparentlyStale() const if (!getLockInfo(&pid, &hostname, &appname)) return false; + // On WinRT there seems to be no way of obtaining information about other + // processes due to sandboxing +#ifndef Q_OS_WINRT HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (!procHandle) return true; @@ -120,6 +131,7 @@ bool QLockFilePrivate::isApparentlyStale() const ::CloseHandle(procHandle); if (dwR == WAIT_TIMEOUT) return true; +#endif // !Q_OS_WINRT const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); return staleLockTime > 0 && age > staleLockTime; } diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index c78b355ac1..a0910869c6 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/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index b3cb4e43f8..b3a17eae7e 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -151,18 +151,27 @@ static bool createFileFromTemplate(NativeFileHandle &file, for (;;) { // Atomically create file and obtain handle #if defined(Q_OS_WIN) +# ifndef Q_OS_WINRT file = CreateFile((const wchar_t *)path.constData(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); +# else // !Q_OS_WINRT + file = CreateFile2((const wchar_t *)path.constData(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_NEW, + NULL); +# endif // Q_OS_WINRT if (file != INVALID_HANDLE_VALUE) return true; DWORD err = GetLastError(); if (err == ERROR_ACCESS_DENIED) { - DWORD attributes = GetFileAttributes((const wchar_t *)path.constData()); - if (attributes == INVALID_FILE_ATTRIBUTES) { + WIN32_FILE_ATTRIBUTE_DATA attributes; + if (!GetFileAttributesEx((const wchar_t *)path.constData(), + GetFileExInfoStandard, &attributes) + || attributes.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { // Potential write error (read-only parent directory, etc.). error = QSystemError(err, QSystemError::NativeError); return false; @@ -336,7 +345,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath()); -#if !defined(Q_OS_WIN) +#if !defined(Q_OS_WIN) || defined(Q_OS_WINRT) d->closeFileHandle = true; #endif 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 0460c52d1c..2e70d40bd2 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_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h index 933faff5a5..a2e7b6b33e 100644 --- a/src/corelib/kernel/qeventdispatcher_glib_p.h +++ b/src/corelib/kernel/qeventdispatcher_glib_p.h @@ -77,19 +77,19 @@ public: bool processEvents(QEventLoop::ProcessEventsFlags flags); bool hasPendingEvents(); - void registerSocketNotifier(QSocketNotifier *socketNotifier); - void unregisterSocketNotifier(QSocketNotifier *socketNotifier); + void registerSocketNotifier(QSocketNotifier *socketNotifier) Q_DECL_FINAL; + void unregisterSocketNotifier(QSocketNotifier *socketNotifier) Q_DECL_FINAL; - 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; + void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) Q_DECL_FINAL; + bool unregisterTimer(int timerId) Q_DECL_FINAL; + bool unregisterTimers(QObject *object) Q_DECL_FINAL; + QList<TimerInfo> registeredTimers(QObject *object) const Q_DECL_FINAL; - int remainingTime(int timerId); + int remainingTime(int timerId) Q_DECL_FINAL; - void wakeUp(); - void interrupt(); - void flush(); + void wakeUp() Q_DECL_FINAL; + void interrupt() Q_DECL_FINAL; + void flush() Q_DECL_FINAL; static bool versionSupported(); diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index 5d69d5e396..242aa9e695 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -94,6 +94,12 @@ public: class QEventDispatcherUNIXPrivate; +#ifdef Q_OS_QNX +# define FINAL_EXCEPT_BLACKBERRY +#else +# define FINAL_EXCEPT_BLACKBERRY Q_DECL_FINAL +#endif + class Q_CORE_EXPORT QEventDispatcherUNIX : public QAbstractEventDispatcher { Q_OBJECT @@ -106,18 +112,18 @@ public: bool processEvents(QEventLoop::ProcessEventsFlags flags); bool hasPendingEvents(); - void registerSocketNotifier(QSocketNotifier *notifier); - void unregisterSocketNotifier(QSocketNotifier *notifier); + void registerSocketNotifier(QSocketNotifier *notifier) FINAL_EXCEPT_BLACKBERRY; + void unregisterSocketNotifier(QSocketNotifier *notifier) FINAL_EXCEPT_BLACKBERRY; - 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; + void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) Q_DECL_FINAL; + bool unregisterTimer(int timerId) Q_DECL_FINAL; + bool unregisterTimers(QObject *object) Q_DECL_FINAL; + QList<TimerInfo> registeredTimers(QObject *object) const Q_DECL_FINAL; - int remainingTime(int timerId); + int remainingTime(int timerId) Q_DECL_FINAL; - void wakeUp(); - void interrupt(); + void wakeUp() FINAL_EXCEPT_BLACKBERRY; + void interrupt() Q_DECL_FINAL; void flush(); protected: @@ -130,7 +136,7 @@ protected: virtual int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - timespec *timeout); + timespec *timeout) Q_DECL_FINAL; }; class Q_CORE_EXPORT QEventDispatcherUNIXPrivate : public QAbstractEventDispatcherPrivate @@ -142,8 +148,8 @@ public: ~QEventDispatcherUNIXPrivate(); int doSelect(QEventLoop::ProcessEventsFlags flags, timespec *timeout); - virtual int initThreadWakeUp(); - virtual int processThreadWakeUp(int nsel); + virtual int initThreadWakeUp() FINAL_EXCEPT_BLACKBERRY; + virtual int processThreadWakeUp(int nsel) FINAL_EXCEPT_BLACKBERRY; bool mainThread; @@ -165,6 +171,8 @@ public: QAtomicInt interrupt; // bool }; +#undef FINAL_EXCEPT_BLACKBERRY + QT_END_NAMESPACE #endif // QEVENTDISPATCHER_UNIX_P_H 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 eab5a37645..c694237dc3 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 50ccca9eda..adad4b81a1 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 8429e41433..c9b98ac5c0 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/qalgorithms.h b/src/corelib/tools/qalgorithms.h index c6eede05cb..f75f33f25c 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -55,28 +55,28 @@ namespace QAlgorithmsPrivate { #if QT_DEPRECATED_SINCE(5, 2) template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan); +QT_DEPRECATED_X("Use std::sort") Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan); template <typename RandomAccessIterator, typename T> -QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy); +QT_DEPRECATED_X("Use std::sort") inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy); template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan); +QT_DEPRECATED_X("Use std::stable_sort") Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan); template <typename RandomAccessIterator, typename T> -QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &); +QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &); template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan); +QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan); template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan); +QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan); template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan); +QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan); #endif // QT_DEPRECATED_SINCE(5, 2) } #if QT_DEPRECATED_SINCE(5, 2) template <typename InputIterator, typename OutputIterator> -QT_DEPRECATED inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest) +QT_DEPRECATED_X("Use std::copy") inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest) { while (begin != end) *dest++ = *begin++; @@ -84,7 +84,7 @@ QT_DEPRECATED inline OutputIterator qCopy(InputIterator begin, InputIterator end } template <typename BiIterator1, typename BiIterator2> -QT_DEPRECATED inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest) +QT_DEPRECATED_X("Use std::copy_backward") inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest) { while (begin != end) *--dest = *--end; @@ -92,7 +92,7 @@ QT_DEPRECATED inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 en } template <typename InputIterator1, typename InputIterator2> -QT_DEPRECATED inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) +QT_DEPRECATED_X("Use std::equal") inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) { for (; first1 != last1; ++first1, ++first2) if (!(*first1 == *first2)) @@ -101,20 +101,20 @@ QT_DEPRECATED inline bool qEqual(InputIterator1 first1, InputIterator1 last1, In } template <typename ForwardIterator, typename T> -QT_DEPRECATED inline void qFill(ForwardIterator first, ForwardIterator last, const T &val) +QT_DEPRECATED_X("Use std::fill") inline void qFill(ForwardIterator first, ForwardIterator last, const T &val) { for (; first != last; ++first) *first = val; } template <typename Container, typename T> -QT_DEPRECATED inline void qFill(Container &container, const T &val) +QT_DEPRECATED_X("Use std::fill") inline void qFill(Container &container, const T &val) { qFill(container.begin(), container.end(), val); } template <typename InputIterator, typename T> -QT_DEPRECATED inline InputIterator qFind(InputIterator first, InputIterator last, const T &val) +QT_DEPRECATED_X("Use std::find") inline InputIterator qFind(InputIterator first, InputIterator last, const T &val) { while (first != last && !(*first == val)) ++first; @@ -122,13 +122,13 @@ QT_DEPRECATED inline InputIterator qFind(InputIterator first, InputIterator last } template <typename Container, typename T> -QT_DEPRECATED inline typename Container::const_iterator qFind(const Container &container, const T &val) +QT_DEPRECATED_X("Use std::find") inline typename Container::const_iterator qFind(const Container &container, const T &val) { return qFind(container.constBegin(), container.constEnd(), val); } template <typename InputIterator, typename T, typename Size> -QT_DEPRECATED inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n) +QT_DEPRECATED_X("Use std::count") inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n) { for (; first != last; ++first) if (*first == value) @@ -136,7 +136,7 @@ QT_DEPRECATED inline void qCount(InputIterator first, InputIterator last, const } template <typename Container, typename T, typename Size> -QT_DEPRECATED inline void qCount(const Container &container, const T &value, Size &n) +QT_DEPRECATED_X("Use std::count") inline void qCount(const Container &container, const T &value, Size &n) { qCount(container.constBegin(), container.constEnd(), value, n); } @@ -153,7 +153,7 @@ LessThan qGreater() } #else template <typename T> -class QT_DEPRECATED qLess +class QT_DEPRECATED_X("Use std::less") qLess { public: inline bool operator()(const T &t1, const T &t2) const @@ -163,7 +163,7 @@ public: }; template <typename T> -class QT_DEPRECATED qGreater +class QT_DEPRECATED_X("Use std::greater") qGreater { public: inline bool operator()(const T &t1, const T &t2) const @@ -174,21 +174,21 @@ public: #endif template <typename RandomAccessIterator> -QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end) +QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end) { if (start != end) QAlgorithmsPrivate::qSortHelper(start, end, *start); } template <typename RandomAccessIterator, typename LessThan> -QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan) +QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan) { if (start != end) QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan); } template<typename Container> -QT_DEPRECATED inline void qSort(Container &c) +QT_DEPRECATED_X("Use std::sort") inline void qSort(Container &c) { #ifdef Q_CC_BOR // Work around Borland 5.5 optimizer bug @@ -199,21 +199,21 @@ QT_DEPRECATED inline void qSort(Container &c) } template <typename RandomAccessIterator> -QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end) +QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end) { if (start != end) QAlgorithmsPrivate::qStableSortHelper(start, end, *start); } template <typename RandomAccessIterator, typename LessThan> -QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan) +QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan) { if (start != end) QAlgorithmsPrivate::qStableSortHelper(start, end, *start, lessThan); } template<typename Container> -QT_DEPRECATED inline void qStableSort(Container &c) +QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(Container &c) { #ifdef Q_CC_BOR // Work around Borland 5.5 optimizer bug @@ -224,7 +224,7 @@ QT_DEPRECATED inline void qStableSort(Container &c) } template <typename RandomAccessIterator, typename T> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value) +QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value) { // Implementation is duplicated from QAlgorithmsPrivate to keep existing code // compiling. We have to allow using *begin and value with different types, @@ -247,19 +247,19 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccess } template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) { return QAlgorithmsPrivate::qLowerBoundHelper(begin, end, value, lessThan); } template <typename Container, typename T> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value) +QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value) { return QAlgorithmsPrivate::qLowerBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>()); } template <typename RandomAccessIterator, typename T> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value) +QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value) { // Implementation is duplicated from QAlgorithmsPrivate. RandomAccessIterator middle; @@ -280,19 +280,19 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccess } template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) { return QAlgorithmsPrivate::qUpperBoundHelper(begin, end, value, lessThan); } template <typename Container, typename T> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value) +QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value) { return QAlgorithmsPrivate::qUpperBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>()); } template <typename RandomAccessIterator, typename T> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value) +QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value) { // Implementation is duplicated from QAlgorithmsPrivate. RandomAccessIterator it = qLowerBound(begin, end, value); @@ -304,13 +304,13 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccess } template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) { return QAlgorithmsPrivate::qBinaryFindHelper(begin, end, value, lessThan); } template <typename Container, typename T> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value) +QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value) { return QAlgorithmsPrivate::qBinaryFindHelper(container.constBegin(), container.constEnd(), value, qLess<T>()); } @@ -340,7 +340,7 @@ namespace QAlgorithmsPrivate { #if QT_DEPRECATED_SINCE(5, 2) template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan) +QT_DEPRECATED_X("Use std::sort") Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan) { top: int span = int(end - start); @@ -393,13 +393,13 @@ top: } template <typename RandomAccessIterator, typename T> -QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy) +QT_DEPRECATED_X("Use std::sort") inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy) { qSortHelper(begin, end, dummy, qLess<T>()); } template <typename RandomAccessIterator> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end) +QT_DEPRECATED_X("Use std::reverse") Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end) { --end; while (begin < end) @@ -407,7 +407,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, Ran } template <typename RandomAccessIterator> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end) +QT_DEPRECATED_X("Use std::rotate") Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end) { qReverse(begin, middle); qReverse(middle, end); @@ -415,7 +415,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, Rand } template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan) +QT_DEPRECATED_X("Use std::merge") Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan) { const int len1 = pivot - begin; const int len2 = end - pivot; @@ -450,7 +450,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, Rando } template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan) +QT_DEPRECATED_X("Use std::stable_sort") Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan) { const int span = end - begin; if (span < 2) @@ -463,13 +463,13 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator b } template <typename RandomAccessIterator, typename T> -QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy) +QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy) { qStableSortHelper(begin, end, dummy, qLess<T>()); } template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) { RandomAccessIterator middle; int n = int(end - begin); @@ -490,7 +490,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(Random template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) { RandomAccessIterator middle; int n = end - begin; @@ -510,7 +510,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(Random } template <typename RandomAccessIterator, typename T, typename LessThan> -QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) +QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan) { RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan); diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp index 282711fbc6..6cc15891f5 100644 --- a/src/corelib/tools/qcollator_win.cpp +++ b/src/corelib/tools/qcollator_win.cpp @@ -125,9 +125,15 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con // comparing strings, the value 2 can be subtracted from a nonzero return value. Then, the // meaning of <0, ==0, and >0 is consistent with the C runtime. +#ifndef Q_OS_WINRT return CompareString(LOCALE_USER_DEFAULT, d->collator, reinterpret_cast<const wchar_t*>(s1), len1, reinterpret_cast<const wchar_t*>(s2), len2) - 2; +#else // !Q_OS_WINRT + return CompareStringEx(LOCALE_NAME_USER_DEFAULT, d->collator, + reinterpret_cast<LPCWSTR>(s1), len1, + reinterpret_cast<LPCWSTR>(s2), len2, NULL, NULL, 0) - 2; +#endif // Q_OS_WINRT } int QCollator::compare(const QString &str1, const QString &str2) const @@ -142,13 +148,31 @@ int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const QCollatorSortKey QCollator::sortKey(const QString &string) const { +#ifndef Q_OS_WINRT int size = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | d->collator, reinterpret_cast<const wchar_t*>(string.constData()), string.size(), 0, 0); +#elif defined(Q_OS_WINPHONE) + int size = 0; + Q_UNIMPLEMENTED(); +#else // Q_OS_WINPHONE + int size = LCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_SORTKEY | d->collator, + reinterpret_cast<LPCWSTR>(string.constData()), string.size(), + 0, 0, NULL, NULL, 0); +#endif // !Q_OS_WINPHONE QString ret(size, Qt::Uninitialized); +#ifndef Q_OS_WINRT int finalSize = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | d->collator, reinterpret_cast<const wchar_t*>(string.constData()), string.size(), reinterpret_cast<wchar_t*>(ret.data()), ret.size()); +#elif defined(Q_OS_WINPHONE) + int finalSize = 0; +#else // Q_OS_WINPHONE + int finalSize = LCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_SORTKEY | d->collator, + reinterpret_cast<LPCWSTR>(string.constData()), string.size(), + reinterpret_cast<LPWSTR>(ret.data()), ret.size(), + NULL, NULL, 0); +#endif // !Q_OS_WINPHONE if (finalSize == 0) { qWarning() << "there were problems when generating the ::sortKey by LCMapStringW with error:" << GetLastError(); } diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 5ce11a43aa..6620c55a0f 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -61,6 +61,9 @@ # ifdef Q_OS_WINCE # include "qfunctions_wince.h" # endif +# ifdef Q_OS_WINRT +# include "qfunctions_winrt.h" +# endif #endif #if defined(Q_OS_MAC) diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp index 0730002ca3..bbc208e673 100644 --- a/src/corelib/tools/qlocale_win.cpp +++ b/src/corelib/tools/qlocale_win.cpp @@ -55,12 +55,32 @@ # include <time.h> #endif +#ifdef Q_OS_WINRT +#include <wrl.h> +#include <windows.foundation.h> +#include <windows.foundation.collections.h> +#ifndef Q_OS_WINPHONE +#include <windows.globalization.h> +#endif +#endif // Q_OS_WINRT + QT_BEGIN_NAMESPACE +#ifndef Q_OS_WINRT static QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT); static const char *winLangCodeToIsoName(int code); static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT); static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT); +#else // !Q_OS_WINRT +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace ABI::Windows::Foundation; + +static QByteArray getWinLocaleName(LPWSTR id = LOCALE_NAME_USER_DEFAULT); +static const char *winLangCodeToIsoName(int code); +static QString winIso639LangName(LPWSTR id = LOCALE_NAME_USER_DEFAULT); +static QString winIso3116CtryName(LPWSTR id = LOCALE_NAME_USER_DEFAULT); +#endif // Q_OS_WINRT #ifndef QT_NO_SYSTEMLOCALE @@ -121,14 +141,23 @@ private: }; // cached values: +#ifndef Q_OS_WINRT LCID lcid; +#else + WCHAR lcName[LOCALE_NAME_MAX_LENGTH]; +#endif SubstitutionType substitutionType; QChar zero; + int getLocaleInfo(LCTYPE type, LPWSTR data, int size); QString getLocaleInfo(LCTYPE type, int maxlen = 0); int getLocaleInfo_int(LCTYPE type, int maxlen = 0); QChar getLocaleInfo_qchar(LCTYPE type); + int getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size); + int getDateFormat(DWORD flags, const SYSTEMTIME * date, LPCWSTR format, LPWSTR data, int size); + int getTimeFormat(DWORD flags, const SYSTEMTIME *date, LPCWSTR format, LPWSTR data, int size); + SubstitutionType substitution(); QString &substituteDigits(QString &string); @@ -140,20 +169,60 @@ Q_GLOBAL_STATIC(QSystemLocalePrivate, systemLocalePrivate) QSystemLocalePrivate::QSystemLocalePrivate() : substitutionType(SUnknown) { +#ifndef Q_OS_WINRT lcid = GetUserDefaultLCID(); +#else + GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH); +#endif +} + +inline int QSystemLocalePrivate::getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size) +{ +#ifndef Q_OS_WINRT + return GetCurrencyFormat(lcid, flags, value, format, data, size); +#else + return GetCurrencyFormatEx(lcName, flags, value, format, data, size); +#endif +} + +inline int QSystemLocalePrivate::getDateFormat(DWORD flags, const SYSTEMTIME * date, LPCWSTR format, LPWSTR data, int size) +{ +#ifndef Q_OS_WINRT + return GetDateFormat(lcid, flags, date, format, data, size); +#else + return GetDateFormatEx(lcName, flags, date, format, data, size, NULL); +#endif +} + +inline int QSystemLocalePrivate::getTimeFormat(DWORD flags, const SYSTEMTIME *date, LPCWSTR format, LPWSTR data, int size) +{ +#ifndef Q_OS_WINRT + return GetTimeFormat(lcid, flags, date, format, data, size); +#else + return GetTimeFormatEx(lcName, flags, date, format, data, size); +#endif +} + +inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int size) +{ +#ifndef Q_OS_WINRT + return GetLocaleInfo(lcid, type, data, size); +#else + return GetLocaleInfoEx(lcName, type, data, size); +#endif } QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) { QVarLengthArray<wchar_t, 64> buf(maxlen ? maxlen : 64); - if (!GetLocaleInfo(lcid, type, buf.data(), buf.size())) + if (!getLocaleInfo(type, buf.data(), buf.size())) return QString(); if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - int cnt = GetLocaleInfo(lcid, type, 0, 0); + int cnt = getLocaleInfo(type, 0, 0); if (cnt == 0) return QString(); buf.resize(cnt); - if (!GetLocaleInfo(lcid, type, buf.data(), buf.size())) + if (!getLocaleInfo(type, buf.data(), buf.size())) return QString(); } return QString::fromWCharArray(buf.data()); @@ -177,7 +246,7 @@ QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution() { if (substitutionType == SUnknown) { wchar_t buf[8]; - if (!GetLocaleInfo(lcid, LOCALE_IDIGITSUBSTITUTION, buf, 8)) { + if (!getLocaleInfo(LOCALE_IDIGITSUBSTITUTION, buf, 8)) { substitutionType = QSystemLocalePrivate::SNever; return substitutionType; } @@ -189,7 +258,7 @@ QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution() substitutionType = QSystemLocalePrivate::SAlways; else { wchar_t digits[11]; - if (!GetLocaleInfo(lcid, LOCALE_SNATIVEDIGITS, digits, 11)) { + if (!getLocaleInfo(LOCALE_SNATIVEDIGITS, digits, 11)) { substitutionType = QSystemLocalePrivate::SNever; return substitutionType; } @@ -332,7 +401,7 @@ QVariant QSystemLocalePrivate::toString(const QDate &date, QLocale::FormatType t DWORD flags = (type == QLocale::LongFormat ? DATE_LONGDATE : DATE_SHORTDATE); wchar_t buf[255]; - if (GetDateFormat(lcid, flags, &st, NULL, buf, 255)) { + if (getDateFormat(flags, &st, NULL, buf, 255)) { QString format = QString::fromWCharArray(buf); if (substitution() == SAlways) substituteDigits(format); @@ -353,7 +422,7 @@ QVariant QSystemLocalePrivate::toString(const QTime &time, QLocale::FormatType) DWORD flags = 0; wchar_t buf[255]; - if (GetTimeFormat(lcid, flags, &st, NULL, buf, 255)) { + if (getTimeFormat(flags, &st, NULL, buf, 255)) { QString format = QString::fromWCharArray(buf); if (substitution() == SAlways) substituteDigits(format); @@ -371,7 +440,7 @@ QVariant QSystemLocalePrivate::measurementSystem() { wchar_t output[2]; - if (GetLocaleInfo(lcid, LOCALE_IMEASURE, output, 2)) { + if (getLocaleInfo(LOCALE_IMEASURE, output, 2)) { QString iMeasure = QString::fromWCharArray(output); if (iMeasure == QLatin1String("1")) { return QLocale::ImperialSystem; @@ -385,7 +454,7 @@ QVariant QSystemLocalePrivate::amText() { wchar_t output[15]; // maximum length including terminating zero character for Win2003+ - if (GetLocaleInfo(lcid, LOCALE_S1159, output, 15)) { + if (getLocaleInfo(LOCALE_S1159, output, 15)) { return QString::fromWCharArray(output); } @@ -396,7 +465,7 @@ QVariant QSystemLocalePrivate::pmText() { wchar_t output[15]; // maximum length including terminating zero character for Win2003+ - if (GetLocaleInfo(lcid, LOCALE_S2359, output, 15)) { + if (getLocaleInfo(LOCALE_S2359, output, 15)) { return QString::fromWCharArray(output); } @@ -407,7 +476,7 @@ QVariant QSystemLocalePrivate::firstDayOfWeek() { wchar_t output[4]; // maximum length including terminating zero character for Win2003+ - if (GetLocaleInfo(lcid, LOCALE_IFIRSTDAYOFWEEK, output, 4)) + if (getLocaleInfo(LOCALE_IFIRSTDAYOFWEEK, output, 4)) return QString::fromWCharArray(output).toUInt()+1; return 1; @@ -418,20 +487,20 @@ QVariant QSystemLocalePrivate::currencySymbol(QLocale::CurrencySymbolFormat form wchar_t buf[13]; switch (format) { case QLocale::CurrencySymbol: - if (GetLocaleInfo(lcid, LOCALE_SCURRENCY, buf, 13)) + if (getLocaleInfo(LOCALE_SCURRENCY, buf, 13)) return QString::fromWCharArray(buf); break; case QLocale::CurrencyIsoCode: - if (GetLocaleInfo(lcid, LOCALE_SINTLSYMBOL, buf, 9)) + if (getLocaleInfo(LOCALE_SINTLSYMBOL, buf, 9)) return QString::fromWCharArray(buf); break; case QLocale::CurrencyDisplayName: { QVarLengthArray<wchar_t, 64> buf(64); - if (!GetLocaleInfo(lcid, LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) { + if (!getLocaleInfo(LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) break; buf.resize(255); // should be large enough, right? - if (!GetLocaleInfo(lcid, LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) + if (!getLocaleInfo(LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) break; } return QString::fromWCharArray(buf.data()); @@ -478,14 +547,14 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS CURRENCYFMT format; CURRENCYFMT *pformat = NULL; if (!arg.symbol.isEmpty()) { - format.NumDigits = getLocaleInfo_int(lcid, LOCALE_ICURRDIGITS); - format.LeadingZero = getLocaleInfo_int(lcid, LOCALE_ILZERO); - decimalSep = getLocaleInfo(lcid, LOCALE_SMONDECIMALSEP); + format.NumDigits = getLocaleInfo_int(LOCALE_ICURRDIGITS); + format.LeadingZero = getLocaleInfo_int(LOCALE_ILZERO); + decimalSep = getLocaleInfo(LOCALE_SMONDECIMALSEP); format.lpDecimalSep = (wchar_t *)decimalSep.utf16(); - thousandSep = getLocaleInfo(lcid, LOCALE_SMONTHOUSANDSEP); + thousandSep = getLocaleInfo(LOCALE_SMONTHOUSANDSEP); format.lpThousandSep = (wchar_t *)thousandSep.utf16(); - format.NegativeOrder = getLocaleInfo_int(lcid, LOCALE_INEGCURR); - format.PositiveOrder = getLocaleInfo_int(lcid, LOCALE_ICURRENCY); + format.NegativeOrder = getLocaleInfo_int(LOCALE_INEGCURR); + format.PositiveOrder = getLocaleInfo_int(LOCALE_ICURRENCY); format.lpCurrencySymbol = (wchar_t *)arg.symbol.utf16(); // grouping is complicated and ugly: @@ -494,7 +563,7 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS // int(30) == "123456,789.00" == string("3;0;0") // int(32) == "12,34,56,789.00" == string("3;2;0") // int(320)== "1234,56,789.00" == string("3;2") - QString groupingStr = getLocaleInfo(lcid, LOCALE_SMONGROUPING); + QString groupingStr = getLocaleInfo(LOCALE_SMONGROUPING); format.Grouping = groupingStr.remove(QLatin1Char(';')).toInt(); if (format.Grouping % 10 == 0) // magic format.Grouping /= 10; @@ -503,13 +572,13 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS pformat = &format; } - int ret = ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()), + int ret = getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()), pformat, out.data(), out.size()); if (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - ret = ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()), + ret = getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()), pformat, out.data(), 0); out.resize(ret); - ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()), + getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()), pformat, out.data(), out.size()); } @@ -528,11 +597,13 @@ QVariant QSystemLocalePrivate::uiLanguages() PWSTR pwszLanguagesBuffer, PULONG pcchLanguagesBuffer); static GetUserPreferredUILanguagesFunc GetUserPreferredUILanguages_ptr = 0; +#ifndef Q_OS_WINRT if (!GetUserPreferredUILanguages_ptr) { QSystemLibrary lib(QLatin1String("kernel32")); if (lib.load()) GetUserPreferredUILanguages_ptr = (GetUserPreferredUILanguagesFunc)lib.resolve("GetUserPreferredUILanguages"); } +#endif // !Q_OS_WINRT if (GetUserPreferredUILanguages_ptr) { unsigned long cnt = 0; QVarLengthArray<wchar_t, 64> buf(64); @@ -560,8 +631,39 @@ QVariant QSystemLocalePrivate::uiLanguages() } } +#ifndef Q_OS_WINRT // old Windows before Vista return QStringList(QString::fromLatin1(winLangCodeToIsoName(GetUserDefaultUILanguage()))); +#else // !Q_OS_WINRT + QStringList result; +#ifndef Q_OS_WINPHONE + ComPtr<ABI::Windows::Globalization::IApplicationLanguagesStatics> appLanguagesStatics; + if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Globalization_ApplicationLanguages).Get(), &appLanguagesStatics))) { + qWarning("Could not obtain ApplicationLanguagesStatic"); + return QStringList(); + } + + ComPtr<ABI::Windows::Foundation::Collections::IVectorView<HSTRING> > languageList; + appLanguagesStatics->get_ManifestLanguages(&languageList); + + if (!languageList) + return QStringList(); + + unsigned int size; + languageList->get_Size(&size); + for (unsigned int i = 0; i < size; ++i) { + HSTRING language; + languageList->GetAt(i, &language); + UINT32 length; + PCWSTR rawString = WindowsGetStringRawBuffer(language, &length); + result << QString::fromWCharArray(rawString, length); + } +#else // !Q_OS_WINPHONE + result << QString::fromWCharArray(lcName); +#endif // Q_OS_WINPHONE + + return result; +#endif // Q_OS_WINRT } QVariant QSystemLocalePrivate::nativeLanguageName() @@ -581,7 +683,11 @@ QVariant QSystemLocalePrivate::nativeCountryName() void QSystemLocalePrivate::update() { +#ifndef Q_OS_WINRT lcid = GetUserDefaultLCID(); +#else + GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH); +#endif substitutionType = SUnknown; zero = QChar(); } @@ -895,7 +1001,11 @@ static const char *winLangCodeToIsoName(int code) } +#ifndef Q_OS_WINRT static QString winIso639LangName(LCID id) +#else +static QString winIso639LangName(LPWSTR id) +#endif { QString result; @@ -903,7 +1013,11 @@ static QString winIso639LangName(LCID id) // the language code QString lang_code; wchar_t out[256]; - if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255)) // ### shouldn't use them according to msdn +#ifndef Q_OS_WINRT + if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255)) +#else + if (GetLocaleInfoEx(id, LOCALE_ILANGUAGE, out, 255)) +#endif lang_code = QString::fromWCharArray(out); if (!lang_code.isEmpty()) { @@ -926,27 +1040,47 @@ static QString winIso639LangName(LCID id) return result; // not one of the problematic languages - do the usual lookup - if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME , out, 255)) +#ifndef Q_OS_WINRT + if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME, out, 255)) +#else + if (GetLocaleInfoEx(id, LOCALE_SISO639LANGNAME, out, 255)) +#endif result = QString::fromWCharArray(out); return result; } +#ifndef Q_OS_WINRT static QString winIso3116CtryName(LCID id) +#else +static QString winIso3116CtryName(LPWSTR id) +#endif { QString result; wchar_t out[256]; +#ifndef Q_OS_WINRT if (GetLocaleInfo(id, LOCALE_SISO3166CTRYNAME, out, 255)) +#else + if (GetLocaleInfoEx(id, LOCALE_SISO3166CTRYNAME, out, 255)) +#endif result = QString::fromWCharArray(out); return result; } +#ifndef Q_OS_WINRT static QByteArray getWinLocaleName(LCID id) +#else +static QByteArray getWinLocaleName(LPWSTR id) +#endif { QByteArray result; +#ifndef Q_OS_WINRT if (id == LOCALE_USER_DEFAULT) { +#else + if (QString::fromWCharArray(id) == QString::fromWCharArray(LOCALE_NAME_USER_DEFAULT)) { +#endif static QByteArray langEnvVar = qgetenv("LANG"); result = langEnvVar; QString lang, script, cntry; @@ -964,9 +1098,17 @@ static QByteArray getWinLocaleName(LCID id) #if defined(Q_OS_WINCE) result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID()); -#else +#else // !Q_OS_WINCE +# ifndef Q_OS_WINRT if (id == LOCALE_USER_DEFAULT) id = GetUserDefaultLCID(); +# else // !Q_OS_WINRT + WCHAR lcName[LOCALE_NAME_MAX_LENGTH]; + if (QString::fromWCharArray(id) == QString::fromWCharArray(LOCALE_NAME_USER_DEFAULT)) { + GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH); + id = lcName; + } +# endif // Q_OS_WINRT QString resultuage = winIso639LangName(id); QString country = winIso3116CtryName(id); result = resultuage.toLatin1(); @@ -974,14 +1116,20 @@ static QByteArray getWinLocaleName(LCID id) result += '_'; result += country.toLatin1(); } -#endif +#endif // !Q_OS_WINCE return result; } Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id) { +#ifndef Q_OS_WINRT return QLocale(QString::fromLatin1(getWinLocaleName(id))); +#else // !Q_OS_WINRT + WCHAR name[LOCALE_NAME_MAX_LENGTH]; + LCIDToLocaleName(id, name, LOCALE_NAME_MAX_LENGTH, 0); + return QLocale(QString::fromLatin1(getWinLocaleName(name))); +#endif // Q_OS_WINRT } QT_END_NAMESPACE diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 0e99a5839c..92556ce50a 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5109,7 +5109,11 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1, return ucstrcmp(data1, length1, data2, length2); #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) +#ifndef Q_OS_WINRT int res = CompareString(GetUserDefaultLCID(), 0, (wchar_t*)data1, length1, (wchar_t*)data2, length2); +#else + int res = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, (LPCWSTR)data1, length1, (LPCWSTR)data2, length2, NULL, NULL, 0); +#endif switch (res) { case CSTR_LESS_THAN: diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp index b6196d99e5..9c7c54ea09 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..553797a22f 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -124,8 +124,11 @@ 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 + winphone: LIBS_PRIVATE += -lWindowsPhoneGlobalizationUtil +} 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/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 06fa1f3550..816419d155 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -274,6 +274,24 @@ QMouseEvent::~QMouseEvent() { } +/*! + \since 5.3 + + Returns information about the mouse event source. + + The mouse event source can be used to distinguish between genuine + and artificial mouse events. The latter are events that are + synthesized from touch events by the operating system or Qt itself. + + \note Many platforms provide no such information. On such platforms + \l Qt::MouseEventNotSynthesized is returned always. + + \sa Qt::MouseEventSource + */ +Qt::MouseEventSource QMouseEvent::source() const +{ + return QGuiApplicationPrivate::mouseEventSource(this); +} /*! \fn QPointF QMouseEvent::localPos() const diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index d22e423248..b6b1e0c76b 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -135,6 +135,8 @@ public: QT_DEPRECATED inline QPointF posF() const { return l; } #endif + Qt::MouseEventSource source() const; + protected: QPointF l, w, s; Qt::MouseButton b; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index d254f7c9bc..db655bd2ad 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -59,6 +59,7 @@ #include <QtCore/qmutex.h> #include <QtCore/private/qthread_p.h> #include <QtCore/qdir.h> +#include <QtCore/qlibraryinfo.h> #include <QtDebug> #ifndef QT_NO_ACCESSIBILITY #include "qaccessible.h" @@ -892,6 +893,9 @@ static void init_platform(const QString &pluginArgument, const QString &platform // Split into platform name and arguments QStringList arguments = pluginArgument.split(QLatin1Char(':')); const QString name = arguments.takeFirst().toLower(); + QString argumentsKey = name; + argumentsKey[0] = argumentsKey.at(0).toUpper(); + arguments.append(QLibraryInfo::platformPluginArguments(argumentsKey)); // Create the platform integration. QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath); @@ -1569,6 +1573,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers); ev.setTimestamp(e->timestamp); + setMouseEventSource(&ev, e->source); #ifndef QT_NO_CURSOR if (!e->synthetic) { if (const QScreen *screen = window->screen()) @@ -1623,6 +1628,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint, button, buttons, e->modifiers); dblClickEvent.setTimestamp(e->timestamp); + setMouseEventSource(&dblClickEvent, e->source); QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent); } } @@ -2044,7 +2050,8 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To synthIt->pos, synthIt->screenPos, Qt::NoButton, - e->modifiers); + e->modifiers, + Qt::MouseEventSynthesizedByQt); fake.synthetic = true; processMouseEvent(&fake); } @@ -3123,9 +3130,16 @@ void QGuiApplicationPrivate::_q_updateFocusObject(QObject *object) emit q->focusObjectChanged(object); } +enum { + MouseCapsMask = 0xFF, + MouseSourceMaskDst = 0xFF00, + MouseSourceMaskSrc = MouseCapsMask, + MouseSourceShift = 8, +}; + int QGuiApplicationPrivate::mouseEventCaps(QMouseEvent *event) { - return event->caps; + return event->caps & MouseCapsMask; } QVector2D QGuiApplicationPrivate::mouseEventVelocity(QMouseEvent *event) @@ -3135,16 +3149,26 @@ QVector2D QGuiApplicationPrivate::mouseEventVelocity(QMouseEvent *event) void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity) { - event->caps = caps; + Q_ASSERT(caps <= MouseCapsMask); + event->caps &= ~MouseCapsMask; + event->caps |= caps & MouseCapsMask; event->velocity = velocity; } -void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, QMouseEvent *other) +Qt::MouseEventSource QGuiApplicationPrivate::mouseEventSource(const QMouseEvent *event) { - event->caps = other->caps; - event->velocity = other->velocity; + return Qt::MouseEventSource((event->caps & MouseSourceMaskDst) >> MouseSourceShift); } +void QGuiApplicationPrivate::setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source) +{ + // Mouse event synthesization status is encoded in the caps field because + // QTouchDevice::CapabilityFlag uses only 6 bits from it. + int value = source; + Q_ASSERT(value <= MouseSourceMaskSrc); + event->caps &= ~MouseSourceMaskDst; + event->caps |= (value & MouseSourceMaskSrc) << MouseSourceShift; +} #include "moc_qguiapplication.cpp" diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 65c6d814e6..b158138bb7 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -265,7 +265,9 @@ public: static int mouseEventCaps(QMouseEvent *event); static QVector2D mouseEventVelocity(QMouseEvent *event); static void setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity); - static void setMouseEventCapsAndVelocity(QMouseEvent *event, QMouseEvent *other); + + static Qt::MouseEventSource mouseEventSource(const QMouseEvent *event); + static void setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source); const QDrawHelperGammaTables *gammaTables(); diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp index b4e936f818..1739e8c6fd 100644 --- a/src/gui/kernel/qguivariant.cpp +++ b/src/gui/kernel/qguivariant.cpp @@ -165,7 +165,7 @@ public: #ifndef QT_NO_ICON bool delegate(const QIcon *) { - return false; + return v_cast<QIcon>(Base::m_a)->cacheKey() == v_cast<QIcon>(Base::m_b)->cacheKey(); } #endif bool delegate(const void *p) { return Base::delegate(p); } diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp index 04ea9c27d5..7899e2540b 100644 --- a/src/gui/kernel/qstylehints.cpp +++ b/src/gui/kernel/qstylehints.cpp @@ -62,6 +62,25 @@ static inline QVariant themeableHint(QPlatformTheme::ThemeHint th, return QGuiApplicationPrivate::platformIntegration()->styleHint(ih); } +class QStyleHintsPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QStyleHints) +public: + inline QStyleHintsPrivate() + : m_mouseDoubleClickInterval(-1) + , m_startDragDistance(-1) + , m_startDragTime(-1) + , m_keyboardInputInterval(-1) + , m_cursorFlashTime(-1) + {} + + int m_mouseDoubleClickInterval; + int m_startDragDistance; + int m_startDragTime; + int m_keyboardInputInterval; + int m_cursorFlashTime; +}; + /*! \class QStyleHints \since 5.0 @@ -80,8 +99,20 @@ static inline QVariant themeableHint(QPlatformTheme::ThemeHint th, \sa QGuiApplication::styleHints(), QPlatformTheme */ QStyleHints::QStyleHints() - : QObject() + : QObject(*new QStyleHintsPrivate(), 0) +{ +} + +/*! + Sets the \a mouseDoubleClickInterval. + \internal + \sa mouseDoubleClickInterval() + \since 5.3 +*/ +void QStyleHints::setMouseDoubleClickInterval(int mouseDoubleClickInterval) { + Q_D(QStyleHints); + d->m_mouseDoubleClickInterval = mouseDoubleClickInterval; } /*! @@ -90,7 +121,22 @@ QStyleHints::QStyleHints() */ int QStyleHints::mouseDoubleClickInterval() const { - return themeableHint(QPlatformTheme::MouseDoubleClickInterval, QPlatformIntegration::MouseDoubleClickInterval).toInt(); + Q_D(const QStyleHints); + return d->m_mouseDoubleClickInterval >= 0 ? + d->m_mouseDoubleClickInterval : + themeableHint(QPlatformTheme::MouseDoubleClickInterval, QPlatformIntegration::MouseDoubleClickInterval).toInt(); +} + +/*! + Sets the \a startDragDistance. + \internal + \sa startDragDistance() + \since 5.3 +*/ +void QStyleHints::setStartDragDistance(int startDragDistance) +{ + Q_D(QStyleHints); + d->m_startDragDistance = startDragDistance; } /*! @@ -112,7 +158,22 @@ int QStyleHints::mouseDoubleClickInterval() const */ int QStyleHints::startDragDistance() const { - return themeableHint(QPlatformTheme::StartDragDistance, QPlatformIntegration::StartDragDistance).toInt(); + Q_D(const QStyleHints); + return d->m_startDragDistance >= 0 ? + d->m_startDragDistance : + themeableHint(QPlatformTheme::StartDragDistance, QPlatformIntegration::StartDragDistance).toInt(); +} + +/*! + Sets the \a startDragDragTime. + \internal + \sa startDragTime() + \since 5.3 +*/ +void QStyleHints::setStartDragTime(int startDragTime) +{ + Q_D(QStyleHints); + d->m_startDragTime = startDragTime; } /*! @@ -127,7 +188,10 @@ int QStyleHints::startDragDistance() const */ int QStyleHints::startDragTime() const { - return themeableHint(QPlatformTheme::StartDragTime, QPlatformIntegration::StartDragTime).toInt(); + Q_D(const QStyleHints); + return d->m_startDragTime >= 0 ? + d->m_startDragTime : + themeableHint(QPlatformTheme::StartDragTime, QPlatformIntegration::StartDragTime).toInt(); } /*! @@ -143,12 +207,27 @@ int QStyleHints::startDragVelocity() const } /*! + Sets the \a keyboardInputInterval. + \internal + \sa keyboardInputInterval() + \since 5.3 +*/ +void QStyleHints::setKeyboardInputInterval(int keyboardInputInterval) +{ + Q_D(QStyleHints); + d->m_keyboardInputInterval = keyboardInputInterval; +} + +/*! Returns the time limit, in milliseconds, that distinguishes a key press from two consecutive key presses. */ int QStyleHints::keyboardInputInterval() const { - return themeableHint(QPlatformTheme::KeyboardInputInterval, QPlatformIntegration::KeyboardInputInterval).toInt(); + Q_D(const QStyleHints); + return d->m_keyboardInputInterval >= 0 ? + d->m_keyboardInputInterval : + themeableHint(QPlatformTheme::KeyboardInputInterval, QPlatformIntegration::KeyboardInputInterval).toInt(); } /*! @@ -161,6 +240,18 @@ int QStyleHints::keyboardAutoRepeatRate() const } /*! + Sets the \a cursorFlashTime. + \internal + \sa cursorFlashTime() + \since 5.3 +*/ +void QStyleHints::setCursorFlashTime(int cursorFlashTime) +{ + Q_D(QStyleHints); + d->m_cursorFlashTime = cursorFlashTime; +} + +/*! Returns the text cursor's flash (blink) time in milliseconds. The flash time is the time used to display, invert and restore the @@ -169,7 +260,10 @@ int QStyleHints::keyboardAutoRepeatRate() const */ int QStyleHints::cursorFlashTime() const { - return themeableHint(QPlatformTheme::CursorFlashTime, QPlatformIntegration::CursorFlashTime).toInt(); + Q_D(const QStyleHints); + return d->m_cursorFlashTime >= 0 ? + d->m_cursorFlashTime : + themeableHint(QPlatformTheme::CursorFlashTime, QPlatformIntegration::CursorFlashTime).toInt(); } /*! diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h index a0facd5f94..cc8d71108a 100644 --- a/src/gui/kernel/qstylehints.h +++ b/src/gui/kernel/qstylehints.h @@ -48,17 +48,24 @@ QT_BEGIN_NAMESPACE class QPlatformIntegration; +class QStyleHintsPrivate; class Q_GUI_EXPORT QStyleHints : public QObject { Q_OBJECT + Q_DECLARE_PRIVATE(QStyleHints) public: + void setMouseDoubleClickInterval(int mouseDoubleClickInterval); int mouseDoubleClickInterval() const; + void setStartDragDistance(int startDragDistance); int startDragDistance() const; + void setStartDragTime(int startDragTime); int startDragTime() const; int startDragVelocity() const; + void setKeyboardInputInterval(int keyboardInputInterval); int keyboardInputInterval() const; int keyboardAutoRepeatRate() const; + void setCursorFlashTime(int cursorFlashTime); int cursorFlashTime() const; bool showIsFullScreen() const; int passwordMaskDelay() const; diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 902c32419d..07717bb63d 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -161,31 +161,35 @@ void QWindowSystemInterface::handleCloseEvent(QWindow *tlw, bool *accepted) \a w == 0 means that the event is in global coords only, \a local will be ignored in this case */ -void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, + Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - handleMouseEvent(w, time, local, global, b, mods); + handleMouseEvent(w, time, local, global, b, mods, source); } -void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, + Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { QWindowSystemInterfacePrivate::MouseEvent * e = - new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods); + new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } -void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, + Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - handleFrameStrutMouseEvent(w, time, local, global, b, mods); + handleFrameStrutMouseEvent(w, time, local, global, b, mods, source); } -void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, + Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { QWindowSystemInterfacePrivate::MouseEvent * e = new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QWindowSystemInterfacePrivate::FrameStrutMouse, - local, global, b, mods); + local, global, b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index d8d0922b96..0c3494a46d 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -73,10 +73,18 @@ class QPlatformDropQtResponse; class Q_GUI_EXPORT QWindowSystemInterface { public: - static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier); - static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier); - static void handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier); - static void handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier); + static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, + Qt::KeyboardModifiers mods = Qt::NoModifier, + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, + Qt::KeyboardModifiers mods = Qt::NoModifier, + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + static void handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, + Qt::KeyboardModifiers mods = Qt::NoModifier, + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + static void handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, + Qt::KeyboardModifiers mods = Qt::NoModifier, + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); static bool tryHandleShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 03e2d420f0..f0398ffc51 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -206,14 +206,17 @@ public: class MouseEvent : public InputEvent { public: MouseEvent(QWindow * w, ulong time, const QPointF & local, const QPointF & global, - Qt::MouseButtons b, Qt::KeyboardModifiers mods) - : InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(b) { } + Qt::MouseButtons b, Qt::KeyboardModifiers mods, + Qt::MouseEventSource src = Qt::MouseEventNotSynthesized) + : InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(b), source(src) { } MouseEvent(QWindow * w, ulong time, EventType t, const QPointF & local, const QPointF & global, - Qt::MouseButtons b, Qt::KeyboardModifiers mods) - : InputEvent(w, time, t, mods), localPos(local), globalPos(global), buttons(b) { } + Qt::MouseButtons b, Qt::KeyboardModifiers mods, + Qt::MouseEventSource src = Qt::MouseEventNotSynthesized) + : InputEvent(w, time, t, mods), localPos(local), globalPos(global), buttons(b), source(src) { } QPointF localPos; QPointF globalPos; Qt::MouseButtons buttons; + Qt::MouseEventSource source; }; class WheelEvent : public InputEvent { diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index d8dfae1e2c..38c2dd6498 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 6a3eacd67a..c0b3769c2d 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/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 328931e1eb..6e14fc23c6 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -693,7 +693,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, FT_Set_Transform(face, &matrix, 0); freetype->matrix = matrix; // fake bold - if ((fontDef.weight == QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face)) + if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face)) embolden = true; // underline metrics line_thickness = QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale)); @@ -1165,7 +1165,7 @@ int QFontEngineFT::synthesized() const int s = 0; if ((fontDef.style != QFont::StyleNormal) && !(freetype->face->style_flags & FT_STYLE_FLAG_ITALIC)) s = SynthesizedItalic; - if ((fontDef.weight == QFont::Bold) && !(freetype->face->style_flags & FT_STYLE_FLAG_BOLD)) + if ((fontDef.weight >= QFont::Bold) && !(freetype->face->style_flags & FT_STYLE_FLAG_BOLD)) s |= SynthesizedBold; if (fontDef.stretch != 100 && FT_IS_SCALABLE(freetype->face)) s |= SynthesizedStretch; diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp index 53675d083b..e776a8eb76 100644 --- a/src/network/kernel/qdnslookup.cpp +++ b/src/network/kernel/qdnslookup.cpp @@ -363,6 +363,25 @@ void QDnsLookup::setType(Type type) } /*! + \property QDnsLookup::nameserver + \brief the nameserver to use for DNS lookup. +*/ + +QHostAddress QDnsLookup::nameserver() const +{ + return d_func()->nameserver; +} + +void QDnsLookup::setNameserver(const QHostAddress &nameserver) +{ + Q_D(QDnsLookup); + if (nameserver != d->nameserver) { + d->nameserver = nameserver; + emit nameserverChanged(nameserver); + } +} + +/*! Returns the list of canonical name records associated with this lookup. */ diff --git a/src/network/kernel/qdnslookup.h b/src/network/kernel/qdnslookup.h index 1df21d866e..ffbef61f92 100644 --- a/src/network/kernel/qdnslookup.h +++ b/src/network/kernel/qdnslookup.h @@ -180,6 +180,7 @@ class Q_NETWORK_EXPORT QDnsLookup : public QObject Q_PROPERTY(QString errorString READ errorString NOTIFY finished) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(Type type READ type WRITE setType NOTIFY typeChanged) + Q_PROPERTY(QHostAddress nameserver READ nameserver WRITE setNameserver NOTIFY nameserverChanged) public: enum Error @@ -209,6 +210,7 @@ public: explicit QDnsLookup(QObject *parent = 0); QDnsLookup(Type type, const QString &name, QObject *parent = 0); + QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent = 0); ~QDnsLookup(); Error error() const; @@ -221,6 +223,9 @@ public: Type type() const; void setType(QDnsLookup::Type); + QHostAddress nameserver() const; + void setNameserver(const QHostAddress &nameserver); + QList<QDnsDomainNameRecord> canonicalNameRecords() const; QList<QDnsHostAddressRecord> hostAddressRecords() const; QList<QDnsMailExchangeRecord> mailExchangeRecords() const; @@ -238,6 +243,7 @@ Q_SIGNALS: void finished(); void nameChanged(const QString &name); void typeChanged(Type type); + void nameserverChanged(const QHostAddress &nameserver); private: Q_DECLARE_PRIVATE(QDnsLookup) diff --git a/src/network/kernel/qdnslookup_p.h b/src/network/kernel/qdnslookup_p.h index 692b9088fe..4bd3bd7603 100644 --- a/src/network/kernel/qdnslookup_p.h +++ b/src/network/kernel/qdnslookup_p.h @@ -100,6 +100,7 @@ public: bool isFinished; QString name; QDnsLookup::Type type; + QHostAddress nameserver; QDnsLookupReply reply; QDnsLookupRunnable *runnable; diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index b5e3aa741e..459a450222 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -58,6 +58,7 @@ #include <locale.h> // LC_CTYPE #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/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index b6e75929f8..e72b1d60c8 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -345,8 +345,8 @@ static inline unsigned parseOptions(const QStringList ¶mList) } } else if (param == QLatin1String("gl=gdi")) { options |= QWindowsIntegration::DisableArb; - } else if (param == QLatin1String("mousefromtouch")) { - options |= QWindowsIntegration::PassOsMouseEventsSynthesizedFromTouch; + } else if (param == QLatin1String("nomousefromtouch")) { + options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch; } } return options; @@ -563,11 +563,9 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co case QPlatformIntegration::SynthesizeMouseFromTouchEvents: #ifdef Q_OS_WINCE // We do not want Qt to synthesize mouse events as Windows also does that. - // Alternatively, Windows-generated touch mouse events can be identified and - // ignored by checking GetMessageExtraInfo() for MI_WP_SIGNATURE (0xFF515700). return false; #else // Q_OS_WINCE - return QVariant(!(d->m_options & PassOsMouseEventsSynthesizedFromTouch)); + return QVariant(bool(d->m_options & DontPassOsMouseEventsSynthesizedFromTouch)); #endif // !Q_OS_WINCE default: break; diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index 97916a479b..270ff7ef68 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -60,7 +60,7 @@ public: DisableArb = 0x4, NoNativeDialogs = 0x8, XpNativeDialogs = 0x10, - PassOsMouseEventsSynthesizedFromTouch = 0x20 // Pass OS-generated mouse events from touch. + DontPassOsMouseEventsSynthesizedFromTouch = 0x20 // Do not pass OS-generated mouse events from touch. }; explicit QWindowsIntegration(const QStringList ¶mList); diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 3dd8c5a0cd..b43aafeba0 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -167,8 +167,12 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, if (et == QtWindows::MouseWheelEvent) return translateMouseWheelEvent(window, hwnd, msg, result); + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized; + #ifndef Q_OS_WINCE - static const bool passSynthesizedMouseEvents = QWindowsIntegration::instance()->options() & QWindowsIntegration::PassOsMouseEventsSynthesizedFromTouch; + // Check for events synthesized from touch. Lower byte is touch index, 0 means pen. + static const bool passSynthesizedMouseEvents = + !(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch); if (!passSynthesizedMouseEvents) { // Check for events synthesized from touch. Lower 7 bits are touch/pen index, bit 8 indicates touch. // However, when tablet support is active, extraInfo is a packet serial number. This is not a problem @@ -177,6 +181,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, const bool fromTouch = (extraInfo & signatureMask) == miWpSignature && (extraInfo & 0x80); if (fromTouch) return false; + source = Qt::MouseEventSynthesizedBySystem; } #endif // !Q_OS_WINCE @@ -187,7 +192,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons(); QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition, globalPosition, buttons, - QWindowsKeyMapper::queryKeyboardModifiers()); + QWindowsKeyMapper::queryKeyboardModifiers(), + source); return false; // Allow further event processing (dragging of windows). } @@ -335,7 +341,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, } QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons, - QWindowsKeyMapper::queryKeyboardModifiers()); + QWindowsKeyMapper::queryKeyboardModifiers(), + source); m_previousCaptureWindow = hasCapture ? window : 0; return true; } 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 ®ion, 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 ®ion) +{ + 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 ®ion, 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..22c50e67f3 --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -0,0 +1,194 @@ +/**************************************************************************** +** +** 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); + + m_success = true; +} + +QWinRTIntegration::~QWinRTIntegration() +{ + Windows::Foundation::Uninitialize(); +} + +QAbstractEventDispatcher *QWinRTIntegration::createEventDispatcher() const +{ + ICoreDispatcher *dispatcher; + if (FAILED(m_screen->coreWindow()->get_Dispatcher(&dispatcher))) + qCritical("Could not capture UI Dispatcher"); + return new QWinRTEventDispatcher(dispatcher); +} + +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::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const +{ + return m_screen->keyboardModifiers(); +} + +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..d9438bcb3a --- /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 *createEventDispatcher() const; + QPlatformFontDatabase *fontDatabase() const; + QPlatformInputContext *inputContext() const; + QPlatformServices *services() const; + Qt::KeyboardModifiers queryKeyboardModifiers() const; + +private: + bool m_success; + QWinRTScreen *m_screen; + 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..911d3619fe --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -0,0 +1,975 @@ +/**************************************************************************** +** +** 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::ScreenOrientations qtOrientationsFromNative(DisplayOrientations native) +{ + Qt::ScreenOrientations orientations = Qt::PrimaryOrientation; + if (native & DisplayOrientations_Portrait) + orientations |= Qt::PortraitOrientation; + if (native & DisplayOrientations_PortraitFlipped) + orientations |= Qt::InvertedPortraitOrientation; + if (native & DisplayOrientations_Landscape) + orientations |= Qt::LandscapeOrientation; + if (native & DisplayOrientations_LandscapeFlipped) + orientations |= Qt::InvertedLandscapeOrientation; + return orientations; +} + +static inline DisplayOrientations nativeOrientationsFromQt(Qt::ScreenOrientations orientation) +{ + DisplayOrientations native = DisplayOrientations_None; + if (orientation & Qt::PortraitOrientation) + native |= DisplayOrientations_Portrait; + if (orientation & Qt::InvertedPortraitOrientation) + native |= DisplayOrientations_PortraitFlipped; + if (orientation & Qt::LandscapeOrientation) + native |= DisplayOrientations_Landscape; + if (orientation & Qt::InvertedLandscapeOrientation) + native |= DisplayOrientations_LandscapeFlipped; + return native; +} + +static inline bool qIsNonPrintable(quint32 keyCode) +{ + switch (keyCode) { + case '\b': + case '\n': + case '\t': + case '\r': + case '\v': + case '\f': + return true; + default: + return false; + } +} + +// Return Qt meta key from VirtualKey +static inline Qt::Key qKeyFromVirtual(VirtualKey key) +{ + switch (key) { + + default: + return Qt::Key_unknown; + + // Non-printable characters + case VirtualKey_Enter: + return Qt::Key_Enter; + case VirtualKey_Tab: + return Qt::Key_Tab; + case VirtualKey_Back: + return Qt::Key_Backspace; + + // 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_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_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 + case VirtualKey_Space: + return Qt::Key_Space; + case VirtualKey_Number0: + case VirtualKey_NumberPad0: + return Qt::Key_0; + case VirtualKey_Number1: + case VirtualKey_NumberPad1: + return Qt::Key_1; + case VirtualKey_Number2: + case VirtualKey_NumberPad2: + return Qt::Key_2; + case VirtualKey_Number3: + case VirtualKey_NumberPad3: + return Qt::Key_3; + case VirtualKey_Number4: + case VirtualKey_NumberPad4: + return Qt::Key_4; + case VirtualKey_Number5: + case VirtualKey_NumberPad5: + return Qt::Key_5; + case VirtualKey_Number6: + case VirtualKey_NumberPad6: + return Qt::Key_6; + case VirtualKey_Number7: + case VirtualKey_NumberPad7: + return Qt::Key_7; + case VirtualKey_Number8: + case VirtualKey_NumberPad8: + return Qt::Key_8; + case VirtualKey_Number9: + case VirtualKey_NumberPad9: + return Qt::Key_9; + case VirtualKey_A: + return Qt::Key_A; + case VirtualKey_B: + return Qt::Key_B; + case VirtualKey_C: + return Qt::Key_C; + case VirtualKey_D: + return Qt::Key_D; + case VirtualKey_E: + return Qt::Key_E; + case VirtualKey_F: + return Qt::Key_F; + case VirtualKey_G: + return Qt::Key_G; + case VirtualKey_H: + return Qt::Key_H; + case VirtualKey_I: + return Qt::Key_I; + case VirtualKey_J: + return Qt::Key_J; + case VirtualKey_K: + return Qt::Key_K; + case VirtualKey_L: + return Qt::Key_L; + case VirtualKey_M: + return Qt::Key_M; + case VirtualKey_N: + return Qt::Key_N; + case VirtualKey_O: + return Qt::Key_O; + case VirtualKey_P: + return Qt::Key_P; + case VirtualKey_Q: + return Qt::Key_Q; + case VirtualKey_R: + return Qt::Key_R; + case VirtualKey_S: + return Qt::Key_S; + case VirtualKey_T: + return Qt::Key_T; + case VirtualKey_U: + return Qt::Key_U; + case VirtualKey_V: + return Qt::Key_V; + case VirtualKey_W: + return Qt::Key_W; + case VirtualKey_X: + return Qt::Key_X; + case VirtualKey_Y: + return Qt::Key_Y; + case VirtualKey_Z: + return Qt::Key_Z; + case VirtualKey_Multiply: + return Qt::Key_9; + case VirtualKey_Add: + return Qt::Key_9; + case VirtualKey_Separator: + return Qt::Key_9; + case VirtualKey_Subtract: + return Qt::Key_9; + case VirtualKey_Decimal: + return Qt::Key_9; + case VirtualKey_Divide: + return Qt::Key_9; + + /* 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:*/ + } +} + +static inline Qt::Key qKeyFromCode(quint32 code, int mods) +{ + if (code >= 'a' && code <= 'z') + code = toupper(code); + if ((mods & Qt::ControlModifier) != 0) { + if (code >= 0 && code <= 31) // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_ + code += '@'; // to @..A..Z.._ + } + return static_cast<Qt::Key>(code & 0xff); +} + +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::onKeyDown).Get(), &m_tokens[QEvent::KeyPress]); + m_coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).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 = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(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::KeyboardModifiers QWinRTScreen::keyboardModifiers() const +{ + Qt::KeyboardModifiers mods; + CoreVirtualKeyStates mod; + m_coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod); + if (mod == CoreVirtualKeyStates_Down) + mods |= Qt::ShiftModifier; + m_coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod); + if (mod == CoreVirtualKeyStates_Down) + mods |= Qt::AltModifier; + m_coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod); + if (mod == CoreVirtualKeyStates_Down) + mods |= Qt::ControlModifier; + m_coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod); + if (mod == CoreVirtualKeyStates_Down) { + mods |= Qt::MetaModifier; + } else { + m_coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod); + if (mod == CoreVirtualKeyStates_Down) + mods |= Qt::MetaModifier; + } + return mods; +} + +Qt::ScreenOrientation QWinRTScreen::nativeOrientation() const +{ + return m_nativeOrientation; +} + +Qt::ScreenOrientation QWinRTScreen::orientation() const +{ + return m_orientation; +} + +void QWinRTScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) +{ + m_displayProperties->put_AutoRotationPreferences(nativeOrientationsFromQt(mask)); +} + +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::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args) +{ + Q_UNUSED(window); + VirtualKey virtualKey; + args->get_VirtualKey(&virtualKey); + Qt::Key key = qKeyFromVirtual(virtualKey); + // Defer character key presses to onCharacterReceived + if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis)) + return S_OK; + QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, keyboardModifiers()); + return S_OK; +} + +HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args) +{ + Q_UNUSED(window); + Qt::KeyboardModifiers mods = keyboardModifiers(); +#ifndef Q_OS_WINPHONE + CorePhysicalKeyStatus status; // Look for a pressed character key + if (SUCCEEDED(args->get_KeyStatus(&status)) && m_activeKeys.contains(status.ScanCode)) { + QPair<Qt::Key, QString> keyStatus = m_activeKeys.take(status.ScanCode); + QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, + keyStatus.first, mods, keyStatus.second); + return S_OK; + } +#endif // !Q_OS_WINPHONE + VirtualKey virtualKey; + args->get_VirtualKey(&virtualKey); + QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, + qKeyFromVirtual(virtualKey), mods); + return S_OK; +} + +HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceivedEventArgs *args) +{ + Q_UNUSED(window); + + quint32 keyCode; + args->get_KeyCode(&keyCode); + // Don't generate character events for non-printables; the meta key stage is enough + if (qIsNonPrintable(keyCode)) + return S_OK; + + Qt::KeyboardModifiers mods = keyboardModifiers(); + Qt::Key key = qKeyFromCode(keyCode, mods); + QString text = QChar(keyCode); + QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text); +#ifndef Q_OS_WINPHONE + CorePhysicalKeyStatus status; // Defer release to onKeyUp for physical keys + if (SUCCEEDED(args->get_KeyStatus(&status)) && !status.IsKeyReleased) { + m_activeKeys.insert(status.ScanCode, qMakePair(key, text)); + return S_OK; + } +#endif // !Q_OS_WINPHONE + 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; +#ifndef Q_OS_WINPHONE + pointerPoint->get_IsInContact(&isPressed); +#else + properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone +#endif + 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 = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(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..21e50fa10a --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtscreen.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 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::KeyboardModifiers keyboardModifiers() const; + + Qt::ScreenOrientation nativeOrientation() const; + Qt::ScreenOrientation orientation() const; + void setOrientationUpdateMask(Qt::ScreenOrientations mask); + + 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 onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args); + HRESULT onKeyUp(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; + +#ifndef Q_OS_WINPHONE + QHash<quint32, QPair<Qt::Key, QString> > m_activeKeys; +#endif + 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 9d81c8e224..8c10b134bd 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp @@ -50,6 +50,7 @@ #include <X11/SM/SMlib.h> #include <errno.h> // ERANGE +#include <cerrno> // ERANGE class QSmSocketReceiver : public QObject { diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp index 661a582afe..e5f4c5fc56 100644 --- a/src/sql/kernel/qsqlquery.cpp +++ b/src/sql/kernel/qsqlquery.cpp @@ -309,19 +309,20 @@ QSqlQuery& QSqlQuery::operator=(const QSqlQuery& other) } /*! - Returns \c true if the query is \l{isActive()}{active} and positioned - on a valid record and the \a field is NULL; otherwise returns - false. Note that for some drivers, isNull() will not return accurate - information until after an attempt is made to retrieve data. + Returns \c true if the query is not \l{isActive()}{active}, + the query is not positioned on a valid record, + there is no such field, or the field is null; otherwise \c false. + Note that for some drivers, isNull() will not return accurate + information until after an attempt is made to retrieve data. - \sa isActive(), isValid(), value() + \sa isActive(), isValid(), value() */ bool QSqlQuery::isNull(int field) const { - if (d->sqlResult->isActive() && d->sqlResult->isValid()) - return d->sqlResult->isNull(field); - return true; + return !d->sqlResult->isActive() + || !d->sqlResult->isValid() + || d->sqlResult->isNull(field); } /*! diff --git a/src/src.pro b/src/src.pro index b7887a6108..74ca7fbf0b 100644 --- a/src/src.pro +++ b/src/src.pro @@ -149,6 +149,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 = \ @@ -156,4 +162,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 383e3ab3f4..d45f623b8d 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -1714,7 +1714,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 fa6306005b..bda448bde3 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -1715,7 +1715,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.cpp b/src/widgets/kernel/qapplication.cpp index 70c63086a3..210cb29120 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2599,7 +2599,7 @@ QDesktopWidget *QApplication::desktop() void QApplication::setStartDragTime(int ms) { - Q_UNUSED(ms) + QGuiApplication::styleHints()->setStartDragTime(ms); } /*! @@ -2632,7 +2632,7 @@ int QApplication::startDragTime() void QApplication::setStartDragDistance(int l) { - Q_UNUSED(l); + QGuiApplication::styleHints()->setStartDragDistance(l); } /*! @@ -3599,7 +3599,7 @@ bool QApplication::keypadNavigationEnabled() */ void QApplication::setCursorFlashTime(int msecs) { - Q_UNUSED(msecs); + QGuiApplication::styleHints()->setCursorFlashTime(msecs); } int QApplication::cursorFlashTime() @@ -3614,12 +3614,10 @@ int QApplication::cursorFlashTime() The default value on X11 is 400 milliseconds. On Windows and Mac OS, the operating system's value is used. - - Setting the interval is not supported anymore in Qt 5. */ void QApplication::setDoubleClickInterval(int ms) { - Q_UNUSED(ms); + QGuiApplication::styleHints()->setMouseDoubleClickInterval(ms); } int QApplication::doubleClickInterval() @@ -3647,7 +3645,7 @@ int QApplication::doubleClickInterval() */ void QApplication::setKeyboardInputInterval(int ms) { - Q_UNUSED(ms); + QGuiApplication::styleHints()->setKeyboardInputInterval(ms); } int QApplication::keyboardInputInterval() 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 abba2b455a..55459ac1ac 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -4175,7 +4175,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 ®ion, 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 ®ion, int msec) { @@ -160,7 +160,7 @@ static void showYellowThing_win(QWidget *widget, const QRegion ®ion, 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 dde705f9b9..9ab8f8f08a 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 }; diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index d0f138269f..c0542ff242 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -69,7 +69,7 @@ typedef ITypedEventHandler<Core::CoreApplicationView *, Activation::IActivatedEv class AppContainer : public Microsoft::WRL::RuntimeClass<Core::IFrameworkView> { public: - AppContainer(int argc, wchar_t **argv) : m_argc(argc) + AppContainer(int argc, wchar_t **argv) : m_argc(argc), m_debugWait(false) { m_argv.reserve(argc); for (int i = 0; i < argc; ++i) { @@ -95,6 +95,11 @@ public: HRESULT __stdcall Load(HSTRING) { return S_OK; } HRESULT __stdcall Run() { + // Wait for debugger before continuing + if (m_debugWait) { + while (!IsDebuggerPresent()) + WaitForSingleObjectEx(GetCurrentThread(), 1, true); + } return main(m_argv.count(), m_argv.data()); } HRESULT __stdcall Uninitialize() { return S_OK; } @@ -113,6 +118,8 @@ private: foreach (const QByteArray &arg, QString::fromWCharArray( WindowsGetStringRawBuffer(arguments, nullptr)).toLocal8Bit().split(' ')) { m_argv.append(qstrdup(arg.constData())); + if (arg == "-qdebug") + m_debugWait = true; } } return S_OK; @@ -120,6 +127,7 @@ private: int m_argc; QVector<char *> m_argv; + bool m_debugWait; EventRegistrationToken m_activationToken; }; diff --git a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp index 20f99e9191..36e01a0ccd 100644 --- a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp +++ b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp @@ -44,6 +44,7 @@ #include <QtGlobal> #include <math.h> +#include <float.h> class tst_QNumeric: public QObject { @@ -53,6 +54,10 @@ private slots: void fuzzyCompare_data(); void fuzzyCompare(); void qNan(); + void floatDistance_data(); + void floatDistance(); + void floatDistance_double_data(); + void floatDistance_double(); }; void tst_QNumeric::fuzzyCompare_data() @@ -121,5 +126,93 @@ void tst_QNumeric::qNan() QVERIFY(qFuzzyCompare(1/inf, 0.0)); } +void tst_QNumeric::floatDistance_data() +{ + QTest::addColumn<float>("val1"); + QTest::addColumn<float>("val2"); + QTest::addColumn<quint32>("expectedDistance"); + + // exponent: 8 bits + // mantissa: 23 bits + const quint32 number_of_denormals = (1 << 23) - 1; // Set to 0 if denormals are not included + + quint32 _0_to_1 = quint32((1 << 23) * 126 + 1 + number_of_denormals); // We need +1 to include the 0 + quint32 _1_to_2 = quint32(1 << 23); + + // We don't need +1 because FLT_MAX has all bits set in the mantissa. (Thus mantissa + // have not wrapped back to 0, which would be the case for 1 in _0_to_1 + quint32 _0_to_FLT_MAX = quint32((1 << 23) * 254) + number_of_denormals; + + quint32 _0_to_FLT_MIN = 1 + number_of_denormals; + QTest::newRow("[0,FLT_MIN]") << 0.F << FLT_MIN << _0_to_FLT_MIN; + QTest::newRow("[0,FLT_MAX]") << 0.F << FLT_MAX << _0_to_FLT_MAX; + QTest::newRow("[1,1.5]") << 1.0F << 1.5F << quint32(1 << 22); + QTest::newRow("[0,1]") << 0.F << 1.0F << _0_to_1; + QTest::newRow("[0.5,1]") << 0.5F << 1.0F << quint32(1 << 23); + QTest::newRow("[1,2]") << 1.F << 2.0F << _1_to_2; + QTest::newRow("[-1,+1]") << -1.F << +1.0F << 2 * _0_to_1; + QTest::newRow("[-1,0]") << -1.F << 0.0F << _0_to_1; + QTest::newRow("[-1,FLT_MAX]") << -1.F << FLT_MAX << _0_to_1 + _0_to_FLT_MAX; + QTest::newRow("[-2,-1") << -2.F << -1.F << _1_to_2; + QTest::newRow("[-1,-2") << -1.F << -2.F << _1_to_2; + QTest::newRow("[FLT_MIN,FLT_MAX]") << FLT_MIN << FLT_MAX << _0_to_FLT_MAX - _0_to_FLT_MIN; + QTest::newRow("[-FLT_MAX,FLT_MAX]") << -FLT_MAX << FLT_MAX << (2*_0_to_FLT_MAX); + float denormal = FLT_MIN; + denormal/=2.0F; + QTest::newRow("denormal") << 0.F << denormal << _0_to_FLT_MIN/2; +} + +void tst_QNumeric::floatDistance() +{ + QFETCH(float, val1); + QFETCH(float, val2); + QFETCH(quint32, expectedDistance); + QCOMPARE(qFloatDistance(val1, val2), expectedDistance); +} + +void tst_QNumeric::floatDistance_double_data() +{ + QTest::addColumn<double>("val1"); + QTest::addColumn<double>("val2"); + QTest::addColumn<quint64>("expectedDistance"); + + // exponent: 11 bits + // mantissa: 52 bits + const quint64 number_of_denormals = (Q_UINT64_C(1) << 52) - 1; // Set to 0 if denormals are not included + + quint64 _0_to_1 = (Q_UINT64_C(1) << 52) * ((1 << (11-1)) - 2) + 1 + number_of_denormals; // We need +1 to include the 0 + quint64 _1_to_2 = Q_UINT64_C(1) << 52; + + // We don't need +1 because DBL_MAX has all bits set in the mantissa. (Thus mantissa + // have not wrapped back to 0, which would be the case for 1 in _0_to_1 + quint64 _0_to_DBL_MAX = quint64((Q_UINT64_C(1) << 52) * ((1 << 11) - 2)) + number_of_denormals; + + quint64 _0_to_DBL_MIN = 1 + number_of_denormals; + QTest::newRow("[0,DBL_MIN]") << 0.0 << DBL_MIN << _0_to_DBL_MIN; + QTest::newRow("[0,DBL_MAX]") << 0.0 << DBL_MAX << _0_to_DBL_MAX; + QTest::newRow("[1,1.5]") << 1.0 << 1.5 << (Q_UINT64_C(1) << 51); + QTest::newRow("[0,1]") << 0.0 << 1.0 << _0_to_1; + QTest::newRow("[0.5,1]") << 0.5 << 1.0 << (Q_UINT64_C(1) << 52); + QTest::newRow("[1,2]") << 1.0 << 2.0 << _1_to_2; + QTest::newRow("[-1,+1]") << -1.0 << +1.0 << 2 * _0_to_1; + QTest::newRow("[-1,0]") << -1.0 << 0.0 << _0_to_1; + QTest::newRow("[-1,DBL_MAX]") << -1.0 << DBL_MAX << _0_to_1 + _0_to_DBL_MAX; + QTest::newRow("[-2,-1") << -2.0 << -1.0 << _1_to_2; + QTest::newRow("[-1,-2") << -1.0 << -2.0 << _1_to_2; + QTest::newRow("[DBL_MIN,DBL_MAX]") << DBL_MIN << DBL_MAX << _0_to_DBL_MAX - _0_to_DBL_MIN; + QTest::newRow("[-DBL_MAX,DBL_MAX]") << -DBL_MAX << DBL_MAX << (2*_0_to_DBL_MAX); + double denormal = DBL_MIN; + denormal/=2.0; + QTest::newRow("denormal") << 0.0 << denormal << _0_to_DBL_MIN/2; +} + +void tst_QNumeric::floatDistance_double() +{ + QFETCH(double, val1); + QFETCH(double, val2); + QFETCH(quint64, expectedDistance); + QCOMPARE(qFloatDistance(val1, val2), expectedDistance); +} + QTEST_APPLESS_MAIN(tst_QNumeric) #include "tst_qnumeric.moc" diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro index ab66323d3b..11815c6160 100644 --- a/tests/auto/corelib/io/io.pro +++ b/tests/auto/corelib/io/io.pro @@ -56,3 +56,9 @@ SUBDIRS=\ win32:!contains(QT_CONFIG, private_tests): SUBDIRS -= \ qfilesystementry + +winrt: SUBDIRS -= \ + qprocess \ + qprocess-noapplication \ + qprocessenvironment \ + qwinoverlappedionotifier diff --git a/tests/auto/corelib/io/qfile/test/test.pro b/tests/auto/corelib/io/qfile/test/test.pro index bc6922b4e9..e282bd091c 100644 --- a/tests/auto/corelib/io/qfile/test/test.pro +++ b/tests/auto/corelib/io/qfile/test/test.pro @@ -13,5 +13,5 @@ TESTDATA += ../dosfile.txt ../noendofline.txt ../testfile.txt \ ../Makefile ../forCopying.txt ../forRenaming.txt \ ../resources/file1.ext1 -win32: LIBS+=-lole32 -luuid +win32:!winrt: LIBS+=-lole32 -luuid DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 2b029203e9..78cb27ee30 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -527,7 +527,7 @@ void tst_QFile::open_data() << false << QFile::OpenError; QTest::newRow("noreadfile") << QString::fromLatin1(noReadFile) << int(QIODevice::ReadOnly) << false << QFile::OpenError; -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) //opening devices requires administrative privileges (and elevation). HANDLE hTest = CreateFile(_T("\\\\.\\PhysicalDrive0"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hTest != INVALID_HANDLE_VALUE) { @@ -1057,7 +1057,7 @@ void tst_QFile::ungetChar() QCOMPARE(buf[2], '4'); } -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) QString driveLetters() { wchar_t volumeName[MAX_PATH]; @@ -1094,7 +1094,7 @@ void tst_QFile::invalidFile_data() #if !defined(Q_OS_WIN) QTest::newRow( "x11" ) << QString( "qwe//" ); #else -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) QTest::newRow( "colon2" ) << invalidDriveLetter() + QString::fromLatin1(":ail:invalid"); #endif QTest::newRow( "colon3" ) << QString( ":failinvalid" ); @@ -1338,10 +1338,12 @@ void tst_QFile::copyFallback() #ifdef Q_OS_WIN #include <objbase.h> +#ifndef Q_OS_WINPHONE #include <shlobj.h> #endif +#endif -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) static QString getWorkingDirectoryForLink(const QString &linkFileName) { bool neededCoInit = false; @@ -1400,7 +1402,7 @@ void tst_QFile::link() QCOMPARE(QFile::symLinkTarget("myLink.lnk"), referenceTarget); -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath()); QCOMPARE(QDir::fromNativeSeparators(wd), QDir::cleanPath(info1.absolutePath())); #endif @@ -2690,8 +2692,12 @@ void tst_QFile::nativeHandleLeaks() } #ifdef Q_OS_WIN +# ifndef Q_OS_WINRT handle1 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); +# else + handle1 = ::CreateFile2(L"qt_file.tmp", GENERIC_READ, 0, OPEN_ALWAYS, NULL); +# endif QVERIFY( INVALID_HANDLE_VALUE != handle1 ); QVERIFY( ::CloseHandle(handle1) ); #endif @@ -2705,8 +2711,12 @@ void tst_QFile::nativeHandleLeaks() } #ifdef Q_OS_WIN +# ifndef Q_OS_WINRT handle2 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); +# else + handle2 = ::CreateFile2(L"qt_file.tmp", GENERIC_READ, 0, OPEN_ALWAYS, NULL); +# endif QVERIFY( INVALID_HANDLE_VALUE != handle2 ); QVERIFY( ::CloseHandle(handle2) ); #endif diff --git a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro index c4b37a8847..64d289bc3c 100644 --- a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro +++ b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro @@ -6,5 +6,5 @@ RESOURCES += qfileinfo.qrc TESTDATA += qfileinfo.qrc qfileinfo.pro tst_qfileinfo.cpp resources/file1 resources/file1.ext1 resources/file1.ext1.ext2 -win32*:!wince*:LIBS += -ladvapi32 -lnetapi32 +win32*:!wince*:!winrt:LIBS += -ladvapi32 -lnetapi32 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index d2171cc64a..74667a951f 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -62,7 +62,7 @@ #ifdef Q_OS_WIN #include <qt_windows.h> #include <qlibrary.h> -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) #include <lm.h> #endif #endif @@ -176,7 +176,7 @@ private slots: void refresh(); -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) void ntfsJunctionPointsAndSymlinks_data(); void ntfsJunctionPointsAndSymlinks(); void brokenShortcut(); @@ -193,7 +193,7 @@ private slots: void detachingOperations(); -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) void owner(); #endif void group(); @@ -1058,7 +1058,7 @@ void tst_QFileInfo::fileTimes() //In Vista the last-access timestamp is not updated when the file is accessed/touched (by default). //To enable this the HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate //is set to 0, in the test machine. -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) HKEY key; if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\FileSystem", 0, KEY_READ, &key)) { @@ -1085,8 +1085,8 @@ void tst_QFileInfo::fileTimes() void tst_QFileInfo::fileTimes_oldFile() { - // This is not supported on WinCE -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + // This is not supported on WinCE or WinRT +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) // All files are opened in share mode (both read and write). DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; @@ -1329,7 +1329,7 @@ void tst_QFileInfo::refresh() QCOMPARE(info2.size(), info.size()); } -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() { QTest::addColumn<QString>("path"); @@ -1680,7 +1680,7 @@ void tst_QFileInfo::detachingOperations() QVERIFY(!info1.caching()); } -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) #if defined (Q_OS_WIN) BOOL IsUserAdmin() { diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index fda6519d82..b681cec802 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -55,6 +55,7 @@ class tst_QFileSystemWatcher : public QObject public: tst_QFileSystemWatcher(); +#ifndef QT_NO_FILESYSTEMWATCHER private slots: void basicTest_data(); void basicTest(); @@ -83,16 +84,20 @@ private slots: private: QString m_tempDirPattern; +#endif // QT_NO_FILESYSTEMWATCHER }; tst_QFileSystemWatcher::tst_QFileSystemWatcher() { +#ifndef QT_NO_FILESYSTEMWATCHER m_tempDirPattern = QDir::tempPath(); if (!m_tempDirPattern.endsWith(QLatin1Char('/'))) m_tempDirPattern += QLatin1Char('/'); m_tempDirPattern += QStringLiteral("tst_qfilesystemwatcherXXXXXX"); +#endif // QT_NO_FILESYSTEMWATCHER } +#ifndef QT_NO_FILESYSTEMWATCHER void tst_QFileSystemWatcher::basicTest_data() { QTest::addColumn<QString>("backend"); @@ -676,6 +681,7 @@ void tst_QFileSystemWatcher::signalsEmittedAfterFileMoved() QTRY_COMPARE(changedSpy.count(), 10); } +#endif // QT_NO_FILESYSTEMWATCHER QTEST_MAIN(tst_QFileSystemWatcher) #include "tst_qfilesystemwatcher.moc" diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index dc83cf2fc4..b020a50346 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -119,7 +119,7 @@ private slots: #if !defined(Q_OS_WIN) && !defined(QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER) void dontReorderIniKeysNeedlessly(); #endif -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void consistentRegistryStorage(); #endif @@ -274,7 +274,7 @@ void tst_QSettings::init() QSettings::setSystemIniPath(settingsPath("__system__")); QSettings::setUserIniPath(settingsPath("__user__")); -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) QSettings("HKEY_CURRENT_USER\\Software\\software.org", QSettings::NativeFormat).clear(); QSettings("HKEY_LOCAL_MACHINE\\Software\\software.org", QSettings::NativeFormat).clear(); QSettings("HKEY_CURRENT_USER\\Software\\other.software.org", QSettings::NativeFormat).clear(); @@ -1502,7 +1502,7 @@ void tst_QSettings::sync() // Now "some other app" will change other.software.org.ini QString userConfDir = settingsPath("__user__") + QDir::separator(); -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) unlink((userConfDir + "other.software.org.ini").toLatin1()); rename((userConfDir + "software.org.ini").toLatin1(), (userConfDir + "other.software.org.ini").toLatin1()); @@ -3202,7 +3202,7 @@ void tst_QSettings::recursionBug() } } -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) static DWORD readKeyType(HKEY handle, const QString &rSubKey) { diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index 713d0c5c17..a6cc083d9c 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -257,7 +257,7 @@ void tst_QTemporaryDir::nonWritableCurrentDir() void tst_QTemporaryDir::openOnRootDrives() { -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); #endif // If it's possible to create a file in the root directory, it @@ -271,7 +271,7 @@ void tst_QTemporaryDir::openOnRootDrives() QVERIFY(dir.isValid()); } } -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) SetErrorMode(lastErrorMode); #endif } diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index 6eb6f83d2a..5ad798ae1f 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -371,7 +371,7 @@ void tst_QTemporaryFile::resize() void tst_QTemporaryFile::openOnRootDrives() { -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); #endif // If it's possible to create a file in the root directory, it @@ -385,7 +385,7 @@ void tst_QTemporaryFile::openOnRootDrives() QVERIFY(file.open()); } } -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) SetErrorMode(lastErrorMode); #endif } diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro index fe3e4b7e0a..c1b867e6eb 100644 --- a/tests/auto/corelib/kernel/kernel.pro +++ b/tests/auto/corelib/kernel/kernel.pro @@ -34,6 +34,6 @@ SUBDIRS=\ qsharedmemory # This test is only applicable on Windows -!win32*:SUBDIRS -= qwineventnotifier +!win32*|winrt: SUBDIRS -= qwineventnotifier android|qnx: SUBDIRS -= qsharedmemory qsystemsemaphore diff --git a/tests/auto/corelib/kernel/qeventloop/qeventloop.pro b/tests/auto/corelib/kernel/qeventloop/qeventloop.pro index e5bcc31e6a..5593aa2430 100644 --- a/tests/auto/corelib/kernel/qeventloop/qeventloop.pro +++ b/tests/auto/corelib/kernel/qeventloop/qeventloop.pro @@ -4,7 +4,7 @@ TARGET = tst_qeventloop QT = core network testlib core-private SOURCES = $$PWD/tst_qeventloop.cpp -win32:!wince*:LIBS += -luser32 +win32:!wince*:!winrt:LIBS += -luser32 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 contains(QT_CONFIG, glib): DEFINES += HAVE_GLIB diff --git a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro index 23a8e6d23a..d19ec23760 100644 --- a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro +++ b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro @@ -6,11 +6,11 @@ SOURCES = tst_qmetatype.cpp TESTDATA=./typeFlags.bin DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 -win32-msvc*|wince { +win32-msvc*|wince|winrt { # Prevents "fatal error C1128: number of sections exceeded object file format limit". QMAKE_CXXFLAGS += /bigobj # Reduce compile time - win32-msvc2012|wince { + win32-msvc2012|wince|winrt { QMAKE_CXXFLAGS_RELEASE -= -O2 QMAKE_CFLAGS_RELEASE -= -O2 } diff --git a/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp b/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp index 7d041e69cb..0d51f69559 100644 --- a/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp +++ b/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp @@ -52,6 +52,8 @@ #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) #include <windows.h> #define sleep(X) Sleep(X) +#elif defined(Q_OS_WINRT) +#define sleep(X) WaitForSingleObjectEx(GetCurrentThread(), X, FALSE); #endif //on solaris, threads that loop on the release bool variable diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index 5cc0e5bdb4..0e53139414 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -55,6 +55,8 @@ #endif #if defined(Q_OS_WINCE) #include <windows.h> +#elif defined(Q_OS_WINRT) +#include <thread> #elif defined(Q_OS_WIN) #include <process.h> #include <windows.h> @@ -326,6 +328,9 @@ void tst_QThread::isRunning() void tst_QThread::setPriority() { +#if defined(Q_OS_WINRT) + QSKIP("Thread priority is not supported on WinRT"); +#endif Simple_Thread thread; // cannot change the priority, since the thread is not running @@ -460,6 +465,10 @@ void tst_QThread::start() QVERIFY(!thread.isFinished()); QVERIFY(!thread.isRunning()); QMutexLocker locker(&thread.mutex); +#ifdef Q_OS_WINRT + if (priorities[i] != QThread::NormalPriority && priorities[i] != QThread::InheritPriority) + QTest::ignoreMessage(QtWarningMsg, "QThread::start: Failed to set thread priority (not implemented)"); +#endif thread.start(priorities[i]); QVERIFY(thread.isRunning()); QVERIFY(!thread.isFinished()); @@ -472,6 +481,9 @@ void tst_QThread::start() void tst_QThread::terminate() { +#if defined(Q_OS_WINRT) + QSKIP("Terminate is not supported on WinRT"); +#endif Terminate_Thread thread; { QMutexLocker locker(&thread.mutex); @@ -535,6 +547,9 @@ void tst_QThread::finished() void tst_QThread::terminated() { +#if defined(Q_OS_WINRT) + QSKIP("Terminate is not supported on WinRT"); +#endif SignalRecorder recorder; Terminate_Thread thread; connect(&thread, SIGNAL(finished()), &recorder, SLOT(slot()), Qt::DirectConnection); @@ -630,6 +645,8 @@ void noop(void*) { } #if defined Q_OS_UNIX typedef pthread_t ThreadHandle; +#elif defined Q_OS_WINRT + typedef std::thread ThreadHandle; #elif defined Q_OS_WIN typedef HANDLE ThreadHandle; #endif @@ -671,6 +688,8 @@ void NativeThreadWrapper::start(FunctionPointer functionPointer, void *data) #if defined Q_OS_UNIX const int state = pthread_create(&nativeThreadHandle, 0, NativeThreadWrapper::runUnix, this); Q_UNUSED(state); +#elif defined(Q_OS_WINRT) + nativeThreadHandle = std::thread(NativeThreadWrapper::runWin, this); #elif defined(Q_OS_WINCE) nativeThreadHandle = CreateThread(NULL, 0 , (LPTHREAD_START_ROUTINE)NativeThreadWrapper::runWin , this, 0, NULL); #elif defined Q_OS_WIN @@ -690,6 +709,8 @@ void NativeThreadWrapper::join() { #if defined Q_OS_UNIX pthread_join(nativeThreadHandle, 0); +#elif defined Q_OS_WINRT + nativeThreadHandle.join(); #elif defined Q_OS_WIN WaitForSingleObject(nativeThreadHandle, INFINITE); CloseHandle(nativeThreadHandle); @@ -780,6 +801,9 @@ void tst_QThread::adoptedThreadAffinity() void tst_QThread::adoptedThreadSetPriority() { +#if defined(Q_OS_WINRT) + QSKIP("Thread priority is not supported on WinRT"); +#endif NativeThreadWrapper nativeThread; nativeThread.setWaitForStop(); @@ -857,6 +881,9 @@ void tst_QThread::adoptedThreadFinished() nativeThread.join(); QTestEventLoop::instance().enterLoop(5); +#if defined(Q_OS_WINRT) + QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort); +#endif QVERIFY(!QTestEventLoop::instance().timeout()); } @@ -872,6 +899,9 @@ void tst_QThread::adoptedThreadExecFinished() nativeThread.join(); QTestEventLoop::instance().enterLoop(5); +#if defined(Q_OS_WINRT) + QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort); +#endif QVERIFY(!QTestEventLoop::instance().timeout()); } @@ -908,6 +938,9 @@ void tst_QThread::adoptMultipleThreads() } QTestEventLoop::instance().enterLoop(5); +#if defined(Q_OS_WINRT) + QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort); +#endif QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(recorder.activationCount.load(), numThreads); } @@ -950,6 +983,9 @@ void tst_QThread::adoptMultipleThreadsOverlap() } QTestEventLoop::instance().enterLoop(5); +#if defined(Q_OS_WINRT) + QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort); +#endif QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(recorder.activationCount.load(), numThreads); } diff --git a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp index 2072034f5f..c96de29b98 100644 --- a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp +++ b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp @@ -232,7 +232,7 @@ void tst_QThreadStorage::adoptedThreads() const int state = pthread_create(&thread, 0, testAdoptedThreadStorageUnix, &pointers); QCOMPARE(state, 0); pthread_join(thread, 0); -#elif defined Q_OS_WIN +#elif defined Q_OS_WIN && !defined(Q_OS_WINRT) HANDLE thread; #if defined(Q_OS_WINCE) thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)testAdoptedThreadStorageWin, &pointers, 0, NULL); diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp index d8965dee5d..1ee6cacd97 100644 --- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp +++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp @@ -546,6 +546,9 @@ void tst_QCommandLineParser::testHelpOption() void tst_QCommandLineParser::testQuoteEscaping() { +#ifdef QT_NO_PROCESS + QSKIP("This test requires QProcess support"); +#else QCoreApplication app(empty_argc, empty_argv); QProcess process; process.start("testhelper/qcommandlineparser_test_helper", QStringList() << @@ -561,6 +564,7 @@ void tst_QCommandLineParser::testQuoteEscaping() QVERIFY2(output.contains("KEY2=\\\"VALUE2\\\""), qPrintable(output)); QVERIFY2(output.contains("QTBUG-15379=C:\\path\\'file.ext"), qPrintable(output)); QVERIFY2(output.contains("QTBUG-30628=C:\\temp\\'file'.ext"), qPrintable(output)); +#endif // !QT_NO_PROCESS } QTEST_APPLESS_MAIN(tst_QCommandLineParser) diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 0ee40713aa..8c0f32bb74 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -49,6 +49,9 @@ #ifdef Q_OS_WIN # include <windows.h> +# if defined(Q_OS_WINRT) +# define tzset() +# endif #endif class tst_QDateTime : public QObject @@ -175,7 +178,7 @@ void tst_QDateTime::init() { #if defined(Q_OS_WINCE) SetUserDefaultLCID(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); -#elif defined(Q_OS_WIN) +#elif defined(Q_OS_WIN32) SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); #endif } diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index d6dea05755..f11e632b2e 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -133,7 +133,7 @@ public: private slots: void initTestCase(); void cleanupTestCase(); -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void windowsDefaultLocale(); #endif #ifdef Q_OS_MAC @@ -1472,7 +1472,7 @@ void tst_QLocale::macDefaultLocale() } #endif // Q_OS_MAC -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) #include <qt_windows.h> static QString getWinLocaleInfo(LCTYPE type) @@ -1526,7 +1526,7 @@ public: #endif // Q_OS_WIN -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void tst_QLocale::windowsDefaultLocale() { RestoreLocaleHelper systemLocale; diff --git a/tests/auto/gui/image/qpixmap/qpixmap.pro b/tests/auto/gui/image/qpixmap/qpixmap.pro index bdd0c15788..33c301a500 100644 --- a/tests/auto/gui/image/qpixmap/qpixmap.pro +++ b/tests/auto/gui/image/qpixmap/qpixmap.pro @@ -5,7 +5,7 @@ QT += core-private gui-private testlib qtHaveModule(widgets): QT += widgets widgets-private SOURCES += tst_qpixmap.cpp -!wince* { +!wince*:!winrt { win32:LIBS += -lgdi32 -luser32 } diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index cb5d836291..79dc3f311a 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -116,7 +116,7 @@ private slots: void convertFromImageDetach(); void convertFromImageCacheKey(); -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void toWinHBITMAP_data(); void toWinHBITMAP(); void fromWinHBITMAP_data(); @@ -805,7 +805,7 @@ void tst_QPixmap::convertFromImageCacheKey() QCOMPARE(copy.cacheKey(), pix.cacheKey()); } -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) QT_BEGIN_NAMESPACE Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap); @@ -1024,7 +1024,7 @@ void tst_QPixmap::fromWinHICON() #endif // Q_OS_WINCE } -#endif // Q_OS_WIN +#endif // Q_OS_WIN && !Q_OS_WINRT void tst_QPixmap::onlyNullPixmapsOutsideGuiThread() { diff --git a/tests/auto/gui/kernel/qguivariant/test/black.png b/tests/auto/gui/kernel/qguivariant/test/black.png Binary files differnew file mode 100644 index 0000000000..6c94085ed5 --- /dev/null +++ b/tests/auto/gui/kernel/qguivariant/test/black.png diff --git a/tests/auto/gui/kernel/qguivariant/test/black2.png b/tests/auto/gui/kernel/qguivariant/test/black2.png Binary files differnew file mode 100644 index 0000000000..6c94085ed5 --- /dev/null +++ b/tests/auto/gui/kernel/qguivariant/test/black2.png diff --git a/tests/auto/gui/kernel/qguivariant/test/test.pro b/tests/auto/gui/kernel/qguivariant/test/test.pro index e3b4a350ca..c4123797d2 100644 --- a/tests/auto/gui/kernel/qguivariant/test/test.pro +++ b/tests/auto/gui/kernel/qguivariant/test/test.pro @@ -2,6 +2,7 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qguivariant SOURCES += tst_qguivariant.cpp +RESOURCES = tst_qguivariant.qrc INCLUDEPATH += $$PWD/../../../../other/qvariant_common QT += testlib RESOURCES += qguivariant.qrc diff --git a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp index 4b2cce63e5..1220ce3b23 100644 --- a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp +++ b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp @@ -125,6 +125,8 @@ private slots: void implicitConstruction(); void guiVariantAtExit(); + + void iconEquality(); }; void tst_QGuiVariant::constructor_invalid_data() @@ -745,5 +747,32 @@ void tst_QGuiVariant::guiVariantAtExit() QVERIFY(true); } +void tst_QGuiVariant::iconEquality() +{ + QIcon i; + QVariant a = i; + QVariant b = i; + QCOMPARE(a, b); + + i = QIcon(":/black.png"); + a = i; + QVERIFY(a != b); + + b = a; + QCOMPARE(a, b); + + i = QIcon(":/black2.png"); + a = i; + QVERIFY(a != b); + + b = i; + QCOMPARE(a, b); + + // This is a "different" QIcon + // even if the contents are the same + b = QIcon(":/black2.png"); + QVERIFY(a != b); +} + QTEST_MAIN(tst_QGuiVariant) #include "tst_qguivariant.moc" diff --git a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.qrc b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.qrc new file mode 100644 index 0000000000..15cfde5788 --- /dev/null +++ b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/"> +<file>black.png</file> +<file>black2.png</file> +</qresource> +</RCC> diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index dd9202c748..acb921b34a 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -50,6 +50,9 @@ #include <qdatastream.h> #ifdef Q_OS_WIN # include <qt_windows.h> +# if defined(Q_OS_WINRT) +# include <winsock2.h> +# endif #endif class tst_QHostAddress : public QObject diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index e81c7f71db..e3156ceb3f 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -67,7 +67,7 @@ #include <time.h> #include <qlibrary.h> -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) #include <windows.h> #else #include <unistd.h> diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h index f87493205f..69ecbcb019 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h +++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h @@ -55,11 +55,14 @@ #include <QtSql/private/qsqldriver_p.h> #include <QtTest/QtTest> -#if defined (Q_OS_WIN) || defined (Q_OS_WIN32) +#if defined(Q_OS_WIN) # include <qt_windows.h> -# if defined (Q_OS_WINCE) +# if defined(Q_OS_WINCE) || defined(Q_OS_WINRT) # include <winsock2.h> # endif +# if defined(Q_OS_WINRT) && !defined(Q_OS_WINPHONE) +static inline int gethostname(char *name, int len) { qstrcpy(name, "localhost"); return 9; } +# endif #else #include <unistd.h> #endif diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 1a100ce706..9098d5b101 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -1393,6 +1393,9 @@ void tst_QSqlQuery::isNull() QVERIFY( q.next() ); QVERIFY( !q.isNull( 0 ) ); QVERIFY( !q.isNull( 1 ) ); + + // For a non existent field, it should be returning true. + QVERIFY(q.isNull(2)); } /*! TDS specific BIT field test */ diff --git a/tests/auto/testlib/selftests/crashes/tst_crashes.cpp b/tests/auto/testlib/selftests/crashes/tst_crashes.cpp index 067c2a9f4f..3b73d87876 100644 --- a/tests/auto/testlib/selftests/crashes/tst_crashes.cpp +++ b/tests/auto/testlib/selftests/crashes/tst_crashes.cpp @@ -57,7 +57,7 @@ private slots: void tst_Crashes::crash() { -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) //we avoid the error dialogbox to appear on windows SetErrorMode( SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); #endif diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 61a2abc084..816d375b97 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -417,7 +417,14 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi wchar_t nativeHiddenFile[MAX_PATH]; memset(nativeHiddenFile, 0, sizeof(nativeHiddenFile)); hiddenFile.toWCharArray(nativeHiddenFile); +#ifndef Q_OS_WINRT DWORD currentAttributes = ::GetFileAttributes(nativeHiddenFile); +#else // !Q_OS_WINRT + WIN32_FILE_ATTRIBUTE_DATA attributeData; + if (!::GetFileAttributesEx(nativeHiddenFile, GetFileExInfoStandard, &attributeData)) + attributeData.dwFileAttributes = 0xFFFFFFFF; + DWORD currentAttributes = attributeData.dwFileAttributes; +#endif // Q_OS_WINRT if (currentAttributes == 0xFFFFFFFF) { qErrnoWarning("failed to get file attributes: %s", qPrintable(hiddenFile)); return false; diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro b/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro index 0c3b46c5d5..527f62b22d 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro @@ -5,5 +5,5 @@ QT += core-private gui-private SOURCES += tst_qgraphicsitem.cpp DEFINES += QT_NO_CAST_TO_ASCII -win32:!wince*: LIBS += -luser32 +win32:!wince*:!winrt: LIBS += -luser32 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index b45ce88c83..4f25aab32a 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -71,7 +71,7 @@ Q_DECLARE_METATYPE(QPainterPath) #include "../../../qtest-config.h" -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) #include <windows.h> #define Q_CHECK_PAINTEVENTS \ if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \ diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro b/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro index 8d00931ef1..a6022e0d7d 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro @@ -4,7 +4,7 @@ QT += widgets widgets-private testlib QT += core-private gui-private SOURCES += tst_qgraphicsscene.cpp RESOURCES += images.qrc -win32:!wince*: LIBS += -luser32 +win32:!wince*:!winrt: LIBS += -luser32 !wince*:DEFINES += SRCDIR=\\\"$$PWD\\\" DEFINES += QT_NO_CAST_TO_ASCII diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index fe1df6c8f0..b3fba29f81 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -54,7 +54,7 @@ #include "../../../shared/platforminputcontext.h" #include <private/qinputmethod_p.h> -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) #include <windows.h> #define Q_CHECK_PAINTEVENTS \ if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \ diff --git a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro index cb935fd2fd..313cadd6a1 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro +++ b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro @@ -3,4 +3,4 @@ TARGET = tst_qitemdelegate QT += widgets testlib SOURCES += tst_qitemdelegate.cpp -win32:!wince*: LIBS += -luser32 +win32:!wince*:!winrt: LIBS += -luser32 diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index 439725b257..addb226101 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -66,7 +66,7 @@ Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint) -#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) #include <windows.h> #define Q_CHECK_PAINTEVENTS \ if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \ diff --git a/tests/auto/widgets/itemviews/qlistview/qlistview.pro b/tests/auto/widgets/itemviews/qlistview/qlistview.pro index 413304bdcf..1ea8beb8df 100644 --- a/tests/auto/widgets/itemviews/qlistview/qlistview.pro +++ b/tests/auto/widgets/itemviews/qlistview/qlistview.pro @@ -2,4 +2,4 @@ CONFIG += testcase TARGET = tst_qlistview QT += widgets gui-private widgets-private core-private testlib SOURCES += tst_qlistview.cpp -win32:!wince*: LIBS += -luser32 +win32:!wince*:!winrt: LIBS += -luser32 diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 268276bd4a..9f5484983d 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -1484,7 +1484,7 @@ void tst_QListView::wordWrap() QTRY_COMPARE(lv.verticalScrollBar()->isVisible(), true); } -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) class SetCurrentIndexAfterAppendRowCrashDialog : public QDialog { Q_OBJECT @@ -1525,7 +1525,7 @@ private: }; #endif -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && WINVER >= 0x0500 +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) && WINVER >= 0x0500 // This test only makes sense on windows 2000 and higher. void tst_QListView::setCurrentIndexAfterAppendRowCrash() { diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index 83ba1ddcda..d2625c400a 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -1758,9 +1758,7 @@ void tst_QTreeWidget::setData() QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item); QCOMPARE(qvariant_cast<int>(args.at(1)), j); item->setIcon(j, icon); - // #### shouldn't cause dataChanged() - QCOMPARE(itemChangedSpy.count(), 1); - itemChangedSpy.clear(); + QCOMPARE(itemChangedSpy.count(), 0); QString toolTip = QString("toolTip %0").arg(i); item->setToolTip(j, toolTip); diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index 8d75298673..f2fa1f87fa 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -178,6 +178,8 @@ private slots: void globalStaticObjectDestruction(); // run this last void abortQuitOnShow(); + + void settableStyleHints(); // Needs to run last as it changes style hints. }; class EventSpy : public QObject @@ -1891,7 +1893,7 @@ void tst_QApplication::windowsCommandLine_data() void tst_QApplication::windowsCommandLine() { -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) QFETCH(QString, args); QFETCH(QString, expected); @@ -2247,6 +2249,22 @@ void tst_QApplication::abortQuitOnShow() QCOMPARE(app.exec(), 1); } +void tst_QApplication::settableStyleHints() +{ + int argc = 0; + QApplication app(argc, 0); + QApplication::setCursorFlashTime(437); + QCOMPARE(QApplication::cursorFlashTime(), 437); + QApplication::setDoubleClickInterval(128); + QCOMPARE(QApplication::doubleClickInterval(), 128); + QApplication::setStartDragDistance(122000); + QCOMPARE(QApplication::startDragDistance(), 122000); + QApplication::setStartDragTime(834); + QCOMPARE(QApplication::startDragTime(), 834); + QApplication::setKeyboardInputInterval(309); + QCOMPARE(QApplication::keyboardInputInterval(), 309); +} + /* This test is meant to ensure that certain objects (public & commonly used) can safely be used in a Q_GLOBAL_STATIC such that their destructors are diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.pro b/tests/auto/widgets/kernel/qwidget/qwidget.pro index a4fcde8a34..3eedfa1d3a 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.pro +++ b/tests/auto/widgets/kernel/qwidget/qwidget.pro @@ -20,7 +20,7 @@ x11 { LIBS += $$QMAKE_LIBS_X11 } -!wince*:win32: LIBS += -luser32 -lgdi32 +!wince*:win32:!winrt: LIBS += -luser32 -lgdi32 mac:CONFIG+=insignificant_test # QTBUG-25300, QTBUG-23695 linux-*:system(". /etc/lsb-release && [ $DISTRIB_CODENAME = oneiric ]"):DEFINES+=UBUNTU_ONEIRIC # QTBUG-30566
\ No newline at end of file diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 227f61b0a3..2da8df6116 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -116,11 +116,13 @@ static bool qt_wince_is_platform(const QString &platformString) { } static inline bool qt_wince_is_smartphone() { return qt_wince_is_platform(QString::fromLatin1("Smartphone")); } # endif // Q_OS_WINCE_WM -# else // Q_OS_WINCE +# elif !defined(Q_OS_WINRT) // Q_OS_WINCE # define Q_CHECK_PAINTEVENTS \ if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \ QSKIP("desktop is not visible, this test would fail"); -# endif // !Q_OS_WINCE +# else // !Q_OS_WINCE && !Q_OS_WINRT +# define Q_CHECK_PAINTEVENTS +# endif // Q_OS_WINRT #else // Q_OS_WIN # define Q_CHECK_PAINTEVENTS #endif // else Q_OS_WIN @@ -285,7 +287,7 @@ private slots: void subtractOpaqueSiblings(); #endif -#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) void setGeometry_win(); #endif @@ -355,7 +357,7 @@ private slots: void quitOnCloseAttribute(); void moveRect(); -#if defined (Q_OS_WIN) +#if defined (Q_OS_WIN) && !defined(Q_OS_WINRT) void gdiPainting(); void paintOnScreenPossible(); #endif @@ -572,7 +574,7 @@ void tst_QWidget::getSetCheck() QCOMPARE(true, obj1.autoFillBackground()); var1.reset(); -#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) obj1.setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint); const HWND handle = reinterpret_cast<HWND>(obj1.winId()); // explicitly create window handle QVERIFY(GetWindowLong(handle, GWL_STYLE) & WS_POPUP); @@ -1257,7 +1259,7 @@ void tst_QWidget::visible_setWindowOpacity() testWidget->hide(); QVERIFY( !testWidget->isVisible() ); testWidget->setWindowOpacity(0.5); -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) QVERIFY(!::IsWindowVisible(winHandleOf(testWidget))); #endif testWidget->setWindowOpacity(1.0); @@ -3597,7 +3599,7 @@ void tst_QWidget::optimizedResize_topLevel() topLevel.partial = false; topLevel.paintedRegion = QRegion(); -#ifndef Q_OS_WIN +#if !defined(Q_OS_WIN32) && !defined(Q_OS_WINCE) topLevel.resize(topLevel.size() + QSize(10, 10)); #else // Static contents does not work when programmatically resizing @@ -4529,7 +4531,7 @@ void tst_QWidget::setWindowGeometry() } } -#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) void tst_QWidget::setGeometry_win() { QWidget widget; @@ -4548,7 +4550,7 @@ void tst_QWidget::setGeometry_win() QEXPECT_FAIL("", "QTBUG-26424", Continue); QVERIFY(rt.top <= 0); } -#endif // defined (Q_OS_WIN) && !defined(Q_OS_WINCE) +#endif // defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) // Since X11 WindowManager operation are all async, and we have no way to know if the window // manager has finished playing with the window geometry, this test can't be reliable on X11. @@ -8047,7 +8049,7 @@ void tst_QWidget::moveRect() child.move(10, 10); // Don't crash. } -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) class GDIWidget : public QDialog { Q_OBJECT @@ -8114,7 +8116,7 @@ void tst_QWidget::paintOnScreenPossible() w2.setAttribute(Qt::WA_PaintOnScreen); QVERIFY(w2.testAttribute(Qt::WA_PaintOnScreen)); } -#endif // Q_OS_WIN +#endif // Q_OS_WIN && !Q_OS_WINRT void tst_QWidget::reparentStaticWidget() { diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp index bfffa357a8..ded3e55283 100644 --- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp @@ -346,7 +346,7 @@ void tst_QDateTimeEdit::cleanupTestCase() void tst_QDateTimeEdit::init() { QLocale::setDefault(QLocale(QLocale::C)); -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); #endif testWidget->setDisplayFormat("dd/MM/yyyy"); // Nice default to have diff --git a/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro b/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro index 72956a6867..c367959cbc 100644 --- a/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro +++ b/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro @@ -8,4 +8,4 @@ INCLUDEPATH += ../ HEADERS += SOURCES += tst_qtabwidget.cpp -win32:!wince*:LIBS += -luser32 +win32:!wince*:!winrt:LIBS += -luser32 diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp index fa518e6afd..e55438f3d3 100644 --- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp @@ -48,7 +48,7 @@ #include <qlabel.h> #include <QtWidgets/qboxlayout.h> -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) # include <qt_windows.h> #define Q_CHECK_PAINTEVENTS \ if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \ diff --git a/tests/baselineserver/shared/baselineprotocol.cpp b/tests/baselineserver/shared/baselineprotocol.cpp index cbe3ec8798..f6190f20c4 100644 --- a/tests/baselineserver/shared/baselineprotocol.cpp +++ b/tests/baselineserver/shared/baselineprotocol.cpp @@ -76,7 +76,11 @@ const QString PI_PulseTestrBranch(QLS("PulseTestrBranch")); void BaselineProtocol::sysSleep(int ms) { #if defined(Q_OS_WIN) +# ifndef Q_OS_WINRT Sleep(DWORD(ms)); +# else + WaitForSingleObjectEx(GetCurrentThread(), ms, false); +# endif #else struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; nanosleep(&ts, NULL); @@ -116,6 +120,7 @@ PlatformInfo PlatformInfo::localHostInfo() pi.insert(PI_OSName, QLS("Other")); #endif +#ifndef QT_NO_PROCESS QProcess git; QString cmd; QStringList args; @@ -151,6 +156,7 @@ PlatformInfo PlatformInfo::localHostInfo() pi.insert(PI_PulseGitBranch, QString::fromLatin1(gb)); } } +#endif // !QT_NO_PROCESS return pi; } diff --git a/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp b/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp index 49672a90bf..b2380b0e58 100644 --- a/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp +++ b/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp @@ -176,7 +176,12 @@ private slots: wcscat(appendedPath, L"\\*"); WIN32_FIND_DATA fd; +#ifndef Q_OS_WINRT HANDLE hSearch = FindFirstFileW(appendedPath, &fd); +#else + HANDLE hSearch = FindFirstFileEx(appendedPath, FindExInfoStandard, &fd, + FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH); +#endif QVERIFY(hSearch != INVALID_HANDLE_VALUE); QBENCHMARK { diff --git a/tests/benchmarks/corelib/io/qdiriterator/main.cpp b/tests/benchmarks/corelib/io/qdiriterator/main.cpp index 5188658bdb..691e822379 100644 --- a/tests/benchmarks/corelib/io/qdiriterator/main.cpp +++ b/tests/benchmarks/corelib/io/qdiriterator/main.cpp @@ -106,7 +106,12 @@ static int posix_helper(const wchar_t *dirpath) wchar_t appendedPath[MAX_PATH]; wcscpy(appendedPath, dirpath); wcscat(appendedPath, L"\\*"); +#ifndef Q_OS_WINRT hSearch = FindFirstFile(appendedPath, &fd); +#else + hSearch = FindFirstFileEx(appendedPath, FindExInfoStandard, &fd, + FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH); +#endif appendedPath[origDirPathLength] = 0; if (hSearch == INVALID_HANDLE_VALUE) { diff --git a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp index bb4a921fc7..82bca1541d 100644 --- a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp +++ b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp @@ -230,7 +230,12 @@ void QFileSystemIteratorPrivate::pushSubDirectory(const QByteArray &path) wchar_t szSearchPath[MAX_PATH]; QString::fromLatin1(path).toWCharArray(szSearchPath); wcscat(szSearchPath, L"\\*"); +#ifndef Q_OS_WINRT HANDLE dir = FindFirstFile(szSearchPath, &m_fileSearchResult); +#else + HANDLE dir = FindFirstFileEx(szSearchPath, FindExInfoStandard, &m_fileSearchResult, + FindExSearchLimitToDirectories, NULL, FIND_FIRST_EX_LARGE_FETCH); +#endif m_bFirstSearchResult = true; #else DIR *dir = ::opendir(path.constData()); diff --git a/tests/benchmarks/corelib/io/qfile/main.cpp b/tests/benchmarks/corelib/io/qfile/main.cpp index 0beffebfb7..e0ae29fbee 100644 --- a/tests/benchmarks/corelib/io/qfile/main.cpp +++ b/tests/benchmarks/corelib/io/qfile/main.cpp @@ -310,7 +310,11 @@ void tst_qfile::readBigFile() // ensure we don't account string conversion wchar_t* cfilename = (wchar_t*)filename.utf16(); +#ifndef Q_OS_WINRT hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); +#else + hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0); +#endif Q_ASSERT(hndl); wchar_t* nativeBuffer = new wchar_t[BUFSIZE]; DWORD numberOfBytesRead; @@ -319,7 +323,12 @@ void tst_qfile::readBigFile() do { ReadFile(hndl, nativeBuffer, blockSize, &numberOfBytesRead, NULL); } while(numberOfBytesRead != 0); +#ifndef Q_OS_WINRT SetFilePointer(hndl, 0, NULL, FILE_BEGIN); +#else + LARGE_INTEGER offset = { 0 }; + SetFilePointerEx(hndl, offset, NULL, FILE_BEGIN); +#endif } delete[] nativeBuffer; CloseHandle(hndl); @@ -400,11 +409,20 @@ void tst_qfile::seek() // ensure we don't account string conversion wchar_t* cfilename = (wchar_t*)filename.utf16(); +#ifndef Q_OS_WINRT hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); +#else + hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0); +#endif Q_ASSERT(hndl); QBENCHMARK { i=(i+1)%sp_size; +#ifndef Q_OS_WINRT SetFilePointer(hndl, seekpos[i], NULL, 0); +#else + LARGE_INTEGER offset = { seekpos[i] }; + SetFilePointerEx(hndl, offset, NULL, FILE_BEGIN); +#endif } CloseHandle(hndl); #else @@ -489,7 +507,11 @@ void tst_qfile::open() wchar_t* cfilename = (wchar_t*)filename.utf16(); QBENCHMARK { +#ifndef Q_OS_WINRT hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); +#else + hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0); +#endif Q_ASSERT(hndl); CloseHandle(hndl); } @@ -698,7 +720,11 @@ void tst_qfile::readSmallFiles() // ensure we don't account string conversion wchar_t* cfilename = (wchar_t*)filename.utf16(); +#ifndef Q_OS_WINRT hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); +#else + hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0); +#endif Q_ASSERT(hndl); wchar_t* nativeBuffer = new wchar_t[BUFSIZE]; DWORD numberOfBytesRead; diff --git a/tests/benchmarks/corelib/io/qfileinfo/main.cpp b/tests/benchmarks/corelib/io/qfileinfo/main.cpp index 594e5b7478..de1aaea177 100644 --- a/tests/benchmarks/corelib/io/qfileinfo/main.cpp +++ b/tests/benchmarks/corelib/io/qfileinfo/main.cpp @@ -54,7 +54,7 @@ class qfileinfo : public QObject private slots: void existsTemporary(); void existsStatic(); -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) void symLinkTargetPerformanceLNK(); void symLinkTargetPerformanceMounpoint(); #endif @@ -84,7 +84,7 @@ void qfileinfo::existsStatic() QBENCHMARK { QFileInfo::exists(appPath); } } -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) void qfileinfo::symLinkTargetPerformanceLNK() { QVERIFY(QFile::link("file","link.lnk")); diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp index a7480e6afe..37fa571f8c 100644 --- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp @@ -93,7 +93,11 @@ void NativeMutexUnlock(NativeMutexType *mutex) typedef CRITICAL_SECTION NativeMutexType; void NativeMutexInitialize(NativeMutexType *mutex) { +#ifndef Q_OS_WINRT InitializeCriticalSection(mutex); +#else + InitializeCriticalSectionEx(mutex, 0, 0); +#endif } void NativeMutexDestroy(NativeMutexType *mutex) { diff --git a/tests/shared/filesystem.h b/tests/shared/filesystem.h index 7aa72cc28e..a68130a324 100644 --- a/tests/shared/filesystem.h +++ b/tests/shared/filesystem.h @@ -92,7 +92,7 @@ public: return file.isNull() ? qint64(-1) : file->write(relativeFileName.toUtf8()); } -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) static void createNtfsJunction(QString target, QString linkName) { typedef struct { diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index c3382a5e0a..b4162b3f0f 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1597,8 +1597,8 @@ void Configure::applySpecSpecifics() dictionary[ "LIBPNG" ] = "qt"; dictionary[ "FREETYPE" ] = "yes"; dictionary[ "ACCESSIBILITY" ] = "no"; - dictionary[ "OPENGL" ] = "no"; - dictionary[ "OPENGL_ES_2" ] = "no"; + dictionary[ "OPENGL" ] = "yes"; + dictionary[ "OPENGL_ES_2" ] = "yes"; dictionary[ "OPENVG" ] = "no"; dictionary[ "OPENSSL" ] = "auto"; dictionary[ "DBUS" ] = "no"; @@ -1607,7 +1607,7 @@ void Configure::applySpecSpecifics() dictionary[ "ICU" ] = "qt"; dictionary[ "CE_CRT" ] = "yes"; dictionary[ "LARGE_FILE" ] = "no"; - dictionary[ "ANGLE" ] = "no"; + dictionary[ "ANGLE" ] = "d3d11"; if (dictionary.value("XQMAKESPEC").startsWith("winphone")) dictionary[ "SQL_SQLITE" ] = "no"; } else if (dictionary.value("XQMAKESPEC").startsWith("wince")) { |