1f9966b7eed4777c44a850e6c71c1f1b44b4a29e
[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 "../Common/freeglut_internal.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  * Helper functions for getting client area from the window rect\r
37  * and the window rect from the client area given the style of the window\r
38  * (or a valid window pointer from which the style can be queried).\r
39  */\r
40 extern RECT fghGetClientArea( const SFG_Window *window, BOOL wantPosOutside );\r
41 extern void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth);\r
42 \r
43 \r
44 /* The following include file is available from SGI but is not standard:\r
45  *   #include <GL/wglext.h>\r
46  * So we copy the necessary parts out of it to support the multisampling query\r
47  */\r
48 #define WGL_SAMPLES_ARB                0x2042\r
49 \r
50 \r
51 \r
52 int fgPlatformGlutGet ( GLenum eWhat )\r
53 {\r
54     int returnValue ;\r
55     GLboolean boolValue ;\r
56 \r
57     int nsamples = 0;\r
58 \r
59     switch( eWhat )\r
60     {\r
61     case GLUT_WINDOW_NUM_SAMPLES:\r
62       glGetIntegerv(WGL_SAMPLES_ARB, &nsamples);\r
63       return nsamples;\r
64 \r
65     /* Handle the OpenGL inquiries */\r
66     case GLUT_WINDOW_RGBA:\r
67 #if defined(_WIN32_WCE)\r
68       boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */\r
69 #else\r
70       glGetBooleanv ( GL_RGBA_MODE, &boolValue );\r
71       returnValue = boolValue ? 1 : 0;\r
72 #endif\r
73       return returnValue;\r
74     case GLUT_WINDOW_DOUBLEBUFFER:\r
75 #if defined(_WIN32_WCE)\r
76       boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */\r
77 #else\r
78       glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue );\r
79       returnValue = boolValue ? 1 : 0;\r
80 #endif\r
81       return returnValue;\r
82     case GLUT_WINDOW_STEREO:\r
83 #if defined(_WIN32_WCE)\r
84       boolValue = (GLboolean)0;  /* WinCE doesn't support this feature */\r
85 #else\r
86       glGetBooleanv ( GL_STEREO, &boolValue );\r
87       returnValue = boolValue ? 1 : 0;\r
88 #endif\r
89       return returnValue;\r
90 \r
91     case GLUT_WINDOW_RED_SIZE:\r
92       glGetIntegerv ( GL_RED_BITS, &returnValue );\r
93       return returnValue;\r
94     case GLUT_WINDOW_GREEN_SIZE:\r
95       glGetIntegerv ( GL_GREEN_BITS, &returnValue );\r
96       return returnValue;\r
97     case GLUT_WINDOW_BLUE_SIZE:\r
98       glGetIntegerv ( GL_BLUE_BITS, &returnValue );\r
99       return returnValue;\r
100     case GLUT_WINDOW_ALPHA_SIZE:\r
101       glGetIntegerv ( GL_ALPHA_BITS, &returnValue );\r
102       return returnValue;\r
103     case GLUT_WINDOW_ACCUM_RED_SIZE:\r
104 #if defined(_WIN32_WCE)\r
105       returnValue = 0;  /* WinCE doesn't support this feature */\r
106 #else\r
107       glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue );\r
108 #endif\r
109       return returnValue;\r
110     case GLUT_WINDOW_ACCUM_GREEN_SIZE:\r
111 #if defined(_WIN32_WCE)\r
112       returnValue = 0;  /* WinCE doesn't support this feature */\r
113 #else\r
114       glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue );\r
115 #endif\r
116       return returnValue;\r
117     case GLUT_WINDOW_ACCUM_BLUE_SIZE:\r
118 #if defined(_WIN32_WCE)\r
119       returnValue = 0;  /* WinCE doesn't support this feature */\r
120 #else\r
121       glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue );\r
122 #endif\r
123       return returnValue;\r
124     case GLUT_WINDOW_ACCUM_ALPHA_SIZE:\r
125 #if defined(_WIN32_WCE)\r
126       returnValue = 0;  /* WinCE doesn't support this feature */\r
127 #else\r
128       glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue );\r
129 #endif\r
130       return returnValue;\r
131     case GLUT_WINDOW_DEPTH_SIZE:\r
132       glGetIntegerv ( GL_DEPTH_BITS, &returnValue );\r
133       return returnValue;\r
134 \r
135     case GLUT_WINDOW_BUFFER_SIZE:\r
136       returnValue = 1 ;                                      /* ????? */\r
137       return returnValue;\r
138     case GLUT_WINDOW_STENCIL_SIZE:\r
139       returnValue = 0 ;                                      /* ????? */\r
140       return returnValue;\r
141 \r
142     case GLUT_WINDOW_X:\r
143     case GLUT_WINDOW_Y:\r
144     case GLUT_WINDOW_WIDTH:\r
145     case GLUT_WINDOW_HEIGHT:\r
146     {\r
147         /*\r
148          *  There is considerable confusion about the "right thing to\r
149          *  do" concerning window  size and position.  GLUT itself is\r
150          *  not consistent between Windows and UNIX/X11; since\r
151          *  platform independence is a virtue for "freeglut", we\r
152          *  decided to break with GLUT's behaviour.\r
153          *\r
154          *  Under UNIX/X11, it is apparently not possible to get the\r
155          *  window border sizes in order to subtract them off the\r
156          *  window's initial position until some time after the window\r
157          *  has been created.  Therefore we decided on the following\r
158          *  behaviour, both under Windows and under UNIX/X11:\r
159          *  - When you create a window with position (x,y) and size\r
160          *    (w,h), the upper left hand corner of the outside of the\r
161          *    window is at (x,y) and the size of the drawable area  is\r
162          *    (w,h).\r
163          *  - When you query the size and position of the window--as\r
164          *    is happening here for Windows--"freeglut" will return\r
165          *    the size of the drawable area--the (w,h) that you\r
166          *    specified when you created the window--and the coordinates\r
167          *    of the upper left hand corner of the drawable\r
168          *    area--which is NOT the (x,y) you specified.\r
169          */\r
170 \r
171         RECT winRect;\r
172 \r
173         freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );\r
174 \r
175 #if defined(_WIN32_WCE)\r
176         GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );\r
177 #else\r
178         winRect = fghGetClientArea(fgStructure.CurrentWindow, FALSE);\r
179 #endif /* defined(_WIN32_WCE) */\r
180 \r
181         switch( eWhat )\r
182         {\r
183         case GLUT_WINDOW_X:      return winRect.left                ;\r
184         case GLUT_WINDOW_Y:      return winRect.top                 ;\r
185         case GLUT_WINDOW_WIDTH:  return winRect.right - winRect.left;\r
186         case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top;\r
187         }\r
188     }\r
189     break;\r
190 \r
191     case GLUT_WINDOW_BORDER_WIDTH :\r
192     case GLUT_WINDOW_HEADER_HEIGHT :\r
193 #if defined(_WIN32_WCE)\r
194         return 0;\r
195 #else\r
196         {\r
197             DWORD windowStyle;\r
198 \r
199             if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle)\r
200                 windowStyle = GetWindowLong(fgStructure.CurrentWindow->Window.Handle, GWL_STYLE);\r
201             else\r
202                 /* If no window, return sizes for a default window with title bar and border */\r
203                 windowStyle = WS_OVERLAPPEDWINDOW;\r
204             \r
205             switch( eWhat )\r
206             {\r
207             case GLUT_WINDOW_BORDER_WIDTH:\r
208                 {\r
209                     int xBorderWidth, yBorderWidth;\r
210                     fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);\r
211                     return xBorderWidth;\r
212                 }\r
213             case GLUT_WINDOW_HEADER_HEIGHT:\r
214                 /* 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
215                 return (windowStyle & WS_MAXIMIZEBOX)? GetSystemMetrics( SM_CYCAPTION ) : 0;\r
216             }\r
217         }\r
218 #endif /* defined(_WIN32_WCE) */\r
219 \r
220     case GLUT_DISPLAY_MODE_POSSIBLE:\r
221 #if defined(_WIN32_WCE)\r
222         return 0;\r
223 #else\r
224         return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,\r
225                                     PFD_MAIN_PLANE );\r
226 #endif /* defined(_WIN32_WCE) */\r
227 \r
228 \r
229     case GLUT_WINDOW_FORMAT_ID:\r
230 #if !defined(_WIN32_WCE)\r
231         if( fgStructure.CurrentWindow != NULL )\r
232             return GetPixelFormat( fgStructure.CurrentWindow->Window.pContext.Device );\r
233 #endif /* defined(_WIN32_WCE) */\r
234         return 0;\r
235 \r
236     default:\r
237         fgWarning( "glutGet(): missing enum handle %d", eWhat );\r
238         break;\r
239     }\r
240 \r
241         return -1;\r
242 }\r
243 \r
244 \r
245 int fgPlatformGlutDeviceGet ( GLenum eWhat )\r
246 {\r
247     switch( eWhat )\r
248     {\r
249     case GLUT_HAS_KEYBOARD:\r
250         /*\r
251          * Win32 is assumed a keyboard, and this cannot be queried,\r
252          * except for WindowsCE.\r
253          *\r
254          * X11 has a core keyboard by definition, although it can\r
255          * be present as a virtual/dummy keyboard. For now, there\r
256          * is no reliable way to tell if a real keyboard is present.\r
257          */\r
258 #if defined(_WIN32_CE)\r
259         return ( GetKeyboardStatus() & KBDI_KEYBOARD_PRESENT ) ? 1 : 0;\r
260 #   if FREEGLUT_LIB_PRAGMAS\r
261 #       pragma comment (lib,"Kbdui.lib")\r
262 #   endif\r
263 \r
264 #else\r
265         return 1;\r
266 #endif\r
267 \r
268     case GLUT_HAS_MOUSE:\r
269         /*\r
270          * MS Windows can be booted without a mouse.\r
271          */\r
272         return GetSystemMetrics( SM_MOUSEPRESENT );\r
273 \r
274     case GLUT_NUM_MOUSE_BUTTONS:\r
275 #  if defined(_WIN32_WCE)\r
276         return 1;\r
277 #  else\r
278         return GetSystemMetrics( SM_CMOUSEBUTTONS );\r
279 #  endif\r
280 \r
281     default:\r
282         fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );\r
283         break;\r
284     }\r
285 \r
286     /* And now -- the failure. */\r
287     return -1;\r
288 }\r
289 \r
290 \r
291 int fgPlatformGlutLayerGet( GLenum eWhat )\r
292 {\r
293     /*\r
294      * This is easy as layers are not implemented ;-)\r
295      *\r
296      * XXX Can we merge the UNIX/X11 and WIN32 sections?  Or\r
297      * XXX is overlay support planned?\r
298      */\r
299     switch( eWhat )\r
300     {\r
301 \r
302     case GLUT_OVERLAY_POSSIBLE:\r
303 /*      return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,\r
304                                    PFD_OVERLAY_PLANE ); */\r
305       return 0 ;\r
306 \r
307     case GLUT_LAYER_IN_USE:\r
308         return GLUT_NORMAL;\r
309 \r
310     case GLUT_HAS_OVERLAY:\r
311         return 0;\r
312 \r
313     case GLUT_TRANSPARENT_INDEX:\r
314         /*\r
315          * Return just anything, which is always defined as zero\r
316          *\r
317          * XXX HUH?\r
318          */\r
319         return 0;\r
320 \r
321     case GLUT_NORMAL_DAMAGED:\r
322         /* XXX Actually I do not know. Maybe. */\r
323         return 0;\r
324 \r
325     case GLUT_OVERLAY_DAMAGED:\r
326         return -1;\r
327 \r
328     default:\r
329         fgWarning( "glutLayerGet(): missing enum handle %d", eWhat );\r
330         break;\r
331     }\r
332 \r
333     /* And fail. That's good. Programs do love failing. */\r
334     return -1;\r
335 }\r
336 \r
337 \r
338 \r