diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ 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 diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,6 +1,3 @@ - - - set(wacom_common_LIBS Qt5::Core Qt5::Gui @@ -11,6 +8,7 @@ KF5::ConfigCore KF5::CoreAddons ${USING_X_LIBRARIES} + ${LIBWACOM_LIBRARIES} ) set(wacom_common_SRC @@ -23,6 +21,7 @@ deviceproperty.cpp devicetype.cpp debug.cpp + libwacomwrapper.cpp mainconfig.cpp profilemanager.cpp profilemanagement.cpp @@ -49,5 +48,6 @@ 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.h b/src/common/libwacomwrapper.h new file mode 100644 --- /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/common/libwacomwrapper.cpp b/src/common/libwacomwrapper.cpp new file mode 100644 --- /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/kded/CMakeLists.txt b/src/kded/CMakeLists.txt --- a/src/kded/CMakeLists.txt +++ b/src/kded/CMakeLists.txt @@ -8,6 +8,7 @@ KF5::DBusAddons KF5::ConfigCore ${USING_X_LIBRARIES} + ${LIBWACOM_LIBRARIES} ) ## sources diff --git a/src/kded/tabletfinder.cpp b/src/kded/tabletfinder.cpp --- a/src/kded/tabletfinder.cpp +++ b/src/kded/tabletfinder.cpp @@ -22,6 +22,7 @@ #include "debug.h" #include "tabletdatabase.h" #include "x11tabletfinder.h" +#include "libwacomwrapper.h" #include #include @@ -169,13 +170,20 @@ 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 --- a/src/kded/x11tabletfinder.cpp +++ b/src/kded/x11tabletfinder.cpp @@ -33,6 +33,7 @@ # include #endif +#include #include using namespace Wacom; @@ -104,7 +105,7 @@ 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; } @@ -136,7 +137,10 @@ 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);