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 FREEGLUT_MAX_MENUS 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 (* FGCBMenuState )( int ); 247 typedef void (* FGCBMenuStatus )( int, int, int ); 248 249 /* The callback used when creating/using menus */ 250 typedef void (* FGCBMenu )( 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 ActiveMenus; /* Num. of currently active menus */ 324 FGCBMenuState MenuStateCallback; /* Menu callbacks are global */ 325 FGCBMenuStatus MenuStatusCallback; 326 void* MenuFont; /* 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 SFG_MenuContext; 643 struct tagSFG_MenuContext 644 { 645 SFG_WindowContextType MContext; /* 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 SFG_MenuEntry; 651 typedef struct tagSFG_Menu SFG_Menu; 652 struct tagSFG_Menu 653 { 654 SFG_Node Node; 655 void *UserData; /* User data passed back at callback */ 656 int ID; /* The global menu ID */ 657 SFG_List Entries; /* The menu entries list */ 658 FGCBMenu Callback; /* The menu callback */ 659 FGCBDestroy Destroy; /* Destruction callback */ 660 GLboolean IsActive; /* Is the menu selected? */ 661 void* Font; /* Font to be used for displaying this menu */ 662 int Width; /* Menu box width in pixels */ 663 int Height; /* Menu box height in pixels */ 664 int X, Y; /* Menu box raster position */ 665 666 SFG_MenuEntry *ActiveEntry; /* Currently active entry in the menu */ 667 SFG_Window *Window; /* Window for menu */ 668 SFG_Window *ParentWindow; /* Window in which the menu is invoked */ 669 }; 670 671 /* This is a menu entry */ 672 struct tagSFG_MenuEntry 673 { 674 SFG_Node Node; 675 int ID; /* The menu entry ID (local) */ 676 int Ordinal; /* The menu's ordinal number */ 677 char* Text; /* The text to be displayed */ 678 SFG_Menu* SubMenu; /* Optional sub-menu tree */ 679 GLboolean IsActive; /* Is the entry highlighted? */ 680 int Width; /* 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* Menu[ FREEGLUT_MAX_MENUS ]; /* Menus appended to window */ 700 SFG_Menu* ActiveMenu; /* 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 IsMenu; /* 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 Menus; /* The global menus list */ 723 SFG_List WindowsToDestroy; 724 725 SFG_Window* CurrentWindow; /* The currently set window */ 726 SFG_Menu* CurrentMenu; /* Same, but menu... */ 727 728 SFG_MenuContext* 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 MenuID; /* 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 (* FGCBMenuEnumerator )( 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 isMenu ); 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* fgCreateMenu( FGCBMenu menuCallback ); 967 void fgDestroyMenu( SFG_Menu* 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* fgMenuByID( int menuID ); 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* fgGetActiveMenu( ); 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 fgUpdateMenuHighlight ( SFG_Menu *menu ); 1038 GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed, 1039 int mouse_x, int mouse_y ); 1040 void fgDeactivateMenu( 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 fgDisplayMenu( 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