diff --git a/CMakeLists.txt b/CMakeLists.txt index 701b1f2db..de06e96b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,8 @@ if (WITH_APPEARANCE) endif() if (WITH_MONITOR) add_subdirectory(lxqt-config-monitor) + add_subdirectory(lxqt-monitor) + add_subdirectory(autostart) endif() if (WITH_BRIGHTNESS) add_subdirectory(lxqt-config-brightness) diff --git a/autostart/CMakeLists.txt b/autostart/CMakeLists.txt new file mode 100644 index 000000000..c027b3908 --- /dev/null +++ b/autostart/CMakeLists.txt @@ -0,0 +1,15 @@ +file(GLOB DESKTOP_FILES_IN *.desktop.in) + +# Translations ********************************** +lxqt_translate_desktop(DESKTOP_FILES + SOURCES + ${DESKTOP_FILES_IN} +) +add_custom_target(lxqt_monitor_autostart_desktop_files ALL DEPENDS ${DESKTOP_FILES}) +#************************************************ + +install(FILES + ${DESKTOP_FILES} + DESTINATION "${LXQT_ETC_XDG_DIR}/autostart" + COMPONENT Runtime +) diff --git a/autostart/lxqt-monitor.desktop.in b/autostart/lxqt-monitor.desktop.in new file mode 100644 index 000000000..e33f53238 --- /dev/null +++ b/autostart/lxqt-monitor.desktop.in @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Version=1.0 +Name=Monitor Settings +TryExec=lxqt-monitor +Exec=lxqt-monitor +OnlyShowIn=LXQt; +X-LXQt-Need-Tray=false +X-LXQt-Module=true + +#TRANSLATIONS_DIR=translations diff --git a/autostart/translations/lxqt-monitor_es.desktop b/autostart/translations/lxqt-monitor_es.desktop new file mode 100644 index 000000000..9d52edab7 --- /dev/null +++ b/autostart/translations/lxqt-monitor_es.desktop @@ -0,0 +1 @@ +Name[es]=Gestión de pantallas diff --git a/lxqt-monitor/CMakeLists.txt b/lxqt-monitor/CMakeLists.txt new file mode 100644 index 000000000..e9916a2da --- /dev/null +++ b/lxqt-monitor/CMakeLists.txt @@ -0,0 +1,65 @@ +project(lxqt-monitor) + +find_package(UDev REQUIRED) +include_directories(${LIBUDEV_INCLUDE_DIR}) +add_definitions(-DWITH_LIBUDEV_MONITOR) + +set(HEADERS + Daemon.h + UdevNotifier.h +) + +set(SOURCES + main.cpp + Daemon.cpp + UdevNotifier.cpp +) + +set(UIS + +) + +#set(ICONS +#) + +# Config file +#configure_file(resources/configure.in configure.h) + +# Translations ********************************** +#lxqt_translate_ts(QM_FILES +# UPDATE_TRANSLATIONS +# ${UPDATE_TRANSLATIONS} +# SOURCES +# ${HEADERS} +# ${SOURCES} +# ${UIS} +# INSTALL_DIR +# "${LXQT_TRANSLATIONS_DIR}/${PROJECT_NAME}" +#) +# +#lxqt_app_translation_loader(QM_LOADER ${PROJECT_NAME}) +#lxqt_translate_desktop(DESKTOP_FILES SOURCES "resources/${PROJECT_NAME}.desktop.in") + +#************************************************ + +add_executable(${PROJECT_NAME} + ${SOURCES} + ${RESOURCES} + ${QRC_SOURCES} + ${DESKTOP_FILES} + ${QM_FILES} + ${QM_LOADER} +) + +target_link_libraries(${PROJECT_NAME} + Qt5::Widgets + KF5::WindowSystem + Qt5::DBus + ${UDEV_LIBS} + lxqt +) + +install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) +install(FILES ${DESKTOP_FILES} DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/applications") +#install(FILES ${ICONS} DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/lxqt/icons") + diff --git a/lxqt-monitor/Daemon.cpp b/lxqt-monitor/Daemon.cpp new file mode 100644 index 000000000..6da5f3cef --- /dev/null +++ b/lxqt-monitor/Daemon.cpp @@ -0,0 +1,40 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * + * Copyright: 2020 LXQt team + * Authors: + * Pedro L. Lucas + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "Daemon.h" +#include +#include + +Daemon::Daemon(QObject *parent) : QObject(parent) +{ + m_dev_notifier_drm_subsystem = new UdevNotifier(QStringLiteral("drm"), this); //will be released upon our destruction + connect(m_dev_notifier_drm_subsystem, &UdevNotifier::deviceChanged, [this] (QString device) + { + Q_UNUSED(device) + qWarning() << QStringLiteral("Display device '%1'").arg(device); + QProcess::startDetached(QStringLiteral("lxqt-config-monitor -l")); + }); +} \ No newline at end of file diff --git a/lxqt-monitor/Daemon.h b/lxqt-monitor/Daemon.h new file mode 100644 index 000000000..c34e87aa5 --- /dev/null +++ b/lxqt-monitor/Daemon.h @@ -0,0 +1,43 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * + * Copyright: 2020 LXQt team + * Authors: + * Pedro L. Lucas + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#ifndef __DAEMON_H__ +#define __DAEMON_H__ + +#include "UdevNotifier.h" + +class Daemon : public QObject +{ + Q_OBJECT + +public: + Daemon(QObject *parent = nullptr); + +private: + UdevNotifier *m_dev_notifier_drm_subsystem; +}; + +#endif \ No newline at end of file diff --git a/lxqt-monitor/UdevNotifier.cpp b/lxqt-monitor/UdevNotifier.cpp new file mode 100644 index 000000000..d9277f0c7 --- /dev/null +++ b/lxqt-monitor/UdevNotifier.cpp @@ -0,0 +1,101 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * https://lxqt.org + * + * Copyright: 2015 LXQt team + * Authors: + * Palo Kisa + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "UdevNotifier.h" +#include +#include +#include +#include + +class UdevNotifier::Impl +{ +public: + struct udev * udev; + struct udev_monitor * monitor; + QScopedPointer notifier; +}; + + +UdevNotifier::UdevNotifier(QString const & subsystem, QObject * parent/* = nullptr*/) + : QObject(parent) + , d(new Impl) +{ + d->udev = udev_new(); + d->monitor = udev_monitor_new_from_netlink(d->udev, "udev"); + if (nullptr == d->monitor) + { + qWarning() << QStringLiteral("UdevNotifier: unable to initialize udev_monitor, monitoring will be disabled"); + return; + } + + int ret = udev_monitor_filter_add_match_subsystem_devtype(d->monitor, subsystem.toLatin1().constData(), nullptr); + if (0 != ret) + qWarning() << QStringLiteral("UdevNotifier: unable to add match subsystem, monitor will receive all devices"); + + ret = udev_monitor_enable_receiving(d->monitor); + if (0 != ret) + { + qWarning() << QStringLiteral("UdevNotifier: unable to enable receiving(%1), monitoring will be disabled").arg(ret); + return; + } + + d->notifier.reset(new QSocketNotifier(udev_monitor_get_fd(d->monitor), QSocketNotifier::Read)); + connect(d->notifier.data(), &QSocketNotifier::activated, this, &UdevNotifier::eventReady); + d->notifier->setEnabled(true); +} + +UdevNotifier::~UdevNotifier() +{ + if (d->monitor) + udev_monitor_unref(d->monitor); + udev_unref(d->udev); +} + +void UdevNotifier::eventReady(int /*socket*/) +{ + struct udev_device * dev; + while (nullptr != (dev = udev_monitor_receive_device(d->monitor))) + { + const char *action = udev_device_get_action(dev); + QString const device = QString::fromUtf8(udev_device_get_devnode(dev)); + + if (action && !device.isEmpty()) { + if (qstrcmp(action, "add") == 0) + emit deviceAdded(std::move(device)); + else if (qstrcmp(action, "remove") == 0) + emit deviceRemoved(std::move(device)); + else if (qstrcmp(action, "change") == 0) + emit deviceChanged(std::move(device)); + else if (qstrcmp(action, "online") == 0) + emit deviceOnline(std::move(device)); + else if (qstrcmp(action, "offline") == 0) + emit deviceOffline(std::move(device)); + } + + udev_device_unref(dev); + } +} diff --git a/lxqt-monitor/UdevNotifier.h b/lxqt-monitor/UdevNotifier.h new file mode 100644 index 000000000..26a534309 --- /dev/null +++ b/lxqt-monitor/UdevNotifier.h @@ -0,0 +1,57 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * https://lxqt.org + * + * Copyright: 2015 LXQt team + * Authors: + * Palo Kisa + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#ifndef UdevNotifier_h +#define UdevNotifier_h + +#include +#include + +class UdevNotifier : public QObject +{ + Q_OBJECT +public: + UdevNotifier(QString const & subsystem, QObject * parent = nullptr); + ~UdevNotifier() override; + +signals: + void deviceAdded(QString path); + void deviceRemoved(QString path); + void deviceChanged(QString path); + void deviceOnline(QString path); + void deviceOffline(QString path); + +private slots: + void eventReady(int socket); + +private: + class Impl; + + QScopedPointer d; +}; + +#endif //UdevNotifier_h diff --git a/lxqt-monitor/main.cpp b/lxqt-monitor/main.cpp new file mode 100644 index 000000000..3432e5a5f --- /dev/null +++ b/lxqt-monitor/main.cpp @@ -0,0 +1,52 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * + * Copyright: 2020 LXQt team + * Authors: + * Pedro L. Lucas + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + + +#include +#include + +#include "Daemon.h" + + + +int main(int argc, char *argv[]) +{ + LXQt::SingleApplication a(argc, argv); + + QCommandLineParser parser; + parser.setApplicationDescription(QStringLiteral("LXQt Screen Daemon")); + const QString VERINFO = QSL(LXQT_CONFIG_VERSION \ + "\nliblxqt " LXQT_VERSION \ + "\nQt " QT_VERSION_STR); + a.setApplicationVersion(VERINFO); + parser.addVersionOption(); + parser.addHelpOption(); + parser.process(a); + + Daemon daemon; + + return a.exec(); +} \ No newline at end of file