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