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