1 /*
2 * fg_state_mswin.c
3 *
4 * The Windows-specific state query methods.
5 *
6 * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
7 * Written by John F. Fay, <fayjf@sourceforge.net>
8 * Creation date: Sun Jan 22, 2012
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28 #include <GL/freeglut.h>
29 #include "../fg_internal.h"
30
31
32 extern GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
33 unsigned char layer_type );
34
35 /*
36 * Helper functions for getting client area from the window rect
37 * and the window rect from the client area given the style of the window
38 * (or a valid window pointer from which the style can be queried).
39 */
40 extern void fghGetClientArea( RECT *clientRect, const SFG_Window *window, BOOL posIsOutside );
41 extern void fghGetStyleFromWindow( const SFG_Window *window, DWORD *windowStyle, DWORD *windowExStyle );
42 extern void fghComputeWindowRectFromClientArea_UseStyle( RECT *clientRect, const DWORD windowStyle, const DWORD windowExStyle, BOOL posIsOutside );
43
44
45 /* The following include file is available from SGI but is not standard:
46 * #include <GL/wglext.h>
47 * So we copy the necessary parts out of it to support the multisampling query
48 */
49 #define WGL_SAMPLES_ARB 0x2042
50
51 #if defined(_WIN32_WCE)
52 # include <Aygshell.h>
53 # ifdef FREEGLUT_LIB_PRAGMAS
54 # pragma comment( lib, "Aygshell.lib" )
55 # endif
56 #endif /* defined(_WIN32_WCE) */
57
58
59
fgPlatformGlutGet(GLenum eWhat)60 int fgPlatformGlutGet ( GLenum eWhat )
61 {
62 int returnValue ;
63 GLboolean boolValue ;
64
65 int nsamples = 0;
66
67 switch( eWhat )
68 {
69 case GLUT_WINDOW_NUM_SAMPLES:
70 glGetIntegerv(WGL_SAMPLES_ARB, &nsamples);
71 return nsamples;
72
73 /* Handle the OpenGL inquiries */
74 case GLUT_WINDOW_RGBA:
75 #if defined(_WIN32_WCE)
76 boolValue = (GLboolean)0; /* WinCE doesn't support this feature */
77 #else
78 glGetBooleanv ( GL_RGBA_MODE, &boolValue );
79 returnValue = boolValue ? 1 : 0;
80 #endif
81 return returnValue;
82 case GLUT_WINDOW_DOUBLEBUFFER:
83 #if defined(_WIN32_WCE)
84 boolValue = (GLboolean)0; /* WinCE doesn't support this feature */
85 #else
86 glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue );
87 returnValue = boolValue ? 1 : 0;
88 #endif
89 return returnValue;
90 case GLUT_WINDOW_STEREO:
91 #if defined(_WIN32_WCE)
92 boolValue = (GLboolean)0; /* WinCE doesn't support this feature */
93 #else
94 glGetBooleanv ( GL_STEREO, &boolValue );
95 returnValue = boolValue ? 1 : 0;
96 #endif
97 return returnValue;
98
99 case GLUT_WINDOW_RED_SIZE:
100 glGetIntegerv ( GL_RED_BITS, &returnValue );
101 return returnValue;
102 case GLUT_WINDOW_GREEN_SIZE:
103 glGetIntegerv ( GL_GREEN_BITS, &returnValue );
104 return returnValue;
105 case GLUT_WINDOW_BLUE_SIZE:
106 glGetIntegerv ( GL_BLUE_BITS, &returnValue );
107 return returnValue;
108 case GLUT_WINDOW_ALPHA_SIZE:
109 glGetIntegerv ( GL_ALPHA_BITS, &returnValue );
110 return returnValue;
111 case GLUT_WINDOW_ACCUM_RED_SIZE:
112 #if defined(_WIN32_WCE)
113 returnValue = 0; /* WinCE doesn't support this feature */
114 #else
115 glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue );
116 #endif
117 return returnValue;
118 case GLUT_WINDOW_ACCUM_GREEN_SIZE:
119 #if defined(_WIN32_WCE)
120 returnValue = 0; /* WinCE doesn't support this feature */
121 #else
122 glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue );
123 #endif
124 return returnValue;
125 case GLUT_WINDOW_ACCUM_BLUE_SIZE:
126 #if defined(_WIN32_WCE)
127 returnValue = 0; /* WinCE doesn't support this feature */
128 #else
129 glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue );
130 #endif
131 return returnValue;
132 case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
133 #if defined(_WIN32_WCE)
134 returnValue = 0; /* WinCE doesn't support this feature */
135 #else
136 glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue );
137 #endif
138 return returnValue;
139 case GLUT_WINDOW_DEPTH_SIZE:
140 glGetIntegerv ( GL_DEPTH_BITS, &returnValue );
141 return returnValue;
142
143 case GLUT_WINDOW_BUFFER_SIZE:
144 {
145 PIXELFORMATDESCRIPTOR pfd;
146 HDC hdc = fgStructure.CurrentWindow->Window.pContext.Device;
147 int iPixelFormat = GetPixelFormat( hdc );
148 DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
149
150 returnValue = pfd.cColorBits;
151 if (pfd.iPixelType==PFD_TYPE_RGBA)
152 returnValue += pfd.cAlphaBits;
153
154 return returnValue;
155 }
156 case GLUT_WINDOW_STENCIL_SIZE:
157 glGetIntegerv ( GL_STENCIL_BITS, &returnValue );
158 return returnValue;
159
160 case GLUT_WINDOW_X:
161 case GLUT_WINDOW_Y:
162 {
163 /*
164 * NB:
165 * - When you create a window with position (x,y) and size
166 * (w,h), the upper left hand corner of the outside of the
167 * window is at (x,y) and the size of the drawable area is
168 * (w,h).
169 * - When you query the size and position of the window--as
170 * is happening here for Windows--"freeglut" will return
171 * the size of the drawable area--the (w,h) that you
172 * specified when you created the window--and the coordinates
173 * of the upper left hand corner of the drawable area, i.e.
174 * of the client rect--which is NOT the (x,y) you specified.
175 */
176
177 RECT winRect;
178 POINT topLeft = {0,0};
179
180 freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );
181
182 #if defined(_WIN32_WCE)
183 GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect);
184 #else
185 ClientToScreen(fgStructure.CurrentWindow->Window.Handle, &topLeft);
186
187 if (fgStructure.CurrentWindow->Parent)
188 /* For child window, we should return relative to upper-left
189 * of parent's client area.
190 */
191 ScreenToClient(fgStructure.CurrentWindow->Parent->Window.Handle,&topLeft);
192
193 winRect.left = topLeft.x;
194 winRect.top = topLeft.y;
195 #endif /* defined(_WIN32_WCE) */
196
197 switch( eWhat )
198 {
199 case GLUT_WINDOW_X: return winRect.left;
200 case GLUT_WINDOW_Y: return winRect.top ;
201 }
202 }
203 break;
204
205 case GLUT_WINDOW_WIDTH:
206 case GLUT_WINDOW_HEIGHT:
207 {
208 RECT winRect;
209 freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );
210
211 GetClientRect( fgStructure.CurrentWindow->Window.Handle, &winRect);
212
213 switch( eWhat )
214 {
215 case GLUT_WINDOW_WIDTH: return winRect.right-winRect.left;
216 case GLUT_WINDOW_HEIGHT: return winRect.bottom-winRect.top;
217 }
218 }
219 break;
220
221 case GLUT_WINDOW_BORDER_WIDTH :
222 case GLUT_WINDOW_BORDER_HEIGHT :
223 #if defined(_WIN32_WCE)
224 return 0;
225 #else
226 {
227 /* We can't get the border width or header height in the simple way
228 * with some calls to GetSystemMetrics. We'd then have to assume which
229 * elements are present for a given decoration, and such calculations
230 * wouldn't be valid for every version of Windows. The below should be
231 * robust. */
232 int borderWidth, captionHeight;
233 DWORD windowStyle, windowExStyle;
234 RECT clientRect, winRect;
235
236 /* Get style of window, or default style */
237 fghGetStyleFromWindow( fgStructure.CurrentWindow, &windowStyle, &windowExStyle );
238 /* Get client area if we have a current window, else use dummy rect */
239 /* Also get window rect (including non-client area) */
240 if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle)
241 {
242 fghGetClientArea(&clientRect,fgStructure.CurrentWindow, FALSE);
243 GetWindowRect(fgStructure.CurrentWindow->Window.Handle,&winRect);
244 }
245 else
246 {
247 SetRect(&clientRect,0,0,200,200);
248 CopyRect(&winRect,&clientRect);
249 fghComputeWindowRectFromClientArea_UseStyle(&winRect,windowStyle,windowExStyle,FALSE);
250 }
251
252 /* Calculate border width by taking width of whole window minus width of client area and divide by two
253 * NB: we assume horizontal and vertical borders have the same size, which should always be the case
254 * unless the user bypassed FreeGLUT and messed with the windowstyle himself.
255 * Once borderwidth is known, account for it when comparing height of window to height of client area.
256 * all other extra pixels are assumed to be atop the window, forming the caption.
257 */
258 borderWidth = ((winRect.right-winRect.left)-(clientRect.right-clientRect.left))/2;
259 captionHeight = (winRect.bottom-winRect.top)-(clientRect.bottom-clientRect.top)-borderWidth; /* include top border in caption height */
260
261 switch( eWhat )
262 {
263 case GLUT_WINDOW_BORDER_WIDTH:
264 return borderWidth;
265 case GLUT_WINDOW_BORDER_HEIGHT:
266 return captionHeight;
267 }
268 }
269 #endif /* defined(_WIN32_WCE) */
270
271 case GLUT_DISPLAY_MODE_POSSIBLE:
272 #if defined(_WIN32_WCE)
273 return 0;
274 #else
275 return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,
276 PFD_MAIN_PLANE );
277 #endif /* defined(_WIN32_WCE) */
278
279
280 case GLUT_WINDOW_FORMAT_ID:
281 #if !defined(_WIN32_WCE)
282 if( fgStructure.CurrentWindow != NULL )
283 return GetPixelFormat( fgStructure.CurrentWindow->Window.pContext.Device );
284 #endif /* defined(_WIN32_WCE) */
285 return 0;
286
287 default:
288 fgWarning( "glutGet(): missing enum handle %d", eWhat );
289 break;
290 }
291
292 return -1;
293 }
294
295
fgPlatformGlutDeviceGet(GLenum eWhat)296 int fgPlatformGlutDeviceGet ( GLenum eWhat )
297 {
298 switch( eWhat )
299 {
300 case GLUT_HAS_KEYBOARD:
301 /*
302 * Win32 is assumed a keyboard, and this cannot be queried,
303 * except for WindowsCE.
304 */
305 #if defined(_WIN32_CE)
306 return ( GetKeyboardStatus() & KBDI_KEYBOARD_PRESENT ) ? 1 : 0;
307 # if FREEGLUT_LIB_PRAGMAS
308 # pragma comment (lib,"Kbdui.lib")
309 # endif
310
311 #else
312 return 1;
313 #endif
314
315 case GLUT_HAS_MOUSE:
316 /*
317 * MS Windows can be booted without a mouse.
318 */
319 return GetSystemMetrics( SM_MOUSEPRESENT );
320
321 case GLUT_NUM_MOUSE_BUTTONS:
322 # if defined(_WIN32_WCE)
323 return 1;
324 # else
325 return GetSystemMetrics( SM_CMOUSEBUTTONS );
326 # endif
327
328 default:
329 fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
330 return -1;
331 break;
332 }
333 }
334
335 /*
336 * This is for querying the number of supported auxiliary or multisample
337 * buffers for a (the current?) display mode.
338 * see http://old.nabble.com/-GLX--glutGetModeValues-to13514723.html#a13514723
339 * Not currently implemented, but we should be able to query the relevant
340 * info using
341 * http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
342 * (if supported on the executing machine!)
343 */
fgPlatformGlutGetModeValues(GLenum eWhat,int * size)344 int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size)
345 {
346 *size = 0;
347 return NULL;
348 }
349