Moving the "\freeglut_xinput.c" file from the Common directory to the x11 directory...
[freeglut] / src / Common / freeglut_callbacks.c
1 /*\r
2  * freeglut_callbacks.c\r
3  *\r
4  * The callbacks setting methods.\r
5  *\r
6  * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.\r
7  * Written by Pawel W. Olszta, <olszta@sourceforge.net>\r
8  * Creation date: Fri Dec 3 1999\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.h"\r
30 \r
31 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */\r
32 \r
33 /*\r
34  * All of the callbacks setting methods can be generalized to this:\r
35  */\r
36 #define SET_CALLBACK(a)                                         \\r
37 do                                                              \\r
38 {                                                               \\r
39     if( fgStructure.CurrentWindow == NULL )                     \\r
40         return;                                                 \\r
41     SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback ); \\r
42 } while( 0 )\r
43 \r
44 /*\r
45  * Sets the Display callback for the current window\r
46  */\r
47 void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) )\r
48 {\r
49     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFunc" );\r
50     if( !callback )\r
51         fgError( "Fatal error in program.  NULL display callback not "\r
52                  "permitted in GLUT 3.0+ or freeglut 2.0.1+" );\r
53     SET_CALLBACK( Display );\r
54 }\r
55 \r
56 /*\r
57  * Sets the Reshape callback for the current window\r
58  */\r
59 void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) )\r
60 {\r
61     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFunc" );\r
62     SET_CALLBACK( Reshape );\r
63 }\r
64 \r
65 /*\r
66  * Sets the Keyboard callback for the current window\r
67  */\r
68 void FGAPIENTRY glutKeyboardFunc( void (* callback)\r
69                                   ( unsigned char, int, int ) )\r
70 {\r
71     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutKeyboardFunc" );\r
72     SET_CALLBACK( Keyboard );\r
73 }\r
74 \r
75 /*\r
76  * Sets the Special callback for the current window\r
77  */\r
78 void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) )\r
79 {\r
80     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpecialFunc" );\r
81     SET_CALLBACK( Special );\r
82 }\r
83 \r
84 /*\r
85  * Sets the global idle callback\r
86  */\r
87 void FGAPIENTRY glutIdleFunc( void (* callback)( void ) )\r
88 {\r
89     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" );\r
90     fgState.IdleCallback = callback;\r
91 }\r
92 \r
93 /*\r
94  * Sets the Timer callback for the current window\r
95  */\r
96 void FGAPIENTRY glutTimerFunc( unsigned int timeOut, void (* callback)( int ),\r
97                                int timerID )\r
98 {\r
99     SFG_Timer *timer, *node;\r
100 \r
101     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" );\r
102 \r
103     if( (timer = fgState.FreeTimers.Last) )\r
104     {\r
105         fgListRemove( &fgState.FreeTimers, &timer->Node );\r
106     }\r
107     else\r
108     {\r
109         if( ! (timer = malloc(sizeof(SFG_Timer))) )\r
110             fgError( "Fatal error: "\r
111                      "Memory allocation failure in glutTimerFunc()" );\r
112     }\r
113 \r
114     timer->Callback  = callback;\r
115     timer->ID        = timerID;\r
116     timer->TriggerTime = fgElapsedTime() + timeOut;\r
117 \r
118     for( node = fgState.Timers.First; node; node = node->Node.Next )\r
119     {\r
120         if( node->TriggerTime > timer->TriggerTime )\r
121             break;\r
122     }\r
123 \r
124     fgListInsert( &fgState.Timers, &node->Node, &timer->Node );\r
125 }\r
126 \r
127 /*\r
128  * Sets the Visibility callback for the current window.\r
129  */\r
130 static void fghVisibility( int status )\r
131 {\r
132     int glut_status = GLUT_VISIBLE;\r
133 \r
134     FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Visibility Callback" );\r
135     freeglut_return_if_fail( fgStructure.CurrentWindow );\r
136 \r
137     if( ( GLUT_HIDDEN == status )  || ( GLUT_FULLY_COVERED == status ) )\r
138         glut_status = GLUT_NOT_VISIBLE;\r
139     INVOKE_WCB( *( fgStructure.CurrentWindow ), Visibility, ( glut_status ) );\r
140 }\r
141 \r
142 void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) )\r
143 {\r
144     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFunc" );\r
145     SET_CALLBACK( Visibility );\r
146 \r
147     if( callback )\r
148         glutWindowStatusFunc( fghVisibility );\r
149     else\r
150         glutWindowStatusFunc( NULL );\r
151 }\r
152 \r
153 /*\r
154  * Sets the keyboard key release callback for the current window\r
155  */\r
156 void FGAPIENTRY glutKeyboardUpFunc( void (* callback)\r
157                                     ( unsigned char, int, int ) )\r
158 {\r
159     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutKeyboardUpFunc" );\r
160     SET_CALLBACK( KeyboardUp );\r
161 }\r
162 \r
163 /*\r
164  * Sets the special key release callback for the current window\r
165  */\r
166 void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) )\r
167 {\r
168     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpecialUpFunc" );\r
169     SET_CALLBACK( SpecialUp );\r
170 }\r
171 \r
172 /*\r
173  * Sets the joystick callback and polling rate for the current window\r
174  */\r
175 void FGAPIENTRY glutJoystickFunc( void (* callback)\r
176                                   ( unsigned int, int, int, int ),\r
177                                   int pollInterval )\r
178 {\r
179     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFunc" );\r
180     fgInitialiseJoysticks ();\r
181 \r
182     if ( ( ( fgStructure.CurrentWindow->State.JoystickPollRate < 0 ) ||\r
183            !FETCH_WCB(*fgStructure.CurrentWindow,Joystick) ) &&  /* Joystick callback was disabled */\r
184          ( callback && ( pollInterval >= 0 ) ) )               /* but is now enabled */\r
185         ++fgState.NumActiveJoysticks;\r
186     else if ( ( ( fgStructure.CurrentWindow->State.JoystickPollRate >= 0 ) &&\r
187                 FETCH_WCB(*fgStructure.CurrentWindow,Joystick) ) &&  /* Joystick callback was enabled */\r
188               ( !callback || ( pollInterval < 0 ) ) )              /* but is now disabled */\r
189         --fgState.NumActiveJoysticks;\r
190 \r
191     SET_CALLBACK( Joystick );\r
192     fgStructure.CurrentWindow->State.JoystickPollRate = pollInterval;\r
193 \r
194     fgStructure.CurrentWindow->State.JoystickLastPoll =\r
195         fgElapsedTime() - fgStructure.CurrentWindow->State.JoystickPollRate;\r
196 \r
197     if( fgStructure.CurrentWindow->State.JoystickLastPoll < 0 )\r
198         fgStructure.CurrentWindow->State.JoystickLastPoll = 0;\r
199 }\r
200 \r
201 /*\r
202  * Sets the mouse callback for the current window\r
203  */\r
204 void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) )\r
205 {\r
206     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMouseFunc" );\r
207     SET_CALLBACK( Mouse );\r
208 }\r
209 \r
210 /*\r
211  * Sets the mouse wheel callback for the current window\r
212  */\r
213 void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) )\r
214 {\r
215     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMouseWheelFunc" );\r
216     SET_CALLBACK( MouseWheel );\r
217 }\r
218 \r
219 /*\r
220  * Sets the mouse motion callback for the current window (one or more buttons\r
221  * are pressed)\r
222  */\r
223 void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) )\r
224 {\r
225     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMotionFunc" );\r
226     SET_CALLBACK( Motion );\r
227 }\r
228 \r
229 /*\r
230  * Sets the passive mouse motion callback for the current window (no mouse\r
231  * buttons are pressed)\r
232  */\r
233 void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) )\r
234 {\r
235     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPassiveMotionFunc" );\r
236     SET_CALLBACK( Passive );\r
237 }\r
238 \r
239 /*\r
240  * Window mouse entry/leave callback\r
241  */\r
242 void FGAPIENTRY glutEntryFunc( void (* callback)( int ) )\r
243 {\r
244     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutEntryFunc" );\r
245     SET_CALLBACK( Entry );\r
246 }\r
247 \r
248 /*\r
249  * Window destruction callbacks\r
250  */\r
251 void FGAPIENTRY glutCloseFunc( void (* callback)( void ) )\r
252 {\r
253     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCloseFunc" );\r
254     SET_CALLBACK( Destroy );\r
255 }\r
256 \r
257 void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) )\r
258 {\r
259     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWMCloseFunc" );\r
260     glutCloseFunc( callback );\r
261 }\r
262 \r
263 /* A. Donev: Destruction callback for menus */\r
264 void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) )\r
265 {\r
266     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFunc" );\r
267     if( fgStructure.CurrentMenu )\r
268         fgStructure.CurrentMenu->Destroy = callback;\r
269 }\r
270 \r
271 /*\r
272  * Deprecated version of glutMenuStatusFunc callback setting method\r
273  */\r
274 void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) )\r
275 {\r
276     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStateFunc" );\r
277     fgState.MenuStateCallback = callback;\r
278 }\r
279 \r
280 /*\r
281  * Sets the global menu status callback for the current window\r
282  */\r
283 void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) )\r
284 {\r
285     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" );\r
286     fgState.MenuStatusCallback = callback;\r
287 }\r
288 \r
289 /*\r
290  * Sets the overlay display callback for the current window\r
291  */\r
292 void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) )\r
293 {\r
294     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutOverlayDisplayFunc" );\r
295     SET_CALLBACK( OverlayDisplay );\r
296 }\r
297 \r
298 /*\r
299  * Sets the window status callback for the current window\r
300  */\r
301 void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) )\r
302 {\r
303     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWindowStatusFunc" );\r
304     SET_CALLBACK( WindowStatus );\r
305 }\r
306 \r
307 /*\r
308  * Sets the spaceball motion callback for the current window\r
309  */\r
310 void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) )\r
311 {\r
312     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFunc" );\r
313     fgInitialiseSpaceball();\r
314 \r
315     SET_CALLBACK( SpaceMotion );\r
316 }\r
317 \r
318 /*\r
319  * Sets the spaceball rotate callback for the current window\r
320  */\r
321 void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) )\r
322 {\r
323     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFunc" );\r
324     fgInitialiseSpaceball();\r
325 \r
326     SET_CALLBACK( SpaceRotation );\r
327 }\r
328 \r
329 /*\r
330  * Sets the spaceball button callback for the current window\r
331  */\r
332 void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) )\r
333 {\r
334     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFunc" );\r
335     fgInitialiseSpaceball();\r
336 \r
337     SET_CALLBACK( SpaceButton );\r
338 }\r
339 \r
340 /*\r
341  * Sets the button box callback for the current window\r
342  */\r
343 void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) )\r
344 {\r
345     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutButtonBoxFunc" );\r
346     SET_CALLBACK( ButtonBox );\r
347 }\r
348 \r
349 /*\r
350  * Sets the dials box callback for the current window\r
351  */\r
352 void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) )\r
353 {\r
354     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDialsFunc" );\r
355     SET_CALLBACK( Dials );\r
356 }\r
357 \r
358 /*\r
359  * Sets the tablet motion callback for the current window\r
360  */\r
361 void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) )\r
362 {\r
363     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTabletMotionFunc" );\r
364     SET_CALLBACK( TabletMotion );\r
365 }\r
366 \r
367 /*\r
368  * Sets the tablet buttons callback for the current window\r
369  */\r
370 void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) )\r
371 {\r
372     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTabletButtonFunc" );\r
373     SET_CALLBACK( TabletButton );\r
374 }\r
375 \r
376 /*\r
377  * Sets the multi-pointer entry callback for the current window\r
378  */\r
379 void FGAPIENTRY glutMultiEntryFunc( void (* callback)(int, int ) )\r
380 {\r
381     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiEntryFunc" );\r
382     SET_CALLBACK( MultiEntry );\r
383 }\r
384 \r
385 /*\r
386  * Sets the multi-pointer button callback for the current window\r
387  */\r
388 void FGAPIENTRY glutMultiButtonFunc( void (* callback)(int, int, int, int, int ) )\r
389 {\r
390     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiButtonFunc" );\r
391     SET_CALLBACK( MultiButton );\r
392 }\r
393 \r
394 /*\r
395  * Sets the multi-pointer motion callback for the current window\r
396  */\r
397 void FGAPIENTRY glutMultiMotionFunc( void (* callback)(int, int, int ) )\r
398 {\r
399     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiMotionFunc" );\r
400     SET_CALLBACK( MultiMotion );\r
401 }\r
402 \r
403 /*\r
404  * Sets the multi-pointer passive motion callback for the current window\r
405  */\r
406 void FGAPIENTRY glutMultiPassiveFunc( void (* callback)(int, int, int ) )\r
407 {\r
408     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiPassiveFunc" );\r
409     SET_CALLBACK( MultiPassive );\r
410 }\r
411 \r
412 /*** END OF FILE ***/\r