diff --git a/autotests/common/commontestutils.cpp b/autotests/common/commontestutils.cpp index e6cf6ce..b9d363c 100644 --- a/autotests/common/commontestutils.cpp +++ b/autotests/common/commontestutils.cpp @@ -1,157 +1,158 @@ /* * 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 "commontestutils.h" + #include #include -#include "commontestutils.h" #include "common/deviceproperty.h" #include "common/devicetype.h" using namespace Wacom; const long CommonTestUtils::DEVICEINFORMATION_DEVICE_ID = 42; const QString CommonTestUtils::DEVICEINFORMATION_DEVICE_NODE = QLatin1String("/dev/input/event1"); const long CommonTestUtils::DEVICEINFORMATION_PRODUCT_ID = 1234; const long CommonTestUtils::DEVICEINFORMATION_TABLET_SERIAL = 123456; const long CommonTestUtils::DEVICEINFORMATION_VENDOR_ID = 4321; const QString CommonTestUtils::TABLETINFORMATION_COMPANY_ID = QLatin1String("1234"); const QString CommonTestUtils::TABLETINFORMATION_COMPANY_NAME = QLatin1String("Wacom Ltd."); const QString CommonTestUtils::TABLETINFORMATION_TABLET_MODEL = QLatin1String("Bamboo Create"); const QString CommonTestUtils::TABLETINFORMATION_TABLET_NAME = QLatin1String("Bamboo Touch"); const QString CommonTestUtils::TABLETINFORMATION_TABLET_SERIAL = QLatin1String("6666"); const QString CommonTestUtils::TABLETINFORMATION_TABLET_ID = QString::fromLatin1("%1").arg(6666, 4, 16, QLatin1Char('0')).toUpper(); const bool CommonTestUtils::TABLETINFORMATION_HAS_BUTTONS = true; const bool CommonTestUtils::TABLETINFORMATION_HAS_TOUCHRING = true; const bool CommonTestUtils::TABLETINFORMATION_HAS_TOUCHSTRIPLEFT = true; const bool CommonTestUtils::TABLETINFORMATION_HAS_TOUCHSTRIPRIGHT = true; const bool CommonTestUtils::TABLETINFORMATION_HAS_WHEEL = true; const bool CommonTestUtils::TABLETINFORMATION_IS_AVAILABLE = true; const QString CommonTestUtils::TABLETINFORMATION_NUM_PAD_BUTTONS = QLatin1String("4"); const QString CommonTestUtils::TABLETINFORMATION_DEV1_NAME = QLatin1String("Device Stylus"); const QString CommonTestUtils::TABLETINFORMATION_DEV1_TYPE = QLatin1String("stylus"); const QString CommonTestUtils::TABLETINFORMATION_DEV2_NAME = QLatin1String("Device Eraser"); const QString CommonTestUtils::TABLETINFORMATION_DEV2_TYPE = QLatin1String("eraser"); const QString CommonTestUtils::TABLETINFORMATION_DEV3_NAME = QLatin1String("Device Pad"); const QString CommonTestUtils::TABLETINFORMATION_DEV3_TYPE = QLatin1String("pad"); void CommonTestUtils::assertValues(const DeviceInformation& info, const DeviceType& expectedType, const QString& expectedName) { QVERIFY (info.getDeviceId() == DEVICEINFORMATION_DEVICE_ID); QCOMPARE (info.getDeviceNode(), DEVICEINFORMATION_DEVICE_NODE); QCOMPARE (info.getName(), expectedName); QVERIFY (info.getProductId() == DEVICEINFORMATION_PRODUCT_ID); QVERIFY (info.getTabletSerial() == DEVICEINFORMATION_TABLET_SERIAL); QVERIFY (info.getType() == expectedType); QVERIFY (info.getVendorId() == DEVICEINFORMATION_VENDOR_ID); } void CommonTestUtils::assertValues(DeviceProfile& profile, const char* name) { foreach(const DeviceProperty& property, DeviceProperty::list()) { QCOMPARE(profile.getProperty(property.id()), property.id().key()); } - if (name != NULL) { + if (name != nullptr) { QCOMPARE(profile.getName(), QLatin1String(name)); } else { QCOMPARE(profile.getName(), DeviceType::Pad.key()); } } void CommonTestUtils::assertValues(const TabletInformation& info) { QCOMPARE (info.get(TabletInfo::CompanyId), TABLETINFORMATION_COMPANY_ID); QCOMPARE (info.get(TabletInfo::CompanyName), TABLETINFORMATION_COMPANY_NAME); QCOMPARE (info.get(TabletInfo::TabletId), TABLETINFORMATION_TABLET_ID); QCOMPARE (info.get(TabletInfo::TabletModel), TABLETINFORMATION_TABLET_MODEL); QCOMPARE (info.get(TabletInfo::TabletName), TABLETINFORMATION_TABLET_NAME); QCOMPARE (info.get(TabletInfo::TabletSerial), TABLETINFORMATION_TABLET_SERIAL); QVERIFY (info.isAvailable() == TABLETINFORMATION_IS_AVAILABLE); QVERIFY (info.hasButtons() == TABLETINFORMATION_HAS_BUTTONS); QStringList deviceList = info.getDeviceList(); QVERIFY (deviceList.size() == 3); QVERIFY (deviceList.contains (TABLETINFORMATION_DEV1_NAME)); QVERIFY (deviceList.contains (TABLETINFORMATION_DEV2_NAME)); QVERIFY (deviceList.contains (TABLETINFORMATION_DEV3_NAME)); } void CommonTestUtils::setValues(DeviceInformation& info) { info.setDeviceId (DEVICEINFORMATION_DEVICE_ID); info.setDeviceNode (DEVICEINFORMATION_DEVICE_NODE); info.setProductId (DEVICEINFORMATION_PRODUCT_ID); info.setTabletSerial (DEVICEINFORMATION_TABLET_SERIAL); info.setVendorId (DEVICEINFORMATION_VENDOR_ID); } void CommonTestUtils::setValues(DeviceProfile& profile) { foreach(const DeviceProperty& property, DeviceProperty::list()) { profile.setProperty(property.id(), property.id().key()); } if (profile.getDeviceType() == DeviceType::Unknown) { profile.setDeviceType(DeviceType::Pad); } } void CommonTestUtils::setValues(TabletInformation& info) { info.set(TabletInfo::CompanyId, TABLETINFORMATION_COMPANY_ID); info.set(TabletInfo::CompanyName, TABLETINFORMATION_COMPANY_NAME); info.set(TabletInfo::TabletModel, TABLETINFORMATION_TABLET_MODEL); info.set(TabletInfo::TabletName, TABLETINFORMATION_TABLET_NAME); info.set(TabletInfo::TabletSerial, TABLETINFORMATION_TABLET_SERIAL); info.set(TabletInfo::HasLeftTouchStrip, TABLETINFORMATION_HAS_TOUCHSTRIPLEFT); info.set(TabletInfo::HasRightTouchStrip, TABLETINFORMATION_HAS_TOUCHSTRIPRIGHT); info.set(TabletInfo::HasTouchRing, TABLETINFORMATION_HAS_TOUCHRING); info.set(TabletInfo::HasWheel, TABLETINFORMATION_HAS_WHEEL); info.setAvailable (TABLETINFORMATION_IS_AVAILABLE); DeviceInformation dev1Info (*DeviceType::find(TABLETINFORMATION_DEV1_TYPE), TABLETINFORMATION_DEV1_NAME); DeviceInformation dev2Info (*DeviceType::find(TABLETINFORMATION_DEV2_TYPE), TABLETINFORMATION_DEV2_NAME); DeviceInformation dev3Info (*DeviceType::find(TABLETINFORMATION_DEV3_TYPE), TABLETINFORMATION_DEV3_NAME); info.setDevice(dev1Info); info.setDevice(dev2Info); info.setDevice(dev3Info); } diff --git a/autotests/common/commontestutils.h b/autotests/common/commontestutils.h index 19f2262..a0d26de 100644 --- a/autotests/common/commontestutils.h +++ b/autotests/common/commontestutils.h @@ -1,87 +1,87 @@ /* * 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 COMMONTESTUTILS_H #define COMMONTESTUTILS_H #include "common/deviceinformation.h" #include "common/deviceprofile.h" #include "common/devicetype.h" #include "common/tabletinformation.h" #include namespace Wacom { class CommonTestUtils { public: /* * Expected Values */ static const long DEVICEINFORMATION_DEVICE_ID; static const QString DEVICEINFORMATION_DEVICE_NODE; static const long DEVICEINFORMATION_PRODUCT_ID; static const long DEVICEINFORMATION_TABLET_SERIAL; static const long DEVICEINFORMATION_VENDOR_ID; static const QString TABLETINFORMATION_COMPANY_ID; static const QString TABLETINFORMATION_COMPANY_NAME; static const QString TABLETINFORMATION_TABLET_MODEL; static const QString TABLETINFORMATION_TABLET_NAME; static const QString TABLETINFORMATION_TABLET_SERIAL; static const QString TABLETINFORMATION_TABLET_ID; static const bool TABLETINFORMATION_HAS_BUTTONS; static const bool TABLETINFORMATION_HAS_WHEEL; static const bool TABLETINFORMATION_HAS_TOUCHRING; static const bool TABLETINFORMATION_HAS_TOUCHSTRIPLEFT; static const bool TABLETINFORMATION_HAS_TOUCHSTRIPRIGHT; static const bool TABLETINFORMATION_IS_AVAILABLE; static const QString TABLETINFORMATION_NUM_PAD_BUTTONS; static const QString TABLETINFORMATION_DEV1_NAME; static const QString TABLETINFORMATION_DEV1_TYPE; static const QString TABLETINFORMATION_DEV2_NAME; static const QString TABLETINFORMATION_DEV2_TYPE; static const QString TABLETINFORMATION_DEV3_NAME; static const QString TABLETINFORMATION_DEV3_TYPE; /* * Helper Methods */ static void assertValues (const DeviceInformation& info, const DeviceType& expectedType, const QString& expectedName); - static void assertValues (DeviceProfile& profile, const char* name = NULL); + static void assertValues (DeviceProfile& profile, const char *name = nullptr); static void assertValues (const TabletInformation& info); static void setValues (DeviceInformation& info); static void setValues (DeviceProfile& profile); static void setValues (TabletInformation& info); }; // CLASS } // NAMESPACE #endif // HEADER PROTECTION diff --git a/autotests/common/enum/testenum.cpp b/autotests/common/enum/testenum.cpp index 7a1bdce..818be64 100644 --- a/autotests/common/enum/testenum.cpp +++ b/autotests/common/enum/testenum.cpp @@ -1,253 +1,253 @@ /* * 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 "common/enum.h" #include using namespace Wacom; /** * @file testenum.cpp * * @test UnitTest for the device properties */ class TestEnum: public QObject { Q_OBJECT private slots: void testCompare(); void testConstructor(); void testFind(); void testIterator(); void testKey(); void testKeys(); void testList(); void testOperator(); void testSize(); }; QTEST_MAIN(TestEnum) /* * Forward Declarations, Typedefs & Helper classes. */ class EnumTest; struct EnumTestTemplateSpecializationLessFunctor; struct EnumTestTemplateSpecializationEqualFunctor; typedef Enum EnumTestTemplateSpecialization; struct EnumTestTemplateSpecializationLessFunctor { bool operator()(const EnumTestTemplateSpecialization* v1, const EnumTestTemplateSpecialization* v2) { return (v1->key() < v2->key()); } }; struct EnumTestTemplateSpecializationEqualFunctor { bool operator()(const QString& v1, const QString& v2) { return (v1.compare(v2, Qt::CaseInsensitive) == 0); } }; // template specialization of helper class template<> EnumTestTemplateSpecialization::Container EnumTestTemplateSpecialization::instances = EnumTestTemplateSpecialization::Container(); /* * A helper class required for this unit test. */ class EnumTest : public EnumTestTemplateSpecialization { private: explicit EnumTest(const QString& value) : EnumTestTemplateSpecialization(this, value) {} public: static const EnumTest VAL01_PRIO10; static const EnumTest VAL02_PRIO10; static const EnumTest VAL03_PRIO10; static const EnumTest VAL01_PRIO50; static const EnumTest VAL01_PRIO99; static const EnumTest VAL02_PRIO99; }; // Do NOT reorder these instances! This has to be done by the enum itself. const EnumTest EnumTest::VAL01_PRIO10(QLatin1String("VAL01_PRIO10")); const EnumTest EnumTest::VAL03_PRIO10(QLatin1String("VAL03_PRIO10")); const EnumTest EnumTest::VAL02_PRIO10(QLatin1String("VAL02_PRIO10")); const EnumTest EnumTest::VAL02_PRIO99(QLatin1String("VAL02_PRIO99")); const EnumTest EnumTest::VAL01_PRIO99(QLatin1String("VAL01_PRIO99")); const EnumTest EnumTest::VAL01_PRIO50(QLatin1String("VAL01_PRIO50")); void TestEnum::testCompare() { // make sure sort order is correct EnumTest::const_iterator iter = EnumTest::begin(); QCOMPARE(iter++->key(), QLatin1String("VAL01_PRIO10")); QCOMPARE(iter++->key(), QLatin1String("VAL01_PRIO50")); QCOMPARE(iter++->key(), QLatin1String("VAL01_PRIO99")); QCOMPARE(iter++->key(), QLatin1String("VAL02_PRIO10")); QCOMPARE(iter++->key(), QLatin1String("VAL02_PRIO99")); QCOMPARE(iter++->key(), QLatin1String("VAL03_PRIO10")); } void TestEnum::testConstructor() { // copy constructor EnumTest test(EnumTest::VAL01_PRIO10); QVERIFY(test == EnumTest::VAL01_PRIO10); } void TestEnum::testFind() { - QVERIFY(EnumTest::find(QLatin1String("NON_EXISTANT")) == NULL); + QCOMPARE(EnumTest::find(QLatin1String("NON_EXISTANT")), nullptr); const EnumTest* find = EnumTest::find(QLatin1String("VAL01_PRIO50")); - QVERIFY(find != NULL); - QVERIFY(*find == EnumTest::VAL01_PRIO50); + QVERIFY(find != nullptr); + QCOMPARE(*find, EnumTest::VAL01_PRIO50); } void TestEnum::testIterator() { EnumTest::const_iterator begin = EnumTest::begin(); EnumTest::const_iterator end = EnumTest::end(); EnumTest::const_iterator iter, second; // begin(), operator*, operator-> QCOMPARE(begin->key(), QLatin1String("VAL01_PRIO10")); QCOMPARE((*begin).key(), EnumTest::VAL01_PRIO10.key()); QVERIFY(*begin == EnumTest::VAL01_PRIO10); QVERIFY(&(*begin) == &EnumTest::VAL01_PRIO10); // operator== QVERIFY(begin == EnumTest::begin()); QVERIFY(end == EnumTest::end()); // operator!= QVERIFY(begin != EnumTest::end()); QVERIFY(end != EnumTest::begin()); // operator= iter = begin; QVERIFY(iter == iter); QVERIFY(iter == begin); QVERIFY(iter == EnumTest::begin()); // operator++ second = begin; ++second; QCOMPARE(second->key(), QLatin1String("VAL01_PRIO50")); iter = begin; QVERIFY(iter++ == begin); QVERIFY(iter == second); // operator++(int) iter = begin; QVERIFY(++iter == second); // operator-- iter = second; QVERIFY(iter-- == second); QVERIFY(iter == begin); // operator--(int) iter = second; QVERIFY(--iter == begin); // end() iter = end; --iter; QCOMPARE(iter->key(), QLatin1String("VAL03_PRIO10")); } void TestEnum::testKey() { QCOMPARE(EnumTest::VAL01_PRIO10.key(), QLatin1String("VAL01_PRIO10")); QCOMPARE(EnumTest::VAL01_PRIO50.key(), QLatin1String("VAL01_PRIO50")); QCOMPARE(EnumTest::VAL01_PRIO99.key(), QLatin1String("VAL01_PRIO99")); QCOMPARE(EnumTest::VAL02_PRIO10.key(), QLatin1String("VAL02_PRIO10")); QCOMPARE(EnumTest::VAL02_PRIO99.key(), QLatin1String("VAL02_PRIO99")); QCOMPARE(EnumTest::VAL03_PRIO10.key(), QLatin1String("VAL03_PRIO10")); } void TestEnum::testKeys() { QStringList values = EnumTest::keys(); QStringList::ConstIterator iter = values.constBegin(); QCOMPARE(*(iter++), QLatin1String("VAL01_PRIO10")); QCOMPARE(*(iter++), QLatin1String("VAL01_PRIO50")); QCOMPARE(*(iter++), QLatin1String("VAL01_PRIO99")); QCOMPARE(*(iter++), QLatin1String("VAL02_PRIO10")); QCOMPARE(*(iter++), QLatin1String("VAL02_PRIO99")); QCOMPARE(*(iter++), QLatin1String("VAL03_PRIO10")); } void TestEnum::testList() { QList list = EnumTest::list(); QList::ConstIterator iter = list.constBegin(); QVERIFY(*(iter++) == EnumTest::VAL01_PRIO10); QVERIFY(*(iter++) == EnumTest::VAL01_PRIO50); QVERIFY(*(iter++) == EnumTest::VAL01_PRIO99); QVERIFY(*(iter++) == EnumTest::VAL02_PRIO10); QVERIFY(*(iter++) == EnumTest::VAL02_PRIO99); QVERIFY(*(iter++) == EnumTest::VAL03_PRIO10); } void TestEnum::testOperator() { // operator== QVERIFY(EnumTest::VAL01_PRIO10 == EnumTest::VAL01_PRIO10); QVERIFY(EnumTest::VAL02_PRIO10 == EnumTest::VAL02_PRIO10); // operator!= QVERIFY(EnumTest::VAL01_PRIO10 != EnumTest::VAL02_PRIO10); // operator= EnumTest test = EnumTest::VAL01_PRIO10; QVERIFY(test == EnumTest::VAL01_PRIO10); } void TestEnum::testSize() { int count = 6; QCOMPARE((int)EnumTest::size(), count); QCOMPARE(EnumTest::keys().size(), count); QCOMPARE(EnumTest::list().size(), count); } #include "testenum.moc" diff --git a/autotests/kded/dbustabletservice/testdbustabletservice.cpp b/autotests/kded/dbustabletservice/testdbustabletservice.cpp index 842c0a9..69f9794 100644 --- a/autotests/kded/dbustabletservice/testdbustabletservice.cpp +++ b/autotests/kded/dbustabletservice/testdbustabletservice.cpp @@ -1,315 +1,315 @@ /* * 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 "../tablethandlermock.h" #include "kded/dbustabletservice.h" #include "common/dbustabletinterface.h" #include "common/tabletinformation.h" #include using namespace Wacom; /** * @file testdbustabletservice.cpp * * @test UnitTest for ... */ class TestDBusTabletService: public QObject { Q_OBJECT public: void assertTabletInformation(const TabletInformation& expectedInformation) const; public slots: void onProfileChanged(const QString &TabletId, const QString& profile); void onTabletAdded(const QString &TabletId); void onTabletRemoved(const QString &TabletId); private slots: //! Run once before all tests. void initTestCase(); void testListProfiles(); void testOnTabletAdded(); void testOnTabletRemoved(); void testSetProfile(); void testSetProperty(); //! Run once after all tests. void cleanupTestCase(); private: TabletHandlerMock m_tabletHandlerMock; DBusTabletService* m_tabletService; QString m_profileWasChangedTo; bool m_tabletWasAdded; bool m_tabletWasRemoved; }; QTEST_MAIN(TestDBusTabletService) void TestDBusTabletService::assertTabletInformation(const TabletInformation& expectedInformation) const { QDBusReply actualString; QDBusReply actualBool; // make sure the device list is equal QStringList expectedDeviceList = expectedInformation.getDeviceList(); QDBusReply actualDeviceList = DBusTabletInterface::instance().getDeviceList(QLatin1String("TabletId")); QVERIFY(actualDeviceList.isValid()); for (int i = 0 ; i < expectedDeviceList.size() ; ++i) { QCOMPARE(actualDeviceList.value().at(i), expectedDeviceList.at(i)); } // make sure the devices are equal foreach(const DeviceType& type, DeviceType::list()) { actualString = DBusTabletInterface::instance().getDeviceName(QLatin1String("TabletId"), type.key()); QVERIFY(actualString.isValid()); QCOMPARE(actualString.value(), expectedInformation.getDeviceName(type)); } // compare tablet information foreach(const TabletInfo& info, TabletInfo::list()) { actualString = DBusTabletInterface::instance().getInformation(QLatin1String("TabletId"), info.key()); QVERIFY(actualString.isValid()); QCOMPARE(actualString.value(), expectedInformation.get(info)); } // check pad buttons actualBool = DBusTabletInterface::instance().hasPadButtons(QLatin1String("TabletId")); QVERIFY(actualBool.isValid()); QVERIFY(expectedInformation.hasButtons() == actualBool.value()); // check availability actualBool = DBusTabletInterface::instance().isAvailable(QLatin1String("TabletId")); QVERIFY(actualBool.isValid()); QVERIFY(expectedInformation.isAvailable() == actualBool.value()); } void TestDBusTabletService::onProfileChanged(const QString &TabletId, const QString& profile) { Q_UNUSED(TabletId) m_profileWasChangedTo = profile; } void TestDBusTabletService::onTabletAdded(const QString &TabletId) { Q_UNUSED(TabletId) m_tabletWasAdded = true; } void TestDBusTabletService::onTabletRemoved(const QString &TabletId) { Q_UNUSED(TabletId) m_tabletWasRemoved = true; } void TestDBusTabletService::initTestCase() { m_tabletService = nullptr; m_profileWasChangedTo.clear(); m_tabletWasAdded = false; m_tabletWasRemoved = false; // make sure the D-Bus service is not already registered DBusTabletInterface::instance().resetInterface(); if (DBusTabletInterface::instance().isValid()) { QSKIP("D-Bus service already running! Please shut it down to run this test!", SkipAll); return; } // register D-Bus service m_tabletService = new DBusTabletService(m_tabletHandlerMock); // reset D-Bus client DBusTabletInterface::instance().resetInterface();; // connect tablet service to us - connect(m_tabletService, SIGNAL(profileChanged(const QString&, const QString&)), this, SLOT(onProfileChanged(const QString&, const QString&))); - connect(m_tabletService, SIGNAL(tabletAdded(const QString&)), this, SLOT(onTabletAdded(const QString&))); - connect(m_tabletService, SIGNAL(tabletRemoved(const QString&)), this, SLOT(onTabletRemoved(const QString&))); + connect(m_tabletService, &DBusTabletService::profileChanged, this, &TestDBusTabletService::onProfileChanged); + connect(m_tabletService, &DBusTabletService::tabletAdded, this, &TestDBusTabletService::onTabletAdded); + connect(m_tabletService, &DBusTabletService::tabletRemoved, this, &TestDBusTabletService::onTabletRemoved); // connect tablet handler to tablet service - connect(&m_tabletHandlerMock, SIGNAL(profileChanged(const QString&, const QString&)), m_tabletService, SLOT(onProfileChanged(const QString&, const QString&))); - connect(&m_tabletHandlerMock, SIGNAL(tabletAdded(const TabletInformation&)), m_tabletService, SLOT(onTabletAdded(const TabletInformation&))); - connect(&m_tabletHandlerMock, SIGNAL(tabletRemoved(const QString&)), m_tabletService, SLOT(onTabletRemoved(const QString&))); + connect(&m_tabletHandlerMock, &TabletHandlerMock::profileChanged, m_tabletService, &DBusTabletService::onProfileChanged); + connect(&m_tabletHandlerMock, &TabletHandlerMock::tabletAdded, m_tabletService, &DBusTabletService::onTabletAdded); + connect(&m_tabletHandlerMock, &TabletHandlerMock::tabletRemoved, m_tabletService, &DBusTabletService::onTabletRemoved); } void TestDBusTabletService::cleanupTestCase() { if (m_tabletService) { delete m_tabletService; m_tabletService = nullptr; } } void TestDBusTabletService::testListProfiles() { m_tabletHandlerMock.m_profiles.clear(); QDBusReply profileList = DBusTabletInterface::instance().listProfiles(QLatin1String("TabletId")); QVERIFY(profileList.isValid()); QVERIFY(profileList.value().isEmpty()); m_tabletHandlerMock.m_profiles.append(QLatin1String("Test Profile 1")); m_tabletHandlerMock.m_profiles.append(QLatin1String("Test Profile 2")); profileList = DBusTabletInterface::instance().listProfiles(QLatin1String("TabletId")); QVERIFY(profileList.isValid()); QCOMPARE(QLatin1String("Test Profile 1"), profileList.value().at(0)); QCOMPARE(QLatin1String("Test Profile 2"), profileList.value().at(1)); } void TestDBusTabletService::testOnTabletAdded() { TabletInformation expectedInformation; foreach(const TabletInfo& tabletInfo, TabletInfo::list()) { expectedInformation.set(tabletInfo, tabletInfo.key()); } expectedInformation.setAvailable(false); // this should be set to true automatically m_tabletWasAdded = false; m_tabletHandlerMock.emitTabletAdded(expectedInformation); QVERIFY(m_tabletWasAdded); expectedInformation.setAvailable(true); assertTabletInformation(expectedInformation); QDBusReply isAvail = DBusTabletInterface::instance().isAvailable(QLatin1String("TabletId")); QVERIFY(isAvail.isValid()); QVERIFY(isAvail.value()); } void TestDBusTabletService::testOnTabletRemoved() { TabletInformation expectedInformation; expectedInformation.setAvailable(false); m_tabletWasRemoved = false; m_tabletHandlerMock.emitTabletRemoved(QLatin1String("TabletId")); assertTabletInformation(expectedInformation); QVERIFY(m_tabletWasRemoved); } void TestDBusTabletService::testSetProfile() { QString expectedProfile; QDBusReply actualProfile; // set new profile and make sure a signal was emitted by D-Bus expectedProfile = QLatin1String("Test Profile"); DBusTabletInterface::instance().setProfile(QLatin1String("TabletId"), expectedProfile); QCOMPARE(m_tabletHandlerMock.m_profile, expectedProfile); QCOMPARE(m_profileWasChangedTo, expectedProfile); // the new profile should also be returned by getProfile actualProfile = DBusTabletInterface::instance().getProfile(QLatin1String("TabletId")); QVERIFY(actualProfile.isValid()); QCOMPARE(actualProfile.value(), expectedProfile); // when the tablet is removed, the profile should be reset // however the tablet handler should be unchanged and no signal should be emitted by D-Bus m_tabletHandlerMock.emitTabletRemoved(QLatin1String("TabletId")); actualProfile = DBusTabletInterface::instance().getProfile(QLatin1String("TabletId")); QVERIFY(actualProfile.isValid()); QVERIFY(actualProfile.value().isEmpty()); QCOMPARE(m_tabletHandlerMock.m_profile, expectedProfile); QCOMPARE(m_profileWasChangedTo, expectedProfile); // set another profile expectedProfile = QLatin1String("New Profile"); DBusTabletInterface::instance().setProfile(QLatin1String("TabletId"), expectedProfile); QCOMPARE(m_tabletHandlerMock.m_profile, expectedProfile); QCOMPARE(m_profileWasChangedTo, expectedProfile); // the new profile should also be returned by getProfile actualProfile = DBusTabletInterface::instance().getProfile(QLatin1String("TabletId")); QVERIFY(actualProfile.isValid()); QCOMPARE(actualProfile.value(), expectedProfile); // clear the profile manually expectedProfile.clear(); DBusTabletInterface::instance().setProfile(QLatin1String("TabletId"), expectedProfile); QCOMPARE(m_tabletHandlerMock.m_profile, expectedProfile); QCOMPARE(m_profileWasChangedTo, expectedProfile); // the new profile should also be returned by getProfile actualProfile = DBusTabletInterface::instance().getProfile(QLatin1String("TabletId")); QVERIFY(actualProfile.isValid()); QCOMPARE(actualProfile.value(), expectedProfile); } void TestDBusTabletService::testSetProperty() { DeviceType expectedDevice = DeviceType::Stylus; Property expectedProperty = Property::Button1; QString expectedValue = QLatin1String("My Value"); // set the property DBusTabletInterface::instance().setProperty(QLatin1String("TabletId"), expectedDevice.key(), expectedProperty.key(), expectedValue); QCOMPARE(m_tabletHandlerMock.m_deviceType, expectedDevice.key()); QCOMPARE(m_tabletHandlerMock.m_property, expectedProperty.key()); QCOMPARE(m_tabletHandlerMock.m_propertyValue, expectedValue); // try to get the property QDBusReply actualValue = DBusTabletInterface::instance().getProperty(QLatin1String("TabletId"), expectedDevice.key(), expectedProperty.key()); QVERIFY(actualValue.isValid()); QCOMPARE(actualValue.value(), expectedValue); } #include "testdbustabletservice.moc" diff --git a/src/common/buttonshortcut.h b/src/common/buttonshortcut.h index 1f69f1b..6480013 100644 --- a/src/common/buttonshortcut.h +++ b/src/common/buttonshortcut.h @@ -1,330 +1,330 @@ /* * 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 BUTTONSHORTCUT_H #define BUTTONSHORTCUT_H #include #include #include namespace Wacom { class ButtonShortcutPrivate; /** * A shortcut class which can handle all supported shortcut types and is * able to convert shortcut sequences between xsetwacom- and QKeySequence- * format. */ class ButtonShortcut { public: //! The shortcut types supported by this class. enum class ShortcutType { NONE = 0, BUTTON = 1, KEYSTROKE = 2, MODIFIER = 3 }; //! Default Constructor ButtonShortcut(); //! Copy Constructor explicit ButtonShortcut(const ButtonShortcut& that); /** * @brief Shortcut assignment constructor. * * Assigns a shortcut as returned by toString(). * * @param shortcut The shortcut to assign. */ explicit ButtonShortcut(const QString& shortcut); /** * @brief Button assignment constructor. * * Assigns a button number to the shortcut. * * @param buttonNumber The button number to assign. */ explicit ButtonShortcut(int buttonNumber); //! Destructor virtual ~ButtonShortcut(); //! Copy operator. ButtonShortcut& operator= (const ButtonShortcut& that); /** * @brief Shortcut assignment operator. * * Assigns a shortcut as returned by toString(). * * @param shortcut The shortcut to assign. */ ButtonShortcut& operator= (const QString& shortcut); //! Equals operator. bool operator== (const ButtonShortcut& that) const; //! Not-Equals operator. bool operator!= (const ButtonShortcut& that) const; /** * Clears the current shortcut. */ void clear(); /** * Returns the button number as integer if this shortcut is a mouse button * shortcut. If it is not a mouse button shortcut, 0 is returned. * * @return The mouse button number if this shortcut is a button shortcut, else 0. */ int getButton() const; /** * @return The shortcut type. */ ShortcutType getType() const; /** * @return True if this shortcut is a mouse button shortcut, else false. */ bool isButton() const; /** * Checks if this shortcut is a keystroke. This does not include modifier * shortcuts! Modifier shortcuts are a special type as they can not be * handled properly by QKeySequence. Therefore a keystroke is a key sequence * which can be handled by QKeySequence. * * @return True if this shortcut is a keystroke, else false. */ bool isKeystroke() const; /** * Checks if this shortcut is a modifier key sequence. Modifier key sequences * only consist of meta keys (ctrl, alt, shift, meta) and can not be handled * properly by QKeySequence. * * @return True if this shortcut is a modifier shortcut, else false. */ bool isModifier() const; /** * @return True if this shortcut is set, else false. */ bool isSet() const; /** * Sets a button shortcut by button number. * * @param buttonNumber The mouse button number this shortcut represents. * * @return True if the shortcut is valid, else false. */ bool setButton(int buttonNumber); /** * Sets this shortcut by string. The shortcut can have one of the following * formats: * * - a mouse button number to set a button shortcut, i.e. "2" * - a keystroke in QKeySequence format, i.e. "Ctrl+x" * - a keystroke in xsetwacom format, i.e. "key ctrl x" or "key +ctrl +x" * - a modifier sequence in QKeySequence format, i.e. "Alt+Shift+Ctrl" * - a modifier sequence in xsetwacom format, i.e. "key alt shift" or "key +alt +shift" * * If the shortcut is invalid it will not be set. * * @param sequence The button, toggle, keystroke or modifier shortcut as string. * * @return True if the shortcut is valid, else false. */ bool set(const QString& sequence); /** * Converts the shortcut to a translated, human readable string. * The result can not be used as input string for this class! * If no shortcut is set, an empty string is returned. * * @return The current shortcut as readble string. */ const QString toDisplayString() const; /** * Converts the current shortcut to QKeySequence format if possible. * Only keystroke shortcuts can be converted to QKeySequence format. * If the shortcut can not be converted, an empty string is returned. * * @return The shortcut in QKeySequence format or an empty string. */ const QString toQKeySequenceString() const; /** * Returns the current shortcut as string in xsetwacom format. This will be: * * - "0" if the sequence is not set * - "modetoggle" if the shortcut is a mode-toggle shortcut. * - "displaytoggle" if the shortcut is a display-toggle shortcut. * - a button number if the shortcut is a mouse button shortcut. * - a modifier or keystroke sequence in xsetwacom format, i.e. "key ctrl x" or "key alt shift" * * @return The shortcut as string in xsetwacom format. */ const QString toString() const; private: /** * A two dimensional array which contains key conversions. The first value * is the key in storage format, the second value is the key in QKeySequence * format. The array has to be NULL terminated! * * DO NOT USE THIS ARRAY DIRECTLY! It is only required to build the static * conversion maps and should not be used for anything else. * * @sa getConvertFromStorageMap() * @sa getConvertToStorageMap() */ static const char* CONVERT_KEY_MAP_DATA[][2]; /** * Converts a key from storage format to QKeySequence format or vice versa. * Storage format is actually the format used by xsetwacom. * * @param key The key to convert. This parameter will also contain the conversion result. * @param fromStorage True to convert from xsetwacom to QKeySequence format, False to convert * from QKeySequence to xsetwacom format. * * @return True if the key was converted, false if it was not touched. */ bool convertKey(QString& key, bool fromStorage) const; /** * Normalizes the key sequence and converts all keys. - * The result is a string of keys seperated by whitespaces. + * The result is a string of keys separated by whitespaces. * * @param sequence The sequence to convert. This parameter will also hold the result of the conversion. * @param fromStorage True to convert from xsetwacom to QKeySequence format, False to convert * from QKeySequence to xsetwacom format. */ void convertToNormalizedKeySequence(QString& sequence, bool fromStorage) const; /** * Normalizes the key sequence and converts it to storage format. - * The result is a string of keys seperated by whitespaces. + * The result is a string of keys separated by whitespaces. * * @param sequence The sequence to convert. This parameter will also hold the result of the conversion. */ void convertKeySequenceToStorageFormat (QString& sequence) const; /** * Normalizes the key sequence and converts it to QKeySequence format. - * The result is a string of keys seperated by whitespaces. + * The result is a string of keys separated by whitespaces. * * @param sequence The sequence to convert. This parameter will also hold the result of the conversion. */ void convertKeySequenceToQKeySequenceFormat (QString& sequence) const; /** * Returns the map which is used to convert keys from storage format to * the QKeySequence format. */ static const QMap& getConvertFromStorageMap(); /** * Returns the map which is used to convert keys from QKeySequence format to * the storage format. */ static const QMap& getConvertToStorageMap(); /** * This is just a helper method to initialize the static conversion maps. * Do not use it for anything else! * * @sa getConvertFromStorageMap() * @sa getConvertToStorageMap() */ static QMap initConversionMap(bool fromStorageMap); /** * Normalizes the key sequence by removing all unnecessary '+' signs. - * The result is a string of keys and modifiers seperated by a whitespace. + * The result is a string of keys and modifiers separated by a whitespace. * This method also does some basic checks to verify that the syntax of * the sequence is valid. If the sequence is invalid it will be cleared and * the result will therefore be an empty string. The result of this method * will be directly written into the parameter \a sequence. * * @param sequence The sequence to normalize. */ void normalizeKeySequence(QString& sequence) const; /** * Prettifies a key by converting the first character to uppercase. * * @param key The key to prettify, this will also contain the result. */ void prettifyKey (QString& key) const; /** * Sets a button sequence. This method expects that the given sequence is * actually a button sequence. If it is not, this method will fail and the * shortcut will not be set. * * @param buttonSequence The mouse button number as string. * * @return True if the button is valid and was set, else false. */ bool setButtonSequence(const QString& buttonSequence); /** * Set a keystroke sequence. This methods expects that the given sequence * is actually a keystroke sequence. If it is not, this method will fail and * the shortcut will not be set. * * @param sequence The keystroke sequence to set. * * @return True if the sequence is valid and was set, else false. */ bool setKeySequence(QString sequence); /** * Sets a modifier sequence. This method expects that the given sequence * is actually a modifier sequence. If it is not, this method will fail and * the shortcut will not be set. * * @param sequence The modifier sequence to set. * * @return True if the sequence is valid and was set, else false. */ bool setModifierSequence(QString sequence); Q_DECLARE_PRIVATE( ButtonShortcut ) ButtonShortcutPrivate *const d_ptr; /**< d-pointer for this class */ }; // CLASS } // NAMESPACE #endif // HEADER PROTECTION diff --git a/src/common/dbustabletinterface.cpp b/src/common/dbustabletinterface.cpp index 5330cfb..c623fd5 100644 --- a/src/common/dbustabletinterface.cpp +++ b/src/common/dbustabletinterface.cpp @@ -1,78 +1,77 @@ /* * 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 "dbustabletinterface.h" #include "stringutils.h" #include #include #include -#include using namespace Wacom; -// instanciate static class members +// instantiate static class members DBusTabletInterface* DBusTabletInterface::m_instance = nullptr; DBusTabletInterface::DBusTabletInterface() : OrgKdeWacomInterface( QLatin1String( "org.kde.Wacom" ), QLatin1String( "/Tablet" ), QDBusConnection::sessionBus()) { DBusTabletInterface::registerMetaTypes(); } DBusTabletInterface& DBusTabletInterface::instance() { if (!m_instance) { static QMutex mutex; mutex.lock(); if (!m_instance) { resetInterface(); } mutex.unlock(); } return *m_instance; } void DBusTabletInterface::resetInterface() { static QMutex mutex; mutex.lock(); if (m_instance) { delete m_instance; m_instance = nullptr; } m_instance = new DBusTabletInterface(); mutex.unlock(); } void DBusTabletInterface::registerMetaTypes() { // nothing to register for now // we keep this method so we have a central location to manage meta-types from //qDBusRegisterMetaType(); } diff --git a/src/common/devicetype.cpp b/src/common/devicetype.cpp index 5328550..ff6cc13 100644 --- a/src/common/devicetype.cpp +++ b/src/common/devicetype.cpp @@ -1,46 +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 . */ #include #include "devicetype.h" using namespace Wacom; /* - * Instanciate static instances-container of the DeviceType template specialization. + * Instantiate static instances-container of the DeviceType template specialization. * This has to be done here obviously before any instance is created. */ template<> DeviceTypeTemplateSpecialization::Container DeviceTypeTemplateSpecialization::instances = DeviceTypeTemplateSpecialization::Container(); bool DeviceType::operator<(const DeviceType& other) const { return(key().compare(other.key(), Qt::CaseInsensitive) < 0); } /* - * Instanciate Device Types. + * Instantiate Device Types. */ const DeviceType DeviceType::Cursor ( QLatin1String("cursor") ); const DeviceType DeviceType::Eraser ( QLatin1String("eraser") ); const DeviceType DeviceType::Pad ( QLatin1String("pad") ); const DeviceType DeviceType::Stylus ( QLatin1String("stylus") ); const DeviceType DeviceType::Touch ( QLatin1String("touch") ); const DeviceType DeviceType::Unknown( QLatin1String("unknown") ); diff --git a/src/common/enum.h b/src/common/enum.h index 5666c3b..d5c5b54 100644 --- a/src/common/enum.h +++ b/src/common/enum.h @@ -1,248 +1,248 @@ /* * 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 ENUM_H #define ENUM_H #include namespace Wacom { /** * A typesafe enumeration template class. It can be used as a comfortable replacement * for C++ enums and supports the following features: * * - enumerators can be listed and iterated over * - enumerator lists are sorted by a given comparator * - enumerators can have a key assigned * - enumerator keys can be listed and searched for * * NOTICE * This class uses template specialization to store a static set of all instances. * Thereofore a specialization of the private instances member 'instances' has - * to be declared and instanciated before this template can be used. + * to be declared and instantiated before this template can be used. * * \tparam D The derived sub class type. This is the class which contains the enum instances. * \tparam K The key type used for these instances. * \tparam L A "less than" functor which can compare objects of type D*. * \tparam E A "equal to" functor which can compare objects of type K. */ template< class D, class K, class L, class E > class Enum { private: typedef QList Container; typedef typename Container::const_iterator ContainerConstIterator; public: typedef typename Container::size_type size_type; /** * A constant iterator which can be used to iterator over all known Enum instances. */ class const_iterator { public: const_iterator() {} const_iterator(const const_iterator& iter) { operator=(iter); } const_iterator(const ContainerConstIterator& iter) { m_iter = iter; } const D& operator*() const { return **m_iter; } const D* operator->() const { return *m_iter; } const_iterator& operator= (const const_iterator& iter) { m_iter = iter.m_iter; return *this; } bool operator==(const const_iterator& iter) const { return (m_iter == iter.m_iter); } bool operator!=(const const_iterator& iter) const { return (m_iter != iter.m_iter); } const_iterator& operator++() { ++m_iter; return *this; } const_iterator operator++(int) { const_iterator copy(*this); ++(*this); return copy; } const_iterator& operator--() { --m_iter; return *this; } const_iterator operator--(int) { const_iterator copy(*this); --(*this); return copy; } private: ContainerConstIterator m_iter; }; /** * Equal-Compare Operator. */ bool operator==(const Enum& that) const { return (m_derived == that.m_derived); } /** * Not-Equal-Compare Operator. */ bool operator!=(const Enum& that) const { return (m_derived != that.m_derived); } /** * @return A constant iterator to the first element. */ static const_iterator begin() { // force the use of const_iterator - fixes compile problem with some containers const Enum::Container* container = &Enum::instances; return const_iterator(container->begin()); } /** * @return A constant iterator to the last element. */ static const_iterator end() { // force the use of const_iterator - fixes compile problem with some containers const Enum::Container* container = &Enum::instances; return const_iterator(container->end()); } /** * Searches for the enumeration instance by key. * * @param key The key of the instance to search. * * @return A constant pointer to the instance or nullptr if not found. */ static const D* find(const K& key) { E comp; for (const_iterator i = begin() ; i != end() ; ++i) { if (comp(i->key(), key)) { return &(*i); } } return nullptr; } /** * @return A list of all valid enum instances of this specialization. */ static QList list() { QList enums; for (const_iterator i = begin() ; i != end() ; ++i) { enums.push_back(*i); } return enums; } /** * @return The key of this enum instance. */ const K& key() const { return m_key; } /** * Returns a list of all instances' keys of this specialization. * * @return A list of keys sorted by the less-than-functor. */ static QList keys() { QList keys; for (const_iterator i = begin() ; i != end() ; ++i) { keys.push_back(i->key()); } return keys; } /** * @return The number of enum instances of this specialization. */ static size_type size() { return Enum::instances.size(); } protected: /** * Initialization constructor. * Used to initialize class-static members. Never make this constructor * available to the public! Never use it for normal instances! It may - * only be used to instanciate class-static Enum instances. + * only be used to instantiate class-static Enum instances. * * @param key The key of this class-static Enum instance. * @param priority The sort order priority of this instance. */ explicit Enum( const D* derived, const K& key ) : m_key(key) { m_derived = derived; insert(derived); } /** * \return A const pointer to the derived class of this instance. */ const D* derived() const { return m_derived; } private: /** * Inserts an element into to the static instances container. * This method should only be called by the constructor! * * \param derived An instance of the derived class, never NULL. */ void insert(const D* derived) { L comp; typename Enum::Container::iterator i = this->instances.begin(); for (; i != this->instances.end() ; ++i) { if (comp(derived, *i)) { this->instances.insert(i, derived); return; } } this->instances.push_back(derived); } K m_key; /**< The key of this instance */ const D* m_derived; /**< Pointer to derived class for fast comparison */ /** * A static container with all the class-static Enum instances. - * Every specialization of this template has to declare and instanciate + * Every specialization of this template has to declare and instantiate * the specialization of this member variable! */ static Container instances; }; // CLASS } // NAMESPACE #endif // HEADER PROTECTION diff --git a/src/common/libwacomwrapper.cpp b/src/common/libwacomwrapper.cpp index 467d119..2e86fd7 100644 --- a/src/common/libwacomwrapper.cpp +++ b/src/common/libwacomwrapper.cpp @@ -1,201 +1,201 @@ /* * 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 "logging.h" #include extern "C" { #include } namespace Wacom { static int skipWheelButtons(int button) { // skip buttons 4-7, which correspond to vertical/horizontal wheel up/down events if (button > 3) { return button + 4; } else { return button; } } #ifndef LIBWACOM_EVDEV_MISSING static int convertEvdevToXsetwacomButton(int evdevCode); #endif // LIBWACOM_EVDEV_MISSING 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) { qCDebug(COMMON) << "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) { qCInfo(COMMON) << "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 const auto layoutFileName = libwacom_get_layout_filename(device.get()); if (layoutFileName) { tabletInfo.set(TabletInfo::ButtonLayout, QString::fromLatin1(layoutFileName)); } // 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, 0); tabletInfo.set(TabletInfo::TabletName, QString::fromLatin1(libwacom_get_name(device.get()))); const int padButtonNumber = libwacom_get_num_buttons(device.get()); tabletInfo.set(TabletInfo::NumPadButtons, padButtonNumber); // Convert button evdev codes to buttonMap if (libwacom_get_num_buttons(device.get()) > 0) { QMap buttonMapping; - for (char i = 1; i < padButtonNumber + 1; i++) { + for (char i = 1; i < padButtonNumber + 1; ++i) { #ifdef LIBWACOM_EVDEV_MISSING // TODO: warn the user in the KCM too qCWarning(COMMON) << "Your libwacom version is too old. We will try and guess button mapping, " << "but it's going to be broken for quirky tablets. Paired device detection is going to be broken as well." << "Use kde_wacomtablet_finder to configure your device instead."; const int buttonIndex = skipWheelButtons(i); buttonMapping[QString::number(i)] = QString::number(buttonIndex); #else const char buttonChar = 'A' + (i - 1); // libwacom marks buttons as 'A', 'B', 'C'... const int buttonEvdevCode = libwacom_get_button_evdev_code(device.get(), buttonChar); const int buttonIndex = convertEvdevToXsetwacomButton(buttonEvdevCode); buttonMapping[QString::number(i)] = QString::number(buttonIndex); if (buttonIndex < 1) { qCWarning(COMMON) << "Unrecognized evdev code. " << "Device:" << tabletId << "Vendor:" << vendorId << "Button:" << buttonChar << "EvdevCode:" << buttonEvdevCode; return false; } #endif } tabletInfo.setButtonMap(buttonMapping); } #ifndef LIBWACOM_EVDEV_MISSING const WacomMatch* paired_device_match = libwacom_get_paired_device(device.get()); if (paired_device_match) { const std::uint32_t pairedTabletId = libwacom_match_get_product_id(paired_device_match); const std::uint32_t pairedVendorId = libwacom_match_get_vendor_id(paired_device_match); const auto pairedDeviceID = QString::number(pairedTabletId, 16); tabletInfo.set(TabletInfo::TouchSensorId, pairedDeviceID); qCDebug(COMMON) << "Libwacom reported a paired device" << pairedTabletId << pairedVendorId << pairedDeviceID; } #endif const int numStrips = libwacom_get_num_strips(device.get()); const bool hasLeftStrip = numStrips > 0; const bool hasRightStrip = numStrips > 1; const 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; } #ifndef LIBWACOM_EVDEV_MISSING static int convertMouseEvdevToXsetwacomButton(int evdevCode) { // some quirky consumer tablets, e.g. Bamboo/Graphire, use mouse button events // instead of just numbered express keys. Translate them back to numbers static const int BTN_LEFT = 0x110; static const int BTN_RIGHT = 0x111; static const int BTN_MIDDLE = 0x112; static const int BTN_FORWARD = 0x115; static const int BTN_BACK = 0x116; switch (evdevCode) { case BTN_LEFT: return 1; case BTN_RIGHT: return 3; case BTN_MIDDLE: return 2; case BTN_FORWARD: return 9; case BTN_BACK: return 8; default: return 0; } } static int convertEvdevToXsetwacomButton(int evdevCode) { // based on set_button_codes_from_heuristics from libwacom/libwacom-database.c static const int BTN_MISC = 0x100; static const int BTN_MOUSE = 0x110; static const int BTN_BASE = 0x126; static const int BTN_GAMEPAD = 0x130; int translatedCode = 0; if (evdevCode >= BTN_GAMEPAD) { translatedCode = evdevCode - BTN_GAMEPAD + 10; } else if (evdevCode >= BTN_BASE) { translatedCode = evdevCode - BTN_BASE + 16; } else if (evdevCode >= BTN_MOUSE) { return convertMouseEvdevToXsetwacomButton(evdevCode); } else if (evdevCode >= BTN_MISC) { translatedCode = evdevCode - BTN_MISC; } else { return 0; } return skipWheelButtons(translatedCode + 1); } #endif // LIBWACOM_EVDEV_MISSING } // namespace ends diff --git a/src/common/property.cpp b/src/common/property.cpp index 1d44077..2cee2d8 100644 --- a/src/common/property.cpp +++ b/src/common/property.cpp @@ -1,89 +1,89 @@ /* * 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 #include "property.h" using namespace Wacom; /* - * Instanciate static instances-container of the Property template specialization. + * Instantiate static instances-container of the Property template specialization. * This has to be done here obviously before any instance is created. */ template<> PropertyTemplateSpecialization::Container PropertyTemplateSpecialization::instances = PropertyTemplateSpecialization::Container(); /* - * Instanciate Properties. + * Instantiate Properties. */ const Property Property::AbsWheel2Down ( QLatin1String("AbsWheel2Down") ); const Property Property::AbsWheel2Up ( QLatin1String("AbsWheel2Up") ); const Property Property::AbsWheelDown ( QLatin1String("AbsWheelDown") ); const Property Property::AbsWheelUp ( QLatin1String("AbsWheelUp") ); const Property Property::Area ( QLatin1String("Area") ); const Property Property::Button1 ( QLatin1String("Button1") ); const Property Property::Button2 ( QLatin1String("Button2") ); const Property Property::Button3 ( QLatin1String("Button3") ); const Property Property::Button4 ( QLatin1String("Button4") ); const Property Property::Button5 ( QLatin1String("Button5") ); const Property Property::Button6 ( QLatin1String("Button6") ); const Property Property::Button7 ( QLatin1String("Button7") ); const Property Property::Button8 ( QLatin1String("Button8") ); const Property Property::Button9 ( QLatin1String("Button9") ); const Property Property::Button10 ( QLatin1String("Button10") ); const Property Property::Button11 ( QLatin1String("Button11") ); const Property Property::Button12 ( QLatin1String("Button12") ); const Property Property::Button13 ( QLatin1String("Button13") ); const Property Property::Button14 ( QLatin1String("Button14") ); const Property Property::Button15 ( QLatin1String("Button15") ); const Property Property::Button16 ( QLatin1String("Button16") ); const Property Property::Button17 ( QLatin1String("Button17") ); const Property Property::Button18 ( QLatin1String("Button18") ); const Property Property::CursorAccelProfile ( QLatin1String("CursorAccelProfile") ); const Property Property::CursorAccelConstantDeceleration ( QLatin1String("CursorAccelConstantDeceleration") ); const Property Property::CursorAccelAdaptiveDeceleration ( QLatin1String("CursorAccelAdaptiveDeceleration") ); const Property Property::CursorAccelVelocityScaling ( QLatin1String("CursorAccelVelocityScaling") ); const Property Property::CursorProximity ( QLatin1String("CursorProximity") ); const Property Property::Gesture ( QLatin1String("Gesture") ); const Property Property::InvertScroll ( QLatin1String("InvertScroll") ); const Property Property::MapToOutput ( QLatin1String("MapToOutput") ); const Property Property::Mode ( QLatin1String("Mode") ); const Property Property::PressureCurve ( QLatin1String("PressureCurve") ); const Property Property::RawSample ( QLatin1String("RawSample") ); const Property Property::RelWheelDown ( QLatin1String("RelWheelDown") ); const Property Property::RelWheelUp ( QLatin1String("RelWheelUp") ); const Property Property::ResetArea ( QLatin1String("ResetArea") ); const Property Property::Rotate ( QLatin1String("Rotate") ); const Property Property::ScreenMap ( QLatin1String("ScreenMap") ); const Property Property::ScreenSpace ( QLatin1String("ScreenSpace") ); const Property Property::ScrollDistance ( QLatin1String("ScrollDistance") ); const Property Property::StatusLEDs ( QLatin1String("StatusLEDs") ); const Property Property::StatusLEDsBrightness ( QLatin1String("StatusLEDsBrightness") ); const Property Property::StripLeftDown ( QLatin1String("StripLeftDown") ); const Property Property::StripLeftUp ( QLatin1String("StripLeftUp") ); const Property Property::StripRightDown ( QLatin1String("StripRightDown") ); const Property Property::StripRightUp ( QLatin1String("StripRightUp") ); const Property Property::Suppress ( QLatin1String("Suppress") ); const Property Property::TabletPcButton ( QLatin1String("TabletPcButton") ); const Property Property::TapTime ( QLatin1String("TapTime") ); const Property Property::Threshold ( QLatin1String("Threshold") ); const Property Property::Touch ( QLatin1String("Touch") ); const Property Property::ZoomDistance ( QLatin1String("ZoomDistance") ); diff --git a/src/common/propertyset.h b/src/common/propertyset.h index a95b87c..cd98ca5 100644 --- a/src/common/propertyset.h +++ b/src/common/propertyset.h @@ -1,138 +1,138 @@ /* * 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 PROPERTYSET_H #define PROPERTYSET_H #include "enum.h" #include "property.h" #include #include #include namespace Wacom { template struct PropertySetTemplateSpecializationLessFunctor { bool operator()(const D* d1, const D* d2) { Q_UNUSED(d1); Q_UNUSED(d2); if ((d1 == d2) || !(d1->key().compare(d2->key(), Qt::CaseInsensitive))) { // FIXME: this template header spans across modules // which do not share logging categories qWarning() << "Adding the same key or the same element is a severe error"; } // property sets should keep the order they were defined return false; } }; /** * A typesafe property enumeration template class. It manages property keys, * mapping ids and priority handling for different kind of property sets. * * Different subsystems have different type of property sets and different * property identifier keys. Moreover properties have to be set in a specific * order or they might overwrite each other. Still all these property sets * have to be mapped on subsystem borders. * * NOTICE * This class uses template specialization to store a static set of all instances. * Thereofore a specialization of the private instances member 'm_instances' has - * to be declared and instanciated before this template can be used. + * to be declared and instantiated before this template can be used. */ template, class E = PropertyKeyEqualsFunctor> class PropertySet : public Enum { public: // typedef for easy maintenance // this has to be the same as the specialization of our base class typedef Enum PropertySetTemplateSpecialization; /** * Maps the given property to an instance of this property set. * * @param id The property id to search for. * * @return A constant pointer to the property or nullptr if the property is not supported by this set. */ static const D* map (const Property& property) { typename PropertySetTemplateSpecialization::const_iterator i = PropertySetTemplateSpecialization::begin(); for ( ; i != PropertySetTemplateSpecialization::end() ; ++i) { if (i->id() == property) { return &(*i); } } return nullptr; } /** * @return The property identifier of this property instance. */ const Property& id() const { return *m_id; } /** * @return A list of property ids supported by this set. */ static QList ids() { QList ids; for (typename PropertySetTemplateSpecialization::const_iterator i = PropertySetTemplateSpecialization::begin() ; i != PropertySetTemplateSpecialization::end() ; ++i) { ids.push_back(i->id()); } return ids; } protected: /** * Initialization constructor. * Used to initialize class-static members. Never make this constructor - * available to the public! It is only used to instanciate class-static + * available to the public! It is only used to instantiate class-static * PropertySet instances. * * @param key The key of this class-static PropertySet instance. */ explicit PropertySet( const D* super, const Property& id, const QString& key ) : PropertySetTemplateSpecialization(super, key) { m_id = &id; } private: const Property *m_id = nullptr; /**< The property identifier used to map between different property sets */ }; // CLASS } // NAMESPACE #endif // HEADER PROTECTION diff --git a/src/common/screenrotation.cpp b/src/common/screenrotation.cpp index f8e1e59..dc98b62 100644 --- a/src/common/screenrotation.cpp +++ b/src/common/screenrotation.cpp @@ -1,54 +1,54 @@ /* * 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 "screenrotation.h" using namespace Wacom; /* - * Instanciate static instances-container of the ScreenRotation template specialization. + * Instantiate static instances-container of the ScreenRotation template specialization. * This has to be done here obviously before any instance is created. */ template<> ScreenRotationTemplateSpecialization::Container ScreenRotationTemplateSpecialization::instances = ScreenRotationTemplateSpecialization::Container(); /* - * Instanciate Device Types. + * Instantiate Device Types. */ const ScreenRotation ScreenRotation::NONE ( QLatin1String("none") ); const ScreenRotation ScreenRotation::CCW ( QLatin1String("ccw") ); const ScreenRotation ScreenRotation::HALF ( QLatin1String("half") ); const ScreenRotation ScreenRotation::CW ( QLatin1String("cw") ); const ScreenRotation ScreenRotation::AUTO ( QLatin1String("auto") ); const ScreenRotation ScreenRotation::AUTO_INVERTED ( QLatin1String("auto-inverted") ); const ScreenRotation& ScreenRotation::invert() const { if (*this == ScreenRotation::CW) { return ScreenRotation::CCW; } else if (*this == ScreenRotation::CCW) { return ScreenRotation::CW; } return *this; } diff --git a/src/common/tabletinfo.cpp b/src/common/tabletinfo.cpp index a0547e9..0e36526 100644 --- a/src/common/tabletinfo.cpp +++ b/src/common/tabletinfo.cpp @@ -1,51 +1,51 @@ /* * 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 #include "tabletinfo.h" using namespace Wacom; /* - * Instanciate static instances-container of the TabletInfo template specialization. + * Instantiate static instances-container of the TabletInfo template specialization. * This has to be done here obviously before any instance is created. */ template<> TabletInfoTemplateSpecialization::Container TabletInfoTemplateSpecialization::instances = TabletInfoTemplateSpecialization::Container(); /* * Instantiate Properties. */ const TabletInfo TabletInfo::ButtonLayout ( QLatin1String("ButtonLayout") ); const TabletInfo TabletInfo::CompanyId ( QLatin1String("CompanyId") ); const TabletInfo TabletInfo::CompanyName ( QLatin1String("CompanyName") ); const TabletInfo TabletInfo::HasLeftTouchStrip ( QLatin1String("HasLeftTouchStrip")); const TabletInfo TabletInfo::HasRightTouchStrip ( QLatin1String("HasRightTouchStrip")); const TabletInfo TabletInfo::HasTouchRing ( QLatin1String("HasTouchRing")); const TabletInfo TabletInfo::HasWheel ( QLatin1String("HasWheel")); const TabletInfo TabletInfo::NumPadButtons ( QLatin1String("NumPadButtons")); const TabletInfo TabletInfo::StatusLEDs ( QLatin1String("StatusLEDs")); const TabletInfo TabletInfo::TabletId ( QLatin1String("TabletId") ); const TabletInfo TabletInfo::TabletModel ( QLatin1String("TabletModel") ); const TabletInfo TabletInfo::TabletName ( QLatin1String("TabletName") ); const TabletInfo TabletInfo::TabletSerial ( QLatin1String("TabletSerial") ); const TabletInfo TabletInfo::TouchSensorId ( QLatin1String("TouchSensorId") ); const TabletInfo TabletInfo::IsTouchSensor ( QLatin1String("IsTouchSensor") ); diff --git a/src/common/x11inputdevice-xlib.cpp b/src/common/x11inputdevice-xlib.cpp index d4f9e4d..5f617b1 100644 --- a/src/common/x11inputdevice-xlib.cpp +++ b/src/common/x11inputdevice-xlib.cpp @@ -1,565 +1,565 @@ /* * 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 "logging.h" -#include +#include #include "x11inputdevice.h" #include #include #include #include using namespace Wacom; /** * Class for private members. */ namespace Wacom { class X11InputDevicePrivate { public: - QString name = QString(); - XDevice * device = nullptr; - Display * display = QX11Info::display(); + QString name; + XDevice *device = nullptr; + Display *display = QX11Info::display(); }; } X11InputDevice::X11InputDevice() : d_ptr(new X11InputDevicePrivate) { } X11InputDevice::X11InputDevice(XID id, const QString& name) : d_ptr(new X11InputDevicePrivate) { open(id, name); } X11InputDevice::X11InputDevice(const X11InputDevice& device) : d_ptr(new X11InputDevicePrivate) { operator=(device); } X11InputDevice::~X11InputDevice() { close(); delete d_ptr; } X11InputDevice& X11InputDevice::operator= (const X11InputDevice& that) { // close current device close(); // connect new device if (that.d_ptr->device) { open(that.d_ptr->device->device_id, that.d_ptr->name); } return *this; } bool X11InputDevice::close() { Q_D(X11InputDevice); if (d->device == nullptr) { Q_ASSERT(d->name.isEmpty()); return false; } XCloseDevice(d->display, d->device); d->device = nullptr; d->name.clear(); return true; } bool X11InputDevice::getAtomProperty(const QString& property, QList< long int >& values, long int nelements) const { return getProperty(property, XA_ATOM, nelements, values); } const QVector X11InputDevice::getDeviceButtonMapping() const { Q_D(const X11InputDevice); QVector buttonMap; if (!isOpen()) { return buttonMap; } // Give it plenty of room! uint8_t map_return[128]; int buttonCount = XGetDeviceButtonMapping(d->display, d->device, map_return, 128); for (int i = 0 ; i < buttonCount ; ++i) { buttonMap.append(map_return[i]); } return buttonMap; } long int X11InputDevice::getDeviceId() const { Q_D(const X11InputDevice); if (!isOpen()) { return 0; } return d->device->device_id; } Display* X11InputDevice::getDisplay() const { Q_D(const X11InputDevice); return d->display; } bool X11InputDevice::getFloatProperty(const QString& property, QList< float >& values, long int nelements) const { if (!isOpen()) { return false; } Atom float_atom; bool success = lookupProperty(QString::fromLatin1("FLOAT"), float_atom); if (success == false) { qCWarning(COMMON) << QLatin1String("Float values are unsupported by this XInput implementation!"); return false; } return getProperty(property, float_atom, nelements, values); } bool X11InputDevice::getLongProperty(const QString& property, QList< long int >& values, long int nelements) const { return getProperty(property, XA_INTEGER, nelements, values); } bool X11InputDevice::getInt32Property(const QString& property, QList< uint32_t >& values, long int nelements) const { return getProperty(property, XA_INTEGER, nelements, values); } const QString& X11InputDevice::getName() const { Q_D(const X11InputDevice); return d->name; } bool X11InputDevice::getStringProperty(const QString& property, QList< QString >& values, long int nelements) const { // get property data & values unsigned char* data = nullptr; unsigned long nitems = 0; int expectedFormat = 8; if (!getPropertyData(property, XA_STRING, expectedFormat, nelements, &data, nitems)) { return false; } unsigned char* strData = data; for (unsigned long i = 0 ; i < nitems ; ++i) { // add first string value up to '\0' QString value = QLatin1String ((const char*)strData); values.append(value); // ++i will jump over '\0' i += value.length(); strData += value.length(); } XFree(data); return true; } bool X11InputDevice::hasProperty(const QString& property) const { Q_D(const X11InputDevice); if (!isOpen()) { // some devices like the virtual core keyboard/pointer can not be opened qCDebug(COMMON) << QString::fromLatin1("Cannot check property '%1' on a device which is not open!").arg(property); return false; } Atom atom; if (!lookupProperty(property, atom)) { return false; } bool found = false; int num_atoms; Atom * reply = XListDeviceProperties(d->display, d->device, &num_atoms); if (reply) { for (int i = 0 ; i < num_atoms; ++i) { if (reply[i] == atom) { found = true; break; } } free(reply); } return found; } bool X11InputDevice::isOpen() const { Q_D(const X11InputDevice); return (d->device != nullptr && d->display != nullptr); } bool X11InputDevice::isTabletDevice() { return hasProperty(QLatin1String("Wacom Tool Type")); } bool X11InputDevice::open(XID id, const QString& name) { Q_D(X11InputDevice); if (isOpen()) { close(); } if (id == 0) { qCWarning(COMMON) << QString::fromLatin1("Unable to open device '%1' as invalid parameters were provided!").arg(name); return false; } XDevice * device = XOpenDevice( d->display , id); if (device == nullptr) { // some virtual devices can not be opened qCWarning(COMMON) << QString::fromLatin1("XOpenDevice failed on device id '%1'!").arg(id); return false; } d->device = device; d->name = name; return true; } bool X11InputDevice::setDeviceButtonMapping(const QVector &buttonMap) const { Q_D(const X11InputDevice); if (!isOpen() || buttonMap.count() == 0) { return false; } int result = XSetDeviceButtonMapping(d->display, d->device, QVector(buttonMap).data(), buttonMap.count()); qCDebug(COMMON) << "setDeviceButtonMapping returned result" << result; return (result == 0); } bool X11InputDevice::setFloatProperty(const QString& property, const QString& values) const { QStringList valueList = values.split (QLatin1String(" ")); bool ok; QString svalue; float fvalue; QList fvalues; for (int i = 0 ; i < valueList.size() ; ++i) { svalue = valueList.at(i); if (svalue.isEmpty()) { continue; } fvalue = svalue.toFloat(&ok); if (!ok) { qCWarning(COMMON) << QString::fromLatin1("Could not convert value '%1' to float!").arg(svalue); return false; } fvalues.append(fvalue); } return setFloatProperty(property, fvalues); } bool X11InputDevice::setFloatProperty(const QString& property, const QList< float >& values) const { if (!isOpen()) { return false; } Atom float_atom; bool has_float = lookupProperty(QString::fromLatin1("FLOAT"), float_atom); if (!has_float) { qCWarning(COMMON) << QLatin1String("Float values are unsupported by this XInput implementation!"); return false; } return setProperty(property, float_atom, values); } bool X11InputDevice::setLongProperty(const QString& property, const QString& values) const { QStringList valueList = values.split (QLatin1String(" ")); bool ok; QString svalue; long lvalue = 0; QList lvalues; for (int i = 0 ; i < valueList.size() ; ++i) { svalue = valueList.at(i); if (svalue.isEmpty()) { continue; } lvalue = svalue.toLong(&ok, 10); if (!ok) { qCWarning(COMMON) << QString::fromLatin1("Could not convert value '%1' to long!").arg(svalue); return false; } lvalues.append(lvalue); } return setLongProperty(property, lvalues); } bool X11InputDevice::setLongProperty(const QString& property, const QList< long int >& values) const { return setProperty(property, XA_INTEGER, values); } bool X11InputDevice::setInt32Property(const QString& property, const QList< uint32_t >& values) const { return setProperty(property, XA_INTEGER, values); } template bool X11InputDevice::getProperty(const QString& property, Atom expectedType, long int nelements, QList< T >& values) const { // get property data & values long* data = nullptr; unsigned long nitems = 0; int expectedFormat = 32; if (!getPropertyData(property, expectedType, expectedFormat, nelements, (unsigned char**)&data, nitems)) { return false; } for (unsigned long i = 0 ; i < nitems ; ++i) { T dataItem = 0; memcpy(&dataItem, data + i, sizeof(T)); values.append(dataItem); } XFree(data); return true; } bool X11InputDevice::getPropertyData (const QString& property, Atom expectedType, int expectedFormat, long int nelements, unsigned char** data, long unsigned int &nitems) const { Q_D(const X11InputDevice); // check parameters if (!isOpen()) { qCWarning(COMMON) << QString::fromLatin1 ("Can not get XInput property '%1' as no device was opened!").arg(property); return false; } // lookup property atom Atom propertyAtom = 0; if (!lookupProperty(property, propertyAtom)) { qCWarning(COMMON) << QString::fromLatin1("Can't get unsupported XInput property '%1'!").arg(property); return false; } // get device property and validate it Atom actualType = None; int actualFormat = 0; unsigned long bytes_after = 0; if (XGetDeviceProperty (d->display, d->device, propertyAtom, 0, nelements, False, AnyPropertyType, &actualType, &actualFormat, &nitems, &bytes_after, data) != Success) { qCWarning(COMMON) << QString::fromLatin1("Could not get XInput property '%1'!").arg(property); return false; } if (actualFormat != expectedFormat || actualType != expectedType) { qCWarning(COMMON) << QString::fromLatin1("Can not process incompatible Xinput property '%1': Format is '%2', expected was '%3'. Type is '%4', expected was '%5'.").arg(property).arg(actualFormat).arg(expectedFormat).arg(actualType).arg(expectedType); XFree(data); return false; } return true; } bool X11InputDevice::lookupProperty(const QString& property, Atom &atom) const { Q_D(const X11InputDevice); if (!isOpen() || property.isEmpty()) { return false; } atom = XInternAtom(d->display, property.toLatin1().constData(), false); if (atom == None) { qCWarning(COMMON) << QString::fromLatin1("The X server does not support XInput property '%1'!").arg(property); return false; } return true; } template bool X11InputDevice::setProperty(const QString& property, Atom expectedType, const QList< T >& values) const { /* This part is simply a double-check copied from getProperty_impl... */ Q_D(const X11InputDevice); // for XInput1 the data is 32 bits for each property int expectedFormat = 32; // check parameters if (!isOpen()) { qCWarning(COMMON) << QString::fromLatin1 ("Can not get XInput property '%1' as no device was opened!").arg(property); return false; } if (values.size() == 0) { qCWarning(COMMON) << QString::fromLatin1 ("Can not set XInput property '%1' as no values were provided!").arg(property); return false; } // lookup property atom Atom propertyAtom = 0; if (!lookupProperty(property, propertyAtom)) { qCWarning(COMMON) << QString::fromLatin1("Can not get unsupported XInput property '%1'!").arg(property); return false; } // get property first to validate format and type Atom actualType; int actualFormat; unsigned long nitems, bytes_after; unsigned char *actualData = nullptr; if (XGetDeviceProperty (d->display, d->device, propertyAtom, 0, values.size(), False, AnyPropertyType, &actualType, &actualFormat, &nitems, &bytes_after, (unsigned char **)&actualData) != Success) { qCWarning(COMMON) << QString::fromLatin1("Could not get XInput property '%1' for type and format validation!").arg(property); return false; } XFree(actualData); if (actualFormat != expectedFormat || actualType != expectedType) { qCWarning(COMMON) << QString::fromLatin1("Can not process incompatible Xinput property '%1': Format is '%2', expected was '%3'. Type is '%4', expected was '%5'.").arg(property).arg(actualFormat).arg(expectedFormat).arg(actualType).arg(expectedType); return false; } // create new data array - long instead of uint32_t seems to be correct for xlib long *data = new long[values.size()]; for (int i = 0 ; i < values.size() ; ++i) { const T& value = values.at(i); memcpy(data + i, &value, sizeof(T)); } XChangeDeviceProperty( d->display, d->device, propertyAtom, expectedType, 32, PropModeReplace, (unsigned char*)data, values.size()); // cleanup delete[] data; // flush the output buffer to make sure all properties are updated XFlush(d->display); return true; } diff --git a/src/dataengine/wacomtabletengine.cpp b/src/dataengine/wacomtabletengine.cpp index f37e266..066d26c 100644 --- a/src/dataengine/wacomtabletengine.cpp +++ b/src/dataengine/wacomtabletengine.cpp @@ -1,164 +1,164 @@ /* * 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. */ #include "wacomtabletengine.h" #include "wacomtabletservice.h" #include "dbustabletinterface.h" #include "multidbuspendingcallwatcher.h" using namespace Wacom; WacomTabletEngine::WacomTabletEngine(QObject* parent, const QVariantList& args): DataEngine(parent, args) ,m_source(QLatin1Literal("wacomtablet")) { // init dbus service watcher QDBusServiceWatcher* dbusServiceWatcher = new QDBusServiceWatcher(this); dbusServiceWatcher->setWatchedServices (QStringList(QLatin1Literal("org.kde.Wacom"))); dbusServiceWatcher->setWatchMode (QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration); dbusServiceWatcher->setConnection (QDBusConnection::sessionBus()); connect(dbusServiceWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(onDBusConnected())); connect(dbusServiceWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(onDBusDisconnected())); onDBusConnected(); } WacomTabletEngine::~WacomTabletEngine() { } void WacomTabletEngine::onDBusConnected() { DBusTabletInterface::resetInterface(); if( !DBusTabletInterface::instance().isValid() ) { onDBusDisconnected(); return; } setData(m_source, QLatin1Literal("serviceAvailable"), true); connect( &DBusTabletInterface::instance(), SIGNAL(tabletAdded(QString)), this, SLOT(onTabletAdded(QString)) ); connect( &DBusTabletInterface::instance(), SIGNAL(tabletRemoved(QString)), this, SLOT(onTabletRemoved(QString)) ); connect( &DBusTabletInterface::instance(), SIGNAL(profileChanged(QString,QString)), this, SLOT(setProfile(QString,QString)) ); // get list of connected tablets QDBusReply connectedTablets = DBusTabletInterface::instance().getTabletList(); foreach(const QString &tabletId, connectedTablets.value()) { onTabletAdded(tabletId); } } void WacomTabletEngine::onDBusDisconnected() { setData(m_source, QLatin1Literal("serviceAvailable"), false); const auto keys = m_tablets.keys(); - for(auto iter = keys.begin(); iter != keys.end(); iter++) { + for (auto iter = keys.begin(); iter != keys.end(); ++iter) { onTabletRemoved(*iter); } m_tablets.clear(); } void WacomTabletEngine::onTabletAdded(const QString& tabletId) { if (m_tablets.contains(tabletId)) { return; } QDBusReply isTouchSensor = DBusTabletInterface::instance().isTouchSensor(tabletId); if (isTouchSensor.isValid() && isTouchSensor.value()) { return; } QList callList; callList << DBusTabletInterface::instance().getInformation(tabletId, TabletInfo::TabletName.key()) << DBusTabletInterface::instance().listProfiles(tabletId) << DBusTabletInterface::instance().getProfile(tabletId) << DBusTabletInterface::instance().getProperty(tabletId, DeviceType::Stylus.key(), Property::Mode.key()) << DBusTabletInterface::instance().getDeviceName(tabletId, DeviceType::Touch.key()) << DBusTabletInterface::instance().getProperty(tabletId, DeviceType::Touch.key(), Property::Touch.key()); MultiDBusPendingCallWatcher *watcher = new MultiDBusPendingCallWatcher(callList, this); connect(watcher, &MultiDBusPendingCallWatcher::finished, [this, watcher, tabletId](const QList& watchers) { watcher->deleteLater(); Q_FOREACH(auto watcher, watchers) { if (watcher->isError()) { return; } } QDBusPendingReply deviceName = *watchers[0]; QDBusPendingReply profileListReply = *watchers[1]; QDBusPendingReply profileName = *watchers[2]; QDBusPendingReply stylusMode = *watchers[3]; QDBusPendingReply hasTouch = *watchers[4]; QDBusPendingReply touchMode = *watchers[5]; const QString sourceName = QString(QLatin1Literal("Tablet%1")).arg(tabletId); auto& tabletData = m_tablets[tabletId]; tabletData.name = deviceName.value(); const auto profileList = profileListReply.value(); tabletData.profiles = profileList; int item = profileList.indexOf(profileName.value()); tabletData.currentProfile = item; tabletData.hasTouch = (hasTouch.isValid() && !hasTouch.value().isEmpty()); tabletData.touch = tabletData.hasTouch ? QString( touchMode ).contains( QLatin1String( "on" )) : false; tabletData.stylusMode = ( QString( stylusMode ).contains( QLatin1String( "absolute" )) || QString( stylusMode ).contains( QLatin1String( "Absolute" )) ); setData(sourceName, QLatin1Literal("currentProfile"), tabletData.currentProfile); setData(sourceName, QLatin1Literal("hasTouch"), tabletData.hasTouch); setData(sourceName, QLatin1Literal("touch"), tabletData.touch); setData(sourceName, QLatin1Literal("profiles"), tabletData.profiles); setData(sourceName, QLatin1Literal("stylusMode"), tabletData.stylusMode); setData(sourceName, QLatin1Literal("name"), tabletData.name); setData(sourceName, QLatin1Literal("id"), tabletId); }); } void WacomTabletEngine::onTabletRemoved(const QString& tabletId) { const QString sourceName = QString(QLatin1Literal("Tablet%1")).arg(tabletId); m_tablets.remove(tabletId); removeSource(sourceName); } void WacomTabletEngine::setProfile(const QString& tabletId, const QString& profile) { if (!m_tablets.contains(tabletId)) { return; } int item = m_tablets[tabletId].currentProfile = m_tablets[tabletId].profiles.indexOf(profile); const QString sourceName = QString(QLatin1Literal("Tablet%1")).arg(tabletId); setData(sourceName, QLatin1Literal("currentProfile"), item); } Plasma::Service* WacomTabletEngine::serviceForSource(const QString& source) { if (source == m_source) { return new WacomTabletService(source, this); } return Plasma::DataEngine::serviceForSource(source); } K_EXPORT_PLASMA_DATAENGINE_WITH_JSON(wacomtablet, WacomTabletEngine, "plasma-dataengine-wacomtablet.json") #include "wacomtabletengine.moc" diff --git a/src/kcmodule/areaselectionwidget.h b/src/kcmodule/areaselectionwidget.h index 8743710..0ae5475 100644 --- a/src/kcmodule/areaselectionwidget.h +++ b/src/kcmodule/areaselectionwidget.h @@ -1,430 +1,430 @@ /* * 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 AREASELECTIONWIDGET_H #define AREASELECTIONWIDGET_H #include #include #include #include #include class QBrush; class QPainter; namespace Wacom { class AreaSelectionWidgetPrivate; class AreaSelectionWidget : public QWidget { Q_OBJECT public: bool paintBelow{false}; explicit AreaSelectionWidget(QWidget* parent = 0); virtual ~AreaSelectionWidget(); /** * Resets the selection back to the full size. */ void clearSelection(); /** * Gets the currently selected area. * * @return The currently selected area. */ const QRect getSelection() const; /** * Returns the current selection as string. * Format is: "x y width height" * * @return The current selection as string. */ const QString getSelectionAsString() const; /** * @return The virtual area rectangle which is the union of all areas currently set. */ const QRect& getVirtualArea() const; /** * Sets the area which should be scaled and displayed to the user. * * @param area The area to scale and present to the user. * @param caption An optional caption which is drawn in the center of the area. */ void setArea(const QRect& area, const QString& caption); /** * Sets the areas which should be scaled and displayed to the user. * All areas will be united and displayed as one big area to the user. * Therefore the areas should be adjecent or overlapping. * * @param areas The areas to display to the user. * @param caption Optional captions to draw in the center of each area. */ void setAreas(const QMap &areas, const QStringList& areaCaptions); /** * Enables or disables drawing of area captions. * * @param value True to draw area captions, false to not draw them. */ void setDrawAreaCaptions(bool value); /** * Enables or disables drawing of the selection area caption. * * @param value True to draw caption, false to not draw it. */ void setDrawSelectionCaption(bool value); /** * Sets the font used to draw all captions. * * @param font The font used for captions. */ void setFont(const QFont& font); /** * Sets the out of bounds margin in pixels or as a percentage. * The out of bounds margin is the amount of pixels, the user is * allowed to drag the selected area outside the bounds of the * displayed area. The margin has to be given as a percentage value * or as a positive value in real size pixels. * * @param margin A percentage (0. - 1.0) or a positive value in pixels. */ void setOutOfBoundsMargin(qreal margin); /** * Selects an area. * * @param selection The area to select. */ void setSelection(const QRect& selection, bool emitUpdate); /** * Selects an area by area index. This is the index from the list * the widget was initialized with. * * @param areaIndex The list index of the sub-area to select. */ void setSelection(QString output); /** * Sets the widget's target size. This is only a hint for the widget * to determine the approximate size it should target for when scaling the * areas. As long as the ratio does not fit to the ratio of the displayed * area, only one value will be used. The other value will be scaled up * or down to fit the ratio of the displayed area. * * @param size The widget's target size (Default: 400x400) */ void setWidgetTargetSize(const QSize& size); void lockProportions(bool enable); signals: /** * Emitted whenever the selected area changes. */ void selectionChanged(); protected: /** - * Overriden QWidget method which captures mouse movements. + * Overridden QWidget method which captures mouse movements. */ virtual void mouseMoveEvent ( QMouseEvent * event ); /** - * Overriden QWidget method which captures mouse button press events. + * Overridden QWidget method which captures mouse button press events. */ virtual void mousePressEvent ( QMouseEvent * event ); /** - * Overriden QWidget method which captures mouse button release events. + * Overridden QWidget method which captures mouse button release events. */ virtual void mouseReleaseEvent ( QMouseEvent * event ); /** - * Overriden QWidget method which paints the widget. + * Overridden QWidget method which paints the widget. */ virtual void paintEvent(QPaintEvent *event); private: /** * The current dragging mode which determines if the * user is dragging one of the border handles or the * whole area with the mouse. */ enum class DragMode { DragNone, //!< The user is currently not dragging. DragSelectedArea, //!< The user drags the whole selection ara. DragTopHandle, //!< The user drags the top border handle. DragRightHandle, //!< The user drags the right border handle. DragBottomHandle, //!< The user drags the bottom border handle. DragLeftHandle //!< The user drags the left border handle. }; /** * Calculates the size and position of the area which is displayed * to the user according to the given virtual area, a scale factor * and an optional margin. * * @param virtualArea The virtual area to calculate the display area for. * @param scaleFactor The scale factor which is applied to the virtual area. * @param totalDisplayAreaMargin The total display area margin. */ const QRectF calculateDisplayArea(const QRect& virtualArea, qreal scaleFactor, qreal totalDisplayAreaMargin) const; /** * Calculates the size and position of the display sub-areas which * make up the whole display area. * * @param areas The display sub-areas. * @param scaleFactor The scale factor which is applied to the areas. * @param totalDisplayAreaMargin The total display area margin. */ const QList< QRectF > calculateDisplayAreas(const QMap areas, qreal scaleFactor, qreal totalDisplayAreaMargin) const; /** * Calculates the out of bounds margin for the virtual area. * * @param virtualArea The virtual area to calculate the oob margin for. * @param outOfBoundMargin A percentage (0-1.0) or a value in pixels (>1). * * @return The out ouf bounds margin in virtual area pixels. */ qreal calculateOutOfBoundsVirtualAreaMargin(const QRect& virtualArea, qreal outOfBoundsMargin) const; /** * Calculates a scaling factor based on a widget target size and the * given virtual area. * * @param targetSize The target size of this widget. * @param virtualArea The virtual area to calculate the scaling factor for. * @param virtualAreaOutOfBoundsMargin The out of bounds margin of the virtual area. * @param displayAreaExtraMargin An extra margin for the display area. * * @return The scaling factor for the given target size. */ qreal calculateScaleFactor(const QSize& targetSize, const QRect& virtualArea, qreal virtualAreaOutOfBoundsMargin, qreal displayAreaExtraMargin) const; /** * Calculates a scaled version of the given area. * * @param area The area to scale. * @param scaleFactor The scale factor which is applied to the area. * @param margin An optional margin around the display area. * * @return The scaled area. */ const QRectF calculateScaledArea(const QRect& area, qreal scaleFactor, qreal totalDisplayAreaMargin) const; /** * Unscales a scaled area. * * @param area The area to unscale. * @param scaleFactor The scale factor which was applied to the area. * @param margin An optional margin around the display area. * * @return The unscaled area. */ const QRect calculateUnscaledArea(const QRectF& area, qreal scaleFactor, qreal totalDisplayAreaMargin) const; /** * Calculates the size of the virtual area. * * @param areas A list of areas to calculate the virtual area for. * * @return The size of the virtual area as rectangle. */ const QRect calculateVirtualArea(const QMap &areas) const; /** * Returns the total margin of the display area. This is is the out of bounds * margin plus any additional margin which might be applied around the widget. * * @return The total display area margin. */ qreal getTotalDisplayAreaMargin() const; /** * Determines if the user is currently dragging a handle or * the selected area with the mouse. * * @return True if user is dragging, else false. */ bool isUserDragging() const; /** * Paints the captions of the display areas. * * @param painter The painter to use. */ void paintDisplayAreaCaptions(QPainter& painter); /** * Paints the display area and all of its sub-areas. * * @param painter The painter to use. * @param outlineOnly A flag if only the outline should be painted. */ void paintDisplayAreas(QPainter& painter, bool outlineOnly); /** * Paints the drag handles. * * @param painter The painter to use. */ void paintDragHandles(QPainter& painter); /** * Paints the selected area. * * @param painter The painter to use. */ void paintSelectedArea(QPainter& painter, bool outlineOnly); /** * Paints the size of the selected area as string. * * @param painter The painter to sue. */ void paintSelectedAreaCaption(QPainter& painter); /** * Sets up the widget. Can be called anytime to recalculate the display area size. */ void setupWidget(); /** * Recalculates the positions of the drag handles. */ void updateDragHandles(); /** * Updates the mouse cursor according to the mouse's position. * * @param mousePosition The current position of the mouse. */ void updateMouseCursor(const QPoint& mousePosition); /** * Updates the selected area when the user drags it. */ void updateSelectedAreaOnDrag(const QPoint& mousePosition); /** * Updates the selected area when the user is moving it. * * @param mousePosition The current mouse position where the user wants to move the selection to. */ void updateSelectedAreaOnDragArea(const QPoint& mousePosition); /** * Updates the selected area when the user is dragging with the bottom handle. * * @param mousePosition The current mouse position where the user wants to have the new border set. */ void updateSelectedAreaOnDragBottom(const QPoint& mousePosition); /** * Updates the selected area when the user is dragging with the left handle. * * @param mousePosition The current mouse position where the user wants to have the new border set. */ void updateSelectedAreaOnDragLeft(const QPoint& mousePosition); /** * Updates the selected area when the user is dragging with the right handle. * * @param mousePosition The current mouse position where the user wants to have the new border set. */ void updateSelectedAreaOnDragRight(const QPoint& mousePosition); /** * Updates the selected area when the user is dragging with the top handle. * * @param mousePosition The current mouse position where the user wants to have the new border set. */ void updateSelectedAreaOnDragTop(const QPoint& mousePosition); /** * Asserts that the selected area is not wider or higher than the display area. * Updates the selected area accordingly. * * @param fixPositionInsteadOfSize Fix x and y value instead of the width and height of the selection. */ void updateSelectedAreaSize(bool fixPositionInsteadOfSize = false); Q_DECLARE_PRIVATE(AreaSelectionWidget) AreaSelectionWidgetPrivate *const d_ptr; //!< D-Pointer for this class. }; // CLASS } // NAMESPACE #endif // HEADER PROTECTION diff --git a/src/kcmodule/tabletpagewidget.h b/src/kcmodule/tabletpagewidget.h index 3835cdd..2d434b8 100644 --- a/src/kcmodule/tabletpagewidget.h +++ b/src/kcmodule/tabletpagewidget.h @@ -1,247 +1,247 @@ /* * 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 PADTABWIDGET_H -#define PADTABWIDGET_H +#ifndef TABLETPAGEWIDGET_H +#define TABLETPAGEWIDGET_H #include "screenmap.h" #include "screenspace.h" #include "screenrotation.h" #include #include namespace Wacom { class TabletPageWidgetPrivate; /** * The "Tablet" tab of the main KCM widget. */ class TabletPageWidget : public QWidget { Q_OBJECT public: explicit TabletPageWidget( QWidget *parent = 0 ); virtual ~TabletPageWidget(); void setTabletId(const QString &tabletId); /** * Loads settings from the current profile and updates the widget accordingly. */ void loadFromProfile(); /** * Reinitializes the widget when a new tablet gets connected. */ void reloadWidget(); /** * Saves the current settings to the current profile. */ void saveToProfile(); public slots: /** * Called when the user enables/disables the auto-rotation checkbox. */ void onAutoRotateChanged (int state); /** * Called when any profile property value changes. */ void onProfileChanged(); /** * Called when the user changes the rotation settings. */ void onRotationChanged(); /** * Called when the user presses the pad tablet mapping button. */ void onTabletMappingClicked(); /** * Called when the state of the absolute tracking mode changes. */ void onTrackingModeAbsolute(bool activated); /** * Called when the state of the relative tracking mode changes. */ void onTrackingModeRelative(bool activated); signals: /** * Emitted when the user changes configuration settings. */ void changed(); /** * Emitted when the rotation changes to inform our other widgets about it. */ void rotationChanged(const ScreenRotation& rotation); protected: /** * Gets the current rotation in profile format. * These are the values returned by ScreenRotation.key(). * * @return The current rotation in profile format. */ const QString getRotation() const; /** * @return The current tablet to screen mapping. */ const ScreenMap& getScreenMap() const; /** * Gets the current tablet area mapping in profile format as * returned by ScreenMap::toString(). * * @return The current tablet mapping in profile format. */ const QString getScreenMapAsString() const; /** * @return The current screen space selection. */ const ScreenSpace& getScreenSpace() const; /** * Gets the current screen area mapping in profile format. * * @return A screen mapping as returned by ScreenSpace::toString(). */ const QString getScreenSpaceAsString() const; /** * Gets the current tracking mode selection. * * @return Either "absolute" or "relative". */ const QString getTrackingMode() const; /** * Checks if auto-rotation or inverted auto-rotation is enabled. * * @return True if auto-rotation is enabled, else false. */ bool isAutoRotationEnabled() const; /** * Check if inverted auto-rotation is enabled. * * @return True if inverted auto-rotation is active, else false. */ bool isAutoRotateInversionEnabled() const; /** * Changes the auto-rotation configuration and updates the widgets. * * @param value True to enable auto-rotation, false to disable it. */ void setAutoRotationEnabled (bool value); /** * Changes the inverte-auto rotation configuration. This will not * update the auto-rotation flag. * * @param value True to enable inverted auto-rotation, false to disable it. */ void setAutoRotateInversionEnabled(bool value); /** * Sets the auto-rotation settings based on a string in profile format * and updates all widgets accordingly. Valid values for the parameter * are all values returned by ScreenRotation::key(). * * @param value The new rotation in profile format. */ void setRotation(const QString& value); /** * Sets a new tablet area mapping and updates all widgets accordingly. * * @param screenMap The new tablet to screen mapping. */ void setScreenMap(const ScreenMap& screenMap); /** * Sets a new tablet area mapping and updates all widgets accordingly. * The given value has to be in profile format as returned by ScreenMap::toString(). * * @param value The new tablet area mapping in profile format. */ void setScreenMap(const QString& value); /** * Sets a new screen area mapping and updates all widgets accordingly. * * @param value The new screen space mapping selection. */ void setScreenSpace(const ScreenSpace& screenSpace); /** * Sets a new screen area mapping and updates all widgets accordingly. * The given value has to be in profile format as returned by ScreenSpace::toString() * * @param value The new screen area mapping selection. */ void setScreenSpace(const QString& value); /** * Sets the tracking mode and updates all widgets accordingly. * * @param value Either "absolute" or "relative" */ void setTrackingMode(const QString& value); private: /** * Checks if the current tablet mapping is available for the currently selected * tracking mode. If it is not available, a warning is displayed to the user. */ void assertValidTabletMapping(); /** * Initializes this widget. Must only be called once by the constructor. */ void setupUi(); Q_DECLARE_PRIVATE( TabletPageWidget ) TabletPageWidgetPrivate *const d_ptr; //!< D-Pointer for this class. }; // CLASS } // NAMESPACE #endif // HEADER PROTECTION diff --git a/src/kded/dbustabletservice.cpp b/src/kded/dbustabletservice.cpp index 4d9177b..ba16bce 100644 --- a/src/kded/dbustabletservice.cpp +++ b/src/kded/dbustabletservice.cpp @@ -1,261 +1,261 @@ /* * 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 "dbustabletinterface.h" +#include "dbustabletservice.h" #include "logging.h" -#include "dbustabletservice.h" +#include "dbustabletinterface.h" #include "devicetype.h" #include "property.h" #include "tabletinfo.h" #include "wacomadaptor.h" #include #include #include using namespace Wacom; namespace Wacom { class DBusTabletServicePrivate { public: WacomAdaptor *wacomAdaptor = nullptr; TabletHandlerInterface *tabletHandler = nullptr; QHash tabletInformationList; //!< Information of all currently connected tablets. QHash currentProfileList; //!< Currently active profile for each tablet. }; // CLASS } // NAMESPACE DBusTabletService::DBusTabletService(TabletHandlerInterface& tabletHandler) : QObject(), d_ptr(new DBusTabletServicePrivate) { Q_D ( DBusTabletService ); d->tabletHandler = &tabletHandler; DBusTabletInterface::registerMetaTypes(); d->wacomAdaptor = new WacomAdaptor( this ); QDBusConnection::sessionBus().registerObject( QLatin1String( "/Tablet" ), this ); QDBusConnection::sessionBus().registerService( QLatin1String( "org.kde.Wacom" ) ); } DBusTabletService::~DBusTabletService() { QDBusConnection::sessionBus().unregisterService( QLatin1String( "org.kde.Wacom" ) ); QDBusConnection::sessionBus().unregisterObject( QLatin1String( "/Tablet" )); delete d_ptr->wacomAdaptor; delete d_ptr; } const QStringList DBusTabletService::getTabletList() const { Q_D ( const DBusTabletService ); return d->tabletInformationList.keys(); } const QStringList DBusTabletService::getDeviceList(const QString &tabletId) const { Q_D ( const DBusTabletService ); return d->tabletInformationList.value(tabletId).getDeviceList(); } QString DBusTabletService::getDeviceName(const QString &tabletId, const QString& device) const { Q_D ( const DBusTabletService ); static const QString unknown; const DeviceType *type = DeviceType::find(device); if (!type) { qCWarning(KDED) << QString::fromLatin1("Unsupported device type '%1'!").arg(device); return unknown; } return d->tabletInformationList.value(tabletId).getDeviceName(*type); } QString DBusTabletService::getInformation(const QString &tabletId,const QString& info) const { Q_D ( const DBusTabletService ); static const QString unknown; const TabletInfo* devinfo = TabletInfo::find(info); if (!devinfo) { qCWarning(KDED) << QString::fromLatin1("Can not get unsupported tablet information '%1'!").arg(info); return unknown; } return d->tabletInformationList.value(tabletId).get(*devinfo); } QString DBusTabletService::getProfile(const QString &tabletId) const { Q_D ( const DBusTabletService ); return d->currentProfileList.value(tabletId); } QString DBusTabletService::getProperty(const QString &tabletId, const QString& deviceType, const QString& property) const { Q_D ( const DBusTabletService ); const DeviceType* type = DeviceType::find(deviceType); if (!type) { qCWarning(KDED) << QString::fromLatin1("Can not get property '%1' from invalid device '%2'!").arg(property).arg(deviceType); return QString(); } const Property* prop = Property::find(property); if (!prop) { qCWarning(KDED) << QString::fromLatin1("Can not get invalid property '%1' from device '%2'!").arg(property).arg(deviceType); return QString(); } return d->tabletHandler->getProperty(tabletId, *type, *prop); } bool DBusTabletService::hasPadButtons(const QString &tabletId) const { Q_D ( const DBusTabletService ); return d->tabletInformationList.value(tabletId).hasButtons(); } bool DBusTabletService::isAvailable(const QString &tabletId) const { Q_D ( const DBusTabletService ); return d->tabletInformationList.contains(tabletId); } QStringList DBusTabletService::listProfiles(const QString &tabletId) { Q_D ( const DBusTabletService ); return d->tabletHandler->listProfiles(tabletId); } void DBusTabletService::setProfile(const QString &tabletId, const QString& profile) { Q_D ( DBusTabletService ); d->tabletHandler->setProfile(tabletId, profile); } void DBusTabletService::setProperty(const QString &tabletId, const QString& deviceType, const QString& property, const QString& value) { Q_D ( DBusTabletService ); const DeviceType* type = DeviceType::find(deviceType); if (!type) { qCWarning(KDED) << QString::fromLatin1("Can not set property '%1' on invalid device '%2' to '%3'!").arg(property).arg(deviceType).arg(value); return; } const Property* prop = Property::find(property); if (!prop) { qCWarning(KDED) << QString::fromLatin1("Can not set invalid property '%1' on device '%2' to '%3'!").arg(property).arg(deviceType).arg(value); return; } d->tabletHandler->setProperty(tabletId, *type, *prop, value); } QStringList DBusTabletService::getProfileRotationList(const QString &tabletId) { Q_D ( DBusTabletService ); return d->tabletHandler->getProfileRotationList(tabletId); } void DBusTabletService::setProfileRotationList(const QString &tabletId, const QStringList &rotationList) { Q_D ( DBusTabletService ); d->tabletHandler->setProfileRotationList(tabletId, rotationList); } QString DBusTabletService::getTouchSensorId(const QString &tabletId) { Q_D(DBusTabletService); return d->tabletInformationList.value(tabletId).get(TabletInfo::TouchSensorId); } bool DBusTabletService::isTouchSensor(const QString &tabletId) { Q_D(DBusTabletService); return d->tabletInformationList.value(tabletId).getBool(TabletInfo::IsTouchSensor); } void DBusTabletService::onProfileChanged(const QString &tabletId, const QString& profile) { Q_D ( DBusTabletService ); d->currentProfileList.insert(tabletId, profile); emit profileChanged(tabletId, profile); } void DBusTabletService::onTabletAdded(const TabletInformation& info) { Q_D ( DBusTabletService ); d->tabletInformationList.insert(info.get(TabletInfo::TabletId), info); emit tabletAdded(info.get(TabletInfo::TabletId)); } void DBusTabletService::onTabletRemoved(const QString &tabletId) { Q_D ( DBusTabletService ); d->currentProfileList.remove(tabletId); d->tabletInformationList.remove(tabletId); emit tabletRemoved(tabletId); } diff --git a/src/kded/dbustabletservice.h b/src/kded/dbustabletservice.h index d8b8d8c..7987d6f 100644 --- a/src/kded/dbustabletservice.h +++ b/src/kded/dbustabletservice.h @@ -1,253 +1,253 @@ /* * 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 DBUSTABLETSERVICE_H #define DBUSTABLETSERVICE_H #include "tablethandlerinterface.h" #include "tabletinformation.h" #include #include #include namespace Wacom { class DBusTabletServicePrivate; /** * @brief The D-Bus tablet service. * * Handles all D-Bus requests to the tablet daemon and passes them to the * tablet handler. All work is done by other modules, this class only * exists to separate the d-bus interface from the business logic and to * facilitate unit testing. */ class DBusTabletService : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.Wacom") public: explicit DBusTabletService (TabletHandlerInterface& tabletHandler); ~DBusTabletService (); // d-bus slots public Q_SLOTS: /** * List all conncted tablets (by tabletid) * * @return StringList of the connected tablets with their id */ Q_SCRIPTABLE const QStringList getTabletList() const; /** * List of the internal device names (pad/stylus/eraser) as used by xsetwacom command * * @param tabletId the ID of the Tablet to check * @return StringList of the connected input devices */ Q_SCRIPTABLE const QStringList getDeviceList(const QString &tabletId) const; /** * Gets the name of a device (pad/stylus/...). * * @param tabletId the ID of the Tablet to check * @param device A device as returned by DeviceType::key() * * @return The name of the device. */ Q_SCRIPTABLE QString getDeviceName(const QString &tabletId, const QString& device) const; /** * Gets information from the tablet. * * @param tabletId the ID of the Tablet to check * @param info The type of information. * * @return The information value. */ Q_SCRIPTABLE QString getInformation(const QString &tabletId, const QString& info) const; /** * Returns the current active profile for this tablet. * * This is not necessary the real configuration in case some other program changed the tablet * behaviour. But this is the name of the profile that was used last. * Can be used to show in the applet as information or as beginning selection in the kcmodule. * * @param tabletId the ID of the Tablet to check * @return name of the last used profile */ Q_SCRIPTABLE QString getProfile(const QString &tabletId) const; /** * Returns the current value for a specific tablet device (stylus/eraser/pad/...). * * @param tabletId the ID of the Tablet to check * @param deviceType Type of device (stylus/eraser/...) to get the value from. * @param property The property we are looking for. * * @return the value as string */ Q_SCRIPTABLE QString getProperty(const QString &tabletId, const QString& deviceType, const QString& property) const; /** * Tells you if the detected tablet has configurable pushbuttons or not * * @param tabletId the ID of the Tablet to check * * @return @c true if pushbuttons are available and thus the conf dialogue can be shown * @c false if nothing is available */ Q_SCRIPTABLE bool hasPadButtons(const QString &tabletId) const; /** * Checks if a tablet is detected and available for further usage * * @param tabletId the ID of the Tablet to check * * @return @c true if tablet is available, @c false otherwise */ Q_SCRIPTABLE bool isAvailable(const QString &tabletId) const; /** * Returns a list of all available profiles * * This way around the plasma applet does not check the local KConfig file itself * and can be used as a remote applet. * * @param tabletId the ID of the Tablet to check * * @return the list of all available profiles */ Q_SCRIPTABLE QStringList listProfiles(const QString &tabletId); /** * Applies a profile to the tablet device * * The profile must exist in the tabletprofilerc file and thus created by the kcmodule. * Otherwise a notification error is send and shown. * * @param tabletId the ID of the Tablet to check * * @param profile name of the profile as specified in the tabletprofilesrc file. */ Q_SCRIPTABLE void setProfile(const QString &tabletId, const QString& profile); /** * Sets the configuration of @p property from @p deviceType to @p value. * * @param tabletId the ID of the Tablet to check * @param deviceType The device type to set the value on. * @param property The property to set. * @param value The new value of the property. */ Q_SCRIPTABLE void setProperty(const QString &tabletId, const QString & deviceType, const QString & property, const QString & value); /** * Returns the list for the device profile rotation * * This list will define which profile will be loaded * via the global next/prev profile shortcut * * @param tabletId the ID of the Tablet to check * * @return stringlist with profile names in the rotation */ Q_SCRIPTABLE QStringList getProfileRotationList(const QString &tabletId); /** * Set the Profile rotation list for this Device * * @param tabletId the ID of the Tablet to check * @param rotationList stringlist with profilenames in the right order */ Q_SCRIPTABLE void setProfileRotationList(const QString &tabletId, const QStringList &rotationList); /** * @brief Get touch sensor device USB ID * * Some tablets report devices with multiple USB IDs (e.g. Cintiq Companion Hybrid) * Primary device (usually the one containing stylus sensor) should have this set * to the USB ID of the corresponding secondary device (touch sensor) * * @param tabletId of the device to check * @return tabletId of the touch device */ Q_SCRIPTABLE QString getTouchSensorId(const QString &tabletId); /** * @brief Reports if this device is a secondary touch sensor * * Touch sensor devices shouldn't be visible in the KCM * * @param tabletId of the device to check * @return true if it's a touch sensor */ Q_SCRIPTABLE bool isTouchSensor(const QString &tabletId); // d-bus signals Q_SIGNALS: /** * Emitted if a new tablet is connected and detected * * This signal is send via DBus to inform other about the recently added device */ Q_SCRIPTABLE void tabletAdded(const QString &tabletId); /** * Emitted if a known tablet is removed * * This signal is send via DBus to inform other about the recently removed device */ Q_SCRIPTABLE void tabletRemoved(const QString &tabletId); /** * Emitted when the profile of the device is changed * * This signal is send via DBus to inform other about the change */ Q_SCRIPTABLE void profileChanged(const QString &tabletId, const QString& profile); // normal Qt slots -private slots: +public slots: //! Has to be called when the current profile was changed. void onProfileChanged (const QString &tabletId, const QString& profile); //! Has to be called when a new tablet is added. void onTabletAdded (const TabletInformation& info); //! Has to be called when the current tablet is removed. void onTabletRemoved (const QString &tabletId); private: Q_DECLARE_PRIVATE(DBusTabletService) DBusTabletServicePrivate *const d_ptr; /**< d-pointer for this class */ }; // CLASS } // NAMESPACE #endif // HEADER PROTECTION diff --git a/src/kded/tabletdaemon.cpp b/src/kded/tabletdaemon.cpp index e16e927..9f7d14b 100644 --- a/src/kded/tabletdaemon.cpp +++ b/src/kded/tabletdaemon.cpp @@ -1,232 +1,227 @@ /* * 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 "tabletdaemon.h" #include "logging.h" #include "dbustabletservice.h" #include "tabletfinder.h" #include "tablethandler.h" #include "wacomadaptor.h" #include "x11eventnotifier.h" #include "globalactions.h" #include "../wacomtablet-version.h" // common includes #include "aboutdata.h" // stdlib includes #include // KDE includes #include #include #include #include #include #include using namespace Wacom; K_PLUGIN_FACTORY_WITH_JSON(WacomTabletFactory, "wacomtablet.json", registerPlugin();) namespace Wacom { /** * Private class of the TabletDaemon for the d-pointer */ class TabletDaemonPrivate { public: TabletDaemonPrivate() : tabletHandler(), dbusTabletService(tabletHandler) {} TabletHandler tabletHandler; /**< tablet handler */ DBusTabletService dbusTabletService; std::shared_ptr actionCollection; /**< Collection of all global actions */ }; // CLASS } // NAMESPACE TabletDaemon::TabletDaemon( QObject *parent, const QVariantList &args ) : KDEDModule( parent ), d_ptr( new TabletDaemonPrivate ) { Q_UNUSED( args ); Q_D( TabletDaemon ); setupApplication(); setupDBus(); setupEventNotifier(); setupActions(); // scan for connected devices TabletFinder::instance().scan(); // connect profile changed handler after searching for tablets as this is only used for the global shortcut workaround. connect(&(d->tabletHandler), &TabletHandler::profileChanged, this, &TabletDaemon::onProfileChanged); // Connecting this after the device has been set up ensures that no notification is send on startup. connect( &(d->tabletHandler), SIGNAL(notify(QString,QString,QString)), this, SLOT(onNotify(QString,QString,QString)) ); } TabletDaemon::~TabletDaemon() { X11EventNotifier::instance().stop(); delete this->d_ptr; } void TabletDaemon::onNotify(const QString& eventId, const QString& title, const QString& message) const { KNotification* notification = new KNotification(eventId); notification->setComponentName( QStringLiteral("wacomtablet") ); notification->setTitle(title); notification->setText(message); notification->setIconName( QLatin1String( "input-tablet" ) ); notification->sendEvent(); } void TabletDaemon::onProfileChanged(const QString &tabletId, const QString& profile) { Q_UNUSED(tabletId); Q_UNUSED(profile); // When closing the KCM module the KAction destructor disables all global shortcuts. // Make sure the global shortcuts are restored when a profile changes. This is not // optimal but at least it will enable the shortcuts again. qCDebug(KDED) << QLatin1String("Restoring global keyboard shortcuts..."); setupActions(); } void TabletDaemon::setupActions() { Q_D( TabletDaemon ); //if someone adds another action also add it to kcmodule/generalwidget.cpp // This method is called multiple times - make sure the action collection is only created once. if (!d->actionCollection) { d->actionCollection = std::shared_ptr(new GlobalActions(false, this)); d->actionCollection->setConfigGlobal(true); } connect(d->actionCollection.get(), &GlobalActions::toggleTouchTriggered, &(d->tabletHandler), &TabletHandler::onToggleTouch, Qt::UniqueConnection); connect(d->actionCollection.get(), &GlobalActions::toggleStylusTriggered, &(d->tabletHandler), &TabletHandler::onTogglePenMode, Qt::UniqueConnection); connect(d->actionCollection.get(), &GlobalActions::toggleScreenMapTriggered, &(d->tabletHandler), &TabletHandler::onToggleScreenMapping, Qt::UniqueConnection); connect(d->actionCollection.get(), &GlobalActions::mapToFullScreenTriggered, &(d->tabletHandler), &TabletHandler::onMapToFullScreen, Qt::UniqueConnection); connect(d->actionCollection.get(), &GlobalActions::mapToScreen1Triggered, &(d->tabletHandler), &TabletHandler::onMapToScreen1, Qt::UniqueConnection); connect(d->actionCollection.get(), &GlobalActions::mapToScreen2Triggered, &(d->tabletHandler), &TabletHandler::onMapToScreen2, Qt::UniqueConnection); connect(d->actionCollection.get(), &GlobalActions::nextProfileTriggered, &(d->tabletHandler), &TabletHandler::onNextProfile, Qt::UniqueConnection); connect(d->actionCollection.get(), &GlobalActions::previousProfileTriggered, &(d->tabletHandler), &TabletHandler::onPreviousProfile, Qt::UniqueConnection); } void TabletDaemon::setupApplication() { static AboutData about(QLatin1Literal("wacomtablet"), i18n( "Graphic Tablet Configuration daemon"), QLatin1String(WACOMTABLET_VERSION_STRING), i18n( "A Wacom tablet control daemon" )); } void TabletDaemon::setupDBus() { Q_D( TabletDaemon ); // connect tablet handler events to D-Bus // this is done here and not in the D-Bus tablet service to facilitate unit testing - connect(&(d->tabletHandler), SIGNAL (profileChanged(QString, QString)), - &(d->dbusTabletService), SLOT (onProfileChanged(QString, QString))); - - connect(&(d->tabletHandler), SIGNAL (tabletAdded(TabletInformation)), - &(d->dbusTabletService), SLOT (onTabletAdded(TabletInformation))); - - connect(&(d->tabletHandler), SIGNAL (tabletRemoved(QString)), - &(d->dbusTabletService), SLOT (onTabletRemoved(QString))); + connect(&(d->tabletHandler), &TabletHandler::profileChanged, &(d->dbusTabletService), &DBusTabletService::onProfileChanged); + connect(&(d->tabletHandler), &TabletHandler::tabletAdded, &(d->dbusTabletService), &DBusTabletService::onTabletAdded); + connect(&(d->tabletHandler), &TabletHandler::tabletRemoved, &(d->dbusTabletService), &DBusTabletService::onTabletRemoved); } void TabletDaemon::setupEventNotifier() { Q_D( TabletDaemon ); // Set up monitoring for individual screen geometry changes monitorAllScreensGeometry(); // Set up monitoring for screens being added, removed or reordered connect(qApp, &QGuiApplication::primaryScreenChanged, &(d->tabletHandler), &TabletHandler::onScreenAddedRemoved); connect(qApp, &QGuiApplication::screenAdded, &(d->tabletHandler), &TabletHandler::onScreenAddedRemoved); connect(qApp, &QGuiApplication::screenRemoved, &(d->tabletHandler), &TabletHandler::onScreenAddedRemoved); // Set up tablet connected/disconnected signals connect( &X11EventNotifier::instance(), &X11EventNotifier::tabletAdded, &TabletFinder::instance(), &TabletFinder::onX11TabletAdded); connect( &X11EventNotifier::instance(), &X11EventNotifier::tabletRemoved, &TabletFinder::instance(), &TabletFinder::onX11TabletRemoved); connect( &TabletFinder::instance(), &TabletFinder::tabletAdded, &(d->tabletHandler), &TabletHandler::onTabletAdded); connect( &TabletFinder::instance(), &TabletFinder::tabletRemoved, &(d->tabletHandler), &TabletHandler::onTabletRemoved); if (QX11Info::isPlatformX11()) { X11EventNotifier::instance().start(); } } void TabletDaemon::monitorAllScreensGeometry() { // Add existing screens for (const auto &screen : QGuiApplication::screens()) { monitorScreenGeometry(screen); } // Monitor future screens connect(qApp, &QGuiApplication::screenAdded, this, &TabletDaemon::monitorScreenGeometry); } void TabletDaemon::monitorScreenGeometry(QScreen *screen) { Q_D( TabletDaemon ); const auto &tabletHandler = &(d->tabletHandler); connect(screen, &QScreen::orientationChanged, [=](const Qt::ScreenOrientation &newScreenRotation){ tabletHandler->onScreenRotated(screen->name(), newScreenRotation); }); screen->setOrientationUpdateMask(Qt::LandscapeOrientation | Qt::PortraitOrientation | Qt::InvertedLandscapeOrientation | Qt::InvertedPortraitOrientation); connect(screen, &QScreen::geometryChanged, &(d->tabletHandler), &TabletHandler::onScreenGeometryChanged); } #include "tabletdaemon.moc"