mirror of
				https://github.com/kunkundi/crossdesk.git
				synced 2025-10-26 20:25:34 +08:00 
			
		
		
		
	[feat] use client_properties_ and server_properties_ to store streams properties
This commit is contained in:
		| @@ -3,7 +3,8 @@ | |||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
|  |  | ||||||
| int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { | int Render::ConnectionStatusWindow( | ||||||
|  |     std::shared_ptr<SubStreamWindowProperties> &properties) { | ||||||
|   if (show_connection_status_window_) { |   if (show_connection_status_window_) { | ||||||
|     const ImGuiViewport *viewport = ImGui::GetMainViewport(); |     const ImGuiViewport *viewport = ImGui::GetMainViewport(); | ||||||
|  |  | ||||||
| @@ -33,11 +34,11 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { | |||||||
|     ImGui::SetWindowFontScale(0.5f); |     ImGui::SetWindowFontScale(0.5f); | ||||||
|     std::string text; |     std::string text; | ||||||
|  |  | ||||||
|     if (ConnectionStatus::Connecting == properties.connection_status_) { |     if (ConnectionStatus::Connecting == properties->connection_status_) { | ||||||
|       text = localization::p2p_connecting[localization_language_index_]; |       text = localization::p2p_connecting[localization_language_index_]; | ||||||
|       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); |       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); | ||||||
|       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); |       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); | ||||||
|     } else if (ConnectionStatus::Connected == properties.connection_status_) { |     } else if (ConnectionStatus::Connected == properties->connection_status_) { | ||||||
|       text = localization::p2p_connected[localization_language_index_]; |       text = localization::p2p_connected[localization_language_index_]; | ||||||
|       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); |       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); | ||||||
|       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); |       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); | ||||||
| @@ -49,7 +50,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { | |||||||
|         show_connection_status_window_ = false; |         show_connection_status_window_ = false; | ||||||
|       } |       } | ||||||
|     } else if (ConnectionStatus::Disconnected == |     } else if (ConnectionStatus::Disconnected == | ||||||
|                properties.connection_status_) { |                properties->connection_status_) { | ||||||
|       text = localization::p2p_disconnected[localization_language_index_]; |       text = localization::p2p_disconnected[localization_language_index_]; | ||||||
|       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); |       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); | ||||||
|       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); |       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); | ||||||
| @@ -60,7 +61,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { | |||||||
|           ImGui::IsKeyPressed(ImGuiKey_Escape)) { |           ImGui::IsKeyPressed(ImGuiKey_Escape)) { | ||||||
|         show_connection_status_window_ = false; |         show_connection_status_window_ = false; | ||||||
|       } |       } | ||||||
|     } else if (ConnectionStatus::Failed == properties.connection_status_) { |     } else if (ConnectionStatus::Failed == properties->connection_status_) { | ||||||
|       text = localization::p2p_failed[localization_language_index_]; |       text = localization::p2p_failed[localization_language_index_]; | ||||||
|       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); |       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); | ||||||
|       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); |       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); | ||||||
| @@ -71,7 +72,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { | |||||||
|           ImGui::IsKeyPressed(ImGuiKey_Escape)) { |           ImGui::IsKeyPressed(ImGuiKey_Escape)) { | ||||||
|         show_connection_status_window_ = false; |         show_connection_status_window_ = false; | ||||||
|       } |       } | ||||||
|     } else if (ConnectionStatus::Closed == properties.connection_status_) { |     } else if (ConnectionStatus::Closed == properties->connection_status_) { | ||||||
|       text = localization::p2p_closed[localization_language_index_]; |       text = localization::p2p_closed[localization_language_index_]; | ||||||
|       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); |       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); | ||||||
|       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); |       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); | ||||||
| @@ -83,7 +84,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { | |||||||
|         show_connection_status_window_ = false; |         show_connection_status_window_ = false; | ||||||
|       } |       } | ||||||
|     } else if (ConnectionStatus::IncorrectPassword == |     } else if (ConnectionStatus::IncorrectPassword == | ||||||
|                properties.connection_status_) { |                properties->connection_status_) { | ||||||
|       if (!password_validating_) { |       if (!password_validating_) { | ||||||
|         if (password_validating_time_ == 1) { |         if (password_validating_time_ == 1) { | ||||||
|           text = localization::input_password[localization_language_index_]; |           text = localization::input_password[localization_language_index_]; | ||||||
| @@ -117,7 +118,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { | |||||||
|         ImGui::Checkbox( |         ImGui::Checkbox( | ||||||
|             localization::remember_password[localization_language_index_] |             localization::remember_password[localization_language_index_] | ||||||
|                 .c_str(), |                 .c_str(), | ||||||
|             &remember_password_); |             &(properties->remember_password_)); | ||||||
|         ImGui::SetWindowFontScale(0.5f); |         ImGui::SetWindowFontScale(0.5f); | ||||||
|         ImGui::PopStyleVar(); |         ImGui::PopStyleVar(); | ||||||
|  |  | ||||||
| @@ -148,7 +149,7 @@ int Render::ConnectionStatusWindow(SubStreamWindowProperties &properties) { | |||||||
|         ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); |         ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); | ||||||
|       } |       } | ||||||
|     } else if (ConnectionStatus::NoSuchTransmissionId == |     } else if (ConnectionStatus::NoSuchTransmissionId == | ||||||
|                properties.connection_status_) { |                properties->connection_status_) { | ||||||
|       text = localization::no_such_id[localization_language_index_]; |       text = localization::no_such_id[localization_language_index_]; | ||||||
|       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); |       ImGui::SetCursorPosX(connection_status_window_width_ * 3 / 7); | ||||||
|       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); |       ImGui::SetCursorPosY(connection_status_window_height_ * 2 / 3); | ||||||
|   | |||||||
| @@ -29,46 +29,45 @@ int LossRateDisplay(float loss_rate) { | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int Render::ControlBar(SubStreamWindowProperties& properties) { | int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& properties) { | ||||||
|   ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); |   ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); | ||||||
|  |  | ||||||
|   ImVec2 mouse_button_pos = ImVec2(0, 0); |   ImVec2 mouse_button_pos = ImVec2(0, 0); | ||||||
|   if (properties.control_bar_expand_) { |   if (properties->control_bar_expand_) { | ||||||
|     ImGui::SetCursorPosX(properties.is_control_bar_in_left_ |     ImGui::SetCursorPosX(properties->is_control_bar_in_left_ | ||||||
|                              ? (properties.control_window_width_ + 5.0f) |                              ? (properties->control_window_width_ + 5.0f) | ||||||
|                              : 38.0f); |                              : 38.0f); | ||||||
|     // mouse control button |     // mouse control button | ||||||
|     ImDrawList* draw_list = ImGui::GetWindowDrawList(); |     ImDrawList* draw_list = ImGui::GetWindowDrawList(); | ||||||
|  |  | ||||||
|     if (properties.is_control_bar_in_left_) { |     if (properties->is_control_bar_in_left_) { | ||||||
|       draw_list->AddLine(ImVec2(ImGui::GetCursorScreenPos().x - 5.0f, |       draw_list->AddLine(ImVec2(ImGui::GetCursorScreenPos().x - 5.0f, | ||||||
|                                 ImGui::GetCursorScreenPos().y - 7.0f), |                                 ImGui::GetCursorScreenPos().y - 7.0f), | ||||||
|                          ImVec2(ImGui::GetCursorScreenPos().x - 5.0f, |                          ImVec2(ImGui::GetCursorScreenPos().x - 5.0f, | ||||||
|                                 ImGui::GetCursorScreenPos().y - 7.0f + |                                 ImGui::GetCursorScreenPos().y - 7.0f + | ||||||
|                                     properties.control_window_height_), |                                     properties->control_window_height_), | ||||||
|                          IM_COL32(178, 178, 178, 255), 1.0f); |                          IM_COL32(178, 178, 178, 255), 1.0f); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     mouse_button_pos = ImGui::GetCursorScreenPos(); |     mouse_button_pos = ImGui::GetCursorScreenPos(); | ||||||
|     float disable_mouse_x = ImGui::GetCursorScreenPos().x + 4.0f; |     float disable_mouse_x = ImGui::GetCursorScreenPos().x + 4.0f; | ||||||
|     float disable_mouse_y = ImGui::GetCursorScreenPos().y + 4.0f; |     float disable_mouse_y = ImGui::GetCursorScreenPos().y + 4.0f; | ||||||
|     std::string mouse = properties.mouse_control_button_pressed_ |     std::string mouse = properties->mouse_control_button_pressed_ | ||||||
|                             ? ICON_FA_COMPUTER_MOUSE |                             ? ICON_FA_COMPUTER_MOUSE | ||||||
|                             : ICON_FA_COMPUTER_MOUSE; |                             : ICON_FA_COMPUTER_MOUSE; | ||||||
|     if (ImGui::Button(mouse.c_str(), ImVec2(25, 25))) { |     if (ImGui::Button(mouse.c_str(), ImVec2(25, 25))) { | ||||||
|       if (properties.connection_established_) { |       if (properties->connection_established_) { | ||||||
|         properties.control_mouse_ = !properties.control_mouse_; |         control_mouse_ = !control_mouse_; | ||||||
|         properties.start_keyboard_capturer_ = |         start_keyboard_capturer_ = !start_keyboard_capturer_; | ||||||
|             !properties.start_keyboard_capturer_; |         properties->mouse_control_button_pressed_ = | ||||||
|         properties.mouse_control_button_pressed_ = |             !properties->mouse_control_button_pressed_; | ||||||
|             !properties.mouse_control_button_pressed_; |         properties->mouse_control_button_label_ = | ||||||
|         properties.mouse_control_button_label_ = |             properties->mouse_control_button_pressed_ | ||||||
|             properties.mouse_control_button_pressed_ |  | ||||||
|                 ? localization::release_mouse[localization_language_index_] |                 ? localization::release_mouse[localization_language_index_] | ||||||
|                 : localization::control_mouse[localization_language_index_]; |                 : localization::control_mouse[localization_language_index_]; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     if (!properties.mouse_control_button_pressed_) { |     if (!properties->mouse_control_button_pressed_) { | ||||||
|       draw_list->AddLine( |       draw_list->AddLine( | ||||||
|           ImVec2(disable_mouse_x, disable_mouse_y), |           ImVec2(disable_mouse_x, disable_mouse_y), | ||||||
|           ImVec2(disable_mouse_x + 16.0f, disable_mouse_y + 14.2f), |           ImVec2(disable_mouse_x + 16.0f, disable_mouse_y + 14.2f), | ||||||
| @@ -87,27 +86,26 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { | |||||||
|     float disable_audio_y = ImGui::GetCursorScreenPos().y + 4.0f; |     float disable_audio_y = ImGui::GetCursorScreenPos().y + 4.0f; | ||||||
|     // std::string audio = audio_capture_button_pressed_ ? ICON_FA_VOLUME_HIGH |     // std::string audio = audio_capture_button_pressed_ ? ICON_FA_VOLUME_HIGH | ||||||
|     //                                                   : ICON_FA_VOLUME_XMARK; |     //                                                   : ICON_FA_VOLUME_XMARK; | ||||||
|     std::string audio = properties.audio_capture_button_pressed_ |     std::string audio = properties->audio_capture_button_pressed_ | ||||||
|                             ? ICON_FA_VOLUME_HIGH |                             ? ICON_FA_VOLUME_HIGH | ||||||
|                             : ICON_FA_VOLUME_HIGH; |                             : ICON_FA_VOLUME_HIGH; | ||||||
|     if (ImGui::Button(audio.c_str(), ImVec2(25, 25))) { |     if (ImGui::Button(audio.c_str(), ImVec2(25, 25))) { | ||||||
|       if (properties.connection_established_) { |       if (properties->connection_established_) { | ||||||
|         properties.audio_capture_ = !properties.audio_capture_; |         properties->audio_capture_button_pressed_ = | ||||||
|         properties.audio_capture_button_pressed_ = |             !properties->audio_capture_button_pressed_; | ||||||
|             !properties.audio_capture_button_pressed_; |         properties->audio_capture_button_label_ = | ||||||
|         properties.audio_capture_button_label_ = |             properties->audio_capture_button_pressed_ | ||||||
|             properties.audio_capture_button_pressed_ |  | ||||||
|                 ? localization::audio_capture[localization_language_index_] |                 ? localization::audio_capture[localization_language_index_] | ||||||
|                 : localization::mute[localization_language_index_]; |                 : localization::mute[localization_language_index_]; | ||||||
|  |  | ||||||
|         RemoteAction remote_action; |         RemoteAction remote_action; | ||||||
|         remote_action.type = ControlType::audio_capture; |         remote_action.type = ControlType::audio_capture; | ||||||
|         remote_action.a = properties.audio_capture_button_pressed_; |         remote_action.a = properties->audio_capture_button_pressed_; | ||||||
|         SendDataFrame(peer_, (const char*)&remote_action, |         SendDataFrame(peer_, (const char*)&remote_action, | ||||||
|                       sizeof(remote_action)); |                       sizeof(remote_action)); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     if (!properties.audio_capture_button_pressed_) { |     if (!properties->audio_capture_button_pressed_) { | ||||||
|       draw_list->AddLine( |       draw_list->AddLine( | ||||||
|           ImVec2(disable_audio_x, disable_audio_y), |           ImVec2(disable_audio_x, disable_audio_y), | ||||||
|           ImVec2(disable_audio_x + 16.0f, disable_audio_y + 14.2f), |           ImVec2(disable_audio_x + 16.0f, disable_audio_y + 14.2f), | ||||||
| @@ -123,19 +121,19 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { | |||||||
|     ImGui::SameLine(); |     ImGui::SameLine(); | ||||||
|     // net traffic stats button |     // net traffic stats button | ||||||
|     bool button_color_style_pushed = false; |     bool button_color_style_pushed = false; | ||||||
|     if (properties.net_traffic_stats_button_pressed_) { |     if (properties->net_traffic_stats_button_pressed_) { | ||||||
|       ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(66 / 255.0f, 150 / 255.0f, |       ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(66 / 255.0f, 150 / 255.0f, | ||||||
|                                                     250 / 255.0f, 1.0f)); |                                                     250 / 255.0f, 1.0f)); | ||||||
|       button_color_style_pushed = true; |       button_color_style_pushed = true; | ||||||
|     } |     } | ||||||
|     std::string net_traffic_stats = ICON_FA_SIGNAL; |     std::string net_traffic_stats = ICON_FA_SIGNAL; | ||||||
|     if (ImGui::Button(net_traffic_stats.c_str(), ImVec2(25, 25))) { |     if (ImGui::Button(net_traffic_stats.c_str(), ImVec2(25, 25))) { | ||||||
|       properties.net_traffic_stats_button_pressed_ = |       properties->net_traffic_stats_button_pressed_ = | ||||||
|           !properties.net_traffic_stats_button_pressed_; |           !properties->net_traffic_stats_button_pressed_; | ||||||
|       properties.control_window_height_is_changing_ = true; |       properties->control_window_height_is_changing_ = true; | ||||||
|       properties.net_traffic_stats_button_pressed_time_ = ImGui::GetTime(); |       properties->net_traffic_stats_button_pressed_time_ = ImGui::GetTime(); | ||||||
|       properties.net_traffic_stats_button_label_ = |       properties->net_traffic_stats_button_label_ = | ||||||
|           properties.net_traffic_stats_button_pressed_ |           properties->net_traffic_stats_button_pressed_ | ||||||
|               ? localization::hide_net_traffic_stats |               ? localization::hide_net_traffic_stats | ||||||
|                     [localization_language_index_] |                     [localization_language_index_] | ||||||
|               : localization::show_net_traffic_stats |               : localization::show_net_traffic_stats | ||||||
| @@ -152,7 +150,7 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { | |||||||
|         fullscreen_button_pressed_ ? ICON_FA_COMPRESS : ICON_FA_EXPAND; |         fullscreen_button_pressed_ ? ICON_FA_COMPRESS : ICON_FA_EXPAND; | ||||||
|     if (ImGui::Button(fullscreen.c_str(), ImVec2(25, 25))) { |     if (ImGui::Button(fullscreen.c_str(), ImVec2(25, 25))) { | ||||||
|       fullscreen_button_pressed_ = !fullscreen_button_pressed_; |       fullscreen_button_pressed_ = !fullscreen_button_pressed_; | ||||||
|       properties.fullscreen_button_label_ = |       properties->fullscreen_button_label_ = | ||||||
|           fullscreen_button_pressed_ |           fullscreen_button_pressed_ | ||||||
|               ? localization::exit_fullscreen[localization_language_index_] |               ? localization::exit_fullscreen[localization_language_index_] | ||||||
|               : localization::fullscreen[localization_language_index_]; |               : localization::fullscreen[localization_language_index_]; | ||||||
| @@ -162,7 +160,7 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { | |||||||
|       } else { |       } else { | ||||||
|         SDL_SetWindowFullscreen(stream_window_, SDL_FALSE); |         SDL_SetWindowFullscreen(stream_window_, SDL_FALSE); | ||||||
|       } |       } | ||||||
|       properties.reset_control_bar_pos_ = true; |       properties->reset_control_bar_pos_ = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ImGui::SameLine(); |     ImGui::SameLine(); | ||||||
| @@ -176,39 +174,39 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { | |||||||
|  |  | ||||||
|     ImGui::SameLine(); |     ImGui::SameLine(); | ||||||
|  |  | ||||||
|     if (!properties.is_control_bar_in_left_) { |     if (!properties->is_control_bar_in_left_) { | ||||||
|       draw_list->AddLine(ImVec2(ImGui::GetCursorScreenPos().x - 3.0f, |       draw_list->AddLine(ImVec2(ImGui::GetCursorScreenPos().x - 3.0f, | ||||||
|                                 ImGui::GetCursorScreenPos().y - 7.0f), |                                 ImGui::GetCursorScreenPos().y - 7.0f), | ||||||
|                          ImVec2(ImGui::GetCursorScreenPos().x - 3.0f, |                          ImVec2(ImGui::GetCursorScreenPos().x - 3.0f, | ||||||
|                                 ImGui::GetCursorScreenPos().y - 7.0f + |                                 ImGui::GetCursorScreenPos().y - 7.0f + | ||||||
|                                     properties.control_window_height_), |                                     properties->control_window_height_), | ||||||
|                          IM_COL32(178, 178, 178, 255), 1.0f); |                          IM_COL32(178, 178, 178, 255), 1.0f); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ImGui::SetCursorPosX(properties.is_control_bar_in_left_ |   ImGui::SetCursorPosX(properties->is_control_bar_in_left_ | ||||||
|                            ? (properties.control_window_width_ * 2 - 20.0f) |                            ? (properties->control_window_width_ * 2 - 20.0f) | ||||||
|                            : 5.0f); |                            : 5.0f); | ||||||
|  |  | ||||||
|   std::string control_bar = |   std::string control_bar = | ||||||
|       properties.control_bar_expand_ |       properties->control_bar_expand_ | ||||||
|           ? (properties.is_control_bar_in_left_ ? ICON_FA_ANGLE_LEFT |           ? (properties->is_control_bar_in_left_ ? ICON_FA_ANGLE_LEFT | ||||||
|                                                 : ICON_FA_ANGLE_RIGHT) |                                                  : ICON_FA_ANGLE_RIGHT) | ||||||
|           : (properties.is_control_bar_in_left_ ? ICON_FA_ANGLE_RIGHT |           : (properties->is_control_bar_in_left_ ? ICON_FA_ANGLE_RIGHT | ||||||
|                                                 : ICON_FA_ANGLE_LEFT); |                                                  : ICON_FA_ANGLE_LEFT); | ||||||
|   if (ImGui::Button(control_bar.c_str(), ImVec2(15, 25))) { |   if (ImGui::Button(control_bar.c_str(), ImVec2(15, 25))) { | ||||||
|     properties.control_bar_expand_ = !properties.control_bar_expand_; |     properties->control_bar_expand_ = !properties->control_bar_expand_; | ||||||
|     properties.control_bar_button_pressed_time_ = ImGui::GetTime(); |     properties->control_bar_button_pressed_time_ = ImGui::GetTime(); | ||||||
|     properties.control_window_width_is_changing_ = true; |     properties->control_window_width_is_changing_ = true; | ||||||
|  |  | ||||||
|     if (!properties.control_bar_expand_) { |     if (!properties->control_bar_expand_) { | ||||||
|       properties.control_window_height_ = 40; |       properties->control_window_height_ = 40; | ||||||
|       properties.net_traffic_stats_button_pressed_ = false; |       properties->net_traffic_stats_button_pressed_ = false; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (properties.net_traffic_stats_button_pressed_ && |   if (properties->net_traffic_stats_button_pressed_ && | ||||||
|       properties.control_bar_expand_) { |       properties->control_bar_expand_) { | ||||||
|     NetTrafficStats(properties); |     NetTrafficStats(properties); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -217,16 +215,17 @@ int Render::ControlBar(SubStreamWindowProperties& properties) { | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int Render::NetTrafficStats(SubStreamWindowProperties& properties) { | int Render::NetTrafficStats( | ||||||
|   ImGui::SetCursorPos(ImVec2(properties.is_control_bar_in_left_ |     std::shared_ptr<SubStreamWindowProperties>& properties) { | ||||||
|                                  ? (properties.control_window_width_ + 5.0f) |   ImGui::SetCursorPos(ImVec2(properties->is_control_bar_in_left_ | ||||||
|  |                                  ? (properties->control_window_width_ + 5.0f) | ||||||
|                                  : 5.0f, |                                  : 5.0f, | ||||||
|                              40.0f)); |                              40.0f)); | ||||||
|  |  | ||||||
|   if (ImGui::BeginTable( |   if (ImGui::BeginTable( | ||||||
|           "NetTrafficStats", 4, ImGuiTableFlags_BordersH, |           "NetTrafficStats", 4, ImGuiTableFlags_BordersH, | ||||||
|           ImVec2(properties.control_window_max_width_ - 10.0f, |           ImVec2(properties->control_window_max_width_ - 10.0f, | ||||||
|                  properties.control_window_max_height_ - 40.0f))) { |                  properties->control_window_max_height_ - 40.0f))) { | ||||||
|     ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed); |     ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed); | ||||||
|     ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch); |     ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch); | ||||||
|     ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch); |     ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch); | ||||||
| @@ -248,13 +247,13 @@ int Render::NetTrafficStats(SubStreamWindowProperties& properties) { | |||||||
|                 localization::video[localization_language_index_].c_str()); |                 localization::video[localization_language_index_].c_str()); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     BitrateDisplay( |     BitrateDisplay( | ||||||
|         (int)properties.net_traffic_stats_.video_inbound_stats.bitrate); |         (int)properties->net_traffic_stats_.video_inbound_stats.bitrate); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     BitrateDisplay( |     BitrateDisplay( | ||||||
|         (int)properties.net_traffic_stats_.video_outbound_stats.bitrate); |         (int)properties->net_traffic_stats_.video_outbound_stats.bitrate); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     LossRateDisplay( |     LossRateDisplay( | ||||||
|         properties.net_traffic_stats_.video_inbound_stats.loss_rate); |         properties->net_traffic_stats_.video_inbound_stats.loss_rate); | ||||||
|  |  | ||||||
|     ImGui::TableNextRow(); |     ImGui::TableNextRow(); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
| @@ -262,25 +261,26 @@ int Render::NetTrafficStats(SubStreamWindowProperties& properties) { | |||||||
|                 localization::audio[localization_language_index_].c_str()); |                 localization::audio[localization_language_index_].c_str()); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     BitrateDisplay( |     BitrateDisplay( | ||||||
|         (int)properties.net_traffic_stats_.audio_inbound_stats.bitrate); |         (int)properties->net_traffic_stats_.audio_inbound_stats.bitrate); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     BitrateDisplay( |     BitrateDisplay( | ||||||
|         (int)properties.net_traffic_stats_.audio_outbound_stats.bitrate); |         (int)properties->net_traffic_stats_.audio_outbound_stats.bitrate); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     LossRateDisplay( |     LossRateDisplay( | ||||||
|         properties.net_traffic_stats_.audio_inbound_stats.loss_rate); |         properties->net_traffic_stats_.audio_inbound_stats.loss_rate); | ||||||
|  |  | ||||||
|     ImGui::TableNextRow(); |     ImGui::TableNextRow(); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     ImGui::Text("%s", localization::data[localization_language_index_].c_str()); |     ImGui::Text("%s", localization::data[localization_language_index_].c_str()); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     BitrateDisplay( |     BitrateDisplay( | ||||||
|         (int)properties.net_traffic_stats_.data_inbound_stats.bitrate); |         (int)properties->net_traffic_stats_.data_inbound_stats.bitrate); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     BitrateDisplay( |     BitrateDisplay( | ||||||
|         (int)properties.net_traffic_stats_.data_outbound_stats.bitrate); |         (int)properties->net_traffic_stats_.data_outbound_stats.bitrate); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     LossRateDisplay(properties.net_traffic_stats_.data_inbound_stats.loss_rate); |     LossRateDisplay( | ||||||
|  |         properties->net_traffic_stats_.data_inbound_stats.loss_rate); | ||||||
|  |  | ||||||
|     ImGui::TableNextRow(); |     ImGui::TableNextRow(); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
| @@ -288,13 +288,13 @@ int Render::NetTrafficStats(SubStreamWindowProperties& properties) { | |||||||
|                 localization::total[localization_language_index_].c_str()); |                 localization::total[localization_language_index_].c_str()); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     BitrateDisplay( |     BitrateDisplay( | ||||||
|         (int)properties.net_traffic_stats_.total_inbound_stats.bitrate); |         (int)properties->net_traffic_stats_.total_inbound_stats.bitrate); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     BitrateDisplay( |     BitrateDisplay( | ||||||
|         (int)properties.net_traffic_stats_.total_outbound_stats.bitrate); |         (int)properties->net_traffic_stats_.total_outbound_stats.bitrate); | ||||||
|     ImGui::TableNextColumn(); |     ImGui::TableNextColumn(); | ||||||
|     LossRateDisplay( |     LossRateDisplay( | ||||||
|         properties.net_traffic_stats_.total_inbound_stats.loss_rate); |         properties->net_traffic_stats_.total_inbound_stats.loss_rate); | ||||||
|  |  | ||||||
|     ImGui::EndTable(); |     ImGui::EndTable(); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,41 +1,42 @@ | |||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
|  |  | ||||||
| int Render::ControlWindow(SubStreamWindowProperties &properties) { | int Render::ControlWindow( | ||||||
|  |     std::shared_ptr<SubStreamWindowProperties> &properties) { | ||||||
|   double time_duration = |   double time_duration = | ||||||
|       ImGui::GetTime() - properties.control_bar_button_pressed_time_; |       ImGui::GetTime() - properties->control_bar_button_pressed_time_; | ||||||
|   if (properties.control_window_width_is_changing_) { |   if (properties->control_window_width_is_changing_) { | ||||||
|     if (properties.control_bar_expand_) { |     if (properties->control_bar_expand_) { | ||||||
|       properties.control_window_width_ = |       properties->control_window_width_ = | ||||||
|           (float)(properties.control_window_min_width_ + |           (float)(properties->control_window_min_width_ + | ||||||
|                   (properties.control_window_max_width_ - |                   (properties->control_window_max_width_ - | ||||||
|                    properties.control_window_min_width_) * |                    properties->control_window_min_width_) * | ||||||
|                       4 * time_duration); |                       4 * time_duration); | ||||||
|     } else { |     } else { | ||||||
|       properties.control_window_width_ = |       properties->control_window_width_ = | ||||||
|           (float)(properties.control_window_max_width_ - |           (float)(properties->control_window_max_width_ - | ||||||
|                   (properties.control_window_max_width_ - |                   (properties->control_window_max_width_ - | ||||||
|                    properties.control_window_min_width_) * |                    properties->control_window_min_width_) * | ||||||
|                       4 * time_duration); |                       4 * time_duration); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   time_duration = |   time_duration = | ||||||
|       ImGui::GetTime() - properties.net_traffic_stats_button_pressed_time_; |       ImGui::GetTime() - properties->net_traffic_stats_button_pressed_time_; | ||||||
|   if (properties.control_window_height_is_changing_) { |   if (properties->control_window_height_is_changing_) { | ||||||
|     if (properties.control_bar_expand_ && |     if (properties->control_bar_expand_ && | ||||||
|         properties.net_traffic_stats_button_pressed_) { |         properties->net_traffic_stats_button_pressed_) { | ||||||
|       properties.control_window_height_ = |       properties->control_window_height_ = | ||||||
|           (float)(properties.control_window_min_height_ + |           (float)(properties->control_window_min_height_ + | ||||||
|                   (properties.control_window_max_height_ - |                   (properties->control_window_max_height_ - | ||||||
|                    properties.control_window_min_height_) * |                    properties->control_window_min_height_) * | ||||||
|                       4 * time_duration); |                       4 * time_duration); | ||||||
|     } else if (properties.control_bar_expand_ && |     } else if (properties->control_bar_expand_ && | ||||||
|                !properties.net_traffic_stats_button_pressed_) { |                !properties->net_traffic_stats_button_pressed_) { | ||||||
|       properties.control_window_height_ = |       properties->control_window_height_ = | ||||||
|           (float)(properties.control_window_max_height_ - |           (float)(properties->control_window_max_height_ - | ||||||
|                   (properties.control_window_max_height_ - |                   (properties->control_window_max_height_ - | ||||||
|                    properties.control_window_min_height_) * |                    properties->control_window_min_height_) * | ||||||
|                       4 * time_duration); |                       4 * time_duration); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -47,189 +48,189 @@ int Render::ControlWindow(SubStreamWindowProperties &properties) { | |||||||
|   ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 10.0f); |   ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 10.0f); | ||||||
|   ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); |   ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); | ||||||
|  |  | ||||||
|   ImGui::SetNextWindowSize(ImVec2(properties.control_window_width_, |   ImGui::SetNextWindowSize(ImVec2(properties->control_window_width_, | ||||||
|                                   properties.control_window_height_), |                                   properties->control_window_height_), | ||||||
|                            ImGuiCond_Always); |                            ImGuiCond_Always); | ||||||
|  |  | ||||||
|   if (0 == properties.control_winodw_pos_.x && |   if (0 == properties->control_winodw_pos_.x && | ||||||
|       0 == properties.control_winodw_pos_.y) { |       0 == properties->control_winodw_pos_.y) { | ||||||
|     ImGui::SetNextWindowPos(ImVec2(0, title_bar_height_ + 1), ImGuiCond_Once); |     ImGui::SetNextWindowPos(ImVec2(0, title_bar_height_ + 1), ImGuiCond_Once); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (properties.reset_control_bar_pos_) { |   if (properties->reset_control_bar_pos_) { | ||||||
|     float new_control_window_pos_x, new_control_window_pos_y, new_cursor_pos_x, |     float new_control_window_pos_x, new_control_window_pos_y, new_cursor_pos_x, | ||||||
|         new_cursor_pos_y; |         new_cursor_pos_y; | ||||||
|  |  | ||||||
|     // set control window pos |     // set control window pos | ||||||
|     new_control_window_pos_x = properties.control_winodw_pos_.x; |     new_control_window_pos_x = properties->control_winodw_pos_.x; | ||||||
|     if (properties.control_winodw_pos_.y < |     if (properties->control_winodw_pos_.y < | ||||||
|         properties.stream_render_rect_last_.y) { |         properties->stream_render_rect_last_.y) { | ||||||
|       new_control_window_pos_y = properties.stream_render_rect_.y - |       new_control_window_pos_y = properties->stream_render_rect_.y - | ||||||
|                                  (properties.stream_render_rect_last_.y - |                                  (properties->stream_render_rect_last_.y - | ||||||
|                                   properties.control_winodw_pos_.y); |                                   properties->control_winodw_pos_.y); | ||||||
|       if (fullscreen_button_pressed_ && new_control_window_pos_y < 0) { |       if (fullscreen_button_pressed_ && new_control_window_pos_y < 0) { | ||||||
|         new_control_window_pos_y = 0; |         new_control_window_pos_y = 0; | ||||||
|       } else if (!fullscreen_button_pressed_ && |       } else if (!fullscreen_button_pressed_ && | ||||||
|                  new_control_window_pos_y < (title_bar_height_ + 1)) { |                  new_control_window_pos_y < (title_bar_height_ + 1)) { | ||||||
|         new_control_window_pos_y = title_bar_height_ + 1; |         new_control_window_pos_y = title_bar_height_ + 1; | ||||||
|       } |       } | ||||||
|     } else if (properties.control_winodw_pos_.y + |     } else if (properties->control_winodw_pos_.y + | ||||||
|                    properties.control_window_height_ > |                    properties->control_window_height_ > | ||||||
|                properties.stream_render_rect_last_.y + |                properties->stream_render_rect_last_.y + | ||||||
|                    properties.stream_render_rect_last_.h) { |                    properties->stream_render_rect_last_.h) { | ||||||
|       new_control_window_pos_y = properties.stream_render_rect_.y + |       new_control_window_pos_y = properties->stream_render_rect_.y + | ||||||
|                                  properties.stream_render_rect_.h + |                                  properties->stream_render_rect_.h + | ||||||
|                                  (properties.control_winodw_pos_.y - |                                  (properties->control_winodw_pos_.y - | ||||||
|                                   properties.stream_render_rect_last_.y - |                                   properties->stream_render_rect_last_.y - | ||||||
|                                   properties.stream_render_rect_last_.h); |                                   properties->stream_render_rect_last_.h); | ||||||
|       if (new_control_window_pos_y > properties.sub_stream_window_height_ - |       if (new_control_window_pos_y > properties->sub_stream_window_height_ - | ||||||
|                                          properties.control_window_height_) { |                                          properties->control_window_height_) { | ||||||
|         new_control_window_pos_y = properties.sub_stream_window_height_ - |         new_control_window_pos_y = properties->sub_stream_window_height_ - | ||||||
|                                    properties.control_window_height_; |                                    properties->control_window_height_; | ||||||
|       } |       } | ||||||
|     } else if (properties.control_winodw_pos_.y + |     } else if (properties->control_winodw_pos_.y + | ||||||
|                    properties.control_window_height_ == |                    properties->control_window_height_ == | ||||||
|                properties.stream_render_rect_last_.y + |                properties->stream_render_rect_last_.y + | ||||||
|                    properties.stream_render_rect_last_.h) { |                    properties->stream_render_rect_last_.h) { | ||||||
|       new_control_window_pos_y = properties.stream_render_rect_.y + |       new_control_window_pos_y = properties->stream_render_rect_.y + | ||||||
|                                  properties.stream_render_rect_.h - |                                  properties->stream_render_rect_.h - | ||||||
|                                  properties.control_window_height_; |                                  properties->control_window_height_; | ||||||
|     } else { |     } else { | ||||||
|       new_control_window_pos_y = |       new_control_window_pos_y = | ||||||
|           (properties.control_winodw_pos_.y - |           (properties->control_winodw_pos_.y - | ||||||
|            properties.stream_render_rect_last_.y) / |            properties->stream_render_rect_last_.y) / | ||||||
|               (float)(properties.stream_render_rect_last_.h) * |               (float)(properties->stream_render_rect_last_.h) * | ||||||
|               properties.stream_render_rect_.h + |               properties->stream_render_rect_.h + | ||||||
|           properties.stream_render_rect_.y; |           properties->stream_render_rect_.y; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ImGui::SetNextWindowPos( |     ImGui::SetNextWindowPos( | ||||||
|         ImVec2(new_control_window_pos_x, new_control_window_pos_y), |         ImVec2(new_control_window_pos_x, new_control_window_pos_y), | ||||||
|         ImGuiCond_Always); |         ImGuiCond_Always); | ||||||
|  |  | ||||||
|     if (0 != properties.mouse_diff_control_bar_pos_x_ && |     if (0 != properties->mouse_diff_control_bar_pos_x_ && | ||||||
|         0 != properties.mouse_diff_control_bar_pos_y_) { |         0 != properties->mouse_diff_control_bar_pos_y_) { | ||||||
|       // set cursor pos |       // set cursor pos | ||||||
|       new_cursor_pos_x = |       new_cursor_pos_x = | ||||||
|           new_control_window_pos_x + properties.mouse_diff_control_bar_pos_x_; |           new_control_window_pos_x + properties->mouse_diff_control_bar_pos_x_; | ||||||
|       new_cursor_pos_y = |       new_cursor_pos_y = | ||||||
|           new_control_window_pos_y + properties.mouse_diff_control_bar_pos_y_; |           new_control_window_pos_y + properties->mouse_diff_control_bar_pos_y_; | ||||||
|  |  | ||||||
|       SDL_WarpMouseInWindow(stream_window_, (int)new_cursor_pos_x, |       SDL_WarpMouseInWindow(stream_window_, (int)new_cursor_pos_x, | ||||||
|                             (int)new_cursor_pos_y); |                             (int)new_cursor_pos_y); | ||||||
|     } |     } | ||||||
|     properties.reset_control_bar_pos_ = false; |     properties->reset_control_bar_pos_ = false; | ||||||
|   } else if (!properties.reset_control_bar_pos_ && |   } else if (!properties->reset_control_bar_pos_ && | ||||||
|                  ImGui::IsMouseReleased(ImGuiPopupFlags_MouseButtonLeft) || |                  ImGui::IsMouseReleased(ImGuiPopupFlags_MouseButtonLeft) || | ||||||
|              properties.control_window_width_is_changing_) { |              properties->control_window_width_is_changing_) { | ||||||
|     if (properties.control_winodw_pos_.x <= |     if (properties->control_winodw_pos_.x <= | ||||||
|         properties.sub_stream_window_width_ / 2) { |         properties->sub_stream_window_width_ / 2) { | ||||||
|       float pos_x = 0; |       float pos_x = 0; | ||||||
|       float pos_y = |       float pos_y = | ||||||
|           (properties.control_winodw_pos_.y >= |           (properties->control_winodw_pos_.y >= | ||||||
|                (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) && |                (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) && | ||||||
|            properties.control_winodw_pos_.y <= |            properties->control_winodw_pos_.y <= | ||||||
|                properties.sub_stream_window_height_ - |                properties->sub_stream_window_height_ - | ||||||
|                    properties.control_window_height_) |                    properties->control_window_height_) | ||||||
|               ? properties.control_winodw_pos_.y |               ? properties->control_winodw_pos_.y | ||||||
|               : (properties.control_winodw_pos_.y < |               : (properties->control_winodw_pos_.y < | ||||||
|                          (fullscreen_button_pressed_ ? 0 |                          (fullscreen_button_pressed_ ? 0 | ||||||
|                                                      : (title_bar_height_ + 1)) |                                                      : (title_bar_height_ + 1)) | ||||||
|                      ? (fullscreen_button_pressed_ ? 0 |                      ? (fullscreen_button_pressed_ ? 0 | ||||||
|                                                    : (title_bar_height_ + 1)) |                                                    : (title_bar_height_ + 1)) | ||||||
|                      : (properties.sub_stream_window_height_ - |                      : (properties->sub_stream_window_height_ - | ||||||
|                         properties.control_window_height_)); |                         properties->control_window_height_)); | ||||||
|  |  | ||||||
|       if (properties.control_bar_expand_) { |       if (properties->control_bar_expand_) { | ||||||
|         if (properties.control_window_width_ >= |         if (properties->control_window_width_ >= | ||||||
|             properties.control_window_max_width_) { |             properties->control_window_max_width_) { | ||||||
|           properties.control_window_width_ = |           properties->control_window_width_ = | ||||||
|               properties.control_window_max_width_; |               properties->control_window_max_width_; | ||||||
|           properties.control_window_width_is_changing_ = false; |           properties->control_window_width_is_changing_ = false; | ||||||
|         } else { |         } else { | ||||||
|           properties.control_window_width_is_changing_ = true; |           properties->control_window_width_is_changing_ = true; | ||||||
|         } |         } | ||||||
|       } else { |       } else { | ||||||
|         if (properties.control_window_width_ <= |         if (properties->control_window_width_ <= | ||||||
|             properties.control_window_min_width_) { |             properties->control_window_min_width_) { | ||||||
|           properties.control_window_width_ = |           properties->control_window_width_ = | ||||||
|               properties.control_window_min_width_; |               properties->control_window_min_width_; | ||||||
|           properties.control_window_width_is_changing_ = false; |           properties->control_window_width_is_changing_ = false; | ||||||
|         } else { |         } else { | ||||||
|           properties.control_window_width_is_changing_ = true; |           properties->control_window_width_is_changing_ = true; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always); |       ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always); | ||||||
|       properties.is_control_bar_in_left_ = true; |       properties->is_control_bar_in_left_ = true; | ||||||
|     } else if (properties.control_winodw_pos_.x > |     } else if (properties->control_winodw_pos_.x > | ||||||
|                properties.sub_stream_window_width_ / 2) { |                properties->sub_stream_window_width_ / 2) { | ||||||
|       float pos_x = 0; |       float pos_x = 0; | ||||||
|       float pos_y = |       float pos_y = | ||||||
|           (properties.control_winodw_pos_.y >= |           (properties->control_winodw_pos_.y >= | ||||||
|                (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) && |                (fullscreen_button_pressed_ ? 0 : (title_bar_height_ + 1)) && | ||||||
|            properties.control_winodw_pos_.y <= |            properties->control_winodw_pos_.y <= | ||||||
|                properties.sub_stream_window_height_ - |                properties->sub_stream_window_height_ - | ||||||
|                    properties.control_window_height_) |                    properties->control_window_height_) | ||||||
|               ? properties.control_winodw_pos_.y |               ? properties->control_winodw_pos_.y | ||||||
|               : (properties.control_winodw_pos_.y < |               : (properties->control_winodw_pos_.y < | ||||||
|                          (fullscreen_button_pressed_ ? 0 |                          (fullscreen_button_pressed_ ? 0 | ||||||
|                                                      : (title_bar_height_ + 1)) |                                                      : (title_bar_height_ + 1)) | ||||||
|                      ? (fullscreen_button_pressed_ ? 0 |                      ? (fullscreen_button_pressed_ ? 0 | ||||||
|                                                    : (title_bar_height_ + 1)) |                                                    : (title_bar_height_ + 1)) | ||||||
|                      : (properties.sub_stream_window_height_ - |                      : (properties->sub_stream_window_height_ - | ||||||
|                         properties.control_window_height_)); |                         properties->control_window_height_)); | ||||||
|  |  | ||||||
|       if (properties.control_bar_expand_) { |       if (properties->control_bar_expand_) { | ||||||
|         if (properties.control_window_width_ >= |         if (properties->control_window_width_ >= | ||||||
|             properties.control_window_max_width_) { |             properties->control_window_max_width_) { | ||||||
|           properties.control_window_width_ = |           properties->control_window_width_ = | ||||||
|               properties.control_window_max_width_; |               properties->control_window_max_width_; | ||||||
|           properties.control_window_width_is_changing_ = false; |           properties->control_window_width_is_changing_ = false; | ||||||
|           pos_x = properties.sub_stream_window_width_ - |           pos_x = properties->sub_stream_window_width_ - | ||||||
|                   properties.control_window_max_width_; |                   properties->control_window_max_width_; | ||||||
|         } else { |         } else { | ||||||
|           properties.control_window_width_is_changing_ = true; |           properties->control_window_width_is_changing_ = true; | ||||||
|           pos_x = properties.sub_stream_window_width_ - |           pos_x = properties->sub_stream_window_width_ - | ||||||
|                   properties.control_window_width_; |                   properties->control_window_width_; | ||||||
|         } |         } | ||||||
|       } else { |       } else { | ||||||
|         if (properties.control_window_width_ <= |         if (properties->control_window_width_ <= | ||||||
|             properties.control_window_min_width_) { |             properties->control_window_min_width_) { | ||||||
|           properties.control_window_width_ = |           properties->control_window_width_ = | ||||||
|               properties.control_window_min_width_; |               properties->control_window_min_width_; | ||||||
|           properties.control_window_width_is_changing_ = false; |           properties->control_window_width_is_changing_ = false; | ||||||
|           pos_x = properties.sub_stream_window_width_ - |           pos_x = properties->sub_stream_window_width_ - | ||||||
|                   properties.control_window_min_width_; |                   properties->control_window_min_width_; | ||||||
|         } else { |         } else { | ||||||
|           properties.control_window_width_is_changing_ = true; |           properties->control_window_width_is_changing_ = true; | ||||||
|           pos_x = properties.sub_stream_window_width_ - |           pos_x = properties->sub_stream_window_width_ - | ||||||
|                   properties.control_window_width_; |                   properties->control_window_width_; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always); |       ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always); | ||||||
|       properties.is_control_bar_in_left_ = false; |       properties->is_control_bar_in_left_ = false; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (properties.control_bar_expand_ && |   if (properties->control_bar_expand_ && | ||||||
|       properties.control_window_height_is_changing_) { |       properties->control_window_height_is_changing_) { | ||||||
|     if (properties.net_traffic_stats_button_pressed_) { |     if (properties->net_traffic_stats_button_pressed_) { | ||||||
|       if (properties.control_window_height_ >= |       if (properties->control_window_height_ >= | ||||||
|           properties.control_window_max_height_) { |           properties->control_window_max_height_) { | ||||||
|         properties.control_window_height_ = |         properties->control_window_height_ = | ||||||
|             properties.control_window_max_height_; |             properties->control_window_max_height_; | ||||||
|         properties.control_window_height_is_changing_ = false; |         properties->control_window_height_is_changing_ = false; | ||||||
|       } else { |       } else { | ||||||
|         properties.control_window_height_is_changing_ = true; |         properties->control_window_height_is_changing_ = true; | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|       if (properties.control_window_height_ <= |       if (properties->control_window_height_ <= | ||||||
|           properties.control_window_min_height_) { |           properties->control_window_min_height_) { | ||||||
|         properties.control_window_height_ = |         properties->control_window_height_ = | ||||||
|             properties.control_window_min_height_; |             properties->control_window_min_height_; | ||||||
|         properties.control_window_height_is_changing_ = false; |         properties->control_window_height_is_changing_ = false; | ||||||
|       } else { |       } else { | ||||||
|         properties.control_window_height_is_changing_ = true; |         properties->control_window_height_is_changing_ = true; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -239,32 +240,32 @@ int Render::ControlWindow(SubStreamWindowProperties &properties) { | |||||||
|                    ImGuiWindowFlags_NoScrollbar); |                    ImGuiWindowFlags_NoScrollbar); | ||||||
|   ImGui::PopStyleVar(); |   ImGui::PopStyleVar(); | ||||||
|  |  | ||||||
|   properties.control_winodw_pos_ = ImGui::GetWindowPos(); |   properties->control_winodw_pos_ = ImGui::GetWindowPos(); | ||||||
|   SDL_GetMouseState(&properties.mouse_pos_x_, &properties.mouse_pos_y_); |   SDL_GetMouseState(&properties->mouse_pos_x_, &properties->mouse_pos_y_); | ||||||
|   properties.mouse_diff_control_bar_pos_x_ = |   properties->mouse_diff_control_bar_pos_x_ = | ||||||
|       properties.mouse_pos_x_ - properties.control_winodw_pos_.x; |       properties->mouse_pos_x_ - properties->control_winodw_pos_.x; | ||||||
|   properties.mouse_diff_control_bar_pos_y_ = |   properties->mouse_diff_control_bar_pos_y_ = | ||||||
|       properties.mouse_pos_y_ - properties.control_winodw_pos_.y; |       properties->mouse_pos_y_ - properties->control_winodw_pos_.y; | ||||||
|  |  | ||||||
|   ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); |   ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); | ||||||
|   static bool a, b, c, d, e; |   static bool a, b, c, d, e; | ||||||
|   ImGui::SetNextWindowPos(ImVec2(properties.is_control_bar_in_left_ |   ImGui::SetNextWindowPos(ImVec2(properties->is_control_bar_in_left_ | ||||||
|                                      ? properties.control_winodw_pos_.x - |                                      ? properties->control_winodw_pos_.x - | ||||||
|                                            properties.control_window_width_ |                                            properties->control_window_width_ | ||||||
|                                      : properties.control_winodw_pos_.x, |                                      : properties->control_winodw_pos_.x, | ||||||
|                                  properties.control_winodw_pos_.y), |                                  properties->control_winodw_pos_.y), | ||||||
|                           ImGuiCond_Always); |                           ImGuiCond_Always); | ||||||
|   ImGui::SetWindowFontScale(0.5f); |   ImGui::SetWindowFontScale(0.5f); | ||||||
|  |  | ||||||
|   ImGui::BeginChild("ControlBar", |   ImGui::BeginChild("ControlBar", | ||||||
|                     ImVec2(properties.control_window_width_ * 2, |                     ImVec2(properties->control_window_width_ * 2, | ||||||
|                            properties.control_window_height_), |                            properties->control_window_height_), | ||||||
|                     ImGuiChildFlags_Border, ImGuiWindowFlags_NoDecoration); |                     ImGuiChildFlags_Border, ImGuiWindowFlags_NoDecoration); | ||||||
|   ImGui::SetWindowFontScale(1.0f); |   ImGui::SetWindowFontScale(1.0f); | ||||||
|   ImGui::PopStyleColor(); |   ImGui::PopStyleColor(); | ||||||
|  |  | ||||||
|   ControlBar(properties); |   ControlBar(properties); | ||||||
|   properties.control_bar_hovered_ = ImGui::IsWindowHovered(); |   properties->control_bar_hovered_ = ImGui::IsWindowHovered(); | ||||||
|  |  | ||||||
|   ImGui::EndChild(); |   ImGui::EndChild(); | ||||||
|   ImGui::End(); |   ImGui::End(); | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ int Render::MainWindow() { | |||||||
|   RecentConnectionsWindow(); |   RecentConnectionsWindow(); | ||||||
|   StatusBar(); |   StatusBar(); | ||||||
|  |  | ||||||
|   for (auto& properties : connection_properties_) { |   for (auto& properties : client_properties_) { | ||||||
|     ConnectionStatusWindow(properties.second); |     ConnectionStatusWindow(properties.second); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -177,11 +177,14 @@ int Render::ShowRecentConnections() { | |||||||
|       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; |         remote_id_ = remote_id; | ||||||
|  |  | ||||||
|  |         bool remember_password_flag = false; | ||||||
|         if (!password.empty() && password.size() == 6) { |         if (!password.empty() && password.size() == 6) { | ||||||
|           remember_password_ = true; |           remember_password_flag = true; | ||||||
|  |           memcpy(remote_password_, password.c_str(), 6); | ||||||
|         } |         } | ||||||
|         memcpy(remote_password_, password.c_str(), 6); |  | ||||||
|         ConnectTo(); |         ConnectTo(remote_id, remote_password_, remember_password_flag); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     ImGui::SetWindowFontScale(1.0f); |     ImGui::SetWindowFontScale(1.0f); | ||||||
|   | |||||||
| @@ -75,11 +75,12 @@ int Render::RemoteWindow() { | |||||||
|         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()); | ||||||
|         ConnectTo(); |         ConnectTo(remote_id_, remote_password_, false); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (rejoin_) { |       if (rejoin_) { | ||||||
|         ConnectTo(); |         ConnectTo(remote_id_, remote_password_, | ||||||
|  |                   client_properties_[remote_id_]->remember_password_); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     ImGui::EndChild(); |     ImGui::EndChild(); | ||||||
| @@ -102,33 +103,44 @@ static int InputTextCallback(ImGuiInputTextCallbackData *data) { | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int Render::ConnectTo() { | int Render::ConnectTo(const std::string &host_name, const char *password, | ||||||
|   // connection_status_ = ConnectionStatus::Connecting; |                       bool remember_password) { | ||||||
|  |   LOG_INFO("Connect to [{}]", host_name); | ||||||
|  |   if (client_properties_.find(host_name) == client_properties_.end()) { | ||||||
|  |     client_properties_[host_name] = | ||||||
|  |         std::make_shared<SubStreamWindowProperties>(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   auto props = client_properties_[host_name]; | ||||||
|  |   props->connection_status_ = ConnectionStatus::Connecting; | ||||||
|  |   props->remember_password_ = remember_password; | ||||||
|  |   memcpy(props->remote_password_, password, 6); | ||||||
|  |  | ||||||
|   int ret = -1; |   int ret = -1; | ||||||
|   if (signal_connected_) { |   if (signal_connected_) { | ||||||
|     // if (!connection_established_) { |     if (!props->connection_established_) { | ||||||
|     if (0 == strcmp(remote_id_.c_str(), client_id_) && !peer_reserved_) { |       if (0 == strcmp(host_name.c_str(), client_id_) && !peer_reserved_) { | ||||||
|       peer_reserved_ = CreatePeer(¶ms_); |         peer_reserved_ = CreatePeer(¶ms_); | ||||||
|       if (peer_reserved_) { |         if (peer_reserved_) { | ||||||
|         LOG_INFO("Create peer[reserved] instance successful"); |           LOG_INFO("Create peer[reserved] instance successful"); | ||||||
|         std::string client_id = "C-"; |           std::string client_id = "C-"; | ||||||
|         client_id += client_id_; |           client_id += client_id_; | ||||||
|         Init(peer_reserved_, client_id.c_str()); |           Init(peer_reserved_, client_id.c_str()); | ||||||
|         LOG_INFO("Peer[reserved] init finish"); |           LOG_INFO("Peer[reserved] init finish"); | ||||||
|  |         } else { | ||||||
|  |           LOG_INFO("Create peer[reserved] instance failed"); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       ret = JoinConnection(peer_reserved_ ? peer_reserved_ : peer_, | ||||||
|  |                            host_name.c_str(), password); | ||||||
|  |       if (0 == ret) { | ||||||
|  |         is_client_mode_ = true; | ||||||
|  |         rejoin_ = false; | ||||||
|       } else { |       } else { | ||||||
|         LOG_INFO("Create peer[reserved] instance failed"); |         rejoin_ = true; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     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; |   return 0; | ||||||
|   | |||||||
| @@ -15,12 +15,12 @@ | |||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "screen_capturer_factory.h" | #include "screen_capturer_factory.h" | ||||||
|  |  | ||||||
| // Refresh Event |  | ||||||
| #define REFRESH_EVENT (SDL_USEREVENT + 1) |  | ||||||
| #define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 | #define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 | ||||||
|  |  | ||||||
| #define MOUSE_GRAB_PADDING 5 | #define MOUSE_GRAB_PADDING 5 | ||||||
|  |  | ||||||
|  | const Uint32 STREAM_FRASH = SDL_RegisterEvents(29); | ||||||
|  |  | ||||||
| SDL_HitTestResult Render::HitTestCallback(SDL_Window* window, | SDL_HitTestResult Render::HitTestCallback(SDL_Window* window, | ||||||
|                                           const SDL_Point* area, void* data) { |                                           const SDL_Point* area, void* data) { | ||||||
|   Render* render = (Render*)data; |   Render* render = (Render*)data; | ||||||
| @@ -40,9 +40,9 @@ SDL_HitTestResult Render::HitTestCallback(SDL_Window* window, | |||||||
|     return SDL_HITTEST_DRAGGABLE; |     return SDL_HITTEST_DRAGGABLE; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (!render->streaming_) { |   // if (!render->streaming_) { | ||||||
|     return SDL_HITTEST_NORMAL; |   //   return SDL_HITTEST_NORMAL; | ||||||
|   } |   // } | ||||||
|  |  | ||||||
|   if (area->y < MOUSE_GRAB_PADDING) { |   if (area->y < MOUSE_GRAB_PADDING) { | ||||||
|     if (area->x < MOUSE_GRAB_PADDING) { |     if (area->x < MOUSE_GRAB_PADDING) { | ||||||
| @@ -69,7 +69,7 @@ SDL_HitTestResult Render::HitTestCallback(SDL_Window* window, | |||||||
|   return SDL_HITTEST_NORMAL; |   return SDL_HITTEST_NORMAL; | ||||||
| } | } | ||||||
|  |  | ||||||
| Render::Render() { memset(&net_traffic_stats_, 0, sizeof(net_traffic_stats_)); } | Render::Render() {} | ||||||
|  |  | ||||||
| Render::~Render() {} | Render::~Render() {} | ||||||
|  |  | ||||||
| @@ -198,7 +198,7 @@ int Render::StartScreenCapturer() { | |||||||
|                             std::chrono::steady_clock::now().time_since_epoch()) |                             std::chrono::steady_clock::now().time_since_epoch()) | ||||||
|                             .count(); |                             .count(); | ||||||
|         auto duration = now_time - last_frame_time_; |         auto duration = now_time - last_frame_time_; | ||||||
|         if (duration >= 0 && connection_established_) { |         if (duration >= 0) { | ||||||
|           XVideoFrame frame; |           XVideoFrame frame; | ||||||
|           frame.data = (const char*)data; |           frame.data = (const char*)data; | ||||||
|           frame.size = size; |           frame.size = size; | ||||||
| @@ -238,9 +238,7 @@ int Render::StartSpeakerCapturer() { | |||||||
|     speaker_capturer_ = (SpeakerCapturer*)speaker_capturer_factory_->Create(); |     speaker_capturer_ = (SpeakerCapturer*)speaker_capturer_factory_->Create(); | ||||||
|     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_) { |           SendAudioFrame(peer_, (const char*)data, size); | ||||||
|             SendAudioFrame(peer_, (const char*)data, size); |  | ||||||
|           } |  | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     if (0 != speaker_capturer_init_ret) { |     if (0 != speaker_capturer_init_ret) { | ||||||
| @@ -518,16 +516,16 @@ int Render::CreateStreamWindow() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   stream_pixformat_ = SDL_PIXELFORMAT_NV12; |   stream_pixformat_ = SDL_PIXELFORMAT_NV12; | ||||||
|   stream_texture_ = SDL_CreateTexture(stream_renderer_, stream_pixformat_, |   // stream_texture_ = SDL_CreateTexture(stream_renderer_, stream_pixformat_, | ||||||
|                                       SDL_TEXTUREACCESS_STREAMING, |   //                                     SDL_TEXTUREACCESS_STREAMING, | ||||||
|                                       texture_width_, texture_height_); |   //                                     texture_width_, texture_height_); | ||||||
|  |  | ||||||
|   SDL_SetWindowResizable(stream_window_, SDL_TRUE); |   SDL_SetWindowResizable(stream_window_, SDL_TRUE); | ||||||
|  |  | ||||||
|   // for window region action |   // for window region action | ||||||
|   SDL_SetWindowHitTest(stream_window_, HitTestCallback, this); |   SDL_SetWindowHitTest(stream_window_, HitTestCallback, this); | ||||||
|  |  | ||||||
|   // change stream_render_rect_ |   // change props->stream_render_rect_ | ||||||
|   SDL_Event event; |   SDL_Event event; | ||||||
|   event.type = SDL_WINDOWEVENT; |   event.type = SDL_WINDOWEVENT; | ||||||
|   event.window.windowID = SDL_GetWindowID(stream_window_); |   event.window.windowID = SDL_GetWindowID(stream_window_); | ||||||
| @@ -733,7 +731,12 @@ int Render::DrawStreamWindow() { | |||||||
|   // Rendering |   // Rendering | ||||||
|   ImGui::Render(); |   ImGui::Render(); | ||||||
|   SDL_RenderClear(stream_renderer_); |   SDL_RenderClear(stream_renderer_); | ||||||
|   SDL_RenderCopy(stream_renderer_, stream_texture_, NULL, &stream_render_rect_); |  | ||||||
|  |   for (auto& it : client_properties_) { | ||||||
|  |     auto props = it.second; | ||||||
|  |     SDL_RenderCopy(stream_renderer_, props->stream_texture_, NULL, | ||||||
|  |                    &(props->stream_render_rect_)); | ||||||
|  |   } | ||||||
|   ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), stream_renderer_); |   ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), stream_renderer_); | ||||||
|   SDL_RenderPresent(stream_renderer_); |   SDL_RenderPresent(stream_renderer_); | ||||||
|  |  | ||||||
| @@ -766,11 +769,6 @@ int Render::Run() { | |||||||
|   screen_width_ = DM.w; |   screen_width_ = DM.w; | ||||||
|   screen_height_ = DM.h; |   screen_height_ = DM.h; | ||||||
|  |  | ||||||
|   stream_render_rect_.x = 0; |  | ||||||
|   stream_render_rect_.y = (int)title_bar_height_; |  | ||||||
|   stream_render_rect_.w = (int)stream_window_width_; |  | ||||||
|   stream_render_rect_.h = (int)(stream_window_height_ - title_bar_height_); |  | ||||||
|  |  | ||||||
|   // use linear filtering to render textures otherwise the graphics will be |   // use linear filtering to render textures otherwise the graphics will be | ||||||
|   // blurry |   // blurry | ||||||
|   SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); |   SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); | ||||||
| @@ -842,40 +840,47 @@ int Render::Run() { | |||||||
|         ImGui_ImplSDL2_ProcessEvent(&event); |         ImGui_ImplSDL2_ProcessEvent(&event); | ||||||
|       } |       } | ||||||
|       if (event.type == SDL_QUIT) { |       if (event.type == SDL_QUIT) { | ||||||
|         if (streaming_) { |         if (stream_window_inited_) { | ||||||
|           LOG_INFO("Destroy stream window"); |           LOG_INFO("Destroy stream window"); | ||||||
|           SDL_SetWindowGrab(stream_window_, SDL_FALSE); |           SDL_SetWindowGrab(stream_window_, SDL_FALSE); | ||||||
|           DestroyStreamWindow(); |           DestroyStreamWindow(); | ||||||
|           DestroyStreamWindowContext(); |           DestroyStreamWindowContext(); | ||||||
|  |  | ||||||
|           if (dst_buffer_) { |           for (auto& it : client_properties_) { | ||||||
|             thumbnail_->SaveToThumbnail( |             auto props = it.second; | ||||||
|                 (char*)dst_buffer_, video_width_, video_height_, remote_id_, |             if (props->dst_buffer_) { | ||||||
|                 remote_host_name_, remember_password_ ? remote_password_ : ""); |               thumbnail_->SaveToThumbnail( | ||||||
|             recent_connection_image_save_time_ = SDL_GetTicks(); |                   (char*)props->dst_buffer_, props->video_width_, | ||||||
|           } |                   props->video_height_, it.first, props->remote_host_name_, | ||||||
|  |                   props->remember_password_ ? props->remote_password_ : ""); | ||||||
|  |             } | ||||||
|  |  | ||||||
|           LOG_INFO("[{}] Leave connection [{}]", client_id_, remote_id_); |             LOG_INFO("[{}] Leave connection [{}]", client_id_, it.first); | ||||||
|           LeaveConnection(peer_reserved_ ? peer_reserved_ : peer_, |             LeaveConnection(peer_reserved_ ? peer_reserved_ : peer_, | ||||||
|                           remote_id_.c_str()); |                             it.first.c_str()); | ||||||
|           if (peer_reserved_) { |             if (peer_reserved_) { | ||||||
|             LOG_INFO("Destroy peer[reserved]"); |               LOG_INFO("Destroy peer[reserved]"); | ||||||
|             DestroyPeer(&peer_reserved_); |               DestroyPeer(&peer_reserved_); | ||||||
|           } |             } | ||||||
|  |  | ||||||
|  |             props->streaming_ = false; | ||||||
|  |             props->remember_password_ = false; | ||||||
|  |             props->connection_established_ = false; | ||||||
|  |             props->audio_capture_button_pressed_ = false; | ||||||
|  |  | ||||||
|  |             memset(&props->net_traffic_stats_, 0, | ||||||
|  |                    sizeof(props->net_traffic_stats_)); | ||||||
|  |             SDL_SetWindowFullscreen(main_window_, SDL_FALSE); | ||||||
|  |             SDL_DestroyTexture(props->stream_texture_); | ||||||
|  |             memset(audio_buffer_, 0, 720); | ||||||
|  |           } | ||||||
|  |           client_properties_.clear(); | ||||||
|  |  | ||||||
|           streaming_ = false; |  | ||||||
|           rejoin_ = false; |           rejoin_ = false; | ||||||
|           connection_established_ = false; |  | ||||||
|           is_client_mode_ = false; |           is_client_mode_ = false; | ||||||
|           audio_capture_button_pressed_ = false; |  | ||||||
|           fullscreen_button_pressed_ = false; |  | ||||||
|           reload_recent_connections_ = true; |           reload_recent_connections_ = true; | ||||||
|           remember_password_ = false; |           fullscreen_button_pressed_ = false; | ||||||
|  |           recent_connection_image_save_time_ = SDL_GetTicks(); | ||||||
|           memset(&net_traffic_stats_, 0, sizeof(net_traffic_stats_)); |  | ||||||
|           SDL_SetWindowFullscreen(main_window_, SDL_FALSE); |  | ||||||
|           memset(audio_buffer_, 0, 720); |  | ||||||
|  |  | ||||||
|           continue; |           continue; | ||||||
|         } else { |         } else { | ||||||
|           LOG_INFO("Quit program"); |           LOG_INFO("Quit program"); | ||||||
| @@ -888,73 +893,101 @@ int Render::Run() { | |||||||
|       } 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_)) { | ||||||
|         // to prevent cursor relocation |         for (auto& it : client_properties_) { | ||||||
|         if (!reset_control_bar_pos_) { |           auto props = it.second; | ||||||
|           mouse_diff_control_bar_pos_x_ = 0; |  | ||||||
|           mouse_diff_control_bar_pos_y_ = 0; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         reset_control_bar_pos_ = true; |           // to prevent cursor relocation | ||||||
|         int stream_window_width, stream_window_height; |           if (!props->reset_control_bar_pos_) { | ||||||
|         SDL_GetWindowSize(stream_window_, &stream_window_width, |             props->mouse_diff_control_bar_pos_x_ = 0; | ||||||
|                           &stream_window_height); |             props->mouse_diff_control_bar_pos_y_ = 0; | ||||||
|         stream_window_width_ = (float)stream_window_width; |           } | ||||||
|         stream_window_height_ = (float)stream_window_height; |  | ||||||
|  |  | ||||||
|         float video_ratio = (float)video_width_ / (float)video_height_; |           props->reset_control_bar_pos_ = true; | ||||||
|         float video_ratio_reverse = (float)video_height_ / (float)video_width_; |           int stream_window_width, stream_window_height; | ||||||
|  |           SDL_GetWindowSize(stream_window_, &stream_window_width, | ||||||
|  |                             &stream_window_height); | ||||||
|  |           stream_window_width_ = (float)stream_window_width; | ||||||
|  |           stream_window_height_ = (float)stream_window_height; | ||||||
|  |  | ||||||
|         float render_area_width = stream_window_width_; |           float video_ratio = | ||||||
|         float render_area_height = |               (float)props->video_width_ / (float)props->video_height_; | ||||||
|             stream_window_height_ - |           float video_ratio_reverse = | ||||||
|             (fullscreen_button_pressed_ ? 0 : title_bar_height_); |               (float)props->video_height_ / (float)props->video_width_; | ||||||
|  |  | ||||||
|         stream_render_rect_last_ = stream_render_rect_; |           float render_area_width = stream_window_width_; | ||||||
|         if (render_area_width < render_area_height * video_ratio) { |           float render_area_height = | ||||||
|           stream_render_rect_.x = 0; |               stream_window_height_ - | ||||||
|           stream_render_rect_.y = |               (fullscreen_button_pressed_ ? 0 : title_bar_height_); | ||||||
|               (int)(abs(render_area_height - |  | ||||||
|                         render_area_width * video_ratio_reverse) / |           props->stream_render_rect_last_ = props->stream_render_rect_; | ||||||
|                         2 + |           if (render_area_width < render_area_height * video_ratio) { | ||||||
|                     (fullscreen_button_pressed_ ? 0 : title_bar_height_)); |             props->stream_render_rect_.x = 0; | ||||||
|           stream_render_rect_.w = (int)render_area_width; |             props->stream_render_rect_.y = | ||||||
|           stream_render_rect_.h = |                 (int)(abs(render_area_height - | ||||||
|               (int)(render_area_width * video_ratio_reverse); |                           render_area_width * video_ratio_reverse) / | ||||||
|         } else if (render_area_width > render_area_height * video_ratio) { |                           2 + | ||||||
|           stream_render_rect_.x = |                       (fullscreen_button_pressed_ ? 0 : title_bar_height_)); | ||||||
|               (int)abs(render_area_width - render_area_height * video_ratio) / |             props->stream_render_rect_.w = (int)render_area_width; | ||||||
|               2; |             props->stream_render_rect_.h = | ||||||
|           stream_render_rect_.y = |                 (int)(render_area_width * video_ratio_reverse); | ||||||
|               fullscreen_button_pressed_ ? 0 : (int)title_bar_height_; |           } else if (render_area_width > render_area_height * video_ratio) { | ||||||
|           stream_render_rect_.w = (int)(render_area_height * video_ratio); |             props->stream_render_rect_.x = | ||||||
|           stream_render_rect_.h = (int)render_area_height; |                 (int)abs(render_area_width - render_area_height * video_ratio) / | ||||||
|         } else { |                 2; | ||||||
|           stream_render_rect_.x = 0; |             props->stream_render_rect_.y = | ||||||
|           stream_render_rect_.y = |                 fullscreen_button_pressed_ ? 0 : (int)title_bar_height_; | ||||||
|               fullscreen_button_pressed_ ? 0 : (int)title_bar_height_; |             props->stream_render_rect_.w = | ||||||
|           stream_render_rect_.w = (int)render_area_width; |                 (int)(render_area_height * video_ratio); | ||||||
|           stream_render_rect_.h = (int)render_area_height; |             props->stream_render_rect_.h = (int)render_area_height; | ||||||
|  |           } else { | ||||||
|  |             props->stream_render_rect_.x = 0; | ||||||
|  |             props->stream_render_rect_.y = | ||||||
|  |                 fullscreen_button_pressed_ ? 0 : (int)title_bar_height_; | ||||||
|  |             props->stream_render_rect_.w = (int)render_area_width; | ||||||
|  |             props->stream_render_rect_.h = (int)render_area_height; | ||||||
|  |           } | ||||||
|         } |         } | ||||||
|       } else if (event.type == SDL_WINDOWEVENT && |       } else if (event.type == SDL_WINDOWEVENT && | ||||||
|                  event.window.event == SDL_WINDOWEVENT_CLOSE) { |                  event.window.event == SDL_WINDOWEVENT_CLOSE) { | ||||||
|         if (connection_established_) { |         if (event.window.windowID == SDL_GetWindowID(stream_window_)) { | ||||||
|           continue; |           continue; | ||||||
|         } else { |         } else { | ||||||
|           exit_ = true; |           exit_ = true; | ||||||
|         } |         } | ||||||
|       } else if (event.type == REFRESH_EVENT) { |       } else if (event.type == STREAM_FRASH) { | ||||||
|         if (stream_texture_) |         SubStreamWindowProperties* props = | ||||||
|           if (video_width_ != texture_width_ || |             static_cast<SubStreamWindowProperties*>(event.user.data1); | ||||||
|               video_height_ != texture_height_) { |         if (!props) { | ||||||
|             texture_width_ = video_width_; |           LOG_ERROR("Invalid stream window properties"); | ||||||
|             texture_height_ = video_height_; |           continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|             SDL_DestroyTexture(stream_texture_); |         if (props->stream_texture_) { | ||||||
|             stream_texture_ = SDL_CreateTexture( |           if (props->video_width_ != props->texture_width_ || | ||||||
|  |               props->video_height_ != props->texture_height_) { | ||||||
|  |             props->texture_width_ = props->video_width_; | ||||||
|  |             props->texture_height_ = props->video_height_; | ||||||
|  |  | ||||||
|  |             SDL_DestroyTexture(props->stream_texture_); | ||||||
|  |             props->stream_texture_ = SDL_CreateTexture( | ||||||
|                 stream_renderer_, stream_pixformat_, |                 stream_renderer_, stream_pixformat_, | ||||||
|                 SDL_TEXTUREACCESS_STREAMING, texture_width_, texture_height_); |                 SDL_TEXTUREACCESS_STREAMING, props->texture_width_, | ||||||
|  |                 props->texture_height_); | ||||||
|           } |           } | ||||||
|         SDL_UpdateTexture(stream_texture_, NULL, dst_buffer_, texture_width_); |         } else { | ||||||
|  |           if (props->video_width_ != props->texture_width_ || | ||||||
|  |               props->video_height_ != props->texture_height_) { | ||||||
|  |             props->texture_width_ = props->video_width_; | ||||||
|  |             props->texture_height_ = props->video_height_; | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           props->stream_texture_ = SDL_CreateTexture( | ||||||
|  |               stream_renderer_, stream_pixformat_, SDL_TEXTUREACCESS_STREAMING, | ||||||
|  |               props->texture_width_, props->texture_height_); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_, | ||||||
|  |                           props->texture_width_); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -965,6 +998,7 @@ int Render::Run() { | |||||||
|         int ret = thumbnail_->LoadThumbnail( |         int ret = thumbnail_->LoadThumbnail( | ||||||
|             main_renderer_, recent_connection_textures_, |             main_renderer_, recent_connection_textures_, | ||||||
|             &recent_connection_image_width_, &recent_connection_image_height_); |             &recent_connection_image_width_, &recent_connection_image_height_); | ||||||
|  |         LOG_INFO("1 Load recent connection thumbnails"); | ||||||
|         if (!ret) { |         if (!ret) { | ||||||
|           LOG_INFO("Load recent connection thumbnails"); |           LOG_INFO("Load recent connection thumbnails"); | ||||||
|         } |         } | ||||||
| @@ -972,10 +1006,13 @@ int Render::Run() { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (connection_established_ && streaming_) { |     if (need_to_create_stream_window_) { | ||||||
|       CreateStreamWindow(); |       CreateStreamWindow(); | ||||||
|       SetupStreamWindow(); |       SetupStreamWindow(); | ||||||
|  |       need_to_create_stream_window_ = false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (stream_window_inited_) { | ||||||
|       if (!stream_window_grabbed_ && control_mouse_) { |       if (!stream_window_grabbed_ && control_mouse_) { | ||||||
|         SDL_SetWindowGrab(stream_window_, SDL_TRUE); |         SDL_SetWindowGrab(stream_window_, SDL_TRUE); | ||||||
|         stream_window_grabbed_ = true; |         stream_window_grabbed_ = true; | ||||||
|   | |||||||
| @@ -25,6 +25,8 @@ | |||||||
| #include "speaker_capturer_factory.h" | #include "speaker_capturer_factory.h" | ||||||
| #include "thumbnail.h" | #include "thumbnail.h" | ||||||
|  |  | ||||||
|  | extern const Uint32 STREAM_FRASH; | ||||||
|  |  | ||||||
| class Render { | class Render { | ||||||
|  public: |  public: | ||||||
|   struct SubStreamWindowProperties { |   struct SubStreamWindowProperties { | ||||||
| @@ -34,14 +36,6 @@ class Render { | |||||||
|     bool mouse_control_button_pressed_ = false; |     bool mouse_control_button_pressed_ = false; | ||||||
|     bool mouse_controller_is_started_ = false; |     bool mouse_controller_is_started_ = false; | ||||||
|     bool audio_capture_button_pressed_ = false; |     bool audio_capture_button_pressed_ = false; | ||||||
|     bool audio_capture_ = true; |  | ||||||
|     bool start_screen_capturer_ = false; |  | ||||||
|     bool screen_capturer_is_started_ = false; |  | ||||||
|     bool start_keyboard_capturer_ = false; |  | ||||||
|     bool keyboard_capturer_is_started_ = false; |  | ||||||
|     bool control_mouse_ = false; |  | ||||||
|     bool stream_window_grabbed_ = false; |  | ||||||
|     bool window_maximized_ = 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; | ||||||
| @@ -50,6 +44,9 @@ class Render { | |||||||
|     bool control_window_width_is_changing_ = false; |     bool control_window_width_is_changing_ = false; | ||||||
|     bool control_window_height_is_changing_ = false; |     bool control_window_height_is_changing_ = false; | ||||||
|     bool p2p_mode_ = true; |     bool p2p_mode_ = true; | ||||||
|  |     bool hostname_sent_ = false; | ||||||
|  |     bool remember_password_ = false; | ||||||
|  |     char remote_password_[7] = ""; | ||||||
|     float sub_stream_window_width_ = 1280; |     float sub_stream_window_width_ = 1280; | ||||||
|     float sub_stream_window_height_ = 720; |     float sub_stream_window_height_ = 720; | ||||||
|     float control_window_min_width_ = 20; |     float control_window_min_width_ = 20; | ||||||
| @@ -80,6 +77,7 @@ class Render { | |||||||
|     std::string mouse_control_button_label_ = "Mouse Control"; |     std::string mouse_control_button_label_ = "Mouse Control"; | ||||||
|     std::string audio_capture_button_label_ = "Audio Capture"; |     std::string audio_capture_button_label_ = "Audio Capture"; | ||||||
|     std::string remote_host_name_ = ""; |     std::string remote_host_name_ = ""; | ||||||
|  |     SDL_Texture *stream_texture_ = nullptr; | ||||||
|     SDL_Rect stream_render_rect_; |     SDL_Rect stream_render_rect_; | ||||||
|     SDL_Rect stream_render_rect_last_; |     SDL_Rect stream_render_rect_last_; | ||||||
|     ImVec2 control_winodw_pos_; |     ImVec2 control_winodw_pos_; | ||||||
| @@ -104,17 +102,19 @@ class Render { | |||||||
|   int RemoteWindow(); |   int RemoteWindow(); | ||||||
|   int RecentConnectionsWindow(); |   int RecentConnectionsWindow(); | ||||||
|   int SettingWindow(); |   int SettingWindow(); | ||||||
|   int ControlWindow(SubStreamWindowProperties &properties); |   int ControlWindow(std::shared_ptr<SubStreamWindowProperties> &properties); | ||||||
|   int ControlBar(SubStreamWindowProperties &properties); |   int ControlBar(std::shared_ptr<SubStreamWindowProperties> &properties); | ||||||
|   int AboutWindow(); |   int AboutWindow(); | ||||||
|   int StatusBar(); |   int StatusBar(); | ||||||
|   int ConnectionStatusWindow(SubStreamWindowProperties &properties); |   int ConnectionStatusWindow( | ||||||
|  |       std::shared_ptr<SubStreamWindowProperties> &properties); | ||||||
|   int LoadRecentConnections(); |   int LoadRecentConnections(); | ||||||
|   int ShowRecentConnections(); |   int ShowRecentConnections(); | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   int CreateRtcConnection(); |   int CreateRtcConnection(); | ||||||
|   int ConnectTo(); |   int ConnectTo(const std::string &host_name, const char *password, | ||||||
|  |                 bool remember_password); | ||||||
|   int CreateMainWindow(); |   int CreateMainWindow(); | ||||||
|   int DestroyMainWindow(); |   int DestroyMainWindow(); | ||||||
|   int CreateStreamWindow(); |   int CreateStreamWindow(); | ||||||
| @@ -127,7 +127,7 @@ class Render { | |||||||
|   int DrawMainWindow(); |   int DrawMainWindow(); | ||||||
|   int DrawStreamWindow(); |   int DrawStreamWindow(); | ||||||
|   int ConfirmDeleteConnection(); |   int ConfirmDeleteConnection(); | ||||||
|   int NetTrafficStats(SubStreamWindowProperties &properties); |   int NetTrafficStats(std::shared_ptr<SubStreamWindowProperties> &properties); | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   static void OnReceiveVideoBufferCb(const XVideoFrame *video_frame, |   static void OnReceiveVideoBufferCb(const XVideoFrame *video_frame, | ||||||
| @@ -150,6 +150,7 @@ class Render { | |||||||
|   static void NetStatusReport(const char *client_id, size_t client_id_size, |   static void NetStatusReport(const char *client_id, size_t client_id_size, | ||||||
|                               TraversalMode mode, |                               TraversalMode mode, | ||||||
|                               const XNetTrafficStats *net_traffic_stats, |                               const XNetTrafficStats *net_traffic_stats, | ||||||
|  |                               const char *user_id, const size_t user_id_size, | ||||||
|                               void *user_data); |                               void *user_data); | ||||||
|  |  | ||||||
|   static SDL_HitTestResult HitTestCallback(SDL_Window *window, |   static SDL_HitTestResult HitTestCallback(SDL_Window *window, | ||||||
| @@ -228,8 +229,16 @@ class Render { | |||||||
|   SDL_Window *main_window_ = nullptr; |   SDL_Window *main_window_ = nullptr; | ||||||
|   SDL_Renderer *main_renderer_ = nullptr; |   SDL_Renderer *main_renderer_ = nullptr; | ||||||
|   ImGuiContext *main_ctx_ = nullptr; |   ImGuiContext *main_ctx_ = nullptr; | ||||||
|  |   bool exit_ = false; | ||||||
|  |  | ||||||
|   // main window properties |   // main window properties | ||||||
|  |   bool start_mouse_controller_ = false; | ||||||
|  |   bool mouse_controller_is_started_ = false; | ||||||
|  |   bool start_screen_capturer_ = false; | ||||||
|  |   bool screen_capturer_is_started_ = false; | ||||||
|  |   bool start_keyboard_capturer_ = false; | ||||||
|  |   bool keyboard_capturer_is_started_ = false; | ||||||
|  |   bool audio_capture_ = false; | ||||||
|   int main_window_width_real_ = 720; |   int main_window_width_real_ = 720; | ||||||
|   int main_window_height_real_ = 540; |   int main_window_height_real_ = 540; | ||||||
|   float main_window_dpi_scaling_w_ = 1.0f; |   float main_window_dpi_scaling_w_ = 1.0f; | ||||||
| @@ -279,8 +288,12 @@ class Render { | |||||||
|   ImGuiContext *stream_ctx_ = nullptr; |   ImGuiContext *stream_ctx_ = nullptr; | ||||||
|  |  | ||||||
|   // stream window properties |   // stream window properties | ||||||
|  |   bool need_to_create_stream_window_ = false; | ||||||
|   bool stream_window_created_ = false; |   bool stream_window_created_ = false; | ||||||
|   bool stream_window_inited_ = false; |   bool stream_window_inited_ = false; | ||||||
|  |   bool window_maximized_ = false; | ||||||
|  |   bool stream_window_grabbed_ = false; | ||||||
|  |   bool control_mouse_ = false; | ||||||
|   int stream_window_width_default_ = 1280; |   int stream_window_width_default_ = 1280; | ||||||
|   int stream_window_height_default_ = 720; |   int stream_window_height_default_ = 720; | ||||||
|   float stream_window_width_ = 1280; |   float stream_window_width_ = 1280; | ||||||
| @@ -309,10 +322,8 @@ class Render { | |||||||
|   bool focus_on_input_widget_ = true; |   bool focus_on_input_widget_ = true; | ||||||
|   bool is_client_mode_ = false; |   bool is_client_mode_ = false; | ||||||
|   bool reload_recent_connections_ = true; |   bool reload_recent_connections_ = true; | ||||||
|   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_ = false; |  | ||||||
|   bool re_enter_remote_id_ = false; |   bool re_enter_remote_id_ = false; | ||||||
|   double copy_start_time_ = 0; |   double copy_start_time_ = 0; | ||||||
|   double regenerate_password_start_time_ = 0; |   double regenerate_password_start_time_ = 0; | ||||||
| @@ -350,9 +361,12 @@ class Render { | |||||||
|   /* ------ main window property end ------ */ |   /* ------ main window property end ------ */ | ||||||
|  |  | ||||||
|   /* ------ sub stream window property start ------ */ |   /* ------ sub stream window property start ------ */ | ||||||
|   std::unordered_map<std::string, SubStreamWindowProperties> |   std::unordered_map<std::string, std::shared_ptr<SubStreamWindowProperties>> | ||||||
|       connection_properties_; |       client_properties_; | ||||||
|   /* ------ stream window property end ------ */ |   /* ------ stream window property end ------ */ | ||||||
|  |  | ||||||
|  |   std::unordered_map<std::string, std::shared_ptr<SubStreamWindowProperties>> | ||||||
|  |       server_properties_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
| @@ -4,8 +4,6 @@ | |||||||
| #include "rd_log.h" | #include "rd_log.h" | ||||||
| #include "render.h" | #include "render.h" | ||||||
|  |  | ||||||
| // Refresh Event |  | ||||||
| #define REFRESH_EVENT (SDL_USEREVENT + 1) |  | ||||||
| #define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 | #define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 | ||||||
|  |  | ||||||
| #ifdef REMOTE_DESK_DEBUG | #ifdef REMOTE_DESK_DEBUG | ||||||
| @@ -80,41 +78,50 @@ void Render::SdlCaptureAudioOut([[maybe_unused]] void *userdata, | |||||||
| } | } | ||||||
|  |  | ||||||
| void Render::OnReceiveVideoBufferCb(const XVideoFrame *video_frame, | void Render::OnReceiveVideoBufferCb(const XVideoFrame *video_frame, | ||||||
|                                     [[maybe_unused]] const char *user_id, |                                     const char *user_id, size_t user_id_size, | ||||||
|                                     [[maybe_unused]] size_t user_id_size, |  | ||||||
|                                     void *user_data) { |                                     void *user_data) { | ||||||
|   Render *render = (Render *)user_data; |   Render *render = (Render *)user_data; | ||||||
|   if (!render) { |   if (!render) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (render->connection_established_) { |   std::string remote_id(user_id, user_id_size); | ||||||
|     if (!render->dst_buffer_) { |   if (render->client_properties_.find(remote_id) == | ||||||
|       render->dst_buffer_capacity_ = video_frame->size; |       render->client_properties_.end()) { | ||||||
|       render->dst_buffer_ = new unsigned char[video_frame->size]; |     return; | ||||||
|  |   } | ||||||
|  |   SubStreamWindowProperties *props = | ||||||
|  |       render->client_properties_.find(remote_id)->second.get(); | ||||||
|  |  | ||||||
|  |   if (props->connection_established_) { | ||||||
|  |     if (!props->dst_buffer_) { | ||||||
|  |       props->dst_buffer_capacity_ = video_frame->size; | ||||||
|  |       props->dst_buffer_ = new unsigned char[video_frame->size]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (render->dst_buffer_capacity_ < video_frame->size) { |     if (props->dst_buffer_capacity_ < video_frame->size) { | ||||||
|       delete render->dst_buffer_; |       delete props->dst_buffer_; | ||||||
|       render->dst_buffer_capacity_ = video_frame->size; |       props->dst_buffer_capacity_ = video_frame->size; | ||||||
|       render->dst_buffer_ = new unsigned char[video_frame->size]; |       props->dst_buffer_ = new unsigned char[video_frame->size]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     memcpy(render->dst_buffer_, video_frame->data, video_frame->size); |     memcpy(props->dst_buffer_, video_frame->data, video_frame->size); | ||||||
|     render->video_width_ = video_frame->width; |     props->video_width_ = video_frame->width; | ||||||
|     render->video_height_ = video_frame->height; |     props->video_height_ = video_frame->height; | ||||||
|     render->video_size_ = video_frame->size; |     props->video_size_ = video_frame->size; | ||||||
|  |  | ||||||
|     SDL_Event event; |     SDL_Event event; | ||||||
|     event.type = REFRESH_EVENT; |     event.type = STREAM_FRASH; | ||||||
|  |     event.user.type = STREAM_FRASH; | ||||||
|  |     event.user.data1 = props; | ||||||
|     SDL_PushEvent(&event); |     SDL_PushEvent(&event); | ||||||
|     render->streaming_ = true; |  | ||||||
|  |     props->streaming_ = true; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void Render::OnReceiveAudioBufferCb(const char *data, size_t size, | void Render::OnReceiveAudioBufferCb(const char *data, size_t size, | ||||||
|                                     [[maybe_unused]] const char *user_id, |                                     const char *user_id, size_t user_id_size, | ||||||
|                                     [[maybe_unused]] size_t user_id_size, |  | ||||||
|                                     void *user_data) { |                                     void *user_data) { | ||||||
|   Render *render = (Render *)user_data; |   Render *render = (Render *)user_data; | ||||||
|   if (!render) { |   if (!render) { | ||||||
| @@ -130,12 +137,16 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size, | |||||||
|                                    void *user_data) { |                                    void *user_data) { | ||||||
|   Render *render = (Render *)user_data; |   Render *render = (Render *)user_data; | ||||||
|   if (!render) { |   if (!render) { | ||||||
|     LOG_ERROR("??????????????????"); |  | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   std::string user(user_id, user_id_size); |   std::string remote_id(user_id, user_id_size); | ||||||
|   LOG_INFO("Receive data from: {}", user); |   if (render->client_properties_.find(remote_id) == | ||||||
|  |       render->client_properties_.end()) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   auto props = render->client_properties_.find(remote_id)->second; | ||||||
|  |  | ||||||
|   RemoteAction remote_action; |   RemoteAction remote_action; | ||||||
|   memcpy(&remote_action, data, size); |   memcpy(&remote_action, data, size); | ||||||
|  |  | ||||||
| @@ -144,18 +155,18 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size, | |||||||
|   } else if (ControlType::audio_capture == remote_action.type) { |   } else if (ControlType::audio_capture == remote_action.type) { | ||||||
|     if (remote_action.a) { |     if (remote_action.a) { | ||||||
|       render->StartSpeakerCapturer(); |       render->StartSpeakerCapturer(); | ||||||
|  |       render->audio_capture_ = true; | ||||||
|     } else { |     } else { | ||||||
|       render->StopSpeakerCapturer(); |       render->StopSpeakerCapturer(); | ||||||
|  |       render->audio_capture_ = false; | ||||||
|     } |     } | ||||||
|   } else if (ControlType::keyboard == remote_action.type) { |   } else if (ControlType::keyboard == remote_action.type) { | ||||||
|     render->ProcessKeyEvent((int)remote_action.k.key_value, |     render->ProcessKeyEvent((int)remote_action.k.key_value, | ||||||
|                             remote_action.k.flag == KeyFlag::key_down); |                             remote_action.k.flag == KeyFlag::key_down); | ||||||
|   } else if (ControlType::host_infomation == remote_action.type) { |   } else if (ControlType::host_infomation == remote_action.type) { | ||||||
|     render->remote_host_name_ = |     props->remote_host_name_ = | ||||||
|         std::string(remote_action.i.host_name, remote_action.i.host_name_size); |         std::string(remote_action.i.host_name, remote_action.i.host_name_size); | ||||||
|     LOG_INFO("Remote hostname: [{}]", render->remote_host_name_); |     LOG_INFO("Remote hostname: [{}]", props->remote_host_name_); | ||||||
|   } else { |  | ||||||
|     LOG_ERROR("Unknown control type: {}", (int)remote_action.type); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -188,31 +199,44 @@ void Render::OnSignalStatusCb(SignalStatus status, void *user_data) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void Render::OnConnectionStatusCb(ConnectionStatus status, | void Render::OnConnectionStatusCb(ConnectionStatus status, const char *user_id, | ||||||
|                                   [[maybe_unused]] const char *user_id, |                                   const size_t user_id_size, void *user_data) { | ||||||
|                                   [[maybe_unused]] const size_t user_id_size, |  | ||||||
|                                   void *user_data) { |  | ||||||
|   Render *render = (Render *)user_data; |   Render *render = (Render *)user_data; | ||||||
|   if (!render) { |   if (!render) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   render->connection_status_ = status; |   bool is_server = false; | ||||||
|  |   std::shared_ptr<SubStreamWindowProperties> props; | ||||||
|  |  | ||||||
|  |   std::string remote_id(user_id, user_id_size); | ||||||
|  |   if (render->client_properties_.find(remote_id) != | ||||||
|  |       render->client_properties_.end()) { | ||||||
|  |     props = render->client_properties_.find(remote_id)->second; | ||||||
|  |   } else { | ||||||
|  |     if (render->server_properties_.find(remote_id) == | ||||||
|  |         render->server_properties_.end()) { | ||||||
|  |       render->server_properties_[remote_id] = | ||||||
|  |           std::make_shared<SubStreamWindowProperties>(); | ||||||
|  |     } | ||||||
|  |     props = render->server_properties_.find(remote_id)->second; | ||||||
|  |     is_server = true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   props->connection_status_ = status; | ||||||
|   render->show_connection_status_window_ = true; |   render->show_connection_status_window_ = true; | ||||||
|   if (ConnectionStatus::Connecting == status) { |   if (ConnectionStatus::Connecting == status) { | ||||||
|     render->connection_status_str_ = "Connecting"; |     render->connection_status_str_ = "Connecting"; | ||||||
|   } else if (ConnectionStatus::Gathering == status) { |   } else if (ConnectionStatus::Gathering == status) { | ||||||
|     render->connection_status_str_ = "Gathering"; |     render->connection_status_str_ = "Gathering"; | ||||||
|   } else if (ConnectionStatus::Connected == status) { |   } else if (ConnectionStatus::Connected == status) { | ||||||
|     std::string remote_id(user_id, user_id_size); |  | ||||||
|     render->connection_properties_[remote_id] = SubStreamWindowProperties(); |  | ||||||
|     render->connection_status_str_ = "Connected"; |     render->connection_status_str_ = "Connected"; | ||||||
|     render->connection_established_ = true; |     if (!render->need_to_create_stream_window_) { | ||||||
|     if (render->peer_reserved_ || !render->is_client_mode_) { |       render->need_to_create_stream_window_ = true; | ||||||
|       render->start_screen_capturer_ = true; |  | ||||||
|       render->start_mouse_controller_ = true; |  | ||||||
|     } |     } | ||||||
|     if (!render->hostname_sent_) { |  | ||||||
|  |     props->connection_established_ = true; | ||||||
|  |     if (!props->hostname_sent_) { | ||||||
|       // TODO: self and remote hostname |       // TODO: self and remote hostname | ||||||
|       std::string host_name = GetHostName(); |       std::string host_name = GetHostName(); | ||||||
|       RemoteAction remote_action; |       RemoteAction remote_action; | ||||||
| @@ -222,11 +246,21 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, | |||||||
|       int ret = SendDataFrame(render->peer_, (const char *)&remote_action, |       int ret = SendDataFrame(render->peer_, (const char *)&remote_action, | ||||||
|                               sizeof(remote_action)); |                               sizeof(remote_action)); | ||||||
|       if (0 == ret) { |       if (0 == ret) { | ||||||
|         render->hostname_sent_ = true; |         props->hostname_sent_ = true; | ||||||
|       } |       } | ||||||
|       LOG_ERROR("1111111111111111 [{}|{}]", ret, host_name); |     } | ||||||
|     } else { |  | ||||||
|       LOG_ERROR("2222222222222222"); |     if (!is_server) { | ||||||
|  |       props->stream_render_rect_.x = 0; | ||||||
|  |       props->stream_render_rect_.y = (int)render->title_bar_height_; | ||||||
|  |       props->stream_render_rect_.w = (int)render->stream_window_width_; | ||||||
|  |       props->stream_render_rect_.h = | ||||||
|  |           (int)(render->stream_window_height_ - render->title_bar_height_); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (render->peer_reserved_ || !render->is_client_mode_) { | ||||||
|  |       render->start_screen_capturer_ = true; | ||||||
|  |       render->start_mouse_controller_ = true; | ||||||
|     } |     } | ||||||
|   } else if (ConnectionStatus::Disconnected == status) { |   } else if (ConnectionStatus::Disconnected == status) { | ||||||
|     render->connection_status_str_ = "Disconnected"; |     render->connection_status_str_ = "Disconnected"; | ||||||
| @@ -239,30 +273,29 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, | |||||||
|     render->password_validating_time_ = 0; |     render->password_validating_time_ = 0; | ||||||
|     render->start_screen_capturer_ = false; |     render->start_screen_capturer_ = false; | ||||||
|     render->start_mouse_controller_ = false; |     render->start_mouse_controller_ = false; | ||||||
|     render->connection_established_ = false; |  | ||||||
|     render->control_mouse_ = false; |  | ||||||
|     render->mouse_control_button_pressed_ = false; |  | ||||||
|     render->start_keyboard_capturer_ = false; |     render->start_keyboard_capturer_ = false; | ||||||
|     render->hostname_sent_ = false; |     render->control_mouse_ = false; | ||||||
|  |     props->connection_established_ = false; | ||||||
|  |     props->mouse_control_button_pressed_ = false; | ||||||
|  |     props->hostname_sent_ = false; | ||||||
|     if (render->audio_capture_) { |     if (render->audio_capture_) { | ||||||
|       render->StopSpeakerCapturer(); |       render->StopSpeakerCapturer(); | ||||||
|       render->audio_capture_ = false; |       render->audio_capture_ = false; | ||||||
|       render->audio_capture_button_pressed_ = false; |  | ||||||
|     } |     } | ||||||
|     if (!render->rejoin_) { |     if (!render->rejoin_) { | ||||||
|       memset(render->remote_password_, 0, sizeof(render->remote_password_)); |       memset(render->remote_password_, 0, sizeof(render->remote_password_)); | ||||||
|     } |     } | ||||||
|     if (render->dst_buffer_) { |     if (props->dst_buffer_) { | ||||||
|       memset(render->dst_buffer_, 0, render->dst_buffer_capacity_); |       memset(props->dst_buffer_, 0, props->dst_buffer_capacity_); | ||||||
|       SDL_UpdateTexture(render->stream_texture_, NULL, render->dst_buffer_, |       SDL_UpdateTexture(props->stream_texture_, NULL, props->dst_buffer_, | ||||||
|                         render->texture_width_); |                         props->texture_width_); | ||||||
|     } |     } | ||||||
|   } else if (ConnectionStatus::IncorrectPassword == status) { |   } else if (ConnectionStatus::IncorrectPassword == status) { | ||||||
|     render->connection_status_str_ = "Incorrect password"; |     render->connection_status_str_ = "Incorrect password"; | ||||||
|     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_) { | ||||||
|       render->connection_established_ = false; |       props->connection_established_ = false; | ||||||
|       render->connect_button_label_ = |       render->connect_button_label_ = | ||||||
|           render->connect_button_pressed_ |           render->connect_button_pressed_ | ||||||
|               ? localization::disconnect[render->localization_language_index_] |               ? localization::disconnect[render->localization_language_index_] | ||||||
| @@ -271,7 +304,7 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, | |||||||
|   } else if (ConnectionStatus::NoSuchTransmissionId == status) { |   } else if (ConnectionStatus::NoSuchTransmissionId == status) { | ||||||
|     render->connection_status_str_ = "No such transmission id"; |     render->connection_status_str_ = "No such transmission id"; | ||||||
|     if (render->connect_button_pressed_) { |     if (render->connect_button_pressed_) { | ||||||
|       render->connection_established_ = false; |       props->connection_established_ = false; | ||||||
|       render->connect_button_label_ = |       render->connect_button_label_ = | ||||||
|           render->connect_button_pressed_ |           render->connect_button_pressed_ | ||||||
|               ? localization::disconnect[render->localization_language_index_] |               ? localization::disconnect[render->localization_language_index_] | ||||||
| @@ -283,21 +316,29 @@ void Render::OnConnectionStatusCb(ConnectionStatus status, | |||||||
| void Render::NetStatusReport(const char *client_id, size_t client_id_size, | void Render::NetStatusReport(const char *client_id, size_t client_id_size, | ||||||
|                              TraversalMode mode, |                              TraversalMode mode, | ||||||
|                              const XNetTrafficStats *net_traffic_stats, |                              const XNetTrafficStats *net_traffic_stats, | ||||||
|  |                              const char *user_id, const size_t user_id_size, | ||||||
|                              void *user_data) { |                              void *user_data) { | ||||||
|   Render *render = (Render *)user_data; |   Render *render = (Render *)user_data; | ||||||
|   if (!render) { |   if (!render) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   std::string remote_id(user_id, user_id_size); | ||||||
|  |   if (render->client_properties_.find(remote_id) == | ||||||
|  |       render->client_properties_.end()) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   auto props = render->client_properties_.find(remote_id)->second; | ||||||
|  |  | ||||||
|   if (0 == strcmp(render->client_id_, "")) { |   if (0 == strcmp(render->client_id_, "")) { | ||||||
|     memset(&render->client_id_, 0, sizeof(render->client_id_)); |     memset(&render->client_id_, 0, sizeof(render->client_id_)); | ||||||
|     memcpy(render->client_id_, client_id, client_id_size); |     memcpy(render->client_id_, client_id, client_id_size); | ||||||
|     LOG_INFO("Use client id [{}] and save id into cache file", client_id); |     LOG_INFO("Use client id [{}] and save id into cache file", client_id); | ||||||
|     render->SaveSettingsIntoCacheFile(); |     render->SaveSettingsIntoCacheFile(); | ||||||
|   } |   } | ||||||
|   if (render->traversal_mode_ != mode) { |   if (props->traversal_mode_ != mode) { | ||||||
|     render->traversal_mode_ = mode; |     props->traversal_mode_ = mode; | ||||||
|     LOG_INFO("Net mode: [{}]", int(render->traversal_mode_)); |     LOG_INFO("Net mode: [{}]", int(props->traversal_mode_)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (!net_traffic_stats) { |   if (!net_traffic_stats) { | ||||||
| @@ -306,6 +347,6 @@ void Render::NetStatusReport(const char *client_id, size_t client_id_size, | |||||||
|  |  | ||||||
|   // only display client side net status if connected to itself |   // only display client side net status if connected to itself | ||||||
|   if (!(render->peer_reserved_ && !strstr(client_id, "C-"))) { |   if (!(render->peer_reserved_ && !strstr(client_id, "C-"))) { | ||||||
|     render->net_traffic_stats_ = *net_traffic_stats; |     props->net_traffic_stats_ = *net_traffic_stats; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -70,7 +70,7 @@ int Render::SettingWindow() { | |||||||
|  |  | ||||||
|       ImGui::Separator(); |       ImGui::Separator(); | ||||||
|  |  | ||||||
|       if (streaming_) { |       if (stream_window_inited_) { | ||||||
|         ImGui::BeginDisabled(); |         ImGui::BeginDisabled(); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -161,7 +161,7 @@ int Render::SettingWindow() { | |||||||
|         ImGui::Checkbox("##enable_turn", &enable_turn_); |         ImGui::Checkbox("##enable_turn", &enable_turn_); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (streaming_) { |       if (stream_window_inited_) { | ||||||
|         ImGui::EndDisabled(); |         ImGui::EndDisabled(); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -234,7 +234,7 @@ int Render::SettingWindow() { | |||||||
|         LoadSettingsFromCacheFile(); |         LoadSettingsFromCacheFile(); | ||||||
|  |  | ||||||
|         // Recreate peer instance |         // Recreate peer instance | ||||||
|         if (!streaming_) { |         if (!stream_window_inited_) { | ||||||
|           LOG_INFO("Recreate peer instance"); |           LOG_INFO("Recreate peer instance"); | ||||||
|           DestroyPeer(&peer_); |           DestroyPeer(&peer_); | ||||||
|           is_create_connection_ = false; |           is_create_connection_ = false; | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ int Render::StreamWindow() { | |||||||
|                    ImGuiWindowFlags_NoBringToFrontOnFocus); |                    ImGuiWindowFlags_NoBringToFrontOnFocus); | ||||||
|   ImGui::PopStyleColor(2); |   ImGui::PopStyleColor(2); | ||||||
|  |  | ||||||
|   for (auto &properties : connection_properties_) { |   for (auto &properties : client_properties_) { | ||||||
|     ControlWindow(properties.second); |     ControlWindow(properties.second); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -96,7 +96,6 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height, | |||||||
|       image_name = remote_id + 'Y' + password + host_name; |       image_name = remote_id + 'Y' + password + host_name; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     LOG_ERROR("1 image_path: [{}]", image_name); |  | ||||||
|     std::string ciphertext = AES_encrypt(image_name, aes128_key_, aes128_iv_); |     std::string ciphertext = AES_encrypt(image_name, aes128_key_, aes128_iv_); | ||||||
|     std::string file_path = image_path_ + ciphertext; |     std::string file_path = image_path_ + ciphertext; | ||||||
|     stbi_write_png(file_path.data(), thumbnail_width_, thumbnail_height_, 4, |     stbi_write_png(file_path.data(), thumbnail_width_, thumbnail_height_, 4, | ||||||
| @@ -219,7 +218,6 @@ int Thumbnail::LoadThumbnail(SDL_Renderer* renderer, | |||||||
|           AES_decrypt(cipher_image_name, aes128_key_, aes128_iv_); |           AES_decrypt(cipher_image_name, aes128_key_, aes128_iv_); | ||||||
|       std::string image_path = image_path_ + cipher_image_name; |       std::string image_path = image_path_ + cipher_image_name; | ||||||
|       textures[original_image_name] = nullptr; |       textures[original_image_name] = nullptr; | ||||||
|       LOG_ERROR("2 image_path: [{}]", original_image_name); |  | ||||||
|       LoadTextureFromFile(image_path.c_str(), renderer, |       LoadTextureFromFile(image_path.c_str(), renderer, | ||||||
|                           &(textures[original_image_name]), width, height); |                           &(textures[original_image_name]), width, height); | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								thirdparty/projectx
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								thirdparty/projectx
									
									
									
									
										vendored
									
									
								
							 Submodule thirdparty/projectx updated: 49d6307154...6e3c8c488d
									
								
							
		Reference in New Issue
	
	Block a user