winrt: Clean up QWinRTScreen

- Remove WP8.0 code paths
- Remove WinRT types from header as much as possible
- Use ComPtr where appropriate
- Use COM convenience methods

Task-number: QTBUG-38115
Change-Id: Ib241c3e5107add255a48340f86ee5885f895ff83
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
This commit is contained in:
Andrew Knight 2014-06-07 23:38:18 +03:00
parent b740e27e36
commit 50001dc801
3 changed files with 311 additions and 336 deletions

View File

@ -82,26 +82,7 @@ QWinRTIntegration::QWinRTIntegration()
, m_fontDatabase(new QWinRTFontDatabase) , m_fontDatabase(new QWinRTFontDatabase)
, m_services(new QWinRTServices) , m_services(new QWinRTServices)
{ {
// Obtain the WinRT Application, view, and window m_screen = new QWinRTScreen;
ICoreApplication *application;
if (FAILED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
IID_PPV_ARGS(&application))))
qCritical("Could not attach to the application factory.");
ICoreApplicationView *view;
if (FAILED(application->GetCurrentView(&view))) {
qCritical("Could not obtain the application view - have you started outside of WinRT?");
return;
}
// Get core window (will act as our screen)
ICoreWindow *window;
if (FAILED(view->get_CoreWindow(&window))) {
qCritical("Could not obtain the application window - have you started outside of WinRT?");
return;
}
window->Activate();
m_screen = new QWinRTScreen(window);
screenAdded(m_screen); screenAdded(m_screen);
m_success = true; m_success = true;

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the plugins of the Qt Toolkit. ** This file is part of the plugins of the Qt Toolkit.
@ -51,6 +51,7 @@
#include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface.h>
#include <QtCore/qt_windows.h> #include <QtCore/qt_windows.h>
#include <QtCore/qfunctions_winrt.h>
#include <wrl.h> #include <wrl.h>
#include <windows.system.h> #include <windows.system.h>
@ -93,11 +94,7 @@ typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler; typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler;
typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler; typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler; typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler;
#if _MSC_VER <=1700
typedef IDisplayPropertiesEventHandler DisplayInformationHandler;
#else
typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler; typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler;
#endif
#ifdef Q_OS_WINPHONE #ifdef Q_OS_WINPHONE
typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler; typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
#endif #endif
@ -419,199 +416,272 @@ static inline Qt::Key qKeyFromCode(quint32 code, int mods)
return static_cast<Qt::Key>(code & 0xff); return static_cast<Qt::Key>(code & 0xff);
} }
QWinRTScreen::QWinRTScreen(ICoreWindow *window) typedef HRESULT (__stdcall ICoreApplication::*CoreApplicationCallbackRemover)(EventRegistrationToken);
: m_coreWindow(window) uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
, m_depth(32) typedef HRESULT (__stdcall ICoreWindow::*CoreWindowCallbackRemover)(EventRegistrationToken);
, m_format(QImage::Format_ARGB32_Premultiplied) 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 #ifdef Q_OS_WINPHONE
, m_inputContext(new QWinRTInputContext(m_coreWindow)) typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken);
#else uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); }
, m_inputContext(Make<QWinRTInputContext>(m_coreWindow).Detach())
#endif #endif
, m_cursor(new QWinRTCursor)
, m_devicePixelRatio(1.0) class QWinRTScreenPrivate
, m_orientation(Qt::PrimaryOrientation)
, m_touchDevice(Q_NULLPTR)
{ {
public:
ComPtr<ICoreApplication> application;
ComPtr<ICoreWindow> coreWindow;
ComPtr<IDisplayInformationStatics> displayInformationStatics;
ComPtr<IDisplayInformation> displayInformation;
#ifdef Q_OS_WINPHONE
ComPtr<IHardwareButtonsStatics> hardwareButtons;
#endif
QScopedPointer<QWinRTCursor> cursor;
#ifdef Q_OS_WINPHONE
QScopedPointer<QWinRTInputContext> inputContext;
#else
ComPtr<QWinRTInputContext> inputContext;
#endif
QRectF geometry;
QSurfaceFormat surfaceFormat;
qreal dpi;
qreal devicePixelRatio;
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;
EGLDisplay eglDisplay;
EGLSurface eglSurface;
QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens;
QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens;
#ifdef Q_OS_WINPHONE
QHash<HardwareButtonsCallbackRemover, EventRegistrationToken> buttonsTokens;
#endif
};
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);
#ifdef Q_OS_WINPHONE
d->inputContext.reset(new QWinRTInputContext(d->coreWindow.Get()));
#else
d->inputContext = Make<QWinRTInputContext>(d->coreWindow.Get());
#endif
Rect rect; Rect rect;
window->get_Bounds(&rect); d->coreWindow->get_Bounds(&rect);
m_geometry = QRectF(0, 0, rect.Width, rect.Height); d->geometry = QRectF(0, 0, rect.Width, rect.Height);
m_surfaceFormat.setAlphaBufferSize(0); d->surfaceFormat.setAlphaBufferSize(0);
m_surfaceFormat.setRedBufferSize(8); d->surfaceFormat.setRedBufferSize(8);
m_surfaceFormat.setGreenBufferSize(8); d->surfaceFormat.setGreenBufferSize(8);
m_surfaceFormat.setBlueBufferSize(8); d->surfaceFormat.setBlueBufferSize(8);
d->surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
d->surfaceFormat.setSamples(1);
d->surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
d->surfaceFormat.setDepthBufferSize(24);
d->surfaceFormat.setStencilBufferSize(8);
m_surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES); d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
m_surfaceFormat.setSamples(1); if (d->eglDisplay == EGL_NO_DISPLAY)
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."); qFatal("Qt WinRT platform plugin: failed to initialize EGL display.");
if (!eglInitialize(m_eglDisplay, NULL, NULL)) if (!eglInitialize(d->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."); 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 // TODO: move this to Window
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, q_configFromGLFormat(m_eglDisplay, m_surfaceFormat), window, NULL); d->eglSurface = eglCreateWindowSurface(d->eglDisplay, q_configFromGLFormat(d->eglDisplay, d->surfaceFormat), d->coreWindow.Get(), NULL);
if (m_eglSurface == EGL_NO_SURFACE) if (d->eglSurface == EGL_NO_SURFACE)
qFatal("Could not create EGL surface, error 0x%X", eglGetError()); qFatal("Could not create EGL surface, error 0x%X", eglGetError());
// Event handlers mapped to QEvents hr = d->coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]);
m_coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &m_tokens[QEvent::KeyPress]); Q_ASSERT_SUCCEEDED(hr);
m_coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &m_tokens[QEvent::KeyRelease]); hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]);
m_coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &m_tokens[QEvent::User]); Q_ASSERT_SUCCEEDED(hr);
m_coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &m_tokens[QEvent::Enter]); hr = d->coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]);
m_coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &m_tokens[QEvent::Leave]); Q_ASSERT_SUCCEEDED(hr);
m_coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseMove]); hr = d->coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]);
m_coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonPress]); Q_ASSERT_SUCCEEDED(hr);
m_coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonRelease]); hr = d->coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]);
m_coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::Wheel]); Q_ASSERT_SUCCEEDED(hr);
m_coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &m_tokens[QEvent::Resize]); 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 #ifdef Q_OS_WINPHONE
ComPtr<IHardwareButtonsStatics> hardwareButtons; hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), IID_PPV_ARGS(&d->hardwareButtons));
if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), &hardwareButtons))) Q_ASSERT_SUCCEEDED(hr);
hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTScreen::onBackButtonPressed).Get(), &m_tokens[QEvent::User]); hr = d->hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTScreen::onBackButtonPressed).Get(), &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]);
Q_ASSERT_SUCCEEDED(hr);
#endif // Q_OS_WINPHONE #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]);
// Orientation handling // Orientation handling
#if _MSC_VER<=1700 hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(),
HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), IID_PPV_ARGS(&d->displayInformationStatics));
&m_displayInformation); Q_ASSERT_SUCCEEDED(hr);
#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); hr = d->displayInformationStatics->GetForCurrentView(&d->displayInformation);
#endif Q_ASSERT_SUCCEEDED(hr);
if (FAILED(hr)) {
qErrnoWarning(hr, "Failed to get display information for the current view.");
return;
}
// Set native orientation // Set native orientation
DisplayOrientations displayOrientation; DisplayOrientations displayOrientation;
hr = m_displayInformation->get_NativeOrientation(&displayOrientation); hr = d->displayInformation->get_NativeOrientation(&displayOrientation);
if (FAILED(hr)) { Q_ASSERT_SUCCEEDED(hr);
qErrnoWarning(hr, "Failed to get native orientation."); d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
return;
}
m_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 = m_displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]);
&m_tokens[QEvent::OrientationChange]); Q_ASSERT_SUCCEEDED(hr);
if (FAILED(hr)) {
qErrnoWarning(hr, "Failed to add orientation change callback.");
return;
}
#if _MSC_VER<=1700
hr = m_displayInformation->add_LogicalDpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(),
&m_tokens[QEvent::Type(QEvent::User + 1)]);
#else
hr = m_displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(),
&m_tokens[QEvent::Type(QEvent::User + 1)]);
#endif
if (FAILED(hr)) {
qErrnoWarning(hr, "Failed to add logical dpi change callback.");
return;
}
// Set initial orientation & pixel density // Set initial orientation & pixel density
#if _MSC_VER<=1700
onOrientationChanged(Q_NULLPTR);
onDpiChanged(Q_NULLPTR);
#else
onOrientationChanged(Q_NULLPTR, Q_NULLPTR); onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
onDpiChanged(Q_NULLPTR, Q_NULLPTR); onDpiChanged(Q_NULLPTR, Q_NULLPTR);
#endif setOrientationUpdateMask(d->nativeOrientation);
setOrientationUpdateMask(m_nativeOrientation); }
if (SUCCEEDED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), QWinRTScreen::~QWinRTScreen()
IID_PPV_ARGS(&m_application)))) { {
m_application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTScreen::onSuspended).Get(), &m_suspendTokens[Qt::ApplicationSuspended]); Q_D(QWinRTScreen);
m_application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTScreen::onResume).Get(), &m_suspendTokens[Qt::ApplicationHidden]);
} // 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 QRect QWinRTScreen::geometry() const
{ {
return m_geometry.toRect(); Q_D(const QWinRTScreen);
return d->geometry.toRect();
} }
int QWinRTScreen::depth() const int QWinRTScreen::depth() const
{ {
return m_depth; return 32;
} }
QImage::Format QWinRTScreen::format() const QImage::Format QWinRTScreen::format() const
{ {
return m_format; return QImage::Format_ARGB32_Premultiplied;
} }
QSurfaceFormat QWinRTScreen::surfaceFormat() const QSurfaceFormat QWinRTScreen::surfaceFormat() const
{ {
return m_surfaceFormat; Q_D(const QWinRTScreen);
return d->surfaceFormat;
} }
QSizeF QWinRTScreen::physicalSize() const QSizeF QWinRTScreen::physicalSize() const
{ {
return m_geometry.size() / m_dpi * qreal(25.4); Q_D(const QWinRTScreen);
return d->geometry.size() / d->dpi * qreal(25.4);
} }
QDpi QWinRTScreen::logicalDpi() const QDpi QWinRTScreen::logicalDpi() const
{ {
return QDpi(m_dpi, m_dpi); Q_D(const QWinRTScreen);
return QDpi(d->dpi, d->dpi);
} }
qreal QWinRTScreen::devicePixelRatio() const qreal QWinRTScreen::devicePixelRatio() const
{ {
return m_devicePixelRatio; Q_D(const QWinRTScreen);
return d->devicePixelRatio;
} }
QWinRTInputContext *QWinRTScreen::inputContext() const 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 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 Qt::KeyboardModifiers QWinRTScreen::keyboardModifiers() const
{ {
Q_D(const QWinRTScreen);
Qt::KeyboardModifiers mods; Qt::KeyboardModifiers mods;
CoreVirtualKeyStates mod; CoreVirtualKeyStates mod;
m_coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod); d->coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod);
if (mod == CoreVirtualKeyStates_Down) if (mod == CoreVirtualKeyStates_Down)
mods |= Qt::ShiftModifier; mods |= Qt::ShiftModifier;
m_coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod); d->coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod);
if (mod == CoreVirtualKeyStates_Down) if (mod == CoreVirtualKeyStates_Down)
mods |= Qt::AltModifier; mods |= Qt::AltModifier;
m_coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod); d->coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod);
if (mod == CoreVirtualKeyStates_Down) if (mod == CoreVirtualKeyStates_Down)
mods |= Qt::ControlModifier; mods |= Qt::ControlModifier;
m_coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod); d->coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod);
if (mod == CoreVirtualKeyStates_Down) { if (mod == CoreVirtualKeyStates_Down) {
mods |= Qt::MetaModifier; mods |= Qt::MetaModifier;
} else { } else {
m_coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod); d->coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod);
if (mod == CoreVirtualKeyStates_Down) if (mod == CoreVirtualKeyStates_Down)
mods |= Qt::MetaModifier; mods |= Qt::MetaModifier;
} }
@ -620,56 +690,63 @@ Qt::KeyboardModifiers QWinRTScreen::keyboardModifiers() const
Qt::ScreenOrientation QWinRTScreen::nativeOrientation() const Qt::ScreenOrientation QWinRTScreen::nativeOrientation() const
{ {
return m_nativeOrientation; Q_D(const QWinRTScreen);
return d->nativeOrientation;
} }
Qt::ScreenOrientation QWinRTScreen::orientation() const Qt::ScreenOrientation QWinRTScreen::orientation() const
{ {
return m_orientation; Q_D(const QWinRTScreen);
return d->orientation;
} }
void QWinRTScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) void QWinRTScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
{ {
#if _MSC_VER<=1700 Q_D(QWinRTScreen);
m_displayInformation->put_AutoRotationPreferences(nativeOrientationsFromQt(mask));
#else HRESULT hr = d->displayInformationStatics->put_AutoRotationPreferences(nativeOrientationsFromQt(mask));
m_displayInformationFactory->put_AutoRotationPreferences(nativeOrientationsFromQt(mask)); RETURN_VOID_IF_FAILED("Failed to set display auto rotation preferences.");
#endif
} }
ICoreWindow *QWinRTScreen::coreWindow() const ICoreWindow *QWinRTScreen::coreWindow() const
{ {
return m_coreWindow; Q_D(const QWinRTScreen);
return d->coreWindow.Get();
} }
EGLDisplay QWinRTScreen::eglDisplay() const EGLDisplay QWinRTScreen::eglDisplay() const
{ {
return m_eglDisplay; Q_D(const QWinRTScreen);
return d->eglDisplay;
} }
EGLSurface QWinRTScreen::eglSurface() const EGLSurface QWinRTScreen::eglSurface() const
{ {
return m_eglSurface; Q_D(const QWinRTScreen);
return d->eglSurface;
} }
QWindow *QWinRTScreen::topWindow() const 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) void QWinRTScreen::addWindow(QWindow *window)
{ {
Q_D(QWinRTScreen);
if (window == topWindow()) if (window == topWindow())
return; return;
m_visibleWindows.prepend(window); d->visibleWindows.prepend(window);
QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
handleExpose(); handleExpose();
} }
void QWinRTScreen::removeWindow(QWindow *window) void QWinRTScreen::removeWindow(QWindow *window)
{ {
Q_D(QWinRTScreen);
const bool wasTopWindow = window == topWindow(); const bool wasTopWindow = window == topWindow();
if (!m_visibleWindows.removeAll(window)) if (!d->visibleWindows.removeAll(window))
return; return;
if (wasTopWindow) if (wasTopWindow)
QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
@ -678,17 +755,19 @@ void QWinRTScreen::removeWindow(QWindow *window)
void QWinRTScreen::raise(QWindow *window) void QWinRTScreen::raise(QWindow *window)
{ {
m_visibleWindows.removeAll(window); Q_D(QWinRTScreen);
d->visibleWindows.removeAll(window);
addWindow(window); addWindow(window);
} }
void QWinRTScreen::lower(QWindow *window) void QWinRTScreen::lower(QWindow *window)
{ {
Q_D(QWinRTScreen);
const bool wasTopWindow = window == topWindow(); const bool wasTopWindow = window == topWindow();
if (wasTopWindow && m_visibleWindows.size() == 1) if (wasTopWindow && d->visibleWindows.size() == 1)
return; return;
m_visibleWindows.removeAll(window); d->visibleWindows.removeAll(window);
m_visibleWindows.append(window); d->visibleWindows.append(window);
if (wasTopWindow) if (wasTopWindow)
QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
handleExpose(); handleExpose();
@ -696,18 +775,18 @@ void QWinRTScreen::lower(QWindow *window)
void QWinRTScreen::handleExpose() void QWinRTScreen::handleExpose()
{ {
if (m_visibleWindows.isEmpty()) Q_D(QWinRTScreen);
if (d->visibleWindows.isEmpty())
return; return;
QList<QWindow *>::const_iterator it = m_visibleWindows.constBegin(); QList<QWindow *>::const_iterator it = d->visibleWindows.constBegin();
QWindowSystemInterface::handleExposeEvent(*it, m_geometry.toRect()); QWindowSystemInterface::handleExposeEvent(*it, d->geometry.toRect());
while (++it != m_visibleWindows.constEnd()) while (++it != d->visibleWindows.constEnd())
QWindowSystemInterface::handleExposeEvent(*it, QRegion()); QWindowSystemInterface::handleExposeEvent(*it, QRegion());
QWindowSystemInterface::flushWindowSystemEvents(); 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; VirtualKey virtualKey;
args->get_VirtualKey(&virtualKey); args->get_VirtualKey(&virtualKey);
Qt::Key key = qKeyFromVirtual(virtualKey); Qt::Key key = qKeyFromVirtual(virtualKey);
@ -718,14 +797,14 @@ HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI
return S_OK; 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(); Qt::KeyboardModifiers mods = keyboardModifiers();
#ifndef Q_OS_WINPHONE #ifndef Q_OS_WINPHONE
Q_D(QWinRTScreen);
CorePhysicalKeyStatus status; // Look for a pressed character key CorePhysicalKeyStatus status; // Look for a pressed character key
if (SUCCEEDED(args->get_KeyStatus(&status)) && m_activeKeys.contains(status.ScanCode)) { if (SUCCEEDED(args->get_KeyStatus(&status)) && d->activeKeys.contains(status.ScanCode)) {
QPair<Qt::Key, QString> keyStatus = m_activeKeys.take(status.ScanCode); QPair<Qt::Key, QString> keyStatus = d->activeKeys.take(status.ScanCode);
QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease,
keyStatus.first, mods, keyStatus.second); keyStatus.first, mods, keyStatus.second);
return S_OK; return S_OK;
@ -738,10 +817,8 @@ HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::
return S_OK; return S_OK;
} }
HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceivedEventArgs *args) HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *, ICharacterReceivedEventArgs *args)
{ {
Q_UNUSED(window);
quint32 keyCode; quint32 keyCode;
args->get_KeyCode(&keyCode); args->get_KeyCode(&keyCode);
// Don't generate character events for non-printables; the meta key stage is enough // Don't generate character events for non-printables; the meta key stage is enough
@ -753,9 +830,10 @@ HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceive
QString text = QChar(keyCode); QString text = QChar(keyCode);
QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text); QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text);
#ifndef Q_OS_WINPHONE #ifndef Q_OS_WINPHONE
Q_D(QWinRTScreen);
CorePhysicalKeyStatus status; // Defer release to onKeyUp for physical keys CorePhysicalKeyStatus status; // Defer release to onKeyUp for physical keys
if (SUCCEEDED(args->get_KeyStatus(&status)) && !status.IsKeyReleased) { 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; return S_OK;
} }
#endif // !Q_OS_WINPHONE #endif // !Q_OS_WINPHONE
@ -763,10 +841,9 @@ HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceive
return S_OK; return S_OK;
} }
HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *window, IPointerEventArgs *args) HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
{ {
Q_UNUSED(window); ComPtr<IPointerPoint> pointerPoint;
IPointerPoint *pointerPoint;
if (SUCCEEDED(args->get_CurrentPoint(&pointerPoint))) { if (SUCCEEDED(args->get_CurrentPoint(&pointerPoint))) {
// Assumes full-screen window // Assumes full-screen window
Point point; Point point;
@ -774,24 +851,20 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *window, IPointerEventArgs *a
QPoint pos(point.X, point.Y); QPoint pos(point.X, point.Y);
QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos); QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos);
pointerPoint->Release();
} }
return S_OK; return S_OK;
} }
HRESULT QWinRTScreen::onPointerExited(ICoreWindow *window, IPointerEventArgs *args) HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *)
{ {
Q_UNUSED(window);
Q_UNUSED(args);
QWindowSystemInterface::handleLeaveEvent(0); QWindowSystemInterface::handleLeaveEvent(0);
return S_OK; return S_OK;
} }
HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *args) HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
{ {
Q_UNUSED(window); Q_D(QWinRTScreen);
ComPtr<IPointerPoint> pointerPoint;
IPointerPoint *pointerPoint;
if (FAILED(args->get_CurrentPoint(&pointerPoint))) if (FAILED(args->get_CurrentPoint(&pointerPoint)))
return E_INVALIDARG; return E_INVALIDARG;
@ -812,27 +885,18 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
if (modifiers & VirtualKeyModifiers_Windows) if (modifiers & VirtualKeyModifiers_Windows)
mods |= Qt::MetaModifier; mods |= Qt::MetaModifier;
IPointerPointProperties *properties; ComPtr<IPointerPointProperties> properties;
if (FAILED(pointerPoint->get_Properties(&properties))) if (FAILED(pointerPoint->get_Properties(&properties)))
return E_INVALIDARG; return E_INVALIDARG;
PointerDeviceType pointerDeviceType;
#if defined(Q_OS_WINPHONE) && _MSC_VER <= 1700
pointerDeviceType = PointerDeviceType_Touch;
#else
ComPtr<IPointerDevice> pointerDevice; ComPtr<IPointerDevice> pointerDevice;
HRESULT hr = pointerPoint->get_PointerDevice(&pointerDevice); HRESULT hr = pointerPoint->get_PointerDevice(&pointerDevice);
if (FAILED(hr)) { RETURN_OK_IF_FAILED("Failed to get pointer device.");
qErrnoWarning(hr, "Failed to get pointer device.");
return S_OK;
}
PointerDeviceType pointerDeviceType;
hr = pointerDevice->get_PointerDeviceType(&pointerDeviceType); hr = pointerDevice->get_PointerDeviceType(&pointerDeviceType);
if (FAILED(hr)) { RETURN_OK_IF_FAILED("Failed to get pointer device type.");
qErrnoWarning(hr, "Failed to get pointer device type.");
return S_OK;
}
#endif
switch (pointerDeviceType) { switch (pointerDeviceType) {
case PointerDeviceType_Mouse: { case PointerDeviceType_Mouse: {
qint32 delta; qint32 delta;
@ -872,12 +936,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
break; break;
} }
case PointerDeviceType_Touch: { case PointerDeviceType_Touch: {
if (!m_touchDevice) { if (!d->touchDevice) {
m_touchDevice = new QTouchDevice; d->touchDevice = new QTouchDevice;
m_touchDevice->setName(QStringLiteral("WinRTTouchScreen")); d->touchDevice->setName(QStringLiteral("WinRTTouchScreen"));
m_touchDevice->setType(QTouchDevice::TouchScreen); d->touchDevice->setType(QTouchDevice::TouchScreen);
m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition); d->touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition);
QWindowSystemInterface::registerTouchDevice(m_touchDevice); QWindowSystemInterface::registerTouchDevice(d->touchDevice);
} }
quint32 id; quint32 id;
@ -889,8 +953,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
float pressure; float pressure;
properties->get_Pressure(&pressure); properties->get_Pressure(&pressure);
QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = m_touchPoints.find(id); QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id);
if (it != m_touchPoints.end()) { if (it != d->touchPoints.end()) {
boolean isPressed; boolean isPressed;
#ifndef Q_OS_WINPHONE #ifndef Q_OS_WINPHONE
pointerPoint->get_IsInContact(&isPressed); pointerPoint->get_IsInContact(&isPressed);
@ -899,20 +963,20 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
#endif #endif
it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased; it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased;
} else { } else {
it = m_touchPoints.insert(id, QWindowSystemInterface::TouchPoint()); it = d->touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
it.value().state = Qt::TouchPointPressed; it.value().state = Qt::TouchPointPressed;
it.value().id = id; it.value().id = id;
} }
it.value().area = QRectF(area.X, area.Y, area.Width, area.Height); 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().normalPosition = QPointF(pos.x()/d->geometry.width(), pos.y()/d->geometry.height());
it.value().pressure = pressure; 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 // 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) if (i.value().state == Qt::TouchPointReleased)
i = m_touchPoints.erase(i); i = d->touchPoints.erase(i);
else else
(i++).value().state = Qt::TouchPointStationary; (i++).value().state = Qt::TouchPointStationary;
} }
@ -950,46 +1014,42 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
} }
} }
properties->Release();
pointerPoint->Release();
return S_OK; return S_OK;
} }
HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args) HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args)
{ {
Q_D(const QWinRTScreen);
#ifndef Q_OS_WINPHONE #ifndef Q_OS_WINPHONE
args->put_AutomationProvider(m_inputContext); args->put_AutomationProvider(d->inputContext.Get());
#else #else
Q_UNUSED(args) Q_UNUSED(args)
#endif #endif
return S_OK; return S_OK;
} }
HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *window, IWindowSizeChangedEventArgs *args) HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args)
{ {
Q_UNUSED(window); Q_D(QWinRTScreen);
Size size; Size size;
if (FAILED(args->get_Size(&size))) { HRESULT hr = args->get_Size(&size);
qWarning(Q_FUNC_INFO ": failed to get size"); RETURN_OK_IF_FAILED("Failed to get window size.");
return S_OK;
}
// Regardless of state, all top-level windows are viewport-sized - this might change if // Regardless of state, all top-level windows are viewport-sized - this might change if
// a more advanced compositor is written. // a more advanced compositor is written.
m_geometry.setSize(QSizeF(size.Width, size.Height)); d->geometry.setSize(QSizeF(size.Width, size.Height));
QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry.toRect()); QWindowSystemInterface::handleScreenGeometryChange(screen(), d->geometry.toRect());
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry.toRect()); QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), d->geometry.toRect());
QPlatformScreen::resizeMaximizedWindows(); QPlatformScreen::resizeMaximizedWindows();
handleExpose(); handleExpose();
return S_OK; return S_OK;
} }
HRESULT QWinRTScreen::onActivated(ICoreWindow *window, IWindowActivatedEventArgs *args) HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args)
{ {
Q_UNUSED(window); Q_D(QWinRTScreen);
CoreWindowActivationState activationState; CoreWindowActivationState activationState;
args->get_WindowActivationState(&activationState); args->get_WindowActivationState(&activationState);
@ -999,7 +1059,7 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *window, IWindowActivatedEventArgs
} }
// Activate topWindow // Activate topWindow
if (!m_visibleWindows.isEmpty()) { if (!d->visibleWindows.isEmpty()) {
Qt::FocusReason focusReason = activationState == CoreWindowActivationState_PointerActivated Qt::FocusReason focusReason = activationState == CoreWindowActivationState_PointerActivated
? Qt::MouseFocusReason : Qt::ActiveWindowFocusReason; ? Qt::MouseFocusReason : Qt::ActiveWindowFocusReason;
QWindowSystemInterface::handleWindowActivated(topWindow(), focusReason); QWindowSystemInterface::handleWindowActivated(topWindow(), focusReason);
@ -1022,21 +1082,15 @@ HRESULT QWinRTScreen::onResume(IInspectable *, IInspectable *)
return S_OK; 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()) foreach (QWindow *w, QGuiApplication::topLevelWindows())
QWindowSystemInterface::handleCloseEvent(w); QWindowSystemInterface::handleCloseEvent(w);
return S_OK; return S_OK;
} }
HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChangedEventArgs *args) HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEventArgs *args)
{ {
Q_UNUSED(window);
Q_UNUSED(args);
boolean visible; boolean visible;
args->get_Visible(&visible); args->get_Visible(&visible);
QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden); QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
@ -1045,60 +1099,48 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChange
return S_OK; return S_OK;
} }
#if _MSC_VER<=1700
HRESULT QWinRTScreen::onOrientationChanged(IInspectable *)
#else
HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *) HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *)
#endif
{ {
Q_D(QWinRTScreen);
DisplayOrientations displayOrientation; 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))); Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
if (m_orientation != newOrientation) { if (d->orientation != newOrientation) {
m_orientation = newOrientation; d->orientation = newOrientation;
QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation); QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
} }
return S_OK; return S_OK;
} }
#if _MSC_VER<=1700
HRESULT QWinRTScreen::onDpiChanged(IInspectable *)
#else
HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *) 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; ComPtr<IDisplayInformation2> displayInformation;
HRESULT hr = m_displayInformation->QueryInterface(IID_IDisplayInformation2, &displayInformation); hr = d->displayInformation.As(&displayInformation);
if (FAILED(hr)) { RETURN_OK_IF_FAILED("Failed to cast display information.");
qErrnoWarning(hr, "Failed to cast display information."); hr = displayInformation->get_RawPixelsPerViewPixel(&d->devicePixelRatio);
return S_OK;
}
hr = displayInformation->get_RawPixelsPerViewPixel(&m_devicePixelRatio);
#else #else
ResolutionScale resolutionScale; ResolutionScale resolutionScale;
HRESULT hr = m_displayInformation->get_ResolutionScale(&resolutionScale); hr = d->displayInformation->get_ResolutionScale(&resolutionScale);
#endif d->devicePixelRatio = qreal(resolutionScale) / 100;
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;
#endif #endif
RETURN_OK_IF_FAILED("Failed to get resolution scale");
// Correct the scale factor for integer window size // Correct the scale factor for integer window size
m_devicePixelRatio = m_devicePixelRatio * ((m_geometry.width()/qRound(m_geometry.width()) + d->devicePixelRatio = d->devicePixelRatio * ((d->geometry.width()/qRound(d->geometry.width()) +
m_geometry.height()/qRound(m_geometry.height())) / 2.0); d->geometry.height()/qRound(d->geometry.height())) / 2.0);
FLOAT dpi; FLOAT dpi;
hr = m_displayInformation->get_LogicalDpi(&dpi); hr = d->displayInformation->get_LogicalDpi(&dpi);
if (FAILED(hr)) { RETURN_OK_IF_FAILED("Failed to get logical DPI.");
qErrnoWarning(hr, "Failed to get logical DPI."); d->dpi = dpi;
return S_OK;
}
m_dpi = dpi;
return S_OK; return S_OK;
} }
@ -1106,14 +1148,16 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
#ifdef Q_OS_WINPHONE #ifdef Q_OS_WINPHONE
HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args) HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
{ {
Q_D(QWinRTScreen);
QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier); QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier); QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
backPress.setAccepted(false); backPress.setAccepted(false);
backRelease.setAccepted(false); backRelease.setAccepted(false);
QObject *receiver = m_visibleWindows.isEmpty() QObject *receiver = d->visibleWindows.isEmpty()
? static_cast<QObject *>(QGuiApplication::instance()) ? 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 // If the event is ignored, the app will suspend
QGuiApplication::sendEvent(receiver, &backPress); QGuiApplication::sendEvent(receiver, &backPress);

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the plugins of the Qt Toolkit. ** This file is part of the plugins of the Qt Toolkit.
@ -45,19 +45,12 @@
#include <qpa/qplatformscreen.h> #include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface.h>
#include <QtCore/QHash>
#include <QtGui/QSurfaceFormat>
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EventToken.h>
namespace ABI { namespace ABI {
namespace Windows { namespace Windows {
namespace ApplicationModel { namespace ApplicationModel {
struct ISuspendingEventArgs; struct ISuspendingEventArgs;
namespace Core {
struct ICoreApplication;
}
} }
namespace UI { namespace UI {
namespace Core { namespace Core {
@ -71,14 +64,9 @@ namespace ABI {
struct IWindowActivatedEventArgs; struct IWindowActivatedEventArgs;
struct IWindowSizeChangedEventArgs; struct IWindowSizeChangedEventArgs;
} }
namespace ViewManagement {
struct IApplicationViewStatics;
}
} }
namespace Graphics { namespace Graphics {
namespace Display { namespace Display {
struct IDisplayPropertiesStatics;
struct IDisplayInformationStatics;
struct IDisplayInformation; struct IDisplayInformation;
} }
} }
@ -99,14 +87,14 @@ QT_BEGIN_NAMESPACE
class QTouchDevice; class QTouchDevice;
class QWinRTEGLContext; class QWinRTEGLContext;
class QWinRTPageFlipper;
class QWinRTCursor; class QWinRTCursor;
class QWinRTInputContext; class QWinRTInputContext;
class QWinRTScreenPrivate;
class QWinRTScreen : public QPlatformScreen class QWinRTScreen : public QPlatformScreen
{ {
public: public:
explicit QWinRTScreen(ABI::Windows::UI::Core::ICoreWindow *window); explicit QWinRTScreen();
~QWinRTScreen();
QRect geometry() const; QRect geometry() const;
int depth() const; int depth() const;
QImage::Format format() const; QImage::Format format() const;
@ -135,69 +123,31 @@ public:
private: private:
void handleExpose(); void handleExpose();
// Event handlers HRESULT onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *);
QHash<QEvent::Type, EventRegistrationToken> m_tokens; HRESULT onKeyUp(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *);
QHash<Qt::ApplicationState, EventRegistrationToken> m_suspendTokens; 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 onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *);
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 onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *); HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
HRESULT onResume(IInspectable *, IInspectable *); HRESULT onResume(IInspectable *, IInspectable *);
HRESULT onClosed(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICoreWindowEventArgs *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 *args); HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *);
HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *args); 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 onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
#endif
#ifdef Q_OS_WINPHONE #ifdef Q_OS_WINPHONE
HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args); HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
#endif #endif
ABI::Windows::UI::Core::ICoreWindow *m_coreWindow; QScopedPointer<QWinRTScreenPrivate> d_ptr;
ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView; Q_DECLARE_PRIVATE(QWinRTScreen)
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;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE