From 2ca20724dd17df96143be160505f982ab6cf4378 Mon Sep 17 00:00:00 2001 From: Samuel Nevala Date: Tue, 17 Nov 2015 07:52:28 +0200 Subject: WinRT: Add camera button events on Windows Phone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows Phone 8.1 provides access to the camera button and press/release events get passed as Key_CameraFocus and Key_Camera. Unfortunately a release does not provide what has been pressed before, hence this information needs to be cached when the press happens. Done-with: Maurice Kalinowski Task-number: QTBUG-39115 Change-Id: I6ce58a1f07a6bf7183b8d99a26e5cd7b0d32d6db Reviewed-by: Topi Reiniƶ Reviewed-by: Samuel Nevala Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtintegration.cpp | 64 +++++++++++++++++++++++ src/plugins/platforms/winrt/qwinrtintegration.h | 4 ++ 2 files changed, 68 insertions(+) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 9db5df995a..e94a0aa846 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -79,6 +79,7 @@ typedef IEventHandler ResumeHandler; typedef IEventHandler SuspendHandler; #ifdef Q_OS_WINPHONE typedef IEventHandler BackPressedHandler; +typedef IEventHandler CameraButtonHandler; #endif QT_BEGIN_NAMESPACE @@ -88,6 +89,8 @@ uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); r #ifdef Q_OS_WINPHONE typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken); uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } +typedef HRESULT (__stdcall IHardwareButtonsStatics2::*HardwareButtons2CallbackRemover)(EventRegistrationToken); +uint qHash(HardwareButtons2CallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } #endif class QWinRTIntegrationPrivate @@ -103,6 +106,10 @@ public: #ifdef Q_OS_WINPHONE ComPtr hardwareButtons; QHash buttonsTokens; + ComPtr cameraButtons; + QHash cameraTokens; + bool cameraHalfPressed : 1; + bool cameraPressed : 1; #endif }; @@ -130,6 +137,23 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) hr = d->hardwareButtons->add_BackPressed(Callback(this, &QWinRTIntegration::onBackButtonPressed).Get(), &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]); Q_ASSERT_SUCCEEDED(hr); + + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), + IID_PPV_ARGS(&d->cameraButtons)); + Q_ASSERT_SUCCEEDED(hr); + if (qEnvironmentVariableIntValue("QT_QPA_ENABLE_CAMERA_KEYS")) { + hr = d->cameraButtons->add_CameraPressed(Callback(this, &QWinRTIntegration::onCameraPressed).Get(), + &d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraPressed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->cameraButtons->add_CameraHalfPressed(Callback(this, &QWinRTIntegration::onCameraHalfPressed).Get(), + &d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraHalfPressed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->cameraButtons->add_CameraReleased(Callback(this, &QWinRTIntegration::onCameraReleased).Get(), + &d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraReleased]); + Q_ASSERT_SUCCEEDED(hr); + } + d->cameraPressed = false; + d->cameraHalfPressed = false; #endif // Q_OS_WINPHONE QEventDispatcherWinRT::runOnXamlThread([d]() { @@ -151,6 +175,10 @@ QWinRTIntegration::~QWinRTIntegration() hr = (d->hardwareButtons.Get()->*i.key())(i.value()); Q_ASSERT_SUCCEEDED(hr); } + for (QHash::const_iterator i = d->cameraTokens.begin(); i != d->cameraTokens.end(); ++i) { + hr = (d->cameraButtons.Get()->*i.key())(i.value()); + Q_ASSERT_SUCCEEDED(hr); + } #endif for (QHash::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i) { hr = (d->application.Get()->*i.key())(i.value()); @@ -268,6 +296,42 @@ HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEvent args->put_Handled(pressed || released); return S_OK; } + +HRESULT QWinRTIntegration::onCameraPressed(IInspectable *, ICameraEventArgs *) +{ + Q_D(QWinRTIntegration); + QWindow *window = d->mainScreen->topWindow(); + QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_Camera, Qt::NoModifier, + 0, 0, 0, QString(), false, 1, false); + d->cameraPressed = true; + return S_OK; +} + +HRESULT QWinRTIntegration::onCameraHalfPressed(IInspectable *, ICameraEventArgs *) +{ + Q_D(QWinRTIntegration); + QWindow *window = d->mainScreen->topWindow(); + QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_CameraFocus, Qt::NoModifier, + 0, 0, 0, QString(), false, 1, false); + d->cameraHalfPressed = true; + return S_OK; +} + +HRESULT QWinRTIntegration::onCameraReleased(IInspectable *, ICameraEventArgs *) +{ + Q_D(QWinRTIntegration); + QWindow *window = d->mainScreen->topWindow(); + if (d->cameraHalfPressed) + QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_CameraFocus, Qt::NoModifier, + 0, 0, 0, QString(), false, 1, false); + + if (d->cameraPressed) + QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_Camera, Qt::NoModifier, + 0, 0, 0, QString(), false, 1, false); + d->cameraHalfPressed = false; + d->cameraPressed = false; + return S_OK; +} #endif // Q_OS_WINPHONE HRESULT QWinRTIntegration::onSuspended(IInspectable *, ISuspendingEventArgs *) diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h index 3a151e1ed8..5456f6922f 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.h +++ b/src/plugins/platforms/winrt/qwinrtintegration.h @@ -52,6 +52,7 @@ namespace ABI { namespace UI { namespace Input { struct IBackPressedEventArgs; + struct ICameraEventArgs; } } } @@ -100,6 +101,9 @@ public: private: #ifdef Q_OS_WINPHONE HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args); + HRESULT onCameraPressed(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *); + HRESULT onCameraHalfPressed(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *); + HRESULT onCameraReleased(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *); #endif HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *); HRESULT onResume(IInspectable *, IInspectable *); -- cgit v1.2.3