Initial project snapshot

This commit is contained in:
2026-04-28 22:29:50 +03:00
commit 8ba0561f4f
365 changed files with 91832 additions and 0 deletions
@@ -0,0 +1,104 @@
#include "rdp_worker/adapter/adapter_event_router.hpp"
#include "rdp_worker/common/json.hpp"
namespace rdp_worker::adapter {
namespace {
AdapterEventDescriptor MakeDescriptor(AdapterChannel channel,
std::string_view type,
bool adapter_origin) {
return AdapterEventDescriptor{
channel,
type,
adapter_origin,
IsReliable(channel),
IsDroppable(channel),
};
}
} // namespace
AdapterEventDescriptor AdapterEventRouter::DescribeRenderNotification(
const runtime::RenderNotification& notification) const {
if (notification.type == "session_frame") {
const auto update_kind = common::GetString(notification.payload, "frame_update_kind").value_or("full");
return MakeDescriptor(
AdapterChannel::kDisplay,
update_kind == "region" ? "display.region_bgra" : "display.baseline_full_bgra",
true);
}
if (notification.type == "session_cursor_updated") {
return MakeDescriptor(AdapterChannel::kCursor, "cursor.update", true);
}
if (notification.type == "session_render_resized") {
return MakeDescriptor(AdapterChannel::kDisplay, "display.resize", true);
}
if (notification.type == "session_render_dirty") {
return MakeDescriptor(AdapterChannel::kDisplay, "display.dirty", true);
}
return MakeDescriptor(AdapterChannel::kTelemetry, notification.type, true);
}
AdapterEventDescriptor AdapterEventRouter::DescribeClipboardNotification(
const runtime::ClipboardNotification&) const {
return MakeDescriptor(AdapterChannel::kClipboard, "clipboard.server_text", true);
}
AdapterEventDescriptor AdapterEventRouter::DescribeClientEnvelope(std::string_view envelope_type,
std::string_view payload_kind,
std::string_view payload_action) const {
if (envelope_type == "input") {
if (payload_kind == "mouse" && payload_action == "move") {
return MakeDescriptor(AdapterChannel::kInput, "input.pointer_move", false);
}
if (payload_kind == "mouse") {
return MakeDescriptor(AdapterChannel::kInput, "input.pointer", false);
}
if (payload_kind == "keyboard") {
return MakeDescriptor(AdapterChannel::kInput, "input.keyboard", false);
}
if (payload_kind == "focus") {
return MakeDescriptor(AdapterChannel::kInput, "input.focus", false);
}
return MakeDescriptor(AdapterChannel::kInput, "input.unknown", false);
}
if (envelope_type == "clipboard") {
return MakeDescriptor(AdapterChannel::kClipboard, "clipboard.client_text", false);
}
if (envelope_type == "file_upload") {
return MakeDescriptor(AdapterChannel::kFileTransfer, "file_upload.client_to_server", false);
}
if (envelope_type == "control") {
return MakeDescriptor(AdapterChannel::kControl, "control.command", false);
}
return MakeDescriptor(AdapterChannel::kTelemetry, envelope_type, false);
}
std::string AdapterEventDescriptorLogLine(const AdapterEventDescriptor& descriptor) {
std::string line;
line.reserve(160);
line += "adapter_event channel=";
line += ChannelName(descriptor.channel);
line += " type=";
line += descriptor.normalized_type;
line += " origin=";
line += descriptor.adapter_origin ? "adapter" : "client";
line += " reliable=";
line += descriptor.reliable ? "true" : "false";
line += " droppable=";
line += descriptor.droppable ? "true" : "false";
return line;
}
} // namespace rdp_worker::adapter
@@ -0,0 +1,134 @@
#include "rdp_worker/adapter/rdp_adapter_runtime.hpp"
#include <utility>
namespace rdp_worker::adapter {
RdpAdapterRuntime::RdpAdapterRuntime(std::shared_ptr<common::Logger> logger)
: logger_(std::move(logger)),
freerdp_(logger_) {}
bool RdpAdapterRuntime::Start(const runtime::ConnectionSpec& spec) {
logger_->Info("rdp_adapter.runtime_start substrate=freerdp resource_id=" + spec.resource_id +
" host=" + spec.host +
" render_quality_profile=" + spec.render_quality_profile);
lifecycle_logged_ = true;
return freerdp_.Start(spec);
}
void RdpAdapterRuntime::Disconnect(bool terminate) {
logger_->Info("rdp_adapter.runtime_disconnect terminate=" + (terminate ? std::string("true") : std::string("false")));
freerdp_.Disconnect(terminate);
}
bool RdpAdapterRuntime::IsConnected() const {
return freerdp_.IsConnected();
}
bool RdpAdapterRuntime::PumpEvents(std::chrono::milliseconds timeout) {
if (!lifecycle_logged_) {
logger_->Info("rdp_adapter.event_pump_start substrate=freerdp");
lifecycle_logged_ = true;
}
return freerdp_.PumpEvents(timeout);
}
int RdpAdapterRuntime::DesktopWidth() const {
return freerdp_.DesktopWidth();
}
int RdpAdapterRuntime::DesktopHeight() const {
return freerdp_.DesktopHeight();
}
bool RdpAdapterRuntime::SendFocusEvent(bool focused) {
TraceClientEnvelope("input", "focus", focused ? "focus_in" : "focus_out");
return freerdp_.SendFocusEvent(focused);
}
bool RdpAdapterRuntime::SendKeyboardInput(uint16_t scan_code, bool key_down, bool extended) {
TraceClientEnvelope("input", "keyboard", key_down ? "key_down" : "key_up");
return freerdp_.SendKeyboardInput(scan_code, key_down, extended);
}
bool RdpAdapterRuntime::SendMouseMove(double normalized_x, double normalized_y) {
TraceClientEnvelope("input", "mouse", "move");
return freerdp_.SendMouseMove(normalized_x, normalized_y);
}
bool RdpAdapterRuntime::SendMouseButton(const std::string& button,
bool pressed,
double normalized_x,
double normalized_y) {
TraceClientEnvelope("input", "mouse", pressed ? "button_down" : "button_up");
return freerdp_.SendMouseButton(button, pressed, normalized_x, normalized_y);
}
bool RdpAdapterRuntime::SendMouseWheel(int wheel_delta, bool horizontal, double normalized_x, double normalized_y) {
TraceClientEnvelope("input", "mouse", "wheel");
return freerdp_.SendMouseWheel(wheel_delta, horizontal, normalized_x, normalized_y);
}
bool RdpAdapterRuntime::SetClipboardText(const std::string& text) {
TraceClientEnvelope("clipboard", "text", "client_to_server");
return freerdp_.SetClipboardText(text);
}
void RdpAdapterRuntime::MarkInputAppliedForGraphicsTrace(const std::string& correlation_id) {
freerdp_.MarkInputAppliedForGraphicsTrace(correlation_id);
}
std::optional<runtime::RenderNotification> RdpAdapterRuntime::CaptureFullFrameNotification(
const std::string& state,
const std::string& capture_source) {
auto notification = freerdp_.CaptureFullFrameNotification(state, capture_source);
if (notification.has_value()) {
TraceAdapterEvent(event_router_.DescribeRenderNotification(*notification));
}
return notification;
}
std::optional<runtime::RenderNotification> RdpAdapterRuntime::PopRenderNotification() {
auto notification = freerdp_.PopRenderNotification();
if (notification.has_value()) {
TraceAdapterEvent(event_router_.DescribeRenderNotification(*notification));
}
return notification;
}
std::optional<runtime::ClipboardNotification> RdpAdapterRuntime::PopClipboardNotification() {
auto notification = freerdp_.PopClipboardNotification();
if (notification.has_value()) {
TraceAdapterEvent(event_router_.DescribeClipboardNotification(*notification));
}
return notification;
}
const std::string& RdpAdapterRuntime::RenderQualityProfile() const {
return freerdp_.RenderQualityProfile();
}
const AdapterEventRouter& RdpAdapterRuntime::EventRouter() const {
return event_router_;
}
void RdpAdapterRuntime::TraceClientEnvelope(std::string_view envelope_type,
std::string_view payload_kind,
std::string_view payload_action) {
const auto descriptor = event_router_.DescribeClientEnvelope(envelope_type, payload_kind, payload_action);
if (descriptor.channel == AdapterChannel::kInput && descriptor.normalized_type == "input.pointer_move") {
return;
}
TraceAdapterEvent(descriptor);
}
void RdpAdapterRuntime::TraceAdapterEvent(const AdapterEventDescriptor& descriptor) {
if (descriptor.channel == AdapterChannel::kDisplay &&
descriptor.normalized_type != "display.resize" &&
descriptor.normalized_type != "display.baseline_full_bgra") {
return;
}
logger_->Info(AdapterEventDescriptorLogLine(descriptor));
}
} // namespace rdp_worker::adapter
@@ -0,0 +1,97 @@
#include "rdp_worker/adapter/service_adapter_protocol.hpp"
namespace rdp_worker::adapter {
std::optional<ChannelSpec> FindChannelSpec(std::string_view name) {
for (const auto& spec : AllChannelSpecs()) {
if (spec.name == name) {
return spec;
}
}
return std::nullopt;
}
std::string_view ChannelName(AdapterChannel channel) {
for (const auto& spec : AllChannelSpecs()) {
if (spec.channel == channel) {
return spec.name;
}
}
return "unknown";
}
std::string_view DirectionName(ChannelDirection direction) {
switch (direction) {
case ChannelDirection::kClientToAdapter:
return "client_to_adapter";
case ChannelDirection::kAdapterToClient:
return "adapter_to_client";
case ChannelDirection::kBidirectional:
return "bidirectional";
}
return "unknown";
}
std::string_view ReliabilityName(ChannelReliability reliability) {
switch (reliability) {
case ChannelReliability::kReliableOrdered:
return "reliable_ordered";
case ChannelReliability::kReliableChunked:
return "reliable_chunked";
case ChannelReliability::kDroppableLatest:
return "droppable_latest";
case ChannelReliability::kAdaptiveDroppable:
return "adaptive_droppable";
case ChannelReliability::kSampledDroppable:
return "sampled_droppable";
}
return "unknown";
}
int PriorityValue(ChannelPriority priority) {
return static_cast<int>(priority);
}
bool IsDroppable(AdapterChannel channel) {
for (const auto& spec : AllChannelSpecs()) {
if (spec.channel == channel) {
return spec.stale_updates_droppable;
}
}
return false;
}
bool IsReliable(AdapterChannel channel) {
for (const auto& spec : AllChannelSpecs()) {
if (spec.channel == channel) {
return spec.reliability == ChannelReliability::kReliableOrdered ||
spec.reliability == ChannelReliability::kReliableChunked;
}
}
return false;
}
bool ValidateAdapterChannelInvariants() {
const auto input = FindChannelSpec("input");
if (!input.has_value() || input->priority != ChannelPriority::kCritical || input->may_block_input) {
return false;
}
for (const auto& spec : AllChannelSpecs()) {
if (spec.channel != AdapterChannel::kInput &&
PriorityValue(spec.priority) <= PriorityValue(ChannelPriority::kCritical)) {
return false;
}
if (spec.may_block_input) {
return false;
}
if ((spec.channel == AdapterChannel::kDisplay || spec.channel == AdapterChannel::kCursor) &&
!spec.stale_updates_droppable) {
return false;
}
}
return true;
}
} // namespace rdp_worker::adapter