/**************************************************************************** ** ** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module 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 "qinputaspect.h" #include "qinputaspect_p.h" #include "inputhandler_p.h" #include "keyboardcontroller_p.h" #include "keyboardinput_p.h" #include "mousecontroller_p.h" #include "mouseinput_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE using namespace Qt3DCore; namespace Qt3DInput { /*! \class Qt3DInput::QInputAspectPrivate \internal */ QInputAspectPrivate::QInputAspectPrivate() : QAbstractAspectPrivate() , m_inputHandler(new Input::InputHandler()) , m_keyboardMouseIntegration(new Input::KeyboardMouseGenericDeviceIntegration(m_inputHandler.data())) { } /*! \class Qt3DInput::QInputAspect \inmodule Qt3DInput \since 5.5 */ QInputAspect::QInputAspect(QObject *parent) : QAbstractAspect(*new QInputAspectPrivate, parent) { registerBackendType(QBackendNodeFunctorPtr(new Input::KeyboardControllerFunctor(this, d_func()->m_inputHandler.data()))); registerBackendType(QBackendNodeFunctorPtr(new Input::KeyboardInputFunctor(d_func()->m_inputHandler.data()))); registerBackendType(QBackendNodeFunctorPtr(new Input::MouseControllerFunctor(this, d_func()->m_inputHandler.data()))); registerBackendType(QBackendNodeFunctorPtr(new Input::MouseInputFunctor(d_func()->m_inputHandler.data()))); registerBackendType(QBackendNodeFunctorPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->axisManager()))); registerBackendType(QBackendNodeFunctorPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->axisInputManager()))); registerBackendType(QBackendNodeFunctorPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->axisSettingManager()))); registerBackendType(QBackendNodeFunctorPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->actionManager()))); registerBackendType(QBackendNodeFunctorPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->actionInputManager()))); registerBackendType(QBackendNodeFunctorPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->inputChordManager()))); registerBackendType(QBackendNodeFunctorPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->inputSequenceManager()))); registerBackendType(QBackendNodeFunctorPtr(new Input::AxisActionHandlerNodeFunctor(d_func()->m_inputHandler->axisActionHandlerManager()))); registerBackendType(QBackendNodeFunctorPtr(new Input::LogicalDeviceNodeFunctor(d_func()->m_inputHandler->logicalDeviceManager()))); registerBackendType(QBackendNodeFunctorPtr(new Input::GenericDeviceBackendFunctor(this, d_func()->m_inputHandler.data()))); registerBackendType(QBackendNodeFunctorPtr(new Input::InputSettingsFunctor(d_func()->m_inputHandler.data()))); // Plugins are QInputDeviceIntegration instances loadInputDevicePlugins(); // KeyboardController and MouseController also provide their own QInputDeviceIntegration Q_D(QInputAspect); d->m_inputHandler->addInputDeviceIntegration(d->m_keyboardMouseIntegration.data()); } void QInputAspect::loadInputDevicePlugins() { Q_D(QInputAspect); QStringList keys = QInputDeviceIntegrationFactory::keys(); Q_FOREACH (QString key, keys) { Qt3DInput::QInputDeviceIntegration *integration = QInputDeviceIntegrationFactory::create(key, QStringList()); if (integration != Q_NULLPTR) { d->m_inputHandler->addInputDeviceIntegration(integration); // Initialize will allow the InputDeviceIntegration to // register their frontend / backend types, // create their managers // launch a thread to listen to the actual physical device.... integration->initialize(this); } } } // Note: caller is responsible for ownership QAbstractPhysicalDevice *QInputAspect::createPhysicalDevice(const QString &name) { Q_D(QInputAspect); QAbstractPhysicalDevice *device = Q_NULLPTR; Q_FOREACH (Qt3DInput::QInputDeviceIntegration *integration, d->m_inputHandler->inputDeviceIntegrations()) { if ((device = integration->createPhysicalDevice(name)) != Q_NULLPTR) break; } return device; } QVector QInputAspect::jobsToExecute(qint64 time) { Q_UNUSED(time); Q_D(QInputAspect); QVector jobs; d->m_inputHandler->updateEventSource(); jobs.append(d->m_inputHandler->keyboardJobs()); jobs.append(d->m_inputHandler->mouseJobs()); Q_FOREACH (QInputDeviceIntegration *integration, d->m_inputHandler->inputDeviceIntegrations()) jobs += integration->jobsToExecute(time); // Jobs that update Axis/Action (store combined axis/action value) QHash logicalDeviceJobs; Q_FOREACH (Input::HLogicalDevice devHandle, d->m_inputHandler->logicalDeviceManager()->activeDevices()) { QAspectJobPtr updateAxisActionJob(new Input::UpdateAxisActionJob(time, d->m_inputHandler.data(), devHandle)); logicalDeviceJobs.insert(devHandle, updateAxisActionJob); Q_FOREACH (const QAspectJobPtr job, jobs) updateAxisActionJob->addDependency(job); } // Jobs that update the axisactionhandlers Q_FOREACH (Input::HAxisActionHandler handlerHandle, d->m_inputHandler->axisActionHandlerManager()->activeAxisActionHandlers()) { Input::AxisActionHandler *axisActionHandler = d->m_inputHandler->axisActionHandlerManager()->data(handlerHandle); Input::HLogicalDevice logicalDeviceHandle = d->m_inputHandler->logicalDeviceManager()->lookupHandle(axisActionHandler->logicalDevice()); QAspectJobPtr updateHandlerJob(new Input::UpdateHandlerJob(axisActionHandler, logicalDeviceHandle, d->m_inputHandler.data())); // Create AxisActionHandler Job jobs += updateHandlerJob; QAspectJobPtr logicalDeviceJob = logicalDeviceJobs.value(logicalDeviceHandle); if (logicalDeviceJob) { updateHandlerJob->addDependency(logicalDeviceJob); jobs += logicalDeviceJob; } } return jobs; } // Called in the aspectThread void QInputAspect::onInitialize() { Q_D(QInputAspect); Qt3DCore::QEventFilterService *eventService = d->services()->eventFilterService(); Q_ASSERT(eventService); // Set it on the input handler which will also handle its lifetime d->m_inputHandler->eventSourceHelper()->setEventFilterService(eventService); } void QInputAspect::onCleanup() { Q_D(QInputAspect); // At this point it is too late to call removeEventFilter as the eventSource (Window) // may already be destroyed d->m_inputHandler.reset(Q_NULLPTR); } } // namespace Qt3DInput QT_END_NAMESPACE QT3D_REGISTER_NAMESPACED_ASPECT("input", QT_PREPEND_NAMESPACE(Qt3DInput), QInputAspect)