e5522916b25236df75e5a324926143e445fc627f
[freeglut] / src / mswin / freeglut_state_mswin.c
1 /*\r
2  * freeglut_state_mswin.c\r
3  *\r
4  * The Windows-specific mouse cursor related stuff.\r
5  *\r
6  * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.\r
7  * Written by John F. Fay, <fayjf@sourceforge.net>\r
8  * Creation date: Sun Jan 22, 2012\r
9  *\r
10  * Permission is hereby granted, free of charge, to any person obtaining a\r
11  * copy of this software and associated documentation files (the "Software"),\r
12  * to deal in the Software without restriction, including without limitation\r
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
14  * and/or sell copies of the Software, and to permit persons to whom the\r
15  * Software is furnished to do so, subject to the following conditions:\r
16  *\r
17  * The above copyright notice and this permission notice shall be included\r
18  * in all copies or substantial portions of the Software.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
23  * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
24  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
25  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
26  */\r
27 \r
28 #include <GL/freeglut.h>\r
29 #include "freeglut_internal_mswin.h"\r
30 \r
31 \r
32 extern GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,\r
33                                      unsigned char layer_type );\r
34 \r
35 \r
36 /* The following include file is available from SGI but is not standard:\r
37  *   #include <GL/wglext.h>\r
38  * So we copy the necessary parts out of it to support the multisampling query\r
39  */\r
40 #define WGL_SAMPLES_ARB                0x2042\r
41 \r
42 \r
43 \r
44 int fgPlatformGlutGet ( GLenum eWhat )\r
45 {\r
46     int returnValue ;\r
47     GLboolean boolValue ;\r
48 \r
49     int nsamples = 0;\r
50 \r
51     switch( eWhat )\r
52     {\r
53     case GLUT_WINDOW_NUM_SAMPLES:\r
54       glGetIntegerv(WGL_SAMPLES_ARB, &nsamples);\r
55       return nsamples;\r
56 \r
57     /* Handle the OpenGL inquiries */\r
58     case GLUT_WINDOW_RGBA:\r
59 #if defined(_WIN32_WCE)\r
60       boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */\r
61 #else\r
62       glGetBooleanv ( GL_RGBA_MODE, &boolValue );\r
63       returnValue = boolValue ? 1 : 0;\r
64 #endif\r
65       return returnValue;\r
66     case GLUT_WINDOW_DOUBLEBUFFER:\r
67 #if defined(_WIN32_WCE)\r
68       boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */\r
69 #else\r
70       glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue );\r
71       returnValue = boolValue ? 1 : 0;\r
72 #endif\r
73       return returnValue;\r
74     case GLUT_WINDOW_STEREO:\r
75 #if defined(_WIN32_WCE)\r
76       boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */\r
77 #else\r
78       glGetBooleanv ( GL_STEREO, &boolValue );\r
79       returnValue = boolValue ? 1 : 0;\r
80 #endif\r
81       return returnValue;\r
82 \r
83     case GLUT_WINDOW_RED_SIZE:\r
84       glGetIntegerv ( GL_RED_BITS, &returnValue );\r
85       return returnValue;\r
86     case GLUT_WINDOW_GREEN_SIZE:\r
87       glGetIntegerv ( GL_GREEN_BITS, &returnValue );\r
88       return returnValue;\r
89     case GLUT_WINDOW_BLUE_SIZE:\r
90       glGetIntegerv ( GL_BLUE_BITS, &returnValue );\r
91       return returnValue;\r
92     case GLUT_WINDOW_ALPHA_SIZE:\r
93       glGetIntegerv ( GL_ALPHA_BITS, &returnValue );\r
94       return returnValue;\r
95     case GLUT_WINDOW_ACCUM_RED_SIZE:\r
96 #if defined(_WIN32_WCE)\r
97       returnValue = 0;  /* WinCE doesn't support this feature */\r
98 #else\r
99       glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue );\r
100 #endif\r
101       return returnValue;\r
102     case GLUT_WINDOW_ACCUM_GREEN_SIZE:\r
103 #if defined(_WIN32_WCE)\r
104       returnValue = 0;  /* WinCE doesn't support this feature */\r
105 #else\r
106       glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue );\r
107 #endif\r
108       return returnValue;\r
109     case GLUT_WINDOW_ACCUM_BLUE_SIZE:\r
110 #if defined(_WIN32_WCE)\r
111       returnValue = 0;  /* WinCE doesn't support this feature */\r
112 #else\r
113       glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue );\r
114 #endif\r
115       return returnValue;\r
116     case GLUT_WINDOW_ACCUM_ALPHA_SIZE:\r
117 #if defined(_WIN32_WCE)\r
118       returnValue = 0;  /* WinCE doesn't support this feature */\r
119 #else\r
120       glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue );\r
121 #endif\r
122       return returnValue;\r
123     case GLUT_WINDOW_DEPTH_SIZE:\r
124       glGetIntegerv ( GL_DEPTH_BITS, &returnValue );\r
125       return returnValue;\r
126 \r
127     case GLUT_WINDOW_BUFFER_SIZE:\r
128       returnValue = 1 ;                                      /* ????? */\r
129       return returnValue;\r
130     case GLUT_WINDOW_STENCIL_SIZE:\r
131       returnValue = 0 ;                                      /* ????? */\r
132       return returnValue;\r
133 \r
134     case GLUT_WINDOW_X:\r
135     case GLUT_WINDOW_Y:\r
136     case GLUT_WINDOW_WIDTH:\r
137     case GLUT_WINDOW_HEIGHT:\r
138     {\r
139         /*\r
140          *  There is considerable confusion about the "right thing to\r
141          *  do" concerning window  size and position.  GLUT itself is\r
142          *  not consistent between Windows and UNIX/X11; since\r
143          *  platform independence is a virtue for "freeglut", we\r
144          *  decided to break with GLUT's behaviour.\r
145          *\r
146          *  Under UNIX/X11, it is apparently not possible to get the\r
147          *  window border sizes in order to subtract them off the\r
148          *  window's initial position until some time after the window\r
149          *  has been created.  Therefore we decided on the following\r
150          *  behaviour, both under Windows and under UNIX/X11:\r
151          *  - When you create a window with position (x,y) and size\r
152          *    (w,h), the upper left hand corner of the outside of the\r
153          *    window is at (x,y) and the size of the drawable area  is\r
154          *    (w,h).\r
155          *  - When you query the size and position of the window--as\r
156          *    is happening here for Windows--"freeglut" will return\r
157          *    the size of the drawable area--the (w,h) that you\r
158          *    specified when you created the window--and the coordinates\r
159          *    of the upper left hand corner of the drawable\r
160          *    area--which is NOT the (x,y) you specified.\r
161          */\r
162 \r
163         RECT winRect;\r
164 \r
165         freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );\r
166 \r
167 #if defined(_WIN32_WCE)\r
168         GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );\r
169 #else\r
170         winRect = fghGetClientArea(fgStructure.CurrentWindow, FALSE);\r
171 #endif /* defined(_WIN32_WCE) */\r
172 \r
173         switch( eWhat )\r
174         {\r
175         case GLUT_WINDOW_X:      return winRect.left                ;\r
176         case GLUT_WINDOW_Y:      return winRect.top                 ;\r
177         case GLUT_WINDOW_WIDTH:  return winRect.right - winRect.left;\r
178         case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top;\r
179         }\r
180     }\r
181     break;\r
182 \r
183     case GLUT_WINDOW_BORDER_WIDTH :\r
184     case GLUT_WINDOW_HEADER_HEIGHT :\r
185 #if defined(_WIN32_WCE)\r
186         return 0;\r
187 #else\r
188         {\r
189             DWORD windowStyle;\r
190 \r
191             if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle)\r
192                 windowStyle = GetWindowLong(fgStructure.CurrentWindow->Window.Handle, GWL_STYLE);\r
193             else\r
194                 /* If no window, return sizes for a default window with title bar and border */\r
195                 windowStyle = WS_OVERLAPPEDWINDOW;\r
196             \r
197             switch( eWhat )\r
198             {\r
199             case GLUT_WINDOW_BORDER_WIDTH:\r
200                 {\r
201                     int xBorderWidth, yBorderWidth;\r
202                     fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);\r
203                     return xBorderWidth;\r
204                 }\r
205             case GLUT_WINDOW_HEADER_HEIGHT:\r
206                 /* 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... */\r
207                 return (windowStyle & WS_MAXIMIZEBOX)? GetSystemMetrics( SM_CYCAPTION ) : 0;\r
208             }\r
209         }\r
210 #endif /* defined(_WIN32_WCE) */\r
211 \r
212     case GLUT_DISPLAY_MODE_POSSIBLE:\r
213 #if defined(_WIN32_WCE)\r
214         return 0;\r
215 #else\r
216         return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,\r
217                                     PFD_MAIN_PLANE );\r
218 #endif /* defined(_WIN32_WCE) */\r
219 \r
220 \r
221     case GLUT_WINDOW_FORMAT_ID:\r
222 #if !defined(_WIN32_WCE)\r
223         if( fgStructure.CurrentWindow != NULL )\r
224             return GetPixelFormat( fgStructure.CurrentWindow->Window.Device );\r
225 #endif /* defined(_WIN32_WCE) */\r
226         return 0;\r
227 \r
228     default:\r
229         fgWarning( "glutGet(): missing enum handle %d", eWhat );\r
230         break;\r
231     }\r
232 \r
233         return -1;\r
234 }\r
235 \r
236 \r
237 int fgPlatformGlutDeviceGet ( GLenum eWhat )\r
238 {\r
239     switch( eWhat )\r
240     {\r
241     case GLUT_HAS_KEYBOARD:\r
242         /*\r
243          * Win32 is assumed a keyboard, and this cannot be queried,\r
244          * except for WindowsCE.\r
245          *\r
246          * X11 has a core keyboard by definition, although it can\r
247          * be present as a virtual/dummy keyboard. For now, there\r
248          * is no reliable way to tell if a real keyboard is present.\r
249          */\r
250 #if defined(_WIN32_CE)\r
251         return ( GetKeyboardStatus() & KBDI_KEYBOARD_PRESENT ) ? 1 : 0;\r
252 #   if FREEGLUT_LIB_PRAGMAS\r
253 #       pragma comment (lib,"Kbdui.lib")\r
254 #   endif\r
255 \r
256 #else\r
257         return 1;\r
258 #endif\r
259 \r
260     case GLUT_HAS_MOUSE:\r
261         /*\r
262          * MS Windows can be booted without a mouse.\r
263          */\r
264         return GetSystemMetrics( SM_MOUSEPRESENT );\r
265 \r
266     case GLUT_NUM_MOUSE_BUTTONS:\r
267 #  if defined(_WIN32_WCE)\r
268         return 1;\r
269 #  else\r
270         return GetSystemMetrics( SM_CMOUSEBUTTONS );\r
271 #  endif\r
272 \r
273     default:\r
274         fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );\r
275         break;\r
276     }\r
277 \r
278     /* And now -- the failure. */\r
279     return -1;\r
280 }\r
281 \r
282 \r
283 int fgPlatformGlutLayerGet( GLenum eWhat )\r
284 {\r
285     /*\r
286      * This is easy as layers are not implemented ;-)\r
287      *\r
288      * XXX Can we merge the UNIX/X11 and WIN32 sections?  Or\r
289      * XXX is overlay support planned?\r
290      */\r
291     switch( eWhat )\r
292     {\r
293 \r
294     case GLUT_OVERLAY_POSSIBLE:\r
295 /*      return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,\r
296                                    PFD_OVERLAY_PLANE ); */\r
297       return 0 ;\r
298 \r
299     case GLUT_LAYER_IN_USE:\r
300         return GLUT_NORMAL;\r
301 \r
302     case GLUT_HAS_OVERLAY:\r
303         return 0;\r
304 \r
305     case GLUT_TRANSPARENT_INDEX:\r
306         /*\r
307          * Return just anything, which is always defined as zero\r
308          *\r
309          * XXX HUH?\r
310          */\r
311         return 0;\r
312 \r
313     case GLUT_NORMAL_DAMAGED:\r
314         /* XXX Actually I do not know. Maybe. */\r
315         return 0;\r
316 \r
317     case GLUT_OVERLAY_DAMAGED:\r
318         return -1;\r
319 \r
320     default:\r
321         fgWarning( "glutLayerGet(): missing enum handle %d", eWhat );\r
322         break;\r
323     }\r
324 \r
325     /* And fail. That's good. Programs do love failing. */\r
326     return -1;\r
327 }\r
328 \r
329 \r
330 \r