/* * Deskflow -- mouse and keyboard sharing utility * SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello * SPDX-FileCopyrightText: (C) 2024 - 2025 Symless Ltd. * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception */ #pragma once #include "common/Enums.h" #include "common/Settings.h" #include "gui/FileTail.h" #include "gui/config/ServerConfig.h" #include #include #include #include namespace deskflow::gui { namespace ipc { class CoreIpcClient; class DaemonIpcClient; } // namespace ipc class CoreProcess : public QObject { using ConnectionState = deskflow::core::ConnectionState; using ProcessMode = Settings::ProcessMode; using ProcessState = deskflow::core::ProcessState; Q_OBJECT public: enum class Error { AddressMissing, StartFailed }; explicit CoreProcess(const ServerConfig &serverConfig); void start(std::optional processMode = std::nullopt); void stop(std::optional processMode = std::nullopt); void restart(); void cleanup(); void applyLogLevel(); void clearSettings(); void retryDaemon(); // getters Settings::CoreMode mode() const { return m_mode; } QString secureSocketVersion() const { return m_secureSocketVersion; } bool isStarted() const { return m_processState == ProcessState::Started; } ProcessState processState() const { return m_processState; } ConnectionState connectionState() const { return m_connectionState; } // setters void setAddress(const QString &address) { m_address = correctedAddress(address); } void setMode(Settings::CoreMode mode) { m_mode = mode; } Q_SIGNALS: void error(deskflow::gui::CoreProcess::Error error); void logLine(const QString &line); void connectionStateChanged(deskflow::core::ConnectionState state); void processStateChanged(deskflow::core::ProcessState state); void secureSocket(bool enabled); void daemonIpcClientConnectionFailed(); void connectedClientsChanged(const QStringList &clients); void securityLevelChanged(QString securityLevel); void unrecognisedClient(const QString &clientName); void connectionRefused(deskflow::core::ConnectionRefusal reason); void retryIn(int seconds); void peerFingerprint(const QString &fingerprint); void missingKeyboardLayouts(const QString &layouts); private Q_SLOTS: void onProcessFinished(int exitCode, QProcess::ExitStatus); void onProcessReadyReadStandardOutput(); void onProcessReadyReadStandardError(); void onCoreIpcMessageReceived(const QString &command, const QString &args); void daemonIpcClientConnected(); private: void startForegroundProcess(const QStringList &args); void startProcessFromDaemon(); void stopForegroundProcess() const; void stopProcessFromDaemon(); QPair persistServerConfig() const; void setConnectionState(ConnectionState state); void setProcessState(ProcessState state); bool checkSecureSocket(const QString &line); void handleLogLines(const QString &text); QString correctedAddress(const QString &address) const; void setupDaemonLogTail(const QString &logPath); static QString makeQuotedArgs(const QString &app, const QStringList &args); static QString processModeToString(const Settings::ProcessMode mode); static QString processStateToString(const CoreProcess::ProcessState state); static QString wrapIpv6(const QString &address); const ServerConfig &m_serverConfig; QString m_address; ProcessState m_processState = ProcessState::Stopped; ConnectionState m_connectionState = ConnectionState::Disconnected; Settings::CoreMode m_mode = Settings::CoreMode::None; QMutex m_processMutex; QString m_secureSocketVersion; std::optional m_lastProcessMode = std::nullopt; QTimer m_retryTimer; deskflow::gui::ipc::CoreIpcClient *m_coreIpcClient = nullptr; deskflow::gui::ipc::DaemonIpcClient *m_daemonIpcClient = nullptr; FileTail *m_daemonFileTail = nullptr; QProcess *m_process = nullptr; QString m_appPath; }; } // namespace deskflow::gui