mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Refactor event handling incl.CEC
This commit is contained in:
@@ -30,29 +30,17 @@ if (APPLE)
|
||||
set_source_files_properties(${BUNDLE_RESOURCE_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
endif(APPLE)
|
||||
|
||||
if (UNIX)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS DBus QUIET )
|
||||
if (Qt${QT_VERSION_MAJOR}DBus_FOUND)
|
||||
set(hyperiond_POWER_MNG_DBUS "Qt${QT_VERSION_MAJOR}::DBus")
|
||||
endif()
|
||||
endif(UNIX)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
console.h
|
||||
hyperiond.h
|
||||
systray.h
|
||||
hyperiond.cpp
|
||||
systray.cpp
|
||||
SuspendHandler.cpp
|
||||
main.cpp
|
||||
${hyperiond_WIN_RC_PATH}
|
||||
${BUNDLE_RESOURCE_FILES}
|
||||
)
|
||||
|
||||
if (UNIX AND NOT APPLE AND Qt${QT_VERSION_MAJOR}DBus_FOUND)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC HYPERION_HAS_DBUS)
|
||||
endif()
|
||||
|
||||
# promote hyperiond as GUI app
|
||||
if (WIN32)
|
||||
target_link_options(${PROJECT_NAME} PUBLIC /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup)
|
||||
@@ -66,11 +54,11 @@ target_link_libraries(${PROJECT_NAME}
|
||||
ssdp
|
||||
database
|
||||
resources
|
||||
events
|
||||
Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Network
|
||||
Qt${QT_VERSION_MAJOR}::Widgets
|
||||
${hyperiond_POWER_MNG_DBUS}
|
||||
)
|
||||
|
||||
if(ENABLE_EFFECTENGINE)
|
||||
@@ -119,7 +107,7 @@ if (ENABLE_MF)
|
||||
endif (ENABLE_MF)
|
||||
|
||||
if (ENABLE_AUDIO)
|
||||
target_link_libraries(hyperiond audio-grabber)
|
||||
target_link_libraries(${PROJECT_NAME} audio-grabber)
|
||||
endif()
|
||||
|
||||
if (ENABLE_AMLOGIC)
|
||||
|
@@ -1,637 +0,0 @@
|
||||
#include "SuspendHandler.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <hyperion/HyperionIManager.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <iostream>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <QCoreApplication>
|
||||
#include <QWidget>
|
||||
#include <windows.h>
|
||||
#include <wtsapi32.h>
|
||||
|
||||
#pragma comment( lib, "wtsapi32.lib" )
|
||||
#endif
|
||||
|
||||
SuspendHandlerBase::SuspendHandlerBase()
|
||||
: _isSuspendEnabled(false)
|
||||
, _isLockEnabled(false)
|
||||
, _isSuspendApiEnabled(false)
|
||||
, _isIdleApiEnabled(false)
|
||||
, _isSuspendOnLock(false)
|
||||
, _isSuspendRegistered(false)
|
||||
, _isLockRegistered(false)
|
||||
, _isSuspendApiRegistered(false)
|
||||
, _isIdleApiRegistered(false)
|
||||
, _isSuspended(false)
|
||||
, _isIdle(false)
|
||||
, _isLocked (false)
|
||||
|
||||
{
|
||||
_log = Logger::getInstance("EVENTS");
|
||||
}
|
||||
|
||||
SuspendHandlerBase::~SuspendHandlerBase()
|
||||
{
|
||||
unregisterLockHandler();
|
||||
unregisterSuspendHandler();
|
||||
|
||||
unregisterIdleApiHandler();
|
||||
unregisterSuspendApiHandler();
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::handleSettingsUpdate(settings::type type, const QJsonDocument& config)
|
||||
{
|
||||
if(type == settings::SYSTEMEVENTS)
|
||||
{
|
||||
const QJsonObject& obj = config.object();
|
||||
|
||||
//Suspend on lock or go into idle mode
|
||||
bool prevIsSuspendOnLock = _isSuspendOnLock;
|
||||
_isSuspendOnLock = obj["suspendOnLockEnable"].toBool(false);
|
||||
|
||||
//Handle OS event related configurations
|
||||
_isSuspendEnabled = obj["suspendEnable"].toBool(true);
|
||||
if (_isSuspendEnabled)
|
||||
{
|
||||
// Listen to suspend/resume/idle events received by the OS
|
||||
registerSuspendHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
unregisterSuspendHandler();
|
||||
}
|
||||
|
||||
_isLockEnabled = obj["lockEnable"].toBool(true);
|
||||
if (_isLockEnabled || _isSuspendOnLock != prevIsSuspendOnLock)
|
||||
{
|
||||
// Listen to lock/screensaver events received by the OS
|
||||
registerLockHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
unregisterLockHandler();
|
||||
}
|
||||
|
||||
//Handle API event related configurations
|
||||
_isSuspendApiEnabled = obj["suspendApiEnable"].toBool(true);
|
||||
if (_isSuspendApiEnabled)
|
||||
{
|
||||
// Listen to suspend/resume/idle events received by the OS
|
||||
registerSuspendApiHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
unregisterSuspendApiHandler();
|
||||
}
|
||||
|
||||
_isIdleApiEnabled = obj["idleApiEnable"].toBool(true);
|
||||
if (_isIdleApiEnabled)
|
||||
{
|
||||
// Listen to lock/screensaver events received by the OS
|
||||
registerIdleApiHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
unregisterIdleApiHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SuspendHandlerBase::registerSuspendHandler()
|
||||
{
|
||||
if (!_isSuspendRegistered)
|
||||
{
|
||||
QObject::connect(this, &SuspendHandlerBase::suspendEvent, HyperionIManager::getInstance(), &HyperionIManager::suspend);
|
||||
QObject::connect(this, &SuspendHandlerBase::resumeEvent, HyperionIManager::getInstance(), &HyperionIManager::resume);
|
||||
Info(_log, "Registered for suspend/resume events.");
|
||||
_isSuspendRegistered = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::unregisterSuspendHandler()
|
||||
{
|
||||
if (_isSuspendRegistered)
|
||||
{
|
||||
QObject::disconnect(this, &SuspendHandlerBase::suspendEvent, HyperionIManager::getInstance(), &HyperionIManager::suspend);
|
||||
QObject::disconnect(this, &SuspendHandlerBase::resumeEvent, HyperionIManager::getInstance(), &HyperionIManager::resume);
|
||||
Info(_log, "Unregistered for suspend/resume events.");
|
||||
_isSuspendRegistered = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SuspendHandlerBase::registerLockHandler()
|
||||
{
|
||||
QObject::disconnect(this, &SuspendHandlerBase::lockedEvent,nullptr, nullptr);
|
||||
if (_isSuspendOnLock)
|
||||
{
|
||||
QObject::connect(this, &SuspendHandlerBase::lockedEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleSuspend);
|
||||
}
|
||||
else
|
||||
{
|
||||
QObject::connect(this, &SuspendHandlerBase::lockedEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
|
||||
}
|
||||
QObject::connect(this, &SuspendHandlerBase::idleEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
|
||||
Info(_log, "Registered for lock/unlock events. %s on lock event.", _isSuspendOnLock ? "Suspend" : "Idle");
|
||||
_isLockRegistered = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::unregisterLockHandler()
|
||||
{
|
||||
if (_isLockRegistered)
|
||||
{
|
||||
QObject::disconnect(this, &SuspendHandlerBase::lockedEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleSuspend);
|
||||
QObject::disconnect(this, &SuspendHandlerBase::lockedEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
|
||||
QObject::disconnect(this, &SuspendHandlerBase::idleEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
|
||||
Info(_log, "Unregistered for lock/unlock events.");
|
||||
_isLockRegistered = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SuspendHandlerBase::registerSuspendApiHandler()
|
||||
{
|
||||
if (!_isSuspendApiRegistered)
|
||||
{
|
||||
QObject::connect(HyperionIManager::getInstance(), &HyperionIManager::triggerSuspend, this, QOverload<bool>::of(&SuspendHandler::suspend));
|
||||
QObject::connect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleSuspend, this, &SuspendHandler::toggleSuspend);
|
||||
Info(_log, "Registered for suspend/resume API events.");
|
||||
_isSuspendApiRegistered = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::unregisterSuspendApiHandler()
|
||||
{
|
||||
if (_isSuspendApiRegistered)
|
||||
{
|
||||
QObject::disconnect(HyperionIManager::getInstance(), &HyperionIManager::triggerSuspend, this, QOverload<bool>::of(&SuspendHandler::suspend));
|
||||
QObject::disconnect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleSuspend, this, &SuspendHandler::toggleSuspend);
|
||||
Info(_log, "Unregistered for suspend/resume API events.");
|
||||
_isSuspendApiRegistered = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SuspendHandlerBase::registerIdleApiHandler()
|
||||
{
|
||||
if (!_isIdleApiRegistered)
|
||||
{
|
||||
QObject::connect(HyperionIManager::getInstance(), &HyperionIManager::triggerIdle, this, &SuspendHandler::idle);
|
||||
QObject::connect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleIdle, this, &SuspendHandler::toggleIdle);
|
||||
Info(_log, "Registered for idle API events.");
|
||||
_isIdleApiRegistered = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::unregisterIdleApiHandler()
|
||||
{
|
||||
if (_isIdleApiRegistered)
|
||||
{
|
||||
QObject::disconnect(HyperionIManager::getInstance(), &HyperionIManager::triggerIdle, this, &SuspendHandler::idle);
|
||||
QObject::disconnect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleIdle, this, &SuspendHandler::toggleIdle);
|
||||
Info(_log, "Unregistered for idle API events.");
|
||||
_isIdleApiRegistered = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::suspend()
|
||||
{
|
||||
suspend(true);
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::suspend(bool sleep)
|
||||
{
|
||||
if (sleep)
|
||||
{
|
||||
if (!_isSuspended)
|
||||
{
|
||||
_isSuspended = true;
|
||||
Info(_log, "Suspend event received - Hyperion is going to sleep");
|
||||
emit suspendEvent();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug(_log, "Suspend event ignored - already suspended");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_isSuspended || _isIdle)
|
||||
{
|
||||
Info(_log, "Resume event received - Hyperion is going into working mode");
|
||||
emit resumeEvent();
|
||||
_isSuspended = false;
|
||||
_isIdle = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug(_log, "Resume event ignored - not in suspend nor idle mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::resume()
|
||||
{
|
||||
suspend(false);
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::toggleSuspend()
|
||||
{
|
||||
Debug(_log, "Toggle suspend event received");
|
||||
if (!_isSuspended)
|
||||
{
|
||||
suspend(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
suspend(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::idle(bool isIdle)
|
||||
{
|
||||
if (!_isSuspended)
|
||||
{
|
||||
if (isIdle)
|
||||
{
|
||||
if (!_isIdle)
|
||||
{
|
||||
_isIdle = true;
|
||||
Info(_log, "Idle event received");
|
||||
emit idleEvent(isIdle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_isIdle)
|
||||
{
|
||||
Info(_log, "Resume from idle event recevied");
|
||||
emit idleEvent(isIdle);
|
||||
_isIdle = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug(_log, "Idle event ignored - Hyperion is suspended");
|
||||
}
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::toggleIdle()
|
||||
{
|
||||
Debug(_log, "Toggle idle event received");
|
||||
if (!_isIdle)
|
||||
{
|
||||
idle(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
idle(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SuspendHandlerBase::lock(bool isLocked)
|
||||
{
|
||||
if (!_isSuspended)
|
||||
{
|
||||
if (isLocked)
|
||||
{
|
||||
if (!_isLocked)
|
||||
{
|
||||
_isLocked = true;
|
||||
Info(_log, "Screen lock event received");
|
||||
emit lockedEvent(isLocked);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_isLocked)
|
||||
{
|
||||
Info(_log, "Screen unlock event received");
|
||||
emit lockedEvent(isLocked);
|
||||
_isLocked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug(_log, "Screen lock event ignored - Hyperion is suspended");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
SuspendHandlerWindows::SuspendHandlerWindows()
|
||||
: _notifyHandle(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
SuspendHandlerWindows::~SuspendHandlerWindows()
|
||||
{
|
||||
unregisterLockHandler();
|
||||
unregisterSuspendHandler();
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
bool SuspendHandlerWindows::nativeEventFilter(const QByteArray& eventType, void* message, qintptr* /*result*/)
|
||||
#else
|
||||
bool SuspendHandlerWindows::nativeEventFilter(const QByteArray& eventType, void* message, long int* /*result*/)
|
||||
#endif
|
||||
{
|
||||
MSG* msg = static_cast<MSG*>(message);
|
||||
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_WTSSESSION_CHANGE:
|
||||
switch (msg->wParam)
|
||||
{
|
||||
case WTS_SESSION_LOCK:
|
||||
emit lock(true);
|
||||
return true;
|
||||
break;
|
||||
case WTS_SESSION_UNLOCK:
|
||||
emit lock(false);
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_POWERBROADCAST:
|
||||
switch (msg->wParam)
|
||||
{
|
||||
case PBT_APMRESUMESUSPEND:
|
||||
emit suspend(false);
|
||||
return true;
|
||||
break;
|
||||
case PBT_APMSUSPEND:
|
||||
emit suspend(true);
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SuspendHandlerWindows::registerSuspendHandler()
|
||||
{
|
||||
bool isRegistered{ _isSuspendRegistered };
|
||||
if (!_isSuspendRegistered)
|
||||
{
|
||||
auto handle = reinterpret_cast<HWND> (_widget.winId());
|
||||
_notifyHandle = RegisterSuspendResumeNotification(handle, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
if (_notifyHandle != NULL)
|
||||
{
|
||||
QCoreApplication::instance()->installNativeEventFilter(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Could not register for suspend/resume events!");
|
||||
}
|
||||
|
||||
if (isRegistered)
|
||||
{
|
||||
isRegistered = SuspendHandlerBase::registerSuspendHandler();
|
||||
}
|
||||
}
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
void SuspendHandlerWindows::unregisterSuspendHandler()
|
||||
{
|
||||
if (_isSuspendRegistered)
|
||||
{
|
||||
if (_notifyHandle != NULL)
|
||||
{
|
||||
QCoreApplication::instance()->removeNativeEventFilter(this);
|
||||
UnregisterSuspendResumeNotification(_notifyHandle);
|
||||
}
|
||||
_notifyHandle = NULL;
|
||||
SuspendHandlerBase::unregisterSuspendHandler();
|
||||
}
|
||||
}
|
||||
|
||||
bool SuspendHandlerWindows::registerLockHandler()
|
||||
{
|
||||
bool isRegistered{ _isLockRegistered };
|
||||
if (!_isLockRegistered)
|
||||
{
|
||||
auto handle = reinterpret_cast<HWND> (_widget.winId());
|
||||
if (WTSRegisterSessionNotification(handle, NOTIFY_FOR_THIS_SESSION))
|
||||
{
|
||||
isRegistered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Could not register for lock/unlock events!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (isRegistered)
|
||||
{
|
||||
isRegistered = SuspendHandlerBase::registerLockHandler();
|
||||
}
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
void SuspendHandlerWindows::unregisterLockHandler()
|
||||
{
|
||||
if (_isLockRegistered)
|
||||
{
|
||||
auto handle = reinterpret_cast<HWND> (_widget.winId());
|
||||
WTSUnRegisterSessionNotification(handle);
|
||||
SuspendHandlerBase::unregisterLockHandler();
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__linux__) && defined(HYPERION_HAS_DBUS)
|
||||
#include <QDBusConnection>
|
||||
|
||||
struct dBusSignals
|
||||
{
|
||||
QString service;
|
||||
QString path;
|
||||
QString interface;
|
||||
QString name;
|
||||
};
|
||||
|
||||
typedef QMultiMap<QString, dBusSignals> DbusSignalsMap;
|
||||
|
||||
// Constants
|
||||
namespace {
|
||||
const DbusSignalsMap dbusSignals = {
|
||||
//system signals
|
||||
{"Suspend", {"org.freedesktop.login1","/org/freedesktop/login1","org.freedesktop.login1.Manager","PrepareForSleep"}},
|
||||
|
||||
//Session signals
|
||||
{"ScreenSaver", {"org.freedesktop.ScreenSaver","/org/freedesktop/ScreenSaver","org.freedesktop.ScreenSaver","ActiveChanged"}},
|
||||
{"ScreenSaver", {"org.gnome.ScreenSaver","/org/gnome/ScreenSaver","org.gnome.ScreenSaver","ActiveChanged"}},
|
||||
};
|
||||
} //End of constants
|
||||
|
||||
SuspendHandlerLinux::SuspendHandlerLinux()
|
||||
{
|
||||
}
|
||||
|
||||
bool SuspendHandlerLinux::registerSuspendHandler()
|
||||
{
|
||||
bool isRegistered {_isSuspendRegistered};
|
||||
if (!_isSuspendRegistered)
|
||||
{
|
||||
QDBusConnection systemBus = QDBusConnection::systemBus();
|
||||
if (!systemBus.isConnected())
|
||||
{
|
||||
Info(_log, "The suspend/resume feature is not supported by your system configuration");
|
||||
}
|
||||
else
|
||||
{
|
||||
QString service = dbusSignals.find("Suspend").value().service;
|
||||
if (systemBus.connect(service,
|
||||
dbusSignals.find("Suspend").value().path,
|
||||
dbusSignals.find("Suspend").value().interface,
|
||||
dbusSignals.find("Suspend").value().name,
|
||||
this, SLOT(suspend(bool))))
|
||||
{
|
||||
Debug(_log, "Registered for suspend/resume events via service: %s", QSTRING_CSTR(service));
|
||||
isRegistered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Could not register for suspend/resume events via service: %s", QSTRING_CSTR(service));
|
||||
}
|
||||
}
|
||||
|
||||
if (isRegistered)
|
||||
{
|
||||
isRegistered = SuspendHandlerBase::registerSuspendHandler();
|
||||
}
|
||||
|
||||
}
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
void SuspendHandlerLinux::unregisterSuspendHandler()
|
||||
{
|
||||
if (_isSuspendRegistered)
|
||||
{
|
||||
QDBusConnection systemBus = QDBusConnection::systemBus();
|
||||
if (!systemBus.isConnected())
|
||||
{
|
||||
Info(_log, "The suspend/resume feature is not supported by your system configuration");
|
||||
}
|
||||
else
|
||||
{
|
||||
QString service = dbusSignals.find("Suspend").value().service;
|
||||
if (systemBus.disconnect(service,
|
||||
dbusSignals.find("Suspend").value().path,
|
||||
dbusSignals.find("Suspend").value().interface,
|
||||
dbusSignals.find("Suspend").value().name,
|
||||
this, SLOT(suspend(bool))))
|
||||
{
|
||||
Debug(_log, "Unregistered for suspend/resume events via service: %s", QSTRING_CSTR(service));
|
||||
SuspendHandlerBase::unregisterSuspendHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Could not unregister for suspend/resume events via service: %s", QSTRING_CSTR(service));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SuspendHandlerLinux::registerLockHandler()
|
||||
{
|
||||
bool isRegistered {_isLockRegistered};
|
||||
|
||||
if (!_isLockRegistered)
|
||||
{
|
||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||
if (!sessionBus.isConnected())
|
||||
{
|
||||
Info(_log, "The lock/unlock feature is not supported by your system configuration");
|
||||
}
|
||||
else
|
||||
{
|
||||
DbusSignalsMap::const_iterator iter = dbusSignals.find("ScreenSaver");
|
||||
while (iter != dbusSignals.end() && iter.key() == "ScreenSaver") {
|
||||
QString service = iter.value().service;
|
||||
if (sessionBus.connect(service,
|
||||
iter.value().path,
|
||||
iter.value().interface,
|
||||
iter.value().name,
|
||||
this, SLOT(lock(bool))))
|
||||
{
|
||||
Debug(_log, "Registered for lock/unlock events via service: %s", QSTRING_CSTR(service));
|
||||
isRegistered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Could not register for lock/unlock events via service: %s", QSTRING_CSTR(service));
|
||||
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (isRegistered)
|
||||
{
|
||||
isRegistered = SuspendHandlerBase::registerLockHandler();
|
||||
}
|
||||
|
||||
return isRegistered;
|
||||
}
|
||||
|
||||
void SuspendHandlerLinux::unregisterLockHandler()
|
||||
{
|
||||
bool isUnregistered {false};
|
||||
|
||||
if (_isLockRegistered)
|
||||
{
|
||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||
if (!sessionBus.isConnected())
|
||||
{
|
||||
Info(_log, "The lock/unlock feature is not supported by your system configuration");
|
||||
}
|
||||
else
|
||||
{
|
||||
DbusSignalsMap::const_iterator iter = dbusSignals.find("ScreenSaver");
|
||||
while (iter != dbusSignals.end() && iter.key() == "ScreenSaver") {
|
||||
QString service = iter.value().service;
|
||||
if (sessionBus.disconnect(service,
|
||||
iter.value().path,
|
||||
iter.value().interface,
|
||||
iter.value().name,
|
||||
this, SLOT(lock(bool))))
|
||||
{
|
||||
Debug(_log, "Unregistered for lock/unlock events via service: %s", QSTRING_CSTR(service));
|
||||
isUnregistered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Could not unregister for lock/unlock events via service: %s", QSTRING_CSTR(service));
|
||||
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (isUnregistered)
|
||||
{
|
||||
SuspendHandlerBase::unregisterLockHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@@ -1,127 +0,0 @@
|
||||
#ifndef SUSPENDHANDLER_H
|
||||
#define SUSPENDHANDLER_H
|
||||
#include <QObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QWidget>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <utils/settings.h>
|
||||
|
||||
class Logger;
|
||||
|
||||
class SuspendHandlerBase : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SuspendHandlerBase();
|
||||
~SuspendHandlerBase() override;
|
||||
|
||||
public slots:
|
||||
|
||||
void suspend(bool sleep);
|
||||
|
||||
void suspend();
|
||||
void resume();
|
||||
void toggleSuspend();
|
||||
|
||||
void idle(bool isIdle);
|
||||
void toggleIdle();
|
||||
|
||||
void lock(bool isLocked);
|
||||
|
||||
virtual void handleSettingsUpdate(settings::type type, const QJsonDocument& config);
|
||||
|
||||
signals:
|
||||
|
||||
void suspendEvent();
|
||||
void resumeEvent();
|
||||
void lockedEvent(bool);
|
||||
void idleEvent(bool);
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool registerSuspendHandler();
|
||||
virtual void unregisterSuspendHandler();
|
||||
virtual bool registerLockHandler();
|
||||
virtual void unregisterLockHandler();
|
||||
|
||||
virtual bool registerSuspendApiHandler();
|
||||
virtual void unregisterSuspendApiHandler();
|
||||
virtual bool registerIdleApiHandler();
|
||||
virtual void unregisterIdleApiHandler();
|
||||
|
||||
bool _isSuspendEnabled;
|
||||
bool _isLockEnabled;
|
||||
bool _isSuspendApiEnabled;
|
||||
bool _isIdleApiEnabled;
|
||||
bool _isSuspendOnLock;
|
||||
|
||||
bool _isSuspendRegistered;
|
||||
bool _isLockRegistered;
|
||||
bool _isSuspendApiRegistered;
|
||||
bool _isIdleApiRegistered;
|
||||
|
||||
Logger * _log {};
|
||||
|
||||
private:
|
||||
|
||||
bool _isSuspended;
|
||||
bool _isIdle;
|
||||
bool _isLocked;
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
class SuspendHandlerWindows : public SuspendHandlerBase, public QAbstractNativeEventFilter {
|
||||
|
||||
public:
|
||||
SuspendHandlerWindows();
|
||||
~SuspendHandlerWindows() override;
|
||||
|
||||
protected:
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
bool nativeEventFilter(const QByteArray& eventType, void* message, qintptr* result) override;
|
||||
#else
|
||||
bool nativeEventFilter(const QByteArray& eventType, void* message, long int* result) override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
bool registerSuspendHandler() override;
|
||||
void unregisterSuspendHandler() override;
|
||||
bool registerLockHandler() override;
|
||||
void unregisterLockHandler() override;
|
||||
|
||||
QWidget _widget;
|
||||
HPOWERNOTIFY _notifyHandle;
|
||||
};
|
||||
|
||||
using SuspendHandler = SuspendHandlerWindows;
|
||||
|
||||
#elif defined(__linux__) && defined(HYPERION_HAS_DBUS)
|
||||
|
||||
class SuspendHandlerLinux : public SuspendHandlerBase {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SuspendHandlerLinux();
|
||||
|
||||
private:
|
||||
bool registerSuspendHandler() override;
|
||||
void unregisterSuspendHandler() override;
|
||||
bool registerLockHandler() override;
|
||||
void unregisterLockHandler() override;
|
||||
};
|
||||
|
||||
using SuspendHandler = SuspendHandlerLinux;
|
||||
|
||||
#else
|
||||
using SuspendHandler = SuspendHandlerBase;
|
||||
#endif
|
||||
|
||||
#endif // SUSPENDHANDLER_H
|
@@ -97,7 +97,8 @@ HyperionDaemon::HyperionDaemon(const QString& rootPath, QObject* parent, bool lo
|
||||
#ifdef ENABLE_CEC
|
||||
, _cecHandler(nullptr)
|
||||
#endif
|
||||
, _suspendHandler(nullptr)
|
||||
, _eventHandler(nullptr)
|
||||
, _osEventHandler(nullptr)
|
||||
, _currVideoMode(VideoMode::VIDEO_2D)
|
||||
{
|
||||
HyperionDaemon::daemon = this;
|
||||
@@ -119,8 +120,6 @@ HyperionDaemon::HyperionDaemon(const QString& rootPath, QObject* parent, bool lo
|
||||
handleSettingsUpdate(settings::LOGGER, getSetting(settings::LOGGER));
|
||||
}
|
||||
|
||||
createCecHandler();
|
||||
|
||||
//Create MdnsBrowser singleton in main tread to ensure thread affinity during destruction
|
||||
#ifdef ENABLE_MDNS
|
||||
MdnsBrowser::getInstance();
|
||||
@@ -178,7 +177,7 @@ HyperionDaemon::HyperionDaemon(const QString& rootPath, QObject* parent, bool lo
|
||||
startNetworkServices();
|
||||
|
||||
// init events services
|
||||
handleSettingsUpdate(settings::SYSTEMEVENTS, getSetting(settings::SYSTEMEVENTS));
|
||||
handleSettingsUpdate(settings::OSEVENTS, getSetting(settings::OSEVENTS));
|
||||
}
|
||||
|
||||
HyperionDaemon::~HyperionDaemon()
|
||||
@@ -234,7 +233,10 @@ void HyperionDaemon::handleInstanceStateChange(InstanceState state, quint8 insta
|
||||
connect(_sslWebserver, &WebServer::publishService, _mDNSProvider, &MdnsProvider::publishService);
|
||||
#endif
|
||||
sslWsThread->start();
|
||||
|
||||
//startCecHandler();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case InstanceState::H_STOPPED:
|
||||
@@ -263,6 +265,8 @@ void HyperionDaemon::freeObjects()
|
||||
{
|
||||
Debug(_log, "Cleaning up Hyperion before quit.");
|
||||
|
||||
stopCecHandler();
|
||||
|
||||
#ifdef ENABLE_MDNS
|
||||
if (_mDNSProvider != nullptr)
|
||||
{
|
||||
@@ -333,19 +337,7 @@ void HyperionDaemon::freeObjects()
|
||||
_sslWebserver = nullptr;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CEC
|
||||
if (_cecHandler != nullptr)
|
||||
{
|
||||
auto cecHandlerThread = _cecHandler->thread();
|
||||
cecHandlerThread->quit();
|
||||
cecHandlerThread->wait();
|
||||
delete cecHandlerThread;
|
||||
delete _cecHandler;
|
||||
_cecHandler = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete _suspendHandler;
|
||||
delete _osEventHandler;
|
||||
|
||||
// stop Hyperions (non blocking)
|
||||
_instanceManager->stopAll();
|
||||
@@ -693,19 +685,6 @@ void HyperionDaemon::handleSettingsUpdate(settings::type settingsType, const QJs
|
||||
}
|
||||
else if (settingsType == settings::V4L2)
|
||||
{
|
||||
|
||||
#ifdef ENABLE_CEC
|
||||
const QJsonObject& grabberConfig = config.object();
|
||||
if (_cecHandler != nullptr && grabberConfig["cecDetection"].toBool(false))
|
||||
{
|
||||
QMetaObject::invokeMethod(_cecHandler, "start", Qt::QueuedConnection);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMetaObject::invokeMethod(_cecHandler, "stop", Qt::QueuedConnection);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_V4L2) || defined(ENABLE_MF)
|
||||
if (_videoGrabber == nullptr)
|
||||
{
|
||||
@@ -743,18 +722,28 @@ void HyperionDaemon::handleSettingsUpdate(settings::type settingsType, const QJs
|
||||
Debug(_log, "Audio capture not supported on this platform");
|
||||
#endif
|
||||
}
|
||||
else if (settingsType == settings::SYSTEMEVENTS)
|
||||
else if (settingsType == settings::OSEVENTS)
|
||||
{
|
||||
// Create suspend handler
|
||||
if (_suspendHandler == nullptr)
|
||||
if (_eventHandler == nullptr)
|
||||
{
|
||||
_suspendHandler = new SuspendHandler();
|
||||
_suspendHandler->handleSettingsUpdate(settings::SYSTEMEVENTS, getSetting(settings::SYSTEMEVENTS));
|
||||
|
||||
connect(this, &HyperionDaemon::settingsChanged, _suspendHandler, &SuspendHandler::handleSettingsUpdate);
|
||||
|
||||
Debug(_log, "SuspendHandler created");
|
||||
_eventHandler = EventHandler::getInstance();
|
||||
Debug(_log, "Hyperion event handler created");
|
||||
}
|
||||
|
||||
// Create suspend handler
|
||||
if (_osEventHandler == nullptr)
|
||||
{
|
||||
_osEventHandler = new OsEventHandler();
|
||||
_osEventHandler->handleSettingsUpdate(settings::OSEVENTS, getSetting(settings::OSEVENTS));
|
||||
|
||||
connect(this, &HyperionDaemon::settingsChanged, _osEventHandler, &OsEventHandler::handleSettingsUpdate);
|
||||
|
||||
Debug(_log, "Operating System event handler created");
|
||||
}
|
||||
}
|
||||
else if (settingsType == settings::CECEVENTS)
|
||||
{
|
||||
startCecHandler();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -929,26 +918,47 @@ void HyperionDaemon::createGrabberOsx(const QJsonObject& grabberConfig)
|
||||
#endif
|
||||
}
|
||||
|
||||
void HyperionDaemon::createCecHandler()
|
||||
void HyperionDaemon::startCecHandler()
|
||||
{
|
||||
#if defined(ENABLE_V4L2) && defined(ENABLE_CEC)
|
||||
_cecHandler = new CECHandler;
|
||||
#if defined(ENABLE_CEC)
|
||||
if (_cecHandler == nullptr)
|
||||
{
|
||||
_cecHandler = new CECHandler;
|
||||
|
||||
QThread* thread = new QThread(this);
|
||||
thread->setObjectName("CECThread");
|
||||
_cecHandler->moveToThread(thread);
|
||||
thread->start();
|
||||
QThread* cecHandlerThread = new QThread(this);
|
||||
cecHandlerThread->setObjectName("CECThread");
|
||||
_cecHandler->moveToThread(cecHandlerThread);
|
||||
|
||||
connect(_cecHandler, &CECHandler::cecEvent, [&](CECEvent event) {
|
||||
if (_videoGrabber != nullptr)
|
||||
{
|
||||
_videoGrabber->handleCecEvent(event);
|
||||
}
|
||||
});
|
||||
connect(cecHandlerThread, &QThread::started, _cecHandler, &CECHandler::start);
|
||||
connect(cecHandlerThread, &QThread::finished, _cecHandler, &CECHandler::stop);
|
||||
|
||||
Info(_log, "CEC handler created");
|
||||
cecHandlerThread->start();
|
||||
|
||||
_cecHandler->handleSettingsUpdate(settings::CECEVENTS, getSetting(settings::CECEVENTS));
|
||||
connect(this, &HyperionDaemon::settingsChanged, _cecHandler, &CECHandler::handleSettingsUpdate);
|
||||
|
||||
Info(_log, "CEC event handler created");
|
||||
}
|
||||
#else
|
||||
Debug(_log, "The CEC handler is not supported on this platform");
|
||||
#endif
|
||||
}
|
||||
|
||||
void HyperionDaemon::stopCecHandler()
|
||||
{
|
||||
#if defined(ENABLE_CEC)
|
||||
if (_cecHandler != nullptr)
|
||||
{
|
||||
disconnect(_cecHandler, &CECHandler::signalEvent, _eventHandler, &EventHandler::handleEvent);
|
||||
|
||||
auto cecHandlerThread = _cecHandler->thread();
|
||||
cecHandlerThread->quit();
|
||||
cecHandlerThread->wait();
|
||||
delete cecHandlerThread;
|
||||
delete _cecHandler;
|
||||
_cecHandler = nullptr;
|
||||
}
|
||||
Info(_log, "CEC handler stopped");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -75,7 +75,8 @@
|
||||
#include <utils/settings.h>
|
||||
#include <utils/Components.h>
|
||||
|
||||
#include "SuspendHandler.h"
|
||||
#include <events/EventHandler.h>
|
||||
#include <events/OsEventHandler.h>
|
||||
|
||||
class HyperionIManager;
|
||||
class SysTray;
|
||||
@@ -103,18 +104,13 @@ class HyperionDaemon : public QObject
|
||||
|
||||
public:
|
||||
HyperionDaemon(const QString& rootPath, QObject *parent, bool logLvlOverwrite, bool readonlyMode = false);
|
||||
~HyperionDaemon();
|
||||
~HyperionDaemon() override;
|
||||
|
||||
///
|
||||
/// @brief Get webserver pointer (systray)
|
||||
///
|
||||
WebServer *getWebServerInstance() { return _webserver; }
|
||||
|
||||
///
|
||||
/// @brief Get suspense handler pointer
|
||||
///
|
||||
SuspendHandler* getSuspendHandlerInstance() { return _suspendHandler; }
|
||||
|
||||
///
|
||||
/// @brief Get the current videoMode
|
||||
///
|
||||
@@ -185,10 +181,12 @@ private:
|
||||
void createGrabberX11(const QJsonObject & grabberConfig);
|
||||
void createGrabberXcb(const QJsonObject & grabberConfig);
|
||||
void createGrabberQt(const QJsonObject & grabberConfig);
|
||||
void createCecHandler();
|
||||
void createGrabberDx(const QJsonObject & grabberConfig);
|
||||
void createGrabberAudio(const QJsonObject & grabberConfig);
|
||||
|
||||
void startCecHandler();
|
||||
void stopCecHandler();
|
||||
|
||||
Logger* _log;
|
||||
HyperionIManager* _instanceManager;
|
||||
AuthManager* _authManager;
|
||||
@@ -216,7 +214,8 @@ private:
|
||||
#ifdef ENABLE_CEC
|
||||
CECHandler* _cecHandler;
|
||||
#endif
|
||||
SuspendHandler* _suspendHandler;
|
||||
EventHandler* _eventHandler;
|
||||
OsEventHandler* _osEventHandler;
|
||||
|
||||
#if defined(ENABLE_FLATBUF_SERVER)
|
||||
FlatBufferServer* _flatBufferServer;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
#include <cassert>
|
||||
#include <csignal>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -46,40 +45,12 @@
|
||||
|
||||
#include "hyperiond.h"
|
||||
#include "systray.h"
|
||||
#include "SuspendHandler.h"
|
||||
#include <events/EventHandler.h>
|
||||
|
||||
using namespace commandline;
|
||||
|
||||
#define PERM0664 (QFileDevice::ReadOwner | QFileDevice::ReadGroup | QFileDevice::ReadOther | QFileDevice::WriteOwner | QFileDevice::WriteGroup)
|
||||
|
||||
#ifndef _WIN32
|
||||
void signal_handler(int signum)
|
||||
{
|
||||
HyperionDaemon* hyperiond = HyperionDaemon::getInstance();
|
||||
SuspendHandler* suspendHandler = hyperiond->getSuspendHandlerInstance();
|
||||
|
||||
if (signum == SIGCHLD)
|
||||
{
|
||||
// only quit when a registered child process is gone
|
||||
// currently this feature is not active ...
|
||||
}
|
||||
else if (signum == SIGUSR1)
|
||||
{
|
||||
if (suspendHandler != nullptr)
|
||||
{
|
||||
suspendHandler->suspend();
|
||||
}
|
||||
}
|
||||
else if (signum == SIGUSR2)
|
||||
{
|
||||
if (suspendHandler != nullptr)
|
||||
{
|
||||
suspendHandler->resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
QCoreApplication* createApplication(int &argc, char *argv[])
|
||||
{
|
||||
bool isGuiApp = false;
|
||||
@@ -150,11 +121,6 @@ int main(int argc, char** argv)
|
||||
|
||||
DefaultSignalHandler::install();
|
||||
|
||||
#ifndef _WIN32
|
||||
signal(SIGCHLD, signal_handler);
|
||||
signal(SIGUSR1, signal_handler);
|
||||
signal(SIGUSR2, signal_handler);
|
||||
#endif
|
||||
// force the locale
|
||||
setlocale(LC_ALL, "C");
|
||||
QLocale::setDefault(QLocale::c());
|
||||
|
@@ -22,10 +22,11 @@
|
||||
#endif
|
||||
#include <webserver/WebServer.h>
|
||||
#include <hyperion/PriorityMuxer.h>
|
||||
#include <events/EventHandler.h>
|
||||
|
||||
#include "hyperiond.h"
|
||||
#include "systray.h"
|
||||
#include "SuspendHandler.h"
|
||||
|
||||
|
||||
SysTray::SysTray(HyperionDaemon *hyperiond)
|
||||
: QWidget()
|
||||
@@ -33,7 +34,6 @@ SysTray::SysTray(HyperionDaemon *hyperiond)
|
||||
, _hyperiond(hyperiond)
|
||||
, _hyperion(nullptr)
|
||||
, _instanceManager(HyperionIManager::getInstance())
|
||||
, _suspendHandler (hyperiond->getSuspendHandlerInstance())
|
||||
, _webPort(8090)
|
||||
{
|
||||
Q_INIT_RESOURCE(resources);
|
||||
@@ -84,13 +84,16 @@ void SysTray::createTrayIcon()
|
||||
restartAction->setIcon(QPixmap(":/restart.svg"));
|
||||
connect(restartAction, &QAction::triggered, this , [=](){ Process::restartHyperion(12); });
|
||||
|
||||
|
||||
// TODO: Check if can be done with SystemEvents
|
||||
suspendAction = new QAction(tr("&Suspend"), this);
|
||||
suspendAction->setIcon(QPixmap(":/suspend.svg"));
|
||||
connect(suspendAction, &QAction::triggered, _suspendHandler, QOverload<>::of(&SuspendHandler::suspend));
|
||||
connect(suspendAction, &QAction::triggered, EventHandler::getInstance(), QOverload<>::of(&EventHandler::suspend));
|
||||
|
||||
resumeAction = new QAction(tr("&Resume"), this);
|
||||
resumeAction->setIcon(QPixmap(":/resume.svg"));
|
||||
connect(resumeAction, &QAction::triggered, _suspendHandler, &SuspendHandler::resume);
|
||||
|
||||
connect(resumeAction, &QAction::triggered, EventHandler::getInstance(), &EventHandler::resume);
|
||||
|
||||
colorAction = new QAction(tr("&Color"), this);
|
||||
colorAction->setIcon(QPixmap(":/color.svg"));
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/HyperionIManager.h>
|
||||
#include "SuspendHandler.h"
|
||||
#include <events/EventHandler.h>
|
||||
|
||||
class HyperionDaemon;
|
||||
|
||||
@@ -22,13 +22,13 @@ class SysTray : public QWidget
|
||||
|
||||
public:
|
||||
SysTray(HyperionDaemon *hyperiond);
|
||||
~SysTray();
|
||||
~SysTray() override;
|
||||
|
||||
|
||||
public slots:
|
||||
void showColorDialog();
|
||||
void setColor(const QColor & color);
|
||||
void closeEvent(QCloseEvent *event);
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
void settings() const;
|
||||
#if defined(ENABLE_EFFECTENGINE)
|
||||
void setEffect();
|
||||
@@ -42,7 +42,7 @@ private slots:
|
||||
///
|
||||
/// @brief is called whenever the webserver changes the port
|
||||
///
|
||||
void webserverPortChanged(quint16 port) { _webPort = port; };
|
||||
void webserverPortChanged(quint16 port) { _webPort = port; }
|
||||
|
||||
///
|
||||
/// @brief is called whenever a hyperion instance state changes
|
||||
@@ -84,6 +84,4 @@ private:
|
||||
Hyperion *_hyperion;
|
||||
HyperionIManager *_instanceManager;
|
||||
quint16 _webPort;
|
||||
|
||||
SuspendHandler *_suspendHandler;
|
||||
};
|
||||
|
Reference in New Issue
Block a user