summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-08-17 19:55:41 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-08-17 19:55:41 +0200
commit5a039bf53e88a727cc52bfedb21796ebfade01a1 (patch)
treeabce106bf1cb1042dcacd249152a11343caa0313
parentdbcf5730ac2d4f61f872e50126d3ce73e3f6031e (diff)
parent89302b8b88b2bfa9581bb15c1caa052cb6d76988 (diff)
Merge dev into 5.6
-rwxr-xr-xconfigure3
-rw-r--r--examples/widgets/mainwindows/application/mainwindow.cpp5
-rw-r--r--examples/widgets/mainwindows/sdi/mainwindow.cpp4
-rwxr-xr-x[-rw-r--r--]src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp1
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp46
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp21
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp21
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp30
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h7
-rw-r--r--src/3rdparty/forkfd/forkfd.c64
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java42
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java5
-rw-r--r--src/angle/patches/0008-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch361
-rw-r--r--src/corelib/global/qglobal.h3
-rw-r--r--src/corelib/io/qprocess.cpp10
-rw-r--r--src/corelib/io/qstandardpaths.cpp2
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp6
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp52
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp108
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt_p.h4
-rw-r--r--src/corelib/thread/qgenericatomic.h81
-rw-r--r--src/corelib/tools/qhash.cpp4
-rw-r--r--src/corelib/tools/qlist.cpp2
-rw-r--r--src/corelib/tools/qmap.cpp4
-rw-r--r--src/gui/kernel/qguiapplication.cpp1
-rw-r--r--src/gui/kernel/qplatformwindow.cpp8
-rw-r--r--src/gui/kernel/qplatformwindow.h1
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp17
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h4
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h5
-rw-r--r--src/gui/painting/qbackingstore.cpp3
-rw-r--r--src/gui/painting/qblendfunctions.cpp187
-rw-r--r--src/gui/painting/qdrawhelper.cpp67
-rw-r--r--src/gui/painting/qdrawhelper_p.h29
-rw-r--r--src/gui/painting/qrgba64.h117
-rw-r--r--src/gui/text/qfontengine_ft.cpp31
-rw-r--r--src/gui/text/qfontengine_ft_p.h3
-rw-r--r--src/gui/text/qtextengine.cpp19
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h2
-rw-r--r--src/network/socket/qabstractsocket.cpp4
-rw-r--r--src/network/socket/qabstractsocket.h2
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp22
-rw-r--r--src/platformsupport/fontdatabases/mac/coretext.pri7
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm140
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h7
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp10
-rw-r--r--src/plugins/platforms/android/androidjniinput.h2
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp4
-rw-r--r--src/plugins/platforms/cocoa/main.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h12
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm34
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.cpp23
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp133
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.h22
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.cpp131
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.h29
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp173
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.h43
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp312
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h33
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp160
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h8
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.cpp34
-rw-r--r--src/tools/qdoc/codeparser.h1
-rw-r--r--src/tools/qdoc/cppcodemarker.cpp8
-rw-r--r--src/tools/qdoc/cppcodeparser.cpp123
-rw-r--r--src/tools/qdoc/cppcodeparser.h16
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc9
-rw-r--r--src/tools/qdoc/generator.cpp18
-rw-r--r--src/tools/qdoc/node.cpp101
-rw-r--r--src/tools/qdoc/node.h26
-rw-r--r--src/tools/qdoc/qdocdatabase.cpp53
-rw-r--r--src/tools/qdoc/qdocdatabase.h11
-rw-r--r--src/tools/qdoc/qdocindexfiles.cpp2
-rw-r--r--src/tools/qdoc/qmlvisitor.cpp4
-rw-r--r--src/tools/qdoc/tokenizer.cpp1
-rw-r--r--src/tools/qdoc/tree.cpp17
-rw-r--r--src/tools/qdoc/tree.h6
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp51
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp47
-rw-r--r--src/widgets/widgets/qdockarealayout_p.h1
-rw-r--r--src/widgets/widgets/qmainwindow.cpp29
-rw-r--r--src/widgets/widgets/qmainwindow.h3
-rw-r--r--src/winmain/qtmain_winrt.cpp263
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp20
-rw-r--r--tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp2
-rw-r--r--tests/auto/dbus/qdbustype/tst_qdbustype.cpp4
-rw-r--r--tests/auto/gui/painting/qcolor/tst_qcolor.cpp19
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp4
-rw-r--r--tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp16
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp64
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp93
-rw-r--r--tests/benchmarks/sql/kernel/qsqlquery/main.cpp40
95 files changed, 2408 insertions, 1387 deletions
diff --git a/configure b/configure
index 9c207bbbda..8540659acc 100755
--- a/configure
+++ b/configure
@@ -3636,9 +3636,6 @@ if [ -z "$QT_INSTALL_PREFIX" ]; then
else
QT_INSTALL_PREFIX="/usr/local/Qt-${QT_VERSION}" # the default install prefix is /usr/local/Qt-$QT_VERSION
fi
- HAVE_INSTALL_PATH=false
-else
- HAVE_INSTALL_PATH=true
fi
QT_INSTALL_PREFIX=`makeabs "$QT_INSTALL_PREFIX"`
diff --git a/examples/widgets/mainwindows/application/mainwindow.cpp b/examples/widgets/mainwindows/application/mainwindow.cpp
index 7a93a0cd22..86dfae166f 100644
--- a/examples/widgets/mainwindows/application/mainwindow.cpp
+++ b/examples/widgets/mainwindows/application/mainwindow.cpp
@@ -196,6 +196,7 @@ void MainWindow::createActions()
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
QToolBar *editToolBar = addToolBar(tr("Edit"));
//!
+#ifndef QT_NO_CLIPBOARD
const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png"));
QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this);
//! [21]
@@ -226,6 +227,8 @@ void MainWindow::createActions()
menuBar()->addSeparator();
+#endif // !QT_NO_CLIPBOARD
+
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
aboutAct->setStatusTip(tr("Show the application's About box"));
@@ -237,11 +240,13 @@ void MainWindow::createActions()
//! [22]
//! [23]
+#ifndef QT_NO_CLIPBOARD
cutAct->setEnabled(false);
//! [23] //! [24]
copyAct->setEnabled(false);
connect(textEdit, &QPlainTextEdit::copyAvailable, cutAct, &QAction::setEnabled);
connect(textEdit, &QPlainTextEdit::copyAvailable, copyAct, &QAction::setEnabled);
+#endif // !QT_NO_CLIPBOARD
}
//! [24]
diff --git a/examples/widgets/mainwindows/sdi/mainwindow.cpp b/examples/widgets/mainwindows/sdi/mainwindow.cpp
index 29618f9ac2..f59172f172 100644
--- a/examples/widgets/mainwindows/sdi/mainwindow.cpp
+++ b/examples/widgets/mainwindows/sdi/mainwindow.cpp
@@ -224,6 +224,7 @@ void MainWindow::createActions()
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
QToolBar *editToolBar = addToolBar(tr("Edit"));
+#ifndef QT_NO_CLIPBOARD
const QIcon cutIcon = QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png"));
QAction *cutAct = new QAction(cutIcon, tr("Cu&t"), this);
cutAct->setShortcuts(QKeySequence::Cut);
@@ -252,6 +253,7 @@ void MainWindow::createActions()
editToolBar->addAction(pasteAct);
menuBar()->addSeparator();
+#endif // !QT_NO_CLIPBOARD
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
@@ -260,10 +262,12 @@ void MainWindow::createActions()
QAction *aboutQtAct = helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
+#ifndef QT_NO_CLIPBOARD
cutAct->setEnabled(false);
copyAct->setEnabled(false);
connect(textEdit, &QTextEdit::copyAvailable, cutAct, &QAction::setEnabled);
connect(textEdit, &QTextEdit::copyAvailable, copyAct, &QAction::setEnabled);
+#endif // !QT_NO_CLIPBOARD
}
void MainWindow::createStatusBar()
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
index 4a87488014..84515f4c6c 100644..100755
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
@@ -203,6 +203,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
if (width == 0 || height == 0)
{
+ checkForOutOfDateSwapChain();
return egl::Error(EGL_SUCCESS);
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
index dc539cf66e..0af2cf12c6 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
@@ -154,14 +154,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- const int textureLength = std::max(backbufferWidth, backbufferHeight);
- offscreenTextureDesc.Width = textureLength;
- offscreenTextureDesc.Height = textureLength;
-#else
offscreenTextureDesc.Width = backbufferWidth;
offscreenTextureDesc.Height = backbufferHeight;
-#endif
offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
offscreenTextureDesc.MipLevels = 1;
offscreenTextureDesc.ArraySize = 1;
@@ -241,14 +235,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
if (mDepthBufferFormat != GL_NONE)
{
D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- const int textureLength = std::max(backbufferWidth, backbufferHeight);
- depthStencilTextureDesc.Width = textureLength;
- depthStencilTextureDesc.Height = textureLength;
-#else
depthStencilTextureDesc.Width = backbufferWidth;
depthStencilTextureDesc.Height = backbufferHeight;
-#endif
depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
depthStencilTextureDesc.MipLevels = 1;
depthStencilTextureDesc.ArraySize = 1;
@@ -349,7 +337,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
return EGL_SUCCESS;
}
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
// Can only call resize if we have already created our swap buffer and resources
ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
@@ -392,12 +379,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
}
return resetOffscreenTexture(backbufferWidth, backbufferHeight);
-#else
- // Do nothing on Windows Phone apart from updating the internal buffer/width height
- mWidth = backbufferWidth;
- mHeight = backbufferHeight;
- return EGL_SUCCESS;
-#endif
}
EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
@@ -552,27 +533,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- // Create a quad in homogeneous coordinates
- float x1 = -1.0f;
- float y1 = -1.0f;
- float x2 = 1.0f;
- float y2 = 1.0f;
-
- const float dim = std::max(mWidth, mHeight);
- float u1 = 0;
- float v1 = 0;
- float u2 = float(width) / dim;
- float v2 = float(height) / dim;
-
- const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags();
- const bool rotateL = flags == NativeWindow::RotateLeft;
- const bool rotateR = flags == NativeWindow::RotateRight;
- d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
- d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
- d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1);
- d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2);
-#else
// Create a quad in homogeneous coordinates
float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
@@ -588,7 +548,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
-#endif
deviceContext->Unmap(mQuadVB, 0);
@@ -618,13 +577,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- viewport.Width = (rotateL || rotateR) ? height : width;
- viewport.Height = (rotateL || rotateR) ? width : height;
-#else
viewport.Width = mWidth;
viewport.Height = mHeight;
-#endif
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
index fa9a69c5a1..f45a077d97 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
@@ -191,25 +191,4 @@ HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWind
return result;
}
-
-static float GetLogicalDpi()
-{
- ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
- float dpi = 96.0f;
-
- if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
- {
- if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
- {
- return dpi;
- }
- }
- return dpi;
-}
-
-long ConvertDipsToPixels(float dips)
-{
- static const float dipsPerInch = 96.0f;
- return lround((dips * GetLogicalDpi() / dipsPerInch));
-}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
index 59df9d5a6c..87cdfe6f22 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
@@ -19,7 +19,6 @@ typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CD
namespace rx
{
-long ConvertDipsToPixels(float dips);
class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
{
@@ -64,8 +63,7 @@ class CoreWindowSizeChangedHandler :
ABI::Windows::Foundation::Size windowSize;
if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize)))
{
- SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) };
- host->setNewClientSize(windowSizeInPixels);
+ host->setNewClientSize(windowSize);
}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
index 2bf48c5d94..e83f47929f 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
@@ -288,4 +288,25 @@ HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Coll
return result;
}
+
+static float GetLogicalDpi()
+{
+ ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
+ float dpi = 96.0f;
+
+ if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
+ {
+ if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
+ {
+ return dpi;
+ }
+ }
+ return dpi;
+}
+
+long ConvertDipsToPixels(float dips)
+{
+ static const float dipsPerInch = 96.0f;
+ return lround((dips * GetLogicalDpi() / dipsPerInch));
+}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
index 575bdf8a58..f0534077ae 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
@@ -26,6 +26,8 @@ using namespace ABI::Windows::Foundation::Collections;
namespace rx
{
+long ConvertDipsToPixels(float dips);
+
class InspectableNativeWindow
{
public:
@@ -45,7 +47,7 @@ class InspectableNativeWindow
virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
virtual bool registerForSizeChangeEvents() = 0;
virtual void unregisterForSizeChangeEvents() = 0;
- virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
+ virtual HRESULT scaleSwapChain(const Size& newSize) { return S_OK; }
bool getClientRect(RECT *rect)
{
@@ -59,11 +61,11 @@ class InspectableNativeWindow
return true;
}
- void setNewClientSize(const SIZE &newSize)
+ void setNewClientSize(const Size &newSize)
{
- if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
+ if (mSupportsSwapChainResize)
{
- mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
+ mNewClientRect = { 0, 0, ConvertDipsToPixels(newSize.Width), ConvertDipsToPixels(newSize.Height) };
mClientRectChanged = true;
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
index 53899dbb30..0b48b54334 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
@@ -66,7 +66,7 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert
}
else
{
- result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect);
+ result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect, &mRequiresSwapChainScaling);
}
}
@@ -139,7 +139,6 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
ComPtr<IDXGISwapChain1> newSwapChain;
ComPtr<ISwapChainPanelNative> swapChainPanelNative;
- RECT currentPanelSize = {};
HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
@@ -167,13 +166,13 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
// first reading the current size of the swapchain panel, then scaling
if (SUCCEEDED(result) && mRequiresSwapChainScaling)
{
- result = GetSwapChainPanelSize(mSwapChainPanel, &currentPanelSize);
- }
+ ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
+ result = mSwapChainPanel.As(&uiElement);
+ ASSERT(SUCCEEDED(result));
- // Scale the swapchain to fit inside the contents of the panel.
- if (SUCCEEDED(result) && mRequiresSwapChainScaling)
- {
- SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom };
+ Size currentSize;
+ result = uiElement->get_RenderSize(&currentSize);
+ ASSERT(SUCCEEDED(result));
result = scaleSwapChain(currentSize);
}
@@ -190,9 +189,9 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
return result;
}
-HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
+HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &newSize)
{
- ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom };
+ ABI::Windows::Foundation::Size renderScale = { newSize.Width / mNewClientRect.right, newSize.Height / mNewClientRect.bottom };
// Setup a scale matrix for the swap chain
DXGI_MATRIX_3X2_F scaleMatrix = {};
scaleMatrix._11 = renderScale.Width;
@@ -208,7 +207,7 @@ HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
return result;
}
-HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize)
+HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive)
{
ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
ABI::Windows::Foundation::Size renderSize = { 0, 0 };
@@ -220,7 +219,14 @@ HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISw
if (SUCCEEDED(result))
{
- *windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) };
+ long width = ConvertDipsToPixels(renderSize.Width);
+ long height = ConvertDipsToPixels(renderSize.Height);
+ *windowSize = { 0, 0, width, height };
+
+ if (scalingActive)
+ {
+ *scalingActive = width != renderSize.Width || height != renderSize.Height;
+ }
}
return result;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
index caf327d913..5debd2fd0b 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
@@ -22,7 +22,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e
bool registerForSizeChangeEvents();
void unregisterForSizeChangeEvents();
HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
- HRESULT scaleSwapChain(const SIZE &newSize);
+ HRESULT scaleSwapChain(const Size &newSize) override;
private:
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
@@ -62,8 +62,7 @@ class SwapChainPanelSizeChangedHandler :
HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
if (SUCCEEDED(result))
{
- SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) };
- host->setNewClientSize(windowSize);
+ host->setNewClientSize(newSize);
}
}
@@ -74,6 +73,6 @@ class SwapChainPanelSizeChangedHandler :
std::weak_ptr<InspectableNativeWindow> mHost;
};
-HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize);
+HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive = nullptr);
}
#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c
index e942db2717..51223aef1f 100644
--- a/src/3rdparty/forkfd/forkfd.c
+++ b/src/3rdparty/forkfd/forkfd.c
@@ -54,6 +54,9 @@
# define HAVE_PIPE2 1
# endif
#endif
+#if defined(__FreeBSD__) && __FreeBSD__ >= 9
+# include <sys/procdesc.h>
+#endif
#if _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500
# define HAVE_WAITID 1
@@ -506,6 +509,46 @@ static int create_pipe(int filedes[], int flags)
return ret;
}
+#if defined(FORKFD_NO_SPAWNFD) && defined(__FreeBSD__) && __FreeBSD__ >= 9
+# if __FreeBSD__ == 9
+/* PROCDESC is an optional feature in the kernel and wasn't enabled
+ * by default on FreeBSD 9. So we need to check for it at runtime. */
+static ffd_atomic_int system_has_forkfd = FFD_ATOMIC_INIT(1);
+# else
+/* On FreeBSD 10, PROCDESC was enabled by default. On v11, it's not an option
+ * anymore and can't be disabled. */
+static const int system_has_forkfd = 1;
+# endif
+
+static int system_forkfd(int flags, pid_t *ppid)
+{
+ int ret;
+ pid_t pid;
+ pid = pdfork(&ret, PD_DAEMON);
+ if (__builtin_expect(pid == -1, 0)) {
+# if __FreeBSD__ == 9
+ if (errno == ENOSYS) {
+ /* PROCDESC wasn't compiled into the kernel: don't try it again. */
+ ffd_atomic_store(&system_has_forkfd, 0, FFD_ATOMIC_RELAXED);
+ }
+# endif
+ return -1;
+ }
+ if (pid == 0) {
+ /* child process */
+ return FFD_CHILD_PROCESS;
+ }
+
+ /* parent process */
+ if (flags & FFD_CLOEXEC)
+ fcntl(ret, F_SETFD, FD_CLOEXEC);
+ if (flags & FFD_NONBLOCK)
+ fcntl(ret, F_SETFL, fcntl(ret, F_GETFL) | O_NONBLOCK);
+ if (ppid)
+ *ppid = pid;
+ return ret;
+}
+#else
static const int system_has_forkfd = 0;
static int system_forkfd(int flags, pid_t *ppid)
{
@@ -513,6 +556,7 @@ static int system_forkfd(int flags, pid_t *ppid)
(void)ppid;
return -1;
}
+#endif
#ifndef FORKFD_NO_FORKFD
/**
@@ -748,6 +792,26 @@ int forkfd_wait(int ffd, forkfd_info *info, struct rusage *rusage)
struct pipe_payload payload;
int ret;
+ if (system_has_forkfd) {
+#if defined(__FreeBSD__) && __FreeBSD__ >= 9
+ pid_t pid;
+ int status;
+ int options = WEXITED;
+
+ ret = pdgetpid(ffd, &pid);
+ if (ret == -1)
+ return ret;
+ ret = fcntl(ffd, F_GETFL);
+ if (ret == -1)
+ return ret;
+ options |= (ret & O_NONBLOCK) ? WNOHANG : 0;
+ ret = wait4(pid, &status, options, rusage);
+ if (ret != -1 && info)
+ convertStatusToForkfdInfo(status, info);
+ return ret == -1 ? -1 : 0;
+#endif
+ }
+
ret = read(ffd, &payload, sizeof(payload));
if (ret == -1)
return ret; /* pass errno, probably EINTR, EBADF or EWOULDBLOCK */
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index ba3ecfecd6..ee196f1aef 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -203,6 +203,16 @@ public class QtActivityDelegate
private final int ImhUrlCharactersOnly = 0x400000;
private final int ImhLatinOnly = 0x800000;
+ // enter key type - must be kept in sync with QTDIR/src/corelib/global/qnamespace.h
+ private final int EnterKeyDefault = 0;
+ private final int EnterKeyReturn = 1;
+ private final int EnterKeyDone = 2;
+ private final int EnterKeyGo = 3;
+ private final int EnterKeySend = 4;
+ private final int EnterKeySearch = 5;
+ private final int EnterKeyNext = 6;
+ private final int EnterKeyPrevious = 7;
+
// application state
private final int ApplicationSuspended = 0x0;
private final int ApplicationHidden = 0x1;
@@ -239,7 +249,7 @@ public class QtActivityDelegate
}, 5);
}
- public void showSoftwareKeyboard(int x, int y, int width, int height, int inputHints)
+ public void showSoftwareKeyboard(int x, int y, int width, int height, int inputHints, int enterKeyType)
{
if (m_imm == null)
return;
@@ -252,7 +262,31 @@ public class QtActivityDelegate
m_activity.getWindow().setSoftInputMode(m_softInputMode);
int initialCapsMode = 0;
+
int imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
+
+ switch (enterKeyType) {
+ case EnterKeyReturn:
+ imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
+ break;
+ case EnterKeyGo:
+ imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
+ break;
+ case EnterKeySend:
+ imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEND;
+ break;
+ case EnterKeySearch:
+ imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH;
+ break;
+ case EnterKeyNext:
+ imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_NEXT;
+ break;
+ case EnterKeyPrevious:
+ if (Build.VERSION.SDK_INT > 10)
+ imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_PREVIOUS;
+ break;
+ }
+
int inputType = android.text.InputType.TYPE_CLASS_TEXT;
if ((inputHints & (ImhPreferNumbers | ImhDigitsOnly | ImhFormattedNumbersOnly)) != 0) {
@@ -278,7 +312,9 @@ public class QtActivityDelegate
if ((inputHints & (ImhEmailCharactersOnly | ImhUrlCharactersOnly)) != 0) {
if ((inputHints & ImhUrlCharactersOnly) != 0) {
inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI;
- imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
+
+ if (enterKeyType == 0) // not explicitly overridden
+ imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
} else if ((inputHints & ImhEmailCharactersOnly) != 0) {
inputType |= android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
}
@@ -305,7 +341,7 @@ public class QtActivityDelegate
}
}
- if ((inputHints & ImhMultiLine) != 0)
+ if (enterKeyType == 0 && (inputHints & ImhMultiLine) != 0)
imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
m_editText.setInitialCapsMode(initialCapsMode);
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 5d7918ea54..a1e7dac4d4 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -389,12 +389,13 @@ public class QtNative
final int y,
final int width,
final int height,
- final int inputHints )
+ final int inputHints,
+ final int enterKeyType)
{
runAction(new Runnable() {
@Override
public void run() {
- m_activityDelegate.showSoftwareKeyboard(x, y, width, height, inputHints);
+ m_activityDelegate.showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType);
}
});
}
diff --git a/src/angle/patches/0008-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch b/src/angle/patches/0008-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch
new file mode 100644
index 0000000000..cf383d7106
--- /dev/null
+++ b/src/angle/patches/0008-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch
@@ -0,0 +1,361 @@
+From 333bb863e5c3e04fcc513e4750208fa3742be7a1 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@intopalo.com>
+Date: Sat, 8 Aug 2015 21:42:03 +0300
+Subject: [PATCH 2/4] ANGLE: Use pixel sizes in the XAML swap chain
+
+This is necessary for Qt applications, as they render to GL in physical
+pixels. This is consistent with the CoreWindow swap chain behavior.
+
+This includes a partial revert of "ANGLE: Improve Windows Phone Support"
+as the modifications to SwapChain11 are incompatible with the XAML swap
+chain.
+
+This change only affects Windows Runtime targets.
+
+Change-Id: I401ae81028a9dfdb9da37f51c60844467c476f76
+---
+ .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 46 ----------------------
+ .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 21 ----------
+ .../d3d/d3d11/winrt/CoreWindowNativeWindow.h | 4 +-
+ .../d3d/d3d11/winrt/InspectableNativeWindow.cpp | 21 ++++++++++
+ .../d3d/d3d11/winrt/InspectableNativeWindow.h | 10 +++--
+ .../d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp | 30 ++++++++------
+ .../d3d/d3d11/winrt/SwapChainPanelNativeWindow.h | 7 ++--
+ 7 files changed, 49 insertions(+), 90 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+index dc539cf..0af2cf1 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+@@ -154,14 +154,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+ const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
+
+ D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
+-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+- const int textureLength = std::max(backbufferWidth, backbufferHeight);
+- offscreenTextureDesc.Width = textureLength;
+- offscreenTextureDesc.Height = textureLength;
+-#else
+ offscreenTextureDesc.Width = backbufferWidth;
+ offscreenTextureDesc.Height = backbufferHeight;
+-#endif
+ offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
+ offscreenTextureDesc.MipLevels = 1;
+ offscreenTextureDesc.ArraySize = 1;
+@@ -241,14 +235,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+ if (mDepthBufferFormat != GL_NONE)
+ {
+ D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
+-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+- const int textureLength = std::max(backbufferWidth, backbufferHeight);
+- depthStencilTextureDesc.Width = textureLength;
+- depthStencilTextureDesc.Height = textureLength;
+-#else
+ depthStencilTextureDesc.Width = backbufferWidth;
+ depthStencilTextureDesc.Height = backbufferHeight;
+-#endif
+ depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
+ depthStencilTextureDesc.MipLevels = 1;
+ depthStencilTextureDesc.ArraySize = 1;
+@@ -349,7 +337,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+ return EGL_SUCCESS;
+ }
+
+-#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
+ // Can only call resize if we have already created our swap buffer and resources
+ ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
+
+@@ -392,12 +379,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+ }
+
+ return resetOffscreenTexture(backbufferWidth, backbufferHeight);
+-#else
+- // Do nothing on Windows Phone apart from updating the internal buffer/width height
+- mWidth = backbufferWidth;
+- mHeight = backbufferHeight;
+- return EGL_SUCCESS;
+-#endif
+ }
+
+ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
+@@ -552,27 +533,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+
+ d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
+
+-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+- // Create a quad in homogeneous coordinates
+- float x1 = -1.0f;
+- float y1 = -1.0f;
+- float x2 = 1.0f;
+- float y2 = 1.0f;
+-
+- const float dim = std::max(mWidth, mHeight);
+- float u1 = 0;
+- float v1 = 0;
+- float u2 = float(width) / dim;
+- float v2 = float(height) / dim;
+-
+- const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags();
+- const bool rotateL = flags == NativeWindow::RotateLeft;
+- const bool rotateR = flags == NativeWindow::RotateRight;
+- d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
+- d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
+- d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1);
+- d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2);
+-#else
+ // Create a quad in homogeneous coordinates
+ float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
+ float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
+@@ -588,7 +548,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
+ d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
+ d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
+-#endif
+
+ deviceContext->Unmap(mQuadVB, 0);
+
+@@ -618,13 +577,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0;
+ viewport.TopLeftY = 0;
+-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+- viewport.Width = (rotateL || rotateR) ? height : width;
+- viewport.Height = (rotateL || rotateR) ? width : height;
+-#else
+ viewport.Width = mWidth;
+ viewport.Height = mHeight;
+-#endif
+ viewport.MinDepth = 0.0f;
+ viewport.MaxDepth = 1.0f;
+ deviceContext->RSSetViewports(1, &viewport);
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
+index fa9a69c..f45a077 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
+@@ -191,25 +191,4 @@ HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWind
+
+ return result;
+ }
+-
+-static float GetLogicalDpi()
+-{
+- ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
+- float dpi = 96.0f;
+-
+- if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
+- {
+- if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
+- {
+- return dpi;
+- }
+- }
+- return dpi;
+-}
+-
+-long ConvertDipsToPixels(float dips)
+-{
+- static const float dipsPerInch = 96.0f;
+- return lround((dips * GetLogicalDpi() / dipsPerInch));
+-}
+ }
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
+index 59df9d5..87cdfe6 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
+@@ -19,7 +19,6 @@ typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CD
+
+ namespace rx
+ {
+-long ConvertDipsToPixels(float dips);
+
+ class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
+ {
+@@ -64,8 +63,7 @@ class CoreWindowSizeChangedHandler :
+ ABI::Windows::Foundation::Size windowSize;
+ if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize)))
+ {
+- SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) };
+- host->setNewClientSize(windowSizeInPixels);
++ host->setNewClientSize(windowSize);
+ }
+ }
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
+index 2bf48c5..e83f479 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
+@@ -288,4 +288,25 @@ HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Coll
+
+ return result;
+ }
++
++static float GetLogicalDpi()
++{
++ ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
++ float dpi = 96.0f;
++
++ if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
++ {
++ if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
++ {
++ return dpi;
++ }
++ }
++ return dpi;
++}
++
++long ConvertDipsToPixels(float dips)
++{
++ static const float dipsPerInch = 96.0f;
++ return lround((dips * GetLogicalDpi() / dipsPerInch));
++}
+ }
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
+index 575bdf8..f053407 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
+@@ -26,6 +26,8 @@ using namespace ABI::Windows::Foundation::Collections;
+
+ namespace rx
+ {
++long ConvertDipsToPixels(float dips);
++
+ class InspectableNativeWindow
+ {
+ public:
+@@ -45,7 +47,7 @@ class InspectableNativeWindow
+ virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
+ virtual bool registerForSizeChangeEvents() = 0;
+ virtual void unregisterForSizeChangeEvents() = 0;
+- virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
++ virtual HRESULT scaleSwapChain(const Size& newSize) { return S_OK; }
+
+ bool getClientRect(RECT *rect)
+ {
+@@ -59,11 +61,11 @@ class InspectableNativeWindow
+ return true;
+ }
+
+- void setNewClientSize(const SIZE &newSize)
++ void setNewClientSize(const Size &newSize)
+ {
+- if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
++ if (mSupportsSwapChainResize)
+ {
+- mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
++ mNewClientRect = { 0, 0, ConvertDipsToPixels(newSize.Width), ConvertDipsToPixels(newSize.Height) };
+ mClientRectChanged = true;
+ }
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
+index 53899db..0b48b54 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
+@@ -66,7 +66,7 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert
+ }
+ else
+ {
+- result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect);
++ result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect, &mRequiresSwapChainScaling);
+ }
+ }
+
+@@ -139,7 +139,6 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
+
+ ComPtr<IDXGISwapChain1> newSwapChain;
+ ComPtr<ISwapChainPanelNative> swapChainPanelNative;
+- RECT currentPanelSize = {};
+
+ HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
+
+@@ -167,13 +166,13 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
+ // first reading the current size of the swapchain panel, then scaling
+ if (SUCCEEDED(result) && mRequiresSwapChainScaling)
+ {
+- result = GetSwapChainPanelSize(mSwapChainPanel, &currentPanelSize);
+- }
++ ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
++ result = mSwapChainPanel.As(&uiElement);
++ ASSERT(SUCCEEDED(result));
+
+- // Scale the swapchain to fit inside the contents of the panel.
+- if (SUCCEEDED(result) && mRequiresSwapChainScaling)
+- {
+- SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom };
++ Size currentSize;
++ result = uiElement->get_RenderSize(&currentSize);
++ ASSERT(SUCCEEDED(result));
+ result = scaleSwapChain(currentSize);
+ }
+
+@@ -190,9 +189,9 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa
+ return result;
+ }
+
+-HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
++HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &newSize)
+ {
+- ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom };
++ ABI::Windows::Foundation::Size renderScale = { newSize.Width / mNewClientRect.right, newSize.Height / mNewClientRect.bottom };
+ // Setup a scale matrix for the swap chain
+ DXGI_MATRIX_3X2_F scaleMatrix = {};
+ scaleMatrix._11 = renderScale.Width;
+@@ -208,7 +207,7 @@ HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
+ return result;
+ }
+
+-HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize)
++HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive)
+ {
+ ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
+ ABI::Windows::Foundation::Size renderSize = { 0, 0 };
+@@ -220,7 +219,14 @@ HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISw
+
+ if (SUCCEEDED(result))
+ {
+- *windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) };
++ long width = ConvertDipsToPixels(renderSize.Width);
++ long height = ConvertDipsToPixels(renderSize.Height);
++ *windowSize = { 0, 0, width, height };
++
++ if (scalingActive)
++ {
++ *scalingActive = width != renderSize.Width || height != renderSize.Height;
++ }
+ }
+
+ return result;
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
+index caf327d..5debd2f 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
+@@ -22,7 +22,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e
+ bool registerForSizeChangeEvents();
+ void unregisterForSizeChangeEvents();
+ HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
+- HRESULT scaleSwapChain(const SIZE &newSize);
++ HRESULT scaleSwapChain(const Size &newSize) override;
+
+ private:
+ ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
+@@ -62,8 +62,7 @@ class SwapChainPanelSizeChangedHandler :
+ HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
+ if (SUCCEEDED(result))
+ {
+- SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) };
+- host->setNewClientSize(windowSize);
++ host->setNewClientSize(newSize);
+ }
+ }
+
+@@ -74,6 +73,6 @@ class SwapChainPanelSizeChangedHandler :
+ std::weak_ptr<InspectableNativeWindow> mHost;
+ };
+
+-HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize);
++HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize, bool *scalingActive = nullptr);
+ }
+ #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
+--
+1.9.5.msysgit.1
+
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 51dd64c7cc..f8f306f614 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -496,10 +496,13 @@ typedef qptrdiff qintptr;
#ifdef Q_CC_MSVC
# define Q_NEVER_INLINE __declspec(noinline)
+# define Q_ALWAYS_INLINE __forceinline
#elif defined(Q_CC_GNU)
# define Q_NEVER_INLINE __attribute__((noinline))
+# define Q_ALWAYS_INLINE inline __attribute__((always_inline))
#else
# define Q_NEVER_INLINE
+# define Q_ALWAYS_INLINE inline
#endif
//defines the type for the WNDPROC on windows
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index dfde5f236d..cdae149678 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -2206,6 +2206,16 @@ void QProcessPrivate::start(QIODevice::OpenMode mode)
mode &= ~QIODevice::ReadOnly; // not open for reading
if (mode == 0)
mode = QIODevice::Unbuffered;
+#ifndef Q_OS_WINCE
+ if ((mode & QIODevice::ReadOnly) == 0) {
+ if (stdoutChannel.type == QProcessPrivate::Channel::Normal)
+ q->setStandardOutputFile(q->nullDevice());
+ if (stderrChannel.type == QProcessPrivate::Channel::Normal
+ && processChannelMode != QProcess::MergedChannels)
+ q->setStandardErrorFile(q->nullDevice());
+ }
+#endif
+
q->QIODevice::open(mode);
stdinChannel.closed = false;
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 04848a38e5..8828e09e8f 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -182,7 +182,7 @@ QT_BEGIN_NAMESPACE
\li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache"
\row \li GenericDataLocation
\li "~/Library/Application Support", "/Library/Application Support"
- \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
+ \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData", "<APPDIR>", "<APPDIR>/data"
\row \li RuntimeLocation
\li "~/Library/Application Support"
\li "C:/Users/<USER>"
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index b1d5821a97..0a13f94f05 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -212,10 +212,8 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
}
dirs.append(result);
#ifndef QT_BOOTSTRAPPED
- if (type != GenericDataLocation) {
- dirs.append(QCoreApplication::applicationDirPath());
- dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data"));
- }
+ dirs.append(QCoreApplication::applicationDirPath());
+ dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data"));
#endif
}
break;
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index e9fdb8c8ef..00d618745b 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -323,17 +323,9 @@ uint QCoreApplicationPrivate::attribs = (1 << Qt::AA_SynthesizeMouseForUnhandled
struct QCoreApplicationData {
QCoreApplicationData() Q_DECL_NOTHROW {
-#ifndef QT_NO_LIBRARY
- app_libpaths = 0;
- manual_libpaths = 0;
-#endif
applicationNameSet = false;
}
~QCoreApplicationData() {
-#ifndef QT_NO_LIBRARY
- delete app_libpaths;
- delete manual_libpaths;
-#endif
#ifndef QT_NO_QOBJECT
// cleanup the QAdoptedThread created for the main() thread
if (QCoreApplicationPrivate::theMainThread) {
@@ -377,8 +369,8 @@ struct QCoreApplicationData {
bool applicationNameSet; // true if setApplicationName was called
#ifndef QT_NO_LIBRARY
- QStringList *app_libpaths;
- QStringList *manual_libpaths;
+ QScopedPointer<QStringList> app_libpaths;
+ QScopedPointer<QStringList> manual_libpaths;
#endif
};
@@ -571,9 +563,9 @@ void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
{
#ifndef QT_NO_LIBRARY
- QStringList *app_libpaths = coreappdata()->app_libpaths;
+ QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (!app_libpaths)
- coreappdata()->app_libpaths = app_libpaths = new QStringList;
+ coreappdata()->app_libpaths.reset(app_libpaths = new QStringList);
QString app_location = QCoreApplication::applicationFilePath();
app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
#ifdef Q_OS_WINRT
@@ -774,16 +766,14 @@ void QCoreApplication::init()
// Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
// into account. If necessary, recompute right away and replay the manual changes on top of the
// new lib paths.
- QStringList *appPaths = coreappdata()->app_libpaths;
- QStringList *manualPaths = coreappdata()->manual_libpaths;
+ QStringList *appPaths = coreappdata()->app_libpaths.take();
+ QStringList *manualPaths = coreappdata()->manual_libpaths.take();
if (appPaths) {
- coreappdata()->app_libpaths = 0;
if (manualPaths) {
// Replay the delta. As paths can only be prepended to the front or removed from
// anywhere in the list, we can just linearly scan the lists and find the items that
// have been removed. Once the original list is exhausted we know all the remaining
// items have been added.
- coreappdata()->manual_libpaths = 0;
QStringList newPaths(libraryPaths());
for (int i = manualPaths->length(), j = appPaths->length(); i > 0 || j > 0; qt_noop()) {
if (--j < 0) {
@@ -796,7 +786,7 @@ void QCoreApplication::init()
}
}
delete manualPaths;
- coreappdata()->manual_libpaths = new QStringList(newPaths);
+ coreappdata()->manual_libpaths.reset(new QStringList(newPaths));
}
delete appPaths;
}
@@ -872,10 +862,8 @@ QCoreApplication::~QCoreApplication()
#endif
#ifndef QT_NO_LIBRARY
- delete coreappdata()->app_libpaths;
- coreappdata()->app_libpaths = 0;
- delete coreappdata()->manual_libpaths;
- coreappdata()->manual_libpaths = 0;
+ coreappdata()->app_libpaths.reset();
+ coreappdata()->manual_libpaths.reset();
#endif
}
@@ -2540,7 +2528,8 @@ QStringList QCoreApplication::libraryPaths()
return *(coreappdata()->manual_libpaths);
if (!coreappdata()->app_libpaths) {
- QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList;
+ QStringList *app_libpaths = new QStringList;
+ coreappdata()->app_libpaths.reset(app_libpaths);
const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
if (!libPathEnv.isEmpty()) {
@@ -2592,9 +2581,10 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths)
if (!coreappdata()->app_libpaths)
libraryPaths();
- if (!coreappdata()->manual_libpaths)
- coreappdata()->manual_libpaths = new QStringList;
- *(coreappdata()->manual_libpaths) = paths;
+ if (coreappdata()->manual_libpaths)
+ *(coreappdata()->manual_libpaths) = paths;
+ else
+ coreappdata()->manual_libpaths.reset(new QStringList(paths));
locker.unlock();
QFactoryLoader::refreshAll();
@@ -2626,18 +2616,18 @@ void QCoreApplication::addLibraryPath(const QString &path)
QMutexLocker locker(libraryPathMutex());
- QStringList *libpaths = coreappdata()->manual_libpaths;
+ QStringList *libpaths = coreappdata()->manual_libpaths.data();
if (libpaths) {
if (libpaths->contains(canonicalPath))
return;
} else {
// make sure that library paths are initialized
libraryPaths();
- QStringList *app_libpaths = coreappdata()->app_libpaths;
+ QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (app_libpaths->contains(canonicalPath))
return;
- libpaths = coreappdata()->manual_libpaths = new QStringList(*app_libpaths);
+ coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
}
libpaths->prepend(canonicalPath);
@@ -2665,18 +2655,18 @@ void QCoreApplication::removeLibraryPath(const QString &path)
QMutexLocker locker(libraryPathMutex());
- QStringList *libpaths = coreappdata()->manual_libpaths;
+ QStringList *libpaths = coreappdata()->manual_libpaths.data();
if (libpaths) {
if (libpaths->removeAll(canonicalPath) == 0)
return;
} else {
// make sure that library paths is initialized
libraryPaths();
- QStringList *app_libpaths = coreappdata()->app_libpaths;
+ QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (!app_libpaths->contains(canonicalPath))
return;
- libpaths = coreappdata()->manual_libpaths = new QStringList(*app_libpaths);
+ coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
libpaths->removeAll(canonicalPath);
}
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index eceba8d002..f771974a24 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -40,6 +40,7 @@
#include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h>
+#include <functional>
#include <wrl.h>
#include <windows.foundation.h>
#include <windows.system.threading.h>
@@ -70,6 +71,23 @@ struct WinRTTimerInfo : public QAbstractEventDispatcher::TimerInfo {
quint64 targetTime;
};
+class AgileDispatchedHandler : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IDispatchedHandler, IAgileObject>
+{
+public:
+ AgileDispatchedHandler(const std::function<HRESULT()> &delegate)
+ : delegate(delegate)
+ {
+ }
+
+ HRESULT __stdcall Invoke()
+ {
+ return delegate();
+ }
+
+private:
+ std::function<HRESULT()> delegate;
+};
+
class QEventDispatcherWinRTPrivate : public QAbstractEventDispatcherPrivate
{
Q_DECLARE_PUBLIC(QEventDispatcherWinRT)
@@ -80,8 +98,6 @@ public:
private:
ComPtr<IThreadPoolTimerStatics> timerFactory;
- ComPtr<ICoreDispatcher> coreDispatcher;
- QPointer<QThread> thread;
QHash<int, QObject *> timerIdToObject;
QVector<WinRTTimerInfo> timerInfos;
@@ -136,40 +152,11 @@ private:
}
return true;
}
-
- void fetchCoreDispatcher()
- {
- ComPtr<ICoreImmersiveApplication> application;
- HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
- IID_PPV_ARGS(&application));
- RETURN_VOID_IF_FAILED("Failed to get the application factory");
-
- static ComPtr<ICoreApplicationView> view;
- if (view)
- return;
-
- hr = application->get_MainView(&view);
- RETURN_VOID_IF_FAILED("Failed to get the main view");
-
- ComPtr<ICoreApplicationView2> view2;
- hr = view.As(&view2);
- RETURN_VOID_IF_FAILED("Failed to cast the main view");
-
- hr = view2->get_Dispatcher(&coreDispatcher);
- if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) // expected in thread pool cases
- return;
- RETURN_VOID_IF_FAILED("Failed to get core dispatcher");
-
- thread = QThread::currentThread();
- }
};
QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
: QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
{
- Q_D(QEventDispatcherWinRT);
-
- d->fetchCoreDispatcher();
}
QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent)
@@ -180,25 +167,43 @@ QEventDispatcherWinRT::~QEventDispatcherWinRT()
{
}
+HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT ()> &delegate)
+{
+ static __declspec(thread) ICoreDispatcher *dispatcher = nullptr;
+ if (!dispatcher) {
+ HRESULT hr;
+ ComPtr<ICoreImmersiveApplication> application;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&application));
+ ComPtr<ICoreApplicationView> view;
+ hr = application->get_MainView(&view);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<ICoreWindow> window;
+ hr = view->get_CoreWindow(&window);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = window->get_Dispatcher(&dispatcher);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ HRESULT hr;
+ boolean onXamlThread;
+ hr = dispatcher->get_HasThreadAccess(&onXamlThread);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (onXamlThread) // Already there
+ return delegate();
+
+ ComPtr<IAsyncAction> op;
+ hr = dispatcher->RunAsync(CoreDispatcherPriority_Normal, Make<AgileDispatchedHandler>(delegate).Get(), &op);
+ if (FAILED(hr))
+ return hr;
+ return QWinRTFunctions::await(op);
+}
+
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherWinRT);
- if (d->thread && d->thread != QThread::currentThread())
- d->fetchCoreDispatcher();
-
do {
- // Process native events
- if (d->coreDispatcher) {
- boolean hasThreadAccess;
- HRESULT hr = d->coreDispatcher->get_HasThreadAccess(&hasThreadAccess);
- if (SUCCEEDED(hr) && hasThreadAccess) {
- hr = d->coreDispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
- if (FAILED(hr))
- qErrnoWarning(hr, "Failed to process events");
- }
- }
-
// Additional user events have to be handled before timer events, but the function may not
// return yet.
const bool userEventsSent = sendPostedEvents(flags);
@@ -284,10 +289,11 @@ void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerTy
TimeSpan period;
period.Duration = interval ? (interval * 10000) : 1; // TimeSpan is based on 100-nanosecond units
- IThreadPoolTimer *timer;
const HANDLE handle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE | EVENT_MODIFY_STATE);
const HANDLE cancelHandle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE|EVENT_MODIFY_STATE);
- HRESULT hr = d->timerFactory->CreatePeriodicTimerWithCompletion(
+ HRESULT hr = runOnXamlThread([&]() {
+ IThreadPoolTimer *timer;
+ HRESULT hr = d->timerFactory->CreatePeriodicTimerWithCompletion(
Callback<ITimerElapsedHandler>([handle, cancelHandle](IThreadPoolTimer *timer) {
DWORD cancelResult = WaitForSingleObjectEx(cancelHandle, 0, TRUE);
if (cancelResult == WAIT_OBJECT_0) {
@@ -306,13 +312,15 @@ void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerTy
CloseHandle(cancelHandle);
return S_OK;
}).Get(), &timer);
+ RETURN_HR_IF_FAILED("Failed to create periodic timer");
+
+ d->addTimer(timerId, interval, timerType, object, handle, cancelHandle);
+ return hr;
+ });
if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to create periodic timer");
CloseHandle(handle);
CloseHandle(cancelHandle);
- return;
}
- d->addTimer(timerId, interval, timerType, object, handle, cancelHandle);
}
bool QEventDispatcherWinRT::unregisterTimer(int timerId)
diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h
index fd3d259c96..073aa1c121 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt_p.h
+++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h
@@ -50,6 +50,8 @@
#include <qt_windows.h>
+namespace std { template <typename T> class function; }
+
QT_BEGIN_NAMESPACE
quint64 qt_msectime();
@@ -65,6 +67,8 @@ public:
explicit QEventDispatcherWinRT(QObject *parent = 0);
~QEventDispatcherWinRT();
+ static HRESULT runOnXamlThread(const std::function<HRESULT()> &delegate);
+
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
index a9a790c14c..d3e7d51efd 100644
--- a/src/corelib/thread/qgenericatomic.h
+++ b/src/corelib/thread/qgenericatomic.h
@@ -46,13 +46,6 @@ QT_END_NAMESPACE
#pragma qt_sync_stop_processing
#endif
-#ifdef Q_CC_GNU
-// lowercase is fine, we'll undef it below
-#define always_inline __attribute__((always_inline, gnu_inline))
-#else
-#define always_inline
-#endif
-
template<int> struct QAtomicOpsSupport { enum { IsSupported = 0 }; };
template<> struct QAtomicOpsSupport<4> { enum { IsSupported = 1 }; };
@@ -84,19 +77,19 @@ template <typename BaseClass> struct QGenericAtomicOps
{
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T load(const T &_q_value) Q_DECL_NOTHROW
{
return _q_value;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
void store(T &_q_value, X newValue) Q_DECL_NOTHROW
{
_q_value = newValue;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T loadAcquire(const T &_q_value) Q_DECL_NOTHROW
{
T tmp = *static_cast<const volatile T *>(&_q_value);
@@ -104,7 +97,7 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
void storeRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
@@ -115,13 +108,13 @@ template <typename BaseClass> struct QGenericAtomicOps
{ return BaseClass::isFetchAndAddNative(); }
static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW
{ return BaseClass::isFetchAndAddWaitFree(); }
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
bool ref(T &_q_value) Q_DECL_NOTHROW
{
return BaseClass::fetchAndAddRelaxed(_q_value, 1) != T(-1);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
bool deref(T &_q_value) Q_DECL_NOTHROW
{
return BaseClass::fetchAndAddRelaxed(_q_value, -1) != 1;
@@ -138,7 +131,7 @@ template <typename BaseClass> struct QGenericAtomicOps
bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW;
#endif
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
{
bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
@@ -146,21 +139,21 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetRelease(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
{
bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
@@ -168,14 +161,14 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetRelease(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
@@ -185,7 +178,7 @@ template <typename BaseClass> struct QGenericAtomicOps
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; }
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; }
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
T fetchAndStoreRelaxed(T &_q_value, X newValue) Q_DECL_NOTHROW
{
// implement fetchAndStore on top of testAndSet
@@ -196,7 +189,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
T fetchAndStoreAcquire(T &_q_value, X newValue) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
@@ -204,14 +197,14 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
T fetchAndStoreRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
T fetchAndStoreOrdered(T &_q_value, X newValue) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
@@ -220,7 +213,7 @@ template <typename BaseClass> struct QGenericAtomicOps
static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return false; }
static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return false; }
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
{
// implement fetchAndAdd on top of testAndSet
@@ -231,7 +224,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
@@ -239,28 +232,28 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
{
// implement fetchAndSub on top of fetchAndAdd
return fetchAndAddRelaxed(_q_value, -operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndSubRelaxed(_q_value, operand);
@@ -268,21 +261,21 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndSubRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndSubRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAndRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
// implement fetchAndAnd on top of testAndSet
@@ -293,7 +286,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAndAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndAndRelaxed(_q_value, operand);
@@ -301,21 +294,21 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAndRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndAndRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAndOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndAndRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndOrRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
// implement fetchAndOr on top of testAndSet
@@ -326,7 +319,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndOrAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndOrRelaxed(_q_value, operand);
@@ -334,21 +327,21 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndOrRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndOrRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndOrOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndOrRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndXorRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
// implement fetchAndXor on top of testAndSet
@@ -359,7 +352,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndXorAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndXorRelaxed(_q_value, operand);
@@ -367,14 +360,14 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndXorRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndXorRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndXorOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
@@ -382,7 +375,5 @@ template <typename BaseClass> struct QGenericAtomicOps
}
};
-#undef always_inline
-
QT_END_NAMESPACE
#endif // QGENERICATOMIC_H
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 87a59c67c8..1f3ea36121 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -2240,7 +2240,7 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
Returns a pointer to the current item's key.
*/
-/*! \fn bool QHash::key_iterator::operator==(key_iterator other)
+/*! \fn bool QHash::key_iterator::operator==(key_iterator other) const
Returns \c true if \a other points to the same item as this
iterator; otherwise returns \c false.
@@ -2248,7 +2248,7 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
\sa operator!=()
*/
-/*! \fn bool QHash::key_iterator::operator!=(key_iterator other)
+/*! \fn bool QHash::key_iterator::operator!=(key_iterator other) const
Returns \c true if \a other points to a different item than this
iterator; otherwise returns \c false.
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 509afadfc2..8ed0da7ca0 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -378,7 +378,7 @@ void **QListData::erase(void **xi)
references into a QVector and non-heap-allocating QLists.
Internally, QList\<T\> is represented as an array of T if
- If \c{sizeof(T) <= sizeof(void*)} and T has been declared to be
+ \c{sizeof(T) <= sizeof(void*)} and T has been declared to be
either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using
\l {Q_DECLARE_TYPEINFO}. Otherwise, QList\<T\> is represented
as an array of T* and the items are allocated on the heap.
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index f7aa7332dd..e49a1a098d 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -1719,7 +1719,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
Returns a pointer to the current item's key.
*/
-/*! \fn bool QMap::key_iterator::operator==(key_iterator other)
+/*! \fn bool QMap::key_iterator::operator==(key_iterator other) const
Returns \c true if \a other points to the same item as this
iterator; otherwise returns \c false.
@@ -1727,7 +1727,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
\sa operator!=()
*/
-/*! \fn bool QMap::key_iterator::operator!=(key_iterator other)
+/*! \fn bool QMap::key_iterator::operator!=(key_iterator other) const
Returns \c true if \a other points to a different item than this
iterator; otherwise returns \c false.
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index f240153f9f..5e2a5b86a4 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1935,6 +1935,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
}
}
#endif
+ e->eventAccepted = ev.isAccepted();
}
void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index d10bd1e9eb..0430d5a4c6 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -690,6 +690,14 @@ QRect QPlatformWindow::windowGeometry() const
}
/*!
+ Returns the QWindow frame geometry.
+*/
+QRect QPlatformWindow::windowFrameGeometry() const
+{
+ return QHighDpi::toNativePixels(window()->frameGeometry(), window());
+}
+
+/*!
Returns the closest acceptable geometry for a given geometry before
a resize/move event for platforms that support it, for example to
implement heightForWidth().
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 692ae862db..1b283dbb4f 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -138,6 +138,7 @@ public:
QSize windowBaseSize() const;
QSize windowSizeIncrement() const;
QRect windowGeometry() const;
+ QRect windowFrameGeometry() const;
QRectF windowClosestAcceptableGeometry(const QRectF &nativeRect) const;
protected:
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 3ab2f59661..88cf2dac93 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -303,24 +303,24 @@ bool QWindowSystemInterface::tryHandleExtendedShortcutEvent(QWindow *w, ulong ti
}
-void QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
+bool QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleKeyEvent(w, time, t, k, mods, text, autorep, count);
+ return handleKeyEvent(w, time, t, k, mods, text, autorep, count);
}
-void QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
+bool QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
{
// This is special handling needed for OS X which eventually will call sendEvent(), on other platforms
// this might not be safe, e.g., on Android. See: QGuiApplicationPrivate::processKeyEvent() for
// shortcut overriding on other platforms.
#if defined(Q_OS_OSX)
if (t == QEvent::KeyPress && QWindowSystemInterface::tryHandleShortcutEvent(tlw, timestamp, k, mods, text))
- return;
+ return true;
#endif // Q_OS_OSX
QWindowSystemInterfacePrivate::KeyEvent * e =
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+ return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
@@ -441,10 +441,12 @@ void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *e
windowSystemEventQueue.remove(event);
}
-void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
+bool QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
{
+ bool accepted = true;
if (synchronousWindowSystemEvents) {
QGuiApplicationPrivate::processWindowSystemEvent(ev);
+ accepted = ev->eventAccepted;
delete ev;
} else {
windowSystemEventQueue.append(ev);
@@ -452,6 +454,7 @@ void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfa
if (dispatcher)
dispatcher->wakeUp();
}
+ return accepted;
}
void QWindowSystemInterface::registerTouchDevice(QTouchDevice *device)
@@ -611,7 +614,7 @@ void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::Process
Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread());
QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex);
- flushWindowSystemEvents(flags);
+ sendWindowSystemEvents(flags);
QWindowSystemInterfacePrivate::eventsFlushed.wakeOne();
}
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 453dbe81cf..ace1a4fe24 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -95,8 +95,8 @@ public:
quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
const QString & text = QString(), bool autorep = false, ushort count = 1);
- static void handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
- static void handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
+ static bool handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
+ static bool handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
static void handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index cbc3bad7cd..cc0ca6bf81 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -101,7 +101,7 @@ public:
};
explicit WindowSystemEvent(EventType t)
- : type(t), flags(0) { }
+ : type(t), flags(0), eventAccepted(true) { }
virtual ~WindowSystemEvent() { }
bool synthetic() const { return flags & Synthetic; }
@@ -109,6 +109,7 @@ public:
EventType type;
int flags;
+ bool eventAccepted;
};
class CloseEvent : public WindowSystemEvent {
@@ -480,7 +481,7 @@ public:
static WindowSystemEvent *getNonUserInputWindowSystemEvent();
static WindowSystemEvent *peekWindowSystemEvent(EventType t);
static void removeWindowSystemEvent(WindowSystemEvent *event);
- static void handleWindowSystemEvent(WindowSystemEvent *ev);
+ static bool handleWindowSystemEvent(WindowSystemEvent *ev);
static QElapsedTimer eventTime;
static bool synchronousWindowSystemEvents;
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 68ed3eae6e..8a5a6d4fcf 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -182,7 +182,8 @@ void QBackingStore::beginPaint(const QRegion &region)
qCDebug(lcScaling) << "QBackingStore::beginPaint new backingstore for" << d_ptr->window;
qCDebug(lcScaling) << " source size" << source->size() << "dpr" << source->devicePixelRatio();
d_ptr->highDpiBackingstore.reset(
- new QImage(source->bits(), source->width(), source->height(), source->format()));
+ new QImage(source->bits(), source->width(), source->height(), source->bytesPerLine(), source->format()));
+
qreal targetDevicePixelRatio = d_ptr->window->devicePixelRatio();
d_ptr->highDpiBackingstore->setDevicePixelRatio(targetDevicePixelRatio);
qCDebug(lcScaling) <<" destination size" << d_ptr->highDpiBackingstore->size()
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index dbdd82e432..0898a20998 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -395,169 +395,6 @@ void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
}
}
-template<QtPixelOrder PixelOrder>
-static void qt_blend_argb32pm_on_a2rgb30pm(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_argb32pm_on_a2rgb30pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- if (const_alpha == 256) {
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint s = src[x];
- dst[x] = qConvertArgb32ToA2rgb30<PixelOrder>(s) + BYTE_MUL_RGB30(dst[x], 255 - qAlpha(s));
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- } else if (const_alpha != 0) {
- const_alpha = (const_alpha * 255) >> 8;
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint s = src[x];
- dst[x] = BYTE_MUL_RGB30(qConvertArgb32ToA2rgb30<PixelOrder>(s), const_alpha) + BYTE_MUL_RGB30(dst[x], 255 - qt_div_255(qAlpha(s) * const_alpha));
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- }
-}
-
-template<QtPixelOrder PixelOrder>
-static void qt_blend_rgb32_on_rgb30(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_rgb32_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- if (const_alpha != 256) {
- qt_blend_argb32pm_on_a2rgb30pm<PixelOrder>(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- return;
- }
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- for (int y = 0; y < h; ++y) {
- for (int x = 0; x < w; ++x) {
- dst[x] = qConvertRgb32ToRgb30<PixelOrder>(src[x]);
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
-}
-
-static void qt_blend_a2rgb30pm_on_a2rgb30pm(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_a2rgb30pm_on_a2rgb30pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- if (const_alpha == 256) {
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint s = src[x];
- dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - qAlphaRgb30(s));
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- } else if (const_alpha != 0) {
- const uint const_alpha255 = (const_alpha * 255) >> 8;
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint a = (qAlphaRgb30(src[x]) * const_alpha) >> 8;
- uint s = BYTE_MUL_RGB30(src[x], const_alpha255);
- dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - a);
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- }
-}
-
-
-static void qt_blend_rgb30_on_rgb30(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_rgb30_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- if (const_alpha != 256) {
- qt_blend_a2rgb30pm_on_a2rgb30pm(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- return;
- }
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- int len = w * 4;
- for (int y=0; y<h; ++y) {
- memcpy(dst, src, len);
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
-}
-
-static void qt_blend_a2bgr30pm_on_a2rgb30pm(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- fprintf(stdout, "qt_blend_a2bgr30pm_on_a2rgb32pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
- fflush(stdout);
-#endif
-
- const uint *src = (const uint *) srcPixels;
- uint *dst = (uint *) destPixels;
- if (const_alpha == 256) {
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint s = qRgbSwapRgb30(src[x]);
- dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - qAlphaRgb30(s));
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- } else if (const_alpha != 0) {
- const uint const_alpha255 = (const_alpha * 255) >> 8;
- for (int y=0; y<h; ++y) {
- for (int x=0; x<w; ++x) {
- uint a = (qAlphaRgb30(src[x]) * const_alpha) >> 8;
- uint s = BYTE_MUL_RGB30(src[x], const_alpha255);
- dst[x] = qRgbSwapRgb30(s) + BYTE_MUL_RGB30(dst[x], 255 - a);
- }
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- }
-}
-
struct Blend_RGB32_on_RGB32_NoAlpha {
inline void write(quint32 *dst, quint32 src) { *dst = src; }
@@ -772,30 +609,6 @@ void qInitBlendFunctions()
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32;
#endif
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderBGR>;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_BGR30] = qt_blend_rgb30_on_rgb30;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_RGB30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_BGR30][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderBGR>;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_BGR30] = qt_blend_rgb30_on_rgb30;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_RGB30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderRGB>;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_BGR30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_RGB30] = qt_blend_rgb30_on_rgb30;
- qBlendFunctions[QImage::Format_RGB30][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderRGB>;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_BGR30] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_RGB30] = qt_blend_rgb30_on_rgb30;
- qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm;
qTransformFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_transform_image_rgb32_on_rgb32;
qTransformFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_argb32;
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 07e5a3d19b..0cf7e20605 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1252,25 +1252,54 @@ static inline void qConvertARGB64PMToA2RGB30PM_sse2(uint *dest, const QRgba64 *b
const __m128i cmask = _mm_set1_epi32(0x000003ff);
int i = 0;
__m128i vr, vg, vb, va;
- for (; i < count-1; i += 2) {
- __m128i vs = _mm_loadu_si128((const __m128i*)buffer);
- buffer += 2;
- vr = _mm_srli_epi64(vs, 6);
- vg = _mm_srli_epi64(vs, 16 + 6 - 10);
- vb = _mm_srli_epi64(vs, 32 + 6);
- vr = _mm_and_si128(vr, cmask);
- vg = _mm_and_si128(vg, gmask);
- vb = _mm_and_si128(vb, cmask);
- va = _mm_srli_epi64(vs, 48 + 14);
- if (PixelOrder == PixelOrderRGB)
- vr = _mm_slli_epi32(vr, 20);
- else
- vb = _mm_slli_epi32(vb, 20);
- va = _mm_slli_epi32(va, 30);
- __m128i vd = _mm_or_si128(_mm_or_si128(vr, vg), _mm_or_si128(vb, va));
- vd = _mm_shuffle_epi32(vd, _MM_SHUFFLE(3, 1, 2, 0));
- _mm_storel_epi64((__m128i*)dest, vd);
- dest += 2;
+ if (i < count && (const uintptr_t)buffer & 0x8) {
+ *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+ ++i;
+ }
+
+ for (; i < count-15; i += 16) {
+ // Repremultiplying is really expensive and hard to do in SIMD without AVX2,
+ // so we try to avoid it by checking if it is needed 16 samples at a time.
+ __m128i vOr = _mm_set1_epi32(0);
+ __m128i vAnd = _mm_set1_epi32(0xffffffff);
+ for (int j = 0; j < 16; j += 2) {
+ __m128i vs = _mm_load_si128((const __m128i*)(buffer + j));
+ vOr = _mm_or_si128(vOr, vs);
+ vAnd = _mm_and_si128(vAnd, vs);
+ }
+ const quint16 orAlpha = ((uint)_mm_extract_epi16(vOr, 3)) | ((uint)_mm_extract_epi16(vOr, 7));
+ const quint16 andAlpha = ((uint)_mm_extract_epi16(vAnd, 3)) & ((uint)_mm_extract_epi16(vAnd, 7));
+
+ if (andAlpha == 0xffff) {
+ for (int j = 0; j < 16; j += 2) {
+ __m128i vs = _mm_load_si128((const __m128i*)buffer);
+ buffer += 2;
+ vr = _mm_srli_epi64(vs, 6);
+ vg = _mm_srli_epi64(vs, 16 + 6 - 10);
+ vb = _mm_srli_epi64(vs, 32 + 6);
+ vr = _mm_and_si128(vr, cmask);
+ vg = _mm_and_si128(vg, gmask);
+ vb = _mm_and_si128(vb, cmask);
+ va = _mm_srli_epi64(vs, 48 + 14);
+ if (PixelOrder == PixelOrderRGB)
+ vr = _mm_slli_epi32(vr, 20);
+ else
+ vb = _mm_slli_epi32(vb, 20);
+ va = _mm_slli_epi32(va, 30);
+ __m128i vd = _mm_or_si128(_mm_or_si128(vr, vg), _mm_or_si128(vb, va));
+ vd = _mm_shuffle_epi32(vd, _MM_SHUFFLE(3, 1, 2, 0));
+ _mm_storel_epi64((__m128i*)dest, vd);
+ dest += 2;
+ }
+ } else if (orAlpha == 0) {
+ for (int j = 0; j < 16; ++j) {
+ *dest++ = 0;
+ buffer++;
+ }
+ } else {
+ for (int j = 0; j < 16; ++j)
+ *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+ }
}
for (; i < count; ++i)
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 2c222b97c2..2fb9e7760c 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -62,15 +62,12 @@ QT_BEGIN_NAMESPACE
#if defined(Q_CC_GNU)
# define Q_STATIC_TEMPLATE_FUNCTION static
-# define Q_ALWAYS_INLINE inline __attribute__((always_inline))
# define Q_DECL_RESTRICT __restrict__
#elif defined(Q_CC_MSVC)
# define Q_STATIC_TEMPLATE_FUNCTION static
-# define Q_ALWAYS_INLINE __forceinline
# define Q_DECL_RESTRICT __restrict
#else
# define Q_STATIC_TEMPLATE_FUNCTION static
-# define Q_ALWAYS_INLINE inline
# define Q_DECL_RESTRICT
#endif
@@ -712,18 +709,6 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) {
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
-static Q_ALWAYS_INLINE uint BYTE_MUL_RGB30(uint x, uint a) {
- uint xa = x >> 30;
- uint xr = (x >> 20) & 0x3ff;
- uint xg = (x >> 10) & 0x3ff;
- uint xb = x & 0x3ff;
- xa = qt_div_255(xa * a);
- xr = qt_div_255(xr * a);
- xg = qt_div_255(xg * a);
- xb = qt_div_255(xb * a);
- return (xa << 30) | (xr << 20) | (xg << 10) | xb;
-}
-
static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c)
{
uint a = c >> 30;
@@ -897,6 +882,18 @@ inline QRgb qRepremultiply(QRgb p)
return qPremultiply(p);
}
+template<unsigned int Shift>
+inline QRgba64 qRepremultiply(QRgba64 p)
+{
+ const uint alpha = p.alpha();
+ if (alpha == 65535 || alpha == 0)
+ return p;
+ p = p.unpremultiplied();
+ Q_CONSTEXPR uint mult = 65535 / (65535 >> Shift);
+ p.setAlpha(mult * (alpha >> Shift));
+ return p.premultiplied();
+}
+
template<>
inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c)
{
@@ -1000,6 +997,7 @@ template<enum QtPixelOrder> inline unsigned int qConvertRgb64ToRgb30(QRgba64);
template<>
inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c)
{
+ c = qRepremultiply<14>(c);
const uint a = c.alpha() >> 14;
const uint r = c.red() >> 6;
const uint g = c.green() >> 6;
@@ -1010,6 +1008,7 @@ inline unsigned int qConvertRgb64ToRgb30<PixelOrderBGR>(QRgba64 c)
template<>
inline unsigned int qConvertRgb64ToRgb30<PixelOrderRGB>(QRgba64 c)
{
+ c = qRepremultiply<14>(c);
const uint a = c.alpha() >> 14;
const uint r = c.red() >> 6;
const uint g = c.green() >> 6;
diff --git a/src/gui/painting/qrgba64.h b/src/gui/painting/qrgba64.h
index 290501047d..b701b224be 100644
--- a/src/gui/painting/qrgba64.h
+++ b/src/gui/painting/qrgba64.h
@@ -40,35 +40,43 @@
QT_BEGIN_NAMESPACE
class QRgba64 {
- struct qrgba_t {
- quint16 red;
- quint16 green;
- quint16 blue;
- quint16 alpha;
+ quint64 rgba;
+
+ // Make sure that the representation always has the order: red green blue alpha, independent
+ // of byte order. This way, vector operations that assume 4 16-bit values see the correct ones.
+ enum {
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ RedShift = 48,
+ GreenShift = 32,
+ BlueShift = 16,
+ AlphaShift = 0
+#else // little endian:
+ RedShift = 0,
+ GreenShift = 16,
+ BlueShift = 32,
+ AlphaShift = 48
+#endif
};
- union {
- struct qrgba_t c;
- quint64 rgba;
- };
public:
// No constructors are allowed, since this needs to be usable in a union in no-c++11 mode.
// When c++11 is mandatory, we can add all but a copy constructor.
- Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha)
+ Q_DECL_RELAXED_CONSTEXPR static
+ QRgba64 fromRgba64(quint16 red, quint16 green, quint16 blue, quint16 alpha)
{
QRgba64 rgba64
#ifdef Q_COMPILER_UNIFORM_INIT
= {}
#endif
;
-
- rgba64.c.red = red;
- rgba64.c.green = green;
- rgba64.c.blue = blue;
- rgba64.c.alpha = alpha;
+ rgba64.rgba = quint64(red) << RedShift
+ | quint64(green) << GreenShift
+ | quint64(blue) << BlueShift
+ | quint64(alpha) << AlphaShift;
return rgba64;
}
- Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromRgba64(quint64 c)
+ Q_DECL_RELAXED_CONSTEXPR static
+ QRgba64 fromRgba64(quint64 c)
{
QRgba64 rgba64
#ifdef Q_COMPILER_UNIFORM_INIT
@@ -85,42 +93,49 @@ public:
rgb64.rgba |= rgb64.rgba << 8;
return rgb64;
}
- Q_DECL_RELAXED_CONSTEXPR static QRgba64 fromArgb32(uint rgb)
+ Q_DECL_RELAXED_CONSTEXPR static
+ QRgba64 fromArgb32(uint rgb)
{
return fromRgba(rgb >> 16, rgb >> 8, rgb, rgb >> 24);
}
- Q_DECL_CONSTEXPR bool isOpaque() const { return c.alpha == 0xffff; }
- Q_DECL_CONSTEXPR bool isTransparent() const { return c.alpha == 0; }
-
- Q_DECL_CONSTEXPR quint16 red() const { return c.red; }
- Q_DECL_CONSTEXPR quint16 green() const { return c.green; }
- Q_DECL_CONSTEXPR quint16 blue() const { return c.blue; }
- Q_DECL_CONSTEXPR quint16 alpha() const { return c.alpha; }
- void setRed(quint16 _red) { c.red = _red; }
- void setGreen(quint16 _green) { c.green = _green; }
- void setBlue(quint16 _blue) { c.blue = _blue; }
- void setAlpha(quint16 _alpha) { c.alpha = _alpha; }
-
- Q_DECL_CONSTEXPR quint8 red8() const { return div_257(c.red); }
- Q_DECL_CONSTEXPR quint8 green8() const { return div_257(c.green); }
- Q_DECL_CONSTEXPR quint8 blue8() const { return div_257(c.blue); }
- Q_DECL_CONSTEXPR quint8 alpha8() const { return div_257(c.alpha); }
+ Q_DECL_CONSTEXPR bool isOpaque() const
+ {
+ return (rgba & alphaMask()) == alphaMask();
+ }
+ Q_DECL_CONSTEXPR bool isTransparent() const
+ {
+ return (rgba & alphaMask()) == 0;
+ }
+
+ Q_DECL_CONSTEXPR quint16 red() const { return rgba >> RedShift; }
+ Q_DECL_CONSTEXPR quint16 green() const { return rgba >> GreenShift; }
+ Q_DECL_CONSTEXPR quint16 blue() const { return rgba >> BlueShift; }
+ Q_DECL_CONSTEXPR quint16 alpha() const { return rgba >> AlphaShift; }
+ void setRed(quint16 _red) { *this = fromRgba64(_red, green(), blue(), alpha()); }
+ void setGreen(quint16 _green) { *this = fromRgba64(red(), _green, blue(), alpha()); }
+ void setBlue(quint16 _blue) { *this = fromRgba64(red(), green(), _blue, alpha()); }
+ void setAlpha(quint16 _alpha) { *this = fromRgba64(red(), green(), blue(), _alpha); }
+
+ Q_DECL_CONSTEXPR quint8 red8() const { return div_257(red()); }
+ Q_DECL_CONSTEXPR quint8 green8() const { return div_257(green()); }
+ Q_DECL_CONSTEXPR quint8 blue8() const { return div_257(blue()); }
+ Q_DECL_CONSTEXPR quint8 alpha8() const { return div_257(alpha()); }
Q_DECL_CONSTEXPR uint toArgb32() const
{
return (alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8();
}
Q_DECL_CONSTEXPR ushort toRgb16() const
{
- return (c.red & 0xf800) | ((c.green >> 10) << 5) | (c.blue >> 11);
+ return (red() & 0xf800) | ((green() >> 10) << 5) | (blue() >> 11);
}
Q_DECL_RELAXED_CONSTEXPR QRgba64 premultiplied() const
{
- const quint32 a = c.alpha;
- const quint16 r = div_65535(c.red * a);
- const quint16 g = div_65535(c.green * a);
- const quint16 b = div_65535(c.blue * a);
+ const quint32 a = alpha();
+ const quint16 r = div_65535(red() * a);
+ const quint16 g = div_65535(green() * a);
+ const quint16 b = div_65535(blue() * a);
return fromRgba64(r, g, b, a);
}
@@ -145,27 +160,31 @@ public:
}
private:
+ static Q_DECL_CONSTEXPR quint64 alphaMask() { return quint64(0xffff) << AlphaShift; }
+
static Q_DECL_CONSTEXPR uint div_257_floor(uint x) { return (x - (x >> 8)) >> 8; }
static Q_DECL_CONSTEXPR uint div_257(uint x) { return div_257_floor(x + 128); }
static Q_DECL_CONSTEXPR uint div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied_32bit() const
{
- if (c.alpha == 0xffff || c.alpha == 0)
+ const quint16 a = alpha();
+ if (a == 0xffff || a == 0)
return *this;
- const quint16 r = (quint32(c.red) * 0xffff + c.alpha/2) / c.alpha;
- const quint16 g = (quint32(c.green) * 0xffff + c.alpha/2) / c.alpha;
- const quint16 b = (quint32(c.blue) * 0xffff + c.alpha/2) / c.alpha;
- return fromRgba64(r, g, b, c.alpha);
+ const quint16 r = (quint32(red()) * 0xffff + a/2) / a;
+ const quint16 g = (quint32(green()) * 0xffff + a/2) / a;
+ const quint16 b = (quint32(blue()) * 0xffff + a/2) / a;
+ return fromRgba64(r, g, b, a);
}
Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied_64bit() const
{
- if (c.alpha == 0xffff || c.alpha == 0)
+ const quint16 a = alpha();
+ if (a == 0xffff || a == 0)
return *this;
- const quint64 fa = (Q_UINT64_C(0xffff00008000) + c.alpha/2) / c.alpha;
- const quint16 r = (c.red * fa + 0x80000000) >> 32;
- const quint16 g = (c.green * fa + 0x80000000) >> 32;
- const quint16 b = (c.blue * fa + 0x80000000) >> 32;
- return fromRgba64(r, g, b, c.alpha);
+ const quint64 fa = (Q_UINT64_C(0xffff00008000) + a/2) / a;
+ const quint16 r = (red() * fa + 0x80000000) >> 32;
+ const quint16 g = (green() * fa + 0x80000000) >> 32;
+ const quint16 b = (blue() * fa + 0x80000000) >> 32;
+ return fromRgba64(r, g, b, a);
}
};
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 37be0afccf..246df127ad 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -99,6 +99,13 @@ static bool ft_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *leng
static QFontEngineFT::Glyph emptyGlyph = {0, 0, 0, 0, 0, 0, 0, 0};
+static const QFontEngine::HintStyle ftInitialDefaultHintStyle =
+#ifdef Q_OS_WIN
+ QFontEngineFT::HintFull;
+#else
+ QFontEngineFT::HintNone;
+#endif
+
// -------------------------- Freetype support ------------------------------
class QtFreetypeData
@@ -629,11 +636,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd)
antialias = true;
freetype = 0;
default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
-#ifndef Q_OS_WIN
- default_hint_style = HintNone;
-#else
- default_hint_style = HintFull;
-#endif
+ default_hint_style = ftInitialDefaultHintStyle;
subpixelType = Subpixel_None;
lcdFilterType = 0;
#if defined(FT_LCD_FILTER_H)
@@ -760,6 +763,24 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
return true;
}
+void QFontEngineFT::setQtDefaultHintStyle(QFont::HintingPreference hintingPreference)
+{
+ switch (hintingPreference) {
+ case QFont::PreferNoHinting:
+ setDefaultHintStyle(HintNone);
+ break;
+ case QFont::PreferFullHinting:
+ setDefaultHintStyle(HintFull);
+ break;
+ case QFont::PreferVerticalHinting:
+ setDefaultHintStyle(HintLight);
+ break;
+ case QFont::PreferDefaultHinting:
+ setDefaultHintStyle(ftInitialDefaultHintStyle);
+ break;
+ }
+}
+
void QFontEngineFT::setDefaultHintStyle(HintStyle style)
{
default_hint_style = style;
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 7b28a4064f..b81e51bf2e 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -281,7 +281,7 @@ private:
virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints) Q_DECL_OVERRIDE;
-
+ void setQtDefaultHintStyle(QFont::HintingPreference hintingPreference);
virtual void setDefaultHintStyle(HintStyle style) Q_DECL_OVERRIDE;
virtual QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE;
@@ -307,6 +307,7 @@ private:
friend class QFontEngineFTRawFont;
friend class QFontconfigDatabase;
friend class QBasicFontDatabase;
+ friend class QCoreTextFontDatabase;
friend class QFontEngineMultiFontConfig;
int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const;
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index d2174c5e06..6b98c14205 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1120,6 +1120,15 @@ QT_BEGIN_INCLUDE_NAMESPACE
QT_END_INCLUDE_NAMESPACE
+#if defined(Q_OS_OSX) && !defined(QT_NO_FREETYPE)
+static const char *s_shapersForOsxFreeType[] =
+{
+ "ot",
+ "fallback",
+ Q_NULLPTR
+};
+#endif
+
int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const
{
uint glyphs_shaped = 0;
@@ -1172,7 +1181,15 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
};
const int num_features = 1;
- bool shapedOk = hb_shape_full(hb_font, buffer, features, num_features, 0);
+ const char *const *shaper_list = Q_NULLPTR;
+#if defined(Q_OS_OSX) && !defined(QT_NO_FREETYPE)
+ // What's behind QFontEngine::FaceData::user_data isn't compatible between CoreText and
+ // FreeType font engines - specifically functions in hb-coretext.cc would run into undefined
+ // behavior with data from the FreeType engine. The OpenType shaper works with that engine.
+ if (actualFontEngine->type() == QFontEngine::Freetype)
+ shaper_list = s_shapersForOsxFreeType;
+#endif
+ bool shapedOk = hb_shape_full(hb_font, buffer, features, num_features, shaper_list);
if (Q_UNLIKELY(!shapedOk)) {
hb_buffer_destroy(buffer);
return 0;
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index 088cb80653..3e720ef597 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -115,8 +115,6 @@ public:
QNetworkReplyImplPrivate();
void _q_startOperation();
- void _q_sourceReadyRead();
- void _q_sourceReadChannelFinished();
void _q_copyReadyRead();
void _q_copyReadChannelFinished();
void _q_bufferOutgoingData();
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 35b541d739..371b9e0264 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -1810,12 +1810,12 @@ QString QAbstractSocket::peerName() const
*/
bool QAbstractSocket::canReadLine() const
{
- bool hasLine = d_func()->buffer.canReadLine();
+ bool hasLine = QIODevice::canReadLine();
#if defined (QABSTRACTSOCKET_DEBUG)
qDebug("QAbstractSocket::canReadLine() == %s, buffer size = %lld, size = %lld",
hasLine ? "true" : "false", d_func()->buffer.size(), d_func()->buffer.size());
#endif
- return hasLine || QIODevice::canReadLine();
+ return hasLine;
}
/*!
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index b433c7e97f..23f0d26cbd 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -149,7 +149,7 @@ public:
qint64 bytesAvailable() const Q_DECL_OVERRIDE;
qint64 bytesToWrite() const Q_DECL_OVERRIDE;
- bool canReadLine() const Q_DECL_OVERRIDE;
+ bool canReadLine() const Q_DECL_OVERRIDE; // ### Qt6: remove me
quint16 localPort() const;
QHostAddress localAddress() const;
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index c41061a9fd..b04ae8ee52 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -76,24 +76,6 @@ void QBasicFontDatabase::populateFontDatabase()
}
}
-inline static void setHintingPreference(QFontEngine *engine, QFont::HintingPreference hintingPreference)
-{
- switch (hintingPreference) {
- case QFont::PreferNoHinting:
- engine->setDefaultHintStyle(QFontEngineFT::HintNone);
- break;
- case QFont::PreferFullHinting:
- engine->setDefaultHintStyle(QFontEngineFT::HintFull);
- break;
- case QFont::PreferVerticalHinting:
- engine->setDefaultHintStyle(QFontEngineFT::HintLight);
- break;
- case QFont::PreferDefaultHinting:
- // Leave it as it is
- break;
- }
-}
-
QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPtr)
{
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
@@ -119,7 +101,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPt
delete engine;
engine = 0;
} else {
- setHintingPreference(engine, static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
+ engine->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
}
return engine;
@@ -172,7 +154,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pi
}
fe->updateFamilyNameAndStyle();
- setHintingPreference(fe, hintingPreference);
+ fe->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
return fe;
}
diff --git a/src/platformsupport/fontdatabases/mac/coretext.pri b/src/platformsupport/fontdatabases/mac/coretext.pri
index f67f00672a..ebb64d15b4 100644
--- a/src/platformsupport/fontdatabases/mac/coretext.pri
+++ b/src/platformsupport/fontdatabases/mac/coretext.pri
@@ -1,6 +1,13 @@
HEADERS += $$PWD/qcoretextfontdatabase_p.h $$PWD/qfontengine_coretext_p.h
OBJECTIVE_SOURCES += $$PWD/qfontengine_coretext.mm $$PWD/qcoretextfontdatabase.mm
+contains(QT_CONFIG, freetype) {
+ include($$QT_SOURCE_TREE/src/3rdparty/freetype_dependency.pri)
+ HEADERS += $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h
+ SOURCES += $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp
+ CONFIG += opentype
+}
+
ios: \
# On iOS CoreText and CoreGraphics are stand-alone frameworks
LIBS_PRIVATE += -framework CoreText -framework CoreGraphics
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 75c4065d66..1f000421cc 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -33,6 +33,8 @@
#include "qglobal.h"
+#include <sys/param.h>
+
#if defined(Q_OS_MACX)
#import <Cocoa/Cocoa.h>
#import <IOKit/graphics/IOGraphicsLib.h>
@@ -45,6 +47,9 @@
#include <QtCore/QSettings>
#include <QtGui/QGuiApplication>
#include <QtCore/QtEndian>
+#ifndef QT_NO_FREETYPE
+#include <QtGui/private/qfontengine_ft_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -102,8 +107,12 @@ static NSInteger languageMapSort(id obj1, id obj2, void *context)
}
#endif
-QCoreTextFontDatabase::QCoreTextFontDatabase()
+QCoreTextFontDatabase::QCoreTextFontDatabase(bool useFreeType)
+#ifndef QT_NO_FREETYPE
+ : m_useFreeType(useFreeType)
+#endif
{
+ Q_UNUSED(useFreeType)
#ifdef Q_OS_MACX
QSettings appleSettings(QLatin1String("apple.com"));
QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
@@ -348,10 +357,48 @@ void QCoreTextFontDatabase::releaseHandle(void *handle)
CFRelease(CTFontDescriptorRef(handle));
}
+#ifndef QT_NO_FREETYPE
+static QByteArray filenameForCFUrl(CFURLRef url)
+{
+ // The on-stack buffer prevents that a QByteArray allocated for the worst case (MAXPATHLEN)
+ // stays around for the lifetime of the font. Additionally, it helps to move the char
+ // signedness cast to an acceptable place.
+ uchar buffer[MAXPATHLEN];
+ QByteArray filename;
+
+ if (!CFURLGetFileSystemRepresentation(url, true, buffer, sizeof(buffer))) {
+ qWarning("QCoreTextFontDatabase::filenameForCFUrl: could not resolve file for URL %s",
+ qPrintable(QString::fromCFString(CFURLGetString(url))));
+ } else {
+ QCFType<CFStringRef> scheme = CFURLCopyScheme(url);
+ if (QString::fromCFString(scheme) == QLatin1String("qrc"))
+ filename = ":";
+
+ filename += reinterpret_cast<char *>(buffer);
+ }
+
+ return filename;
+}
+#endif
+
extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
+ CTFontDescriptorRef descriptor = static_cast<CTFontDescriptorRef>(usrPtr);
+
+#ifndef QT_NO_FREETYPE
+ if (m_useFreeType) {
+ QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute)));
+
+ QByteArray filename;
+ if (url)
+ filename = filenameForCFUrl(url);
+
+ return freeTypeFontEngine(f, filename);
+ }
+#endif
+
qreal scaledPointSize = f.pixelSize;
// When 96 DPI is forced, the Mac plugin will use DPI 72 for some
@@ -363,7 +410,6 @@ QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
if (QGuiApplication::testAttribute(Qt::AA_Use96Dpi))
scaledPointSize = f.pointSize;
- CTFontDescriptorRef descriptor = (CTFontDescriptorRef) usrPtr;
CGAffineTransform matrix = qt_transform_from_fontdef(f);
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix);
if (font) {
@@ -385,6 +431,29 @@ static void releaseFontData(void* info, const void* data, size_t size)
QFontEngine *QCoreTextFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
{
+#ifndef QT_NO_FREETYPE
+ if (m_useFreeType) {
+ QByteArray *fontDataCopy = new QByteArray(fontData);
+ QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
+ fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
+ QCFType<CGFontRef> cgFont(CGFontCreateWithDataProvider(dataProvider));
+
+ if (!cgFont) {
+ qWarning("QCoreTextFontDatabase::fontEngine: CGFontCreateWithDataProvider failed");
+ return Q_NULLPTR;
+ }
+
+ QFontDef fontDef;
+ fontDef.pixelSize = pixelSize;
+ fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
+ fontDef.hintingPreference = hintingPreference;
+ CGAffineTransform transform = qt_transform_from_fontdef(fontDef);
+ QCFType<CTFontRef> ctFont(CTFontCreateWithGraphicsFont(cgFont, fontDef.pixelSize, &transform, Q_NULLPTR));
+ QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontCopyAttribute(ctFont, kCTFontURLAttribute)));
+ return freeTypeFontEngine(fontDef, filenameForCFUrl(url), fontData);
+ }
+#endif
+
Q_UNUSED(hintingPreference);
QByteArray* fontDataCopy = new QByteArray(fontData);
@@ -556,10 +625,36 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
}
#if HAVE_CORETEXT
-static CFArrayRef createDescriptorArrayForFont(CTFontRef font)
+static CFArrayRef createDescriptorArrayForFont(CTFontRef font, const QString &fileName = QString())
{
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- CFArrayAppendValue(array, QCFType<CTFontDescriptorRef>(CTFontCopyFontDescriptor(font)));
+ QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
+
+ Q_UNUSED(fileName)
+#ifndef QT_NO_FREETYPE
+ // The physical font source URL (usually a local file or Qt resource) is only required for
+ // FreeType, when using non-system fonts, and needs some hackery to attach in a format
+ // agreeable to OSX.
+ if (!fileName.isEmpty()) {
+ QCFType<CFURLRef> fontURL;
+
+ if (fileName.startsWith(QLatin1String(":/"))) {
+ // QUrl::fromLocalFile() doesn't accept qrc pseudo-paths like ":/fonts/myfont.ttf".
+ // Therefore construct from QString with the qrc:// scheme -> "qrc:///fonts/myfont.ttf".
+ fontURL = QUrl(QStringLiteral("qrc://") + fileName.mid(1)).toCFURL();
+ } else if (!fileName.isEmpty()) {
+ // At this point we hope that filename is in a format that QUrl can handle.
+ fontURL = QUrl::fromLocalFile(fileName).toCFURL();
+ }
+
+ QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 1,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(attributes, kCTFontURLAttribute, fontURL);
+ descriptor = CTFontDescriptorCreateCopyWithAttributes(descriptor, attributes);
+ }
+#endif
+
+ CFArrayAppendValue(array, descriptor);
return array;
}
#endif
@@ -580,7 +675,11 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
if (cgFont) {
if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) {
QCFType<CTFontRef> font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
- fonts = createDescriptorArrayForFont(font);
+ fonts = createDescriptorArrayForFont(font
+#ifndef QT_NO_FREETYPE
+ , m_useFreeType ? fileName : QString()
+#endif
+ );
m_applicationFonts.append(QVariant::fromValue(QCFType<CGFontRef>::constructFromGet(cgFont)));
}
}
@@ -880,5 +979,36 @@ void QCoreTextFontDatabase::removeApplicationFonts()
#endif
}
+#ifndef QT_NO_FREETYPE
+QFontEngine *QCoreTextFontDatabase::freeTypeFontEngine(const QFontDef &fontDef, const QByteArray &filename,
+ const QByteArray &fontData)
+{
+ QFontEngine::FaceId faceId;
+ faceId.filename = filename;
+ const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+
+ QScopedPointer<QFontEngineFT> engine(new QFontEngineFT(fontDef));
+ QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_Mono;
+ if (antialias) {
+ QFontEngine::SubpixelAntialiasingType subpixelType = subpixelAntialiasingTypeHint();
+ if (subpixelType == QFontEngine::Subpixel_None || (fontDef.styleStrategy & QFont::NoSubpixelAntialias)) {
+ format = QFontEngineFT::Format_A8;
+ engine->subpixelType = QFontEngine::Subpixel_None;
+ } else {
+ format = QFontEngineFT::Format_A32;
+ engine->subpixelType = subpixelType;
+ }
+ }
+
+ if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) {
+ qWarning() << "QCoreTextFontDatabase::freeTypefontEngine Failed to create engine";
+ return Q_NULLPTR;
+ }
+ engine->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
+
+ return engine.take();
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index a423ed5ae2..95af1210b3 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
class QCoreTextFontDatabase : public QPlatformFontDatabase
{
public:
- QCoreTextFontDatabase();
+ QCoreTextFontDatabase(bool useFreeType = false);
~QCoreTextFontDatabase();
void populateFontDatabase() Q_DECL_OVERRIDE;
void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
@@ -95,6 +95,11 @@ public:
private:
void populateFromDescriptor(CTFontDescriptorRef font);
+#ifndef QT_NO_FREETYPE
+ bool m_useFreeType;
+ QFontEngine *freeTypeFontEngine(const QFontDef &fontDef, const QByteArray &filename,
+ const QByteArray &fontData = QByteArray());
+#endif
mutable QString defaultFontName;
void removeApplicationFonts();
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index be5e969d2b..b410e5f68e 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -70,18 +70,20 @@ namespace QtAndroidInput
candidatesEnd);
}
- void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints)
+ void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
{
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
"showSoftwareKeyboard",
- "(IIIII)V",
+ "(IIIIII)V",
left,
top,
width,
height,
- inputHints);
+ inputHints,
+ enterKeyType
+ );
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints;
+ qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints << enterKeyType;
#endif
}
diff --git a/src/plugins/platforms/android/androidjniinput.h b/src/plugins/platforms/android/androidjniinput.h
index b5a2ef06e4..d737dc9c98 100644
--- a/src/plugins/platforms/android/androidjniinput.h
+++ b/src/plugins/platforms/android/androidjniinput.h
@@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE
namespace QtAndroidInput
{
// Software keyboard support
- void showSoftwareKeyboard(int top, int left, int width, int height, int inputHints);
+ void showSoftwareKeyboard(int top, int left, int width, int height, int inputHints, int enterKeyType);
void resetSoftwareKeyboard();
void hideSoftwareKeyboard();
bool isSoftwareKeyboardVisible();
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index d264f74d66..b44340106d 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -545,7 +545,9 @@ void QAndroidInputContext::showInputPanel()
rect.top(),
rect.width(),
rect.height(),
- query->value(Qt::ImHints).toUInt());
+ query->value(Qt::ImHints).toUInt(),
+ query->value(Qt::ImEnterKeyType).toUInt()
+ );
}
void QAndroidInputContext::showInputPanelLater(Qt::ApplicationState state)
diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm
index e6c1ed79b2..43ff715161 100644
--- a/src/plugins/platforms/cocoa/main.mm
+++ b/src/plugins/platforms/cocoa/main.mm
@@ -50,11 +50,9 @@ public:
QPlatformIntegration * QCocoaIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
- Q_UNUSED(paramList);
-
QMacAutoReleasePool pool;
if (system.compare(QLatin1String("cocoa"), Qt::CaseInsensitive) == 0)
- return new QCocoaIntegration;
+ return new QCocoaIntegration(paramList);
return 0;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 3b8730151e..32a08dbb0d 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -73,6 +73,7 @@ public:
QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return m_cursor; }
QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE;
QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; }
+ QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE;
// ----------------------------------------------------
// Additional methods
@@ -97,10 +98,16 @@ public:
class QCocoaIntegration : public QPlatformIntegration
{
public:
- QCocoaIntegration();
+ enum Option {
+ UseFreeTypeFontEngine = 0x1
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
+ QCocoaIntegration(const QStringList &paramList);
~QCocoaIntegration();
static QCocoaIntegration *instance();
+ Options options() const;
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
@@ -141,6 +148,7 @@ public:
void setApplicationIcon(const QIcon &icon) const Q_DECL_OVERRIDE;
private:
static QCocoaIntegration *mInstance;
+ Options mOptions;
QScopedPointer<QCoreTextFontDatabase> mFontDb;
@@ -160,6 +168,8 @@ private:
QList<QCocoaWindow *> m_popupWindowStack;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QCocoaIntegration::Options)
+
QT_END_NAMESPACE
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 545e920057..2e6bfc95db 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -142,6 +142,16 @@ qreal QCocoaScreen::devicePixelRatio() const
return qreal(screen ? [screen backingScaleFactor] : 1.0);
}
+QPlatformScreen::SubpixelAntialiasingType QCocoaScreen::subpixelAntialiasingTypeHint() const
+{
+ QPlatformScreen::SubpixelAntialiasingType type = QPlatformScreen::subpixelAntialiasingTypeHint();
+ if (type == QPlatformScreen::Subpixel_None) {
+ // Every OSX machine has RGB pixels unless a peculiar or rotated non-Apple screen is attached
+ type = QPlatformScreen::Subpixel_RGB;
+ }
+ return type;
+}
+
QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
{
NSPoint screenPoint = qt_mac_flipPoint(point);
@@ -244,10 +254,25 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height
return windowPixmap;
}
+static QCocoaIntegration::Options parseOptions(const QStringList &paramList)
+{
+ QCocoaIntegration::Options options;
+ foreach (const QString &param, paramList) {
+#ifndef QT_NO_FREETYPE
+ if (param == QLatin1String("fontengine=freetype"))
+ options |= QCocoaIntegration::UseFreeTypeFontEngine;
+ else
+#endif
+ qWarning() << "Unknown option" << param;
+ }
+ return options;
+}
+
QCocoaIntegration *QCocoaIntegration::mInstance = 0;
-QCocoaIntegration::QCocoaIntegration()
- : mFontDb(new QCoreTextFontDatabase())
+QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
+ : mOptions(parseOptions(paramList))
+ , mFontDb(new QCoreTextFontDatabase(mOptions.testFlag(UseFreeTypeFontEngine)))
#ifndef QT_NO_ACCESSIBILITY
, mAccessibility(new QCocoaAccessibility)
#endif
@@ -345,6 +370,11 @@ QCocoaIntegration *QCocoaIntegration::instance()
return mInstance;
}
+QCocoaIntegration::Options QCocoaIntegration::options() const
+{
+ return mOptions;
+}
+
/*!
\brief Synchronizes the screen list, adds new screens, removes deleted ones
*/
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp
index 94ce23bd2c..707f3bf0ba 100644
--- a/src/plugins/platforms/winrt/qwinrtcursor.cpp
+++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp
@@ -36,11 +36,13 @@
#include "qwinrtcursor.h"
#include "qwinrtscreen.h"
+#include <private/qeventdispatcher_winrt_p.h>
#include <QtCore/qfunctions_winrt.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
+#include <functional>
#include <wrl.h>
#include <windows.ui.core.h>
#include <windows.foundation.h>
@@ -77,12 +79,17 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window)
{
Q_D(QWinRTCursor);
+ HRESULT hr;
ICoreWindow *coreWindow = static_cast<QWinRTScreen *>(window->screen()->handle())->coreWindow();
CoreCursorType type;
switch (windowCursor ? windowCursor->shape() : Qt::ArrowCursor) {
case Qt::BlankCursor:
- coreWindow->put_PointerCursor(Q_NULLPTR);
+ hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow]() {
+ coreWindow->put_PointerCursor(Q_NULLPTR);
+ return S_OK;
+ });
+ RETURN_VOID_IF_FAILED("Failed to set blank native cursor");
return;
default:
case Qt::OpenHandCursor:
@@ -142,11 +149,13 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window)
}
ComPtr<ICoreCursor> cursor;
- HRESULT hr = d->cursorFactory->CreateCursor(type, 0, &cursor);
+ hr = d->cursorFactory->CreateCursor(type, 0, &cursor);
RETURN_VOID_IF_FAILED("Failed to create native cursor.");
- hr = coreWindow->put_PointerCursor(cursor.Get());
- RETURN_VOID_IF_FAILED("Failed to set native cursor.");
+ hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, &cursor]() {
+ return coreWindow->put_PointerCursor(cursor.Get());
+ });
+ RETURN_VOID_IF_FAILED("Failed to set native cursor");
}
#endif // QT_NO_CURSOR
@@ -154,8 +163,12 @@ QPoint QWinRTCursor::pos() const
{
ICoreWindow *coreWindow =
static_cast<QWinRTScreen *>(QGuiApplication::primaryScreen()->handle())->coreWindow();
+ HRESULT hr;
Point point;
- coreWindow->get_PointerPosition(&point);
+ hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, &point]() {
+ return coreWindow->get_PointerPosition(&point);
+ });
+ RETURN_IF_FAILED("Failed to get native cursor position", QPoint());
return QPoint(point.X, point.Y);
}
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
index 42ffe8f716..44aab266ca 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
@@ -35,38 +35,131 @@
****************************************************************************/
#include "qwinrteglcontext.h"
+#include "qwinrtwindow.h"
+#include <private/qeventdispatcher_winrt_p.h>
+#include <functional>
+
+#include <EGL/egl.h>
#define EGL_EGLEXT_PROTOTYPES
-#include "EGL/eglext.h"
+#include <EGL/eglext.h>
+
+#include <QOpenGLContext>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
QT_BEGIN_NAMESPACE
-QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config)
- : QEGLPlatformContext(format, share, display, &config), m_eglSurface(surface)
+class QWinRTEGLContextPrivate
+{
+public:
+ QSurfaceFormat format;
+ EGLDisplay eglDisplay;
+ EGLConfig eglConfig;
+ EGLContext eglContext;
+ QHash<QPlatformSurface *, EGLSurface> surfaceForWindow;
+};
+
+QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context)
+ : d_ptr(new QWinRTEGLContextPrivate)
+{
+ Q_D(QWinRTEGLContext);
+ d->format = context->format();
+ d->format.setRenderableType(QSurfaceFormat::OpenGLES);
+}
+
+QWinRTEGLContext::~QWinRTEGLContext()
{
+ Q_D(QWinRTEGLContext);
+ foreach (const EGLSurface &surface, d->surfaceForWindow)
+ eglDestroySurface(d->eglDisplay, surface);
+ if (d->eglContext != EGL_NO_CONTEXT)
+ eglDestroyContext(d->eglDisplay, d->eglContext);
+ if (d->eglDisplay != EGL_NO_DISPLAY)
+ eglTerminate(d->eglDisplay);
}
-void QWinRTEGLContext::swapBuffers(QPlatformSurface *surface)
+void QWinRTEGLContext::initialize()
{
-#ifdef Q_OS_WINPHONE
- const QSize size = surface->surface()->size();
- eglPostSubBufferNV(eglDisplay(), eglSurfaceForPlatformSurface(surface),
- 0, 0, size.width(), size.height());
-#else
- eglSwapBuffers(eglDisplay(), eglSurfaceForPlatformSurface(surface));
-#endif
+ Q_D(QWinRTEGLContext);
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (d->eglDisplay == EGL_NO_DISPLAY)
+ qCritical("Failed to initialize EGL display: 0x%x", eglGetError());
+
+ if (!eglInitialize(d->eglDisplay, nullptr, nullptr))
+ qCritical("Failed to initialize EGL: 0x%x", eglGetError());
+
+ d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->format);
+
+ const EGLint flags = d->format.testOption(QSurfaceFormat::DebugContext)
+ ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0;
+ const EGLint attributes[] = {
+ EGL_CONTEXT_CLIENT_VERSION, d->format.majorVersion(),
+ EGL_CONTEXT_MINOR_VERSION_KHR, d->format.minorVersion(),
+ EGL_CONTEXT_FLAGS_KHR, flags,
+ EGL_NONE
+ };
+ d->eglContext = eglCreateContext(d->eglDisplay, d->eglConfig, nullptr, attributes);
+ if (d->eglContext == EGL_NO_CONTEXT) {
+ qWarning("QEGLPlatformContext: Failed to create context: %x", eglGetError());
+ return;
+ }
}
-EGLSurface QWinRTEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface)
{
- 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;
+ Q_D(QWinRTEGLContext);
+ Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface);
+
+ EGLSurface surface = d->surfaceForWindow.value(windowSurface);
+ if (surface == EGL_NO_SURFACE) {
+ QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d, window, &surface]() {
+ surface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig,
+ reinterpret_cast<EGLNativeWindowType>(window->winId()),
+ nullptr);
+ if (surface == EGL_NO_SURFACE) {
+ qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
+ return E_FAIL;
+ }
+ return S_OK;
+ });
+ if (FAILED(hr))
+ return false;
+ d->surfaceForWindow.insert(windowSurface, surface);
}
+
+ const bool ok = eglMakeCurrent(d->eglDisplay, surface, surface, d->eglContext);
+ if (!ok) {
+ qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError());
+ return false;
+ }
+
+ eglSwapInterval(d->eglDisplay, d->format.swapInterval());
+ return true;
+}
+
+void QWinRTEGLContext::doneCurrent()
+{
+ Q_D(const QWinRTEGLContext);
+ const bool ok = eglMakeCurrent(d->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (!ok)
+ qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError());
+}
+
+void QWinRTEGLContext::swapBuffers(QPlatformSurface *windowSurface)
+{
+ Q_D(QWinRTEGLContext);
+ Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface);
+
+ eglSwapBuffers(d->eglDisplay, d->surfaceForWindow.value(windowSurface));
+}
+
+QSurfaceFormat QWinRTEGLContext::format() const
+{
+ Q_D(const QWinRTEGLContext);
+ return d->format;
}
QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
@@ -221,7 +314,7 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
if (i != standardFuncs.end())
return i.value();
- return QEGLPlatformContext::getProcAddress(procName);
+ return eglGetProcAddress(procName.constData());
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h
index 958d623c4c..31a2124b03 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.h
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.h
@@ -37,23 +37,29 @@
#ifndef QWINDOWSEGLCONTEXT_H
#define QWINDOWSEGLCONTEXT_H
-#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+#include <qpa/qplatformopenglcontext.h>
QT_BEGIN_NAMESPACE
-class QWinRTEGLContext : public QEGLPlatformContext
+class QWinRTEGLContextPrivate;
+class QWinRTEGLContext : public QPlatformOpenGLContext
{
public:
- explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config);
+ explicit QWinRTEGLContext(QOpenGLContext *context);
+ ~QWinRTEGLContext();
- void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
+ void initialize() Q_DECL_OVERRIDE;
+
+ bool makeCurrent(QPlatformSurface *windowSurface) Q_DECL_OVERRIDE;
+ void doneCurrent() Q_DECL_OVERRIDE;
+ void swapBuffers(QPlatformSurface *windowSurface) Q_DECL_OVERRIDE;
-protected:
- EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
+ QSurfaceFormat format() const Q_DECL_OVERRIDE;
+ QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
private:
- EGLSurface m_eglSurface;
+ QScopedPointer<QWinRTEGLContextPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTEGLContext)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
index c94b53ef1c..7bd9e87ca6 100644
--- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
@@ -182,135 +182,6 @@ void QWinRTInputContext::hideInputPanel()
qErrnoWarning(hr, "Failed to hide input panel.");
}
-#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_screen->coreWindow();
- break;
- }
- return S_OK;
-}
-
-HRESULT QWinRTInputContext::get_HostRawElementProvider(IRawElementProviderSimple **retVal)
-{
- // Return the window's element provider
- IInspectable *hostProvider;
- HRESULT hr = m_screen->coreWindow()->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
+#endif // Q_OS_WINPHONE
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h
index ce7fbabf49..cc3bce435f 100644
--- a/src/plugins/platforms/winrt/qwinrtinputcontext.h
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h
@@ -41,9 +41,6 @@
#include <QtCore/QRectF>
#include <wrl.h>
-#ifndef Q_OS_WINPHONE
-# include <UIAutomationCore.h>
-#endif
namespace ABI {
namespace Windows {
@@ -63,11 +60,6 @@ QT_BEGIN_NAMESPACE
class QWinRTScreen;
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(QWinRTScreen *);
@@ -79,26 +71,7 @@ public:
#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
+#endif
private:
HRESULT onShowing(ABI::Windows::UI::ViewManagement::IInputPane *,
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index 70ee6dbe6a..7079d46523 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -45,37 +45,138 @@
#include "qwinrtfontdatabase.h"
#include "qwinrttheme.h"
+#include <QtCore/QCoreApplication>
+#include <QtGui/QSurface>
#include <QtGui/QOpenGLContext>
+#include <qfunctions_winrt.h>
+#include <functional>
#include <wrl.h>
+#include <windows.ui.xaml.h>
+#include <windows.applicationmodel.h>
+#include <windows.applicationmodel.core.h>
#include <windows.ui.core.h>
#include <windows.ui.viewmanagement.h>
-#include <Windows.ApplicationModel.core.h>
+#include <windows.graphics.display.h>
+#ifdef Q_OS_WINPHONE
+# include <windows.phone.ui.input.h>
+#endif
using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::ApplicationModel;
+using namespace ABI::Windows::ApplicationModel::Core;
+using namespace ABI::Windows::UI;
using namespace ABI::Windows::UI::Core;
using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::Graphics::Display;
using namespace ABI::Windows::ApplicationModel::Core;
+#ifdef Q_OS_WINPHONE
+using namespace ABI::Windows::Phone::UI::Input;
+#endif
+
+typedef IEventHandler<IInspectable *> ResumeHandler;
+typedef IEventHandler<SuspendingEventArgs *> SuspendHandler;
+#ifdef Q_OS_WINPHONE
+typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
+#endif
QT_BEGIN_NAMESPACE
-QWinRTIntegration::QWinRTIntegration()
- : m_success(false)
- , m_fontDatabase(new QWinRTFontDatabase)
- , m_services(new QWinRTServices)
+typedef HRESULT (__stdcall ICoreApplication::*CoreApplicationCallbackRemover)(EventRegistrationToken);
+uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
+#ifdef Q_OS_WINPHONE
+typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken);
+uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
+#endif
+
+class QWinRTIntegrationPrivate
+{
+public:
+ QPlatformFontDatabase *fontDatabase;
+ QPlatformServices *platformServices;
+ QWinRTScreen *mainScreen;
+ QScopedPointer<QWinRTInputContext> inputContext;
+
+ ComPtr<ICoreApplication> application;
+ QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
+#ifdef Q_OS_WINPHONE
+ ComPtr<IHardwareButtonsStatics> hardwareButtons;
+ QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens;
+#endif
+};
+
+QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
{
- m_screen = new QWinRTScreen;
- screenAdded(m_screen);
+ Q_D(QWinRTIntegration);
+
+ d->fontDatabase = new QWinRTFontDatabase;
+
+ HRESULT hr;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&d->application));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTIntegration::onSuspended).Get(),
+ &d->applicationTokens[&ICoreApplication::remove_Resuming]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTIntegration::onResume).Get(),
+ &d->applicationTokens[&ICoreApplication::remove_Resuming]);
+ Q_ASSERT_SUCCEEDED(hr);
- m_success = true;
+#ifdef Q_OS_WINPHONE
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(),
+ IID_PPV_ARGS(&d->hardwareButtons));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTIntegration::onBackButtonPressed).Get(),
+ &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]);
+ Q_ASSERT_SUCCEEDED(hr);
+#endif // Q_OS_WINPHONE
+
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ HRESULT hr;
+ ComPtr<Xaml::IWindowStatics> windowStatics;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(),
+ IID_PPV_ARGS(&windowStatics));
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Xaml::IWindow> window;
+ hr = windowStatics->get_Current(&window);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = window->Activate();
+ Q_ASSERT_SUCCEEDED(hr);
+
+ d->mainScreen = new QWinRTScreen(window.Get());
+ d->inputContext.reset(new QWinRTInputContext(d->mainScreen));
+ screenAdded(d->mainScreen);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
}
QWinRTIntegration::~QWinRTIntegration()
{
+ Q_D(QWinRTIntegration);
+ HRESULT hr;
+#ifdef Q_OS_WINPHONE
+ for (QHash<HardwareButtonsCallbackRemover, EventRegistrationToken>::const_iterator i = d->buttonsTokens.begin(); i != d->buttonsTokens.end(); ++i) {
+ hr = (d->hardwareButtons.Get()->*i.key())(i.value());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+#endif
+ for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i) {
+ hr = (d->application.Get()->*i.key())(i.value());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ destroyScreen(d->mainScreen);
Windows::Foundation::Uninitialize();
}
+bool QWinRTIntegration::succeeded() const
+{
+ Q_D(const QWinRTIntegration);
+ return d->mainScreen;
+}
+
QAbstractEventDispatcher *QWinRTIntegration::createEventDispatcher() const
{
return new QWinRTEventDispatcher;
@@ -112,28 +213,31 @@ QPlatformBackingStore *QWinRTIntegration::createPlatformBackingStore(QWindow *wi
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(), screen->eglConfig());
+ return new QWinRTEGLContext(context);
}
QPlatformFontDatabase *QWinRTIntegration::fontDatabase() const
{
- return m_fontDatabase;
+ Q_D(const QWinRTIntegration);
+ return d->fontDatabase;
}
QPlatformInputContext *QWinRTIntegration::inputContext() const
{
- return m_screen->inputContext();
+ Q_D(const QWinRTIntegration);
+ return d->inputContext.data();
}
QPlatformServices *QWinRTIntegration::services() const
{
- return m_services;
+ Q_D(const QWinRTIntegration);
+ return d->platformServices;
}
Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
{
- return m_screen->keyboardModifiers();
+ Q_D(const QWinRTIntegration);
+ return d->mainScreen->keyboardModifiers();
}
QStringList QWinRTIntegration::themeNames() const
@@ -149,4 +253,45 @@ name) const
return 0;
}
+
+// System-level integration points
+
+#ifdef Q_OS_WINPHONE
+HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
+{
+ Q_D(QWinRTIntegration);
+
+ QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
+ QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
+ backPress.setAccepted(false);
+ backRelease.setAccepted(false);
+
+ QWindow *window = d->mainScreen->topWindow();
+ QObject *receiver = window ? static_cast<QObject *>(window)
+ : static_cast<QObject *>(QCoreApplication::instance());
+
+ // If the event is ignored, the app go to the background
+ QCoreApplication::sendEvent(receiver, &backPress);
+ QCoreApplication::sendEvent(receiver, &backRelease);
+ args->put_Handled(backPress.isAccepted() || backRelease.isAccepted());
+
+ return S_OK;
+}
+#endif // Q_OS_WINPHONE
+
+HRESULT QWinRTIntegration::onSuspended(IInspectable *, ISuspendingEventArgs *)
+{
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
+ QWindowSystemInterface::flushWindowSystemEvents();
+ return S_OK;
+}
+
+HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *)
+{
+ // First the system invokes onResume and then changes
+ // the visibility of the screen to be active.
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationHidden);
+ return S_OK;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h
index bbd6c1e41b..0115e034b5 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.h
+++ b/src/plugins/platforms/winrt/qwinrtintegration.h
@@ -39,11 +39,33 @@
#include <qpa/qplatformintegration.h>
+namespace ABI {
+ namespace Windows {
+ namespace ApplicationModel {
+ struct ISuspendingEventArgs;
+ }
+ namespace Foundation {
+ struct IAsyncAction;
+ }
+#ifdef Q_OS_WINPHONE
+ namespace Phone {
+ namespace UI {
+ namespace Input {
+ struct IBackPressedEventArgs;
+ }
+ }
+ }
+#endif
+ }
+}
+struct IAsyncInfo;
+struct IInspectable;
+
QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
-class QWinRTScreen;
+class QWinRTIntegrationPrivate;
class QWinRTIntegration : public QPlatformIntegration
{
private:
@@ -53,10 +75,12 @@ public:
static QWinRTIntegration *create()
{
- QWinRTIntegration *integration = new QWinRTIntegration;
- return integration->m_success ? integration : 0;
+ QScopedPointer<QWinRTIntegration> integration(new QWinRTIntegration);
+ return integration->succeeded() ? integration.take() : nullptr;
}
+ bool succeeded() const;
+
bool hasCapability(QPlatformIntegration::Capability cap) const;
QVariant styleHint(StyleHint hint) const;
@@ -71,11 +95,16 @@ public:
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
+
private:
- bool m_success;
- QWinRTScreen *m_screen;
- QPlatformFontDatabase *m_fontDatabase;
- QPlatformServices *m_services;
+#ifdef Q_OS_WINPHONE
+ HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
+#endif
+ HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
+ HRESULT onResume(IInspectable *, IInspectable *);
+
+ QScopedPointer<QWinRTIntegrationPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTIntegration)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 1d36bb31f6..89ad33657b 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -36,26 +36,18 @@
#include "qwinrtscreen.h"
-#define EGL_EGLEXT_PROTOTYPES
-#include <EGL/eglext.h>
-#include <d3d11.h>
-#include <dxgi1_2.h>
-#ifndef Q_OS_WINPHONE
-#include <dxgi1_3.h>
-#endif
-
#include "qwinrtbackingstore.h"
#include "qwinrtinputcontext.h"
#include "qwinrtcursor.h"
-#include "qwinrteglcontext.h"
+#include <private/qeventdispatcher_winrt_p.h>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QGuiApplication>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/qt_windows.h>
#include <QtCore/qfunctions_winrt.h>
+#include <functional>
#include <wrl.h>
#include <windows.system.h>
#include <Windows.Applicationmodel.h>
@@ -64,12 +56,10 @@
#include <windows.ui.h>
#include <windows.ui.core.h>
#include <windows.ui.input.h>
+#include <windows.ui.xaml.h>
#include <windows.ui.viewmanagement.h>
#include <windows.graphics.display.h>
#include <windows.foundation.h>
-#ifdef Q_OS_WINPHONE
-#include <windows.phone.ui.input.h>
-#endif
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@@ -77,17 +67,13 @@ using namespace ABI::Windows::ApplicationModel;
using namespace ABI::Windows::ApplicationModel::Core;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::System;
+using namespace ABI::Windows::UI;
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;
-#ifdef Q_OS_WINPHONE
-using namespace ABI::Windows::Phone::UI::Input;
-#endif
-typedef IEventHandler<IInspectable*> ResumeHandler;
-typedef IEventHandler<SuspendingEventArgs*> SuspendHandler;
typedef ITypedEventHandler<CoreWindow*, WindowActivatedEventArgs*> ActivatedHandler;
typedef ITypedEventHandler<CoreWindow*, CoreWindowEventArgs*> ClosedHandler;
typedef ITypedEventHandler<CoreWindow*, CharacterReceivedEventArgs*> CharacterReceivedHandler;
@@ -96,11 +82,7 @@ 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;
typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler;
-#ifdef Q_OS_WINPHONE
-typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
-#endif
QT_BEGIN_NAMESPACE
@@ -419,33 +401,23 @@ static inline Qt::Key qKeyFromCode(quint32 code, int mods)
return static_cast<Qt::Key>(code & 0xff);
}
-typedef HRESULT (__stdcall ICoreApplication::*CoreApplicationCallbackRemover)(EventRegistrationToken);
-uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
typedef HRESULT (__stdcall ICoreWindow::*CoreWindowCallbackRemover)(EventRegistrationToken);
uint qHash(CoreWindowCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRegistrationToken);
uint qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
-#ifdef Q_OS_WINPHONE
-typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken);
-uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
-#endif
class QWinRTScreenPrivate
{
public:
- ComPtr<ICoreApplication> application;
+ QTouchDevice *touchDevice;
ComPtr<ICoreWindow> coreWindow;
+ ComPtr<Xaml::IDependencyObject> canvas;
+ ComPtr<IApplicationView> view;
ComPtr<IDisplayInformation> displayInformation;
-#ifdef Q_OS_WINPHONE
- ComPtr<IHardwareButtonsStatics> hardwareButtons;
-#endif
QScopedPointer<QWinRTCursor> cursor;
-#ifdef Q_OS_WINPHONE
- QScopedPointer<QWinRTInputContext> inputContext;
-#else
- ComPtr<QWinRTInputContext> inputContext;
-#endif
+
+ QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints;
QSizeF logicalSize;
QSurfaceFormat surfaceFormat;
@@ -458,68 +430,30 @@ public:
#ifndef Q_OS_WINPHONE
QHash<quint32, QPair<Qt::Key, QString>> activeKeys;
#endif
- QTouchDevice *touchDevice;
- QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints;
- EGLDisplay eglDisplay;
- EGLSurface eglSurface;
- EGLConfig eglConfig;
-
- QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens;
QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens;
-#ifdef Q_OS_WINPHONE
- QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens;
-#endif
};
-QWinRTScreen::QWinRTScreen()
+// To be called from the XAML thread
+QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow)
: d_ptr(new QWinRTScreenPrivate)
{
Q_D(QWinRTScreen);
d->orientation = Qt::PrimaryOrientation;
d->touchDevice = Q_NULLPTR;
- d->eglDisplay = EGL_NO_DISPLAY;
- // Obtain the WinRT Application, view, and window
HRESULT hr;
- hr = RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
- IID_PPV_ARGS(&d->application));
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTScreen::onSuspended).Get(), &d->applicationTokens[&ICoreApplication::remove_Resuming]);
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTScreen::onResume).Get(), &d->applicationTokens[&ICoreApplication::remove_Resuming]);
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<ICoreApplicationView> view;
- hr = d->application->GetCurrentView(&view);
- Q_ASSERT_SUCCEEDED(hr);
- hr = view->get_CoreWindow(&d->coreWindow);
+ hr = xamlWindow->get_CoreWindow(&d->coreWindow);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->Activate();
Q_ASSERT_SUCCEEDED(hr);
-#ifdef Q_OS_WINPHONE
- d->inputContext.reset(new QWinRTInputContext(this));
-#else
- d->inputContext = Make<QWinRTInputContext>(this);
-#endif
-
Rect rect;
hr = d->coreWindow->get_Bounds(&rect);
Q_ASSERT_SUCCEEDED(hr);
d->logicalSize = QSizeF(rect.Width, rect.Height);
- d->surfaceFormat.setAlphaBufferSize(0);
- d->surfaceFormat.setRedBufferSize(8);
- d->surfaceFormat.setGreenBufferSize(8);
- d->surfaceFormat.setBlueBufferSize(8);
- d->surfaceFormat.setDepthBufferSize(24);
- d->surfaceFormat.setStencilBufferSize(8);
- d->surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
- d->surfaceFormat.setSamples(1);
- d->surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
-
hr = d->coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]);
@@ -538,24 +472,14 @@ QWinRTScreen::QWinRTScreen()
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
Q_ASSERT_SUCCEEDED(hr);
-#ifndef Q_OS_WINPHONE
hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
Q_ASSERT_SUCCEEDED(hr);
-#endif
hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]);
Q_ASSERT_SUCCEEDED(hr);
- hr = d->coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &d->windowTokens[&ICoreWindow::remove_AutomationProviderRequested]);
- Q_ASSERT_SUCCEEDED(hr);
-#ifdef Q_OS_WINPHONE
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), IID_PPV_ARGS(&d->hardwareButtons));
- Q_ASSERT_SUCCEEDED(hr);
- hr = d->hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTScreen::onBackButtonPressed).Get(), &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]);
- Q_ASSERT_SUCCEEDED(hr);
-#endif // Q_OS_WINPHONE
// Orientation handling
ComPtr<IDisplayInformationStatics> displayInformationStatics;
@@ -583,45 +507,34 @@ QWinRTScreen::QWinRTScreen()
d->orientation = d->nativeOrientation;
onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
- d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (d->eglDisplay == EGL_NO_DISPLAY)
- qCritical("Failed to initialize EGL display: 0x%x", eglGetError());
-
- if (!eglInitialize(d->eglDisplay, NULL, NULL))
- qCritical("Failed to initialize EGL: 0x%x", eglGetError());
-
- // Check that the device properly supports depth/stencil rendering, and disable them if not
- ComPtr<ID3D11Device> d3dDevice;
- const EGLBoolean ok = eglQuerySurfacePointerANGLE(d->eglDisplay, EGL_NO_SURFACE, EGL_DEVICE_EXT, (void **)d3dDevice.GetAddressOf());
- if (ok && d3dDevice) {
- ComPtr<IDXGIDevice> dxgiDevice;
- hr = d3dDevice.As(&dxgiDevice);
- if (SUCCEEDED(hr)) {
- ComPtr<IDXGIAdapter> dxgiAdapter;
- hr = dxgiDevice->GetAdapter(&dxgiAdapter);
- if (SUCCEEDED(hr)) {
- ComPtr<IDXGIAdapter2> dxgiAdapter2;
- hr = dxgiAdapter.As(&dxgiAdapter2);
- if (SUCCEEDED(hr)) {
- DXGI_ADAPTER_DESC2 desc;
- hr = dxgiAdapter2->GetDesc2(&desc);
- if (SUCCEEDED(hr)) {
- // The following GPUs do not render properly with depth/stencil
- if ((desc.VendorId == 0x4d4f4351 && desc.DeviceId == 0x32303032)) { // Qualcomm Adreno 225
- d->surfaceFormat.setDepthBufferSize(-1);
- d->surfaceFormat.setStencilBufferSize(-1);
- }
- }
- }
- }
- }
- }
+ ComPtr<IApplicationViewStatics2> applicationViewStatics;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
+ IID_PPV_ARGS(&applicationViewStatics));
+ RETURN_VOID_IF_FAILED("Could not get ApplicationViewStatics");
- d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->surfaceFormat);
- d->surfaceFormat = q_glFormatFromConfig(d->eglDisplay, d->eglConfig, d->surfaceFormat);
- d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), NULL);
- if (d->eglSurface == EGL_NO_SURFACE)
- qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
+ hr = applicationViewStatics->GetForCurrentView(&d->view);
+ RETURN_VOID_IF_FAILED("Could not access currentView");
+
+ // Create a canvas and set it as the window content. Eventually, this should have its own method so multiple "screens" can be added
+ ComPtr<Xaml::Controls::ICanvas> canvas;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_Canvas).Get(), &canvas);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Xaml::IFrameworkElement> frameworkElement;
+ hr = canvas.As(&frameworkElement);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = frameworkElement->put_Width(d->logicalSize.width());
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = frameworkElement->put_Height(d->logicalSize.height());
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Xaml::IUIElement> uiElement;
+ hr = canvas.As(&uiElement);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = xamlWindow->put_Content(uiElement.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = canvas.As(&d->canvas);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ d->cursor.reset(new QWinRTCursor);
}
QWinRTScreen::~QWinRTScreen()
@@ -629,16 +542,20 @@ QWinRTScreen::~QWinRTScreen()
Q_D(QWinRTScreen);
// Unregister callbacks
- for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i)
- (d->application.Get()->*i.key())(i.value());
- for (QHash<CoreWindowCallbackRemover, EventRegistrationToken>::const_iterator i = d->windowTokens.begin(); i != d->windowTokens.end(); ++i)
- (d->coreWindow.Get()->*i.key())(i.value());
- for (QHash<DisplayCallbackRemover, EventRegistrationToken>::const_iterator i = d->displayTokens.begin(); i != d->displayTokens.end(); ++i)
- (d->displayInformation.Get()->*i.key())(i.value());
-#ifdef Q_OS_WINPHONE
- for (QHash<HardwareButtonsCallbackRemover, EventRegistrationToken>::const_iterator i = d->buttonsTokens.begin(); i != d->buttonsTokens.end(); ++i)
- (d->hardwareButtons.Get()->*i.key())(i.value());
-#endif
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ HRESULT hr;
+ for (QHash<CoreWindowCallbackRemover, EventRegistrationToken>::const_iterator i = d->windowTokens.begin(); i != d->windowTokens.end(); ++i) {
+ hr = (d->coreWindow.Get()->*i.key())(i.value());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ for (QHash<DisplayCallbackRemover, EventRegistrationToken>::const_iterator i = d->displayTokens.begin(); i != d->displayTokens.end(); ++i) {
+ hr = (d->displayInformation.Get()->*i.key())(i.value());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ return hr;
+ });
+ RETURN_VOID_IF_FAILED("Failed to unregister screen event callbacks");
}
QRect QWinRTScreen::geometry() const
@@ -657,12 +574,6 @@ QImage::Format QWinRTScreen::format() const
return QImage::Format_ARGB32_Premultiplied;
}
-QSurfaceFormat QWinRTScreen::surfaceFormat() const
-{
- Q_D(const QWinRTScreen);
- return d->surfaceFormat;
-}
-
QSizeF QWinRTScreen::physicalSize() const
{
Q_D(const QWinRTScreen);
@@ -682,21 +593,9 @@ qreal QWinRTScreen::scaleFactor() const
return d->scaleFactor;
}
-QWinRTInputContext *QWinRTScreen::inputContext() const
-{
- Q_D(const QWinRTScreen);
-#ifdef Q_OS_WINPHONE
- return d->inputContext.data();
-#else
- return d->inputContext.Get();
-#endif
-}
-
QPlatformCursor *QWinRTScreen::cursor() const
{
Q_D(const QWinRTScreen);
- if (!d->cursor)
- const_cast<QWinRTScreenPrivate *>(d)->cursor.reset(new QWinRTCursor);
return d->cursor.data();
}
@@ -744,22 +643,10 @@ ICoreWindow *QWinRTScreen::coreWindow() const
return d->coreWindow.Get();
}
-EGLDisplay QWinRTScreen::eglDisplay() const
-{
- Q_D(const QWinRTScreen);
- return d->eglDisplay;
-}
-
-EGLSurface QWinRTScreen::eglSurface() const
-{
- Q_D(const QWinRTScreen);
- return d->eglSurface;
-}
-
-EGLConfig QWinRTScreen::eglConfig() const
+Xaml::IDependencyObject *QWinRTScreen::canvas() const
{
Q_D(const QWinRTScreen);
- return d->eglConfig;
+ return d->canvas.Get();
}
QWindow *QWinRTScreen::topWindow() const
@@ -809,6 +696,20 @@ void QWinRTScreen::lower(QWindow *window)
handleExpose();
}
+void QWinRTScreen::updateWindowTitle()
+{
+ Q_D(QWinRTScreen);
+
+ QWindow *window = topWindow();
+ if (!window)
+ return;
+
+ const QString title = window->title();
+ HStringReference titleRef(reinterpret_cast<LPCWSTR>(title.utf16()), title.length());
+ HRESULT hr = d->view->put_Title(titleRef.Get());
+ RETURN_VOID_IF_FAILED("Unable to set window title");
+}
+
void QWinRTScreen::handleExpose()
{
Q_D(QWinRTScreen);
@@ -1055,17 +956,6 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
return S_OK;
}
-HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args)
-{
-#ifndef Q_OS_WINPHONE
- Q_D(const QWinRTScreen);
- args->put_AutomationProvider(d->inputContext.Get());
-#else
- Q_UNUSED(args)
-#endif
- return S_OK;
-}
-
HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *)
{
Q_D(QWinRTScreen);
@@ -1075,18 +965,14 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
hr = d->coreWindow->get_Bounds(&size);
RETURN_OK_IF_FAILED("Failed to get window bounds");
QSizeF logicalSize = QSizeF(size.Width, size.Height);
-#ifndef Q_OS_WINPHONE // This handler is called from orientation changed, in which case we should always update the size
if (d->logicalSize == logicalSize)
return S_OK;
-#endif
d->logicalSize = logicalSize;
- if (d->eglDisplay) {
- const QRect newGeometry = geometry();
- QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
- QPlatformScreen::resizeMaximizedWindows();
- handleExpose();
- }
+ const QRect newGeometry = geometry();
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
+ QPlatformScreen::resizeMaximizedWindows();
+ handleExpose();
return S_OK;
}
@@ -1110,31 +996,6 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args
return S_OK;
}
-HRESULT QWinRTScreen::onSuspended(IInspectable *, ISuspendingEventArgs *)
-{
-#ifndef Q_OS_WINPHONE
- Q_D(QWinRTScreen);
- ComPtr<ID3D11Device> d3dDevice;
- const EGLBoolean ok = eglQuerySurfacePointerANGLE(d->eglDisplay, EGL_NO_SURFACE, EGL_DEVICE_EXT, (void **)d3dDevice.GetAddressOf());
- if (ok && d3dDevice) {
- ComPtr<IDXGIDevice3> dxgiDevice;
- if (SUCCEEDED(d3dDevice.As(&dxgiDevice)))
- dxgiDevice->Trim();
- }
-#endif
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
- QWindowSystemInterface::flushWindowSystemEvents();
- return S_OK;
-}
-
-HRESULT QWinRTScreen::onResume(IInspectable *, IInspectable *)
-{
- // First the system invokes onResume and then changes
- // the visibility of the screen to be active.
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationHidden);
- return S_OK;
-}
-
HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *)
{
foreach (QWindow *w, QGuiApplication::topLevelWindows())
@@ -1165,10 +1026,6 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *
d->orientation = newOrientation;
QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
}
-
-#ifdef Q_OS_WINPHONE // The size changed handler is ignored in favor of this callback
- onSizeChanged(Q_NULLPTR, Q_NULLPTR);
-#endif
return S_OK;
}
@@ -1205,27 +1062,4 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
return S_OK;
}
-#ifdef Q_OS_WINPHONE
-HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
-{
- Q_D(QWinRTScreen);
-
- QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
- QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
- backPress.setAccepted(false);
- backRelease.setAccepted(false);
-
- QObject *receiver = d->visibleWindows.isEmpty()
- ? static_cast<QObject *>(QGuiApplication::instance())
- : static_cast<QObject *>(d->visibleWindows.first());
-
- // If the event is ignored, the app will suspend
- QGuiApplication::sendEvent(receiver, &backPress);
- QGuiApplication::sendEvent(receiver, &backRelease);
- args->put_Handled(backPress.isAccepted() || backRelease.isAccepted());
-
- return S_OK;
-}
-#endif // Q_OS_WINPHONE
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index d34ce75748..796e6abb80 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -40,8 +40,6 @@
#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
-#include <EGL/egl.h>
-
namespace ABI {
namespace Windows {
namespace ApplicationModel {
@@ -59,21 +57,16 @@ namespace ABI {
struct IWindowActivatedEventArgs;
struct IWindowSizeChangedEventArgs;
}
+ namespace Xaml {
+ struct IDependencyObject;
+ struct IWindow;
+ }
}
namespace Graphics {
namespace Display {
struct IDisplayInformation;
}
}
-#ifdef Q_OS_WINPHONE
- namespace Phone {
- namespace UI {
- namespace Input {
- struct IBackPressedEventArgs;
- }
- }
- }
-#endif
}
}
struct IInspectable;
@@ -81,23 +74,20 @@ struct IInspectable;
QT_BEGIN_NAMESPACE
class QTouchDevice;
-class QWinRTEGLContext;
class QWinRTCursor;
class QWinRTInputContext;
class QWinRTScreenPrivate;
class QWinRTScreen : public QPlatformScreen
{
public:
- explicit QWinRTScreen();
+ explicit QWinRTScreen(ABI::Windows::UI::Xaml::IWindow *xamlWindow);
~QWinRTScreen();
QRect geometry() const;
int depth() const;
QImage::Format format() const;
- QSurfaceFormat surfaceFormat() const;
QSizeF physicalSize() const Q_DECL_OVERRIDE;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
qreal scaleFactor() const;
- QWinRTInputContext *inputContext() const;
QPlatformCursor *cursor() const;
Qt::KeyboardModifiers keyboardModifiers() const;
@@ -110,10 +100,10 @@ public:
void raise(QWindow *window);
void lower(QWindow *window);
+ void updateWindowTitle();
+
ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
- EGLDisplay eglDisplay() const; // To opengl context
- EGLSurface eglSurface() const; // To window
- EGLConfig eglConfig() const;
+ ABI::Windows::UI::Xaml::IDependencyObject *canvas() const;
private:
void handleExpose();
@@ -127,20 +117,13 @@ private:
HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *);
- HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
- HRESULT onResume(IInspectable *, IInspectable *);
HRESULT onClosed(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICoreWindowEventArgs *);
HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *);
- HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *);
HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
-#ifdef Q_OS_WINPHONE
- HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
-#endif
-
QScopedPointer<QWinRTScreenPrivate> d_ptr;
Q_DECLARE_PRIVATE(QWinRTScreen)
};
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index adc5dfb776..634d62ef24 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -36,47 +36,138 @@
#include "qwinrtwindow.h"
#include "qwinrtscreen.h"
+#include <private/qeventdispatcher_winrt_p.h>
-#include <qpa/qwindowsysteminterface.h>
+#include <EGL/egl.h>
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/eglext.h>
+
+#include <qfunctions_winrt.h>
#include <qpa/qplatformscreen.h>
+#include <qpa/qwindowsysteminterface.h>
#include <QtGui/QGuiApplication>
-#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QWindow>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
-#include <qfunctions_winrt.h>
-#include <windows.ui.viewmanagement.h>
+#include <functional>
#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#include <windows.ui.xaml.h>
+#include <windows.ui.xaml.controls.h>
+#include <windows.ui.viewmanagement.h>
using namespace ABI::Windows::UI::ViewManagement;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::UI;
QT_BEGIN_NAMESPACE
+class QWinRTWindowPrivate
+{
+public:
+ QWinRTScreen *screen;
+
+ QSurfaceFormat surfaceFormat;
+ QString windowTitle;
+
+ ComPtr<Xaml::Controls::ISwapChainPanel> swapChainPanel;
+};
+
QWinRTWindow::QWinRTWindow(QWindow *window)
: QPlatformWindow(window)
- , m_screen(static_cast<QWinRTScreen*>(screen()))
+ , d_ptr(new QWinRTWindowPrivate)
{
+ Q_D(QWinRTWindow);
+
+ d->screen = static_cast<QWinRTScreen *>(screen());
setWindowFlags(window->flags());
setWindowState(window->windowState());
setWindowTitle(window->title());
handleContentOrientationChange(window->contentOrientation());
+
+ d->surfaceFormat.setAlphaBufferSize(0);
+ d->surfaceFormat.setRedBufferSize(8);
+ d->surfaceFormat.setGreenBufferSize(8);
+ d->surfaceFormat.setBlueBufferSize(8);
+ d->surfaceFormat.setDepthBufferSize(24);
+ d->surfaceFormat.setStencilBufferSize(8);
+ d->surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
+ d->surfaceFormat.setSamples(1);
+ d->surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ // Create a new swapchain and place it inside the canvas
+ HRESULT hr;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_SwapChainPanel).Get(),
+ &d->swapChainPanel);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<Xaml::IUIElement> uiElement;
+ hr = d->swapChainPanel.As(&uiElement);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<Xaml::IDependencyObject> canvas = d->screen->canvas();
+ ComPtr<Xaml::Controls::IPanel> panel;
+ hr = canvas.As(&panel);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVector<Xaml::UIElement *>> children;
+ hr = panel->get_Children(&children);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = children->Append(uiElement.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+
setGeometry(window->geometry());
}
QWinRTWindow::~QWinRTWindow()
{
- m_screen->removeWindow(window());
+ Q_D(QWinRTWindow);
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
+ HRESULT hr;
+ ComPtr<Xaml::IDependencyObject> canvas = d->screen->canvas();
+ ComPtr<Xaml::Controls::IPanel> panel;
+ hr = canvas.As(&panel);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVector<Xaml::UIElement *>> children;
+ hr = panel->get_Children(&children);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<Xaml::IUIElement> uiElement;
+ hr = d->swapChainPanel.As(&uiElement);
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 index;
+ boolean found;
+ hr = children->IndexOf(uiElement.Get(), &index, &found);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (found) {
+ hr = children->RemoveAt(index);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ return S_OK;
+ });
+ RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down");
}
QSurfaceFormat QWinRTWindow::format() const
{
- return m_screen->surfaceFormat();
+ Q_D(const QWinRTWindow);
+ return d->surfaceFormat;
}
bool QWinRTWindow::isActive() const
{
- return m_screen->topWindow() == window();
+ Q_D(const QWinRTWindow);
+ return d->screen->topWindow() == window();
}
bool QWinRTWindow::isExposed() const
@@ -87,55 +178,70 @@ bool QWinRTWindow::isExposed() const
void QWinRTWindow::setGeometry(const QRect &rect)
{
+ Q_D(QWinRTWindow);
+
if (window()->isTopLevel()) {
- QPlatformWindow::setGeometry(m_screen->geometry());
+ QPlatformWindow::setGeometry(d->screen->geometry());
QWindowSystemInterface::handleGeometryChange(window(), geometry());
} else {
QPlatformWindow::setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(window(), rect);
}
+
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ HRESULT hr;
+ ComPtr<Xaml::IFrameworkElement> frameworkElement;
+ hr = d->swapChainPanel.As(&frameworkElement);
+ Q_ASSERT_SUCCEEDED(hr);
+ const QSizeF size = QSizeF(geometry().size()) / d->screen->scaleFactor();
+ hr = frameworkElement->put_Width(size.width());
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = frameworkElement->put_Height(size.height());
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
}
void QWinRTWindow::setVisible(bool visible)
{
+ Q_D(QWinRTWindow);
if (!window()->isTopLevel())
return;
if (visible)
- m_screen->addWindow(window());
+ d->screen->addWindow(window());
else
- m_screen->removeWindow(window());
+ d->screen->removeWindow(window());
}
void QWinRTWindow::setWindowTitle(const QString &title)
{
- ComPtr<IApplicationViewStatics2> statics;
- HRESULT hr;
-
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
- IID_PPV_ARGS(&statics));
- RETURN_VOID_IF_FAILED("Could not get ApplicationViewStatics");
-
- ComPtr<IApplicationView> view;
- hr = statics->GetForCurrentView(&view);
- RETURN_VOID_IF_FAILED("Could not access currentView");
-
- HStringReference str(reinterpret_cast<LPCWSTR>(title.utf16()), title.length());
- hr = view->put_Title(str.Get());
- RETURN_VOID_IF_FAILED("Unable to set window title");
+ Q_D(QWinRTWindow);
+ d->windowTitle = title;
+ d->screen->updateWindowTitle();
}
void QWinRTWindow::raise()
{
+ Q_D(QWinRTWindow);
if (!window()->isTopLevel())
return;
- m_screen->raise(window());
+ d->screen->raise(window());
}
void QWinRTWindow::lower()
{
+ Q_D(QWinRTWindow);
if (!window()->isTopLevel())
return;
- m_screen->lower(window());
+ d->screen->lower(window());
+}
+
+WId QWinRTWindow::winId() const
+{
+ Q_D(const QWinRTWindow);
+ return WId(d->swapChainPanel.Get());
}
qreal QWinRTWindow::devicePixelRatio() const
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
index 3cfe346ab2..88c149b080 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.h
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -42,8 +42,7 @@
QT_BEGIN_NAMESPACE
-class QWinRTScreen;
-
+class QWinRTWindowPrivate;
class QWinRTWindow : public QPlatformWindow
{
public:
@@ -59,10 +58,13 @@ public:
void raise();
void lower();
+ WId winId() const Q_DECL_OVERRIDE;
+
qreal devicePixelRatio() const Q_DECL_OVERRIDE;
private:
- QWinRTScreen *m_screen;
+ QScopedPointer<QWinRTWindowPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTWindow)
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index 086a232746..ea8a918dcf 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -237,7 +237,11 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
QVariant::Type type;
switch (mysqltype) {
case FIELD_TYPE_TINY :
+ type = static_cast<QVariant::Type>((flags & UNSIGNED_FLAG) ? QMetaType::UChar : QMetaType::Char);
+ break;
case FIELD_TYPE_SHORT :
+ type = static_cast<QVariant::Type>((flags & UNSIGNED_FLAG) ? QMetaType::UShort : QMetaType::Short);
+ break;
case FIELD_TYPE_LONG :
case FIELD_TYPE_INT24 :
type = (flags & UNSIGNED_FLAG) ? QVariant::UInt : QVariant::Int;
@@ -316,14 +320,12 @@ static bool qIsBlob(int t)
static bool qIsInteger(int t)
{
- return t == MYSQL_TYPE_TINY
- || t == MYSQL_TYPE_SHORT
- || t == MYSQL_TYPE_LONG
- || t == MYSQL_TYPE_LONGLONG
- || t == MYSQL_TYPE_INT24;
+ return t == QMetaType::Char || t == QMetaType::UChar
+ || t == QMetaType::Short || t == QMetaType::UShort
+ || t == QMetaType::Int || t == QMetaType::UInt
+ || t == QMetaType::LongLong || t == QMetaType::ULongLong;
}
-
void QMYSQLResultPrivate::bindBlobs()
{
int i;
@@ -371,14 +373,9 @@ bool QMYSQLResultPrivate::bindInValues()
// after mysql_stmt_exec() in QMYSQLResult::exec()
fieldInfo->length = 0;
hasBlobs = true;
+ } else if (qIsInteger(f.type)) {
+ fieldInfo->length = 8;
} else {
- // fieldInfo->length specifies the display width, which may be too
- // small to hold valid integer values (see
- // http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html ), so
- // always use the MAX_BIGINT_WIDTH for integer types
- if (qIsInteger(fieldInfo->type)) {
- fieldInfo->length = MAX_BIGINT_WIDTH;
- }
fieldInfo->type = MYSQL_TYPE_STRING;
}
bind = &inBinds[i];
@@ -598,6 +595,9 @@ QVariant QMYSQLResult::data(int field)
if (f.nullIndicator)
return QVariant(f.type);
+ if (qIsInteger(f.type))
+ return QVariant(f.type, f.outField);
+
if (f.type != QVariant::ByteArray)
val = toUnicode(d->driver->d_func()->tc, f.outField, f.bufLength);
} else {
@@ -605,18 +605,24 @@ QVariant QMYSQLResult::data(int field)
// NULL value
return QVariant(f.type);
}
+
fieldLength = mysql_fetch_lengths(d->result)[field];
+
if (f.type != QVariant::ByteArray)
val = toUnicode(d->driver->d_func()->tc, d->row[field], fieldLength);
}
- switch(f.type) {
+ switch (static_cast<int>(f.type)) {
case QVariant::LongLong:
return QVariant(val.toLongLong());
case QVariant::ULongLong:
return QVariant(val.toULongLong());
+ case QMetaType::Char:
+ case QMetaType::Short:
case QVariant::Int:
return QVariant(val.toInt());
+ case QMetaType::UChar:
+ case QMetaType::UShort:
case QVariant::UInt:
return QVariant(val.toUInt());
case QVariant::Double: {
diff --git a/src/tools/qdoc/codeparser.h b/src/tools/qdoc/codeparser.h
index 379deb7e23..9d9e9286ec 100644
--- a/src/tools/qdoc/codeparser.h
+++ b/src/tools/qdoc/codeparser.h
@@ -40,7 +40,6 @@
QT_BEGIN_NAMESPACE
class Config;
-class Node;
class QString;
class QDocDatabase;
diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp
index 868b249290..774ff115b9 100644
--- a/src/tools/qdoc/cppcodemarker.cpp
+++ b/src/tools/qdoc/cppcodemarker.cpp
@@ -157,11 +157,11 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
synopsis += "(";
if (!func->parameters().isEmpty()) {
//synopsis += QLatin1Char(' ');
- QList<Parameter>::ConstIterator p = func->parameters().constBegin();
+ QVector<Parameter>::ConstIterator p = func->parameters().constBegin();
while (p != func->parameters().constEnd()) {
if (p != func->parameters().constBegin())
synopsis += ", ";
- synopsis += typified((*p).leftType());
+ synopsis += typified((*p).dataType());
if (style != Subpage && !(*p).name().isEmpty())
synopsis +=
"<@param>" + protect((*p).name()) + "</@param>";
@@ -328,11 +328,11 @@ QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
synopsis = name;
synopsis += QLatin1Char('(');
if (!func->parameters().isEmpty()) {
- QList<Parameter>::ConstIterator p = func->parameters().constBegin();
+ QVector<Parameter>::ConstIterator p = func->parameters().constBegin();
while (p != func->parameters().constEnd()) {
if (p != func->parameters().constBegin())
synopsis += ", ";
- synopsis += typified((*p).leftType());
+ synopsis += typified((*p).dataType());
if (!(*p).name().isEmpty()) {
if (!synopsis.endsWith(QLatin1Char('(')))
synopsis += QLatin1Char(' ');
diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp
index cab416370a..0f70777256 100644
--- a/src/tools/qdoc/cppcodeparser.cpp
+++ b/src/tools/qdoc/cppcodeparser.cpp
@@ -54,6 +54,7 @@ static bool inMacroCommand_ = false;
static bool parsingHeaderFile_ = false;
QStringList CppCodeParser::exampleFiles;
QStringList CppCodeParser::exampleDirs;
+CppCodeParser* CppCodeParser::cppParser_ = 0;
/*!
The constructor initializes some regular expressions
@@ -63,6 +64,7 @@ CppCodeParser::CppCodeParser()
: varComment("/\\*\\s*([a-zA-Z_0-9]+)\\s*\\*/"), sep("(?:<[^>]+>)?::")
{
reset();
+ cppParser_ = this;
}
/*!
@@ -374,12 +376,12 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc,
}
else {
func->setMetaness(FunctionNode::MacroWithParams);
- QList<Parameter> params = func->parameters();
+ QVector<Parameter> params = func->parameters();
for (int i = 0; i < params.size(); ++i) {
Parameter &param = params[i];
- if (param.name().isEmpty() && !param.leftType().isEmpty()
- && param.leftType() != "...")
- param = Parameter("", "", param.leftType());
+ if (param.name().isEmpty() && !param.dataType().isEmpty()
+ && param.dataType() != "...")
+ param = Parameter("", "", param.dataType());
}
func->setParameters(params);
}
@@ -685,10 +687,10 @@ bool CppCodeParser::splitQmlPropertyArg(const QString& arg,
<type> <QML-type>::<name>(<param>, <param>, ...)
<type> <QML-module>::<QML-type>::<name>(<param>, <param>, ...)
- This function splits the argument into one of those two
- forms, sets \a module, \a qmlTypeName, and \a name, and returns
- true. If the argument doesn't match either form, an error
- message is emitted and false is returned.
+ This function splits the \a{arg}ument into one of those
+ two forms, sets \a type, \a module, and \a qmlTypeName,
+ and returns true. If the argument doesn't match either
+ form, an error message is emitted and false is returned.
\note The two QML types \e{Component} and \e{QtObject} never
have a module qualifier.
@@ -698,30 +700,29 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg,
QString& module,
QString& qmlTypeName)
{
- QStringList colonSplit(arg.split("::"));
+ QString name;
+ int leftParen = arg.indexOf(QChar('('));
+ if (leftParen > 0)
+ name = arg.left(leftParen);
+ else
+ name = arg;
+ int firstBlank = name.indexOf(QChar(' '));
+ if (firstBlank > 0) {
+ type = name.left(firstBlank);
+ name = name.right(name.length() - firstBlank - 1);
+ }
+ else
+ type.clear();
+
+ QStringList colonSplit(name.split("::"));
if (colonSplit.size() > 1) {
- QStringList blankSplit = colonSplit[0].split(QLatin1Char(' '));
- if (blankSplit.size() > 1) {
- type = blankSplit[0];
- if (colonSplit.size() > 2) {
- module = blankSplit[1];
- qmlTypeName = colonSplit[1];
- }
- else {
- module.clear();
- qmlTypeName = blankSplit[1];
- }
+ if (colonSplit.size() > 2) {
+ module = colonSplit[0];
+ qmlTypeName = colonSplit[1];
}
else {
- type.clear();
- if (colonSplit.size() > 2) {
- module = colonSplit[0];
- qmlTypeName = colonSplit[1];
- }
- else {
- module.clear();
- qmlTypeName = colonSplit[0];
- }
+ module.clear();
+ qmlTypeName = colonSplit[0];
}
return true;
}
@@ -1308,23 +1309,23 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var)
/*!
Parse the next function parameter, if there is one, and
- append it to parameter list \a p. Return true if a parameter
- is parsed and appended to \a p. Otherwise return false.
+ append it to parameter vector \a pvect. Return true if
+ a parameter is parsed and appended to \a pvect.
+ Otherwise return false.
*/
-bool CppCodeParser::matchParameter(ParsedParameterList& pplist)
+bool CppCodeParser::matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal)
{
- ParsedParameter pp;
if (match(Tok_QPrivateSignal)) {
- pp.qPrivateSignal_ = true;
- pplist.append(pp);
+ isQPrivateSignal = true;
return true;
}
+ Parameter p;
CodeChunk chunk;
- if (!matchDataType(&chunk, &pp.name_)) {
+ if (!matchDataType(&chunk, &p.name_)) {
return false;
}
- pp.dataType_ = chunk.toString();
+ p.dataType_ = chunk.toString();
chunk.clear();
match(Tok_Comment);
if (match(Tok_Equal)) {
@@ -1336,8 +1337,8 @@ bool CppCodeParser::matchParameter(ParsedParameterList& pplist)
readToken();
}
}
- pp.defaultValue_ = chunk.toString();
- pplist.append(pp);
+ p.defaultValue_ = chunk.toString();
+ pvect.append(p);
return true;
}
@@ -1542,10 +1543,11 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent,
readToken();
// A left paren was seen. Parse the parameters
- ParsedParameterList pplist;
+ bool isQPrivateSignal = false;
+ QVector<Parameter> pvect;
if (tok != Tok_RightParen) {
do {
- if (!matchParameter(pplist))
+ if (!matchParameter(pvect, isQPrivateSignal))
return false;
} while (match(Tok_Comma));
}
@@ -1629,13 +1631,10 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent,
func->setStatic(matched_static);
func->setConst(matchedConst);
func->setVirtualness(virtuality);
- if (!pplist.isEmpty()) {
- foreach (const ParsedParameter& pp, pplist) {
- if (pp.qPrivateSignal_)
- func->setPrivateSignal();
- else
- func->addParameter(Parameter(pp.dataType_, "", pp.name_, pp.defaultValue_));
- }
+ if (isQPrivateSignal)
+ func->setPrivateSignal();
+ if (!pvect.isEmpty()) {
+ func->setParameters(pvect);
}
}
if (parentPathPtr != 0)
@@ -2417,6 +2416,34 @@ bool CppCodeParser::makeFunctionNode(const QString& signature,
}
/*!
+ This function uses a Tokenizer to parse the \a parameters of a
+ function into the parameter vector \a {pvect}.
+ */
+bool CppCodeParser::parseParameters(const QString& parameters,
+ QVector<Parameter>& pvect,
+ bool& isQPrivateSignal)
+{
+ Tokenizer* outerTokenizer = tokenizer;
+ int outerTok = tok;
+
+ QByteArray latin1 = parameters.toLatin1();
+ Tokenizer stringTokenizer(Location(), latin1);
+ stringTokenizer.setParsingFnOrMacro(true);
+ tokenizer = &stringTokenizer;
+ readToken();
+
+ inMacroCommand_ = false;
+ do {
+ if (!matchParameter(pvect, isQPrivateSignal))
+ return false;
+ } while (match(Tok_Comma));
+
+ tokenizer = outerTokenizer;
+ tok = outerTok;
+ return true;
+}
+
+/*!
Create a new FunctionNode for a QML method or signal, as
specified by \a type, as a child of \a parent. \a sig is
the complete signature, and if \a attached is true, the
diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h
index 733418e27a..ec04482321 100644
--- a/src/tools/qdoc/cppcodeparser.h
+++ b/src/tools/qdoc/cppcodeparser.h
@@ -51,16 +51,6 @@ class CppCodeParser : public CodeParser
{
Q_DECLARE_TR_FUNCTIONS(QDoc::CppCodeParser)
- struct ParsedParameter {
- bool qPrivateSignal_;
- QString dataType_;
- QString name_;
- QString defaultValue_;
- ParsedParameter() : qPrivateSignal_(false) { }
- };
- friend class QTypeInfo<ParsedParameter>;
- typedef QVector<ParsedParameter> ParsedParameterList;
-
struct ExtraFuncData {
Aggregate* root; // Used as the parent.
Node::NodeType type; // The node type: Function, etc.
@@ -74,6 +64,7 @@ class CppCodeParser : public CodeParser
public:
CppCodeParser();
~CppCodeParser();
+ static CppCodeParser* cppParser() { return cppParser_; }
virtual void initializeParser(const Config& config) Q_DECL_OVERRIDE;
virtual void terminateParser() Q_DECL_OVERRIDE;
@@ -84,6 +75,7 @@ public:
virtual void parseSourceFile(const Location& location, const QString& filePath) Q_DECL_OVERRIDE;
virtual void doneParsingHeaderFiles() Q_DECL_OVERRIDE;
virtual void doneParsingSourceFiles() Q_DECL_OVERRIDE;
+ bool parseParameters(const QString& parameters, QVector<Parameter>& pvect, bool& isQPrivateSignal);
protected:
const QSet<QString>& topicCommands();
@@ -126,7 +118,7 @@ protected:
bool matchTemplateAngles(CodeChunk *type = 0);
bool matchTemplateHeader();
bool matchDataType(CodeChunk *type, QString *var = 0);
- bool matchParameter(ParsedParameterList& pplist);
+ bool matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal);
bool matchFunctionDecl(Aggregate *parent,
QStringList *parentPathPtr,
FunctionNode **funcPtr,
@@ -184,10 +176,10 @@ protected:
static QStringList exampleFiles;
static QStringList exampleDirs;
+ static CppCodeParser* cppParser_;
QString exampleNameFilter;
QString exampleImageFilter;
};
-Q_DECLARE_TYPEINFO(CppCodeParser::ParsedParameter, Q_MOVABLE_TYPE);
#define COMMAND_ABSTRACT Doc::alias("abstract")
#define COMMAND_CLASS Doc::alias("class")
diff --git a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc
index 0f9ca463bb..49cbfc0654 100644
--- a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc
+++ b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc
@@ -1839,8 +1839,13 @@
\li \c {\l QWidget} - The name of a class documented with the \l
{class-command} {\\class} command.
- \li \c {\l QWidget::sizeHint()} - The name of a member function,
- documented with or without an \l {fn-command} {\\fn} command.
+ \li \c {\l QWidget::sizeHint()} - The signature of a function without
+ parameters. If a matching function without parameters can't be found,
+ the link is satisfied with the first matching function found.
+
+ \li \c {\l QWidget::removeAction(QAction* action)} - The signature
+ of a function with parameters. If an exact match is not found, the
+ link is not satisfied and qdoc reports a \e {Can't link to...} error.
\li \c {\l <QtGlobal>} - The subject of a \l {headerfile-command}
{\\headerfile} command.
diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp
index 5153b0de5c..7dfbbb1cb8 100644
--- a/src/tools/qdoc/generator.cpp
+++ b/src/tools/qdoc/generator.cpp
@@ -804,9 +804,9 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
else if (node->type() == Node::Function) {
const FunctionNode *func = static_cast<const FunctionNode *>(node);
QSet<QString> definedParams;
- QList<Parameter>::ConstIterator p = func->parameters().constBegin();
+ QVector<Parameter>::ConstIterator p = func->parameters().constBegin();
while (p != func->parameters().constEnd()) {
- if ((*p).name().isEmpty() && (*p).leftType() != QLatin1String("...")
+ if ((*p).name().isEmpty() && (*p).dataType() != QLatin1String("...")
&& func->name() != QLatin1String("operator++")
&& func->name() != QLatin1String("operator--")) {
node->doc().location().warning(tr("Missing parameter name"));
@@ -836,7 +836,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
else if (!(*a).isEmpty() && !documentedParams.contains(*a)) {
bool needWarning = (func->status() > Node::Obsolete);
if (func->overloadNumber() > 0) {
- FunctionNode *primaryFunc = func->parent()->findFunctionNode(func->name());
+ FunctionNode *primaryFunc = func->parent()->findFunctionNode(func->name(), QString());
if (primaryFunc) {
foreach (const Parameter &param,
primaryFunc->parameters()) {
@@ -1504,7 +1504,7 @@ void Generator::generateOverloadedSignal(const Node* node, CodeMarker* marker)
if (i != 0)
code += ", ";
const Parameter &p = func->parameters().at(i);
- code += p.leftType() + p.rightType();
+ code += p.dataType() + p.rightType();
}
code += ")";
@@ -1516,7 +1516,7 @@ void Generator::generateOverloadedSignal(const Node* node, CodeMarker* marker)
if (i != 0)
code += ", ";
const Parameter &p = func->parameters().at(i);
- code += p.leftType();
+ code += p.dataType();
if (code[code.size()-1].isLetterOrNumber())
code += " ";
code += p.name() + p.rightType();
@@ -2049,14 +2049,14 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList)
if (func->name().startsWith("set") && func->name().size() >= 4) {
alternateName = func->name()[3].toLower();
alternateName += func->name().mid(4);
- alternateFunc = func->parent()->findFunctionNode(alternateName);
+ alternateFunc = func->parent()->findFunctionNode(alternateName, QString());
if (!alternateFunc) {
alternateName = "is" + func->name().mid(3);
- alternateFunc = func->parent()->findFunctionNode(alternateName);
+ alternateFunc = func->parent()->findFunctionNode(alternateName, QString());
if (!alternateFunc) {
alternateName = "has" + func->name().mid(3);
- alternateFunc = func->parent()->findFunctionNode(alternateName);
+ alternateFunc = func->parent()->findFunctionNode(alternateName, QString());
}
}
}
@@ -2064,7 +2064,7 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList)
alternateName = "set";
alternateName += func->name()[0].toUpper();
alternateName += func->name().mid(1);
- alternateFunc = func->parent()->findFunctionNode(alternateName);
+ alternateFunc = func->parent()->findFunctionNode(alternateName, QString());
}
if (alternateFunc && alternateFunc->access() != Node::Private) {
diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp
index ebb54735d4..c803acbf60 100644
--- a/src/tools/qdoc/node.cpp
+++ b/src/tools/qdoc/node.cpp
@@ -34,11 +34,12 @@
#include "node.h"
#include "tree.h"
#include "codemarker.h"
-#include "codeparser.h"
+#include "cppcodeparser.h"
#include <quuid.h>
#include "qdocdatabase.h"
#include <qdebug.h>
#include "generator.h"
+#include "tokenizer.h"
QT_BEGIN_NAMESPACE
@@ -810,9 +811,56 @@ Node* Aggregate::findChildNode(const QString& name, NodeType type)
Find a function node that is a child of this nose, such
that the function node has the specified \a name.
*/
-FunctionNode *Aggregate::findFunctionNode(const QString& name) const
-{
- return static_cast<FunctionNode *>(primaryFunctionMap_.value(name));
+FunctionNode *Aggregate::findFunctionNode(const QString& name, const QString& params) const
+{
+ FunctionNode* pfn = static_cast<FunctionNode*>(primaryFunctionMap_.value(name));
+ FunctionNode* fn = pfn;
+ if (fn) {
+ const QVector<Parameter>* funcParams = &(fn->parameters());
+ if (params.isEmpty() && funcParams->isEmpty())
+ return fn;
+ bool isQPrivateSignal = false; // Not used in the search
+ QVector<Parameter> testParams;
+ if (!params.isEmpty()) {
+ CppCodeParser* cppParser = CppCodeParser::cppParser();
+ cppParser->parseParameters(params, testParams, isQPrivateSignal);
+ }
+ NodeList funcs = secondaryFunctionMap_.value(name);
+ int i = -1;
+ while (fn) {
+ if (testParams.size() == funcParams->size()) {
+ if (testParams.isEmpty())
+ return fn;
+ bool different = false;
+ for (int j=0; j<testParams.size(); j++) {
+ if (testParams.at(j).dataType() != funcParams->at(j).dataType()) {
+ different = true;
+ break;
+ }
+ }
+ if (!different)
+ return fn;
+ }
+ if (++i < funcs.size()) {
+ fn = static_cast<FunctionNode*>(funcs.at(i));
+ funcParams = &(fn->parameters());
+ }
+ else
+ fn = 0;
+ }
+ if (!fn && !testParams.empty())
+ return 0;
+ }
+ /*
+ Most \l commands that link to functions don't include
+ the parameter declarations in the function signature,
+ so if the \l is meant to go to a function that does
+ have parameters, the algorithm above won't find it.
+ Therefore we must return the pointer to the function
+ in the primary function map in the cases where the
+ parameters should have been specified in the \l command.
+ */
+ return (fn ? fn : pfn);
}
/*!
@@ -1090,20 +1138,20 @@ void Aggregate::setIncludes(const QStringList& includes)
*/
bool Aggregate::isSameSignature(const FunctionNode *f1, const FunctionNode *f2)
{
- if (f1->parameters().count() != f2->parameters().count())
+ if (f1->parameters().size() != f2->parameters().size())
return false;
if (f1->isConst() != f2->isConst())
return false;
- QList<Parameter>::ConstIterator p1 = f1->parameters().constBegin();
- QList<Parameter>::ConstIterator p2 = f2->parameters().constBegin();
+ QVector<Parameter>::ConstIterator p1 = f1->parameters().constBegin();
+ QVector<Parameter>::ConstIterator p2 = f2->parameters().constBegin();
while (p2 != f2->parameters().constEnd()) {
if ((*p1).hasType() && (*p2).hasType()) {
if ((*p1).rightType() != (*p2).rightType())
return false;
- QString t1 = p1->leftType();
- QString t2 = p2->leftType();
+ QString t1 = p1->dataType();
+ QString t2 = p2->dataType();
if (t1.length() < t2.length())
qSwap(t1, t2);
@@ -1751,33 +1799,40 @@ void TypedefNode::setAssociatedEnum(const EnumNode *enume)
/*!
Constructs this parameter from the left and right types
- \a leftType and rightType, the parameter \a name, and the
+ \a dataType and rightType, the parameter \a name, and the
\a defaultValue. In practice, \a rightType is not used,
and I don't know what is was meant for.
*/
-Parameter::Parameter(const QString& leftType,
+Parameter::Parameter(const QString& dataType,
const QString& rightType,
const QString& name,
const QString& defaultValue)
- : leftType_(leftType), rightType_(rightType), name_(name), defaultValue_(defaultValue)
+ : dataType_(dataType),
+ rightType_(rightType),
+ name_(name),
+ defaultValue_(defaultValue)
{
+ // nothing.
}
/*!
- The standard copy constructor copies the strings from \a p.
+ Standard copy constructor copies \p.
*/
Parameter::Parameter(const Parameter& p)
- : leftType_(p.leftType_), rightType_(p.rightType_), name_(p.name_), defaultValue_(p.defaultValue_)
+ : dataType_(p.dataType_),
+ rightType_(p.rightType_),
+ name_(p.name_),
+ defaultValue_(p.defaultValue_)
{
+ // nothing.
}
/*!
- Assigning Parameter \a p to this Parameter copies the
- strings across.
+ standard assignment operator assigns \p.
*/
Parameter& Parameter::operator=(const Parameter& p)
{
- leftType_ = p.leftType_;
+ dataType_ = p.dataType_;
rightType_ = p.rightType_;
name_ = p.name_;
defaultValue_ = p.defaultValue_;
@@ -1791,7 +1846,7 @@ Parameter& Parameter::operator=(const Parameter& p)
*/
QString Parameter::reconstruct(bool value) const
{
- QString p = leftType_ + rightType_;
+ QString p = dataType_ + rightType_;
if (!p.endsWith(QChar('*')) && !p.endsWith(QChar('&')) && !p.endsWith(QChar(' ')))
p += QLatin1Char(' ');
p += name_;
@@ -1902,8 +1957,8 @@ void FunctionNode::addParameter(const Parameter& parameter)
*/
void FunctionNode::borrowParameterNames(const FunctionNode *source)
{
- QList<Parameter>::Iterator t = parameters_.begin();
- QList<Parameter>::ConstIterator s = source->parameters_.constBegin();
+ QVector<Parameter>::Iterator t = parameters_.begin();
+ QVector<Parameter>::ConstIterator s = source->parameters_.constBegin();
while (s != source->parameters_.constEnd() && t != parameters_.end()) {
if (!(*s).name().isEmpty())
(*t).setName((*s).name());
@@ -1958,7 +2013,7 @@ bool FunctionNode::hasActiveAssociatedProperty() const
QStringList FunctionNode::parameterNames() const
{
QStringList names;
- QList<Parameter>::ConstIterator p = parameters().constBegin();
+ QVector<Parameter>::ConstIterator p = parameters().constBegin();
while (p != parameters().constEnd()) {
names << (*p).name();
++p;
@@ -1975,7 +2030,7 @@ QString FunctionNode::rawParameters(bool names, bool values) const
{
QString raw;
foreach (const Parameter &parameter, parameters()) {
- raw += parameter.leftType() + parameter.rightType();
+ raw += parameter.dataType() + parameter.rightType();
if (names)
raw += parameter.name();
if (values)
@@ -1991,7 +2046,7 @@ QString FunctionNode::rawParameters(bool names, bool values) const
QStringList FunctionNode::reconstructParameters(bool values) const
{
QStringList reconstructedParameters;
- QList<Parameter>::ConstIterator p = parameters().constBegin();
+ QVector<Parameter>::ConstIterator p = parameters().constBegin();
while (p != parameters().constEnd()) {
reconstructedParameters << (*p).reconstruct(values);
++p;
diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h
index e9816dad19..596a71b6d5 100644
--- a/src/tools/qdoc/node.h
+++ b/src/tools/qdoc/node.h
@@ -376,7 +376,7 @@ public:
Node* findChildNode(const QString& name, Node::Genus genus) const;
Node* findChildNode(const QString& name, NodeType type);
virtual void findChildren(const QString& name, NodeList& nodes) const Q_DECL_OVERRIDE;
- FunctionNode* findFunctionNode(const QString& name) const;
+ FunctionNode* findFunctionNode(const QString& name, const QString& params) const;
FunctionNode* findFunctionNode(const FunctionNode* clone) const;
void addInclude(const QString &include);
void setIncludes(const QStringList &includes);
@@ -815,12 +815,11 @@ inline void EnumNode::setFlagsType(TypedefNode* t)
t->setAssociatedEnum(this);
}
-
class Parameter
{
public:
Parameter() {}
- Parameter(const QString& leftType,
+ Parameter(const QString& dataType,
const QString& rightType = QString(),
const QString& name = QString(),
const QString& defaultValue = QString());
@@ -830,21 +829,24 @@ public:
void setName(const QString& name) { name_ = name; }
- bool hasType() const { return leftType_.length() + rightType_.length() > 0; }
- const QString& leftType() const { return leftType_; }
+ bool hasType() const { return dataType_.length() + rightType_.length() > 0; }
+ const QString& dataType() const { return dataType_; }
const QString& rightType() const { return rightType_; }
const QString& name() const { return name_; }
const QString& defaultValue() const { return defaultValue_; }
QString reconstruct(bool value = false) const;
-private:
- QString leftType_;
- QString rightType_;
+ public:
+ QString dataType_;
+ QString rightType_; // mws says remove this 04/08/2015
QString name_;
QString defaultValue_;
};
+//friend class QTypeInfo<Parameter>;
+//Q_DECLARE_TYPEINFO(Parameter, Q_MOVABLE_TYPE);
+
class FunctionNode : public LeafNode
{
public:
@@ -874,7 +876,7 @@ public:
void setOverloadNumber(unsigned char n) { overloadNumber_ = n; }
void setReimplemented(bool b);
void addParameter(const Parameter& parameter);
- inline void setParameters(const QList<Parameter>& parameters);
+ inline void setParameters(const QVector<Parameter>& parameters);
void borrowParameterNames(const FunctionNode* source);
void setReimplementedFrom(FunctionNode* from);
@@ -907,7 +909,7 @@ public:
virtual bool isJsMethod() const Q_DECL_OVERRIDE {
return (type() == Node::QmlMethod) && (genus() == Node::JS);
}
- const QList<Parameter>& parameters() const { return parameters_; }
+ const QVector<Parameter>& parameters() const { return parameters_; }
void clearParams() { parameters_.clear(); }
QStringList parameterNames() const;
QString rawParameters(bool names = false, bool values = false) const;
@@ -957,7 +959,7 @@ private:
bool privateSignal_: 1;
bool overload_ : 1;
unsigned char overloadNumber_;
- QList<Parameter> parameters_;
+ QVector<Parameter> parameters_;
const FunctionNode* reimplementedFrom_;
PropNodeList associatedProperties_;
QList<FunctionNode*> reimplementedBy_;
@@ -1030,7 +1032,7 @@ private:
const PropertyNode* overrides_;
};
-inline void FunctionNode::setParameters(const QList<Parameter> &p)
+inline void FunctionNode::setParameters(const QVector<Parameter> &p)
{
parameters_ = p;
}
diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp
index 5f2a61bb76..7f2e64b00c 100644
--- a/src/tools/qdoc/qdocdatabase.cpp
+++ b/src/tools/qdoc/qdocdatabase.cpp
@@ -380,6 +380,30 @@ QString QDocForest::getLinkCounts(QStringList& strings, QVector<int>& counts)
return depends;
}
+/*!
+ */
+const Node* QDocForest::findFunctionNode(const QString& target,
+ const Node* relative,
+ Node::Genus genus)
+{
+ QString function, params;
+ int length = target.length();
+ if (target.endsWith(QChar(')'))) {
+ int position = target.lastIndexOf(QChar('('));
+ params = target.mid(position+1, length-position-2);
+ function = target.left(position);
+ }
+ else
+ function = target;
+ foreach (Tree* t, searchOrder()) {
+ const Node* n = t->findFunctionNode(function, params, relative, genus);
+ if (n)
+ return n;
+ relative = 0;
+ }
+ return 0;
+}
+
/*! \class QDocDatabase
This class provides exclusive access to the qdoc database,
which consists of a forrest of trees and a lot of maps and
@@ -1342,8 +1366,16 @@ void QDocDatabase::resolveNamespaces()
}
}
}
-
-
+#if 0
+/*!
+ */
+const Node* QDocDatabase::findFunctionNode(const QString& target,
+ const Node* relative,
+ Node::Genus genus)
+{
+ return forest_.findFunctionNode(target, relative, genus);
+}
+#endif
/*!
This function is called for autolinking to a \a type,
which could be a function return type or a parameter
@@ -1641,6 +1673,8 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
Atom* atom = const_cast<Atom*>(a);
QStringList targetPath = atom->string().split("#");
QString first = targetPath.first().trimmed();
+ if (Generator::debugging())
+ qDebug() << " first:" << first;
Tree* domain = 0;
Node::Genus genus = Node::DontCare;
@@ -1659,8 +1693,14 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
else if (domain) {
if (first.endsWith(".html"))
node = domain->findNodeByNameAndType(QStringList(first), Node::Document);
- else if (first.endsWith("()"))
- node = domain->findFunctionNode(first, 0, genus);
+ else if (first.endsWith(QChar(')'))) {
+ QString function, params;
+ int length = first.length();
+ int position = first.lastIndexOf(QChar('('));
+ params = first.mid(position+1, length-position-2);
+ function = first.left(position);
+ node = domain->findFunctionNode(function, params, 0, genus);
+ }
else {
int flags = SearchBaseClasses | SearchEnumValues;
QStringList nodePath = first.split("::");
@@ -1683,8 +1723,11 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q
if (!node && first.contains("/"))
return findNodeForTarget(targetPath, relative, genus, ref);
}
- else if (first.endsWith("()"))
+ else if (first.endsWith(QChar(')'))) {
node = findFunctionNode(first, relative, genus);
+ if (Generator::debugging())
+ qDebug() << " node:" << node;
+ }
else {
node = findNodeForTarget(targetPath, relative, genus, ref);
return node;
diff --git a/src/tools/qdoc/qdocdatabase.h b/src/tools/qdoc/qdocdatabase.h
index 5d55ea48e1..80a92af4ed 100644
--- a/src/tools/qdoc/qdocdatabase.h
+++ b/src/tools/qdoc/qdocdatabase.h
@@ -141,15 +141,8 @@ class QDocForest
const Node* findFunctionNode(const QString& target,
const Node* relative,
- Node::Genus genus) {
- foreach (Tree* t, searchOrder()) {
- const Node* n = t->findFunctionNode(target, relative, genus);
- if (n)
- return n;
- relative = 0;
- }
- return 0;
- }
+ Node::Genus genus);
+
const Node* findNodeForTarget(QStringList& targetPath,
const Node* relative,
Node::Genus genus,
diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp
index 37194b911c..8db901bbc7 100644
--- a/src/tools/qdoc/qdocindexfiles.cpp
+++ b/src/tools/qdoc/qdocindexfiles.cpp
@@ -1238,7 +1238,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
for (int i = 0; i < functionNode->parameters().size(); ++i) {
Parameter parameter = functionNode->parameters()[i];
writer.writeStartElement("parameter");
- writer.writeAttribute("left", parameter.leftType());
+ writer.writeAttribute("left", parameter.dataType());
writer.writeAttribute("right", parameter.rightType());
writer.writeAttribute("name", parameter.name());
writer.writeAttribute("default", parameter.defaultValue());
diff --git a/src/tools/qdoc/qmlvisitor.cpp b/src/tools/qdoc/qmlvisitor.cpp
index 6f63624bf0..155e1de054 100644
--- a/src/tools/qdoc/qmlvisitor.cpp
+++ b/src/tools/qdoc/qmlvisitor.cpp
@@ -675,7 +675,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member)
QString name = member->name.toString();
FunctionNode *qmlSignal = new FunctionNode(Node::QmlSignal, current, name, false);
- QList<Parameter> parameters;
+ QVector<Parameter> parameters;
for (QQmlJS::AST::UiParameterList *it = member->parameters; it; it = it->next) {
if (!it->type.isEmpty() && !it->name.isEmpty())
parameters.append(Parameter(it->type.toString(), QString(), it->name.toString()));
@@ -754,7 +754,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::FunctionDeclaration* fd)
}
if (overloads > 1)
qmlMethod->setOverloadFlag(true);
- QList<Parameter> parameters;
+ QVector<Parameter> parameters;
QQmlJS::AST::FormalParameterList* formals = fd->formals;
if (formals) {
QQmlJS::AST::FormalParameterList* fpl = formals;
diff --git a/src/tools/qdoc/tokenizer.cpp b/src/tools/qdoc/tokenizer.cpp
index a85c3b00d8..987fff548c 100644
--- a/src/tools/qdoc/tokenizer.cpp
+++ b/src/tools/qdoc/tokenizer.cpp
@@ -33,6 +33,7 @@
#include "config.h"
#include "tokenizer.h"
+#include "generator.h"
#include <qfile.h>
#include <qhash.h>
diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp
index e0fd68d2e7..d64903e61e 100644
--- a/src/tools/qdoc/tree.cpp
+++ b/src/tools/qdoc/tree.cpp
@@ -220,6 +220,7 @@ QmlTypeNode* Tree::findQmlTypeNode(const QStringList& path)
used as the starting point.
*/
const FunctionNode* Tree::findFunctionNode(const QStringList& path,
+ const QString& params,
const Node* relative,
int findFlags,
Node::Genus genus) const
@@ -234,7 +235,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
qcn = static_cast<QmlTypeNode*>(n);
}
if (qcn)
- return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2]));
+ return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2], params));
}
if (!relative)
@@ -254,7 +255,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
const Node* next;
if (i == path.size() - 1)
- next = ((const Aggregate*) node)->findFunctionNode(path.at(i));
+ next = ((const Aggregate*) node)->findFunctionNode(path.at(i), params);
else
next = ((const Aggregate*) node)->findChildNode(path.at(i), genus);
@@ -262,7 +263,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path,
NodeList baseClasses = allBaseClasses(static_cast<const ClassNode*>(node));
foreach (const Node* baseClass, baseClasses) {
if (i == path.size() - 1)
- next = static_cast<const Aggregate*>(baseClass)->findFunctionNode(path.at(i));
+ next = static_cast<const Aggregate*>(baseClass)->findFunctionNode(path.at(i), params);
else
next = static_cast<const Aggregate*>(baseClass)->findChildNode(path.at(i), genus);
@@ -1452,13 +1453,17 @@ void Tree::insertQmlType(const QString& key, QmlTypeNode* n)
Split \a target on "::" and find the function node with that
path.
*/
-const Node* Tree::findFunctionNode(const QString& target, const Node* relative, Node::Genus genus)
+const Node* Tree::findFunctionNode(const QString& target,
+ const QString& params,
+ const Node* relative,
+ Node::Genus genus) const
{
QString t = target;
- if (t.endsWith("()"))
+ if (t.endsWith("()")) {
t.chop(2);
+ }
QStringList path = t.split("::");
- const FunctionNode* fn = findFunctionNode(path, relative, SearchBaseClasses, genus);
+ const FunctionNode* fn = findFunctionNode(path, params, relative, SearchBaseClasses, genus);
if (fn && fn->metaness() != FunctionNode::MacroWithoutParams)
return fn;
return 0;
diff --git a/src/tools/qdoc/tree.h b/src/tools/qdoc/tree.h
index 9e195c90ae..1fef15bc6d 100644
--- a/src/tools/qdoc/tree.h
+++ b/src/tools/qdoc/tree.h
@@ -107,7 +107,10 @@ class Tree
ClassNode* findClassNode(const QStringList& path, const Node* start = 0) const;
NamespaceNode* findNamespaceNode(const QStringList& path) const;
FunctionNode* findFunctionNode(const QStringList& parentPath, const FunctionNode* clone);
- const Node* findFunctionNode(const QString& target, const Node* relative, Node::Genus genus);
+ const Node* findFunctionNode(const QString& target,
+ const QString& params,
+ const Node* relative,
+ Node::Genus genus) const;
Node* findNodeRecursive(const QStringList& path,
int pathIndex,
@@ -163,6 +166,7 @@ class Tree
NamespaceNode *root() { return &root_; }
const FunctionNode *findFunctionNode(const QStringList &path,
+ const QString& params,
const Node *relative = 0,
int findFlags = 0,
Node::Genus genus = Node::DontCare) const;
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 914ee8ec9c..2ebbaaee10 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -159,23 +159,6 @@ public:
QWindow dummyTransparentWindow;
#endif
-#ifdef Q_DEAD_CODE_FROM_QT4_MAC
- void openCocoaColorPanel(const QColor &initial,
- QWidget *parent, const QString &title, QColorDialog::ColorDialogOptions options);
- void closeCocoaColorPanel();
- void releaseCocoaColorPanelDelegate();
- void setCocoaPanelColor(const QColor &color);
-
- inline void done(int result) { q_func()->done(result); }
- inline QColorDialog *colorDialog() { return q_func(); }
-
- void *delegate;
-
- static bool sharedColorPanelAvailable;
-
- void _q_macRunNativeAppModalPanel();
- void mac_nativeDialogModalHelp();
-#endif
private:
virtual void initHelper(QPlatformDialogHelper *h) Q_DECL_OVERRIDE;
virtual void helperPrepareShow(QPlatformDialogHelper *h) Q_DECL_OVERRIDE;
@@ -1731,9 +1714,6 @@ void QColorDialogPrivate::init(const QColor &initial)
if (!nativeDialogInUse)
initWidgets();
-#ifdef Q_DEAD_CODE_FROM_QT4_MAC
- delegate = 0;
-#endif
#ifdef Q_OS_WIN32
dummyTransparentWindow.resize(1, 1);
dummyTransparentWindow.setFlags(Qt::Tool | Qt::FramelessWindowHint);
@@ -2135,11 +2115,6 @@ QColorDialog::ColorDialogOptions QColorDialog::options() const
\sa color, colorSelected()
*/
-#ifdef Q_DEAD_CODE_FROM_QT4_MAC
-// can only have one Cocoa color panel active
-bool QColorDialogPrivate::sharedColorPanelAvailable = true;
-#endif
-
/*!
\fn void QColorDialog::colorSelected(const QColor &color);
@@ -2166,23 +2141,6 @@ void QColorDialog::setVisible(bool visible)
if (visible)
d->selectedQColor = QColor();
-#if defined(Q_DEAD_CODE_FROM_QT4_MAC)
- if (visible) {
- if (d->delegate || (QColorDialogPrivate::sharedColorPanelAvailable &&
- !(testAttribute(Qt::WA_DontShowOnScreen) || (d->opts & DontUseNativeDialog)))){
- d->openCocoaColorPanel(currentColor(), parentWidget(), windowTitle(), options());
- QColorDialogPrivate::sharedColorPanelAvailable = false;
- setAttribute(Qt::WA_DontShowOnScreen);
- }
- setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags);
- } else {
- if (d->delegate) {
- d->closeCocoaColorPanel();
- setAttribute(Qt::WA_DontShowOnScreen, false);
- }
- }
-#else
-
if (d->nativeDialogInUse) {
d->setNativeDialogVisible(visible);
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
@@ -2191,7 +2149,6 @@ void QColorDialog::setVisible(bool visible)
} else {
setAttribute(Qt::WA_DontShowOnScreen, false);
}
-#endif
QDialog::setVisible(visible);
}
@@ -2267,13 +2224,7 @@ QRgb QColorDialog::getRgba(QRgb initial, bool *ok, QWidget *parent)
QColorDialog::~QColorDialog()
{
-#if defined(Q_DEAD_CODE_FROM_QT4_MAC)
- Q_D(QColorDialog);
- if (d->delegate) {
- d->releaseCocoaColorPanelDelegate();
- QColorDialogPrivate::sharedColorPanelAvailable = true;
- }
-#endif
+
}
/*!
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
index c61984a457..0a00086138 100644
--- a/src/widgets/widgets/qdockarealayout.cpp
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -3101,6 +3101,53 @@ void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
remove(index);
}
+void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
+ const QList<int> &sizes, Qt::Orientation o)
+{
+ if (docks.count() != sizes.count()) {
+ qWarning("QMainWidget::resizeDocks: size of the lists are not the same");
+ return;
+ }
+ int count = docks.count();
+ fallbackToSizeHints = false;
+ for (int i = 0; i < count; ++i) {
+ QList<int> path = indexOf(docks[i]);
+ if (path.isEmpty()) {
+ qWarning("QMainWidget::resizeDocks: one QDockWidget is not part of the layout");
+ continue;
+ }
+ int size = sizes[i];
+ if (size <= 0) {
+ qWarning("QMainWidget::resizeDocks: all sizes need to be larger than 0");
+ size = 1;
+ }
+
+ while (path.size() > 1) {
+ QDockAreaLayoutInfo *info = this->info(path);
+ if (!info->tabbed && info->o == o) {
+ info->item_list[path.last()].size = size;
+ int totalSize = 0;
+ foreach (const QDockAreaLayoutItem &item, info->item_list) {
+ if (!item.skip()) {
+ if (totalSize != 0)
+ totalSize += sep;
+ totalSize += item.size == -1 ? pick(o, item.sizeHint()) : item.size;
+ }
+ }
+ size = totalSize;
+ }
+ path.removeLast();
+ }
+
+ const int dockNum = path.first();
+ Q_ASSERT(dockNum < QInternal::DockCount);
+ QRect &r = this->docks[dockNum].rect;
+ QSize s = r.size();
+ rpick(o, s) = size;
+ r.setSize(s);
+ }
+}
+
void QDockAreaLayout::splitDockWidget(QDockWidget *after,
QDockWidget *dockWidget,
Qt::Orientation orientation)
diff --git a/src/widgets/widgets/qdockarealayout_p.h b/src/widgets/widgets/qdockarealayout_p.h
index 93b005f64f..5d352f0124 100644
--- a/src/widgets/widgets/qdockarealayout_p.h
+++ b/src/widgets/widgets/qdockarealayout_p.h
@@ -268,6 +268,7 @@ public:
void splitDockWidget(QDockWidget *after, QDockWidget *dockWidget,
Qt::Orientation orientation);
void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
+ void resizeDocks(const QList<QDockWidget *> &docks, const QList<int> &sizes, Qt::Orientation o);
void apply(bool animate);
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 5d53e7def4..ff4bb3cc98 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1237,6 +1237,35 @@ void QMainWindow::removeDockWidget(QDockWidget *dockwidget)
Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
{ return d_func()->layout->dockWidgetArea(dockwidget); }
+
+/*!
+ \since 5.6
+ Resizes the dock widgets in the list \a docks to the corresponding size in
+ pixels from the list \a sizes. If \a orientation is Qt::Horizontal, adjusts
+ the width, otherwise adjusts the height of the dock widgets.
+ The sizes will be adjusted such that the maximum and the minimum sizes are
+ respected and the QMainWindow itself will not be resized.
+ Any additional/missing space is distributed amongst the widgets according
+ to the relative weight of the sizes.
+
+ Example:
+ \code
+ resizeDocks({blueWidget, yellowWidget}, {20 , 40}, Qt::Horizontal);
+ \endcode
+ If the blue and the yellow widget are nested on the same level they will be
+ resized such that the yellowWidget is twice as big as the blueWidget
+
+ If some widgets are grouped in tabs, only one widget per group should be
+ specified. Widgets not in the list might be changed to repect the constraints.
+*/
+void QMainWindow::resizeDocks(const QList<QDockWidget *> &docks,
+ const QList<int> &sizes, Qt::Orientation orientation)
+{
+ d_func()->layout->layoutState.dockAreaLayout.resizeDocks(docks, sizes, orientation);
+ d_func()->layout->invalidate();
+}
+
+
#endif // QT_NO_DOCKWIDGET
/*!
diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h
index ab6ee22748..70d78a7904 100644
--- a/src/widgets/widgets/qmainwindow.h
+++ b/src/widgets/widgets/qmainwindow.h
@@ -165,6 +165,9 @@ public:
bool restoreDockWidget(QDockWidget *dockwidget);
Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const;
+
+ void resizeDocks(const QList<QDockWidget *> &docks,
+ const QList<int> &sizes, Qt::Orientation orientation);
#endif // QT_NO_DOCKWIDGET
QByteArray saveState(int version = 0) const;
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp
index 141e3ed135..d9f8c8f991 100644
--- a/src/winmain/qtmain_winrt.cpp
+++ b/src/winmain/qtmain_winrt.cpp
@@ -49,38 +49,44 @@
entry point within the newly created GUI thread.
*/
+#if _MSC_VER < 1900
#include <new.h>
typedef struct
{
int newmode;
} _startupinfo;
+#endif // _MSC_VER < 1900
extern "C" {
+#if _MSC_VER < 1900
int __getmainargs(int *argc, char ***argv, char ***env, int expandWildcards, _startupinfo *info);
+#endif
int main(int, char **);
}
#include <qbytearray.h>
#include <qstring.h>
-#include <qlist.h>
-#include <qvector.h>
#include <qdir.h>
#include <qstandardpaths.h>
+#include <qfunctions_winrt.h>
#include <wrl.h>
#include <Windows.ApplicationModel.core.h>
+#include <windows.ui.xaml.h>
+#include <windows.ui.xaml.controls.h>
using namespace ABI::Windows::ApplicationModel;
+using namespace ABI::Windows::ApplicationModel::Activation;
+using namespace ABI::Windows::ApplicationModel::Core;
using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
#define qHString(x) Wrappers::HString::MakeReference(x).Get()
#define CoreApplicationClass RuntimeClass_Windows_ApplicationModel_Core_CoreApplication
-typedef ITypedEventHandler<Core::CoreApplicationView *, Activation::IActivatedEventArgs *> ActivatedHandler;
-
-static int g_mainExitCode;
+typedef ITypedEventHandler<CoreApplicationView *, Activation::IActivatedEventArgs *> ActivatedHandler;
static QtMessageHandler defaultMessageHandler;
static void devMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message)
@@ -103,53 +109,112 @@ static void devMessageHandler(QtMsgType type, const QMessageLogContext &context,
defaultMessageHandler(type, context, message);
}
-class AppContainer : public Microsoft::WRL::RuntimeClass<Core::IFrameworkView>
+class AppContainer : public RuntimeClass<Xaml::IApplicationOverrides>
{
public:
- AppContainer(int argc, char *argv[]) : m_argc(argc), m_deleteArgv0(false)
+ AppContainer()
{
- m_argv.reserve(argc);
- for (int i = 0; i < argc; ++i) {
- // Workaround for empty argv[0] which occurs when WMAppManifest's ImageParams is used
- // The second argument is taken to be the executable
- if (i == 0 && argc >= 2 && !qstrlen(argv[0])) {
- const QByteArray argv0 = QDir::current()
- .absoluteFilePath(QString::fromLatin1(argv[1])).toUtf8();
- m_argv.append(qstrdup(argv0.constData()));
- m_argc -= 1;
- m_deleteArgv0 = true;
- ++i;
- continue;
- }
- m_argv.append(argv[i]);
- }
+ ComPtr<Xaml::IApplicationFactory> applicationFactory;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Application).Get(),
+ IID_PPV_ARGS(&applicationFactory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = applicationFactory->CreateInstance(this, &base, &core);
+ RETURN_VOID_IF_FAILED("Failed to create application container instance");
}
~AppContainer()
{
- if (m_deleteArgv0)
- delete[] m_argv[0];
- for (int i = m_argc; i < m_argv.size(); ++i)
- delete[] m_argv[i];
}
- // IFrameworkView Methods
- HRESULT __stdcall Initialize(Core::ICoreApplicationView *view)
+ int exec(int argc, char **argv)
{
- view->add_Activated(Callback<ActivatedHandler>(this, &AppContainer::onActivated).Get(),
- &m_activationToken);
- return S_OK;
+ args.reserve(argc);
+ for (int i = 0; i < argc; ++i)
+ args.append(argv[i]);
+
+ mainThread = CreateThread(NULL, 0, [](void *param) -> DWORD {
+ AppContainer *app = reinterpret_cast<AppContainer *>(param);
+ int argc = app->args.count();
+ char **argv = app->args.data();
+ return main(argc, argv);
+ }, this, CREATE_SUSPENDED, nullptr);
+
+ HRESULT hr;
+ ComPtr<Xaml::IApplicationStatics> appStatics;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Application).Get(),
+ IID_PPV_ARGS(&appStatics));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = appStatics->Start(Callback<Xaml::IApplicationInitializationCallback>([](Xaml::IApplicationInitializationCallbackParams *) {
+ return S_OK;
+ }).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ DWORD exitCode;
+ GetExitCodeThread(mainThread, &exitCode);
+ return exitCode;
+ }
+
+private:
+ HRESULT __stdcall OnActivated(IActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ return base->OnActivated(args);
}
- HRESULT __stdcall SetWindow(ABI::Windows::UI::Core::ICoreWindow *) { return S_OK; }
- HRESULT __stdcall Load(HSTRING) { return S_OK; }
- HRESULT __stdcall Run()
+
+ HRESULT __stdcall OnLaunched(ILaunchActivatedEventArgs *launchArgs) Q_DECL_OVERRIDE
{
+#if _MSC_VER >= 1900
+ commandLine = QString::fromWCharArray(GetCommandLine()).toUtf8();
+#endif
+ HString launchCommandLine;
+ launchArgs->get_Arguments(launchCommandLine.GetAddressOf());
+ if (launchCommandLine.IsValid()) {
+ quint32 launchCommandLineLength;
+ const wchar_t *launchCommandLineBuffer = launchCommandLine.GetRawBuffer(&launchCommandLineLength);
+ if (!commandLine.isEmpty() && launchCommandLineLength)
+ commandLine += ' ';
+ if (launchCommandLineLength)
+ commandLine += QString::fromWCharArray(launchCommandLineBuffer, launchCommandLineLength).toUtf8();
+ }
+ if (!commandLine.isEmpty())
+ args.append(commandLine.data());
+
+ bool quote = false;
+ bool escape = false;
+ for (int i = 0; i < commandLine.size(); ++i) {
+ switch (commandLine.at(i)) {
+ case '\\':
+ escape = true;
+ break;
+ case '"':
+ if (escape) {
+ escape = false;
+ break;
+ }
+ quote = !quote;
+ commandLine[i] = '\0';
+ break;
+ case ' ':
+ if (quote)
+ break;
+ commandLine[i] = '\0';
+ if (args.last()[0] != '\0')
+ args.append(commandLine.data() + i + 1);
+ // fall through
+ default:
+ if (args.last()[0] == '\0')
+ args.last() = commandLine.data() + i;
+ escape = false; // only quotes are escaped
+ break;
+ }
+ }
+
bool develMode = false;
bool debugWait = false;
- foreach (const QByteArray &arg, m_argv) {
- if (arg == "-qdevel")
+ foreach (const char *arg, args) {
+ if (strcmp(arg, "-qdevel") == 0)
develMode = true;
- if (arg == "-qdebug")
+ if (strcmp(arg, "-qdebug") == 0)
debugWait = true;
}
if (develMode) {
@@ -173,98 +238,70 @@ public:
while (!IsDebuggerPresent())
WaitForSingleObjectEx(GetCurrentThread(), 1, true);
}
- g_mainExitCode = main(m_argv.count(), m_argv.data());
+
+ ResumeThread(mainThread);
return S_OK;
}
- HRESULT __stdcall Uninitialize() { return S_OK; }
-private:
- // Activation handler
- HRESULT onActivated(Core::ICoreApplicationView *, Activation::IActivatedEventArgs *args)
+ HRESULT __stdcall OnFileActivated(IFileActivatedEventArgs *args) Q_DECL_OVERRIDE
{
- Activation::ILaunchActivatedEventArgs *launchArgs;
- if (SUCCEEDED(args->QueryInterface(&launchArgs))) {
- for (int i = m_argc; i < m_argv.size(); ++i)
- delete[] m_argv[i];
- m_argv.resize(m_argc);
- HString arguments;
- launchArgs->get_Arguments(arguments.GetAddressOf());
- if (arguments.IsValid()) {
- foreach (const QByteArray &arg, QString::fromWCharArray(
- arguments.GetRawBuffer(nullptr)).toLocal8Bit().split(' ')) {
- m_argv.append(qstrdup(arg.constData()));
- }
- }
- }
+ Q_UNUSED(args);
return S_OK;
}
- int m_argc;
- QVector<char *> m_argv;
- bool m_deleteArgv0;
- EventRegistrationToken m_activationToken;
-};
+ HRESULT __stdcall OnSearchActivated(ISearchActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
-class AppViewSource : public Microsoft::WRL::RuntimeClass<Core::IFrameworkViewSource>
-{
-public:
- AppViewSource(int argc, char **argv) : m_argc(argc), m_argv(argv) { }
- HRESULT __stdcall CreateView(Core::IFrameworkView **frameworkView)
+ HRESULT __stdcall OnShareTargetActivated(IShareTargetActivatedEventArgs *args) Q_DECL_OVERRIDE
{
- return (*frameworkView = Make<AppContainer>(m_argc, m_argv).Detach()) ? S_OK : E_OUTOFMEMORY;
+ Q_UNUSED(args);
+ return S_OK;
}
-private:
- int m_argc;
- char **m_argv;
+
+ HRESULT __stdcall OnFileOpenPickerActivated(IFileOpenPickerActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
+
+ HRESULT __stdcall OnFileSavePickerActivated(IFileSavePickerActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
+
+ HRESULT __stdcall OnCachedFileUpdaterActivated(ICachedFileUpdaterActivatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
+
+ HRESULT __stdcall OnWindowCreated(Xaml::IWindowCreatedEventArgs *args) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(args);
+ return S_OK;
+ }
+
+ ComPtr<Xaml::IApplicationOverrides> base;
+ ComPtr<Xaml::IApplication> core;
+ QByteArray commandLine;
+ QVarLengthArray<char *> args;
+ HANDLE mainThread;
};
// Main entry point for Appx containers
int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
-#if _MSC_VER < 1900
int argc = 0;
- char **argv, **env;
+ char **argv = 0, **env = 0;
+#if _MSC_VER < 1900
_startupinfo info = { _query_new_mode() };
if (int init = __getmainargs(&argc, &argv, &env, false, &info))
return init;
-#else
- QByteArray commandLine = QString::fromWCharArray(GetCommandLine()).toUtf8();
- QVarLengthArray<char *> args;
- args.append(commandLine.data());
- bool quote = false;
- bool escape = false;
- for (int i = 0; i < commandLine.size(); ++i) {
- switch (commandLine.at(i)) {
- case '\\':
- escape = true;
- break;
- case '"':
- if (escape) {
- escape = false;
- break;
- }
- quote = !quote;
- commandLine[i] = '\0';
- break;
- case ' ':
- if (quote)
- break;
- commandLine[i] = '\0';
- if (args.last()[0] != '\0')
- args.append(commandLine.data() + i + 1);
- // fall through
- default:
- if (args.last()[0] == '\0')
- args.last() = commandLine.data() + i;
- escape = false; // only quotes are escaped
- break;
- }
- }
- int argc = args.size();
- char **argv = args.data();
- char **env = Q_NULLPTR;
#endif // _MSC_VER >= 1900
-
for (int i = 0; env && env[i]; ++i) {
QByteArray var(env[i]);
int split = var.indexOf('=');
@@ -275,10 +312,6 @@ int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
if (FAILED(RoInitialize(RO_INIT_MULTITHREADED)))
return 1;
- Core::ICoreApplication *appFactory;
- if (FAILED(RoGetActivationFactory(qHString(CoreApplicationClass), IID_PPV_ARGS(&appFactory))))
- return 2;
-
- appFactory->Run(Make<AppViewSource>(argc, argv).Get());
- return g_mainExitCode;
+ ComPtr<AppContainer> app = Make<AppContainer>();
+ return app->exec(argc, argv);
}
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index 0ffac21186..e810f48d6c 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -122,6 +122,7 @@ private slots:
void removeFileWhileProcessIsRunning();
void fileWriterProcess();
void switchReadChannels();
+ void discardUnwantedOutput();
void setWorkingDirectory();
void setNonExistentWorkingDirectory();
#endif // not Q_OS_WINCE
@@ -2228,6 +2229,25 @@ void tst_QProcess::switchReadChannels()
}
#endif
+#ifndef Q_OS_WINCE
+// Reading and writing to a process is not supported on Qt/CE
+void tst_QProcess::discardUnwantedOutput()
+{
+ QProcess process;
+
+ process.setProgram("testProcessEcho2/testProcessEcho2");
+ process.start(QIODevice::WriteOnly);
+ process.write("Hello, World");
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished(5000));
+
+ process.setReadChannel(QProcess::StandardOutput);
+ QCOMPARE(process.bytesAvailable(), Q_INT64_C(0));
+ process.setReadChannel(QProcess::StandardError);
+ QCOMPARE(process.bytesAvailable(), Q_INT64_C(0));
+}
+#endif
+
//-----------------------------------------------------------------------------
#ifndef Q_OS_WINCE
// Q_OS_WIN - setWorkingDirectory will chdir before starting the process on unices
diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp
index a07247316e..b681f9829a 100644
--- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp
+++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp
@@ -1079,7 +1079,7 @@ static bool canSendUnixFd(DBusConnection *connection)
# if DBUS_VERSION-0 >= 0x010400
can_send_type = dbus_connection_can_send_type;
# endif
-#else
+#elif !defined(QT_NO_LIBRARY)
// run-time check if the next functions are available
can_send_type = (can_send_type_t)qdbus_resolve_conditionally("dbus_connection_can_send_type");
#endif
diff --git a/tests/auto/dbus/qdbustype/tst_qdbustype.cpp b/tests/auto/dbus/qdbustype/tst_qdbustype.cpp
index 63444b61ad..4408729e7c 100644
--- a/tests/auto/dbus/qdbustype/tst_qdbustype.cpp
+++ b/tests/auto/dbus/qdbustype/tst_qdbustype.cpp
@@ -94,7 +94,11 @@ static void addFixedTypes()
// the library recognizes this as valid type first.
// The following function was added for Unix FD support, so if it is
// present, so is support for Unix FDs.
+# ifndef QT_NO_LIBRARY
bool supportsUnixFds = qdbus_resolve_conditionally("dbus_connection_can_send_type");
+# else
+ bool supportsUnixFds = false;
+# endif
# else
bool supportsUnixFds = true;
# endif
diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
index b9d17bae62..b81a4e2c4c 100644
--- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
+++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
@@ -107,6 +107,7 @@ private slots:
void premultiply();
void unpremultiply_sse4();
void qrgba64();
+ void qrgba64MemoryLayout();
void qrgba64Premultiply();
void qrgba64Equivalence();
@@ -1495,6 +1496,24 @@ void tst_QColor::qrgba64()
QCOMPARE(rgb64.green(), quint16(0x4422));
}
+void tst_QColor::qrgba64MemoryLayout()
+{
+ QRgba64 rgb64 = QRgba64::fromRgba64(0x0123, 0x4567, 0x89ab, 0xcdef);
+ QCOMPARE(rgb64.red(), quint16(0x0123));
+ QCOMPARE(rgb64.green(), quint16(0x4567));
+ QCOMPARE(rgb64.blue(), quint16(0x89ab));
+ QCOMPARE(rgb64.alpha(), quint16(0xcdef));
+
+ // Check in-memory order, so it can be used by things like SSE
+ Q_STATIC_ASSERT(sizeof(QRgba64) == sizeof(quint64));
+ quint16 memory[4];
+ memcpy(memory, &rgb64, sizeof(QRgba64));
+ QCOMPARE(memory[0], quint16(0x0123));
+ QCOMPARE(memory[1], quint16(0x4567));
+ QCOMPARE(memory[2], quint16(0x89ab));
+ QCOMPARE(memory[3], quint16(0xcdef));
+}
+
void tst_QColor::qrgba64Premultiply()
{
// Tests that qPremultiply(qUnpremultiply(rgba64)) returns rgba64.
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index 3e98e630c2..e8d90edd2d 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -4882,8 +4882,12 @@ void tst_QPainter::blendARGBonRGB_data()
<< QPainter::CompositionMode_SourceOver << qRgba(85, 0, 0, 85) << 85;
QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32
<< QPainter::CompositionMode_Source << qRgba(255, 0, 0, 85) << 85;
+ QTest::newRow("ARGB source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 120) << 85;
QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied
<< QPainter::CompositionMode_Source << qRgba(85, 0, 0, 85) << 85;
+ QTest::newRow("ARGB_PM source RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_Source << qRgba(180, 0, 0, 180) << 170;
QTest::newRow("ARGB source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32
<< QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 85) << 85;
QTest::newRow("ARGB_PM source-in RGB30") << QImage::Format_RGB30 << QImage::Format_ARGB32_Premultiplied
diff --git a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp
index 3bf59910f3..48a15641b2 100644
--- a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp
+++ b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp
@@ -47,6 +47,7 @@
#include <QtCore/QVariant>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
+#include <QtCore/QJsonDocument>
#include <algorithm>
@@ -107,6 +108,7 @@ private slots:
void testConfiguration();
void testGlConfiguration();
void testBugList();
+ void testDefaultWindowsBlacklist();
};
static void dumpConfiguration(QTextStream &str)
@@ -284,6 +286,20 @@ void tst_QOpenGlConfig::testBugList()
msgSetMismatch(expectedFeatures, actualFeatures));
}
+void tst_QOpenGlConfig::testDefaultWindowsBlacklist()
+{
+ if (qGuiApp->platformName() != QStringLiteral("windows"))
+ QSKIP("Only applicable to Windows");
+
+ QFile f(QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json"));
+ QVERIFY(f.open(QIODevice::ReadOnly | QIODevice::Text));
+ QJsonParseError err;
+ QJsonDocument doc = QJsonDocument::fromJson(f.readAll(), &err);
+ QVERIFY2(err.error == 0,
+ QStringLiteral("Failed to parse built-in Windows GPU blacklist. %1 : %2")
+ .arg(err.offset).arg(err.errorString()).toLatin1());
+}
+
QTEST_MAIN(tst_QOpenGlConfig)
#include "tst_qopenglconfig.moc"
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index 61586eb841..b98ab68ae9 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -241,6 +241,10 @@ private slots:
void aggregateFunctionTypes_data() { generic_data(); }
void aggregateFunctionTypes();
+
+ void integralTypesMysql_data() { generic_data("QMYSQL"); }
+ void integralTypesMysql();
+
private:
// returns all database connections
void generic_data(const QString &engine=QString());
@@ -3974,5 +3978,65 @@ void tst_QSqlQuery::aggregateFunctionTypes()
}
}
+template<typename T>
+void runIntegralTypesMysqlTest(QSqlDatabase &db, const QString &tableName, const QString &type, const bool withPreparedStatement,
+ const T min = std::numeric_limits<T>::min(), const T max = std::numeric_limits<T>::max())
+{
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec("DROP TABLE IF EXISTS " + tableName));
+ QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id " + type + ")"));
+
+ const int steps = 20;
+ const T increment = max / steps - min / steps;
+
+ // insert some values
+ QVector<T> values;
+ values.resize(steps);
+ T v = min;
+ if (withPreparedStatement) {
+ QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " (id) VALUES (?)"));
+ }
+ for (int i = 0; i < values.size(); ++i) {
+ if (withPreparedStatement) {
+ q.bindValue(0, v);
+ QVERIFY_SQL(q, exec());
+ } else {
+ QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (" + QString::number(v) + ")"));
+ }
+ values[i] = v;
+ v += increment;
+ }
+
+ // ensure we can read them back properly
+ QVERIFY_SQL(q, exec("SELECT id FROM " + tableName));
+ QVector<T> actualValues;
+ actualValues.reserve(values.size());
+ while (q.next()) {
+ actualValues << q.value(0).value<T>();
+ }
+ QCOMPARE(actualValues, values);
+}
+
+void tst_QSqlQuery::integralTypesMysql()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ for (int i = 0; i < 2; ++i) {
+ const bool withPreparedStatement = (i == 1);
+ runIntegralTypesMysqlTest<char>(db, "tinyIntTest", "TINYINT", withPreparedStatement);
+ runIntegralTypesMysqlTest<unsigned char>(db, "unsignedTinyIntTest", "TINYINT UNSIGNED", withPreparedStatement);
+ runIntegralTypesMysqlTest<char>(db, "smallIntTest", "SMALLINT", withPreparedStatement);
+ runIntegralTypesMysqlTest<unsigned char>(db, "unsignedSmallIntTest", "SMALLINT UNSIGNED", withPreparedStatement);
+ runIntegralTypesMysqlTest<int>(db, "mediumIntTest", "MEDIUMINT", withPreparedStatement, -(1 << 23), (1 << 23) - 1);
+ runIntegralTypesMysqlTest<unsigned int>(db, "unsignedMediumIntTest", "MEDIUMINT UNSIGNED", withPreparedStatement, 0, (1 << 24) - 1);
+ runIntegralTypesMysqlTest<int>(db, "intTest", "INT", withPreparedStatement);
+ runIntegralTypesMysqlTest<unsigned int>(db, "unsignedIntTest", "INT UNSIGNED", withPreparedStatement);
+ runIntegralTypesMysqlTest<long long>(db, "bigIntTest", "BIGINT", withPreparedStatement);
+ runIntegralTypesMysqlTest<unsigned long long>(db, "unsignedBigIntTest", "BIGINT UNSIGNED", withPreparedStatement);
+ }
+}
+
QTEST_MAIN( tst_QSqlQuery )
#include "tst_qsqlquery.moc"
diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
index e8c533f301..6282028746 100644
--- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
@@ -149,6 +149,8 @@ private slots:
void toggleUnifiedTitleAndToolBarOnMac();
#endif
void QTBUG21378_animationFinished();
+ void resizeDocks();
+ void resizeDocks_data();
};
@@ -1950,5 +1952,96 @@ void tst_QMainWindow::QTBUG21378_animationFinished()
delete mwClickTimer;
QVERIFY(true);
}
+
+Q_DECLARE_METATYPE(Qt::Orientation)
+
+void tst_QMainWindow::resizeDocks_data()
+{
+ QTest::addColumn<Qt::Orientation>("orientation");
+ QTest::addColumn<QStringList>("docks");
+ QTest::addColumn<QList<int> >("sizes");
+
+ QTest::newRow("1") << Qt::Horizontal
+ << (QStringList() << "blue" << "orange" << "green" << "gray")
+ << (QList<int>() << 190 << 190 << 320 << 160);
+
+ QTest::newRow("2") << Qt::Vertical
+ << (QStringList() << "yellow" << "orange")
+ << (QList<int>() << 147 << 133 );
+
+
+ QTest::newRow("3") << Qt::Horizontal
+ << (QStringList() << "blue" << "yellow")
+ << (QList<int>() << 190 << 600);
+}
+
+void tst_QMainWindow::resizeDocks()
+{
+ AddList addList;
+ addList
+ << AddDockWidget("blue", Qt::LeftDockWidgetArea)
+ << AddDockWidget("red", Qt::TopDockWidgetArea)
+ << AddDockWidget("pink", "red")
+ << AddDockWidget("yellow", Qt::RightDockWidgetArea)
+ << AddDockWidget("orange", Qt::RightDockWidgetArea)
+ << AddDockWidget("green", "orange", Qt::Horizontal)
+ << AddDockWidget("gray", "orange", Qt::Horizontal);
+ /*
+ +--------------------------------+
+ | red/pink |
+ +------+-+-----------------------+
+ | | | yellow |
+ | blue + +--------+------+-------+
+ | | | orange | gray | green |
+ +------+-+--------+------+-------+
+
+ */
+
+ QMainWindow mw(0, Qt::BypassWindowManagerHint);
+ mw.setDockNestingEnabled(true);
+ mw.resize(1800, 600);
+
+ foreach (const AddDockWidget &i, addList)
+ i.apply(&mw);
+
+ foreach (QDockWidget *dw, mw.findChildren<QDockWidget *>())
+ dw->setStyleSheet( "* { background-color: " + dw->objectName() +" }");
+
+ mw.setCentralWidget(new QTextEdit);
+
+ mw.show();
+ QTest::qWaitForWindowExposed(&mw);
+
+ QFETCH(Qt::Orientation, orientation);
+ QFETCH(QStringList, docks);
+ QFETCH(QList<int>, sizes);
+
+ QList<QDockWidget *> list;
+ foreach (const QString &name, docks) {
+ QDockWidget *d = mw.findChild<QDockWidget *>(name);
+ QVERIFY(d);
+ list << d;
+ }
+
+ mw.resizeDocks(list, sizes, orientation);
+
+ qApp->processEvents();
+
+ int totalFromList = 0;
+ int actualTotal = 0;
+ for (int i = 0; i < docks.count(); ++i) {
+ totalFromList += sizes[i];
+ QSize s = list[i]->size();
+ actualTotal += (orientation == Qt::Horizontal) ? s.width() : s.height();
+// qDebug() << list[i] << list[i]->size() << sizes[i];
+ }
+
+ for (int i = 0; i < docks.count(); ++i) {
+ QSize s = list[i]->size();
+ int value = (orientation == Qt::Horizontal) ? s.width() : s.height();
+ QCOMPARE(value, qRound(sizes[i]*actualTotal/double(totalFromList)));
+ }
+}
+
QTEST_MAIN(tst_QMainWindow)
#include "tst_qmainwindow.moc"
diff --git a/tests/benchmarks/sql/kernel/qsqlquery/main.cpp b/tests/benchmarks/sql/kernel/qsqlquery/main.cpp
index 63aa6f7250..b5937b76b0 100644
--- a/tests/benchmarks/sql/kernel/qsqlquery/main.cpp
+++ b/tests/benchmarks/sql/kernel/qsqlquery/main.cpp
@@ -55,6 +55,8 @@ public slots:
private slots:
void benchmark_data() { generic_data(); }
void benchmark();
+ void benchmarkSelectPrepared_data() { generic_data(); }
+ void benchmarkSelectPrepared();
private:
// returns all database connections
@@ -264,4 +266,42 @@ void tst_QSqlQuery::benchmark()
tst_Databases::safeDropTable( db, tableName );
}
+void tst_QSqlQuery::benchmarkSelectPrepared()
+{
+ QFETCH( QString, dbName );
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ if (tst_Databases::getMySqlVersion(db).section(QChar('.'), 0, 0).toInt() < 5)
+ QSKIP("Test requires MySQL >= 5.0");
+
+ QSqlQuery q(db);
+ const QString tableName(qTableName("benchmark", __FILE__, db));
+
+ tst_Databases::safeDropTable(db, tableName);
+
+ QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + "(id INT NOT NULL)"));
+
+ const int NUM_ROWS = 1000;
+ int expectedSum = 0;
+ QString fillQuery = "INSERT INTO " + tableName + " VALUES (0)";
+ for (int i = 1; i < NUM_ROWS; ++i) {
+ fillQuery += ", (" + QString::number(i) + ")";
+ expectedSum += i;
+ }
+ QVERIFY_SQL(q, exec(fillQuery));
+
+ QVERIFY_SQL(q, prepare("SELECT id FROM "+tableName));
+ QBENCHMARK {
+ QVERIFY_SQL(q, exec());
+ int sum = 0;
+
+ while (q.next())
+ sum += q.value(0).toInt();
+
+ QCOMPARE(sum, expectedSum);
+ }
+
+ tst_Databases::safeDropTable(db, tableName);
+}
+
#include "main.moc"