Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 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_USE_SECURE_CRT
155
#if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L
156
#define _MULTIMON_USE_SECURE_CRT 1
157
#else
158
#define _MULTIMON_USE_SECURE_CRT 0
159
#endif
160
#endif
161
 
162
#ifndef MULTIMON_FNS_DEFINED
163
 
164
int      (WINAPI* g_pfnGetSystemMetrics)(int) = NULL;
165
HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, DWORD) = NULL;
166
HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, DWORD) = NULL;
167
HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, DWORD) = NULL;
168
BOOL     (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;
169
BOOL     (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM) = NULL;
170
BOOL     (WINAPI* g_pfnEnumDisplayDevices)(PVOID, DWORD, PDISPLAY_DEVICE,DWORD) = NULL;
171
BOOL     g_fMultiMonInitDone = FALSE;
172
BOOL     g_fMultimonPlatformNT = FALSE;
173
 
174
#endif
175
 
176
BOOL IsPlatformNT()
177
{
178
    OSVERSIONINFOA osvi = {0};
179
    osvi.dwOSVersionInfoSize = sizeof(osvi);
180
    GetVersionExA((OSVERSIONINFOA*)&osvi);
181
    return (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId);    
182
}
183
 
184
BOOL InitMultipleMonitorStubs(void)
185
{
186
    HMODULE hUser32;
187
    if (g_fMultiMonInitDone)
188
    {
189
        return g_pfnGetMonitorInfo != NULL;
190
    }
191
 
192
    g_fMultimonPlatformNT = IsPlatformNT();
193
    hUser32 = GetModuleHandle(TEXT("USER32"));
194
    if (hUser32 &&
195
        (*(FARPROC*)&g_pfnGetSystemMetrics    = GetProcAddress(hUser32,"GetSystemMetrics")) != NULL &&
196
        (*(FARPROC*)&g_pfnMonitorFromWindow   = GetProcAddress(hUser32,"MonitorFromWindow")) != NULL &&
197
        (*(FARPROC*)&g_pfnMonitorFromRect     = GetProcAddress(hUser32,"MonitorFromRect")) != NULL &&
198
        (*(FARPROC*)&g_pfnMonitorFromPoint    = GetProcAddress(hUser32,"MonitorFromPoint")) != NULL &&
199
        (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) != NULL &&
200
#ifdef UNICODE
201
        (*(FARPROC*)&g_pfnEnumDisplayDevices  = GetProcAddress(hUser32,"EnumDisplayDevicesW")) != NULL &&
202
        (*(FARPROC*)&g_pfnGetMonitorInfo      = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfoW") :
203
                                                GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL
204
#else
205
        (*(FARPROC*)&g_pfnGetMonitorInfo      = GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL &&
206
        (*(FARPROC*)&g_pfnEnumDisplayDevices  = GetProcAddress(hUser32,"EnumDisplayDevicesA")) != NULL
207
#endif
208
    ) {
209
        g_fMultiMonInitDone = TRUE;
210
        return TRUE;
211
    }
212
    else
213
    {
214
        g_pfnGetSystemMetrics    = NULL;
215
        g_pfnMonitorFromWindow   = NULL;
216
        g_pfnMonitorFromRect     = NULL;
217
        g_pfnMonitorFromPoint    = NULL;
218
        g_pfnGetMonitorInfo      = NULL;
219
        g_pfnEnumDisplayMonitors = NULL;
220
        g_pfnEnumDisplayDevices  = NULL;
221
 
222
        g_fMultiMonInitDone = TRUE;
223
        return FALSE;
224
    }
225
}
226
 
227
//-----------------------------------------------------------------------------
228
//
229
// fake implementations of Monitor APIs that work with the primary display
230
// no special parameter validation is made since these run in client code
231
//
232
//-----------------------------------------------------------------------------
233
 
234
int WINAPI
235
xGetSystemMetrics(int nIndex)
236
{
237
    if (InitMultipleMonitorStubs())
238
        return g_pfnGetSystemMetrics(nIndex);
239
 
240
    switch (nIndex)
241
    {
242
    case SM_CMONITORS:
243
    case SM_SAMEDISPLAYFORMAT:
244
        return 1;
245
 
246
    case SM_XVIRTUALSCREEN:
247
    case SM_YVIRTUALSCREEN:
248
        return 0;
249
 
250
    case SM_CXVIRTUALSCREEN:
251
        nIndex = SM_CXSCREEN;
252
        break;
253
 
254
    case SM_CYVIRTUALSCREEN:
255
        nIndex = SM_CYSCREEN;
256
        break;
257
    }
258
 
259
    return GetSystemMetrics(nIndex);
260
}
261
 
262
#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
263
 
264
HMONITOR WINAPI
265
xMonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
266
{
267
    if (InitMultipleMonitorStubs())
268
        return g_pfnMonitorFromPoint(ptScreenCoords, dwFlags);
269
 
270
    if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
271
        ((ptScreenCoords.x >= 0) &&
272
        (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
273
        (ptScreenCoords.y >= 0) &&
274
        (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
275
    {
276
        return xPRIMARY_MONITOR;
277
    }
278
 
279
    return NULL;
280
}
281
 
282
HMONITOR WINAPI
283
xMonitorFromRect(LPCRECT lprcScreenCoords, DWORD dwFlags)
284
{
285
    if (InitMultipleMonitorStubs())
286
        return g_pfnMonitorFromRect(lprcScreenCoords, dwFlags);
287
 
288
    if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
289
        ((lprcScreenCoords->right > 0) &&
290
        (lprcScreenCoords->bottom > 0) &&
291
        (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
292
        (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
293
    {
294
        return xPRIMARY_MONITOR;
295
    }
296
 
297
    return NULL;
298
}
299
 
300
HMONITOR WINAPI
301
xMonitorFromWindow(HWND hWnd, DWORD dwFlags)
302
{
303
    WINDOWPLACEMENT wp;
304
 
305
    if (InitMultipleMonitorStubs())
306
        return g_pfnMonitorFromWindow(hWnd, dwFlags);
307
 
308
    if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
309
        return xPRIMARY_MONITOR;
310
 
311
    if (IsIconic(hWnd) ?
312
            GetWindowPlacement(hWnd, &wp) :
313
            GetWindowRect(hWnd, &wp.rcNormalPosition)) {
314
 
315
        return xMonitorFromRect(&wp.rcNormalPosition, dwFlags);
316
    }
317
 
318
    return NULL;
319
}
320
 
321
BOOL WINAPI
322
xGetMonitorInfo(HMONITOR hMonitor, __inout LPMONITORINFO lpMonitorInfo)
323
{
324
    RECT rcWork;
325
 
326
    if (InitMultipleMonitorStubs())
327
    {
328
        BOOL f = g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
329
#ifdef UNICODE
330
        if (f && !g_fMultimonPlatformNT && (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)))
331
        {
332
            MultiByteToWideChar(CP_ACP, 0,
333
                (LPSTR)((MONITORINFOEX*)lpMonitorInfo)->szDevice, -1,
334
                ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
335
        }
336
#endif
337
        return f;
338
    }
339
 
340
    if ((hMonitor == xPRIMARY_MONITOR) &&
341
        lpMonitorInfo &&
342
        (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
343
        SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
344
    {
345
        lpMonitorInfo->rcMonitor.left = 0;
346
        lpMonitorInfo->rcMonitor.top  = 0;
347
        lpMonitorInfo->rcMonitor.right  = GetSystemMetrics(SM_CXSCREEN);
348
        lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
349
        lpMonitorInfo->rcWork = rcWork;
350
        lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
351
 
352
        if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
353
        {
354
#ifdef UNICODE
355
            MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
356
#else // UNICODE
357
#if _MULTIMON_USE_SECURE_CRT
358
            strncpy_s(((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)) - 1);
359
#else
360
            lstrcpyn(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"), (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
361
#endif // _MULTIMON_USE_SECURE_CRT
362
#endif // UNICODE
363
        }
364
 
365
        return TRUE;
366
    }
367
 
368
    return FALSE;
369
}
370
 
371
BOOL WINAPI
372
xEnumDisplayMonitors(
373
        HDC             hdcOptionalForPainting,
374
        LPCRECT         lprcEnumMonitorsThatIntersect,
375
        MONITORENUMPROC lpfnEnumProc,
376
        LPARAM          dwData)
377
{
378
    RECT rcLimit;
379
 
380
    if (InitMultipleMonitorStubs()) {
381
        return g_pfnEnumDisplayMonitors(
382
                hdcOptionalForPainting,
383
                lprcEnumMonitorsThatIntersect,
384
                lpfnEnumProc,
385
                dwData);
386
    }
387
 
388
    if (!lpfnEnumProc)
389
        return FALSE;
390
 
391
    rcLimit.left   = 0;
392
    rcLimit.top    = 0;
393
    rcLimit.right  = GetSystemMetrics(SM_CXSCREEN);
394
    rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
395
 
396
    if (hdcOptionalForPainting)
397
    {
398
        RECT    rcClip;
399
        POINT   ptOrg;
400
 
401
        switch (GetClipBox(hdcOptionalForPainting, &rcClip))
402
        {
403
        default:
404
            if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
405
                return FALSE;
406
 
407
            OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
408
            if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
409
                (!lprcEnumMonitorsThatIntersect ||
410
                     IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
411
 
412
                break;
413
            }
414
            //fall thru
415
        case NULLREGION:
416
             return TRUE;
417
        case ERROR:
418
             return FALSE;
419
        }
420
    } else {
421
        if (    lprcEnumMonitorsThatIntersect &&
422
                !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
423
 
424
            return TRUE;
425
        }
426
    }
427
 
428
    return lpfnEnumProc(
429
            xPRIMARY_MONITOR,
430
            hdcOptionalForPainting,
431
            &rcLimit,
432
            dwData);
433
}
434
 
435
BOOL WINAPI
436
xEnumDisplayDevices(
437
    PVOID Unused,
438
    DWORD iDevNum,
439
    __inout PDISPLAY_DEVICE lpDisplayDevice,
440
    DWORD dwFlags)
441
{
442
    if (InitMultipleMonitorStubs())
443
        return g_pfnEnumDisplayDevices(Unused, iDevNum, lpDisplayDevice, dwFlags);
444
 
445
    if (Unused != NULL)
446
        return FALSE;
447
 
448
    if (iDevNum != 0)
449
        return FALSE;
450
 
451
    if (lpDisplayDevice == NULL || lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
452
        return FALSE;
453
 
454
#ifdef UNICODE
455
    MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
456
    MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)));
457
#else // UNICODE
458
#if _MULTIMON_USE_SECURE_CRT
459
    strncpy_s((LPTSTR)lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)) - 1);
460
    strncpy_s((LPTSTR)lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)) - 1);
461
#else
462
    lstrcpyn((LPTSTR)lpDisplayDevice->DeviceName,   TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
463
    lstrcpyn((LPTSTR)lpDisplayDevice->DeviceString, TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)));
464
#endif // _MULTIMON_USE_SECURE_CRT
465
#endif // UNICODE
466
 
467
    lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE;
468
 
469
    return TRUE;
470
}
471
 
472
#undef xPRIMARY_MONITOR
473
#undef COMPILE_MULTIMON_STUBS
474
 
475
#else   // COMPILE_MULTIMON_STUBS
476
 
477
extern int  WINAPI xGetSystemMetrics(int);
478
extern HMONITOR WINAPI xMonitorFromWindow(HWND, DWORD);
479
extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, DWORD);
480
extern HMONITOR WINAPI xMonitorFromPoint(POINT, DWORD);
481
extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
482
extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
483
extern BOOL WINAPI xEnumDisplayDevices(PVOID, DWORD, PDISPLAY_DEVICE, DWORD);
484
 
485
#endif  // COMPILE_MULTIMON_STUBS
486
 
487
//
488
// build defines that replace the regular APIs with our versions
489
//
490
#define GetSystemMetrics    xGetSystemMetrics
491
#define MonitorFromWindow   xMonitorFromWindow
492
#define MonitorFromRect     xMonitorFromRect
493
#define MonitorFromPoint    xMonitorFromPoint
494
#define GetMonitorInfo      xGetMonitorInfo
495
#define EnumDisplayMonitors xEnumDisplayMonitors
496
#define EnumDisplayDevices  xEnumDisplayDevices
497
 
498
#ifdef __cplusplus
499
}
500
#endif  // __cplusplus
501