#include #include "xlibtouchpad.h" #include #include #include #include XlibTouchpad::XlibTouchpad(Display *display, int deviceId) : m_display(display) , m_connection(XGetXCBConnection(display)) , m_deviceId(deviceId) { m_floatType.intern(m_connection, "FLOAT"); m_enabledAtom.intern(m_connection, XI_PROP_ENABLED); } void XlibTouchpad::loadSupportedProperties(const Parameter *props) { m_paramList = props; for (const Parameter *param = props; param->name; param++) { QLatin1String name(param->prop_name); if (!m_atoms.contains(name)) { m_atoms.insert(name, std::make_shared(m_connection, param->prop_name)); } } } QVariant XlibTouchpad::getParameter(const Parameter *par) { PropertyInfo *p = getDevProperty(QLatin1String(par->prop_name)); if (!p || par->prop_offset >= p->nitems) { return QVariant(); } return p->value(par->prop_offset); } void XlibTouchpad::flush() { for (const QLatin1String &name : std::as_const(m_changed)) { m_props[name].set(); } m_changed.clear(); XFlush(m_display); } PropertyInfo *XlibTouchpad::getDevProperty(const QLatin1String &propName) { if (m_props.contains(propName)) { return &m_props[propName]; } if (!m_atoms.contains(propName) || !m_atoms[propName]) { return nullptr; } xcb_atom_t prop = m_atoms[propName]->atom(); if (!prop) { return nullptr; } PropertyInfo p(m_display, m_deviceId, prop, m_floatType.atom()); if (!p.b && !p.f && !p.i) { return nullptr; } return &m_props.insert(propName, p).value(); } bool XlibTouchpad::setParameter(const Parameter *par, const QVariant &value) { QLatin1String propName(par->prop_name); PropertyInfo *p = getDevProperty(propName); if (!p || par->prop_offset >= p->nitems) { return false; } QVariant converted(value); QMetaType::Type convType = QMetaType::Type::Int; if (p->f) { convType = QMetaType::Type::Double; } else if (value.typeId() == QMetaType::Type::Double) { converted = QVariant(qRound(static_cast(value.toDouble()))); } if (!converted.convert(QMetaType(convType))) { return false; } if (converted == p->value(par->prop_offset)) { return true; } if (p->b) { p->b[par->prop_offset] = static_cast(converted.toInt()); } else if (p->i) { p->i[par->prop_offset] = converted.toInt(); } else if (p->f) { p->f[par->prop_offset] = converted.toDouble(); } m_changed.insert(propName); return true; } void XlibTouchpad::setSuspended(bool suspend) { PropertyInfo enabled(m_display, m_deviceId, m_enabledAtom.atom(), 0); if (enabled.b && *(enabled.b) == suspend) { *(enabled.b) = !suspend; enabled.set(); } flush(); } bool XlibTouchpad::isSuspended() { PropertyInfo enabled(m_display, m_deviceId, m_enabledAtom.atom(), 0); return !enabled.value(0).toBool(); } const Parameter *XlibTouchpad::findParameter(const QString &name) { for (const Parameter *par = m_paramList; par->name; par++) { if (name == par->name) { return par; } } return nullptr; }