1 /** 2 * This file has no copyright assigned and is placed in the Public Domain. 3 * This file is part of the mingw-w64 runtime package. 4 * No warranty is given; refer to the file DISCLAIMER.PD within this package. 5 */ 6 7 #include <_mingw_unicode.h> 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 #ifndef SM_CMONITORS 14 #define SM_XVIRTUALSCREEN 76 15 #define SM_YVIRTUALSCREEN 77 16 #define SM_CXVIRTUALSCREEN 78 17 #define SM_CYVIRTUALSCREEN 79 18 #define SM_CMONITORS 80 19 #define SM_SAMEDISPLAYFORMAT 81 20 21 #define MONITOR_DEFAULTTONULL 0x00000000 22 #define MONITOR_DEFAULTTOPRIMARY 0x00000001 23 #define MONITOR_DEFAULTTONEAREST 0x00000002 24 25 #define MONITORINFOF_PRIMARY 0x00000001 26 27 typedef struct tagMONITORINFO { 28 DWORD cbSize; 29 RECT rcMonitor; 30 RECT rcWork; 31 DWORD dwFlags; 32 } MONITORINFO,*LPMONITORINFO; 33 34 #ifndef CCHDEVICENAME 35 #define CCHDEVICENAME 32 36 #endif 37 38 #ifdef __cplusplus 39 typedef struct tagMONITORINFOEXA : public tagMONITORINFO { 40 CHAR szDevice[CCHDEVICENAME]; 41 } MONITORINFOEXA,*LPMONITORINFOEXA; 42 43 typedef struct tagMONITORINFOEXW : public tagMONITORINFO { 44 WCHAR szDevice[CCHDEVICENAME]; 45 } MONITORINFOEXW,*LPMONITORINFOEXW; 46 47 __MINGW_TYPEDEF_AW(MONITORINFOEX) 48 __MINGW_TYPEDEF_AW(LPMONITORINFOEX) 49 #else 50 typedef struct tagMONITORINFOEXA { 51 MONITORINFO; 52 CHAR szDevice[CCHDEVICENAME]; 53 } MONITORINFOEXA,*LPMONITORINFOEXA; 54 55 typedef struct tagMONITORINFOEXW { 56 MONITORINFO; 57 WCHAR szDevice[CCHDEVICENAME]; 58 } MONITORINFOEXW,*LPMONITORINFOEXW; 59 __MINGW_TYPEDEF_AW(MONITORINFOEX) 60 __MINGW_TYPEDEF_AW(LPMONITORINFOEX) 61 #endif 62 63 typedef WINBOOL (CALLBACK *MONITORENUMPROC)(HMONITOR,HDC,LPRECT,LPARAM); 64 65 #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 66 typedef struct _DISPLAY_DEVICEA { 67 DWORD cb; 68 CHAR DeviceName[32]; 69 CHAR DeviceString[128]; 70 DWORD StateFlags; 71 CHAR DeviceID[128]; 72 CHAR DeviceKey[128]; 73 } DISPLAY_DEVICEA,*PDISPLAY_DEVICEA,*LPDISPLAY_DEVICEA; 74 75 typedef struct _DISPLAY_DEVICEW { 76 DWORD cb; 77 WCHAR DeviceName[32]; 78 WCHAR DeviceString[128]; 79 DWORD StateFlags; 80 WCHAR DeviceID[128]; 81 WCHAR DeviceKey[128]; 82 } DISPLAY_DEVICEW,*PDISPLAY_DEVICEW,*LPDISPLAY_DEVICEW; 83 84 __MINGW_TYPEDEF_AW(DISPLAY_DEVICE) 85 __MINGW_TYPEDEF_AW(PDISPLAY_DEVICE) 86 __MINGW_TYPEDEF_AW(LPDISPLAY_DEVICE) 87 88 #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001 89 #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002 90 #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004 91 #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008 92 #define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010 93 #endif 94 #endif 95 96 #undef GetMonitorInfo 97 #undef GetSystemMetrics 98 #undef MonitorFromWindow 99 #undef MonitorFromRect 100 #undef MonitorFromPoint 101 #undef EnumDisplayMonitors 102 #undef EnumDisplayDevices 103 104 #ifdef COMPILE_MULTIMON_STUBS 105 106 #ifndef MULTIMON_FNS_DEFINED 107 int (WINAPI *g_pfnGetSystemMetrics)(int) = NULL; 108 HMONITOR (WINAPI *g_pfnMonitorFromWindow)(HWND,DWORD) = NULL; 109 HMONITOR (WINAPI *g_pfnMonitorFromRect)(LPCRECT,DWORD) = NULL; 110 HMONITOR (WINAPI *g_pfnMonitorFromPoint)(POINT,DWORD) = NULL; 111 WINBOOL (WINAPI *g_pfnGetMonitorInfo)(HMONITOR,LPMONITORINFO) = NULL; 112 WINBOOL (WINAPI *g_pfnEnumDisplayMonitors)(HDC,LPCRECT,MONITORENUMPROC,LPARAM) = NULL; 113 WINBOOL (WINAPI *g_pfnEnumDisplayDevices)(PVOID,DWORD,PDISPLAY_DEVICE,DWORD) = NULL; 114 WINBOOL g_fMultiMonInitDone = FALSE; 115 WINBOOL g_fMultimonPlatformNT = FALSE; 116 #endif 117 118 WINBOOL IsPlatformNT() { 119 OSVERSIONINFOA osvi = {0}; 120 osvi.dwOSVersionInfoSize = sizeof(osvi); 121 GetVersionExA((OSVERSIONINFOA*)&osvi); 122 return (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId); 123 } 124 125 WINBOOL InitMultipleMonitorStubs(void) { 126 HMODULE hUser32; 127 if(g_fMultiMonInitDone) return g_pfnGetMonitorInfo!=NULL; 128 g_fMultimonPlatformNT = IsPlatformNT(); 129 hUser32 = GetModuleHandle(TEXT("USER32")); 130 if(hUser32 && 131 (*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics"))!=NULL && 132 (*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow"))!=NULL && 133 (*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect"))!=NULL && 134 (*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint"))!=NULL && 135 (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors"))!=NULL && 136 (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevices" __MINGW_PROCNAMEEXT_AW))!=NULL && 137 (*(FARPROC*)&g_pfnGetMonitorInfo = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfo" __MINGW_PROCNAMEEXT_AW) : 138 GetProcAddress(hUser32,"GetMonitorInfoA"))!=NULL 139 ) { 140 g_fMultiMonInitDone = TRUE; 141 return TRUE; 142 } else { 143 g_pfnGetSystemMetrics = NULL; 144 g_pfnMonitorFromWindow = NULL; 145 g_pfnMonitorFromRect = NULL; 146 g_pfnMonitorFromPoint = NULL; 147 g_pfnGetMonitorInfo = NULL; 148 g_pfnEnumDisplayMonitors = NULL; 149 g_pfnEnumDisplayDevices = NULL; 150 g_fMultiMonInitDone = TRUE; 151 return FALSE; 152 } 153 } 154 155 int WINAPI xGetSystemMetrics(int nIndex) { 156 if(InitMultipleMonitorStubs()) return g_pfnGetSystemMetrics(nIndex); 157 switch(nIndex) { 158 case SM_CMONITORS: 159 case SM_SAMEDISPLAYFORMAT: 160 return 1; 161 case SM_XVIRTUALSCREEN: 162 case SM_YVIRTUALSCREEN: 163 return 0; 164 case SM_CXVIRTUALSCREEN: 165 nIndex = SM_CXSCREEN; 166 break; 167 case SM_CYVIRTUALSCREEN: 168 nIndex = SM_CYSCREEN; 169 break; 170 } 171 return GetSystemMetrics(nIndex); 172 } 173 174 #define xPRIMARY_MONITOR ((HMONITOR)0x12340042) 175 176 HMONITOR WINAPI xMonitorFromPoint(POINT ptScreenCoords,DWORD dwFlags) { 177 if(InitMultipleMonitorStubs()) return g_pfnMonitorFromPoint(ptScreenCoords,dwFlags); 178 if((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) || 179 ((ptScreenCoords.x >= 0) && 180 (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) && 181 (ptScreenCoords.y >= 0) && 182 (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN)))) 183 { 184 return xPRIMARY_MONITOR; 185 } 186 return NULL; 187 } 188 189 HMONITOR WINAPI xMonitorFromRect(LPCRECT lprcScreenCoords,DWORD dwFlags) 190 { 191 if(InitMultipleMonitorStubs()) return g_pfnMonitorFromRect(lprcScreenCoords,dwFlags); 192 if((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) || 193 ((lprcScreenCoords->right > 0) && 194 (lprcScreenCoords->bottom > 0) && 195 (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) && 196 (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN)))) 197 { 198 return xPRIMARY_MONITOR; 199 } 200 return NULL; 201 } 202 203 HMONITOR WINAPI xMonitorFromWindow(HWND hWnd,DWORD dwFlags) { 204 WINDOWPLACEMENT wp; 205 if(InitMultipleMonitorStubs()) return g_pfnMonitorFromWindow(hWnd,dwFlags); 206 if(dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) return xPRIMARY_MONITOR; 207 if(IsIconic(hWnd) ? GetWindowPlacement(hWnd,&wp) : GetWindowRect(hWnd,&wp.rcNormalPosition)) return xMonitorFromRect(&wp.rcNormalPosition,dwFlags); 208 return NULL; 209 } 210 211 WINBOOL WINAPI xGetMonitorInfo(HMONITOR hMonitor,LPMONITORINFO lpMonitorInfo) { 212 RECT rcWork; 213 if(InitMultipleMonitorStubs()) { 214 WINBOOL f = g_pfnGetMonitorInfo(hMonitor,lpMonitorInfo); 215 #if defined(UNICODE) 216 if(f && !g_fMultimonPlatformNT && (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))) { 217 MultiByteToWideChar(CP_ACP,0,(LPSTR)((MONITORINFOEX*)lpMonitorInfo)->szDevice,-1,((MONITORINFOEX*)lpMonitorInfo)->szDevice,(sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR))); 218 } 219 #endif 220 return f; 221 } 222 if((hMonitor==xPRIMARY_MONITOR) && 223 lpMonitorInfo && 224 (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) && 225 SystemParametersInfoA(SPI_GETWORKAREA,0,&rcWork,0)) 226 { 227 lpMonitorInfo->rcMonitor.left = 0; 228 lpMonitorInfo->rcMonitor.top = 0; 229 lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN); 230 lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN); 231 lpMonitorInfo->rcWork = rcWork; 232 lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY; 233 if(lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)) { 234 #if defined(UNICODE) 235 MultiByteToWideChar(CP_ACP,0,"DISPLAY",-1,((MONITORINFOEX*)lpMonitorInfo)->szDevice,(sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR))); 236 #else 237 lstrcpyn(((MONITORINFOEX*)lpMonitorInfo)->szDevice,TEXT("DISPLAY"),(sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR))); 238 #endif 239 } 240 241 return TRUE; 242 } 243 244 return FALSE; 245 } 246 247 WINBOOL WINAPI 248 xEnumDisplayMonitors(HDC hdcOptionalForPainting,LPCRECT lprcEnumMonitorsThatIntersect,MONITORENUMPROC lpfnEnumProc,LPARAM dwData) 249 { 250 RECT rcLimit; 251 252 if(InitMultipleMonitorStubs()) { 253 return g_pfnEnumDisplayMonitors(hdcOptionalForPainting,lprcEnumMonitorsThatIntersect,lpfnEnumProc,dwData); 254 } 255 256 if(!lpfnEnumProc) 257 return FALSE; 258 259 rcLimit.left = 0; 260 rcLimit.top = 0; 261 rcLimit.right = GetSystemMetrics(SM_CXSCREEN); 262 rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN); 263 264 if(hdcOptionalForPainting) 265 { 266 RECT rcClip; 267 POINT ptOrg; 268 269 switch (GetClipBox(hdcOptionalForPainting,&rcClip)) 270 { 271 default: 272 if(!GetDCOrgEx(hdcOptionalForPainting,&ptOrg)) 273 return FALSE; 274 275 OffsetRect(&rcLimit,-ptOrg.x,-ptOrg.y); 276 if(IntersectRect(&rcLimit,&rcLimit,&rcClip) && 277 (!lprcEnumMonitorsThatIntersect || 278 IntersectRect(&rcLimit,&rcLimit,lprcEnumMonitorsThatIntersect))) { 279 280 break; 281 } 282 283 case NULLREGION: 284 return TRUE; 285 case ERROR: 286 return FALSE; 287 } 288 } else { 289 if(lprcEnumMonitorsThatIntersect && 290 !IntersectRect(&rcLimit,&rcLimit,lprcEnumMonitorsThatIntersect)) { 291 292 return TRUE; 293 } 294 } 295 296 return lpfnEnumProc(xPRIMARY_MONITOR,hdcOptionalForPainting,&rcLimit,dwData); 297 } 298 299 WINBOOL WINAPI 300 xEnumDisplayDevices(PVOID Unused,DWORD iDevNum,PDISPLAY_DEVICE lpDisplayDevice,DWORD dwFlags) 301 { 302 if(InitMultipleMonitorStubs()) 303 return g_pfnEnumDisplayDevices(Unused,iDevNum,lpDisplayDevice,dwFlags); 304 305 if(Unused!=NULL) 306 return FALSE; 307 308 if(iDevNum!=0) 309 return FALSE; 310 311 if(!lpDisplayDevice || lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE)) 312 return FALSE; 313 314 #if defined(UNICODE) 315 MultiByteToWideChar(CP_ACP,0,"DISPLAY",-1,lpDisplayDevice->DeviceName,(sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR))); 316 MultiByteToWideChar(CP_ACP,0,"DISPLAY",-1,lpDisplayDevice->DeviceString,(sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR))); 317 #else 318 lstrcpyn((LPTSTR)lpDisplayDevice->DeviceName,TEXT("DISPLAY"),(sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR))); 319 lstrcpyn((LPTSTR)lpDisplayDevice->DeviceString,TEXT("DISPLAY"),(sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR))); 320 #endif 321 lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE; 322 return TRUE; 323 } 324 325 #undef xPRIMARY_MONITOR 326 #undef COMPILE_MULTIMON_STUBS 327 #else 328 329 extern int WINAPI xGetSystemMetrics(int); 330 extern HMONITOR WINAPI xMonitorFromWindow(HWND,DWORD); 331 extern HMONITOR WINAPI xMonitorFromRect(LPCRECT,DWORD); 332 extern HMONITOR WINAPI xMonitorFromPoint(POINT,DWORD); 333 extern WINBOOL WINAPI xGetMonitorInfo(HMONITOR,LPMONITORINFO); 334 extern WINBOOL WINAPI xEnumDisplayMonitors(HDC,LPCRECT,MONITORENUMPROC,LPARAM); 335 extern WINBOOL WINAPI xEnumDisplayDevices(PVOID,DWORD,PDISPLAY_DEVICE,DWORD); 336 #endif 337 338 #define GetSystemMetrics xGetSystemMetrics 339 #define MonitorFromWindow xMonitorFromWindow 340 #define MonitorFromRect xMonitorFromRect 341 #define MonitorFromPoint xMonitorFromPoint 342 #define GetMonitorInfo xGetMonitorInfo 343 #define EnumDisplayMonitors xEnumDisplayMonitors 344 #define EnumDisplayDevices xEnumDisplayDevices 345 346 #ifdef __cplusplus 347 } 348 #endif 349