multimon.h 11 KB

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