File indexing completed on 2024-05-12 17:07:21
0001 /* 0002 SPDX-FileCopyrightText: 2018 Roman Gilg <subdiff@gmail.com> 0003 SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #pragma once 0009 0010 #include "InputDevice_interface.h" 0011 0012 #include <QObject> 0013 #include <QString> 0014 0015 #include <optional> 0016 0017 class InputDevice : public QObject 0018 { 0019 Q_OBJECT 0020 0021 Q_PROPERTY(QString sysName READ sysName CONSTANT) 0022 Q_PROPERTY(QString name READ name CONSTANT) 0023 Q_PROPERTY(QSizeF size READ size CONSTANT) 0024 Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) 0025 Q_PROPERTY(bool supportsLeftHanded READ supportsLeftHanded CONSTANT) 0026 Q_PROPERTY(bool leftHanded READ isLeftHanded WRITE setLeftHanded NOTIFY leftHandedChanged) 0027 0028 Q_PROPERTY(bool supportsOrientation READ supportsOrientation CONSTANT) 0029 Q_PROPERTY(int orientation READ orientation WRITE setOrientation NOTIFY orientationChanged) 0030 Q_PROPERTY(QString outputName READ outputName WRITE setOutputName NOTIFY outputNameChanged) 0031 Q_PROPERTY(QRectF outputArea READ outputArea WRITE setOutputArea NOTIFY outputAreaChanged) 0032 0033 public: 0034 InputDevice(const QString &dbusName, QObject *parent); 0035 0036 void load(); 0037 void save(); 0038 void defaults(); 0039 bool isSaveNeeded() const; 0040 bool isDefaults() const; 0041 0042 QString name() const 0043 { 0044 return m_name.value(); 0045 } 0046 0047 QString sysName() const 0048 { 0049 return m_sysName.value(); 0050 } 0051 bool isLeftHanded() const 0052 { 0053 return m_leftHanded.value(); 0054 } 0055 bool supportsLeftHanded() const 0056 { 0057 return m_leftHanded.isSupported(); 0058 } 0059 void setLeftHanded(bool set); 0060 0061 bool supportsOrientation() const 0062 { 0063 return m_orientation.isSupported(); 0064 } 0065 int orientation() const 0066 { 0067 return m_orientation.value(); 0068 } 0069 void setOrientation(int ori); 0070 0071 QString outputName() const 0072 { 0073 return m_outputName.value(); 0074 } 0075 void setOutputName(const QString &outputName); 0076 QSizeF size() const 0077 { 0078 return m_size.value(); 0079 } 0080 0081 QRectF outputArea() const 0082 { 0083 return m_outputArea.value(); 0084 } 0085 void setOutputArea(const QRectF &outputArea); 0086 0087 bool isEnabled() const 0088 { 0089 return m_enabled.value(); 0090 } 0091 0092 void setEnabled(bool enabled); 0093 0094 Q_SIGNALS: 0095 void needsSaveChanged(); 0096 0097 void leftHandedChanged(); 0098 void orientationChanged(); 0099 void outputNameChanged(); 0100 void outputAreaChanged(); 0101 void enabledChanged(); 0102 0103 private: 0104 template<typename T> 0105 struct Prop { 0106 typedef T (OrgKdeKWinInputDeviceInterface::*ValueFunction)() const; 0107 typedef bool (OrgKdeKWinInputDeviceInterface::*SupportedFunction)() const; 0108 typedef bool (OrgKdeKWinInputDeviceInterface::*SetterFunction)(const T &value); 0109 typedef void (InputDevice::*ChangedSignal)(); 0110 0111 explicit Prop(InputDevice *device, const char *propName, ValueFunction defaultValueFunction, SupportedFunction supported, ChangedSignal changedSignal) 0112 : m_defaultValueFunction(defaultValueFunction) 0113 , m_supportedFunction(supported) 0114 , m_changedSignalFunction(changedSignal) 0115 , m_device(device) 0116 { 0117 int idx = OrgKdeKWinInputDeviceInterface::staticMetaObject.indexOfProperty(propName); 0118 if (idx < 0) { 0119 qDebug() << "there is no" << propName; 0120 } 0121 Q_ASSERT(idx >= 0); 0122 m_prop = OrgKdeKWinInputDeviceInterface::staticMetaObject.property(idx); 0123 } 0124 0125 explicit Prop(InputDevice *device, const char *propName) 0126 : m_defaultValueFunction(nullptr) 0127 , m_supportedFunction(nullptr) 0128 , m_changedSignalFunction(nullptr) 0129 , m_device(device) 0130 { 0131 Q_ASSERT(m_device); 0132 int idx = OrgKdeKWinInputDeviceInterface::staticMetaObject.indexOfProperty(propName); 0133 Q_ASSERT(idx >= 0); 0134 m_prop = OrgKdeKWinInputDeviceInterface::staticMetaObject.property(idx); 0135 } 0136 0137 T value() const 0138 { 0139 if (!m_value.has_value()) { 0140 auto iface = m_device->m_iface.get(); 0141 if (isSupported()) { 0142 m_value = m_prop.read(iface).value<T>(); 0143 } 0144 } 0145 return m_value ? m_value.value() : T(); 0146 } 0147 void resetFromDefaults() 0148 { 0149 if (isSupported()) { 0150 set(defaultValue()); 0151 } 0152 } 0153 void resetFromSaved() 0154 { 0155 m_value = {}; 0156 value(); 0157 m_configValue = m_value; 0158 if (m_changedSignalFunction) { 0159 (m_device->*m_changedSignalFunction)(); 0160 } 0161 } 0162 0163 void set(T newVal); 0164 T defaultValue() const 0165 { 0166 return m_defaultValueFunction ? (m_device->m_iface.get()->*m_defaultValueFunction)() : T(); 0167 } 0168 bool changed() const; 0169 void set(const Prop<T> &p) 0170 { 0171 set(p.value); 0172 } 0173 0174 bool isSupported() const 0175 { 0176 auto iface = m_device->m_iface.get(); 0177 return !m_supportedFunction || (iface->*m_supportedFunction)(); 0178 } 0179 0180 bool save(); 0181 bool isDefaults() const 0182 { 0183 return m_value == defaultValue(); 0184 } 0185 0186 private: 0187 QMetaProperty m_prop; 0188 const ValueFunction m_defaultValueFunction; 0189 const SupportedFunction m_supportedFunction; 0190 const ChangedSignal m_changedSignalFunction; 0191 InputDevice *const m_device; 0192 mutable std::optional<T> m_configValue; 0193 mutable std::optional<T> m_value; 0194 }; 0195 0196 // 0197 // general 0198 Prop<QString> m_name = Prop<QString>(this, "name"); 0199 Prop<QSizeF> m_size = Prop<QSizeF>(this, "size"); 0200 Prop<QString> m_sysName = Prop<QString>(this, "sysName"); 0201 0202 Prop<bool> m_leftHanded = Prop<bool>(this, 0203 "leftHanded", 0204 &OrgKdeKWinInputDeviceInterface::leftHandedEnabledByDefault, 0205 &OrgKdeKWinInputDeviceInterface::supportsLeftHanded, 0206 &InputDevice::leftHandedChanged); 0207 Prop<int> m_orientation = 0208 Prop<int>(this, "orientationDBus", nullptr, &OrgKdeKWinInputDeviceInterface::supportsCalibrationMatrix, &InputDevice::orientationChanged); 0209 Prop<bool> m_enabled = Prop<bool>(this, "enabled", &OrgKdeKWinInputDeviceInterface::enabledByDefault, nullptr, &InputDevice::enabledChanged); 0210 0211 Prop<QString> m_outputName = Prop<QString>(this, "outputName", nullptr, nullptr, &InputDevice::outputNameChanged); 0212 Prop<QRectF> m_outputArea = Prop<QRectF>(this, 0213 "outputArea", 0214 &OrgKdeKWinInputDeviceInterface::defaultOutputArea, 0215 &OrgKdeKWinInputDeviceInterface::supportsOutputArea, 0216 &InputDevice::outputAreaChanged); 0217 0218 std::unique_ptr<OrgKdeKWinInputDeviceInterface> m_iface; 0219 };