mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-12-23 08:29:09 +08:00
Compare commits
3 Commits
libdatacha
...
3843104f8c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3843104f8c | ||
|
|
b953dcac88 | ||
|
|
73bbf642fa |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -144,7 +144,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- arch: x64
|
- arch: x64
|
||||||
runner: macos-13
|
runner: macos-15-intel
|
||||||
cache-key: intel
|
cache-key: intel
|
||||||
out-dir: ./build/macosx/x86_64/release/crossdesk
|
out-dir: ./build/macosx/x86_64/release/crossdesk
|
||||||
package_script: ./scripts/macosx/pkg_x64.sh
|
package_script: ./scripts/macosx/pkg_x64.sh
|
||||||
|
|||||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
|||||||
[submodule "submodules/minirtc"]
|
[submodule "thirdparty/minirtc"]
|
||||||
path = submodules/minirtc
|
path = thirdparty/minirtc
|
||||||
url = https://github.com/kunkundi/minirtc.git
|
url = https://github.com/kunkundi/minirtc.git
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# CrossDesk
|
# CrossDesk
|
||||||
|
|
||||||
[]()
|
[]()
|
||||||
[](https://www.gnu.org/licenses/lgpl-3.0)
|
[](https://www.gnu.org/licenses/lgpl-3.0)
|
||||||
[](https://github.com/kunkundi/crossdesk/commits/self-hosted-server)
|
[](https://github.com/kunkundi/crossdesk/commits/self-hosted-server)
|
||||||
[](https://github.com/kunkundi/crossdesk/actions)
|
[](https://github.com/kunkundi/crossdesk/actions)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# CrossDesk
|
# CrossDesk
|
||||||
|
|
||||||
[]()
|
[]()
|
||||||
[](https://www.gnu.org/licenses/lgpl-3.0)
|
[](https://www.gnu.org/licenses/lgpl-3.0)
|
||||||
[](https://github.com/kunkundi/crossdesk/commits/self-hosted-server)
|
[](https://github.com/kunkundi/crossdesk/commits/self-hosted-server)
|
||||||
[](https://github.com/kunkundi/crossdesk/actions)
|
[](https://github.com/kunkundi/crossdesk/actions)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef CROSSDESK_DEBUG
|
#ifdef DESK_PORT_DEBUG
|
||||||
#pragma comment(linker, "/subsystem:\"console\"")
|
#pragma comment(linker, "/subsystem:\"console\"")
|
||||||
#else
|
#else
|
||||||
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
|
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
|
||||||
|
|||||||
@@ -181,9 +181,8 @@ int ConfigCenter::SetServerPort(int signal_server_port) {
|
|||||||
|
|
||||||
int ConfigCenter::SetCoturnServerPort(int coturn_server_port) {
|
int ConfigCenter::SetCoturnServerPort(int coturn_server_port) {
|
||||||
coturn_server_port_ = coturn_server_port;
|
coturn_server_port_ = coturn_server_port;
|
||||||
ini_.SetLongValue(section_, "coturn_server_port",
|
SI_Error rc = ini_.SetLongValue(section_, "coturn_server_port",
|
||||||
static_cast<long>(coturn_server_port_));
|
static_cast<long>(coturn_server_port_));
|
||||||
SI_Error rc = ini_.SaveFile(config_path_.c_str());
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -202,7 +201,6 @@ int ConfigCenter::SetCertFilePath(const std::string& cert_file_path) {
|
|||||||
|
|
||||||
int ConfigCenter::SetSelfHosted(bool enable_self_hosted) {
|
int ConfigCenter::SetSelfHosted(bool enable_self_hosted) {
|
||||||
enable_self_hosted_ = enable_self_hosted;
|
enable_self_hosted_ = enable_self_hosted;
|
||||||
ini_.SetBoolValue(section_, "enable_self_hosted", enable_self_hosted_);
|
|
||||||
SI_Error rc = ini_.SaveFile(config_path_.c_str());
|
SI_Error rc = ini_.SaveFile(config_path_.c_str());
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -212,12 +210,6 @@ int ConfigCenter::SetSelfHosted(bool enable_self_hosted) {
|
|||||||
|
|
||||||
int ConfigCenter::SetMinimizeToTray(bool enable_minimize_to_tray) {
|
int ConfigCenter::SetMinimizeToTray(bool enable_minimize_to_tray) {
|
||||||
enable_minimize_to_tray_ = enable_minimize_to_tray;
|
enable_minimize_to_tray_ = enable_minimize_to_tray;
|
||||||
ini_.SetBoolValue(section_, "enable_minimize_to_tray",
|
|
||||||
enable_minimize_to_tray_);
|
|
||||||
SI_Error rc = ini_.SaveFile(config_path_.c_str());
|
|
||||||
if (rc < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class ConfigCenter {
|
|||||||
|
|
||||||
LANGUAGE language_ = LANGUAGE::CHINESE;
|
LANGUAGE language_ = LANGUAGE::CHINESE;
|
||||||
VIDEO_QUALITY video_quality_ = VIDEO_QUALITY::MEDIUM;
|
VIDEO_QUALITY video_quality_ = VIDEO_QUALITY::MEDIUM;
|
||||||
VIDEO_FRAME_RATE video_frame_rate_ = VIDEO_FRAME_RATE::FPS_60;
|
VIDEO_FRAME_RATE video_frame_rate_ = VIDEO_FRAME_RATE::FPS_30;
|
||||||
VIDEO_ENCODE_FORMAT video_encode_format_ = VIDEO_ENCODE_FORMAT::H264;
|
VIDEO_ENCODE_FORMAT video_encode_format_ = VIDEO_ENCODE_FORMAT::H264;
|
||||||
bool hardware_video_codec_ = false;
|
bool hardware_video_codec_ = false;
|
||||||
bool enable_turn_ = false;
|
bool enable_turn_ = false;
|
||||||
|
|||||||
@@ -9,11 +9,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "display_info.h"
|
#include "display_info.h"
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
namespace crossdesk {
|
namespace crossdesk {
|
||||||
|
|
||||||
@@ -59,7 +55,7 @@ typedef struct {
|
|||||||
int* bottom;
|
int* bottom;
|
||||||
} HostInfo;
|
} HostInfo;
|
||||||
|
|
||||||
struct RemoteAction {
|
typedef struct {
|
||||||
ControlType type;
|
ControlType type;
|
||||||
union {
|
union {
|
||||||
Mouse m;
|
Mouse m;
|
||||||
@@ -68,111 +64,7 @@ struct RemoteAction {
|
|||||||
bool a;
|
bool a;
|
||||||
int d;
|
int d;
|
||||||
};
|
};
|
||||||
|
} RemoteAction;
|
||||||
// parse
|
|
||||||
std::string to_json() const { return ToJson(*this); }
|
|
||||||
|
|
||||||
bool from_json(const std::string& json_str) {
|
|
||||||
RemoteAction temp;
|
|
||||||
if (!FromJson(json_str, temp)) return false;
|
|
||||||
*this = temp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string ToJson(const RemoteAction& a) {
|
|
||||||
json j;
|
|
||||||
j["type"] = a.type;
|
|
||||||
switch (a.type) {
|
|
||||||
case ControlType::mouse:
|
|
||||||
j["mouse"] = {
|
|
||||||
{"x", a.m.x}, {"y", a.m.y}, {"s", a.m.s}, {"flag", a.m.flag}};
|
|
||||||
break;
|
|
||||||
case ControlType::keyboard:
|
|
||||||
j["keyboard"] = {{"key_value", a.k.key_value}, {"flag", a.k.flag}};
|
|
||||||
break;
|
|
||||||
case ControlType::audio_capture:
|
|
||||||
j["audio_capture"] = a.a;
|
|
||||||
break;
|
|
||||||
case ControlType::display_id:
|
|
||||||
j["display_id"] = a.d;
|
|
||||||
break;
|
|
||||||
case ControlType::host_infomation: {
|
|
||||||
json displays = json::array();
|
|
||||||
for (size_t idx = 0; idx < a.i.display_num; idx++) {
|
|
||||||
displays.push_back(
|
|
||||||
{{"name", a.i.display_list ? a.i.display_list[idx] : ""},
|
|
||||||
{"left", a.i.left ? a.i.left[idx] : 0},
|
|
||||||
{"top", a.i.top ? a.i.top[idx] : 0},
|
|
||||||
{"right", a.i.right ? a.i.right[idx] : 0},
|
|
||||||
{"bottom", a.i.bottom ? a.i.bottom[idx] : 0}});
|
|
||||||
}
|
|
||||||
|
|
||||||
j["host_info"] = {{"host_name", a.i.host_name},
|
|
||||||
{"display_num", a.i.display_num},
|
|
||||||
{"displays", displays}};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return j.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool FromJson(const std::string& json_str, RemoteAction& out) {
|
|
||||||
try {
|
|
||||||
json j = json::parse(json_str);
|
|
||||||
out.type = (ControlType)j.at("type").get<int>();
|
|
||||||
switch (out.type) {
|
|
||||||
case ControlType::mouse:
|
|
||||||
out.m.x = j.at("mouse").at("x").get<float>();
|
|
||||||
out.m.y = j.at("mouse").at("y").get<float>();
|
|
||||||
out.m.s = j.at("mouse").at("s").get<int>();
|
|
||||||
out.m.flag = (MouseFlag)j.at("mouse").at("flag").get<int>();
|
|
||||||
break;
|
|
||||||
case ControlType::keyboard:
|
|
||||||
out.k.key_value = j.at("keyboard").at("key_value").get<size_t>();
|
|
||||||
out.k.flag = (KeyFlag)j.at("keyboard").at("flag").get<int>();
|
|
||||||
break;
|
|
||||||
case ControlType::audio_capture:
|
|
||||||
out.a = j.at("audio_capture").get<bool>();
|
|
||||||
break;
|
|
||||||
case ControlType::display_id:
|
|
||||||
out.d = j.at("display_id").get<int>();
|
|
||||||
break;
|
|
||||||
case ControlType::host_infomation: {
|
|
||||||
std::string host_name =
|
|
||||||
j.at("host_info").at("host_name").get<std::string>();
|
|
||||||
strncpy(out.i.host_name, host_name.c_str(), sizeof(out.i.host_name));
|
|
||||||
out.i.host_name[sizeof(out.i.host_name) - 1] = '\0';
|
|
||||||
out.i.host_name_size = host_name.size();
|
|
||||||
|
|
||||||
out.i.display_num = j.at("host_info").at("display_num").get<size_t>();
|
|
||||||
auto displays = j.at("host_info").at("displays");
|
|
||||||
|
|
||||||
out.i.display_list =
|
|
||||||
(char**)malloc(out.i.display_num * sizeof(char*));
|
|
||||||
out.i.left = (int*)malloc(out.i.display_num * sizeof(int));
|
|
||||||
out.i.top = (int*)malloc(out.i.display_num * sizeof(int));
|
|
||||||
out.i.right = (int*)malloc(out.i.display_num * sizeof(int));
|
|
||||||
out.i.bottom = (int*)malloc(out.i.display_num * sizeof(int));
|
|
||||||
|
|
||||||
for (size_t idx = 0; idx < out.i.display_num; idx++) {
|
|
||||||
std::string name = displays[idx].at("name").get<std::string>();
|
|
||||||
out.i.display_list[idx] = (char*)malloc(name.size() + 1);
|
|
||||||
strcpy(out.i.display_list[idx], name.c_str());
|
|
||||||
out.i.left[idx] = displays[idx].at("left").get<int>();
|
|
||||||
out.i.top[idx] = displays[idx].at("top").get<int>();
|
|
||||||
out.i.right[idx] = displays[idx].at("right").get<int>();
|
|
||||||
out.i.bottom[idx] = displays[idx].at("bottom").get<int>();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
printf("Failed to parse RemoteAction JSON: %s\n", e.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// int key_code, bool is_down
|
// int key_code, bool is_down
|
||||||
typedef void (*OnKeyAction)(int, bool, void*);
|
typedef void (*OnKeyAction)(int, bool, void*);
|
||||||
|
|||||||
@@ -145,10 +145,6 @@ int Render::ConnectTo(const std::string& remote_id, const char* password,
|
|||||||
memcpy(&props->params_, ¶ms_, sizeof(Params));
|
memcpy(&props->params_, ¶ms_, sizeof(Params));
|
||||||
props->params_.user_id = props->local_id_.c_str();
|
props->params_.user_id = props->local_id_.c_str();
|
||||||
props->peer_ = CreatePeer(&props->params_);
|
props->peer_ = CreatePeer(&props->params_);
|
||||||
|
|
||||||
for (auto& display_info : display_info_list_) {
|
|
||||||
AddVideoStream(peer_, display_info.name.c_str());
|
|
||||||
}
|
|
||||||
AddAudioStream(props->peer_, props->audio_label_.c_str());
|
AddAudioStream(props->peer_, props->audio_label_.c_str());
|
||||||
AddDataStream(props->peer_, props->data_label_.c_str());
|
AddDataStream(props->peer_, props->data_label_.c_str());
|
||||||
|
|
||||||
|
|||||||
@@ -258,7 +258,6 @@ int Render::LoadSettingsFromCacheFile() {
|
|||||||
enable_hardware_video_codec_ = config_center_->IsHardwareVideoCodec();
|
enable_hardware_video_codec_ = config_center_->IsHardwareVideoCodec();
|
||||||
enable_turn_ = config_center_->IsEnableTurn();
|
enable_turn_ = config_center_->IsEnableTurn();
|
||||||
enable_srtp_ = config_center_->IsEnableSrtp();
|
enable_srtp_ = config_center_->IsEnableSrtp();
|
||||||
enable_self_hosted_ = config_center_->IsSelfHosted();
|
|
||||||
|
|
||||||
language_button_value_last_ = language_button_value_;
|
language_button_value_last_ = language_button_value_;
|
||||||
video_quality_button_value_last_ = video_quality_button_value_;
|
video_quality_button_value_last_ = video_quality_button_value_;
|
||||||
@@ -266,7 +265,6 @@ int Render::LoadSettingsFromCacheFile() {
|
|||||||
enable_hardware_video_codec_last_ = enable_hardware_video_codec_;
|
enable_hardware_video_codec_last_ = enable_hardware_video_codec_;
|
||||||
enable_turn_last_ = enable_turn_;
|
enable_turn_last_ = enable_turn_;
|
||||||
enable_srtp_last_ = enable_srtp_;
|
enable_srtp_last_ = enable_srtp_;
|
||||||
enable_self_hosted_last_ = enable_self_hosted_;
|
|
||||||
|
|
||||||
LOG_INFO("Load settings from cache file");
|
LOG_INFO("Load settings from cache file");
|
||||||
|
|
||||||
@@ -495,8 +493,6 @@ int Render::CreateConnectionPeer() {
|
|||||||
: false;
|
: false;
|
||||||
params_.enable_turn = config_center_->IsEnableTurn();
|
params_.enable_turn = config_center_->IsEnableTurn();
|
||||||
params_.enable_srtp = config_center_->IsEnableSrtp();
|
params_.enable_srtp = config_center_->IsEnableSrtp();
|
||||||
params_.video_quality =
|
|
||||||
static_cast<VideoQuality>(config_center_->GetVideoQuality());
|
|
||||||
params_.on_receive_video_buffer = nullptr;
|
params_.on_receive_video_buffer = nullptr;
|
||||||
params_.on_receive_audio_buffer = OnReceiveAudioBufferCb;
|
params_.on_receive_audio_buffer = OnReceiveAudioBufferCb;
|
||||||
params_.on_receive_data_buffer = OnReceiveDataBufferCb;
|
params_.on_receive_data_buffer = OnReceiveDataBufferCb;
|
||||||
@@ -568,14 +564,6 @@ void Render::UpdateInteractions() {
|
|||||||
screen_capturer_is_started_ = false;
|
screen_capturer_is_started_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start_speaker_capturer_ && !speaker_capturer_is_started_) {
|
|
||||||
StartSpeakerCapturer();
|
|
||||||
speaker_capturer_is_started_ = true;
|
|
||||||
} else if (!start_speaker_capturer_ && speaker_capturer_is_started_) {
|
|
||||||
StopSpeakerCapturer();
|
|
||||||
speaker_capturer_is_started_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start_mouse_controller_ && !mouse_controller_is_started_) {
|
if (start_mouse_controller_ && !mouse_controller_is_started_) {
|
||||||
StartMouseController();
|
StartMouseController();
|
||||||
mouse_controller_is_started_ = true;
|
mouse_controller_is_started_ = true;
|
||||||
@@ -1065,9 +1053,9 @@ void Render::MainLoop() {
|
|||||||
remote_action.i.host_name[host_name.size()] = '\0';
|
remote_action.i.host_name[host_name.size()] = '\0';
|
||||||
remote_action.i.host_name_size = host_name.size();
|
remote_action.i.host_name_size = host_name.size();
|
||||||
|
|
||||||
std::string msg = remote_action.to_json();
|
std::vector<char> serialized = SerializeRemoteAction(remote_action);
|
||||||
int ret =
|
int ret = SendDataFrame(peer_, serialized.data(), serialized.size(),
|
||||||
SendDataFrame(peer_, msg.data(), msg.size(), data_label_.c_str());
|
data_label_.c_str());
|
||||||
FreeRemoteAction(remote_action);
|
FreeRemoteAction(remote_action);
|
||||||
if (0 == ret) {
|
if (0 == ret) {
|
||||||
need_to_send_host_info_ = false;
|
need_to_send_host_info_ = false;
|
||||||
@@ -1193,10 +1181,6 @@ void Render::CleanupPeers() {
|
|||||||
LOG_INFO("[{}] Leave connection [{}]", client_id_, client_id_);
|
LOG_INFO("[{}] Leave connection [{}]", client_id_, client_id_);
|
||||||
LeaveConnection(peer_, client_id_);
|
LeaveConnection(peer_, client_id_);
|
||||||
is_client_mode_ = false;
|
is_client_mode_ = false;
|
||||||
StopScreenCapturer();
|
|
||||||
StopSpeakerCapturer();
|
|
||||||
StopMouseController();
|
|
||||||
StopKeyboardCapturer();
|
|
||||||
LOG_INFO("Destroy peer [{}]", client_id_);
|
LOG_INFO("Destroy peer [{}]", client_id_);
|
||||||
DestroyPeer(&peer_);
|
DestroyPeer(&peer_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,10 @@ class Render {
|
|||||||
bool connection_established_ = false;
|
bool connection_established_ = false;
|
||||||
bool rejoin_ = false;
|
bool rejoin_ = false;
|
||||||
bool net_traffic_stats_button_pressed_ = false;
|
bool net_traffic_stats_button_pressed_ = false;
|
||||||
bool mouse_control_button_pressed_ = true;
|
bool mouse_control_button_pressed_ = false;
|
||||||
bool mouse_controller_is_started_ = false;
|
bool mouse_controller_is_started_ = false;
|
||||||
bool audio_capture_button_pressed_ = true;
|
bool audio_capture_button_pressed_ = false;
|
||||||
bool control_mouse_ = true;
|
bool control_mouse_ = false;
|
||||||
bool streaming_ = false;
|
bool streaming_ = false;
|
||||||
bool is_control_bar_in_left_ = true;
|
bool is_control_bar_in_left_ = true;
|
||||||
bool control_bar_hovered_ = false;
|
bool control_bar_hovered_ = false;
|
||||||
@@ -311,9 +311,7 @@ class Render {
|
|||||||
bool mouse_controller_is_started_ = false;
|
bool mouse_controller_is_started_ = false;
|
||||||
bool start_screen_capturer_ = false;
|
bool start_screen_capturer_ = false;
|
||||||
bool screen_capturer_is_started_ = false;
|
bool screen_capturer_is_started_ = false;
|
||||||
bool start_speaker_capturer_ = false;
|
bool start_keyboard_capturer_ = false;
|
||||||
bool speaker_capturer_is_started_ = false;
|
|
||||||
bool start_keyboard_capturer_ = true;
|
|
||||||
bool keyboard_capturer_is_started_ = false;
|
bool keyboard_capturer_is_started_ = false;
|
||||||
bool foucs_on_main_window_ = false;
|
bool foucs_on_main_window_ = false;
|
||||||
bool foucs_on_stream_window_ = false;
|
bool foucs_on_stream_window_ = false;
|
||||||
@@ -438,7 +436,7 @@ class Render {
|
|||||||
char password_saved_[7] = "";
|
char password_saved_[7] = "";
|
||||||
int language_button_value_ = 0;
|
int language_button_value_ = 0;
|
||||||
int video_quality_button_value_ = 0;
|
int video_quality_button_value_ = 0;
|
||||||
int video_frame_rate_button_value_ = 1;
|
int video_frame_rate_button_value_ = 0;
|
||||||
int video_encode_format_button_value_ = 0;
|
int video_encode_format_button_value_ = 0;
|
||||||
bool enable_hardware_video_codec_ = false;
|
bool enable_hardware_video_codec_ = false;
|
||||||
bool enable_turn_ = false;
|
bool enable_turn_ = false;
|
||||||
@@ -447,15 +445,13 @@ class Render {
|
|||||||
char signal_server_port_[6] = "9099";
|
char signal_server_port_[6] = "9099";
|
||||||
char coturn_server_port_[6] = "3478";
|
char coturn_server_port_[6] = "3478";
|
||||||
char cert_file_path_[256] = "";
|
char cert_file_path_[256] = "";
|
||||||
bool enable_self_hosted_ = false;
|
bool enable_self_hosted_server_ = false;
|
||||||
int language_button_value_last_ = 0;
|
int language_button_value_last_ = 0;
|
||||||
int video_quality_button_value_last_ = 0;
|
int video_quality_button_value_last_ = 0;
|
||||||
int video_frame_rate_button_value_last_ = 0;
|
|
||||||
int video_encode_format_button_value_last_ = 0;
|
int video_encode_format_button_value_last_ = 0;
|
||||||
bool enable_hardware_video_codec_last_ = false;
|
bool enable_hardware_video_codec_last_ = false;
|
||||||
bool enable_turn_last_ = false;
|
bool enable_turn_last_ = false;
|
||||||
bool enable_srtp_last_ = false;
|
bool enable_srtp_last_ = false;
|
||||||
bool enable_self_hosted_last_ = false;
|
|
||||||
bool enable_minimize_to_tray_ = false;
|
bool enable_minimize_to_tray_ = false;
|
||||||
bool enable_minimize_to_tray_last_ = false;
|
bool enable_minimize_to_tray_last_ = false;
|
||||||
char signal_server_ip_self_[256] = "";
|
char signal_server_ip_self_[256] = "";
|
||||||
@@ -473,9 +469,6 @@ class Render {
|
|||||||
client_properties_;
|
client_properties_;
|
||||||
void CloseTab(decltype(client_properties_)::iterator& it);
|
void CloseTab(decltype(client_properties_)::iterator& it);
|
||||||
/* ------ stream window property end ------ */
|
/* ------ stream window property end ------ */
|
||||||
|
|
||||||
/* ------ server mode ------ */
|
|
||||||
std::unordered_map<std::string, ConnectionStatus> connection_status_;
|
|
||||||
};
|
};
|
||||||
} // namespace crossdesk
|
} // namespace crossdesk
|
||||||
#endif
|
#endif
|
||||||
@@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
#define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2
|
#define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2
|
||||||
|
|
||||||
|
#ifdef DESK_PORT_DEBUG
|
||||||
|
#else
|
||||||
|
#define MOUSE_CONTROL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace crossdesk {
|
namespace crossdesk {
|
||||||
|
|
||||||
int Render::SendKeyCommand(int key_code, bool is_down) {
|
int Render::SendKeyCommand(int key_code, bool is_down) {
|
||||||
@@ -23,9 +28,8 @@ int Render::SendKeyCommand(int key_code, bool is_down) {
|
|||||||
client_properties_.end()) {
|
client_properties_.end()) {
|
||||||
auto props = client_properties_[controlled_remote_id_];
|
auto props = client_properties_[controlled_remote_id_];
|
||||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
if (props->connection_status_ == ConnectionStatus::Connected) {
|
||||||
std::string msg = remote_action.to_json();
|
SendDataFrame(props->peer_, (const char*)&remote_action,
|
||||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
sizeof(remote_action), props->data_label_.c_str());
|
||||||
props->data_label_.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,10 +94,8 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
|||||||
if (props->control_bar_hovered_ || props->display_selectable_hovered_) {
|
if (props->control_bar_hovered_ || props->display_selectable_hovered_) {
|
||||||
remote_action.m.flag = MouseFlag::move;
|
remote_action.m.flag = MouseFlag::move;
|
||||||
}
|
}
|
||||||
|
SendDataFrame(props->peer_, (const char*)&remote_action,
|
||||||
std::string msg = remote_action.to_json();
|
sizeof(remote_action), props->data_label_.c_str());
|
||||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
|
||||||
props->data_label_.c_str());
|
|
||||||
} else if (SDL_EVENT_MOUSE_WHEEL == event.type &&
|
} else if (SDL_EVENT_MOUSE_WHEEL == event.type &&
|
||||||
last_mouse_event.button.x >= props->stream_render_rect_.x &&
|
last_mouse_event.button.x >= props->stream_render_rect_.x &&
|
||||||
last_mouse_event.button.x <= props->stream_render_rect_.x +
|
last_mouse_event.button.x <= props->stream_render_rect_.x +
|
||||||
@@ -125,9 +127,8 @@ int Render::ProcessMouseEvent(const SDL_Event& event) {
|
|||||||
(float)(event.button.y - props->stream_render_rect_.y) /
|
(float)(event.button.y - props->stream_render_rect_.y) /
|
||||||
render_height;
|
render_height;
|
||||||
|
|
||||||
std::string msg = remote_action.to_json();
|
SendDataFrame(props->peer_, (const char*)&remote_action,
|
||||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
sizeof(remote_action), props->data_label_.c_str());
|
||||||
props->data_label_.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,8 +226,6 @@ void Render::OnReceiveVideoBufferCb(const XVideoFrame* video_frame,
|
|||||||
props->video_height_ = video_frame->height;
|
props->video_height_ = video_frame->height;
|
||||||
props->video_size_ = video_frame->size;
|
props->video_size_ = video_frame->size;
|
||||||
|
|
||||||
LOG_ERROR("receive: {}x{}", props->video_width_, props->video_height_);
|
|
||||||
|
|
||||||
if (need_to_update_render_rect) {
|
if (need_to_update_render_rect) {
|
||||||
render->UpdateRenderRect();
|
render->UpdateRenderRect();
|
||||||
}
|
}
|
||||||
@@ -280,56 +279,66 @@ void Render::OnReceiveDataBufferCb(const char* data, size_t size,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string json_str(data, size);
|
|
||||||
RemoteAction remote_action;
|
RemoteAction remote_action;
|
||||||
|
memcpy(&remote_action, data, size);
|
||||||
try {
|
|
||||||
remote_action.from_json(json_str);
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
LOG_ERROR("Failed to parse RemoteAction JSON: {}", e.what());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string remote_id(user_id, user_id_size);
|
std::string remote_id(user_id, user_id_size);
|
||||||
if (render->client_properties_.find(remote_id) !=
|
if (render->client_properties_.find(remote_id) !=
|
||||||
render->client_properties_.end()) {
|
render->client_properties_.end()) {
|
||||||
// local
|
// local
|
||||||
auto props = render->client_properties_.find(remote_id)->second;
|
auto props = render->client_properties_.find(remote_id)->second;
|
||||||
if (remote_action.type == ControlType::host_infomation &&
|
RemoteAction host_info;
|
||||||
|
if (DeserializeRemoteAction(data, size, host_info)) {
|
||||||
|
if (ControlType::host_infomation == host_info.type &&
|
||||||
props->remote_host_name_.empty()) {
|
props->remote_host_name_.empty()) {
|
||||||
|
props->remote_host_name_ =
|
||||||
|
std::string(host_info.i.host_name, host_info.i.host_name_size);
|
||||||
|
LOG_INFO("Remote hostname: [{}]", props->remote_host_name_);
|
||||||
|
|
||||||
|
for (int i = 0; i < host_info.i.display_num; i++) {
|
||||||
|
props->display_info_list_.push_back(DisplayInfo(
|
||||||
|
std::string(host_info.i.display_list[i]), host_info.i.left[i],
|
||||||
|
host_info.i.top[i], host_info.i.right[i], host_info.i.bottom[i]));
|
||||||
|
LOG_INFO("Remote display [{}:{}], bound [({}, {}) ({}, {})]", i + 1,
|
||||||
|
props->display_info_list_[i].name,
|
||||||
|
props->display_info_list_[i].left,
|
||||||
|
props->display_info_list_[i].top,
|
||||||
|
props->display_info_list_[i].right,
|
||||||
|
props->display_info_list_[i].bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
props->remote_host_name_ = std::string(remote_action.i.host_name,
|
props->remote_host_name_ = std::string(remote_action.i.host_name,
|
||||||
remote_action.i.host_name_size);
|
remote_action.i.host_name_size);
|
||||||
LOG_INFO("Remote hostname: [{}]", props->remote_host_name_);
|
LOG_INFO("Remote hostname: [{}]", props->remote_host_name_);
|
||||||
|
LOG_ERROR("No remote display detected");
|
||||||
for (int i = 0; i < remote_action.i.display_num; i++) {
|
|
||||||
props->display_info_list_.push_back(
|
|
||||||
DisplayInfo(remote_action.i.display_list[i],
|
|
||||||
remote_action.i.left[i], remote_action.i.top[i],
|
|
||||||
remote_action.i.right[i], remote_action.i.bottom[i]));
|
|
||||||
}
|
}
|
||||||
}
|
FreeRemoteAction(host_info);
|
||||||
FreeRemoteAction(remote_action);
|
|
||||||
} else {
|
} else {
|
||||||
// remote
|
// remote
|
||||||
if (remote_action.type == ControlType::mouse && render->mouse_controller_) {
|
if (ControlType::mouse == remote_action.type && render->mouse_controller_) {
|
||||||
render->mouse_controller_->SendMouseCommand(remote_action,
|
render->mouse_controller_->SendMouseCommand(remote_action,
|
||||||
render->selected_display_);
|
render->selected_display_);
|
||||||
} else if (remote_action.type == ControlType::audio_capture) {
|
} else if (ControlType::audio_capture == remote_action.type) {
|
||||||
if (remote_action.a && !render->start_speaker_capturer_)
|
if (remote_action.a) {
|
||||||
render->StartSpeakerCapturer();
|
render->StartSpeakerCapturer();
|
||||||
else if (!remote_action.a && render->start_speaker_capturer_)
|
render->audio_capture_ = true;
|
||||||
|
} else {
|
||||||
render->StopSpeakerCapturer();
|
render->StopSpeakerCapturer();
|
||||||
} else if (remote_action.type == ControlType::keyboard &&
|
render->audio_capture_ = false;
|
||||||
|
}
|
||||||
|
} else if (ControlType::keyboard == remote_action.type &&
|
||||||
render->keyboard_capturer_) {
|
render->keyboard_capturer_) {
|
||||||
render->keyboard_capturer_->SendKeyboardCommand(
|
render->keyboard_capturer_->SendKeyboardCommand(
|
||||||
(int)remote_action.k.key_value,
|
(int)remote_action.k.key_value,
|
||||||
remote_action.k.flag == KeyFlag::key_down);
|
remote_action.k.flag == KeyFlag::key_down);
|
||||||
} else if (remote_action.type == ControlType::display_id &&
|
} else if (ControlType::display_id == remote_action.type) {
|
||||||
render->screen_capturer_) {
|
if (render->screen_capturer_) {
|
||||||
render->selected_display_ = remote_action.d;
|
render->selected_display_ = remote_action.d;
|
||||||
render->screen_capturer_->SwitchTo(remote_action.d);
|
render->screen_capturer_->SwitchTo(remote_action.d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Render::OnSignalStatusCb(SignalStatus status, const char* user_id,
|
void Render::OnSignalStatusCb(SignalStatus status, const char* user_id,
|
||||||
@@ -400,7 +409,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
props->connection_status_ = status;
|
props->connection_status_ = status;
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case ConnectionStatus::Connected: {
|
case ConnectionStatus::Connected:
|
||||||
if (!render->need_to_create_stream_window_ &&
|
if (!render->need_to_create_stream_window_ &&
|
||||||
!render->client_properties_.empty()) {
|
!render->client_properties_.empty()) {
|
||||||
render->need_to_create_stream_window_ = true;
|
render->need_to_create_stream_window_ = true;
|
||||||
@@ -411,10 +420,14 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
(int)render->stream_window_width_,
|
(int)render->stream_window_width_,
|
||||||
(int)(render->stream_window_height_ - render->title_bar_height_)};
|
(int)(render->stream_window_height_ - render->title_bar_height_)};
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ConnectionStatus::Disconnected:
|
case ConnectionStatus::Disconnected:
|
||||||
case ConnectionStatus::Failed:
|
case ConnectionStatus::Failed:
|
||||||
case ConnectionStatus::Closed: {
|
case ConnectionStatus::Closed:
|
||||||
|
render->password_validating_time_ = 0;
|
||||||
|
render->start_screen_capturer_ = false;
|
||||||
|
render->start_mouse_controller_ = false;
|
||||||
|
render->start_keyboard_capturer_ = false;
|
||||||
|
render->control_mouse_ = false;
|
||||||
props->connection_established_ = false;
|
props->connection_established_ = false;
|
||||||
props->mouse_control_button_pressed_ = false;
|
props->mouse_control_button_pressed_ = false;
|
||||||
if (props->dst_buffer_) {
|
if (props->dst_buffer_) {
|
||||||
@@ -423,10 +436,8 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
props->texture_width_);
|
props->texture_width_);
|
||||||
}
|
}
|
||||||
render->CleanSubStreamWindowProperties(props);
|
render->CleanSubStreamWindowProperties(props);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
case ConnectionStatus::IncorrectPassword:
|
||||||
case ConnectionStatus::IncorrectPassword: {
|
|
||||||
render->password_validating_ = false;
|
render->password_validating_ = false;
|
||||||
render->password_validating_time_++;
|
render->password_validating_time_++;
|
||||||
if (render->connect_button_pressed_) {
|
if (render->connect_button_pressed_) {
|
||||||
@@ -436,45 +447,28 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
localization::connect[render->localization_language_index_];
|
localization::connect[render->localization_language_index_];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case ConnectionStatus::NoSuchTransmissionId:
|
||||||
case ConnectionStatus::NoSuchTransmissionId: {
|
|
||||||
if (render->connect_button_pressed_) {
|
if (render->connect_button_pressed_) {
|
||||||
props->connection_established_ = false;
|
props->connection_established_ = false;
|
||||||
render->connect_button_label_ =
|
render->connect_button_label_ =
|
||||||
localization::connect[render->localization_language_index_];
|
localization::connect[render->localization_language_index_];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
render->is_client_mode_ = false;
|
render->is_client_mode_ = false;
|
||||||
render->show_connection_status_window_ = true;
|
render->show_connection_status_window_ = true;
|
||||||
render->connection_status_[remote_id] = status;
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case ConnectionStatus::Connected: {
|
case ConnectionStatus::Connected:
|
||||||
render->need_to_send_host_info_ = true;
|
render->need_to_send_host_info_ = true;
|
||||||
render->start_screen_capturer_ = true;
|
render->start_screen_capturer_ = true;
|
||||||
render->start_speaker_capturer_ = true;
|
|
||||||
#ifdef CROSSDESK_DEBUG
|
|
||||||
render->start_mouse_controller_ = false;
|
|
||||||
render->start_keyboard_capturer_ = false;
|
|
||||||
#else
|
|
||||||
render->start_mouse_controller_ = true;
|
render->start_mouse_controller_ = true;
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
case ConnectionStatus::Closed:
|
||||||
case ConnectionStatus::Closed: {
|
|
||||||
if (std::all_of(render->connection_status_.begin(),
|
|
||||||
render->connection_status_.end(), [](const auto& kv) {
|
|
||||||
return kv.second == ConnectionStatus::Closed ||
|
|
||||||
kv.second == ConnectionStatus::Failed ||
|
|
||||||
kv.second == ConnectionStatus::Disconnected;
|
|
||||||
})) {
|
|
||||||
render->start_screen_capturer_ = false;
|
render->start_screen_capturer_ = false;
|
||||||
render->start_speaker_capturer_ = false;
|
|
||||||
render->start_mouse_controller_ = false;
|
render->start_mouse_controller_ = false;
|
||||||
render->start_keyboard_capturer_ = false;
|
render->start_keyboard_capturer_ = false;
|
||||||
render->need_to_send_host_info_ = false;
|
render->need_to_send_host_info_ = false;
|
||||||
@@ -483,11 +477,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char* user_id,
|
|||||||
render->StopSpeakerCapturer();
|
render->StopSpeakerCapturer();
|
||||||
render->audio_capture_ = false;
|
render->audio_capture_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
render->connection_status_.erase(remote_id);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,9 +68,8 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
|||||||
remote_action.type = ControlType::display_id;
|
remote_action.type = ControlType::display_id;
|
||||||
remote_action.d = i;
|
remote_action.d = i;
|
||||||
if (props->connection_status_ == ConnectionStatus::Connected) {
|
if (props->connection_status_ == ConnectionStatus::Connected) {
|
||||||
std::string msg = remote_action.to_json();
|
SendDataFrame(props->peer_, (const char*)&remote_action,
|
||||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
sizeof(remote_action), props->data_label_.c_str());
|
||||||
props->data_label_.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
props->display_selectable_hovered_ = ImGui::IsWindowHovered();
|
props->display_selectable_hovered_ = ImGui::IsWindowHovered();
|
||||||
@@ -143,9 +142,8 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
|||||||
RemoteAction remote_action;
|
RemoteAction remote_action;
|
||||||
remote_action.type = ControlType::audio_capture;
|
remote_action.type = ControlType::audio_capture;
|
||||||
remote_action.a = props->audio_capture_button_pressed_;
|
remote_action.a = props->audio_capture_button_pressed_;
|
||||||
std::string msg = remote_action.to_json();
|
SendDataFrame(props->peer_, (const char*)&remote_action,
|
||||||
SendDataFrame(props->peer_, msg.c_str(), msg.size(),
|
sizeof(remote_action), props->data_label_.c_str());
|
||||||
props->data_label_.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!props->audio_capture_button_pressed_) {
|
if (!props->audio_capture_button_pressed_) {
|
||||||
|
|||||||
@@ -82,11 +82,11 @@ int Render::SettingWindow() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
const char* video_quality_items[] = {
|
const char* video_quality_items[] = {
|
||||||
localization::video_quality_low[localization_language_index_]
|
localization::video_quality_high[localization_language_index_]
|
||||||
.c_str(),
|
.c_str(),
|
||||||
localization::video_quality_medium[localization_language_index_]
|
localization::video_quality_medium[localization_language_index_]
|
||||||
.c_str(),
|
.c_str(),
|
||||||
localization::video_quality_high[localization_language_index_]
|
localization::video_quality_low[localization_language_index_]
|
||||||
.c_str()};
|
.c_str()};
|
||||||
|
|
||||||
settings_items_offset += settings_items_padding;
|
settings_items_offset += settings_items_padding;
|
||||||
@@ -231,7 +231,8 @@ int Render::SettingWindow() {
|
|||||||
ImGui::SetCursorPosX(ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_EN);
|
ImGui::SetCursorPosX(ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_EN);
|
||||||
}
|
}
|
||||||
ImGui::SetCursorPosY(settings_items_offset);
|
ImGui::SetCursorPosY(settings_items_offset);
|
||||||
ImGui::Checkbox("##enable_self_hosted", &enable_self_hosted_);
|
ImGui::Checkbox("##enable_self_hosted_server",
|
||||||
|
&enable_self_hosted_server_);
|
||||||
}
|
}
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
@@ -288,23 +289,14 @@ int Render::SettingWindow() {
|
|||||||
|
|
||||||
// Video quality
|
// Video quality
|
||||||
if (video_quality_button_value_ == 0) {
|
if (video_quality_button_value_ == 0) {
|
||||||
config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::LOW);
|
config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::HIGH);
|
||||||
} else if (video_quality_button_value_ == 1) {
|
} else if (video_quality_button_value_ == 1) {
|
||||||
config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::MEDIUM);
|
config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::MEDIUM);
|
||||||
} else {
|
} else {
|
||||||
config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::HIGH);
|
config_center_->SetVideoQuality(ConfigCenter::VIDEO_QUALITY::LOW);
|
||||||
}
|
}
|
||||||
video_quality_button_value_last_ = video_quality_button_value_;
|
video_quality_button_value_last_ = video_quality_button_value_;
|
||||||
|
|
||||||
if (video_frame_rate_button_value_ == 0) {
|
|
||||||
config_center_->SetVideoFrameRate(
|
|
||||||
ConfigCenter::VIDEO_FRAME_RATE::FPS_30);
|
|
||||||
} else if (video_frame_rate_button_value_ == 1) {
|
|
||||||
config_center_->SetVideoFrameRate(
|
|
||||||
ConfigCenter::VIDEO_FRAME_RATE::FPS_60);
|
|
||||||
}
|
|
||||||
video_frame_rate_button_value_last_ = video_frame_rate_button_value_;
|
|
||||||
|
|
||||||
// Video encode format
|
// Video encode format
|
||||||
if (video_encode_format_button_value_ == 0) {
|
if (video_encode_format_button_value_ == 0) {
|
||||||
config_center_->SetVideoEncodeFormat(
|
config_center_->SetVideoEncodeFormat(
|
||||||
@@ -340,12 +332,11 @@ int Render::SettingWindow() {
|
|||||||
}
|
}
|
||||||
enable_srtp_last_ = enable_srtp_;
|
enable_srtp_last_ = enable_srtp_;
|
||||||
|
|
||||||
if (enable_self_hosted_) {
|
if (enable_self_hosted_server_) {
|
||||||
config_center_->SetSelfHosted(true);
|
config_center_->SetSelfHosted(true);
|
||||||
} else {
|
} else {
|
||||||
config_center_->SetSelfHosted(false);
|
config_center_->SetSelfHosted(false);
|
||||||
}
|
}
|
||||||
enable_self_hosted_last_ = enable_self_hosted_;
|
|
||||||
|
|
||||||
settings_window_pos_reset_ = true;
|
settings_window_pos_reset_ = true;
|
||||||
|
|
||||||
@@ -375,11 +366,6 @@ int Render::SettingWindow() {
|
|||||||
video_quality_button_value_ = video_quality_button_value_last_;
|
video_quality_button_value_ = video_quality_button_value_last_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (video_frame_rate_button_value_ !=
|
|
||||||
video_frame_rate_button_value_last_) {
|
|
||||||
video_frame_rate_button_value_ = video_frame_rate_button_value_last_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (video_encode_format_button_value_ !=
|
if (video_encode_format_button_value_ !=
|
||||||
video_encode_format_button_value_last_) {
|
video_encode_format_button_value_last_) {
|
||||||
video_encode_format_button_value_ =
|
video_encode_format_button_value_ =
|
||||||
|
|||||||
@@ -18,11 +18,7 @@ std::filesystem::path PathManager::GetConfigPath() {
|
|||||||
|
|
||||||
std::filesystem::path PathManager::GetCachePath() {
|
std::filesystem::path PathManager::GetCachePath() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef CROSSDESK_DEBUG
|
|
||||||
return "cache";
|
|
||||||
#else
|
|
||||||
return GetKnownFolder(FOLDERID_LocalAppData) / app_name_ / "cache";
|
return GetKnownFolder(FOLDERID_LocalAppData) / app_name_ / "cache";
|
||||||
#endif
|
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
return GetEnvOrDefault("XDG_CACHE_HOME", GetHome() + "/.cache") / app_name_;
|
return GetEnvOrDefault("XDG_CACHE_HOME", GetHome() + "/.cache") / app_name_;
|
||||||
#else
|
#else
|
||||||
@@ -76,34 +72,22 @@ std::filesystem::path PathManager::GetKnownFolder(REFKNOWNFOLDERID id) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string PathManager::GetHome() {
|
std::string PathManager::GetHome() {
|
||||||
|
if (const char* home = getenv("HOME")) {
|
||||||
|
return std::string(home);
|
||||||
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, path)))
|
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, path)))
|
||||||
return std::string(path);
|
return std::string(path);
|
||||||
#else
|
|
||||||
if (const char* home = getenv("HOME")) {
|
|
||||||
return std::string(home);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path PathManager::GetEnvOrDefault(const char* env_var,
|
std::filesystem::path PathManager::GetEnvOrDefault(const char* env_var,
|
||||||
const std::string& def) {
|
const std::string& def) {
|
||||||
#ifdef _WIN32
|
|
||||||
char* buffer = nullptr;
|
|
||||||
size_t size = 0;
|
|
||||||
|
|
||||||
if (_dupenv_s(&buffer, &size, env_var) == 0 && buffer != nullptr) {
|
|
||||||
std::filesystem::path result(buffer);
|
|
||||||
free(buffer);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (const char* val = getenv(env_var)) {
|
if (const char* val = getenv(env_var)) {
|
||||||
return std::filesystem::path(val);
|
return std::filesystem::path(val);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return std::filesystem::path(def);
|
return std::filesystem::path(def);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,10 +22,14 @@
|
|||||||
#include "display_info.h"
|
#include "display_info.h"
|
||||||
#include "rd_log.h"
|
#include "rd_log.h"
|
||||||
|
|
||||||
using namespace crossdesk;
|
|
||||||
|
|
||||||
class ScreenCapturerSckImpl;
|
class ScreenCapturerSckImpl;
|
||||||
|
|
||||||
|
namespace crossdesk {
|
||||||
|
std::unique_ptr<ScreenCapturer> ScreenCapturerSck::CreateScreenCapturerSck() {
|
||||||
|
return std::make_unique<ScreenCapturerSckImpl>();
|
||||||
|
}
|
||||||
|
} // namespace crossdesk
|
||||||
|
|
||||||
static const int kFullDesktopScreenId = -1;
|
static const int kFullDesktopScreenId = -1;
|
||||||
|
|
||||||
// The ScreenCaptureKit API was available in macOS 12.3, but full-screen capture
|
// The ScreenCaptureKit API was available in macOS 12.3, but full-screen capture
|
||||||
@@ -485,7 +489,3 @@ void ScreenCapturerSckImpl::StartOrReconfigureCapturer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
std::unique_ptr<ScreenCapturer> ScreenCapturerSck::CreateScreenCapturerSck() {
|
|
||||||
return std::make_unique<ScreenCapturerSckImpl>();
|
|
||||||
}
|
|
||||||
@@ -14,42 +14,33 @@ namespace crossdesk {
|
|||||||
|
|
||||||
static std::vector<DisplayInfo> gs_display_list;
|
static std::vector<DisplayInfo> gs_display_list;
|
||||||
|
|
||||||
std::string WideToUtf8(const std::wstring& wstr) {
|
std::string WideToUtf8(const wchar_t* wideStr) {
|
||||||
if (wstr.empty()) return {};
|
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, nullptr, 0,
|
||||||
int size_needed = WideCharToMultiByte(
|
nullptr, nullptr);
|
||||||
CP_UTF8, 0, wstr.data(), (int)wstr.size(), nullptr, 0, nullptr, nullptr);
|
|
||||||
std::string result(size_needed, 0);
|
std::string result(size_needed, 0);
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), result.data(),
|
WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, &result[0], size_needed, nullptr,
|
||||||
size_needed, nullptr, nullptr);
|
nullptr);
|
||||||
|
result.pop_back();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CleanDisplayName(const std::wstring& wide_name) {
|
|
||||||
std::string name = WideToUtf8(wide_name);
|
|
||||||
name.erase(std::remove_if(name.begin(), name.end(),
|
|
||||||
[](unsigned char c) { return !std::isalnum(c); }),
|
|
||||||
name.end());
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI EnumMonitorProc(HMONITOR hmonitor, [[maybe_unused]] HDC hdc,
|
BOOL WINAPI EnumMonitorProc(HMONITOR hmonitor, [[maybe_unused]] HDC hdc,
|
||||||
[[maybe_unused]] LPRECT lprc, LPARAM data) {
|
[[maybe_unused]] LPRECT lprc, LPARAM data) {
|
||||||
MONITORINFOEX monitor_info_;
|
MONITORINFOEX monitor_info_;
|
||||||
monitor_info_.cbSize = sizeof(MONITORINFOEX);
|
monitor_info_.cbSize = sizeof(MONITORINFOEX);
|
||||||
|
|
||||||
if (GetMonitorInfo(hmonitor, &monitor_info_)) {
|
if (GetMonitorInfo(hmonitor, &monitor_info_)) {
|
||||||
std::string display_name = CleanDisplayName(monitor_info_.szDevice);
|
|
||||||
if (monitor_info_.dwFlags & MONITORINFOF_PRIMARY) {
|
if (monitor_info_.dwFlags & MONITORINFOF_PRIMARY) {
|
||||||
gs_display_list.insert(
|
gs_display_list.insert(
|
||||||
gs_display_list.begin(),
|
gs_display_list.begin(),
|
||||||
{(void*)hmonitor, display_name,
|
{(void*)hmonitor, WideToUtf8(monitor_info_.szDevice),
|
||||||
(monitor_info_.dwFlags & MONITORINFOF_PRIMARY) ? true : false,
|
(monitor_info_.dwFlags & MONITORINFOF_PRIMARY) ? true : false,
|
||||||
monitor_info_.rcMonitor.left, monitor_info_.rcMonitor.top,
|
monitor_info_.rcMonitor.left, monitor_info_.rcMonitor.top,
|
||||||
monitor_info_.rcMonitor.right, monitor_info_.rcMonitor.bottom});
|
monitor_info_.rcMonitor.right, monitor_info_.rcMonitor.bottom});
|
||||||
*(HMONITOR*)data = hmonitor;
|
*(HMONITOR*)data = hmonitor;
|
||||||
} else {
|
} else {
|
||||||
gs_display_list.push_back(DisplayInfo(
|
gs_display_list.push_back(DisplayInfo(
|
||||||
(void*)hmonitor, display_name,
|
(void*)hmonitor, WideToUtf8(monitor_info_.szDevice),
|
||||||
(monitor_info_.dwFlags & MONITORINFOF_PRIMARY) ? true : false,
|
(monitor_info_.dwFlags & MONITORINFOF_PRIMARY) ? true : false,
|
||||||
monitor_info_.rcMonitor.left, monitor_info_.rcMonitor.top,
|
monitor_info_.rcMonitor.left, monitor_info_.rcMonitor.top,
|
||||||
monitor_info_.rcMonitor.right, monitor_info_.rcMonitor.bottom));
|
monitor_info_.rcMonitor.right, monitor_info_.rcMonitor.bottom));
|
||||||
|
|||||||
@@ -118,13 +118,13 @@ void ScaleNv12ToABGR(char* src, int src_w, int src_h, int dst_w, int dst_h,
|
|||||||
|
|
||||||
memset(dst_rgba, 0, dst_w * dst_h * 4);
|
memset(dst_rgba, 0, dst_w * dst_h * 4);
|
||||||
for (int i = 0; i < dst_w * dst_h; ++i) {
|
for (int i = 0; i < dst_w * dst_h; ++i) {
|
||||||
dst_rgba[i * 4 + 3] = static_cast<char>(0xFF);
|
dst_rgba[i * 4 + 3] = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int row = 0; row < fit_h; ++row) {
|
for (int y = 0; y < fit_h; ++y) {
|
||||||
int dst_offset =
|
int dst_offset =
|
||||||
((row + (dst_h - fit_h) / 2) * dst_w + (dst_w - fit_w) / 2) * 4;
|
((y + (dst_h - fit_h) / 2) * dst_w + (dst_w - fit_w) / 2) * 4;
|
||||||
memcpy(dst_rgba + dst_offset, abgr.data() + row * fit_w * 4, fit_w * 4);
|
memcpy(dst_rgba + dst_offset, abgr.data() + y * fit_w * 4, fit_w * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
|
|||||||
memset(rgba_buffer_, 0x00, thumbnail_width_ * thumbnail_height_ * 4);
|
memset(rgba_buffer_, 0x00, thumbnail_width_ * thumbnail_height_ * 4);
|
||||||
for (int i = 0; i < thumbnail_width_ * thumbnail_height_; ++i) {
|
for (int i = 0; i < thumbnail_width_ * thumbnail_height_; ++i) {
|
||||||
// Set alpha channel to opaque
|
// Set alpha channel to opaque
|
||||||
rgba_buffer_[i * 4 + 3] = static_cast<char>(0xFF);
|
rgba_buffer_[i * 4 + 3] = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ int Thumbnail::LoadThumbnail(
|
|||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < image_paths.size(); i++) {
|
for (int i = 0; i < image_paths.size(); i++) {
|
||||||
// size_t pos1 = image_paths[i].string().find('/') + 1;
|
size_t pos1 = image_paths[i].string().find('/') + 1;
|
||||||
std::string cipher_image_name = image_paths[i].filename().string();
|
std::string cipher_image_name = image_paths[i].filename().string();
|
||||||
std::string remote_id;
|
std::string remote_id;
|
||||||
std::string cipher_password;
|
std::string cipher_password;
|
||||||
@@ -241,7 +241,7 @@ int Thumbnail::LoadThumbnail(
|
|||||||
AES_decrypt(cipher_password, aes128_key_, aes128_iv_);
|
AES_decrypt(cipher_password, aes128_key_, aes128_iv_);
|
||||||
} else {
|
} else {
|
||||||
size_t pos_n = cipher_image_name.find('N');
|
size_t pos_n = cipher_image_name.find('N');
|
||||||
// size_t pos_at = cipher_image_name.find('@');
|
size_t pos_at = cipher_image_name.find('@');
|
||||||
|
|
||||||
if (pos_n == std::string::npos) {
|
if (pos_n == std::string::npos) {
|
||||||
LOG_ERROR("Invalid filename");
|
LOG_ERROR("Invalid filename");
|
||||||
|
|||||||
Submodule submodules/minirtc deleted from 2f8b0c1ff4
1
thirdparty/minirtc
vendored
Submodule
1
thirdparty/minirtc
vendored
Submodule
Submodule thirdparty/minirtc added at 40eaf93b42
@@ -13,17 +13,15 @@ set_encodings("utf-8")
|
|||||||
|
|
||||||
-- set_policy("build.warning", true)
|
-- set_policy("build.warning", true)
|
||||||
-- set_warnings("all", "extra")
|
-- set_warnings("all", "extra")
|
||||||
-- add_cxxflags("/W4", "/WX")
|
|
||||||
|
|
||||||
add_defines("UNICODE")
|
add_defines("UNICODE")
|
||||||
if is_mode("debug") then
|
if is_mode("debug") then
|
||||||
add_defines("CROSSDESK_DEBUG")
|
add_defines("DESK_PORT_DEBUG")
|
||||||
end
|
end
|
||||||
|
|
||||||
add_requires("spdlog 1.14.1", {system = false})
|
add_requires("spdlog 1.14.1", {system = false})
|
||||||
add_requires("imgui v1.91.5-docking", {configs = {sdl3 = true, sdl3_renderer = true}})
|
add_requires("imgui v1.91.5-docking", {configs = {sdl3 = true, sdl3_renderer = true}})
|
||||||
add_requires("openssl3 3.3.2", {system = false})
|
add_requires("openssl3 3.3.2", {system = false})
|
||||||
add_requires("nlohmann_json 3.11.3")
|
|
||||||
|
|
||||||
if is_os("windows") then
|
if is_os("windows") then
|
||||||
add_requires("libyuv", "miniaudio 0.11.21")
|
add_requires("libyuv", "miniaudio 0.11.21")
|
||||||
@@ -46,9 +44,9 @@ elseif is_os("macosx") then
|
|||||||
"CoreMedia", "CoreVideo", "CoreAudio", "AudioToolbox")
|
"CoreMedia", "CoreVideo", "CoreAudio", "AudioToolbox")
|
||||||
end
|
end
|
||||||
|
|
||||||
add_packages("spdlog", "imgui", "nlohmann_json")
|
add_packages("spdlog", "imgui")
|
||||||
|
|
||||||
includes("submodules")
|
includes("thirdparty")
|
||||||
|
|
||||||
target("rd_log")
|
target("rd_log")
|
||||||
set_kind("object")
|
set_kind("object")
|
||||||
|
|||||||
Reference in New Issue
Block a user