1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-02 03:50:36 +00:00

Update FreeGLUT to v2.8.1

This commit is contained in:
Samuel Gomes 2024-01-30 03:01:26 +05:30
parent b5e896384a
commit 3a260f1002
17 changed files with 8108 additions and 4977 deletions

View file

@ -27,7 +27,7 @@ $(PATH_INTERNAL_C)/parts/core/glew/%.o: $(PATH_INTERNAL_C)/parts/core/glew/%.c
$(CC) -O1 $(CFLAGS) $(FREEGLUT_INCLUDE) -DGLEW_STATIC -Wall $< -c -o $@
$(PATH_INTERNAL_C)/parts/core/freeglut/%.o: $(PATH_INTERNAL_C)/parts/core/freeglut/%.c
$(CC) -O3 $(CFLAGS) $(FREEGLUT_INCLUDE) -DFREEGLUT_STATIC -Wall $< -c -o $@
$(CC) -O3 $(CFLAGS) $(FREEGLUT_INCLUDE) -DFREEGLUT_STATIC -DHAVE_UNISTD_H -DHAVE_FCNTL_H -Wall $< -c -o $@
$(FREEGLUT_LIB): $(FREEGLUT_OBJS)
$(AR) rcs $@ $(FREEGLUT_OBJS)

View file

@ -159,6 +159,22 @@ static void fghWarpPointer ( int x, int y )
/* Make the warp visible immediately. */
XFlush( fgDisplay.Display );
}
void fghGetCursorPos(SFG_XYUse *mouse_pos)
{
/* Get current pointer location in screen coordinates
*/
Window junk_window;
unsigned int junk_mask;
int junk_pos;
XQueryPointer(fgDisplay.Display, fgDisplay.RootWindow,
&junk_window, &junk_window,
&mouse_pos->X, &mouse_pos->Y,
&junk_pos, &junk_pos, &junk_mask);
mouse_pos->Use = GL_TRUE;
}
#endif
@ -205,7 +221,7 @@ static void fghSetCursor ( SFG_Window *window, int cursorID )
{
MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW );
MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, IDC_ARROW );
MAP_CURSOR( GLUT_CURSOR_INFO, IDC_HAND );
MAP_CURSOR( GLUT_CURSOR_INFO, IDC_HAND ); // QB64-PE: GLUT_CURSOR_INFO -> IDC_HAND per FreeGLUT 3.4.0
MAP_CURSOR( GLUT_CURSOR_DESTROY, IDC_CROSS );
MAP_CURSOR( GLUT_CURSOR_HELP, IDC_HELP );
MAP_CURSOR( GLUT_CURSOR_CYCLE, IDC_SIZEALL );
@ -244,6 +260,18 @@ static void fghWarpPointer ( int x, int y )
ClientToScreen( fgStructure.CurrentWindow->Window.Handle, &coords );
SetCursorPos( coords.x, coords.y );
}
void fghGetCursorPos(SFG_XYUse *mouse_pos)
{
/* Get current pointer location in screen coordinates
*/
POINT pos;
GetCursorPos(&pos);
mouse_pos->X = pos.x;
mouse_pos->Y = pos.y;
mouse_pos->Use = GL_TRUE;
}
#endif

View file

@ -136,6 +136,8 @@ static GLUTproc fghGetGLUTProcAddress( const char* procName )
CHECK_NAME(glutSolidTorus);
CHECK_NAME(glutWireDodecahedron);
CHECK_NAME(glutSolidDodecahedron);
CHECK_NAME(glutWireTeapot);
CHECK_NAME(glutSolidTeapot);
CHECK_NAME(glutWireOctahedron);
CHECK_NAME(glutSolidOctahedron);
CHECK_NAME(glutWireTetrahedron);

View file

