blob: 9c7869dcc5f289893dfed156946bdd36ac592bda [file] [log] [blame]
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the w64 mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SM_CMONITORS
#define SM_XVIRTUALSCREEN 76
#define SM_YVIRTUALSCREEN 77
#define SM_CXVIRTUALSCREEN 78
#define SM_CYVIRTUALSCREEN 79
#define SM_CMONITORS 80
#define SM_SAMEDISPLAYFORMAT 81
#define MONITOR_DEFAULTTONULL 0x00000000
#define MONITOR_DEFAULTTOPRIMARY 0x00000001
#define MONITOR_DEFAULTTONEAREST 0x00000002
#define MONITORINFOF_PRIMARY 0x00000001
typedef struct tagMONITORINFO {
DWORD cbSize;
RECT rcMonitor;
RECT rcWork;
DWORD dwFlags;
} MONITORINFO,*LPMONITORINFO;
#ifndef CCHDEVICENAME
#define CCHDEVICENAME 32
#endif
#ifdef __cplusplus
typedef struct tagMONITORINFOEXA : public tagMONITORINFO {
CHAR szDevice[CCHDEVICENAME];
} MONITORINFOEXA,*LPMONITORINFOEXA;
typedef struct tagMONITORINFOEXW : public tagMONITORINFO {
WCHAR szDevice[CCHDEVICENAME];
} MONITORINFOEXW,*LPMONITORINFOEXW;
#ifdef UNICODE
typedef MONITORINFOEXW MONITORINFOEX;
typedef LPMONITORINFOEXW LPMONITORINFOEX;
#else
typedef MONITORINFOEXA MONITORINFOEX;
typedef LPMONITORINFOEXA LPMONITORINFOEX;
#endif
#else
typedef struct tagMONITORINFOEXA {
MONITORINFO;
CHAR szDevice[CCHDEVICENAME];
} MONITORINFOEXA,*LPMONITORINFOEXA;
typedef struct tagMONITORINFOEXW {
MONITORINFO;
WCHAR szDevice[CCHDEVICENAME];
} MONITORINFOEXW,*LPMONITORINFOEXW;
#ifdef UNICODE
typedef MONITORINFOEXW MONITORINFOEX;
typedef LPMONITORINFOEXW LPMONITORINFOEX;
#else
typedef MONITORINFOEXA MONITORINFOEX;
typedef LPMONITORINFOEXA LPMONITORINFOEX;
#endif
#endif
typedef WINBOOL (CALLBACK *MONITORENUMPROC)(HMONITOR,HDC,LPRECT,LPARAM);
#ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
typedef struct _DISPLAY_DEVICEA {
DWORD cb;
CHAR DeviceName[32];
CHAR DeviceString[128];
DWORD StateFlags;
CHAR DeviceID[128];
CHAR DeviceKey[128];
} DISPLAY_DEVICEA,*PDISPLAY_DEVICEA,*LPDISPLAY_DEVICEA;
typedef struct _DISPLAY_DEVICEW {
DWORD cb;
WCHAR DeviceName[32];
WCHAR DeviceString[128];
DWORD StateFlags;
WCHAR DeviceID[128];
WCHAR DeviceKey[128];
} DISPLAY_DEVICEW,*PDISPLAY_DEVICEW,*LPDISPLAY_DEVICEW;
#ifdef UNICODE
typedef DISPLAY_DEVICEW DISPLAY_DEVICE;
typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE;
typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE;
#else
typedef DISPLAY_DEVICEA DISPLAY_DEVICE;
typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE;
typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE;
#endif
#define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
#define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
#define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
#define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
#define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010
#endif
#endif
#undef GetMonitorInfo
#undef GetSystemMetrics
#undef MonitorFromWindow
#undef MonitorFromRect
#undef MonitorFromPoint
#undef EnumDisplayMonitors
#undef EnumDisplayDevices
#ifdef COMPILE_MULTIMON_STUBS
#ifndef MULTIMON_FNS_DEFINED
int (WINAPI *g_pfnGetSystemMetrics)(int) = NULL;
HMONITOR (WINAPI *g_pfnMonitorFromWindow)(HWND,DWORD) = NULL;
HMONITOR (WINAPI *g_pfnMonitorFromRect)(LPCRECT,DWORD) = NULL;
HMONITOR (WINAPI *g_pfnMonitorFromPoint)(POINT,DWORD) = NULL;
WINBOOL (WINAPI *g_pfnGetMonitorInfo)(HMONITOR,LPMONITORINFO) = NULL;
WINBOOL (WINAPI *g_pfnEnumDisplayMonitors)(HDC,LPCRECT,MONITORENUMPROC,LPARAM) = NULL;
WINBOOL (WINAPI *g_pfnEnumDisplayDevices)(PVOID,DWORD,PDISPLAY_DEVICE,DWORD) = NULL;
WINBOOL g_fMultiMonInitDone = FALSE;
WINBOOL g_fMultimonPlatformNT = FALSE;
#endif
WINBOOL IsPlatformNT() {
OSVERSIONINFOA osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionExA((OSVERSIONINFOA*)&osvi);
return (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId);
}
WINBOOL InitMultipleMonitorStubs(void) {
HMODULE hUser32;
if(g_fMultiMonInitDone) return g_pfnGetMonitorInfo!=NULL;
g_fMultimonPlatformNT = IsPlatformNT();
hUser32 = GetModuleHandle(TEXT("USER32"));
if(hUser32 &&
(*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics"))!=NULL &&
(*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow"))!=NULL &&
(*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect"))!=NULL &&
(*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint"))!=NULL &&
(*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors"))!=NULL &&
#ifdef UNICODE
(*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesW"))!=NULL &&
(*(FARPROC*)&g_pfnGetMonitorInfo = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfoW") :
GetProcAddress(hUser32,"GetMonitorInfoA"))!=NULL
#else
(*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoA"))!=NULL &&
(*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesA"))!=NULL
#endif
) {
g_fMultiMonInitDone = TRUE;
return TRUE;
} else {
g_pfnGetSystemMetrics = NULL;
g_pfnMonitorFromWindow = NULL;
g_pfnMonitorFromRect = NULL;
g_pfnMonitorFromPoint = NULL;
g_pfnGetMonitorInfo = NULL;
g_pfnEnumDisplayMonitors = NULL;
g_pfnEnumDisplayDevices = NULL;
g_fMultiMonInitDone = TRUE;
return FALSE;
}
}
int WINAPI xGetSystemMetrics(int nIndex) {
if(InitMultipleMonitorStubs()) return g_pfnGetSystemMetrics(nIndex);
switch(nIndex) {
case SM_CMONITORS:
case SM_SAMEDISPLAYFORMAT:
return 1;
case SM_XVIRTUALSCREEN:
case SM_YVIRTUALSCREEN:
return 0;
case SM_CXVIRTUALSCREEN:
nIndex = SM_CXSCREEN;
break;
case SM_CYVIRTUALSCREEN:
nIndex = SM_CYSCREEN;
break;
}
return GetSystemMetrics(nIndex);
}
#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
HMONITOR WINAPI xMonitorFromPoint(POINT ptScreenCoords,DWORD dwFlags) {
if(InitMultipleMonitorStubs()) return g_pfnMonitorFromPoint(ptScreenCoords,dwFlags);
if((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
((ptScreenCoords.x >= 0) &&
(ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
(ptScreenCoords.y >= 0) &&
(ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
{
return xPRIMARY_MONITOR;
}
return NULL;
}
HMONITOR WINAPI xMonitorFromRect(LPCRECT lprcScreenCoords,DWORD dwFlags)
{
if(InitMultipleMonitorStubs()) return g_pfnMonitorFromRect(lprcScreenCoords,dwFlags);
if((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
((lprcScreenCoords->right > 0) &&
(lprcScreenCoords->bottom > 0) &&
(lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
(lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
{
return xPRIMARY_MONITOR;
}
return NULL;
}
HMONITOR WINAPI xMonitorFromWindow(HWND hWnd,DWORD dwFlags) {
WINDOWPLACEMENT wp;
if(InitMultipleMonitorStubs()) return g_pfnMonitorFromWindow(hWnd,dwFlags);
if(dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) return xPRIMARY_MONITOR;
if(IsIconic(hWnd) ? GetWindowPlacement(hWnd,&wp) : GetWindowRect(hWnd,&wp.rcNormalPosition)) return xMonitorFromRect(&wp.rcNormalPosition,dwFlags);
return NULL;
}
WINBOOL WINAPI xGetMonitorInfo(HMONITOR hMonitor,LPMONITORINFO lpMonitorInfo) {
RECT rcWork;
if(InitMultipleMonitorStubs()) {
WINBOOL f = g_pfnGetMonitorInfo(hMonitor,lpMonitorInfo);
#if defined(UNICODE)
if(f && !g_fMultimonPlatformNT && (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))) {
MultiByteToWideChar(CP_ACP,0,(LPSTR)((MONITORINFOEX*)lpMonitorInfo)->szDevice,-1,((MONITORINFOEX*)lpMonitorInfo)->szDevice,(sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
}
#endif
return f;
}
if((hMonitor==xPRIMARY_MONITOR) &&
lpMonitorInfo &&
(lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
SystemParametersInfoA(SPI_GETWORKAREA,0,&rcWork,0))
{
lpMonitorInfo->rcMonitor.left = 0;
lpMonitorInfo->rcMonitor.top = 0;
lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
lpMonitorInfo->rcWork = rcWork;
lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
if(lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)) {
#if defined(UNICODE)
MultiByteToWideChar(CP_ACP,0,"DISPLAY",-1,((MONITORINFOEX*)lpMonitorInfo)->szDevice,(sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
#else
lstrcpyn(((MONITORINFOEX*)lpMonitorInfo)->szDevice,TEXT("DISPLAY"),(sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
#endif
}
return TRUE;
}
return FALSE;
}
WINBOOL WINAPI
xEnumDisplayMonitors(HDC hdcOptionalForPainting,LPCRECT lprcEnumMonitorsThatIntersect,MONITORENUMPROC lpfnEnumProc,LPARAM dwData)
{
RECT rcLimit;
if(InitMultipleMonitorStubs()) {
return g_pfnEnumDisplayMonitors(hdcOptionalForPainting,lprcEnumMonitorsThatIntersect,lpfnEnumProc,dwData);
}
if(!lpfnEnumProc)
return FALSE;
rcLimit.left = 0;
rcLimit.top = 0;
rcLimit.right = GetSystemMetrics(SM_CXSCREEN);
rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
if(hdcOptionalForPainting)
{
RECT rcClip;
POINT ptOrg;
switch (GetClipBox(hdcOptionalForPainting,&rcClip))
{
default:
if(!GetDCOrgEx(hdcOptionalForPainting,&ptOrg))
return FALSE;
OffsetRect(&rcLimit,-ptOrg.x,-ptOrg.y);
if(IntersectRect(&rcLimit,&rcLimit,&rcClip) &&
(!lprcEnumMonitorsThatIntersect ||
IntersectRect(&rcLimit,&rcLimit,lprcEnumMonitorsThatIntersect))) {
break;
}
case NULLREGION:
return TRUE;
case ERROR:
return FALSE;
}
} else {
if(lprcEnumMonitorsThatIntersect &&
!IntersectRect(&rcLimit,&rcLimit,lprcEnumMonitorsThatIntersect)) {
return TRUE;
}
}
return lpfnEnumProc(xPRIMARY_MONITOR,hdcOptionalForPainting,&rcLimit,dwData);
}
WINBOOL WINAPI
xEnumDisplayDevices(PVOID Unused,DWORD iDevNum,PDISPLAY_DEVICE lpDisplayDevice,DWORD dwFlags)
{
if(InitMultipleMonitorStubs())
return g_pfnEnumDisplayDevices(Unused,iDevNum,lpDisplayDevice,dwFlags);
if(Unused!=NULL)
return FALSE;
if(iDevNum!=0)
return FALSE;
if(!lpDisplayDevice || lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
return FALSE;
#if defined(UNICODE)
MultiByteToWideChar(CP_ACP,0,"DISPLAY",-1,lpDisplayDevice->DeviceName,(sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
MultiByteToWideChar(CP_ACP,0,"DISPLAY",-1,lpDisplayDevice->DeviceString,(sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)));
#else
lstrcpyn((LPTSTR)lpDisplayDevice->DeviceName,TEXT("DISPLAY"),(sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
lstrcpyn((LPTSTR)lpDisplayDevice->DeviceString,TEXT("DISPLAY"),(sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)));
#endif
lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE;
return TRUE;
}
#undef xPRIMARY_MONITOR
#undef COMPILE_MULTIMON_STUBS
#else
extern int WINAPI xGetSystemMetrics(int);
extern HMONITOR WINAPI xMonitorFromWindow(HWND,DWORD);
extern HMONITOR WINAPI xMonitorFromRect(LPCRECT,DWORD);
extern HMONITOR WINAPI xMonitorFromPoint(POINT,DWORD);
extern WINBOOL WINAPI xGetMonitorInfo(HMONITOR,LPMONITORINFO);
extern WINBOOL WINAPI xEnumDisplayMonitors(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
extern WINBOOL WINAPI xEnumDisplayDevices(PVOID,DWORD,PDISPLAY_DEVICE,DWORD);
#endif
#define GetSystemMetrics xGetSystemMetrics
#define MonitorFromWindow xMonitorFromWindow
#define MonitorFromRect xMonitorFromRect
#define MonitorFromPoint xMonitorFromPoint
#define GetMonitorInfo xGetMonitorInfo
#define EnumDisplayMonitors xEnumDisplayMonitors
#define EnumDisplayDevices xEnumDisplayDevices
#ifdef __cplusplus
}
#endif