diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(battery) add_subdirectory(findmyphone) add_subdirectory(remotekeyboard) +add_subdirectory(remotebrightness) if(WIN32) add_subdirectory(mousepad_windows) else() @@ -20,6 +21,7 @@ add_subdirectory(mousepad) add_subdirectory(screensaver-inhibit) add_subdirectory(sftp) + add_subdirectory(brightness) endif() if(EXPERIMENTALAPP_ENABLED) add_subdirectory(remotecommands) diff --git a/plugins/brightness/CMakeLists.txt b/plugins/brightness/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/plugins/brightness/CMakeLists.txt @@ -0,0 +1,13 @@ +set(kdeconnect_brightness_SRCS + brightnessplugin.cpp +) + +qt5_add_dbus_interface(kdeconnect_brightness_SRCS org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml brightnesscontroldbusinterface) + +kdeconnect_add_plugin(kdeconnect_brightness JSON kdeconnect_brightness.json SOURCES ${kdeconnect_brightness_SRCS}) + +target_link_libraries(kdeconnect_brightness + kdeconnectcore + Qt5::DBus + KF5::I18n +) diff --git a/plugins/brightness/README b/plugins/brightness/README new file mode 100644 --- /dev/null +++ b/plugins/brightness/README @@ -0,0 +1,2 @@ + +TODO diff --git a/plugins/brightness/brightnessplugin.h b/plugins/brightness/brightnessplugin.h new file mode 100644 --- /dev/null +++ b/plugins/brightness/brightnessplugin.h @@ -0,0 +1,58 @@ +/** + * Copyright 2018 Friedrich W. H. Kossebau + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 BRIGHTNESSPLUGIN_H +#define BRIGHTNESSPLUGIN_H + +#include + +class OrgKdeSolidPowerManagementActionsBrightnessControlInterface; + +#define PACKET_TYPE_BRIGHTNESS QStringLiteral("kdeconnect.brightness") + +// TODO: support also redshift/nightshift modes +// investigate about per-screen brightness +class Q_DECL_EXPORT BrightnessPlugin + : public KdeConnectPlugin +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.brightness") + +public: + explicit BrightnessPlugin(QObject* parent, const QVariantList& args); + ~BrightnessPlugin() override; + + bool receivePacket(const NetworkPacket& np) override; + void connected() override; + + QString dbusPath() const override; + +private: + void onLocalBrightnessChanged(int brightness); + void onLocalBrightnessMaxChanged(int brightnessMax); + + int brightnessMinForBrightnessMax(int brightnessMax) const; + OrgKdeSolidPowerManagementActionsBrightnessControlInterface* iface(); + +private: + OrgKdeSolidPowerManagementActionsBrightnessControlInterface* m_iface; +}; + +#endif diff --git a/plugins/brightness/brightnessplugin.cpp b/plugins/brightness/brightnessplugin.cpp new file mode 100644 --- /dev/null +++ b/plugins/brightness/brightnessplugin.cpp @@ -0,0 +1,123 @@ +/** + * Copyright 2018 Friedrich W. H. Kossebau + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 "brightnessplugin.h" + +// plugin +#include +#include +// KF +#include +#include +// Qt +#include +#include +#include + +K_PLUGIN_FACTORY_WITH_JSON(KdeConnectPluginFactory, "kdeconnect_brightness.json", registerPlugin(); ) + +Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_BRIGHTNESS, "kdeconnect.plugin.brightness") + + +BrightnessPlugin::BrightnessPlugin(QObject* parent, const QVariantList& args) + : KdeConnectPlugin(parent, args) + , m_iface(nullptr) +{ +} + +BrightnessPlugin::~BrightnessPlugin() +{ +} + +void BrightnessPlugin::connected() +{ +} + +bool BrightnessPlugin::receivePacket(const NetworkPacket& np) +{ + if (np.has(QStringLiteral("setBrightness"))) { + const int newBrightness = np.get(QStringLiteral("setBrightness")); + const int brightnessMax = iface()->brightnessMax(); + if ((brightnessMinForBrightnessMax(brightnessMax) <= newBrightness) && (newBrightness <= brightnessMax)) { + iface()->setBrightness(newBrightness); + } + } + if (np.has(QStringLiteral("requestBrightness"))) { + NetworkPacket np(PACKET_TYPE_BRIGHTNESS); + np.set(QStringLiteral("brightness"), iface()->brightness()); + // TODO: given these values belong together and are not expected to change individually, + // should they rather be messaged as a combined struct (also internally)? + np.set(QStringLiteral("brightnessMin"), brightnessMinForBrightnessMax(iface()->brightnessMax())); + np.set(QStringLiteral("brightnessMax"), iface()->brightnessMax()); + np.set(QStringLiteral("brightnessSteps"), iface()->brightnessSteps()); + sendPacket(np); + } + + return true; +} + +QString BrightnessPlugin::dbusPath() const +{ + return "/modules/kdeconnect/devices/" + device()->id() + "/brightness"; +} + +void BrightnessPlugin::onLocalBrightnessChanged(int brightness) +{ + NetworkPacket np(PACKET_TYPE_BRIGHTNESS); + np.set(QStringLiteral("brightness"), brightness); + sendPacket(np); +} + +void BrightnessPlugin::onLocalBrightnessMaxChanged(int brightnessMax) +{ + NetworkPacket np(PACKET_TYPE_BRIGHTNESS); + np.set(QStringLiteral("brightnessMin"), brightnessMinForBrightnessMax(brightnessMax)); + np.set(QStringLiteral("brightnessMax"), brightnessMax); + sendPacket(np); +} + +int BrightnessPlugin::brightnessMinForBrightnessMax(int brightnessMax) const +{ + // Don't allow the slider to turn off the screen + // Please see https://git.reviewboard.kde.org/r/122505/ for more information + return brightnessMax > 100 ? 1 : 0; +} + +OrgKdeSolidPowerManagementActionsBrightnessControlInterface* BrightnessPlugin::iface() +{ + if (!m_iface) { + m_iface = new OrgKdeSolidPowerManagementActionsBrightnessControlInterface( + QStringLiteral("org.kde.Solid.PowerManagement"), + QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"), + QDBusConnection::sessionBus(), this); + // TODO: how do we know no-one is interested in further updates? + connect(m_iface, &OrgKdeSolidPowerManagementActionsBrightnessControlInterface::brightnessChanged, + this, &BrightnessPlugin::onLocalBrightnessChanged); + connect(m_iface, &OrgKdeSolidPowerManagementActionsBrightnessControlInterface::brightnessMaxChanged, + this, &BrightnessPlugin::onLocalBrightnessMaxChanged); + if (!m_iface->isValid()) { + qCWarning(KDECONNECT_PLUGIN_BRIGHTNESS) << "Couldn't connect to the PowerManagement interface"; + } + } + + return m_iface; +} + +#include "brightnessplugin.moc" diff --git a/plugins/brightness/kdeconnect_brightness.json b/plugins/brightness/kdeconnect_brightness.json new file mode 100644 --- /dev/null +++ b/plugins/brightness/kdeconnect_brightness.json @@ -0,0 +1,26 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "kossebau@kde.org", + "Name": "Friedrich W. H. Kossebau" + } + ], + "Name": "Brightness", + "Description": "Report brightness of screen", + "EnabledByDefault": true, + "Icon": "contrast", + "Id": "kdeconnect_brightness", + "License": "GPL", + "ServiceTypes": [ + "KdeConnect/Plugin" + ], + "Version": "0.1" + }, + "X-KdeConnect-OutgoingPacketType": [ + "kdeconnect.brightness" + ], + "X-KdeConnect-SupportedPacketType": [ + "kdeconnect.brightness.request" + ] +} diff --git a/plugins/brightness/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml b/plugins/brightness/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml new file mode 100644 --- /dev/null +++ b/plugins/brightness/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/remotebrightness/CMakeLists.txt b/plugins/remotebrightness/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/plugins/remotebrightness/CMakeLists.txt @@ -0,0 +1,11 @@ +set(kdeconnect_remotebrightness_SRCS + remotebrightnessplugin.cpp +) + +kdeconnect_add_plugin(kdeconnect_remotebrightness JSON kdeconnect_remotebrightness.json SOURCES ${kdeconnect_remotebrightness_SRCS}) + +target_link_libraries(kdeconnect_remotebrightness + kdeconnectcore + Qt5::DBus + KF5::I18n +) diff --git a/plugins/remotebrightness/README b/plugins/remotebrightness/README new file mode 100644 --- /dev/null +++ b/plugins/remotebrightness/README @@ -0,0 +1,2 @@ + +TODO diff --git a/plugins/remotebrightness/kdeconnect_remotebrightness.json b/plugins/remotebrightness/kdeconnect_remotebrightness.json new file mode 100644 --- /dev/null +++ b/plugins/remotebrightness/kdeconnect_remotebrightness.json @@ -0,0 +1,26 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "kossebau@kde.org", + "Name": "Friedrich W. H. Kossebau" + } + ], + "Name": "Brightness", + "Description": "Control brightness of remote screen", + "EnabledByDefault": true, + "Icon": "contrast", + "Id": "kdeconnect_remotebrightness", + "License": "GPL", + "ServiceTypes": [ + "KdeConnect/Plugin" + ], + "Version": "0.1" + }, + "X-KdeConnect-OutgoingPacketType": [ + "kdeconnect.brightness.request" + ], + "X-KdeConnect-SupportedPacketType": [ + "kdeconnect.brightness" + ] +} diff --git a/plugins/remotebrightness/remotebrightnessplugin.h b/plugins/remotebrightness/remotebrightnessplugin.h new file mode 100644 --- /dev/null +++ b/plugins/remotebrightness/remotebrightnessplugin.h @@ -0,0 +1,70 @@ +/** + * Copyright 2018 Friedrich W. H. Kossebau + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 REMOTEBRIGHTNESSPLUGIN_H +#define REMOTEBRIGHTNESSPLUGIN_H + +#include + +#define PACKET_TYPE_BRIGHTNESS_REQUEST QStringLiteral("kdeconnect.brightness.request") + +// TODO: support also redshift/nightshift modes +// look into seeing this exposed as Plasma "system" property, so it is covered in the general brightmess control +// investigate about per-screen brightness +class Q_DECL_EXPORT RemoteBrightnessPlugin + : public KdeConnectPlugin +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.remotebrightness") + Q_PROPERTY(int brightness READ remoteBrightness WRITE setRemoteBrightness NOTIFY remoteBrightnessChanged) + Q_PROPERTY(int brightnessMin READ remoteBrightnessMin NOTIFY remoteBrightnessMinChanged) + Q_PROPERTY(int brightnessMax READ remoteBrightnessMax NOTIFY remoteBrightnessMaxChanged) + Q_PROPERTY(int brightnessSteps READ remoteBrightnessSteps NOTIFY remoteBrightnessStepsChanged) + +public: + explicit RemoteBrightnessPlugin(QObject* parent, const QVariantList& args); + ~RemoteBrightnessPlugin() override; + + bool receivePacket(const NetworkPacket& np) override; + void connected() override; + + QString dbusPath() const override; + +public: + int remoteBrightness() const; + int remoteBrightnessMin() const; + int remoteBrightnessMax() const; + int remoteBrightnessSteps() const; + void setRemoteBrightness(int brightness); + +Q_SIGNALS: + void remoteBrightnessChanged(int brightness); + void remoteBrightnessMinChanged(int brightnessMin); + void remoteBrightnessMaxChanged(int brightnessMax); + void remoteBrightnessStepsChanged(int brightnessSteps); + +private: + int m_remoteBrightness; + int m_remoteBrightnessMin; + int m_remoteBrightnessMax; + int m_remoteBrightnessSteps; +}; + +#endif diff --git a/plugins/remotebrightness/remotebrightnessplugin.cpp b/plugins/remotebrightness/remotebrightnessplugin.cpp new file mode 100644 --- /dev/null +++ b/plugins/remotebrightness/remotebrightnessplugin.cpp @@ -0,0 +1,126 @@ +/** + * Copyright 2018 Friedrich W. H. Kossebau + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 "remotebrightnessplugin.h" + +// plugin +#include +// KF +#include +#include +// Qt +#include +#include + +K_PLUGIN_FACTORY_WITH_JSON(KdeConnectPluginFactory, "kdeconnect_remotebrightness.json", + registerPlugin(); ) + +Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_BRIGHTNESS, "kdeconnect.plugin.remotebrightness") + + +RemoteBrightnessPlugin::RemoteBrightnessPlugin(QObject* parent, const QVariantList& args) + : KdeConnectPlugin(parent, args) + , m_remoteBrightness(0) + , m_remoteBrightnessMin(0) + , m_remoteBrightnessMax(0) + , m_remoteBrightnessSteps(1) +{ +} + +RemoteBrightnessPlugin::~RemoteBrightnessPlugin() +{ +} + +void RemoteBrightnessPlugin::connected() +{ + NetworkPacket np(PACKET_TYPE_BRIGHTNESS_REQUEST); + np.set(QStringLiteral("requestBrightness"), true); + sendPacket(np); +} + +bool RemoteBrightnessPlugin::receivePacket(const NetworkPacket& np) +{ + // change notification? + if (np.has(QStringLiteral("brightness"))) { + const int brightness = np.get(QStringLiteral("brightness")); + if (m_remoteBrightness != brightness) { + m_remoteBrightness = brightness; + Q_EMIT remoteBrightnessChanged(brightness); + } + } + if (np.has(QStringLiteral("brightnessMin"))) { + const int brightnessMin = np.get(QStringLiteral("brightnessMin")); + if (m_remoteBrightnessMin != brightnessMin) { + m_remoteBrightnessMin = brightnessMin; + Q_EMIT remoteBrightnessMinChanged(brightnessMin); + } + } + if (np.has(QStringLiteral("brightnessMax"))) { + const int brightnessMax = np.get(QStringLiteral("brightnessMax")); + if (m_remoteBrightnessMax != brightnessMax) { + m_remoteBrightnessMax = brightnessMax; + Q_EMIT remoteBrightnessMaxChanged(brightnessMax); + } + } + if (np.has(QStringLiteral("brightnessSteps"))) { + const int brightnessSteps = np.get(QStringLiteral("brightnessSteps")); + if (m_remoteBrightnessSteps != brightnessSteps) { + m_remoteBrightnessSteps = brightnessSteps; + Q_EMIT remoteBrightnessStepsChanged(brightnessSteps); + } + } + + return true; +} + +QString RemoteBrightnessPlugin::dbusPath() const +{ + return "/modules/kdeconnect/devices/" + device()->id() + "/remotebrightness"; +} + +int RemoteBrightnessPlugin::remoteBrightness() const +{ + return m_remoteBrightness; +} + +int RemoteBrightnessPlugin::remoteBrightnessMax() const +{ + return m_remoteBrightnessMax; +} + +int RemoteBrightnessPlugin::remoteBrightnessMin() const +{ + return m_remoteBrightnessMin; +} + +int RemoteBrightnessPlugin::remoteBrightnessSteps() const +{ + return m_remoteBrightnessSteps; +} + +void RemoteBrightnessPlugin::setRemoteBrightness(int brightness) +{ + // TODO: check range here and discard, or leave to receiver? + NetworkPacket np(PACKET_TYPE_BRIGHTNESS_REQUEST); + np.set(QStringLiteral("setBrightness"), brightness); + sendPacket(np); +} + +#include "remotebrightnessplugin.moc"