From d60fdf9050e73c350713453bf07c68bd26f81365 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Mon, 25 Aug 2025 19:46:30 +0800 Subject: [PATCH] [feat] update SDL2 to SDL3 --- src/single_window/control_bar.cpp | 4 +- src/single_window/render.cpp | 354 ++++++++++----------- src/single_window/render.h | 27 +- src/single_window/render_callback_func.cpp | 22 +- src/single_window/stream_window.cpp | 8 +- src/single_window/thumbnail.cpp | 9 +- src/single_window/thumbnail.h | 2 +- src/single_window/title_bar.cpp | 2 +- xmake.lua | 11 +- 9 files changed, 205 insertions(+), 234 deletions(-) diff --git a/src/single_window/control_bar.cpp b/src/single_window/control_bar.cpp index e70a998..8d12b92 100644 --- a/src/single_window/control_bar.cpp +++ b/src/single_window/control_bar.cpp @@ -195,9 +195,9 @@ int Render::ControlBar(std::shared_ptr& props) { : localization::fullscreen[localization_language_index_]; if (fullscreen_button_pressed_) { - SDL_SetWindowFullscreen(stream_window_, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_SetWindowFullscreen(stream_window_, true); } else { - SDL_SetWindowFullscreen(stream_window_, SDL_FALSE); + SDL_SetWindowFullscreen(stream_window_, false); } props->reset_control_bar_pos_ = true; } diff --git a/src/single_window/render.cpp b/src/single_window/render.cpp index 03c529a..4e71580 100644 --- a/src/single_window/render.cpp +++ b/src/single_window/render.cpp @@ -19,8 +19,6 @@ #define MOUSE_GRAB_PADDING 5 -#define STREAM_FRASH (SDL_USEREVENT + 1) - std::vector Render::SerializeRemoteAction(const RemoteAction& action) { std::vector buffer; buffer.push_back(static_cast(action.type)); @@ -128,7 +126,7 @@ SDL_HitTestResult Render::HitTestCallback(SDL_Window* window, } int window_width, window_height; - SDL_GetWindowSize(window, &window_width, &window_height); + SDL_GetWindowSizeInPixels(window, &window_width, &window_height); if (area->y < 30 && area->y > MOUSE_GRAB_PADDING && area->x < window_width - 120 && area->x > MOUSE_GRAB_PADDING && @@ -512,49 +510,47 @@ int Render::CreateConnectionPeer() { } int Render::AudioDeviceInit() { - // Audio - SDL_AudioSpec want_in = {}; - SDL_AudioSpec want_out = {}; - SDL_zero(want_in); - want_in.freq = 48000; - want_in.format = AUDIO_S16LSB; - want_in.channels = 1; - want_in.samples = 480; - want_in.callback = SdlCaptureAudioIn; - want_in.userdata = this; + SDL_AudioSpec desired_in{}; + desired_in.freq = 48000; + desired_in.format = SDL_AUDIO_S16; + desired_in.channels = 1; - // input_dev_ = SDL_OpenAudioDevice(NULL, 1, &want_in, &have_in, 0); - // if (input_dev_ == 0) { - // SDL_Log("Failed to open input: %s", SDL_GetError()); - // // return 1; - // } + SDL_AudioSpec desired_out{}; + desired_out.freq = 48000; + desired_out.format = SDL_AUDIO_S16; + desired_out.channels = 1; - SDL_zero(want_out); - want_out.freq = 48000; - want_out.format = AUDIO_S16LSB; - want_out.channels = 1; - // want_out.silence = 0; - want_out.samples = 480; - want_out.callback = nullptr; - want_out.userdata = this; - - output_dev_ = SDL_OpenAudioDevice(nullptr, 0, &want_out, NULL, 0); - if (output_dev_ == 0) { - SDL_Log("Failed to open input: %s", SDL_GetError()); - // return 1; + input_stream_ = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_RECORDING, + &desired_in, nullptr, nullptr); + if (!input_stream_) { + LOG_ERROR("Failed to open input stream: {}", SDL_GetError()); + return -1; } - // SDL_PauseAudioDevice(input_dev_, 0); - SDL_PauseAudioDevice(output_dev_, 0); + output_stream_ = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, + &desired_out, nullptr, nullptr); + if (!output_stream_) { + LOG_ERROR("Failed to open output stream: {}", SDL_GetError()); + return -1; + } + + SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(input_stream_)); + SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(output_stream_)); return 0; } int Render::AudioDeviceDestroy() { - SDL_PauseAudioDevice(output_dev_, 1); - SDL_CloseAudioDevice(output_dev_); - // SDL_CloseAudioDevice(input_dev_); - + if (input_stream_) { + SDL_CloseAudioDevice(SDL_GetAudioStreamDevice(input_stream_)); + SDL_DestroyAudioStream(input_stream_); + input_stream_ = nullptr; + } + if (output_stream_) { + SDL_CloseAudioDevice(SDL_GetAudioStreamDevice(output_stream_)); + SDL_DestroyAudioStream(output_stream_); + output_stream_ = nullptr; + } return 0; } @@ -595,22 +591,18 @@ int Render::CreateMainWindow() { ImGui::SetCurrentContext(main_ctx_); - SDL_WindowFlags window_flags = - (SDL_WindowFlags)(SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_BORDERLESS | - SDL_WINDOW_HIDDEN); - main_window_ = - SDL_CreateWindow("Remote Desk", SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, (int)main_window_width_default_, - (int)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("Error creating SDL_Renderer"); - return 0; + if (!SDL_CreateWindowAndRenderer( + "Remote Desk", (int)main_window_width_default_, + (int)main_window_height_default_, + SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_BORDERLESS | + SDL_WINDOW_HIDDEN, + &main_window_, &main_renderer_)) { + LOG_ERROR("Error creating main_window_ and main_renderer_: {}", + SDL_GetError()); + return -1; } - SDL_SetWindowResizable(main_window_, SDL_FALSE); + SDL_SetWindowResizable(main_window_, false); // for window region action SDL_SetWindowHitTest(main_window_, HitTestCallback, this); @@ -647,35 +639,27 @@ int Render::CreateStreamWindow() { 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; + if (!SDL_CreateWindowAndRenderer( + "Stream window", (int)stream_window_width_default_, + (int)stream_window_height_default_, + SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_BORDERLESS, + &stream_window_, &stream_renderer_)) { + LOG_ERROR("Error creating stream_window_ and stream_renderer_: {}", + SDL_GetError()); + return -1; } 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); + SDL_SetWindowResizable(stream_window_, true); // for window region action SDL_SetWindowHitTest(stream_window_, HitTestCallback, this); // change props->stream_render_rect_ SDL_Event event; - event.type = SDL_WINDOWEVENT; + event.type = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED; event.window.windowID = SDL_GetWindowID(stream_window_); - event.window.event = SDL_WINDOWEVENT_SIZE_CHANGED; SDL_PushEvent(&event); stream_window_created_ = true; @@ -744,25 +728,16 @@ int Render::SetupMainWindow() { SetupFontAndStyle(); - SDL_GL_GetDrawableSize(main_window_, &main_window_width_real_, - &main_window_height_real_); - main_window_dpi_scaling_w_ = main_window_width_real_ / main_window_width_; - main_window_dpi_scaling_h_ = main_window_width_real_ / 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_); + ImGui_ImplSDL3_InitForSDLRenderer(main_window_, main_renderer_); + ImGui_ImplSDLRenderer3_Init(main_renderer_); return 0; } int Render::DestroyMainWindowContext() { ImGui::SetCurrentContext(main_ctx_); - ImGui_ImplSDLRenderer2_Shutdown(); - ImGui_ImplSDL2_Shutdown(); + ImGui_ImplSDLRenderer3_Shutdown(); + ImGui_ImplSDL3_Shutdown(); ImGui::DestroyContext(main_ctx_); return 0; @@ -782,21 +757,8 @@ int Render::SetupStreamWindow() { SetupFontAndStyle(); - SDL_GL_GetDrawableSize(stream_window_, &stream_window_width_real_, - &stream_window_height_real_); - - stream_window_dpi_scaling_w_ = - stream_window_width_real_ / stream_window_width_; - stream_window_dpi_scaling_h_ = - stream_window_width_real_ / 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_); + ImGui_ImplSDL3_InitForSDLRenderer(stream_window_, stream_renderer_); + ImGui_ImplSDLRenderer3_Init(stream_renderer_); stream_window_inited_ = true; LOG_INFO("Stream window inited"); @@ -807,8 +769,8 @@ int Render::SetupStreamWindow() { int Render::DestroyStreamWindowContext() { stream_window_inited_ = false; ImGui::SetCurrentContext(stream_ctx_); - ImGui_ImplSDLRenderer2_Shutdown(); - ImGui_ImplSDL2_Shutdown(); + ImGui_ImplSDLRenderer3_Shutdown(); + ImGui_ImplSDL3_Shutdown(); ImGui::DestroyContext(stream_ctx_); return 0; @@ -821,8 +783,8 @@ int Render::DrawMainWindow() { } ImGui::SetCurrentContext(main_ctx_); - ImGui_ImplSDLRenderer2_NewFrame(); - ImGui_ImplSDL2_NewFrame(); + ImGui_ImplSDLRenderer3_NewFrame(); + ImGui_ImplSDL3_NewFrame(); ImGui::NewFrame(); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); @@ -845,7 +807,7 @@ int Render::DrawMainWindow() { // Rendering ImGui::Render(); SDL_RenderClear(main_renderer_); - ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), main_renderer_); + ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), main_renderer_); SDL_RenderPresent(main_renderer_); return 0; @@ -858,8 +820,8 @@ int Render::DrawStreamWindow() { } ImGui::SetCurrentContext(stream_ctx_); - ImGui_ImplSDLRenderer2_NewFrame(); - ImGui_ImplSDL2_NewFrame(); + ImGui_ImplSDLRenderer3_NewFrame(); + ImGui_ImplSDL3_NewFrame(); ImGui::NewFrame(); StreamWindow(); @@ -889,11 +851,16 @@ int Render::DrawStreamWindow() { for (auto& it : client_properties_) { auto props = it.second; if (props->tab_selected_) { - SDL_RenderCopy(stream_renderer_, props->stream_texture_, NULL, - &(props->stream_render_rect_)); + SDL_FRect render_rect_f = { + static_cast(props->stream_render_rect_.x), + static_cast(props->stream_render_rect_.y), + static_cast(props->stream_render_rect_.w), + static_cast(props->stream_render_rect_.h)}; + SDL_RenderTexture(stream_renderer_, props->stream_texture_, NULL, + &render_rect_f); } } - ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), stream_renderer_); + ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), stream_renderer_); SDL_RenderPresent(stream_renderer_); return 0; @@ -946,20 +913,23 @@ void Render::InitializeSettings() { } void Render::InitializeSDL() { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | - SDL_INIT_GAMECONTROLLER) != 0) { - printf("Error: %s\n", SDL_GetError()); - exit(-1); + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + LOG_ERROR("Error: {}", SDL_GetError()); + return; } - SDL_DisplayMode DM; - SDL_GetCurrentDisplayMode(0, &DM); - screen_width_ = DM.w; - screen_height_ = DM.h; + const SDL_DisplayMode* dm = SDL_GetCurrentDisplayMode(0); + if (dm) { + screen_width_ = dm->w; + screen_height_ = dm->h; + } + + STREAM_REFRESH_EVENT = SDL_RegisterEvents(1); + if (STREAM_REFRESH_EVENT == (uint32_t)-1) { + LOG_ERROR("Failed to register custom SDL event"); + } LOG_INFO("Screen resolution: [{}x{}]", screen_width_, screen_height_); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); } void Render::InitializeModules() { @@ -1082,10 +1052,10 @@ void Render::HandleStreamWindow() { if (stream_window_inited_) { if (!stream_window_grabbed_ && control_mouse_) { - SDL_SetWindowGrab(stream_window_, SDL_TRUE); + SDL_SetWindowMouseGrab(stream_window_, true); stream_window_grabbed_ = true; } else if (stream_window_grabbed_ && !control_mouse_) { - SDL_SetWindowGrab(stream_window_, SDL_FALSE); + SDL_SetWindowMouseGrab(stream_window_, false); stream_window_grabbed_ = false; } } @@ -1135,13 +1105,13 @@ void Render::CleanupFactories() { } if (device_controller_factory_) { - delete device_controller_factory_; + SDL_FlushEvent(STREAM_REFRESH_EVENT); device_controller_factory_ = nullptr; } } void Render::CleanupPeer(std::shared_ptr props) { - SDL_FlushEvent(STREAM_FRASH); + SDL_FlushEvent(STREAM_REFRESH_EVENT); if (props->dst_buffer_) { thumbnail_->SaveToThumbnail( @@ -1200,8 +1170,8 @@ void Render::UpdateRenderRect() { } int stream_window_width, stream_window_height; - SDL_GetWindowSize(stream_window_, &stream_window_width, - &stream_window_height); + SDL_GetWindowSizeInPixels(stream_window_, &stream_window_width, + &stream_window_height); stream_window_width_ = (float)stream_window_width; stream_window_height_ = (float)stream_window_height; @@ -1241,7 +1211,7 @@ void Render::ProcessSdlEvent() { while (SDL_PollEvent(&event)) { if (main_ctx_) { ImGui::SetCurrentContext(main_ctx_); - ImGui_ImplSDL2_ProcessEvent(&event); + ImGui_ImplSDL3_ProcessEvent(&event); } else { LOG_ERROR("Main context is null"); return; @@ -1250,7 +1220,7 @@ void Render::ProcessSdlEvent() { if (stream_window_inited_) { if (stream_ctx_) { ImGui::SetCurrentContext(stream_ctx_); - ImGui_ImplSDL2_ProcessEvent(&event); + ImGui_ImplSDL3_ProcessEvent(&event); } else { LOG_ERROR("Stream context is null"); return; @@ -1258,10 +1228,10 @@ void Render::ProcessSdlEvent() { } switch (event.type) { - case SDL_QUIT: + case SDL_EVENT_QUIT: if (stream_window_inited_) { LOG_INFO("Destroy stream window"); - SDL_SetWindowGrab(stream_window_, SDL_FALSE); + SDL_SetWindowMouseGrab(stream_window_, false); DestroyStreamWindow(); DestroyStreamWindowContext(); @@ -1283,13 +1253,13 @@ void Render::ProcessSdlEvent() { props->streaming_ = false; props->remember_password_ = false; - props->connection_established_ = false; + SDL_FlushEvents(STREAM_REFRESH_EVENT, STREAM_REFRESH_EVENT); props->audio_capture_button_pressed_ = false; memset(&props->net_traffic_stats_, 0, sizeof(props->net_traffic_stats_)); - SDL_SetWindowFullscreen(main_window_, SDL_FALSE); - SDL_FlushEvents(STREAM_FRASH, STREAM_FRASH); + SDL_SetWindowFullscreen(main_window_, false); + SDL_FlushEvents(STREAM_REFRESH_EVENT, STREAM_REFRESH_EVENT); memset(audio_buffer_, 0, 720); } client_properties_.clear(); @@ -1306,79 +1276,83 @@ void Render::ProcessSdlEvent() { } break; - case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_CLOSE && - event.window.windowID != SDL_GetWindowID(stream_window_)) { + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + if (event.window.windowID != SDL_GetWindowID(stream_window_)) { exit_ = true; - } else if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED && - stream_window_created_ && - event.window.windowID == SDL_GetWindowID(stream_window_)) { + } + break; + + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + if (stream_window_created_ && + event.window.windowID == SDL_GetWindowID(stream_window_)) { UpdateRenderRect(); - } else if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED || - event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { - bool focus_gained = - event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED; - if (stream_window_ && - SDL_GetWindowID(stream_window_) == event.window.windowID) { - foucs_on_stream_window_ = focus_gained; - } else if (main_window_ && - SDL_GetWindowID(main_window_) == event.window.windowID) { - foucs_on_main_window_ = focus_gained; - } } break; - case STREAM_FRASH: { - auto* props = static_cast(event.user.data1); - if (!props) { - continue; + case SDL_EVENT_WINDOW_FOCUS_GAINED: + if (stream_window_ && + SDL_GetWindowID(stream_window_) == event.window.windowID) { + foucs_on_stream_window_ = true; + } else if (main_window_ && + SDL_GetWindowID(main_window_) == event.window.windowID) { + foucs_on_main_window_ = true; } - if (props->video_width_ <= 0 || props->video_height_ <= 0) { - continue; - } - if (!props->dst_buffer_) { - continue; - } - - if (props->stream_texture_) { - if (props->video_width_ != props->texture_width_ || - props->video_height_ != props->texture_height_) { - // LOG_WARN("Resolution changed, old: [{}x{}], new: [{}x{}]", - // props->texture_width_, props->texture_height_, - // props->video_width_, props->video_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 { - 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_); break; - } - case SDL_MOUSEMOTION: - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEWHEEL: + case SDL_EVENT_WINDOW_FOCUS_LOST: + if (stream_window_ && + SDL_GetWindowID(stream_window_) == event.window.windowID) { + foucs_on_stream_window_ = false; + } else if (main_window_ && + SDL_GetWindowID(main_window_) == event.window.windowID) { + foucs_on_main_window_ = false; + } + break; + + case SDL_EVENT_MOUSE_MOTION: + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + case SDL_EVENT_MOUSE_WHEEL: if (foucs_on_stream_window_) { ProcessMouseEvent(event); } break; + } - default: - break; + if (event.type == STREAM_REFRESH_EVENT) { + auto* props = static_cast(event.user.data1); + if (!props) { + continue; + } + if (props->video_width_ <= 0 || props->video_height_ <= 0) { + continue; + } + if (!props->dst_buffer_) { + continue; + } + + 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 { + 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_); + break; } } } \ No newline at end of file diff --git a/src/single_window/render.h b/src/single_window/render.h index 5b74f93..a685adf 100644 --- a/src/single_window/render.h +++ b/src/single_window/render.h @@ -7,7 +7,7 @@ #ifndef _MAIN_WINDOW_H_ #define _MAIN_WINDOW_H_ -#include +#include #include #include @@ -21,8 +21,8 @@ #include "config_center.h" #include "device_controller_factory.h" #include "imgui.h" -#include "imgui_impl_sdl2.h" -#include "imgui_impl_sdlrenderer2.h" +#include "imgui_impl_sdl3.h" +#include "imgui_impl_sdlrenderer3.h" #include "imgui_internal.h" #include "minirtc.h" #include "path_manager.h" @@ -76,10 +76,10 @@ class Render { double net_traffic_stats_button_pressed_time_ = 0; unsigned char *dst_buffer_ = nullptr; size_t dst_buffer_capacity_ = 0; - int mouse_pos_x_ = 0; - int mouse_pos_y_ = 0; - int mouse_pos_x_last_ = 0; - int mouse_pos_y_last_ = 0; + float mouse_pos_x_ = 0; + float mouse_pos_y_ = 0; + float mouse_pos_x_last_ = 0; + float mouse_pos_y_last_ = 0; int texture_width_ = 1280; int texture_height_ = 720; int video_width_ = 0; @@ -300,10 +300,6 @@ class Render { bool foucs_on_main_window_ = false; bool foucs_on_stream_window_ = 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; - float main_window_dpi_scaling_h_ = 1.0f; float main_window_width_default_ = 640; float main_window_height_default_ = 480; float main_window_width_ = 640; @@ -346,6 +342,9 @@ class Render { std::string focused_remote_id_ = ""; bool need_to_send_host_info_ = false; SDL_Event last_mouse_event; + SDL_AudioStream *input_stream_; + SDL_AudioStream *output_stream_; + uint32_t STREAM_REFRESH_EVENT = 0; // stream window render SDL_Window *stream_window_ = nullptr; @@ -363,11 +362,7 @@ class Render { int stream_window_height_default_ = 720; float stream_window_width_ = 1280; float stream_window_height_ = 720; - uint32_t stream_pixformat_ = 0; - 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; + SDL_PixelFormat stream_pixformat_ = SDL_PIXELFORMAT_NV12; bool label_inited_ = false; bool connect_button_pressed_ = false; diff --git a/src/single_window/render_callback_func.cpp b/src/single_window/render_callback_func.cpp index ddc3ae6..2d22997 100644 --- a/src/single_window/render_callback_func.cpp +++ b/src/single_window/render_callback_func.cpp @@ -6,8 +6,6 @@ #define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 -#define STREAM_FRASH (SDL_USEREVENT + 1) - #ifdef DESK_PORT_DEBUG #else #define MOUSE_CONTROL 1 @@ -68,7 +66,7 @@ int Render::ProcessMouseEvent(SDL_Event &event) { (float)(event.button.y - props->stream_render_rect_.y) / render_height; - if (SDL_MOUSEBUTTONDOWN == event.type) { + if (SDL_EVENT_MOUSE_BUTTON_DOWN == event.type) { remote_action.type = ControlType::mouse; if (SDL_BUTTON_LEFT == event.button.button) { remote_action.m.flag = MouseFlag::left_down; @@ -77,7 +75,7 @@ int Render::ProcessMouseEvent(SDL_Event &event) { } else if (SDL_BUTTON_MIDDLE == event.button.button) { remote_action.m.flag = MouseFlag::middle_down; } - } else if (SDL_MOUSEBUTTONUP == event.type) { + } else if (SDL_EVENT_MOUSE_BUTTON_UP == event.type) { remote_action.type = ControlType::mouse; if (SDL_BUTTON_LEFT == event.button.button) { remote_action.m.flag = MouseFlag::left_up; @@ -86,7 +84,7 @@ int Render::ProcessMouseEvent(SDL_Event &event) { } else if (SDL_BUTTON_MIDDLE == event.button.button) { remote_action.m.flag = MouseFlag::middle_up; } - } else if (SDL_MOUSEMOTION == event.type) { + } else if (SDL_EVENT_MOUSE_MOTION == event.type) { remote_action.type = ControlType::mouse; remote_action.m.flag = MouseFlag::move; } @@ -96,7 +94,7 @@ int Render::ProcessMouseEvent(SDL_Event &event) { } SendDataFrame(props->peer_, (const char *)&remote_action, sizeof(remote_action), props->data_label_.c_str()); - } else if (SDL_MOUSEWHEEL == event.type && + } else if (SDL_EVENT_MOUSE_WHEEL == event.type && last_mouse_event.button.x >= props->stream_render_rect_.x && last_mouse_event.button.x <= props->stream_render_rect_.x + props->stream_render_rect_.w && @@ -231,8 +229,7 @@ void Render::OnReceiveVideoBufferCb(const XVideoFrame *video_frame, } SDL_Event event; - event.type = STREAM_FRASH; - event.user.type = STREAM_FRASH; + event.type = render->STREAM_REFRESH_EVENT; event.user.data1 = props; SDL_PushEvent(&event); props->streaming_ = true; @@ -248,7 +245,14 @@ void Render::OnReceiveAudioBufferCb(const char *data, size_t size, } render->audio_buffer_fresh_ = true; - SDL_QueueAudio(render->output_dev_, data, (uint32_t)size); + + if (render->output_stream_) { + int pushed = SDL_PutAudioStreamData( + render->output_stream_, (const Uint8 *)data, static_cast(size)); + if (pushed < 0) { + LOG_ERROR("Failed to push audio data: {}", SDL_GetError()); + } + } } void Render::OnReceiveDataBufferCb(const char *data, size_t size, diff --git a/src/single_window/stream_window.cpp b/src/single_window/stream_window.cpp index 7f7ded6..64ba758 100644 --- a/src/single_window/stream_window.cpp +++ b/src/single_window/stream_window.cpp @@ -34,7 +34,7 @@ void Render::CloseTab(decltype(client_properties_)::iterator& it) { it = client_properties_.erase(it); if (client_properties_.empty()) { SDL_Event event; - event.type = SDL_QUIT; + event.type = SDL_EVENT_QUIT; SDL_PushEvent(&event); } } @@ -120,7 +120,7 @@ int Render::StreamWindow() { it = client_properties_.erase(it); if (client_properties_.empty()) { SDL_Event event; - event.type = SDL_QUIT; + event.type = SDL_EVENT_QUIT; SDL_PushEvent(&event); } } else { @@ -175,11 +175,11 @@ int Render::StreamWindow() { if (!props->peer_) { fullscreen_button_pressed_ = false; - SDL_SetWindowFullscreen(stream_window_, SDL_FALSE); + SDL_SetWindowFullscreen(stream_window_, false); it = client_properties_.erase(it); if (client_properties_.empty()) { SDL_Event event; - event.type = SDL_QUIT; + event.type = SDL_EVENT_QUIT; SDL_PushEvent(&event); } } else { diff --git a/src/single_window/thumbnail.cpp b/src/single_window/thumbnail.cpp index 4a4679c..cb9d3fa 100644 --- a/src/single_window/thumbnail.cpp +++ b/src/single_window/thumbnail.cpp @@ -38,9 +38,10 @@ bool LoadTextureFromMemory(const void* data, size_t data_size, } // ABGR - SDL_Surface* surface = SDL_CreateRGBSurfaceFrom( - (void*)image_data, image_width, image_height, channels * 8, - channels * image_width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); + int pitch = image_width * channels; + SDL_Surface* surface = + SDL_CreateSurfaceFrom(image_width, image_height, SDL_PIXELFORMAT_RGBA32, + (void*)image_data, pitch); if (surface == nullptr) { LOG_ERROR("Failed to create SDL surface: [{}]", SDL_GetError()); return false; @@ -55,7 +56,7 @@ bool LoadTextureFromMemory(const void* data, size_t data_size, *out_width = image_width; *out_height = image_height; - SDL_FreeSurface(surface); + SDL_DestroySurface(surface); stbi_image_free(image_data); return true; diff --git a/src/single_window/thumbnail.h b/src/single_window/thumbnail.h index 273a8b3..3756781 100644 --- a/src/single_window/thumbnail.h +++ b/src/single_window/thumbnail.h @@ -7,7 +7,7 @@ #ifndef _THUMBNAIL_H_ #define _THUMBNAIL_H_ -#include +#include #include #include diff --git a/src/single_window/title_bar.cpp b/src/single_window/title_bar.cpp index 6cdc5ee..cd75b29 100644 --- a/src/single_window/title_bar.cpp +++ b/src/single_window/title_bar.cpp @@ -139,7 +139,7 @@ int Render::TitleBar(bool main_window) { std::string close_button = "##xmark"; // ICON_FA_XMARK; if (ImGui::Button(close_button.c_str(), ImVec2(BUTTON_PADDING, 30))) { SDL_Event event; - event.type = SDL_QUIT; + event.type = SDL_EVENT_QUIT; SDL_PushEvent(&event); } draw_list->AddLine(ImVec2(xmark_pos_x - xmark_size / 2 - 0.25f, diff --git a/xmake.lua b/xmake.lua index cd280b8..ded7e91 100644 --- a/xmake.lua +++ b/xmake.lua @@ -17,26 +17,23 @@ if is_mode("debug") then end add_requires("spdlog 1.14.1", {system = false}) -add_requires("imgui v1.91.5-docking", {configs = {sdl2 = true, sdl2_renderer = true}}) +add_requires("imgui v1.91.5-docking", {configs = {sdl3 = true, sdl3_renderer = true}}) add_requires("openssl3 3.3.2", {system = false}) -add_requires("libsdl2", {configs = {pulseaudio = true}}) -add_packages("libsdl2") - if is_os("windows") then add_requires("libyuv", "miniaudio 0.11.21") add_links("Shell32", "windowsapp", "dwmapi", "User32", "kernel32", - "SDL2-static", "SDL2main", "gdi32", "winmm", "setupapi", "version", + "SDL3-static", "gdi32", "winmm", "setupapi", "version", "Imm32", "iphlpapi") add_cxflags("/WX") elseif is_os("linux") then add_links("pulse-simple", "pulse") add_requires("libyuv") add_syslinks("pthread", "dl") - add_links("SDL2", "asound", "X11", "Xtst", "Xrandr") + add_links("SDL3", "asound", "X11", "Xtst", "Xrandr") add_cxflags("-Wno-unused-variable") elseif is_os("macosx") then - add_links("SDL2", "SDL2main") + add_links("SDL3") add_ldflags("-Wl,-ld_classic") add_cxflags("-Wno-unused-variable") add_frameworks("OpenGL", "IOSurface", "ScreenCaptureKit", "AVFoundation",