[refactor] reorganize platform and wire sources

This commit is contained in:
dijunkun
2026-09-01 01:29:30 +08:00
parent fb0ab4f14e
commit 90184f5251
354 changed files with 2837 additions and 2456 deletions
+65
View File
@@ -0,0 +1,65 @@
/*
* @Author: DI JUNKUN
* @Date: 2026-09-01
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _DISPLAY_STREAM_ID_H_
#define _DISPLAY_STREAM_ID_H_
#include <cstddef>
#include <string>
namespace crossdesk {
// MiniRTC stream identifiers are wire-facing logical identifiers. Keep
// them independent from platform display handles and user-visible names, both
// of which may change or contain duplicate/Unicode text.
inline std::string MakeDisplayStreamId(size_t display_index) {
return "Display" + std::to_string(display_index + 1);
}
inline bool IsRegisteredDisplayStreamId(const std::string& stream_id,
size_t display_count) {
if (stream_id.empty()) {
return false;
}
for (size_t index = 0; index < display_count; ++index) {
if (stream_id == MakeDisplayStreamId(index)) {
return true;
}
}
return false;
}
// Resolves a backend-reported identifier to a stream registered with MiniRTC.
// Backends should report MakeDisplayStreamId(index); the fallbacks keep older
// capture plugins and hotplug transitions safe.
inline std::string ResolveDisplayStreamId(
const char* reported_id, size_t display_count, int preferred_index = -1,
const std::string& previous_id = {}) {
const std::string candidate = reported_id ? reported_id : "";
if (IsRegisteredDisplayStreamId(candidate, display_count)) {
return candidate;
}
if (preferred_index >= 0 &&
preferred_index < static_cast<int>(display_count)) {
return MakeDisplayStreamId(static_cast<size_t>(preferred_index));
}
if (IsRegisteredDisplayStreamId(previous_id, display_count)) {
return previous_id;
}
if (display_count == 1) {
return MakeDisplayStreamId(0);
}
return {};
}
} // namespace crossdesk
#endif
+70
View File
@@ -0,0 +1,70 @@
/*
* @Author: DI JUNKUN
* @Date: 2026-09-01
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _FILE_TRANSFER_FORMAT_H_
#define _FILE_TRANSFER_FORMAT_H_
#include <array>
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>
namespace crossdesk {
inline constexpr uint32_t kFileChunkMagic = 0x4A4E544D; // 'JNTM'
inline constexpr uint32_t kFileAckMagic = 0x4A4E5443; // 'JNTC'
#pragma pack(push, 1)
struct FileChunkHeader {
uint32_t magic;
uint32_t file_id;
uint64_t offset;
uint64_t total_size;
uint32_t chunk_size;
uint16_t name_len;
uint8_t flags;
};
struct FileTransferAck {
uint32_t magic;
uint32_t file_id;
uint64_t acked_offset;
uint64_t total_size;
uint32_t flags;
};
#pragma pack(pop)
static_assert(sizeof(FileChunkHeader) == 31,
"FileChunkHeader wire layout must remain stable");
static_assert(sizeof(FileTransferAck) == 28,
"FileTransferAck wire layout must remain stable");
struct FileChunkView {
FileChunkHeader header{};
std::string file_name;
const char* payload = nullptr;
std::size_t payload_size = 0;
};
std::vector<char> EncodeFileChunk(uint32_t file_id, uint64_t offset,
uint64_t total_size, const char* data,
uint32_t data_size,
const std::string* file_name, bool is_first,
bool is_last);
bool DecodeFileChunk(const char* data, std::size_t size,
FileChunkView* output);
std::array<char, sizeof(FileTransferAck)> EncodeFileTransferAck(
const FileTransferAck& ack);
bool DecodeFileTransferAck(const char* data, std::size_t size,
FileTransferAck* output);
} // namespace crossdesk
#endif
+139
View File
@@ -0,0 +1,139 @@
/*
* @Author: DI JUNKUN
* @Date: 2026-09-01
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _REMOTE_ACTION_H_
#define _REMOTE_ACTION_H_
#include <cstddef>
#include <cstdint>
#include <string>
#include <remote_cursor_shape.h>
namespace crossdesk {
enum ControlType {
invalid = -1,
mouse = 0,
keyboard = 1,
audio_capture = 2,
host_infomation = 3,
display_id = 4,
service_status = 5,
service_command = 6,
keyboard_state = 7,
cursor_state = 8,
};
enum MouseFlag {
move = 0,
left_down,
left_up,
right_down,
right_up,
middle_down,
middle_up,
wheel_vertical,
wheel_horizontal,
};
enum KeyFlag { key_down = 0, key_up };
enum ServiceCommandFlag { send_sas = 0, lock_workstation };
struct Mouse {
float x;
float y;
int s;
MouseFlag flag;
};
struct Key {
std::size_t key_value;
uint32_t scan_code;
bool extended;
KeyFlag flag;
};
inline constexpr std::size_t kMaxKeyboardStateKeys = 32;
struct KeyboardStateKey {
std::size_t key_value;
uint32_t scan_code;
bool extended;
};
struct KeyboardState {
uint32_t seq;
std::size_t pressed_count;
KeyboardStateKey pressed_keys[kMaxKeyboardStateKeys];
};
struct CursorState {
uint32_t seq;
bool visible;
RemoteCursorShape shape;
bool position_valid;
float x;
float y;
// Normalized displacement from the input hotspot to the visible cursor
// anchor. This is presentation metadata and must not affect input mapping.
float visual_offset_x;
float visual_offset_y;
int display_id;
// Whether receivers should apply the position fields in this message.
// Shape-only updates set this to false so cursor appearance can remain
// responsive while position feedback to the input source is suppressed.
bool position_update;
};
struct HostInfo {
char host_name[64];
std::size_t host_name_size;
char** display_list;
std::size_t display_num;
int* left;
int* top;
int* right;
int* bottom;
};
struct ServiceStatus {
bool available;
char interactive_stage[32];
};
struct ServiceCommand {
ServiceCommandFlag flag;
};
struct RemoteAction {
ControlType type = ControlType::invalid;
union {
Mouse m;
Key k;
KeyboardState ks;
CursorState cs;
HostInfo i;
bool a;
int d;
ServiceStatus ss;
ServiceCommand c;
};
std::string to_json() const;
bool from_json(const std::string& json_string);
static std::string ToJson(const RemoteAction& action);
static bool FromJson(const std::string& json_string, RemoteAction& output);
};
// Releases the dynamically allocated display arrays held by host information.
// Other RemoteAction variants do not own memory and are left unchanged.
void FreeRemoteAction(RemoteAction& action);
} // namespace crossdesk
#endif
+51
View File
@@ -0,0 +1,51 @@
/*
* @Author: DI JUNKUN
* @Date: 2026-09-01
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _REMOTE_CURSOR_SHAPE_H_
#define _REMOTE_CURSOR_SHAPE_H_
#include <cstdint>
namespace crossdesk {
// Keep these values aligned with Slint's MouseCursor enum. The wire
// intentionally carries a semantic cursor instead of a platform handle so a
// Windows, macOS or Linux host can control a different desktop platform.
enum class RemoteCursorShape : uint8_t {
default_cursor = 0,
none,
help,
pointer,
progress,
wait,
crosshair,
text,
alias,
copy,
move,
no_drop,
not_allowed,
grab,
grabbing,
col_resize,
row_resize,
n_resize,
e_resize,
s_resize,
w_resize,
ne_resize,
nw_resize,
se_resize,
sw_resize,
ew_resize,
ns_resize,
nesw_resize,
nwse_resize,
};
} // namespace crossdesk
#endif
+28
View File
@@ -0,0 +1,28 @@
/*
* @Author: DI JUNKUN
* @Date: 2026-09-01
* Copyright (c) 2026 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _STREAM_NAMES_H_
#define _STREAM_NAMES_H_
#include <cstddef>
namespace crossdesk {
inline constexpr char kAudioStream[] = "control_audio";
inline constexpr char kDataStream[] = "data";
inline constexpr char kMouseStream[] = "mouse";
inline constexpr char kKeyboardStream[] = "keyboard";
inline constexpr char kControlStream[] = "control_data";
inline constexpr char kFileStream[] = "file";
inline constexpr char kFileFeedbackStream[] = "file_feedback";
inline constexpr char kClipboardStream[] = "clipboard";
inline constexpr std::size_t kFileChunkSize = 64 * 1024;
inline constexpr std::size_t kMaxClipboardBytes = 128 * 1024;
} // namespace crossdesk
#endif