Commit 2006f76b authored by Zhiyi Zhang's avatar Zhiyi Zhang Committed by Alexandre Julliard

gdi32: Report correct HORZRES and VERTRES values for GetDeviceCaps() with DCs on…

gdi32: Report correct HORZRES and VERTRES values for GetDeviceCaps() with DCs on a specific monitor. Fix DLC Quest uses the primary monitor size to render when in fullscreen mode on non-primary monitors. Signed-off-by: 's avatarZhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: 's avatarHuw Davies <huw@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 640f7081
......@@ -623,6 +623,7 @@ BOOL WINAPI RestoreDC( HDC hdc, INT level )
HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
const DEVMODEW *initData )
{
const WCHAR *display, *p;
HDC hdc;
DC * dc;
const struct gdi_dc_funcs *funcs;
......@@ -663,6 +664,23 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
}
}
if (is_display_device( driver ))
display = driver;
else if (is_display_device( device ))
display = device;
else
display = NULL;
if (display)
{
/* Copy only the display name. For example, \\.\DISPLAY1 in \\.\DISPLAY1\Monitor0 */
p = display + 12;
while (iswdigit( *p ))
++p;
lstrcpynW( dc->display, display, p - display + 1 );
dc->display[p - display] = '\0';
}
dc->vis_rect.left = 0;
dc->vis_rect.top = 0;
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
......
......@@ -81,7 +81,9 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
};
static CRITICAL_SECTION driver_section = { &critsect_debug, -1, 0, 0, 0, 0 };
static BOOL (WINAPI *pEnumDisplayMonitors)(HDC, LPRECT, MONITORENUMPROC, LPARAM);
static HWND (WINAPI *pGetDesktopWindow)(void);
static BOOL (WINAPI *pGetMonitorInfoW)(HMONITOR, LPMONITORINFO);
static INT (WINAPI *pGetSystemMetrics)(INT);
static DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
......@@ -137,10 +139,13 @@ static const struct gdi_dc_funcs *get_display_driver(void)
/**********************************************************************
* is_display_device
*/
static BOOL is_display_device( LPCWSTR name )
BOOL is_display_device( LPCWSTR name )
{
const WCHAR *p = name;
if (!name)
return FALSE;
if (wcsnicmp( name, L"\\\\.\\DISPLAY", lstrlenW(L"\\\\.\\DISPLAY") )) return FALSE;
p += lstrlenW(L"\\\\.\\DISPLAY");
......@@ -237,10 +242,33 @@ void CDECL __wine_set_display_driver( HMODULE module )
HeapFree( GetProcessHeap(), 0, driver );
user32 = LoadLibraryA( "user32.dll" );
pGetMonitorInfoW = (void *)GetProcAddress( user32, "GetMonitorInfoW" );
pGetSystemMetrics = (void *)GetProcAddress( user32, "GetSystemMetrics" );
pEnumDisplayMonitors = (void *)GetProcAddress( user32, "EnumDisplayMonitors" );
pSetThreadDpiAwarenessContext = (void *)GetProcAddress( user32, "SetThreadDpiAwarenessContext" );
}
struct monitor_info
{
const WCHAR *name;
RECT rect;
};
static BOOL CALLBACK monitor_enum_proc( HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lparam )
{
struct monitor_info *info = (struct monitor_info *)lparam;
MONITORINFOEXW mi;
mi.cbSize = sizeof(mi);
pGetMonitorInfoW( monitor, (MONITORINFO *)&mi );
if (!lstrcmpiW( info->name, mi.szDevice ))
{
info->rect = mi.rcMonitor;
return FALSE;
}
return TRUE;
}
static INT CDECL nulldrv_AbortDoc( PHYSDEV dev )
{
......@@ -378,8 +406,38 @@ static INT CDECL nulldrv_GetDeviceCaps( PHYSDEV dev, INT cap )
GetDeviceCaps( dev->hdc, LOGPIXELSX ) * 10 );
case VERTSIZE: return MulDiv( GetDeviceCaps( dev->hdc, VERTRES ), 254,
GetDeviceCaps( dev->hdc, LOGPIXELSY ) * 10 );
case HORZRES: return pGetSystemMetrics ? pGetSystemMetrics( SM_CXSCREEN ) : 640;
case VERTRES: return pGetSystemMetrics ? pGetSystemMetrics( SM_CYSCREEN ) : 480;
case HORZRES:
{
DC *dc = get_nulldrv_dc( dev );
struct monitor_info info;
if (dc->display[0] && pEnumDisplayMonitors && pGetMonitorInfoW)
{
info.name = dc->display;
SetRectEmpty( &info.rect );
pEnumDisplayMonitors( NULL, NULL, monitor_enum_proc, (LPARAM)&info );
if (!IsRectEmpty( &info.rect ))
return info.rect.right - info.rect.left;
}
return pGetSystemMetrics ? pGetSystemMetrics( SM_CXSCREEN ) : 640;
}
case VERTRES:
{
DC *dc = get_nulldrv_dc( dev );
struct monitor_info info;
if (dc->display[0] && pEnumDisplayMonitors && pGetMonitorInfoW)
{
info.name = dc->display;
SetRectEmpty( &info.rect );
pEnumDisplayMonitors( NULL, NULL, monitor_enum_proc, (LPARAM)&info );
if (!IsRectEmpty( &info.rect ))
return info.rect.bottom - info.rect.top;
}
return pGetSystemMetrics ? pGetSystemMetrics( SM_CYSCREEN ) : 480;
}
case BITSPIXEL: return 32;
case PLANES: return 1;
case NUMBRUSHES: return -1;
......
......@@ -84,6 +84,7 @@ typedef struct tagDC
int pixel_format; /* pixel format (for memory DCs) */
UINT aa_flags; /* anti-aliasing flags to pass to GetGlyphOutline for current font */
FLOAT miterLimit;
WCHAR display[CCHDEVICENAME]; /* Display name when created for a specific display device */
int flags;
DWORD layout;
......@@ -487,6 +488,9 @@ typedef struct
#define WMFC_MAGIC 0x43464d57
/* driver.c */
extern BOOL is_display_device( LPCWSTR name ) DECLSPEC_HIDDEN;
/* path.c */
extern void free_gdi_path( struct gdi_path *path ) DECLSPEC_HIDDEN;
......
......@@ -2085,7 +2085,7 @@ static void test_display_dc(void)
hdc = CreateDCA(dd.DeviceName, NULL, NULL, NULL);
ok(!!hdc, "CreateDCA %s failed.\n", dd.DeviceName);
check_display_dc(hdc, &dm, TRUE);
check_display_dc(hdc, &dm, FALSE);
/* Tests after mode changes */
memset(&dm2, 0, sizeof(dm2));
......@@ -2108,7 +2108,7 @@ static void test_display_dc(void)
continue;
}
check_display_dc(hdc, &dm2, TRUE);
check_display_dc(hdc, &dm2, FALSE);
/* Tests after monitor detach */
if (!(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment