mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 12:15:34 +08:00
[feat] display switch supported on Windows platform
This commit is contained in:
@@ -43,6 +43,8 @@ typedef struct {
|
||||
typedef struct {
|
||||
char host_name[64];
|
||||
size_t host_name_size;
|
||||
char **display_list;
|
||||
size_t display_num;
|
||||
} HostInfo;
|
||||
|
||||
typedef struct {
|
||||
@@ -57,7 +59,7 @@ typedef struct {
|
||||
} RemoteAction;
|
||||
|
||||
// int key_code, bool is_down
|
||||
typedef void (*OnKeyAction)(int, bool, void*);
|
||||
typedef void (*OnKeyAction)(int, bool, void *);
|
||||
|
||||
class DeviceController {
|
||||
public:
|
||||
|
||||
@@ -36,7 +36,7 @@ class ScreenCapturer {
|
||||
virtual int Pause(int monitor_index) = 0;
|
||||
virtual int Resume(int monitor_index) = 0;
|
||||
|
||||
virtual std::vector<DisplayInfo> GetDisplayList() = 0;
|
||||
virtual std::vector<DisplayInfo> GetDisplayInfoList() = 0;
|
||||
virtual int SwitchTo(int monitor_index) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -107,15 +107,15 @@ int ScreenCapturerWgc::Init(const int fps, cb_desktop_data cb) {
|
||||
|
||||
monitor_ = GetPrimaryMonitor();
|
||||
|
||||
display_list_ = gs_display_list;
|
||||
display_info_list_ = gs_display_list;
|
||||
|
||||
if (display_list_.empty()) {
|
||||
if (display_info_list_.empty()) {
|
||||
LOG_ERROR("No display found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < display_list_.size(); i++) {
|
||||
const auto &display = display_list_[i];
|
||||
for (int i = 0; i < display_info_list_.size(); i++) {
|
||||
const auto &display = display_info_list_[i];
|
||||
LOG_INFO(
|
||||
"index: {}, display name: {}, is primary: {}, bounds: ({}, {}) - "
|
||||
"({}, {})",
|
||||
@@ -134,7 +134,7 @@ int ScreenCapturerWgc::Init(const int fps, cb_desktop_data cb) {
|
||||
}
|
||||
|
||||
LOG_INFO("Default on monitor {}:{}", monitor_index_,
|
||||
display_list_[monitor_index_].name);
|
||||
display_info_list_[monitor_index_].name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -217,11 +217,11 @@ int ScreenCapturerWgc::Stop() {
|
||||
int ScreenCapturerWgc::SwitchTo(int monitor_index) {
|
||||
if (monitor_index_ == monitor_index) {
|
||||
LOG_INFO("Already on monitor {}:{}", monitor_index_,
|
||||
display_list_[monitor_index_].name);
|
||||
display_info_list_[monitor_index_].name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (monitor_index >= display_list_.size()) {
|
||||
if (monitor_index >= display_info_list_.size()) {
|
||||
LOG_ERROR("Invalid monitor index: {}", monitor_index);
|
||||
return -1;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ int ScreenCapturerWgc::SwitchTo(int monitor_index) {
|
||||
|
||||
monitor_index_ = monitor_index;
|
||||
LOG_INFO("Switching to monitor {}:{}", monitor_index_,
|
||||
display_list_[monitor_index_].name);
|
||||
display_info_list_[monitor_index_].name);
|
||||
|
||||
Resume(monitor_index);
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class ScreenCapturerWgc : public ScreenCapturer,
|
||||
virtual int Pause(int monitor_index) override;
|
||||
virtual int Resume(int monitor_index) override;
|
||||
|
||||
std::vector<DisplayInfo> GetDisplayList() { return display_list_; }
|
||||
std::vector<DisplayInfo> GetDisplayInfoList() { return display_info_list_; }
|
||||
|
||||
int SwitchTo(int monitor_index);
|
||||
|
||||
@@ -40,7 +40,7 @@ class ScreenCapturerWgc : public ScreenCapturer,
|
||||
private:
|
||||
HMONITOR monitor_;
|
||||
MONITORINFOEX monitor_info_;
|
||||
std::vector<DisplayInfo> display_list_;
|
||||
std::vector<DisplayInfo> display_info_list_;
|
||||
int monitor_index_ = 0;
|
||||
|
||||
private:
|
||||
|
||||
@@ -57,13 +57,9 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
||||
ImVec2 btn_size_actual = ImGui::GetItemRectSize();
|
||||
|
||||
if (ImGui::BeginPopup("display")) {
|
||||
std::vector<ScreenCapturer::DisplayInfo> display_list;
|
||||
if (screen_capturer_) {
|
||||
display_list = screen_capturer_->GetDisplayList();
|
||||
}
|
||||
ImGui::SetWindowFontScale(0.5f);
|
||||
for (int i = 0; i < display_list.size(); i++) {
|
||||
if (ImGui::Selectable(display_list[i].name.c_str())) {
|
||||
for (int i = 0; i < props->display_names_.size(); i++) {
|
||||
if (ImGui::Selectable(props->display_names_[i].c_str())) {
|
||||
selected_display_ = i + 1;
|
||||
|
||||
RemoteAction remote_action;
|
||||
|
||||
@@ -842,8 +842,26 @@ void Render::MainLoop() {
|
||||
}
|
||||
|
||||
if (!host_info_sent_ && screen_width_ > 0 && screen_height_ > 0) {
|
||||
std::string host_name = GetHostName();
|
||||
RemoteAction remote_action;
|
||||
if (screen_capturer_) {
|
||||
display_info_list_ = screen_capturer_->GetDisplayInfoList();
|
||||
}
|
||||
|
||||
remote_action.i.display_num = display_info_list_.size();
|
||||
remote_action.i.display_list =
|
||||
(char**)malloc(remote_action.i.display_num * sizeof(char*));
|
||||
for (int i = 0; i < remote_action.i.display_num; i++) {
|
||||
LOG_INFO("Local display [{}:{}]", i + 1, display_info_list_[i].name);
|
||||
remote_action.i.display_list[i] =
|
||||
(char*)malloc(display_info_list_[i].name.length() + 1);
|
||||
strncpy(remote_action.i.display_list[i],
|
||||
display_info_list_[i].name.c_str(),
|
||||
display_info_list_[i].name.length());
|
||||
remote_action.i.display_list[i][display_info_list_[i].name.length()] =
|
||||
'\0';
|
||||
}
|
||||
|
||||
std::string host_name = GetHostName();
|
||||
remote_action.type = ControlType::host_infomation;
|
||||
memcpy(&remote_action.i.host_name, host_name.data(), host_name.size());
|
||||
remote_action.i.host_name_size = host_name.size();
|
||||
@@ -1136,9 +1154,9 @@ void Render::ProcessSdlEvent() {
|
||||
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_);
|
||||
// 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_;
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ class Render {
|
||||
std::string mouse_control_button_label_ = "Mouse Control";
|
||||
std::string audio_capture_button_label_ = "Audio Capture";
|
||||
std::string remote_host_name_ = "";
|
||||
std::vector<std::string> display_names_;
|
||||
SDL_Texture *stream_texture_ = nullptr;
|
||||
SDL_Rect stream_render_rect_;
|
||||
SDL_Rect stream_render_rect_last_;
|
||||
@@ -389,6 +390,7 @@ class Render {
|
||||
DeviceControllerFactory *device_controller_factory_ = nullptr;
|
||||
MouseController *mouse_controller_ = nullptr;
|
||||
KeyboardCapturer *keyboard_capturer_ = nullptr;
|
||||
std::vector<ScreenCapturer::DisplayInfo> display_info_list_;
|
||||
uint64_t last_frame_time_;
|
||||
char client_id_[10] = "";
|
||||
char client_id_display_[12] = "";
|
||||
|
||||
@@ -251,6 +251,24 @@ void Render::OnReceiveAudioBufferCb(const char *data, size_t size,
|
||||
SDL_QueueAudio(render->output_dev_, data, (uint32_t)size);
|
||||
}
|
||||
|
||||
std::vector<std::string> restore_display_list(char **display_list,
|
||||
size_t display_num) {
|
||||
std::vector<std::string> result;
|
||||
result.reserve(display_num); // 预分配空间,提升效率
|
||||
|
||||
for (size_t i = 0; i < display_num; i++) {
|
||||
if (display_list[i] != nullptr) {
|
||||
// 直接用std::string构造函数复制C字符串
|
||||
result.emplace_back(display_list[i]);
|
||||
} else {
|
||||
// 如果遇到nullptr指针,放空字符串或者处理错误
|
||||
result.emplace_back("");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Render::OnReceiveDataBufferCb(const char *data, size_t size,
|
||||
const char *user_id, size_t user_id_size,
|
||||
void *user_data) {
|
||||
@@ -271,6 +289,13 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size,
|
||||
props->remote_host_name_ = std::string(remote_action.i.host_name,
|
||||
remote_action.i.host_name_size);
|
||||
LOG_INFO("Remote hostname: [{}]", props->remote_host_name_);
|
||||
|
||||
props->display_names_ = restore_display_list(remote_action.i.display_list,
|
||||
remote_action.i.display_num);
|
||||
|
||||
for (int i = 0; i < props->display_names_.size(); i++) {
|
||||
LOG_INFO("Remote display [{}:{}]", i + 1, props->display_names_[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// remote
|
||||
|
||||
Reference in New Issue
Block a user