@ -58,7 +58,7 @@ static int xrandr_resize(int xsz, int ysz, int rate, int just_checking)
/* we only heed the rate if we CAN actually use it (Xrandr >= 1.1) and
* the user actually cares about it (rate > 0)
*/
use_rate = ( rate > 0 ) && ( ( ver_major >= 1 ) ||
use_rate = ( rate > 0 ) && ( ( ver_major > 1 ) ||
( ( ver_major == 1 ) && ( ver_minor >= 1 ) ) );
/* this loop is only so that the whole thing will be repeated if someone
@ -105,7 +105,7 @@ static int xrandr_resize(int xsz, int ysz, int rate, int just_checking)
if(res_idx == -1)
break; /* no matching resolution */
#if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
#if ( RANDR_MAJOR > 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
if(use_rate) {
rate = fgState.GameModeRefresh;
@ -130,7 +130,7 @@ static int xrandr_resize(int xsz, int ysz, int rate, int just_checking)
break;
}
#if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
#if ( RANDR_MAJOR > 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
if(use_rate)
result = XRRSetScreenConfigAndRate(fgDisplay.Display, xrr_config,
fgDisplay.RootWindow, res_idx, rot, rate, timestamp);
@ -154,6 +154,96 @@ static int xrandr_resize(int xsz, int ysz, int rate, int just_checking)
}
#endif /* TARGET_HOST_POSIX_X11 */
#if TARGET_HOST_MS_WINDOWS
/*
* Changes to requested devmode, if it doesn't match current mode
*/
GLboolean fghPlatformChangeDisplayMode(GLboolean haveToTest, DEVMODE *devModeRequested)
{
GLboolean success = GL_FALSE;
DEVMODE devModeCurrent;
char *fggmstr = NULL;
char displayMode[300];
/* Get current display mode */
EnumDisplaySettings( fgDisplay.DisplayName, ENUM_CURRENT_SETTINGS, &devModeCurrent );
/* Now see if requested matches current mode, then we're done
* There's only four fields we touch:
* - dmPelsWidth
* - dmPelsHeight
* - dmBitsPerPel
* - dmDisplayFrequency
*/
if (devModeCurrent.dmPelsWidth ==devModeRequested->dmPelsWidth &&
devModeCurrent.dmPelsHeight ==devModeRequested->dmPelsHeight &&
devModeCurrent.dmBitsPerPel ==devModeRequested->dmBitsPerPel &&
devModeCurrent.dmDisplayFrequency==devModeRequested->dmDisplayFrequency)
{
if (!haveToTest)
{
/* update vars in case if actual switch was requested */
EnumDisplaySettings( fgDisplay.DisplayName, ENUM_CURRENT_SETTINGS, &devModeCurrent );
fgState.GameModeSize.X = devModeCurrent.dmPelsWidth;
fgState.GameModeSize.Y = devModeCurrent.dmPelsHeight;
fgState.GameModeDepth = devModeCurrent.dmBitsPerPel;
fgState.GameModeRefresh = devModeCurrent.dmDisplayFrequency;
}
/* We're done */
return GL_TRUE;
}
/* Ok, we do have a mode switch to perform/test */
switch ( ChangeDisplaySettingsEx(fgDisplay.DisplayName, devModeRequested, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
{
case DISP_CHANGE_SUCCESSFUL:
success = GL_TRUE;
if (!haveToTest)
{
/* update vars in case if windows switched to proper mode */
EnumDisplaySettings( fgDisplay.DisplayName, ENUM_CURRENT_SETTINGS, &devModeCurrent );
fgState.GameModeSize.X = devModeCurrent.dmPelsWidth;
fgState.GameModeSize.Y = devModeCurrent.dmPelsHeight;
fgState.GameModeDepth = devModeCurrent.dmBitsPerPel;
fgState.GameModeRefresh = devModeCurrent.dmDisplayFrequency;
}
break;
case DISP_CHANGE_RESTART:
fggmstr = "The computer must be restarted for the graphics mode to work.";
break;
case DISP_CHANGE_BADFLAGS:
fggmstr = "An invalid set of flags was passed in.";
break;
case DISP_CHANGE_BADPARAM:
fggmstr = "An invalid parameter was passed in. This can include an invalid flag or combination of flags.";
break;
case DISP_CHANGE_FAILED:
fggmstr = "The display driver failed the specified graphics mode.";
break;
case DISP_CHANGE_BADMODE:
fggmstr = "The graphics mode is not supported.";
break;
default:
fggmstr = "Unknown error in graphics mode???"; /* dunno if it is possible, MSDN does not mention any other error */
break;
}
if ( !success )
{
/* I'd rather get info whats going on in my program than wonder about */
/* what magic happens behind my back, its lib for devels after all ;) */
/* append display mode to error to make things more informative */
sprintf(displayMode,"%s Problem with requested mode: %lux%lu:%lu@%lu", fggmstr, devModeRequested->dmPelsWidth, devModeRequested->dmPelsHeight, devModeRequested->dmBitsPerPel, devModeRequested->dmDisplayFrequency);
fgWarning(displayMode);
}
return success;
}
#endif
/*
* Remembers the current visual settings, so that
* we can change them and restore later...
@ -190,7 +280,7 @@ static void fghRememberState( void )
fgDisplay.prev_ysz = ssizes[curr].height;
fgDisplay.prev_refresh = -1;
# if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
# if ( RANDR_MAJOR > 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
if(fgState.GameModeRefresh != -1) {
fgDisplay.prev_refresh = XRRConfigCurrentRate(xrr_config);
}
@ -355,7 +445,7 @@ static void fghRestoreState( void )
#elif TARGET_HOST_MS_WINDOWS
/* Restore the previously remembered desktop display settings */
ChangeDisplaySettingsEx( fgDisplay.DisplayName,&fgDisplay.DisplayMode, 0,0,0 );
fghPlatformChangeDisplayMode(GL_FALSE,&fgDisplay.DisplayMode);
#endif
}
@ -516,11 +606,10 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
#elif TARGET_HOST_MS_WINDOWS
DEVMODE devMode;
char *fggmstr = NULL;
char displayMode[300];
success = GL_FALSE;
/* Get current display mode */
EnumDisplaySettings( fgDisplay.DisplayName, -1, &devMode );
devMode.dmFields = 0;
@ -545,50 +634,7 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
devMode.dmFields |= DM_DISPLAYFREQUENCY;
}
switch ( ChangeDisplaySettingsEx(fgDisplay.DisplayName, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
{
case DISP_CHANGE_SUCCESSFUL:
success = GL_TRUE;
if (!haveToTest)
{
/* update vars in case if windows switched to proper mode */
EnumDisplaySettings( fgDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS, &devMode );
fgState.GameModeSize.X = devMode.dmPelsWidth;
fgState.GameModeSize.Y = devMode.dmPelsHeight;
fgState.GameModeDepth = devMode.dmBitsPerPel;
fgState.GameModeRefresh = devMode.dmDisplayFrequency;
}
break;
case DISP_CHANGE_RESTART:
fggmstr = "The computer must be restarted for the graphics mode to work.";
break;
case DISP_CHANGE_BADFLAGS:
fggmstr = "An invalid set of flags was passed in.";
break;
case DISP_CHANGE_BADPARAM:
fggmstr = "An invalid parameter was passed in. This can include an invalid flag or combination of flags.";
break;
case DISP_CHANGE_FAILED:
fggmstr = "The display driver failed the specified graphics mode.";
break;
case DISP_CHANGE_BADMODE:
fggmstr = "The graphics mode is not supported.";
break;
default:
fggmstr = "Unknown error in graphics mode???"; /* dunno if it is possible,MSDN does not mention any other error */
break;
}
if ( !success )
{
/* I'd rather get info whats going on in my program than wonder about */
/* magic happenings behind my back, its lib for devels at last ;) */
/* append display mode to error to make things more informative */
sprintf(displayMode,"%s Problem with requested mode: %ix%i:%i@%i", fggmstr, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel, devMode.dmDisplayFrequency);
fgWarning(displayMode);
}
success = fghPlatformChangeDisplayMode(haveToTest, &devMode);
#endif
return success;

View file

@ -391,13 +391,13 @@ void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLi
glBegin(GL_TRIANGLES);
glNormal3d(cost[0]*sinn, sint[0]*sinn, cosn);
glNormal3d(cost[0]*cosn, sint[0]*cosn, sinn);
for (j=0; j<slices; j++)
{
glVertex3d(cost[j+0]*r0, sint[j+0]*r0, z0 );
glVertex3d(0, 0, height);
glNormal3d(cost[j+1]*sinn, sint[j+1]*sinn, cosn );
glNormal3d(cost[j+1]*cosn, sint[j+1]*cosn, sinn );
glVertex3d(cost[j+1]*r0, sint[j+1]*r0, z0 );
}
@ -463,7 +463,7 @@ void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLin
for (j=0; j<slices; j++)
{
glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn );
glNormal3d(cost[j]*cosn, sint[j]*cosn, sinn );
glVertex3d(cost[j]*r, sint[j]*r, 0.0 );
glVertex3d(0.0, 0.0, height);
}

View file

@ -48,7 +48,7 @@
/* -- GLOBAL VARIABLES ----------------------------------------------------- */
/*
* A structure pointed by g_pDisplay holds all information
* A structure fgDisplay holds all information
* regarding the display, screen, root window etc.
*/
SFG_Display fgDisplay;
@ -77,9 +77,9 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
0, /* ActiveMenus */
NULL, /* MenuStateCallback */
NULL, /* MenuStatusCallback */
{ 640, 480, GL_TRUE }, /* GameModeSize */
16, /* GameModeDepth */
72, /* GameModeRefresh */
{ -1, -1, GL_TRUE }, /* GameModeSize */
-1, /* GameModeDepth */
-1, /* GameModeRefresh */
GLUT_ACTION_EXIT, /* ActionOnWindowClose */
GLUT_EXEC_STATE_INIT, /* ExecState */
NULL, /* ProgramName */
@ -89,6 +89,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
0, /* MouseWheelTicks */
1, /* AuxiliaryBufferNumber */
4, /* SampleNumber */
GL_FALSE, /* SkipStaleMotion */
1, /* MajorVersion */
0, /* MinorVersion */
0, /* ContextFlags */
@ -392,7 +393,10 @@ static void fghInitialize( const char* displayName )
fgState.Initialised = GL_TRUE;
/* Avoid registering atexit callback on Win32 as it results in an access
* violation due to calling into a module which has been unloaded. */
* violation due to calling into a module which has been unloaded.
* Any cleanup isn't needed on Windows anyway, the OS takes care of it.c
* see: http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx
*/
#if ( TARGET_HOST_MS_WINDOWS == 0 )
atexit(fgDeinitialize);
#endif
@ -483,10 +487,10 @@ void fgDeinitialize( void )
fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
fgState.Modifiers = INVALID_MODIFIERS;
fgState.GameModeSize.X = 640;
fgState.GameModeSize.Y = 480;
fgState.GameModeDepth = 16;
fgState.GameModeRefresh = 72;
fgState.GameModeSize.X = -1;
fgState.GameModeSize.Y = -1;
fgState.GameModeDepth = -1;
fgState.GameModeRefresh = -1;
fgListInit( &fgState.Timers );
fgListInit( &fgState.FreeTimers );
@ -1114,6 +1118,7 @@ void FGAPIENTRY glutInitDisplayString( const char* displayMode )
case 35 : /* "borderless": windows should not have borders */
#if TARGET_HOST_POSIX_X11
#endif
glut_state_flag |= GLUT_BORDERLESS;
break ;
case 36 : /* "aux": some number of aux buffers */

View file

@ -34,8 +34,8 @@
/* XXX Update these for each release! */
#define VERSION_MAJOR 2
#define VERSION_MINOR 7
#define VERSION_PATCH 0
#define VERSION_MINOR 8
#define VERSION_PATCH 1
/* Freeglut is intended to function under all Unix/X11 and Win32 platforms. */
/* XXX: Don't all MS-Windows compilers (except Cygwin) have _WIN32 defined?
@ -109,7 +109,7 @@
# include <X11/Xlib.h>
# include <X11/Xatom.h>
# include <X11/keysym.h>
# include <X11/extensions/XI.h>
# include <X11/extensions/XI.h> // QB64-PE: replaced XInput.h with XI.h
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
# include <X11/extensions/xf86vmode.h>
# endif
@ -138,9 +138,9 @@
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <unistd.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
@ -344,6 +344,8 @@ struct tagSFG_State
int AuxiliaryBufferNumber; /* Number of auxiliary buffers */
int SampleNumber; /* Number of samples per pixel */
GLboolean SkipStaleMotion; /* skip stale motion events */
int MajorVersion; /* Major OpenGL context version */
int MinorVersion; /* Minor OpenGL context version */
int ContextFlags; /* OpenGL context flags */
@ -729,7 +731,8 @@ struct tagSFG_Enumerator
GLboolean found; /* Used to terminate search */
void* data; /* Custom data pointer */
};
typedef void (* FGCBenumerator )( SFG_Window *, SFG_Enumerator * );
typedef void (* FGCBWindowEnumerator )( SFG_Window *, SFG_Enumerator * );
typedef void (* FGCBMenuEnumerator )( SFG_Menu *, SFG_Enumerator * );
/* The bitmap font structure */
typedef struct tagSFG_Font SFG_Font;
@ -928,8 +931,8 @@ void fgSetCursor ( SFG_Window *window, int cursorID );
* and userData is the a custom user-supplied pointer. Functions
* are defined and exported from freeglut_structure.c file.
*/
void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator );
void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback,
void fgEnumWindows( FGCBWindowEnumerator enumCallback, SFG_Enumerator* enumerator );
void fgEnumSubWindows( SFG_Window* window, FGCBWindowEnumerator enumCallback,
SFG_Enumerator* enumerator );
#if TARGET_HOST_MS_WINDOWS
@ -938,11 +941,11 @@ void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback,
* and the window rect from the client area given the style of the window
* (or a valid window pointer from which the style can be queried).
*/
void fghComputeWindowRectFromClientArea_UseStyle ( const DWORD windowStyle , RECT *clientRect, BOOL posIsOutside );
void fghComputeWindowRectFromClientArea_QueryWindow( const SFG_Window *window, RECT *clientRect, BOOL posIsOutside );
void fghComputeClientAreaFromWindowRect ( const SFG_Window *window, RECT *windowRect, BOOL wantPosOutside );
RECT fghGetClientArea ( const SFG_Window *window, BOOL wantPosOutside );
void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth);
void fghGetDefaultWindowStyle(DWORD *flags);
void fghGetStyleFromWindow( const SFG_Window *window, DWORD *windowStyle, DWORD *windowExStyle );
void fghComputeWindowRectFromClientArea_UseStyle( RECT *clientRect, const DWORD windowStyle, const DWORD windowExStyle, BOOL posIsOutside );
void fghComputeWindowRectFromClientArea_QueryWindow( RECT *clientRect, const SFG_Window *window, BOOL posIsOutside );
void fghGetClientArea( RECT *clientRect, const SFG_Window *window, BOOL wantPosOutside );
#endif
/*
@ -965,6 +968,12 @@ SFG_Window* fgWindowByID( int windowID );
*/
SFG_Menu* fgMenuByID( int menuID );
/*
* Returns active menu, if any. Assumption: only one menu active throughout application at any one time.
* This is easier than fgWindowByXXX as all menus are placed in one doubly linked list...
*/
SFG_Menu* fgGetActiveMenu( );
/*
* The menu activation and deactivation the code. This is the meat
* of the menu user interface handling code...
@ -1018,8 +1027,6 @@ SFG_Proc fghGetProcAddress( const char *procName );
extern void (__cdecl *__glutExitFunc)( int return_value );
#endif
#include <fcntl.h>
#endif /* FREEGLUT_INTERNAL_H */
/*** END OF FILE ***/

