diff options
Diffstat (limited to 'src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp')
-rw-r--r-- | src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp | 404 |
1 files changed, 0 insertions, 404 deletions
diff --git a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp deleted file mode 100644 index 59aa91b03..000000000 --- a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwinrtvideodeviceselectorcontrol.h" - -#include <QtCore/qfunctions_winrt.h> -#include <QtCore/QVector> -#include <QtCore/QCoreApplication> -#include <QtCore/QEventLoop> -#include <QtCore/QGlobalStatic> - -#include <wrl.h> -#include <windows.devices.enumeration.h> - -using namespace ABI::Windows::Devices::Enumeration; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Foundation::Collections; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; - -typedef ITypedEventHandler<DeviceWatcher *, DeviceInformation *> DeviceInformationHandler; -typedef ITypedEventHandler<DeviceWatcher *, DeviceInformationUpdate *> DeviceInformationUpdateHandler; -typedef ITypedEventHandler<DeviceWatcher *, IInspectable *> DeviceEnumerationCompletedHandler; - -QT_BEGIN_NAMESPACE - -static QString deviceName(IDeviceInformation *device) -{ - HRESULT hr; - HString id; - hr = device->get_Id(id.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - quint32 length; - const wchar_t *buffer = id.GetRawBuffer(&length); - return QString::fromWCharArray(buffer, int(length)); -} - -static QString deviceDescription(IDeviceInformation *device) -{ - HRESULT hr; - HString name; - hr = device->get_Name(name.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - quint32 length; - const wchar_t *buffer = name.GetRawBuffer(&length); - return QString::fromWCharArray(buffer, int(length)); -} - -struct QWinRTVideoDeviceSelectorControlGlobal -{ - QWinRTVideoDeviceSelectorControlGlobal() - : defaultDeviceIndex(-1) - { - HRESULT hr; - ComPtr<IDeviceInformationStatics> deviceWatcherFactory; - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(), - IID_PPV_ARGS(&deviceWatcherFactory)); - Q_ASSERT_SUCCEEDED(hr); - hr = deviceWatcherFactory->CreateWatcherDeviceClass(DeviceClass_VideoCapture, &deviceWatcher); - Q_ASSERT_SUCCEEDED(hr); - - hr = deviceWatcher->add_Added( - Callback<DeviceInformationHandler>(this, &QWinRTVideoDeviceSelectorControlGlobal::onDeviceAdded).Get(), - &deviceAddedToken); - Q_ASSERT_SUCCEEDED(hr); - - hr = deviceWatcher->add_Removed( - Callback<DeviceInformationUpdateHandler>(this, &QWinRTVideoDeviceSelectorControlGlobal::onDeviceRemoved).Get(), - &deviceRemovedToken); - Q_ASSERT_SUCCEEDED(hr); - - hr = deviceWatcher->add_Updated( - Callback<DeviceInformationUpdateHandler>(this, &QWinRTVideoDeviceSelectorControlGlobal::onDeviceUpdated).Get(), - &deviceUpdatedToken); - Q_ASSERT_SUCCEEDED(hr); - - // Synchronously populate the devices on construction - ComPtr<IAsyncOperation<DeviceInformationCollection *>> op; - hr = deviceWatcherFactory->FindAllAsyncDeviceClass(DeviceClass_VideoCapture, &op); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IVectorView<DeviceInformation *>> deviceList; - hr = QWinRTFunctions::await(op, deviceList.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - quint32 deviceCount; - hr = deviceList->get_Size(&deviceCount); - Q_ASSERT_SUCCEEDED(hr); - for (quint32 i = 0; i < deviceCount; ++i) { - IDeviceInformation *device; - hr = deviceList->GetAt(i, &device); - Q_ASSERT_SUCCEEDED(hr); - onDeviceAdded(nullptr, device); - } - - // If there is no default device provided by the API, choose the first one - if (!devices.isEmpty() && defaultDeviceIndex < 0) - defaultDeviceIndex = 0; - } - - ~QWinRTVideoDeviceSelectorControlGlobal() - { - HRESULT hr; - hr = deviceWatcher->remove_Added(deviceAddedToken); - Q_ASSERT_SUCCEEDED(hr); - hr = deviceWatcher->remove_Removed(deviceRemovedToken); - Q_ASSERT_SUCCEEDED(hr); - hr = deviceWatcher->remove_Updated(deviceUpdatedToken); - Q_ASSERT_SUCCEEDED(hr); - } - -private: - HRESULT onDeviceAdded(IDeviceWatcher *, IDeviceInformation *device) - { - const QString name = deviceName(device); - if (deviceIndex.contains(name)) - return S_OK; - - devices.append(device); - const int index = devices.size() - 1; - deviceIndex.insert(name, index); - - HRESULT hr; - boolean isDefault; - hr = device->get_IsDefault(&isDefault); - Q_ASSERT_SUCCEEDED(hr); - if (isDefault) - defaultDeviceIndex = index; - - for (QWinRTVideoDeviceSelectorControl *watcher : qAsConst(watchers)) - emit watcher->devicesChanged(); - - return S_OK; - } - - HRESULT onDeviceRemoved(IDeviceWatcher *, IDeviceInformationUpdate *device) - { - HRESULT hr; - HString id; - hr = device->get_Id(id.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - - HString name; - hr = device->get_Id(name.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - quint32 nameLength; - const wchar_t *nameString = name.GetRawBuffer(&nameLength); - const int index = deviceIndex.take(QString::fromWCharArray(nameString, int(nameLength))); - if (index >= 0) - devices.remove(index); - - for (QWinRTVideoDeviceSelectorControl *watcher : qAsConst(watchers)) - emit watcher->devicesChanged(); - - return S_OK; - } - - HRESULT onDeviceUpdated(IDeviceWatcher *, IDeviceInformationUpdate *) - { - // A name or description may have changed, so emit devicesChanged - for (QWinRTVideoDeviceSelectorControl *watcher : qAsConst(watchers)) - emit watcher->devicesChanged(); - - return S_OK; - } - -public: - void addWatcher(QWinRTVideoDeviceSelectorControl *control) - { - watchers.append(control); - - HRESULT hr; - DeviceWatcherStatus status; - hr = deviceWatcher->get_Status(&status); - Q_ASSERT_SUCCEEDED(hr); - if (status != DeviceWatcherStatus_Started && - status != DeviceWatcherStatus_EnumerationCompleted) { - // We can't immediately Start() if we have just called Stop() - while (status == DeviceWatcherStatus_Stopping) { - QThread::yieldCurrentThread(); - hr = deviceWatcher->get_Status(&status); - Q_ASSERT_SUCCEEDED(hr); - } - hr = deviceWatcher->Start(); - Q_ASSERT_SUCCEEDED(hr); - } - } - - void removeWatcher(QWinRTVideoDeviceSelectorControl *control) - { - watchers.removeAll(control); - - if (!watchers.isEmpty()) - return; - - HRESULT hr; - DeviceWatcherStatus status; - hr = deviceWatcher->get_Status(&status); - Q_ASSERT_SUCCEEDED(hr); - if (status == DeviceWatcherStatus_Stopped || status == DeviceWatcherStatus_Stopping) - return; - - hr = deviceWatcher->Stop(); - Q_ASSERT_SUCCEEDED(hr); - } - - QVector<ComPtr<IDeviceInformation>> devices; - QHash<QString, int> deviceIndex; - int defaultDeviceIndex; - -private: - ComPtr<IDeviceWatcher> deviceWatcher; - QList<QWinRTVideoDeviceSelectorControl *> watchers; - EventRegistrationToken deviceAddedToken; - EventRegistrationToken deviceRemovedToken; - EventRegistrationToken deviceUpdatedToken; -}; -Q_GLOBAL_STATIC(QWinRTVideoDeviceSelectorControlGlobal, g) - -static ComPtr<IEnclosureLocation> enclosureLocation(const QString &deviceName) -{ - ComPtr<IEnclosureLocation> enclosureLocation; - int deviceIndex = g->deviceIndex.value(deviceName); - IDeviceInformation *deviceInfo = g->devices.value(deviceIndex).Get(); - if (!deviceInfo) - return enclosureLocation; - - HRESULT hr; - hr = deviceInfo->get_EnclosureLocation(&enclosureLocation); - if (FAILED(hr)) - qErrnoWarning(hr, "Failed to get camera enclosure location"); - - return enclosureLocation; -} - -class QWinRTVideoDeviceSelectorControlPrivate -{ -public: - int selectedDevice; -}; - -QWinRTVideoDeviceSelectorControl::QWinRTVideoDeviceSelectorControl(QObject *parent) - : QVideoDeviceSelectorControl(parent), d_ptr(new QWinRTVideoDeviceSelectorControlPrivate) -{ - Q_D(QWinRTVideoDeviceSelectorControl); - d->selectedDevice = -1; - g->addWatcher(this); -} - -QWinRTVideoDeviceSelectorControl::~QWinRTVideoDeviceSelectorControl() -{ - if (g.isDestroyed()) - return; - - g->removeWatcher(this); -} - -int QWinRTVideoDeviceSelectorControl::deviceCount() const -{ - return g->devices.size(); -} - -QString QWinRTVideoDeviceSelectorControl::deviceName(int index) const -{ - if (index < 0 || index >= g->devices.size()) - return QString(); - - return ::deviceName(g->devices.at(index).Get()); -} - -QString QWinRTVideoDeviceSelectorControl::deviceDescription(int index) const -{ - if (index < 0 || index >= g->devices.size()) - return QString(); - - return ::deviceDescription(g->devices.at(index).Get()); -} - -int QWinRTVideoDeviceSelectorControl::defaultDevice() const -{ - return g->defaultDeviceIndex; -} - -int QWinRTVideoDeviceSelectorControl::selectedDevice() const -{ - Q_D(const QWinRTVideoDeviceSelectorControl); - return d->selectedDevice; -} - -QCamera::Position QWinRTVideoDeviceSelectorControl::cameraPosition(const QString &deviceName) -{ - ComPtr<IEnclosureLocation> enclosure = enclosureLocation(deviceName); - if (!enclosure) - return QCamera::UnspecifiedPosition; - - HRESULT hr; - Panel panel; - hr = enclosure->get_Panel(&panel); - RETURN_IF_FAILED("Failed to get camera panel location", return QCamera::UnspecifiedPosition); - - switch (panel) { - case Panel_Front: - return QCamera::FrontFace; - case Panel_Back: - return QCamera::BackFace; - default: - break; - } - return QCamera::UnspecifiedPosition; -} - -int QWinRTVideoDeviceSelectorControl::cameraOrientation(const QString &deviceName) -{ - ComPtr<IEnclosureLocation> enclosure = enclosureLocation(deviceName); - if (!enclosure) - return 0; - - HRESULT hr; - ComPtr<IEnclosureLocation2> enclosure2; - hr = enclosure.As(&enclosure2); - RETURN_IF_FAILED("Failed to cast camera enclosure location", return 0); - quint32 rotation; - hr = enclosure2->get_RotationAngleInDegreesClockwise(&rotation); - RETURN_IF_FAILED("Failed to get camera rotation angle", return 0); - return int(rotation); -} - -QList<QByteArray> QWinRTVideoDeviceSelectorControl::deviceNames() -{ - QList<QByteArray> devices; - devices.reserve(g->deviceIndex.size()); - for (auto it = g->deviceIndex.keyBegin(), end = g->deviceIndex.keyEnd(); it != end; ++it) - devices.append((*it).toUtf8()); - - return devices; -} - -QByteArray QWinRTVideoDeviceSelectorControl::deviceDescription(const QByteArray &deviceName) -{ - int deviceIndex = g->deviceIndex.value(QString::fromUtf8(deviceName), -1); - if (deviceIndex < 0) - return QByteArray(); - - return ::deviceDescription(g->devices.value(deviceIndex).Get()).toUtf8(); -} - -QByteArray QWinRTVideoDeviceSelectorControl::defaultDeviceName() -{ - if (g->defaultDeviceIndex < 0) - return QByteArray(); - - return ::deviceName(g->devices.value(g->defaultDeviceIndex).Get()).toUtf8(); -} - -void QWinRTVideoDeviceSelectorControl::setSelectedDevice(int index) -{ - Q_D(QWinRTVideoDeviceSelectorControl); - - int selectedDevice = index; - if (index < 0 || index >= g->devices.size()) - selectedDevice = -1; - - if (d->selectedDevice != selectedDevice) { - d->selectedDevice = selectedDevice; - emit selectedDeviceChanged(d->selectedDevice); - emit selectedDeviceChanged(deviceName(d->selectedDevice)); - } -} - -QT_END_NAMESPACE |