[refactor] build host information in the wire library

This commit is contained in:
dijunkun
2026-09-21 00:56:16 +08:00
parent 485e347337
commit 1a59a6ac2e
9 changed files with 118 additions and 241 deletions
+20
View File
@@ -10,6 +10,7 @@
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>
#include <remote_cursor_shape.h>
@@ -179,6 +180,25 @@ struct RemoteAction {
// Other RemoteAction variants do not own memory and are left unchanged.
void FreeRemoteAction(RemoteAction& action);
// One display as advertised in host information; bounds are virtual-desktop
// pixel coordinates.
struct HostDisplay {
std::string name;
int left = 0;
int top = 0;
int right = 0;
int bottom = 0;
};
// Builds the host_infomation message advertised on every new connection.
// |host_name| is truncated to the wire field size. The display arrays are
// heap-allocated with the same layout the decoder produces; release the
// result with FreeRemoteAction. An allocation failure yields an empty display
// list rather than a partially filled one.
RemoteAction MakeHostInformation(const std::string& host_name,
const std::vector<HostDisplay>& displays,
bool supports_privacy_screen);
} // namespace crossdesk
#endif
+39
View File
@@ -37,8 +37,47 @@ bool AllocateHostDisplays(HostInfo& info, std::size_t count) {
info.bottom;
}
char* DuplicateString(const std::string& value) {
char* copy = static_cast<char*>(std::malloc(value.size() + 1));
if (copy == nullptr) return nullptr;
std::memcpy(copy, value.data(), value.size());
copy[value.size()] = '\0';
return copy;
}
} // namespace
RemoteAction MakeHostInformation(const std::string& host_name,
const std::vector<HostDisplay>& displays,
bool supports_privacy_screen) {
RemoteAction action{};
action.type = ControlType::host_infomation;
ResetHostInfo(action.i);
const std::size_t count = displays.size();
if (AllocateHostDisplays(action.i, count)) {
action.i.display_num = count;
for (std::size_t index = 0; index < count; ++index) {
const HostDisplay& display = displays[index];
action.i.display_list[index] = DuplicateString(display.name);
action.i.left[index] = display.left;
action.i.top[index] = display.top;
action.i.right[index] = display.right;
action.i.bottom[index] = display.bottom;
}
} else {
FreeRemoteAction(action);
}
action.i.supports_privacy_screen = supports_privacy_screen;
const std::size_t name_size =
std::min(host_name.size(), sizeof(action.i.host_name) - 1);
std::memcpy(action.i.host_name, host_name.data(), name_size);
action.i.host_name[name_size] = '\0';
action.i.host_name_size = name_size;
return action;
}
std::string RemoteAction::to_json() const { return ToJson(*this); }
bool RemoteAction::from_json(const std::string& json_string) {