File diff suppressed because it is too large Load diff

View file

@ -84,6 +84,9 @@ static float menu_pen_hfore [4] = {0.0f, 0.0f, 0.0f, 1.0f};
static float menu_pen_hback [4] = {1.0f, 1.0f, 1.0f, 1.0f};
#endif
extern void fghGetCursorPos(SFG_XYUse *mouse_pos);
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
/*
@ -532,14 +535,15 @@ void fgDisplayMenu( void )
static void fghActivateMenu( SFG_Window* window, int button )
{
int max_x, max_y;
SFG_XYUse mouse_pos;
/* We'll be referencing this menu a lot, so remember its address: */
SFG_Menu* menu = window->Menu[ button ];
SFG_Window* current_window = fgStructure.CurrentWindow;
/* If the menu is already active in another window, deactivate it there */
/* If the menu is already active in another window, deactivate it (and any submenus) there */
if ( menu->ParentWindow )
menu->ParentWindow->ActiveMenu = NULL ;
fgDeactivateMenu(menu->ParentWindow);
/* Mark the menu as active, so that it gets displayed: */
window->ActiveMenu = menu;
@ -550,9 +554,17 @@ static void fghActivateMenu( SFG_Window* window, int button )
/* Set up the initial menu position now: */
fghGetVMaxExtent(menu->ParentWindow, &max_x, &max_y);
fgSetWindow( window );
menu->X = window->State.MouseX + glutGet( GLUT_WINDOW_X );
menu->Y = window->State.MouseY + glutGet( GLUT_WINDOW_Y );
/* get mouse position on screen (window->State.MouseX and window->State.MouseY
* are relative to client area origin), and not easy to correct given that
* glutGet( GLUT_WINDOW_X ) and glutGet( GLUT_WINDOW_Y ) return relative to parent
* origin when looking at a child window
* for parent windows: window->State.MouseX + glutGet( GLUT_WINDOW_X ) == mouse_pos.X
*/
fghGetCursorPos(&mouse_pos);
menu->X = mouse_pos.X;
menu->Y = mouse_pos.Y;
/* Make sure the whole menu is on the screen */
if( menu->X + menu->Width > max_x )
menu->X -=menu->Width;
@ -563,10 +575,21 @@ static void fghActivateMenu( SFG_Window* window, int button )
menu->Y = 0;
}
menu->Window->State.MouseX =
window->State.MouseX + glutGet( GLUT_WINDOW_X ) - menu->X;
menu->Window->State.MouseY =
window->State.MouseY + glutGet( GLUT_WINDOW_Y ) - menu->Y;
/* Set position of mouse relative to top-left menu in menu's window state (could as well set 0 at creation time...) */
menu->Window->State.MouseX = mouse_pos.X - menu->X;
menu->Window->State.MouseY = mouse_pos.Y - menu->Y;
/* Menu status callback */
if (fgState.MenuStateCallback || fgState.MenuStatusCallback)
{
fgStructure.CurrentMenu = menu;
fgStructure.CurrentWindow = window;
if (fgState.MenuStateCallback)
fgState.MenuStateCallback(GLUT_MENU_IN_USE);
if (fgState.MenuStatusCallback)
/* window->State.MouseX and window->State.MouseY are relative to client area origin, as needed */
fgState.MenuStatusCallback(GLUT_MENU_IN_USE, window->State.MouseX, window->State.MouseY);
}
fgSetWindow( menu->Window );
glutPositionWindow( menu->X, menu->Y );
@ -645,9 +668,8 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
/*
* Outside the menu, deactivate if it's a downclick
*
* XXX This isn't enough. A downclick outside of
* XXX the interior of our freeglut windows should also
* XXX deactivate the menu. This is more complicated.
* A downclick outside of the interior of our freeglut windows
* is dealt with in the WM_KILLFOCUS handler of fgPlatformWindowProc
*/
fgDeactivateMenu( window->ActiveMenu->ParentWindow );
@ -684,12 +706,13 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
void fgDeactivateMenu( SFG_Window *window )
{
SFG_Window *parent_window = NULL;
/* Check if there is an active menu attached to this window... */
SFG_Menu* menu = window->ActiveMenu;
SFG_Menu* menu;
SFG_MenuEntry *menuEntry;
/* Did we find an active window? */
freeglut_return_if_fail( window );
/* Check if there is an active menu attached to this window... */
menu = window->ActiveMenu;
freeglut_return_if_fail( menu );
parent_window = menu->ParentWindow;
@ -714,12 +737,32 @@ void fgDeactivateMenu( SFG_Window *window )
{
menuEntry->IsActive = GL_FALSE;
/* Is that an active submenu by any case? */
/* Is that an active submenu by any chance? */
if( menuEntry->SubMenu )
fghDeactivateSubMenu( menuEntry );
}
fgSetWindow ( parent_window ) ;
/* Menu status callback */
if (fgState.MenuStateCallback || fgState.MenuStatusCallback)
{
fgStructure.CurrentMenu = menu;
fgStructure.CurrentWindow = parent_window;
if (fgState.MenuStateCallback)
fgState.MenuStateCallback(GLUT_MENU_NOT_IN_USE);
if (fgState.MenuStatusCallback)
{
/* Get cursor position on screen and convert to relative to parent_window's client area */
SFG_XYUse mouse_pos;
fghGetCursorPos(&mouse_pos);
mouse_pos.X -= glutGet( GLUT_WINDOW_X );
mouse_pos.Y -= glutGet( GLUT_WINDOW_Y );
fgState.MenuStatusCallback(GLUT_MENU_NOT_IN_USE, mouse_pos.X, mouse_pos.Y);
}
}
}
/*
@ -766,6 +809,53 @@ void fghCalculateMenuBoxSize( void )
fgStructure.CurrentMenu->Width = width + 4 * FREEGLUT_MENU_BORDER;
}
#if TARGET_HOST_MS_WINDOWS
void fgPlatformCheckMenuDeactivate()
{
/* If we have an open menu, see if the open menu should be closed
* when focus was lost because user either switched
* application or FreeGLUT window (if one is running multiple
* windows). If so, close menu the active menu.
*/
SFG_Menu* menu = NULL;
if ( fgStructure.Menus.First )
menu = fgGetActiveMenu();
if ( menu )
{
SFG_Window* wnd = NULL;
HWND hwnd = GetFocus(); /* Get window with current focus - NULL for non freeglut windows */
if (hwnd)
/* See which of our windows it is */
wnd = fgWindowByHandle(hwnd);
if (!hwnd || !wnd)
/* User switched to another application*/
fgDeactivateMenu(menu->ParentWindow);
else if (!wnd->IsMenu) /* Make sure we don't kill the menu when trying to enter a submenu */
{
if (wnd!=menu->ParentWindow)
/* User switched to another FreeGLUT window */
fgDeactivateMenu(menu->ParentWindow);
else
{
/* Check if focus lost because non-client area of
* window was pressed (pressing on client area is
* handled in fgCheckActiveMenu)
*/
POINT mouse_pos;
RECT clientArea;
fghGetClientArea(&clientArea,menu->ParentWindow, GL_FALSE);
GetCursorPos(&mouse_pos);
if ( !PtInRect( &clientArea, mouse_pos ) )
fgDeactivateMenu(menu->ParentWindow);
}
}
}
};
#endif
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
@ -776,6 +866,8 @@ int FGAPIENTRY glutCreateMenu( void(* callback)( int ) )
{
/* The menu object creation code resides in freeglut_structure.c */
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
if (fgGetActiveMenu())
fgError("Menu manipulation not allowed while menus in use.");
return fgCreateMenu( callback )->ID;
}
@ -799,6 +891,9 @@ void FGAPIENTRY glutDestroyMenu( int menuID )
freeglut_return_if_fail( menu );
if (fgGetActiveMenu())
fgError("Menu manipulation not allowed while menus in use.");
/* The menu object destruction code resides in freeglut_structure.c */
fgDestroyMenu( menu );
}
@ -839,7 +934,10 @@ void FGAPIENTRY glutAddMenuEntry( const char* label, int value )
SFG_MenuEntry* menuEntry;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutAddMenuEntry" );
menuEntry = (SFG_MenuEntry *)calloc( sizeof(SFG_MenuEntry), 1 );
freeglut_return_if_fail( fgStructure.CurrentMenu );
if (fgGetActiveMenu())
fgError("Menu manipulation not allowed while menus in use.");
menuEntry->Text = strdup( label );
menuEntry->ID = value;
@ -863,6 +961,9 @@ void FGAPIENTRY glutAddSubMenu( const char *label, int subMenuID )
subMenu = fgMenuByID( subMenuID );
freeglut_return_if_fail( fgStructure.CurrentMenu );
if (fgGetActiveMenu())
fgError("Menu manipulation not allowed while menus in use.");
freeglut_return_if_fail( subMenu );
menuEntry->Text = strdup( label );
@ -881,7 +982,10 @@ void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value )
SFG_MenuEntry* menuEntry = NULL;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutChangeToMenuEntry" );
freeglut_return_if_fail( fgStructure.CurrentMenu );
if (fgGetActiveMenu())
fgError("Menu manipulation not allowed while menus in use.");
/* Get n-th menu entry in the current menu, starting from one: */
menuEntry = fghFindMenuEntry( fgStructure.CurrentMenu, item );
@ -908,10 +1012,15 @@ void FGAPIENTRY glutChangeToSubMenu( int item, const char* label,
SFG_MenuEntry* menuEntry;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutChangeToSubMenu" );
freeglut_return_if_fail( fgStructure.CurrentMenu );
if (fgGetActiveMenu())
fgError("Menu manipulation not allowed while menus in use.");
/* Get handle to sub menu */
subMenu = fgMenuByID( subMenuID );
menuEntry = NULL;
freeglut_return_if_fail( fgStructure.CurrentMenu );
freeglut_return_if_fail( subMenu );
/* Get n-th menu entry in the current menu, starting from one: */
@ -937,7 +1046,10 @@ void FGAPIENTRY glutRemoveMenuItem( int item )
SFG_MenuEntry* menuEntry;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutRemoveMenuItem" );
freeglut_return_if_fail( fgStructure.CurrentMenu );
if (fgGetActiveMenu())
fgError("Menu manipulation not allowed while menus in use.");
/* Get n-th menu entry in the current menu, starting from one: */
menuEntry = fghFindMenuEntry( fgStructure.CurrentMenu, item );
@ -960,7 +1072,10 @@ void FGAPIENTRY glutAttachMenu( int button )
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutAttachMenu" );
freeglut_return_if_fail( fgStructure.CurrentWindow );
freeglut_return_if_fail( fgStructure.CurrentMenu );
if (fgGetActiveMenu())
fgError("Menu manipulation not allowed while menus in use.");
freeglut_return_if_fail( button >= 0 );
freeglut_return_if_fail( button < FREEGLUT_MAX_MENUS );
@ -976,7 +1091,10 @@ void FGAPIENTRY glutDetachMenu( int button )
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDetachMenu" );
freeglut_return_if_fail( fgStructure.CurrentWindow );
freeglut_return_if_fail( fgStructure.CurrentMenu );
if (fgGetActiveMenu())
fgError("Menu manipulation not allowed while menus in use.");
freeglut_return_if_fail( button >= 0 );
freeglut_return_if_fail( button < FREEGLUT_MAX_MENUS );

View file

@ -124,6 +124,10 @@ void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
fgState.SampleNumber = value;
break;
case GLUT_SKIP_STALE_MOTION_EVENTS:
fgState.SkipStaleMotion = value;
break;
default:
fgWarning( "glutSetOption(): missing enum handle %d", eWhat );
break;
@ -132,7 +136,7 @@ void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
#if TARGET_HOST_MS_WINDOWS
/* The following include file is available from SGI but is not standard:
* #include <wglext.h>
* #include <GL/wglext.h>
* So we copy the necessary parts out of it to support the multisampling query
*/
#define WGL_SAMPLES_ARB 0x2042
@ -434,7 +438,7 @@ int FGAPIENTRY glutGet( GLenum eWhat )
* behaviour, both under Windows and under UNIX/X11:
* - When you create a window with position (x,y) and size
* (w,h), the upper left hand corner of the outside of the
* window is at (x,y) and the size of the drawable area is
* window is at (x,y) and the size of the drawable area is
* (w,h).
* - When you query the size and position of the window--as
* is happening here for Windows--"freeglut" will return
@ -451,7 +455,20 @@ int FGAPIENTRY glutGet( GLenum eWhat )
#if defined(_WIN32_WCE)
GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );
#else
winRect = fghGetClientArea(fgStructure.CurrentWindow, FALSE);
fghGetClientArea(&winRect,fgStructure.CurrentWindow, FALSE);
if (fgStructure.CurrentWindow->Parent && (eWhat==GLUT_WINDOW_X || eWhat==GLUT_WINDOW_Y))
{
/* For child window, we should return relative to upper-left
* of parent's client area.
*/
POINT topleft;
topleft.x = winRect.left;
topleft.y = winRect.top;
ScreenToClient(fgStructure.CurrentWindow->Parent->Window.Handle,&topleft);
winRect.left = topleft.x;
winRect.top = topleft.y;
}
#endif /* defined(_WIN32_WCE) */
switch( eWhat )
@ -465,30 +482,47 @@ int FGAPIENTRY glutGet( GLenum eWhat )
break;
case GLUT_WINDOW_BORDER_WIDTH :
case GLUT_WINDOW_HEADER_HEIGHT :
case GLUT_WINDOW_BORDER_HEIGHT :
#if defined(_WIN32_WCE)
return 0;
#else
{
DWORD windowStyle;
/* We can't get the border width or header height in the simple way
* with some calls to GetSystemMetrics. We'd then have to assume which
* elements are present for a given decoration, and such calculations
* wouldn't be valid for every version of Windows. The below should be
* robust. */
int borderWidth, captionHeight;
DWORD windowStyle, windowExStyle;
RECT clientRect, winRect;
/* Get style of window, or default style */
fghGetStyleFromWindow( fgStructure.CurrentWindow, &windowStyle, &windowExStyle );
/* Get client area if any window */
if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle)
windowStyle = GetWindowLong(fgStructure.CurrentWindow->Window.Handle, GWL_STYLE);
fghGetClientArea(&clientRect,fgStructure.CurrentWindow,FALSE);
else
/* If no window, return sizes for a default window with title bar and border */
windowStyle = WS_OVERLAPPEDWINDOW;
SetRect(&clientRect,0,0,200,200);
/* Compute window rect (including non-client area) */
CopyRect(&winRect,&clientRect);
fghComputeWindowRectFromClientArea_UseStyle(&winRect,windowStyle,windowExStyle,FALSE);
/* Calculate border width by taking width of whole window minus width of client area and divide by two
* NB: we assume horizontal and vertical borders have the same size, which should always be the case
* unless the user bypassed FreeGLUT and messed with the windowstyle himself.
* Once borderwidth is known, account for it when comparing height of window to height of client area.
* all other extra pixels are assumed to be atop the window, forming the caption.
*/
borderWidth = ((winRect.right-winRect.left)-(clientRect.right-clientRect.left))/2;
captionHeight = (winRect.bottom-winRect.top)-(clientRect.bottom-clientRect.top)-borderWidth*2;
switch( eWhat )
{
case GLUT_WINDOW_BORDER_WIDTH:
{
int xBorderWidth, yBorderWidth;
fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
return xBorderWidth;
}
case GLUT_WINDOW_HEADER_HEIGHT:
/* Need to query for WS_SYSMENU to see if we have a title bar, the WS_CAPTION query is also true for a WS_DLGFRAME only... */
return (windowStyle & WS_SYSMENU)? GetSystemMetrics( SM_CYCAPTION ) : 0;
return borderWidth;
case GLUT_WINDOW_BORDER_HEIGHT:
return captionHeight;
}
}
#endif /* defined(_WIN32_WCE) */
@ -554,6 +588,9 @@ int FGAPIENTRY glutGet( GLenum eWhat )
case GLUT_MULTISAMPLE:
return fgState.SampleNumber;
case GLUT_SKIP_STALE_MOTION_EVENTS:
return fgState.SkipStaleMotion;
default:
fgWarning( "glutGet(): missing enum handle %d", eWhat );
break;

