From 50e8da22c6680d6b4dd060d60eb1e016993e959d Mon Sep 17 00:00:00 2001 From: Christian Dywan Date: Mon, 17 Jun 2013 10:53:23 +0200 Subject: [PATCH 1/2] Implement command line-based MIR feedback plugin diff --git a/src/plugins/feedback/feedback.pro b/src/plugins/feedback/feedback.pro index 4c04e0a..2028353 100644 --- a/src/plugins/feedback/feedback.pro +++ b/src/plugins/feedback/feedback.pro @@ -1,5 +1,10 @@ TEMPLATE = subdirs +contains(mir_enabled, yes) { + message("Building with Mir support") + SUBDIRS += mir +} + contains(immersion_enabled, yes) { message("Building with Immersion TouchSense support") SUBDIRS += immersion diff --git a/src/plugins/feedback/mir/mir.json b/src/plugins/feedback/mir/mir.json new file mode 100644 index 0000000..3f32701 --- /dev/null +++ b/src/plugins/feedback/mir/mir.json @@ -0,0 +1 @@ +{ "Interfaces": [ "QFeedbackHapticsInterface", "QFeedbackFileInterface" ] } diff --git a/src/plugins/feedback/mir/mir.pro b/src/plugins/feedback/mir/mir.pro new file mode 100644 index 0000000..70589eb --- /dev/null +++ b/src/plugins/feedback/mir/mir.pro @@ -0,0 +1,9 @@ +TARGET = qtfeedback_mir +QT = core feedback + +PLUGIN_TYPE = feedback +load(qt_plugin) + +HEADERS += qfeedback.h +SOURCES += qfeedback.cpp + diff --git a/src/plugins/feedback/mir/qfeedback.cpp b/src/plugins/feedback/mir/qfeedback.cpp new file mode 100644 index 0000000..097fdd9 --- /dev/null +++ b/src/plugins/feedback/mir/qfeedback.cpp @@ -0,0 +1,257 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtFeedback 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 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 +#include "qfeedback.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QFeedbackImmersion::QFeedbackImmersion() : QObject(qApp), + QFeedbackThemeInterface() +{ + if (false) { + // one-time initialization; currently not required + qWarning() << "initialization failed"; + } else { + const int nbDev = 1; + for (int i = 0; i < nbDev; ++i) { + actuatorList << createFeedbackActuator(this, i); + } + } +} + +QFeedbackImmersion::~QFeedbackImmersion() +{ + // Close device handles + const int nbDev = 1; + for (int i = 0 ; i < nbDev; ++i) + /* close device */; + + // Done +} + +QFeedbackInterface::PluginPriority QFeedbackImmersion::pluginPriority() +{ + return PluginNormalPriority; +} + +QList QFeedbackImmersion::actuators() +{ + return actuatorList; +} + +void QFeedbackImmersion::setActuatorProperty(const QFeedbackActuator &actuator, ActuatorProperty prop, const QVariant &value) +{ + switch (prop) + { + case Enabled: + qWarning() << "mir fp enabled"; + break; + default: + break; + } +} + +QVariant QFeedbackImmersion::actuatorProperty(const QFeedbackActuator &actuator, ActuatorProperty prop) +{ + switch (prop) + { + case Name: + { + if (false /* actuator.id()*/) + return QString(); + + return QString::fromLocal8Bit("Command line vibrator"); + } + + case State: + { + QFeedbackActuator::State ret = QFeedbackActuator::Unknown; + if (actuator.isValid() && true /* actuator.id() */) { + ret = QFeedbackActuator::Ready; + // ret = QFeedbackActuator:: Busy; + } + + return ret; + } + case Enabled: + { + // no global vibration policy, always enabled + return true; + } + default: + return QVariant(); + } +} + +bool QFeedbackImmersion::isActuatorCapabilitySupported(const QFeedbackActuator &, QFeedbackActuator::Capability cap) +{ + switch(cap) + { + case QFeedbackActuator::Envelope: + case QFeedbackActuator::Period: + return true; + default: + return false; + } +} + +void QFeedbackImmersion::updateEffectProperty(const QFeedbackHapticsEffect *effect, EffectProperty) +{ + if (effect->period() > 0) { + /* + periodic effect + effect->duration(), // QFeedbackEffect::Infinite means infinite + effect->intensity(), + effect->period(), + effect->attackTime(), + effect->attackIntensity(), + effect->fadeTime(), + effect->fadeIntensity() + */ + } else { + /* one-off */ + } + + if (false) + reportError(effect, QFeedbackEffect::UnknownError); + +} + +void QFeedbackImmersion::vibrateOnce(const QFeedbackEffect* effect) +{ + qWarning() << "vibrateOnce" << effect; + QProcess gzip; + gzip.setStandardOutputFile("/sys/class/timed_output/vibrator/enable"); + gzip.start("echo", QStringList() << "150"); + if (!gzip.waitForStarted()) + qWarning("!started"); + + if (!gzip.waitForFinished()) + qWarning("!finished"); +} + +void QFeedbackImmersion::setEffectState(const QFeedbackHapticsEffect *effect, QFeedbackEffect::State state) +{ + switch (state) + { + case QFeedbackEffect::Stopped: + break; + case QFeedbackEffect::Paused: + break; + case QFeedbackEffect::Running: + vibrateOnce(effect); + break; + default: + break; + } +} + +QFeedbackEffect::State QFeedbackImmersion::effectState(const QFeedbackHapticsEffect *effect) +{ + return QFeedbackEffect::Stopped; +} + +void QFeedbackImmersion::setLoaded(QFeedbackFileEffect *effect, bool load) +{ + const QUrl url = effect->source(); + // This doesn't handle qrc urls.. + const QString fileName = url.toLocalFile(); + if (fileName.isEmpty()) + return; + + if (!load /* && !fileData.contains(filename) */) + return; + + if (false) + reportLoadFinished(effect, true); +} + +void QFeedbackImmersion::setEffectState(QFeedbackFileEffect *effect, QFeedbackEffect::State state) +{ + switch (state) + { + case QFeedbackEffect::Stopped: + break; + case QFeedbackEffect::Paused: + break; + case QFeedbackEffect::Running: + break; + default: + break; + } + + if (false) + reportError(effect, QFeedbackEffect::UnknownError); +} + +QFeedbackEffect::State QFeedbackImmersion::effectState(const QFeedbackFileEffect *effect) +{ + //return QFeedbackEffect::Paused; + //return QFeedbackEffect::Running; + return QFeedbackEffect::Stopped; +} + +int QFeedbackImmersion::effectDuration(const QFeedbackFileEffect *effect) +{ + QString fileName = effect->source().toLocalFile(); + return 0; +} + +QStringList QFeedbackImmersion::supportedMimeTypes() +{ + return QStringList() << QLatin1String("vibra/ivt"); +} + +bool QFeedbackImmersion::play(QFeedbackEffect::Effect effect) +{ + QFeedbackHapticsEffect themeEffect; + vibrateOnce(&themeEffect); + return true; +} + diff --git a/src/plugins/feedback/mir/qfeedback.h b/src/plugins/feedback/mir/qfeedback.h new file mode 100644 index 0000000..4df69f5 --- /dev/null +++ b/src/plugins/feedback/mir/qfeedback.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtFeedback 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 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$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt Feedback framework. This header file may change from version +// to version without notice, or even be removed. +// +// We mean it. +// +// + +#ifndef QFEEDBACK_IMMERSION_H +#define QFEEDBACK_IMMERSION_H + +#include +#include +#include +#include +#include +#include + +#include + +QT_BEGIN_HEADER +QT_USE_NAMESPACE + +class QFeedbackImmersion : public QObject, public QFeedbackHapticsInterface, public QFeedbackFileInterface, public QFeedbackThemeInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtFeedbackPlugin" FILE "mir.json") + + Q_INTERFACES(QFeedbackHapticsInterface) + Q_INTERFACES(QFeedbackFileInterface) + Q_INTERFACES(QFeedbackThemeInterface) + +public: + QFeedbackImmersion(); + virtual ~QFeedbackImmersion(); + + virtual PluginPriority pluginPriority(); + virtual QList actuators(); + + //for actuator handling + virtual void setActuatorProperty(const QFeedbackActuator &, ActuatorProperty, const QVariant &); + virtual QVariant actuatorProperty(const QFeedbackActuator &, ActuatorProperty); + virtual bool isActuatorCapabilitySupported(const QFeedbackActuator &, QFeedbackActuator::Capability); + + virtual void updateEffectProperty(const QFeedbackHapticsEffect *, EffectProperty); + virtual void setEffectState(const QFeedbackHapticsEffect *, QFeedbackEffect::State); + virtual QFeedbackEffect::State effectState(const QFeedbackHapticsEffect *); + + //for loading files + virtual void setLoaded(QFeedbackFileEffect*, bool); + virtual void setEffectState(QFeedbackFileEffect *, QFeedbackEffect::State); + virtual QFeedbackEffect::State effectState(const QFeedbackFileEffect *); + virtual int effectDuration(const QFeedbackFileEffect *); + virtual QStringList supportedMimeTypes(); + + // theming + virtual bool play(QFeedbackEffect::Effect); +private: + QList actuatorList; + + void vibrateOnce(const QFeedbackEffect* effect); +}; + +QT_END_HEADER + +#endif // QFEEDBACK_IMMERSION_H -- 1.8.1.2