feat: Convert daemon to Qt app and introduce Qt local server
This commit is contained in:
parent
95603c82ec
commit
c0094554b1
7 changed files with 106 additions and 31 deletions
|
|
@ -14,6 +14,8 @@ if(WIN32)
|
||||||
|
|
||||||
add_executable(${target} WIN32 ${target}.cpp ${CMAKE_CURRENT_BINARY_DIR}/${target}.rc)
|
add_executable(${target} WIN32 ${target}.cpp ${CMAKE_CURRENT_BINARY_DIR}/${target}.rc)
|
||||||
|
|
||||||
|
find_package(Qt6 COMPONENTS Core Network)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
${target}
|
${target}
|
||||||
arch
|
arch
|
||||||
|
|
@ -24,7 +26,8 @@ if(WIN32)
|
||||||
net
|
net
|
||||||
platform
|
platform
|
||||||
app
|
app
|
||||||
${libs})
|
${libs}
|
||||||
|
Qt6::Core)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS ${target}
|
TARGETS ${target}
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||||
Log log;
|
Log log;
|
||||||
EventQueue events;
|
EventQueue events;
|
||||||
|
|
||||||
DaemonApp app(&events);
|
DaemonApp app(&events, __argc, __argv);
|
||||||
return app.run(__argc, __argv);
|
return DaemonApp::exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ endif()
|
||||||
####################Start Making Library#########################
|
####################Start Making Library#########################
|
||||||
set(lib_name app)
|
set(lib_name app)
|
||||||
|
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
# arch
|
# arch
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(PLATFORM_CODE
|
set(PLATFORM_CODE
|
||||||
|
|
@ -143,8 +145,12 @@ add_library(${lib_name} STATIC ${PLATFORM_CODE}
|
||||||
XScreen.h
|
XScreen.h
|
||||||
languages/LanguageManager.cpp
|
languages/LanguageManager.cpp
|
||||||
languages/LanguageManager.h
|
languages/LanguageManager.h
|
||||||
|
ipc/IpcServer2.cpp
|
||||||
|
ipc/IpcServer2.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
find_package(Qt6 COMPONENTS Core Network)
|
||||||
|
target_link_libraries(${lib_name} PRIVATE Qt6::Core Qt6::Network)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_compile_definitions(${lib_name} PUBLIC HAVE_WINTOAST)
|
target_compile_definitions(${lib_name} PUBLIC HAVE_WINTOAST)
|
||||||
|
|
@ -161,6 +167,7 @@ target_include_directories(
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
${lib_name}
|
${lib_name}
|
||||||
|
PRIVATE
|
||||||
arch
|
arch
|
||||||
client
|
client
|
||||||
ipc
|
ipc
|
||||||
|
|
@ -174,12 +181,13 @@ if(UNIX)
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT APPLE)
|
if(NOT APPLE)
|
||||||
target_link_libraries(${lib_name} pugixml)
|
target_link_libraries(${lib_name} PRIVATE pugixml)
|
||||||
|
|
||||||
find_package(PkgConfig)
|
find_package(PkgConfig)
|
||||||
if(PKG_CONFIG_FOUND)
|
if(PKG_CONFIG_FOUND)
|
||||||
target_link_libraries(${lib_name} PkgConfig::lib_glib
|
target_link_libraries(${lib_name}
|
||||||
PkgConfig::lib_gdkpixbuf PkgConfig::lib_notify)
|
PRIVATE
|
||||||
|
PkgConfig::lib_glib PkgConfig::lib_gdkpixbuf PkgConfig::lib_notify)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "ipc/IpcClientProxy.h"
|
#include "ipc/IpcClientProxy.h"
|
||||||
#include "ipc/IpcLogOutputter.h"
|
#include "ipc/IpcLogOutputter.h"
|
||||||
#include "ipc/IpcMessage.h"
|
#include "ipc/IpcMessage.h"
|
||||||
|
#include "ipc/IpcServer2.h"
|
||||||
#include "ipc/IpcSettingMessage.h"
|
#include "ipc/IpcSettingMessage.h"
|
||||||
#include "net/SocketMultiplexer.h"
|
#include "net/SocketMultiplexer.h"
|
||||||
|
|
||||||
|
|
@ -95,8 +96,16 @@ int winMainLoopStatic(int, const char **)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DaemonApp::DaemonApp(IEventQueue *events) : m_events(events)
|
DaemonApp::DaemonApp(IEventQueue *events, int argc, char **argv)
|
||||||
|
: QCoreApplication(argc, argv),
|
||||||
|
m_events(events),
|
||||||
|
m_ipcServer2{new deskflow::ipc::IpcServer2(this)}
|
||||||
{
|
{
|
||||||
|
// HACK: init used to be run, which was the main loop.
|
||||||
|
// now it's used for arg parsing, install/uninstall, etc.
|
||||||
|
if (init(argc, argv) != kExitSuccess) {
|
||||||
|
exit(kExitFailed);
|
||||||
|
}
|
||||||
s_instance = this;
|
s_instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,7 +114,14 @@ DaemonApp::~DaemonApp()
|
||||||
s_instance = nullptr;
|
s_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DaemonApp::run(int argc, char **argv)
|
void DaemonApp::startAsync()
|
||||||
|
{
|
||||||
|
#if SYSAPI_WIN32
|
||||||
|
m_watchdog->startAsync();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int DaemonApp::init(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool uninstall = false;
|
bool uninstall = false;
|
||||||
try {
|
try {
|
||||||
|
|
@ -141,27 +157,11 @@ int DaemonApp::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
|
||||||
if (!foreground) {
|
if (!foreground) {
|
||||||
|
#if SYSAPI_WIN32
|
||||||
// Only use MS debug outputter when the process is daemonized, since stdout won't be accessible
|
// Only use MS debug outputter when the process is daemonized, since stdout won't be accessible
|
||||||
// in that case, but is accessible when running in the foreground.
|
// in that case, but is accessible when running in the foreground.
|
||||||
CLOG->insert(new MSWindowsDebugOutputter()); // NOSONAR -- Adopted by `Log`
|
CLOG->insert(new MSWindowsDebugOutputter()); // NOSONAR - Adopted by `Log`
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (foreground) {
|
|
||||||
LOG((CLOG_NOTE "starting daemon in foreground"));
|
|
||||||
|
|
||||||
// run process in foreground instead of daemonizing.
|
|
||||||
// useful for debugging.
|
|
||||||
mainLoop(false, foreground);
|
|
||||||
} else {
|
|
||||||
#if SYSAPI_WIN32
|
|
||||||
LOG((CLOG_PRINT "daemonizing windows service"));
|
|
||||||
ARCH->daemonize(kAppName, winMainLoopStatic);
|
|
||||||
#elif SYSAPI_UNIX
|
|
||||||
LOG((CLOG_PRINT "daemonizing unix service"));
|
|
||||||
ARCH->daemonize(kAppName, unixMainLoopStatic);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,7 +255,7 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground)
|
||||||
void DaemonApp::foregroundError(const char *message)
|
void DaemonApp::foregroundError(const char *message)
|
||||||
{
|
{
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
MessageBox(NULL, message, "Deskflow Service", MB_OK | MB_ICONERROR);
|
MessageBoxA(NULL, message, "Deskflow Service", MB_OK | MB_ICONERROR);
|
||||||
#elif SYSAPI_UNIX
|
#elif SYSAPI_UNIX
|
||||||
cerr << message << endl;
|
cerr << message << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,16 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
class Event;
|
class Event;
|
||||||
class IpcLogOutputter;
|
class IpcLogOutputter;
|
||||||
class FileLogOutputter;
|
class FileLogOutputter;
|
||||||
|
class QLocalServer;
|
||||||
|
|
||||||
|
namespace deskflow::ipc {
|
||||||
|
class IpcServer2;
|
||||||
|
}
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
class MSWindowsWatchdog;
|
class MSWindowsWatchdog;
|
||||||
|
|
@ -21,16 +28,16 @@ class MSWindowsWatchdog;
|
||||||
|
|
||||||
extern const char *const kLogFilename;
|
extern const char *const kLogFilename;
|
||||||
|
|
||||||
class DaemonApp
|
class DaemonApp : public QCoreApplication
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DaemonApp(IEventQueue *events);
|
DaemonApp(IEventQueue *events, int argc, char **argv);
|
||||||
~DaemonApp();
|
~DaemonApp();
|
||||||
int run(int argc, char **argv);
|
void startAsync();
|
||||||
void mainLoop(bool logToFile, bool foreground = false);
|
void mainLoop(bool logToFile, bool foreground = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int init(int argc, char **argv);
|
||||||
void daemonize();
|
void daemonize();
|
||||||
void foregroundError(const char *message);
|
void foregroundError(const char *message);
|
||||||
std::string logFilename();
|
std::string logFilename();
|
||||||
|
|
@ -48,4 +55,5 @@ private:
|
||||||
std::unique_ptr<IpcLogOutputter> m_ipcLogOutputter;
|
std::unique_ptr<IpcLogOutputter> m_ipcLogOutputter;
|
||||||
IEventQueue *m_events = nullptr;
|
IEventQueue *m_events = nullptr;
|
||||||
FileLogOutputter *m_fileLogOutputter = nullptr;
|
FileLogOutputter *m_fileLogOutputter = nullptr;
|
||||||
|
std::unique_ptr<deskflow::ipc::IpcServer2> m_ipcServer2;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
29
src/lib/deskflow/ipc/IpcServer2.cpp
Normal file
29
src/lib/deskflow/ipc/IpcServer2.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
|
* SPDX-FileCopyrightText: (C) 2025 Symless Ltd.
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "IpcServer2.h"
|
||||||
|
|
||||||
|
#include "base/Log.h"
|
||||||
|
|
||||||
|
#include <QLocalServer>
|
||||||
|
|
||||||
|
namespace deskflow::ipc {
|
||||||
|
|
||||||
|
const auto kServerName = QStringLiteral("deskflow-daemon");
|
||||||
|
|
||||||
|
IpcServer2::IpcServer2(QObject *parent) : QObject(parent), m_server{new QLocalServer(this)}
|
||||||
|
{
|
||||||
|
m_server->removeServer(kServerName);
|
||||||
|
m_server->listen(kServerName);
|
||||||
|
LOG_INFO("ipc server listening on %s", kServerName.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcServer2::~IpcServer2()
|
||||||
|
{
|
||||||
|
m_server->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace deskflow::ipc
|
||||||
27
src/lib/deskflow/ipc/IpcServer2.h
Normal file
27
src/lib/deskflow/ipc/IpcServer2.h
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
|
* SPDX-FileCopyrightText: (C) 2025 Symless Ltd.
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class QLocalServer;
|
||||||
|
|
||||||
|
namespace deskflow::ipc {
|
||||||
|
|
||||||
|
class IpcServer2 : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
IpcServer2(QObject *parent);
|
||||||
|
~IpcServer2();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLocalServer *m_server;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace deskflow::ipc
|
||||||
Loading…
Reference in a new issue