diff --git a/CMakeLists.txt b/CMakeLists.txt index 5636abd..2b68d4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,62 +1,63 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0048 NEW) project(wacomtablet VERSION "3.0.0") set(QT_MIN_VERSION "5.7.0") find_package(ECM 1.6.0 REQUIRED CONFIG) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake/modules) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(FeatureSummary) include(ECMOptionalAddSubdirectory) include(ECMInstallIcons) include(ECMSetupVersion) ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX WACOMTABLET VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/src/wacomtablet-version.h" ) find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets DBus X11Extras Qml) find_package(KF5 REQUIRED COMPONENTS CoreAddons I18n GlobalAccel Config XmlGui WidgetsAddons WindowSystem Notifications DBusAddons Plasma DocTools) find_package(XCB OPTIONAL_COMPONENTS XINPUT) find_package(X11 REQUIRED COMPONENTS XLIB) find_package(XorgWacom REQUIRED) +find_package(LibWacom REQUIRED) # xcb-xinput is an experimental API and is not built by default in the xcb # repository. Downstream distributions without xcb-xinput, such as Kubuntu, can # build using the Xlib version of the library instead. # # Because Qt5 uses xcb exclusively for native event handling, kded is unable # to monitor hotplugging events, since these are signaled as xinput events. # # Users can enable xcb-xinput by building xcb with the configuration flag --enable-xinput. if(XCB_XINPUT_FOUND) message(STATUS "Using XCB_XINPUT. Please note this is an unstable API.") set(USING_X_LIBRARIES XCB::XINPUT ${X11_Xinput_LIB}) add_definitions(-DHAVE_XCB_XINPUT) else() message(STATUS "Falling back to X11_XINPUT.") set(USING_X_LIBRARIES ${X11_LIBRARIES} ${X11_Xinput_LIB}) endif() add_definitions( -DQT_STRICT_ITERATORS ) add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) add_definitions( -DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS ) add_subdirectory( src ) add_subdirectory( data ) add_subdirectory( images ) add_subdirectory( doc ) ### Tests if(BUILD_TESTING) find_package(Qt5Test ${QT_MIN_VERSION} CONFIG REQUIRED) add_subdirectory( autotests ) endif() feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index dc2557b..71f8672 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,53 +1,53 @@ - - - set(wacom_common_LIBS Qt5::Core Qt5::Gui Qt5::Widgets Qt5::X11Extras KF5::I18n KF5::GlobalAccel KF5::ConfigCore KF5::CoreAddons ${USING_X_LIBRARIES} + ${LIBWACOM_LIBRARIES} ) set(wacom_common_SRC aboutdata.cpp buttonshortcut.cpp dbustabletinterface.cpp deviceinformation.cpp deviceprofile.cpp deviceprofileconfigadaptor.cpp deviceproperty.cpp devicetype.cpp debug.cpp + libwacomwrapper.cpp mainconfig.cpp profilemanager.cpp profilemanagement.cpp property.cpp propertyadaptor.cpp screenrotation.cpp screenmap.cpp screenspace.cpp stringutils.cpp tabletarea.cpp tabletdatabase.cpp tabletinfo.cpp tabletinformation.cpp tabletprofile.cpp tabletprofileconfigadaptor.cpp x11info.cpp x11input.cpp x11inputdevice.cpp x11wacom.cpp ) qt5_add_dbus_interfaces(wacom_common_SRC ../kded/org.kde.Wacom.xml) add_library( wacom_common STATIC ${wacom_common_SRC}) +target_include_directories(wacom_common PUBLIC ${LIBWACOM_INCLUDE_DIRS}) target_link_libraries( wacom_common ${wacom_common_LIBS} ) set_target_properties( wacom_common PROPERTIES COMPILE_FLAGS "-fPIC" ) diff --git a/src/common/libwacomwrapper.cpp b/src/common/libwacomwrapper.cpp new file mode 100644 index 0000000..e83114e --- /dev/null +++ b/src/common/libwacomwrapper.cpp @@ -0,0 +1,90 @@ +/* + * This file is part of the KDE wacomtablet project. For copyright + * information and license terms see the AUTHORS and COPYING files + * in the top-level directory of this distribution. + * + * 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, see . + */ + +#include "libwacomwrapper.h" + +#include "debug.h" + +#include + +extern "C" { +#include +} + +namespace Wacom { + +libWacomWrapper::libWacomWrapper() +{ + db = libwacom_database_new(); +} + +libWacomWrapper &libWacomWrapper::instance() +{ + static libWacomWrapper instance; + return instance; +} + +libWacomWrapper::~libWacomWrapper() +{ + libwacom_database_destroy(db); +} + +bool libWacomWrapper::lookupTabletInfo(int tabletId, int vendorId, TabletInformation &tabletInfo) +{ + dbgWacom << "LibWacom lookup for" << tabletId << vendorId; + auto errorDeleter = [](WacomError *&e){libwacom_error_free(&e);}; + std::unique_ptr + error(libwacom_error_new(), errorDeleter); + std::unique_ptr + device(libwacom_new_from_usbid(db, vendorId, tabletId, error.get()), &libwacom_destroy); + + if (!device) { + dbgWacom << "LibWacom lookup failed:" << libwacom_error_get_message(error.get()); + return false; + } + + // TODO: libWacom returned button layouts don't make much sense (yet) + // because they use letters instead of numbers + tabletInfo.set(TabletInfo::ButtonLayout, QString()); + // Seems like there is no model or vendor names in libwacom + // TODO: are these properties even used anywhere? + tabletInfo.set(TabletInfo::CompanyName, QString()); + tabletInfo.set(TabletInfo::TabletModel, QString()); + // TODO: Seems like there's no info about the pad wheel in libwacom + // Only a couple of tablets have the wheel anyway, so it probably can be hacked around + tabletInfo.set(TabletInfo::HasWheel, false); + // TODO: Returns more detailed information than we expect, + // current LED code is broken anyway so this should be untangled later + tabletInfo.set(TabletInfo::StatusLEDs, QString::number(0)); + + tabletInfo.set(TabletInfo::TabletName, QString::fromLatin1(libwacom_get_name(device.get()))); + tabletInfo.set(TabletInfo::NumPadButtons, QString::number(libwacom_get_num_buttons(device.get()))); + + int numStrips = libwacom_get_num_strips(device.get()); + bool hasLeftStrip = numStrips > 0; + bool hasRightStrip = numStrips > 1; + bool hasRing = libwacom_has_ring(device.get()) != 0; + + tabletInfo.set(TabletInfo::HasLeftTouchStrip, hasLeftStrip); + tabletInfo.set(TabletInfo::HasRightTouchStrip, hasRightStrip); + tabletInfo.set(TabletInfo::HasTouchRing, hasRing); + return true; +} + +} diff --git a/src/common/libwacomwrapper.h b/src/common/libwacomwrapper.h new file mode 100644 index 0000000..228385c --- /dev/null +++ b/src/common/libwacomwrapper.h @@ -0,0 +1,46 @@ +/* + * This file is part of the KDE wacomtablet project. For copyright + * information and license terms see the AUTHORS and COPYING files + * in the top-level directory of this distribution. + * + * 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, see . + */ + +#ifndef LIBWACOMWRAPPER_H +#define LIBWACOMWRAPPER_H + +#include "tabletinformation.h" + +struct _WacomDeviceDatabase; +typedef struct _WacomDeviceDatabase WacomDeviceDatabase; + +namespace Wacom { + +class libWacomWrapper { +private: + libWacomWrapper(); + ~libWacomWrapper(); + +public: + static libWacomWrapper &instance(); + + bool lookupTabletInfo(int tabletId, int vendorId, TabletInformation& tabletInfo); + +private: + WacomDeviceDatabase *db = nullptr; +}; + +} + +#endif diff --git a/src/kded/CMakeLists.txt b/src/kded/CMakeLists.txt index 01df9a2..ca7a980 100644 --- a/src/kded/CMakeLists.txt +++ b/src/kded/CMakeLists.txt @@ -1,68 +1,69 @@ ## libraries set(kded_wacomtablet_LIBS wacom_common KF5::CoreAddons KF5::Notifications KF5::XmlGui KF5::DBusAddons KF5::ConfigCore ${USING_X_LIBRARIES} + ${LIBWACOM_LIBRARIES} ) ## sources set(kded_wacomtablet_SRCS dbustabletservice.cpp eventnotifier.cpp procsystemadaptor.cpp procsystemproperty.cpp tabletbackend.cpp tabletbackendfactory.cpp tabletdaemon.cpp tabletfinder.cpp tablethandler.cpp x11eventnotifier.cpp x11tabletfinder.cpp xinputadaptor.cpp xinputproperty.cpp xsetwacomadaptor.cpp xsetwacomproperty.cpp ../common/globalactions.cpp ) ## dbus interfaces qt5_add_dbus_adaptor(kded_wacomtablet_SRCS org.kde.Wacom.xml dbustabletservice.h Wacom::DBusTabletService) ## build KDE daemon module add_definitions(-DTRANSLATION_DOMAIN=\"wacomtablet\") add_library(kded_wacomtablet MODULE ${kded_wacomtablet_SRCS}) target_link_libraries( kded_wacomtablet ${kded_wacomtablet_LIBS} ) set_target_properties(kded_wacomtablet PROPERTIES OUTPUT_NAME wacomtablet) ## files to install kcoreaddons_desktop_to_json(kded_wacomtablet wacomtablet.desktop) install(TARGETS kded_wacomtablet DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kded) install(FILES wacomtablet.notifyrc DESTINATION "${KNOTIFYRC_INSTALL_DIR}") install(FILES org.kde.Wacom.xml DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR}) ## LIBRARY FOR UNIT TESTS if (BUILD_TESTING) ## headers which need to be moc'ed for the static unit-testing library set(kded_wacomtablet_HDRS dbustabletservice.h tabletdaemon.h tablethandler.h eventnotifier.h x11eventnotifier.h ) ## build static library for unit testing add_library( kded_wacomtablet_lib STATIC ${kded_wacomtablet_SRCS} ) target_link_libraries( kded_wacomtablet_lib ${kded_wacomtablet_LIBS} ) set_target_properties( kded_wacomtablet_lib PROPERTIES COMPILE_FLAGS "-fPIC" ) endif (BUILD_TESTING) diff --git a/src/kded/tabletfinder.cpp b/src/kded/tabletfinder.cpp index 9a47ac0..1bf0aad 100644 --- a/src/kded/tabletfinder.cpp +++ b/src/kded/tabletfinder.cpp @@ -1,181 +1,189 @@ /* * This file is part of the KDE wacomtablet project. For copyright * information and license terms see the AUTHORS and COPYING files * in the top-level directory of this distribution. * * 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, see . */ #include "tabletfinder.h" #include "debug.h" #include "tabletdatabase.h" #include "x11tabletfinder.h" +#include "libwacomwrapper.h" #include #include #include using namespace Wacom; namespace Wacom { class TabletFinderPrivate { public: typedef QList TabletInformationList; TabletInformationList tabletList; }; // CLASS } // NAMESPACE TabletFinder::TabletFinder() : QObject(nullptr) , d_ptr(new TabletFinderPrivate) { } TabletFinder::~TabletFinder() { delete d_ptr; } TabletFinder& TabletFinder::instance() { static TabletFinder instance; return instance; } bool TabletFinder::scan() { Q_D(TabletFinder); if (!QX11Info::isPlatformX11()) { return false; } X11TabletFinder x11tabletFinder; QMap buttonMap; if (x11tabletFinder.scanDevices()) { d->tabletList = x11tabletFinder.getTablets(); TabletFinderPrivate::TabletInformationList::Iterator iter; for (iter = d->tabletList.begin() ; iter != d->tabletList.end() ; ++iter) { // lookup device information and button map lookupInformation(*iter); // empty device name will crash the system, ignore them for now if (iter->get(TabletInfo::TabletName).isEmpty()) { continue; } dbgWacom << QString::fromLatin1("Tablet '%1' (%2) found.").arg(iter->get(TabletInfo::TabletName)).arg(iter->get(TabletInfo::TabletId)); // emit tablet added signal emit tabletAdded(*iter); } return true; } return false; } void TabletFinder::onX11TabletAdded(int deviceId) { Q_D(TabletFinder); // check if we already know this tablet for (int i = 0 ; i < d->tabletList.size() ; ++i) { if (d->tabletList.at(i).hasDevice(deviceId)) { // we already know this tablet errWacom << "X11 id:" << deviceId << "already added to Tablet" << d->tabletList.at(i).getDeviceName(DeviceType::Pad); return; } } // scan for tablet devices X11TabletFinder x11TabletFinder; if (!x11TabletFinder.scanDevices()) { errWacom << "Could not find Wacom device with X11 id:" << deviceId; return; } // check if the device id can be found foreach (const TabletInformation& info, x11TabletFinder.getTablets()) { if (info.hasDevice(deviceId)) { // tablet found - lookup additional information TabletInformation tabletInfo = info; lookupInformation(tabletInfo); // empty device name will crash the system, ignore them for now if (tabletInfo.get(TabletInfo::TabletName).isEmpty()) { continue; } dbgWacom << QString::fromLatin1("Tablet '%1' (%2) added.").arg(tabletInfo.get(TabletInfo::TabletName)).arg(tabletInfo.get(TabletInfo::TabletId)); // add tablet to the list of known tablets and emit added signal d->tabletList.append(tabletInfo); emit tabletAdded(tabletInfo); return; } } } void TabletFinder::onX11TabletRemoved(int deviceId) { Q_D(TabletFinder); // check if we know this tablet TabletFinderPrivate::TabletInformationList::iterator iter; for (iter = d->tabletList.begin() ; iter != d->tabletList.end() ; ++iter) { if (iter->hasDevice(deviceId)) { TabletInformation info = *iter; d->tabletList.erase(iter); dbgWacom << QString::fromLatin1("Removed tablet '%1' (%2).").arg(info.get(TabletInfo::TabletName)).arg(info.get(TabletInfo::TabletId)); emit tabletRemoved(info); return; } } } bool TabletFinder::lookupInformation(TabletInformation& info) { - // lookup information from our tablet database - if (!TabletDatabase::instance().lookupTablet(info.get (TabletInfo::TabletId), info)) { - dbgWacom << QString::fromLatin1("Could not find tablet with id '%1' in database.").arg(info.get (TabletInfo::TabletId)); - return false; + // lookup information from our local & system-wide tablet databases + if (TabletDatabase::instance().lookupTablet(info.get (TabletInfo::TabletId), info)) { + dbgWacom << "Found in database: " << info.get(TabletInfo::TabletId); + return true; } - // TODO use libwacom to get more tablet information + // lookup information in libWacom tablet database + auto tabletId = info.get(TabletInfo::TabletId).toInt(nullptr, 16); + auto vendorId = info.get(TabletInfo::CompanyId).toInt(nullptr, 16); + if (libWacomWrapper::instance().lookupTabletInfo(tabletId, vendorId, info)) { + dbgWacom << "Found in libwacom: " << info.get(TabletInfo::TabletId); + return true; + } - return true; + dbgWacom << QString::fromLatin1("Could not find tablet with id '%1' in database.").arg(info.get (TabletInfo::TabletId)); + return false; } diff --git a/src/kded/x11tabletfinder.cpp b/src/kded/x11tabletfinder.cpp index 951fa18..81addc2 100644 --- a/src/kded/x11tabletfinder.cpp +++ b/src/kded/x11tabletfinder.cpp @@ -1,291 +1,295 @@ /* * This file is part of the KDE wacomtablet project. For copyright * information and license terms see the AUTHORS and COPYING files * in the top-level directory of this distribution. * * 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, see . */ #include "debug.h" #include "x11tabletfinder.h" #include "deviceinformation.h" #include "x11input.h" #if defined(HAVE_XCB_XINPUT) # include #else # include # include # include # include #endif +#include #include using namespace Wacom; /** * Class for private members. */ namespace Wacom { class X11TabletFinderPrivate { public: typedef QMap TabletMap; TabletMap tabletMap; //!< A map which is used while visiting devices. QList scannedList; //!< A list which is build after scanning all devices. }; } X11TabletFinder::X11TabletFinder() : d_ptr(new X11TabletFinderPrivate) { } X11TabletFinder::~X11TabletFinder() { delete d_ptr; } const QList< TabletInformation >& X11TabletFinder::getTablets() const { Q_D (const X11TabletFinder); return d->scannedList; } bool X11TabletFinder::scanDevices() { Q_D (X11TabletFinder); d->tabletMap.clear(); d->scannedList.clear(); X11Input::scanDevices(*this); X11TabletFinderPrivate::TabletMap::ConstIterator iter; for (iter = d->tabletMap.constBegin() ; iter != d->tabletMap.constEnd() ; ++iter) { d->scannedList.append(iter.value()); } return (d->tabletMap.size() > 0); } bool X11TabletFinder::visit (X11InputDevice& x11device) { if (!x11device.isTabletDevice()) { return false; } // gather basic device information which we need to create a device information structure QString deviceName = x11device.getName(); const DeviceType* deviceType = getDeviceType (getToolType (x11device)); - if (deviceName.isEmpty() || deviceType == NULL) { + if (deviceName.isEmpty() || deviceType == nullptr) { errWacom << QString::fromLatin1("Unsupported device '%1' detected!").arg(deviceName); return false; } // create device information and gather all information we can DeviceInformation deviceInfo (*deviceType, x11device.getName()); gatherDeviceInformation(x11device, deviceInfo); // add device information to tablet map addDeviceInformation(deviceInfo); // true is only returned if device visiting should be aborted by X11Input return false; } void X11TabletFinder::addDeviceInformation (DeviceInformation& deviceInformation) { Q_D(X11TabletFinder); long serial = deviceInformation.getTabletSerial(); if (serial < 1) { dbgWacom << QString::fromLatin1("Device '%1' has an invalid serial number '%2'!").arg(deviceInformation.getName()).arg(serial); } X11TabletFinderPrivate::TabletMap::iterator mapIter = d->tabletMap.find (serial); if (mapIter == d->tabletMap.end()) { - mapIter = d->tabletMap.insert(serial, TabletInformation (serial)); + auto newTabletInformation = TabletInformation(serial); + // LibWacom needs CompanyId so set it too + newTabletInformation.set(TabletInfo::CompanyId, QString::fromLatin1("%1").arg(deviceInformation.getVendorId(), 4, 16, QLatin1Char('0')).toUpper()); + mapIter = d->tabletMap.insert(serial, newTabletInformation); } mapIter.value().setDevice(deviceInformation); } void X11TabletFinder::gatherDeviceInformation(X11InputDevice& device, DeviceInformation& deviceInformation) const { // get X11 device id deviceInformation.setDeviceId(device.getDeviceId()); // get tablet serial deviceInformation.setTabletSerial(getTabletSerial(device)); // get product and vendor id if set long vendorId = 0, productId = 0; if (getProductId(device, vendorId, productId)) { deviceInformation.setVendorId(vendorId); deviceInformation.setProductId(productId); } // get the device node which is the full path to the input device deviceInformation.setDeviceNode(getDeviceNode(device)); } const QString X11TabletFinder::getDeviceNode(X11InputDevice& device) const { QList values; if (!device.getStringProperty(X11Input::PROPERTY_DEVICE_NODE, values, 1000) || values.size() == 0) { dbgWacom << QString::fromLatin1("Could not get device node from device '%1'!").arg(device.getName()); return QString(); } return values.at(0); } const DeviceType* X11TabletFinder::getDeviceType (const QString& toolType) const { if (toolType.contains (QLatin1String ("pad"), Qt::CaseInsensitive)) { return &(DeviceType::Pad); } else if (toolType.contains(QLatin1String ("eraser"), Qt::CaseInsensitive)) { return &(DeviceType::Eraser); } else if (toolType.contains(QLatin1String ("cursor"), Qt::CaseInsensitive)) { return &(DeviceType::Cursor); } else if (toolType.contains(QLatin1String ("touch"), Qt::CaseInsensitive)) { return &(DeviceType::Touch); } else if (toolType.contains(QLatin1String ("stylus"), Qt::CaseInsensitive)) { return &(DeviceType::Stylus); } return NULL; } bool X11TabletFinder::getProductId(X11InputDevice& device, long int& vendorId, long int& productId) const { QList values; if (!device.getLongProperty(X11Input::PROPERTY_DEVICE_PRODUCT_ID, values, 2)) { return false; } if (values.size() != 2) { errWacom << QString::fromLatin1("Unexpected number of values when fetching XInput property '%1'!").arg(X11Input::PROPERTY_DEVICE_PRODUCT_ID); return false; } long value; if ((value = values.at(0)) > 0) { vendorId = value; } if ((value = values.at(1)) > 0) { productId = value; } return true; } long int X11TabletFinder::getTabletSerial (X11InputDevice& device) const { long tabletId = 0; QList serialIdValues; if (!device.getLongProperty(X11Input::PROPERTY_WACOM_SERIAL_IDS, serialIdValues, 1000)) { return tabletId; } // the offset for the tablet id is 0 see wacom-properties.h in the xf86-input-wacom driver for more information on this if (serialIdValues.size() > 0) { tabletId = serialIdValues.at(0); if (tabletId > 0) { return tabletId; } } return tabletId; } const QString X11TabletFinder::getToolType (X11InputDevice& device) const { QList toolTypeAtoms; if (!device.getAtomProperty(X11Input::PROPERTY_WACOM_TOOL_TYPE, toolTypeAtoms)) { return QString(); } QString toolTypeName; if (toolTypeAtoms.size() == 1) { #if defined(HAVE_XCB_XINPUT) xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(QX11Info::connection(), toolTypeAtoms.at(0)); xcb_get_atom_name_reply_t* reply = xcb_get_atom_name_reply(QX11Info::connection(), cookie, NULL); if (reply) { toolTypeName = QString::fromLatin1(QByteArray(xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply))); free(reply); } #else // HAVE_XCB_XINPUT char *type_name = XGetAtomName (device.getDisplay(), (Atom)toolTypeAtoms.at(0)); if (type_name != NULL) { toolTypeName = QLatin1String(type_name); XFree( type_name ); } else { dbgWacom << "Could not get tool type of device" << device.getName(); } #endif // HAVE_XCB_XINPUT } return toolTypeName; }