View file

@ -380,7 +380,7 @@ void fgDestroyStructure( void )
/*
* Helper function to enumerate through all registered top-level windows
*/
void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator )
void fgEnumWindows( FGCBWindowEnumerator enumCallback, SFG_Enumerator* enumerator )
{
SFG_Window *window;
@ -399,11 +399,33 @@ void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator )
}
}
/*
* Helper function to enumerate through all registered top-level windows
*/
void fgEnumMenus( FGCBMenuEnumerator enumCallback, SFG_Enumerator* enumerator )
{
SFG_Menu *menu;
FREEGLUT_INTERNAL_ERROR_EXIT ( enumCallback && enumerator,
"Enumerator or callback missing from window enumerator call",
"fgEnumWindows" );
/* It's enough to check all entries in fgStructure.Menus... */
for( menu = (SFG_Menu *)fgStructure.Menus.First;
menu;
menu = (SFG_Menu *)menu->Node.Next )
{
enumCallback( menu, enumerator );
if( enumerator->found )
return;
}
}
/*
* Helper function to enumerate through all a window's subwindows
* (single level descent)
*/
void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback,
void fgEnumSubWindows( SFG_Window* window, FGCBWindowEnumerator enumCallback,
SFG_Enumerator* enumerator )
{
SFG_Window *child;
@ -487,7 +509,7 @@ static void fghcbWindowByID( SFG_Window *window, SFG_Enumerator *enumerator )
}
/*
* This function is similiar to the previous one, except it is
* This function is similar to the previous one, except it is
* looking for a specified (sub)window identifier. The function
* is defined in freeglut_structure.c file.
*/
@ -495,7 +517,7 @@ SFG_Window* fgWindowByID( int windowID )
{
SFG_Enumerator enumerator;
/* Uses a method very similiar for fgWindowByHandle... */
/* Uses a method very similar for fgWindowByHandle... */
enumerator.found = GL_FALSE;
enumerator.data = ( void * )&windowID;
fgEnumWindows( fghcbWindowByID, &enumerator );
@ -506,18 +528,75 @@ SFG_Window* fgWindowByID( int windowID )
/*
* Looks up a menu given its ID. This is easier that fgWindowByXXX
* A static helper function to look for a menu given its ID
*/
static void fghcbMenuByID( SFG_Menu *menu, SFG_Enumerator *enumerator )
{
if ( enumerator->found )
return;
/* Check the menu's ID. */
if( menu->ID == (int)(enumerator->data) )
{
enumerator->found = GL_TRUE;
enumerator->data = menu;
return;
}
}
/*
* Looks up a menu given its ID. This is easier than fgWindowByXXX
* as all menus are placed in one doubly linked list...
*/
SFG_Menu* fgMenuByID( int menuID )
{
SFG_Menu *menu = NULL;
SFG_Enumerator enumerator;
/* It's enough to check all entries in fgStructure.Menus... */
for( menu = (SFG_Menu *)fgStructure.Menus.First;
menu;
menu = (SFG_Menu *)menu->Node.Next )
if( menu->ID == menuID )
return menu;
/* This is easy and makes use of the menus enumeration defined above */
enumerator.found = GL_FALSE;
enumerator.data = (void *)menuID;
fgEnumMenus( fghcbMenuByID, &enumerator );
if( enumerator.found )
return( SFG_Menu *) enumerator.data;
return NULL;
}
/*
* A static helper function to look for an active menu
*/
static void fghcbGetActiveMenu( SFG_Menu *menu, SFG_Enumerator *enumerator )
{
if ( enumerator->found )
return;
/* Check the menu's ID. */
if( menu->IsActive )
{
enumerator->found = GL_TRUE;
enumerator->data = menu;
return;
}
}
/*
* Returns active menu, if any. Assumption: only one menu active throughout application at any one time.
* This is easier than fgWindowByXXX as all menus are placed in one doubly linked list...
*/
SFG_Menu* fgGetActiveMenu( )
{
SFG_Enumerator enumerator;
/* This is easy and makes use of the menus enumeration defined above */
enumerator.found = GL_FALSE;
fgEnumMenus( fghcbGetActiveMenu, &enumerator );
if( enumerator.found )
return( SFG_Menu *) enumerator.data;
return NULL;
}

View file

@ -0,0 +1,200 @@
/*
* freeglut_teapot.c
*
* Teapot(tm) rendering code.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Fri Dec 24 1999
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Original teapot code copyright follows:
*/
/*
* (c) Copyright 1993, Silicon Graphics, Inc.
*
* ALL RIGHTS RESERVED
*
* Permission to use, copy, modify, and distribute this software
* for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that
* both the copyright notice and this permission notice appear in
* supporting documentation, and that the name of Silicon
* Graphics, Inc. not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
* "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
* OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
* EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
* ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
* INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
* SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
* NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* US Government Users Restricted Rights
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer
* Software clause at DFARS 252.227-7013 and/or in similar or
* successor clauses in the FAR or the DOD or NASA FAR
* Supplement. Unpublished-- rights reserved under the copyright
* laws of the United States. Contractor/manufacturer is Silicon
* Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
* 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
#include "freeglut_teapot_data.h"
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
static void fghTeapot( GLint grid, GLdouble scale, GLenum type )
{
#if defined(_WIN32_WCE)
int i, numV=sizeof(strip_vertices)/4, numI=sizeof(strip_normals)/4;
#else
double p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
long i, j, k, l;
#endif
glPushAttrib( GL_ENABLE_BIT | GL_EVAL_BIT );
glEnable( GL_AUTO_NORMAL );
glEnable( GL_NORMALIZE );
glEnable( GL_MAP2_VERTEX_3 );
glEnable( GL_MAP2_TEXTURE_COORD_2 );
glPushMatrix();
glRotated( 270.0, 1.0, 0.0, 0.0 );
glScaled( 0.5 * scale, 0.5 * scale, 0.5 * scale );
glTranslated( 0.0, 0.0, -1.5 );
#if defined(_WIN32_WCE)
glRotated( 90.0, 1.0, 0.0, 0.0 );
glBegin( GL_TRIANGLE_STRIP );
for( i = 0; i < numV-1; i++ )
{
int vidx = strip_vertices[i],
nidx = strip_normals[i];
if( vidx != -1 )
{
glNormal3fv( normals[nidx] );
glVertex3fv( vertices[vidx] );
}
else
{
glEnd();
glBegin( GL_TRIANGLE_STRIP );
}
}
glEnd();
#else
for (i = 0; i < 10; i++) {
for (j = 0; j < 4; j++) {
for (k = 0; k < 4; k++) {
for (l = 0; l < 3; l++) {
p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l];
if (l == 1)
q[j][k][l] *= -1.0;
if (i < 6) {
r[j][k][l] =
cpdata[patchdata[i][j * 4 + (3 - k)]][l];
if (l == 0)
r[j][k][l] *= -1.0;
s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
if (l == 0)
s[j][k][l] *= -1.0;
if (l == 1)
s[j][k][l] *= -1.0;
}
}
}
}
glMap2d(GL_MAP2_TEXTURE_COORD_2, 0.0, 1.0, 2, 2, 0.0, 1.0, 4, 2,
&tex[0][0][0]);
glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,
&p[0][0][0]);
glMapGrid2d(grid, 0.0, 1.0, grid, 0.0, 1.0);
glEvalMesh2(type, 0, grid, 0, grid);
glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,
&q[0][0][0]);
glEvalMesh2(type, 0, grid, 0, grid);
if (i < 6) {
glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,
&r[0][0][0]);
glEvalMesh2(type, 0, grid, 0, grid);
glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,
&s[0][0][0]);
glEvalMesh2(type, 0, grid, 0, grid);
}
}
#endif /* defined(_WIN32_WCE) */
glPopMatrix();
glPopAttrib();
}
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* Renders a beautiful wired teapot...
*/
void FGAPIENTRY glutWireTeapot( GLdouble size )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTeapot" );
/* We will use the general teapot rendering code */
fghTeapot( 10, size, GL_LINE );
}
/*
* Renders a beautiful filled teapot...
*/
void FGAPIENTRY glutSolidTeapot( GLdouble size )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTeapot" );
/* We will use the general teapot rendering code */
fghTeapot( 7, size, GL_FILL );
}
/*** END OF FILE ***/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -13,6 +13,9 @@
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
/* convert the XInput button state mask to the regular X mouse event button mask */
#define BUTTON_MASK(xistate) ((xistate) << 8)
/* import function from freeglut_main.c */
int fghGetXModifiers( int state );
@ -112,9 +115,9 @@ void fgPrintXIDeviceEvent(XIDeviceEvent* event)
printf(" device: %d (%d)\n", event->deviceid, event->sourceid);
printf(" detail: %d\n", event->detail);
printf(" buttons:");
for (i = 0; i < event->buttons.mask_len * 8; i++)
if (XIMaskIsSet(event->buttons.mask, i))
printf(" %d", i);
for (i = 0; i < event->buttons.mask_len * 8; i++)
if (XIMaskIsSet(event->buttons.mask, i))
printf(" %d", i);
printf("\n");
printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n",
@ -143,76 +146,124 @@ void fgPrintXIDeviceEvent(XIDeviceEvent* event)
* \brief This function is called when an Extension Event is received
* and calls the corresponding callback functions for these events.
*/
void fgHandleExtensionEvents( XEvent* base_ev ) {
void fgHandleExtensionEvents( XEvent* base_ev )
{
XEvent std_ev; /* standard single-pointer event to be added to the event queue */
int i, button = 0;
XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie);
int i, button = 0;
XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie);
/* initialize the generic fields from base_ev */
std_ev.xany = base_ev->xany;
if ( XGetEventData( fgDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) {
XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data);
/*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/
XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data);
XIEnterEvent *evcross;
/*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/
SFG_Window* window = fgWindowByHandle( event->event );
if (!window) return;
if (!window) return;
switch (cookie->evtype) {
switch (cookie->evtype) {
case XI_Enter:
case XI_Leave:
evcross = (XIEnterEvent*)event;
case XI_Enter:
case XI_Leave:
fgState.Modifiers = fghGetXModifiers( ((XIEnterEvent*)event)->mods.base );
INVOKE_WCB( *window, MultiEntry, (
event->deviceid,
(event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT)
));
#if _DEBUG
fgPrintXILeaveEvent((XILeaveEvent*)event);
#endif
break;
fgState.Modifiers = fghGetXModifiers( evcross->mods.base );
INVOKE_WCB( *window, MultiEntry, (
event->deviceid,
(event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT)
));
#if _DEBUG
fgPrintXILeaveEvent((XILeaveEvent*)event);
#endif
case XI_ButtonPress:
case XI_ButtonRelease:
fgState.Modifiers = fghGetXModifiers( event->mods.base );
INVOKE_WCB( *window, MultiButton, (
event->deviceid,
event->event_x,
event->event_y,
(event->detail)-1,
(event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP)
));
INVOKE_WCB( *window, Mouse, (
(event->detail)-1,
(event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP),
event->event_x,
event->event_y
));
break;
/* Also process the standard crossing event */
std_ev.type = evcross->evtype == XI_Enter ? EnterNotify : LeaveNotify;
std_ev.xcrossing.window = evcross->event;
std_ev.xcrossing.root = evcross->root;
std_ev.xcrossing.subwindow = evcross->child;
std_ev.xcrossing.x = evcross->event_x;
std_ev.xcrossing.y = evcross->event_y;
std_ev.xcrossing.x_root = evcross->root_x;
std_ev.xcrossing.y_root = evcross->root_y;
std_ev.xcrossing.mode = evcross->mode;
std_ev.xcrossing.detail = evcross->detail;
std_ev.xcrossing.same_screen = evcross->same_screen;
std_ev.xcrossing.focus = evcross->focus;
std_ev.xcrossing.state = BUTTON_MASK(*(unsigned int*)evcross->buttons.mask);
case XI_Motion:
fgState.Modifiers = fghGetXModifiers( event->mods.base );
for (i = 0; i < event->buttons.mask_len; i++) if (event->buttons.mask[i]) button = 1;
if (button) {
INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) );
INVOKE_WCB( *window, Motion, ( event->event_x, event->event_y ) );
} else {
INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) );
INVOKE_WCB( *window, Passive, ( event->event_x, event->event_y ) );
}
#if _DEBUG
fgPrintXIDeviceEvent(event);
#endif
break;
XPutBackEvent(fgDisplay.Display, &std_ev);
break;
default:
#if _DEBUG
fgWarning( "Unknown XI2 device event:" );
fgPrintXIDeviceEvent( event );
#endif
break;
}
fgState.Modifiers = INVALID_MODIFIERS;
}
XFreeEventData( fgDisplay.Display, cookie );
case XI_ButtonPress:
case XI_ButtonRelease:
fgState.Modifiers = fghGetXModifiers( event->mods.base );
INVOKE_WCB( *window, MultiButton, (
event->deviceid,
event->event_x,
event->event_y,
event->detail-1,
(event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP)
));
/* Also process the standard button event */
std_ev.type = event->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
std_ev.xbutton.window = event->event;
std_ev.xbutton.root = event->root;
std_ev.xbutton.subwindow = event->child;
std_ev.xbutton.x = event->event_x;
std_ev.xbutton.y = event->event_y;
std_ev.xbutton.x_root = event->root_x;
std_ev.xbutton.y_root = event->root_y;
std_ev.xbutton.state = event->mods.base;
std_ev.xbutton.button = event->detail;
XPutBackEvent(fgDisplay.Display, &std_ev);
break;
case XI_Motion:
fgState.Modifiers = fghGetXModifiers( event->mods.base );
for (i = 0; i < event->buttons.mask_len; i++) {
if (event->buttons.mask[i]) {
button = 1;
}
}
if (button) {
INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) );
} else {
INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) );
}
#if _DEBUG
fgPrintXIDeviceEvent(event);
#endif
/* Also process the standard motion event */
std_ev.type = MotionNotify;
std_ev.xmotion.window = event->event;
std_ev.xmotion.root = event->root;
std_ev.xmotion.subwindow = event->child;
std_ev.xmotion.time = event->time;
std_ev.xmotion.x = event->event_x;
std_ev.xmotion.y = event->event_y;
std_ev.xmotion.x_root = event->root_x;
std_ev.xmotion.y_root = event->root_y;
std_ev.xmotion.state = BUTTON_MASK(*(unsigned int*)event->buttons.mask);
std_ev.xmotion.is_hint = NotifyNormal;
XPutBackEvent(fgDisplay.Display, &std_ev);
break;
default:
#if _DEBUG
fgWarning( "Unknown XI2 device event:" );
fgPrintXIDeviceEvent( event );
#endif
break;
}
fgState.Modifiers = INVALID_MODIFIERS;
}
XFreeEventData( fgDisplay.Display, cookie );
}
#endif

