/** * This file has no copyright assigned and is placed in the Public Domain. * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #include <_mingw_unicode.h> #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; __MINGW_TYPEDEF_AW(MONITORINFOEX) __MINGW_TYPEDEF_AW(LPMONITORINFOEX) #else typedef struct tagMONITORINFOEXA { MONITORINFO; CHAR szDevice[CCHDEVICENAME]; } MONITORINFOEXA,*LPMONITORINFOEXA; typedef struct tagMONITORINFOEXW { MONITORINFO; WCHAR szDevice[CCHDEVICENAME]; } MONITORINFOEXW,*LPMONITORINFOEXW; __MINGW_TYPEDEF_AW(MONITORINFOEX) __MINGW_TYPEDEF_AW(LPMONITORINFOEX) #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; __MINGW_TYPEDEF_AW(DISPLAY_DEVICE) __MINGW_TYPEDEF_AW(PDISPLAY_DEVICE) __MINGW_TYPEDEF_AW(LPDISPLAY_DEVICE) #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 && (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevices" __MINGW_PROCNAMEEXT_AW))!=NULL && (*(FARPROC*)&g_pfnGetMonitorInfo = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfo" __MINGW_PROCNAMEEXT_AW) : GetProcAddress(hUser32,"GetMonitorInfoA"))!=NULL ) { 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