mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
[feat] display selection supported on Windows platform
This commit is contained in:
@@ -13,7 +13,8 @@ typedef enum {
|
|||||||
mouse = 0,
|
mouse = 0,
|
||||||
keyboard,
|
keyboard,
|
||||||
audio_capture,
|
audio_capture,
|
||||||
host_infomation
|
host_infomation,
|
||||||
|
display_id,
|
||||||
} ControlType;
|
} ControlType;
|
||||||
typedef enum {
|
typedef enum {
|
||||||
move = 0,
|
move = 0,
|
||||||
@@ -51,6 +52,7 @@ typedef struct {
|
|||||||
Key k;
|
Key k;
|
||||||
HostInfo i;
|
HostInfo i;
|
||||||
bool a;
|
bool a;
|
||||||
|
int d;
|
||||||
};
|
};
|
||||||
} RemoteAction;
|
} RemoteAction;
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,11 @@ class ScreenCapturer {
|
|||||||
virtual int Destroy() = 0;
|
virtual int Destroy() = 0;
|
||||||
virtual int Start() = 0;
|
virtual int Start() = 0;
|
||||||
virtual int Stop() = 0;
|
virtual int Stop() = 0;
|
||||||
|
virtual int Pause(int monitor_index) = 0;
|
||||||
|
virtual int Resume(int monitor_index) = 0;
|
||||||
|
|
||||||
virtual std::vector<DisplayInfo> GetDisplayList() = 0;
|
virtual std::vector<DisplayInfo> GetDisplayList() = 0;
|
||||||
|
virtual int SwitchTo(int monitor_index) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -28,19 +28,25 @@ BOOL WINAPI EnumMonitorProc(HMONITOR hmonitor, [[maybe_unused]] HDC hdc,
|
|||||||
monitor_info_.cbSize = sizeof(MONITORINFOEX);
|
monitor_info_.cbSize = sizeof(MONITORINFOEX);
|
||||||
|
|
||||||
if (GetMonitorInfo(hmonitor, &monitor_info_)) {
|
if (GetMonitorInfo(hmonitor, &monitor_info_)) {
|
||||||
gs_display_list.push_back(
|
if (monitor_info_.dwFlags & MONITORINFOF_PRIMARY) {
|
||||||
{(void *)hmonitor, WideToUtf8(monitor_info_.szDevice),
|
gs_display_list.insert(
|
||||||
(monitor_info_.dwFlags & MONITORINFOF_PRIMARY) ? true : false,
|
gs_display_list.begin(),
|
||||||
monitor_info_.rcMonitor.left, monitor_info_.rcMonitor.top,
|
{(void *)hmonitor, WideToUtf8(monitor_info_.szDevice),
|
||||||
monitor_info_.rcMonitor.right, monitor_info_.rcMonitor.bottom});
|
(monitor_info_.dwFlags & MONITORINFOF_PRIMARY) ? true : false,
|
||||||
|
monitor_info_.rcMonitor.left, monitor_info_.rcMonitor.top,
|
||||||
|
monitor_info_.rcMonitor.right, monitor_info_.rcMonitor.bottom});
|
||||||
|
*(HMONITOR *)data = hmonitor;
|
||||||
|
} else {
|
||||||
|
gs_display_list.push_back(
|
||||||
|
{(void *)hmonitor, WideToUtf8(monitor_info_.szDevice),
|
||||||
|
(monitor_info_.dwFlags & MONITORINFOF_PRIMARY) ? true : false,
|
||||||
|
monitor_info_.rcMonitor.left, monitor_info_.rcMonitor.top,
|
||||||
|
monitor_info_.rcMonitor.right, monitor_info_.rcMonitor.bottom});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monitor_info_.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER) return true;
|
if (monitor_info_.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER) return true;
|
||||||
|
|
||||||
if (monitor_info_.dwFlags & MONITORINFOF_PRIMARY) {
|
|
||||||
*(HMONITOR *)data = hmonitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,164 +90,160 @@ bool ScreenCapturerWgc::IsWgcSupported() {
|
|||||||
|
|
||||||
int ScreenCapturerWgc::Init(const int fps, cb_desktop_data cb) {
|
int ScreenCapturerWgc::Init(const int fps, cb_desktop_data cb) {
|
||||||
int error = 0;
|
int error = 0;
|
||||||
if (_inited == true) return error;
|
if (inited_ == true) return error;
|
||||||
|
|
||||||
// nv12_frame_ = new unsigned char[rect.right * rect.bottom * 3 / 2];
|
// nv12_frame_ = new unsigned char[rect.right * rect.bottom * 3 / 2];
|
||||||
// nv12_frame_scaled_ = new unsigned char[1280 * 720 * 3 / 2];
|
// nv12_frame_scaled_ = new unsigned char[1280 * 720 * 3 / 2];
|
||||||
|
|
||||||
_fps = fps;
|
fps_ = fps;
|
||||||
|
|
||||||
_on_data = cb;
|
on_data_ = cb;
|
||||||
|
|
||||||
do {
|
if (!IsWgcSupported()) {
|
||||||
if (!IsWgcSupported()) {
|
LOG_ERROR("WGC not supported");
|
||||||
std::cout << "AE_UNSUPPORT" << std::endl;
|
error = 2;
|
||||||
error = 2;
|
return error;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
session_ = new WgcSessionImpl();
|
|
||||||
if (!session_) {
|
|
||||||
error = -1;
|
|
||||||
std::cout << "AE_WGC_CREATE_CAPTURER_FAILED" << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
session_->RegisterObserver(this);
|
|
||||||
|
|
||||||
monitor_ = GetPrimaryMonitor();
|
|
||||||
|
|
||||||
display_list_ = gs_display_list;
|
|
||||||
|
|
||||||
for (const auto &display : display_list_) {
|
|
||||||
LOG_INFO("Display Name: {}, Is Primary: {}, Bounds: ({}, {}) - ({}, {})",
|
|
||||||
display.name, (display.is_primary ? "Yes" : "No"), display.left,
|
|
||||||
display.top, display.right, display.bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
error = session_->Initialize(monitor_);
|
|
||||||
|
|
||||||
_inited = true;
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
if (error != 0) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
monitor_ = GetPrimaryMonitor();
|
||||||
|
|
||||||
|
display_list_ = gs_display_list;
|
||||||
|
|
||||||
|
if (display_list_.empty()) {
|
||||||
|
LOG_ERROR("No display found");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < display_list_.size(); i++) {
|
||||||
|
const auto &display = display_list_[i];
|
||||||
|
LOG_INFO(
|
||||||
|
"index: {}, display name: {}, is primary: {}, bounds: ({}, {}) - "
|
||||||
|
"({}, {})",
|
||||||
|
i, display.name, (display.is_primary ? "yes" : "no"), display.left,
|
||||||
|
display.top, display.right, display.bottom);
|
||||||
|
|
||||||
|
sessions_.push_back(
|
||||||
|
{std::make_unique<WgcSessionImpl>(), false, false, false});
|
||||||
|
sessions_.back().session_->RegisterObserver(this);
|
||||||
|
error = sessions_.back().session_->Initialize((HMONITOR)display.handle);
|
||||||
|
if (error != 0) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
sessions_[i].inited_ = true;
|
||||||
|
inited_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO("Default on monitor {}:{}", monitor_index_,
|
||||||
|
display_list_[monitor_index_].name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScreenCapturerWgc::Destroy() { return 0; }
|
int ScreenCapturerWgc::Destroy() { return 0; }
|
||||||
|
|
||||||
int ScreenCapturerWgc::Start() {
|
int ScreenCapturerWgc::Start() {
|
||||||
if (_running == true) {
|
if (running_ == true) {
|
||||||
std::cout << "record desktop duplication is already running" << std::endl;
|
LOG_ERROR("Screen capturer already running");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_inited == false) {
|
if (inited_ == false) {
|
||||||
std::cout << "AE_NEED_INIT" << std::endl;
|
LOG_ERROR("Screen capturer not inited");
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
_running = true;
|
for (int i = 0; i < sessions_.size(); i++) {
|
||||||
session_->Start();
|
if (sessions_[i].inited_ == false) {
|
||||||
|
LOG_ERROR("Session {} not inited", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessions_[i].running_) {
|
||||||
|
LOG_ERROR("Session {} is already running", i);
|
||||||
|
} else {
|
||||||
|
sessions_[i].session_->Start();
|
||||||
|
|
||||||
|
if (i != 0) {
|
||||||
|
sessions_[i].session_->Pause();
|
||||||
|
sessions_[i].paused_ = true;
|
||||||
|
}
|
||||||
|
sessions_[i].running_ = true;
|
||||||
|
}
|
||||||
|
running_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScreenCapturerWgc::Pause() {
|
int ScreenCapturerWgc::Pause(int monitor_index) {
|
||||||
_paused = true;
|
if (monitor_index >= sessions_.size() || monitor_index < 0) {
|
||||||
if (session_) session_->Pause();
|
LOG_ERROR("Invalid session index: {}", monitor_index);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sessions_[monitor_index].paused_) {
|
||||||
|
sessions_[monitor_index].session_->Pause();
|
||||||
|
sessions_[monitor_index].paused_ = true;
|
||||||
|
LOG_INFO("Pausing session {}", monitor_index);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScreenCapturerWgc::Resume() {
|
int ScreenCapturerWgc::Resume(int monitor_index) {
|
||||||
_paused = false;
|
if (monitor_index >= sessions_.size() || monitor_index < 0) {
|
||||||
if (session_) session_->Resume();
|
LOG_ERROR("Invalid session index: {}", monitor_index);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessions_[monitor_index].paused_) {
|
||||||
|
sessions_[monitor_index].session_->Resume();
|
||||||
|
sessions_[monitor_index].paused_ = false;
|
||||||
|
LOG_INFO("Resuming session {}", monitor_index);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScreenCapturerWgc::Stop() {
|
int ScreenCapturerWgc::Stop() {
|
||||||
_running = false;
|
for (int i = 0; i < sessions_.size(); i++) {
|
||||||
|
if (sessions_[i].running_) {
|
||||||
if (session_) session_->Stop();
|
sessions_[i].session_->Stop();
|
||||||
|
sessions_[i].running_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScreenCapturerWgc::SwitchTo(int monitor_index) {
|
int ScreenCapturerWgc::SwitchTo(int monitor_index) {
|
||||||
if (!_inited) return -1;
|
if (monitor_index_ == monitor_index) {
|
||||||
|
LOG_INFO("Already on monitor {}:{}", monitor_index_,
|
||||||
|
display_list_[monitor_index_].name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (monitor_index >= display_list_.size()) {
|
if (monitor_index >= display_list_.size()) {
|
||||||
LOG_ERROR("Invalid monitor index: {}", monitor_index);
|
LOG_ERROR("Invalid monitor index: {}", monitor_index);
|
||||||
return -3;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("Switching to monitor {}:{}", monitor_index,
|
if (!sessions_[monitor_index].inited_) {
|
||||||
display_list_[monitor_index].name);
|
LOG_ERROR("Monitor {} not inited", monitor_index);
|
||||||
|
return -1;
|
||||||
Stop();
|
|
||||||
|
|
||||||
if (session_) {
|
|
||||||
session_->Release();
|
|
||||||
delete session_;
|
|
||||||
session_ = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session_ = new WgcSessionImpl();
|
Pause(monitor_index_);
|
||||||
if (!session_) {
|
|
||||||
LOG_ERROR("Failed to create new WgcSessionImpl.");
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
session_->RegisterObserver(this);
|
monitor_index_ = monitor_index;
|
||||||
|
LOG_INFO("Switching to monitor {}:{}", monitor_index_,
|
||||||
|
display_list_[monitor_index_].name);
|
||||||
|
|
||||||
int err = session_->Initialize((HMONITOR)display_list_[monitor_index].handle);
|
Resume(monitor_index);
|
||||||
if (err != 0) {
|
|
||||||
LOG_ERROR("Failed to re-initialize session on new monitor.");
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor_ = (HMONITOR)display_list_[monitor_index].handle;
|
return 0;
|
||||||
_inited = true;
|
|
||||||
|
|
||||||
return Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConvertABGRtoBGRA(const uint8_t *abgr_data, uint8_t *bgra_data, int width,
|
|
||||||
int height, int abgr_stride, int bgra_stride) {
|
|
||||||
for (int i = 0; i < height; ++i) {
|
|
||||||
for (int j = 0; j < width; ++j) {
|
|
||||||
int abgr_index = (i * abgr_stride + j) * 4;
|
|
||||||
int bgra_index = (i * bgra_stride + j) * 4;
|
|
||||||
|
|
||||||
bgra_data[bgra_index + 0] = abgr_data[abgr_index + 2]; // 蓝色
|
|
||||||
bgra_data[bgra_index + 1] = abgr_data[abgr_index + 1]; // 绿色
|
|
||||||
bgra_data[bgra_index + 2] = abgr_data[abgr_index + 0]; // 红色
|
|
||||||
bgra_data[bgra_index + 3] = abgr_data[abgr_index + 3]; // Alpha
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConvertBGRAtoABGR(const uint8_t *bgra_data, uint8_t *abgr_data, int width,
|
|
||||||
int height, int bgra_stride, int abgr_stride) {
|
|
||||||
for (int i = 0; i < height; ++i) {
|
|
||||||
for (int j = 0; j < width; ++j) {
|
|
||||||
int bgra_index = (i * bgra_stride + j) * 4;
|
|
||||||
int abgr_index = (i * abgr_stride + j) * 4;
|
|
||||||
|
|
||||||
abgr_data[abgr_index + 0] = bgra_data[bgra_index + 3]; // Alpha
|
|
||||||
abgr_data[abgr_index + 1] = bgra_data[bgra_index + 0]; // Blue
|
|
||||||
abgr_data[abgr_index + 2] = bgra_data[bgra_index + 1]; // Green
|
|
||||||
abgr_data[abgr_index + 3] = bgra_data[bgra_index + 2]; // Red
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenCapturerWgc::OnFrame(const WgcSession::wgc_session_frame &frame) {
|
void ScreenCapturerWgc::OnFrame(const WgcSession::wgc_session_frame &frame) {
|
||||||
if (_on_data) {
|
if (on_data_) {
|
||||||
// int width = 1280;
|
|
||||||
// int height = 720;
|
|
||||||
|
|
||||||
if (!nv12_frame_) {
|
if (!nv12_frame_) {
|
||||||
nv12_frame_ = new unsigned char[frame.width * frame.height * 3 / 2];
|
nv12_frame_ = new unsigned char[frame.width * frame.height * 3 / 2];
|
||||||
}
|
}
|
||||||
@@ -251,15 +253,20 @@ void ScreenCapturerWgc::OnFrame(const WgcSession::wgc_session_frame &frame) {
|
|||||||
(uint8_t *)(nv12_frame_ + frame.width * frame.height),
|
(uint8_t *)(nv12_frame_ + frame.width * frame.height),
|
||||||
frame.width, frame.width, frame.height);
|
frame.width, frame.width, frame.height);
|
||||||
|
|
||||||
_on_data(nv12_frame_, frame.width * frame.height * 3 / 2, frame.width,
|
on_data_(nv12_frame_, frame.width * frame.height * 3 / 2, frame.width,
|
||||||
frame.height);
|
frame.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenCapturerWgc::CleanUp() {
|
void ScreenCapturerWgc::CleanUp() {
|
||||||
_inited = false;
|
if (inited_) {
|
||||||
|
for (auto &session : sessions_) {
|
||||||
if (session_) session_->Release();
|
if (session.session_) {
|
||||||
|
session.session_->Stop();
|
||||||
session_ = nullptr;
|
session.session_->Release();
|
||||||
|
session.session_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sessions_.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ class ScreenCapturerWgc : public ScreenCapturer,
|
|||||||
virtual int Start() override;
|
virtual int Start() override;
|
||||||
virtual int Stop() override;
|
virtual int Stop() override;
|
||||||
|
|
||||||
int Pause();
|
virtual int Pause(int monitor_index) override;
|
||||||
int Resume();
|
virtual int Resume(int monitor_index) override;
|
||||||
|
|
||||||
std::vector<DisplayInfo> GetDisplayList() { return display_list_; }
|
std::vector<DisplayInfo> GetDisplayList() { return display_list_; }
|
||||||
|
|
||||||
@@ -41,21 +41,25 @@ class ScreenCapturerWgc : public ScreenCapturer,
|
|||||||
HMONITOR monitor_;
|
HMONITOR monitor_;
|
||||||
MONITORINFOEX monitor_info_;
|
MONITORINFOEX monitor_info_;
|
||||||
std::vector<DisplayInfo> display_list_;
|
std::vector<DisplayInfo> display_list_;
|
||||||
|
int monitor_index_ = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WgcSession *session_ = nullptr;
|
class WgcSessionInfo {
|
||||||
|
public:
|
||||||
|
std::unique_ptr<WgcSession> session_;
|
||||||
|
bool inited_ = false;
|
||||||
|
bool running_ = false;
|
||||||
|
bool paused_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
std::atomic_bool _running;
|
std::vector<WgcSessionInfo> sessions_;
|
||||||
std::atomic_bool _paused;
|
|
||||||
std::atomic_bool _inited;
|
|
||||||
|
|
||||||
std::thread _thread;
|
std::atomic_bool running_;
|
||||||
|
std::atomic_bool inited_;
|
||||||
|
|
||||||
std::string _device_name;
|
int fps_;
|
||||||
|
|
||||||
int _fps;
|
cb_desktop_data on_data_ = nullptr;
|
||||||
|
|
||||||
cb_desktop_data _on_data = nullptr;
|
|
||||||
|
|
||||||
unsigned char *nv12_frame_ = nullptr;
|
unsigned char *nv12_frame_ = nullptr;
|
||||||
unsigned char *nv12_frame_scaled_ = nullptr;
|
unsigned char *nv12_frame_scaled_ = nullptr;
|
||||||
|
|||||||
@@ -124,6 +124,8 @@ int WgcSessionImpl::Stop() {
|
|||||||
int WgcSessionImpl::Pause() {
|
int WgcSessionImpl::Pause() {
|
||||||
std::lock_guard locker(lock_);
|
std::lock_guard locker(lock_);
|
||||||
|
|
||||||
|
is_paused_ = true;
|
||||||
|
|
||||||
CHECK_INIT;
|
CHECK_INIT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -131,6 +133,8 @@ int WgcSessionImpl::Pause() {
|
|||||||
int WgcSessionImpl::Resume() {
|
int WgcSessionImpl::Resume() {
|
||||||
std::lock_guard locker(lock_);
|
std::lock_guard locker(lock_);
|
||||||
|
|
||||||
|
is_paused_ = false;
|
||||||
|
|
||||||
CHECK_INIT;
|
CHECK_INIT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -233,6 +237,10 @@ void WgcSessionImpl::OnFrame(
|
|||||||
|
|
||||||
// copy to mapped texture
|
// copy to mapped texture
|
||||||
{
|
{
|
||||||
|
if (is_paused_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto frame_captured =
|
auto frame_captured =
|
||||||
GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
|
GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,14 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
|||||||
for (int i = 0; i < display_list.size(); i++) {
|
for (int i = 0; i < display_list.size(); i++) {
|
||||||
if (ImGui::Selectable(display_list[i].name.c_str())) {
|
if (ImGui::Selectable(display_list[i].name.c_str())) {
|
||||||
selected_display_ = i + 1;
|
selected_display_ = i + 1;
|
||||||
|
|
||||||
|
RemoteAction remote_action;
|
||||||
|
remote_action.type = ControlType::display_id;
|
||||||
|
remote_action.d = i;
|
||||||
|
if (props->connection_status_ == ConnectionStatus::Connected) {
|
||||||
|
SendDataFrame(props->peer_, (const char*)&remote_action,
|
||||||
|
sizeof(remote_action));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::SetWindowFontScale(1.0f);
|
ImGui::SetWindowFontScale(1.0f);
|
||||||
@@ -118,7 +126,8 @@ int Render::ControlBar(std::shared_ptr<SubStreamWindowProperties>& props) {
|
|||||||
float disable_audio_x = ImGui::GetCursorScreenPos().x + 4;
|
float disable_audio_x = ImGui::GetCursorScreenPos().x + 4;
|
||||||
float disable_audio_y = ImGui::GetCursorScreenPos().y + 4.0f;
|
float disable_audio_y = ImGui::GetCursorScreenPos().y + 4.0f;
|
||||||
// std::string audio = audio_capture_button_pressed_ ? ICON_FA_VOLUME_HIGH
|
// std::string audio = audio_capture_button_pressed_ ? ICON_FA_VOLUME_HIGH
|
||||||
// : ICON_FA_VOLUME_XMARK;
|
// :
|
||||||
|
// ICON_FA_VOLUME_XMARK;
|
||||||
std::string audio = props->audio_capture_button_pressed_
|
std::string audio = props->audio_capture_button_pressed_
|
||||||
? ICON_FA_VOLUME_HIGH
|
? ICON_FA_VOLUME_HIGH
|
||||||
: ICON_FA_VOLUME_HIGH;
|
: ICON_FA_VOLUME_HIGH;
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ class Render {
|
|||||||
int texture_height_ = 720;
|
int texture_height_ = 720;
|
||||||
int video_width_ = 0;
|
int video_width_ = 0;
|
||||||
int video_height_ = 0;
|
int video_height_ = 0;
|
||||||
|
int video_width_last_ = 0;
|
||||||
|
int video_height_last_ = 0;
|
||||||
size_t video_size_ = 0;
|
size_t video_size_ = 0;
|
||||||
bool tab_selected_ = false;
|
bool tab_selected_ = false;
|
||||||
bool tab_opened_ = true;
|
bool tab_opened_ = true;
|
||||||
|
|||||||
@@ -215,8 +215,11 @@ void Render::OnReceiveVideoBufferCb(const XVideoFrame *video_frame,
|
|||||||
|
|
||||||
memcpy(props->dst_buffer_, video_frame->data, video_frame->size);
|
memcpy(props->dst_buffer_, video_frame->data, video_frame->size);
|
||||||
bool need_to_update_render_rect = false;
|
bool need_to_update_render_rect = false;
|
||||||
if (props->video_width_ == 0 && props->video_height_ == 0) {
|
if (props->video_width_ != props->video_width_last_ ||
|
||||||
|
props->video_height_ != props->video_height_last_) {
|
||||||
need_to_update_render_rect = true;
|
need_to_update_render_rect = true;
|
||||||
|
props->video_width_last_ = props->video_width_;
|
||||||
|
props->video_height_last_ = props->video_height_;
|
||||||
}
|
}
|
||||||
props->video_width_ = video_frame->width;
|
props->video_width_ = video_frame->width;
|
||||||
props->video_height_ = video_frame->height;
|
props->video_height_ = video_frame->height;
|
||||||
@@ -261,6 +264,7 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size,
|
|||||||
std::string remote_id(user_id, user_id_size);
|
std::string remote_id(user_id, user_id_size);
|
||||||
if (render->client_properties_.find(remote_id) !=
|
if (render->client_properties_.find(remote_id) !=
|
||||||
render->client_properties_.end()) {
|
render->client_properties_.end()) {
|
||||||
|
// local
|
||||||
auto props = render->client_properties_.find(remote_id)->second;
|
auto props = render->client_properties_.find(remote_id)->second;
|
||||||
if (ControlType::host_infomation == remote_action.type) {
|
if (ControlType::host_infomation == remote_action.type) {
|
||||||
props->remote_host_name_ = std::string(remote_action.i.host_name,
|
props->remote_host_name_ = std::string(remote_action.i.host_name,
|
||||||
@@ -268,6 +272,7 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size,
|
|||||||
LOG_INFO("Remote hostname: [{}]", props->remote_host_name_);
|
LOG_INFO("Remote hostname: [{}]", props->remote_host_name_);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// remote
|
||||||
if (ControlType::mouse == remote_action.type && render->mouse_controller_) {
|
if (ControlType::mouse == remote_action.type && render->mouse_controller_) {
|
||||||
render->mouse_controller_->SendMouseCommand(remote_action);
|
render->mouse_controller_->SendMouseCommand(remote_action);
|
||||||
} else if (ControlType::audio_capture == remote_action.type) {
|
} else if (ControlType::audio_capture == remote_action.type) {
|
||||||
@@ -283,6 +288,10 @@ void Render::OnReceiveDataBufferCb(const char *data, size_t size,
|
|||||||
render->keyboard_capturer_->SendKeyboardCommand(
|
render->keyboard_capturer_->SendKeyboardCommand(
|
||||||
(int)remote_action.k.key_value,
|
(int)remote_action.k.key_value,
|
||||||
remote_action.k.flag == KeyFlag::key_down);
|
remote_action.k.flag == KeyFlag::key_down);
|
||||||
|
} else if (ControlType::display_id == remote_action.type) {
|
||||||
|
if (render->screen_capturer_) {
|
||||||
|
render->screen_capturer_->SwitchTo(remote_action.d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ int Render::StreamWindow() {
|
|||||||
props->render_window_y_ = pos.y;
|
props->render_window_y_ = pos.y;
|
||||||
props->render_window_width_ = size.x;
|
props->render_window_width_ = size.x;
|
||||||
props->render_window_height_ = size.y;
|
props->render_window_height_ = size.y;
|
||||||
|
UpdateRenderRect();
|
||||||
|
|
||||||
ControlWindow(props);
|
ControlWindow(props);
|
||||||
|
|
||||||
@@ -139,6 +140,7 @@ int Render::StreamWindow() {
|
|||||||
props->render_window_y_ = pos.y;
|
props->render_window_y_ = pos.y;
|
||||||
props->render_window_width_ = size.x;
|
props->render_window_width_ = size.x;
|
||||||
props->render_window_height_ = size.y;
|
props->render_window_height_ = size.y;
|
||||||
|
UpdateRenderRect();
|
||||||
|
|
||||||
ControlWindow(props);
|
ControlWindow(props);
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
@@ -161,7 +163,7 @@ int Render::StreamWindow() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateRenderRect();
|
// UpdateRenderRect();
|
||||||
ImGui::End(); // End VideoBg
|
ImGui::End(); // End VideoBg
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
2
thirdparty/projectx
vendored
2
thirdparty/projectx
vendored
Submodule thirdparty/projectx updated: 881cecc3f9...5aa61bf735
Reference in New Issue
Block a user