summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/winrt
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/winrt')
-rw-r--r--src/plugins/platforms/winrt/blit.hlsl14
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.cpp359
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.h16
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.cpp60
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.h24
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp155
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrteventdispatcher.cpp1
-rw-r--r--src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp512
-rw-r--r--src/plugins/platforms/winrt/qwinrtfiledialoghelper.h104
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.cpp505
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.h (renamed from src/plugins/platforms/winrt/qwinrtplatformtheme.cpp)78
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp58
-rw-r--r--src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp232
-rw-r--r--src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h (renamed from src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h)29
-rw-r--r--src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp204
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp582
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h86
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.cpp129
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.h27
-rw-r--r--src/plugins/platforms/winrt/qwinrttheme.cpp259
-rw-r--r--src/plugins/platforms/winrt/qwinrttheme.h (renamed from src/plugins/platforms/winrt/qwinrtplatformtheme.h)20
-rw-r--r--src/plugins/platforms/winrt/winrt.pro31
23 files changed, 2393 insertions, 1094 deletions
diff --git a/src/plugins/platforms/winrt/blit.hlsl b/src/plugins/platforms/winrt/blit.hlsl
deleted file mode 100644
index 170e7f40ca..0000000000
--- a/src/plugins/platforms/winrt/blit.hlsl
+++ /dev/null
@@ -1,14 +0,0 @@
-uniform SamplerState Sampler : register(s0);
-uniform Texture2D Texture : register(t0);
-
-void blitvs(in float4 pos0 : TEXCOORD0, in float2 tex0 : TEXCOORD1,
- out float4 gl_Position : SV_POSITION, out float2 coord : TEXCOORD0)
-{
- coord = tex0;
- gl_Position = pos0 * float4(1.0, -1.0, 1.0, 1.0);
-}
-
-float4 blitps(in float4 gl_Position : SV_POSITION, in float2 coord : TEXCOORD0) : SV_TARGET0
-{
- return Texture.Sample(Sampler, coord);
-}
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
index b8418eef6a..8513e872e2 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
@@ -45,343 +45,136 @@
#include "qwinrtwindow.h"
#include "qwinrteglcontext.h"
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFramebufferObject>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
-// Generated shader headers
-#include "blitps.h"
-#include "blitvs.h"
-
-namespace { // Utility namespace for writing out an ANGLE-compatible binary blob
-
-// Must match packaged ANGLE
-enum : quint32 {
- AngleMajorVersion = 1,
- AngleMinorVersion = 3
-};
-
-struct ShaderString
-{
- ShaderString(const char *data = 0) : data(data) { }
- const char *data;
-};
-
-// ANGLE stream compatibility - when size_t is 32-bit, QDataStream::writeBytes() also works
-QDataStream &operator<<(QDataStream &stream, const ShaderString &shaderString)
-{
- if (!shaderString.data)
- return stream << size_t(0);
-
- size_t len = strlen(shaderString.data);
- stream << len;
- stream.writeRawData(shaderString.data, int(len));
- return stream;
-}
-
-struct Attribute
-{
- Attribute(GLenum type = 0, const char *name = 0, quint32 index = 0)
- : type(type), name(name), index(index) { }
- GLenum type;
- ShaderString name;
- quint32 index;
-};
-
-struct Sampler
-{
- enum TextureType { Texture2D, TextureCube };
- Sampler(bool active = false, GLint unit = 0, TextureType type = Texture2D)
- : active(active), unit(unit), type(type) { }
- bool active;
- GLint unit;
- TextureType type;
-};
-
-struct Uniform
-{
- Uniform() { }
- Uniform(GLenum type, quint32 precision, const char *name, quint32 arraySize,
- quint32 psRegisterIndex, quint32 vsRegisterIndex, quint32 registerCount)
- : type(type), precision(precision), name(name), arraySize(arraySize)
- , psRegisterIndex(psRegisterIndex), vsRegisterIndex(vsRegisterIndex), registerCount(registerCount) { }
- GLenum type;
- quint32 precision;
- ShaderString name;
- quint32 arraySize;
- quint32 psRegisterIndex;
- quint32 vsRegisterIndex;
- quint32 registerCount;
-};
+QT_BEGIN_NAMESPACE
-struct UniformIndex
+class QWinRTBackingStorePrivate
{
- UniformIndex(const char *name = 0, quint32 element = 0, quint32 index = 0)
- : name(name), element(element), index(index) { }
- ShaderString name;
- quint32 element;
- quint32 index;
+public:
+ bool initialized;
+ QSize size;
+ QScopedPointer<QOpenGLContext> context;
+ QScopedPointer<QOpenGLFramebufferObject> fbo;
+ QWinRTScreen *screen;
+ QImage paintDevice;
};
-static const QByteArray createAngleBinary(
- const QVector<Attribute> &attributes,
- const QVector<Sampler> &textureSamplers,
- const QVector<Sampler> &vertexSamplers,
- const QVector<Uniform> &uniforms,
- const QVector<UniformIndex> &uniformIndex,
- const QByteArray &pixelShader,
- const QByteArray &vertexShader,
- const QByteArray &geometryShader = QByteArray(),
- bool usesPointSize = false)
+QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
+ : QPlatformBackingStore(window), d_ptr(new QWinRTBackingStorePrivate)
{
- QByteArray binary;
-
- QDataStream stream(&binary, QIODevice::WriteOnly);
- stream.setByteOrder(QDataStream::LittleEndian);
-
- stream << quint32(GL_PROGRAM_BINARY_ANGLE)
- << qint32(AngleMajorVersion)
- << qint32(AngleMinorVersion);
-
- // Vertex attributes
- for (int i = 0; i < 16; ++i) {
- if (i < attributes.size())
- stream << quint32(attributes[i].type) << attributes[i].name << attributes[i].index;
- else
- stream << quint32(GL_NONE) << ShaderString() << qint32(-1);
- }
-
- // Texture units
- for (int i = 0; i < 16; ++i) {
- if (i < textureSamplers.size())
- stream << textureSamplers[i].active << textureSamplers[i].unit << qint32(textureSamplers[i].type);
- else
- stream << false << qint32(0) << qint32(Sampler::Texture2D);
- }
-
- // Vertex texture units
- for (int i = 0; i < 16; ++i) {
- if (i < vertexSamplers.size())
- stream << vertexSamplers[i].active << vertexSamplers[i].unit << qint32(vertexSamplers[i].type);
- else
- stream << false << qint32(0) << qint32(Sampler::Texture2D);
- }
-
- stream << vertexSamplers.size()
- << textureSamplers.size()
- << usesPointSize;
-
- stream << size_t(uniforms.size());
- foreach (const Uniform &uniform, uniforms) {
- stream << uniform.type << uniform.precision << uniform.name << uniform.arraySize
- << uniform.psRegisterIndex << uniform.vsRegisterIndex << uniform.registerCount;
- }
-
- stream << size_t(uniformIndex.size());
- foreach (const UniformIndex &index, uniformIndex)
- stream << index.name << index.element << index.index;
-
- stream << quint32(pixelShader.size())
- << quint32(vertexShader.size())
- << quint32(geometryShader.size());
-
- stream.writeRawData(pixelShader.constData(), pixelShader.size());
- stream.writeRawData(vertexShader.constData(), vertexShader.size());
- if (!geometryShader.isEmpty())
- stream.writeRawData(geometryShader.constData(), geometryShader.size());
-
- return binary;
-}
-
-} // namespace
-
-QT_BEGIN_NAMESPACE
+ Q_D(QWinRTBackingStore);
-static const GLfloat normCoords[] = { -1, 1, 1, 1, 1, -1, -1, -1 };
-static const GLfloat quadCoords[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
+ d->initialized = false;
+ d->screen = static_cast<QWinRTScreen*>(window->screen()->handle());
-QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
- , m_context(new QOpenGLContext)
- , m_shaderProgram(0)
- , m_fbo(0)
- , m_texture(0)
- , m_screen(static_cast<QWinRTScreen*>(window->screen()->handle()))
- , m_initialized(false)
-{
window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap
}
bool QWinRTBackingStore::initialize()
{
- if (m_initialized)
+ Q_D(QWinRTBackingStore);
+
+ if (d->initialized)
return true;
- m_context->setFormat(window()->requestedFormat());
- m_context->setScreen(window()->screen());
- if (!m_context->create())
+ d->context.reset(new QOpenGLContext);
+ QSurfaceFormat format = window()->requestedFormat();
+ format.setVersion(3, 0); // Required for ES3 framebuffer blit
+ d->context->setFormat(format);
+ d->context->setScreen(window()->screen());
+ if (!d->context->create())
return false;
- if (!m_context->makeCurrent(window()))
+ if (!d->context->makeCurrent(window()))
return false;
- glGenFramebuffers(1, &m_fbo);
- glGenRenderbuffers(1, &m_rbo);
- glGenTextures(1, &m_texture);
- m_shaderProgram = glCreateProgram();
-
-#if 0 // Standard GLES passthrough shader program
- static const char *vertexShaderSource =
- "attribute vec4 pos0;\n"
- "attribute vec2 tex0;\n"
- "varying vec2 coord;\n"
- "void main() {\n"
- " coord = tex0;\n"
- " gl_Position = pos0;\n"
- "}\n";
- static const char *fragmentShaderSource =
- "uniform sampler2D texture;\n"
- "varying highp vec2 coord;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(texture, coord);\n"
- "}\n";
- GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
- glCompileShader(vertexShader);
- GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
- glCompileShader(fragmentShader);
- glAttachShader(m_shaderProgram, vertexShader);
- glAttachShader(m_shaderProgram, fragmentShader);
- glLinkProgram(m_shaderProgram);
-#else // Precompiled passthrough shader
- QVector<Attribute> attributes = QVector<Attribute>() << Attribute(GL_FLOAT_VEC4, "pos0", 0)
- << Attribute(GL_FLOAT_VEC2, "tex0", 1);
- QVector<Sampler> textureSamplers = QVector<Sampler>() << Sampler(true, 0, Sampler::Texture2D);
- QVector<Sampler> vertexSamplers;
- QVector<Uniform> uniforms = QVector<Uniform>() << Uniform(GL_SAMPLER_2D, 0, "texture", 0, 0, -1, 1);
- QVector<UniformIndex> uniformsIndex = QVector<UniformIndex>() << UniformIndex("texture", 0, 0);
- QByteArray pixelShader(reinterpret_cast<const char *>(q_blitps), sizeof(q_blitps));
- QByteArray vertexShader(reinterpret_cast<const char *>(q_blitvs), sizeof(q_blitvs));
- QByteArray binary = createAngleBinary(attributes, textureSamplers, vertexSamplers,
- uniforms, uniformsIndex, pixelShader, vertexShader);
- glProgramBinaryOES(m_shaderProgram, GL_PROGRAM_BINARY_ANGLE, binary.constData(), binary.size());
-#endif
- m_context->doneCurrent();
- m_initialized = true;
+ d->context->doneCurrent();
+ d->initialized = true;
return true;
}
QWinRTBackingStore::~QWinRTBackingStore()
{
- if (!m_initialized)
- return;
- glDeleteBuffers(1, &m_fbo);
- glDeleteRenderbuffers(1, &m_rbo);
- glDeleteTextures(1, &m_texture);
- glDeleteProgram(m_shaderProgram);
}
QPaintDevice *QWinRTBackingStore::paintDevice()
{
- return &m_paintDevice;
+ Q_D(QWinRTBackingStore);
+ return &d->paintDevice;
}
void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
+ Q_D(QWinRTBackingStore);
Q_UNUSED(offset)
- if (m_size.isEmpty())
+
+ if (d->size.isEmpty())
return;
- m_context->makeCurrent(window);
-
- // Blitting the entire image width trades zero image copy/relayout for a larger texture upload.
- // Since we're blitting the whole width anyway, the boundingRect() is used in the assumption that
- // we don't repeat upload. This is of course dependent on the distance between update regions.
- // Ideally, we would use the GL_EXT_unpack_subimage extension, which should be possible to implement
- // since D3D11_MAPPED_SUBRESOURCE supports RowPitch (see below).
- // Note that single-line blits in a loop are *very* slow, so reducing calls to glTexSubImage2D
- // is probably a good idea anyway.
- glBindTexture(GL_TEXTURE_2D, m_texture);
- QRect bounds = region.boundingRect();
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), m_size.width(), bounds.height(),
- GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_paintDevice.constScanLine(bounds.y()));
- // TODO: Implement GL_EXT_unpack_subimage in ANGLE for more minimal uploads
- //glPixelStorei(GL_UNPACK_ROW_LENGTH, image->bytesPerLine());
- //glTexSubImage2D(GL_TEXTURE_2D, 0, bounds.x(), bounds.y(), bounds.width(), bounds.height(),
- // GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y()) + bounds.x() * 4);
-
- // Bind render buffer
- glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
-
- // Bind position
- glUseProgram(m_shaderProgram);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, normCoords);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, quadCoords);
-
- // Render
- const QSize blitSize = m_size * window->devicePixelRatio();
- glViewport(0, 0, blitSize.width(), blitSize.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- // Unbind
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
- glUseProgram(0);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- glBindTexture(GL_TEXTURE_2D, 0);
+ const bool ok = d->context->makeCurrent(window);
+ if (!ok)
+ qWarning("unable to flush");
- // fast blit - TODO: perform the blit inside swap buffers instead
- glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_fbo);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0);
- glBlitFramebufferANGLE(0, 0, blitSize.width(), blitSize.height(), // TODO: blit only the changed rectangle
- 0, 0, blitSize.width(), blitSize.height(),
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ const QRect bounds = region.boundingRect();
+ glBindTexture(GL_TEXTURE_2D, d->fbo->texture());
+ // TODO: when ANGLE GLES3 support is finished, use the glPixelStorei functions to minimize upload
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), d->size.width(), bounds.height(),
+ GL_RGBA, GL_UNSIGNED_BYTE, d->paintDevice.constScanLine(bounds.y()));
+ glBindTexture(GL_TEXTURE_2D, 0);
- m_context->swapBuffers(window);
- m_context->doneCurrent();
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, d->fbo->handle());
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ const int y1 = bounds.y();
+ const int y2 = y1 + bounds.height();
+ const int x1 = bounds.x();
+ const int x2 = x1 + bounds.width();
+ glBlitFramebuffer(x1, y1, x2, y2,
+ x1, d->size.height() - y1, x2, d->size.height() - y2,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ d->context->swapBuffers(window);
+ d->context->doneCurrent();
}
void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents)
{
+ Q_D(QWinRTBackingStore);
Q_UNUSED(staticContents)
+
if (!initialize())
return;
- if (m_size == size)
+ if (d->size == size)
return;
- m_size = size;
- if (m_size.isEmpty())
+ d->size = size;
+ if (d->size.isEmpty())
return;
- m_paintDevice = QImage(m_size, QImage::Format_ARGB32_Premultiplied);
-
- m_context->makeCurrent(window());
- // Input texture
- glBindTexture(GL_TEXTURE_2D, m_texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, m_size.width(), m_size.height(),
- 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glBindTexture(GL_TEXTURE_2D, 0);
- // Render buffer
- glBindRenderbuffer(GL_RENDERBUFFER, m_rbo);
- const QSize blitSize = m_size * window()->devicePixelRatio();
- glRenderbufferStorage(GL_RENDERBUFFER, GL_BGRA8_EXT, blitSize.width(), blitSize.height());
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
- m_context->doneCurrent();
+ d->paintDevice = QImage(d->size, QImage::Format_RGBA8888_Premultiplied);
+
+ const bool ok = d->context->makeCurrent(window());
+ if (!ok)
+ qWarning("unable to resize");
+
+ d->fbo.reset(new QOpenGLFramebufferObject(d->size));
+
+ d->context->doneCurrent();
+}
+
+QImage QWinRTBackingStore::toImage() const
+{
+ Q_D(const QWinRTBackingStore);
+ return d->paintDevice;
}
void QWinRTBackingStore::beginPaint(const QRegion &region)
{
- Q_UNUSED(region)
- resize(window()->size(), QRegion());
+ resize(window()->size(), region);
}
void QWinRTBackingStore::endPaint()
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h
index f00fa85a26..40728559f7 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.h
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h
@@ -48,8 +48,8 @@
QT_BEGIN_NAMESPACE
class QWinRTScreen;
-class QOpenGLContext;
+class QWinRTBackingStorePrivate;
class QWinRTBackingStore : public QPlatformBackingStore
{
public:
@@ -60,19 +60,13 @@ public:
void endPaint();
void flush(QWindow *window, const QRegion &region, const QPoint &offset);
void resize(const QSize &size, const QRegion &staticContents);
- QImage toImage() const Q_DECL_OVERRIDE { return m_paintDevice; }
+ QImage toImage() const Q_DECL_OVERRIDE;
private:
bool initialize();
- bool m_initialized;
- QSize m_size;
- QScopedPointer<QOpenGLContext> m_context;
- quint32 m_shaderProgram;
- quint32 m_fbo;
- quint32 m_rbo;
- quint32 m_texture;
- QWinRTScreen *m_screen;
- QImage m_paintDevice;
+
+ QScopedPointer<QWinRTBackingStorePrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTBackingStore)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp
index f09454ebc3..d2d87bde0b 100644
--- a/src/plugins/platforms/winrt/qwinrtcursor.cpp
+++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp
@@ -40,40 +40,54 @@
****************************************************************************/
#include "qwinrtcursor.h"
+#include "qwinrtscreen.h"
+
+#include <QtCore/qfunctions_winrt.h>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
#include <wrl.h>
#include <windows.ui.core.h>
#include <windows.foundation.h>
+using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::UI::Core;
using namespace ABI::Windows::Foundation;
-QT_BEGIN_NAMESPACE
+QT_USE_NAMESPACE
+
+class QWinRTCursorPrivate
+{
+public:
+ ComPtr<ICoreCursorFactory> cursorFactory;
+};
-QWinRTCursor::QWinRTCursor(ICoreWindow *window) : m_window(window), m_cursorFactory(nullptr)
+QWinRTCursor::QWinRTCursor()
+ : d_ptr(new QWinRTCursorPrivate)
{
-#ifndef Q_OS_WINPHONE
- GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Core_CoreCursor).Get(), &m_cursorFactory);
-#endif
+ Q_D(QWinRTCursor);
+
+ HRESULT hr;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Core_CoreCursor).Get(),
+ IID_PPV_ARGS(&d->cursorFactory));
+ Q_ASSERT_SUCCEEDED(hr);
}
QWinRTCursor::~QWinRTCursor()
{
- if (m_cursorFactory)
- m_cursorFactory->Release();
}
#ifndef QT_NO_CURSOR
-void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *)
+void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window)
{
-#ifndef Q_OS_WINPHONE
- if (!m_cursorFactory)
- return;
+ Q_D(QWinRTCursor);
+
+ ICoreWindow *coreWindow = static_cast<QWinRTScreen *>(window->screen()->handle())->coreWindow();
CoreCursorType type;
switch (windowCursor ? windowCursor->shape() : Qt::ArrowCursor) {
case Qt::BlankCursor:
- m_window->put_PointerCursor(nullptr);
+ coreWindow->put_PointerCursor(Q_NULLPTR);
return;
default:
case Qt::OpenHandCursor:
@@ -132,24 +146,20 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *)
break;
}
- ICoreCursor *cursor;
- if (SUCCEEDED(m_cursorFactory->CreateCursor(type, 0, &cursor)))
- m_window->put_PointerCursor(cursor);
-#else // Q_OS_WINPHONE
- Q_UNUSED(windowCursor)
-#endif // Q_OS_WINPHONE
+ ComPtr<ICoreCursor> cursor;
+ HRESULT 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.");
}
#endif // QT_NO_CURSOR
QPoint QWinRTCursor::pos() const
{
-#ifdef Q_OS_WINPHONE
- return QPlatformCursor::pos();
-#else
+ ICoreWindow *coreWindow =
+ static_cast<QWinRTScreen *>(QGuiApplication::primaryScreen()->handle())->coreWindow();
Point point;
- m_window->get_PointerPosition(&point);
+ coreWindow->get_PointerPosition(&point);
return QPoint(point.X, point.Y);
-#endif
}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.h b/src/plugins/platforms/winrt/qwinrtcursor.h
index f7b301a98b..a08002f34c 100644
--- a/src/plugins/platforms/winrt/qwinrtcursor.h
+++ b/src/plugins/platforms/winrt/qwinrtcursor.h
@@ -44,34 +44,22 @@
#include <qpa/qplatformcursor.h>
-namespace ABI {
- namespace Windows {
- namespace UI {
- namespace Core {
- struct ICoreWindow;
- struct ICoreCursorFactory;
- }
- }
- }
-}
-
-QT_BEGIN_NAMESPACE
+QT_USE_NAMESPACE
+class QWinRTCursorPrivate;
class QWinRTCursor : public QPlatformCursor
{
public:
- explicit QWinRTCursor(ABI::Windows::UI::Core::ICoreWindow *window);
+ explicit QWinRTCursor();
~QWinRTCursor();
#ifndef QT_NO_CURSOR
- void changeCursor(QCursor * windowCursor, QWindow *);
+ void changeCursor(QCursor * windowCursor, QWindow *window);
#endif
QPoint pos() const;
private:
- ABI::Windows::UI::Core::ICoreWindow *m_window;
- ABI::Windows::UI::Core::ICoreCursorFactory *m_cursorFactory;
+ QScopedPointer<QWinRTCursorPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTCursor)
};
-QT_END_NAMESPACE
-
#endif // QWINRTCURSOR_H
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
index 3a1958a20e..9e77a1a88a 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
@@ -60,4 +60,159 @@ EGLSurface QWinRTEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surf
}
}
+QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
+{
+ static QHash<QByteArray, QFunctionPointer> standardFuncs;
+ if (standardFuncs.isEmpty()) {
+ standardFuncs.insert(QByteArrayLiteral("glBindTexture"), (QFunctionPointer)&glBindTexture);
+ standardFuncs.insert(QByteArrayLiteral("glBlendFunc"), (QFunctionPointer)&glBlendFunc);
+ standardFuncs.insert(QByteArrayLiteral("glClear"), (QFunctionPointer)&glClear);
+ standardFuncs.insert(QByteArrayLiteral("glClearColor"), (QFunctionPointer)&glClearColor);
+ standardFuncs.insert(QByteArrayLiteral("glClearStencil"), (QFunctionPointer)&glClearStencil);
+ standardFuncs.insert(QByteArrayLiteral("glColorMask"), (QFunctionPointer)&glColorMask);
+ standardFuncs.insert(QByteArrayLiteral("glCopyTexImage2D"), (QFunctionPointer)&glCopyTexImage2D);
+ standardFuncs.insert(QByteArrayLiteral("glCopyTexSubImage2D"), (QFunctionPointer)&glCopyTexSubImage2D);
+ standardFuncs.insert(QByteArrayLiteral("glCullFace"), (QFunctionPointer)&glCullFace);
+ standardFuncs.insert(QByteArrayLiteral("glDeleteTextures"), (QFunctionPointer)&glDeleteTextures);
+ standardFuncs.insert(QByteArrayLiteral("glDepthFunc"), (QFunctionPointer)&glDepthFunc);
+ standardFuncs.insert(QByteArrayLiteral("glDepthMask"), (QFunctionPointer)&glDepthMask);
+ standardFuncs.insert(QByteArrayLiteral("glDisable"), (QFunctionPointer)&glDisable);
+ standardFuncs.insert(QByteArrayLiteral("glDrawArrays"), (QFunctionPointer)&glDrawArrays);
+ standardFuncs.insert(QByteArrayLiteral("glDrawElements"), (QFunctionPointer)&glDrawElements);
+ standardFuncs.insert(QByteArrayLiteral("glEnable"), (QFunctionPointer)&glEnable);
+ standardFuncs.insert(QByteArrayLiteral("glFinish"), (QFunctionPointer)&glFinish);
+ standardFuncs.insert(QByteArrayLiteral("glFlush"), (QFunctionPointer)&glFlush);
+ standardFuncs.insert(QByteArrayLiteral("glFrontFace"), (QFunctionPointer)&glFrontFace);
+ standardFuncs.insert(QByteArrayLiteral("glGenTextures"), (QFunctionPointer)&glGenTextures);
+ standardFuncs.insert(QByteArrayLiteral("glGetBooleanv"), (QFunctionPointer)&glGetBooleanv);
+ standardFuncs.insert(QByteArrayLiteral("glGetError"), (QFunctionPointer)&glGetError);
+ standardFuncs.insert(QByteArrayLiteral("glGetFloatv"), (QFunctionPointer)&glGetFloatv);
+ standardFuncs.insert(QByteArrayLiteral("glGetIntegerv"), (QFunctionPointer)&glGetIntegerv);
+ standardFuncs.insert(QByteArrayLiteral("glGetString"), (QFunctionPointer)&glGetString);
+ standardFuncs.insert(QByteArrayLiteral("glGetTexParameterfv"), (QFunctionPointer)&glGetTexParameterfv);
+ standardFuncs.insert(QByteArrayLiteral("glGetTexParameteriv"), (QFunctionPointer)&glGetTexParameteriv);
+ standardFuncs.insert(QByteArrayLiteral("glHint"), (QFunctionPointer)&glHint);
+ standardFuncs.insert(QByteArrayLiteral("glIsEnabled"), (QFunctionPointer)&glIsEnabled);
+ standardFuncs.insert(QByteArrayLiteral("glIsTexture"), (QFunctionPointer)&glIsTexture);
+ standardFuncs.insert(QByteArrayLiteral("glLineWidth"), (QFunctionPointer)&glLineWidth);
+ standardFuncs.insert(QByteArrayLiteral("glPixelStorei"), (QFunctionPointer)&glPixelStorei);
+ standardFuncs.insert(QByteArrayLiteral("glPolygonOffset"), (QFunctionPointer)&glPolygonOffset);
+ standardFuncs.insert(QByteArrayLiteral("glReadPixels"), (QFunctionPointer)&glReadPixels);
+ standardFuncs.insert(QByteArrayLiteral("glScissor"), (QFunctionPointer)&glScissor);
+ standardFuncs.insert(QByteArrayLiteral("glStencilFunc"), (QFunctionPointer)&glStencilFunc);
+ standardFuncs.insert(QByteArrayLiteral("glStencilMask"), (QFunctionPointer)&glStencilMask);
+ standardFuncs.insert(QByteArrayLiteral("glStencilOp"), (QFunctionPointer)&glStencilOp);
+ standardFuncs.insert(QByteArrayLiteral("glTexImage2D"), (QFunctionPointer)&glTexImage2D);
+ standardFuncs.insert(QByteArrayLiteral("glTexParameterf"), (QFunctionPointer)&glTexParameterf);
+ standardFuncs.insert(QByteArrayLiteral("glTexParameterfv"), (QFunctionPointer)&glTexParameterfv);
+ standardFuncs.insert(QByteArrayLiteral("glTexParameteri"), (QFunctionPointer)&glTexParameteri);
+ standardFuncs.insert(QByteArrayLiteral("glTexParameteriv"), (QFunctionPointer)&glTexParameteriv);
+ standardFuncs.insert(QByteArrayLiteral("glTexSubImage2D"), (QFunctionPointer)&glTexSubImage2D);
+ standardFuncs.insert(QByteArrayLiteral("glViewport"), (QFunctionPointer)&glViewport);
+ standardFuncs.insert(QByteArrayLiteral("glActiveTexture"), (QFunctionPointer)&glActiveTexture);
+ standardFuncs.insert(QByteArrayLiteral("glAttachShader"), (QFunctionPointer)&glAttachShader);
+ standardFuncs.insert(QByteArrayLiteral("glBindAttribLocation"), (QFunctionPointer)&glBindAttribLocation);
+ standardFuncs.insert(QByteArrayLiteral("glBindBuffer"), (QFunctionPointer)&glBindBuffer);
+ standardFuncs.insert(QByteArrayLiteral("glBindFramebuffer"), (QFunctionPointer)&glBindFramebuffer);
+ standardFuncs.insert(QByteArrayLiteral("glBindRenderbuffer"), (QFunctionPointer)&glBindRenderbuffer);
+ standardFuncs.insert(QByteArrayLiteral("glBlendColor"), (QFunctionPointer)&glBlendColor);
+ standardFuncs.insert(QByteArrayLiteral("glBlendEquation"), (QFunctionPointer)&glBlendEquation);
+ standardFuncs.insert(QByteArrayLiteral("glBlendEquationSeparate"), (QFunctionPointer)&glBlendEquationSeparate);
+ standardFuncs.insert(QByteArrayLiteral("glBlendFuncSeparate"), (QFunctionPointer)&glBlendFuncSeparate);
+ standardFuncs.insert(QByteArrayLiteral("glBufferData"), (QFunctionPointer)&glBufferData);
+ standardFuncs.insert(QByteArrayLiteral("glBufferSubData"), (QFunctionPointer)&glBufferSubData);
+ standardFuncs.insert(QByteArrayLiteral("glCheckFramebufferStatus"), (QFunctionPointer)&glCheckFramebufferStatus);
+ standardFuncs.insert(QByteArrayLiteral("glCompileShader"), (QFunctionPointer)&glCompileShader);
+ standardFuncs.insert(QByteArrayLiteral("glCompressedTexImage2D"), (QFunctionPointer)&glCompressedTexImage2D);
+ standardFuncs.insert(QByteArrayLiteral("glCompressedTexSubImage2D"), (QFunctionPointer)&glCompressedTexSubImage2D);
+ standardFuncs.insert(QByteArrayLiteral("glCreateProgram"), (QFunctionPointer)&glCreateProgram);
+ standardFuncs.insert(QByteArrayLiteral("glCreateShader"), (QFunctionPointer)&glCreateShader);
+ standardFuncs.insert(QByteArrayLiteral("glDeleteBuffers"), (QFunctionPointer)&glDeleteBuffers);
+ standardFuncs.insert(QByteArrayLiteral("glDeleteFramebuffers"), (QFunctionPointer)&glDeleteFramebuffers);
+ standardFuncs.insert(QByteArrayLiteral("glDeleteProgram"), (QFunctionPointer)&glDeleteProgram);
+ standardFuncs.insert(QByteArrayLiteral("glDeleteRenderbuffers"), (QFunctionPointer)&glDeleteRenderbuffers);
+ standardFuncs.insert(QByteArrayLiteral("glDeleteShader"), (QFunctionPointer)&glDeleteShader);
+ standardFuncs.insert(QByteArrayLiteral("glDetachShader"), (QFunctionPointer)&glDetachShader);
+ standardFuncs.insert(QByteArrayLiteral("glDisableVertexAttribArray"), (QFunctionPointer)&glDisableVertexAttribArray);
+ standardFuncs.insert(QByteArrayLiteral("glEnableVertexAttribArray"), (QFunctionPointer)&glEnableVertexAttribArray);
+ standardFuncs.insert(QByteArrayLiteral("glFramebufferRenderbuffer"), (QFunctionPointer)&glFramebufferRenderbuffer);
+ standardFuncs.insert(QByteArrayLiteral("glFramebufferTexture2D"), (QFunctionPointer)&glFramebufferTexture2D);
+ standardFuncs.insert(QByteArrayLiteral("glGenBuffers"), (QFunctionPointer)&glGenBuffers);
+ standardFuncs.insert(QByteArrayLiteral("glGenerateMipmap"), (QFunctionPointer)&glGenerateMipmap);
+ standardFuncs.insert(QByteArrayLiteral("glGenFramebuffers"), (QFunctionPointer)&glGenFramebuffers);
+ standardFuncs.insert(QByteArrayLiteral("glGenRenderbuffers"), (QFunctionPointer)&glGenRenderbuffers);
+ standardFuncs.insert(QByteArrayLiteral("glGetActiveAttrib"), (QFunctionPointer)&glGetActiveAttrib);
+ standardFuncs.insert(QByteArrayLiteral("glGetActiveUniform"), (QFunctionPointer)&glGetActiveUniform);
+ standardFuncs.insert(QByteArrayLiteral("glGetAttachedShaders"), (QFunctionPointer)&glGetAttachedShaders);
+ standardFuncs.insert(QByteArrayLiteral("glGetAttribLocation"), (QFunctionPointer)&glGetAttribLocation);
+ standardFuncs.insert(QByteArrayLiteral("glGetBufferParameteriv"), (QFunctionPointer)&glGetBufferParameteriv);
+ standardFuncs.insert(QByteArrayLiteral("glGetFramebufferAttachmentParameteriv"), (QFunctionPointer)&glGetFramebufferAttachmentParameteriv);
+ standardFuncs.insert(QByteArrayLiteral("glGetProgramiv"), (QFunctionPointer)&glGetProgramiv);
+ standardFuncs.insert(QByteArrayLiteral("glGetProgramInfoLog"), (QFunctionPointer)&glGetProgramInfoLog);
+ standardFuncs.insert(QByteArrayLiteral("glGetRenderbufferParameteriv"), (QFunctionPointer)&glGetRenderbufferParameteriv);
+ standardFuncs.insert(QByteArrayLiteral("glGetShaderiv"), (QFunctionPointer)&glGetShaderiv);
+ standardFuncs.insert(QByteArrayLiteral("glGetShaderInfoLog"), (QFunctionPointer)&glGetShaderInfoLog);
+ standardFuncs.insert(QByteArrayLiteral("glGetShaderPrecisionFormat"), (QFunctionPointer)&glGetShaderPrecisionFormat);
+ standardFuncs.insert(QByteArrayLiteral("glGetShaderSource"), (QFunctionPointer)&glGetShaderSource);
+ standardFuncs.insert(QByteArrayLiteral("glGetUniformfv"), (QFunctionPointer)&glGetUniformfv);
+ standardFuncs.insert(QByteArrayLiteral("glGetUniformiv"), (QFunctionPointer)&glGetUniformiv);
+ standardFuncs.insert(QByteArrayLiteral("glGetUniformLocation"), (QFunctionPointer)&glGetUniformLocation);
+ standardFuncs.insert(QByteArrayLiteral("glGetVertexAttribfv"), (QFunctionPointer)&glGetVertexAttribfv);
+ standardFuncs.insert(QByteArrayLiteral("glGetVertexAttribiv"), (QFunctionPointer)&glGetVertexAttribiv);
+ standardFuncs.insert(QByteArrayLiteral("glGetVertexAttribPointerv"), (QFunctionPointer)&glGetVertexAttribPointerv);
+ standardFuncs.insert(QByteArrayLiteral("glIsBuffer"), (QFunctionPointer)&glIsBuffer);
+ standardFuncs.insert(QByteArrayLiteral("glIsFramebuffer"), (QFunctionPointer)&glIsFramebuffer);
+ standardFuncs.insert(QByteArrayLiteral("glIsProgram"), (QFunctionPointer)&glIsProgram);
+ standardFuncs.insert(QByteArrayLiteral("glIsRenderbuffer"), (QFunctionPointer)&glIsRenderbuffer);
+ standardFuncs.insert(QByteArrayLiteral("glIsShader"), (QFunctionPointer)&glIsShader);
+ standardFuncs.insert(QByteArrayLiteral("glLinkProgram"), (QFunctionPointer)&glLinkProgram);
+ standardFuncs.insert(QByteArrayLiteral("glReleaseShaderCompiler"), (QFunctionPointer)&glReleaseShaderCompiler);
+ standardFuncs.insert(QByteArrayLiteral("glRenderbufferStorage"), (QFunctionPointer)&glRenderbufferStorage);
+ standardFuncs.insert(QByteArrayLiteral("glSampleCoverage"), (QFunctionPointer)&glSampleCoverage);
+ standardFuncs.insert(QByteArrayLiteral("glShaderBinary"), (QFunctionPointer)&glShaderBinary);
+ standardFuncs.insert(QByteArrayLiteral("glShaderSource"), (QFunctionPointer)&glShaderSource);
+ standardFuncs.insert(QByteArrayLiteral("glStencilFuncSeparate"), (QFunctionPointer)&glStencilFuncSeparate);
+ standardFuncs.insert(QByteArrayLiteral("glStencilMaskSeparate"), (QFunctionPointer)&glStencilMaskSeparate);
+ standardFuncs.insert(QByteArrayLiteral("glStencilOpSeparate"), (QFunctionPointer)&glStencilOpSeparate);
+ standardFuncs.insert(QByteArrayLiteral("glUniform1f"), (QFunctionPointer)&glUniform1f);
+ standardFuncs.insert(QByteArrayLiteral("glUniform1fv"), (QFunctionPointer)&glUniform1fv);
+ standardFuncs.insert(QByteArrayLiteral("glUniform1i"), (QFunctionPointer)&glUniform1i);
+ standardFuncs.insert(QByteArrayLiteral("glUniform1iv"), (QFunctionPointer)&glUniform1iv);
+ standardFuncs.insert(QByteArrayLiteral("glUniform2f"), (QFunctionPointer)&glUniform2f);
+ standardFuncs.insert(QByteArrayLiteral("glUniform2fv"), (QFunctionPointer)&glUniform2fv);
+ standardFuncs.insert(QByteArrayLiteral("glUniform2i"), (QFunctionPointer)&glUniform2i);
+ standardFuncs.insert(QByteArrayLiteral("glUniform2iv"), (QFunctionPointer)&glUniform2iv);
+ standardFuncs.insert(QByteArrayLiteral("glUniform3f"), (QFunctionPointer)&glUniform3f);
+ standardFuncs.insert(QByteArrayLiteral("glUniform3fv"), (QFunctionPointer)&glUniform3fv);
+ standardFuncs.insert(QByteArrayLiteral("glUniform3i"), (QFunctionPointer)&glUniform3i);
+ standardFuncs.insert(QByteArrayLiteral("glUniform3iv"), (QFunctionPointer)&glUniform3iv);
+ standardFuncs.insert(QByteArrayLiteral("glUniform4f"), (QFunctionPointer)&glUniform4f);
+ standardFuncs.insert(QByteArrayLiteral("glUniform4fv"), (QFunctionPointer)&glUniform4fv);
+ standardFuncs.insert(QByteArrayLiteral("glUniform4i"), (QFunctionPointer)&glUniform4i);
+ standardFuncs.insert(QByteArrayLiteral("glUniform4iv"), (QFunctionPointer)&glUniform4iv);
+ standardFuncs.insert(QByteArrayLiteral("glUniformMatrix2fv"), (QFunctionPointer)&glUniformMatrix2fv);
+ standardFuncs.insert(QByteArrayLiteral("glUniformMatrix3fv"), (QFunctionPointer)&glUniformMatrix3fv);
+ standardFuncs.insert(QByteArrayLiteral("glUniformMatrix4fv"), (QFunctionPointer)&glUniformMatrix4fv);
+ standardFuncs.insert(QByteArrayLiteral("glUseProgram"), (QFunctionPointer)&glUseProgram);
+ standardFuncs.insert(QByteArrayLiteral("glValidateProgram"), (QFunctionPointer)&glValidateProgram);
+ standardFuncs.insert(QByteArrayLiteral("glVertexAttrib1f"), (QFunctionPointer)&glVertexAttrib1f);
+ standardFuncs.insert(QByteArrayLiteral("glVertexAttrib1fv"), (QFunctionPointer)&glVertexAttrib1fv);
+ standardFuncs.insert(QByteArrayLiteral("glVertexAttrib2f"), (QFunctionPointer)&glVertexAttrib2f);
+ standardFuncs.insert(QByteArrayLiteral("glVertexAttrib2fv"), (QFunctionPointer)&glVertexAttrib2fv);
+ standardFuncs.insert(QByteArrayLiteral("glVertexAttrib3f"), (QFunctionPointer)&glVertexAttrib3f);
+ standardFuncs.insert(QByteArrayLiteral("glVertexAttrib3fv"), (QFunctionPointer)&glVertexAttrib3fv);
+ standardFuncs.insert(QByteArrayLiteral("glVertexAttrib4f"), (QFunctionPointer)&glVertexAttrib4f);
+ standardFuncs.insert(QByteArrayLiteral("glVertexAttrib4fv"), (QFunctionPointer)&glVertexAttrib4fv);
+ standardFuncs.insert(QByteArrayLiteral("glVertexAttribPointer"), (QFunctionPointer)&glVertexAttribPointer);
+ standardFuncs.insert(QByteArrayLiteral("glClearDepthf"), (QFunctionPointer)&glClearDepthf);
+ standardFuncs.insert(QByteArrayLiteral("glDepthRangef"), (QFunctionPointer)&glDepthRangef);
+ };
+
+ QHash<QByteArray, QFunctionPointer>::const_iterator i = standardFuncs.find(procName);
+ if (i != standardFuncs.end())
+ return i.value();
+
+ return QEGLPlatformContext::getProcAddress(procName);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h
index c065847374..6dc8dc6c9f 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.h
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.h
@@ -51,6 +51,8 @@ class QWinRTEGLContext : public QEGLPlatformContext
public:
explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface);
+ QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
+
protected:
EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
diff --git a/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp
index 98eb83f5eb..2bc8e6602f 100644
--- a/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp
+++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp
@@ -42,7 +42,6 @@
#include "qwinrteventdispatcher.h"
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformscreen.h>
-#include <qpa/qplatformscreenpageflipper.h>
#include <QtCore/QThread>
#include <QtGui/QGuiApplication>
diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
new file mode 100644
index 0000000000..768a94e951
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
@@ -0,0 +1,512 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtfiledialoghelper.h"
+#include "qwinrtfileengine.h"
+
+#include <QtCore/QEventLoop>
+#include <QtCore/QMap>
+#include <QtCore/QVector>
+#include <QtCore/qfunctions_winrt.h>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.pickers.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::Storage::Pickers;
+
+typedef IAsyncOperationCompletedHandler<StorageFile *> SingleFileHandler;
+typedef IAsyncOperationCompletedHandler<IVectorView<StorageFile *> *> MultipleFileHandler;
+typedef IAsyncOperationCompletedHandler<StorageFolder *> SingleFolderHandler;
+
+QT_BEGIN_NAMESPACE
+
+// Required for save file picker
+class WindowsStringVector : public RuntimeClass<IVector<HSTRING>>
+{
+public:
+ HRESULT __stdcall GetAt(quint32 index, HSTRING *item)
+ {
+ *item = impl.at(index);
+ return S_OK;
+ }
+ HRESULT __stdcall get_Size(quint32 *size)
+ {
+ *size = impl.size();
+ return S_OK;
+ }
+ HRESULT __stdcall GetView(IVectorView<HSTRING> **view)
+ {
+ *view = Q_NULLPTR;
+ return E_NOTIMPL;
+ }
+ HRESULT __stdcall IndexOf(HSTRING value, quint32 *index, boolean *found)
+ {
+ *found = false;
+ for (int i = 0; i < impl.size(); ++i) {
+ qint32 result;
+ HRESULT hr = WindowsCompareStringOrdinal(impl.at(i), value, &result);
+ if (FAILED(hr))
+ return hr;
+ if (result == 0) {
+ *index = quint32(i);
+ *found = true;
+ break;
+ }
+ }
+ return S_OK;
+ }
+ HRESULT __stdcall SetAt(quint32 index, HSTRING item)
+ {
+ HSTRING newItem;
+ HRESULT hr = WindowsDuplicateString(item, &newItem);
+ if (FAILED(hr))
+ return hr;
+ impl[index] = newItem;
+ return S_OK;
+ }
+ HRESULT __stdcall InsertAt(quint32 index, HSTRING item)
+ {
+ HSTRING newItem;
+ HRESULT hr = WindowsDuplicateString(item, &newItem);
+ if (FAILED(hr))
+ return hr;
+ impl.insert(index, newItem);
+ return S_OK;
+ }
+ HRESULT __stdcall RemoveAt(quint32 index)
+ {
+ WindowsDeleteString(impl.takeAt(index));
+ return S_OK;
+ }
+ HRESULT __stdcall Append(HSTRING item)
+ {
+ HSTRING newItem;
+ HRESULT hr = WindowsDuplicateString(item, &newItem);
+ if (FAILED(hr))
+ return hr;
+ impl.append(newItem);
+ return S_OK;
+ }
+ HRESULT __stdcall RemoveAtEnd()
+ {
+ WindowsDeleteString(impl.takeLast());
+ return S_OK;
+ }
+ HRESULT __stdcall Clear()
+ {
+ foreach (const HSTRING &item, impl)
+ WindowsDeleteString(item);
+ impl.clear();
+ return S_OK;
+ }
+private:
+ QVector<HSTRING> impl;
+};
+
+template<typename T>
+static bool initializePicker(HSTRING runtimeId, T **picker, const QSharedPointer<QFileDialogOptions> &options)
+{
+ HRESULT hr;
+
+ ComPtr<IInspectable> basePicker;
+ hr = RoActivateInstance(runtimeId, &basePicker);
+ RETURN_FALSE_IF_FAILED("Failed to instantiate file picker");
+ hr = basePicker.Get()->QueryInterface(IID_PPV_ARGS(picker));
+ RETURN_FALSE_IF_FAILED("Failed to cast file picker");
+
+ if (options->isLabelExplicitlySet(QFileDialogOptions::Accept)) {
+ const QString labelText = options->labelText(QFileDialogOptions::Accept);
+ HStringReference labelTextRef(reinterpret_cast<const wchar_t *>(labelText.utf16()),
+ labelText.length());
+ hr = (*picker)->put_CommitButtonText(labelTextRef.Get());
+ RETURN_FALSE_IF_FAILED("Failed to set commit button text");
+ }
+
+ return true;
+}
+
+template<typename T>
+static bool initializeOpenPickerOptions(T *picker, const QSharedPointer<QFileDialogOptions> &options)
+{
+ HRESULT hr;
+ hr = picker->put_ViewMode(options->viewMode() == QFileDialogOptions::Detail
+ ? PickerViewMode_Thumbnail : PickerViewMode_List);
+ RETURN_FALSE_IF_FAILED("Failed to set picker view mode");
+
+ ComPtr<IVector<HSTRING>> filters;
+ hr = picker->get_FileTypeFilter(&filters);
+ RETURN_FALSE_IF_FAILED("Failed to get file type filters list");
+ foreach (const QString &namedFilter, options->nameFilters()) {
+ foreach (const QString &filter, QPlatformFileDialogHelper::cleanFilterList(namedFilter)) {
+ // Remove leading star
+ const int offset = (filter.length() > 1 && filter.startsWith(QLatin1Char('*'))) ? 1 : 0;
+ HStringReference filterRef(reinterpret_cast<const wchar_t *>(filter.utf16() + offset),
+ filter.length() - offset);
+ hr = filters->Append(filterRef.Get());
+ if (FAILED(hr)) {
+ qWarning("Failed to add named file filter \"%s\": %s",
+ qPrintable(filter), qPrintable(qt_error_string(hr)));
+ }
+ }
+ }
+ // The file dialog won't open with an empty list - add a default wildcard
+ quint32 size;
+ hr = filters->get_Size(&size);
+ RETURN_FALSE_IF_FAILED("Failed to get file type filters list size");
+ if (!size) {
+ hr = filters->Append(HString::MakeReference(L"*").Get());
+ RETURN_FALSE_IF_FAILED("Failed to add default wildcard to file type filters list");
+ }
+
+ return true;
+}
+
+class QWinRTFileDialogHelperPrivate
+{
+public:
+ bool shown;
+ QEventLoop loop;
+
+ // Input
+ QUrl directory;
+ QUrl saveFileName;
+ QString selectedNameFilter;
+
+ // Output
+ QList<QUrl> selectedFiles;
+};
+
+QWinRTFileDialogHelper::QWinRTFileDialogHelper()
+ : QPlatformFileDialogHelper(), d_ptr(new QWinRTFileDialogHelperPrivate)
+{
+ Q_D(QWinRTFileDialogHelper);
+
+ d->shown = false;
+}
+
+QWinRTFileDialogHelper::~QWinRTFileDialogHelper()
+{
+}
+
+void QWinRTFileDialogHelper::exec()
+{
+ Q_D(QWinRTFileDialogHelper);
+
+ if (!d->shown)
+ show(Qt::Dialog, Qt::ApplicationModal, 0);
+ d->loop.exec();
+}
+
+bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+{
+ Q_UNUSED(windowFlags)
+ Q_UNUSED(windowModality)
+ Q_UNUSED(parent)
+ Q_D(QWinRTFileDialogHelper);
+
+ HRESULT hr;
+ const QSharedPointer<QFileDialogOptions> dialogOptions = options();
+ switch (dialogOptions->acceptMode()) {
+ default:
+ case QFileDialogOptions::AcceptOpen: {
+ switch (dialogOptions->fileMode()) {
+ case QFileDialogOptions::AnyFile:
+ case QFileDialogOptions::ExistingFile:
+ case QFileDialogOptions::ExistingFiles: {
+ ComPtr<IFileOpenPicker> picker;
+ if (!initializePicker(HString::MakeReference(RuntimeClass_Windows_Storage_Pickers_FileOpenPicker).Get(),
+ picker.GetAddressOf(), dialogOptions)) {
+ return false;
+ }
+ if (!initializeOpenPickerOptions(picker.Get(), dialogOptions))
+ return false;
+
+ if (dialogOptions->fileMode() == QFileDialogOptions::ExistingFiles) {
+ ComPtr<IAsyncOperation<IVectorView<StorageFile *> *>> op;
+ hr = picker->PickMultipleFilesAsync(&op);
+ RETURN_FALSE_IF_FAILED("Failed to open multi file picker");
+ hr = op->put_Completed(Callback<MultipleFileHandler>(this, &QWinRTFileDialogHelper::onMultipleFilesPicked).Get());
+ } else {
+ ComPtr<IAsyncOperation<StorageFile *>> op;
+ hr = picker->PickSingleFileAsync(&op);
+ RETURN_FALSE_IF_FAILED("Failed to open single file picker");
+ hr = op->put_Completed(Callback<SingleFileHandler>(this, &QWinRTFileDialogHelper::onSingleFilePicked).Get());
+ }
+ RETURN_FALSE_IF_FAILED("Failed to attach file picker callback");
+ break;
+ }
+ case QFileDialogOptions::Directory:
+ case QFileDialogOptions::DirectoryOnly: {
+ ComPtr<IFolderPicker> picker;
+ if (!initializePicker(HString::MakeReference(RuntimeClass_Windows_Storage_Pickers_FolderPicker).Get(),
+ picker.GetAddressOf(), dialogOptions)) {
+ return false;
+ }
+ if (!initializeOpenPickerOptions(picker.Get(), dialogOptions))
+ return false;
+
+ ComPtr<IAsyncOperation<StorageFolder *>> op;
+ hr = picker->PickSingleFolderAsync(&op);
+ RETURN_FALSE_IF_FAILED("Failed to open folder picker");
+ hr = op->put_Completed(Callback<SingleFolderHandler>(this, &QWinRTFileDialogHelper::onSingleFolderPicked).Get());
+ RETURN_FALSE_IF_FAILED("Failed to attach folder picker callback");
+ break;
+ }
+ }
+ break;
+ }
+ case QFileDialogOptions::AcceptSave: {
+ ComPtr<IFileSavePicker> picker;
+ if (!initializePicker(HString::MakeReference(RuntimeClass_Windows_Storage_Pickers_FileSavePicker).Get(),
+ picker.GetAddressOf(), dialogOptions)) {
+ return false;
+ }
+
+ ComPtr<IMap<HSTRING, IVector<HSTRING> *>> choices;
+ hr = picker->get_FileTypeChoices(&choices);
+ RETURN_FALSE_IF_FAILED("Failed to get file extension choices");
+ foreach (const QString &namedFilter, dialogOptions->nameFilters()) {
+ ComPtr<IVector<HSTRING>> entry = Make<WindowsStringVector>();
+ foreach (const QString &filter, QPlatformFileDialogHelper::cleanFilterList(namedFilter)) {
+ // Remove leading star
+ const int offset = (filter.length() > 1 && filter.startsWith(QLatin1Char('*'))) ? 1 : 0;
+ HStringReference filterRef(reinterpret_cast<const wchar_t *>(filter.utf16() + offset),
+ filter.length() - offset);
+ hr = entry->Append(filterRef.Get());
+ if (FAILED(hr)) {
+ qWarning("Failed to add named file filter \"%s\": %s",
+ qPrintable(filter), qPrintable(qt_error_string(hr)));
+ }
+ }
+ const int offset = namedFilter.indexOf(QLatin1String(" ("));
+ const QString filterTitle = offset > 0 ? namedFilter.left(offset) : filterTitle;
+ HStringReference namedFilterRef(reinterpret_cast<const wchar_t *>(filterTitle.utf16()),
+ filterTitle.length());
+ boolean replaced;
+ hr = choices->Insert(namedFilterRef.Get(), entry.Get(), &replaced);
+ RETURN_FALSE_IF_FAILED("Failed to insert file extension choice entry");
+ }
+
+ const QString suffix = dialogOptions->defaultSuffix();
+ HStringReference nativeSuffix(reinterpret_cast<const wchar_t *>(suffix.utf16()),
+ suffix.length());
+ hr = picker->put_DefaultFileExtension(nativeSuffix.Get());
+ RETURN_FALSE_IF_FAILED("Failed to set default file extension");
+
+ const QString suggestedName = QFileInfo(d->saveFileName.toLocalFile()).fileName();
+ HStringReference nativeSuggestedName(reinterpret_cast<const wchar_t *>(suggestedName.utf16()),
+ suggestedName.length());
+ hr = picker->put_SuggestedFileName(nativeSuggestedName.Get());
+ RETURN_FALSE_IF_FAILED("Failed to set suggested file name");
+
+ ComPtr<IAsyncOperation<StorageFile *>> op;
+ hr = picker->PickSaveFileAsync(&op);
+ RETURN_FALSE_IF_FAILED("Failed to open save file picker");
+ hr = op->put_Completed(Callback<SingleFileHandler>(this, &QWinRTFileDialogHelper::onSingleFilePicked).Get());
+ RETURN_FALSE_IF_FAILED("Failed to attach file picker callback");
+ break;
+ }
+ }
+
+ d->shown = true;
+ return true;
+}
+
+void QWinRTFileDialogHelper::hide()
+{
+ Q_D(QWinRTFileDialogHelper);
+
+ if (!d->shown)
+ return;
+
+ d->shown = false;
+}
+
+void QWinRTFileDialogHelper::setDirectory(const QUrl &directory)
+{
+ Q_D(QWinRTFileDialogHelper);
+ d->directory = directory;
+}
+
+QUrl QWinRTFileDialogHelper::directory() const
+{
+ Q_D(const QWinRTFileDialogHelper);
+ return d->directory;
+}
+
+void QWinRTFileDialogHelper::selectFile(const QUrl &saveFileName)
+{
+ Q_D(QWinRTFileDialogHelper);
+ d->saveFileName = saveFileName;
+}
+
+QList<QUrl> QWinRTFileDialogHelper::selectedFiles() const
+{
+ Q_D(const QWinRTFileDialogHelper);
+ return d->selectedFiles;
+}
+
+void QWinRTFileDialogHelper::selectNameFilter(const QString &selectedNameFilter)
+{
+ Q_D(QWinRTFileDialogHelper);
+ d->selectedNameFilter = selectedNameFilter;
+}
+
+QString QWinRTFileDialogHelper::selectedNameFilter() const
+{
+ Q_D(const QWinRTFileDialogHelper);
+ return d->selectedNameFilter;
+}
+
+HRESULT QWinRTFileDialogHelper::onSingleFilePicked(IAsyncOperation<StorageFile *> *args, AsyncStatus status)
+{
+ Q_D(QWinRTFileDialogHelper);
+
+ QEventLoopLocker locker(&d->loop);
+ d->shown = false;
+ d->selectedFiles.clear();
+ if (status == Canceled || status == Error) {
+ emit reject();
+ return S_OK;
+ }
+
+ HRESULT hr;
+ ComPtr<IStorageFile> file;
+ hr = args->GetResults(&file);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (!file) {
+ emit reject();
+ return S_OK;
+ }
+
+ appendFile(file.Get());
+ emit accept();
+ return S_OK;
+}
+
+HRESULT QWinRTFileDialogHelper::onMultipleFilesPicked(IAsyncOperation<IVectorView<StorageFile *> *> *args, AsyncStatus status)
+{
+ Q_D(QWinRTFileDialogHelper);
+
+ QEventLoopLocker locker(&d->loop);
+ d->shown = false;
+ d->selectedFiles.clear();
+ if (status == Canceled || status == Error) {
+ emit reject();
+ return S_OK;
+ }
+
+ HRESULT hr;
+ ComPtr<IVectorView<StorageFile *>> fileList;
+ hr = args->GetResults(&fileList);
+ RETURN_HR_IF_FAILED("Failed to get file list");
+
+ quint32 size;
+ hr = fileList->get_Size(&size);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (!size) {
+ emit reject();
+ return S_OK;
+ }
+ for (quint32 i = 0; i < size; ++i) {
+ ComPtr<IStorageFile> file;
+ hr = fileList->GetAt(i, &file);
+ Q_ASSERT_SUCCEEDED(hr);
+ appendFile(file.Get());
+ }
+
+ emit accept();
+ return S_OK;
+}
+
+HRESULT QWinRTFileDialogHelper::onSingleFolderPicked(IAsyncOperation<StorageFolder *> *args, AsyncStatus status)
+{
+ Q_D(QWinRTFileDialogHelper);
+
+ QEventLoopLocker locker(&d->loop);
+ d->shown = false;
+ d->selectedFiles.clear();
+ if (status == Canceled || status == Error) {
+ emit reject();
+ return S_OK;
+ }
+
+ HRESULT hr;
+ ComPtr<IStorageFolder> folder;
+ hr = args->GetResults(&folder);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (!folder) {
+ emit reject();
+ return S_OK;
+ }
+
+ appendFile(folder.Get());
+ emit accept();
+ return S_OK;
+}
+
+void QWinRTFileDialogHelper::appendFile(IInspectable *file)
+{
+ Q_D(QWinRTFileDialogHelper);
+
+ HRESULT hr;
+ ComPtr<IStorageItem> item;
+ hr = file->QueryInterface(IID_PPV_ARGS(&item));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ HString path;
+ hr = item->get_Path(path.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ quint32 pathLen;
+ const wchar_t *pathStr = path.GetRawBuffer(&pathLen);
+ const QString filePath = QString::fromWCharArray(pathStr, pathLen);
+ QWinRTFileEngineHandler::registerFile(filePath, item.Get());
+ d->selectedFiles.append(QUrl::fromLocalFile(filePath));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
new file mode 100644
index 0000000000..f333f3f4ae
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTFILEDIALOGHELPER_H
+#define QWINRTFILEDIALOGHELPER_H
+
+#include <qpa/qplatformdialoghelper.h>
+#include <QtCore/qt_windows.h>
+
+struct IInspectable;
+namespace ABI {
+ namespace Windows {
+ namespace Storage {
+ class StorageFile;
+ class StorageFolder;
+ struct IStorageFile;
+ }
+ namespace Foundation {
+ enum class AsyncStatus;
+ template <typename T> struct IAsyncOperation;
+ namespace Collections {
+ template <typename T> struct IVectorView;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTFileDialogHelperPrivate;
+class QWinRTFileDialogHelper : public QPlatformFileDialogHelper
+{
+ Q_OBJECT
+public:
+ explicit QWinRTFileDialogHelper();
+ ~QWinRTFileDialogHelper();
+
+ void exec() Q_DECL_OVERRIDE;
+ bool show(Qt::WindowFlags, Qt::WindowModality, QWindow *) Q_DECL_OVERRIDE;
+ void hide() Q_DECL_OVERRIDE;
+
+ bool defaultNameFilterDisables() const Q_DECL_OVERRIDE { return false; }
+ void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ QUrl directory() const Q_DECL_OVERRIDE;
+ void selectFile(const QUrl &saveFileName);
+ QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ void setFilter() Q_DECL_OVERRIDE { }
+ void selectNameFilter(const QString &selectedNameFilter) Q_DECL_OVERRIDE;
+ QString selectedNameFilter() const;
+
+private:
+ HRESULT onSingleFilePicked(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::StorageFile *> *,
+ ABI::Windows::Foundation::AsyncStatus);
+ HRESULT onMultipleFilesPicked(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile *> *> *,
+ ABI::Windows::Foundation::AsyncStatus);
+ HRESULT onSingleFolderPicked(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::StorageFolder *> *,
+ ABI::Windows::Foundation::AsyncStatus);
+ void appendFile(IInspectable *);
+
+ QScopedPointer<QWinRTFileDialogHelperPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTFileDialogHelper)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTFILEDIALOGHELPER_H
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
new file mode 100644
index 0000000000..3a4aa519cc
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
@@ -0,0 +1,505 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtfileengine.h"
+
+#include <QtCore/QDateTime>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QHash>
+#include <QtCore/qfunctions_winrt.h>
+
+#include <wrl.h>
+#include <windows.storage.h>
+#include <robuffer.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::Storage::Streams;
+
+typedef IAsyncOperationCompletedHandler<IRandomAccessStream *> StreamCompletedHandler;
+typedef IAsyncOperationWithProgressCompletedHandler<IBuffer *, UINT32> StreamReadCompletedHandler;
+
+QT_BEGIN_NAMESPACE
+
+#define RETURN_AND_SET_ERROR_IF_FAILED(error, ret) \
+ setError(error, qt_error_string(hr)); \
+ if (FAILED(hr)) \
+ return ret;
+
+Q_GLOBAL_STATIC(QWinRTFileEngineHandler, handlerInstance)
+
+class QWinRTFileEngineHandlerPrivate
+{
+public:
+ QHash<QString, ComPtr<IStorageItem>> files;
+};
+
+class QWinRTFileEnginePrivate
+{
+public:
+ QWinRTFileEnginePrivate(const QString &fileName, IStorageItem *file)
+ : fileName(fileName), file(file)
+ {
+ HRESULT hr;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
+ IID_PPV_ARGS(&bufferFactory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ lastSeparator = fileName.size() - 1;
+ for (int i = lastSeparator; i >= 0; --i) {
+ if (fileName.at(i).unicode() == '/' || fileName.at(i).unicode() == '\\') {
+ lastSeparator = i;
+ break;
+ }
+ }
+
+ firstDot = fileName.size();
+ for (int i = lastSeparator; i > fileName.size(); ++i) {
+ if (fileName.at(i).unicode() == '.') {
+ firstDot = i;
+ break;
+ }
+ }
+ }
+
+ ComPtr<IBufferFactory> bufferFactory;
+
+ QString fileName;
+ int lastSeparator;
+ int firstDot;
+ ComPtr<IStorageItem> file;
+ ComPtr<IRandomAccessStream> stream;
+
+ qint64 pos;
+
+private:
+ QWinRTFileEngineHandler *q_ptr;
+ Q_DECLARE_PUBLIC(QWinRTFileEngineHandler)
+};
+
+
+QWinRTFileEngineHandler::QWinRTFileEngineHandler()
+ : d_ptr(new QWinRTFileEngineHandlerPrivate)
+{
+}
+
+QWinRTFileEngineHandler::~QWinRTFileEngineHandler()
+{
+}
+
+void QWinRTFileEngineHandler::registerFile(const QString &fileName, IStorageItem *file)
+{
+ handlerInstance->d_func()->files.insert(QDir::cleanPath(fileName), file);
+}
+
+IStorageItem *QWinRTFileEngineHandler::registeredFile(const QString &fileName)
+{
+ return handlerInstance->d_func()->files.value(fileName).Get();
+}
+
+QAbstractFileEngine *QWinRTFileEngineHandler::create(const QString &fileName) const
+{
+ Q_D(const QWinRTFileEngineHandler);
+
+ QHash<QString, ComPtr<IStorageItem>>::const_iterator file = d->files.find(fileName);
+ if (file != d->files.end())
+ return new QWinRTFileEngine(fileName, file.value().Get());
+
+ return Q_NULLPTR;
+}
+
+static HRESULT getDestinationFolder(const QString &fileName, const QString newFileName,
+ IStorageItem *file, IStorageFolder **folder)
+{
+ HRESULT hr;
+ ComPtr<IAsyncOperation<StorageFolder *>> op;
+ QFileInfo newFileInfo(newFileName);
+#ifndef Q_OS_WINPHONE
+ QFileInfo fileInfo(fileName);
+ if (fileInfo.dir() == newFileInfo.dir()) {
+ ComPtr<IStorageItem2> item;
+ hr = file->QueryInterface(IID_PPV_ARGS(&item));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = item->GetParentAsync(&op);
+ } else
+#else
+ Q_UNUSED(fileName);
+ Q_UNUSED(file)
+#endif
+ {
+ ComPtr<IStorageFolderStatics> folderFactory;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFolder).Get(),
+ IID_PPV_ARGS(&folderFactory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ const QString newFilePath = QDir::toNativeSeparators(newFileInfo.absolutePath());
+ HStringReference nativeNewFilePath(reinterpret_cast<LPCWSTR>(newFilePath.utf16()),
+ newFilePath.length());
+ hr = folderFactory->GetFolderFromPathAsync(nativeNewFilePath.Get(), &op);
+ }
+ if (FAILED(hr))
+ return hr;
+ return QWinRTFunctions::await(op, folder);
+}
+
+QWinRTFileEngine::QWinRTFileEngine(const QString &fileName, IStorageItem *file)
+ : d_ptr(new QWinRTFileEnginePrivate(fileName, file))
+{
+}
+
+QWinRTFileEngine::~QWinRTFileEngine()
+{
+}
+
+bool QWinRTFileEngine::open(QIODevice::OpenMode openMode)
+{
+ Q_D(QWinRTFileEngine);
+
+ FileAccessMode fileAccessMode = (openMode & QIODevice::WriteOnly)
+ ? FileAccessMode_ReadWrite : FileAccessMode_Read;
+
+ HRESULT hr;
+ ComPtr<IStorageFile> file;
+ hr = d->file.As(&file);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::OpenError, false);
+
+ ComPtr<IAsyncOperation<IRandomAccessStream *>> op;
+ hr = file->OpenAsync(fileAccessMode, &op);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::OpenError, false);
+
+ hr = QWinRTFunctions::await(op, d->stream.GetAddressOf());
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::OpenError, false);
+
+ return SUCCEEDED(hr);
+}
+
+bool QWinRTFileEngine::close()
+{
+ Q_D(QWinRTFileEngine);
+
+ if (!d->stream)
+ return false;
+
+ ComPtr<IClosable> closable;
+ HRESULT hr = d->stream.As(&closable);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = closable->Close();
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::UnspecifiedError, false);
+ d->stream.Reset();
+ return SUCCEEDED(hr);
+}
+
+qint64 QWinRTFileEngine::size() const
+{
+ Q_D(const QWinRTFileEngine);
+
+ if (!d->stream)
+ return 0;
+
+ UINT64 size;
+ HRESULT hr;
+ hr = d->stream->get_Size(&size);
+ RETURN_IF_FAILED("Failed to get file size", return 0);
+
+ return qint64(size);
+}
+
+qint64 QWinRTFileEngine::pos() const
+{
+ Q_D(const QWinRTFileEngine);
+ return d->pos;
+}
+
+bool QWinRTFileEngine::seek(qint64 pos)
+{
+ Q_D(QWinRTFileEngine);
+
+ if (!d->stream)
+ return false;
+
+ HRESULT hr = d->stream->Seek(pos);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::PositionError, false);
+ d->pos = pos;
+ return SUCCEEDED(hr);
+}
+
+bool QWinRTFileEngine::remove()
+{
+ Q_D(QWinRTFileEngine);
+
+ ComPtr<IAsyncAction> op;
+ HRESULT hr = d->file->DeleteAsync(StorageDeleteOption_Default, &op);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RemoveError, false);
+
+ hr = QWinRTFunctions::await(op);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RemoveError, false);
+ return SUCCEEDED(hr);
+}
+
+bool QWinRTFileEngine::copy(const QString &newName)
+{
+ Q_D(QWinRTFileEngine);
+
+ HRESULT hr;
+ ComPtr<IStorageFolder> destinationFolder;
+ hr = getDestinationFolder(d->fileName, newName, d->file.Get(), destinationFolder.GetAddressOf());
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
+
+ ComPtr<IStorageFile> file;
+ hr = d->file.As(&file);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
+
+ const QString destinationName = QFileInfo(newName).fileName();
+ HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()), destinationName.length());
+ ComPtr<IAsyncOperation<StorageFile *>> op;
+ hr = file->CopyOverloadDefaultOptions(destinationFolder.Get(), nativeDestinationName.Get(), &op);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
+
+ ComPtr<IStorageFile> newFile;
+ hr = QWinRTFunctions::await(op, newFile.GetAddressOf());
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
+ return SUCCEEDED(hr);
+}
+
+bool QWinRTFileEngine::rename(const QString &newName)
+{
+ Q_D(QWinRTFileEngine);
+
+ HRESULT hr;
+ ComPtr<IStorageFolder> destinationFolder;
+ hr = getDestinationFolder(d->fileName, newName, d->file.Get(), destinationFolder.GetAddressOf());
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
+
+ const QString destinationName = QFileInfo(newName).fileName();
+ HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()), destinationName.length());
+ ComPtr<IAsyncAction> op;
+ hr = d->file->RenameAsyncOverloadDefaultOptions(nativeDestinationName.Get(), &op);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
+ return SUCCEEDED(hr);
+}
+
+bool QWinRTFileEngine::renameOverwrite(const QString &newName)
+{
+ Q_D(QWinRTFileEngine);
+
+ HRESULT hr;
+ ComPtr<IStorageFolder> destinationFolder;
+ hr = getDestinationFolder(d->fileName, newName, d->file.Get(), destinationFolder.GetAddressOf());
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
+
+ const QString destinationName = QFileInfo(newName).fileName();
+ HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()), destinationName.length());
+ ComPtr<IAsyncAction> op;
+ hr = d->file->RenameAsync(nativeDestinationName.Get(), NameCollisionOption_ReplaceExisting, &op);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
+ return SUCCEEDED(hr);
+}
+
+QAbstractFileEngine::FileFlags QWinRTFileEngine::fileFlags(FileFlags type) const
+{
+ Q_D(const QWinRTFileEngine);
+
+ FileFlags flags = ExistsFlag|ReadOwnerPerm|ReadUserPerm|WriteOwnerPerm|WriteUserPerm;
+
+ HRESULT hr;
+ FileAttributes attributes;
+ hr = d->file->get_Attributes(&attributes);
+ RETURN_IF_FAILED("Failed to get file attributes", return flags);
+ if (attributes & FileAttributes_ReadOnly)
+ flags ^= WriteUserPerm;
+ if (attributes & FileAttributes_Directory)
+ flags |= DirectoryType;
+ else
+ flags |= FileType;
+
+ return type & flags;
+}
+
+bool QWinRTFileEngine::setPermissions(uint perms)
+{
+ Q_UNUSED(perms);
+ Q_UNIMPLEMENTED();
+ return false;
+}
+
+QString QWinRTFileEngine::fileName(FileName type) const
+{
+ Q_D(const QWinRTFileEngine);
+
+ switch (type) {
+ default:
+ case DefaultName:
+ case AbsoluteName:
+ case CanonicalName:
+ break;
+ case BaseName:
+ return d->lastSeparator < 0
+ ? d->fileName : d->fileName.mid(d->lastSeparator, d->firstDot - d->lastSeparator);
+ case PathName:
+ case AbsolutePathName:
+ case CanonicalPathName:
+ return d->fileName.mid(0, d->lastSeparator);
+ case LinkName:
+ case BundleName:
+ return QString();
+ }
+ return d->fileName;
+}
+
+QDateTime QWinRTFileEngine::fileTime(FileTime type) const
+{
+ Q_D(const QWinRTFileEngine);
+
+ HRESULT hr;
+ DateTime dateTime = { 0 };
+ switch (type) {
+ case CreationTime:
+ hr = d->file->get_DateCreated(&dateTime);
+ RETURN_IF_FAILED("Failed to get file creation time", return QDateTime());
+ break;
+ case ModificationTime:
+ case AccessTime: {
+ ComPtr<IAsyncOperation<FileProperties::BasicProperties *>> op;
+ hr = d->file->GetBasicPropertiesAsync(&op);
+ RETURN_IF_FAILED("Failed to initiate file properties", return QDateTime());
+ ComPtr<FileProperties::IBasicProperties> properties;
+ hr = QWinRTFunctions::await(op, properties.GetAddressOf());
+ RETURN_IF_FAILED("Failed to get file properties", return QDateTime());
+ hr = type == ModificationTime ? properties->get_DateModified(&dateTime)
+ : properties->get_ItemDate(&dateTime);
+ RETURN_IF_FAILED("Failed to get file date", return QDateTime());
+ }
+ break;
+ }
+
+ SYSTEMTIME systemTime;
+ FileTimeToSystemTime((const FILETIME *)&dateTime, &systemTime);
+ QDate date(systemTime.wYear, systemTime.wMonth, systemTime.wDay);
+ QTime time(systemTime.wHour, systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds);
+ return QDateTime(date, time);
+}
+
+qint64 QWinRTFileEngine::read(char *data, qint64 maxlen)
+{
+ Q_D(QWinRTFileEngine);
+
+ if (!d->stream)
+ return -1;
+
+ ComPtr<IInputStream> stream;
+ HRESULT hr = d->stream.As(&stream);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
+
+ UINT32 length = qBound(quint64(0), quint64(maxlen), quint64(UINT_MAX));
+ ComPtr<IBuffer> buffer;
+ hr = d->bufferFactory->Create(length, &buffer);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
+
+ ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> op;
+ hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &op);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
+
+ hr = QWinRTFunctions::await(op, buffer.GetAddressOf());
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
+
+ hr = buffer->get_Length(&length);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
+
+ ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
+ hr = buffer.As(&byteArrayAccess);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
+
+ byte *bytes;
+ hr = byteArrayAccess->Buffer(&bytes);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
+ memcpy(data, bytes, length);
+ return qint64(length);
+}
+
+qint64 QWinRTFileEngine::write(const char *data, qint64 maxlen)
+{
+ Q_D(QWinRTFileEngine);
+
+ if (!d->stream)
+ return -1;
+
+ ComPtr<IOutputStream> stream;
+ HRESULT hr = d->stream.As(&stream);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
+
+ UINT32 length = qBound(quint64(0), quint64(maxlen), quint64(UINT_MAX));
+ ComPtr<IBuffer> buffer;
+ hr = d->bufferFactory->Create(length, &buffer);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
+ hr = buffer->put_Length(length);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
+
+ ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
+ hr = buffer.As(&byteArrayAccess);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
+
+ byte *bytes;
+ hr = byteArrayAccess->Buffer(&bytes);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
+ memcpy(bytes, data, length);
+
+ ComPtr<IAsyncOperationWithProgress<UINT32, UINT32>> op;
+ hr = stream->WriteAsync(buffer.Get(), &op);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
+
+ hr = QWinRTFunctions::await(op, &length);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
+
+ ComPtr<IAsyncOperation<bool>> flushOp;
+ hr = stream->FlushAsync(&flushOp);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
+ boolean flushed;
+ hr = QWinRTFunctions::await(flushOp, &flushed);
+ RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
+
+ return qint64(length);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.h
index d4034ec571..59eeb1c44c 100644
--- a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.h
@@ -39,38 +39,66 @@
**
****************************************************************************/
-#include "qwinrtplatformtheme.h"
-#include "qwinrtplatformmessagedialoghelper.h"
+#ifndef QWINRTFILEENGINE_H
+#define QWINRTFILEENGINE_H
+
+#include <private/qabstractfileengine_p.h>
QT_BEGIN_NAMESPACE
-QWinRTPlatformTheme::QWinRTPlatformTheme()
-{
+namespace ABI {
+ namespace Windows {
+ namespace Storage {
+ struct IStorageItem;
+ }
+ }
}
-bool QWinRTPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const
+class QWinRTFileEngineHandlerPrivate;
+class QWinRTFileEngineHandler : public QAbstractFileEngineHandler
{
-#if !(defined(Q_OS_WINPHONE) && _MSC_VER<=1700)
- if (type == QPlatformTheme::MessageDialog)
- return true;
-#else
- Q_UNUSED(type)
-#endif // !(Q_OS_WINPHONE && _MSC_VER<=1700)
- return false;
-}
+public:
+ QWinRTFileEngineHandler();
+ ~QWinRTFileEngineHandler();
+ QAbstractFileEngine *create(const QString &fileName) const Q_DECL_OVERRIDE;
+
+ static void registerFile(const QString &fileName, ABI::Windows::Storage::IStorageItem *file);
+ static ABI::Windows::Storage::IStorageItem *registeredFile(const QString &fileName);
+
+private:
+ QScopedPointer<QWinRTFileEngineHandlerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTFileEngineHandler)
+};
-QPlatformDialogHelper *QWinRTPlatformTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const
+class QWinRTFileEnginePrivate;
+class QWinRTFileEngine : public QAbstractFileEngine
{
-#if !(defined(Q_OS_WINPHONE) && _MSC_VER<=1700)
- switch (type) {
- case QPlatformTheme::MessageDialog:
- return new QWinRTPlatformMessageDialogHelper();
- default:
- return QPlatformTheme::createPlatformDialogHelper(type);
- }
-#else // !(Q_OS_WINPHONE && _MSC_VER<=1700)
- return QPlatformTheme::createPlatformDialogHelper(type);
-#endif // Q_OS_WINPHONE && _MSC_VER<=1700
-}
+public:
+ QWinRTFileEngine(const QString &fileName, ABI::Windows::Storage::IStorageItem *file);
+ ~QWinRTFileEngine();
+
+ bool open(QIODevice::OpenMode openMode) Q_DECL_OVERRIDE;
+ bool close() Q_DECL_OVERRIDE;
+ qint64 size() const Q_DECL_OVERRIDE;
+ qint64 pos() const Q_DECL_OVERRIDE;
+ bool seek(qint64 pos) Q_DECL_OVERRIDE;
+ bool remove() Q_DECL_OVERRIDE;
+ bool copy(const QString &newName) Q_DECL_OVERRIDE;
+ bool rename(const QString &newName) Q_DECL_OVERRIDE;
+ bool renameOverwrite(const QString &newName) Q_DECL_OVERRIDE;
+ FileFlags fileFlags(FileFlags type=FileInfoAll) const Q_DECL_OVERRIDE;
+ bool setPermissions(uint perms) Q_DECL_OVERRIDE;
+ QString fileName(FileName type=DefaultName) const Q_DECL_OVERRIDE;
+ QDateTime fileTime(FileTime type) const Q_DECL_OVERRIDE;
+
+ qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWinRTFileEnginePrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTFileEngine)
+};
QT_END_NAMESPACE
+
+#endif // QWINRTFILEENGINE_H
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index b3a2cafa2e..53d52a430c 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -48,7 +48,7 @@
#include "qwinrtservices.h"
#include "qwinrteglcontext.h"
#include "qwinrtfontdatabase.h"
-#include "qwinrtplatformtheme.h"
+#include "qwinrttheme.h"
#include <QtGui/QOpenGLContext>
@@ -63,18 +63,6 @@ using namespace ABI::Windows::UI::Core;
using namespace ABI::Windows::UI::ViewManagement;
using namespace ABI::Windows::ApplicationModel::Core;
-static IUISettings *getSettings()
-{
- static IUISettings *settings = 0;
- if (!settings) {
- if (FAILED(RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_UISettings).Get(),
- reinterpret_cast<IInspectable **>(&settings)))) {
- qWarning("Could not activate UISettings.");
- }
- }
- return settings;
-}
-
QT_BEGIN_NAMESPACE
QWinRTIntegration::QWinRTIntegration()
@@ -82,26 +70,7 @@ QWinRTIntegration::QWinRTIntegration()
, m_fontDatabase(new QWinRTFontDatabase)
, m_services(new QWinRTServices)
{
- // Obtain the WinRT Application, view, and window
- ICoreApplication *application;
- if (FAILED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
- IID_PPV_ARGS(&application))))
- qCritical("Could not attach to the application factory.");
-
- ICoreApplicationView *view;
- if (FAILED(application->GetCurrentView(&view))) {
- qCritical("Could not obtain the application view - have you started outside of WinRT?");
- return;
- }
-
- // Get core window (will act as our screen)
- ICoreWindow *window;
- if (FAILED(view->get_CoreWindow(&window))) {
- qCritical("Could not obtain the application window - have you started outside of WinRT?");
- return;
- }
- window->Activate();
- m_screen = new QWinRTScreen(window);
+ m_screen = new QWinRTScreen;
screenAdded(m_screen);
m_success = true;
@@ -133,26 +102,7 @@ bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
QVariant QWinRTIntegration::styleHint(StyleHint hint) const
{
- switch (hint) {
- case CursorFlashTime:
- if (IUISettings *settings = getSettings()) {
- quint32 blinkRate;
- settings->get_CaretBlinkRate(&blinkRate);
- return blinkRate;
- }
- break;
- case MouseDoubleClickInterval:
- if (IUISettings *settings = getSettings()) {
- quint32 doubleClickTime;
- settings->get_DoubleClickTime(&doubleClickTime);
- return doubleClickTime;
- }
- case ShowIsFullScreen:
- return true;
- default:
- break;
- }
- return QPlatformIntegration::styleHint(hint);
+ return QWinRTTheme::styleHint(hint);
}
QPlatformWindow *QWinRTIntegration::createPlatformWindow(QWindow *window) const
@@ -200,7 +150,7 @@ QPlatformTheme *QWinRTIntegration::createPlatformTheme(const QString &
name) const
{
if (name == QLatin1String("winrt"))
- return new QWinRTPlatformTheme();
+ return new QWinRTTheme();
return 0;
}
diff --git a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp
new file mode 100644
index 0000000000..6de90ba1ec
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtmessagedialoghelper.h"
+#include "qwinrttheme.h"
+
+#include <QtCore/qfunctions_winrt.h>
+
+#include <windows.ui.popups.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#include <wrl.h>
+
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::UI::Popups;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+typedef IAsyncOperationCompletedHandler<IUICommand *> DialogCompletedHandler;
+
+QT_BEGIN_NAMESPACE
+
+class CommandId : public RuntimeClass<IInspectable>
+{
+public:
+ CommandId(QPlatformDialogHelper::StandardButton button)
+ : button(button) { }
+ QPlatformDialogHelper::StandardButton button;
+};
+
+class QWinRTMessageDialogHelperPrivate
+{
+public:
+ const QWinRTTheme *theme;
+ bool shown;
+ ComPtr<IAsyncInfo> info;
+ QEventLoop loop;
+};
+
+QWinRTMessageDialogHelper::QWinRTMessageDialogHelper(const QWinRTTheme *theme)
+ : QPlatformMessageDialogHelper(), d_ptr(new QWinRTMessageDialogHelperPrivate)
+{
+ Q_D(QWinRTMessageDialogHelper);
+
+ d->theme = theme;
+ d->shown = false;
+}
+
+QWinRTMessageDialogHelper::~QWinRTMessageDialogHelper()
+{
+ Q_D(QWinRTMessageDialogHelper);
+
+ if (d->shown)
+ hide();
+}
+
+void QWinRTMessageDialogHelper::exec()
+{
+ Q_D(QWinRTMessageDialogHelper);
+
+ if (!d->shown)
+ show(Qt::Dialog, Qt::ApplicationModal, 0);
+ d->loop.exec();
+}
+
+bool QWinRTMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+{
+ Q_UNUSED(windowFlags)
+ Q_UNUSED(windowModality)
+ Q_UNUSED(parent)
+ Q_D(QWinRTMessageDialogHelper);
+
+ QSharedPointer<QMessageDialogOptions> options = this->options();
+ const QString informativeText = options->informativeText();
+ const QString title = options->windowTitle();
+ const QString text = informativeText.isEmpty() ? options->text() : (options->text() + QLatin1Char('\n') + informativeText);
+
+ HRESULT hr;
+ ComPtr<IMessageDialogFactory> dialogFactory;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_MessageDialog).Get(),
+ IID_PPV_ARGS(&dialogFactory));
+ RETURN_FALSE_IF_FAILED("Failed to create dialog factory");
+
+ ComPtr<IUICommandFactory> commandFactory;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_UICommand).Get(),
+ IID_PPV_ARGS(&commandFactory));
+ RETURN_FALSE_IF_FAILED("Failed to create command factory");
+
+ ComPtr<IMessageDialog> dialog;
+ HStringReference nativeText(reinterpret_cast<LPCWSTR>(text.utf16()), text.size());
+ if (!title.isEmpty()) {
+ HStringReference nativeTitle(reinterpret_cast<LPCWSTR>(title.utf16()), title.size());
+ hr = dialogFactory->CreateWithTitle(nativeText.Get(), nativeTitle.Get(), &dialog);
+ RETURN_FALSE_IF_FAILED("Failed to create dialog with title");
+ } else {
+ hr = dialogFactory->Create(nativeText.Get(), &dialog);
+ RETURN_FALSE_IF_FAILED("Failed to create dialog");
+ }
+
+ // Add Buttons
+ ComPtr<IVector<IUICommand *>> dialogCommands;
+ hr = dialog->get_Commands(&dialogCommands);
+ RETURN_FALSE_IF_FAILED("Failed to get dialog commands");
+
+ // If no button is specified we need to create one to get close notification
+ int buttons = options->standardButtons();
+ if (buttons == 0)
+ buttons = Ok;
+
+ for (int i = FirstButton; i < LastButton; i<<=1) {
+ if (!(buttons & i))
+ continue;
+ // Add native command
+ const QString label = d->theme->standardButtonText(i);
+ HStringReference nativeLabel(reinterpret_cast<LPCWSTR>(label.utf16()), label.size());
+ ComPtr<IUICommand> command;
+ hr = commandFactory->Create(nativeLabel.Get(), &command);
+ RETURN_FALSE_IF_FAILED("Failed to create message box command");
+ ComPtr<IInspectable> id = Make<CommandId>(static_cast<StandardButton>(i));
+ hr = command->put_Id(id.Get());
+ RETURN_FALSE_IF_FAILED("Failed to set command ID");
+ hr = dialogCommands->Append(command.Get());
+ if (hr == E_BOUNDS) {
+ qErrnoWarning(hr, "The WinRT message dialog supports a maximum of three buttons");
+ continue;
+ }
+ RETURN_FALSE_IF_FAILED("Failed to append message box command");
+ if (i == Abort || i == Cancel || i == Close) {
+ quint32 size;
+ hr = dialogCommands->get_Size(&size);
+ RETURN_FALSE_IF_FAILED("Failed to get command list size");
+ hr = dialog->put_CancelCommandIndex(size - 1);
+ RETURN_FALSE_IF_FAILED("Failed to set cancel index");
+ }
+ }
+
+ ComPtr<IAsyncOperation<IUICommand *>> op;
+ hr = dialog->ShowAsync(&op);
+ RETURN_FALSE_IF_FAILED("Failed to show dialog");
+ hr = op->put_Completed(Callback<DialogCompletedHandler>(this, &QWinRTMessageDialogHelper::onCompleted).Get());
+ RETURN_FALSE_IF_FAILED("Failed to set dialog callback");
+
+ d->shown = true;
+ hr = op.As(&d->info);
+ RETURN_FALSE_IF_FAILED("Failed to acquire AsyncInfo for MessageDialog");
+
+ return true;
+}
+
+void QWinRTMessageDialogHelper::hide()
+{
+ Q_D(QWinRTMessageDialogHelper);
+
+ if (!d->shown)
+ return;
+
+ HRESULT hr = d->info->Cancel();
+ if (FAILED(hr))
+ qErrnoWarning(hr, "Failed to cancel dialog operation");
+
+ d->shown = false;
+}
+
+HRESULT QWinRTMessageDialogHelper::onCompleted(IAsyncOperation<IUICommand *> *asyncInfo, AsyncStatus status)
+{
+ Q_UNUSED(status);
+ Q_D(QWinRTMessageDialogHelper);
+
+ if (d->loop.isRunning())
+ d->loop.exit();
+
+ d->shown = false;
+
+ if (status == Canceled) {
+ emit reject();
+ return S_OK;
+ }
+
+ HRESULT hr;
+ ComPtr<IUICommand> command;
+ hr = asyncInfo->GetResults(&command);
+ RETURN_OK_IF_FAILED("Failed to get command");
+
+ ComPtr<CommandId> id;
+ hr = command->get_Id(&id);
+ RETURN_OK_IF_FAILED("Failed to get command ID");
+
+ ButtonRole role = buttonRole(id->button);
+ emit clicked(id->button, role);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h
index fbb21ed69c..25199e569c 100644
--- a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h
+++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h
@@ -39,11 +39,10 @@
**
****************************************************************************/
-#ifndef QWINRTPLATFORMMESSAGEDIALOGHELPER_H
-#define QWINRTPLATFORMMESSAGEDIALOGHELPER_H
+#ifndef QWINRTMESSAGEDIALOGHELPER_H
+#define QWINRTMESSAGEDIALOGHELPER_H
#include <qpa/qplatformdialoghelper.h>
-#include <QtCore/QEventLoop>
#include <QtCore/qt_windows.h>
namespace ABI {
@@ -53,19 +52,24 @@ namespace ABI {
struct IUICommand;
}
}
+ namespace Foundation {
+ enum class AsyncStatus;
+ template <typename T> struct IAsyncOperation;
+ }
}
}
QT_BEGIN_NAMESPACE
-struct QWinRTPlatformMessageDialogInfo;
+class QWinRTTheme;
-class QWinRTPlatformMessageDialogHelper : public QPlatformMessageDialogHelper
+class QWinRTMessageDialogHelperPrivate;
+class QWinRTMessageDialogHelper : public QPlatformMessageDialogHelper
{
Q_OBJECT
public:
- explicit QWinRTPlatformMessageDialogHelper();
- ~QWinRTPlatformMessageDialogHelper();
+ explicit QWinRTMessageDialogHelper(const QWinRTTheme *theme);
+ ~QWinRTMessageDialogHelper();
void exec();
bool show(Qt::WindowFlags windowFlags,
@@ -73,13 +77,14 @@ public:
QWindow *parent);
void hide();
- HRESULT onInvoked(ABI::Windows::UI::Popups::IUICommand *command);
private:
- QWinRTPlatformMessageDialogInfo *m_info;
- QEventLoop m_loop;
- bool m_shown;
+ HRESULT onCompleted(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::UI::Popups::IUICommand *> *asyncInfo,
+ ABI::Windows::Foundation::AsyncStatus status);
+
+ QScopedPointer<QWinRTMessageDialogHelperPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTMessageDialogHelper)
};
QT_END_NAMESPACE
-#endif // QWINRTPLATFORMMESSAGEDIALOGHELPER_H
+#endif // QWINRTMESSAGEDIALOGHELPER_H
diff --git a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp
deleted file mode 100644
index c2f884055d..0000000000
--- a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwinrtplatformmessagedialoghelper.h"
-
-#include <QtGui/QGuiApplication>
-#include <private/qguiapplication_p.h>
-#include <qpa/qplatformtheme.h>
-
-#include <asyncinfo.h>
-#include <windows.ui.popups.h>
-#include <windows.foundation.h>
-#include <windows.foundation.collections.h>
-#include <wrl.h>
-
-using namespace ABI::Windows::Foundation;
-using namespace ABI::Windows::Foundation::Collections;
-using namespace ABI::Windows::UI::Popups;
-using namespace Microsoft::WRL;
-using namespace Microsoft::WRL::Wrappers;
-
-QT_BEGIN_NAMESPACE
-
-struct QWinRTPlatformMessageDialogInfo
-{
- ComPtr<IAsyncInfo> info;
-};
-
-QWinRTPlatformMessageDialogHelper::QWinRTPlatformMessageDialogHelper() :
- QPlatformMessageDialogHelper(),
- m_info(new QWinRTPlatformMessageDialogInfo),
- m_shown(false)
-{
-}
-
-QWinRTPlatformMessageDialogHelper::~QWinRTPlatformMessageDialogHelper()
-{
- if (m_shown)
- hide();
- delete m_info;
-}
-
-void QWinRTPlatformMessageDialogHelper::exec()
-{
- if (!m_shown)
- show(Qt::Dialog, Qt::ApplicationModal, 0);
- m_loop.exec();
-}
-
-bool QWinRTPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
-{
- Q_UNUSED(windowFlags)
- Q_UNUSED(windowModality)
- Q_UNUSED(parent)
-
- QSharedPointer<QMessageDialogOptions> options = this->options();
-
- const QString informativeText = options->informativeText();
- const QString title = options->windowTitle();
- const QString text = informativeText.isEmpty() ? options->text() : (options->text() + QLatin1Char('\n') + informativeText);
-
-
- ComPtr<IMessageDialogFactory> dialogFactory;
- if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_MessageDialog).Get(), &dialogFactory)))
- return false;
-
- ComPtr<IUICommandFactory> commandFactory;
- if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_UICommand).Get(), &commandFactory)))
- return false;
-
- HString nativeText;
- nativeText.Set(reinterpret_cast<LPCWSTR>(text.utf16()), text.size());
- ComPtr<IMessageDialog> dialog;
-
- if (!title.isEmpty()) {
- HString nativeTitle;
- nativeTitle.Set(reinterpret_cast<LPCWSTR>(title.utf16()), title.size());
- if (FAILED(dialogFactory->CreateWithTitle(nativeText.Get(), nativeTitle.Get(), &dialog)))
- return false;
- } else {
- if (FAILED(dialogFactory->Create(nativeText.Get(), &dialog)))
- return false;
- }
-
- // Add Buttons
- ComPtr<IVector<IUICommand*> > dialogCommands;
- if (FAILED(dialog->get_Commands(&dialogCommands)))
- return false;
-
- // If no button is specified we need to create one to get close notification
- int buttons = options->standardButtons();
- if (buttons == 0)
- buttons = QPlatformDialogHelper::Ok;
-
- for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) {
- if (buttons & i) {
- // Add native command
- const QString label = QGuiApplicationPrivate::platformTheme()->standardButtonText(i);
-
- HString hLabel;
- hLabel.Set(reinterpret_cast<LPCWSTR>(label.utf16()), label.size());
-
- ABI::Windows::UI::Popups::IUICommand *command;
- if (FAILED(commandFactory->CreateWithHandler(hLabel.Get(),
- Callback<IUICommandInvokedHandler>(this, &QWinRTPlatformMessageDialogHelper::onInvoked).Get(),
- &command)))
- return false;
- dialogCommands->Append(command);
- }
- }
-
- ComPtr<IAsyncOperation<IUICommand*> > op;
- if (FAILED(dialog->ShowAsync(&op)))
- return false;
-
- m_shown = true;
- if (FAILED(op.As(&m_info->info))) {
- m_shown = false;
- // The dialog is shown already, so we cannot return false
- qWarning("Failed to acquire AsyncInfo for MessageDialog");
- }
- return true;
-}
-
-void QWinRTPlatformMessageDialogHelper::hide()
-{
- if (!m_shown)
- return;
-
- m_info->info->Cancel();
- m_shown = false;
-}
-
-HRESULT QWinRTPlatformMessageDialogHelper::onInvoked(ABI::Windows::UI::Popups::IUICommand *command)
-{
- HString hLabel;
- UINT32 labelLength;
- command->get_Label(hLabel.GetAddressOf());
- PCWSTR rawString = hLabel.GetRawBuffer(&labelLength);
- QString label = QString::fromWCharArray(rawString, labelLength);
- int buttonId = -1;
- for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) {
- if ( options()->standardButtons() & i ) {
- if (QGuiApplicationPrivate::platformTheme()->standardButtonText(i) == label) {
- buttonId = i;
- break;
- }
- }
- }
- if (m_loop.isRunning())
- m_loop.exit();
-
- m_shown = false;
-
- if (buttonId < 0) {
- emit reject();
- return S_OK;
- }
-
- QPlatformDialogHelper::StandardButton standardButton = static_cast<QPlatformDialogHelper::StandardButton>(buttonId);
- QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(standardButton);
- emit clicked(standardButton, role);
- return S_OK;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index f948cf9924..a18bd2834e 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -51,6 +51,7 @@
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/qt_windows.h>
+#include <QtCore/qfunctions_winrt.h>
#include <wrl.h>
#include <windows.system.h>
@@ -93,11 +94,7 @@ typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler;
typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler;
-#if _MSC_VER <=1700
-typedef IDisplayPropertiesEventHandler DisplayInformationHandler;
-#else
typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler;
-#endif
#ifdef Q_OS_WINPHONE
typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
#endif
@@ -419,199 +416,266 @@ static inline Qt::Key qKeyFromCode(quint32 code, int mods)
return static_cast<Qt::Key>(code & 0xff);
}
-QWinRTScreen::QWinRTScreen(ICoreWindow *window)
- : m_coreWindow(window)
- , m_depth(32)
- , m_format(QImage::Format_ARGB32_Premultiplied)
+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
- , m_inputContext(new QWinRTInputContext(m_coreWindow))
-#else
- , m_inputContext(Make<QWinRTInputContext>(m_coreWindow).Detach())
+typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken);
+uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
#endif
- , m_cursor(new QWinRTCursor(window))
- , m_devicePixelRatio(1.0)
- , m_orientation(Qt::PrimaryOrientation)
- , m_touchDevice(Q_NULLPTR)
+
+class QWinRTScreenPrivate
{
- Rect rect;
- window->get_Bounds(&rect);
- m_geometry = QRectF(0, 0, rect.Width, rect.Height);
-
- m_surfaceFormat.setAlphaBufferSize(0);
- m_surfaceFormat.setRedBufferSize(8);
- m_surfaceFormat.setGreenBufferSize(8);
- m_surfaceFormat.setBlueBufferSize(8);
-
- m_surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
- m_surfaceFormat.setSamples(1);
- m_surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
- m_surfaceFormat.setDepthBufferSize(24);
- m_surfaceFormat.setStencilBufferSize(8);
-
- m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (m_eglDisplay == EGL_NO_DISPLAY)
- qFatal("Qt WinRT platform plugin: failed to initialize EGL display.");
-
- if (!eglInitialize(m_eglDisplay, NULL, NULL))
- qFatal("Qt WinRT platform plugin: failed to initialize EGL. This can happen if you haven't included the D3D compiler DLL in your application package.");
-
- // TODO: move this to Window
- m_eglSurface = eglCreateWindowSurface(m_eglDisplay, q_configFromGLFormat(m_eglDisplay, m_surfaceFormat), window, NULL);
- if (m_eglSurface == EGL_NO_SURFACE)
- qFatal("Could not create EGL surface, error 0x%X", eglGetError());
-
- // Event handlers mapped to QEvents
- m_coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &m_tokens[QEvent::KeyPress]);
- m_coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &m_tokens[QEvent::KeyRelease]);
- m_coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &m_tokens[QEvent::User]);
- m_coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &m_tokens[QEvent::Enter]);
- m_coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &m_tokens[QEvent::Leave]);
- m_coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseMove]);
- m_coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonPress]);
- m_coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonRelease]);
- m_coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::Wheel]);
- m_coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &m_tokens[QEvent::Resize]);
+public:
+ ComPtr<ICoreApplication> application;
+ ComPtr<ICoreWindow> coreWindow;
+ ComPtr<IDisplayInformation> displayInformation;
#ifdef Q_OS_WINPHONE
ComPtr<IHardwareButtonsStatics> hardwareButtons;
- if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), &hardwareButtons)))
- hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTScreen::onBackButtonPressed).Get(), &m_tokens[QEvent::User]);
-#endif // Q_OS_WINPHONE
-
- // Window event handlers
- m_coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &m_tokens[QEvent::WindowActivate]);
- m_coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &m_tokens[QEvent::WindowDeactivate]);
- m_coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &m_tokens[QEvent::Show]);
- m_coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &m_tokens[QEvent::InputMethodQuery]);
+#endif
- // Orientation handling
-#if _MSC_VER<=1700
- HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(),
- &m_displayInformation);
+ QScopedPointer<QWinRTCursor> cursor;
+#ifdef Q_OS_WINPHONE
+ QScopedPointer<QWinRTInputContext> inputContext;
#else
- HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(),
- &m_displayInformationFactory);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to get display information factory.");
- return;
- }
-
- hr = m_displayInformationFactory->GetForCurrentView(&m_displayInformation);
+ ComPtr<QWinRTInputContext> inputContext;
#endif
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to get display information for the current view.");
- return;
- }
+ QSizeF logicalSize;
+ QSurfaceFormat surfaceFormat;
+ qreal logicalDpi;
+ QDpi physicalDpi;
+ qreal scaleFactor;
+ Qt::ScreenOrientation nativeOrientation;
+ Qt::ScreenOrientation orientation;
+ QList<QWindow *> visibleWindows;
+#ifndef Q_OS_WINPHONE
+ QHash<quint32, QPair<Qt::Key, QString>> activeKeys;
+#endif
+ QTouchDevice *touchDevice;
+ QHash<quint32, QWindowSystemInterface::TouchPoint> touchPoints;
- // Set native orientation
- DisplayOrientations displayOrientation;
- hr = m_displayInformation->get_NativeOrientation(&displayOrientation);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to get native orientation.");
- return;
- }
+ EGLDisplay eglDisplay;
+ EGLSurface eglSurface;
- m_nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
+ QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
+ QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens;
+ QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens;
+#ifdef Q_OS_WINPHONE
+ QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens;
+#endif
+};
- hr = m_displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(),
- &m_tokens[QEvent::OrientationChange]);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to add orientation change callback.");
- return;
- }
+QWinRTScreen::QWinRTScreen()
+ : d_ptr(new QWinRTScreenPrivate)
+{
+ Q_D(QWinRTScreen);
+ d->orientation = Qt::PrimaryOrientation;
+ d->touchDevice = Q_NULLPTR;
+
+ // 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);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->Activate();
+ Q_ASSERT_SUCCEEDED(hr);
-#if _MSC_VER<=1700
- hr = m_displayInformation->add_LogicalDpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(),
- &m_tokens[QEvent::Type(QEvent::User + 1)]);
+#ifdef Q_OS_WINPHONE
+ d->inputContext.reset(new QWinRTInputContext(d->coreWindow.Get()));
#else
- hr = m_displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(),
- &m_tokens[QEvent::Type(QEvent::User + 1)]);
+ d->inputContext = Make<QWinRTInputContext>(d->coreWindow.Get());
#endif
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to add logical dpi change callback.");
- return;
- }
+
+ 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.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]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
+ Q_ASSERT_SUCCEEDED(hr);
+ 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;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(),
+ IID_PPV_ARGS(&displayInformationStatics));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = displayInformationStatics->GetForCurrentView(&d->displayInformation);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ // Set native orientation
+ DisplayOrientations displayOrientation;
+ hr = d->displayInformation->get_NativeOrientation(&displayOrientation);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
+
+ hr = d->displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]);
+ Q_ASSERT_SUCCEEDED(hr);
// Set initial orientation & pixel density
-#if _MSC_VER<=1700
- onOrientationChanged(Q_NULLPTR);
- onDpiChanged(Q_NULLPTR);
-#else
- onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
onDpiChanged(Q_NULLPTR, Q_NULLPTR);
-#endif
- setOrientationUpdateMask(m_nativeOrientation);
+ d->orientation = d->nativeOrientation;
+ onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
- if (SUCCEEDED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
- IID_PPV_ARGS(&m_application)))) {
- m_application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTScreen::onSuspended).Get(), &m_suspendTokens[Qt::ApplicationSuspended]);
- m_application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTScreen::onResume).Get(), &m_suspendTokens[Qt::ApplicationHidden]);
- }
+ d->eglDisplay = eglGetDisplay(d->displayInformation.Get());
+ 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());
+
+ d->eglSurface = eglCreateWindowSurface(d->eglDisplay, q_configFromGLFormat(d->eglDisplay, d->surfaceFormat), d->coreWindow.Get(), NULL);
+ if (d->eglSurface == EGL_NO_SURFACE)
+ qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
+}
+
+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
}
QRect QWinRTScreen::geometry() const
{
- return m_geometry.toRect();
+ Q_D(const QWinRTScreen);
+ return QRect(QPoint(), (d->logicalSize * d->scaleFactor).toSize());
}
int QWinRTScreen::depth() const
{
- return m_depth;
+ return 32;
}
QImage::Format QWinRTScreen::format() const
{
- return m_format;
+ return QImage::Format_ARGB32_Premultiplied;
}
QSurfaceFormat QWinRTScreen::surfaceFormat() const
{
- return m_surfaceFormat;
+ Q_D(const QWinRTScreen);
+ return d->surfaceFormat;
}
QSizeF QWinRTScreen::physicalSize() const
{
- return m_geometry.size() / m_dpi * qreal(25.4);
+ Q_D(const QWinRTScreen);
+ return QSizeF(d->logicalSize.width() * d->scaleFactor / d->physicalDpi.first * qreal(25.4),
+ d->logicalSize.height() * d->scaleFactor / d->physicalDpi.second * qreal(25.4));
}
QDpi QWinRTScreen::logicalDpi() const
{
- return QDpi(m_dpi, m_dpi);
-}
-
-qreal QWinRTScreen::devicePixelRatio() const
-{
- return m_devicePixelRatio;
+ Q_D(const QWinRTScreen);
+ return QDpi(d->logicalDpi, d->logicalDpi);
}
QWinRTInputContext *QWinRTScreen::inputContext() const
{
- return m_inputContext;
+ Q_D(const QWinRTScreen);
+#ifdef Q_OS_WINPHONE
+ return d->inputContext.data();
+#else
+ return d->inputContext.Get();
+#endif
}
QPlatformCursor *QWinRTScreen::cursor() const
{
- return m_cursor;
+ Q_D(const QWinRTScreen);
+ if (!d->cursor)
+ const_cast<QWinRTScreenPrivate *>(d)->cursor.reset(new QWinRTCursor);
+ return d->cursor.data();
}
Qt::KeyboardModifiers QWinRTScreen::keyboardModifiers() const
{
+ Q_D(const QWinRTScreen);
+
Qt::KeyboardModifiers mods;
CoreVirtualKeyStates mod;
- m_coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod);
+ d->coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod);
if (mod == CoreVirtualKeyStates_Down)
mods |= Qt::ShiftModifier;
- m_coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod);
+ d->coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod);
if (mod == CoreVirtualKeyStates_Down)
mods |= Qt::AltModifier;
- m_coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod);
+ d->coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod);
if (mod == CoreVirtualKeyStates_Down)
mods |= Qt::ControlModifier;
- m_coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod);
+ d->coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod);
if (mod == CoreVirtualKeyStates_Down) {
mods |= Qt::MetaModifier;
} else {
- m_coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod);
+ d->coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod);
if (mod == CoreVirtualKeyStates_Down)
mods |= Qt::MetaModifier;
}
@@ -620,56 +684,55 @@ Qt::KeyboardModifiers QWinRTScreen::keyboardModifiers() const
Qt::ScreenOrientation QWinRTScreen::nativeOrientation() const
{
- return m_nativeOrientation;
+ Q_D(const QWinRTScreen);
+ return d->nativeOrientation;
}
Qt::ScreenOrientation QWinRTScreen::orientation() const
{
- return m_orientation;
-}
-
-void QWinRTScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
-{
-#if _MSC_VER<=1700
- m_displayInformation->put_AutoRotationPreferences(nativeOrientationsFromQt(mask));
-#else
- m_displayInformationFactory->put_AutoRotationPreferences(nativeOrientationsFromQt(mask));
-#endif
+ Q_D(const QWinRTScreen);
+ return d->orientation;
}
ICoreWindow *QWinRTScreen::coreWindow() const
{
- return m_coreWindow;
+ Q_D(const QWinRTScreen);
+ return d->coreWindow.Get();
}
EGLDisplay QWinRTScreen::eglDisplay() const
{
- return m_eglDisplay;
+ Q_D(const QWinRTScreen);
+ return d->eglDisplay;
}
EGLSurface QWinRTScreen::eglSurface() const
{
- return m_eglSurface;
+ Q_D(const QWinRTScreen);
+ return d->eglSurface;
}
QWindow *QWinRTScreen::topWindow() const
{
- return m_visibleWindows.isEmpty() ? 0 : m_visibleWindows.first();
+ Q_D(const QWinRTScreen);
+ return d->visibleWindows.isEmpty() ? 0 : d->visibleWindows.first();
}
void QWinRTScreen::addWindow(QWindow *window)
{
+ Q_D(QWinRTScreen);
if (window == topWindow())
return;
- m_visibleWindows.prepend(window);
+ d->visibleWindows.prepend(window);
QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
handleExpose();
}
void QWinRTScreen::removeWindow(QWindow *window)
{
+ Q_D(QWinRTScreen);
const bool wasTopWindow = window == topWindow();
- if (!m_visibleWindows.removeAll(window))
+ if (!d->visibleWindows.removeAll(window))
return;
if (wasTopWindow)
QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
@@ -678,17 +741,19 @@ void QWinRTScreen::removeWindow(QWindow *window)
void QWinRTScreen::raise(QWindow *window)
{
- m_visibleWindows.removeAll(window);
+ Q_D(QWinRTScreen);
+ d->visibleWindows.removeAll(window);
addWindow(window);
}
void QWinRTScreen::lower(QWindow *window)
{
+ Q_D(QWinRTScreen);
const bool wasTopWindow = window == topWindow();
- if (wasTopWindow && m_visibleWindows.size() == 1)
+ if (wasTopWindow && d->visibleWindows.size() == 1)
return;
- m_visibleWindows.removeAll(window);
- m_visibleWindows.append(window);
+ d->visibleWindows.removeAll(window);
+ d->visibleWindows.append(window);
if (wasTopWindow)
QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
handleExpose();
@@ -696,18 +761,17 @@ void QWinRTScreen::lower(QWindow *window)
void QWinRTScreen::handleExpose()
{
- if (m_visibleWindows.isEmpty())
+ Q_D(QWinRTScreen);
+ if (d->visibleWindows.isEmpty())
return;
- QList<QWindow *>::const_iterator it = m_visibleWindows.constBegin();
- QWindowSystemInterface::handleExposeEvent(*it, m_geometry.toRect());
- while (++it != m_visibleWindows.constEnd())
+ QList<QWindow *>::const_iterator it = d->visibleWindows.constBegin();
+ QWindowSystemInterface::handleExposeEvent(*it, geometry());
+ while (++it != d->visibleWindows.constEnd())
QWindowSystemInterface::handleExposeEvent(*it, QRegion());
- QWindowSystemInterface::flushWindowSystemEvents();
}
-HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args)
+HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args)
{
- Q_UNUSED(window);
VirtualKey virtualKey;
args->get_VirtualKey(&virtualKey);
Qt::Key key = qKeyFromVirtual(virtualKey);
@@ -718,14 +782,14 @@ HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI
return S_OK;
}
-HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args)
+HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args)
{
- Q_UNUSED(window);
Qt::KeyboardModifiers mods = keyboardModifiers();
#ifndef Q_OS_WINPHONE
+ Q_D(QWinRTScreen);
CorePhysicalKeyStatus status; // Look for a pressed character key
- if (SUCCEEDED(args->get_KeyStatus(&status)) && m_activeKeys.contains(status.ScanCode)) {
- QPair<Qt::Key, QString> keyStatus = m_activeKeys.take(status.ScanCode);
+ if (SUCCEEDED(args->get_KeyStatus(&status)) && d->activeKeys.contains(status.ScanCode)) {
+ QPair<Qt::Key, QString> keyStatus = d->activeKeys.take(status.ScanCode);
QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease,
keyStatus.first, mods, keyStatus.second);
return S_OK;
@@ -738,10 +802,8 @@ HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::
return S_OK;
}
-HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceivedEventArgs *args)
+HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *, ICharacterReceivedEventArgs *args)
{
- Q_UNUSED(window);
-
quint32 keyCode;
args->get_KeyCode(&keyCode);
// Don't generate character events for non-printables; the meta key stage is enough
@@ -753,9 +815,10 @@ HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceive
QString text = QChar(keyCode);
QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text);
#ifndef Q_OS_WINPHONE
+ Q_D(QWinRTScreen);
CorePhysicalKeyStatus status; // Defer release to onKeyUp for physical keys
if (SUCCEEDED(args->get_KeyStatus(&status)) && !status.IsKeyReleased) {
- m_activeKeys.insert(status.ScanCode, qMakePair(key, text));
+ d->activeKeys.insert(status.ScanCode, qMakePair(key, text));
return S_OK;
}
#endif // !Q_OS_WINPHONE
@@ -763,42 +826,39 @@ HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceive
return S_OK;
}
-HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *window, IPointerEventArgs *args)
+HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
{
- Q_UNUSED(window);
- IPointerPoint *pointerPoint;
+ Q_D(QWinRTScreen);
+
+ ComPtr<IPointerPoint> pointerPoint;
if (SUCCEEDED(args->get_CurrentPoint(&pointerPoint))) {
// Assumes full-screen window
Point point;
pointerPoint->get_Position(&point);
- QPoint pos(point.X, point.Y);
+ QPoint pos(point.X * d->scaleFactor, point.Y * d->scaleFactor);
QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos);
- pointerPoint->Release();
}
return S_OK;
}
-HRESULT QWinRTScreen::onPointerExited(ICoreWindow *window, IPointerEventArgs *args)
+HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *)
{
- Q_UNUSED(window);
- Q_UNUSED(args);
QWindowSystemInterface::handleLeaveEvent(0);
return S_OK;
}
-HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *args)
+HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
{
- Q_UNUSED(window);
-
- IPointerPoint *pointerPoint;
+ Q_D(QWinRTScreen);
+ ComPtr<IPointerPoint> pointerPoint;
if (FAILED(args->get_CurrentPoint(&pointerPoint)))
return E_INVALIDARG;
// Common traits - point, modifiers, properties
Point point;
pointerPoint->get_Position(&point);
- QPointF pos(point.X, point.Y);
+ QPointF pos(point.X * d->scaleFactor, point.Y * d->scaleFactor);
VirtualKeyModifiers modifiers;
args->get_KeyModifiers(&modifiers);
@@ -812,27 +872,18 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
if (modifiers & VirtualKeyModifiers_Windows)
mods |= Qt::MetaModifier;
- IPointerPointProperties *properties;
+ ComPtr<IPointerPointProperties> properties;
if (FAILED(pointerPoint->get_Properties(&properties)))
return E_INVALIDARG;
- PointerDeviceType pointerDeviceType;
-#if defined(Q_OS_WINPHONE) && _MSC_VER <= 1700
- pointerDeviceType = PointerDeviceType_Touch;
-#else
ComPtr<IPointerDevice> pointerDevice;
HRESULT hr = pointerPoint->get_PointerDevice(&pointerDevice);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to get pointer device.");
- return S_OK;
- }
+ RETURN_OK_IF_FAILED("Failed to get pointer device.");
+ PointerDeviceType pointerDeviceType;
hr = pointerDevice->get_PointerDeviceType(&pointerDeviceType);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to get pointer device type.");
- return S_OK;
- }
-#endif
+ RETURN_OK_IF_FAILED("Failed to get pointer device type.");
+
switch (pointerDeviceType) {
case PointerDeviceType_Mouse: {
qint32 delta;
@@ -872,12 +923,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
break;
}
case PointerDeviceType_Touch: {
- if (!m_touchDevice) {
- m_touchDevice = new QTouchDevice;
- m_touchDevice->setName(QStringLiteral("WinRTTouchScreen"));
- m_touchDevice->setType(QTouchDevice::TouchScreen);
- m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition);
- QWindowSystemInterface::registerTouchDevice(m_touchDevice);
+ if (!d->touchDevice) {
+ d->touchDevice = new QTouchDevice;
+ d->touchDevice->setName(QStringLiteral("WinRTTouchScreen"));
+ d->touchDevice->setType(QTouchDevice::TouchScreen);
+ d->touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition);
+ QWindowSystemInterface::registerTouchDevice(d->touchDevice);
}
quint32 id;
@@ -889,8 +940,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
float pressure;
properties->get_Pressure(&pressure);
- QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = m_touchPoints.find(id);
- if (it != m_touchPoints.end()) {
+ QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id);
+ if (it != d->touchPoints.end()) {
boolean isPressed;
#ifndef Q_OS_WINPHONE
pointerPoint->get_IsInContact(&isPressed);
@@ -899,20 +950,21 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
#endif
it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased;
} else {
- it = m_touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
+ it = d->touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
it.value().state = Qt::TouchPointPressed;
it.value().id = id;
}
- it.value().area = QRectF(area.X, area.Y, area.Width, area.Height);
- it.value().normalPosition = QPointF(pos.x()/m_geometry.width(), pos.y()/m_geometry.height());
+ it.value().area = QRectF(area.X * d->scaleFactor, area.Y * d->scaleFactor,
+ area.Width * d->scaleFactor, area.Height * d->scaleFactor);
+ it.value().normalPosition = QPointF(point.X/d->logicalSize.width(), point.Y/d->logicalSize.height());
it.value().pressure = pressure;
- QWindowSystemInterface::handleTouchEvent(topWindow(), m_touchDevice, m_touchPoints.values(), mods);
+ QWindowSystemInterface::handleTouchEvent(topWindow(), d->touchDevice, d->touchPoints.values(), mods);
// Remove released points, station others
- for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = m_touchPoints.begin(); i != m_touchPoints.end();) {
+ for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = d->touchPoints.begin(); i != d->touchPoints.end();) {
if (i.value().state == Qt::TouchPointReleased)
- i = m_touchPoints.erase(i);
+ i = d->touchPoints.erase(i);
else
(i++).value().state = Qt::TouchPointStationary;
}
@@ -950,46 +1002,46 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
}
}
- properties->Release();
- pointerPoint->Release();
-
return S_OK;
}
HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args)
{
+ Q_D(const QWinRTScreen);
#ifndef Q_OS_WINPHONE
- args->put_AutomationProvider(m_inputContext);
+ args->put_AutomationProvider(d->inputContext.Get());
#else
Q_UNUSED(args)
#endif
return S_OK;
}
-HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *window, IWindowSizeChangedEventArgs *args)
+HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args)
{
- Q_UNUSED(window);
+ Q_D(QWinRTScreen);
Size size;
- if (FAILED(args->get_Size(&size))) {
- qWarning(Q_FUNC_INFO ": failed to get size");
+ HRESULT hr = args->get_Size(&size);
+ RETURN_OK_IF_FAILED("Failed to get window size.");
+
+ QSizeF logicalSize = QSizeF(size.Width, size.Height);
+ if (d->logicalSize == logicalSize)
return S_OK;
- }
// Regardless of state, all top-level windows are viewport-sized - this might change if
// a more advanced compositor is written.
- m_geometry.setSize(QSizeF(size.Width, size.Height));
- QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry.toRect());
- QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry.toRect());
+ d->logicalSize = logicalSize;
+ const QRect newGeometry = geometry();
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
QPlatformScreen::resizeMaximizedWindows();
handleExpose();
return S_OK;
}
-HRESULT QWinRTScreen::onActivated(ICoreWindow *window, IWindowActivatedEventArgs *args)
+HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args)
{
- Q_UNUSED(window);
+ Q_D(QWinRTScreen);
CoreWindowActivationState activationState;
args->get_WindowActivationState(&activationState);
@@ -999,7 +1051,7 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *window, IWindowActivatedEventArgs
}
// Activate topWindow
- if (!m_visibleWindows.isEmpty()) {
+ if (!d->visibleWindows.isEmpty()) {
Qt::FocusReason focusReason = activationState == CoreWindowActivationState_PointerActivated
? Qt::MouseFocusReason : Qt::ActiveWindowFocusReason;
QWindowSystemInterface::handleWindowActivated(topWindow(), focusReason);
@@ -1022,21 +1074,15 @@ HRESULT QWinRTScreen::onResume(IInspectable *, IInspectable *)
return S_OK;
}
-HRESULT QWinRTScreen::onClosed(ICoreWindow *window, ICoreWindowEventArgs *args)
+HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *)
{
- Q_UNUSED(window);
- Q_UNUSED(args);
-
foreach (QWindow *w, QGuiApplication::topLevelWindows())
QWindowSystemInterface::handleCloseEvent(w);
return S_OK;
}
-HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChangedEventArgs *args)
+HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEventArgs *args)
{
- Q_UNUSED(window);
- Q_UNUSED(args);
-
boolean visible;
args->get_Visible(&visible);
QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
@@ -1045,60 +1091,52 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChange
return S_OK;
}
-#if _MSC_VER<=1700
-HRESULT QWinRTScreen::onOrientationChanged(IInspectable *)
-#else
HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *)
-#endif
{
+ Q_D(QWinRTScreen);
+
DisplayOrientations displayOrientation;
- m_displayInformation->get_CurrentOrientation(&displayOrientation);
+ HRESULT hr = d->displayInformation->get_CurrentOrientation(&displayOrientation);
+ RETURN_OK_IF_FAILED("Failed to get current orientations.");
+
Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
- if (m_orientation != newOrientation) {
- m_orientation = newOrientation;
- QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
+ if (d->orientation != newOrientation) {
+ d->orientation = newOrientation;
+ QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
}
return S_OK;
}
-#if _MSC_VER<=1700
-HRESULT QWinRTScreen::onDpiChanged(IInspectable *)
-#else
HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
-#endif
{
-#if defined(Q_OS_WINPHONE) && _MSC_VER>=1800 // WP 8.1
+ Q_D(QWinRTScreen);
+
+ HRESULT hr;
+#ifdef Q_OS_WINPHONE
ComPtr<IDisplayInformation2> displayInformation;
- HRESULT hr = m_displayInformation->QueryInterface(IID_IDisplayInformation2, &displayInformation);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to cast display information.");
- return S_OK;
- }
- hr = displayInformation->get_RawPixelsPerViewPixel(&m_devicePixelRatio);
+ hr = d->displayInformation.As(&displayInformation);
+ RETURN_OK_IF_FAILED("Failed to cast display information.");
+ hr = displayInformation->get_RawPixelsPerViewPixel(&d->scaleFactor);
#else
ResolutionScale resolutionScale;
- HRESULT hr = m_displayInformation->get_ResolutionScale(&resolutionScale);
-#endif
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to get display resolution scale.");
- return S_OK;
- }
-#if !(defined(Q_OS_WINPHONE) && _MSC_VER>=1800) // !WP8.1
- m_devicePixelRatio = qreal(resolutionScale) / 100;
+ hr = d->displayInformation->get_ResolutionScale(&resolutionScale);
+ d->scaleFactor = qreal(resolutionScale) / 100;
#endif
-
- // Correct the scale factor for integer window size
- m_devicePixelRatio = m_devicePixelRatio * ((m_geometry.width()/qRound(m_geometry.width()) +
- m_geometry.height()/qRound(m_geometry.height())) / 2.0);
+ RETURN_OK_IF_FAILED("Failed to get scale factor");
FLOAT dpi;
- hr = m_displayInformation->get_LogicalDpi(&dpi);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to get logical DPI.");
- return S_OK;
- }
- m_dpi = dpi;
+ hr = d->displayInformation->get_LogicalDpi(&dpi);
+ RETURN_OK_IF_FAILED("Failed to get logical DPI.");
+ d->logicalDpi = dpi;
+
+ hr = d->displayInformation->get_RawDpiX(&dpi);
+ RETURN_OK_IF_FAILED("Failed to get x raw DPI.");
+ d->physicalDpi.first = dpi ? dpi : 96.0;
+
+ hr = d->displayInformation->get_RawDpiY(&dpi);
+ RETURN_OK_IF_FAILED("Failed to get y raw DPI.");
+ d->physicalDpi.second = dpi ? dpi : 96.0;
return S_OK;
}
@@ -1106,14 +1144,16 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
#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 = m_visibleWindows.isEmpty()
+ QObject *receiver = d->visibleWindows.isEmpty()
? static_cast<QObject *>(QGuiApplication::instance())
- : static_cast<QObject *>(m_visibleWindows.first());
+ : static_cast<QObject *>(d->visibleWindows.first());
// If the event is ignored, the app will suspend
QGuiApplication::sendEvent(receiver, &backPress);
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index d39683a960..6764450d84 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -45,19 +45,12 @@
#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
-#include <QtCore/QHash>
-#include <QtGui/QSurfaceFormat>
#include <EGL/egl.h>
-#include <EventToken.h>
-
namespace ABI {
namespace Windows {
namespace ApplicationModel {
struct ISuspendingEventArgs;
- namespace Core {
- struct ICoreApplication;
- }
}
namespace UI {
namespace Core {
@@ -71,14 +64,9 @@ namespace ABI {
struct IWindowActivatedEventArgs;
struct IWindowSizeChangedEventArgs;
}
- namespace ViewManagement {
- struct IApplicationViewStatics;
- }
}
namespace Graphics {
namespace Display {
- struct IDisplayPropertiesStatics;
- struct IDisplayInformationStatics;
struct IDisplayInformation;
}
}
@@ -99,28 +87,26 @@ QT_BEGIN_NAMESPACE
class QTouchDevice;
class QWinRTEGLContext;
-class QWinRTPageFlipper;
class QWinRTCursor;
class QWinRTInputContext;
-
+class QWinRTScreenPrivate;
class QWinRTScreen : public QPlatformScreen
{
public:
- explicit QWinRTScreen(ABI::Windows::UI::Core::ICoreWindow *window);
+ explicit QWinRTScreen();
+ ~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 devicePixelRatio() const Q_DECL_OVERRIDE;
QWinRTInputContext *inputContext() const;
QPlatformCursor *cursor() const;
Qt::KeyboardModifiers keyboardModifiers() const;
Qt::ScreenOrientation nativeOrientation() const;
Qt::ScreenOrientation orientation() const;
- void setOrientationUpdateMask(Qt::ScreenOrientations mask);
QWindow *topWindow() const;
void addWindow(QWindow *window);
@@ -135,69 +121,31 @@ public:
private:
void handleExpose();
- // Event handlers
- QHash<QEvent::Type, EventRegistrationToken> m_tokens;
- QHash<Qt::ApplicationState, EventRegistrationToken> m_suspendTokens;
+ HRESULT onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *);
+ HRESULT onKeyUp(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *);
+ HRESULT onCharacterReceived(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICharacterReceivedEventArgs *);
+ HRESULT onPointerEntered(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IPointerEventArgs *);
+ HRESULT onPointerExited(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IPointerEventArgs *);
+ HRESULT onPointerUpdated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IPointerEventArgs *);
+ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
- HRESULT onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args);
- HRESULT onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args);
- HRESULT onCharacterReceived(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::ICharacterReceivedEventArgs *args);
- HRESULT onPointerEntered(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
- HRESULT onPointerExited(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
- HRESULT onPointerUpdated(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
- HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *args);
-
- HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *args);
+ HRESULT 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 *args);
- HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *args);
- HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *args);
+ HRESULT 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 *);
-#if _MSC_VER<=1700
- HRESULT onOrientationChanged(IInspectable *);
- HRESULT onDpiChanged(IInspectable *);
-#else
HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
-#endif
#ifdef Q_OS_WINPHONE
HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
#endif
- ABI::Windows::UI::Core::ICoreWindow *m_coreWindow;
- ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView;
- ABI::Windows::ApplicationModel::Core::ICoreApplication *m_application;
-
- QRectF m_geometry;
- QImage::Format m_format;
- QSurfaceFormat m_surfaceFormat;
- qreal m_dpi;
- int m_depth;
- QWinRTInputContext *m_inputContext;
- QWinRTCursor *m_cursor;
- QList<QWindow *> m_visibleWindows;
-
- EGLDisplay m_eglDisplay;
- EGLSurface m_eglSurface;
-
-#if _MSC_VER<=1700
- ABI::Windows::Graphics::Display::IDisplayPropertiesStatics *m_displayInformation;
-#else
- ABI::Windows::Graphics::Display::IDisplayInformationStatics *m_displayInformationFactory;
- ABI::Windows::Graphics::Display::IDisplayInformation *m_displayInformation;
-#endif
- qreal m_devicePixelRatio;
- Qt::ScreenOrientation m_nativeOrientation;
- Qt::ScreenOrientation m_orientation;
-
-#ifndef Q_OS_WINPHONE
- QHash<quint32, QPair<Qt::Key, QString> > m_activeKeys;
-#endif
- QTouchDevice *m_touchDevice;
- QHash<quint32, QWindowSystemInterface::TouchPoint> m_touchPoints;
+ QScopedPointer<QWinRTScreenPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTScreen)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp
index b0f9247d36..4ee2aa68f8 100644
--- a/src/plugins/platforms/winrt/qwinrtservices.cpp
+++ b/src/plugins/platforms/winrt/qwinrtservices.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -40,9 +40,11 @@
****************************************************************************/
#include "qwinrtservices.h"
+#include "qwinrtfileengine.h"
#include <QtCore/QUrl>
#include <QtCore/QDir>
#include <QtCore/QCoreApplication>
+#include <QtCore/qfunctions_winrt.h>
#include <wrl.h>
#include <windows.foundation.h>
@@ -56,83 +58,90 @@ using namespace ABI::Windows::System;
QT_BEGIN_NAMESPACE
+class QWinRTServicesPrivate
+{
+public:
+ ComPtr<IUriRuntimeClassFactory> uriFactory;
+ ComPtr<IStorageFileStatics> fileFactory;
+ ComPtr<ILauncherStatics> launcher;
+};
+
QWinRTServices::QWinRTServices()
+ : d_ptr(new QWinRTServicesPrivate)
{
- GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Uri).Get(), &m_uriFactory);
- GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFile).Get(), &m_fileFactory);
- GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Launcher).Get(), &m_launcher);
+ Q_D(QWinRTServices);
+
+ HRESULT hr;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Uri).Get(),
+ IID_PPV_ARGS(&d->uriFactory));
+ Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
+
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFile).Get(),
+ IID_PPV_ARGS(&d->fileFactory));
+ Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
+
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Launcher).Get(),
+ IID_PPV_ARGS(&d->launcher));
+ Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
}
QWinRTServices::~QWinRTServices()
{
- if (m_uriFactory)
- m_uriFactory->Release();
-
- if (m_fileFactory)
- m_fileFactory->Release();
-
- if (m_launcher)
- m_launcher->Release();
}
bool QWinRTServices::openUrl(const QUrl &url)
{
- if (!(m_uriFactory && m_launcher))
- return QPlatformServices::openUrl(url);
+ Q_D(QWinRTServices);
- IUriRuntimeClass *uri;
+ ComPtr<IUriRuntimeClass> uri;
QString urlString = url.toString();
- // ### TODO: Replace with HStringReference when WP8.0 support is removed
- HString uriString;
- uriString.Set((const wchar_t*)urlString.utf16(), urlString.length());
- m_uriFactory->CreateUri(uriString.Get(), &uri);
- if (!uri)
- return false;
-
- IAsyncOperation<bool> *launchOp;
- m_launcher->LaunchUriAsync(uri, &launchOp);
- uri->Release();
- if (!launchOp)
- return false;
-
- boolean result = false;
- while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
- QCoreApplication::processEvents();
- launchOp->Release();
+ HStringReference uriString(reinterpret_cast<LPCWSTR>(urlString.utf16()), urlString.length());
+ HRESULT hr = d->uriFactory->CreateUri(uriString.Get(), &uri);
+ RETURN_FALSE_IF_FAILED("Failed to create URI from QUrl.");
+
+ ComPtr<IAsyncOperation<bool>> op;
+ hr = d->launcher->LaunchUriAsync(uri.Get(), &op);
+ RETURN_FALSE_IF_FAILED("Failed to start URI launch.");
+
+ boolean result;
+ hr = QWinRTFunctions::await(op, &result);
+ RETURN_FALSE_IF_FAILED("Failed to launch URI.");
return result;
}
bool QWinRTServices::openDocument(const QUrl &url)
{
- if (!(m_fileFactory && m_launcher))
- return QPlatformServices::openDocument(url);
-
- const QString pathString = QDir::toNativeSeparators(url.toLocalFile());
- // ### TODO: Replace with HStringReference when WP8.0 support is removed
- HString path;
- path.Set((const wchar_t*)pathString.utf16(), pathString.length());
- IAsyncOperation<StorageFile*> *fileOp;
- m_fileFactory->GetFileFromPathAsync(path.Get(), &fileOp);
- if (!fileOp)
- return false;
-
- IStorageFile *file = nullptr;
- while (fileOp->GetResults(&file) == E_ILLEGAL_METHOD_CALL)
- QCoreApplication::processEvents();
- fileOp->Release();
- if (!file)
- return false;
-
- IAsyncOperation<bool> *launchOp;
- m_launcher->LaunchFileAsync(file, &launchOp);
- if (!launchOp)
- return false;
-
- boolean result = false;
- while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
- QCoreApplication::processEvents();
- launchOp->Release();
+ Q_D(QWinRTServices);
+
+ HRESULT hr;
+ ComPtr<IStorageFile> file;
+ ComPtr<IStorageItem> item = QWinRTFileEngineHandler::registeredFile(url.toLocalFile());
+ if (item) {
+ hr = item.As(&file);
+ if (FAILED(hr))
+ qErrnoWarning(hr, "Failed to cast picked item to a file");
+ }
+ if (!file) {
+ const QString pathString = QDir::toNativeSeparators(url.toLocalFile());
+ HStringReference path(reinterpret_cast<LPCWSTR>(pathString.utf16()), pathString.length());
+ ComPtr<IAsyncOperation<StorageFile *>> op;
+ hr = d->fileFactory->GetFileFromPathAsync(path.Get(), &op);
+ RETURN_FALSE_IF_FAILED("Failed to initialize file URI.");
+
+ hr = QWinRTFunctions::await(op, file.GetAddressOf());
+ RETURN_FALSE_IF_FAILED("Failed to get file URI.");
+ }
+
+ boolean result;
+ {
+ ComPtr<IAsyncOperation<bool>> op;
+ hr = d->launcher->LaunchFileAsync(file.Get(), &op);
+ RETURN_FALSE_IF_FAILED("Failed to start file launch.");
+
+ hr = QWinRTFunctions::await(op, &result);
+ RETURN_FALSE_IF_FAILED("Failed to launch file.");
+ }
return result;
}
diff --git a/src/plugins/platforms/winrt/qwinrtservices.h b/src/plugins/platforms/winrt/qwinrtservices.h
index 9cc917030a..d3abe6f2bd 100644
--- a/src/plugins/platforms/winrt/qwinrtservices.h
+++ b/src/plugins/platforms/winrt/qwinrtservices.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -43,23 +43,11 @@
#define QWINRTSERVICES_H
#include <qpa/qplatformservices.h>
+#include <QtCore/QScopedPointer>
-namespace ABI {
- namespace Windows {
- namespace Foundation {
- struct IUriRuntimeClassFactory;
- }
- namespace Storage {
- struct IStorageFileStatics;
- }
- namespace System {
- struct ILauncherStatics;
- }
- }
-}
-
-QT_BEGIN_NAMESPACE
+QT_USE_NAMESPACE
+class QWinRTServicesPrivate;
class QWinRTServices : public QPlatformServices
{
public:
@@ -70,11 +58,8 @@ public:
bool openDocument(const QUrl &url);
private:
- ABI::Windows::Foundation::IUriRuntimeClassFactory *m_uriFactory;
- ABI::Windows::Storage::IStorageFileStatics *m_fileFactory;
- ABI::Windows::System::ILauncherStatics *m_launcher;
+ QScopedPointer<QWinRTServicesPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTServices)
};
-QT_END_NAMESPACE
-
#endif // QWINRTSERVICES_H
diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp
new file mode 100644
index 0000000000..7004abf888
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrttheme.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrttheme.h"
+#include "qwinrtmessagedialoghelper.h"
+#include "qwinrtfiledialoghelper.h"
+
+#include <QtCore/qfunctions_winrt.h>
+#include <QtGui/QPalette>
+
+#include <wrl.h>
+#include <windows.ui.h>
+#include <windows.ui.viewmanagement.h>
+using namespace Microsoft::WRL;
+using namespace ABI::Windows::UI;
+using namespace ABI::Windows::UI::ViewManagement;
+
+QT_BEGIN_NAMESPACE
+
+static IUISettings *uiSettings()
+{
+ static ComPtr<IUISettings> settings;
+ if (!settings) {
+ HRESULT hr;
+ hr = RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_UISettings).Get(),
+ &settings);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ return settings.Get();
+}
+
+class QWinRTThemePrivate
+{
+public:
+ QPalette palette;
+};
+
+static inline QColor fromColor(const Color &color)
+{
+ return QColor(color.R, color.G, color.B, color.A);
+}
+
+QWinRTTheme::QWinRTTheme()
+ : d_ptr(new QWinRTThemePrivate)
+{
+ Q_D(QWinRTTheme);
+
+ HRESULT hr;
+ Color color;
+
+#ifdef Q_OS_WINPHONE
+ hr = uiSettings()->UIElementColor(UIElementType_PopupBackground, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::ToolTipBase, fromColor(color));
+ d->palette.setColor(QPalette::AlternateBase, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_NonTextMedium, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Button, fromColor(color));
+ hr = uiSettings()->UIElementColor(UIElementType_NonTextMediumHigh, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Midlight, fromColor(color));
+ hr = uiSettings()->UIElementColor(UIElementType_NonTextHigh, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Light, fromColor(color));
+ hr = uiSettings()->UIElementColor(UIElementType_NonTextMediumLow, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Mid, fromColor(color));
+ hr = uiSettings()->UIElementColor(UIElementType_NonTextLow, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Dark, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_TextHigh, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::ButtonText, fromColor(color));
+ d->palette.setColor(QPalette::Text, fromColor(color));
+ d->palette.setColor(QPalette::WindowText, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_TextMedium, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::ToolTipText, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_AccentColor, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Highlight, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_PageBackground, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Window, fromColor(color));
+ d->palette.setColor(QPalette::Base, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_TextContrastWithHigh, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::BrightText, fromColor(color));
+#else
+ hr = uiSettings()->UIElementColor(UIElementType_ActiveCaption, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::ToolTipBase, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_Background, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::AlternateBase, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_ButtonFace, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Button, fromColor(color));
+ d->palette.setColor(QPalette::Midlight, fromColor(color).lighter(110));
+ d->palette.setColor(QPalette::Light, fromColor(color).lighter(150));
+ d->palette.setColor(QPalette::Mid, fromColor(color).dark(130));
+ d->palette.setColor(QPalette::Dark, fromColor(color).dark(150));
+
+ hr = uiSettings()->UIElementColor(UIElementType_ButtonText, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::ButtonText, fromColor(color));
+ d->palette.setColor(QPalette::Text, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_CaptionText, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::ToolTipText, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_Highlight, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Highlight, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_HighlightText, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::HighlightedText, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_Window, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::Window, fromColor(color));
+ d->palette.setColor(QPalette::Base, fromColor(color));
+
+ hr = uiSettings()->UIElementColor(UIElementType_Hotlight, &color);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->palette.setColor(QPalette::BrightText, fromColor(color));
+#endif
+}
+
+bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const
+{
+ static bool useNativeDialogs = qEnvironmentVariableIsSet("QT_USE_WINRT_NATIVE_DIALOGS")
+ ? qgetenv("QT_USE_WINRT_NATIVE_DIALOGS").toInt() : true;
+
+ if (type == FileDialog || type == MessageDialog)
+ return useNativeDialogs;
+ return false;
+}
+
+QPlatformDialogHelper *QWinRTTheme::createPlatformDialogHelper(DialogType type) const
+{
+ switch (type) {
+ case FileDialog:
+ return new QWinRTFileDialogHelper;
+ case MessageDialog:
+ return new QWinRTMessageDialogHelper(this);
+ default:
+ break;
+ }
+ return QPlatformTheme::createPlatformDialogHelper(type);
+}
+
+QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint)
+{
+ HRESULT hr;
+ switch (hint) {
+ case QPlatformIntegration::CursorFlashTime: {
+ quint32 blinkRate;
+ hr = uiSettings()->get_CaretBlinkRate(&blinkRate);
+ RETURN_IF_FAILED("Failed to get caret blink rate", return defaultThemeHint(CursorFlashTime));
+ return blinkRate;
+ }
+ case QPlatformIntegration::KeyboardInputInterval:
+ return defaultThemeHint(KeyboardInputInterval);
+ case QPlatformIntegration::MouseDoubleClickInterval: {
+ quint32 doubleClickTime;
+ hr = uiSettings()->get_DoubleClickTime(&doubleClickTime);
+ RETURN_IF_FAILED("Failed to get double click time", return defaultThemeHint(MouseDoubleClickInterval));
+ return doubleClickTime;
+ }
+ case QPlatformIntegration::StartDragDistance:
+ return defaultThemeHint(StartDragDistance);
+ case QPlatformIntegration::StartDragTime:
+ return defaultThemeHint(StartDragTime);
+ case QPlatformIntegration::KeyboardAutoRepeatRate:
+ return defaultThemeHint(KeyboardAutoRepeatRate);
+ case QPlatformIntegration::ShowIsFullScreen:
+ return true;
+ case QPlatformIntegration::PasswordMaskDelay:
+ return defaultThemeHint(PasswordMaskDelay);
+ case QPlatformIntegration::FontSmoothingGamma:
+ return qreal(1.7);
+ case QPlatformIntegration::StartDragVelocity:
+ return defaultThemeHint(StartDragVelocity);
+ case QPlatformIntegration::UseRtlExtensions:
+ return false;
+ case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
+ return true;
+ case QPlatformIntegration::PasswordMaskCharacter:
+ return defaultThemeHint(PasswordMaskCharacter);
+ case QPlatformIntegration::SetFocusOnTouchRelease:
+ return false;
+ case QPlatformIntegration::ShowIsMaximized:
+ return false;
+ case MousePressAndHoldInterval:
+ return defaultThemeHint(MousePressAndHoldInterval);
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+const QPalette *QWinRTTheme::palette(Palette type) const
+{
+ Q_D(const QWinRTTheme);
+ if (type == SystemPalette)
+ return &d->palette;
+ return QPlatformTheme::palette(type);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtplatformtheme.h b/src/plugins/platforms/winrt/qwinrttheme.h
index f4a61982b2..f7fd07c70d 100644
--- a/src/plugins/platforms/winrt/qwinrtplatformtheme.h
+++ b/src/plugins/platforms/winrt/qwinrttheme.h
@@ -39,22 +39,32 @@
**
****************************************************************************/
-#ifndef QWINRTPLATFORMTHEME_H
-#define QWINRTPLATFORMTHEME_H
+#ifndef QWINRTTHEME_H
+#define QWINRTTHEME_H
#include <qpa/qplatformtheme.h>
+#include <qpa/qplatformintegration.h>
QT_BEGIN_NAMESPACE
-class QWinRTPlatformTheme : public QPlatformTheme
+class QWinRTThemePrivate;
+class QWinRTTheme : public QPlatformTheme
{
public:
- QWinRTPlatformTheme();
+ QWinRTTheme();
bool usePlatformNativeDialog(DialogType type) const;
QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
+
+ const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE;
+
+ static QVariant styleHint(QPlatformIntegration::StyleHint hint);
+
+private:
+ QScopedPointer<QWinRTThemePrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTTheme)
};
QT_END_NAMESPACE
-#endif // QWINRTPLATFORMTHEME_H
+#endif // QWINRTTHEME_H
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index 349cdf11c9..80429daeed 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -32,48 +32,37 @@ SOURCES = \
qwinrtcursor.cpp \
qwinrteglcontext.cpp \
qwinrteventdispatcher.cpp \
+ qwinrtfiledialoghelper.cpp \
+ qwinrtfileengine.cpp \
qwinrtfontdatabase.cpp \
qwinrtinputcontext.cpp \
qwinrtintegration.cpp \
- qwinrtplatformmessagedialoghelper.cpp \
- qwinrtplatformtheme.cpp \
+ qwinrtmessagedialoghelper.cpp \
qwinrtscreen.cpp \
qwinrtservices.cpp \
+ qwinrttheme.cpp \
qwinrtwindow.cpp
+
HEADERS = \
qwinrtbackingstore.h \
qwinrtcursor.h \
qwinrteglcontext.h \
qwinrteventdispatcher.h \
+ qwinrtfiledialoghelper.h \
+ qwinrtfileengine.h \
qwinrtfontdatabase.h \
qwinrtinputcontext.h \
qwinrtintegration.h \
- qwinrtplatformmessagedialoghelper.h \
- qwinrtplatformtheme.h \
+ qwinrtmessagedialoghelper.h \
qwinrtscreen.h \
qwinrtservices.h \
+ qwinrttheme.h \
qwinrtwindow.h
-BLIT_INPUT = $$PWD/blit.hlsl
-fxc_blitps.commands = fxc.exe /nologo /T ps_4_0_level_9_1 /E blitps /Vn q_blitps /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
-fxc_blitps.output = $$OUT_PWD/blitps.h
-fxc_blitps.input = BLIT_INPUT
-fxc_blitps.dependency_type = TYPE_C
-fxc_blitps.variable_out = HEADERS
-fxc_blitps.CONFIG += target_predeps
-fxc_blitvs.commands = fxc.exe /nologo /T vs_4_0_level_9_1 /E blitvs /Vn q_blitvs /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
-fxc_blitvs.output = $$OUT_PWD/blitvs.h
-fxc_blitvs.input = BLIT_INPUT
-fxc_blitvs.dependency_type = TYPE_C
-fxc_blitvs.variable_out = HEADERS
-fxc_blitvs.CONFIG += target_predeps
-QMAKE_EXTRA_COMPILERS += fxc_blitps fxc_blitvs
-
winphone:equals(WINSDK_VER, 8.0): {
SOURCES -= qwinrtplatformmessagedialoghelper.cpp
HEADERS -= qwinrtplatformmessagedialoghelper.h
}
-OTHER_FILES += winrt.json \
- blit.hlsl
+OTHER_FILES += winrt.json