diff --git a/kcms/touchpad/src/backends/x11/libinputtouchpad.cpp b/kcms/touchpad/src/backends/x11/libinputtouchpad.cpp index 3cb95caff..e454d564d 100644 --- a/kcms/touchpad/src/backends/x11/libinputtouchpad.cpp +++ b/kcms/touchpad/src/backends/x11/libinputtouchpad.cpp @@ -1,413 +1,423 @@ /* * Copyright (C) 2019 Atul Bisht * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "libinputtouchpad.h" #include "logging.h" #include #include #include #include #include #include const Parameter libinputProperties[] = { /* libinput disable supports property */ {"supportsDisableEvents", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_AVAILABLE, 8, 0}, {"enabled", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_ENABLED, 8, 0}, {"enabledDefault", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_ENABLED_DEFAULT, 8, 0}, /* LeftHandSupport */ {"leftHandedEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_LEFT_HANDED_DEFAULT, 8, 0}, {"leftHanded", PT_INT, 0, 1, LIBINPUT_PROP_LEFT_HANDED, 8, 0}, /* Disable on external mouse */ {"supportsDisableEventsOnExternalMouse",PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_AVAILABLE, 8, 1}, {"disableEventsOnExternalMouse", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_ENABLED, 8, 1}, {"disableEventsOnExternalMouseDefault", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_ENABLED_DEFAULT, 8, 1}, /* Disable while typing */ {"disableWhileTypingEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_DISABLE_WHILE_TYPING_DEFAULT, 8, 0}, {"disableWhileTyping", PT_INT, 0, 1, LIBINPUT_PROP_DISABLE_WHILE_TYPING, 8, 0}, /* Middle Emulation */ {"middleEmulationEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_MIDDLE_EMULATION_ENABLED_DEFAULT, 8, 0}, {"middleEmulation", PT_INT, 0, 1, LIBINPUT_PROP_MIDDLE_EMULATION_ENABLED, 8, 0}, /* This is a boolean for all three fingers, no per-finger config */ {"tapToClick", PT_INT, 0, 1, LIBINPUT_PROP_TAP, 8, 0}, {"tapToClickEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DEFAULT, 8, 0}, /* LMR */ {"lrmTapButtonMapEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT, 8, 0}, {"lrmTapButtonMap", PT_INT, 0, 1, LIBINPUT_PROP_TAP_BUTTONMAP, 8, 0}, {"lmrTapButtonMapEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT, 8, 1}, {"lmrTapButtonMap", PT_INT, 0, 1, LIBINPUT_PROP_TAP_BUTTONMAP, 8, 1}, /* Tap and Drag Enabled */ {"tapAndDragEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DRAG_DEFAULT, 8, 0}, {"tapAndDrag", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DRAG, 8, 0}, /* Tap and Drag Lock Enabled */ {"tapDragLockEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DRAG_LOCK_DEFAULT, 8, 0}, {"tapDragLock", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DRAG_LOCK, 8, 0}, /* libinput normalizes the accel to -1/1 */ {"defaultPointerAcceleration", PT_DOUBLE, -1.0, 1.0, LIBINPUT_PROP_ACCEL_DEFAULT, 0 /*float */, 0}, {"pointerAcceleration", PT_DOUBLE, -1.0, 1.0, LIBINPUT_PROP_ACCEL, 0 /*float */, 0}, /* Libinput Accel Profile */ {"supportsPointerAccelerationProfileAdaptive", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILES_AVAILABLE, 8, 0}, {"defaultPointerAccelerationProfileAdaptive", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILE_ENABLED_DEFAULT, 8, 0}, {"pointerAccelerationProfileAdaptive", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILE_ENABLED, 8, 0}, {"supportsPointerAccelerationProfileFlat", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILES_AVAILABLE, 8, 1}, {"defaultPointerAccelerationProfileFlat", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILE_ENABLED_DEFAULT, 8, 1}, {"pointerAccelerationProfileFlat", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILE_ENABLED, 8, 1}, /* Natural Scrolling */ {"naturalScrollEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_NATURAL_SCROLL_DEFAULT, 8, 0}, {"naturalScroll", PT_INT, 0, 1, LIBINPUT_PROP_NATURAL_SCROLL, 8, 0}, /* Horizontal scrolling */ {"horizontalScrolling", PT_INT, 0, 1, LIBINPUT_PROP_HORIZ_SCROLL_ENABLED, 8, 0}, /* Two-Finger Scrolling */ {"supportsScrollTwoFinger", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE, 8, 0}, {"scrollTwoFingerEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED_DEFAULT, 8, 0}, {"scrollTwoFinger", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED, 8, 0}, /* Edge Scrolling */ {"supportsScrollEdge", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE, 8, 1}, {"scrollEdgeEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED_DEFAULT, 8, 1}, {"scrollEdge", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED, 8, 1}, /* scroll on button */ {"supportsScrollOnButtonDown", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE, 8, 2}, {"scrollOnButtonDownEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED_DEFAULT, 8, 2}, {"scrollOnButtonDown", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED, 8, 2}, /* Scroll Button for scroll on button Down */ {"defaultScrollButton", PT_INT, 0, INT_MAX, LIBINPUT_PROP_SCROLL_BUTTON_DEFAULT, 32, 0}, {"scrollButton", PT_INT, 0, INT_MAX, LIBINPUT_PROP_SCROLL_BUTTON, 32, 0}, /* Click Methods */ {"supportsClickMethodAreas", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHODS_AVAILABLE, 8, 0}, {"defaultClickMethodAreas", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHOD_ENABLED_DEFAULT, 8, 0}, {"clickMethodAreas", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHOD_ENABLED, 8, 0}, {"supportsClickMethodClickfinger", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHODS_AVAILABLE, 8, 1}, {"defaultClickMethodClickfinger", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHOD_ENABLED_DEFAULT, 8, 1}, {"clickMethodClickfinger", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHOD_ENABLED, 8, 1}, /* libinput doesn't have a separate toggle for horiz scrolling */ { nullptr, PT_INT, 0, 0, nullptr, 0, 0 } }; Qt::MouseButtons maskBtns(Display *display, XIButtonClassInfo *buttonInfo) { Qt::MouseButtons buttons = Qt::NoButton; for (int i = 0; i < buttonInfo->num_buttons; ++i) { QByteArray reply = XGetAtomName(display, buttonInfo->labels[i]); if (reply == BTN_LABEL_PROP_BTN_LEFT) { buttons |= Qt::LeftButton; } if (reply == BTN_LABEL_PROP_BTN_RIGHT) { buttons |= Qt::RightButton; } if (reply == BTN_LABEL_PROP_BTN_MIDDLE) { buttons |= Qt::MiddleButton; } if (reply == BTN_LABEL_PROP_BTN_SIDE) { buttons |= Qt::ExtraButton1; } if (reply == BTN_LABEL_PROP_BTN_EXTRA) { buttons |= Qt::ExtraButton2; } if (reply == BTN_LABEL_PROP_BTN_FORWARD) { buttons |= Qt::ForwardButton; } if (reply == BTN_LABEL_PROP_BTN_BACK) { buttons |= Qt::BackButton; } if (reply == BTN_LABEL_PROP_BTN_TASK) { buttons |= Qt::TaskButton; } } return buttons; } LibinputTouchpad::LibinputTouchpad(Display *display, int deviceId): LibinputCommon(), XlibTouchpad(display, deviceId) { loadSupportedProperties(libinputProperties); int nDevices = 0; XIDeviceInfo *deviceInfo = XIQueryDevice(m_display, m_deviceId, &nDevices); m_name = deviceInfo->name; for (int i = 0; i < deviceInfo->num_classes; ++i) { XIAnyClassInfo *classInfo = deviceInfo->classes[i]; if (classInfo->type == XIButtonClass) { XIButtonClassInfo *btnInfo = (XIButtonClassInfo*) classInfo; m_supportedButtons.avail = true; m_supportedButtons.set(maskBtns(m_display, btnInfo)); } if (classInfo->type == XITouchClass) { XITouchClassInfo *touchInfo = (XITouchClassInfo*) classInfo; m_tapFingerCount.avail = true; m_tapFingerCount.set(touchInfo->num_touches); } } XIFreeDeviceInfo(deviceInfo); /* FingerCount cannot be zero */ if (!m_tapFingerCount.val) { m_tapFingerCount.avail = true; m_tapFingerCount.set(1); } m_config = KSharedConfig::openConfig(QStringLiteral("touchpadxlibinputrc")); } bool LibinputTouchpad::getConfig() { bool success = true; success &= valueLoader(m_supportsDisableEvents); success &= valueLoader(m_enabled); success &= valueLoader(m_enabledDefault); success &= valueLoader(m_tapToClickEnabledByDefault); success &= valueLoader(m_tapToClick); success &= valueLoader(m_lrmTapButtonMapEnabledByDefault); success &= valueLoader(m_lrmTapButtonMap); success &= valueLoader(m_lmrTapButtonMapEnabledByDefault); success &= valueLoader(m_lmrTapButtonMap); success &= valueLoader(m_tapAndDragEnabledByDefault); success &= valueLoader(m_tapAndDrag); success &= valueLoader(m_tapDragLockEnabledByDefault); success &= valueLoader(m_tapDragLock); success &= valueLoader(m_leftHandedEnabledByDefault); success &= valueLoader(m_leftHanded); success &= valueLoader(m_supportsDisableEventsOnExternalMouse); success &= valueLoader(m_disableEventsOnExternalMouse); success &= valueLoader(m_disableEventsOnExternalMouseDefault); success &= valueLoader(m_disableWhileTypingEnabledByDefault); success &= valueLoader(m_disableWhileTyping); success &= valueLoader(m_middleEmulationEnabledByDefault); success &= valueLoader(m_middleEmulation); success &= valueLoader(m_defaultPointerAcceleration); success &= valueLoader(m_pointerAcceleration); success &= valueLoader(m_supportsPointerAccelerationProfileFlat); success &= valueLoader(m_defaultPointerAccelerationProfileFlat); success &= valueLoader(m_pointerAccelerationProfileFlat); success &= valueLoader(m_supportsPointerAccelerationProfileAdaptive); success &= valueLoader(m_defaultPointerAccelerationProfileAdaptive); success &= valueLoader(m_pointerAccelerationProfileAdaptive); success &= valueLoader(m_naturalScrollEnabledByDefault); success &= valueLoader(m_naturalScroll); success &= valueLoader(m_horizontalScrolling); success &= valueLoader(m_supportsScrollTwoFinger); success &= valueLoader(m_scrollTwoFingerEnabledByDefault); success &= valueLoader(m_isScrollTwoFinger); success &= valueLoader(m_supportsScrollEdge); success &= valueLoader(m_scrollEdgeEnabledByDefault); success &= valueLoader(m_isScrollEdge); success &= valueLoader(m_supportsScrollOnButtonDown); success &= valueLoader(m_scrollOnButtonDownEnabledByDefault); success &= valueLoader(m_isScrollOnButtonDown); success &= valueLoader(m_defaultScrollButton); success &= valueLoader(m_scrollButton); // click methods success &= valueLoader(m_supportsClickMethodAreas); success &= valueLoader(m_supportsClickMethodClickfinger); success &= valueLoader(m_defaultClickMethodAreas); success &= valueLoader(m_defaultClickMethodClickfinger); success &= valueLoader(m_clickMethodAreas); success &= valueLoader(m_clickMethodClickfinger); return success; } bool LibinputTouchpad::applyConfig() { QVector msgs; msgs << valueWriter(m_enabled) << valueWriter(m_tapToClick) << valueWriter(m_lrmTapButtonMap) << valueWriter(m_lmrTapButtonMap) << valueWriter(m_tapAndDrag) << valueWriter(m_tapDragLock) << valueWriter(m_leftHanded) << valueWriter(m_disableWhileTyping) << valueWriter(m_middleEmulation) << valueWriter(m_pointerAcceleration) << valueWriter(m_pointerAccelerationProfileFlat) << valueWriter(m_pointerAccelerationProfileAdaptive) << valueWriter(m_naturalScroll) << valueWriter(m_horizontalScrolling) << valueWriter(m_isScrollTwoFinger) << valueWriter(m_isScrollEdge) << valueWriter(m_isScrollOnButtonDown) << valueWriter(m_scrollButton) << valueWriter(m_clickMethodAreas) << valueWriter(m_clickMethodClickfinger); bool success = true; QString error_msg; for (QString m : msgs) { if (!m.isNull()) { qCCritical(KCM_TOUCHPAD) << "in error:" << m; if (!success) { error_msg.append("\n"); } error_msg.append(m); success = false; } } if (!success) { qCCritical(KCM_TOUCHPAD) << error_msg; } flush(); return success; } bool LibinputTouchpad::getDefaultConfig() { m_enabled.set(m_enabledDefault); m_tapToClick.set(m_tapToClickEnabledByDefault); m_lrmTapButtonMap.set(m_lrmTapButtonMap); m_lmrTapButtonMap.set(m_lmrTapButtonMapEnabledByDefault); m_tapAndDrag.set(m_tapAndDragEnabledByDefault); m_tapDragLock.set(m_tapDragLockEnabledByDefault); m_leftHanded.set(m_leftHandedEnabledByDefault); m_disableEventsOnExternalMouse.set(m_disableEventsOnExternalMouseDefault); m_disableWhileTyping.set(m_disableWhileTypingEnabledByDefault); m_middleEmulation.set(m_middleEmulationEnabledByDefault); m_pointerAcceleration.set(m_defaultPointerAcceleration); m_pointerAccelerationProfileFlat.set(m_defaultPointerAccelerationProfileFlat); m_pointerAccelerationProfileAdaptive.set(m_defaultPointerAccelerationProfileAdaptive); m_naturalScroll.set(m_naturalScrollEnabledByDefault); m_horizontalScrolling.set(true); m_isScrollTwoFinger.set(m_scrollTwoFingerEnabledByDefault); m_isScrollEdge.set(m_scrollEdgeEnabledByDefault); m_isScrollOnButtonDown.set(m_scrollOnButtonDownEnabledByDefault); m_scrollButton.set(m_defaultScrollButton); m_clickMethodAreas.set(m_defaultClickMethodAreas); m_clickMethodClickfinger.set(m_defaultClickMethodClickfinger); return true; } bool LibinputTouchpad::isChangedConfig() { bool changed = m_enabled.changed() || m_tapToClick.changed() || m_lrmTapButtonMap.changed() || m_lmrTapButtonMap.changed() || m_tapAndDrag.changed() || m_tapDragLock.changed() || m_leftHanded.changed() || m_disableEventsOnExternalMouse.changed() || m_disableWhileTyping.changed() || m_middleEmulation.changed() || m_pointerAcceleration.changed() || m_pointerAccelerationProfileFlat.changed() || m_pointerAccelerationProfileAdaptive.changed() || m_naturalScroll.changed() || m_horizontalScrolling.changed() || m_isScrollTwoFinger.changed() || m_isScrollEdge.changed() || m_isScrollOnButtonDown.changed() || m_scrollButton.changed() || m_clickMethodAreas.changed() || m_clickMethodClickfinger.changed(); return changed; } +int LibinputTouchpad::touchpadOff() +{ + return m_enabled.val; +} + +XcbAtom &LibinputTouchpad::touchpadOffAtom() +{ + return *m_atoms[QLatin1Literal("enabled")].data(); +} + template bool LibinputTouchpad::valueLoader(Prop &prop) { const Parameter *p = findParameter(QString::fromAscii(prop.name)); if (!p) { qCCritical(KCM_TOUCHPAD) << "Error on read of " << QString::fromAscii(prop.name); } QVariant reply = getParameter(p); if (!reply.isValid()) { prop.avail = false; return true; } prop.avail = true; auto touchpadConfig = m_config->group(m_name); const T replyValue = valueLoaderPart(reply); const T loadedValue = touchpadConfig.readEntry(QString(prop.name), replyValue); prop.old = replyValue; prop.val = loadedValue; return true; } template QString LibinputTouchpad::valueWriter(const Prop &prop) { const Parameter *p = findParameter(QString::fromAscii(prop.name)); if (!p || !prop.changed()) { return QString(); } bool error = !setParameter( p, prop.val); if (error) { qCCritical(KCM_TOUCHPAD) << "Cannot set property " + QString::fromAscii(prop.name); return QStringLiteral("Cannot set property ") + QString::fromAscii(prop.name); } auto touchpadConfig = m_config->group(m_name); touchpadConfig.writeEntry(QString(prop.name), prop.val); touchpadConfig.config()->sync(); return QString(); } diff --git a/kcms/touchpad/src/backends/x11/libinputtouchpad.h b/kcms/touchpad/src/backends/x11/libinputtouchpad.h index 3668bee4c..39353265f 100644 --- a/kcms/touchpad/src/backends/x11/libinputtouchpad.h +++ b/kcms/touchpad/src/backends/x11/libinputtouchpad.h @@ -1,133 +1,136 @@ /* * Copyright (C) 2019 Atul Bisht * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef LIBINPUTTOUCHPAD_H #define LIBINPUTTOUCHPAD_H #include "xlibtouchpad.h" #include "backends/libinputcommon.h" #include #include class LibinputTouchpad : public LibinputCommon, public XlibTouchpad { Q_OBJECT public: LibinputTouchpad(Display *display, int deviceId); ~LibinputTouchpad() override {} bool getConfig() override; bool applyConfig() override; bool getDefaultConfig() override; bool isChangedConfig() override; + int touchpadOff() override; + XcbAtom &touchpadOffAtom() override; + private: template bool valueLoader(Prop &prop); template QString valueWriter(const Prop &prop); KSharedConfigPtr m_config; // // general QString name() const override { return m_name; } bool supportsDisableEvents() const override { return m_supportsDisableEvents.avail && m_supportsDisableEvents.val; } bool isEnabled() const override { return !m_enabled.val; } void setEnabled(bool set) override { m_enabled.set(!set); } // // Tapping void setLmrTapButtonMap(bool set) override { m_lrmTapButtonMap.set(!set); m_lmrTapButtonMap.set(set); } // // advanced bool supportsLeftHanded() const override { return m_leftHanded.avail; } bool supportsDisableEventsOnExternalMouse() const override { return m_supportsDisableEventsOnExternalMouse.avail && m_supportsDisableEventsOnExternalMouse.val; } bool supportsDisableWhileTyping() const override { return m_disableWhileTyping.avail; } bool supportsMiddleEmulation() const override { return m_middleEmulation.avail; } // // acceleration speed and profile bool supportsPointerAcceleration() const override { return m_pointerAcceleration.avail; } bool supportsPointerAccelerationProfileFlat() const override { return m_supportsPointerAccelerationProfileFlat.avail && m_supportsPointerAccelerationProfileFlat.val; } bool supportsPointerAccelerationProfileAdaptive() const override { return m_supportsPointerAccelerationProfileAdaptive.avail && m_supportsPointerAccelerationProfileAdaptive.val; } // // scrolling bool supportsNaturalScroll() const override { return m_naturalScroll.avail; } bool supportsHorizontalScrolling() const override { return true; } bool supportsScrollTwoFinger() const override { return m_supportsScrollTwoFinger.avail && m_supportsScrollTwoFinger.val; } bool supportsScrollEdge() const override { return m_supportsScrollEdge.avail && m_supportsScrollEdge.val; } bool supportsScrollOnButtonDown() const override { return m_supportsScrollOnButtonDown.avail && m_supportsScrollOnButtonDown.val; } // // click method bool supportsClickMethodAreas() const override { return m_supportsClickMethodAreas.avail && m_supportsClickMethodAreas.val; } bool supportsClickMethodClickfinger() const override { return m_supportsClickMethodClickfinger.avail && m_supportsClickMethodClickfinger.val; } // Tapping Prop m_lrmTapButtonMapEnabledByDefault = Prop("lrmTapButtonMapEnabledByDefault"); Prop m_lrmTapButtonMap = Prop("lrmTapButtonMap"); // // advanced Prop m_disableEventsOnExternalMouse = Prop("disableEventsOnExternalMouse"); Prop m_disableEventsOnExternalMouseDefault = Prop("disableEventsOnExternalMouseDefault"); QString m_name; }; #endif // LIBINPUTTOUCHPAD_H diff --git a/kcms/touchpad/src/backends/x11/synapticstouchpad.cpp b/kcms/touchpad/src/backends/x11/synapticstouchpad.cpp index eb222aed3..a3945d46a 100644 --- a/kcms/touchpad/src/backends/x11/synapticstouchpad.cpp +++ b/kcms/touchpad/src/backends/x11/synapticstouchpad.cpp @@ -1,251 +1,273 @@ /* * Copyright (C) 2013 Alexander Mezin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* //krazy:excludeall=copyright * This file incorporates work covered by the following copyright and * permission notice: * * Copyright © 2002-2005,2007 Peter Osterlund * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies * and that both that copyright notice and this permission notice * appear in supporting documentation, and that the name of Red Hat * not be used in advertising or publicity pertaining to distribution * of the software without specific, written prior permission. Red * Hat makes no representations about the suitability of this software * for any purpose. It is provided "as is" without express or implied * warranty. * * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Authors: * Peter Osterlund (petero2@telia.com) */ #include #include #include "synapticstouchpad.h" #include #include #include #define SYN_MAX_BUTTONS 12 const struct Parameter synapticsProperties[] = { {"LeftEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 0}, {"RightEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 1}, {"TopEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 2}, {"BottomEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 3}, {"FingerLow", PT_INT, 0, 255, SYNAPTICS_PROP_FINGER, 32, 0}, {"FingerHigh", PT_INT, 0, 255, SYNAPTICS_PROP_FINGER, 32, 1}, {"MaxTapTime", PT_INT, 0, 1000, SYNAPTICS_PROP_TAP_TIME, 32, 0}, {"MaxTapMove", PT_INT, 0, 2000, SYNAPTICS_PROP_TAP_MOVE, 32, 0}, {"MaxDoubleTapTime", PT_INT, 0, 1000, SYNAPTICS_PROP_TAP_DURATIONS,32, 1}, {"SingleTapTimeout", PT_INT, 0, 1000, SYNAPTICS_PROP_TAP_DURATIONS,32, 0}, {"ClickTime", PT_INT, 0, 1000, SYNAPTICS_PROP_TAP_DURATIONS,32, 2}, {"FastTaps", PT_BOOL, 0, 1, SYNAPTICS_PROP_TAP_FAST, 8, 0}, {"EmulateMidButtonTime", PT_INT, 0, 1000, SYNAPTICS_PROP_MIDDLE_TIMEOUT,32, 0}, {"EmulateTwoFingerMinZ", PT_INT, 0, 1000, SYNAPTICS_PROP_TWOFINGER_PRESSURE, 32, 0}, {"EmulateTwoFingerMinW", PT_INT, 0, 15, SYNAPTICS_PROP_TWOFINGER_WIDTH, 32, 0}, {"VertScrollDelta", PT_INT, -1000, 1000, SYNAPTICS_PROP_SCROLL_DISTANCE, 32, 0}, {"HorizScrollDelta", PT_INT, -1000, 1000, SYNAPTICS_PROP_SCROLL_DISTANCE, 32, 1}, {"VertEdgeScroll", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_EDGE, 8, 0}, {"HorizEdgeScroll", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_EDGE, 8, 1}, {"CornerCoasting", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_EDGE, 8, 2}, {"VertTwoFingerScroll", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_TWOFINGER, 8, 0}, {"HorizTwoFingerScroll", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_TWOFINGER, 8, 1}, {"MinSpeed", PT_DOUBLE, 0, 255.0, SYNAPTICS_PROP_SPEED, 0, /*float */ 0}, {"MaxSpeed", PT_DOUBLE, 0, 255.0, SYNAPTICS_PROP_SPEED, 0, /*float */ 1}, {"AccelFactor", PT_DOUBLE, 0, 1.0, SYNAPTICS_PROP_SPEED, 0, /*float */ 2}, /*{"TouchpadOff", PT_INT, 0, 2, SYNAPTICS_PROP_OFF, 8, 0},*/ {"LockedDrags", PT_BOOL, 0, 1, SYNAPTICS_PROP_LOCKED_DRAGS, 8, 0}, {"LockedDragTimeout", PT_INT, 0, 30000, SYNAPTICS_PROP_LOCKED_DRAGS_TIMEOUT, 32, 0}, {"RTCornerButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 0}, {"RBCornerButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 1}, {"LTCornerButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 2}, {"LBCornerButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 3}, {"OneFingerTapButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 4}, {"TwoFingerTapButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 5}, {"ThreeFingerTapButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 6}, {"ClickFinger1", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_CLICK_ACTION, 8, 0}, {"ClickFinger2", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_CLICK_ACTION, 8, 1}, {"ClickFinger3", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_CLICK_ACTION, 8, 2}, {"CircularScrolling", PT_BOOL, 0, 1, SYNAPTICS_PROP_CIRCULAR_SCROLLING, 8, 0}, {"CircScrollDelta", PT_DOUBLE, .01, 3, SYNAPTICS_PROP_CIRCULAR_SCROLLING_DIST, 0 /* float */, 0}, {"CircScrollTrigger", PT_INT, 0, 8, SYNAPTICS_PROP_CIRCULAR_SCROLLING_TRIGGER, 8, 0}, {"PalmDetect", PT_BOOL, 0, 1, SYNAPTICS_PROP_PALM_DETECT, 8, 0}, {"PalmMinWidth", PT_INT, 0, 15, SYNAPTICS_PROP_PALM_DIMENSIONS, 32, 0}, {"PalmMinZ", PT_INT, 0, 255, SYNAPTICS_PROP_PALM_DIMENSIONS, 32, 1}, {"CoastingSpeed", PT_DOUBLE, 0, 255, SYNAPTICS_PROP_COASTING_SPEED, 0 /* float*/, 0}, {"CoastingFriction", PT_DOUBLE, 0, 255, SYNAPTICS_PROP_COASTING_SPEED, 0 /* float*/, 1}, {"PressureMotionMinZ", PT_INT, 1, 255, SYNAPTICS_PROP_PRESSURE_MOTION, 32, 0}, {"PressureMotionMaxZ", PT_INT, 1, 255, SYNAPTICS_PROP_PRESSURE_MOTION, 32, 1}, {"PressureMotionMinFactor", PT_DOUBLE, 0, 10.0,SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR, 0 /*float*/, 0}, {"PressureMotionMaxFactor", PT_DOUBLE, 0, 10.0,SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR, 0 /*float*/, 1}, {"GrabEventDevice", PT_BOOL, 0, 1, SYNAPTICS_PROP_GRAB, 8, 0}, {"TapAndDragGesture", PT_BOOL, 0, 1, SYNAPTICS_PROP_GESTURES, 8, 0}, {"AreaLeftEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 0}, {"AreaRightEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 1}, {"AreaTopEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 2}, {"AreaBottomEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 3}, {"HorizHysteresis", PT_INT, 0, 10000, SYNAPTICS_PROP_NOISE_CANCELLATION, 32, 0}, {"VertHysteresis", PT_INT, 0, 10000, SYNAPTICS_PROP_NOISE_CANCELLATION, 32, 1}, {"ClickPad", PT_BOOL, 0, 1, SYNAPTICS_PROP_CLICKPAD, 8, 0}, {"RightButtonAreaLeft", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 0}, {"RightButtonAreaRight", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 1}, {"RightButtonAreaTop", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 2}, {"RightButtonAreaBottom", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 3}, {"MiddleButtonAreaLeft", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 4}, {"MiddleButtonAreaRight", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 5}, {"MiddleButtonAreaTop", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 6}, {"MiddleButtonAreaBottom", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 7}, { NULL, PT_INT, 0, 0, 0, 0, 0 } }; SynapticsTouchpad::SynapticsTouchpad(Display *display, int deviceId): XlibTouchpad(display, deviceId), m_resX(1), m_resY(1) { m_capsAtom.intern(m_connection, SYNAPTICS_PROP_CAPABILITIES); m_touchpadOffAtom.intern(m_connection, SYNAPTICS_PROP_OFF); XcbAtom resolutionAtom(m_connection, SYNAPTICS_PROP_RESOLUTION); XcbAtom edgesAtom(m_connection, SYNAPTICS_PROP_EDGES); loadSupportedProperties(synapticsProperties); m_toRadians.append("CircScrollDelta"); PropertyInfo edges(m_display, m_deviceId, edgesAtom, 0); if (edges.i && edges.nitems == 4) { int w = qAbs(edges.i[1] - edges.i[0]); int h = qAbs(edges.i[3] - edges.i[2]); m_resX = w / 90; m_resY = h / 50; qDebug() << "Width: " << w << " height: " << h; qDebug() << "Approx. resX: " << m_resX << " resY: " << m_resY; } PropertyInfo resolution(m_display, m_deviceId, resolutionAtom, 0); if (resolution.i && resolution.nitems == 2 && resolution.i[0] > 1 && resolution.i[1] > 1) { m_resY = qMin(static_cast(resolution.i[0]), static_cast(INT_MAX)); m_resX = qMin(static_cast(resolution.i[1]), static_cast(INT_MAX)); qDebug() << "Touchpad resolution: x: " << m_resX << " y: " << m_resY; } m_scaleByResX.append("HorizScrollDelta"); m_scaleByResY.append("VertScrollDelta"); m_scaleByResX.append("MaxTapMove"); m_scaleByResY.append("MaxTapMove"); m_resX = qMax(10, m_resX); m_resY = qMax(10, m_resY); qDebug() << "Final resolution x:" << m_resX << " y:" << m_resY; m_negate["HorizScrollDelta"] = "InvertHorizScroll"; m_negate["VertScrollDelta"] = "InvertVertScroll"; m_supported.append(m_negate.values()); m_supported.append("Coasting"); PropertyInfo caps(m_display, m_deviceId, m_capsAtom.atom(), 0); if (!caps.b) { return; } enum TouchpadCapabilitiy { TouchpadHasLeftButton, TouchpadHasMiddleButton, TouchpadHasRightButton, TouchpadTwoFingerDetect, TouchpadThreeFingerDetect, TouchpadPressureDetect, TouchpadPalmDetect, TouchpadCapsCount }; QVector cap(TouchpadCapsCount, false); qCopy(caps.b, caps.b + qMin(cap.size(), static_cast(caps.nitems)), cap.begin()); if (!cap[TouchpadTwoFingerDetect]) { m_supported.removeAll("HorizTwoFingerScroll"); m_supported.removeAll("VertTwoFingerScroll"); m_supported.removeAll("TwoFingerTapButton"); } if (!cap[TouchpadThreeFingerDetect]) { m_supported.removeAll("ThreeFingerTapButton"); } if (!cap[TouchpadPressureDetect]) { m_supported.removeAll("FingerHigh"); m_supported.removeAll("FingerLow"); m_supported.removeAll("PalmMinZ"); m_supported.removeAll("PressureMotionMinZ"); m_supported.removeAll("PressureMotionMinFactor"); m_supported.removeAll("PressureMotionMaxZ"); m_supported.removeAll("PressureMotionMaxFactor"); m_supported.removeAll("EmulateTwoFingerMinZ"); } if (!cap[TouchpadPalmDetect]) { m_supported.removeAll("PalmDetect"); m_supported.removeAll("PalmMinWidth"); m_supported.removeAll("PalmMinZ"); m_supported.removeAll("EmulateTwoFingerMinW"); } for (QMap::Iterator i = m_negate.begin(); i != m_negate.end(); ++i) { if (!m_supported.contains(i.key())) { m_supported.removeAll(i.value()); } } m_paramList = synapticsProperties; } +void SynapticsTouchpad::setTouchpadOff(int touchpadOff) +{ + PropertyInfo off(m_display, m_deviceId, m_touchpadOffAtom.atom(), 0); + if (off.b && *(off.b) != touchpadOff) { + *(off.b) = touchpadOff; + off.set(); + } + + flush(); +} + +int SynapticsTouchpad::touchpadOff() +{ + PropertyInfo off(m_display, m_deviceId, m_touchpadOffAtom.atom(), 0); + return off.value(0).toInt(); +} + +XcbAtom &SynapticsTouchpad::touchpadOffAtom() +{ + return m_touchpadOffAtom; +} + double SynapticsTouchpad::getPropertyScale(const QString &name) const { if (m_scaleByResX.contains(name) && m_scaleByResY.contains(name)) { return std::sqrt(static_cast(m_resX) * m_resX + static_cast(m_resY) * m_resY); } else if (m_scaleByResX.contains(name)) { return m_resX; } else if (m_scaleByResY.contains(name)) { return m_resY; } else if (m_toRadians.contains(name)) { return M_PI_4 / 45.0; } return 1.0; } diff --git a/kcms/touchpad/src/backends/x11/synapticstouchpad.h b/kcms/touchpad/src/backends/x11/synapticstouchpad.h index 0f4b30b05..c5d964e17 100644 --- a/kcms/touchpad/src/backends/x11/synapticstouchpad.h +++ b/kcms/touchpad/src/backends/x11/synapticstouchpad.h @@ -1,41 +1,46 @@ /* * Copyright (C) 2015 Weng Xuetian * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SYNAPTICSTOUCHPAD_H #define SYNAPTICSTOUCHPAD_H #include "xlibtouchpad.h" #include "xcbatom.h" class SynapticsTouchpad : public QObject, public XlibTouchpad { Q_OBJECT public: SynapticsTouchpad(Display *display, int deviceId); + void setTouchpadOff(int touchpadOff) override; + int touchpadOff() override; + + XcbAtom &touchpadOffAtom() override; + protected: double getPropertyScale(const QString &name) const override; private: - XcbAtom m_capsAtom; + XcbAtom m_capsAtom, m_touchpadOffAtom; int m_resX, m_resY; QStringList m_scaleByResX, m_scaleByResY, m_toRadians; }; #endif // SYNAPTICSTOUCHPAD_H diff --git a/kcms/touchpad/src/backends/x11/xlibtouchpad.cpp b/kcms/touchpad/src/backends/x11/xlibtouchpad.cpp index 53eb24915..569e140fa 100644 --- a/kcms/touchpad/src/backends/x11/xlibtouchpad.cpp +++ b/kcms/touchpad/src/backends/x11/xlibtouchpad.cpp @@ -1,285 +1,262 @@ #include #include "xlibtouchpad.h" #include #include #include #include static QVariant negateVariant(const QVariant &value) { if (value.type() == QVariant::Double) { return QVariant(-value.toDouble()); } else if (value.type() == QVariant::Int) { return QVariant(-value.toInt()); } return value; } 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); } bool XlibTouchpad::applyConfig(const QVariantHash& p) { m_props.clear(); bool error = false; Q_FOREACH(const QString &name, m_supported) { QVariantHash::ConstIterator i = p.find(name); if (i == p.end()) { continue; } const Parameter *par = findParameter(name); if (par) { QVariant value(i.value()); double k = getPropertyScale(name); if (k != 1.0) { bool ok = false; value = QVariant(value.toDouble(&ok) * k); if (!ok) { error = true; continue; } } if (m_negate.contains(name)) { QVariantHash::ConstIterator i = p.find(m_negate[name]); if (i != p.end() && i.value().toBool()) { value = negateVariant(value); } } if (name == "CoastingSpeed") { QVariantHash::ConstIterator coastingEnabled = p.find("Coasting"); if (coastingEnabled != p.end() && !coastingEnabled.value().toBool()) { value = QVariant(0); } } if (!setParameter(par, value)) { error = true; } } } flush(); return !error; } bool XlibTouchpad::getConfig(QVariantHash& p) { if (m_supported.isEmpty()) { return false; } m_props.clear(); bool error = false; Q_FOREACH(const QString &name, m_supported) { const Parameter *par = findParameter(name); if (!par) { continue; } QVariant value(getParameter(par)); if (!value.isValid()) { error = true; continue; } double k = getPropertyScale(name); if (k != 1.0) { bool ok = false; value = QVariant(value.toDouble(&ok) / k); if (!ok) { error = true; continue; } } if (m_negate.contains(name)) { bool negative = value.toDouble() < 0.0; p[m_negate[name]] = QVariant(negative); if (negative) { value = negateVariant(value); } } if (name == "CoastingSpeed") { bool coasting = value.toDouble() != 0.0; p["Coasting"] = QVariant(coasting); if (!coasting) { continue; } } p[name] = value; } return !error; } 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, QSharedPointer( new XcbAtom(m_connection, param->prop_name))); } } for (const Parameter *p = props; p->name; p++) { if (getParameter(p).isValid()) { m_supported.append(p->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() { Q_FOREACH(const QLatin1String &name, m_changed) { m_props[name].set(); } m_changed.clear(); XFlush(m_display); } double XlibTouchpad::getPropertyScale(const QString& name) const { Q_UNUSED(name); return 1.0; } PropertyInfo* XlibTouchpad::getDevProperty(const QLatin1String& propName) { if (m_props.contains(propName)) { return &m_props[propName]; } if (!m_atoms.contains(propName) || !m_atoms[propName]) { return 0; } xcb_atom_t prop = m_atoms[propName]->atom(); if (!prop) { return 0; } PropertyInfo p(m_display, m_deviceId, prop, m_floatType.atom()); if (!p.b && !p.f && !p.i) { return 0; } 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); QVariant::Type convType = QVariant::Int; if (p->f) { convType = QVariant::Double; } else if (value.type() == QVariant::Double) { converted = QVariant(qRound(static_cast(value.toDouble()))); } if (!converted.convert(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::setEnabled(bool enable) { PropertyInfo enabled(m_display, m_deviceId, m_enabledAtom.atom(), 0); if (enabled.b && *(enabled.b) != enable) { *(enabled.b) = enable; enabled.set(); } flush(); } bool XlibTouchpad::enabled() { PropertyInfo enabled(m_display, m_deviceId, m_enabledAtom.atom(), 0); return enabled.value(0).toBool(); } - -void XlibTouchpad::setTouchpadOff(int touchpadOff) -{ - PropertyInfo off(m_display, m_deviceId, m_touchpadOffAtom.atom(), 0); - if (off.b && *(off.b) != touchpadOff) { - *(off.b) = touchpadOff; - off.set(); - } - - flush(); -} - -int XlibTouchpad::touchpadOff() -{ - PropertyInfo off(m_display, m_deviceId, m_touchpadOffAtom.atom(), 0); - return off.value(0).toInt(); -} - -XcbAtom& XlibTouchpad::touchpadOffAtom() -{ - return m_touchpadOffAtom; -} - const Parameter* XlibTouchpad::findParameter(const QString& name) { for (const Parameter *par = m_paramList; par->name; par++) { if (name == par->name) { return par; } } return 0; } diff --git a/kcms/touchpad/src/backends/x11/xlibtouchpad.h b/kcms/touchpad/src/backends/x11/xlibtouchpad.h index e6845156f..999c28092 100644 --- a/kcms/touchpad/src/backends/x11/xlibtouchpad.h +++ b/kcms/touchpad/src/backends/x11/xlibtouchpad.h @@ -1,92 +1,92 @@ /* * Copyright (C) 2015 Weng Xuetian * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef XLIBTOUCHPAD_H #define XLIBTOUCHPAD_H #include #include #include #include #include "xcbatom.h" #include "propertyinfo.h" enum ParaType { PT_INT, PT_BOOL, PT_DOUBLE }; struct Parameter { const char *name; /* Name of parameter */ enum ParaType type; /* Type of parameter */ double min_val; /* Minimum allowed value */ double max_val; /* Maximum allowed value */ const char *prop_name; /* Property name */ int prop_format; /* Property format (0 for floats) */ unsigned prop_offset; /* Offset inside property */ }; class XlibTouchpad { public: XlibTouchpad(Display *display, int deviceId); virtual ~XlibTouchpad() {} int deviceId() { return m_deviceId; } const QStringList &supportedParameters() const { return m_supported; } bool applyConfig(const QVariantHash &p); bool getConfig(QVariantHash &p); virtual bool getConfig() { return false; } virtual bool applyConfig() { return false; } virtual bool getDefaultConfig() { return false; } virtual bool isChangedConfig() { return false; } void setEnabled(bool enable); bool enabled(); - void setTouchpadOff(int touchpadOff); - int touchpadOff(); + virtual void setTouchpadOff(int touchpadOff) {} + virtual int touchpadOff() = 0; - XcbAtom &touchpadOffAtom(); + virtual XcbAtom &touchpadOffAtom() = 0; protected: void loadSupportedProperties(const Parameter *props); bool setParameter(const struct Parameter *, const QVariant &); QVariant getParameter(const struct Parameter *); struct PropertyInfo *getDevProperty(const QLatin1String &propName); void flush(); virtual double getPropertyScale(const QString &name) const; const Parameter * findParameter(const QString &name); Display *m_display; xcb_connection_t *m_connection; int m_deviceId; - XcbAtom m_floatType, m_enabledAtom, m_touchpadOffAtom; + XcbAtom m_floatType, m_enabledAtom; QMap > m_atoms; QMap m_negate; QMap m_props; QSet m_changed; QStringList m_supported; const struct Parameter *m_paramList; }; #endif