>From 98043face18a5fae93ed01c14a15140a60dd7ad4 Mon Sep 17 00:00:00 2001
From: Dilshod Mukhtarov <dilshodm@gmail.com>
Date: Fri, 25 Jan 2019 11:52:02 +0400
Subject: [PATCH] libavdevice/gdigrab: Fix HIDPI support
In Windows HIDPI mode grigrab mouse was not properly positioned when
using area recording. When using windowed recording the window size was
not correct (recording window cropped)
Signed-off-by: Dilshod Mukhtarov <dilshodm@gmail.com>
---
libavdevice/gdigrab.c | 43 ++++++++++++++++++++++++++++---------------
1 file changed, 28 insertions(+), 15 deletions(-)
@@ -243,6 +243,8 @@ gdigrab_read_header(AVFormatContext *s1)
RECT clip_rect;
BITMAP bmp;
int ret;
+ double h_dpr; // Horizontal device pixel ratio
+ double v_dpr; // Vertical device pixel ratio
if (!strncmp(filename, "title=", 6)) {
name = filename + 6;
@@ -277,18 +279,25 @@ gdigrab_read_header(AVFormatContext *s1)
}
bpp = GetDeviceCaps(source_hdc, BITSPIXEL);
+ horzres = GetDeviceCaps(source_hdc, HORZRES);
+ vertres = GetDeviceCaps(source_hdc, VERTRES);
+ desktophorzres = GetDeviceCaps(source_hdc, DESKTOPHORZRES);
+ desktopvertres = GetDeviceCaps(source_hdc, DESKTOPVERTRES);
+ h_dpr = (double) desktophorzres / horzres;
+ v_dpr = (double) desktopvertres / vertres;
+
if (hwnd) {
GetClientRect(hwnd, &virtual_rect);
+ virtual_rect.left *= h_dpr;
+ virtual_rect.right *= h_dpr;
+ virtual_rect.top *= v_dpr;
+ virtual_rect.bottom *= v_dpr;
} else {
/* desktop -- get the right height and width for scaling DPI */
- horzres = GetDeviceCaps(source_hdc, HORZRES);
- vertres = GetDeviceCaps(source_hdc, VERTRES);
- desktophorzres = GetDeviceCaps(source_hdc, DESKTOPHORZRES);
- desktopvertres = GetDeviceCaps(source_hdc, DESKTOPVERTRES);
virtual_rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
virtual_rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
- virtual_rect.right = (virtual_rect.left + GetSystemMetrics(SM_CXVIRTUALSCREEN)) * desktophorzres / horzres;
- virtual_rect.bottom = (virtual_rect.top + GetSystemMetrics(SM_CYVIRTUALSCREEN)) * desktopvertres / vertres;
+ virtual_rect.right = (virtual_rect.left + GetSystemMetrics(SM_CXVIRTUALSCREEN)) * h_dpr;
+ virtual_rect.bottom = (virtual_rect.top + GetSystemMetrics(SM_CYVIRTUALSCREEN)) * h_dpr;
}
/* If no width or height set, use full screen/window area */
@@ -455,6 +464,8 @@ static void paint_mouse_pointer(AVFormatContext *s1, struct gdigrab *gdigrab)
int vertres = GetDeviceCaps(gdigrab->source_hdc, VERTRES);
int desktophorzres = GetDeviceCaps(gdigrab->source_hdc, DESKTOPHORZRES);
int desktopvertres = GetDeviceCaps(gdigrab->source_hdc, DESKTOPVERTRES);
+ double h_dpr = (double) desktophorzres / horzres; // Horizontal device pixel ratio
+ double v_dpr = (double) desktopvertres / vertres; // Vertical device pixel ratio
info.hbmMask = NULL;
info.hbmColor = NULL;
@@ -473,24 +484,26 @@ static void paint_mouse_pointer(AVFormatContext *s1, struct gdigrab *gdigrab)
goto icon_error;
}
- pos.x = ci.ptScreenPos.x - clip_rect.left - info.xHotspot;
- pos.y = ci.ptScreenPos.y - clip_rect.top - info.yHotspot;
-
if (hwnd) {
RECT rect;
if (GetWindowRect(hwnd, &rect)) {
- pos.x -= rect.left;
- pos.y -= rect.top;
+ pos.x = ci.ptScreenPos.x - clip_rect.left - info.xHotspot - rect.left;
+ pos.y = ci.ptScreenPos.y - clip_rect.top - info.yHotspot - rect.top;
+
+ //that would keep the correct location of mouse with hidpi screens
+ pos.x *= h_dpr;
+ pos.y *= v_dpr;
} else {
CURSOR_ERROR("Couldn't get window rectangle");
goto icon_error;
}
}
-
- //that would keep the correct location of mouse with hidpi screens
- pos.x = pos.x * desktophorzres / horzres;
- pos.y = pos.y * desktopvertres / vertres;
+ else {
+ //that would keep the correct location of mouse with hidpi screens
+ pos.x = ci.ptScreenPos.x * h_dpr - clip_rect.left - info.xHotspot;
+ pos.y = ci.ptScreenPos.y * v_dpr - clip_rect.top - info.yHotspot;
+ }
av_log(s1, AV_LOG_DEBUG, "Cursor pos (%li,%li) -> (%li,%li)\n",
ci.ptScreenPos.x, ci.ptScreenPos.y, pos.x, pos.y);
--
2.17.1