1 | /* |
2 | * fg_internal.h |
3 | * |
4 | * The freeglut library private include file. |
5 | * |
6 | * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. |
7 | * Written by Pawel W. Olszta, <olszta@sourceforge.net> |
8 | * Creation date: Thu Dec 2 1999 |
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 | #ifndef FREEGLUT_INTERNAL_H |
29 | #define FREEGLUT_INTERNAL_H |
30 | |
31 | #ifdef HAVE_CONFIG_H |
32 | # include "config.h" |
33 | #endif |
34 | |
35 | #include "fg_version.h" |
36 | |
37 | /* Freeglut is intended to function under all Unix/X11 and Win32 platforms. */ |
38 | /* XXX: Don't all MS-Windows compilers (except Cygwin) have _WIN32 defined? |
39 | * XXX: If so, remove the first set of defined()'s below. |
40 | */ |
41 | #if !defined(TARGET_HOST_POSIX_X11) && !defined(TARGET_HOST_MS_WINDOWS) && !defined(TARGET_HOST_MAC_OSX) && !defined(TARGET_HOST_SOLARIS) |
42 | #if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__) \ |
43 | || defined(_WIN32) || defined(_WIN32_WCE) \ |
44 | || ( defined(__CYGWIN__) && defined(X_DISPLAY_MISSING) ) |
45 | # define TARGET_HOST_MS_WINDOWS 1 |
46 | |
47 | #elif defined (__ANDROID__) |
48 | # define TARGET_HOST_ANDROID 1 |
49 | |
50 | #elif defined (__QNXNTO__) || defined (__PLAYBOOK__) |
51 | # define TARGET_HOST_BLACKBERRY 1 |
52 | |
53 | #elif defined(__posix__) || defined(__unix__) || defined(__linux__) || defined(__sun) |
54 | # define TARGET_HOST_POSIX_X11 1 |
55 | |
56 | #elif defined(__APPLE__) |
57 | /* This is a placeholder until we get native OSX support ironed out -- JFF 11/18/09 */ |
58 | # define TARGET_HOST_POSIX_X11 1 |
59 | /* # define TARGET_HOST_MAC_OSX 1 */ |
60 | |
61 | #else |
62 | # error "Unrecognized target host!" |
63 | |
64 | #endif |
65 | #endif |
66 | |
67 | /* Detect both SunPro and gcc compilers on Sun Solaris */ |
68 | #if defined (__SVR4) && defined (__sun) |
69 | # define TARGET_HOST_SOLARIS 1 |
70 | #endif |
71 | |
72 | #ifndef TARGET_HOST_MS_WINDOWS |
73 | # define TARGET_HOST_MS_WINDOWS 0 |
74 | #endif |
75 | |
76 | #ifndef TARGET_HOST_ANDROID |
77 | # define TARGET_HOST_ANDROID 0 |
78 | #endif |
79 | |
80 | #ifndef TARGET_HOST_BLACKBERRY |
81 | # define TARGET_HOST_BLACKBERRY 0 |
82 | #endif |
83 | |
84 | #ifndef TARGET_HOST_POSIX_X11 |
85 | # define TARGET_HOST_POSIX_X11 0 |
86 | #endif |
87 | |
88 | #ifndef TARGET_HOST_MAC_OSX |
89 | # define TARGET_HOST_MAC_OSX 0 |
90 | #endif |
91 | |
92 | #ifndef TARGET_HOST_SOLARIS |
93 | # define TARGET_HOST_SOLARIS 0 |
94 | #endif |
95 | |
96 | /* -- FIXED CONFIGURATION LIMITS ------------------------------------------- */ |
97 | |
98 | #define 3 |
99 | |
100 | /* These files should be available on every platform. */ |
101 | #include <stdio.h> |
102 | #include <string.h> |
103 | #include <math.h> |
104 | #include <stdlib.h> |
105 | #include <stdarg.h> |
106 | |
107 | /* These are included based on autoconf directives. */ |
108 | #ifdef HAVE_SYS_TYPES_H |
109 | # include <sys/types.h> |
110 | #endif |
111 | #ifdef HAVE_UNISTD_H |
112 | # include <unistd.h> |
113 | #endif |
114 | #ifdef TIME_WITH_SYS_TIME |
115 | # include <sys/time.h> |
116 | # include <time.h> |
117 | #elif defined(HAVE_SYS_TIME_H) |
118 | # include <sys/time.h> |
119 | #else |
120 | # include <time.h> |
121 | #endif |
122 | |
123 | /* -- AUTOCONF HACKS --------------------------------------------------------*/ |
124 | |
125 | /* XXX: Update autoconf to avoid these. |
126 | * XXX: Are non-POSIX platforms intended not to use autoconf? |
127 | * If so, perhaps there should be a config_guess.h for them. Alternatively, |
128 | * config guesses could be placed above, just after the config.h exclusion. |
129 | */ |
130 | #if defined(__FreeBSD__) || defined(__NetBSD__) |
131 | # define HAVE_USB_JS 1 |
132 | # if defined(__NetBSD__) || ( defined(__FreeBSD__) && __FreeBSD_version >= 500000) |
133 | # define HAVE_USBHID_H 1 |
134 | # endif |
135 | #endif |
136 | |
137 | #if defined(_MSC_VER) || defined(__WATCOMC__) |
138 | /* strdup() is non-standard, for all but POSIX-2001 */ |
139 | #define strdup _strdup |
140 | #endif |
141 | |
142 | /* M_PI is non-standard (defined by BSD, not ISO-C) */ |
143 | #ifndef M_PI |
144 | # define M_PI 3.14159265358979323846 |
145 | #endif |
146 | |
147 | #ifdef HAVE_STDBOOL_H |
148 | # include <stdbool.h> |
149 | # ifndef TRUE |
150 | # define TRUE true |
151 | # endif |
152 | # ifndef FALSE |
153 | # define FALSE false |
154 | # endif |
155 | #else |
156 | # ifndef TRUE |
157 | # define TRUE 1 |
158 | # endif |
159 | # ifndef FALSE |
160 | # define FALSE 0 |
161 | # endif |
162 | #endif |
163 | |
164 | /* General defines */ |
165 | #define INVALID_MODIFIERS 0xffffffff |
166 | |
167 | /* FreeGLUT internal time type */ |
168 | #if defined(HAVE_STDINT_H) |
169 | # include <stdint.h> |
170 | typedef uint64_t fg_time_t; |
171 | #elif defined(HAVE_INTTYPES_H) |
172 | # include <inttypes.h> |
173 | typedef uint64_t fg_time_t; |
174 | #elif defined(HAVE_U__INT64) |
175 | typedef unsigned __int64 fg_time_t; |
176 | #elif defined(HAVE_ULONG_LONG) |
177 | typedef unsigned long long fg_time_t; |
178 | #else |
179 | typedef unsigned long fg_time_t; |
180 | #endif |
181 | |
182 | #ifndef __fg_unused |
183 | # ifdef __GNUC__ |
184 | # define __fg_unused __attribute__((unused)) |
185 | # else |
186 | # define __fg_unused |
187 | # endif |
188 | #endif |
189 | |
190 | /* Platform-specific includes */ |
191 | #if TARGET_HOST_POSIX_X11 |
192 | #include "x11/fg_internal_x11.h" |
193 | #endif |
194 | #if TARGET_HOST_MS_WINDOWS |
195 | #include "mswin/fg_internal_mswin.h" |
196 | #endif |
197 | #if TARGET_HOST_ANDROID |
198 | #include "android/fg_internal_android.h" |
199 | #endif |
200 | #if TARGET_HOST_BLACKBERRY |
201 | #include "blackberry/fg_internal_blackberry.h" |
202 | #endif |
203 | |
204 | |
205 | /* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ |
206 | |
207 | /* Freeglut callbacks type definitions */ |
208 | typedef void (* FGCBDisplay )( void ); |
209 | typedef void (* FGCBReshape )( int, int ); |
210 | typedef void (* FGCBPosition )( int, int ); |
211 | typedef void (* FGCBVisibility )( int ); |
212 | typedef void (* FGCBKeyboard )( unsigned char, int, int ); |
213 | typedef void (* FGCBKeyboardExt )( int, int, int ); |
214 | typedef void (* FGCBKeyboardDown )( unsigned char, int, int ); |
215 | typedef void (* FGCBKeyboardUp )( unsigned char, int, int ); |
216 | typedef void (* FGCBSpecial )( int, int, int ); |
217 | typedef void (* FGCBSpecialUp )( int, int, int ); |
218 | typedef void (* FGCBMouse )( int, int, int, int ); |
219 | typedef void (* FGCBMouseWheel )( int, int, int, int ); |
220 | typedef void (* FGCBMotion )( int, int ); |
221 | typedef void (* FGCBPassive )( int, int ); |
222 | typedef void (* FGCBEntry )( int ); |
223 | typedef void (* FGCBWindowStatus )( int ); |
224 | typedef void (* FGCBJoystick )( unsigned int, int, int, int ); |
225 | typedef void (* FGCBOverlayDisplay)( void ); |
226 | typedef void (* FGCBSpaceMotion )( int, int, int ); |
227 | typedef void (* FGCBSpaceRotation )( int, int, int ); |
228 | typedef void (* FGCBSpaceButton )( int, int ); |
229 | typedef void (* FGCBDials )( int, int ); |
230 | typedef void (* FGCBButtonBox )( int, int ); |
231 | typedef void (* FGCBTabletMotion )( int, int ); |
232 | typedef void (* FGCBTabletButton )( int, int, int, int ); |
233 | typedef void (* FGCBDestroy )( void ); /* Used for both window and menu destroy callbacks */ |
234 | |
235 | typedef void (* FGCBMultiEntry )( int, int ); |
236 | typedef void (* FGCBMultiButton )( int, int, int, int, int ); |
237 | typedef void (* FGCBMultiMotion )( int, int, int ); |
238 | typedef void (* FGCBMultiPassive )( int, int, int ); |
239 | |
240 | typedef void (* FGCBInitContext)(); |
241 | typedef void (* FGCBAppStatus)(int); |
242 | |
243 | /* The global callbacks type definitions */ |
244 | typedef void (* FGCBIdle )( void ); |
245 | typedef void (* FGCBTimer )( int ); |
246 | typedef void (* )( int ); |
247 | typedef void (* )( int, int, int ); |
248 | |
249 | /* The callback used when creating/using menus */ |
250 | typedef void (* )( int ); |
251 | |
252 | /* The FreeGLUT error/warning handler type definition */ |
253 | typedef void (* FGError ) ( const char *fmt, va_list ap); |
254 | typedef void (* FGWarning ) ( const char *fmt, va_list ap); |
255 | |
256 | |
257 | /* A list structure */ |
258 | typedef struct tagSFG_List SFG_List; |
259 | struct tagSFG_List |
260 | { |
261 | void *First; |
262 | void *Last; |
263 | }; |
264 | |
265 | /* A list node structure */ |
266 | typedef struct tagSFG_Node SFG_Node; |
267 | struct tagSFG_Node |
268 | { |
269 | void *Next; |
270 | void *Prev; |
271 | }; |
272 | |
273 | /* A helper structure holding two ints and a boolean */ |
274 | typedef struct tagSFG_XYUse SFG_XYUse; |
275 | struct tagSFG_XYUse |
276 | { |
277 | GLint X, Y; /* The two integers... */ |
278 | GLboolean Use; /* ...and a single boolean. */ |
279 | }; |
280 | |
281 | /* |
282 | * An enumeration containing the state of the GLUT execution: |
283 | * initializing, running, or stopping |
284 | */ |
285 | typedef enum |
286 | { |
287 | GLUT_EXEC_STATE_INIT, |
288 | GLUT_EXEC_STATE_RUNNING, |
289 | GLUT_EXEC_STATE_STOP |
290 | } fgExecutionState ; |
291 | |
292 | /* This structure holds different freeglut settings */ |
293 | typedef struct tagSFG_State SFG_State; |
294 | struct tagSFG_State |
295 | { |
296 | SFG_XYUse Position; /* The default windows' position */ |
297 | SFG_XYUse Size; /* The default windows' size */ |
298 | unsigned int DisplayMode; /* Display mode for new windows */ |
299 | |
300 | GLboolean Initialised; /* freeglut has been initialised */ |
301 | |
302 | int DirectContext; /* Direct rendering state */ |
303 | |
304 | GLboolean ForceIconic; /* New top windows are iconified */ |
305 | GLboolean UseCurrentContext; /* New windows share with current */ |
306 | |
307 | GLboolean GLDebugSwitch; /* OpenGL state debugging switch */ |
308 | GLboolean XSyncSwitch; /* X11 sync protocol switch */ |
309 | |
310 | int KeyRepeat; /* Global key repeat mode. */ |
311 | int Modifiers; /* Current ALT/SHIFT/CTRL state */ |
312 | |
313 | GLuint FPSInterval; /* Interval between FPS printfs */ |
314 | GLuint SwapCount; /* Count of glutSwapBuffer calls */ |
315 | GLuint SwapTime; /* Time of last SwapBuffers */ |
316 | |
317 | fg_time_t Time; /* Time that glutInit was called */ |
318 | SFG_List Timers; /* The freeglut timer hooks */ |
319 | SFG_List FreeTimers; /* The unused timer hooks */ |
320 | |
321 | FGCBIdle IdleCallback; /* The global idle callback */ |
322 | |
323 | int ; /* Num. of currently active menus */ |
324 | FGCBMenuState ; /* Menu callbacks are global */ |
325 | FGCBMenuStatus ; |
326 | void* ; /* Font to be used for newly created menus */ |
327 | |
328 | SFG_XYUse GameModeSize; /* Game mode screen's dimensions */ |
329 | int GameModeDepth; /* The pixel depth for game mode */ |
330 | int GameModeRefresh; /* The refresh rate for game mode */ |
331 | |
332 | int ActionOnWindowClose; /* Action when user closes window */ |
333 | |
334 | fgExecutionState ExecState; /* Used for GLUT termination */ |
335 | char *ProgramName; /* Name of the invoking program */ |
336 | GLboolean JoysticksInitialised; /* Only initialize if application calls for them */ |
337 | int NumActiveJoysticks; /* Number of active joysticks (callback defined and positive pollrate) -- if zero, don't poll joysticks */ |
338 | GLboolean InputDevsInitialised; /* Only initialize if application calls for them */ |
339 | |
340 | int MouseWheelTicks; /* Number of ticks the mouse wheel has turned */ |
341 | |
342 | int AuxiliaryBufferNumber; /* Number of auxiliary buffers */ |
343 | int SampleNumber; /* Number of samples per pixel */ |
344 | |
345 | GLboolean SkipStaleMotion; /* skip stale motion events */ |
346 | |
347 | GLboolean StrokeFontDrawJoinDots;/* Draw dots between line segments of stroke fonts? */ |
348 | |
349 | int MajorVersion; /* Major OpenGL context version */ |
350 | int MinorVersion; /* Minor OpenGL context version */ |
351 | int ContextFlags; /* OpenGL context flags */ |
352 | int ContextProfile; /* OpenGL context profile */ |
353 | int HasOpenGL20; /* fgInitGL2 could find all OpenGL 2.0 functions */ |
354 | FGError ErrorFunc; /* User defined error handler */ |
355 | FGWarning WarningFunc; /* User defined warning handler */ |
356 | }; |
357 | |
358 | /* The structure used by display initialization in fg_init.c */ |
359 | typedef struct tagSFG_Display SFG_Display; |
360 | struct tagSFG_Display |
361 | { |
362 | SFG_PlatformDisplay pDisplay; |
363 | |
364 | int ScreenWidth; /* The screen's width in pixels */ |
365 | int ScreenHeight; /* The screen's height in pixels */ |
366 | int ScreenWidthMM; /* The screen's width in milimeters */ |
367 | int ScreenHeightMM; /* The screen's height in milimeters */ |
368 | }; |
369 | |
370 | |
371 | /* The user can create any number of timer hooks */ |
372 | typedef struct tagSFG_Timer SFG_Timer; |
373 | struct tagSFG_Timer |
374 | { |
375 | SFG_Node Node; |
376 | int ID; /* The timer ID integer */ |
377 | FGCBTimer Callback; /* The timer callback */ |
378 | fg_time_t TriggerTime; /* The timer trigger time */ |
379 | }; |
380 | |
381 | /* |
382 | * A window and its OpenGL context. The contents of this structure |
383 | * are highly dependent on the target operating system we aim at... |
384 | */ |
385 | typedef struct tagSFG_Context SFG_Context; |
386 | struct tagSFG_Context |
387 | { |
388 | SFG_WindowHandleType Handle; /* The window's handle */ |
389 | SFG_WindowContextType Context; /* The window's OpenGL/WGL context */ |
390 | |
391 | SFG_PlatformContext pContext; /* The window's FBConfig (X11) or device context (Windows) */ |
392 | |
393 | int DoubleBuffered; /* Treat the window as double-buffered */ |
394 | |
395 | /* When drawing geometry to vertex attribute buffers, user specifies |
396 | * the attribute indices for vertices, normals and/or texture coords |
397 | * to freeglut. Those are stored here |
398 | */ |
399 | GLint attribute_v_coord; |
400 | GLint attribute_v_normal; |
401 | GLint attribute_v_texture; |
402 | }; |
403 | |
404 | |
405 | /* |
406 | * Bitmasks indicating the different kinds of |
407 | * actions that can be scheduled for a window. |
408 | */ |
409 | #define GLUT_INIT_WORK (1<<0) |
410 | #define GLUT_VISIBILITY_WORK (1<<1) |
411 | #define GLUT_POSITION_WORK (1<<2) |
412 | #define GLUT_SIZE_WORK (1<<3) |
413 | #define GLUT_ZORDER_WORK (1<<4) |
414 | #define GLUT_FULL_SCREEN_WORK (1<<5) |
415 | #define GLUT_DISPLAY_WORK (1<<6) |
416 | |
417 | /* |
418 | * An enumeration containing the state of the GLUT execution: |
419 | * initializing, running, or stopping |
420 | */ |
421 | typedef enum |
422 | { |
423 | DesireHiddenState, |
424 | DesireIconicState, |
425 | DesireNormalState |
426 | } fgDesiredVisibility ; |
427 | |
428 | /* |
429 | * There is considerable confusion about the "right thing to |
430 | * do" concerning window size and position. GLUT itself is |
431 | * not consistent between Windows and UNIX/X11; since |
432 | * platform independence is a virtue for "freeglut", we |
433 | * decided to break with GLUT's behaviour. |
434 | * |
435 | * Under UNIX/X11, it is apparently not possible to get the |
436 | * window border sizes in order to subtract them off the |
437 | * window's initial position until some time after the window |
438 | * has been created. Therefore we decided on the following |
439 | * behaviour, both under Windows and under UNIX/X11: |
440 | * - When you create a window with position (x,y) and size |
441 | * (w,h), the upper left hand corner of the outside of the |
442 | * window is at (x,y) and the size of the drawable area is |
443 | * (w,h). |
444 | * - When you query the size and position of the window--as |
445 | * is happening here for Windows--"freeglut" will return |
446 | * the size of the drawable area--the (w,h) that you |
447 | * specified when you created the window--and the coordinates |
448 | * of the upper left hand corner of the drawable area, i.e. |
449 | * of the client rect--which is NOT the (x,y) you specified. |
450 | */ |
451 | typedef struct tagSFG_WindowState SFG_WindowState; |
452 | struct tagSFG_WindowState /* as per notes above, sizes always refer to the client area (thus without the window decorations) */ |
453 | { |
454 | /* window state - size, position, look */ |
455 | int Xpos; /* Window's top-left of client area, X-coordinate */ |
456 | int Ypos; /* Window's top-left of client area, Y-coordinate */ |
457 | int Width; /* Window's width in pixels */ |
458 | int Height; /* The same about the height */ |
459 | GLboolean Visible; /* Is the window visible now? Not using fgVisibilityState as we only care if visible or not */ |
460 | int Cursor; /* The currently selected cursor style */ |
461 | GLboolean IsFullscreen; /* is the window fullscreen? */ |
462 | |
463 | /* FreeGLUT operations are deferred, that is, window moving, resizing, |
464 | * Z-order changing, making full screen or not do not happen immediately |
465 | * upon the user's request, but only in the next iteration of the main |
466 | * loop, before the display callback is called. This allows multiple |
467 | * reshape, position, etc requests to be combined into one and is |
468 | * compatible with the way GLUT does things. Callbacks get triggered |
469 | * based on the feedback/messages/notifications from the window manager. |
470 | * Below here we define what work should be done, as well as the relevant |
471 | * parameters for this work. |
472 | */ |
473 | unsigned int WorkMask; /* work (resize, etc) to be done on the window */ |
474 | int DesiredXpos; /* desired X location */ |
475 | int DesiredYpos; /* desired Y location */ |
476 | int DesiredWidth; /* desired window width */ |
477 | int DesiredHeight; /* desired window height */ |
478 | int DesiredZOrder; /* desired window Z Order position */ |
479 | fgDesiredVisibility DesiredVisibility;/* desired visibility (hidden, iconic, shown/normal) */ |
480 | |
481 | SFG_PlatformWindowState pWState; /* Window width/height (X11) or rectangle/style (Windows) from before a resize, and other stuff only needed on specific platforms */ |
482 | |
483 | long JoystickPollRate; /* The joystick polling rate */ |
484 | fg_time_t JoystickLastPoll; /* When the last poll happened */ |
485 | |
486 | int MouseX, MouseY; /* The most recent mouse position */ |
487 | |
488 | GLboolean IgnoreKeyRepeat; /* Whether to ignore key repeat. */ |
489 | |
490 | GLboolean VisualizeNormals; /* When drawing objects, draw vectors representing the normals as well? */ |
491 | }; |
492 | |
493 | |
494 | /* |
495 | * A generic function pointer. We should really use the GLUTproc type |
496 | * defined in freeglut_ext.h, but if we include that header in this file |
497 | * a bunch of other stuff (font-related) blows up! |
498 | */ |
499 | typedef void (*SFG_Proc)(); |
500 | |
501 | |
502 | /* |
503 | * SET_WCB() is used as: |
504 | * |
505 | * SET_WCB( window, cbname, func ); |
506 | * |
507 | * ...where {window} is the freeglut window to set the callback, |
508 | * {cbname} is the window-specific callback to set, |
509 | * {func} is a function-pointer. |
510 | * |
511 | * Originally, {FETCH_WCB( ... ) = func} was rather sloppily used, |
512 | * but this can cause warnings because the FETCH_WCB() macro type- |
513 | * casts its result, and a type-cast value shouldn't be an lvalue. |
514 | * |
515 | * The {if( FETCH_WCB( ... ) != func )} test is to do type-checking |
516 | * and for no other reason. Since it's hidden in the macro, the |
517 | * ugliness is felt to be rather benign. |
518 | */ |
519 | #define SET_WCB(window,cbname,func) \ |
520 | do \ |
521 | { \ |
522 | if( FETCH_WCB( window, cbname ) != (SFG_Proc)(func) ) \ |
523 | (((window).CallBacks[WCB_ ## cbname]) = (SFG_Proc)(func)); \ |
524 | } while( 0 ) |
525 | |
526 | /* |
527 | * FETCH_WCB() is used as: |
528 | * |
529 | * FETCH_WCB( window, cbname ); |
530 | * |
531 | * ...where {window} is the freeglut window to fetch the callback from, |
532 | * {cbname} is the window-specific callback to fetch. |
533 | * |
534 | * The result is correctly type-cast to the callback function pointer |
535 | * type. |
536 | */ |
537 | #define FETCH_WCB(window,cbname) \ |
538 | ((window).CallBacks[WCB_ ## cbname]) |
539 | |
540 | /* |
541 | * INVOKE_WCB() is used as: |
542 | * |
543 | * INVOKE_WCB( window, cbname, ( arg_list ) ); |
544 | * |
545 | * ...where {window} is the freeglut window, |
546 | * {cbname} is the window-specific callback to be invoked, |
547 | * {(arg_list)} is the parameter list. |
548 | * |
549 | * The callback is invoked as: |
550 | * |
551 | * callback( arg_list ); |
552 | * |
553 | * ...so the parentheses are REQUIRED in the {arg_list}. |
554 | * |
555 | * NOTE that it does a sanity-check and also sets the |
556 | * current window. |
557 | * |
558 | */ |
559 | #if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) /* FIXME: also WinCE? */ |
560 | #define INVOKE_WCB(window,cbname,arg_list) \ |
561 | do \ |
562 | { \ |
563 | if( FETCH_WCB( window, cbname ) ) \ |
564 | { \ |
565 | FGCB ## cbname func = (FGCB ## cbname)(FETCH_WCB( window, cbname )); \ |
566 | fgSetWindow( &window ); \ |
567 | func arg_list; \ |
568 | } \ |
569 | } while( 0 ) |
570 | #else |
571 | #define INVOKE_WCB(window,cbname,arg_list) \ |
572 | do \ |
573 | { \ |
574 | if( FETCH_WCB( window, cbname ) ) \ |
575 | { \ |
576 | fgSetWindow( &window ); \ |
577 | ((FGCB ## cbname)FETCH_WCB( window, cbname )) arg_list; \ |
578 | } \ |
579 | } while( 0 ) |
580 | #endif |
581 | |
582 | /* |
583 | * The window callbacks the user can supply us with. Should be kept portable. |
584 | * |
585 | * This enumeration provides the freeglut CallBack numbers. |
586 | * The symbolic constants are indices into a window's array of |
587 | * function callbacks. The names are formed by splicing a common |
588 | * prefix onto the callback's base name. (This was originally |
589 | * done so that an early stage of development could live side-by- |
590 | * side with the old callback code. The old callback code used |
591 | * the bare callback's name as a structure member, so I used a |
592 | * prefix for the array index name.) |
593 | */ |
594 | enum |
595 | { |
596 | WCB_Display, |
597 | WCB_Reshape, |
598 | WCB_Position, |
599 | WCB_Keyboard, |
600 | WCB_KeyboardExt, |
601 | WCB_KeyboardDown, |
602 | WCB_KeyboardUp, |
603 | WCB_Special, |
604 | WCB_SpecialUp, |
605 | WCB_Mouse, |
606 | WCB_MouseWheel, |
607 | WCB_Motion, |
608 | WCB_Passive, |
609 | WCB_Entry, |
610 | WCB_Visibility, |
611 | WCB_WindowStatus, |
612 | WCB_Joystick, |
613 | WCB_Destroy, |
614 | |
615 | /* Multi-Pointer X and touch related */ |
616 | WCB_MultiEntry, |
617 | WCB_MultiButton, |
618 | WCB_MultiMotion, |
619 | WCB_MultiPassive, |
620 | |
621 | /* Mobile platforms LifeCycle */ |
622 | WCB_InitContext, |
623 | WCB_AppStatus, |
624 | |
625 | /* Presently ignored */ |
626 | WCB_Select, |
627 | WCB_OverlayDisplay, |
628 | WCB_SpaceMotion, /* presently implemented only on UNIX/X11 */ |
629 | WCB_SpaceRotation, /* presently implemented only on UNIX/X11 */ |
630 | WCB_SpaceButton, /* presently implemented only on UNIX/X11 */ |
631 | WCB_Dials, |
632 | WCB_ButtonBox, |
633 | WCB_TabletMotion, |
634 | WCB_TabletButton, |
635 | |
636 | /* Always make this the LAST one */ |
637 | TOTAL_CALLBACKS |
638 | }; |
639 | |
640 | |
641 | /* This structure holds the OpenGL rendering context for all the menu windows */ |
642 | typedef struct tagSFG_MenuContext ; |
643 | struct |
644 | { |
645 | SFG_WindowContextType ; /* The menu window's WGL context */ |
646 | }; |
647 | |
648 | /* This structure describes a menu */ |
649 | typedef struct tagSFG_Window SFG_Window; |
650 | typedef struct tagSFG_MenuEntry ; |
651 | typedef struct tagSFG_Menu ; |
652 | struct |
653 | { |
654 | SFG_Node ; |
655 | void *; /* User data passed back at callback */ |
656 | int ; /* The global menu ID */ |
657 | SFG_List ; /* The menu entries list */ |
658 | FGCBMenu ; /* The menu callback */ |
659 | FGCBDestroy ; /* Destruction callback */ |
660 | GLboolean ; /* Is the menu selected? */ |
661 | void* ; /* Font to be used for displaying this menu */ |
662 | int ; /* Menu box width in pixels */ |
663 | int ; /* Menu box height in pixels */ |
664 | int , ; /* Menu box raster position */ |
665 | |
666 | SFG_MenuEntry *; /* Currently active entry in the menu */ |
667 | SFG_Window *; /* Window for menu */ |
668 | SFG_Window *; /* Window in which the menu is invoked */ |
669 | }; |
670 | |
671 | /* This is a menu entry */ |
672 | struct |
673 | { |
674 | SFG_Node ; |
675 | int ; /* The menu entry ID (local) */ |
676 | int ; /* The menu's ordinal number */ |
677 | char* ; /* The text to be displayed */ |
678 | SFG_Menu* ; /* Optional sub-menu tree */ |
679 | GLboolean ; /* Is the entry highlighted? */ |
680 | int ; /* Label's width in pixels */ |
681 | }; |
682 | |
683 | /* |
684 | * A window, making part of freeglut windows hierarchy. |
685 | * Should be kept portable. |
686 | * |
687 | * NOTE that ActiveMenu is set to menu itself if the window is a menu. |
688 | */ |
689 | struct tagSFG_Window |
690 | { |
691 | SFG_Node Node; |
692 | int ID; /* Window's ID number */ |
693 | |
694 | SFG_Context Window; /* Window and OpenGL context */ |
695 | SFG_WindowState State; /* The window state */ |
696 | SFG_Proc CallBacks[ TOTAL_CALLBACKS ]; /* Array of window callbacks */ |
697 | void *UserData ; /* For use by user */ |
698 | |
699 | SFG_Menu* [ FREEGLUT_MAX_MENUS ]; /* Menus appended to window */ |
700 | SFG_Menu* ; /* The window's active menu */ |
701 | |
702 | SFG_Window* Parent; /* The parent to this window */ |
703 | SFG_List Children; /* The subwindows d.l. list */ |
704 | |
705 | GLboolean ; /* Set to 1 if we are a menu */ |
706 | }; |
707 | |
708 | |
709 | /* A linked list structure of windows */ |
710 | typedef struct tagSFG_WindowList SFG_WindowList ; |
711 | struct tagSFG_WindowList |
712 | { |
713 | SFG_Node node; |
714 | SFG_Window *window ; |
715 | }; |
716 | |
717 | /* This holds information about all the windows, menus etc. */ |
718 | typedef struct tagSFG_Structure SFG_Structure; |
719 | struct tagSFG_Structure |
720 | { |
721 | SFG_List Windows; /* The global windows list */ |
722 | SFG_List ; /* The global menus list */ |
723 | SFG_List WindowsToDestroy; |
724 | |
725 | SFG_Window* CurrentWindow; /* The currently set window */ |
726 | SFG_Menu* ; /* Same, but menu... */ |
727 | |
728 | SFG_MenuContext* ; /* OpenGL rendering context for menus */ |
729 | |
730 | SFG_Window* GameModeWindow; /* The game mode window */ |
731 | |
732 | int WindowID; /* The window ID for the next window to be created */ |
733 | int ; /* The menu ID for the next menu to be created */ |
734 | }; |
735 | |
736 | /* |
737 | * This structure is used for the enumeration purposes. |
738 | * You can easily extend its functionalities by declaring |
739 | * a structure containing enumerator's contents and custom |
740 | * data, then casting its pointer to (SFG_Enumerator *). |
741 | */ |
742 | typedef struct tagSFG_Enumerator SFG_Enumerator; |
743 | struct tagSFG_Enumerator |
744 | { |
745 | GLboolean found; /* Used to terminate search */ |
746 | void* data; /* Custom data pointer */ |
747 | }; |
748 | typedef void (* FGCBWindowEnumerator )( SFG_Window *, SFG_Enumerator * ); |
749 | typedef void (* )( SFG_Menu *, SFG_Enumerator * ); |
750 | |
751 | /* The bitmap font structure */ |
752 | typedef struct tagSFG_Font SFG_Font; |
753 | struct tagSFG_Font |
754 | { |
755 | char* Name; /* The source font name */ |
756 | int Quantity; /* Number of chars in font */ |
757 | int Height; /* Height of the characters */ |
758 | const GLubyte** Characters; /* The characters mapping */ |
759 | |
760 | float xorig, yorig; /* Relative origin of the character */ |
761 | }; |
762 | |
763 | /* The stroke font structures */ |
764 | |
765 | typedef struct tagSFG_StrokeVertex SFG_StrokeVertex; |
766 | struct tagSFG_StrokeVertex |
767 | { |
768 | GLfloat X, Y; |
769 | }; |
770 | |
771 | typedef struct tagSFG_StrokeStrip SFG_StrokeStrip; |
772 | struct tagSFG_StrokeStrip |
773 | { |
774 | int Number; |
775 | const SFG_StrokeVertex* Vertices; |
776 | }; |
777 | |
778 | typedef struct tagSFG_StrokeChar SFG_StrokeChar; |
779 | struct tagSFG_StrokeChar |
780 | { |
781 | GLfloat Right; |
782 | int Number; |
783 | const SFG_StrokeStrip* Strips; |
784 | }; |
785 | |
786 | typedef struct tagSFG_StrokeFont SFG_StrokeFont; |
787 | struct tagSFG_StrokeFont |
788 | { |
789 | char* Name; /* The source font name */ |
790 | int Quantity; /* Number of chars in font */ |
791 | GLfloat Height; /* Height of the characters */ |
792 | const SFG_StrokeChar** Characters; /* The characters mapping */ |
793 | }; |
794 | |
795 | |
796 | /* -- JOYSTICK-SPECIFIC STRUCTURES AND TYPES ------------------------------- */ |
797 | /* |
798 | * Initial defines from "js.h" starting around line 33 with the existing "fg_joystick.c" |
799 | * interspersed |
800 | */ |
801 | |
802 | #if TARGET_HOST_MACINTOSH |
803 | # include <InputSprocket.h> |
804 | #endif |
805 | |
806 | #if TARGET_HOST_MAC_OSX |
807 | # include <mach/mach.h> |
808 | # include <IOKit/IOkitLib.h> |
809 | # include <IOKit/hid/IOHIDLib.h> |
810 | #endif |
811 | |
812 | /* XXX It might be better to poll the operating system for the numbers of buttons and |
813 | * XXX axes and then dynamically allocate the arrays. |
814 | */ |
815 | #define _JS_MAX_BUTTONS 32 |
816 | |
817 | #if TARGET_HOST_MACINTOSH |
818 | # define _JS_MAX_AXES 9 |
819 | typedef struct tagSFG_PlatformJoystick SFG_PlatformJoystick; |
820 | struct tagSFG_PlatformJoystick |
821 | { |
822 | #define ISP_NUM_AXIS 9 |
823 | #define ISP_NUM_NEEDS 41 |
824 | ISpElementReference isp_elem [ ISP_NUM_NEEDS ]; |
825 | ISpNeed isp_needs [ ISP_NUM_NEEDS ]; |
826 | }; |
827 | #endif |
828 | |
829 | #if TARGET_HOST_MAC_OSX |
830 | # define _JS_MAX_AXES 16 |
831 | typedef struct tagSFG_PlatformJoystick SFG_PlatformJoystick; |
832 | struct tagSFG_PlatformJoystick |
833 | { |
834 | IOHIDDeviceInterface ** hidDev; |
835 | IOHIDElementCookie buttonCookies[41]; |
836 | IOHIDElementCookie axisCookies[_JS_MAX_AXES]; |
837 | /* The next two variables are not used anywhere */ |
838 | /* long minReport[_JS_MAX_AXES], |
839 | * maxReport[_JS_MAX_AXES]; |
840 | */ |
841 | }; |
842 | #endif |
843 | |
844 | |
845 | /* |
846 | * Definition of "SFG_Joystick" structure -- based on JS's "jsJoystick" object class. |
847 | * See "js.h" lines 80-178. |
848 | */ |
849 | typedef struct tagSFG_Joystick SFG_Joystick; |
850 | struct tagSFG_Joystick |
851 | { |
852 | SFG_PlatformJoystick pJoystick; |
853 | |
854 | int id; |
855 | GLboolean error; |
856 | char name [ 128 ]; |
857 | int num_axes; |
858 | int num_buttons; |
859 | |
860 | float dead_band[ _JS_MAX_AXES ]; |
861 | float saturate [ _JS_MAX_AXES ]; |
862 | float center [ _JS_MAX_AXES ]; |
863 | float max [ _JS_MAX_AXES ]; |
864 | float min [ _JS_MAX_AXES ]; |
865 | }; |
866 | |
867 | |
868 | |
869 | /* -- GLOBAL VARIABLES EXPORTS --------------------------------------------- */ |
870 | |
871 | /* Freeglut display related stuff (initialized once per session) */ |
872 | extern SFG_Display fgDisplay; |
873 | |
874 | /* Freeglut internal structure */ |
875 | extern SFG_Structure fgStructure; |
876 | |
877 | /* The current freeglut settings */ |
878 | extern SFG_State fgState; |
879 | |
880 | |
881 | /* -- PRIVATE FUNCTION DECLARATIONS ---------------------------------------- */ |
882 | |
883 | /* |
884 | * A call to this function makes us sure that the Display and Structure |
885 | * subsystems have been properly initialized and are ready to be used |
886 | */ |
887 | #define FREEGLUT_EXIT_IF_NOT_INITIALISED( string ) \ |
888 | if ( ! fgState.Initialised ) \ |
889 | { \ |
890 | fgError ( " ERROR: Function <%s> called" \ |
891 | " without first calling 'glutInit'.", (string) ) ; \ |
892 | } |
893 | |
894 | #define FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED( string ) \ |
895 | if ( ! fgState.Initialised ) \ |
896 | { \ |
897 | fgError ( " ERROR: Internal <%s> function called" \ |
898 | " without first calling 'glutInit'.", (string) ) ; \ |
899 | } |
900 | |
901 | #define FREEGLUT_INTERNAL_ERROR_EXIT( cond, string, function ) \ |
902 | if ( ! ( cond ) ) \ |
903 | { \ |
904 | fgError ( " ERROR: Internal error <%s> in function %s", \ |
905 | (string), (function) ) ; \ |
906 | } |
907 | |
908 | /* |
909 | * Following definitions are somewhat similar to GLib's, |
910 | * but do not generate any log messages: |
911 | */ |
912 | #define freeglut_return_if_fail( expr ) \ |
913 | if( !(expr) ) \ |
914 | return; |
915 | #define freeglut_return_val_if_fail( expr, val ) \ |
916 | if( !(expr) ) \ |
917 | return val ; |
918 | |
919 | /* |
920 | * A call to those macros assures us that there is a current |
921 | * window set, respectively: |
922 | */ |
923 | #define FREEGLUT_EXIT_IF_NO_WINDOW( string ) \ |
924 | if ( ! fgStructure.CurrentWindow && \ |
925 | ( fgState.ActionOnWindowClose != GLUT_ACTION_CONTINUE_EXECUTION ) ) \ |
926 | { \ |
927 | fgError ( " ERROR: Function <%s> called" \ |
928 | " with no current window defined.", (string) ) ; \ |
929 | } |
930 | |
931 | /* |
932 | * The deinitialize function gets called on glutMainLoop() end. It should clean up |
933 | * everything inside of the freeglut |
934 | */ |
935 | void fgDeinitialize( void ); |
936 | |
937 | /* |
938 | * Those two functions are used to create/destroy the freeglut internal |
939 | * structures. This actually happens when calling glutInit() and when |
940 | * quitting the glutMainLoop() (which actually happens, when all windows |
941 | * have been closed). |
942 | */ |
943 | void fgCreateStructure( void ); |
944 | void fgDestroyStructure( void ); |
945 | |
946 | /* |
947 | * Window creation, opening, closing and destruction. |
948 | * Also CallBack clearing/initialization. |
949 | * Defined in fg_structure.c, fg_window.c. |
950 | */ |
951 | SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, |
952 | GLboolean positionUse, int x, int y, |
953 | GLboolean sizeUse, int w, int h, |
954 | GLboolean gameMode, GLboolean ); |
955 | void fgSetWindow ( SFG_Window *window ); |
956 | void fgOpenWindow( SFG_Window* window, const char* title, |
957 | GLboolean positionUse, int x, int y, |
958 | GLboolean sizeUse, int w, int h, |
959 | GLboolean gameMode, GLboolean isSubWindow ); |
960 | void fgCloseWindow( SFG_Window* window ); |
961 | void fgAddToWindowDestroyList ( SFG_Window* window ); |
962 | void fgCloseWindows (); |
963 | void fgDestroyWindow( SFG_Window* window ); |
964 | |
965 | /* Menu creation and destruction. Defined in fg_structure.c */ |
966 | SFG_Menu* ( FGCBMenu ); |
967 | void ( SFG_Menu* ); |
968 | |
969 | /* Joystick device management functions, defined in fg_joystick.c */ |
970 | int fgJoystickDetect( void ); |
971 | void fgInitialiseJoysticks( void ); |
972 | void fgJoystickClose( void ); |
973 | void fgJoystickPollWindow( SFG_Window* window ); |
974 | |
975 | /* InputDevice Initialisation and Closure */ |
976 | int fgInputDeviceDetect( void ); |
977 | void fgInitialiseInputDevices( void ); |
978 | void fgInputDeviceClose( void ); |
979 | |
980 | /* spaceball device functions, defined in fg_spaceball.c */ |
981 | void fgInitialiseSpaceball( void ); |
982 | void fgSpaceballClose( void ); |
983 | void fgSpaceballSetWindow( SFG_Window *window ); |
984 | |
985 | int fgHasSpaceball( void ); |
986 | int fgSpaceballNumButtons( void ); |
987 | |
988 | /* Setting the cursor for a given window */ |
989 | void fgSetCursor ( SFG_Window *window, int cursorID ); |
990 | |
991 | /* |
992 | * Helper function to enumerate through all registered windows |
993 | * and one to enumerate all of a window's subwindows... |
994 | * |
995 | * The GFunc callback for those functions will be defined as: |
996 | * |
997 | * void enumCallback( gpointer window, gpointer enumerator ); |
998 | * |
999 | * where window is the enumerated (sub)window pointer (SFG_Window *), |
1000 | * and userData is the a custom user-supplied pointer. Functions |
1001 | * are defined and exported from fg_structure.c file. |
1002 | */ |
1003 | void fgEnumWindows( FGCBWindowEnumerator enumCallback, SFG_Enumerator* enumerator ); |
1004 | void fgEnumSubWindows( SFG_Window* window, FGCBWindowEnumerator enumCallback, |
1005 | SFG_Enumerator* enumerator ); |
1006 | |
1007 | /* |
1008 | * fgWindowByHandle returns a (SFG_Window *) value pointing to the |
1009 | * first window in the queue matching the specified window handle. |
1010 | * The function is defined in fg_structure.c file. |
1011 | */ |
1012 | SFG_Window* fgWindowByHandle( SFG_WindowHandleType hWindow ); |
1013 | |
1014 | /* |
1015 | * This function is similar to the previous one, except it is |
1016 | * looking for a specified (sub)window identifier. The function |
1017 | * is defined in fg_structure.c file. |
1018 | */ |
1019 | SFG_Window* fgWindowByID( int windowID ); |
1020 | |
1021 | /* |
1022 | * Looks up a menu given its ID. This is easier than fgWindowByXXX |
1023 | * as all menus are placed in a single doubly linked list... |
1024 | */ |
1025 | SFG_Menu* ( int ); |
1026 | |
1027 | /* |
1028 | * Returns active menu, if any. Assumption: only one menu active throughout application at any one time. |
1029 | * This is easier than fgWindowByXXX as all menus are placed in one doubly linked list... |
1030 | */ |
1031 | SFG_Menu* ( ); |
1032 | |
1033 | /* |
1034 | * The menu activation and deactivation the code. This is the meat |
1035 | * of the menu user interface handling code... |
1036 | */ |
1037 | void ( SFG_Menu * ); |
1038 | GLboolean ( SFG_Window *window, int button, GLboolean pressed, |
1039 | int mouse_x, int mouse_y ); |
1040 | void ( SFG_Window *window ); |
1041 | |
1042 | /* |
1043 | * This function gets called just before the buffers swap, so that |
1044 | * freeglut can display the pull-down menus via OpenGL. The function |
1045 | * is defined in fg_menu.c file. |
1046 | */ |
1047 | void ( void ); |
1048 | |
1049 | /* Elapsed time as per glutGet(GLUT_ELAPSED_TIME). */ |
1050 | fg_time_t fgElapsedTime( void ); |
1051 | |
1052 | /* System time in milliseconds */ |
1053 | fg_time_t fgSystemTime(void); |
1054 | |
1055 | /* List functions */ |
1056 | void fgListInit(SFG_List *list); |
1057 | void fgListAppend(SFG_List *list, SFG_Node *node); |
1058 | void fgListRemove(SFG_List *list, SFG_Node *node); |
1059 | int fgListLength(SFG_List *list); |
1060 | void fgListInsert(SFG_List *list, SFG_Node *next, SFG_Node *node); |
1061 | |
1062 | /* Error Message functions */ |
1063 | void fgError( const char *fmt, ... ); |
1064 | void fgWarning( const char *fmt, ... ); |
1065 | |
1066 | SFG_Proc fgPlatformGetProcAddress( const char *procName ); |
1067 | |
1068 | void fgPlatformSetClipboard(int selection, const char *text); |
1069 | const char *fgPlatformGetClipboard(int selection); |
1070 | |
1071 | /* pushing attribute/value pairs into an array */ |
1072 | #define ATTRIB(a) attributes[where++]=(a) |
1073 | #define ATTRIB_VAL(a,v) {ATTRIB(a); ATTRIB(v);} |
1074 | |
1075 | int fghMapBit( int mask, int from, int to ); |
1076 | int fghIsLegacyContextRequested( void ); |
1077 | void fghContextCreationError( void ); |
1078 | int fghNumberOfAuxBuffersRequested( void ); |
1079 | |
1080 | #endif /* FREEGLUT_INTERNAL_H */ |
1081 | |
1082 | /*** END OF FILE ***/ |
1083 | |