comparison lib/legacy_dx/multimon.h @ 0:9c0607679772

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