Files
orbithub/src/rdp_session_backend.h
T

109 lines
3.3 KiB
C++

#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