mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 20:25:34 +08:00
[feat] quick connecting supported
This commit is contained in:
@@ -102,15 +102,25 @@ int Render::ShowRecentConnections() {
|
|||||||
ImGuiWindowFlags_NoTitleBar |
|
ImGuiWindowFlags_NoTitleBar |
|
||||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||||
ImGuiWindowFlags_NoScrollbar);
|
ImGuiWindowFlags_NoScrollbar);
|
||||||
// size_t pos1 = it->first.find('\\') + 1;
|
std::string connection_info = it->first;
|
||||||
// size_t pos2 = it->first.rfind('@');
|
std::string remote_id;
|
||||||
// std::string host_name = it->first.substr(pos1, pos2 - pos1);
|
std::string password;
|
||||||
|
std::string host_name;
|
||||||
|
|
||||||
size_t pos1 = it->first.find('@') + 1;
|
// remote id length is 9
|
||||||
size_t pos2 = it->first.rfind('@');
|
// password length is 6
|
||||||
std::string password = it->first.substr(0, pos1);
|
// connection_info -> remote_id + Y + password + host_name
|
||||||
std::string host_name = it->first.substr(pos1, pos2 - pos1);
|
// -> remote_id + N + host_name
|
||||||
std::string remote_id = it->first.substr(pos2 + 1);
|
if ('Y' == connection_info[9] && connection_info.size() >= 16) {
|
||||||
|
remote_id = connection_info.substr(0, 9);
|
||||||
|
password = connection_info.substr(10, 6);
|
||||||
|
host_name = connection_info.substr(16);
|
||||||
|
} else if ('N' == connection_info[9] && connection_info.size() >= 10) {
|
||||||
|
remote_id = connection_info.substr(0, 9);
|
||||||
|
host_name = connection_info.substr(10);
|
||||||
|
} else {
|
||||||
|
host_name = "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::SetWindowFontScale(0.4f);
|
ImGui::SetWindowFontScale(0.4f);
|
||||||
ImVec2 window_size = ImGui::GetWindowSize();
|
ImVec2 window_size = ImGui::GetWindowSize();
|
||||||
@@ -159,8 +169,11 @@ int Render::ShowRecentConnections() {
|
|||||||
connect + "##ConnectionTo" + it->first;
|
connect + "##ConnectionTo" + it->first;
|
||||||
if (ImGui::Button(connect_to_this_connection_button_name.c_str(),
|
if (ImGui::Button(connect_to_this_connection_button_name.c_str(),
|
||||||
ImVec2(button_width, button_height))) {
|
ImVec2(button_width, button_height))) {
|
||||||
LOG_ERROR("Connect to [{}]",
|
LOG_ERROR("Connect to [{}], password [{}]", remote_id.c_str(),
|
||||||
connect_to_this_connection_button_name.c_str());
|
password.c_str());
|
||||||
|
remote_id_ = remote_id;
|
||||||
|
strncpy(remote_password_, password.c_str(), 6);
|
||||||
|
ConnectTo();
|
||||||
}
|
}
|
||||||
ImGui::SetWindowFontScale(1.0f);
|
ImGui::SetWindowFontScale(1.0f);
|
||||||
ImGui::PopStyleColor(3);
|
ImGui::PopStyleColor(3);
|
||||||
@@ -171,55 +184,6 @@ int Render::ShowRecentConnections() {
|
|||||||
ImGui::SameLine(0, count != recent_connections_count ? 23.0f : 0.0f);
|
ImGui::SameLine(0, count != recent_connections_count ? 23.0f : 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
|
||||||
// ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 0, 0, 0));
|
|
||||||
// ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0, 0, 0, 0));
|
|
||||||
// for (const auto& pos : sub_containers_pos) {
|
|
||||||
// ImVec2 delete_button_pos =
|
|
||||||
// ImVec2(pos.second.x + recent_connection_sub_container_width - 11.0f,
|
|
||||||
// pos.second.y - 7.0f);
|
|
||||||
// ImGui::SetCursorPos(delete_button_pos);
|
|
||||||
// ImGui::SetWindowFontScale(0.5f);
|
|
||||||
// std::string xmake = ICON_FA_CIRCLE_XMARK;
|
|
||||||
// std::string recent_connection_delete_button_name =
|
|
||||||
// xmake + "##RecentConnectionDelete" +
|
|
||||||
// std::to_string(delete_button_pos.x);
|
|
||||||
// if (ImGui::SmallButton(recent_connection_delete_button_name.c_str())) {
|
|
||||||
// show_confirm_delete_connection_ = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (delete_connection_) {
|
|
||||||
// if (!thumbnail_.DeleteThumbnail(pos.first)) {
|
|
||||||
// reload_recent_connections_ = true;
|
|
||||||
// delete_connection_ = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ImGui::SetWindowFontScale(1.0f);
|
|
||||||
|
|
||||||
// {
|
|
||||||
// int delete_button_width = 20;
|
|
||||||
// int delete_button_height = 20;
|
|
||||||
// int pos_x = pos.second.x;
|
|
||||||
// int pos_y = pos.second.y + recent_connection_sub_container_height -
|
|
||||||
// delete_button_height;
|
|
||||||
// ImVec2 connect_button_pos = ImVec2(pos_x, pos_y);
|
|
||||||
// ImGui::SetCursorPos(connect_button_pos);
|
|
||||||
// ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 0, 0, 1));
|
|
||||||
// ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 1, 0, 1));
|
|
||||||
// ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0, 0, 1, 1));
|
|
||||||
// std::string connect_to_this_connection_button_name =
|
|
||||||
// "##ConnectionTo" + pos.first;
|
|
||||||
// if (ImGui::Button(connect_to_this_connection_button_name.c_str(),
|
|
||||||
// ImVec2(delete_button_width, delete_button_height))) {
|
|
||||||
// LOG_ERROR("Connect to [{}]",
|
|
||||||
// connect_to_this_connection_button_name.c_str());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ImGui::PopStyleColor(3);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ImGui::PopStyleColor(3);
|
|
||||||
|
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
|
||||||
if (show_confirm_delete_connection_) {
|
if (show_confirm_delete_connection_) {
|
||||||
|
|||||||
@@ -66,39 +66,17 @@ int Render::RemoteWindow() {
|
|||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button(ICON_FA_ARROW_RIGHT_LONG, ImVec2(55, 38)) ||
|
if (ImGui::Button(ICON_FA_ARROW_RIGHT_LONG, ImVec2(55, 38)) ||
|
||||||
enter_pressed || rejoin_) {
|
enter_pressed) {
|
||||||
connect_button_pressed_ = true;
|
connect_button_pressed_ = true;
|
||||||
connection_status_ = ConnectionStatus::Connecting;
|
|
||||||
int ret = -1;
|
|
||||||
if (signal_connected_) {
|
|
||||||
if (!connection_established_) {
|
|
||||||
remote_id_ = remote_id_display_;
|
remote_id_ = remote_id_display_;
|
||||||
remote_id_.erase(remove_if(remote_id_.begin(), remote_id_.end(),
|
remote_id_.erase(remove_if(remote_id_.begin(), remote_id_.end(),
|
||||||
static_cast<int (*)(int)>(&isspace)),
|
static_cast<int (*)(int)>(&isspace)),
|
||||||
remote_id_.end());
|
remote_id_.end());
|
||||||
if (0 == strcmp(remote_id_.c_str(), client_id_) &&
|
ConnectTo();
|
||||||
!peer_reserved_) {
|
|
||||||
peer_reserved_ = CreatePeer(¶ms_);
|
|
||||||
if (peer_reserved_) {
|
|
||||||
LOG_INFO("Create peer[reserved] instance successful");
|
|
||||||
std::string client_id = "C-";
|
|
||||||
client_id += client_id_;
|
|
||||||
Init(peer_reserved_, client_id.c_str());
|
|
||||||
LOG_INFO("Peer[reserved] init finish");
|
|
||||||
} else {
|
|
||||||
LOG_INFO("Create peer[reserved] instance failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret = JoinConnection(peer_reserved_ ? peer_reserved_ : peer_,
|
|
||||||
remote_id_.c_str(), remote_password_);
|
|
||||||
if (0 == ret) {
|
|
||||||
is_client_mode_ = true;
|
|
||||||
rejoin_ = false;
|
|
||||||
} else {
|
|
||||||
rejoin_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rejoin_) {
|
||||||
|
ConnectTo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
@@ -120,3 +98,35 @@ static int InputTextCallback(ImGuiInputTextCallbackData *data) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Render::ConnectTo() {
|
||||||
|
connection_status_ = ConnectionStatus::Connecting;
|
||||||
|
int ret = -1;
|
||||||
|
if (signal_connected_) {
|
||||||
|
if (!connection_established_) {
|
||||||
|
if (0 == strcmp(remote_id_.c_str(), client_id_) && !peer_reserved_) {
|
||||||
|
peer_reserved_ = CreatePeer(¶ms_);
|
||||||
|
if (peer_reserved_) {
|
||||||
|
LOG_INFO("Create peer[reserved] instance successful");
|
||||||
|
std::string client_id = "C-";
|
||||||
|
client_id += client_id_;
|
||||||
|
Init(peer_reserved_, client_id.c_str());
|
||||||
|
LOG_INFO("Peer[reserved] init finish");
|
||||||
|
} else {
|
||||||
|
LOG_INFO("Create peer[reserved] instance failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = JoinConnection(peer_reserved_ ? peer_reserved_ : peer_,
|
||||||
|
remote_id_.c_str(), remote_password_);
|
||||||
|
if (0 == ret) {
|
||||||
|
is_client_mode_ = true;
|
||||||
|
rejoin_ = false;
|
||||||
|
} else {
|
||||||
|
rejoin_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -217,7 +217,7 @@ int Render::StartSpeakerCapture() {
|
|||||||
int speaker_capturer_init_ret = speaker_capturer_->Init(
|
int speaker_capturer_init_ret = speaker_capturer_->Init(
|
||||||
[this](unsigned char* data, size_t size) -> void {
|
[this](unsigned char* data, size_t size) -> void {
|
||||||
if (connection_established_) {
|
if (connection_established_) {
|
||||||
// SendData(peer_, DATA_TYPE::AUDIO, (const char*)data, size);
|
SendData(peer_, DATA_TYPE::AUDIO, (const char*)data, size);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -803,8 +803,8 @@ int Render::Run() {
|
|||||||
|
|
||||||
if (dst_buffer_) {
|
if (dst_buffer_) {
|
||||||
thumbnail_.SaveToThumbnail(
|
thumbnail_.SaveToThumbnail(
|
||||||
(char*)dst_buffer_, video_width_, video_height_, host_name_,
|
(char*)dst_buffer_, video_width_, video_height_, remote_id_,
|
||||||
remote_id_, remember_password_ ? remote_password_ : "");
|
host_name_, remember_password_ ? remote_password_ : "");
|
||||||
recent_connection_image_save_time_ = SDL_GetTicks();
|
recent_connection_image_save_time_ = SDL_GetTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ class Render {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int CreateRtcConnection();
|
int CreateRtcConnection();
|
||||||
|
int ConnectTo();
|
||||||
int CreateMainWindow();
|
int CreateMainWindow();
|
||||||
int DestroyMainWindow();
|
int DestroyMainWindow();
|
||||||
int CreateStreamWindow();
|
int CreateStreamWindow();
|
||||||
@@ -279,7 +280,7 @@ class Render {
|
|||||||
bool hostname_sent_ = false;
|
bool hostname_sent_ = false;
|
||||||
bool show_confirm_delete_connection_ = false;
|
bool show_confirm_delete_connection_ = false;
|
||||||
bool delete_connection_ = false;
|
bool delete_connection_ = false;
|
||||||
bool remember_password_ = true;
|
bool remember_password_ = false;
|
||||||
|
|
||||||
double copy_start_time_ = 0;
|
double copy_start_time_ = 0;
|
||||||
double regenerate_password_start_time_ = 0;
|
double regenerate_password_start_time_ = 0;
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ Thumbnail::~Thumbnail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
|
int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
|
||||||
const std::string& host_name,
|
|
||||||
const std::string& remote_id,
|
const std::string& remote_id,
|
||||||
|
const std::string& host_name,
|
||||||
const std::string& password) {
|
const std::string& password) {
|
||||||
if (!rgba_buffer_) {
|
if (!rgba_buffer_) {
|
||||||
rgba_buffer_ = new char[thumbnail_width_ * thumbnail_height_ * 4];
|
rgba_buffer_ = new char[thumbnail_width_ * thumbnail_height_ * 4];
|
||||||
@@ -84,10 +84,20 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
|
|||||||
ScaleYUV420pToABGR((char*)yuv420p, width, height, thumbnail_width_,
|
ScaleYUV420pToABGR((char*)yuv420p, width, height, thumbnail_width_,
|
||||||
thumbnail_height_, rgba_buffer_);
|
thumbnail_height_, rgba_buffer_);
|
||||||
|
|
||||||
std::string image_name = password + "@" + host_name + "@" + remote_id;
|
std::string image_name;
|
||||||
|
if (password.empty()) {
|
||||||
|
image_name = remote_id + "N" + host_name;
|
||||||
|
} else {
|
||||||
|
// delete the file which has no password in its name
|
||||||
|
std::string filename_without_password = remote_id + "N" + host_name;
|
||||||
|
DeleteThumbnail(filename_without_password);
|
||||||
|
|
||||||
|
image_name = remote_id + "Y" + password + host_name;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ciphertext = AES_encrypt(image_name, key_, iv_);
|
std::string ciphertext = AES_encrypt(image_name, key_, iv_);
|
||||||
std::string save_path = image_path_ + ciphertext;
|
std::string file_path = image_path_ + ciphertext;
|
||||||
stbi_write_png(save_path.data(), thumbnail_width_, thumbnail_height_, 4,
|
stbi_write_png(file_path.data(), thumbnail_width_, thumbnail_height_, 4,
|
||||||
rgba_buffer_, thumbnail_width_ * 4);
|
rgba_buffer_, thumbnail_width_ * 4);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -103,7 +113,7 @@ bool LoadTextureFromMemory(const void* data, size_t data_size,
|
|||||||
stbi_load_from_memory((const unsigned char*)data, (int)data_size,
|
stbi_load_from_memory((const unsigned char*)data, (int)data_size,
|
||||||
&image_width, &image_height, NULL, 4);
|
&image_width, &image_height, NULL, 4);
|
||||||
if (image_data == nullptr) {
|
if (image_data == nullptr) {
|
||||||
fprintf(stderr, "Failed to load image: %s\n", stbi_failure_reason());
|
LOG_ERROR("Failed to load image: [{}]", stbi_failure_reason());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,13 +122,14 @@ bool LoadTextureFromMemory(const void* data, size_t data_size,
|
|||||||
(void*)image_data, image_width, image_height, channels * 8,
|
(void*)image_data, image_width, image_height, channels * 8,
|
||||||
channels * image_width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
channels * image_width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||||
if (surface == nullptr) {
|
if (surface == nullptr) {
|
||||||
fprintf(stderr, "Failed to create SDL surface: %s\n", SDL_GetError());
|
LOG_ERROR("Failed to create SDL surface: [{}]", SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||||
if (texture == nullptr)
|
if (texture == nullptr) {
|
||||||
fprintf(stderr, "Failed to create SDL texture: %s\n", SDL_GetError());
|
LOG_ERROR("Failed to create SDL texture: [{}]", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
*out_texture = texture;
|
*out_texture = texture;
|
||||||
*out_width = image_width;
|
*out_width = image_width;
|
||||||
@@ -185,7 +196,14 @@ std::vector<std::filesystem::path> Thumbnail::FindThumbnailPath(
|
|||||||
int Thumbnail::LoadThumbnail(SDL_Renderer* renderer,
|
int Thumbnail::LoadThumbnail(SDL_Renderer* renderer,
|
||||||
std::map<std::string, SDL_Texture*>& textures,
|
std::map<std::string, SDL_Texture*>& textures,
|
||||||
int* width, int* height) {
|
int* width, int* height) {
|
||||||
|
for (auto& it : textures) {
|
||||||
|
if (it.second != nullptr) {
|
||||||
|
SDL_DestroyTexture(it.second);
|
||||||
|
it.second = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
textures.clear();
|
textures.clear();
|
||||||
|
|
||||||
std::vector<std::filesystem::path> image_paths =
|
std::vector<std::filesystem::path> image_paths =
|
||||||
FindThumbnailPath(image_path_);
|
FindThumbnailPath(image_path_);
|
||||||
|
|
||||||
@@ -207,13 +225,13 @@ int Thumbnail::LoadThumbnail(SDL_Renderer* renderer,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Thumbnail::DeleteThumbnail(const std::string& file_path) {
|
int Thumbnail::DeleteThumbnail(const std::string& file_name) {
|
||||||
|
std::string ciphertext = AES_encrypt(file_name, key_, iv_);
|
||||||
|
std::string file_path = image_path_ + ciphertext;
|
||||||
if (std::filesystem::exists(file_path)) {
|
if (std::filesystem::exists(file_path)) {
|
||||||
std::filesystem::remove(file_path);
|
std::filesystem::remove(file_path);
|
||||||
LOG_INFO("File [{}] removed successfully", file_path);
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("File [{}] does not exist", file_path);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,15 +19,15 @@ class Thumbnail {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
int SaveToThumbnail(const char* yuv420p, int width, int height,
|
int SaveToThumbnail(const char* yuv420p, int width, int height,
|
||||||
const std::string& host_name,
|
|
||||||
const std::string& remote_id,
|
const std::string& remote_id,
|
||||||
|
const std::string& host_name,
|
||||||
const std::string& password);
|
const std::string& password);
|
||||||
|
|
||||||
int LoadThumbnail(SDL_Renderer* renderer,
|
int LoadThumbnail(SDL_Renderer* renderer,
|
||||||
std::map<std::string, SDL_Texture*>& textures, int* width,
|
std::map<std::string, SDL_Texture*>& textures, int* width,
|
||||||
int* height);
|
int* height);
|
||||||
|
|
||||||
int DeleteThumbnail(const std::string& file_path);
|
int DeleteThumbnail(const std::string& file_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::filesystem::path> FindThumbnailPath(
|
std::vector<std::filesystem::path> FindThumbnailPath(
|
||||||
|
|||||||
Reference in New Issue
Block a user