mirror of
				https://github.com/kunkundi/crossdesk.git
				synced 2025-10-26 20:25:34 +08:00 
			
		
		
		
	[feat] use an additional window to show video streams
This commit is contained in:
		| @@ -29,18 +29,18 @@ int Render::ControlWindow() { | ||||
|   ImGui::SetNextWindowPos(ImVec2(0, title_bar_height_), ImGuiCond_Once); | ||||
|   if (ImGui::IsMouseReleased(ImGuiPopupFlags_MouseButtonLeft) || | ||||
|       control_window_width_is_changing_) { | ||||
|     if (control_winodw_pos_.x <= main_window_width_ / 2) { | ||||
|     if (control_winodw_pos_.x <= stream_window_width_ / 2) { | ||||
|       int pos_x = 0; | ||||
|       int pos_y = | ||||
|           (control_winodw_pos_.y >= | ||||
|                (fullscreen_button_pressed_ ? 0 : title_bar_height_) && | ||||
|            control_winodw_pos_.y <= | ||||
|                main_window_height_ - control_window_height_) | ||||
|                stream_window_height_ - control_window_height_) | ||||
|               ? control_winodw_pos_.y | ||||
|               : (control_winodw_pos_.y < | ||||
|                          (fullscreen_button_pressed_ ? 0 : title_bar_height_) | ||||
|                      ? (fullscreen_button_pressed_ ? 0 : title_bar_height_) | ||||
|                      : (main_window_height_ - control_window_height_)); | ||||
|                      : (stream_window_height_ - control_window_height_)); | ||||
|  | ||||
|       if (control_bar_expand_) { | ||||
|         if (control_window_width_ >= control_window_max_width_) { | ||||
| @@ -59,36 +59,36 @@ int Render::ControlWindow() { | ||||
|       } | ||||
|       ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always); | ||||
|       is_control_bar_in_left_ = true; | ||||
|     } else if (control_winodw_pos_.x > main_window_width_ / 2) { | ||||
|     } else if (control_winodw_pos_.x > stream_window_width_ / 2) { | ||||
|       int pos_x = 0; | ||||
|       int pos_y = | ||||
|           (control_winodw_pos_.y >= | ||||
|                (fullscreen_button_pressed_ ? 0 : title_bar_height_) && | ||||
|            control_winodw_pos_.y <= | ||||
|                main_window_height_ - control_window_height_) | ||||
|                stream_window_height_ - control_window_height_) | ||||
|               ? control_winodw_pos_.y | ||||
|               : (control_winodw_pos_.y < | ||||
|                          (fullscreen_button_pressed_ ? 0 : title_bar_height_) | ||||
|                      ? (fullscreen_button_pressed_ ? 0 : title_bar_height_) | ||||
|                      : (main_window_height_ - control_window_height_)); | ||||
|                      : (stream_window_height_ - control_window_height_)); | ||||
|  | ||||
|       if (control_bar_expand_) { | ||||
|         if (control_window_width_ >= control_window_max_width_) { | ||||
|           control_window_width_ = control_window_max_width_; | ||||
|           control_window_width_is_changing_ = false; | ||||
|           pos_x = main_window_width_ - control_window_max_width_; | ||||
|           pos_x = stream_window_width_ - control_window_max_width_; | ||||
|         } else { | ||||
|           control_window_width_is_changing_ = true; | ||||
|           pos_x = main_window_width_ - control_window_width_; | ||||
|           pos_x = stream_window_width_ - control_window_width_; | ||||
|         } | ||||
|       } else { | ||||
|         if (control_window_width_ <= control_window_min_width_) { | ||||
|           control_window_width_ = control_window_min_width_; | ||||
|           control_window_width_is_changing_ = false; | ||||
|           pos_x = main_window_width_ - control_window_min_width_; | ||||
|           pos_x = stream_window_width_ - control_window_min_width_; | ||||
|         } else { | ||||
|           control_window_width_is_changing_ = true; | ||||
|           pos_x = main_window_width_ - control_window_width_; | ||||
|           pos_x = stream_window_width_ - control_window_width_; | ||||
|         } | ||||
|       } | ||||
|       ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always); | ||||
| @@ -131,8 +131,8 @@ int Render::ControlWindow() { | ||||
|       ImVec2(0, fullscreen_button_pressed_ ? 0 : title_bar_height_), | ||||
|       ImGuiCond_Always); | ||||
|   ImGui::SetNextWindowSize( | ||||
|       ImVec2(main_window_width_, | ||||
|              main_window_height_ - | ||||
|       ImVec2(stream_window_width_, | ||||
|              stream_window_height_ - | ||||
|                  (fullscreen_button_pressed_ ? 0 : title_bar_height_)), | ||||
|       ImGuiCond_Always); | ||||
|   ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0)); | ||||
|   | ||||
| @@ -352,44 +352,150 @@ int Render::AudioDeviceDestroy() { | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::Run() { | ||||
|   LoadSettingsFromCacheFile(); | ||||
| int Render::CreateRtcConnection() { | ||||
|   // create connection | ||||
|   if (SignalStatus::SignalConnected == signal_status_ && | ||||
|       !is_create_connection_ && password_inited_) { | ||||
|     LOG_INFO("Connected with signal server, create p2p connection"); | ||||
|     is_create_connection_ = | ||||
|         CreateConnection(peer_, client_id_, password_saved_) ? false : true; | ||||
|   } | ||||
|  | ||||
|   localization_language_ = (ConfigCenter::LANGUAGE)language_button_value_; | ||||
|   localization_language_index_ = language_button_value_; | ||||
|   if (start_screen_capture_ && !screen_capture_is_started_) { | ||||
|     StartScreenCapture(); | ||||
|     screen_capture_is_started_ = true; | ||||
|   } else if (!start_screen_capture_ && screen_capture_is_started_) { | ||||
|     StopScreenCapture(); | ||||
|     screen_capture_is_started_ = false; | ||||
|   } | ||||
|  | ||||
|   // Setup SDL | ||||
|   if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | | ||||
|                SDL_INIT_GAMECONTROLLER) != 0) { | ||||
|     printf("Error: %s\n", SDL_GetError()); | ||||
|   if (start_mouse_control_ && !mouse_control_is_started_) { | ||||
|     StartMouseControl(); | ||||
|     mouse_control_is_started_ = true; | ||||
|   } else if (!start_mouse_control_ && mouse_control_is_started_) { | ||||
|     StopMouseControl(); | ||||
|     mouse_control_is_started_ = false; | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::CreateMainWindow() { | ||||
|   main_ctx_ = ImGui::CreateContext(); | ||||
|   if (!main_ctx_) { | ||||
|     LOG_ERROR("Main context is null"); | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   // get screen resolution | ||||
|   SDL_DisplayMode DM; | ||||
|   SDL_GetCurrentDisplayMode(0, &DM); | ||||
|   screen_width_ = DM.w; | ||||
|   screen_height_ = DM.h; | ||||
|   ImGui::SetCurrentContext(main_ctx_); | ||||
|  | ||||
|   stream_render_rect_.x = 0; | ||||
|   stream_render_rect_.y = title_bar_height_; | ||||
|   stream_render_rect_.w = main_window_width_; | ||||
|   stream_render_rect_.h = main_window_height_ - title_bar_height_; | ||||
|   SDL_WindowFlags window_flags = | ||||
|       (SDL_WindowFlags)(SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_BORDERLESS); | ||||
|   main_window_ = SDL_CreateWindow( | ||||
|       "Remote Desk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, | ||||
|       main_window_width_default_, main_window_height_default_, window_flags); | ||||
|  | ||||
|   // use linear filtering to render textures otherwise the graphics will be | ||||
|   // blurry | ||||
|   SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); | ||||
|   main_renderer_ = SDL_CreateRenderer( | ||||
|       main_window_, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); | ||||
|   if (main_renderer_ == nullptr) { | ||||
|     LOG_ERROR("Error creating SDL_Renderer"); | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   // Setup Dear ImGui context | ||||
|   IMGUI_CHECKVERSION(); | ||||
|   ImGui::CreateContext(); | ||||
|   SDL_SetWindowResizable(main_window_, SDL_FALSE); | ||||
|  | ||||
|   // for window region action | ||||
|   SDL_SetWindowHitTest(main_window_, HitTestCallback, this); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::DestroyMainWindow() { | ||||
|   if (main_ctx_) { | ||||
|     ImGui::SetCurrentContext(main_ctx_); | ||||
|   } | ||||
|  | ||||
|   if (main_renderer_) { | ||||
|     SDL_DestroyRenderer(main_renderer_); | ||||
|   } | ||||
|  | ||||
|   if (main_window_) { | ||||
|     SDL_DestroyWindow(main_window_); | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::CreateStreamWindow() { | ||||
|   if (stream_window_created_) { | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   stream_ctx_ = ImGui::CreateContext(); | ||||
|   if (!stream_ctx_) { | ||||
|     LOG_ERROR("Stream context is null"); | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   ImGui::SetCurrentContext(stream_ctx_); | ||||
|  | ||||
|   SDL_WindowFlags window_flags = | ||||
|       (SDL_WindowFlags)(SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_BORDERLESS); | ||||
|   stream_window_ = | ||||
|       SDL_CreateWindow("Stream window", SDL_WINDOWPOS_UNDEFINED, | ||||
|                        SDL_WINDOWPOS_UNDEFINED, stream_window_width_default_, | ||||
|                        stream_window_height_default_, window_flags); | ||||
|  | ||||
|   stream_renderer_ = SDL_CreateRenderer( | ||||
|       stream_window_, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); | ||||
|   if (stream_renderer_ == nullptr) { | ||||
|     LOG_ERROR("Error creating SDL_Renderer"); | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   stream_pixformat_ = SDL_PIXELFORMAT_NV12; | ||||
|   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); | ||||
|  | ||||
|   stream_window_created_ = true; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::DestroyStreamWindow() { | ||||
|   if (stream_ctx_) { | ||||
|     ImGui::SetCurrentContext(stream_ctx_); | ||||
|   } | ||||
|  | ||||
|   if (stream_renderer_) { | ||||
|     SDL_DestroyRenderer(stream_renderer_); | ||||
|   } | ||||
|  | ||||
|   if (stream_window_) { | ||||
|     SDL_DestroyWindow(stream_window_); | ||||
|   } | ||||
|  | ||||
|   stream_window_created_ = false; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::SetupFontAndStyle() { | ||||
|   // Setup Dear ImGui style | ||||
|   ImGuiIO &io = ImGui::GetIO(); | ||||
|   // Master keyboard navigation enable flag. Enable full Tabbing + directional | ||||
|   // arrows + space/enter to activate. | ||||
|   io.ConfigFlags |= | ||||
|       ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls | ||||
|   io.ConfigFlags |= | ||||
|       ImGuiConfigFlags_NavEnableGamepad;  // Enable Gamepad Controls | ||||
|       ImGuiConfigFlags_NavEnableGamepad;             // Enable Gamepad Controls | ||||
|   io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;  // Enable Docking | ||||
|  | ||||
|   // Load Fonts | ||||
|   io.Fonts->AddFontFromMemoryTTF(OPPOSans_Regular_ttf, | ||||
| @@ -413,6 +519,191 @@ int Render::Run() { | ||||
|   // ImGui::StyleColorsDark(); | ||||
|   ImGui::StyleColorsLight(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::SetupMainWindow() { | ||||
|   if (!main_ctx_) { | ||||
|     LOG_ERROR("Main context is null"); | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   ImGui::SetCurrentContext(main_ctx_); | ||||
|   SetupFontAndStyle(); | ||||
|  | ||||
|   SDL_GL_GetDrawableSize(main_window_, &main_window_width_real_, | ||||
|                          &main_window_height_real_); | ||||
|   main_window_dpi_scaling_w_ = | ||||
|       (float)main_window_width_real_ / (float)main_window_width_; | ||||
|   main_window_dpi_scaling_h_ = | ||||
|       (float)main_window_width_real_ / (float)main_window_width_; | ||||
|   SDL_RenderSetScale(main_renderer_, main_window_dpi_scaling_w_, | ||||
|                      main_window_dpi_scaling_h_); | ||||
|   LOG_INFO("Use dpi scaling [{}x{}] for main window", | ||||
|            main_window_dpi_scaling_w_, main_window_dpi_scaling_h_); | ||||
|  | ||||
|   ImGui_ImplSDL2_InitForSDLRenderer(main_window_, main_renderer_); | ||||
|   ImGui_ImplSDLRenderer2_Init(main_renderer_); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::DestroyMainWindowContext() { | ||||
|   ImGui_ImplSDLRenderer2_Shutdown(); | ||||
|   ImGui_ImplSDL2_Shutdown(); | ||||
|   ImGui::DestroyContext(main_ctx_); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::SetupStreamWindow() { | ||||
|   if (stream_window_inited_) { | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   if (!stream_ctx_) { | ||||
|     LOG_ERROR("Stream context is null"); | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   ImGui::SetCurrentContext(stream_ctx_); | ||||
|   SetupFontAndStyle(); | ||||
|  | ||||
|   SDL_GL_GetDrawableSize(stream_window_, &stream_window_width_real_, | ||||
|                          &stream_window_height_real_); | ||||
|   stream_window_dpi_scaling_w_ = | ||||
|       (float)stream_window_width_real_ / (float)stream_window_width_; | ||||
|   stream_window_dpi_scaling_h_ = | ||||
|       (float)stream_window_width_real_ / (float)stream_window_width_; | ||||
|   SDL_RenderSetScale(stream_renderer_, stream_window_dpi_scaling_w_, | ||||
|                      stream_window_dpi_scaling_h_); | ||||
|   LOG_INFO("Use dpi scaling [{}x{}] for stream window", | ||||
|            stream_window_dpi_scaling_w_, stream_window_dpi_scaling_h_); | ||||
|  | ||||
|   ImGui_ImplSDL2_InitForSDLRenderer(stream_window_, stream_renderer_); | ||||
|   ImGui_ImplSDLRenderer2_Init(stream_renderer_); | ||||
|  | ||||
|   stream_window_inited_ = true; | ||||
|   LOG_INFO("Stream window inited"); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::DestroyStreamWindowContext() { | ||||
|   stream_window_inited_ = false; | ||||
|   ImGui_ImplSDLRenderer2_Shutdown(); | ||||
|   ImGui_ImplSDL2_Shutdown(); | ||||
|   ImGui::DestroyContext(stream_ctx_); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::DrawMainWindow() { | ||||
|   if (!main_ctx_) { | ||||
|     LOG_ERROR("Main context is null"); | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   ImGui::SetCurrentContext(main_ctx_); | ||||
|   ImGui_ImplSDLRenderer2_NewFrame(); | ||||
|   ImGui_ImplSDL2_NewFrame(); | ||||
|   ImGui::NewFrame(); | ||||
|  | ||||
|   ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); | ||||
|   ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); | ||||
|   ImGui::SetNextWindowSize( | ||||
|       ImVec2(main_window_width_, main_window_height_default_), | ||||
|       ImGuiCond_Always); | ||||
|   ImGui::Begin("MainRender", nullptr, | ||||
|                ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | | ||||
|                    ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | | ||||
|                    ImGuiWindowFlags_NoBringToFrontOnFocus); | ||||
|   ImGui::PopStyleColor(); | ||||
|  | ||||
|   TitleBar(true); | ||||
|  | ||||
|   MainWindow(); | ||||
|  | ||||
|   ImGui::End(); | ||||
|  | ||||
|   // Rendering | ||||
|   ImGui::Render(); | ||||
|   SDL_RenderClear(main_renderer_); | ||||
|   ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), main_renderer_); | ||||
|   SDL_RenderPresent(main_renderer_); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::DrawStreamWindow() { | ||||
|   if (!stream_ctx_) { | ||||
|     LOG_ERROR("Stream context is null"); | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   ImGui::SetCurrentContext(stream_ctx_); | ||||
|   ImGui_ImplSDLRenderer2_NewFrame(); | ||||
|   ImGui_ImplSDL2_NewFrame(); | ||||
|   ImGui::NewFrame(); | ||||
|  | ||||
|   ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); | ||||
|   ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); | ||||
|   ImGui::SetNextWindowSize( | ||||
|       ImVec2(stream_window_width_, | ||||
|              fullscreen_button_pressed_ ? 0 : title_bar_height_), | ||||
|       ImGuiCond_Always); | ||||
|   ImGui::Begin("StreamRender", nullptr, | ||||
|                ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | | ||||
|                    ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | | ||||
|                    ImGuiWindowFlags_NoBringToFrontOnFocus); | ||||
|   ImGui::PopStyleColor(); | ||||
|  | ||||
|   TitleBar(false); | ||||
|   ControlWindow(); | ||||
|  | ||||
|   ImGui::End(); | ||||
|  | ||||
|   // Rendering | ||||
|   ImGui::Render(); | ||||
|   SDL_RenderClear(stream_renderer_); | ||||
|   SDL_RenderCopy(stream_renderer_, stream_texture_, NULL, &stream_render_rect_); | ||||
|   ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), stream_renderer_); | ||||
|   SDL_RenderPresent(stream_renderer_); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int Render::Run() { | ||||
|   LoadSettingsFromCacheFile(); | ||||
|  | ||||
|   localization_language_ = (ConfigCenter::LANGUAGE)language_button_value_; | ||||
|   localization_language_index_ = language_button_value_; | ||||
|  | ||||
|   // Setup SDL | ||||
|   if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | | ||||
|                SDL_INIT_GAMECONTROLLER) != 0) { | ||||
|     printf("Error: %s\n", SDL_GetError()); | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   // get screen resolution | ||||
|   SDL_DisplayMode DM; | ||||
|   SDL_GetCurrentDisplayMode(0, &DM); | ||||
|   screen_width_ = DM.w; | ||||
|   screen_height_ = DM.h; | ||||
|  | ||||
|   stream_render_rect_.x = 0; | ||||
|   stream_render_rect_.y = title_bar_height_; | ||||
|   stream_render_rect_.w = stream_window_width_; | ||||
|   stream_render_rect_.h = 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"); | ||||
|  | ||||
|   // Setup Dear ImGui context | ||||
|   IMGUI_CHECKVERSION(); | ||||
|  | ||||
|   // init modules | ||||
|   if (!modules_inited_) { | ||||
|     // audio | ||||
| @@ -433,38 +724,9 @@ int Render::Run() { | ||||
|     modules_inited_ = true; | ||||
|   } | ||||
|  | ||||
|   // create main window with SDL_Renderer graphics context | ||||
|   SDL_WindowFlags window_flags = | ||||
|       (SDL_WindowFlags)(SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_BORDERLESS); | ||||
|   main_window_ = SDL_CreateWindow( | ||||
|       "Remote Desk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, | ||||
|       main_window_width_default_, main_window_height_default_, window_flags); | ||||
|  | ||||
|   main_renderer_ = SDL_CreateRenderer( | ||||
|       main_window_, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); | ||||
|   if (main_renderer_ == nullptr) { | ||||
|     LOG_ERROR("1 Error creating SDL_Renderer"); | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   stream_pixformat_ = SDL_PIXELFORMAT_NV12; | ||||
|   stream_texture_ = SDL_CreateTexture(main_renderer_, stream_pixformat_, | ||||
|                                       SDL_TEXTUREACCESS_STREAMING, | ||||
|                                       texture_width_, texture_height_); | ||||
|  | ||||
|   // for window region action | ||||
|   SDL_SetWindowHitTest(main_window_, HitTestCallback, this); | ||||
|  | ||||
|   SDL_GL_GetDrawableSize(main_window_, &main_window_width_real_, | ||||
|                          &main_window_height_real_); | ||||
|   dpi_scaling_w_ = (float)main_window_width_real_ / (float)main_window_width_; | ||||
|   dpi_scaling_h_ = (float)main_window_width_real_ / (float)main_window_width_; | ||||
|   SDL_RenderSetScale(main_renderer_, dpi_scaling_w_, dpi_scaling_h_); | ||||
|   LOG_INFO("Use dpi scaling [{}x{}]", dpi_scaling_w_, dpi_scaling_h_); | ||||
|  | ||||
|   // Setup Platform/Renderer backends | ||||
|   ImGui_ImplSDL2_InitForSDLRenderer(main_window_, main_renderer_); | ||||
|   ImGui_ImplSDLRenderer2_Init(main_renderer_); | ||||
|   // create window | ||||
|   CreateMainWindow(); | ||||
|   SetupMainWindow(); | ||||
|  | ||||
|   // Main loop | ||||
|   while (!exit_) { | ||||
| @@ -496,91 +758,32 @@ int Render::Run() { | ||||
|       localization_language_index_last_ = localization_language_index_; | ||||
|     } | ||||
|  | ||||
|     // Start the Dear ImGui frame | ||||
|     ImGui_ImplSDLRenderer2_NewFrame(); | ||||
|     ImGui_ImplSDL2_NewFrame(); | ||||
|     ImGui::NewFrame(); | ||||
|  | ||||
|     if (!fullscreen_button_pressed_) { | ||||
|       ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); | ||||
|       ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); | ||||
|       ImGui::SetNextWindowSize( | ||||
|           ImVec2(main_window_width_, | ||||
|                  (connection_established_ && streaming_ && is_client_mode_) | ||||
|                      ? (fullscreen_button_pressed_ ? 0 : title_bar_height_) | ||||
|                      : main_window_height_default_), | ||||
|           ImGuiCond_Always); | ||||
|       ImGui::Begin("Render", nullptr, | ||||
|                    ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | | ||||
|                        ImGuiWindowFlags_NoResize | | ||||
|                        ImGuiWindowFlags_NoScrollbar | | ||||
|                        ImGuiWindowFlags_NoBringToFrontOnFocus); | ||||
|       ImGui::PopStyleColor(); | ||||
|  | ||||
|       TitleBar(); | ||||
|  | ||||
|       if (connection_established_ && streaming_ && is_client_mode_) { | ||||
|         if (!resizable_) { | ||||
|           resizable_ = !resizable_; | ||||
|           SDL_SetWindowResizable(main_window_, SDL_TRUE); | ||||
|         } | ||||
|         ControlWindow(); | ||||
|       } else { | ||||
|         if (resizable_) { | ||||
|           resizable_ = !resizable_; | ||||
|           SDL_SetWindowResizable(main_window_, SDL_FALSE); | ||||
|         } | ||||
|         MainWindow(); | ||||
|       } | ||||
|  | ||||
|       ImGui::End(); | ||||
|     } else { | ||||
|       if (connection_established_ && streaming_ && is_client_mode_) { | ||||
|         if (!resizable_) { | ||||
|           resizable_ = !resizable_; | ||||
|           SDL_SetWindowResizable(main_window_, SDL_TRUE); | ||||
|         } | ||||
|  | ||||
|         ControlWindow(); | ||||
|       } else { | ||||
|         if (resizable_) { | ||||
|           resizable_ = !resizable_; | ||||
|           SDL_SetWindowResizable(main_window_, SDL_FALSE); | ||||
|         } | ||||
|         MainWindow(); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // create connection | ||||
|     if (SignalStatus::SignalConnected == signal_status_ && | ||||
|         !is_create_connection_ && password_inited_) { | ||||
|       LOG_INFO("Connected with signal server, create p2p connection"); | ||||
|       is_create_connection_ = | ||||
|           CreateConnection(peer_, client_id_, password_saved_) ? false : true; | ||||
|     } | ||||
|  | ||||
|     if (start_screen_capture_ && !screen_capture_is_started_) { | ||||
|       StartScreenCapture(); | ||||
|       screen_capture_is_started_ = true; | ||||
|     } else if (!start_screen_capture_ && screen_capture_is_started_) { | ||||
|       StopScreenCapture(); | ||||
|       screen_capture_is_started_ = false; | ||||
|     } | ||||
|  | ||||
|     if (start_mouse_control_ && !mouse_control_is_started_) { | ||||
|       StartMouseControl(); | ||||
|       mouse_control_is_started_ = true; | ||||
|     } else if (!start_mouse_control_ && mouse_control_is_started_) { | ||||
|       StopMouseControl(); | ||||
|       mouse_control_is_started_ = false; | ||||
|     } | ||||
|  | ||||
|     SDL_Event event; | ||||
|     while (SDL_PollEvent(&event)) { | ||||
|       ImGui_ImplSDL2_ProcessEvent(&event); | ||||
|       { | ||||
|         if (!main_ctx_) { | ||||
|           LOG_ERROR("Main context is null"); | ||||
|           return -1; | ||||
|         } | ||||
|  | ||||
|         ImGui::SetCurrentContext(main_ctx_); | ||||
|         ImGui_ImplSDL2_ProcessEvent(&event); | ||||
|       } | ||||
|       if (stream_window_inited_) { | ||||
|         if (!stream_ctx_) { | ||||
|           LOG_ERROR("Stream context is null"); | ||||
|           return -1; | ||||
|         } | ||||
|  | ||||
|         ImGui::SetCurrentContext(stream_ctx_); | ||||
|         ImGui_ImplSDL2_ProcessEvent(&event); | ||||
|       } | ||||
|       if (event.type == SDL_QUIT) { | ||||
|         if (streaming_) { | ||||
|           LOG_INFO("Return to main interface"); | ||||
|           LOG_INFO("Destroy stream window"); | ||||
|           DestroyStreamWindow(); | ||||
|           DestroyStreamWindowContext(); | ||||
|  | ||||
|           LOG_INFO("[{}] Leave connection [{}]", client_id_, remote_id_); | ||||
|           LeaveConnection(peer_reserved_ ? peer_reserved_ : peer_, | ||||
|                           remote_id_.c_str()); | ||||
| @@ -601,11 +804,11 @@ int Render::Run() { | ||||
|           SDL_SetWindowSize(main_window_, main_window_width_default_, | ||||
|                             main_window_height_default_); | ||||
|  | ||||
|           SDL_Rect display_bounds; | ||||
|           SDL_GetDisplayBounds(0, &display_bounds); | ||||
|           int center_x = (display_bounds.w - main_window_width_default_) / 2; | ||||
|           int center_y = (display_bounds.h - main_window_height_default_) / 2; | ||||
|           SDL_SetWindowPosition(main_window_, center_x, center_y); | ||||
|           // SDL_Rect display_bounds; | ||||
|           // SDL_GetDisplayBounds(0, &display_bounds); | ||||
|           // int center_x = (display_bounds.w - main_window_width_default_) / 2; | ||||
|           // int center_y = (display_bounds.h - main_window_height_default_) / | ||||
|           // 2; SDL_SetWindowPosition(main_window_, center_x, center_y); | ||||
|  | ||||
|           continue; | ||||
|         } else { | ||||
| @@ -617,15 +820,15 @@ int Render::Run() { | ||||
|       } else if (event.window.event == SDL_WINDOWEVENT_RESTORED) { | ||||
|         window_maximized_ = false; | ||||
|       } else if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { | ||||
|         SDL_GetWindowSize(main_window_, &main_window_width_, | ||||
|                           &main_window_height_); | ||||
|         SDL_GetWindowSize(stream_window_, &stream_window_width_, | ||||
|                           &stream_window_height_); | ||||
|  | ||||
|         float video_ratio = (float)video_width_ / (float)video_height_; | ||||
|         float video_ratio_reverse = (float)video_height_ / (float)video_width_; | ||||
|  | ||||
|         int render_area_width = main_window_width_; | ||||
|         int render_area_width = stream_window_width_; | ||||
|         int render_area_height = | ||||
|             main_window_height_ - | ||||
|             stream_window_height_ - | ||||
|             (fullscreen_button_pressed_ ? 0 : title_bar_height_); | ||||
|  | ||||
|         if (render_area_width < render_area_height * video_ratio) { | ||||
| @@ -667,8 +870,8 @@ int Render::Run() { | ||||
|  | ||||
|             SDL_DestroyTexture(stream_texture_); | ||||
|             stream_texture_ = SDL_CreateTexture( | ||||
|                 main_renderer_, stream_pixformat_, SDL_TEXTUREACCESS_STREAMING, | ||||
|                 texture_width_, texture_height_); | ||||
|                 stream_renderer_, stream_pixformat_, | ||||
|                 SDL_TEXTUREACCESS_STREAMING, texture_width_, texture_height_); | ||||
|           } | ||||
|         SDL_UpdateTexture(stream_texture_, NULL, dst_buffer_, texture_width_); | ||||
|       } else { | ||||
| @@ -678,17 +881,19 @@ int Render::Run() { | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Rendering | ||||
|     ImGui::Render(); | ||||
|  | ||||
|     SDL_RenderClear(main_renderer_); | ||||
|     if (connection_established_ && received_frame_ && streaming_) { | ||||
|       SDL_RenderCopy(main_renderer_, stream_texture_, NULL, | ||||
|                      &stream_render_rect_); | ||||
|     if (connection_established_ && streaming_) { | ||||
|       CreateStreamWindow(); | ||||
|       SetupStreamWindow(); | ||||
|     } | ||||
|  | ||||
|     ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), main_renderer_); | ||||
|     SDL_RenderPresent(main_renderer_); | ||||
|     DrawMainWindow(); | ||||
|  | ||||
|     if (stream_window_inited_) { | ||||
|       DrawStreamWindow(); | ||||
|     } | ||||
|  | ||||
|     // create connection | ||||
|     CreateRtcConnection(); | ||||
|  | ||||
|     // frame_count_++; | ||||
|     // end_time_ = SDL_GetTicks(); | ||||
| @@ -754,12 +959,8 @@ int Render::Run() { | ||||
|  | ||||
|   AudioDeviceDestroy(); | ||||
|  | ||||
|   ImGui_ImplSDLRenderer2_Shutdown(); | ||||
|   ImGui_ImplSDL2_Shutdown(); | ||||
|  | ||||
|   SDL_DestroyTexture(stream_texture_); | ||||
|   SDL_DestroyRenderer(main_renderer_); | ||||
|   SDL_DestroyWindow(main_window_); | ||||
|   DestroyMainWindow(); | ||||
|   DestroyMainWindowContext(); | ||||
|  | ||||
|   SDL_Quit(); | ||||
|  | ||||
|   | ||||
| @@ -32,7 +32,7 @@ class Render { | ||||
|  | ||||
|  private: | ||||
|   int CreateStreamRenderWindow(); | ||||
|   int TitleBar(); | ||||
|   int TitleBar(bool main_window); | ||||
|   int MainWindow(); | ||||
|   int LocalWindow(); | ||||
|   int RemoteWindow(); | ||||
| @@ -43,6 +43,20 @@ class Render { | ||||
|   int StatusBar(); | ||||
|   int ConnectionStatusWindow(); | ||||
|  | ||||
|  private: | ||||
|   int CreateRtcConnection(); | ||||
|   int CreateMainWindow(); | ||||
|   int DestroyMainWindow(); | ||||
|   int CreateStreamWindow(); | ||||
|   int DestroyStreamWindow(); | ||||
|   int SetupFontAndStyle(); | ||||
|   int SetupMainWindow(); | ||||
|   int DestroyMainWindowContext(); | ||||
|   int SetupStreamWindow(); | ||||
|   int DestroyStreamWindowContext(); | ||||
|   int DrawMainWindow(); | ||||
|   int DrawStreamWindow(); | ||||
|  | ||||
|  public: | ||||
|   static void OnReceiveVideoBufferCb(const XVideoFrame *video_frame, | ||||
|                                      const char *user_id, size_t user_id_size, | ||||
| @@ -145,6 +159,8 @@ class Render { | ||||
|   int main_window_height_ = 570; | ||||
|   int main_window_width_last_ = 960; | ||||
|   int main_window_height_last_ = 540; | ||||
|   int stream_window_width_default_ = 1280; | ||||
|   int stream_window_height_default_ = 720; | ||||
|   int stream_window_width_ = 1280; | ||||
|   int stream_window_height_ = 720; | ||||
|   int stream_window_width_last_ = 1280; | ||||
| @@ -169,8 +185,13 @@ class Render { | ||||
|  | ||||
|   int main_window_width_real_ = 960; | ||||
|   int main_window_height_real_ = 540; | ||||
|   float dpi_scaling_w_ = 1.0f; | ||||
|   float dpi_scaling_h_ = 1.0f; | ||||
|   float main_window_dpi_scaling_w_ = 1.0f; | ||||
|   float main_window_dpi_scaling_h_ = 1.0f; | ||||
|  | ||||
|   int stream_window_width_real_ = 1280; | ||||
|   int stream_window_height_real_ = 720; | ||||
|   float stream_window_dpi_scaling_w_ = 1.0f; | ||||
|   float stream_window_dpi_scaling_h_ = 1.0f; | ||||
|  | ||||
|   int texture_width_ = 1280; | ||||
|   int texture_height_ = 720; | ||||
| @@ -179,8 +200,15 @@ class Render { | ||||
|   int video_height_ = 720; | ||||
|   int video_size_ = 1280 * 720 * 3; | ||||
|  | ||||
|   SDL_Window *main_window_; | ||||
|   SDL_Window *main_window_ = nullptr; | ||||
|   SDL_Renderer *main_renderer_ = nullptr; | ||||
|   ImGuiContext *main_ctx_ = nullptr; | ||||
|  | ||||
|   SDL_Window *stream_window_ = nullptr; | ||||
|   SDL_Renderer *stream_renderer_ = nullptr; | ||||
|   ImGuiContext *stream_ctx_ = nullptr; | ||||
|   bool stream_window_created_ = false; | ||||
|   bool stream_window_inited_ = false; | ||||
|  | ||||
|   // video window | ||||
|   SDL_Texture *stream_texture_ = nullptr; | ||||
|   | ||||
| @@ -4,20 +4,23 @@ | ||||
|  | ||||
| #define BUTTON_PADDING 36.0f | ||||
|  | ||||
| int Render::TitleBar() { | ||||
| int Render::TitleBar(bool main_window) { | ||||
|   ImGui::PushStyleColor(ImGuiCol_MenuBarBg, ImVec4(1, 1, 1, 0.0f)); | ||||
|   ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); | ||||
|   ImGui::SetWindowFontScale(0.8f); | ||||
|   ImGui::BeginChild("TitleBar", ImVec2(main_window_width_, title_bar_height_), | ||||
|                     ImGuiChildFlags_None, | ||||
|                     ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDecoration | | ||||
|                         ImGuiWindowFlags_NoBringToFrontOnFocus); | ||||
|   ImGui::BeginChild( | ||||
|       "TitleBar", | ||||
|       ImVec2(main_window ? main_window_width_ : stream_window_width_, | ||||
|              title_bar_height_), | ||||
|       ImGuiChildFlags_None, | ||||
|       ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDecoration | | ||||
|           ImGuiWindowFlags_NoBringToFrontOnFocus); | ||||
|   ImDrawList* draw_list = ImGui::GetWindowDrawList(); | ||||
|  | ||||
|   if (ImGui::BeginMenuBar()) { | ||||
|     ImGui::SetCursorPosX(main_window_width_ - (streaming_ | ||||
|                                                    ? BUTTON_PADDING * 4 - 3 | ||||
|                                                    : BUTTON_PADDING * 3 - 3)); | ||||
|     ImGui::SetCursorPosX( | ||||
|         (main_window ? main_window_width_ : stream_window_width_) - | ||||
|         (streaming_ ? BUTTON_PADDING * 4 - 3 : BUTTON_PADDING * 3 - 3)); | ||||
|     ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0, 0, 0, 0.1f)); | ||||
|     ImGui::PushStyleColor(ImGuiCol_HeaderActive, | ||||
|                           ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); | ||||
| @@ -58,9 +61,9 @@ int Render::TitleBar() { | ||||
|     ImGui::PopStyleColor(2); | ||||
|  | ||||
|     ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); | ||||
|     ImGui::SetCursorPosX(main_window_width_ - (streaming_ | ||||
|                                                    ? BUTTON_PADDING * 3 | ||||
|                                                    : BUTTON_PADDING * 2)); | ||||
|     ImGui::SetCursorPosX( | ||||
|         (main_window ? main_window_width_ : stream_window_width_) - | ||||
|         (streaming_ ? BUTTON_PADDING * 3 : BUTTON_PADDING * 2)); | ||||
|     ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 0, 0, 0.1f)); | ||||
|     ImGui::PushStyleColor(ImGuiCol_ButtonActive, | ||||
|                           ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); | ||||
| @@ -70,7 +73,7 @@ int Render::TitleBar() { | ||||
|     std::string window_minimize_button = "##minimize";  // ICON_FA_MINUS; | ||||
|     if (ImGui::Button(window_minimize_button.c_str(), | ||||
|                       ImVec2(BUTTON_PADDING, 30))) { | ||||
|       SDL_MinimizeWindow(main_window_); | ||||
|       SDL_MinimizeWindow(main_window ? main_window_ : stream_window_); | ||||
|     } | ||||
|     draw_list->AddLine(ImVec2(minimize_pos_x, minimize_pos_y), | ||||
|                        ImVec2(minimize_pos_x + 12, minimize_pos_y), | ||||
| @@ -78,7 +81,9 @@ int Render::TitleBar() { | ||||
|     ImGui::PopStyleColor(2); | ||||
|  | ||||
|     if (streaming_) { | ||||
|       ImGui::SetCursorPosX(main_window_width_ - BUTTON_PADDING * 2); | ||||
|       ImGui::SetCursorPosX( | ||||
|           (main_window ? main_window_width_ : stream_window_width_) - | ||||
|           BUTTON_PADDING * 2); | ||||
|       ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 0, 0, 0.1f)); | ||||
|       ImGui::PushStyleColor(ImGuiCol_ButtonActive, | ||||
|                             ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); | ||||
| @@ -92,7 +97,7 @@ int Render::TitleBar() { | ||||
|             "##restore";  // ICON_FA_WINDOW_RESTORE; | ||||
|         if (ImGui::Button(window_restore_button.c_str(), | ||||
|                           ImVec2(BUTTON_PADDING, 30))) { | ||||
|           SDL_RestoreWindow(main_window_); | ||||
|           SDL_RestoreWindow(main_window ? main_window_ : stream_window_); | ||||
|           window_maximized_ = false; | ||||
|         } | ||||
|         draw_list->AddRect(ImVec2(pos_x_top, pos_y_top), | ||||
| @@ -111,7 +116,7 @@ int Render::TitleBar() { | ||||
|             "##maximize";  // ICON_FA_SQUARE_FULL; | ||||
|         if (ImGui::Button(window_maximize_button.c_str(), | ||||
|                           ImVec2(BUTTON_PADDING, 30))) { | ||||
|           SDL_MaximizeWindow(main_window_); | ||||
|           SDL_MaximizeWindow(main_window ? main_window_ : stream_window_); | ||||
|           window_maximized_ = !window_maximized_; | ||||
|         } | ||||
|         draw_list->AddRect(ImVec2(maximize_pos_x, maximize_pos_y), | ||||
| @@ -121,7 +126,9 @@ int Render::TitleBar() { | ||||
|       ImGui::PopStyleColor(2); | ||||
|     } | ||||
|  | ||||
|     ImGui::SetCursorPosX(main_window_width_ - BUTTON_PADDING); | ||||
|     ImGui::SetCursorPosX( | ||||
|         (main_window ? main_window_width_ : stream_window_width_) - | ||||
|         BUTTON_PADDING); | ||||
|     ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0, 0, 1.0f)); | ||||
|     ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 0, 0, 0.5f)); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user