Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

484 lines
14 KiB

  1. //=============================================================================
  2. //
  3. // multimon.h -- Stub module that fakes multiple monitor apis on Win32 OSes
  4. // without them.
  5. //
  6. // By using this header your code will get back default values from
  7. // GetSystemMetrics() for new metrics, and the new multimonitor APIs
  8. // will act like only one display is present on a Win32 OS without
  9. // multimonitor APIs.
  10. //
  11. // Exactly one source must include this with COMPILE_MULTIMON_STUBS defined.
  12. //
  13. // Copyright (c) Microsoft Corporation. All rights reserved.
  14. //
  15. //=============================================================================
  16. #ifdef __cplusplus
  17. extern "C" { // Assume C declarations for C++
  18. #endif // __cplusplus
  19. //
  20. // If we are building with Win95/NT4 headers, we need to declare
  21. // the multimonitor-related metrics and APIs ourselves.
  22. //
  23. #ifndef SM_CMONITORS
  24. #define SM_XVIRTUALSCREEN 76
  25. #define SM_YVIRTUALSCREEN 77
  26. #define SM_CXVIRTUALSCREEN 78
  27. #define SM_CYVIRTUALSCREEN 79
  28. #define SM_CMONITORS 80
  29. #define SM_SAMEDISPLAYFORMAT 81
  30. // HMONITOR is already declared if WINVER >= 0x0500 in windef.h
  31. // This is for components built with an older version number.
  32. //
  33. #if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
  34. DECLARE_HANDLE(HMONITOR);
  35. #define HMONITOR_DECLARED
  36. #endif
  37. #define MONITOR_DEFAULTTONULL 0x00000000
  38. #define MONITOR_DEFAULTTOPRIMARY 0x00000001
  39. #define MONITOR_DEFAULTTONEAREST 0x00000002
  40. #define MONITORINFOF_PRIMARY 0x00000001
  41. typedef struct tagMONITORINFO
  42. {
  43. DWORD cbSize;
  44. RECT rcMonitor;
  45. RECT rcWork;
  46. DWORD dwFlags;
  47. } MONITORINFO, *LPMONITORINFO;
  48. #ifndef CCHDEVICENAME
  49. #define CCHDEVICENAME 32
  50. #endif
  51. #ifdef __cplusplus
  52. typedef struct tagMONITORINFOEXA : public tagMONITORINFO
  53. {
  54. CHAR szDevice[CCHDEVICENAME];
  55. } MONITORINFOEXA, *LPMONITORINFOEXA;
  56. typedef struct tagMONITORINFOEXW : public tagMONITORINFO
  57. {
  58. WCHAR szDevice[CCHDEVICENAME];
  59. } MONITORINFOEXW, *LPMONITORINFOEXW;
  60. #ifdef UNICODE
  61. typedef MONITORINFOEXW MONITORINFOEX;
  62. typedef LPMONITORINFOEXW LPMONITORINFOEX;
  63. #else
  64. typedef MONITORINFOEXA MONITORINFOEX;
  65. typedef LPMONITORINFOEXA LPMONITORINFOEX;
  66. #endif // UNICODE
  67. #else // ndef __cplusplus
  68. typedef struct tagMONITORINFOEXA
  69. {
  70. MONITORINFO;
  71. CHAR szDevice[CCHDEVICENAME];
  72. } MONITORINFOEXA, *LPMONITORINFOEXA;
  73. typedef struct tagMONITORINFOEXW
  74. {
  75. MONITORINFO;
  76. WCHAR szDevice[CCHDEVICENAME];
  77. } MONITORINFOEXW, *LPMONITORINFOEXW;
  78. #ifdef UNICODE
  79. typedef MONITORINFOEXW MONITORINFOEX;
  80. typedef LPMONITORINFOEXW LPMONITORINFOEX;
  81. #else
  82. typedef MONITORINFOEXA MONITORINFOEX;
  83. typedef LPMONITORINFOEXA LPMONITORINFOEX;
  84. #endif // UNICODE
  85. #endif
  86. typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
  87. #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
  88. typedef struct _DISPLAY_DEVICEA {
  89. DWORD cb;
  90. CHAR DeviceName[32];
  91. CHAR DeviceString[128];
  92. DWORD StateFlags;
  93. CHAR DeviceID[128];
  94. CHAR DeviceKey[128];
  95. } DISPLAY_DEVICEA, *PDISPLAY_DEVICEA, *LPDISPLAY_DEVICEA;
  96. typedef struct _DISPLAY_DEVICEW {
  97. DWORD cb;
  98. WCHAR DeviceName[32];
  99. WCHAR DeviceString[128];
  100. DWORD StateFlags;
  101. WCHAR DeviceID[128];
  102. WCHAR DeviceKey[128];
  103. } DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW;
  104. #ifdef UNICODE
  105. typedef DISPLAY_DEVICEW DISPLAY_DEVICE;
  106. typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE;
  107. typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE;
  108. #else
  109. typedef DISPLAY_DEVICEA DISPLAY_DEVICE;
  110. typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE;
  111. typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE;
  112. #endif // UNICODE
  113. #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
  114. #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
  115. #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
  116. #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
  117. #define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010
  118. #endif
  119. #endif // SM_CMONITORS
  120. #undef GetMonitorInfo
  121. #undef GetSystemMetrics
  122. #undef MonitorFromWindow
  123. #undef MonitorFromRect
  124. #undef MonitorFromPoint
  125. #undef EnumDisplayMonitors
  126. #undef EnumDisplayDevices
  127. //
  128. // Define COMPILE_MULTIMON_STUBS to compile the stubs;
  129. // otherwise, you get the declarations.
  130. //
  131. #ifdef COMPILE_MULTIMON_STUBS
  132. //-----------------------------------------------------------------------------
  133. //
  134. // Implement the API stubs.
  135. //
  136. //-----------------------------------------------------------------------------
  137. #ifndef MULTIMON_FNS_DEFINED
  138. int (WINAPI* g_pfnGetSystemMetrics)(int) = NULL;
  139. HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, DWORD) = NULL;
  140. HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, DWORD) = NULL;
  141. HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, DWORD) = NULL;
  142. BOOL (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;
  143. BOOL (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM) = NULL;
  144. BOOL (WINAPI* g_pfnEnumDisplayDevices)(PVOID, DWORD, PDISPLAY_DEVICE,DWORD) = NULL;
  145. BOOL g_fMultiMonInitDone = FALSE;
  146. BOOL g_fMultimonPlatformNT = FALSE;
  147. #endif
  148. BOOL IsPlatformNT()
  149. {
  150. OSVERSIONINFOA osvi = {0};
  151. osvi.dwOSVersionInfoSize = sizeof(osvi);
  152. GetVersionExA((OSVERSIONINFOA*)&osvi);
  153. return (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId);
  154. }
  155. BOOL InitMultipleMonitorStubs(void)
  156. {
  157. HMODULE hUser32;
  158. if (g_fMultiMonInitDone)
  159. {
  160. return g_pfnGetMonitorInfo != NULL;
  161. }
  162. g_fMultimonPlatformNT = IsPlatformNT();
  163. hUser32 = GetModuleHandle(TEXT("USER32"));
  164. if (hUser32 &&
  165. (*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics")) != NULL &&
  166. (*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow")) != NULL &&
  167. (*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect")) != NULL &&
  168. (*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint")) != NULL &&
  169. (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) != NULL &&
  170. #ifdef UNICODE
  171. (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesW")) != NULL &&
  172. (*(FARPROC*)&g_pfnGetMonitorInfo = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfoW") :
  173. GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL
  174. #else
  175. (*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL &&
  176. (*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesA")) != NULL
  177. #endif
  178. ) {
  179. g_fMultiMonInitDone = TRUE;
  180. return TRUE;
  181. }
  182. else
  183. {
  184. g_pfnGetSystemMetrics = NULL;
  185. g_pfnMonitorFromWindow = NULL;
  186. g_pfnMonitorFromRect = NULL;
  187. g_pfnMonitorFromPoint = NULL;
  188. g_pfnGetMonitorInfo = NULL;
  189. g_pfnEnumDisplayMonitors = NULL;
  190. g_pfnEnumDisplayDevices = NULL;
  191. g_fMultiMonInitDone = TRUE;
  192. return FALSE;
  193. }
  194. }
  195. //-----------------------------------------------------------------------------
  196. //
  197. // fake implementations of Monitor APIs that work with the primary display
  198. // no special parameter validation is made since these run in client code
  199. //
  200. //-----------------------------------------------------------------------------
  201. int WINAPI
  202. xGetSystemMetrics(int nIndex)
  203. {
  204. if (InitMultipleMonitorStubs())
  205. return g_pfnGetSystemMetrics(nIndex);
  206. switch (nIndex)
  207. {
  208. case SM_CMONITORS:
  209. case SM_SAMEDISPLAYFORMAT:
  210. return 1;
  211. case SM_XVIRTUALSCREEN:
  212. case SM_YVIRTUALSCREEN:
  213. return 0;
  214. case SM_CXVIRTUALSCREEN:
  215. nIndex = SM_CXSCREEN;
  216. break;
  217. case SM_CYVIRTUALSCREEN:
  218. nIndex = SM_CYSCREEN;
  219. break;
  220. }
  221. return GetSystemMetrics(nIndex);
  222. }
  223. #define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
  224. HMONITOR WINAPI
  225. xMonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
  226. {
  227. if (InitMultipleMonitorStubs())
  228. return g_pfnMonitorFromPoint(ptScreenCoords, dwFlags);
  229. if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  230. ((ptScreenCoords.x >= 0) &&
  231. (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
  232. (ptScreenCoords.y >= 0) &&
  233. (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
  234. {
  235. return xPRIMARY_MONITOR;
  236. }
  237. return NULL;
  238. }
  239. HMONITOR WINAPI
  240. xMonitorFromRect(LPCRECT lprcScreenCoords, DWORD dwFlags)
  241. {
  242. if (InitMultipleMonitorStubs())
  243. return g_pfnMonitorFromRect(lprcScreenCoords, dwFlags);
  244. if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
  245. ((lprcScreenCoords->right > 0) &&
  246. (lprcScreenCoords->bottom > 0) &&
  247. (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
  248. (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
  249. {
  250. return xPRIMARY_MONITOR;
  251. }
  252. return NULL;
  253. }
  254. HMONITOR WINAPI
  255. xMonitorFromWindow(HWND hWnd, DWORD dwFlags)
  256. {
  257. WINDOWPLACEMENT wp;
  258. if (InitMultipleMonitorStubs())
  259. return g_pfnMonitorFromWindow(hWnd, dwFlags);
  260. if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
  261. return xPRIMARY_MONITOR;
  262. if (IsIconic(hWnd) ?
  263. GetWindowPlacement(hWnd, &wp) :
  264. GetWindowRect(hWnd, &wp.rcNormalPosition)) {
  265. return xMonitorFromRect(&wp.rcNormalPosition, dwFlags);
  266. }
  267. return NULL;
  268. }
  269. BOOL WINAPI
  270. xGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
  271. {
  272. RECT rcWork;
  273. if (InitMultipleMonitorStubs())
  274. {
  275. BOOL f = g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
  276. #ifdef UNICODE
  277. if (f && !g_fMultimonPlatformNT && (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)))
  278. {
  279. MultiByteToWideChar(CP_ACP, 0,
  280. (LPSTR)((MONITORINFOEX*)lpMonitorInfo)->szDevice, -1,
  281. ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
  282. }
  283. #endif
  284. return f;
  285. }
  286. if ((hMonitor == xPRIMARY_MONITOR) &&
  287. lpMonitorInfo &&
  288. (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
  289. SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
  290. {
  291. lpMonitorInfo->rcMonitor.left = 0;
  292. lpMonitorInfo->rcMonitor.top = 0;
  293. lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
  294. lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
  295. lpMonitorInfo->rcWork = rcWork;
  296. lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
  297. if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
  298. {
  299. #ifdef UNICODE
  300. MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
  301. #else // UNICODE
  302. lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"));
  303. #endif // UNICODE
  304. }
  305. return TRUE;
  306. }
  307. return FALSE;
  308. }
  309. BOOL WINAPI
  310. xEnumDisplayMonitors(
  311. HDC hdcOptionalForPainting,
  312. LPCRECT lprcEnumMonitorsThatIntersect,
  313. MONITORENUMPROC lpfnEnumProc,
  314. LPARAM dwData)
  315. {
  316. RECT rcLimit;
  317. if (InitMultipleMonitorStubs()) {
  318. return g_pfnEnumDisplayMonitors(
  319. hdcOptionalForPainting,
  320. lprcEnumMonitorsThatIntersect,
  321. lpfnEnumProc,
  322. dwData);
  323. }
  324. if (!lpfnEnumProc)
  325. return FALSE;
  326. rcLimit.left = 0;
  327. rcLimit.top = 0;
  328. rcLimit.right = GetSystemMetrics(SM_CXSCREEN);
  329. rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
  330. if (hdcOptionalForPainting)
  331. {
  332. RECT rcClip;
  333. POINT ptOrg;
  334. switch (GetClipBox(hdcOptionalForPainting, &rcClip))
  335. {
  336. default:
  337. if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
  338. return FALSE;
  339. OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
  340. if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
  341. (!lprcEnumMonitorsThatIntersect ||
  342. IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
  343. break;
  344. }
  345. //fall thru
  346. case NULLREGION:
  347. return TRUE;
  348. case ERROR:
  349. return FALSE;
  350. }
  351. } else {
  352. if ( lprcEnumMonitorsThatIntersect &&
  353. !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
  354. return TRUE;
  355. }
  356. }
  357. return lpfnEnumProc(
  358. xPRIMARY_MONITOR,
  359. hdcOptionalForPainting,
  360. &rcLimit,
  361. dwData);
  362. }
  363. BOOL WINAPI
  364. xEnumDisplayDevices(
  365. PVOID Unused,
  366. DWORD iDevNum,
  367. PDISPLAY_DEVICE lpDisplayDevice,
  368. DWORD dwFlags)
  369. {
  370. if (InitMultipleMonitorStubs())
  371. return g_pfnEnumDisplayDevices(Unused, iDevNum, lpDisplayDevice, dwFlags);
  372. if (Unused != NULL)
  373. return FALSE;
  374. if (iDevNum != 0)
  375. return FALSE;
  376. if (lpDisplayDevice == NULL || lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
  377. return FALSE;
  378. #ifdef UNICODE
  379. MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
  380. MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
  381. #else // UNICODE
  382. lstrcpy((LPTSTR)lpDisplayDevice->DeviceName, TEXT("DISPLAY"));
  383. lstrcpy((LPTSTR)lpDisplayDevice->DeviceString, TEXT("DISPLAY"));
  384. #endif // UNICODE
  385. lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE;
  386. return TRUE;
  387. }
  388. #undef xPRIMARY_MONITOR
  389. #undef COMPILE_MULTIMON_STUBS
  390. #else // COMPILE_MULTIMON_STUBS
  391. extern int WINAPI xGetSystemMetrics(int);
  392. extern HMONITOR WINAPI xMonitorFromWindow(HWND, DWORD);
  393. extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, DWORD);
  394. extern HMONITOR WINAPI xMonitorFromPoint(POINT, DWORD);
  395. extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
  396. extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
  397. extern BOOL WINAPI xEnumDisplayDevices(PVOID, DWORD, PDISPLAY_DEVICE, DWORD);
  398. #endif // COMPILE_MULTIMON_STUBS
  399. //
  400. // build defines that replace the regular APIs with our versions
  401. //
  402. #define GetSystemMetrics xGetSystemMetrics
  403. #define MonitorFromWindow xMonitorFromWindow
  404. #define MonitorFromRect xMonitorFromRect
  405. #define MonitorFromPoint xMonitorFromPoint
  406. #define GetMonitorInfo xGetMonitorInfo
  407. #define EnumDisplayMonitors xEnumDisplayMonitors
  408. #define EnumDisplayDevices xEnumDisplayDevices
  409. #ifdef __cplusplus
  410. }
  411. #endif // __cplusplus