Fix absolute mouse coordinates with multiple monitors on Windows

This commit is contained in:
loki 2021-06-23 21:51:15 +02:00
commit 926e95f527
4 changed files with 41 additions and 27 deletions

View file

@ -91,6 +91,10 @@ int display_base_t::init() {
});
*/
// Get rectangle of full desktop for absolute mouse coordinates
env_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
env_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
HRESULT status;
status = CreateDXGIFactory1(IID_IDXGIFactory1, (void **)&factory);
@ -133,6 +137,11 @@ int display_base_t::init() {
offset_y = desc.DesktopCoordinates.top;
width = desc.DesktopCoordinates.right - offset_x;
height = desc.DesktopCoordinates.bottom - offset_y;
// left and bottom may be negative, yet absolute mouse coordinates start at 0x0
// Ensure offset starts at 0x0
offset_x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
offset_y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
}
}
@ -195,7 +204,9 @@ int display_base_t::init() {
<< "Device Sys Mem : "sv << adapter_desc.DedicatedSystemMemory / 1048576 << " MiB"sv << std::endl
<< "Share Sys Mem : "sv << adapter_desc.SharedSystemMemory / 1048576 << " MiB"sv << std::endl
<< "Feature Level : 0x"sv << util::hex(feature_level).to_string_view() << std::endl
<< "Capture size : "sv << width << 'x' << height;
<< "Capture size : "sv << width << 'x' << height << std::endl
<< "Offset : "sv << offset_x << 'x' << offset_y << std::endl
<< "Virtual Desktop : "sv << env_width << 'x' << env_height;
// Bump up thread priority
{

View file

@ -123,8 +123,8 @@ void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y)
// MOUSEEVENTF_VIRTUALDESK maps to the entirety of the desktop rather than the primary desktop
MOUSEEVENTF_VIRTUALDESK;
auto scaled_x = std::lround((x + touch_port.offset_x) * ((float)target_touch_port.width / (float)touch_port.width));
auto scaled_y = std::lround((y + touch_port.offset_y) * ((float)target_touch_port.height / (float)touch_port.height));
auto scaled_x = std::lround((x + touch_port.offset_x) * ((float)target_touch_port.env_width / (float)touch_port.env_width));
auto scaled_y = std::lround((y + touch_port.offset_y) * ((float)target_touch_port.env_height / (float)touch_port.env_height));
mi.dx = scaled_x;
mi.dy = scaled_y;

View file

@ -565,7 +565,7 @@ void recvThread(broadcast_ctx_t &ctx) {
});
auto type_str = buf_elem ? "AUDIO"sv : "VIDEO"sv;
BOOST_LOG(debug) << "Recv: "sv << peer.address().to_string() << ":"sv << peer.port() << " :: " << type_str;
BOOST_LOG(verbose) << "Recv: "sv << peer.address().to_string() << ':' << peer.port() << " :: " << type_str;
populate_peer_to_session();

View file

@ -1008,7 +1008,7 @@ void encode_run(
auto shutdown_event = mail->event<bool>(mail::shutdown);
auto packets = mail::man->queue<packet_t>(mail::video_packets);
auto idr_events = mail->queue<idr_t>(mail::idr);
auto idr_events = mail->event<idr_t>(mail::idr);
while(true) {
if(shutdown_event->peek() || reinit_event.peek() || !images->running()) {
@ -1061,6 +1061,28 @@ void encode_run(
}
}
platf::touch_port_t make_port(platf::display_t *display, const config_t &config) {
float wd = display->width;
float hd = display->height;
float wt = config.width;
float ht = config.height;
auto scalar = std::fminf(wt / wd, ht / hd);
auto w2 = scalar * wd;
auto h2 = scalar * hd;
return platf::touch_port_t {
display->offset_x,
display->offset_y,
display->env_width,
display->env_height,
(int)w2,
(int)h2,
};
}
std::optional<sync_session_t> make_synced_session(platf::display_t *disp, const encoder_t &encoder, platf::img_t &img, sync_session_ctx_t &ctx) {
sync_session_t encode_session;
@ -1075,6 +1097,9 @@ std::optional<sync_session_t> make_synced_session(platf::display_t *disp, const
return std::nullopt;
}
// absolute mouse coordinates require that the dimensions of the screen are known
ctx.touch_port_events->raise(make_port(disp, ctx.config));
auto session = make_session(encoder, ctx.config, img.width, img.height, hwdevice.get());
if(!session) {
return std::nullopt;
@ -1261,28 +1286,6 @@ void captureThreadSync() {
while(encode_run_sync(synced_session_ctxs, ctx) == encode_e::reinit) {}
}
platf::touch_port_t make_port(platf::display_t *display, const config_t &config) {
float wd = display->width;
float hd = display->height;
float wt = config.width;
float ht = config.height;
auto scalar = std::fminf(wt / wd, ht / hd);
auto w2 = scalar * wd;
auto h2 = scalar * hd;
return platf::touch_port_t {
display->offset_x,
display->offset_y,
display->env_width,
display->env_height,
(int)w2,
(int)h2,
};
}
void capture_async(
safe::mail_t mail,
config_t &config,