[feat] update SDL2 to SDL3

This commit is contained in:
dijunkun
2025-08-25 19:46:30 +08:00
parent 9912a88a13
commit d60fdf9050
9 changed files with 205 additions and 234 deletions

View File

@@ -195,9 +195,9 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
: localization::fullscreen[localization_language_index_]; : localization::fullscreen[localization_language_index_];
if (fullscreen_button_pressed_) { if (fullscreen_button_pressed_) {
SDL_SetWindowFullscreen(stream_window_, SDL_WINDOW_FULLSCREEN_DESKTOP); SDL_SetWindowFullscreen(stream_window_, true);
} else { } else {
SDL_SetWindowFullscreen(stream_window_, SDL_FALSE); SDL_SetWindowFullscreen(stream_window_, false);
} }
props->reset_control_bar_pos_ = true; props->reset_control_bar_pos_ = true;
} }

View File

@@ -19,8 +19,6 @@
#define MOUSE_GRAB_PADDING 5 #define MOUSE_GRAB_PADDING 5
#define STREAM_FRASH (SDL_USEREVENT + 1)
std::vector<char> Render::SerializeRemoteAction(const RemoteAction& action) { std::vector<char> Render::SerializeRemoteAction(const RemoteAction& action) {
std::vector<char> buffer; std::vector<char> buffer;
buffer.push_back(static_cast<char>(action.type)); buffer.push_back(static_cast<char>(action.type));
@@ -128,7 +126,7 @@ SDL_HitTestResult Render::HitTestCallback(SDL_Window* window,
} }
int window_width, window_height; 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 && if (area->y < 30 && area->y > MOUSE_GRAB_PADDING &&
area->x < window_width - 120 && area->x > MOUSE_GRAB_PADDING && area->x < window_width - 120 && area->x > MOUSE_GRAB_PADDING &&
@@ -512,49 +510,47 @@ int Render::CreateConnectionPeer() {
} }
int Render::AudioDeviceInit() { int Render::AudioDeviceInit() {
// Audio SDL_AudioSpec desired_in{};
SDL_AudioSpec want_in = {}; desired_in.freq = 48000;
SDL_AudioSpec want_out = {}; desired_in.format = SDL_AUDIO_S16;
SDL_zero(want_in); desired_in.channels = 1;
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;
// input_dev_ = SDL_OpenAudioDevice(NULL, 1, &want_in, &have_in, 0); SDL_AudioSpec desired_out{};
// if (input_dev_ == 0) { desired_out.freq = 48000;
// SDL_Log("Failed to open input: %s", SDL_GetError()); desired_out.format = SDL_AUDIO_S16;
// // return 1; desired_out.channels = 1;
// }
SDL_zero(want_out); input_stream_ = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_RECORDING,
want_out.freq = 48000; &desired_in, nullptr, nullptr);
want_out.format = AUDIO_S16LSB; if (!input_stream_) {
want_out.channels = 1; LOG_ERROR("Failed to open input stream: {}", SDL_GetError());
// want_out.silence = 0; return -1;
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;
} }
// SDL_PauseAudioDevice(input_dev_, 0); output_stream_ = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK,
SDL_PauseAudioDevice(output_dev_, 0); &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; return 0;
} }
int Render::AudioDeviceDestroy() { int Render::AudioDeviceDestroy() {
SDL_PauseAudioDevice(output_dev_, 1); if (input_stream_) {
SDL_CloseAudioDevice(output_dev_); SDL_CloseAudioDevice(SDL_GetAudioStreamDevice(input_stream_));
// SDL_CloseAudioDevice(input_dev_); 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; return 0;
} }
@@ -595,22 +591,18 @@ int Render::CreateMainWindow() {
ImGui::SetCurrentContext(main_ctx_); ImGui::SetCurrentContext(main_ctx_);
SDL_WindowFlags window_flags = if (!SDL_CreateWindowAndRenderer(
(SDL_WindowFlags)(SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_BORDERLESS | "Remote Desk", (int)main_window_width_default_,
SDL_WINDOW_HIDDEN); (int)main_window_height_default_,
main_window_ = SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_BORDERLESS |
SDL_CreateWindow("Remote Desk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOW_HIDDEN,
SDL_WINDOWPOS_UNDEFINED, (int)main_window_width_default_, &main_window_, &main_renderer_)) {
(int)main_window_height_default_, window_flags); LOG_ERROR("Error creating main_window_ and main_renderer_: {}",
SDL_GetError());
main_renderer_ = SDL_CreateRenderer( return -1;
main_window_, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
if (main_renderer_ == nullptr) {
LOG_ERROR("Error creating SDL_Renderer");
return 0;
} }
SDL_SetWindowResizable(main_window_, SDL_FALSE); SDL_SetWindowResizable(main_window_, false);
// for window region action // for window region action
SDL_SetWindowHitTest(main_window_, HitTestCallback, this); SDL_SetWindowHitTest(main_window_, HitTestCallback, this);
@@ -647,35 +639,27 @@ int Render::CreateStreamWindow() {
ImGui::SetCurrentContext(stream_ctx_); ImGui::SetCurrentContext(stream_ctx_);
SDL_WindowFlags window_flags = if (!SDL_CreateWindowAndRenderer(
(SDL_WindowFlags)(SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_BORDERLESS); "Stream window", (int)stream_window_width_default_,
stream_window_ = (int)stream_window_height_default_,
SDL_CreateWindow("Stream window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_BORDERLESS,
SDL_WINDOWPOS_UNDEFINED, stream_window_width_default_, &stream_window_, &stream_renderer_)) {
stream_window_height_default_, window_flags); LOG_ERROR("Error creating stream_window_ and stream_renderer_: {}",
SDL_GetError());
stream_renderer_ = SDL_CreateRenderer( return -1;
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_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 // for window region action
SDL_SetWindowHitTest(stream_window_, HitTestCallback, this); SDL_SetWindowHitTest(stream_window_, HitTestCallback, this);
// change props->stream_render_rect_ // change props->stream_render_rect_
SDL_Event event; SDL_Event event;
event.type = SDL_WINDOWEVENT; event.type = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED;
event.window.windowID = SDL_GetWindowID(stream_window_); event.window.windowID = SDL_GetWindowID(stream_window_);
event.window.event = SDL_WINDOWEVENT_SIZE_CHANGED;
SDL_PushEvent(&event); SDL_PushEvent(&event);
stream_window_created_ = true; stream_window_created_ = true;
@@ -744,25 +728,16 @@ int Render::SetupMainWindow() {
SetupFontAndStyle(); SetupFontAndStyle();
SDL_GL_GetDrawableSize(main_window_, &main_window_width_real_, ImGui_ImplSDL3_InitForSDLRenderer(main_window_, main_renderer_);
&main_window_height_real_); ImGui_ImplSDLRenderer3_Init(main_renderer_);
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_);
return 0; return 0;
} }
int Render::DestroyMainWindowContext() { int Render::DestroyMainWindowContext() {
ImGui::SetCurrentContext(main_ctx_); ImGui::SetCurrentContext(main_ctx_);
ImGui_ImplSDLRenderer2_Shutdown(); ImGui_ImplSDLRenderer3_Shutdown();
ImGui_ImplSDL2_Shutdown(); ImGui_ImplSDL3_Shutdown();
ImGui::DestroyContext(main_ctx_); ImGui::DestroyContext(main_ctx_);
return 0; return 0;
@@ -782,21 +757,8 @@ int Render::SetupStreamWindow() {
SetupFontAndStyle(); SetupFontAndStyle();
SDL_GL_GetDrawableSize(stream_window_, &stream_window_width_real_, ImGui_ImplSDL3_InitForSDLRenderer(stream_window_, stream_renderer_);
&stream_window_height_real_); ImGui_ImplSDLRenderer3_Init(stream_renderer_);
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_);
stream_window_inited_ = true; stream_window_inited_ = true;
LOG_INFO("Stream window inited"); LOG_INFO("Stream window inited");
@@ -807,8 +769,8 @@ int Render::SetupStreamWindow() {
int Render::DestroyStreamWindowContext() { int Render::DestroyStreamWindowContext() {
stream_window_inited_ = false; stream_window_inited_ = false;
ImGui::SetCurrentContext(stream_ctx_); ImGui::SetCurrentContext(stream_ctx_);
ImGui_ImplSDLRenderer2_Shutdown(); ImGui_ImplSDLRenderer3_Shutdown();
ImGui_ImplSDL2_Shutdown(); ImGui_ImplSDL3_Shutdown();
ImGui::DestroyContext(stream_ctx_); ImGui::DestroyContext(stream_ctx_);
return 0; return 0;
@@ -821,8 +783,8 @@ int Render::DrawMainWindow() {
} }
ImGui::SetCurrentContext(main_ctx_); ImGui::SetCurrentContext(main_ctx_);
ImGui_ImplSDLRenderer2_NewFrame(); ImGui_ImplSDLRenderer3_NewFrame();
ImGui_ImplSDL2_NewFrame(); ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
@@ -845,7 +807,7 @@ int Render::DrawMainWindow() {
// Rendering // Rendering
ImGui::Render(); ImGui::Render();
SDL_RenderClear(main_renderer_); SDL_RenderClear(main_renderer_);
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), main_renderer_); ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), main_renderer_);
SDL_RenderPresent(main_renderer_); SDL_RenderPresent(main_renderer_);
return 0; return 0;
@@ -858,8 +820,8 @@ int Render::DrawStreamWindow() {
} }
ImGui::SetCurrentContext(stream_ctx_); ImGui::SetCurrentContext(stream_ctx_);
ImGui_ImplSDLRenderer2_NewFrame(); ImGui_ImplSDLRenderer3_NewFrame();
ImGui_ImplSDL2_NewFrame(); ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
StreamWindow(); StreamWindow();
@@ -889,11 +851,16 @@ int Render::DrawStreamWindow() {
for (auto& it : client_properties_) { for (auto& it : client_properties_) {
auto props = it.second; auto props = it.second;
if (props->tab_selected_) { if (props->tab_selected_) {
SDL_RenderCopy(stream_renderer_, props->stream_texture_, NULL, SDL_FRect render_rect_f = {
&(props->stream_render_rect_)); static_cast<float>(props->stream_render_rect_.x),
static_cast<float>(props->stream_render_rect_.y),
static_cast<float>(props->stream_render_rect_.w),
static_cast<float>(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_); SDL_RenderPresent(stream_renderer_);
return 0; return 0;
@@ -946,20 +913,23 @@ void Render::InitializeSettings() {
} }
void Render::InitializeSDL() { void Render::InitializeSDL() {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
SDL_INIT_GAMECONTROLLER) != 0) { LOG_ERROR("Error: {}", SDL_GetError());
printf("Error: %s\n", SDL_GetError()); return;
exit(-1);
} }
SDL_DisplayMode DM; const SDL_DisplayMode* dm = SDL_GetCurrentDisplayMode(0);
SDL_GetCurrentDisplayMode(0, &DM); if (dm) {
screen_width_ = DM.w; screen_width_ = dm->w;
screen_height_ = DM.h; 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_); LOG_INFO("Screen resolution: [{}x{}]", screen_width_, screen_height_);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
} }
void Render::InitializeModules() { void Render::InitializeModules() {
@@ -1082,10 +1052,10 @@ void Render::HandleStreamWindow() {
if (stream_window_inited_) { if (stream_window_inited_) {
if (!stream_window_grabbed_ && control_mouse_) { if (!stream_window_grabbed_ && control_mouse_) {
SDL_SetWindowGrab(stream_window_, SDL_TRUE); SDL_SetWindowMouseGrab(stream_window_, true);
stream_window_grabbed_ = true; stream_window_grabbed_ = true;
} else if (stream_window_grabbed_ && !control_mouse_) { } else if (stream_window_grabbed_ && !control_mouse_) {
SDL_SetWindowGrab(stream_window_, SDL_FALSE); SDL_SetWindowMouseGrab(stream_window_, false);
stream_window_grabbed_ = false; stream_window_grabbed_ = false;
} }
} }
@@ -1135,13 +1105,13 @@ void Render::CleanupFactories() {
} }
if (device_controller_factory_) { if (device_controller_factory_) {
delete device_controller_factory_; SDL_FlushEvent(STREAM_REFRESH_EVENT);
device_controller_factory_ = nullptr; device_controller_factory_ = nullptr;
} }
} }
void Render::CleanupPeer(std::shared_ptr<SubStreamWindowProperties> props) { void Render::CleanupPeer(std::shared_ptr<SubStreamWindowProperties> props) {
SDL_FlushEvent(STREAM_FRASH); SDL_FlushEvent(STREAM_REFRESH_EVENT);
if (props->dst_buffer_) { if (props->dst_buffer_) {
thumbnail_->SaveToThumbnail( thumbnail_->SaveToThumbnail(
@@ -1200,7 +1170,7 @@ void Render::UpdateRenderRect() {
} }
int stream_window_width, stream_window_height; int stream_window_width, stream_window_height;
SDL_GetWindowSize(stream_window_, &stream_window_width, SDL_GetWindowSizeInPixels(stream_window_, &stream_window_width,
&stream_window_height); &stream_window_height);
stream_window_width_ = (float)stream_window_width; stream_window_width_ = (float)stream_window_width;
stream_window_height_ = (float)stream_window_height; stream_window_height_ = (float)stream_window_height;
@@ -1241,7 +1211,7 @@ void Render::ProcessSdlEvent() {
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
if (main_ctx_) { if (main_ctx_) {
ImGui::SetCurrentContext(main_ctx_); ImGui::SetCurrentContext(main_ctx_);
ImGui_ImplSDL2_ProcessEvent(&event); ImGui_ImplSDL3_ProcessEvent(&event);
} else { } else {
LOG_ERROR("Main context is null"); LOG_ERROR("Main context is null");
return; return;
@@ -1250,7 +1220,7 @@ void Render::ProcessSdlEvent() {
if (stream_window_inited_) { if (stream_window_inited_) {
if (stream_ctx_) { if (stream_ctx_) {
ImGui::SetCurrentContext(stream_ctx_); ImGui::SetCurrentContext(stream_ctx_);
ImGui_ImplSDL2_ProcessEvent(&event); ImGui_ImplSDL3_ProcessEvent(&event);
} else { } else {
LOG_ERROR("Stream context is null"); LOG_ERROR("Stream context is null");
return; return;
@@ -1258,10 +1228,10 @@ void Render::ProcessSdlEvent() {
} }
switch (event.type) { switch (event.type) {
case SDL_QUIT: case SDL_EVENT_QUIT:
if (stream_window_inited_) { if (stream_window_inited_) {
LOG_INFO("Destroy stream window"); LOG_INFO("Destroy stream window");
SDL_SetWindowGrab(stream_window_, SDL_FALSE); SDL_SetWindowMouseGrab(stream_window_, false);
DestroyStreamWindow(); DestroyStreamWindow();
DestroyStreamWindowContext(); DestroyStreamWindowContext();
@@ -1283,13 +1253,13 @@ void Render::ProcessSdlEvent() {
props->streaming_ = false; props->streaming_ = false;
props->remember_password_ = false; props->remember_password_ = false;
props->connection_established_ = false; SDL_FlushEvents(STREAM_REFRESH_EVENT, STREAM_REFRESH_EVENT);
props->audio_capture_button_pressed_ = false; props->audio_capture_button_pressed_ = false;
memset(&props->net_traffic_stats_, 0, memset(&props->net_traffic_stats_, 0,
sizeof(props->net_traffic_stats_)); sizeof(props->net_traffic_stats_));
SDL_SetWindowFullscreen(main_window_, SDL_FALSE); SDL_SetWindowFullscreen(main_window_, false);
SDL_FlushEvents(STREAM_FRASH, STREAM_FRASH); SDL_FlushEvents(STREAM_REFRESH_EVENT, STREAM_REFRESH_EVENT);
memset(audio_buffer_, 0, 720); memset(audio_buffer_, 0, 720);
} }
client_properties_.clear(); client_properties_.clear();
@@ -1306,29 +1276,50 @@ void Render::ProcessSdlEvent() {
} }
break; break;
case SDL_WINDOWEVENT: case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
if (event.window.event == SDL_WINDOWEVENT_CLOSE && if (event.window.windowID != SDL_GetWindowID(stream_window_)) {
event.window.windowID != SDL_GetWindowID(stream_window_)) {
exit_ = true; exit_ = true;
} else if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED &&
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; break;
case STREAM_FRASH: { case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
if (stream_window_created_ &&
event.window.windowID == SDL_GetWindowID(stream_window_)) {
UpdateRenderRect();
}
break;
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;
}
break;
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;
}
if (event.type == STREAM_REFRESH_EVENT) {
auto* props = static_cast<SubStreamWindowProperties*>(event.user.data1); auto* props = static_cast<SubStreamWindowProperties*>(event.user.data1);
if (!props) { if (!props) {
continue; continue;
@@ -1343,17 +1334,13 @@ void Render::ProcessSdlEvent() {
if (props->stream_texture_) { if (props->stream_texture_) {
if (props->video_width_ != props->texture_width_ || if (props->video_width_ != props->texture_width_ ||
props->video_height_ != props->texture_height_) { 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_width_ = props->video_width_;
props->texture_height_ = props->video_height_; props->texture_height_ = props->video_height_;
SDL_DestroyTexture(props->stream_texture_); SDL_DestroyTexture(props->stream_texture_);
props->stream_texture_ = SDL_CreateTexture( props->stream_texture_ = SDL_CreateTexture(
stream_renderer_, stream_pixformat_, stream_renderer_, stream_pixformat_, SDL_TEXTUREACCESS_STREAMING,
SDL_TEXTUREACCESS_STREAMING, props->texture_width_, props->texture_width_, props->texture_height_);
props->texture_height_);
} }
} else { } else {
props->texture_width_ = props->video_width_; props->texture_width_ = props->video_width_;
@@ -1367,18 +1354,5 @@ void Render::ProcessSdlEvent() {
props->texture_width_); props->texture_width_);
break; break;
} }
case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEWHEEL:
if (foucs_on_stream_window_) {
ProcessMouseEvent(event);
}
break;
default:
break;
}
} }
} }

View File

@@ -7,7 +7,7 @@
#ifndef _MAIN_WINDOW_H_ #ifndef _MAIN_WINDOW_H_
#define _MAIN_WINDOW_H_ #define _MAIN_WINDOW_H_
#include <SDL.h> #include <SDL3/SDL.h>
#include <atomic> #include <atomic>
#include <chrono> #include <chrono>
@@ -21,8 +21,8 @@
#include "config_center.h" #include "config_center.h"
#include "device_controller_factory.h" #include "device_controller_factory.h"
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_sdl2.h" #include "imgui_impl_sdl3.h"
#include "imgui_impl_sdlrenderer2.h" #include "imgui_impl_sdlrenderer3.h"
#include "imgui_internal.h" #include "imgui_internal.h"
#include "minirtc.h" #include "minirtc.h"
#include "path_manager.h" #include "path_manager.h"
@@ -76,10 +76,10 @@ class Render {
double net_traffic_stats_button_pressed_time_ = 0; double net_traffic_stats_button_pressed_time_ = 0;
unsigned char *dst_buffer_ = nullptr; unsigned char *dst_buffer_ = nullptr;
size_t dst_buffer_capacity_ = 0; size_t dst_buffer_capacity_ = 0;
int mouse_pos_x_ = 0; float mouse_pos_x_ = 0;
int mouse_pos_y_ = 0; float mouse_pos_y_ = 0;
int mouse_pos_x_last_ = 0; float mouse_pos_x_last_ = 0;
int mouse_pos_y_last_ = 0; float mouse_pos_y_last_ = 0;
int texture_width_ = 1280; int texture_width_ = 1280;
int texture_height_ = 720; int texture_height_ = 720;
int video_width_ = 0; int video_width_ = 0;
@@ -300,10 +300,6 @@ class Render {
bool foucs_on_main_window_ = false; bool foucs_on_main_window_ = false;
bool foucs_on_stream_window_ = false; bool foucs_on_stream_window_ = false;
bool audio_capture_ = 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_width_default_ = 640;
float main_window_height_default_ = 480; float main_window_height_default_ = 480;
float main_window_width_ = 640; float main_window_width_ = 640;
@@ -346,6 +342,9 @@ class Render {
std::string focused_remote_id_ = ""; std::string focused_remote_id_ = "";
bool need_to_send_host_info_ = false; bool need_to_send_host_info_ = false;
SDL_Event last_mouse_event; SDL_Event last_mouse_event;
SDL_AudioStream *input_stream_;
SDL_AudioStream *output_stream_;
uint32_t STREAM_REFRESH_EVENT = 0;
// stream window render // stream window render
SDL_Window *stream_window_ = nullptr; SDL_Window *stream_window_ = nullptr;
@@ -363,11 +362,7 @@ class Render {
int stream_window_height_default_ = 720; int stream_window_height_default_ = 720;
float stream_window_width_ = 1280; float stream_window_width_ = 1280;
float stream_window_height_ = 720; float stream_window_height_ = 720;
uint32_t stream_pixformat_ = 0; SDL_PixelFormat stream_pixformat_ = SDL_PIXELFORMAT_NV12;
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;
bool label_inited_ = false; bool label_inited_ = false;
bool connect_button_pressed_ = false; bool connect_button_pressed_ = false;

View File

@@ -6,8 +6,6 @@
#define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2 #define NV12_BUFFER_SIZE 1280 * 720 * 3 / 2
#define STREAM_FRASH (SDL_USEREVENT + 1)
#ifdef DESK_PORT_DEBUG #ifdef DESK_PORT_DEBUG
#else #else
#define MOUSE_CONTROL 1 #define MOUSE_CONTROL 1
@@ -68,7 +66,7 @@ int Render::ProcessMouseEvent(SDL_Event &event) {
(float)(event.button.y - props->stream_render_rect_.y) / (float)(event.button.y - props->stream_render_rect_.y) /
render_height; render_height;
if (SDL_MOUSEBUTTONDOWN == event.type) { if (SDL_EVENT_MOUSE_BUTTON_DOWN == event.type) {
remote_action.type = ControlType::mouse; remote_action.type = ControlType::mouse;
if (SDL_BUTTON_LEFT == event.button.button) { if (SDL_BUTTON_LEFT == event.button.button) {
remote_action.m.flag = MouseFlag::left_down; 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) { } else if (SDL_BUTTON_MIDDLE == event.button.button) {
remote_action.m.flag = MouseFlag::middle_down; 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; remote_action.type = ControlType::mouse;
if (SDL_BUTTON_LEFT == event.button.button) { if (SDL_BUTTON_LEFT == event.button.button) {
remote_action.m.flag = MouseFlag::left_up; 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) { } else if (SDL_BUTTON_MIDDLE == event.button.button) {
remote_action.m.flag = MouseFlag::middle_up; 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.type = ControlType::mouse;
remote_action.m.flag = MouseFlag::move; remote_action.m.flag = MouseFlag::move;
} }
@@ -96,7 +94,7 @@ int Render::ProcessMouseEvent(SDL_Event &event) {
} }
SendDataFrame(props->peer_, (const char *)&remote_action, SendDataFrame(props->peer_, (const char *)&remote_action,
sizeof(remote_action), props->data_label_.c_str()); 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 &&
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 && props->stream_render_rect_.w &&
@@ -231,8 +229,7 @@ void Render::OnReceiveVideoBufferCb(const XVideoFrame *video_frame,
} }
SDL_Event event; SDL_Event event;
event.type = STREAM_FRASH; event.type = render->STREAM_REFRESH_EVENT;
event.user.type = STREAM_FRASH;
event.user.data1 = props; event.user.data1 = props;
SDL_PushEvent(&event); SDL_PushEvent(&event);
props->streaming_ = true; props->streaming_ = true;
@@ -248,7 +245,14 @@ void Render::OnReceiveAudioBufferCb(const char *data, size_t size,
} }
render->audio_buffer_fresh_ = true; 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<int>(size));
if (pushed < 0) {
LOG_ERROR("Failed to push audio data: {}", SDL_GetError());
}
}
} }
void Render::OnReceiveDataBufferCb(const char *data, size_t size, void Render::OnReceiveDataBufferCb(const char *data, size_t size,

View File

@@ -34,7 +34,7 @@ void Render::CloseTab(decltype(client_properties_)::iterator& it) {
it = client_properties_.erase(it); it = client_properties_.erase(it);
if (client_properties_.empty()) { if (client_properties_.empty()) {
SDL_Event event; SDL_Event event;
event.type = SDL_QUIT; event.type = SDL_EVENT_QUIT;
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
} }
@@ -120,7 +120,7 @@ int Render::StreamWindow() {
it = client_properties_.erase(it); it = client_properties_.erase(it);
if (client_properties_.empty()) { if (client_properties_.empty()) {
SDL_Event event; SDL_Event event;
event.type = SDL_QUIT; event.type = SDL_EVENT_QUIT;
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
} else { } else {
@@ -175,11 +175,11 @@ int Render::StreamWindow() {
if (!props->peer_) { if (!props->peer_) {
fullscreen_button_pressed_ = false; fullscreen_button_pressed_ = false;
SDL_SetWindowFullscreen(stream_window_, SDL_FALSE); SDL_SetWindowFullscreen(stream_window_, false);
it = client_properties_.erase(it); it = client_properties_.erase(it);
if (client_properties_.empty()) { if (client_properties_.empty()) {
SDL_Event event; SDL_Event event;
event.type = SDL_QUIT; event.type = SDL_EVENT_QUIT;
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
} else { } else {

View File

@@ -38,9 +38,10 @@ bool LoadTextureFromMemory(const void* data, size_t data_size,
} }
// ABGR // ABGR
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom( int pitch = image_width * channels;
(void*)image_data, image_width, image_height, channels * 8, SDL_Surface* surface =
channels * image_width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); SDL_CreateSurfaceFrom(image_width, image_height, SDL_PIXELFORMAT_RGBA32,
(void*)image_data, pitch);
if (surface == nullptr) { if (surface == nullptr) {
LOG_ERROR("Failed to create SDL surface: [{}]", SDL_GetError()); LOG_ERROR("Failed to create SDL surface: [{}]", SDL_GetError());
return false; return false;
@@ -55,7 +56,7 @@ bool LoadTextureFromMemory(const void* data, size_t data_size,
*out_width = image_width; *out_width = image_width;
*out_height = image_height; *out_height = image_height;
SDL_FreeSurface(surface); SDL_DestroySurface(surface);
stbi_image_free(image_data); stbi_image_free(image_data);
return true; return true;

View File

@@ -7,7 +7,7 @@
#ifndef _THUMBNAIL_H_ #ifndef _THUMBNAIL_H_
#define _THUMBNAIL_H_ #define _THUMBNAIL_H_
#include <SDL.h> #include <SDL3/SDL.h>
#include <filesystem> #include <filesystem>
#include <map> #include <map>

View File

@@ -139,7 +139,7 @@ int Render::TitleBar(bool main_window) {
std::string close_button = "##xmark"; // ICON_FA_XMARK; std::string close_button = "##xmark"; // ICON_FA_XMARK;
if (ImGui::Button(close_button.c_str(), ImVec2(BUTTON_PADDING, 30))) { if (ImGui::Button(close_button.c_str(), ImVec2(BUTTON_PADDING, 30))) {
SDL_Event event; SDL_Event event;
event.type = SDL_QUIT; event.type = SDL_EVENT_QUIT;
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
draw_list->AddLine(ImVec2(xmark_pos_x - xmark_size / 2 - 0.25f, draw_list->AddLine(ImVec2(xmark_pos_x - xmark_size / 2 - 0.25f,

View File

@@ -17,26 +17,23 @@ if is_mode("debug") then
end end
add_requires("spdlog 1.14.1", {system = false}) 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("openssl3 3.3.2", {system = false})
add_requires("libsdl2", {configs = {pulseaudio = true}})
add_packages("libsdl2")
if is_os("windows") then if is_os("windows") then
add_requires("libyuv", "miniaudio 0.11.21") add_requires("libyuv", "miniaudio 0.11.21")
add_links("Shell32", "windowsapp", "dwmapi", "User32", "kernel32", add_links("Shell32", "windowsapp", "dwmapi", "User32", "kernel32",
"SDL2-static", "SDL2main", "gdi32", "winmm", "setupapi", "version", "SDL3-static", "gdi32", "winmm", "setupapi", "version",
"Imm32", "iphlpapi") "Imm32", "iphlpapi")
add_cxflags("/WX") add_cxflags("/WX")
elseif is_os("linux") then elseif is_os("linux") then
add_links("pulse-simple", "pulse") add_links("pulse-simple", "pulse")
add_requires("libyuv") add_requires("libyuv")
add_syslinks("pthread", "dl") add_syslinks("pthread", "dl")
add_links("SDL2", "asound", "X11", "Xtst", "Xrandr") add_links("SDL3", "asound", "X11", "Xtst", "Xrandr")
add_cxflags("-Wno-unused-variable") add_cxflags("-Wno-unused-variable")
elseif is_os("macosx") then elseif is_os("macosx") then
add_links("SDL2", "SDL2main") add_links("SDL3")
add_ldflags("-Wl,-ld_classic") add_ldflags("-Wl,-ld_classic")
add_cxflags("-Wno-unused-variable") add_cxflags("-Wno-unused-variable")
add_frameworks("OpenGL", "IOSurface", "ScreenCaptureKit", "AVFoundation", add_frameworks("OpenGL", "IOSurface", "ScreenCaptureKit", "AVFoundation",