virtual void close() = 0;
virtual bool queryDeviceCapabilities() = 0;
virtual bool removeAndEraseEffect(const int idx) = 0;
+ virtual bool setAutocentering(const int strength) = 0;
virtual bool setGain(const int gain) = 0;
virtual bool startEffect(const int idx, const FFBEffectTypes type, std::shared_ptr<FFBEffectParameters> parameters) = 0;
virtual bool stopEffect(const int idx) = 0;
std::vector<ConditionSubtypes> m_availableConditionSubtypes;
std::vector<FFBEffectTypes> m_availableEffects;
std::vector<PeriodicWaveforms> m_availablePeriodicWaveforms;
+ bool m_adjustableAC;
bool m_adjustableGain;
std::vector<std::shared_ptr<FFBEffect>> m_effects;
/* Query device-wide capabilities */
if (testBit(FF_GAIN, caps))
m_adjustableGain = true;
+ if (testBit(FF_AUTOCENTER, caps))
+ m_adjustableAC = true;
return true;
}
return true;
}
+bool LinuxFFBDevice::setAutocentering(const int strength)
+{
+ struct input_event evt;
+ int ret;
+
+ if (!m_adjustableAC) {
+ QMessageBox::warning(nullptr, LNXDEV_ERR_CAPTION, "Device does not have adjustable autocentering");
+ return false;
+ }
+
+ if (strength < 0 || strength > 0xFFFF) {
+ QMessageBox::warning(nullptr, LNXDEV_ERR_CAPTION, "Autocentering strength must be within <0; 65535>");
+ return false;
+ }
+
+ evt.type = EV_FF;
+ evt.code = FF_AUTOCENTER;
+ evt.value = strength;
+ ret = write(c_fd, &evt, sizeof(struct input_event));
+ if (ret != sizeof(struct input_event)) {
+ QMessageBox::warning(nullptr, LNXDEV_ERR_CAPTION, "Unable to set autocentering strength");
+ return false;
+ }
+
+ return true;
+}
+
+
bool LinuxFFBDevice::setGain(const int gain)
{
struct input_event evt;
void close();
bool queryDeviceCapabilities();
bool removeAndEraseEffect(const int idx);
+ bool setAutocentering(const int strength);
bool setGain(const int gain);
bool startEffect(const int idx, const FFBEffectTypes type, std::shared_ptr<FFBEffectParameters> parameters);
bool stopEffect(const int idx);
connect(ui->cbox_interfaces, SIGNAL(activated(int)), this, SLOT(onInterfaceSelected(const int)));
connect(ui->qpb_refreshDevices, SIGNAL(clicked()), this, SLOT(onRefreshDevicesClicked()));
connect(ui->qpb_remove, SIGNAL(clicked()), this, SLOT(onRemoveEffectClicked()));
+ connect(ui->qpb_setAC, SIGNAL(clicked()), this, SLOT(onSetACClicked()));
connect(ui->qpb_setGain, SIGNAL(clicked()), this, SLOT(onSetGainClicked()));
connect(ui->qpb_start, SIGNAL(clicked()), this, SLOT(onStartEffectClicked()));
connect(ui->qpb_stop, SIGNAL(clicked()), this, SLOT(onStopEffectClicked()));
setEffectStatusText(m_activeDevice->effectStatusByIdx(effectIdx));
}
+void MainWindow::onSetACClicked()
+{
+ bool ok;
+ int strength;
+
+ if (m_activeDevice == nullptr)
+ return;
+
+ strength = ui->qle_autocentering->text().toInt(&ok);
+ if (!ok) {
+ QMessageBox::warning(this, res_inputFormatErrCap, "Invalid autocentering strength value");
+ return;
+ }
+
+ m_activeDevice->setAutocentering(strength);
+}
+
+
void MainWindow::onSetGainClicked()
{
bool ok;
void onInterfaceSelected(const int cboxIdx);
void onRefreshDevicesClicked();
void onRemoveEffectClicked();
+ void onSetACClicked();
void onSetGainClicked();
void onStartEffectClicked();
void onStopEffectClicked();
<x>0</x>
<y>0</y>
<width>444</width>
- <height>623</height>
+ <height>670</height>
</rect>
</property>
<property name="windowTitle">
<item row="0" column="1">
<widget class="QComboBox" name="cbox_devices"/>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="ql_effectSlots">
- <property name="text">
- <string>Effect slots:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QComboBox" name="cbox_effectSlots"/>
- </item>
<item row="3" column="0" colspan="2">
<widget class="QPushButton" name="qpb_refreshDevices">
<property name="text">
</property>
</widget>
</item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="ql_autocentering">
+ <property name="text">
+ <string>Autocentering:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="qle_autocentering">
+ <property name="text">
+ <string>65535</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="qpb_setAC">
+ <property name="text">
+ <string>Set AC</string>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
</property>
</widget>
</item>
+ <item>
+ <layout class="QFormLayout" name="formLayout_4">
+ <item row="0" column="0">
+ <widget class="QLabel" name="ql_effectSlots">
+ <property name="text">
+ <string>Effect slots:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="cbox_effectSlots"/>
+ </item>
+ </layout>
+ </item>
<item>
<widget class="QLabel" name="ql_effectStatus">
<property name="font">
if (caps & SDL_HAPTIC_GAIN)
m_adjustableGain = true;
+ if (caps & SDL_HAPTIC_AUTOCENTER)
+ m_adjustableAC = true;
+
return true;
}
return true;
}
+bool SDL2FFBDevice::setAutocentering(const int strength)
+{
+ if (!m_adjustableAC) {
+ QMessageBox::warning(nullptr, SDL2DEV_ERR_CAPTION, "Device does not have adjustable autocentering");
+ return false;
+ }
+
+ if (strength < 0 || strength > 100) {
+ QMessageBox::warning(nullptr, SDL2DEV_ERR_CAPTION, "Autocentering strength must be within <0; 100>");
+ return false;
+ }
+
+ if (SDL_HapticSetAutocenter(c_haptic, strength) < 0) {
+ QMessageBox::warning(nullptr, SDL2DEV_ERR_CAPTION, QString("Unable to set autocentering:\n%1").arg(SDL_GetError()));
+ return false;
+ }
+
+ return true;
+}
+
+
bool SDL2FFBDevice::setGain(const int gain)
{
if (!m_adjustableGain) {
void close();
bool queryDeviceCapabilities();
bool removeAndEraseEffect(const int idx);
+ bool setAutocentering(const int strength);
bool setGain(const int idx);
bool startEffect(const int idx, const FFBEffectTypes type, std::shared_ptr<FFBEffectParameters> parameters);
bool stopEffect(const int idx);