07ffdb1d64e1ac43f031d8ca902fe5090702501c
[freeglut] / src / mswin / fg_state_mswin.c
1 /*
2  * freeglut_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 RECT fghGetClientArea( const SFG_Window *window, BOOL wantPosOutside );
41 extern void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth);
42
43
44 /* The following include file is available from SGI but is not standard:
45  *   #include <GL/wglext.h>
46  * So we copy the necessary parts out of it to support the multisampling query
47  */
48 #define WGL_SAMPLES_ARB                0x2042
49
50 #if defined(_WIN32_WCE)
51 #   include <Aygshell.h>
52 #   ifdef FREEGLUT_LIB_PRAGMAS
53 #       pragma comment( lib, "Aygshell.lib" )
54 #   endif
55 #endif /* defined(_WIN32_WCE) */
56
57
58
59 int fgPlatformGlutGet ( GLenum eWhat )
60 {
61     int returnValue ;
62     GLboolean boolValue ;
63
64     int nsamples = 0;
65
66     switch( eWhat )
67     {
68     case GLUT_WINDOW_NUM_SAMPLES:
69       glGetIntegerv(WGL_SAMPLES_ARB, &nsamples);
70       return nsamples;
71
72     /* Handle the OpenGL inquiries */
73     case GLUT_WINDOW_RGBA:
74 #if defined(_WIN32_WCE)
75       boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */
76 #else
77       glGetBooleanv ( GL_RGBA_MODE, &boolValue );
78       returnValue = boolValue ? 1 : 0;
79 #endif
80       return returnValue;
81     case GLUT_WINDOW_DOUBLEBUFFER:
82 #if defined(_WIN32_WCE)
83       boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */
84 #else
85       glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue );
86       returnValue = boolValue ? 1 : 0;
87 #endif
88       return returnValue;
89     case GLUT_WINDOW_STEREO:
90 #if defined(_WIN32_WCE)
91       boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */
92 #else
93       glGetBooleanv ( GL_STEREO, &boolValue );
94       returnValue = boolValue ? 1 : 0;
95 #endif
96       return returnValue;
97
98     case GLUT_WINDOW_RED_SIZE:
99       glGetIntegerv ( GL_RED_BITS, &returnValue );
100       return returnValue;
101     case GLUT_WINDOW_GREEN_SIZE:
102       glGetIntegerv ( GL_GREEN_BITS, &returnValue );
103       return returnValue;
104     case GLUT_WINDOW_BLUE_SIZE:
105       glGetIntegerv ( GL_BLUE_BITS, &returnValue );
106       return returnValue;
107     case GLUT_WINDOW_ALPHA_SIZE:
108       glGetIntegerv ( GL_ALPHA_BITS, &returnValue );
109       return returnValue;
110     case GLUT_WINDOW_ACCUM_RED_SIZE:
111 #if defined(_WIN32_WCE)
112       returnValue = 0;  /* WinCE doesn't support this feature */
113 #else
114       glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue );
115 #endif
116       return returnValue;
117     case GLUT_WINDOW_ACCUM_GREEN_SIZE:
118 #if defined(_WIN32_WCE)
119       returnValue = 0;  /* WinCE doesn't support this feature */
120 #else
121       glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue );
122 #endif
123       return returnValue;
124     case GLUT_WINDOW_ACCUM_BLUE_SIZE:
125 #if defined(_WIN32_WCE)
126       returnValue = 0;  /* WinCE doesn't support this feature */
127 #else
128       glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue );
129 #endif
130       return returnValue;
131     case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
132 #if defined(_WIN32_WCE)
133       returnValue = 0;  /* WinCE doesn't support this feature */
134 #else
135       glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue );
136 #endif
137       return returnValue;
138     case GLUT_WINDOW_DEPTH_SIZE:
139       glGetIntegerv ( GL_DEPTH_BITS, &returnValue );
140       return returnValue;
141
142     case GLUT_WINDOW_BUFFER_SIZE:
143       returnValue = 1 ;                                      /* ????? */
144       return returnValue;
145     case GLUT_WINDOW_STENCIL_SIZE:
146       returnValue = 0 ;                                      /* ????? */
147       return returnValue;
148
149     case GLUT_WINDOW_X:
150     case GLUT_WINDOW_Y:
151     case GLUT_WINDOW_WIDTH:
152     case GLUT_WINDOW_HEIGHT:
153     {
154         /*
155          *  There is considerable confusion about the "right thing to
156          *  do" concerning window  size and position.  GLUT itself is
157          *  not consistent between Windows and UNIX/X11; since
158          *  platform independence is a virtue for "freeglut", we
159          *  decided to break with GLUT's behaviour.
160          *
161          *  Under UNIX/X11, it is apparently not possible to get the
162          *  window border sizes in order to subtract them off the
163          *  window's initial position until some time after the window
164          *  has been created.  Therefore we decided on the following
165          *  behaviour, both under Windows and under UNIX/X11:
166          *  - When you create a window with position (x,y) and size
167          *    (w,h), the upper left hand corner of the outside of the
168          *    window is at (x,y) and the size of the drawable area  is
169          *    (w,h).
170          *  - When you query the size and position of the window--as
171          *    is happening here for Windows--"freeglut" will return
172          *    the size of the drawable area--the (w,h) that you
173          *    specified when you created the window--and the coordinates
174          *    of the upper left hand corner of the drawable
175          *    area--which is NOT the (x,y) you specified.
176          */
177
178         RECT winRect;
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         winRect = fghGetClientArea(fgStructure.CurrentWindow, FALSE);
186 #endif /* defined(_WIN32_WCE) */
187
188         switch( eWhat )
189         {
190         case GLUT_WINDOW_X:      return winRect.left                ;
191         case GLUT_WINDOW_Y:      return winRect.top                 ;
192         case GLUT_WINDOW_WIDTH:  return winRect.right - winRect.left;
193         case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top;
194         }
195     }
196     break;
197
198     case GLUT_WINDOW_BORDER_WIDTH :
199     case GLUT_WINDOW_HEADER_HEIGHT :
200 #if defined(_WIN32_WCE)
201         return 0;
202 #else
203         {
204             DWORD windowStyle;
205
206             if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle)
207                 windowStyle = GetWindowLong(fgStructure.CurrentWindow->Window.Handle, GWL_STYLE);
208             else
209                 /* If no window, return sizes for a default window with title bar and border */
210                 windowStyle = WS_OVERLAPPEDWINDOW;
211             
212             switch( eWhat )
213             {
214             case GLUT_WINDOW_BORDER_WIDTH:
215                 {
216                     int xBorderWidth, yBorderWidth;
217                     fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
218                     return xBorderWidth;
219                 }
220             case GLUT_WINDOW_HEADER_HEIGHT:
221                 /* Need to query for WS_MAXIMIZEBOX to see if we have a title bar, the WS_CAPTION query is also true for a WS_DLGFRAME only... */
222                 return (windowStyle & WS_MAXIMIZEBOX)? GetSystemMetrics( SM_CYCAPTION ) : 0;
223             }
224         }
225 #endif /* defined(_WIN32_WCE) */
226
227     case GLUT_DISPLAY_MODE_POSSIBLE:
228 #if defined(_WIN32_WCE)
229         return 0;
230 #else
231         return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,
232                                     PFD_MAIN_PLANE );
233 #endif /* defined(_WIN32_WCE) */
234
235
236     case GLUT_WINDOW_FORMAT_ID:
237 #if !defined(_WIN32_WCE)
238         if( fgStructure.CurrentWindow != NULL )
239             return GetPixelFormat( fgStructure.CurrentWindow->Window.pContext.Device );
240 #endif /* defined(_WIN32_WCE) */
241         return 0;
242
243     default:
244         fgWarning( "glutGet(): missing enum handle %d", eWhat );
245         break;
246     }
247
248         return -1;
249 }
250
251
252 int fgPlatformGlutDeviceGet ( GLenum eWhat )
253 {
254     switch( eWhat )
255     {
256     case GLUT_HAS_KEYBOARD:
257         /*
258          * Win32 is assumed a keyboard, and this cannot be queried,
259          * except for WindowsCE.
260          */
261 #if defined(_WIN32_CE)
262         return ( GetKeyboardStatus() & KBDI_KEYBOARD_PRESENT ) ? 1 : 0;
263 #   if FREEGLUT_LIB_PRAGMAS
264 #       pragma comment (lib,"Kbdui.lib")
265 #   endif
266
267 #else
268         return 1;
269 #endif
270
271     case GLUT_HAS_MOUSE:
272         /*
273          * MS Windows can be booted without a mouse.
274          */
275         return GetSystemMetrics( SM_MOUSEPRESENT );
276
277     case GLUT_NUM_MOUSE_BUTTONS:
278 #  if defined(_WIN32_WCE)
279         return 1;
280 #  else
281         return GetSystemMetrics( SM_CMOUSEBUTTONS );
282 #  endif
283
284     default:
285         fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
286         break;
287     }
288
289     /* And now -- the failure. */
290     return -1;
291 }
292
293 /*
294  * This is for querying the number of supported auxiliary or multisample
295  * buffers for a (the current?) display mode.
296  * see http://old.nabble.com/-GLX--glutGetModeValues-to13514723.html#a13514723
297  * Not currently implemented, but we should be able to query the relevant
298  * info using
299  * http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
300  * (if supported on the executing machine!)
301  */
302 int *fgPlatformGlutGetModeValues(GLenum eWhat, int *size)
303 {
304   *size = 0;
305   return NULL;
306 }