View file

@ -74,7 +74,8 @@
#define GLUT_ACTION_ON_WINDOW_CLOSE 0x01F9
#define GLUT_WINDOW_BORDER_WIDTH 0x01FA
#define GLUT_WINDOW_HEADER_HEIGHT 0x01FB
#define GLUT_WINDOW_BORDER_HEIGHT 0x01FB
#define GLUT_WINDOW_HEADER_HEIGHT 0x01FB /* Docs say it should always have been GLUT_WINDOW_BORDER_HEIGHT, keep this for backward compatibility */
#define GLUT_VERSION 0x01FC
@ -83,6 +84,8 @@
#define GLUT_FULL_SCREEN 0x01FF
#define GLUT_SKIP_STALE_MOTION_EVENTS 0x0204
/*
* New tokens for glutInitDisplayMode.
* Only one GLUT_AUXn bit may be used at a time.

View file

@ -113,14 +113,21 @@
*/
#define FREEGLUT 1
#define GLUT_API_VERSION 4
#define FREEGLUT_VERSION_2_0 1
#define GLUT_XLIB_IMPLEMENTATION 13
/* Deprecated:
cf. http://sourceforge.net/mailarchive/forum.php?thread_name=CABcAi1hw7cr4xtigckaGXB5X8wddLfMcbA_rZ3NAuwMrX_zmsw%40mail.gmail.com&forum_name=freeglut-developer */
#define FREEGLUT_VERSION_2_0 1
/*
* Always include OpenGL and GLU headers
*/
#include <GL/gl.h>
#include <GL/glu.h>
#if __APPLE__
# include <OpenGL/gl.h>
# include <OpenGL/glu.h>
#else
# include <GL/gl.h>
# include <GL/glu.h>
#endif
/*
* GLUT API macro definitions -- the special key codes:
@ -531,6 +538,13 @@ FGAPI void FGAPIENTRY glutSolidTetrahedron( void );
FGAPI void FGAPIENTRY glutWireIcosahedron( void );
FGAPI void FGAPIENTRY glutSolidIcosahedron( void );
/*
* Teapot rendering functions, found in freeglut_teapot.c
* NB: front facing polygons have clockwise winding, not counter clockwise
*/
FGAPI void FGAPIENTRY glutWireTeapot( GLdouble size );
FGAPI void FGAPIENTRY glutSolidTeapot( GLdouble size );
/*
* Game mode functions, see freeglut_gamemode.c
*/