X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_internal.h;h=f6c31edfd803a064a9ccce67dd51330721894653;hb=fe573d6af98de430357a7321cd50f5e92e9a2aab;hp=b8b88828db7a50121bb9f66faf2302b4e99a2a9a;hpb=6fadb32a79a194e7d09a553d425c7e2e26db258b;p=freeglut diff --git a/src/freeglut_internal.h b/src/freeglut_internal.h index b8b8882..f6c31ed 100644 --- a/src/freeglut_internal.h +++ b/src/freeglut_internal.h @@ -28,75 +28,146 @@ #ifndef FREEGLUT_INTERNAL_H #define FREEGLUT_INTERNAL_H +#if HAVE_CONFIG_H +# include "config.h" +#endif + /* XXX Update these for each release! */ #define VERSION_MAJOR 2 -#define VERSION_MINOR 0 -#define VERSION_PATCH 0 +#define VERSION_MINOR 4 +#define VERSION_PATCH 0 -/* - * Freeglut is meant to be available under all Unix/X11 and Win32 platforms. +/* Freeglut is intended to function under all Unix/X11 and Win32 platforms. */ +/* XXX: Don't all MS-Windows compilers (except Cygwin) have _WIN32 defined? + * XXX: If so, remove the first set of defined()'s below. */ -#if !defined(_WIN32) -# define TARGET_HOST_UNIX_X11 1 -# define TARGET_HOST_WIN32 0 +#if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__) \ + || defined(_WIN32) || defined(_WIN32_WCE) \ + || ( defined(__CYGWIN__) && defined(X_DISPLAY_MISSING) ) +# define TARGET_HOST_MS_WINDOWS 1 + +#elif defined(__posix__) || defined(__unix__) || defined(__linux__) +# define TARGET_HOST_POSIX_X11 1 + +/* FIXME: no Macintosh support? +#if ... +# define TARGET_HOST_MAC_OSX 1 #else -# define TARGET_HOST_UNIX_X11 0 -# define TARGET_HOST_WIN32 1 +# error "Unrecognized target host!" +*/ #endif -#define FREEGLUT_MAX_MENUS 3 -#define FREEGLUT_DEBUG 1 +#ifndef TARGET_HOST_MS_WINDOWS +# define TARGET_HOST_MS_WINDOWS 0 +#endif -#if FREEGLUT_DEBUG - #undef G_DISABLE_ASSERT - #undef G_DISABLE_CHECKS -#else - #define G_DISABLE_ASSERT - #define G_DISABLE_CHECKS +#ifndef TARGET_HOST_POSIX_X11 +# define TARGET_HOST_POSIX_X11 0 #endif -/* - * Somehow all Win32 include headers depend on this one: - */ -#if TARGET_HOST_WIN32 -#include -#include +#ifndef TARGET_HOST_MAC_OSX +# define TARGET_HOST_MAC_OSX 0 +#endif + +/* -- FIXED CONFIGURATION LIMITS ------------------------------------------- */ + +#define FREEGLUT_MAX_MENUS 3 + +/* -- PLATFORM-SPECIFIC INCLUDES ------------------------------------------- */ + +/* All Win32 headers depend on the huge Windows.h recursive include. + * Note: Let's use proper case for MS-Win headers. Even though it's + * not required due to case insensitivity, it's a good habit to keep + * because the cross-platform includes are case sensitive. + */ +#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) +# include +# include +# include +/* CYGWIN does not have tchar.h, but has TEXT(x), defined in winnt.h. */ +# ifndef __CYGWIN__ +# include +# else +# define _TEXT(x) TEXT(x) +# define _T(x) TEXT(x) +# endif + +#elif TARGET_HOST_POSIX_X11 +# include +# include +# include +# include +# include +# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H +# include +# endif -#define strdup _strdup #endif -/* - * Those files should be available on every platform. - */ +/* These files should be available on every platform. */ #include #include #include #include #include #include -#include -#include -#if TARGET_HOST_UNIX_X11 -#include + +/* These are included based on autoconf directives. */ +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_UNISTD_H +# include +#endif +#if TIME_WITH_SYS_TIME +# include +# include +#elif HAVE_SYS_TIME_H +# include +#else +# include #endif -/* - * The system-dependant include files should go here: +/* -- AUTOCONF HACKS --------------------------------------------------------*/ + +/* XXX: Update autoconf to avoid these. + * XXX: Are non-POSIX platforms intended not to use autoconf? + * If so, perhaps there should be a config_guess.h for them. Alternatively, + * config guesses could be placed above, just after the config.h exclusion. */ -#if TARGET_HOST_UNIX_X11 - #include - #include - #include - #include - - #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H - #include - #endif +#if defined(__FreeBSD__) || defined(__NetBSD__) +# define HAVE_USB_JS 1 +# if defined(__NetBSD__) || ( defined(__FreeBSD__) && __FreeBSD_version >= 500000) +# define HAVE_USBHID_H 1 +# endif #endif -/* - * Microsoft VisualC++ 5.0's does not define the PI - */ +#if TARGET_HOST_MS_WINDOWS +# define HAVE_VPRINTF 1 +#endif + +#if !defined(HAVE_VPRINTF) && !defined(HAVE_DOPRNT) +/* XXX warning directive here? */ +# define HAVE_VPRINTF 1 +#endif + +/* MinGW may lack a prototype for ChangeDisplaySettingsEx() (depending on the version?) */ +#if TARGET_HOST_MS_WINDOWS && !defined(ChangeDisplaySettingsEx) +LONG WINAPI ChangeDisplaySettingsExA(LPCSTR,LPDEVMODEA,HWND,DWORD,LPVOID); +LONG WINAPI ChangeDisplaySettingsExW(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID); +# ifdef UNICODE +# define ChangeDisplaySettingsEx ChangeDisplaySettingsExW +# else +# define ChangeDisplaySettingsEx ChangeDisplaySettingsExA +# endif +#endif + +#if defined(_MSC_VER) || defined(__WATCOMC__) +/* strdup() is non-standard, for all but POSIX-2001 */ +#define strdup _strdup +#endif + +/* M_PI is non-standard (defined by BSD, not ISO-C) */ #ifndef M_PI # define M_PI 3.14159265358979323846 #endif @@ -109,52 +180,49 @@ # define FALSE 0 #endif -/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ - -/* - * Freeglut callbacks type definitions - */ -typedef void (* FGCBdisplay )( void ); -typedef void (* FGCBreshape )( int, int ); -typedef void (* FGCBvisibility )( int ); -typedef void (* FGCBkeyboard )( unsigned char, int, int ); -typedef void (* FGCBspecial )( int, int, int ); -typedef void (* FGCBmouse )( int, int, int, int ); -typedef void (* FGCBmotion )( int, int ); -typedef void (* FGCBpassive )( int, int ); -typedef void (* FGCBentry )( int ); -typedef void (* FGCBwindowStatus )( int ); -typedef void (* FGCBselect )( int, int, int ); -typedef void (* FGCBjoystick )( unsigned int, int, int, int ); -typedef void (* FGCBkeyboardUp )( unsigned char, int, int ); -typedef void (* FGCBspecialUp )( int, int, int ); -typedef void (* FGCBoverlayDisplay)( void ); -typedef void (* FGCBspaceMotion )( int, int, int ); -typedef void (* FGCBspaceRotate )( int, int, int ); -typedef void (* FGCBspaceButton )( int, int ); -typedef void (* FGCBdials )( int, int ); -typedef void (* FGCBbuttonBox )( int, int ); -typedef void (* FGCBtabletMotion )( int, int ); -typedef void (* FGCBtabletButton )( int, int, int, int ); -typedef void (* FGCBdestroy )( void ); +/* General defines */ -/* - * The global callbacks type definitions - */ -typedef void (* FGCBidle )( void ); -typedef void (* FGCBtimer )( int ); -typedef void (* FGCBmenuState )( int ); -typedef void (* FGCBmenuStatus )( int, int, int ); - -/* - * The callback used when creating/using menus - */ -typedef void (* FGCBmenu )( int ); +#define INVALID_MODIFIERS 0xffffffff +/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */ -/* - * A list structure - */ +/* Freeglut callbacks type definitions */ +typedef void (* FGCBDisplay )( void ); +typedef void (* FGCBReshape )( int, int ); +typedef void (* FGCBVisibility )( int ); +typedef void (* FGCBKeyboard )( unsigned char, int, int ); +typedef void (* FGCBSpecial )( int, int, int ); +typedef void (* FGCBMouse )( int, int, int, int ); +typedef void (* FGCBMouseWheel )( int, int, int, int ); +typedef void (* FGCBMotion )( int, int ); +typedef void (* FGCBPassive )( int, int ); +typedef void (* FGCBEntry )( int ); +typedef void (* FGCBWindowStatus )( int ); +typedef void (* FGCBSelect )( int, int, int ); +typedef void (* FGCBJoystick )( unsigned int, int, int, int ); +typedef void (* FGCBKeyboardUp )( unsigned char, int, int ); +typedef void (* FGCBSpecialUp )( int, int, int ); +typedef void (* FGCBOverlayDisplay)( void ); +typedef void (* FGCBSpaceMotion )( int, int, int ); +typedef void (* FGCBSpaceRotation )( int, int, int ); +typedef void (* FGCBSpaceButton )( int, int ); +typedef void (* FGCBDials )( int, int ); +typedef void (* FGCBButtonBox )( int, int ); +typedef void (* FGCBTabletMotion )( int, int ); +typedef void (* FGCBTabletButton )( int, int, int, int ); +typedef void (* FGCBDestroy )( void ); + +/* The global callbacks type definitions */ +typedef void (* FGCBIdle )( void ); +typedef void (* FGCBTimer )( int ); +typedef void (* FGCBMenuState )( int ); +typedef void (* FGCBMenuStatus )( int, int, int ); + +/* The callback used when creating/using menus */ +typedef void (* FGCBMenu )( int ); + + +/* A list structure */ typedef struct tagSFG_List SFG_List; struct tagSFG_List { @@ -162,9 +230,7 @@ struct tagSFG_List void *Last; }; -/* - * A list node structure - */ +/* A list node structure */ typedef struct tagSFG_Node SFG_Node; struct tagSFG_Node { @@ -172,9 +238,7 @@ struct tagSFG_Node void *Prev; }; -/* - * A helper structure holding two ints and a boolean - */ +/* A helper structure holding two ints and a boolean */ typedef struct tagSFG_XYUse SFG_XYUse; struct tagSFG_XYUse { @@ -183,78 +247,68 @@ struct tagSFG_XYUse }; /* - * A helper structure holding a timeval and a boolean + * An enumeration containing the state of the GLUT execution: + * initializing, running, or stopping */ -typedef struct tagSFG_Time SFG_Time; -struct tagSFG_Time +typedef enum { -#ifdef WIN32 - DWORD Value; -#else - struct timeval Value; -#endif - GLboolean Set; -}; - -/* - * An enumeration containing the state of the GLUT execution: initializing, running, or stopping - */ -typedef enum { GLUT_EXEC_STATE_INIT, GLUT_EXEC_STATE_RUNNING, GLUT_EXEC_STATE_STOP } fgExecutionState ; -/* - * This structure holds different freeglut settings - */ +/* This structure holds different freeglut settings */ typedef struct tagSFG_State SFG_State; struct tagSFG_State { - SFG_XYUse Position; /* The default windows' position */ - SFG_XYUse Size; /* The default windows' size */ - unsigned int DisplayMode; /* The display mode for new windows */ + SFG_XYUse Position; /* The default windows' position */ + SFG_XYUse Size; /* The default windows' size */ + unsigned int DisplayMode; /* Display mode for new windows */ + + GLboolean Initialised; /* freeglut has been initialised */ - GLboolean ForceDirectContext; /* Should we force direct contexts? */ - GLboolean TryDirectContext; /* What about giving a try to? */ + int DirectContext; /* Direct rendering state */ - GLboolean ForceIconic; /* All new top windows are iconified */ - GLboolean UseCurrentContext; /* New windows use current window's rendering context */ + GLboolean ForceIconic; /* New top windows are iconified */ + GLboolean UseCurrentContext; /* New windows share with current */ - GLboolean GLDebugSwitch; /* OpenGL state debugging switch */ - GLboolean XSyncSwitch; /* X11 sync protocol switch */ + GLboolean GLDebugSwitch; /* OpenGL state debugging switch */ + GLboolean XSyncSwitch; /* X11 sync protocol switch */ - GLboolean IgnoreKeyRepeat; /* Whether to ignore key repeat... */ + int KeyRepeat; /* Global key repeat mode. */ + int Modifiers; /* Current ALT/SHIFT/CTRL state */ - GLuint FPSInterval; /* Interval between FPS printfs */ - GLuint SwapCount; /* Count of glutSwapBuffer calls */ - GLuint SwapTime; /* Time of last SwapBuffers */ + GLuint FPSInterval; /* Interval between FPS printfs */ + GLuint SwapCount; /* Count of glutSwapBuffer calls */ + GLuint SwapTime; /* Time of last SwapBuffers */ - SFG_Time Time; /* The time that glutInit was called */ - SFG_List Timers; /* The freeglut timer hooks */ + unsigned long Time; /* Time that glutInit was called */ + SFG_List Timers; /* The freeglut timer hooks */ + SFG_List FreeTimers; /* The unused timer hooks */ - FGCBidle IdleCallback; /* The global idle callback */ + FGCBIdle IdleCallback; /* The global idle callback */ - GLboolean BuildingAMenu; /* True if we are presently making a menu */ - FGCBmenuState MenuStateCallback; /* Menu callbacks are global */ - FGCBmenuStatus MenuStatusCallback; + int ActiveMenus; /* Num. of currently active menus */ + FGCBMenuState MenuStateCallback; /* Menu callbacks are global */ + FGCBMenuStatus MenuStatusCallback; - SFG_XYUse GameModeSize; /* The game mode screen's dimensions */ - int GameModeDepth; /* The pixel depth for game mode */ - int GameModeRefresh; /* The refresh rate for game mode */ + SFG_XYUse GameModeSize; /* Game mode screen's dimensions */ + int GameModeDepth; /* The pixel depth for game mode */ + int GameModeRefresh; /* The refresh rate for game mode */ - int ActionOnWindowClose ; /* Action when user clicks "x" on window header bar */ + int ActionOnWindowClose; /* Action when user closes window */ - fgExecutionState ExecState ; /* Current state of the GLUT execution */ + fgExecutionState ExecState; /* Used for GLUT termination */ + char *ProgramName; /* Name of the invoking program */ + GLboolean JoysticksInitialised; /* Only initialize if application calls for them */ + GLboolean InputDevsInitialised; /* Only initialize if application calls for them */ }; -/* - * The structure used by display initialization in freeglut_init.c - */ +/* The structure used by display initialization in freeglut_init.c */ typedef struct tagSFG_Display SFG_Display; struct tagSFG_Display { -#if TARGET_HOST_UNIX_X11 +#if TARGET_HOST_POSIX_X11 Display* Display; /* The display we are being run in. */ int Screen; /* The screen we are about to use. */ Window RootWindow; /* The screen's root window. */ @@ -269,9 +323,14 @@ struct tagSFG_Display int DisplayModeValid; /* Flag that indicates runtime status*/ XF86VidModeModeLine DisplayMode; /* Current screen's display settings */ int DisplayModeClock; /* The display mode's refresh rate */ -#endif + int DisplayViewPortX; /* saved X location of the viewport */ + int DisplayViewPortY; /* saved Y location of the viewport */ + int DisplayPointerX; /* saved X location of the pointer */ + int DisplayPointerY; /* saved Y location of the pointer */ -#elif TARGET_HOST_WIN32 +#endif /* X_XF86VidModeGetModeLine */ + +#elif TARGET_HOST_MS_WINDOWS HINSTANCE Instance; /* The application's instance */ DEVMODE DisplayMode; /* Desktop's display settings */ @@ -284,148 +343,249 @@ struct tagSFG_Display }; -/* - * The user can create any number of timer hooks - */ +/* The user can create any number of timer hooks */ typedef struct tagSFG_Timer SFG_Timer; struct tagSFG_Timer { SFG_Node Node; int ID; /* The timer ID integer */ - FGCBtimer Callback; /* The timer callback */ + FGCBTimer Callback; /* The timer callback */ long TriggerTime; /* The timer trigger time */ }; /* + * Make "freeglut" window handle and context types so that we don't need so + * much conditionally-compiled code later in the library. + */ +#if TARGET_HOST_POSIX_X11 + +typedef Window SFG_WindowHandleType ; +typedef GLXContext SFG_WindowContextType ; + +#elif TARGET_HOST_MS_WINDOWS + +typedef HWND SFG_WindowHandleType ; +typedef HGLRC SFG_WindowContextType ; + +#endif + +/* * A window and its OpenGL context. The contents of this structure * are highly dependant on the target operating system we aim at... */ typedef struct tagSFG_Context SFG_Context; struct tagSFG_Context { -#if TARGET_HOST_UNIX_X11 - Window Handle; /* The window's handle */ - GLXContext Context; /* The OpenGL context */ - XVisualInfo* VisualInfo; /* The window's visual information */ - -#elif TARGET_HOST_WIN32 - HWND Handle; /* The window's handle */ - HDC Device; /* The window's device context */ - HGLRC Context; /* The window's WGL context */ + SFG_WindowHandleType Handle; /* The window's handle */ + SFG_WindowContextType Context; /* The window's OpenGL/WGL context */ +#if TARGET_HOST_POSIX_X11 + XVisualInfo* VisualInfo; /* The window's visual information */ +#elif TARGET_HOST_MS_WINDOWS + HDC Device; /* The window's device context */ #endif - int DoubleBuffered; /* Treat the window as double-buffered */ + int DoubleBuffered; /* Treat the window as double-buffered */ }; -/* - * Window's state description. This structure should be kept portable. - */ +/* Window's state description. This structure should be kept portable. */ typedef struct tagSFG_WindowState SFG_WindowState; struct tagSFG_WindowState { int Width; /* Window's width in pixels */ int Height; /* The same about the height */ + int OldWidth; /* Window width from before a resize */ + int OldHeight; /* " height " " " " */ GLboolean Redisplay; /* Do we have to redisplay? */ GLboolean Visible; /* Is the window visible now */ int Cursor; /* The currently selected cursor */ - int Modifiers; /* The current ALT/SHIFT/CTRL state */ long JoystickPollRate; /* The joystick polling rate */ - long JoystickLastPoll; /* When the last poll has happened */ + long JoystickLastPoll; /* When the last poll happened */ int MouseX, MouseY; /* The most recent mouse position */ - GLboolean IsGameMode; /* Is this the game mode window? */ + GLboolean IgnoreKeyRepeat; /* Whether to ignore key repeat. */ + GLboolean KeyRepeating; /* Currently in repeat mode */ -#if TARGET_HOST_WIN32 - GLboolean NeedToResize; /* Do we need to explicitly resize? */ -#endif + GLboolean NeedToResize; /* Do we need to resize the window? */ }; + /* - * The window callbacks the user can supply us with. Should be kept portable. + * A generic function pointer. We should really use the GLUTproc type + * defined in freeglut_ext.h, but if we include that header in this file + * a bunch of other stuff (font-related) blows up! */ -typedef struct tagSFG_WindowCallbacks SFG_WindowCallbacks; -struct tagSFG_WindowCallbacks -{ - /* - * Following callbacks are fully supported right now - * and are ready to be tested for GLUT conformance: - */ - FGCBdisplay Display; - FGCBreshape Reshape; - FGCBkeyboard Keyboard; - FGCBkeyboardUp KeyboardUp; - FGCBspecial Special; - FGCBspecialUp SpecialUp; - FGCBmouse Mouse; - FGCBmotion Motion; - FGCBpassive Passive; - FGCBentry Entry; - FGCBvisibility Visibility; - FGCBwindowStatus WindowStatus; - FGCBjoystick Joystick; - FGCBdestroy Destroy; +typedef void (*SFG_Proc)(); - /* - * Those callbacks are being ignored for the moment - */ - FGCBselect Select; - FGCBoverlayDisplay OverlayDisplay; - FGCBspaceMotion SpaceMotion; - FGCBspaceRotate SpaceRotation; - FGCBspaceButton SpaceButton; - FGCBdials Dials; - FGCBbuttonBox ButtonBox; - FGCBtabletMotion TabletMotion; - FGCBtabletButton TabletButton; -}; /* - * This structure holds the OpenGL rendering context for all the menu windows + * SET_WCB() is used as: + * + * SET_WCB( window, cbname, func ); + * + * ...where {window} is the freeglut window to set the callback, + * {cbname} is the window-specific callback to set, + * {func} is a function-pointer. + * + * Originally, {FETCH_WCB( ... ) = func} was rather sloppily used, + * but this can cause warnings because the FETCH_WCB() macro type- + * casts its result, and a type-cast value shouldn't be an lvalue. + * + * The {if( FETCH_WCB( ... ) != func )} test is to do type-checking + * and for no other reason. Since it's hidden in the macro, the + * ugliness is felt to be rather benign. */ +#define SET_WCB(window,cbname,func) \ +do \ +{ \ + if( FETCH_WCB( window, cbname ) != (SFG_Proc)(func) ) \ + (((window).CallBacks[CB_ ## cbname]) = (SFG_Proc)(func)); \ +} while( 0 ) + +/* + * FETCH_WCB() is used as: + * + * FETCH_WCB( window, cbname ); + * + * ...where {window} is the freeglut window to fetch the callback from, + * {cbname} is the window-specific callback to fetch. + * + * The result is correctly type-cast to the callback function pointer + * type. + */ +#define FETCH_WCB(window,cbname) \ + ((window).CallBacks[CB_ ## cbname]) + +/* + * INVOKE_WCB() is used as: + * + * INVOKE_WCB( window, cbname, ( arg_list ) ); + * + * ...where {window} is the freeglut window, + * {cbname} is the window-specific callback to be invoked, + * {(arg_list)} is the parameter list. + * + * The callback is invoked as: + * + * callback( arg_list ); + * + * ...so the parentheses are REQUIRED in the {arg_list}. + * + * NOTE that it does a sanity-check and also sets the + * current window. + * + */ +#if TARGET_HOST_MS_WINDOWS && !defined(_WIN32_WCE) /* FIXME: also WinCE? */ +#define INVOKE_WCB(window,cbname,arg_list) \ +do \ +{ \ + if( FETCH_WCB( window, cbname ) ) \ + { \ + FGCB ## cbname func = (FGCB ## cbname)(FETCH_WCB( window, cbname )); \ + fgSetWindow( &window ); \ + func arg_list; \ + } \ +} while( 0 ) +#else +#define INVOKE_WCB(window,cbname,arg_list) \ +do \ +{ \ + if( FETCH_WCB( window, cbname ) ) \ + { \ + fgSetWindow( &window ); \ + ((FGCB ## cbname)FETCH_WCB( window, cbname )) arg_list; \ + } \ +} while( 0 ) +#endif + +/* + * The window callbacks the user can supply us with. Should be kept portable. + * + * This enumeration provides the freeglut CallBack numbers. + * The symbolic constants are indices into a window's array of + * function callbacks. The names are formed by splicing a common + * prefix onto the callback's base name. (This was originally + * done so that an early stage of development could live side-by- + * side with the old callback code. The old callback code used + * the bare callback's name as a structure member, so I used a + * prefix for the array index name.) + * + * XXX For consistancy, perhaps the prefix should match the + * XXX FETCH* and INVOKE* macro suffices. I.e., WCB_, rather than + * XXX CB_. + */ +enum +{ + CB_Display, + CB_Reshape, + CB_Keyboard, + CB_KeyboardUp, + CB_Special, + CB_SpecialUp, + CB_Mouse, + CB_MouseWheel, + CB_Motion, + CB_Passive, + CB_Entry, + CB_Visibility, + CB_WindowStatus, + CB_Joystick, + CB_Destroy, + + /* Presently ignored */ + CB_Select, + CB_OverlayDisplay, + CB_SpaceMotion, + CB_SpaceRotation, + CB_SpaceButton, + CB_Dials, + CB_ButtonBox, + CB_TabletMotion, + CB_TabletButton, + + /* Always make this the LAST one */ + TOTAL_CALLBACKS +}; + + +/* This structure holds the OpenGL rendering context for all the menu windows */ typedef struct tagSFG_MenuContext SFG_MenuContext; struct tagSFG_MenuContext { -#if TARGET_HOST_UNIX_X11 - GLXContext Context; /* The menu OpenGL context */ - XVisualInfo* VisualInfo; /* The window's visual information */ -#elif TARGET_HOST_WIN32 - HGLRC Context; /* The menu window's WGL context */ +#if TARGET_HOST_POSIX_X11 + XVisualInfo* MVisualInfo; /* The window's visual information */ #endif + SFG_WindowContextType MContext; /* The menu window's WGL context */ }; -/* - * This structure describes a menu - */ +/* This structure describes a menu */ typedef struct tagSFG_Window SFG_Window; typedef struct tagSFG_MenuEntry SFG_MenuEntry; typedef struct tagSFG_Menu SFG_Menu; struct tagSFG_Menu { SFG_Node Node; - void *UserData ; /* A. Donev: User data passed back at callback */ - int ID; /* The global menu ID */ - SFG_List Entries; /* The menu entries list */ - FGCBmenu Callback; /* The menu callback */ - FGCBdestroy Destroy; /* A. Donev: Destruction callback */ - GLboolean IsActive; /* Is the menu selected? */ - int Width; /* Menu box width in pixels */ - int Height; /* Menu box height in pixels */ - int X, Y; /* Menu box raster position */ - - SFG_MenuEntry *ActiveEntry ; /* Currently active entry in the menu */ - SFG_Window *Window ; /* OpenGL window for menu */ - SFG_Window *ParentWindow ; /* OpenGL window in which the menu is defined */ + void *UserData; /* User data passed back at callback */ + int ID; /* The global menu ID */ + SFG_List Entries; /* The menu entries list */ + FGCBMenu Callback; /* The menu callback */ + FGCBDestroy Destroy; /* Destruction callback */ + GLboolean IsActive; /* Is the menu selected? */ + int Width; /* Menu box width in pixels */ + int Height; /* Menu box height in pixels */ + int X, Y; /* Menu box raster position */ + + SFG_MenuEntry *ActiveEntry; /* Currently active entry in the menu */ + SFG_Window *Window; /* Window for menu */ + SFG_Window *ParentWindow; /* Window in which the menu is invoked */ }; -/* - * This is a menu entry - */ +/* This is a menu entry */ struct tagSFG_MenuEntry { SFG_Node Node; @@ -438,7 +598,10 @@ struct tagSFG_MenuEntry }; /* - * A window, making part of freeglut windows hierarchy. Should be kept portable. + * A window, making part of freeglut windows hierarchy. + * Should be kept portable. + * + * NOTE that ActiveMenu is set to menu itself if the window is a menu. */ struct tagSFG_Window { @@ -447,8 +610,8 @@ struct tagSFG_Window SFG_Context Window; /* Window and OpenGL context */ SFG_WindowState State; /* The window state */ - SFG_WindowCallbacks Callbacks; /* The window callbacks */ - void *UserData ; /* A. Donev: A pointer to user data used in rendering */ + SFG_Proc CallBacks[ TOTAL_CALLBACKS ]; /* Array of window callbacks */ + void *UserData ; /* For use by user */ SFG_Menu* Menu[ FREEGLUT_MAX_MENUS ]; /* Menus appended to window */ SFG_Menu* ActiveMenu; /* The window's active menu */ @@ -459,35 +622,32 @@ struct tagSFG_Window GLboolean IsMenu; /* Set to 1 if we are a menu */ }; -/* - * A linked list structure of windows - */ + +/* A linked list structure of windows */ typedef struct tagSFG_WindowList SFG_WindowList ; struct tagSFG_WindowList { - SFG_Window *window ; - GLboolean needToClose ; - SFG_WindowList *next ; -} ; + SFG_Node node; + SFG_Window *window ; +}; -/* - * This holds information about all the windows, menus etc. - */ +/* This holds information about all the windows, menus etc. */ typedef struct tagSFG_Structure SFG_Structure; struct tagSFG_Structure { - SFG_List Windows; /* The global windows list */ - SFG_List Menus; /* The global menus list */ + SFG_List Windows; /* The global windows list */ + SFG_List Menus; /* The global menus list */ + SFG_List WindowsToDestroy; - SFG_Window* Window; /* The currently active win. */ - SFG_Menu* Menu; /* Same, but menu... */ + SFG_Window* CurrentWindow; /* The currently set window */ + SFG_Menu* CurrentMenu; /* Same, but menu... */ - SFG_MenuContext* MenuContext; /* OpenGL rendering context for menus */ + SFG_MenuContext* MenuContext; /* OpenGL rendering context for menus */ - SFG_Window* GameMode; /* The game mode window */ + SFG_Window* GameModeWindow; /* The game mode window */ - int WindowID; /* The new current window ID */ - int MenuID; /* The new current menu ID */ + int WindowID; /* The new current window ID */ + int MenuID; /* The new current menu ID */ }; /* @@ -504,23 +664,19 @@ struct tagSFG_Enumerator }; typedef void (* FGCBenumerator )( SFG_Window *, SFG_Enumerator * ); -/* - * The bitmap font structure - */ +/* The bitmap font structure */ typedef struct tagSFG_Font SFG_Font; struct tagSFG_Font { - char* Name; /* The source font name */ - int Quantity; /* Number of chars in font */ - int Height; /* Height of the characters */ - const GLubyte** Characters; /* The characters mapping */ + char* Name; /* The source font name */ + int Quantity; /* Number of chars in font */ + int Height; /* Height of the characters */ + const GLubyte** Characters; /* The characters mapping */ - float xorig, yorig ; /* The origin of the character relative to the draw location */ + float xorig, yorig; /* Relative origin of the character */ }; -/* - * The stroke font structures - */ +/* The stroke font structures */ typedef struct tagSFG_StrokeVertex SFG_StrokeVertex; struct tagSFG_StrokeVertex @@ -554,19 +710,13 @@ struct tagSFG_StrokeFont /* -- GLOBAL VARIABLES EXPORTS --------------------------------------------- */ -/* - * Freeglut display related stuff (initialized once per session) - */ +/* Freeglut display related stuff (initialized once per session) */ extern SFG_Display fgDisplay; -/* - * Freeglut internal structure - */ +/* Freeglut internal structure */ extern SFG_Structure fgStructure; -/* - * The current freeglut settings - */ +/* The current freeglut settings */ extern SFG_State fgState; @@ -576,28 +726,53 @@ extern SFG_State fgState; * A call to this function makes us sure that the Display and Structure * subsystems have been properly initialized and are ready to be used */ -#define freeglut_assert_ready assert( fgState.Time.Set ); +#define FREEGLUT_EXIT_IF_NOT_INITIALISED( string ) \ + if ( ! fgState.Initialised ) \ + { \ + fgError ( " ERROR: Function <%s> called" \ + " without first calling 'glutInit'.", (string) ) ; \ + } + +#define FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED( string ) \ + if ( ! fgState.Initialised ) \ + { \ + fgError ( " ERROR: Internal <%s> function called" \ + " without first calling 'glutInit'.", (string) ) ; \ + } + +#define FREEGLUT_INTERNAL_ERROR_EXIT( cond, string, function ) \ + if ( ! ( cond ) ) \ + { \ + fgError ( " ERROR: Internal error <%s> in function %s", \ + (string), (function) ) ; \ + } /* * Following definitions are somewhat similiar to GLib's, * but do not generate any log messages: */ -#define freeglut_return_if_fail( expr ) if( !(expr) ) return; -#define freeglut_return_val_if_fail( expr, val ) if( !(expr) ) return( val ); +#define freeglut_return_if_fail( expr ) \ + if( !(expr) ) \ + return; +#define freeglut_return_val_if_fail( expr, val ) \ + if( !(expr) ) \ + return val ; /* * A call to those macros assures us that there is a current - * window and menu set, respectively: + * window set, respectively: */ -#define freeglut_assert_window assert( fgStructure.Window != NULL ); -#define freeglut_assert_menu assert( fgStructure.Menu != NULL ); +#define FREEGLUT_EXIT_IF_NO_WINDOW( string ) \ + if ( ! fgStructure.CurrentWindow ) \ + { \ + fgError ( " ERROR: Function <%s> called" \ + " with no current window defined.", (string) ) ; \ + } /* - * The initialize and deinitialize functions get called on glutInit() - * and glutMainLoop() end respectively. They should create/clean up + * The deinitialize function gets called on glutMainLoop() end. It should clean up * everything inside of the freeglut */ -void fgInitialize( const char* displayName ); void fgDeinitialize( void ); /* @@ -609,46 +784,56 @@ void fgDeinitialize( void ); void fgCreateStructure( void ); void fgDestroyStructure( void ); -/* - * A helper function to check if a display mode is possible to use - */ -#if TARGET_HOST_UNIX_X11 +/* A helper function to check if a display mode is possible to use */ +#if TARGET_HOST_POSIX_X11 XVisualInfo* fgChooseVisual( void ); #endif -/* - * The window procedure for Win32 events handling - */ -#if TARGET_HOST_WIN32 -LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); -GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type ); +/* The window procedure for Win32 events handling */ +#if TARGET_HOST_MS_WINDOWS +LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam ); +GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, + unsigned char layer_type ); #endif /* * Window creation, opening, closing and destruction. + * Also CallBack clearing/initialization. * Defined in freeglut_structure.c, freeglut_window.c. */ -SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, int x, int y, int w, int h, GLboolean gameMode ); -void fgSetWindow ( SFG_Window *window ) ; -void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, int isSubWindow ); +SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, + GLboolean positionUse, int x, int y, + GLboolean sizeUse, int w, int h, + GLboolean gameMode, GLboolean isMenu ); +void fgSetWindow ( SFG_Window *window ); +void fgOpenWindow( SFG_Window* window, const char* title, + GLboolean positionUse, int x, int y, + GLboolean sizeUse, int w, int h, + GLboolean gameMode, GLboolean isSubWindow ); void fgCloseWindow( SFG_Window* window ); -void fgAddToWindowDestroyList ( SFG_Window* window, GLboolean needToClose ) ; -void fgCloseWindows () ; -void fgDestroyWindow( SFG_Window* window, GLboolean needToClose ); +void fgAddToWindowDestroyList ( SFG_Window* window ); +void fgCloseWindows (); +void fgDestroyWindow( SFG_Window* window ); -/* - * Menu creation and destruction. Defined in freeglut_structure.c - */ -SFG_Menu* fgCreateMenu( FGCBmenu menuCallback ); +/* Menu creation and destruction. Defined in freeglut_structure.c */ +SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ); void fgDestroyMenu( SFG_Menu* menu ); -/* - * Joystick device management functions, defined in freeglut_joystick.c - */ -void fgJoystickInit( int ident ); +/* Joystick device management functions, defined in freeglut_joystick.c */ +int fgJoystickDetect( void ); +void fgInitialiseJoysticks( void ); void fgJoystickClose( void ); void fgJoystickPollWindow( SFG_Window* window ); +/* InputDevice Initialisation and Closure */ +int fgInputDeviceDetect( void ); +void fgInitialiseInputDevices( void ); +void fgInputDeviceClose( void ); + +/* Setting the cursor for a given window */ +void fgSetCursor ( SFG_Window *window, int cursorID ); + /* * Helper function to enumerate through all registered windows * and one to enumerate all of a window's subwindows... @@ -662,19 +847,15 @@ void fgJoystickPollWindow( SFG_Window* window ); * are defined and exported from freeglut_structure.c file. */ void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator ); -void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback, SFG_Enumerator* enumerator ); +void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback, + SFG_Enumerator* enumerator ); /* * fgWindowByHandle returns a (SFG_Window *) value pointing to the * first window in the queue matching the specified window handle. * The function is defined in freeglut_structure.c file. */ -#if TARGET_HOST_UNIX_X11 - SFG_Window* fgWindowByHandle( Window hWindow ); -#elif TARGET_HOST_WIN32 - - SFG_Window* fgWindowByHandle( HWND hWindow ); -#endif +SFG_Window* fgWindowByHandle( SFG_WindowHandleType hWindow ); /* * This function is similiar to the previous one, except it is @@ -684,7 +865,7 @@ void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback, SFG_Enum SFG_Window* fgWindowByID( int windowID ); /* - * Looks up a menu given its ID. This is easier that fgWindowByXXX + * Looks up a menu given its ID. This is easier than fgWindowByXXX * as all menus are placed in a single doubly linked list... */ SFG_Menu* fgMenuByID( int menuID ); @@ -693,11 +874,10 @@ SFG_Menu* fgMenuByID( int menuID ); * The menu activation and deactivation the code. This is the meat * of the menu user interface handling code... */ -void fgActivateMenu( SFG_Window* window, int button ); -void fgExecuteMenuCallback( SFG_Menu* menu ) ; -GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu ) ; +void fgUpdateMenuHighlight ( SFG_Menu *menu ); +GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed, + int mouse_x, int mouse_y ); void fgDeactivateMenu( SFG_Window *window ); -void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry ); /* * This function gets called just before the buffers swap, so that @@ -706,28 +886,20 @@ void fgDeactivateSubMenu( SFG_MenuEntry *menuEntry ); */ void fgDisplayMenu( void ); -/* - * Display the mouse cursor using OpenGL calls. The function - * is defined in freeglut_cursor.c file. - */ -void fgDisplayCursor( void ); - -/* - * Elapsed time as per glutGet(GLUT_ELAPSED_TIME). - */ +/* Elapsed time as per glutGet(GLUT_ELAPSED_TIME). */ long fgElapsedTime( void ); -/* - * List functions - */ +/* System time in milliseconds */ +long unsigned fgSystemTime(void); + +/* List functions */ void fgListInit(SFG_List *list); void fgListAppend(SFG_List *list, SFG_Node *node); void fgListRemove(SFG_List *list, SFG_Node *node); int fgListLength(SFG_List *list); +void fgListInsert(SFG_List *list, SFG_Node *next, SFG_Node *node); -/* - * Error Messages functions - */ +/* Error Message functions */ void fgError( const char *fmt, ... ); void fgWarning( const char *fmt, ... );