mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 20:25:34 +08:00
[fix] fix control bar position when stream window created
This commit is contained in:
@@ -104,8 +104,8 @@ int Render::ConnectionStatusWindow(
|
|||||||
focus_on_input_widget_ = false;
|
focus_on_input_widget_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::InputText("##password", remote_password_,
|
ImGui::InputText("##password", props->remote_password_,
|
||||||
IM_ARRAYSIZE(remote_password_),
|
IM_ARRAYSIZE(props->remote_password_),
|
||||||
ImGuiInputTextFlags_CharsNoBlank);
|
ImGuiInputTextFlags_CharsNoBlank);
|
||||||
|
|
||||||
ImGui::SetWindowFontScale(0.4f);
|
ImGui::SetWindowFontScale(0.4f);
|
||||||
@@ -138,7 +138,7 @@ int Render::ConnectionStatusWindow(
|
|||||||
if (ImGui::Button(
|
if (ImGui::Button(
|
||||||
localization::cancel[localization_language_index_].c_str()) ||
|
localization::cancel[localization_language_index_].c_str()) ||
|
||||||
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||||
memset(remote_password_, 0, sizeof(remote_password_));
|
memset(props->remote_password_, 0, sizeof(props->remote_password_));
|
||||||
show_connection_status_window_ = false;
|
show_connection_status_window_ = false;
|
||||||
focus_on_input_widget_ = true;
|
focus_on_input_widget_ = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,12 +56,12 @@ int Render::ShowRecentConnections() {
|
|||||||
ImGuiWindowFlags_NoScrollWithMouse);
|
ImGuiWindowFlags_NoScrollWithMouse);
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
size_t recent_connections_count = recent_connection_textures_.size();
|
size_t recent_connections_count = recent_connections_.size();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
float button_width = 22;
|
float button_width = 22;
|
||||||
float button_height = 22;
|
float button_height = 22;
|
||||||
for (auto it = recent_connection_textures_.begin();
|
for (auto it = recent_connections_.begin(); it != recent_connections_.end();
|
||||||
it != recent_connection_textures_.end(); ++it) {
|
++it) {
|
||||||
sub_containers_pos[it->first] = ImGui::GetCursorPos();
|
sub_containers_pos[it->first] = ImGui::GetCursorPos();
|
||||||
std::string recent_connection_sub_window_name =
|
std::string recent_connection_sub_window_name =
|
||||||
"RecentConnectionsSubContainer" + it->first;
|
"RecentConnectionsSubContainer" + it->first;
|
||||||
@@ -77,23 +77,23 @@ int Render::ShowRecentConnections() {
|
|||||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||||
ImGuiWindowFlags_NoScrollbar);
|
ImGuiWindowFlags_NoScrollbar);
|
||||||
std::string connection_info = it->first;
|
std::string connection_info = it->first;
|
||||||
std::string remote_id;
|
|
||||||
std::string password;
|
|
||||||
std::string host_name;
|
|
||||||
|
|
||||||
// remote id length is 9
|
// remote id length is 9
|
||||||
// password length is 6
|
// password length is 6
|
||||||
// connection_info -> remote_id + 'Y' + password + host_name
|
// connection_info -> remote_id + 'Y' + password + host_name
|
||||||
// -> remote_id + 'N' + host_name
|
// -> remote_id + 'N' + host_name
|
||||||
if ('Y' == connection_info[9] && connection_info.size() >= 16) {
|
if ('Y' == connection_info[9] && connection_info.size() >= 16) {
|
||||||
remote_id = connection_info.substr(0, 9);
|
it->second.remote_id = connection_info.substr(0, 9);
|
||||||
password = connection_info.substr(10, 6);
|
it->second.password = connection_info.substr(10, 6);
|
||||||
host_name = connection_info.substr(16);
|
it->second.remote_host_name = connection_info.substr(16);
|
||||||
|
it->second.remember_password = true;
|
||||||
} else if ('N' == connection_info[9] && connection_info.size() >= 10) {
|
} else if ('N' == connection_info[9] && connection_info.size() >= 10) {
|
||||||
remote_id = connection_info.substr(0, 9);
|
it->second.remote_id = connection_info.substr(0, 9);
|
||||||
host_name = connection_info.substr(10);
|
it->second.remote_host_name = connection_info.substr(10);
|
||||||
|
it->second.password = "";
|
||||||
|
it->second.remember_password = false;
|
||||||
} else {
|
} else {
|
||||||
host_name = "unknown";
|
it->second.remote_host_name = "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
ImVec2 image_screen_pos = ImVec2(ImGui::GetCursorScreenPos().x + 5.0f,
|
ImVec2 image_screen_pos = ImVec2(ImGui::GetCursorScreenPos().x + 5.0f,
|
||||||
@@ -101,7 +101,7 @@ int Render::ShowRecentConnections() {
|
|||||||
ImVec2 image_pos =
|
ImVec2 image_pos =
|
||||||
ImVec2(ImGui::GetCursorPosX() + 5.0f, ImGui::GetCursorPosY() + 5.0f);
|
ImVec2(ImGui::GetCursorPosX() + 5.0f, ImGui::GetCursorPosY() + 5.0f);
|
||||||
ImGui::SetCursorPos(image_pos);
|
ImGui::SetCursorPos(image_pos);
|
||||||
ImGui::Image((ImTextureID)(intptr_t)it->second,
|
ImGui::Image((ImTextureID)(intptr_t)it->second.texture,
|
||||||
ImVec2((float)recent_connection_image_width_,
|
ImVec2((float)recent_connection_image_width_,
|
||||||
(float)recent_connection_image_height_));
|
(float)recent_connection_image_height_));
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ int Render::ShowRecentConnections() {
|
|||||||
|
|
||||||
ImVec2 dummy_button_pos =
|
ImVec2 dummy_button_pos =
|
||||||
ImVec2(image_pos.x, image_pos.y + recent_connection_image_height_);
|
ImVec2(image_pos.x, image_pos.y + recent_connection_image_height_);
|
||||||
std::string dummy_button_name = "##DummyButton" + remote_id;
|
std::string dummy_button_name = "##DummyButton" + it->second.remote_id;
|
||||||
ImGui::SetCursorPos(dummy_button_pos);
|
ImGui::SetCursorPos(dummy_button_pos);
|
||||||
ImGui::SetWindowFontScale(0.6f);
|
ImGui::SetWindowFontScale(0.6f);
|
||||||
ImGui::Button(dummy_button_name.c_str(),
|
ImGui::Button(dummy_button_name.c_str(),
|
||||||
@@ -123,14 +123,14 @@ int Render::ShowRecentConnections() {
|
|||||||
ImGui::SetCursorPos(
|
ImGui::SetCursorPos(
|
||||||
ImVec2(dummy_button_pos.x + 2.0f, dummy_button_pos.y + 1.0f));
|
ImVec2(dummy_button_pos.x + 2.0f, dummy_button_pos.y + 1.0f));
|
||||||
ImGui::SetWindowFontScale(0.65f);
|
ImGui::SetWindowFontScale(0.65f);
|
||||||
ImGui::Text("%s", remote_id.c_str());
|
ImGui::Text("%s", it->second.remote_id.c_str());
|
||||||
ImGui::SetWindowFontScale(1.0f);
|
ImGui::SetWindowFontScale(1.0f);
|
||||||
ImGui::PopStyleColor(3);
|
ImGui::PopStyleColor(3);
|
||||||
|
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::SetWindowFontScale(0.5f);
|
ImGui::SetWindowFontScale(0.5f);
|
||||||
ImGui::Text("%s", host_name.c_str());
|
ImGui::Text("%s", it->second.remote_host_name.c_str());
|
||||||
ImGui::SetWindowFontScale(1.0f);
|
ImGui::SetWindowFontScale(1.0f);
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
@@ -176,15 +176,8 @@ 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))) {
|
||||||
remote_id_ = remote_id;
|
ConnectTo(it->second.remote_id, it->second.password.c_str(),
|
||||||
|
it->second.remember_password);
|
||||||
bool remember_password_flag = false;
|
|
||||||
if (!password.empty() && password.size() == 6) {
|
|
||||||
remember_password_flag = true;
|
|
||||||
memcpy(remote_password_, password.c_str(), 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConnectTo(remote_id, remote_password_, remember_password_flag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::SetWindowFontScale(1.0f);
|
ImGui::SetWindowFontScale(1.0f);
|
||||||
|
|||||||
@@ -68,21 +68,44 @@ int Render::RemoteWindow() {
|
|||||||
|
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
std::string 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 (ImGui::Button(ICON_FA_ARROW_RIGHT_LONG, ImVec2(55, 38)) ||
|
if (ImGui::Button(ICON_FA_ARROW_RIGHT_LONG, ImVec2(55, 38)) ||
|
||||||
enter_pressed) {
|
enter_pressed) {
|
||||||
connect_button_pressed_ = true;
|
connect_button_pressed_ = true;
|
||||||
remote_id_ = remote_id_display_;
|
bool found = false;
|
||||||
remote_id_.erase(remove_if(remote_id_.begin(), remote_id_.end(),
|
for (auto &[id, props] : recent_connections_) {
|
||||||
static_cast<int (*)(int)>(&isspace)),
|
if (id.find(remote_id) != std::string::npos) {
|
||||||
remote_id_.end());
|
found = true;
|
||||||
ConnectTo(remote_id_, remote_password_, false);
|
if (client_properties_.find(remote_id) !=
|
||||||
|
client_properties_.end()) {
|
||||||
|
if (!client_properties_[remote_id]->connection_established_) {
|
||||||
|
ConnectTo(props.remote_id, props.password.c_str(), false);
|
||||||
|
} else {
|
||||||
|
// todo: show warning message
|
||||||
|
LOG_INFO("Already connected to [{}]", remote_id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ConnectTo(props.remote_id, props.password.c_str(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
ConnectTo(remote_id, "", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_properties_.find(remote_id_) != client_properties_.end()) {
|
if (need_to_rejoin_) {
|
||||||
auto props = client_properties_[remote_id_];
|
need_to_rejoin_ = false;
|
||||||
if (props->rejoin_) {
|
for (const auto &[_, props] : client_properties_) {
|
||||||
ConnectTo(remote_id_, remote_password_,
|
if (props->rejoin_) {
|
||||||
client_properties_[remote_id_]->remember_password_);
|
ConnectTo(props->remote_id_, props->remote_password_,
|
||||||
|
props->remember_password_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,13 +156,14 @@ int Render::ConnectTo(const std::string &remote_id, const char *password,
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
auto props = client_properties_[remote_id];
|
auto props = client_properties_[remote_id];
|
||||||
if (!props->connection_established_) {
|
if (!props->connection_established_) {
|
||||||
|
props->remember_password_ = remember_password;
|
||||||
|
memcpy(props->remote_password_, password, 6);
|
||||||
ret = JoinConnection(props->peer_, remote_id.c_str(), password);
|
ret = JoinConnection(props->peer_, remote_id.c_str(), password);
|
||||||
if (0 == ret) {
|
if (0 == ret) {
|
||||||
props->rejoin_ = false;
|
props->rejoin_ = false;
|
||||||
props->remember_password_ = remember_password;
|
|
||||||
memcpy(props->remote_password_, password, 6);
|
|
||||||
} else {
|
} else {
|
||||||
props->rejoin_ = true;
|
props->rejoin_ = true;
|
||||||
|
need_to_rejoin_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -527,6 +527,7 @@ int Render::CreateStreamWindow() {
|
|||||||
SDL_PushEvent(&event);
|
SDL_PushEvent(&event);
|
||||||
|
|
||||||
stream_window_created_ = true;
|
stream_window_created_ = true;
|
||||||
|
just_created_ = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -841,9 +842,9 @@ void Render::HandleRecentConnections() {
|
|||||||
if (reload_recent_connections_ && main_renderer_) {
|
if (reload_recent_connections_ && main_renderer_) {
|
||||||
uint32_t now_time = SDL_GetTicks();
|
uint32_t now_time = SDL_GetTicks();
|
||||||
if (now_time - recent_connection_image_save_time_ >= 50) {
|
if (now_time - recent_connection_image_save_time_ >= 50) {
|
||||||
int ret = thumbnail_->LoadThumbnail(
|
int ret = thumbnail_->LoadThumbnail(main_renderer_, recent_connections_,
|
||||||
main_renderer_, recent_connection_textures_,
|
&recent_connection_image_width_,
|
||||||
&recent_connection_image_width_, &recent_connection_image_height_);
|
&recent_connection_image_height_);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
LOG_INFO("Load recent connection thumbnails");
|
LOG_INFO("Load recent connection thumbnails");
|
||||||
}
|
}
|
||||||
@@ -1029,51 +1030,55 @@ void Render::ProcessSdlEvent() {
|
|||||||
} else if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED &&
|
} else if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED &&
|
||||||
stream_window_created_ &&
|
stream_window_created_ &&
|
||||||
event.window.windowID == SDL_GetWindowID(stream_window_)) {
|
event.window.windowID == SDL_GetWindowID(stream_window_)) {
|
||||||
for (auto& [_, props] : client_properties_) {
|
if (just_created_) {
|
||||||
if (!props->reset_control_bar_pos_) {
|
just_created_ = false;
|
||||||
props->mouse_diff_control_bar_pos_x_ = 0;
|
} else {
|
||||||
props->mouse_diff_control_bar_pos_y_ = 0;
|
for (auto& [_, props] : client_properties_) {
|
||||||
}
|
if (!props->reset_control_bar_pos_) {
|
||||||
|
props->mouse_diff_control_bar_pos_x_ = 0;
|
||||||
|
props->mouse_diff_control_bar_pos_y_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
props->reset_control_bar_pos_ = true;
|
props->reset_control_bar_pos_ = true;
|
||||||
int stream_window_width, stream_window_height;
|
int stream_window_width, stream_window_height;
|
||||||
SDL_GetWindowSize(stream_window_, &stream_window_width,
|
SDL_GetWindowSize(stream_window_, &stream_window_width,
|
||||||
&stream_window_height);
|
&stream_window_height);
|
||||||
stream_window_width_ = (float)stream_window_width;
|
stream_window_width_ = (float)stream_window_width;
|
||||||
stream_window_height_ = (float)stream_window_height;
|
stream_window_height_ = (float)stream_window_height;
|
||||||
|
|
||||||
float video_ratio =
|
float video_ratio =
|
||||||
(float)props->video_width_ / (float)props->video_height_;
|
(float)props->video_width_ / (float)props->video_height_;
|
||||||
float video_ratio_reverse =
|
float video_ratio_reverse =
|
||||||
(float)props->video_height_ / (float)props->video_width_;
|
(float)props->video_height_ / (float)props->video_width_;
|
||||||
|
|
||||||
float render_area_width = stream_window_width_;
|
float render_area_width = stream_window_width_;
|
||||||
float render_area_height =
|
float render_area_height =
|
||||||
stream_window_height_ -
|
stream_window_height_ -
|
||||||
(fullscreen_button_pressed_ ? 0 : title_bar_height_);
|
(fullscreen_button_pressed_ ? 0 : title_bar_height_);
|
||||||
|
|
||||||
props->stream_render_rect_last_ = props->stream_render_rect_;
|
props->stream_render_rect_last_ = props->stream_render_rect_;
|
||||||
if (render_area_width < render_area_height * video_ratio) {
|
if (render_area_width < render_area_height * video_ratio) {
|
||||||
props->stream_render_rect_ = {
|
props->stream_render_rect_ = {
|
||||||
0,
|
0,
|
||||||
(int)(abs(render_area_height -
|
(int)(abs(render_area_height -
|
||||||
render_area_width * video_ratio_reverse) /
|
render_area_width * video_ratio_reverse) /
|
||||||
2 +
|
2 +
|
||||||
(fullscreen_button_pressed_ ? 0 : title_bar_height_)),
|
(fullscreen_button_pressed_ ? 0 : title_bar_height_)),
|
||||||
(int)render_area_width,
|
(int)render_area_width,
|
||||||
(int)(render_area_width * video_ratio_reverse)};
|
(int)(render_area_width * video_ratio_reverse)};
|
||||||
} else if (render_area_width > render_area_height * video_ratio) {
|
} else if (render_area_width > render_area_height * video_ratio) {
|
||||||
props->stream_render_rect_ = {
|
props->stream_render_rect_ = {
|
||||||
(int)abs(render_area_width -
|
(int)abs(render_area_width -
|
||||||
render_area_height * video_ratio) /
|
render_area_height * video_ratio) /
|
||||||
2,
|
2,
|
||||||
fullscreen_button_pressed_ ? 0 : (int)title_bar_height_,
|
fullscreen_button_pressed_ ? 0 : (int)title_bar_height_,
|
||||||
(int)(render_area_height * video_ratio),
|
(int)(render_area_height * video_ratio),
|
||||||
(int)render_area_height};
|
(int)render_area_height};
|
||||||
} else {
|
} else {
|
||||||
props->stream_render_rect_ = {
|
props->stream_render_rect_ = {
|
||||||
0, fullscreen_button_pressed_ ? 0 : (int)title_bar_height_,
|
0, fullscreen_button_pressed_ ? 0 : (int)title_bar_height_,
|
||||||
(int)render_area_width, (int)render_area_height};
|
(int)render_area_width, (int)render_area_height};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED ||
|
} else if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED ||
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ class Render {
|
|||||||
std::unique_ptr<Thumbnail> thumbnail_;
|
std::unique_ptr<Thumbnail> thumbnail_;
|
||||||
|
|
||||||
// recent connections
|
// recent connections
|
||||||
std::map<std::string, SDL_Texture *> recent_connection_textures_;
|
std::map<std::string, Thumbnail::RecentConnection> recent_connections_;
|
||||||
int recent_connection_image_width_ = 160;
|
int recent_connection_image_width_ = 160;
|
||||||
int recent_connection_image_height_ = 90;
|
int recent_connection_image_height_ = 90;
|
||||||
uint32_t recent_connection_image_save_time_ = 0;
|
uint32_t recent_connection_image_save_time_ = 0;
|
||||||
@@ -296,13 +296,13 @@ class Render {
|
|||||||
char input_password_tmp_[7] = "";
|
char input_password_tmp_[7] = "";
|
||||||
char input_password_[7] = "";
|
char input_password_[7] = "";
|
||||||
std::string random_password_ = "";
|
std::string random_password_ = "";
|
||||||
char remote_password_[7] = "";
|
|
||||||
char new_password_[7] = "";
|
char new_password_[7] = "";
|
||||||
char remote_id_display_[12] = "";
|
char remote_id_display_[12] = "";
|
||||||
std::string remote_id_ = "";
|
|
||||||
unsigned char audio_buffer_[720];
|
unsigned char audio_buffer_[720];
|
||||||
int audio_len_ = 0;
|
int audio_len_ = 0;
|
||||||
bool audio_buffer_fresh_ = false;
|
bool audio_buffer_fresh_ = false;
|
||||||
|
bool need_to_rejoin_ = false;
|
||||||
|
bool just_created_ = false;
|
||||||
|
|
||||||
// stream window render
|
// stream window render
|
||||||
SDL_Window *stream_window_ = nullptr;
|
SDL_Window *stream_window_ = nullptr;
|
||||||
|
|||||||
@@ -359,9 +359,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, const char *user_id,
|
|||||||
render->StopSpeakerCapturer();
|
render->StopSpeakerCapturer();
|
||||||
render->audio_capture_ = false;
|
render->audio_capture_ = false;
|
||||||
}
|
}
|
||||||
if (!render->rejoin_) {
|
|
||||||
memset(render->remote_password_, 0, sizeof(render->remote_password_));
|
|
||||||
}
|
|
||||||
if (props->dst_buffer_) {
|
if (props->dst_buffer_) {
|
||||||
memset(props->dst_buffer_, 0, props->dst_buffer_capacity_);
|
memset(props->dst_buffer_, 0, props->dst_buffer_capacity_);
|
||||||
SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_,
|
SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_,
|
||||||
|
|||||||
@@ -23,6 +23,65 @@
|
|||||||
|
|
||||||
static std::string test;
|
static std::string test;
|
||||||
|
|
||||||
|
bool LoadTextureFromMemory(const void* data, size_t data_size,
|
||||||
|
SDL_Renderer* renderer, SDL_Texture** out_texture,
|
||||||
|
int* out_width, int* out_height) {
|
||||||
|
int image_width = 0;
|
||||||
|
int image_height = 0;
|
||||||
|
int channels = 4;
|
||||||
|
unsigned char* image_data =
|
||||||
|
stbi_load_from_memory((const unsigned char*)data, (int)data_size,
|
||||||
|
&image_width, &image_height, NULL, 4);
|
||||||
|
if (image_data == nullptr) {
|
||||||
|
LOG_ERROR("Failed to load image: [{}]", stbi_failure_reason());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABGR
|
||||||
|
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(
|
||||||
|
(void*)image_data, image_width, image_height, channels * 8,
|
||||||
|
channels * image_width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||||
|
if (surface == nullptr) {
|
||||||
|
LOG_ERROR("Failed to create SDL surface: [{}]", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||||
|
if (texture == nullptr) {
|
||||||
|
LOG_ERROR("Failed to create SDL texture: [{}]", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_texture = texture;
|
||||||
|
*out_width = image_width;
|
||||||
|
*out_height = image_height;
|
||||||
|
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
stbi_image_free(image_data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadTextureFromFile(const char* file_name, SDL_Renderer* renderer,
|
||||||
|
SDL_Texture** out_texture, int* out_width,
|
||||||
|
int* out_height) {
|
||||||
|
std::filesystem::path file_path(file_name);
|
||||||
|
if (!std::filesystem::exists(file_path)) return false;
|
||||||
|
std::ifstream file(file_path, std::ios::binary);
|
||||||
|
if (!file) return false;
|
||||||
|
file.seekg(0, std::ios::end);
|
||||||
|
size_t file_size = file.tellg();
|
||||||
|
file.seekg(0, std::ios::beg);
|
||||||
|
if (file_size == -1) return false;
|
||||||
|
char* file_data = new char[file_size];
|
||||||
|
if (!file_data) return false;
|
||||||
|
file.read(file_data, file_size);
|
||||||
|
bool ret = LoadTextureFromMemory(file_data, file_size, renderer, out_texture,
|
||||||
|
out_width, out_height);
|
||||||
|
delete[] file_data;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void ScaleYUV420pToABGR(char* dst_buffer_, int video_width_, int video_height_,
|
void ScaleYUV420pToABGR(char* dst_buffer_, int video_width_, int video_height_,
|
||||||
int scaled_video_width_, int scaled_video_height_,
|
int scaled_video_width_, int scaled_video_height_,
|
||||||
char* rgba_buffer_) {
|
char* rgba_buffer_) {
|
||||||
@@ -87,7 +146,7 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
|
|||||||
|
|
||||||
std::string image_name;
|
std::string image_name;
|
||||||
if (password.empty()) {
|
if (password.empty()) {
|
||||||
image_name = remote_id + 'N' + host_name;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// delete the file which has no password in its name
|
// delete the file which has no password in its name
|
||||||
std::string filename_without_password = remote_id + "N" + host_name;
|
std::string filename_without_password = remote_id + "N" + host_name;
|
||||||
@@ -104,63 +163,49 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadTextureFromMemory(const void* data, size_t data_size,
|
int Thumbnail::LoadThumbnail(
|
||||||
SDL_Renderer* renderer, SDL_Texture** out_texture,
|
SDL_Renderer* renderer,
|
||||||
int* out_width, int* out_height) {
|
std::map<std::string, RecentConnection>& recent_connections, int* width,
|
||||||
int image_width = 0;
|
int* height) {
|
||||||
int image_height = 0;
|
for (auto& it : recent_connections) {
|
||||||
int channels = 4;
|
if (it.second.texture != nullptr) {
|
||||||
unsigned char* image_data =
|
SDL_DestroyTexture(it.second.texture);
|
||||||
stbi_load_from_memory((const unsigned char*)data, (int)data_size,
|
it.second.texture = nullptr;
|
||||||
&image_width, &image_height, NULL, 4);
|
}
|
||||||
if (image_data == nullptr) {
|
|
||||||
LOG_ERROR("Failed to load image: [{}]", stbi_failure_reason());
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
recent_connections.clear();
|
||||||
|
|
||||||
// ABGR
|
std::vector<std::filesystem::path> image_paths =
|
||||||
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(
|
FindThumbnailPath(image_path_);
|
||||||
(void*)image_data, image_width, image_height, channels * 8,
|
|
||||||
channels * image_width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
if (image_paths.size() == 0) {
|
||||||
if (surface == nullptr) {
|
return -1;
|
||||||
LOG_ERROR("Failed to create SDL surface: [{}]", SDL_GetError());
|
} else {
|
||||||
return false;
|
for (int i = 0; i < image_paths.size(); i++) {
|
||||||
|
size_t pos1 = image_paths[i].string().find('/') + 1;
|
||||||
|
std::string cipher_image_name = image_paths[i].string().substr(pos1);
|
||||||
|
std::string original_image_name =
|
||||||
|
AES_decrypt(cipher_image_name, aes128_key_, aes128_iv_);
|
||||||
|
std::string image_path = image_path_ + cipher_image_name;
|
||||||
|
recent_connections[original_image_name].texture = nullptr;
|
||||||
|
LoadTextureFromFile(image_path.c_str(), renderer,
|
||||||
|
&(recent_connections[original_image_name].texture),
|
||||||
|
width, height);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
||||||
if (texture == nullptr) {
|
|
||||||
LOG_ERROR("Failed to create SDL texture: [{}]", SDL_GetError());
|
|
||||||
}
|
|
||||||
|
|
||||||
*out_texture = texture;
|
|
||||||
*out_width = image_width;
|
|
||||||
*out_height = image_height;
|
|
||||||
|
|
||||||
SDL_FreeSurface(surface);
|
|
||||||
stbi_image_free(image_data);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadTextureFromFile(const char* file_name, SDL_Renderer* renderer,
|
int Thumbnail::DeleteThumbnail(const std::string& file_name) {
|
||||||
SDL_Texture** out_texture, int* out_width,
|
std::string ciphertext = AES_encrypt(file_name, aes128_key_, aes128_iv_);
|
||||||
int* out_height) {
|
std::string file_path = image_path_ + ciphertext;
|
||||||
std::filesystem::path file_path(file_name);
|
if (std::filesystem::exists(file_path)) {
|
||||||
if (!std::filesystem::exists(file_path)) return false;
|
std::filesystem::remove(file_path);
|
||||||
std::ifstream file(file_path, std::ios::binary);
|
return 0;
|
||||||
if (!file) return false;
|
} else {
|
||||||
file.seekg(0, std::ios::end);
|
return -1;
|
||||||
size_t file_size = file.tellg();
|
}
|
||||||
file.seekg(0, std::ios::beg);
|
|
||||||
if (file_size == -1) return false;
|
|
||||||
char* file_data = new char[file_size];
|
|
||||||
if (!file_data) return false;
|
|
||||||
file.read(file_data, file_size);
|
|
||||||
bool ret = LoadTextureFromMemory(file_data, file_size, renderer, out_texture,
|
|
||||||
out_width, out_height);
|
|
||||||
delete[] file_data;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::filesystem::path> Thumbnail::FindThumbnailPath(
|
std::vector<std::filesystem::path> Thumbnail::FindThumbnailPath(
|
||||||
@@ -194,49 +239,6 @@ std::vector<std::filesystem::path> Thumbnail::FindThumbnailPath(
|
|||||||
return thumbnails_path;
|
return thumbnails_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_);
|
|
||||||
|
|
||||||
if (image_paths.size() == 0) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < image_paths.size(); i++) {
|
|
||||||
size_t pos1 = image_paths[i].string().find('/') + 1;
|
|
||||||
std::string cipher_image_name = image_paths[i].string().substr(pos1);
|
|
||||||
std::string original_image_name =
|
|
||||||
AES_decrypt(cipher_image_name, aes128_key_, aes128_iv_);
|
|
||||||
std::string image_path = image_path_ + cipher_image_name;
|
|
||||||
textures[original_image_name] = nullptr;
|
|
||||||
LoadTextureFromFile(image_path.c_str(), renderer,
|
|
||||||
&(textures[original_image_name]), width, height);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Thumbnail::DeleteThumbnail(const std::string& file_name) {
|
|
||||||
std::string ciphertext = AES_encrypt(file_name, aes128_key_, aes128_iv_);
|
|
||||||
std::string file_path = image_path_ + ciphertext;
|
|
||||||
if (std::filesystem::exists(file_path)) {
|
|
||||||
std::filesystem::remove(file_path);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Thumbnail::DeleteAllFilesInDirectory() {
|
int Thumbnail::DeleteAllFilesInDirectory() {
|
||||||
if (std::filesystem::exists(image_path_) &&
|
if (std::filesystem::exists(image_path_) &&
|
||||||
std::filesystem::is_directory(image_path_)) {
|
std::filesystem::is_directory(image_path_)) {
|
||||||
|
|||||||
@@ -13,6 +13,15 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class Thumbnail {
|
class Thumbnail {
|
||||||
|
public:
|
||||||
|
struct RecentConnection {
|
||||||
|
SDL_Texture* texture = nullptr;
|
||||||
|
std::string remote_id;
|
||||||
|
std::string remote_host_name;
|
||||||
|
std::string password;
|
||||||
|
bool remember_password = false;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Thumbnail();
|
Thumbnail();
|
||||||
explicit Thumbnail(unsigned char* aes128_key, unsigned char* aes128_iv);
|
explicit Thumbnail(unsigned char* aes128_key, unsigned char* aes128_iv);
|
||||||
@@ -25,8 +34,8 @@ class Thumbnail {
|
|||||||
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, RecentConnection>& recent_connections,
|
||||||
int* height);
|
int* width, int* height);
|
||||||
|
|
||||||
int DeleteThumbnail(const std::string& file_name);
|
int DeleteThumbnail(const std::string& file_name);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user