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_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoScrollbar);
|
||||
// size_t pos1 = it->first.find('\\') + 1;
|
||||
// size_t pos2 = it->first.rfind('@');
|
||||
// std::string host_name = it->first.substr(pos1, pos2 - pos1);
|
||||
std::string connection_info = it->first;
|
||||
std::string remote_id;
|
||||
std::string password;
|
||||
std::string host_name;
|
||||
|
||||
size_t pos1 = it->first.find('@') + 1;
|
||||
size_t pos2 = it->first.rfind('@');
|
||||
std::string password = it->first.substr(0, pos1);
|
||||
std::string host_name = it->first.substr(pos1, pos2 - pos1);
|
||||
std::string remote_id = it->first.substr(pos2 + 1);
|
||||
// remote id length is 9
|
||||
// password length is 6
|
||||
// connection_info -> remote_id + Y + password + host_name
|
||||
// -> remote_id + N + host_name
|
||||
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);
|
||||
ImVec2 window_size = ImGui::GetWindowSize();
|
||||
@@ -159,8 +169,11 @@ int Render::ShowRecentConnections() {
|
||||
connect + "##ConnectionTo" + it->first;
|
||||
if (ImGui::Button(connect_to_this_connection_button_name.c_str(),
|
||||
ImVec2(button_width, button_height))) {
|
||||
LOG_ERROR("Connect to [{}]",
|
||||
connect_to_this_connection_button_name.c_str());
|
||||
LOG_ERROR("Connect to [{}], password [{}]", remote_id.c_str(),
|
||||
password.c_str());
|
||||
remote_id_ = remote_id;
|
||||
strncpy(remote_password_, password.c_str(), 6);
|
||||
ConnectTo();
|
||||
}
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
ImGui::PopStyleColor(3);
|
||||
@@ -171,55 +184,6 @@ int Render::ShowRecentConnections() {
|
||||
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();
|
||||
|
||||
if (show_confirm_delete_connection_) {
|
||||
|
||||
@@ -66,39 +66,17 @@ int Render::RemoteWindow() {
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_FA_ARROW_RIGHT_LONG, ImVec2(55, 38)) ||
|
||||
enter_pressed || rejoin_) {
|
||||
enter_pressed) {
|
||||
connect_button_pressed_ = true;
|
||||
connection_status_ = ConnectionStatus::Connecting;
|
||||
int ret = -1;
|
||||
if (signal_connected_) {
|
||||
if (!connection_established_) {
|
||||
remote_id_ = remote_id_display_;
|
||||
remote_id_.erase(remove_if(remote_id_.begin(), remote_id_.end(),
|
||||
static_cast<int (*)(int)>(&isspace)),
|
||||
remote_id_.end());
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
remote_id_ = remote_id_display_;
|
||||
remote_id_.erase(remove_if(remote_id_.begin(), remote_id_.end(),
|
||||
static_cast<int (*)(int)>(&isspace)),
|
||||
remote_id_.end());
|
||||
ConnectTo();
|
||||
}
|
||||
|
||||
if (rejoin_) {
|
||||
ConnectTo();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
@@ -118,5 +96,37 @@ static int InputTextCallback(ImGuiInputTextCallbackData *data) {
|
||||
data->InsertChars(7, " ");
|
||||
}
|
||||
|
||||
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(
|
||||
[this](unsigned char* data, size_t size) -> void {
|
||||
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_) {
|
||||
thumbnail_.SaveToThumbnail(
|
||||
(char*)dst_buffer_, video_width_, video_height_, host_name_,
|
||||
remote_id_, remember_password_ ? remote_password_ : "");
|
||||
(char*)dst_buffer_, video_width_, video_height_, remote_id_,
|
||||
host_name_, remember_password_ ? remote_password_ : "");
|
||||
recent_connection_image_save_time_ = SDL_GetTicks();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ class Render {
|
||||
|
||||
private:
|
||||
int CreateRtcConnection();
|
||||
int ConnectTo();
|
||||
int CreateMainWindow();
|
||||
int DestroyMainWindow();
|
||||
int CreateStreamWindow();
|
||||
@@ -279,7 +280,7 @@ class Render {
|
||||
bool hostname_sent_ = false;
|
||||
bool show_confirm_delete_connection_ = false;
|
||||
bool delete_connection_ = false;
|
||||
bool remember_password_ = true;
|
||||
bool remember_password_ = false;
|
||||
|
||||
double copy_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,
|
||||
const std::string& host_name,
|
||||
const std::string& remote_id,
|
||||
const std::string& host_name,
|
||||
const std::string& password) {
|
||||
if (!rgba_buffer_) {
|
||||
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_,
|
||||
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 save_path = image_path_ + ciphertext;
|
||||
stbi_write_png(save_path.data(), thumbnail_width_, thumbnail_height_, 4,
|
||||
std::string file_path = image_path_ + ciphertext;
|
||||
stbi_write_png(file_path.data(), thumbnail_width_, thumbnail_height_, 4,
|
||||
rgba_buffer_, thumbnail_width_ * 4);
|
||||
}
|
||||
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,
|
||||
&image_width, &image_height, NULL, 4);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -112,13 +122,14 @@ bool LoadTextureFromMemory(const void* data, size_t data_size,
|
||||
(void*)image_data, image_width, image_height, channels * 8,
|
||||
channels * image_width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
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;
|
||||
}
|
||||
|
||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (texture == nullptr)
|
||||
fprintf(stderr, "Failed to create SDL texture: %s\n", SDL_GetError());
|
||||
if (texture == nullptr) {
|
||||
LOG_ERROR("Failed to create SDL texture: [{}]", SDL_GetError());
|
||||
}
|
||||
|
||||
*out_texture = texture;
|
||||
*out_width = image_width;
|
||||
@@ -185,7 +196,14 @@ std::vector<std::filesystem::path> Thumbnail::FindThumbnailPath(
|
||||
int Thumbnail::LoadThumbnail(SDL_Renderer* renderer,
|
||||
std::map<std::string, SDL_Texture*>& textures,
|
||||
int* width, int* height) {
|
||||
for (auto& it : textures) {
|
||||
if (it.second != nullptr) {
|
||||
SDL_DestroyTexture(it.second);
|
||||
it.second = nullptr;
|
||||
}
|
||||
}
|
||||
textures.clear();
|
||||
|
||||
std::vector<std::filesystem::path> image_paths =
|
||||
FindThumbnailPath(image_path_);
|
||||
|
||||
@@ -207,13 +225,13 @@ int Thumbnail::LoadThumbnail(SDL_Renderer* renderer,
|
||||
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)) {
|
||||
std::filesystem::remove(file_path);
|
||||
LOG_INFO("File [{}] removed successfully", file_path);
|
||||
return 0;
|
||||
} else {
|
||||
LOG_ERROR("File [{}] does not exist", file_path);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,15 @@ class Thumbnail {
|
||||
|
||||
public:
|
||||
int SaveToThumbnail(const char* yuv420p, int width, int height,
|
||||
const std::string& host_name,
|
||||
const std::string& remote_id,
|
||||
const std::string& host_name,
|
||||
const std::string& password);
|
||||
|
||||
int LoadThumbnail(SDL_Renderer* renderer,
|
||||
std::map<std::string, SDL_Texture*>& textures, int* width,
|
||||
int* height);
|
||||
|
||||
int DeleteThumbnail(const std::string& file_path);
|
||||
int DeleteThumbnail(const std::string& file_name);
|
||||
|
||||
private:
|
||||
std::vector<std::filesystem::path> FindThumbnailPath(
|
||||
|
||||
Reference in New Issue
Block a user