Internal
Public Access
Milestone 5: deliver embedded RDP sessions and lifecycle hardening
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
#ifndef ORBITHUB_RDP_SESSION_BACKEND_H
|
||||
#define ORBITHUB_RDP_SESSION_BACKEND_H
|
||||
|
||||
#include "session_backend.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
struct rdp_freerdp;
|
||||
|
||||
class RdpSessionBackend : public SessionBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RdpSessionBackend(const Profile& profile, QObject* parent = nullptr);
|
||||
~RdpSessionBackend() override;
|
||||
|
||||
public slots:
|
||||
void connectSession(const SessionConnectOptions& options) override;
|
||||
void disconnectSession() override;
|
||||
void reconnectSession(const SessionConnectOptions& options) override;
|
||||
void sendInput(const QString& input) override;
|
||||
void confirmHostKey(bool trustHost) override;
|
||||
void updateTerminalSize(int columns, int rows) override;
|
||||
void sendKeyEvent(int key,
|
||||
quint32 nativeScanCode,
|
||||
const QString& text,
|
||||
bool pressed,
|
||||
int modifiers) override;
|
||||
void sendMouseMoveEvent(int x, int y) override;
|
||||
void sendMouseButtonEvent(int x, int y, int button, bool pressed) override;
|
||||
void sendMouseWheelEvent(int x, int y, int deltaX, int deltaY) override;
|
||||
|
||||
private:
|
||||
enum class InputEventType {
|
||||
Key,
|
||||
MouseMove,
|
||||
MouseButton,
|
||||
MouseWheel,
|
||||
Resize,
|
||||
};
|
||||
|
||||
struct InputEvent {
|
||||
InputEventType type = InputEventType::MouseMove;
|
||||
int key = 0;
|
||||
quint32 nativeScanCode = 0;
|
||||
QString text;
|
||||
bool pressed = false;
|
||||
int modifiers = 0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int button = 0;
|
||||
int deltaX = 0;
|
||||
int deltaY = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
};
|
||||
|
||||
SessionState m_state;
|
||||
SessionConnectOptions m_activeOptions;
|
||||
std::atomic_bool m_userInitiatedDisconnect;
|
||||
|
||||
std::atomic_int m_requestedDesktopWidth;
|
||||
std::atomic_int m_requestedDesktopHeight;
|
||||
|
||||
std::thread m_worker;
|
||||
std::atomic_bool m_workerRunning;
|
||||
std::atomic_bool m_stopRequested;
|
||||
|
||||
std::mutex m_instanceMutex;
|
||||
rdp_freerdp* m_instance;
|
||||
|
||||
std::mutex m_inputMutex;
|
||||
std::deque<InputEvent> m_inputEvents;
|
||||
|
||||
std::mutex m_displayControlMutex;
|
||||
void* m_displayControlContext;
|
||||
bool m_displayControlReady;
|
||||
bool m_resizeFailureLogged;
|
||||
int m_lastResizeWidth;
|
||||
int m_lastResizeHeight;
|
||||
|
||||
void setState(SessionState state, const QString& message);
|
||||
bool validateProfile(QString& message) const;
|
||||
void startWorker();
|
||||
void stopWorker(bool userInitiated);
|
||||
void workerMain();
|
||||
void enqueueInputEvent(const InputEvent& event);
|
||||
void processInputEvents(rdp_freerdp* instance);
|
||||
bool sendDisplayResize(rdp_freerdp* instance, int width, int height);
|
||||
public:
|
||||
void onChannelConnectedEvent(const char* name, void* channelInterface);
|
||||
void onChannelDisconnectedEvent(const char* name, void* channelInterface);
|
||||
void onDisplayControlCaps(uint32_t maxNumMonitors,
|
||||
uint32_t maxMonitorAreaFactorA,
|
||||
uint32_t maxMonitorAreaFactorB);
|
||||
private:
|
||||
void emitStateAsync(SessionState state, const QString& message);
|
||||
void emitConnectionFailureAsync(const QString& displayMessage, const QString& rawMessage);
|
||||
int sanitizeDesktopWidth(int width) const;
|
||||
int sanitizeDesktopHeight(int height) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user