Commit 41b4b29d4aed16d44a8f9fc3097d5fac8dd449f9
- Diff rendering mode:
- inline
- side by side
CMakeLists.txt
(21 / 1)
|   | |||
| 20 | 20 | include_directories(${X11_X11_INCLUDE_PATH}) | |
| 21 | 21 | include_directories(${X11_Xinput_INCLUDE_PATH}) | |
| 22 | 22 | ||
| 23 | include(CheckPrototypeExists) | ||
| 24 | |||
| 25 | find_package(PkgConfig) | ||
| 26 | if(PKG_CONFIG_FOUND) | ||
| 27 | # rely on pkg-config if possible | ||
| 28 | pkg_search_module(UDEV "libudev") | ||
| 29 | else(PKG_CONFIG_FOUND) | ||
| 30 | # if pkg-config is not available, check if we can compile against libudev | ||
| 31 | # in standard include and library directories | ||
| 32 | check_prototype_exists(udev_new libudev.h UDEV_FOUND) | ||
| 33 | set(UDEV_LIBRARIES "udev") | ||
| 34 | endif(PKG_CONFIG_FOUND) | ||
| 35 | if(UDEV_FOUND) | ||
| 36 | include_directories(${UDEV_INCLUDE_DIRS}) | ||
| 37 | link_directories(${UDEV_LIBRARY_DIRS}) | ||
| 38 | endif(UDEV_FOUND) | ||
| 39 | |||
| 23 | 40 | option(WITH_XINPUT2 "Search for XInput2" OFF) | |
| 24 | 41 | ||
| 25 | 42 | # determine availability of XInput device property API | |
| 26 | include(CheckPrototypeExists) | ||
| 27 | 43 | check_prototype_exists(XChangeDeviceProperty X11/extensions/XInput.h | |
| 28 | 44 | HAVE_DEVICE_PROPERTIES) | |
| 29 | 45 | if(WITH_XINPUT2) | |
| … | … | ||
| 55 | 55 | macro_log_feature(HAVE_DEVICE_PROPERTIES_V2 "Device properties 2" | |
| 56 | 56 | "XInput device properties 2.x" "http://www.x.org/") | |
| 57 | 57 | macro_bool_to_01(HAVE_DEVICE_PROPERTIES_V2 HAVE_XINPUT2) | |
| 58 | # udev | ||
| 59 | macro_log_feature(UDEV_FOUND "libudev" "UDev library" | ||
| 60 | "http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html" | ||
| 61 | TRUE) | ||
| 58 | 62 | ||
| 59 | 63 | configure_file( | |
| 60 | 64 | "${CMAKE_CURRENT_SOURCE_DIR}/config-synaptiks.h.cmake" |
daemon/CMakeLists.txt
(1 / 1)
|   | |||
| 12 | 12 | kde4_add_plugin(kded_synaptiks ${kded_synaptiks_sources}) | |
| 13 | 13 | ||
| 14 | 14 | target_link_libraries(kded_synaptiks | |
| 15 | ${KDE4_KDEUI_LIBS} ${X11_X11_LIB} ${X11_Xinput_LIB}) | ||
| 15 | ${KDE4_KDEUI_LIBS} ${X11_X11_LIB} ${X11_Xinput_LIB} ${UDEV_LIBRARIES}) | ||
| 16 | 16 | ||
| 17 | 17 | install(TARGETS kded_synaptiks DESTINATION ${PLUGIN_INSTALL_DIR}) | |
| 18 | 18 | install(FILES synaptiks.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded) |
daemon/mousedevicesmonitor.cpp
(109 / 124)
|   | |||
| 27 | 27 | * POSSIBILITY OF SUCH DAMAGE. | |
| 28 | 28 | */ | |
| 29 | 29 | ||
| 30 | #define QT_NO_CAST_TO_ASCII 1 | ||
| 30 | 31 | #include "mousedevicesmonitor.h" | |
| 32 | #include "qudevpointer.h" | ||
| 31 | 33 | #include <KDebug> | |
| 32 | #include <QtDBus/QDBusInterface> | ||
| 33 | #include <QtDBus/QDBusServiceWatcher> | ||
| 34 | #include <QtDBus/QDBusReply> | ||
| 35 | 34 | #include <QtCore/QStringList> | |
| 36 | #include <QtCore/QPointer> | ||
| 35 | #include <QtCore/QSocketNotifier> | ||
| 37 | 36 | ||
| 38 | 37 | ||
| 39 | 38 | using namespace synaptiks; | |
| 40 | 39 | ||
| 41 | 40 | ||
| 42 | static const char HAL_SERVICE[] = "org.freedesktop.Hal"; | ||
| 43 | static const char HAL_MANAGER_PATH[] = "/org/freedesktop/Hal/Manager"; | ||
| 44 | static const char HAL_MANAGER_IFACE[] = "org.freedesktop.Hal.Manager"; | ||
| 45 | static const char HAL_DEVICE_IFACE[] = "org.freedesktop.Hal.Device"; | ||
| 46 | |||
| 47 | |||
| 48 | #define DEVICE_INTERFACE(device, udi) \ | ||
| 49 | QDBusInterface device(HAL_SERVICE, udi, HAL_DEVICE_IFACE, \ | ||
| 50 | QDBusConnection::systemBus()); \ | ||
| 51 | |||
| 52 | |||
| 53 | 41 | namespace synaptiks { | |
| 54 | 42 | class MouseDevicesMonitorPrivate { | |
| 55 | 43 | public: | |
| … | … | ||
| 47 | 47 | ||
| 48 | 48 | virtual ~MouseDevicesMonitorPrivate() {}; | |
| 49 | 49 | ||
| 50 | void _k_deviceAdded(const QString &udi); | ||
| 51 | void _k_deviceRemoved(const QString &udi); | ||
| 52 | void _k_halRegistered(); | ||
| 53 | void _k_halUnregistered(); | ||
| 54 | QStringList pluggedMouseDevices() const; | ||
| 55 | bool queryCapability(const QString &udi, | ||
| 56 | const QString &capability) const; | ||
| 57 | QString getProperty(const QString &udi, | ||
| 58 | const QString &property) const; | ||
| 50 | void _k_udevDataAvailable(); | ||
| 59 | 51 | ||
| 60 | QPointer<QDBusInterface> hal_manager; | ||
| 61 | QDBusServiceWatcher *hal_watcher; | ||
| 52 | QUDevDevicePtr findDeviceBySerial(const QByteArray &serial) const; | ||
| 53 | |||
| 62 | 54 | QSet<QString> mouseDevices; | |
| 55 | QUDevContextPtr context; | ||
| 56 | QUDevMonitorPtr monitor; | ||
| 57 | QSocketNotifier *monitorNotifier; | ||
| 63 | 58 | MouseDevicesMonitor *q_ptr; | |
| 64 | 59 | }; | |
| 65 | 60 | } | |
| … | … | ||
| 63 | 63 | MouseDevicesMonitorPrivate::MouseDevicesMonitorPrivate( | |
| 64 | 64 | MouseDevicesMonitor *qq): q_ptr(qq) { | |
| 65 | 65 | Q_Q(MouseDevicesMonitor); | |
| 66 | this->hal_manager = new QDBusInterface( | ||
| 67 | HAL_SERVICE, HAL_MANAGER_PATH, HAL_MANAGER_IFACE, QDBusConnection::systemBus(), q); | ||
| 68 | q->connect(this->hal_manager, SIGNAL(DeviceAdded(const QString&)), | ||
| 69 | SLOT(_k_deviceAdded(const QString&))); | ||
| 70 | q->connect(this->hal_manager, SIGNAL(DeviceRemoved(const QString&)), | ||
| 71 | SLOT(_k_deviceRemoved(const QString&))); | ||
| 72 | // watch the HAL service for (un-)registration to re-initialize the | ||
| 73 | // connection to this service if required (e.g. HAL was restarted due to | ||
| 74 | // an update or HAL crashed or whatever) | ||
| 75 | this->hal_watcher = new QDBusServiceWatcher(q); | ||
| 76 | this->hal_watcher->addWatchedService(HAL_SERVICE); | ||
| 77 | q->connect(this->hal_watcher, SIGNAL(serviceRegistered(const QString&)), | ||
| 78 | SLOT(_k_halRegistered())); | ||
| 79 | q->connect( | ||
| 80 | this->hal_watcher, SIGNAL(serviceUnregistered(const QString&)), | ||
| 81 | SLOT(_k_halUnregistered())); | ||
| 82 | this->hal_watcher->setConnection(this->hal_manager->connection()); | ||
| 83 | this->mouseDevices = QSet<QString>::fromList( | ||
| 84 | this->pluggedMouseDevices()); | ||
| 66 | this->context = udev_new(); | ||
| 67 | this->monitor = udev_monitor_new_from_netlink(this->context, "udev"); | ||
| 68 | this->monitorNotifier = new QSocketNotifier( | ||
| 69 | udev_monitor_get_fd(this->monitor), QSocketNotifier::Read, q); | ||
| 70 | q->connect(this->monitorNotifier, SIGNAL(activated(int)), | ||
| 71 | SLOT(_k_udevDataAvailable())); | ||
| 72 | udev_monitor_filter_add_match_subsystem_devtype( | ||
| 73 | this->monitor, "input", 0); | ||
| 74 | udev_monitor_enable_receiving(this->monitor); | ||
| 85 | 75 | } | |
| 86 | 76 | ||
| 87 | void MouseDevicesMonitorPrivate::_k_deviceAdded(const QString& udi) { | ||
| 88 | if (this->queryCapability(udi, "input.mouse")) { | ||
| 89 | Q_Q(MouseDevicesMonitor); | ||
| 90 | this->mouseDevices.insert(udi); | ||
| 91 | emit q->mousePlugged(udi); | ||
| 92 | } | ||
| 77 | /** | ||
| 78 | * @return @c true, if @p device is a mouse (not a touchpad!), @c false | ||
| 79 | * otherwise | ||
| 80 | */ | ||
| 81 | inline bool isMouse(const QUDevDevicePtr &device) { | ||
| 82 | QByteArray sysName = udev_device_get_sysname(device); | ||
| 83 | // check, if the device really is a mouse | ||
| 84 | QByteArray isMouse = udev_device_get_property_value( | ||
| 85 | device, "ID_INPUT_MOUSE"); | ||
| 86 | QByteArray isTouchpad = udev_device_get_property_value( | ||
| 87 | device, "ID_INPUT_TOUCHPAD"); | ||
| 88 | return (isMouse.toInt() && (!isTouchpad.toInt()) | ||
| 89 | && sysName.startsWith("mouse")); | ||
| 93 | 90 | } | |
| 94 | 91 | ||
| 95 | void MouseDevicesMonitorPrivate::_k_deviceRemoved(const QString& udi) { | ||
| 96 | if (this->mouseDevices.contains(udi)) { | ||
| 97 | Q_Q(MouseDevicesMonitor); | ||
| 98 | this->mouseDevices.remove(udi); | ||
| 99 | emit q->mouseUnplugged(udi); | ||
| 100 | } | ||
| 92 | inline QByteArray getSerial(const QUDevDevicePtr &device) { | ||
| 93 | return udev_device_get_property_value(device, "ID_SERIAL"); | ||
| 101 | 94 | } | |
| 102 | 95 | ||
| 103 | void MouseDevicesMonitorPrivate::_k_halRegistered() { | ||
| 104 | // HAL is available now, create the interface and "connect" all mouses | ||
| 96 | void MouseDevicesMonitorPrivate::_k_udevDataAvailable() { | ||
| 105 | 97 | Q_Q(MouseDevicesMonitor); | |
| 106 | this->hal_manager = new QDBusInterface( | ||
| 107 | HAL_SERVICE, HAL_MANAGER_PATH, HAL_MANAGER_IFACE, | ||
| 108 | this->hal_watcher->connection(), q); | ||
| 109 | this->mouseDevices = QSet<QString>::fromList( | ||
| 110 | this->pluggedMouseDevices()); | ||
| 111 | foreach (const QString &udi, this->mouseDevices) { | ||
| 112 | emit q->mousePlugged(udi); | ||
| 98 | kDebug() << "udev data available"; | ||
| 99 | QUDevDevicePtr device = udev_monitor_receive_device(this->monitor); | ||
| 100 | if (!device) | ||
| 101 | return; | ||
| 102 | kDebug() << "udev device received"; | ||
| 103 | if (isMouse(device)) { | ||
| 104 | QByteArray action = udev_device_get_action(device); | ||
| 105 | QByteArray serial = getSerial(device); | ||
| 106 | if (action == "add") { | ||
| 107 | kDebug() << "mouse added:" << serial; | ||
| 108 | emit q->mousePlugged(QString::fromAscii(serial)); | ||
| 109 | } else if (action == "remove") { | ||
| 110 | kDebug() << "mouse removed:" << serial; | ||
| 111 | emit q->mouseUnplugged(QString::fromAscii(serial)); | ||
| 112 | } | ||
| 113 | 113 | } | |
| 114 | 114 | } | |
| 115 | 115 | ||
| 116 | void MouseDevicesMonitorPrivate::_k_halUnregistered() { | ||
| 117 | // HAL is gone, so we consider all mouses being disconnected now, just | ||
| 118 | // to be on the safe side, because we can't montor mouse devices | ||
| 119 | // anymore. | ||
| 120 | Q_Q(MouseDevicesMonitor); | ||
| 121 | foreach (const QString &udi, this->mouseDevices) { | ||
| 122 | emit q->mouseUnplugged(udi); | ||
| 116 | QUDevDevicePtr MouseDevicesMonitorPrivate::findDeviceBySerial( | ||
| 117 | const QByteArray &serial) const { | ||
| 118 | kDebug() << "searching device for serial" << serial; | ||
| 119 | QUDevDevicePtr device; | ||
| 120 | QUDevEnumeratePtr enumerator = udev_enumerate_new(this->context); | ||
| 121 | Q_ASSERT(enumerator); | ||
| 122 | // filter for the given serial number | ||
| 123 | udev_enumerate_add_match_subsystem(enumerator, "input"); | ||
| 124 | udev_enumerate_add_match_property(enumerator, "ID_SERIAL", serial); | ||
| 125 | udev_enumerate_scan_devices(enumerator); | ||
| 126 | // iterate over all matching devices | ||
| 127 | udev_list_entry *device_entries = | ||
| 128 | udev_enumerate_get_list_entry(enumerator); | ||
| 129 | udev_list_entry *current_entry = 0; | ||
| 130 | udev_list_entry_foreach(current_entry, device_entries) { | ||
| 131 | device = udev_device_new_from_syspath( | ||
| 132 | this->context, udev_list_entry_get_name(current_entry)); | ||
| 133 | // we have a matching mouse device | ||
| 134 | if (device && isMouse(device)) { | ||
| 135 | kDebug() << "found device for serial:" << serial; | ||
| 136 | break; | ||
| 137 | } | ||
| 123 | 138 | } | |
| 124 | this->mouseDevices.clear(); | ||
| 125 | // delete the now invalid interface | ||
| 126 | delete this->hal_manager; | ||
| 139 | return device; | ||
| 127 | 140 | } | |
| 128 | 141 | ||
| 129 | QStringList MouseDevicesMonitorPrivate::pluggedMouseDevices() const { | ||
| 130 | kDebug() << "enumerating plugged devices"; | ||
| 131 | if (!this->hal_manager) | ||
| 132 | return QStringList(); | ||
| 133 | QDBusReply<QStringList> devices = this->hal_manager->call( | ||
| 134 | "FindDeviceByCapability", "input.mouse"); | ||
| 135 | if (!devices.isValid()) { | ||
| 136 | kError() << "dbus error:" << devices.error().name() | ||
| 137 | << ":" << devices.error().message(); | ||
| 138 | return QStringList(); | ||
| 139 | } else | ||
| 140 | return devices.value(); | ||
| 141 | } | ||
| 142 | |||
| 143 | bool MouseDevicesMonitorPrivate::queryCapability( | ||
| 144 | const QString &udi, const QString &capability) const { | ||
| 145 | DEVICE_INTERFACE(device, udi); | ||
| 146 | QDBusReply<bool> hasCapability = device.call("QueryCapability", | ||
| 147 | capability); | ||
| 148 | if (!hasCapability.isValid()) { | ||
| 149 | kError() << "dbus error:" << hasCapability.error().name() | ||
| 150 | << ":" << hasCapability.error().message(); | ||
| 151 | return false; | ||
| 152 | } else { | ||
| 153 | return hasCapability.value(); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | QString MouseDevicesMonitorPrivate::getProperty( | ||
| 158 | const QString &udi, const QString &property) const { | ||
| 159 | DEVICE_INTERFACE(device, udi); | ||
| 160 | QDBusReply<QString> value = device.call("GetProperty", property); | ||
| 161 | if (!value.isValid()) { | ||
| 162 | kError() << "dbus error:" << value.error().name() | ||
| 163 | << ":" << value.error().message(); | ||
| 164 | return QString(); | ||
| 165 | } else { | ||
| 166 | return value.value(); | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | 142 | MouseDevicesMonitor::MouseDevicesMonitor(QObject *parent): | |
| 171 | 143 | QObject(parent), d_ptr(new MouseDevicesMonitorPrivate(this)) {} | |
| 172 | 144 | ||
| … | … | ||
| 148 | 148 | ||
| 149 | 149 | QStringList MouseDevicesMonitor::pluggedMouseDevices() const { | |
| 150 | 150 | Q_D(const MouseDevicesMonitor); | |
| 151 | return d->pluggedMouseDevices(); | ||
| 151 | QStringList devices; | ||
| 152 | kDebug() << "enumerating plugged devices"; | ||
| 153 | QUDevEnumeratePtr enumerator = udev_enumerate_new(d->context); | ||
| 154 | Q_ASSERT(enumerator); | ||
| 155 | // filter for mouse devices | ||
| 156 | udev_enumerate_add_match_subsystem(enumerator, "input"); | ||
| 157 | udev_enumerate_add_match_property(enumerator, "ID_INPUT_MOUSE", "1"); | ||
| 158 | udev_enumerate_scan_devices(enumerator); | ||
| 159 | udev_list_entry *device_entries = | ||
| 160 | udev_enumerate_get_list_entry(enumerator); | ||
| 161 | // iterate over all mouse devices | ||
| 162 | udev_list_entry *current_entry = 0; | ||
| 163 | udev_list_entry_foreach(current_entry, device_entries) { | ||
| 164 | QUDevDevicePtr device = udev_device_new_from_syspath( | ||
| 165 | d->context, udev_list_entry_get_name(current_entry)); | ||
| 166 | // a true mouse device | ||
| 167 | if (device && isMouse(device)) { | ||
| 168 | QByteArray serial = getSerial(device); | ||
| 169 | kDebug() << "found device with serial" << serial; | ||
| 170 | devices << QString::fromAscii(serial); | ||
| 171 | } | ||
| 172 | } | ||
| 173 | return devices; | ||
| 152 | 174 | } | |
| 153 | 175 | ||
| 154 | 176 | QString MouseDevicesMonitor::productName(const QString &id) const { | |
| 155 | 177 | Q_D(const MouseDevicesMonitor); | |
| 156 | return d->getProperty(id, "info.product"); | ||
| 157 | } | ||
| 158 | |||
| 159 | bool MouseDevicesMonitor::isTouchpad(const QString &id) const { | ||
| 160 | Q_D(const MouseDevicesMonitor); | ||
| 161 | return d->queryCapability(id, "input.touchpad"); | ||
| 178 | kDebug() << "querying product name for serial" << id; | ||
| 179 | QString name; | ||
| 180 | QUDevDevicePtr device = d->findDeviceBySerial(id.toAscii()); | ||
| 181 | if (device) { | ||
| 182 | // no need for a guarded pointer here, the parent device is freed | ||
| 183 | // together with the child | ||
| 184 | udev_device *parent = udev_device_get_parent(device); | ||
| 185 | if (parent) { | ||
| 186 | kDebug() << "got" << name << "for serial" << id; | ||
| 187 | name = QString::fromAscii( | ||
| 188 | udev_device_get_property_value(parent, "NAME")); | ||
| 189 | } | ||
| 190 | } | ||
| 191 | return name; | ||
| 162 | 192 | } | |
| 163 | 193 | ||
| 164 | 194 | #include "moc_mousedevicesmonitor.cpp" |
daemon/mousedevicesmonitor.h
(2 / 19)
|   | |||
| 38 | 38 | */ | |
| 39 | 39 | ||
| 40 | 40 | #include <QtCore/QObject> | |
| 41 | #include <QtCore/QString> | ||
| 41 | 42 | ||
| 42 | 43 | namespace synaptiks { | |
| 43 | 44 | ||
| … | … | ||
| 116 | 116 | */ | |
| 117 | 117 | Q_SCRIPTABLE QString productName(const QString &id) const; | |
| 118 | 118 | ||
| 119 | /** | ||
| 120 | * @brief Is the given device a touchpad? | ||
| 121 | * | ||
| 122 | * @warning | ||
| 123 | * | ||
| 124 | * Only use this method with @em plugged devices. This class cannot | ||
| 125 | * obtain information about devices, which are not currently | ||
| 126 | * plugged. | ||
| 127 | * | ||
| 128 | * @param id the device id | ||
| 129 | * @return @c true, if the given device is a touchpad, @c false | ||
| 130 | * otherwise | ||
| 131 | */ | ||
| 132 | Q_SCRIPTABLE bool isTouchpad(const QString &id) const; | ||
| 133 | |||
| 134 | 119 | Q_SIGNALS: | |
| 135 | 120 | /** | |
| 136 | 121 | * @brief A mouse device was plugged. | |
| … | … | ||
| 141 | 141 | Q_DECLARE_PRIVATE(MouseDevicesMonitor) | |
| 142 | 142 | Q_DISABLE_COPY(MouseDevicesMonitor) | |
| 143 | 143 | ||
| 144 | Q_PRIVATE_SLOT(d_func(), void _k_deviceAdded(const QString&)) | ||
| 145 | Q_PRIVATE_SLOT(d_func(), void _k_deviceRemoved(const QString&)) | ||
| 146 | Q_PRIVATE_SLOT(d_func(), void _k_halRegistered()) | ||
| 147 | Q_PRIVATE_SLOT(d_func(), void _k_halUnregistered()) | ||
| 144 | Q_PRIVATE_SLOT(d_func(), void _k_udevDataAvailable()) | ||
| 148 | 145 | ||
| 149 | 146 | MouseDevicesMonitorPrivate * const d_ptr; | |
| 150 | 147 | }; |
|   | |||
| 14 | 14 | <arg type="s" direction="out"/> | |
| 15 | 15 | <arg name="id" type="s" direction="in"/> | |
| 16 | 16 | </method> | |
| 17 | <method name="isTouchpad"> | ||
| 18 | <arg type="b" direction="out"/> | ||
| 19 | <arg name="id" type="s" direction="in"/> | ||
| 20 | </method> | ||
| 21 | 17 | </interface> | |
| 22 | 18 | </node> |
daemon/qudevpointer.h
(177 / 0)
|   | |||
| 1 | /* | ||
| 2 | * synaptiks -- a touchpad control tool | ||
| 3 | * | ||
| 4 | * | ||
| 5 | * Copyright (C) 2010 Sebastian Wiesner <lunaryorn@googlemail.com> | ||
| 6 | * All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions are met: | ||
| 10 | * | ||
| 11 | * 1. Redistributions of source code must retain the above copyright notice, | ||
| 12 | * this list of conditions and the following disclaimer. | ||
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in the | ||
| 15 | * documentation and/or other materials provided with the distribution. | ||
| 16 | * | ||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
| 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 27 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 28 | */ | ||
| 29 | |||
| 30 | #ifndef QUDEVPOINTER_H | ||
| 31 | #define QUDEVPOINTER_H | ||
| 32 | |||
| 33 | extern "C" { | ||
| 34 | #include <libudev.h> | ||
| 35 | } | ||
| 36 | |||
| 37 | /** | ||
| 38 | * @brief A managed pointer a-top of libudev | ||
| 39 | * | ||
| 40 | * @param T the pointer type | ||
| 41 | * @param Ref a function which increases the reference count on T* | ||
| 42 | * @param Unref a function which decreases the reference count on T* | ||
| 43 | */ | ||
| 44 | template<class T, T* (*Ref)(T*), void (*Unref)(T*)> class QUDevPointer { | ||
| 45 | public: | ||
| 46 | /** | ||
| 47 | * @brief Default constructor | ||
| 48 | */ | ||
| 49 | QUDevPointer(): m_ptr(0) { | ||
| 50 | } | ||
| 51 | |||
| 52 | /** | ||
| 53 | * @brief Copy constructor. | ||
| 54 | * | ||
| 55 | * Copy internal pointer of @p other to this object and increase ref | ||
| 56 | * count. | ||
| 57 | */ | ||
| 58 | QUDevPointer(const QUDevPointer<T, Ref, Unref> &other) { | ||
| 59 | this->m_ptr = other.m_ptr; | ||
| 60 | Ref(this->m_ptr); | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * @brief Construct a managed udev pointer from a raw pointer. | ||
| 65 | * | ||
| 66 | * The reference count of @p ptr is @em not increased. | ||
| 67 | * | ||
| 68 | * @param ptr the raw pointer | ||
| 69 | */ | ||
| 70 | QUDevPointer(T *ptr) { | ||
| 71 | this->m_ptr = ptr; | ||
| 72 | } | ||
| 73 | |||
| 74 | /** | ||
| 75 | * @brief Destroy this pointer and decrease reference count on internal | ||
| 76 | * pointer. | ||
| 77 | */ | ||
| 78 | ~QUDevPointer() { | ||
| 79 | Unref(this->m_ptr); | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * @brief Assignment operator. | ||
| 84 | * | ||
| 85 | * Decrease reference count on the current internal pointer of this | ||
| 86 | * object (if it has one), copy the internal pointer of @p other into | ||
| 87 | * this object, and increase the reference count on the new internal | ||
| 88 | * pointer. | ||
| 89 | * | ||
| 90 | * @param other managed pointer to assign to this pointer | ||
| 91 | */ | ||
| 92 | QUDevPointer &operator=(const QUDevPointer<T, Ref, Unref> &other) { | ||
| 93 | if (this->m_ptr) | ||
| 94 | Unref(this->m_ptr); | ||
| 95 | this->m_ptr = other->m_ptr; | ||
| 96 | Ref(this->m_ptr); | ||
| 97 | return *this; | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Decrease reference count on the current internal pointer of this | ||
| 102 | * object (if it has one) and set internal pointer to @p ptr. | ||
| 103 | * | ||
| 104 | * @param ptr the raw pointer to assign to this pointer | ||
| 105 | */ | ||
| 106 | QUDevPointer &operator=(T *ptr) { | ||
| 107 | if (this->m_ptr) | ||
| 108 | Unref(this->m_ptr); | ||
| 109 | this->m_ptr = ptr; | ||
| 110 | return *this; | ||
| 111 | } | ||
| 112 | |||
| 113 | /** | ||
| 114 | * @brief Forcibly increase the reference count on the underlying | ||
| 115 | * pointer. | ||
| 116 | */ | ||
| 117 | void ref() { | ||
| 118 | Ref(this->m_ptr); | ||
| 119 | } | ||
| 120 | |||
| 121 | /** | ||
| 122 | * @brief Conversion operator to T* | ||
| 123 | * | ||
| 124 | * A managed udev pointer implicitly converts to T*. | ||
| 125 | * | ||
| 126 | * @return the underlying raw pointer | ||
| 127 | */ | ||
| 128 | operator T*() const { | ||
| 129 | return this->m_ptr; | ||
| 130 | } | ||
| 131 | |||
| 132 | /** | ||
| 133 | * @brief Get the underyling raw pointer. | ||
| 134 | * | ||
| 135 | * @return the underlying raw pointer. | ||
| 136 | */ | ||
| 137 | T *data() const { | ||
| 138 | return this->m_ptr; | ||
| 139 | } | ||
| 140 | |||
| 141 | /** | ||
| 142 | * @brief Implicit conversion to bool. | ||
| 143 | * | ||
| 144 | * @return @c true, if the internal pointer is not 0, @c false | ||
| 145 | * otherwise. | ||
| 146 | */ | ||
| 147 | operator bool() const { | ||
| 148 | return this->m_ptr; | ||
| 149 | } | ||
| 150 | |||
| 151 | /** | ||
| 152 | * @brief Test, if this pointer is 0. | ||
| 153 | * | ||
| 154 | * @return @c true, if the internal pointer is not 0, @false otherwise. | ||
| 155 | */ | ||
| 156 | bool isNull() const { | ||
| 157 | return !this->m_ptr; | ||
| 158 | } | ||
| 159 | |||
| 160 | private: | ||
| 161 | /** internal pointer */ | ||
| 162 | T *m_ptr; | ||
| 163 | }; | ||
| 164 | |||
| 165 | /** Managed pointer to @c udev_context* */ | ||
| 166 | typedef QUDevPointer<struct udev, udev_ref, udev_unref> QUDevContextPtr; | ||
| 167 | /** Managed pointer to @c udev_enumerate* */ | ||
| 168 | typedef QUDevPointer<struct udev_enumerate, udev_enumerate_ref, | ||
| 169 | udev_enumerate_unref> QUDevEnumeratePtr; | ||
| 170 | /** Managed pointer to @c udev_monitor* */ | ||
| 171 | typedef QUDevPointer<struct udev_monitor, udev_monitor_ref, | ||
| 172 | udev_monitor_unref> QUDevMonitorPtr; | ||
| 173 | /** Managed pointer to @c udev_device* */ | ||
| 174 | typedef QUDevPointer<struct udev_device, udev_device_ref, | ||
| 175 | udev_device_unref> QUDevDevicePtr; | ||
| 176 | |||
| 177 | #endif /* QUDEVPOINTER_H */ |
daemon/touchpadmanager.cpp
(1 / 2)
|   | |||
| 64 | 64 | } | |
| 65 | 65 | ||
| 66 | 66 | bool shallIgnoreMouse(const QString &mouse) { | |
| 67 | return (this->mouseDevices->isTouchpad(mouse) || | ||
| 68 | this->ignoredMouseDevices.contains(mouse) || | ||
| 67 | return (this->ignoredMouseDevices.contains(mouse) || | ||
| 69 | 68 | // don't register the same mouse twice | |
| 70 | 69 | this->pluggedMouses.contains(mouse)); | |
| 71 | 70 | } |
kcmodule/mousedevicesmodel.cpp
(20 / 54)
|   | |||
| 52 | 52 | ||
| 53 | 53 | void resetDeviceIndex(); | |
| 54 | 54 | ||
| 55 | void _k_mousePlugged(const QString &udi); | ||
| 56 | void _k_mouseUnplugged(const QString &udi); | ||
| 55 | void _k_mousePlugged(const QString &id); | ||
| 56 | void _k_mouseUnplugged(const QString &id); | ||
| 57 | 57 | ||
| 58 | /** | ||
| 59 | * Check, whether udi may be added to the device index. | ||
| 60 | * | ||
| 61 | * A device may be added, if ignoreTouchpads is @c false or the | ||
| 62 | * device is not a touchpad. | ||
| 63 | * | ||
| 64 | * @return @c true, if the device may be added, @c false otherwise | ||
| 65 | */ | ||
| 66 | bool mayAddDevice(const QString &udi) { | ||
| 67 | if (this->touchpadsIgnored) { | ||
| 68 | QDBusReply<bool> isTouchpad = | ||
| 69 | this->devices->call("isTouchpad", udi); | ||
| 70 | return !(isTouchpad.isValid() && isTouchpad.value()); | ||
| 71 | } | ||
| 72 | return true; | ||
| 73 | }; | ||
| 74 | |||
| 75 | 58 | MouseDevicesModel *q_ptr; | |
| 76 | 59 | QDBusInterface *devices; | |
| 77 | 60 | QStringList deviceIndex; | |
| … | … | ||
| 79 | 79 | } | |
| 80 | 80 | } | |
| 81 | 81 | ||
| 82 | void MouseDevicesModelPrivate::_k_mousePlugged(const QString &udi) { | ||
| 82 | void MouseDevicesModelPrivate::_k_mousePlugged(const QString &id) { | ||
| 83 | 83 | Q_Q(MouseDevicesModel); | |
| 84 | if (this->mayAddDevice(udi)) { | ||
| 85 | int position = q->rowCount(); | ||
| 86 | q->beginInsertRows(QModelIndex(), position, position); | ||
| 87 | this->deviceIndex.append(udi); | ||
| 88 | q->endInsertRows(); | ||
| 89 | } | ||
| 84 | int position = q->rowCount(); | ||
| 85 | q->beginInsertRows(QModelIndex(), position, position); | ||
| 86 | this->deviceIndex.append(id); | ||
| 87 | q->endInsertRows(); | ||
| 90 | 88 | } | |
| 91 | 89 | ||
| 92 | void MouseDevicesModelPrivate::_k_mouseUnplugged(const QString &udi) { | ||
| 90 | void MouseDevicesModelPrivate::_k_mouseUnplugged(const QString &id) { | ||
| 93 | 91 | Q_Q(MouseDevicesModel); | |
| 94 | int position = this->deviceIndex.indexOf(udi); | ||
| 92 | int position = this->deviceIndex.indexOf(id); | ||
| 95 | 93 | if (position >= 0) { | |
| 96 | 94 | q->beginRemoveRows(QModelIndex(), position, position); | |
| 97 | 95 | this->deviceIndex.removeAt(position); | |
| … | … | ||
| 103 | 103 | this->devices->call("pluggedMouseDevices"); | |
| 104 | 104 | if (!pluggedMouses.isValid()) | |
| 105 | 105 | return; | |
| 106 | foreach (const QString &udi, pluggedMouses.value()) { | ||
| 107 | if (this->mayAddDevice(udi)) { | ||
| 108 | this->deviceIndex.append(udi); | ||
| 109 | } | ||
| 106 | foreach (const QString &id, pluggedMouses.value()) { | ||
| 107 | this->deviceIndex.append(id); | ||
| 110 | 108 | } | |
| 111 | 109 | } | |
| 112 | 110 | ||
| … | … | ||
| 131 | 131 | QVariant MouseDevicesModel::data(const QModelIndex &index, int role) const { | |
| 132 | 132 | Q_D(const MouseDevicesModel); | |
| 133 | 133 | if (index.isValid()) { | |
| 134 | QString udi = d->deviceIndex.at(index.row()); | ||
| 134 | QString id = d->deviceIndex.at(index.row()); | ||
| 135 | 135 | QDBusReply<QString> productName = | |
| 136 | d->devices->call("productName", udi); | ||
| 136 | d->devices->call("productName", id); | ||
| 137 | 137 | switch (role) { | |
| 138 | 138 | case Qt::DisplayRole: | |
| 139 | 139 | if (productName.isValid()) | |
| … | … | ||
| 141 | 141 | else | |
| 142 | 142 | return QString(); | |
| 143 | 143 | case Qt::ToolTipRole: | |
| 144 | return udi; | ||
| 144 | return id; | ||
| 145 | 145 | case Qt::CheckStateRole: | |
| 146 | if (d->checkedDevices.contains(udi)) { | ||
| 146 | if (d->checkedDevices.contains(id)) { | ||
| 147 | 147 | return Qt::Checked; | |
| 148 | 148 | } else { | |
| 149 | 149 | return Qt::Unchecked; | |
| … | … | ||
| 161 | 161 | Q_D(MouseDevicesModel); | |
| 162 | 162 | bool changed = false; | |
| 163 | 163 | if (index.isValid() && role == Qt::CheckStateRole) { | |
| 164 | QString udi = d->deviceIndex.at(index.row()); | ||
| 164 | QString id = d->deviceIndex.at(index.row()); | ||
| 165 | 165 | int state = value.toInt(); | |
| 166 | 166 | if (state == Qt::Checked) { | |
| 167 | kDebug() << "checking device" << udi; | ||
| 168 | d->checkedDevices.insert(udi); | ||
| 167 | kDebug() << "checking device" << id; | ||
| 168 | d->checkedDevices.insert(id); | ||
| 169 | 169 | changed = true; | |
| 170 | 170 | } else if (state == Qt::Unchecked) { | |
| 171 | kDebug() << "unchecking device" << udi; | ||
| 172 | d->checkedDevices.remove(udi); | ||
| 171 | kDebug() << "unchecking device" << id; | ||
| 172 | d->checkedDevices.remove(id); | ||
| 173 | 173 | changed = true; | |
| 174 | 174 | } | |
| 175 | 175 | } | |
| … | … | ||
| 178 | 178 | emit this->checkedDevicesChanged(this->checkedDevices()); | |
| 179 | 179 | } | |
| 180 | 180 | return changed; | |
| 181 | } | ||
| 182 | |||
| 183 | bool MouseDevicesModel::touchpadsIgnored() const { | ||
| 184 | Q_D(const MouseDevicesModel); | ||
| 185 | return d->touchpadsIgnored; | ||
| 186 | } | ||
| 187 | |||
| 188 | void MouseDevicesModel::setTouchpadsIgnored(bool ignore) { | ||
| 189 | Q_D(MouseDevicesModel); | ||
| 190 | if (this->touchpadsIgnored() != ignore) { | ||
| 191 | d->touchpadsIgnored = ignore; | ||
| 192 | d->resetDeviceIndex(); | ||
| 193 | } | ||
| 194 | 181 | } | |
| 195 | 182 | ||
| 196 | 183 | QStringList MouseDevicesModel::checkedDevices() const { |
kcmodule/mousedevicesmodel.h
(1 / 33)
|   | |||
| 2 | 2 | * synaptiks -- a touchpad control tool | |
| 3 | 3 | * | |
| 4 | 4 | * | |
| 5 | * Copyright (C) 2009 Sebastian Wiesner <lunaryorn@googlemail.com> | ||
| 5 | * Copyright (C) 2009, 2010 Sebastian Wiesner <lunaryorn@googlemail.com> | ||
| 6 | 6 | * All rights reserved. | |
| 7 | 7 | * | |
| 8 | 8 | * Redistribution and use in source and binary forms, with or without | |
| … | … | ||
| 47 | 47 | */ | |
| 48 | 48 | class MouseDevicesModel: public QAbstractListModel { | |
| 49 | 49 | Q_OBJECT | |
| 50 | /** | ||
| 51 | * @brief Whether touchpads are ignored or not. | ||
| 52 | * | ||
| 53 | * @sa setTouchpadsIgnored(bool) | ||
| 54 | * @sa touchpadsIgnored() | ||
| 55 | */ | ||
| 56 | Q_PROPERTY(bool touchpadsIgnored | ||
| 57 | READ touchpadsIgnored | ||
| 58 | WRITE setTouchpadsIgnored) | ||
| 59 | 50 | ||
| 60 | 51 | /** | |
| 61 | 52 | * @brief A list of devices checked by the user. | |
| … | … | ||
| 114 | 114 | */ | |
| 115 | 115 | bool setData(const QModelIndex &index, const QVariant &value, | |
| 116 | 116 | int role); | |
| 117 | |||
| 118 | /** | ||
| 119 | * Are touchpads ignored by this model? | ||
| 120 | * | ||
| 121 | * @return @c true, if this model ignores touchpads, @c false | ||
| 122 | * otherwise | ||
| 123 | */ | ||
| 124 | bool touchpadsIgnored() const; | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Ignore touchpads. Generally touchpads are mouses too and | ||
| 128 | * displayed by this model. However, there are cases, in which | ||
| 129 | * touchpads should not be considered as mouse devices. For such | ||
| 130 | * cases, you can have the model ignore touchpads with this | ||
| 131 | * function. | ||
| 132 | * | ||
| 133 | * Setting this will reset the model. | ||
| 134 | * | ||
| 135 | * By default, mouse devices are not ignored. | ||
| 136 | * | ||
| 137 | * @param ignore if @c true, ignore touchpads | ||
| 138 | */ | ||
| 139 | void setTouchpadsIgnored(bool ignore); | ||
| 140 | 117 | ||
| 141 | 118 | /** | |
| 142 | 119 | * Query the checked devices. |
kcmodule/mousedevicesview.cpp
(0 / 11)
|   | |||
| 61 | 61 | checkedDevices(); | |
| 62 | 62 | } | |
| 63 | 63 | ||
| 64 | void MouseDevicesView::setTouchpadsIgnored(bool ignored) { | ||
| 65 | qobject_cast<MouseDevicesModel *>(this->model())-> | ||
| 66 | setTouchpadsIgnored(ignored); | ||
| 67 | } | ||
| 68 | |||
| 69 | bool MouseDevicesView::touchpadsIgnored() const { | ||
| 70 | return qobject_cast<MouseDevicesModel *>(this->model())-> | ||
| 71 | touchpadsIgnored(); | ||
| 72 | } | ||
| 73 | |||
| 74 | |||
| 75 | 64 | #include "moc_mousedevicesview.cpp" |
kcmodule/mousedevicesview.h
(0 / 14)
|   | |||
| 81 | 81 | */ | |
| 82 | 82 | QStringList checkedDevices(); | |
| 83 | 83 | ||
| 84 | /** | ||
| 85 | * @brief Ignore touchpads. | ||
| 86 | * | ||
| 87 | * @param ignored if @c true, touchpads are ignored | ||
| 88 | */ | ||
| 89 | void setTouchpadsIgnored(bool ignored); | ||
| 90 | |||
| 91 | /** | ||
| 92 | * @brief Are touchpads ignored? | ||
| 93 | * | ||
| 94 | * @return @c true, if touchpads are ignored, @c false otherwise | ||
| 95 | */ | ||
| 96 | bool touchpadsIgnored() const; | ||
| 97 | |||
| 98 | 84 | Q_SIGNALS: | |
| 99 | 85 | /** | |
| 100 | 86 | * @brief Signal a change of checked devices. |
|   | |||
| 119 | 119 | QWidget(parent) { | |
| 120 | 120 | Ui::AutoTouchpadControlPage ui; | |
| 121 | 121 | ui.setupUi(this); | |
| 122 | ui.kcfg_IgnoredMouseDevices->setTouchpadsIgnored(true); | ||
| 123 | 122 | } | |
| 124 | 123 | ||
| 125 | 124 | GeneralPage::GeneralPage(QWidget *parent): QWidget(parent) { |

