]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/multimon.h
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / libs / multimon.h
1 #ifndef __MULTIMON_H\r
2 #define __MULTIMON_H\r
3 \r
4 #ifdef _WIN32\r
5 \r
6 //=============================================================================\r
7 //\r
8 // MULTIMON\r
9 // stub module that "stubs" multiple monitor APIs on pre-Memphis Win32 OSes\r
10 //\r
11 // By using this header your code will work unchanged on Win95,\r
12 // you will get back correct values from GetSystemMetrics() for new metrics\r
13 // and the new APIs will act like only one display is present.\r
14 //\r
15 // exactly one source must include this with COMPILE_MULTIMON_STUBS defined\r
16 //\r
17 //=============================================================================\r
18 \r
19 #ifdef __cplusplus\r
20 extern "C" {            /* Assume C declarations for C++ */\r
21 #endif  /* __cplusplus */\r
22 \r
23 //\r
24 // if we are building on Win95/NT4 headers we need to declare this stuff ourselves\r
25 //\r
26 #ifndef SM_CMONITORS\r
27 \r
28 #define SM_XVIRTUALSCREEN                   76\r
29 #define SM_YVIRTUALSCREEN                   77\r
30 #define SM_CXVIRTUALSCREEN                  78\r
31 #define SM_CYVIRTUALSCREEN                  79\r
32 #define SM_CMONITORS                        80\r
33 #define SM_SAMEDISPLAYFORMAT                81\r
34 \r
35 DECLARE_HANDLE(HMONITOR);\r
36 \r
37 #define MONITOR_DEFAULTTONULL               0x00000000\r
38 #define MONITOR_DEFAULTTOPRIMARY            0x00000001\r
39 #define MONITOR_DEFAULTTONEAREST            0x00000002\r
40 \r
41 #define MONITORINFOF_PRIMARY                0x00000001\r
42 \r
43 typedef struct tagMONITORINFO\r
44 {\r
45   DWORD cbSize;\r
46   RECT  rcMonitor;\r
47   RECT  rcWork;\r
48   DWORD dwFlags;\r
49 } MONITORINFO, *LPMONITORINFO;\r
50 \r
51 #define CCHDEVICENAME 32\r
52 \r
53 #ifdef __cplusplus\r
54 typedef struct tagMONITORINFOEX : public tagMONITORINFO\r
55 {\r
56   TCHAR       szDevice[CCHDEVICENAME];\r
57 } MONITORINFOEX, *LPMONITORINFOEX;\r
58 #else\r
59 typedef struct\r
60 {\r
61   MONITORINFO;\r
62   TCHAR       szDevice[CCHDEVICENAME];\r
63 } MONITORINFOEX, *LPMONITORINFOEX;\r
64 #endif\r
65 \r
66 typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);\r
67 \r
68 #endif // SM_CMONITORS\r
69 \r
70 #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP\r
71 \r
72 typedef struct {\r
73   DWORD cb;\r
74   CHAR  DeviceName[32];\r
75   CHAR  DeviceString[128];\r
76   DWORD StateFlags;\r
77 } DISPLAY_DEVICE;\r
78 \r
79 #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP  0x00000001\r
80 #define DISPLAY_DEVICE_MULTI_DRIVER         0x00000002\r
81 #define DISPLAY_DEVICE_PRIMARY_DEVICE       0x00000004\r
82 #define DISPLAY_DEVICE_MIRRORING_DRIVER     0x00000008\r
83 \r
84 #endif\r
85 #define DISPLAY_DEVICE_VGA                  0x00000010\r
86 \r
87 #ifndef ENUM_CURRENT_SETTINGS\r
88 #define ENUM_CURRENT_SETTINGS               ((DWORD)-1)\r
89 #define ENUM_REGISTRY_SETTINGS              ((DWORD)-2)\r
90 #endif\r
91 \r
92 #undef GetMonitorInfo\r
93 #undef GetSystemMetrics\r
94 #undef MonitorFromWindow\r
95 #undef MonitorFromRect\r
96 #undef MonitorFromPoint\r
97 #undef EnumDisplayMonitors\r
98 #undef EnumDisplayDevices\r
99 \r
100 //\r
101 // define this to compile the stubs\r
102 // otherwise you get the declarations\r
103 //\r
104 #ifdef COMPILE_MULTIMON_STUBS\r
105 \r
106   //---------------------------------------------------------------------------\r
107   //\r
108   // Implement the API stubs.\r
109   //\r
110   //---------------------------------------------------------------------------\r
111 \r
112   int       (WINAPI* g_pfnGetSystemMetrics)(int);\r
113   HMONITOR  (WINAPI* g_pfnMonitorFromWindow)(HWND, BOOL);\r
114   HMONITOR  (WINAPI* g_pfnMonitorFromRect)(LPCRECT, BOOL);\r
115   HMONITOR  (WINAPI* g_pfnMonitorFromPoint)(POINT, BOOL);\r
116   BOOL      (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO);\r
117   BOOL      (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);\r
118   BOOL      (WINAPI *g_pfnEnumDisplayDevices)(LPVOID, int, DISPLAY_DEVICE *, DWORD);\r
119 \r
120   BOOL InitMultipleMonitorStubs(void)\r
121   {\r
122     HMODULE hUser32;\r
123     static BOOL fInitDone;\r
124 \r
125     if (fInitDone)\r
126     {\r
127       return g_pfnGetMonitorInfo != NULL;\r
128     }\r
129 \r
130     if ((hUser32 = GetModuleHandle(TEXT("USER32"))) &&\r
131         (*(FARPROC*)&g_pfnGetSystemMetrics    = GetProcAddress(hUser32,"GetSystemMetrics")) &&\r
132         (*(FARPROC*)&g_pfnMonitorFromWindow   = GetProcAddress(hUser32,"MonitorFromWindow")) &&\r
133         (*(FARPROC*)&g_pfnMonitorFromRect     = GetProcAddress(hUser32,"MonitorFromRect")) &&\r
134         (*(FARPROC*)&g_pfnMonitorFromPoint    = GetProcAddress(hUser32,"MonitorFromPoint")) &&\r
135         (*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) &&\r
136     #ifdef UNICODE\r
137         (*(FARPROC*)&g_pfnGetMonitorInfo      = GetProcAddress(hUser32,"GetMonitorInfoW")) &&\r
138         (*(FARPROC*)&g_pfnEnumDisplayDevices  = GetProcAddress(hUser32,"EnumDisplayDevicesW")) &&\r
139     #else\r
140         (*(FARPROC*)&g_pfnGetMonitorInfo      = GetProcAddress(hUser32,"GetMonitorInfoA")) &&\r
141         (*(FARPROC*)&g_pfnEnumDisplayDevices  = GetProcAddress(hUser32,"EnumDisplayDevicesA")) &&\r
142     #endif\r
143         (GetSystemMetrics(SM_CXVIRTUALSCREEN) >= GetSystemMetrics(SM_CXSCREEN)) &&\r
144         (GetSystemMetrics(SM_CYVIRTUALSCREEN) >= GetSystemMetrics(SM_CYSCREEN)) )\r
145     {\r
146       fInitDone = TRUE;\r
147       return TRUE;\r
148     }\r
149     else\r
150     {\r
151       g_pfnGetSystemMetrics    = NULL;\r
152       g_pfnMonitorFromWindow   = NULL;\r
153       g_pfnMonitorFromRect     = NULL;\r
154       g_pfnMonitorFromPoint    = NULL;\r
155       g_pfnGetMonitorInfo      = NULL;\r
156       g_pfnEnumDisplayMonitors = NULL;\r
157       g_pfnEnumDisplayDevices  = NULL;\r
158 \r
159       fInitDone = TRUE;\r
160       return FALSE;\r
161     }\r
162   }\r
163 \r
164   //---------------------------------------------------------------------------\r
165   //\r
166   // "stubbed" implementations of Monitor APIs that work with the primary           //  display\r
167   //\r
168   //---------------------------------------------------------------------------\r
169 \r
170   int WINAPI\r
171   xGetSystemMetrics(int nIndex)\r
172   {\r
173     if (InitMultipleMonitorStubs())\r
174       return g_pfnGetSystemMetrics(nIndex);\r
175 \r
176     switch (nIndex)\r
177     {\r
178     case SM_CMONITORS:\r
179     case SM_SAMEDISPLAYFORMAT:\r
180       return 1;\r
181 \r
182     case SM_XVIRTUALSCREEN:\r
183     case SM_YVIRTUALSCREEN:\r
184       return 0;\r
185 \r
186     case SM_CXVIRTUALSCREEN:\r
187       nIndex = SM_CXSCREEN;\r
188       break;\r
189 \r
190     case SM_CYVIRTUALSCREEN:\r
191       nIndex = SM_CYSCREEN;\r
192       break;\r
193     }\r
194 \r
195     return GetSystemMetrics(nIndex);\r
196   }\r
197 \r
198   #define xPRIMARY_MONITOR ((HMONITOR)0x42)\r
199 \r
200   HMONITOR WINAPI\r
201   xMonitorFromRect(LPCRECT lprcScreenCoords,\r
202                    UINT uFlags)\r
203   {\r
204     if (InitMultipleMonitorStubs())\r
205       return g_pfnMonitorFromRect(lprcScreenCoords, uFlags);\r
206 \r
207     if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||\r
208         ((lprcScreenCoords->right > 0) &&\r
209         (lprcScreenCoords->bottom > 0) &&\r
210         (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&\r
211         (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))\r
212     {\r
213       return xPRIMARY_MONITOR;\r
214     }\r
215 \r
216     return NULL;\r
217   }\r
218 \r
219   HMONITOR WINAPI\r
220   xMonitorFromWindow(HWND hWnd,\r
221                      UINT uFlags)\r
222   {\r
223     RECT rc;\r
224 \r
225     if (InitMultipleMonitorStubs())\r
226       return g_pfnMonitorFromWindow(hWnd, uFlags);\r
227 \r
228     if (uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))\r
229       return xPRIMARY_MONITOR;\r
230 \r
231     if (GetWindowRect(hWnd, &rc))\r
232       return xMonitorFromRect(&rc, uFlags);\r
233 \r
234     return NULL;\r
235   }\r
236 \r
237   HMONITOR WINAPI\r
238   xMonitorFromPoint(POINT ptScreenCoords,\r
239                     UINT uFlags)\r
240   {\r
241     if (InitMultipleMonitorStubs())\r
242       return g_pfnMonitorFromPoint(ptScreenCoords, uFlags);\r
243 \r
244     if ((uFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||\r
245         ((ptScreenCoords.x >= 0) &&\r
246         (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&\r
247         (ptScreenCoords.y >= 0) &&\r
248         (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))\r
249     {\r
250       return xPRIMARY_MONITOR;\r
251     }\r
252 \r
253     return NULL;\r
254   }\r
255 \r
256   BOOL WINAPI\r
257   xGetMonitorInfo(HMONITOR hMonitor,\r
258                   LPMONITORINFO lpMonitorInfo)\r
259   {\r
260     RECT rcWork;\r
261 \r
262     if (InitMultipleMonitorStubs())\r
263       return g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);\r
264 \r
265     if ((hMonitor == xPRIMARY_MONITOR) && lpMonitorInfo &&\r
266         (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&\r
267         SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0))\r
268     {\r
269       lpMonitorInfo->rcMonitor.left = 0;\r
270       lpMonitorInfo->rcMonitor.top  = 0;\r
271       lpMonitorInfo->rcMonitor.right  = GetSystemMetrics(SM_CXSCREEN);\r
272       lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);\r
273       lpMonitorInfo->rcWork = rcWork;\r
274       lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;\r
275 \r
276       if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))\r
277           lstrcpy(((MONITORINFOEX*)lpMonitorInfo)->szDevice,\r
278           TEXT("DISPLAY"));\r
279 \r
280       return TRUE;\r
281     }\r
282 \r
283     return FALSE;\r
284   }\r
285 \r
286   BOOL WINAPI\r
287   xEnumDisplayMonitors(HDC hdc,\r
288                        LPCRECT lprcIntersect, \r
289                        MONITORENUMPROC lpfnEnumProc,\r
290                        LPARAM lData)\r
291   {\r
292     RECT rcCallback, rcLimit;\r
293 \r
294     if (InitMultipleMonitorStubs())\r
295       return g_pfnEnumDisplayMonitors(hdc, lprcIntersect, lpfnEnumProc, lData);\r
296     \r
297     if (!lpfnEnumProc)\r
298       return FALSE;\r
299 \r
300     rcLimit.left   = 0;\r
301     rcLimit.top    = 0;\r
302     rcLimit.right  = GetSystemMetrics(SM_CXSCREEN);\r
303     rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);\r
304 \r
305     if (hdc)\r
306     {\r
307       RECT rcClip;\r
308       HWND hWnd;\r
309 \r
310       if ((hWnd = WindowFromDC(hdc)) == NULL)\r
311         return FALSE;\r
312 \r
313       switch (GetClipBox(hdc, &rcClip))\r
314       {\r
315       default:\r
316         MapWindowPoints(NULL, hWnd, (LPPOINT)&rcLimit, 2);\r
317         if (IntersectRect(&rcCallback, &rcClip, &rcLimit))\r
318           break;\r
319       //fall thru\r
320       case NULLREGION:\r
321         return TRUE;\r
322       case ERROR:\r
323         return FALSE;\r
324       }\r
325 \r
326       rcLimit = rcCallback;\r
327     }\r
328 \r
329     if (!lprcIntersect || IntersectRect(&rcCallback, lprcIntersect, &rcLimit))\r
330     {\r
331       lpfnEnumProc(xPRIMARY_MONITOR, hdc, &rcCallback, lData);\r
332     }\r
333 \r
334     return TRUE;\r
335   }\r
336 \r
337   BOOL WINAPI\r
338   xEnumDisplayDevices(LPVOID lpReserved,\r
339                       int iDeviceNum, \r
340                       DISPLAY_DEVICE * pDisplayDevice,\r
341                       DWORD dwFlags)\r
342   {\r
343     if (InitMultipleMonitorStubs())\r
344       return g_pfnEnumDisplayDevices(lpReserved, iDeviceNum, pDisplayDevice, dwFlags);\r
345     \r
346     return FALSE;\r
347   }\r
348 \r
349   #undef xPRIMARY_MONITOR\r
350   #undef COMPILE_MULTIMON_STUBS\r
351 \r
352 #else    // COMPILE_MULTIMON_STUBS\r
353 \r
354   extern int      WINAPI xGetSystemMetrics(int);\r
355   extern HMONITOR WINAPI xMonitorFromWindow(HWND, UINT);\r
356   extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, UINT);\r
357   extern HMONITOR WINAPI xMonitorFromPoint(POINT, UINT);\r
358   extern BOOL     WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);\r
359   extern BOOL     WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);\r
360   extern BOOL     WINAPI xEnumDisplayDevices(LPVOID, int, DISPLAY_DEVICE *, DWORD);\r
361 \r
362 #endif    // COMPILE_MULTIMON_STUBS\r
363 \r
364 //\r
365 // build defines that replace the regular APIs with our versions\r
366 //\r
367 #define GetSystemMetrics    xGetSystemMetrics\r
368 #define MonitorFromWindow   xMonitorFromWindow\r
369 #define MonitorFromRect     xMonitorFromRect\r
370 #define MonitorFromPoint    xMonitorFromPoint\r
371 #define GetMonitorInfo      xGetMonitorInfo\r
372 #define EnumDisplayMonitors xEnumDisplayMonitors\r
373 #define EnumDisplayDevices  xEnumDisplayDevices\r
374 \r
375 #ifdef __cplusplus\r
376 }\r
377 #endif // __cplusplus\r
378 \r
379 #endif // WIN32\r
380 \r
381 #endif // __MULTIMON_H